Skip to content

Commit

Permalink
pkg/cosmos: add Context to ReaderWriter methods (#424)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmank88 authored Oct 17, 2024
1 parent b275f14 commit 5277829
Show file tree
Hide file tree
Showing 21 changed files with 344 additions and 304 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
cosmossdk.io/errors v1.0.1
github.com/CosmWasm/wasmd v0.40.1
github.com/cometbft/cometbft v0.37.5
github.com/cosmos/btcutil v1.0.5
github.com/cosmos/cosmos-sdk v0.47.11
github.com/cosmos/go-bip39 v1.0.0
github.com/gogo/protobuf v1.3.3
Expand Down Expand Up @@ -72,7 +73,6 @@ require (
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/containerd/containerd v1.7.18 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
github.com/cosmos/gogoproto v1.4.11 // indirect
github.com/cosmos/iavl v0.20.1 // indirect
Expand Down
11 changes: 7 additions & 4 deletions integration-tests/ocr2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

relaylogger "github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"

"github.com/smartcontractkit/chainlink-cosmos/integration-tests/common"
"github.com/smartcontractkit/chainlink-cosmos/integration-tests/gauntlet"
Expand All @@ -32,6 +33,7 @@ import (
)

func TestOCRBasic(t *testing.T) {
ctx := tests.Context(t)
// Set up test environment
logger := common.GetTestLogger(t)
commonConfig := common.NewCommon(t)
Expand Down Expand Up @@ -62,13 +64,13 @@ func TestOCRBasic(t *testing.T) {

gasPrice := types.NewDecCoinFromDec("ucosm", types.MustNewDecFromStr("1"))
amount := []types.Coin{types.NewCoin("ucosm", types.NewInt(int64(10000000)))}
accountNumber, sequenceNumber, err := cosmosClient.Account(testAccount)
accountNumber, sequenceNumber, err := cosmosClient.Account(ctx, testAccount)
require.NoError(t, err, "Could not get account")

for i, nodeAddr := range chainlinkClient.GetNodeAddresses() {
to := types.MustAccAddressFromBech32(nodeAddr)
msgSend := banktypes.NewMsgSend(testAccount, to, amount)
resp, err2 := cosmosClient.SignAndBroadcast([]types.Msg{msgSend}, accountNumber, sequenceNumber+uint64(i), gasPrice, privateKey, txtypes.BroadcastMode_BROADCAST_MODE_SYNC)
resp, err2 := cosmosClient.SignAndBroadcast(ctx, []types.Msg{msgSend}, accountNumber, sequenceNumber+uint64(i), gasPrice, privateKey, txtypes.BroadcastMode_BROADCAST_MODE_SYNC)
require.NoError(t, err2, "Could not send tokens")
logger.Info().Str("from", testAccount.String()).
Str("to", nodeAddr).
Expand All @@ -79,7 +81,7 @@ func TestOCRBasic(t *testing.T) {
tx, success := client.AwaitTxCommitted(t, cosmosClient, resp.TxResponse.TxHash)
require.True(t, success)
require.Equal(t, cometbfttypes.CodeTypeOK, tx.TxResponse.Code)
balance, err2 := cosmosClient.Balance(to, "ucosm")
balance, err2 := cosmosClient.Balance(ctx, to, "ucosm")
require.NoError(t, err2, "Could not fetch ucosm balance")
require.Equal(t, balance.String(), "10000000ucosm")
}
Expand Down Expand Up @@ -218,6 +220,7 @@ func validateRounds(t *testing.T, cosmosClient *client.Client, ocrAddress types.
stuckCount := 0
var positive bool
resp, err := cosmosClient.ContractState(
ctx,
ocrAddress,
[]byte(`{"link_available_for_payment":{}}`),
)
Expand Down Expand Up @@ -332,7 +335,7 @@ func validateRounds(t *testing.T, cosmosClient *client.Client, ocrAddress types.

// Test proxy reading
// TODO: would be good to test proxy switching underlying feeds
resp, err = cosmosClient.ContractState(ocrProxyAddress, []byte(`{"latest_round_data":{}}`))
resp, err = cosmosClient.ContractState(ctx, ocrProxyAddress, []byte(`{"latest_round_data":{}}`))
if !isSoak {
require.NoError(t, err, "Reading round data from proxy should not fail")
//assert.Equal(t, len(roundDataRaw), 5, "Round data from proxy should match expected size")
Expand Down
1 change: 0 additions & 1 deletion ops/test_helpers.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/cosmos/adapters/cosmwasm/contract_config_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (ct *ContractTracker) Notify() <-chan struct{} {
// TODO: seems heavy to fetch whole block rather than rpc.Status() -> SyncInfo.LatestBlockHeight
// LatestBlockHeight returns the height of the most recent block in the chain.
func (ct *ContractTracker) LatestBlockHeight(ctx context.Context) (blockHeight uint64, err error) {
b, err := ct.chainReader.LatestBlock()
b, err := ct.chainReader.LatestBlock(ctx)
if err != nil {
return 0, err
}
Expand Down
10 changes: 6 additions & 4 deletions pkg/cosmos/adapters/cosmwasm/contract_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (

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

"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/libocr/offchainreporting2/types"

"github.com/smartcontractkit/chainlink-common/pkg/logger"

"github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/client"
)

Expand All @@ -34,6 +35,7 @@ func NewOCR2Reader(addess cosmosSDK.AccAddress, chainReader client.Reader, lggr

func (r *OCR2Reader) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest types.ConfigDigest, err error) {
resp, err := r.chainReader.ContractState(
ctx,
r.address,
[]byte(`{"latest_config_details":{}}`),
)
Expand All @@ -54,7 +56,7 @@ func (r *OCR2Reader) LatestConfig(ctx context.Context, changedInBlock uint64) (t
// work with wasmd 0.41.0, which is at cosmos-sdk v0.47.4, which contains the following regex for each event query string:
// https://github.com/cosmos/cosmos-sdk/blob/3b509c187e1643757f5ef8a0b5ae3decca0c7719/x/auth/tx/service.go#L49
query := []string{fmt.Sprintf("tx.height=%d", changedInBlock), fmt.Sprintf("wasm._contract_address='%s'", r.address)}
res, err := r.chainReader.TxsEvents(query, nil)
res, err := r.chainReader.TxsEvents(ctx, query, nil)
if err != nil {
return types.ContractConfig{}, err
}
Expand Down Expand Up @@ -228,7 +230,7 @@ func (r *OCR2Reader) LatestTransmissionDetails(ctx context.Context) (
latestTimestamp time.Time,
err error,
) {
resp, err := r.chainReader.ContractState(r.address, []byte(`{"latest_transmission_details":{}}`))
resp, err := r.chainReader.ContractState(ctx, r.address, []byte(`{"latest_transmission_details":{}}`))
if err != nil {
// Handle the 500 error that occurs when there has not been a submission
// "rpc error: code = Unknown desc = ocr2::state::Transmission not found: contract query failed: unknown request"
Expand Down Expand Up @@ -338,7 +340,7 @@ func (r *OCR2Reader) LatestConfigDigestAndEpoch(ctx context.Context) (
err error,
) {
resp, err := r.chainReader.ContractState(
r.address, []byte(`{"latest_config_digest_and_epoch":{}}`),
ctx, r.address, []byte(`{"latest_config_digest_and_epoch":{}}`),
)
if err != nil {
return types.ConfigDigest{}, 0, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/cosmos/adapters/injective/config_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (c *CosmosModuleConfigTracker) LatestBlockHeight(
blockHeight uint64,
err error,
) {
b, err := c.tendermintServiceClient.GetLatestBlock(context.Background(), &tmtypes.GetLatestBlockRequest{})
b, err := c.tendermintServiceClient.GetLatestBlock(ctx, &tmtypes.GetLatestBlockRequest{})
if err != nil {
return 0, err
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/cosmos/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,13 @@ func (c *chain) HealthReport() map[string]error {
return m
}

func (c *chain) LatestHead(_ context.Context) (types.Head, error) {
func (c *chain) LatestHead(ctx context.Context) (types.Head, error) {
reader, err := c.Reader("")
if err != nil {
return types.Head{}, fmt.Errorf("chain unreachable: %v", err)
}

latestBlock, err := reader.LatestBlock()
latestBlock, err := reader.LatestBlock(ctx)
if err != nil {
return types.Head{}, err
}
Expand Down Expand Up @@ -249,7 +249,7 @@ func (c *chain) Transact(ctx context.Context, from, to string, amount *big.Int,
return fmt.Errorf("gas price unavailable: %v", err2)
}

err = validateBalance(reader, gasPrice, fromAcc, coin)
err = validateBalance(ctx, reader, gasPrice, fromAcc, coin)
if err != nil {
return fmt.Errorf("failed to validate balance: %v", err)
}
Expand Down Expand Up @@ -300,8 +300,8 @@ func nodeStatus(n *config.Node, id string) (types.NodeStatus, error) {
const maxGasUsedTransfer = 100_000

// validateBalance validates that fromAddr's balance can cover coin, including fees at gasPrice.
func validateBalance(reader client.Reader, gasPrice sdk.DecCoin, fromAddr sdk.AccAddress, coin sdk.Coin) error {
balance, err := reader.Balance(fromAddr, coin.GetDenom())
func validateBalance(ctx context.Context, reader client.Reader, gasPrice sdk.DecCoin, fromAddr sdk.AccAddress, coin sdk.Coin) error {
balance, err := reader.Balance(ctx, fromAddr, coin.GetDenom())
if err != nil {
return err
}
Expand Down
74 changes: 37 additions & 37 deletions pkg/cosmos/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ type ReaderWriter interface {

// Reader provides methods for reading from a cosmos chain.
type Reader interface {
Account(address sdk.AccAddress) (uint64, uint64, error)
ContractState(contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error)
TxsEvents(events []string, paginationParams *query.PageRequest) (*txtypes.GetTxsEventResponse, error)
Tx(hash string) (*txtypes.GetTxResponse, error)
LatestBlock() (*tmtypes.GetLatestBlockResponse, error)
BlockByHeight(height int64) (*tmtypes.GetBlockByHeightResponse, error)
Balance(addr sdk.AccAddress, denom string) (*sdk.Coin, error)
Account(ctx context.Context, address sdk.AccAddress) (uint64, uint64, error)
ContractState(ctx context.Context, contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error)
TxsEvents(ctx context.Context, events []string, paginationParams *query.PageRequest) (*txtypes.GetTxsEventResponse, error)
Tx(ctx context.Context, hash string) (*txtypes.GetTxResponse, error)
LatestBlock(context.Context) (*tmtypes.GetLatestBlockResponse, error)
BlockByHeight(ctx context.Context, height int64) (*tmtypes.GetBlockByHeightResponse, error)
Balance(ctx context.Context, addr sdk.AccAddress, denom string) (*sdk.Coin, error)
// TODO: escape hatch for injective client
Context() *cosmosclient.Context
}
Expand All @@ -54,11 +54,11 @@ type Reader interface {
// We may want to support multiple from addresses + signers if a use case arises.
type Writer interface {
// TODO: SignAndBroadcast is only used for testing, remove it
SignAndBroadcast(msgs []sdk.Msg, accountNum uint64, sequence uint64, gasPrice sdk.DecCoin, signer cryptotypes.PrivKey, mode txtypes.BroadcastMode) (*txtypes.BroadcastTxResponse, error)
Broadcast(txBytes []byte, mode txtypes.BroadcastMode) (*txtypes.BroadcastTxResponse, error)
Simulate(txBytes []byte) (*txtypes.SimulateResponse, error)
BatchSimulateUnsigned(msgs SimMsgs, sequence uint64) (*BatchSimResults, error)
SimulateUnsigned(msgs []sdk.Msg, sequence uint64) (*txtypes.SimulateResponse, error)
SignAndBroadcast(ctx context.Context, msgs []sdk.Msg, accountNum uint64, sequence uint64, gasPrice sdk.DecCoin, signer cryptotypes.PrivKey, mode txtypes.BroadcastMode) (*txtypes.BroadcastTxResponse, error)
Broadcast(ctx context.Context, txBytes []byte, mode txtypes.BroadcastMode) (*txtypes.BroadcastTxResponse, error)
Simulate(ctx context.Context, txBytes []byte) (*txtypes.SimulateResponse, error)
BatchSimulateUnsigned(ctx context.Context, msgs SimMsgs, sequence uint64) (*BatchSimResults, error)
SimulateUnsigned(ctx context.Context, msgs []sdk.Msg, sequence uint64) (*txtypes.SimulateResponse, error)
CreateAndSign(msgs []sdk.Msg, account uint64, sequence uint64, gasLimit uint64, gasLimitMultiplier float64, gasPrice sdk.DecCoin, signer cryptotypes.PrivKey, timeoutHeight uint64) ([]byte, error)
}

Expand Down Expand Up @@ -146,8 +146,8 @@ func (c *Client) Context() *cosmosclient.Context {

// Account read the account address for the account number and sequence number.
// !!Note only one sequence number can be used per account per block!!
func (c *Client) Account(addr sdk.AccAddress) (uint64, uint64, error) {
r, err := c.authClient.Account(context.Background(), &authtypes.QueryAccountRequest{Address: addr.String()})
func (c *Client) Account(ctx context.Context, addr sdk.AccAddress) (uint64, uint64, error) {
r, err := c.authClient.Account(ctx, &authtypes.QueryAccountRequest{Address: addr.String()})
if err != nil {
return 0, 0, err
}
Expand All @@ -160,8 +160,8 @@ func (c *Client) Account(addr sdk.AccAddress) (uint64, uint64, error) {
}

// ContractState reads from a WASM contract store
func (c *Client) ContractState(contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error) {
s, err := c.wasmClient.SmartContractState(context.Background(), &wasmtypes.QuerySmartContractStateRequest{
func (c *Client) ContractState(ctx context.Context, contractAddress sdk.AccAddress, queryMsg []byte) ([]byte, error) {
s, err := c.wasmClient.SmartContractState(ctx, &wasmtypes.QuerySmartContractStateRequest{
Address: contractAddress.String(),
QueryData: queryMsg,
})
Expand All @@ -176,8 +176,8 @@ func (c *Client) ContractState(contractAddress sdk.AccAddress, queryMsg []byte)
// Each event is ANDed together and follows the query language defined
// https://docs.cosmos.network/master/core/events.html
// Note one current issue https://github.com/cosmos/cosmos-sdk/issues/10448
func (c *Client) TxsEvents(events []string, paginationParams *query.PageRequest) (*txtypes.GetTxsEventResponse, error) {
e, err := c.cosmosServiceClient.GetTxsEvent(context.Background(), &txtypes.GetTxsEventRequest{
func (c *Client) TxsEvents(ctx context.Context, events []string, paginationParams *query.PageRequest) (*txtypes.GetTxsEventResponse, error) {
e, err := c.cosmosServiceClient.GetTxsEvent(ctx, &txtypes.GetTxsEventRequest{
Events: events,
Pagination: paginationParams,
OrderBy: txtypes.OrderBy_ORDER_BY_DESC,
Expand All @@ -186,21 +186,21 @@ func (c *Client) TxsEvents(events []string, paginationParams *query.PageRequest)
}

// Tx gets a tx by hash
func (c *Client) Tx(hash string) (*txtypes.GetTxResponse, error) {
e, err := c.cosmosServiceClient.GetTx(context.Background(), &txtypes.GetTxRequest{
func (c *Client) Tx(ctx context.Context, hash string) (*txtypes.GetTxResponse, error) {
e, err := c.cosmosServiceClient.GetTx(ctx, &txtypes.GetTxRequest{
Hash: hash,
})
return e, err
}

// LatestBlock returns the latest block
func (c *Client) LatestBlock() (*tmtypes.GetLatestBlockResponse, error) {
return c.tendermintServiceClient.GetLatestBlock(context.Background(), &tmtypes.GetLatestBlockRequest{})
func (c *Client) LatestBlock(ctx context.Context) (*tmtypes.GetLatestBlockResponse, error) {
return c.tendermintServiceClient.GetLatestBlock(ctx, &tmtypes.GetLatestBlockRequest{})
}

// BlockByHeight gets a block by height
func (c *Client) BlockByHeight(height int64) (*tmtypes.GetBlockByHeightResponse, error) {
return c.tendermintServiceClient.GetBlockByHeight(context.Background(), &tmtypes.GetBlockByHeightRequest{Height: height})
func (c *Client) BlockByHeight(ctx context.Context, height int64) (*tmtypes.GetBlockByHeightResponse, error) {
return c.tendermintServiceClient.GetBlockByHeight(ctx, &tmtypes.GetBlockByHeightRequest{Height: height})
}

// CreateAndSign creates and signs a transaction
Expand Down Expand Up @@ -336,12 +336,12 @@ func (c *Client) failedMsgIndex(err error) (bool, int) {
// Note that the error from simulating indicates the first
// msg in the slice which failed (it simply loops over the msgs
// and simulates them one by one, breaking at the first failure).
func (c *Client) BatchSimulateUnsigned(msgs SimMsgs, sequence uint64) (*BatchSimResults, error) {
func (c *Client) BatchSimulateUnsigned(ctx context.Context, msgs SimMsgs, sequence uint64) (*BatchSimResults, error) {
var succeeded []SimMsg
var failed []SimMsg
toSim := msgs
for {
_, err := c.SimulateUnsigned(toSim.GetMsgs(), sequence)
_, err := c.SimulateUnsigned(ctx, toSim.GetMsgs(), sequence)
containsFailure, failureIndex := c.failedMsgIndex(err)
if err != nil && !containsFailure {
return nil, err
Expand Down Expand Up @@ -370,7 +370,7 @@ func (c *Client) BatchSimulateUnsigned(msgs SimMsgs, sequence uint64) (*BatchSim
}

// SimulateUnsigned simulates an unsigned msg
func (c *Client) SimulateUnsigned(msgs []sdk.Msg, sequence uint64) (*txtypes.SimulateResponse, error) {
func (c *Client) SimulateUnsigned(ctx context.Context, msgs []sdk.Msg, sequence uint64) (*txtypes.SimulateResponse, error) {
txConfig := params.ClientTxConfig()
txBuilder := txConfig.NewTxBuilder()
if err := txBuilder.SetMsgs(msgs...); err != nil {
Expand All @@ -393,23 +393,23 @@ func (c *Client) SimulateUnsigned(msgs []sdk.Msg, sequence uint64) (*txtypes.Sim
if err != nil {
return nil, err
}
s, err := c.cosmosServiceClient.Simulate(context.Background(), &txtypes.SimulateRequest{
s, err := c.cosmosServiceClient.Simulate(ctx, &txtypes.SimulateRequest{
TxBytes: txBytes,
})
return s, err
}

// Simulate simulates a signed transaction
func (c *Client) Simulate(txBytes []byte) (*txtypes.SimulateResponse, error) {
s, err := c.cosmosServiceClient.Simulate(context.Background(), &txtypes.SimulateRequest{
func (c *Client) Simulate(ctx context.Context, txBytes []byte) (*txtypes.SimulateResponse, error) {
s, err := c.cosmosServiceClient.Simulate(ctx, &txtypes.SimulateRequest{
TxBytes: txBytes,
})
return s, err
}

// Broadcast broadcasts a tx
func (c *Client) Broadcast(txBytes []byte, mode txtypes.BroadcastMode) (*txtypes.BroadcastTxResponse, error) {
res, err := c.cosmosServiceClient.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
func (c *Client) Broadcast(ctx context.Context, txBytes []byte, mode txtypes.BroadcastMode) (*txtypes.BroadcastTxResponse, error) {
res, err := c.cosmosServiceClient.BroadcastTx(ctx, &txtypes.BroadcastTxRequest{
Mode: mode,
TxBytes: txBytes,
})
Expand All @@ -426,8 +426,8 @@ func (c *Client) Broadcast(txBytes []byte, mode txtypes.BroadcastMode) (*txtypes
}

// SignAndBroadcast signs and broadcasts a group of msgs.
func (c *Client) SignAndBroadcast(msgs []sdk.Msg, account uint64, sequence uint64, gasPrice sdk.DecCoin, signer cryptotypes.PrivKey, mode txtypes.BroadcastMode) (*txtypes.BroadcastTxResponse, error) {
sim, err := c.SimulateUnsigned(msgs, sequence)
func (c *Client) SignAndBroadcast(ctx context.Context, msgs []sdk.Msg, account uint64, sequence uint64, gasPrice sdk.DecCoin, signer cryptotypes.PrivKey, mode txtypes.BroadcastMode) (*txtypes.BroadcastTxResponse, error) {
sim, err := c.SimulateUnsigned(ctx, msgs, sequence)
if err != nil {
return nil, err
}
Expand All @@ -436,12 +436,12 @@ func (c *Client) SignAndBroadcast(msgs []sdk.Msg, account uint64, sequence uint6
if err != nil {
return nil, err
}
return c.Broadcast(txBytes, mode)
return c.Broadcast(ctx, txBytes, mode)
}

// Balance returns the balance of an address
func (c *Client) Balance(addr sdk.AccAddress, denom string) (*sdk.Coin, error) {
b, err := c.bankClient.Balance(context.Background(), &banktypes.QueryBalanceRequest{Address: addr.String(), Denom: denom})
func (c *Client) Balance(ctx context.Context, addr sdk.AccAddress, denom string) (*sdk.Coin, error) {
b, err := c.bankClient.Balance(ctx, &banktypes.QueryBalanceRequest{Address: addr.String(), Denom: denom})
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 5277829

Please sign in to comment.