Skip to content

Commit

Permalink
Merge pull request #13 from babylonchain/chain-poller
Browse files Browse the repository at this point in the history
Add initial poller implementation
  • Loading branch information
KonradStaniec authored Jul 19, 2023
2 parents 2765773 + 5d56e72 commit aec19d2
Show file tree
Hide file tree
Showing 6 changed files with 369 additions and 19 deletions.
42 changes: 41 additions & 1 deletion bbnclient/bbncontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,29 @@ package babylonclient
import (
"context"
"fmt"
"github.com/babylonchain/btc-validator/valcfg"
"strconv"
"time"

"github.com/babylonchain/babylon/types"
btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types"
finalitytypes "github.com/babylonchain/babylon/x/finality/types"
"github.com/babylonchain/rpc-client/client"
ctypes "github.com/cometbft/cometbft/rpc/core/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
"github.com/sirupsen/logrus"
lensquery "github.com/strangelove-ventures/lens/client/query"
"google.golang.org/grpc/metadata"
"github.com/babylonchain/btc-validator/valcfg"

)

var _ BabylonClient = &BabylonController{}

type BabylonController struct {
rpcClient *client.Client
logger *logrus.Logger
timeout time.Duration
}

func NewBabylonController(
Expand All @@ -39,6 +47,7 @@ func NewBabylonController(
return &BabylonController{
rpcClient,
logger,
cfg.Timeout,
}, nil
}

Expand Down Expand Up @@ -105,3 +114,34 @@ func (bc *BabylonController) QueryShouldSubmitJurySigs(btcPubKey *types.BIP340Pu
func (bc *BabylonController) QueryShouldValidatorVote(btcPubKey *types.BIP340PubKey, blockHeight uint64) (bool, error) {
panic("implement me")
}

func (bc *BabylonController) QueryNodeStatus() (*ctypes.ResultStatus, error) {
status, err := bc.rpcClient.QueryClient.GetStatus()
if err != nil {
return nil, err
}

return status, nil
}

func getQueryContext(timeout time.Duration) (context.Context, context.CancelFunc) {
defaultOptions := lensquery.DefaultOptions()
ctx, cancel := context.WithTimeout(context.Background(), timeout)
strHeight := strconv.Itoa(int(defaultOptions.Height))
ctx = metadata.AppendToOutgoingContext(ctx, grpctypes.GRPCBlockHeightHeader, strHeight)
return ctx, cancel
}

func (bc *BabylonController) QueryHeader(height int64) (*ctypes.ResultHeader, error) {
ctx, cancel := getQueryContext(bc.timeout)
headerResp, err := bc.rpcClient.ChainClient.RPCClient.Header(ctx, &height)
defer cancel()

if err != nil {
return nil, err
}

// Returning response directly, if header with specified number did not exist
// at request will contain nill header
return headerResp, nil
}
8 changes: 8 additions & 0 deletions bbnclient/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package babylonclient
import (
"github.com/babylonchain/babylon/types"
btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types"
ctypes "github.com/cometbft/cometbft/rpc/core/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
)

Expand All @@ -28,4 +29,11 @@ type BabylonClient interface {
QueryShouldSubmitJurySigs(btcPubKey *types.BIP340PubKey) (bool, []*types.BIP340PubKey, error)
// QueryShouldValidatorVote asks Babylon if the validator should submit a finality sig for the given block height
QueryShouldValidatorVote(btcPubKey *types.BIP340PubKey, blockHeight uint64) (bool, error)

// QueryNodeStatus returns current node status, with info about latest block
QueryNodeStatus() (*ctypes.ResultStatus, error)

// QueryHeader queries the header at the given height, if header is not found
// it returns result with nil header
QueryHeader(height int64) (*ctypes.ResultHeader, error)
}
61 changes: 43 additions & 18 deletions itest/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
package e2etest

import (
"os"
"testing"
"time"

"github.com/babylonchain/rpc-client/client"
"github.com/babylonchain/rpc-client/config"
babylonclient "github.com/babylonchain/btc-validator/bbnclient"
"github.com/babylonchain/btc-validator/service"
"github.com/babylonchain/btc-validator/valcfg"
cfg "github.com/babylonchain/btc-validator/valcfg"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
)

// TODO For now tests checks only if test works. Add something more sensible
func TestBabylonNodeProgressing(t *testing.T) {
func TestPoller(t *testing.T) {
handler, err := NewBabylonNodeHandler()
require.NoError(t, err)

Expand All @@ -24,22 +27,44 @@ func TestBabylonNodeProgressing(t *testing.T) {
// Let the node start up
// TODO Add polling with to check for startup
// time.Sleep(5 * time.Second)
defaultConfig := config.DefaultBabylonConfig()
client, err := client.New(&defaultConfig)
defaultConfig := valcfg.DefaultBBNConfig()
logger := logrus.New()
logger.SetLevel(logrus.DebugLevel)
logger.Out = os.Stdout
defaultPollerConfig := cfg.DefaulPollerConfig()

bc, err := babylonclient.NewBabylonController(&defaultConfig, logger)
require.NoError(t, err)

poller := service.NewChainPoller(logger, &defaultPollerConfig, bc)
require.NoError(t, err)

err = poller.Start()
require.NoError(t, err)
defer poller.Stop()

// Get 3 blocks which should be received in order
select {
case info := <-poller.GetBlockInfoChan():
require.Equal(t, uint64(1), info.Height)

case <-time.After(10 * time.Second):
t.Fatalf("Failed to get block info")
}

select {
case info := <-poller.GetBlockInfoChan():
require.Equal(t, uint64(2), info.Height)

require.Eventually(t, func() bool {
resp, err := client.QueryClient.GetStatus()
if err != nil {
return false
}
case <-time.After(10 * time.Second):
t.Fatalf("Failed to get block info")
}

// Wait for 3 blocks to check node is progressing as expected
if resp.SyncInfo.LatestBlockHeight < 3 {
return false
}
select {
case info := <-poller.GetBlockInfoChan():
require.Equal(t, uint64(3), info.Height)

return true
// TODO parametrize timeout and interval
}, 30*time.Second, 1*time.Second)
case <-time.After(10 * time.Second):
t.Fatalf("Failed to get block info")
}
}
Loading

0 comments on commit aec19d2

Please sign in to comment.