package guardiand import ( "context" "fmt" publicrpcv1 "github.com/certusone/wormhole/node/pkg/proto/publicrpc/v1" "github.com/spf13/pflag" "io/ioutil" "log" "time" "github.com/spf13/cobra" "github.com/status-im/keycard-go/hexutils" "google.golang.org/grpc" "google.golang.org/protobuf/encoding/prototext" nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1" ) var ( clientSocketPath *string ) func init() { // Shared flags for all admin commands pf := pflag.NewFlagSet("commonAdminFlags", pflag.ContinueOnError) clientSocketPath = pf.String("socket", "", "gRPC admin server socket to connect to") err := cobra.MarkFlagRequired(pf, "socket") if err != nil { panic(err) } AdminClientInjectGuardianSetUpdateCmd.Flags().AddFlagSet(pf) AdminClientListNodes.Flags().AddFlagSet(pf) AdminCmd.AddCommand(AdminClientInjectGuardianSetUpdateCmd) AdminCmd.AddCommand(AdminClientGovernanceVAAVerifyCmd) AdminCmd.AddCommand(AdminClientListNodes) } var AdminCmd = &cobra.Command{ Use: "admin", Short: "Guardian node admin commands", } var AdminClientInjectGuardianSetUpdateCmd = &cobra.Command{ Use: "governance-vaa-inject [FILENAME]", Short: "Inject and sign a governance VAA from a prototxt file (see docs!)", Run: runInjectGovernanceVAA, Args: cobra.ExactArgs(1), } func getAdminClient(ctx context.Context, addr string) (*grpc.ClientConn, error, nodev1.NodePrivilegedServiceClient) { conn, err := grpc.DialContext(ctx, fmt.Sprintf("unix:///%s", addr), grpc.WithInsecure()) if err != nil { log.Fatalf("failed to connect to %s: %v", addr, err) } c := nodev1.NewNodePrivilegedServiceClient(conn) return conn, err, c } func getPublicRPCServiceClient(ctx context.Context, addr string) (*grpc.ClientConn, error, publicrpcv1.PublicRPCServiceClient) { conn, err := grpc.DialContext(ctx, fmt.Sprintf("unix:///%s", addr), grpc.WithInsecure()) if err != nil { log.Fatalf("failed to connect to %s: %v", addr, err) } c := publicrpcv1.NewPublicRPCServiceClient(conn) return conn, err, c } func runInjectGovernanceVAA(cmd *cobra.Command, args []string) { path := args[0] ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() conn, err, c := getAdminClient(ctx, *clientSocketPath) defer conn.Close() if err != nil { log.Fatalf("failed to get admin client: %v", err) } b, err := ioutil.ReadFile(path) if err != nil { log.Fatalf("failed to read file: %v", err) } var msg nodev1.InjectGovernanceVAARequest err = prototext.Unmarshal(b, &msg) if err != nil { log.Fatalf("failed to deserialize: %v", err) } resp, err := c.InjectGovernanceVAA(ctx, &msg) if err != nil { log.Fatalf("failed to submit governance VAA: %v", err) } log.Printf("VAA successfully injected with digest %s", hexutils.BytesToHex(resp.Digest)) }