Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integration tests #85

Merged
merged 2 commits into from
Aug 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ endif

.PHONY: run-tests test test-all $(TEST_TARGETS)

test-babylon-integration:
@echo "Running babylon integration test"
@go test github.com/babylonchain/babylon/test -v -count=1 --tags=integration

test-sim-nondeterminism:
@echo "Running non-determinism test..."
@go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \
Expand Down
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
Expand Down Expand Up @@ -555,6 +556,7 @@ github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1C
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jhump/protoreflect v1.9.0 h1:npqHz788dryJiR/l6K/RUQAyh2SwV91+d1dnh4RjO9w=
github.com/jhump/protoreflect v1.9.0/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
Expand Down Expand Up @@ -696,6 +698,7 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
github.com/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
Expand All @@ -711,6 +714,7 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
Expand Down Expand Up @@ -743,6 +747,11 @@ github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ=
github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
Expand Down Expand Up @@ -1261,6 +1270,7 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s=
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
Expand Down Expand Up @@ -1327,8 +1337,10 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
Expand Down Expand Up @@ -1462,6 +1474,7 @@ google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ6
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f h1:P8EiVSxZwC6xH2niv2N66aqwMtYFg+D54gbjpcqKJtM=
google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
Expand All @@ -1477,6 +1490,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
Expand Down
12 changes: 12 additions & 0 deletions proto/babylon/btclightclient/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ service Query {
rpc MainChain(QueryMainChainRequest) returns (QueryMainChainResponse) {
option (google.api.http).get = "/babylon/btclightclient/v1/mainchain";
}

// BestHeader return best header on canonical chain
rpc BestHeader(QueryBestHeaderRequest) returns (QueryBestHeaderResponse) {
option (google.api.http).get = "/babylon/btclightclient/v1/bestheader";
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rpc BestHeader(QueryBestHeaderRequest) returns (QueryBestHeaderResponse) {
option (google.api.http).get = "/babylon/btclightclient/v1/bestheader";
}
rpc Tip(QueryTipRequest) returns (QueryTipResponse) {
option (google.api.http).get = "/babylon/btclightclient/v1/tip";
}

Nothing against "best header", just curious, why introduce new names for already existing concepts? Do you think "tip" is confusing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it a bit ambiguous to be honest it can mean tip of the blockchain, or maybe some tip to the miner. It can be interpreted in too many ways to my taste. I find best header having a bit more precise.

But I can change it to tip, to not introduce new terminolgy. We can debate naming of external apis when we will have some kind public testnet, and biger sample of people using those apis.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I saw that "best block" is a thing in Bitcoin, so it's fine with me.

}

// QueryParamsRequest is request type for the Query/Params RPC method.
Expand Down Expand Up @@ -79,3 +84,10 @@ message QueryMainChainResponse {

cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

message QueryBestHeaderRequest {
}

message QueryBestHeaderResponse {
BTCHeaderInfo header = 1;
}
120 changes: 120 additions & 0 deletions test/integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
//go:build integration
// +build integration

package babylon_integration_test

import (
"context"
"errors"
"os"
"testing"
"time"

appparams "github.com/babylonchain/babylon/app/params"
bbl "github.com/babylonchain/babylon/types"
lightclient "github.com/babylonchain/babylon/x/btclightclient/types"
ref "github.com/cosmos/cosmos-sdk/client/grpc/reflection"
"google.golang.org/grpc"
)

// Addresses of all nodes in local testnet.
// TODO: instead of hardcoding them it would be nice to get them from env variables
// so docker-compose and this file would stay compatible
var addresses = []string{
"localhost:9090",
"localhost:9091",
"localhost:9092",
"localhost:9093",
}

var clients []*grpc.ClientConn

func checkInterfacesWithRetries(client *grpc.ClientConn, maxTries int, sleepTime time.Duration) error {
tries := 0
refClient := ref.NewReflectionServiceClient(client)
for {
_, err := refClient.ListAllInterfaces(context.Background(), &ref.ListAllInterfacesRequest{})

if err == nil {
// successful call to client, finish calling
return nil
}

tries++

if tries > maxTries {
return errors.New("Failed to call client")
}

<-time.After(sleepTime)
}
}

func TestMain(m *testing.M) {

// This is needed so that all address prefixes are in bbl format
appparams.SetAddressPrefixes()

for _, addr := range addresses {
grpcConn, err := grpc.Dial(
addr, // Or your gRPC server address.
grpc.WithInsecure(), // The Cosmos SDK doesn't support any transport security mechanism.
)

if err != nil {
panic("Grpc connection failed cannot perform integration tests")
}

clients = append(clients, grpcConn)
}
//runs all following tests
exitVal := m.Run()

for _, c := range clients {
// close all connections after the tests
c.Close()
}

os.Exit(exitVal)
}

// This test serves as a waiting point for testnet to start, it is needed as
// docker compose is usually started in detached mode in CI, therefore tests
// are started even before all nodes are up.
// TODO: investigate starting testnet from golang test file.
func TestTestnetRuninng(t *testing.T) {
Comment on lines +81 to +85
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to https://stackoverflow.com/a/31204016 the execution order of tests should not be relied upon. It suggests calling this from init() or TestMain() instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I didn't know that.

From what I see one can also provide flag go test -p 1 which will force sequential execution. In general I plan for those tests to be stateful (there will be one testnet running against which there weill be bunch of tx executed) and deterministic, so the execution order of tests will matter, also they do not run with other test due to build tag // +build integration so the won't execute by accident.

So I think I prefer to just add this flag to make target test-babylon-integration and have this smoke test as initial one to just check everything is working.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If -p 1 means not just sequential but in the order of appearance, great 👍


for _, c := range clients {
err := checkInterfacesWithRetries(c, 40, 5*time.Second)

if err != nil {
panic("Could not start integration tests. Testnet not running")
}
}
}

// Check all nodes are properly initialized to genesis
// TODO ultimatly we would like to check genesis related to all modules here.
func TestBtcLightClientGenesis(t *testing.T) {
// TODO currently btclightclient hardcodes this header in some function. Ultimately
// we would like to get it from config file, and assert here that each node
// start with genesis header from this config file
hardcodedHeaderHash, _ := bbl.NewBTCHeaderHashBytesFromHex("00000000000000000002bf1c218853bc920f41f74491e6c92c6bc6fdc881ab47")
hardcodedHeaderHeight := uint64(736056)

for i, c := range clients {
lc := lightclient.NewQueryClient(c)

res, err := lc.BestHeader(context.Background(), lightclient.NewQueryBestHeaderRequest())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the BestHeader endpoint will always be the best choice to test what the genesis block is, if we assume that an actual local testnet is running. Ostensibly that could include BTC relayers that feed new headers to Babylon, otherwise the testnet will never produce a checkpoint. By the time you run this test, it might already have moved on to a new tip.

The Mainchain method should document what order it returns headers in, but looking at the code you can ask for results to be iterated in reverse in which case it wills tart from the base, and with a limit of 1 you should get the genesis header.

Copy link
Collaborator Author

@KonradStaniec KonradStaniec Aug 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mention in earlier comment, I intend for those tests to be stateful and deterministic, so as this will be the first test which will run, then at this point best header should be be genesis header. In later tests, after ingesting few header tip should move by expected amount of headers.

Copy link
Contributor

@aakoshh aakoshh Aug 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry that's not what I meant. I meant that according to the PR description you start with make localnet-start; ostensibly that could include a BTC node that starts creating blocks and some relayers, or maybe it could include just relayers who pull data from the BTC testnet, I don't know. A real local testnet would surely not stand still forever.

Admittedly it will probably not move on before this test executes, but just wanted to point out that there is a deterministic endpoint for you to use.


if err != nil {
// this is fatal, as it means we most probably did not get any response and
// at least one of the nodes is down
t.Fatalf("Test failed due to client error: %v to node with address %s", err, addresses[i])
}

if res.Header.Height != hardcodedHeaderHeight || !res.Header.Hash.Eq(&hardcodedHeaderHash) {
t.Errorf("Node with address %s started with unexpected header", addresses[i])
}
}
}
27 changes: 27 additions & 0 deletions x/btclightclient/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"context"
"fmt"

"github.com/babylonchain/babylon/x/btclightclient/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
Expand All @@ -24,6 +25,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command {
cmd.AddCommand(CmdHashes())
cmd.AddCommand(CmdContains())
cmd.AddCommand(CmdMainChain())
cmd.AddCommand(CmdBestHeader())

return cmd
}
Expand Down Expand Up @@ -140,3 +142,28 @@ func CmdMainChain() *cobra.Command {

return cmd
}

func CmdBestHeader() *cobra.Command {
cmd := &cobra.Command{
Use: "best-header",
Short: "retrieve the canonical chain",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)

queryClient := types.NewQueryClient(clientCtx)

params := types.NewQueryBestHeaderRequest()
res, err := queryClient.BestHeader(context.Background(), params)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
13 changes: 13 additions & 0 deletions x/btclightclient/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
"context"

bbl "github.com/babylonchain/babylon/types"
"github.com/babylonchain/babylon/x/btclightclient/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -148,3 +149,15 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest)
// The headers that we should return start from the depth of the start header
return &types.QueryMainChainResponse{Headers: headers, Pagination: pageRes}, nil
}

func (k Keeper) BestHeader(ctx context.Context, req *types.QueryBestHeaderRequest) (*types.QueryBestHeaderResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}

sdkCtx := sdk.UnwrapSDKContext(ctx)

tip := k.headersState(sdkCtx).GetTip()

return &types.QueryBestHeaderResponse{Header: tip}, nil
}
4 changes: 4 additions & 0 deletions x/btclightclient/types/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ func NewQueryContainsRequest(hash string) (*QueryContainsRequest, error) {
func NewQueryMainChainRequest(req *query.PageRequest) *QueryMainChainRequest {
return &QueryMainChainRequest{Pagination: req}
}

func NewQueryBestHeaderRequest() *QueryBestHeaderRequest {
return &QueryBestHeaderRequest{}
}
Loading