|
@@ -1,9 +1,16 @@
|
|
|
package publicrpc
|
|
package publicrpc
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
|
+ "context"
|
|
|
|
|
+ "encoding/hex"
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "github.com/certusone/wormhole/bridge/pkg/db"
|
|
|
gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1"
|
|
gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1"
|
|
|
publicrpcv1 "github.com/certusone/wormhole/bridge/pkg/proto/publicrpc/v1"
|
|
publicrpcv1 "github.com/certusone/wormhole/bridge/pkg/proto/publicrpc/v1"
|
|
|
|
|
+ "github.com/certusone/wormhole/bridge/pkg/vaa"
|
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap"
|
|
|
|
|
+ "google.golang.org/grpc/codes"
|
|
|
|
|
+ "google.golang.org/grpc/status"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// PublicrpcServer implements the publicrpc gRPC service.
|
|
// PublicrpcServer implements the publicrpc gRPC service.
|
|
@@ -11,12 +18,14 @@ type PublicrpcServer struct {
|
|
|
publicrpcv1.UnimplementedPublicrpcServer
|
|
publicrpcv1.UnimplementedPublicrpcServer
|
|
|
rawHeartbeatListeners *RawHeartbeatConns
|
|
rawHeartbeatListeners *RawHeartbeatConns
|
|
|
logger *zap.Logger
|
|
logger *zap.Logger
|
|
|
|
|
+ db *db.Database
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func NewPublicrpcServer(logger *zap.Logger, rawHeartbeatListeners *RawHeartbeatConns) *PublicrpcServer {
|
|
|
|
|
|
|
+func NewPublicrpcServer(logger *zap.Logger, rawHeartbeatListeners *RawHeartbeatConns, db *db.Database) *PublicrpcServer {
|
|
|
return &PublicrpcServer{
|
|
return &PublicrpcServer{
|
|
|
rawHeartbeatListeners: rawHeartbeatListeners,
|
|
rawHeartbeatListeners: rawHeartbeatListeners,
|
|
|
logger: logger.Named("publicrpcserver"),
|
|
logger: logger.Named("publicrpcserver"),
|
|
|
|
|
+ db: db,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -40,3 +49,34 @@ func (s *PublicrpcServer) GetRawHeartbeats(req *publicrpcv1.GetRawHeartbeatsRequ
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+func (s *PublicrpcServer) GetSignedVAA(ctx context.Context, req *publicrpcv1.GetSignedVAARequest) (*publicrpcv1.GetSignedVAAResponse, error) {
|
|
|
|
|
+ address, err := hex.DecodeString(req.MessageId.EmitterAddress)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed to decode address: %v", err))
|
|
|
|
|
+ }
|
|
|
|
|
+ if len(address) != 32 {
|
|
|
|
|
+ return nil, status.Error(codes.InvalidArgument, "address must be 32 bytes")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ addr := vaa.Address{}
|
|
|
|
|
+ copy(addr[:], address)
|
|
|
|
|
+
|
|
|
|
|
+ b, err := s.db.GetSignedVAABytes(db.VAAID{
|
|
|
|
|
+ EmitterChain: vaa.ChainID(req.MessageId.EmitterChain.Number()),
|
|
|
|
|
+ EmitterAddress: addr,
|
|
|
|
|
+ Sequence: uint64(req.MessageId.Sequence),
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ if err == db.ErrVAANotFound {
|
|
|
|
|
+ return nil, status.Error(codes.NotFound, err.Error())
|
|
|
|
|
+ }
|
|
|
|
|
+ s.logger.Error("failed to fetch VAA", zap.Error(err), zap.Any("request", req))
|
|
|
|
|
+ return nil, status.Error(codes.Internal, "internal server error")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return &publicrpcv1.GetSignedVAAResponse{
|
|
|
|
|
+ VaaBytes: b,
|
|
|
|
|
+ }, nil
|
|
|
|
|
+}
|