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

pkg/cosmos: add Context to ReaderWriter methods #424

Merged
merged 1 commit into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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
Loading