Feature/add grpc support (#73)
* Add grpc web support * Add endpoints GRPC - GovernorGetAvailableNotionalByChain - GovernorGetEnqueuedVAAs - GovernorIsVAAEnqueued - GovernorGetTokenList * Add endpoint GRPC - GetSignedVAA, GetSignedBatchVAA, GetLastHeartbeats, GetCurrentGuardianSet Co-authored-by: Fernando Torres <fert1335@gmail.com>
This commit is contained in:
parent
cf274f1fd8
commit
5225cc13fa
74
api/go.mod
74
api/go.mod
|
@ -4,55 +4,56 @@ go 1.19
|
|||
|
||||
require (
|
||||
github.com/ansrivas/fiberprometheus/v2 v2.4.1
|
||||
github.com/certusone/wormhole/node v0.0.0-20220907133901-8e231501b6cd
|
||||
github.com/ethereum/go-ethereum v1.10.6
|
||||
github.com/certusone/wormhole/node v0.0.0-20230120141536-53d554d93b02
|
||||
github.com/ethereum/go-ethereum v1.10.21
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/gofiber/adaptor/v2 v2.1.29
|
||||
github.com/gofiber/fiber/v2 v2.39.0
|
||||
github.com/ipfs/go-log/v2 v2.5.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/spf13/viper v1.13.0
|
||||
github.com/swaggo/swag v1.8.9
|
||||
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20221118153622-cddfe74b6787
|
||||
go.mongodb.org/mongo-driver v1.10.3
|
||||
go.uber.org/zap v1.22.0
|
||||
go.uber.org/zap v1.23.0
|
||||
google.golang.org/grpc v1.50.1
|
||||
)
|
||||
|
||||
require github.com/improbable-eng/grpc-web v0.15.0
|
||||
|
||||
require (
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
|
||||
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/btcsuite/btcd v0.22.1 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/edsrzf/mmap-go v1.0.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
|
||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/gofiber/adaptor/v2 v2.1.29 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/gogo/protobuf v1.3.3 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.3 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
|
||||
github.com/holiman/uint256 v1.2.0 // indirect
|
||||
github.com/huin/goupnp v1.0.3 // indirect
|
||||
github.com/ipfs/go-cid v0.2.0 // indirect
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.15.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.1.0 // indirect
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
|
||||
github.com/libp2p/go-libp2p v0.22.0 // indirect
|
||||
github.com/libp2p/go-openssl v0.1.0 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-pointer v0.0.1 // indirect
|
||||
|
@ -69,30 +70,21 @@ require (
|
|||
github.com/multiformats/go-multicodec v0.5.0 // indirect
|
||||
github.com/multiformats/go-multihash v0.2.1 // indirect
|
||||
github.com/multiformats/go-varint v0.0.6 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect
|
||||
github.com/prometheus/client_golang v1.13.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/prometheus/tsdb v0.7.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.2 // indirect
|
||||
github.com/rjeczalik/notify v0.9.1 // indirect
|
||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
|
||||
github.com/rs/cors v1.8.2 // indirect
|
||||
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.5 // indirect
|
||||
github.com/tklauser/numcpus v0.2.2 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.41.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
|
@ -102,19 +94,19 @@ require (
|
|||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect
|
||||
google.golang.org/grpc v1.46.2 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
golang.org/x/crypto v0.2.0 // indirect
|
||||
golang.org/x/net v0.2.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1 // indirect
|
||||
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/blake3 v1.1.7 // indirect
|
||||
nhooyr.io/websocket v1.8.7 // indirect
|
||||
)
|
||||
|
||||
// Needed for cosmos-sdk based chains. See
|
||||
|
|
572
api/go.sum
572
api/go.sum
File diff suppressed because it is too large
Load Diff
|
@ -4,9 +4,9 @@ package governor
|
|||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/mongo"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
)
|
||||
|
||||
// GovConfigPage represent a governor configuration.
|
||||
|
|
|
@ -7,10 +7,10 @@ import (
|
|||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/pkg/errors"
|
||||
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
|
|
@ -4,9 +4,9 @@ package governor
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/common"
|
||||
|
||||
eth_common "github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
)
|
||||
|
||||
// ObservationDoc represent an observation document.
|
||||
|
|
|
@ -5,10 +5,10 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/pkg/errors"
|
||||
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
|
|
@ -4,8 +4,8 @@ package observations
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
)
|
||||
|
||||
// chanID constants.
|
||||
|
|
|
@ -4,10 +4,10 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/pkg/errors"
|
||||
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
|
|
@ -5,12 +5,12 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/cache"
|
||||
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
|
23
api/main.go
23
api/main.go
|
@ -3,16 +3,20 @@ package main
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ansrivas/fiberprometheus/v2"
|
||||
"github.com/gofiber/adaptor/v2"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/cache"
|
||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/gofiber/fiber/v2/middleware/requestid"
|
||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||
|
||||
ipfslog "github.com/ipfs/go-log/v2"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/governor"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/guardian"
|
||||
|
@ -25,6 +29,7 @@ import (
|
|||
"github.com/wormhole-foundation/wormhole-explorer/api/internal/db"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||
rpcApi "github.com/wormhole-foundation/wormhole-explorer/api/rpc"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -175,7 +180,7 @@ func main() {
|
|||
signedVAA := publicAPIV1.Group("/signed_vaa")
|
||||
signedVAA.Get("/:chain/:emitter/:sequence", vaaCtrl.FindSignedVAAByID)
|
||||
signedBatchVAA := publicAPIV1.Group("/signed_batch_vaa")
|
||||
signedBatchVAA.Get("/:chain/:emitter/:sequence", vaaCtrl.FindSignedBatchVAAByID)
|
||||
signedBatchVAA.Get("/:chain/:trxID/:nonce", vaaCtrl.FindSignedBatchVAAByID)
|
||||
// guardianSet resource.
|
||||
guardianSet := publicAPIV1.Group("/guardianset")
|
||||
guardianSet.Get("/current", guardianCtrl.GetGuardianSet)
|
||||
|
@ -189,7 +194,21 @@ func main() {
|
|||
gov.Get("/is_vaa_enqueued/:chain/:emitter/:sequence", governorCtrl.IsVaaEnqueued)
|
||||
gov.Get("/token_list", governorCtrl.GetTokenList)
|
||||
|
||||
app.Listen(":" + strconv.Itoa(cfg.PORT))
|
||||
handler := rpcApi.NewHandler(vaaService, heartbeatsService, governorService, rootLogger)
|
||||
grpcServer := rpcApi.NewServer(handler, rootLogger)
|
||||
grpcWebServer := grpcweb.WrapServer(grpcServer)
|
||||
app.Use(
|
||||
adaptor.HTTPMiddleware(func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if grpcWebServer.IsGrpcWebRequest(r) {
|
||||
grpcWebServer.ServeHTTP(w, r)
|
||||
} else {
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
rootLogger.Fatal("http listen", zap.Error(app.Listen(":"+strconv.Itoa(cfg.PORT))))
|
||||
}
|
||||
|
||||
// NewCache return a CacheGetFunc to get a value by a Key from cache.
|
||||
|
|
|
@ -5,10 +5,10 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/vaa"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/response"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
|
||||
publicrpcv1 "github.com/certusone/wormhole/node/pkg/proto/publicrpc/v1"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/governor"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/guardian"
|
||||
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/heartbeats"
|
||||
vaaservice "github.com/wormhole-foundation/wormhole-explorer/api/handlers/vaa"
|
||||
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// Handler rpc handler.
|
||||
type Handler struct {
|
||||
publicrpcv1.UnimplementedPublicRPCServiceServer
|
||||
vaaSrv *vaaservice.Service
|
||||
hbSrv *heartbeats.Service
|
||||
govSrv *governor.Service
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewHandler create a new rpc Handler.
|
||||
func NewHandler(vaaSrv *vaaservice.Service, hbSrv *heartbeats.Service, govSrv *governor.Service, logger *zap.Logger) *Handler {
|
||||
return &Handler{vaaSrv: vaaSrv, hbSrv: hbSrv, govSrv: govSrv, logger: logger}
|
||||
}
|
||||
|
||||
// GetSignedVAA get signedVAA by chainID, address, sequence.
|
||||
func (h *Handler) GetSignedVAA(ctx context.Context, request *publicrpcv1.GetSignedVAARequest) (*publicrpcv1.GetSignedVAAResponse, error) {
|
||||
// check and get chainID/address/sequence
|
||||
if request.MessageId == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "no message ID specified")
|
||||
}
|
||||
|
||||
chainID := vaa.ChainID(request.MessageId.EmitterChain.Number())
|
||||
|
||||
// This interface is not supported for PythNet messages because those VAAs are not stored in the database.
|
||||
if chainID == vaa.ChainIDPythNet {
|
||||
return nil, status.Error(codes.InvalidArgument, "not supported for PythNet")
|
||||
}
|
||||
|
||||
address, err := hex.DecodeString(request.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)
|
||||
|
||||
sequence := strconv.FormatUint(request.MessageId.Sequence, 10)
|
||||
|
||||
// get vaa by Id.
|
||||
vaa, err := h.vaaSrv.FindById(ctx, chainID, addr, sequence)
|
||||
if err != nil {
|
||||
if errors.Is(err, errs.ErrNotFound) {
|
||||
return nil, status.Error(codes.NotFound, "requested VAA not found in store")
|
||||
}
|
||||
h.logger.Error("failed to fetch VAA", zap.Error(err), zap.Any("request", request))
|
||||
return nil, status.Error(codes.Internal, "internal server error")
|
||||
}
|
||||
|
||||
// build GetSignedVAAResponse response.
|
||||
return &publicrpcv1.GetSignedVAAResponse{
|
||||
VaaBytes: vaa.Data.Vaa,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetSignedBatchVAA get signed batch VAA.
|
||||
func (h *Handler) GetSignedBatchVAA(ctx context.Context, _ *publicrpcv1.GetSignedBatchVAARequest) (*publicrpcv1.GetSignedBatchVAAResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "not yet implemented")
|
||||
}
|
||||
|
||||
// GetLastHeartbeats get last heartbeats.
|
||||
func (h *Handler) GetLastHeartbeats(ctx context.Context, request *publicrpcv1.GetLastHeartbeatsRequest) (*publicrpcv1.GetLastHeartbeatsResponse, error) {
|
||||
// check guardianSet exists.
|
||||
if len(guardian.ByIndex) == 0 {
|
||||
return nil, status.Error(codes.Unavailable, "guardian set not fetched from chain yet")
|
||||
}
|
||||
|
||||
// get lasted guardianSet.
|
||||
guardianSet := guardian.GetLatest()
|
||||
guardianAddresses := guardianSet.KeysAsHexStrings()
|
||||
|
||||
// get last heartbeats by ids.
|
||||
heartbeats, err := h.hbSrv.GetHeartbeatsByIds(ctx, guardianAddresses)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "internal server error")
|
||||
}
|
||||
|
||||
response := &publicrpcv1.GetLastHeartbeatsResponse{
|
||||
Entries: make([]*publicrpcv1.GetLastHeartbeatsResponse_Entry, 0),
|
||||
}
|
||||
|
||||
for _, hb := range heartbeats {
|
||||
networkResponses := make([]*gossipv1.Heartbeat_Network, 0, len(hb.Networks))
|
||||
for _, network := range hb.Networks {
|
||||
networkResponse := gossipv1.Heartbeat_Network{
|
||||
Id: uint32(network.ID),
|
||||
Height: network.Height,
|
||||
ContractAddress: network.ContractAddress,
|
||||
ErrorCount: uint64(network.ErrorCount), //TODO:check
|
||||
}
|
||||
networkResponses = append(networkResponses, &networkResponse)
|
||||
}
|
||||
|
||||
rawHeartbeat := gossipv1.Heartbeat{
|
||||
Counter: hb.Counter,
|
||||
NodeName: hb.NodeName,
|
||||
Timestamp: hb.Timestamp,
|
||||
Networks: networkResponses,
|
||||
Version: hb.Version,
|
||||
GuardianAddr: hb.GuardianAddr,
|
||||
BootTimestamp: hb.BootTimestamp,
|
||||
Features: hb.Features,
|
||||
}
|
||||
|
||||
response.Entries = append(response.Entries, &publicrpcv1.GetLastHeartbeatsResponse_Entry{
|
||||
VerifiedGuardianAddr: hb.ID,
|
||||
P2PNodeAddr: "",
|
||||
RawHeartbeat: &rawHeartbeat,
|
||||
})
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// GetCurrentGuardianSet get current guardian set.
|
||||
func (h *Handler) GetCurrentGuardianSet(ctx context.Context, request *publicrpcv1.GetCurrentGuardianSetRequest) (*publicrpcv1.GetCurrentGuardianSetResponse, error) {
|
||||
// check guardianSet exists.
|
||||
if len(guardian.ByIndex) == 0 {
|
||||
return nil, status.Error(codes.Unavailable, "guardian set not fetched from chain yet")
|
||||
}
|
||||
// get lasted guardianSet.
|
||||
guardinSet := guardian.GetLatest()
|
||||
|
||||
// get guardian addresses.
|
||||
addresses := make([]string, len(guardinSet.Keys))
|
||||
for i, v := range guardinSet.Keys {
|
||||
addresses[i] = v.Hex()
|
||||
}
|
||||
|
||||
return &publicrpcv1.GetCurrentGuardianSetResponse{
|
||||
GuardianSet: &publicrpcv1.GuardianSet{
|
||||
Index: guardinSet.Index,
|
||||
Addresses: addresses,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GovernorGetAvailableNotionalByChain get availableNotional.
|
||||
func (h *Handler) GovernorGetAvailableNotionalByChain(ctx context.Context, _ *publicrpcv1.GovernorGetAvailableNotionalByChainRequest) (*publicrpcv1.GovernorGetAvailableNotionalByChainResponse, error) {
|
||||
availableNotional, err := h.govSrv.GetAvailNotionByChain(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries := make([]*publicrpcv1.GovernorGetAvailableNotionalByChainResponse_Entry, 0)
|
||||
for _, v := range availableNotional {
|
||||
entry := publicrpcv1.GovernorGetAvailableNotionalByChainResponse_Entry{
|
||||
ChainId: uint32(v.ChainID),
|
||||
NotionalLimit: uint64(v.NotionalLimit),
|
||||
RemainingAvailableNotional: uint64(v.AvailableNotional),
|
||||
BigTransactionSize: uint64(v.MaxTransactionSize),
|
||||
}
|
||||
entries = append(entries, &entry)
|
||||
}
|
||||
response := publicrpcv1.GovernorGetAvailableNotionalByChainResponse{
|
||||
Entries: entries,
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// GovernorGetEnqueuedVAAs get enqueuedVaa.
|
||||
func (h *Handler) GovernorGetEnqueuedVAAs(ctx context.Context, _ *publicrpcv1.GovernorGetEnqueuedVAAsRequest) (*publicrpcv1.GovernorGetEnqueuedVAAsResponse, error) {
|
||||
enqueuedVaa, err := h.govSrv.GetEnqueuedVaas(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entries := make([]*publicrpcv1.GovernorGetEnqueuedVAAsResponse_Entry, 0, len(enqueuedVaa))
|
||||
for _, v := range enqueuedVaa {
|
||||
seqUint64, err := strconv.ParseUint(v.Sequence, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry := publicrpcv1.GovernorGetEnqueuedVAAsResponse_Entry{
|
||||
EmitterChain: uint32(v.EmitterChain),
|
||||
EmitterAddress: v.EmitterAddress,
|
||||
Sequence: seqUint64,
|
||||
ReleaseTime: uint32(v.ReleaseTime),
|
||||
NotionalValue: uint64(v.NotionalValue),
|
||||
TxHash: v.TxHash,
|
||||
}
|
||||
entries = append(entries, &entry)
|
||||
}
|
||||
response := publicrpcv1.GovernorGetEnqueuedVAAsResponse{
|
||||
Entries: entries,
|
||||
}
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// GovernorIsVAAEnqueued check if a vaa is enqueued.
|
||||
func (h *Handler) GovernorIsVAAEnqueued(ctx context.Context, request *publicrpcv1.GovernorIsVAAEnqueuedRequest) (*publicrpcv1.GovernorIsVAAEnqueuedResponse, error) {
|
||||
if request.MessageId == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "Parameters are required")
|
||||
}
|
||||
chainID := vaa.ChainID(request.MessageId.EmitterChain)
|
||||
emitterAddress, err := vaa.StringToAddress(request.MessageId.EmitterAddress)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "Invalid emitter address")
|
||||
}
|
||||
isEnqueued, err := h.govSrv.IsVaaEnqueued(ctx, chainID, emitterAddress, strconv.FormatUint(request.MessageId.Sequence, 10))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &publicrpcv1.GovernorIsVAAEnqueuedResponse{IsEnqueued: isEnqueued}, nil
|
||||
}
|
||||
|
||||
// GovernorGetTokenList get governor token list.
|
||||
func (h *Handler) GovernorGetTokenList(ctx context.Context, _ *publicrpcv1.GovernorGetTokenListRequest) (*publicrpcv1.GovernorGetTokenListResponse, error) {
|
||||
tokenList, err := h.govSrv.GetTokenList(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entries := make([]*publicrpcv1.GovernorGetTokenListResponse_Entry, 0, len(tokenList))
|
||||
for _, t := range tokenList {
|
||||
entry := publicrpcv1.GovernorGetTokenListResponse_Entry{
|
||||
OriginChainId: uint32(t.OriginChainID),
|
||||
OriginAddress: t.OriginAddress,
|
||||
Price: t.Price,
|
||||
}
|
||||
entries = append(entries, &entry)
|
||||
}
|
||||
|
||||
response := publicrpcv1.GovernorGetTokenListResponse{
|
||||
Entries: entries,
|
||||
}
|
||||
|
||||
return &response, nil
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"github.com/certusone/wormhole/node/pkg/common"
|
||||
publicrpcv1 "github.com/certusone/wormhole/node/pkg/proto/publicrpc/v1"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Srv *grpc.Server
|
||||
}
|
||||
|
||||
// NewServer creates a GRPC server.
|
||||
func NewServer(h *Handler, logger *zap.Logger) *grpc.Server {
|
||||
grpcServer := common.NewInstrumentedGRPCServer(logger)
|
||||
publicrpcv1.RegisterPublicRPCServiceServer(grpcServer, h)
|
||||
return grpcServer
|
||||
}
|
Loading…
Reference in New Issue