Skip to content

Commit

Permalink
moving relayer code
Browse files Browse the repository at this point in the history
  • Loading branch information
Lazar955 committed Jan 20, 2025
1 parent cd2e006 commit 56df3aa
Show file tree
Hide file tree
Showing 18 changed files with 3,061 additions and 26 deletions.
9 changes: 4 additions & 5 deletions client/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ package client

import (
"context"
relayerclient "github.com/babylonlabs-io/babylon/client/relayer"
"time"

bbn "github.com/babylonlabs-io/babylon/app"
"github.com/babylonlabs-io/babylon/client/config"
"github.com/babylonlabs-io/babylon/client/query"
rpchttp "github.com/cometbft/cometbft/rpc/client/http"
"github.com/cosmos/relayer/v2/relayer/chains/cosmos"
"go.uber.org/zap"
)

type Client struct {
*query.QueryClient

provider *cosmos.CosmosProvider
provider *relayerclient.CosmosProvider
timeout time.Duration
logger *zap.Logger
cfg *config.BabylonConfig
Expand Down Expand Up @@ -44,20 +44,19 @@ func New(cfg *config.BabylonConfig, logger *zap.Logger) (*Client, error) {
provider, err := cfg.ToCosmosProviderConfig().NewProvider(
zapLogger,
"", // TODO: set home path
true,
"babylon",
)
if err != nil {
return nil, err
}

cp := provider.(*cosmos.CosmosProvider)
cp := provider.(*relayerclient.CosmosProvider)
cp.PCfg.KeyDirectory = cfg.KeyDirectory

// Create tmp Babylon app to retrieve and register codecs
// Need to override this manually as otherwise option from config is ignored
encCfg := bbn.GetEncodingConfig()
cp.Cdc = cosmos.Codec{
cp.Cdc = relayerclient.Codec{
InterfaceRegistry: encCfg.InterfaceRegistry,
Marshaler: encCfg.Codec,
TxConfig: encCfg.TxConfig,
Expand Down
33 changes: 16 additions & 17 deletions client/client/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package client
import (
"context"
"fmt"
relayerclient "github.com/babylonlabs-io/babylon/client/relayer"
"sync"

signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1"
Expand All @@ -21,16 +22,14 @@ import (
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/relayer/v2/relayer/chains/cosmos"
pv "github.com/cosmos/relayer/v2/relayer/provider"
"go.uber.org/zap"
)

// ToProviderMsgs converts a list of sdk.Msg to a list of provider.RelayerMessage
func ToProviderMsgs(msgs []sdk.Msg) []pv.RelayerMessage {
relayerMsgs := []pv.RelayerMessage{}
func ToProviderMsgs(msgs []sdk.Msg) []relayerclient.RelayerMessage {
relayerMsgs := make([]relayerclient.RelayerMessage, 0, len(msgs))
for _, m := range msgs {
relayerMsgs = append(relayerMsgs, cosmos.NewCosmosMessage(m, func(signer string) {}))
relayerMsgs = append(relayerMsgs, relayerclient.NewCosmosMessage(m, func(signer string) {}))
}
return relayerMsgs
}
Expand All @@ -48,7 +47,7 @@ func (c *Client) SendMsgsToMempool(ctx context.Context, msgs []sdk.Msg) error {
if err := retry.Do(func() error {
var sendMsgErr error
krErr := c.accessKeyWithLock(func() {
sendMsgErr = c.provider.SendMessagesToMempool(ctx, relayerMsgs, "", ctx, []func(*pv.RelayerTxResponse, error){})
sendMsgErr = c.provider.SendMessagesToMempool(ctx, relayerMsgs, "", ctx, []func(*relayerclient.RelayerTxResponse, error){})
})
if krErr != nil {
c.logger.Error("unrecoverable err when submitting the tx, skip retrying", zap.Error(krErr))
Expand All @@ -67,21 +66,21 @@ func (c *Client) SendMsgsToMempool(ctx context.Context, msgs []sdk.Msg) error {
// ReliablySendMsg reliable sends a message to the chain.
// It utilizes a file lock as well as a keyring lock to ensure atomic access.
// TODO: needs tests
func (c *Client) ReliablySendMsg(ctx context.Context, msg sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*pv.RelayerTxResponse, error) {
func (c *Client) ReliablySendMsg(ctx context.Context, msg sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*relayerclient.RelayerTxResponse, error) {
return c.ReliablySendMsgs(ctx, []sdk.Msg{msg}, expectedErrors, unrecoverableErrors)
}

// ReliablySendMsgs reliably sends a list of messages to the chain.
// It utilizes a file lock as well as a keyring lock to ensure atomic access.
// TODO: needs tests
func (c *Client) ReliablySendMsgs(ctx context.Context, msgs []sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*pv.RelayerTxResponse, error) {
func (c *Client) ReliablySendMsgs(ctx context.Context, msgs []sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*relayerclient.RelayerTxResponse, error) {
var (
rlyResp *pv.RelayerTxResponse
rlyResp *relayerclient.RelayerTxResponse
callbackErr error
wg sync.WaitGroup
)

callback := func(rtr *pv.RelayerTxResponse, err error) {
callback := func(rtr *relayerclient.RelayerTxResponse, err error) {
rlyResp = rtr
callbackErr = err
wg.Done()
Expand All @@ -96,7 +95,7 @@ func (c *Client) ReliablySendMsgs(ctx context.Context, msgs []sdk.Msg, expectedE
if err := retry.Do(func() error {
var sendMsgErr error
krErr := c.accessKeyWithLock(func() {
sendMsgErr = c.provider.SendMessagesToMempool(ctx, relayerMsgs, "", ctx, []func(*pv.RelayerTxResponse, error){callback})
sendMsgErr = c.provider.SendMessagesToMempool(ctx, relayerMsgs, "", ctx, []func(*relayerclient.RelayerTxResponse, error){callback})
})
if krErr != nil {
c.logger.Error("unrecoverable err when submitting the tx, skip retrying", zap.Error(krErr))
Expand Down Expand Up @@ -147,9 +146,9 @@ func (c *Client) ReliablySendMsgs(ctx context.Context, msgs []sdk.Msg, expectedE

// ReliablySendMsgsWithSigner reliably sends a list of messages to the chain.
// It utilizes the signer private key to sign all msgs
func (c *Client) ReliablySendMsgsWithSigner(ctx context.Context, signerAddr sdk.AccAddress, signerPvKey *secp256k1.PrivKey, msgs []sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*pv.RelayerTxResponse, error) {
func (c *Client) ReliablySendMsgsWithSigner(ctx context.Context, signerAddr sdk.AccAddress, signerPvKey *secp256k1.PrivKey, msgs []sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*relayerclient.RelayerTxResponse, error) {
var (
rlyResp *pv.RelayerTxResponse
rlyResp *relayerclient.RelayerTxResponse
callbackErr error
wg sync.WaitGroup
)
Expand Down Expand Up @@ -209,9 +208,9 @@ func (c *Client) SendMessageWithSigner(
ctx context.Context,
signerAddr sdk.AccAddress,
signerPvKey *secp256k1.PrivKey,
relayerMsgs []pv.RelayerMessage,
relayerMsgs []relayerclient.RelayerMessage,
) (result *coretypes.ResultBroadcastTx, err error) {
cMsgs := cosmos.CosmosMsgs(relayerMsgs...)
cMsgs := relayerclient.CosmosMsgs(relayerMsgs...)
var (
num, seq uint64
)
Expand Down Expand Up @@ -486,11 +485,11 @@ func Sign(
// - we do not support cancellation of submitting messages
// - the only timeout is the block inclusion timeout i.e block-timeout
// TODO: To properly support cancellation we need to expose ctx in our client calls
func (c *Client) InsertBTCSpvProof(ctx context.Context, msg *btcctypes.MsgInsertBTCSpvProof) (*pv.RelayerTxResponse, error) {
func (c *Client) InsertBTCSpvProof(ctx context.Context, msg *btcctypes.MsgInsertBTCSpvProof) (*relayerclient.RelayerTxResponse, error) {
return c.ReliablySendMsg(ctx, msg, []*errors.Error{}, []*errors.Error{})
}

func (c *Client) InsertHeaders(ctx context.Context, msg *btclctypes.MsgInsertHeaders) (*pv.RelayerTxResponse, error) {
func (c *Client) InsertHeaders(ctx context.Context, msg *btclctypes.MsgInsertHeaders) (*relayerclient.RelayerTxResponse, error) {
return c.ReliablySendMsg(ctx, msg, []*errors.Error{}, []*errors.Error{})
}

Expand Down
6 changes: 3 additions & 3 deletions client/config/babylon_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package config

import (
"fmt"
"github.com/cosmos/relayer/v2/relayer/chains/cosmos"
relayerclient "github.com/babylonlabs-io/babylon/client/relayer"
"net/url"
"os"
"path/filepath"
Expand Down Expand Up @@ -42,8 +42,8 @@ func (cfg *BabylonConfig) Validate() error {
return nil
}

func (cfg *BabylonConfig) ToCosmosProviderConfig() cosmos.CosmosProviderConfig {
return cosmos.CosmosProviderConfig{
func (cfg *BabylonConfig) ToCosmosProviderConfig() relayerclient.CosmosProviderConfig {
return relayerclient.CosmosProviderConfig{
Key: cfg.Key,
ChainID: cfg.ChainID,
RPCAddr: cfg.RPCAddr,
Expand Down
2 changes: 1 addition & 1 deletion client/config/babylon_query_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"time"
)

// BabylonConfig defines configuration for the Babylon query client
// BabylonQueryConfig defines configuration for the Babylon query client
type BabylonQueryConfig struct {
RPCAddr string `mapstructure:"rpc-addr"`
Timeout time.Duration `mapstructure:"timeout"`
Expand Down
75 changes: 75 additions & 0 deletions client/relayer/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package relayerclient

import (
"context"
"fmt"
"strconv"

"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)

var _ client.AccountRetriever = &CosmosProvider{}

// GetAccount queries for an account given an address and a block height. An
// error is returned if the query or decoding fails.
func (cc *CosmosProvider) GetAccount(clientCtx client.Context, addr sdk.AccAddress) (client.Account, error) {
account, _, err := cc.GetAccountWithHeight(clientCtx, addr)
return account, err
}

// GetAccountWithHeight queries for an account given an address. Returns the
// height of the query with the account. An error is returned if the query
// or decoding fails.
func (cc *CosmosProvider) GetAccountWithHeight(_ client.Context, addr sdk.AccAddress) (client.Account, int64, error) {
var header metadata.MD
address, err := cc.EncodeBech32AccAddr(addr)
if err != nil {
return nil, 0, err
}

queryClient := authtypes.NewQueryClient(cc)
res, err := queryClient.Account(context.Background(), &authtypes.QueryAccountRequest{Address: address}, grpc.Header(&header))
if err != nil {
return nil, 0, err
}

blockHeight := header.Get(grpctypes.GRPCBlockHeightHeader)
if l := len(blockHeight); l != 1 {
return nil, 0, fmt.Errorf("unexpected '%s' header length; got %d, expected: %d", grpctypes.GRPCBlockHeightHeader, l, 1)
}

nBlockHeight, err := strconv.Atoi(blockHeight[0])
if err != nil {
return nil, 0, fmt.Errorf("failed to parse block height: %w", err)
}

var acc authtypes.AccountI
if err := cc.Cdc.InterfaceRegistry.UnpackAny(res.Account, &acc); err != nil {
return nil, 0, err
}

return acc, int64(nBlockHeight), nil
}

// EnsureExists returns an error if no account exists for the given address else nil.
func (cc *CosmosProvider) EnsureExists(clientCtx client.Context, addr sdk.AccAddress) error {
if _, err := cc.GetAccount(clientCtx, addr); err != nil {
return err
}
return nil
}

// GetAccountNumberSequence returns sequence and account number for the given address.
// It returns an error if the account couldn't be retrieved from the state.
func (cc *CosmosProvider) GetAccountNumberSequence(clientCtx client.Context, addr sdk.AccAddress) (uint64, uint64, error) {
acc, err := cc.GetAccount(clientCtx, addr)
if err != nil {
return 0, 0, err
}
return acc.GetAccountNumber(), acc.GetSequence(), nil
}
28 changes: 28 additions & 0 deletions client/relayer/bech32_hack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package relayerclient

import (
"sync"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// This file is cursed and this mutex is too
// you don't want none of this dewey cox.
var sdkConfigMutex sync.Mutex

// SetSDKContext sets the SDK config to the proper bech32 prefixes.
// Don't use this unless you know what you're doing.
// TODO: :dagger: :knife: :chainsaw: remove this function
func (cc *CosmosProvider) SetSDKContext() func() {
return SetSDKConfigContext(cc.PCfg.AccountPrefix)
}

// SetSDKConfigContext sets the SDK config to the given bech32 prefixes
func SetSDKConfigContext(prefix string) func() {
sdkConfigMutex.Lock()
sdkConf := sdk.GetConfig()
sdkConf.SetBech32PrefixForAccount(prefix, prefix+"pub")
sdkConf.SetBech32PrefixForValidator(prefix+"valoper", prefix+"valoperpub")
sdkConf.SetBech32PrefixForConsensusNode(prefix+"valcons", prefix+"valconspub")
return sdkConfigMutex.Unlock
}
18 changes: 18 additions & 0 deletions client/relayer/broadcast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package relayerclient

import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
)

const (
ErrTimeoutAfterWaitingForTxBroadcast _err = "timed out after waiting for tx to get included in the block"
)

type _err string

func (e _err) Error() string { return string(e) }

// todo(lazar) remove this
type intoAny interface {
AsAny() *codectypes.Any
}
Loading

0 comments on commit 56df3aa

Please sign in to comment.