From fc64658ce89fb4e298e296c81d135a752ad7b445 Mon Sep 17 00:00:00 2001 From: Hendrik Hofstadt <1405758+hendrikhofstadt@users.noreply.github.com> Date: Tue, 10 Jan 2023 17:54:35 +0100 Subject: [PATCH] node: add admin command to sign existing VAAs (#2183) * node: add admin command to sign existing VAAs Change-Id: Ia59c077db1817a3f35ec30544c307448e01455ca * node: add tests for signing of existing VAAs Change-Id: I16fca1181fc9d96abb4ebdfad91bc686da517090 --- node/cmd/guardiand/adminclient.go | 151 ++++++++++++ node/cmd/guardiand/adminserver.go | 165 ++++++++++++- node/cmd/guardiand/adminserver_test.go | 257 +++++++++++++++++++ node/cmd/guardiand/node.go | 2 +- node/go.mod | 1 + node/go.sum | 2 + node/pkg/proto/node/v1/node.pb.go | 325 ++++++++++++++++++------- node/pkg/proto/node/v1/node.pb.gw.go | 81 ++++++ node/pkg/proto/node/v1/node_grpc.pb.go | 38 +++ proto/node/v1/node.proto | 15 +- 10 files changed, 937 insertions(+), 100 deletions(-) create mode 100644 node/cmd/guardiand/adminserver_test.go diff --git a/node/cmd/guardiand/adminclient.go b/node/cmd/guardiand/adminclient.go index cfdb5c2b3..5d5a9855f 100644 --- a/node/cmd/guardiand/adminclient.go +++ b/node/cmd/guardiand/adminclient.go @@ -2,14 +2,18 @@ package guardiand import ( "context" + "encoding/csv" "encoding/hex" "fmt" + "io" "log" "os" "strconv" "strings" "time" + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/crypto" "github.com/mr-tron/base58" @@ -58,6 +62,8 @@ func init() { ClientChainGovernorReleasePendingVAACmd.Flags().AddFlagSet(pf) ClientChainGovernorResetReleaseTimerCmd.Flags().AddFlagSet(pf) PurgePythNetVaasCmd.Flags().AddFlagSet(pf) + SignExistingVaaCmd.Flags().AddFlagSet(pf) + SignExistingVaasFromCSVCmd.Flags().AddFlagSet(pf) AdminCmd.AddCommand(AdminClientInjectGuardianSetUpdateCmd) AdminCmd.AddCommand(AdminClientFindMissingMessagesCmd) @@ -72,6 +78,8 @@ func init() { AdminCmd.AddCommand(ClientChainGovernorReleasePendingVAACmd) AdminCmd.AddCommand(ClientChainGovernorResetReleaseTimerCmd) AdminCmd.AddCommand(PurgePythNetVaasCmd) + AdminCmd.AddCommand(SignExistingVaaCmd) + AdminCmd.AddCommand(SignExistingVaasFromCSVCmd) } var AdminCmd = &cobra.Command{ @@ -156,6 +164,20 @@ var PurgePythNetVaasCmd = &cobra.Command{ Args: cobra.RangeArgs(1, 2), } +var SignExistingVaaCmd = &cobra.Command{ + Use: "sign-existing-vaa [VAA] [NEW_GUARDIANS] [NEW_GUARDIAN_SET_INDEX]", + Short: "Signs an existing VAA for a new guardian set using the local guardian key. This only works if the new VAA would have quorum.", + Run: runSignExistingVaa, + Args: cobra.ExactArgs(3), +} + +var SignExistingVaasFromCSVCmd = &cobra.Command{ + Use: "sign-existing-vaas-csv [IN_FILE] [OUT_FILE] [NEW_GUARDIANS] [NEW_GUARDIAN_SET_INDEX]", + Short: "Signs a CSV [VAA_ID,VAA_HEX] of existing VAAs for a new guardian set using the local guardian key and writes it to a new CSV. VAAs that don't have quorum on the new set will be dropped.", + Run: runSignExistingVaasFromCSV, + Args: cobra.ExactArgs(4), +} + func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, nodev1.NodePrivilegedServiceClient, error) { conn, err := grpc.DialContext(ctx, fmt.Sprintf("unix:///%s", addr), grpc.WithTransportCredentials(insecure.NewCredentials())) @@ -491,3 +513,132 @@ func runPurgePythNetVaas(cmd *cobra.Command, args []string) { fmt.Println(resp.Response) } + +func runSignExistingVaa(cmd *cobra.Command, args []string) { + existingVAA := ethcommon.Hex2Bytes(args[0]) + if len(existingVAA) == 0 { + log.Fatalf("vaa hex invalid") + } + + newGsStrings := strings.Split(args[1], ",") + + newGsIndex, err := strconv.ParseUint(args[2], 10, 32) + if err != nil { + log.Fatalf("invalid new guardian set index") + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + conn, c, err := getAdminClient(ctx, *clientSocketPath) + if err != nil { + log.Fatalf("failed to get admin client: %v", err) + } + defer conn.Close() + + msg := nodev1.SignExistingVAARequest{ + Vaa: existingVAA, + NewGuardianAddrs: newGsStrings, + NewGuardianSetIndex: uint32(newGsIndex), + } + resp, err := c.SignExistingVAA(ctx, &msg) + if err != nil { + log.Fatalf("failed to run SignExistingVAA RPC: %s", err) + } + + fmt.Println(hex.EncodeToString(resp.Vaa)) +} + +func runSignExistingVaasFromCSV(cmd *cobra.Command, args []string) { + oldVAAFile, err := os.Open(args[0]) + if err != nil { + log.Fatalf("failed to read old VAA db: %v", err) + } + defer oldVAAFile.Close() + + newVAAFile, err := os.OpenFile(args[1], os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644) + if err != nil { + log.Fatalf("failed to create new VAA db: %v", err) + } + defer newVAAFile.Close() + newVAAWriter := csv.NewWriter(newVAAFile) + + newGsStrings := strings.Split(args[2], ",") + + newGsIndex, err := strconv.ParseUint(args[3], 10, 32) + if err != nil { + log.Fatalf("invalid new guardian set index") + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + conn, c, err := getAdminClient(ctx, *clientSocketPath) + if err != nil { + log.Fatalf("failed to get admin client: %v", err) + } + defer conn.Close() + + // Scan the CSV once to make sure it won't fail while reading unless raced + oldVAAReader := csv.NewReader(oldVAAFile) + numOldVAAs := 0 + for { + row, err := oldVAAReader.Read() + if err != nil { + if err == io.EOF { + break + } + log.Fatalf("failed to parse VAA CSV: %v", err) + } + if len(row) != 2 { + log.Fatalf("row [%d] does not have 2 elements", numOldVAAs) + } + numOldVAAs++ + } + + // Reset reader + _, err = oldVAAFile.Seek(0, io.SeekStart) + if err != nil { + log.Fatalf("failed to seek back in CSV file: %v", err) + } + oldVAAReader = csv.NewReader(oldVAAFile) + + counter, i := 0, 0 + for { + row, err := oldVAAReader.Read() + if err != nil { + if err == io.EOF { + break + } + log.Fatalf("failed to parse VAA CSV: %v", err) + } + if len(row) != 2 { + log.Fatalf("row [%d] does not have 2 elements", i) + } + i++ + + if i%10 == 0 { + log.Printf("Processing VAA %d/%d", i, numOldVAAs) + } + + vaaBytes := ethcommon.Hex2Bytes(row[1]) + msg := nodev1.SignExistingVAARequest{ + Vaa: vaaBytes, + NewGuardianAddrs: newGsStrings, + NewGuardianSetIndex: uint32(newGsIndex), + } + resp, err := c.SignExistingVAA(ctx, &msg) + if err != nil { + log.Printf("signing VAA (%s)[%d] failed - skipping: %v", row[0], i, err) + continue + } + err = newVAAWriter.Write([]string{row[0], hex.EncodeToString(resp.Vaa)}) + if err != nil { + log.Fatalf("failed to write new VAA to out db: %v", err) + } + counter++ + } + + log.Printf("Successfully signed %d out of %d VAAs", counter, numOldVAAs) + newVAAWriter.Flush() +} diff --git a/node/cmd/guardiand/adminserver.go b/node/cmd/guardiand/adminserver.go index a05cc6895..13b1392dc 100644 --- a/node/cmd/guardiand/adminserver.go +++ b/node/cmd/guardiand/adminserver.go @@ -1,7 +1,9 @@ package guardiand import ( + "bytes" "context" + "crypto/ecdsa" "encoding/base64" "encoding/hex" "encoding/json" @@ -12,8 +14,13 @@ import ( "net" "net/http" "os" + "sync" "time" + "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors" + ethcrypto "github.com/ethereum/go-ethereum/crypto" + "golang.org/x/exp/slices" + "github.com/certusone/wormhole/node/pkg/db" "github.com/certusone/wormhole/node/pkg/governor" gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1" @@ -32,12 +39,16 @@ import ( type nodePrivilegedService struct { nodev1.UnimplementedNodePrivilegedServiceServer - db *db.Database - injectC chan<- *vaa.VAA - obsvReqSendC chan *gossipv1.ObservationRequest - logger *zap.Logger - signedInC chan *gossipv1.SignedVAAWithQuorum - governor *governor.ChainGovernor + db *db.Database + injectC chan<- *vaa.VAA + obsvReqSendC chan *gossipv1.ObservationRequest + logger *zap.Logger + signedInC chan *gossipv1.SignedVAAWithQuorum + governor *governor.ChainGovernor + evmConnector connectors.Connector + gsCache sync.Map + gk *ecdsa.PrivateKey + guardianAddress ethcommon.Address } // adminGuardianSetUpdateToVAA converts a nodev1.GuardianSetUpdate message to its canonical VAA representation. @@ -387,7 +398,7 @@ func (s *nodePrivilegedService) FindMissingMessages(ctx context.Context, req *no } func adminServiceRunnable(logger *zap.Logger, socketPath string, injectC chan<- *vaa.VAA, signedInC chan *gossipv1.SignedVAAWithQuorum, obsvReqSendC chan *gossipv1.ObservationRequest, - db *db.Database, gst *common.GuardianSetState, gov *governor.ChainGovernor) (supervisor.Runnable, error) { + db *db.Database, gst *common.GuardianSetState, gov *governor.ChainGovernor, gk *ecdsa.PrivateKey, ethRpc *string, ethContract *string) (supervisor.Runnable, error) { // Delete existing UNIX socket, if present. fi, err := os.Stat(socketPath) if err == nil { @@ -419,13 +430,28 @@ func adminServiceRunnable(logger *zap.Logger, socketPath string, injectC chan<- logger.Info("admin server listening on", zap.String("path", socketPath)) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + var evmConnector connectors.Connector + if ethRPC != nil && ethContract != nil { + contract := ethcommon.HexToAddress(*ethContract) + evmConnector, err = connectors.NewEthereumConnector(ctx, "eth", *ethRpc, contract, logger) + if err != nil { + return nil, fmt.Errorf("failed to connecto to ethereum") + } + } + nodeService := &nodePrivilegedService{ - injectC: injectC, - obsvReqSendC: obsvReqSendC, - db: db, - logger: logger.Named("adminservice"), - signedInC: signedInC, - governor: gov, + db: db, + injectC: injectC, + obsvReqSendC: obsvReqSendC, + logger: logger.Named("adminservice"), + signedInC: signedInC, + governor: gov, + gk: gk, + guardianAddress: ethcrypto.PubkeyToAddress(gk.PublicKey), + evmConnector: evmConnector, } publicrpcService := publicrpc.NewPublicrpcServer(logger, db, gst, gov) @@ -539,3 +565,116 @@ func (s *nodePrivilegedService) PurgePythNetVaas(ctx context.Context, req *nodev Response: resp, }, nil } + +func (s *nodePrivilegedService) SignExistingVAA(ctx context.Context, req *nodev1.SignExistingVAARequest) (*nodev1.SignExistingVAAResponse, error) { + v, err := vaa.Unmarshal(req.Vaa) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal VAA: %w", err) + } + + if req.NewGuardianSetIndex <= v.GuardianSetIndex { + return nil, errors.New("new guardian set index must be higher than provided VAA") + } + + if s.evmConnector == nil { + return nil, errors.New("the node needs to have an Ethereum connection configured to sign existing VAAs") + } + + var gs *common.GuardianSet + if cachedGs, exists := s.gsCache.Load(v.GuardianSetIndex); exists { + gs = cachedGs.(*common.GuardianSet) + } else { + evmGs, err := s.evmConnector.GetGuardianSet(ctx, v.GuardianSetIndex) + if err != nil { + return nil, fmt.Errorf("failed to load guardian set [%d]: %w", v.GuardianSetIndex, err) + } + gs = &common.GuardianSet{ + Keys: evmGs.Keys, + Index: v.GuardianSetIndex, + } + s.gsCache.Store(v.GuardianSetIndex, gs) + } + + if slices.Index(gs.Keys, s.guardianAddress) != -1 { + return nil, fmt.Errorf("local guardian is already on the old set") + } + + // Verify VAA + err = v.Verify(gs.Keys) + if err != nil { + return nil, fmt.Errorf("failed to verify existing VAA: %w", err) + } + + if len(req.NewGuardianAddrs) > 255 { + return nil, errors.New("new guardian set has too many guardians") + } + newGS := make([]ethcommon.Address, len(req.NewGuardianAddrs)) + for i, guardianString := range req.NewGuardianAddrs { + guardianAddress := ethcommon.HexToAddress(guardianString) + newGS[i] = guardianAddress + } + + // Make sure there are no duplicates. Compact needs to take a sorted slice to remove all duplicates. + newGSSorted := slices.Clone(newGS) + slices.SortFunc(newGSSorted, func(a, b ethcommon.Address) bool { + return bytes.Compare(a[:], b[:]) < 0 + }) + newGsLen := len(newGSSorted) + if len(slices.Compact(newGSSorted)) != newGsLen { + return nil, fmt.Errorf("duplicate guardians in the guardian set") + } + + localGuardianIndex := slices.Index(newGS, s.guardianAddress) + if localGuardianIndex == -1 { + return nil, fmt.Errorf("local guardian is not a member of the new guardian set") + } + + newVAA := &vaa.VAA{ + Version: v.Version, + // Set the new guardian set index + GuardianSetIndex: req.NewGuardianSetIndex, + // Signatures will be repopulated + Signatures: nil, + Timestamp: v.Timestamp, + Nonce: v.Nonce, + Sequence: v.Sequence, + ConsistencyLevel: v.ConsistencyLevel, + EmitterChain: v.EmitterChain, + EmitterAddress: v.EmitterAddress, + Payload: v.Payload, + } + + // Copy original VAA signatures + for _, sig := range v.Signatures { + signerAddress := gs.Keys[sig.Index] + newIndex := slices.Index(newGS, signerAddress) + // Guardian is not part of the new set + if newIndex == -1 { + continue + } + newVAA.Signatures = append(newVAA.Signatures, &vaa.Signature{ + Index: uint8(newIndex), + Signature: sig.Signature, + }) + } + + // Add our own signature only if the new guardian set would reach quorum + if vaa.CalculateQuorum(len(newGS)) > len(newVAA.Signatures)+1 { + return nil, errors.New("cannot reach quorum on new guardian set with the local signature") + } + + // Add local signature + newVAA.AddSignature(s.gk, uint8(localGuardianIndex)) + + // Sort VAA signatures by guardian ID + slices.SortFunc(newVAA.Signatures, func(a, b *vaa.Signature) bool { + return a.Index < b.Index + }) + + newVAABytes, err := newVAA.Marshal() + if err != nil { + return nil, fmt.Errorf("failed to marshal new VAA: %w", err) + } + + return &nodev1.SignExistingVAAResponse{Vaa: newVAABytes}, nil +} diff --git a/node/cmd/guardiand/adminserver_test.go b/node/cmd/guardiand/adminserver_test.go new file mode 100644 index 000000000..c83c17a7f --- /dev/null +++ b/node/cmd/guardiand/adminserver_test.go @@ -0,0 +1,257 @@ +package guardiand + +import ( + "context" + "crypto/ecdsa" + "testing" + "time" + + nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1" + "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors" + "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/ethabi" + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + ethcrypto "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/event" + "github.com/stretchr/testify/require" + "github.com/wormhole-foundation/wormhole/sdk/vaa" + "go.uber.org/zap" +) + +type mockEVMConnector struct { + guardianAddrs []common.Address + guardianSetIndex uint32 +} + +func (m mockEVMConnector) GetCurrentGuardianSetIndex(ctx context.Context) (uint32, error) { + return m.guardianSetIndex, nil +} + +func (m mockEVMConnector) GetGuardianSet(ctx context.Context, index uint32) (ethabi.StructsGuardianSet, error) { + return ethabi.StructsGuardianSet{ + Keys: m.guardianAddrs, + ExpirationTime: 0, + }, nil +} + +func (m mockEVMConnector) NetworkName() string { + panic("unimplemented") +} + +func (m mockEVMConnector) ContractAddress() common.Address { + panic("unimplemented") +} + +func (m mockEVMConnector) WatchLogMessagePublished(ctx context.Context, sink chan<- *ethabi.AbiLogMessagePublished) (event.Subscription, error) { + panic("unimplemented") +} + +func (m mockEVMConnector) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + panic("unimplemented") +} + +func (m mockEVMConnector) TimeOfBlockByHash(ctx context.Context, hash common.Hash) (uint64, error) { + panic("unimplemented") +} + +func (m mockEVMConnector) ParseLogMessagePublished(log types.Log) (*ethabi.AbiLogMessagePublished, error) { + panic("unimplemented") +} + +func (m mockEVMConnector) SubscribeForBlocks(ctx context.Context, sink chan<- *connectors.NewBlock) (ethereum.Subscription, error) { + panic("unimplemented") +} + +func (m mockEVMConnector) RawCallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { + panic("unimplemented") +} + +func generateGS(num int) (keys []*ecdsa.PrivateKey, addrs []common.Address) { + for i := 0; i < num; i++ { + key, err := ethcrypto.GenerateKey() + if err != nil { + panic(err) + } + keys = append(keys, key) + addrs = append(addrs, ethcrypto.PubkeyToAddress(key.PublicKey)) + } + return +} + +func addrsToHexStrings(addrs []common.Address) (out []string) { + for _, addr := range addrs { + out = append(out, addr.String()) + } + return +} + +func generateMockVAA(gsIndex uint32, gsKeys []*ecdsa.PrivateKey) []byte { + v := &vaa.VAA{ + Version: 1, + GuardianSetIndex: gsIndex, + Signatures: nil, + Timestamp: time.Now(), + Nonce: 3, + Sequence: 79, + ConsistencyLevel: 1, + EmitterChain: 1, + EmitterAddress: vaa.Address{}, + Payload: []byte("test"), + } + for i, key := range gsKeys { + v.AddSignature(key, uint8(i)) + } + + vBytes, err := v.Marshal() + if err != nil { + panic(err) + } + return vBytes +} + +func setupAdminServerForVAASigning(gsIndex uint32, gsAddrs []common.Address) *nodePrivilegedService { + gk, err := ethcrypto.GenerateKey() + if err != nil { + panic(err) + } + + connector := mockEVMConnector{ + guardianAddrs: gsAddrs, + guardianSetIndex: gsIndex, + } + + return &nodePrivilegedService{ + db: nil, + injectC: nil, + obsvReqSendC: nil, + logger: zap.L(), + signedInC: nil, + governor: nil, + evmConnector: connector, + gk: gk, + guardianAddress: ethcrypto.PubkeyToAddress(gk.PublicKey), + } +} + +func TestSignExistingVAA_NoVAA(t *testing.T) { + s := setupAdminServerForVAASigning(0, []common.Address{}) + + _, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{ + Vaa: nil, + NewGuardianAddrs: nil, + NewGuardianSetIndex: 0, + }) + require.ErrorContains(t, err, "failed to unmarshal VAA") +} + +func TestSignExistingVAA_NotGuardian(t *testing.T) { + gsKeys, gsAddrs := generateGS(5) + s := setupAdminServerForVAASigning(0, gsAddrs) + + v := generateMockVAA(0, gsKeys) + + _, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{ + Vaa: v, + NewGuardianAddrs: addrsToHexStrings(gsAddrs), + NewGuardianSetIndex: 1, + }) + require.ErrorContains(t, err, "local guardian is not a member of the new guardian set") +} + +func TestSignExistingVAA_InvalidVAA(t *testing.T) { + gsKeys, gsAddrs := generateGS(5) + s := setupAdminServerForVAASigning(0, gsAddrs) + + v := generateMockVAA(0, gsKeys[:2]) + + gsAddrs = append(gsAddrs, s.guardianAddress) + _, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{ + Vaa: v, + NewGuardianAddrs: addrsToHexStrings(gsAddrs), + NewGuardianSetIndex: 1, + }) + require.ErrorContains(t, err, "failed to verify existing VAA") +} + +func TestSignExistingVAA_DuplicateGuardian(t *testing.T) { + gsKeys, gsAddrs := generateGS(5) + s := setupAdminServerForVAASigning(0, gsAddrs) + + v := generateMockVAA(0, gsKeys) + + gsAddrs = append(gsAddrs, s.guardianAddress) + gsAddrs = append(gsAddrs, s.guardianAddress) + _, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{ + Vaa: v, + NewGuardianAddrs: addrsToHexStrings(gsAddrs), + NewGuardianSetIndex: 1, + }) + require.ErrorContains(t, err, "duplicate guardians in the guardian set") +} + +func TestSignExistingVAA_AlreadyGuardian(t *testing.T) { + gsKeys, gsAddrs := generateGS(5) + s := setupAdminServerForVAASigning(0, gsAddrs) + s.evmConnector = mockEVMConnector{ + guardianAddrs: append(gsAddrs, s.guardianAddress), + guardianSetIndex: 0, + } + + v := generateMockVAA(0, append(gsKeys, s.gk)) + + gsAddrs = append(gsAddrs, s.guardianAddress) + _, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{ + Vaa: v, + NewGuardianAddrs: addrsToHexStrings(gsAddrs), + NewGuardianSetIndex: 1, + }) + require.ErrorContains(t, err, "local guardian is already on the old set") +} + +func TestSignExistingVAA_NotAFutureGuardian(t *testing.T) { + gsKeys, gsAddrs := generateGS(5) + s := setupAdminServerForVAASigning(0, gsAddrs) + + v := generateMockVAA(0, gsKeys) + + _, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{ + Vaa: v, + NewGuardianAddrs: addrsToHexStrings(gsAddrs), + NewGuardianSetIndex: 1, + }) + require.ErrorContains(t, err, "local guardian is not a member of the new guardian set") +} + +func TestSignExistingVAA_CantReachQuorum(t *testing.T) { + gsKeys, gsAddrs := generateGS(5) + s := setupAdminServerForVAASigning(0, gsAddrs) + + v := generateMockVAA(0, gsKeys) + + gsAddrs = append(gsAddrs, s.guardianAddress) + _, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{ + Vaa: v, + NewGuardianAddrs: addrsToHexStrings(append(gsAddrs, common.Address{0, 1}, common.Address{3, 1}, common.Address{8, 1})), + NewGuardianSetIndex: 1, + }) + require.ErrorContains(t, err, "cannot reach quorum on new guardian set with the local signature") +} + +func TestSignExistingVAA_Valid(t *testing.T) { + gsKeys, gsAddrs := generateGS(5) + s := setupAdminServerForVAASigning(0, gsAddrs) + + v := generateMockVAA(0, gsKeys) + + gsAddrs = append(gsAddrs, s.guardianAddress) + res, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{ + Vaa: v, + NewGuardianAddrs: addrsToHexStrings(gsAddrs), + NewGuardianSetIndex: 1, + }) + + require.NoError(t, err) + v2 := generateMockVAA(1, append(gsKeys, s.gk)) + require.Equal(t, v2, res.Vaa) +} diff --git a/node/cmd/guardiand/node.go b/node/cmd/guardiand/node.go index 4611505d6..ff1f2bd3d 100644 --- a/node/cmd/guardiand/node.go +++ b/node/cmd/guardiand/node.go @@ -917,7 +917,7 @@ func runNode(cmd *cobra.Command, args []string) { } // local admin service socket - adminService, err := adminServiceRunnable(logger, *adminSocketPath, injectC, signedInC, obsvReqSendC, db, gst, gov) + adminService, err := adminServiceRunnable(logger, *adminSocketPath, injectC, signedInC, obsvReqSendC, db, gst, gov, gk, ethRPC, ethContract) if err != nil { logger.Fatal("failed to create admin service socket", zap.Error(err)) } diff --git a/node/go.mod b/node/go.mod index 5080b6343..51f3c7b59 100644 --- a/node/go.mod +++ b/node/go.mod @@ -56,6 +56,7 @@ require ( github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/test-go/testify v1.1.4 github.com/wormhole-foundation/wormhole/sdk v0.0.0-00010101000000-000000000000 + golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5 golang.org/x/text v0.4.0 ) diff --git a/node/go.sum b/node/go.sum index 9c42a17b9..fe4813897 100644 --- a/node/go.sum +++ b/node/go.sum @@ -1338,6 +1338,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5 h1:rxKZ2gOnYxjfmakvUUqh9Gyb6KXfrj7JWTxORTYqb0E= +golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= diff --git a/node/pkg/proto/node/v1/node.pb.go b/node/pkg/proto/node/v1/node.pb.go index e457230e8..178f49ce2 100644 --- a/node/pkg/proto/node/v1/node.pb.go +++ b/node/pkg/proto/node/v1/node.pb.go @@ -1485,6 +1485,116 @@ func (x *PurgePythNetVaasResponse) GetResponse() string { return "" } +type SignExistingVAARequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vaa []byte `protobuf:"bytes,1,opt,name=vaa,proto3" json:"vaa,omitempty"` + NewGuardianAddrs []string `protobuf:"bytes,2,rep,name=new_guardian_addrs,json=newGuardianAddrs,proto3" json:"new_guardian_addrs,omitempty"` + NewGuardianSetIndex uint32 `protobuf:"varint,3,opt,name=new_guardian_set_index,json=newGuardianSetIndex,proto3" json:"new_guardian_set_index,omitempty"` +} + +func (x *SignExistingVAARequest) Reset() { + *x = SignExistingVAARequest{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignExistingVAARequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignExistingVAARequest) ProtoMessage() {} + +func (x *SignExistingVAARequest) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignExistingVAARequest.ProtoReflect.Descriptor instead. +func (*SignExistingVAARequest) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{26} +} + +func (x *SignExistingVAARequest) GetVaa() []byte { + if x != nil { + return x.Vaa + } + return nil +} + +func (x *SignExistingVAARequest) GetNewGuardianAddrs() []string { + if x != nil { + return x.NewGuardianAddrs + } + return nil +} + +func (x *SignExistingVAARequest) GetNewGuardianSetIndex() uint32 { + if x != nil { + return x.NewGuardianSetIndex + } + return 0 +} + +type SignExistingVAAResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vaa []byte `protobuf:"bytes,1,opt,name=vaa,proto3" json:"vaa,omitempty"` +} + +func (x *SignExistingVAAResponse) Reset() { + *x = SignExistingVAAResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_node_v1_node_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignExistingVAAResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignExistingVAAResponse) ProtoMessage() {} + +func (x *SignExistingVAAResponse) ProtoReflect() protoreflect.Message { + mi := &file_node_v1_node_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignExistingVAAResponse.ProtoReflect.Descriptor instead. +func (*SignExistingVAAResponse) Descriptor() ([]byte, []int) { + return file_node_v1_node_proto_rawDescGZIP(), []int{27} +} + +func (x *SignExistingVAAResponse) GetVaa() []byte { + if x != nil { + return x.Vaa + } + return nil +} + // List of guardian set members. type GuardianSetUpdate_Guardian struct { state protoimpl.MessageState @@ -1501,7 +1611,7 @@ type GuardianSetUpdate_Guardian struct { func (x *GuardianSetUpdate_Guardian) Reset() { *x = GuardianSetUpdate_Guardian{} if protoimpl.UnsafeEnabled { - mi := &file_node_v1_node_proto_msgTypes[26] + mi := &file_node_v1_node_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1514,7 +1624,7 @@ func (x *GuardianSetUpdate_Guardian) String() string { func (*GuardianSetUpdate_Guardian) ProtoMessage() {} func (x *GuardianSetUpdate_Guardian) ProtoReflect() protoreflect.Message { - mi := &file_node_v1_node_proto_msgTypes[26] + mi := &file_node_v1_node_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1720,74 +1830,91 @@ var file_node_v1_node_proto_rawDesc = []byte{ 0x67, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x36, 0x0a, 0x18, 0x50, 0x75, 0x72, 0x67, 0x65, 0x50, 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe5, 0x07, - 0x0a, 0x15, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x49, 0x6e, 0x6a, 0x65, 0x63, - 0x74, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x12, 0x23, - 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x6a, 0x65, 0x63, 0x74, 0x47, - 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, - 0x6a, 0x65, 0x63, 0x74, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, - 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x46, 0x69, 0x6e, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8d, 0x01, + 0x0a, 0x16, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x41, + 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x76, 0x61, 0x61, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x65, + 0x77, 0x5f, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x47, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x33, 0x0a, 0x16, 0x6e, 0x65, 0x77, 0x5f, + 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6e, 0x65, 0x77, 0x47, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x2b, 0x0a, + 0x17, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x76, 0x61, 0x61, 0x32, 0xbb, 0x08, 0x0a, 0x15, 0x4e, + 0x6f, 0x64, 0x65, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x49, 0x6e, 0x6a, 0x65, 0x63, 0x74, 0x47, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x12, 0x23, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x6a, 0x65, 0x63, 0x74, 0x47, 0x6f, 0x76, 0x65, + 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x6a, 0x65, 0x63, + 0x74, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x41, 0x41, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x69, + 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x23, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, - 0x12, 0x23, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4d, - 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x16, 0x53, - 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, - 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73, 0x65, - 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, - 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, - 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, - 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, - 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, - 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x12, - 0x23, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, - 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x6f, - 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x1b, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x44, 0x72, 0x6f, 0x70, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x12, 0x2b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, - 0x72, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x16, 0x53, 0x65, 0x6e, 0x64, + 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x26, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, + 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, + 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, + 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, + 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x23, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, + 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x24, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x1b, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x12, 0x2b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x44, 0x72, - 0x6f, 0x70, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, - 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x12, 0x2e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x43, 0x68, 0x61, - 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x2e, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, - 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, - 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, - 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, - 0x69, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, - 0x50, 0x75, 0x72, 0x67, 0x65, 0x50, 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, - 0x12, 0x20, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, - 0x50, 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, - 0x67, 0x65, 0x50, 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, 0x73, 0x6f, 0x6e, 0x65, 0x2f, 0x77, 0x6f, - 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, - 0x64, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x70, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x44, 0x72, 0x6f, 0x70, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, + 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x56, 0x41, 0x41, 0x12, 0x2e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x1e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, + 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x2e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, + 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, + 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x50, 0x75, 0x72, + 0x67, 0x65, 0x50, 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x12, 0x20, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, 0x50, 0x79, 0x74, + 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x21, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, 0x50, + 0x79, 0x74, 0x68, 0x4e, 0x65, 0x74, 0x56, 0x61, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x56, 0x41, 0x41, 0x12, 0x1f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x69, 0x67, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x56, 0x41, 0x41, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, 0x73, 0x6f, 0x6e, 0x65, + 0x2f, 0x77, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, + 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, + 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1802,7 +1929,7 @@ func file_node_v1_node_proto_rawDescGZIP() []byte { return file_node_v1_node_proto_rawDescData } -var file_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 27) +var file_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 29) var file_node_v1_node_proto_goTypes = []interface{}{ (*InjectGovernanceVAARequest)(nil), // 0: node.v1.InjectGovernanceVAARequest (*GovernanceMessage)(nil), // 1: node.v1.GovernanceMessage @@ -1830,8 +1957,10 @@ var file_node_v1_node_proto_goTypes = []interface{}{ (*ChainGovernorResetReleaseTimerResponse)(nil), // 23: node.v1.ChainGovernorResetReleaseTimerResponse (*PurgePythNetVaasRequest)(nil), // 24: node.v1.PurgePythNetVaasRequest (*PurgePythNetVaasResponse)(nil), // 25: node.v1.PurgePythNetVaasResponse - (*GuardianSetUpdate_Guardian)(nil), // 26: node.v1.GuardianSetUpdate.Guardian - (*v1.ObservationRequest)(nil), // 27: gossip.v1.ObservationRequest + (*SignExistingVAARequest)(nil), // 26: node.v1.SignExistingVAARequest + (*SignExistingVAAResponse)(nil), // 27: node.v1.SignExistingVAAResponse + (*GuardianSetUpdate_Guardian)(nil), // 28: node.v1.GuardianSetUpdate.Guardian + (*v1.ObservationRequest)(nil), // 29: gossip.v1.ObservationRequest } var file_node_v1_node_proto_depIdxs = []int32{ 1, // 0: node.v1.InjectGovernanceVAARequest.messages:type_name -> node.v1.GovernanceMessage @@ -1841,8 +1970,8 @@ var file_node_v1_node_proto_depIdxs = []int32{ 7, // 4: node.v1.GovernanceMessage.bridge_contract_upgrade:type_name -> node.v1.BridgeUpgradeContract 8, // 5: node.v1.GovernanceMessage.wormchain_store_code:type_name -> node.v1.WormchainStoreCode 9, // 6: node.v1.GovernanceMessage.wormchain_instantiate_contract:type_name -> node.v1.WormchainInstantiateContract - 26, // 7: node.v1.GuardianSetUpdate.guardians:type_name -> node.v1.GuardianSetUpdate.Guardian - 27, // 8: node.v1.SendObservationRequestRequest.observation_request:type_name -> gossip.v1.ObservationRequest + 28, // 7: node.v1.GuardianSetUpdate.guardians:type_name -> node.v1.GuardianSetUpdate.Guardian + 29, // 8: node.v1.SendObservationRequestRequest.observation_request:type_name -> gossip.v1.ObservationRequest 0, // 9: node.v1.NodePrivilegedService.InjectGovernanceVAA:input_type -> node.v1.InjectGovernanceVAARequest 10, // 10: node.v1.NodePrivilegedService.FindMissingMessages:input_type -> node.v1.FindMissingMessagesRequest 12, // 11: node.v1.NodePrivilegedService.SendObservationRequest:input_type -> node.v1.SendObservationRequestRequest @@ -1852,17 +1981,19 @@ var file_node_v1_node_proto_depIdxs = []int32{ 20, // 15: node.v1.NodePrivilegedService.ChainGovernorReleasePendingVAA:input_type -> node.v1.ChainGovernorReleasePendingVAARequest 22, // 16: node.v1.NodePrivilegedService.ChainGovernorResetReleaseTimer:input_type -> node.v1.ChainGovernorResetReleaseTimerRequest 24, // 17: node.v1.NodePrivilegedService.PurgePythNetVaas:input_type -> node.v1.PurgePythNetVaasRequest - 2, // 18: node.v1.NodePrivilegedService.InjectGovernanceVAA:output_type -> node.v1.InjectGovernanceVAAResponse - 11, // 19: node.v1.NodePrivilegedService.FindMissingMessages:output_type -> node.v1.FindMissingMessagesResponse - 13, // 20: node.v1.NodePrivilegedService.SendObservationRequest:output_type -> node.v1.SendObservationRequestResponse - 15, // 21: node.v1.NodePrivilegedService.ChainGovernorStatus:output_type -> node.v1.ChainGovernorStatusResponse - 17, // 22: node.v1.NodePrivilegedService.ChainGovernorReload:output_type -> node.v1.ChainGovernorReloadResponse - 19, // 23: node.v1.NodePrivilegedService.ChainGovernorDropPendingVAA:output_type -> node.v1.ChainGovernorDropPendingVAAResponse - 21, // 24: node.v1.NodePrivilegedService.ChainGovernorReleasePendingVAA:output_type -> node.v1.ChainGovernorReleasePendingVAAResponse - 23, // 25: node.v1.NodePrivilegedService.ChainGovernorResetReleaseTimer:output_type -> node.v1.ChainGovernorResetReleaseTimerResponse - 25, // 26: node.v1.NodePrivilegedService.PurgePythNetVaas:output_type -> node.v1.PurgePythNetVaasResponse - 18, // [18:27] is the sub-list for method output_type - 9, // [9:18] is the sub-list for method input_type + 26, // 18: node.v1.NodePrivilegedService.SignExistingVAA:input_type -> node.v1.SignExistingVAARequest + 2, // 19: node.v1.NodePrivilegedService.InjectGovernanceVAA:output_type -> node.v1.InjectGovernanceVAAResponse + 11, // 20: node.v1.NodePrivilegedService.FindMissingMessages:output_type -> node.v1.FindMissingMessagesResponse + 13, // 21: node.v1.NodePrivilegedService.SendObservationRequest:output_type -> node.v1.SendObservationRequestResponse + 15, // 22: node.v1.NodePrivilegedService.ChainGovernorStatus:output_type -> node.v1.ChainGovernorStatusResponse + 17, // 23: node.v1.NodePrivilegedService.ChainGovernorReload:output_type -> node.v1.ChainGovernorReloadResponse + 19, // 24: node.v1.NodePrivilegedService.ChainGovernorDropPendingVAA:output_type -> node.v1.ChainGovernorDropPendingVAAResponse + 21, // 25: node.v1.NodePrivilegedService.ChainGovernorReleasePendingVAA:output_type -> node.v1.ChainGovernorReleasePendingVAAResponse + 23, // 26: node.v1.NodePrivilegedService.ChainGovernorResetReleaseTimer:output_type -> node.v1.ChainGovernorResetReleaseTimerResponse + 25, // 27: node.v1.NodePrivilegedService.PurgePythNetVaas:output_type -> node.v1.PurgePythNetVaasResponse + 27, // 28: node.v1.NodePrivilegedService.SignExistingVAA:output_type -> node.v1.SignExistingVAAResponse + 19, // [19:29] is the sub-list for method output_type + 9, // [9:19] is the sub-list for method input_type 9, // [9:9] is the sub-list for extension type_name 9, // [9:9] is the sub-list for extension extendee 0, // [0:9] is the sub-list for field type_name @@ -2187,6 +2318,30 @@ func file_node_v1_node_proto_init() { } } file_node_v1_node_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignExistingVAARequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignExistingVAAResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_node_v1_node_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GuardianSetUpdate_Guardian); i { case 0: return &v.state @@ -2213,7 +2368,7 @@ func file_node_v1_node_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_node_v1_node_proto_rawDesc, NumEnums: 0, - NumMessages: 27, + NumMessages: 29, NumExtensions: 0, NumServices: 1, }, diff --git a/node/pkg/proto/node/v1/node.pb.gw.go b/node/pkg/proto/node/v1/node.pb.gw.go index 59455baf6..20c28323f 100644 --- a/node/pkg/proto/node/v1/node.pb.gw.go +++ b/node/pkg/proto/node/v1/node.pb.gw.go @@ -337,6 +337,40 @@ func local_request_NodePrivilegedService_PurgePythNetVaas_0(ctx context.Context, } +func request_NodePrivilegedService_SignExistingVAA_0(ctx context.Context, marshaler runtime.Marshaler, client NodePrivilegedServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignExistingVAARequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.SignExistingVAA(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_NodePrivilegedService_SignExistingVAA_0(ctx context.Context, marshaler runtime.Marshaler, server NodePrivilegedServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignExistingVAARequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.SignExistingVAA(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterNodePrivilegedServiceHandlerServer registers the http handlers for service NodePrivilegedService to "mux". // UnaryRPC :call NodePrivilegedServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -550,6 +584,29 @@ func RegisterNodePrivilegedServiceHandlerServer(ctx context.Context, mux *runtim }) + mux.Handle("POST", pattern_NodePrivilegedService_SignExistingVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/node.v1.NodePrivilegedService/SignExistingVAA", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/SignExistingVAA")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_NodePrivilegedService_SignExistingVAA_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_NodePrivilegedService_SignExistingVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -771,6 +828,26 @@ func RegisterNodePrivilegedServiceHandlerClient(ctx context.Context, mux *runtim }) + mux.Handle("POST", pattern_NodePrivilegedService_SignExistingVAA_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/node.v1.NodePrivilegedService/SignExistingVAA", runtime.WithHTTPPathPattern("/node.v1.NodePrivilegedService/SignExistingVAA")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_NodePrivilegedService_SignExistingVAA_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_NodePrivilegedService_SignExistingVAA_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -792,6 +869,8 @@ var ( pattern_NodePrivilegedService_ChainGovernorResetReleaseTimer_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "ChainGovernorResetReleaseTimer"}, "")) pattern_NodePrivilegedService_PurgePythNetVaas_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "PurgePythNetVaas"}, "")) + + pattern_NodePrivilegedService_SignExistingVAA_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"node.v1.NodePrivilegedService", "SignExistingVAA"}, "")) ) var ( @@ -812,4 +891,6 @@ var ( forward_NodePrivilegedService_ChainGovernorResetReleaseTimer_0 = runtime.ForwardResponseMessage forward_NodePrivilegedService_PurgePythNetVaas_0 = runtime.ForwardResponseMessage + + forward_NodePrivilegedService_SignExistingVAA_0 = runtime.ForwardResponseMessage ) diff --git a/node/pkg/proto/node/v1/node_grpc.pb.go b/node/pkg/proto/node/v1/node_grpc.pb.go index a53c4fdb0..b2d8f5224 100644 --- a/node/pkg/proto/node/v1/node_grpc.pb.go +++ b/node/pkg/proto/node/v1/node_grpc.pb.go @@ -46,6 +46,8 @@ type NodePrivilegedServiceClient interface { ChainGovernorResetReleaseTimer(ctx context.Context, in *ChainGovernorResetReleaseTimerRequest, opts ...grpc.CallOption) (*ChainGovernorResetReleaseTimerResponse, error) // PurgePythNetVaas deletes PythNet VAAs from the database that are more than the specified number of days old. PurgePythNetVaas(ctx context.Context, in *PurgePythNetVaasRequest, opts ...grpc.CallOption) (*PurgePythNetVaasResponse, error) + // SignExistingVAA signs an existing VAA for a new guardian set using the local guardian key. + SignExistingVAA(ctx context.Context, in *SignExistingVAARequest, opts ...grpc.CallOption) (*SignExistingVAAResponse, error) } type nodePrivilegedServiceClient struct { @@ -137,6 +139,15 @@ func (c *nodePrivilegedServiceClient) PurgePythNetVaas(ctx context.Context, in * return out, nil } +func (c *nodePrivilegedServiceClient) SignExistingVAA(ctx context.Context, in *SignExistingVAARequest, opts ...grpc.CallOption) (*SignExistingVAAResponse, error) { + out := new(SignExistingVAAResponse) + err := c.cc.Invoke(ctx, "/node.v1.NodePrivilegedService/SignExistingVAA", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // NodePrivilegedServiceServer is the server API for NodePrivilegedService service. // All implementations must embed UnimplementedNodePrivilegedServiceServer // for forward compatibility @@ -169,6 +180,8 @@ type NodePrivilegedServiceServer interface { ChainGovernorResetReleaseTimer(context.Context, *ChainGovernorResetReleaseTimerRequest) (*ChainGovernorResetReleaseTimerResponse, error) // PurgePythNetVaas deletes PythNet VAAs from the database that are more than the specified number of days old. PurgePythNetVaas(context.Context, *PurgePythNetVaasRequest) (*PurgePythNetVaasResponse, error) + // SignExistingVAA signs an existing VAA for a new guardian set using the local guardian key. + SignExistingVAA(context.Context, *SignExistingVAARequest) (*SignExistingVAAResponse, error) mustEmbedUnimplementedNodePrivilegedServiceServer() } @@ -203,6 +216,9 @@ func (UnimplementedNodePrivilegedServiceServer) ChainGovernorResetReleaseTimer(c func (UnimplementedNodePrivilegedServiceServer) PurgePythNetVaas(context.Context, *PurgePythNetVaasRequest) (*PurgePythNetVaasResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method PurgePythNetVaas not implemented") } +func (UnimplementedNodePrivilegedServiceServer) SignExistingVAA(context.Context, *SignExistingVAARequest) (*SignExistingVAAResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SignExistingVAA not implemented") +} func (UnimplementedNodePrivilegedServiceServer) mustEmbedUnimplementedNodePrivilegedServiceServer() {} // UnsafeNodePrivilegedServiceServer may be embedded to opt out of forward compatibility for this service. @@ -378,6 +394,24 @@ func _NodePrivilegedService_PurgePythNetVaas_Handler(srv interface{}, ctx contex return interceptor(ctx, in, info, handler) } +func _NodePrivilegedService_SignExistingVAA_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignExistingVAARequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(NodePrivilegedServiceServer).SignExistingVAA(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/node.v1.NodePrivilegedService/SignExistingVAA", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(NodePrivilegedServiceServer).SignExistingVAA(ctx, req.(*SignExistingVAARequest)) + } + return interceptor(ctx, in, info, handler) +} + // NodePrivilegedService_ServiceDesc is the grpc.ServiceDesc for NodePrivilegedService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -421,6 +455,10 @@ var NodePrivilegedService_ServiceDesc = grpc.ServiceDesc{ MethodName: "PurgePythNetVaas", Handler: _NodePrivilegedService_PurgePythNetVaas_Handler, }, + { + MethodName: "SignExistingVAA", + Handler: _NodePrivilegedService_SignExistingVAA_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "node/v1/node.proto", diff --git a/proto/node/v1/node.proto b/proto/node/v1/node.proto index ffae513a5..282022083 100644 --- a/proto/node/v1/node.proto +++ b/proto/node/v1/node.proto @@ -45,7 +45,10 @@ service NodePrivilegedService { rpc ChainGovernorResetReleaseTimer (ChainGovernorResetReleaseTimerRequest) returns (ChainGovernorResetReleaseTimerResponse); // PurgePythNetVaas deletes PythNet VAAs from the database that are more than the specified number of days old. - rpc PurgePythNetVaas (PurgePythNetVaasRequest) returns (PurgePythNetVaasResponse); + rpc PurgePythNetVaas (PurgePythNetVaasRequest) returns (PurgePythNetVaasResponse); + + // SignExistingVAA signs an existing VAA for a new guardian set using the local guardian key. + rpc SignExistingVAA (SignExistingVAARequest) returns (SignExistingVAAResponse); } message InjectGovernanceVAARequest { @@ -233,3 +236,13 @@ message PurgePythNetVaasRequest { message PurgePythNetVaasResponse { string response = 1; } + +message SignExistingVAARequest { + bytes vaa = 1; + repeated string new_guardian_addrs = 2; + uint32 new_guardian_set_index = 3; +} + +message SignExistingVAAResponse { + bytes vaa = 1; +}