publicrpcserver.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package publicrpc
  2. import (
  3. "context"
  4. "encoding/hex"
  5. "fmt"
  6. "github.com/certusone/wormhole/node/pkg/common"
  7. "github.com/certusone/wormhole/node/pkg/db"
  8. publicrpcv1 "github.com/certusone/wormhole/node/pkg/proto/publicrpc/v1"
  9. "github.com/certusone/wormhole/node/pkg/vaa"
  10. "go.uber.org/zap"
  11. "google.golang.org/grpc/codes"
  12. "google.golang.org/grpc/status"
  13. )
  14. // PublicrpcServer implements the publicrpc gRPC service.
  15. type PublicrpcServer struct {
  16. publicrpcv1.UnsafePublicRPCServiceServer
  17. logger *zap.Logger
  18. db *db.Database
  19. gst *common.GuardianSetState
  20. }
  21. func NewPublicrpcServer(
  22. logger *zap.Logger,
  23. db *db.Database,
  24. gst *common.GuardianSetState,
  25. ) *PublicrpcServer {
  26. return &PublicrpcServer{
  27. logger: logger.Named("publicrpcserver"),
  28. db: db,
  29. gst: gst,
  30. }
  31. }
  32. func (s *PublicrpcServer) GetLastHeartbeats(ctx context.Context, req *publicrpcv1.GetLastHeartbeatsRequest) (*publicrpcv1.GetLastHeartbeatsResponse, error) {
  33. gs := s.gst.Get()
  34. if gs == nil {
  35. return nil, status.Error(codes.Unavailable, "guardian set not fetched from chain yet")
  36. }
  37. resp := &publicrpcv1.GetLastHeartbeatsResponse{
  38. Entries: make([]*publicrpcv1.GetLastHeartbeatsResponse_Entry, 0),
  39. }
  40. // Fetch all heartbeats (including from nodes not in the guardian set - which
  41. // can happen either with --disableHeartbeatVerify or when the guardian set changes)
  42. for addr, v := range s.gst.GetAll() {
  43. for peerId, hb := range v {
  44. resp.Entries = append(resp.Entries, &publicrpcv1.GetLastHeartbeatsResponse_Entry{
  45. VerifiedGuardianAddr: addr.Hex(),
  46. P2PNodeAddr: peerId.Pretty(),
  47. RawHeartbeat: hb,
  48. })
  49. }
  50. }
  51. return resp, nil
  52. }
  53. func (s *PublicrpcServer) GetSignedVAA(ctx context.Context, req *publicrpcv1.GetSignedVAARequest) (*publicrpcv1.GetSignedVAAResponse, error) {
  54. address, err := hex.DecodeString(req.MessageId.EmitterAddress)
  55. if err != nil {
  56. return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed to decode address: %v", err))
  57. }
  58. if len(address) != 32 {
  59. return nil, status.Error(codes.InvalidArgument, "address must be 32 bytes")
  60. }
  61. addr := vaa.Address{}
  62. copy(addr[:], address)
  63. b, err := s.db.GetSignedVAABytes(db.VAAID{
  64. EmitterChain: vaa.ChainID(req.MessageId.EmitterChain.Number()),
  65. EmitterAddress: addr,
  66. Sequence: uint64(req.MessageId.Sequence),
  67. })
  68. if err != nil {
  69. if err == db.ErrVAANotFound {
  70. return nil, status.Error(codes.NotFound, err.Error())
  71. }
  72. s.logger.Error("failed to fetch VAA", zap.Error(err), zap.Any("request", req))
  73. return nil, status.Error(codes.Internal, "internal server error")
  74. }
  75. return &publicrpcv1.GetSignedVAAResponse{
  76. VaaBytes: b,
  77. }, nil
  78. }
  79. func (s *PublicrpcServer) GetCurrentGuardianSet(ctx context.Context, req *publicrpcv1.GetCurrentGuardianSetRequest) (*publicrpcv1.GetCurrentGuardianSetResponse, error) {
  80. gs := s.gst.Get()
  81. if gs == nil {
  82. return nil, status.Error(codes.Unavailable, "guardian set not fetched from chain yet")
  83. }
  84. resp := &publicrpcv1.GetCurrentGuardianSetResponse{
  85. GuardianSet: &publicrpcv1.GuardianSet{
  86. Index: gs.Index,
  87. Addresses: make([]string, len(gs.Keys)),
  88. },
  89. }
  90. for i, v := range gs.Keys {
  91. resp.GuardianSet.Addresses[i] = v.Hex()
  92. }
  93. return resp, nil
  94. }