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

[BP: v7 <- #979] refactor!: changing block height type from uint64 to int64 #984

Merged
merged 3 commits into from
Feb 19, 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
29 changes: 21 additions & 8 deletions chain/cosmos/chain_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import (
"github.com/docker/go-connections/nat"
"go.uber.org/zap"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

ccvclient "github.com/cosmos/interchain-security/v3/x/ccv/provider/client"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
Expand All @@ -51,6 +53,7 @@ type ChainNode struct {
NetworkID string
DockerClient *dockerclient.Client
Client rpcclient.Client
GrpcConn *grpc.ClientConn
TestName string
Image ibc.DockerImage

Expand Down Expand Up @@ -124,6 +127,15 @@ func (tn *ChainNode) NewClient(addr string) error {
}

tn.Client = rpcClient

grpcConn, err := grpc.Dial(
Copy link
Member

@Reecepbcups Reecepbcups Feb 19, 2024

Choose a reason for hiding this comment

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

pulled from v8 for the module_*.go support (only gov queries here)

Future can backport other changes to v7

tn.hostGRPCPort, grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
return fmt.Errorf("grpc dial: %w", err)
}
tn.GrpcConn = grpcConn

return nil
}

Expand Down Expand Up @@ -176,6 +188,7 @@ func (tn *ChainNode) CliContext() client.Context {
return client.Context{
Client: tn.Client,
ChainID: cfg.ChainID,
GRPCClient: tn.GrpcConn,
InterfaceRegistry: cfg.EncodingConfig.InterfaceRegistry,
Input: os.Stdin,
Output: os.Stdout,
Expand Down Expand Up @@ -376,17 +389,17 @@ func (tn *ChainNode) SetPeers(ctx context.Context, peers string) error {
)
}

func (tn *ChainNode) Height(ctx context.Context) (uint64, error) {
func (tn *ChainNode) Height(ctx context.Context) (int64, error) {
res, err := tn.Client.Status(ctx)
if err != nil {
return 0, fmt.Errorf("tendermint rpc client status: %w", err)
}
height := res.SyncInfo.LatestBlockHeight
return uint64(height), nil
return height, nil
}

// FindTxs implements blockdb.BlockSaver.
func (tn *ChainNode) FindTxs(ctx context.Context, height uint64) ([]blockdb.Tx, error) {
func (tn *ChainNode) FindTxs(ctx context.Context, height int64) ([]blockdb.Tx, error) {
h := int64(height)
var eg errgroup.Group
var blockRes *coretypes.ResultBlockResults
Expand All @@ -410,12 +423,12 @@ func (tn *ChainNode) FindTxs(ctx context.Context, height uint64) ([]blockdb.Tx,

sdkTx, err := decodeTX(interfaceRegistry, tx)
if err != nil {
tn.logger().Info("Failed to decode tx", zap.Uint64("height", height), zap.Error(err))
tn.logger().Info("Failed to decode tx", zap.Int64("height", height), zap.Error(err))
continue
}
b, err := encodeTxToJSON(interfaceRegistry, sdkTx)
if err != nil {
tn.logger().Info("Failed to marshal tx to json", zap.Uint64("height", height), zap.Error(err))
tn.logger().Info("Failed to marshal tx to json", zap.Int64("height", height), zap.Error(err))
continue
}
newTx.Data = b
Expand Down Expand Up @@ -1115,10 +1128,10 @@ func (tn *ChainNode) GetModuleAccount(ctx context.Context, moduleName string) (Q
}

// VoteOnProposal submits a vote for the specified proposal.
func (tn *ChainNode) VoteOnProposal(ctx context.Context, keyName string, proposalID string, vote string) error {
func (tn *ChainNode) VoteOnProposal(ctx context.Context, keyName string, proposalID int64, vote string) error {
_, err := tn.ExecTx(ctx, keyName,
"gov", "vote",
proposalID, vote, "--gas", "auto",
strconv.FormatInt(proposalID, 10), vote, "--gas", "auto",
)
return err
}
Expand Down Expand Up @@ -1163,7 +1176,7 @@ func (tn *ChainNode) UpgradeProposal(ctx context.Context, keyName string, prop S
command := []string{
"gov", "submit-proposal",
"software-upgrade", prop.Name,
"--upgrade-height", strconv.FormatUint(prop.Height, 10),
"--upgrade-height", strconv.FormatInt(prop.Height, 10),
"--title", prop.Title,
"--description", prop.Description,
"--deposit", prop.Deposit,
Expand Down
27 changes: 17 additions & 10 deletions chain/cosmos/cosmos_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"sync"
"time"

govv1beta1 "cosmossdk.io/api/cosmos/gov/v1beta1"
sdkmath "cosmossdk.io/math"
abcitypes "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/proto/tendermint/crypto"
Expand All @@ -27,6 +28,7 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankTypes "github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govv1beta1type "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
paramsutils "github.com/cosmos/cosmos-sdk/x/params/client/utils"
cosmosproto "github.com/cosmos/gogoproto/proto"
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
Expand Down Expand Up @@ -352,7 +354,7 @@ func (c *CosmosChain) SendIBCTransfer(
if txResp.Code != 0 {
return tx, fmt.Errorf("error in transaction (code: %d): %s", txResp.Code, txResp.RawLog)
}
tx.Height = uint64(txResp.Height)
tx.Height = txResp.Height
tx.TxHash = txHash
// In cosmos, user is charged for entire gas requested, not the actual gas used.
tx.GasSpent = txResp.GasWanted
Expand Down Expand Up @@ -522,7 +524,7 @@ func (c *CosmosChain) txProposal(txHash string) (tx TxProposal, _ error) {
if err != nil {
return tx, fmt.Errorf("failed to get transaction %s: %w", txHash, err)
}
tx.Height = uint64(txResp.Height)
tx.Height = txResp.Height
tx.TxHash = txHash
// In cosmos, user is charged for entire gas requested, not the actual gas used.
tx.GasSpent = txResp.GasWanted
Expand Down Expand Up @@ -1160,11 +1162,16 @@ func (c *CosmosChain) StartProvider(testName string, ctx context.Context, additi
return err
}

if err := c.VoteOnProposalAllValidators(ctx, propTx.ProposalID, ProposalVoteYes); err != nil {
propId, err := strconv.ParseInt(propTx.ProposalID, 10, 64)
if err != nil {
return fmt.Errorf("failed to parse proposal id: %w", err)
}

if err := c.VoteOnProposalAllValidators(ctx, propId, ProposalVoteYes); err != nil {
return err
}

_, err = PollForProposalStatus(ctx, c, height, height+10, propTx.ProposalID, ProposalStatusPassed)
_, err = PollForProposalStatus(ctx, c, height, height+10, propId, govv1beta1type.ProposalStatus(govv1beta1.ProposalStatus_PROPOSAL_STATUS_PASSED))
if err != nil {
return fmt.Errorf("proposal status did not change to passed in expected number of blocks: %w", err)
}
Expand Down Expand Up @@ -1288,7 +1295,7 @@ func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additi
DefaultProviderUnbondingPeriod, // Needs to match provider unbonding period
ccvprovidertypes.DefaultMaxClockDrift,
clienttypes.Height{
RevisionHeight: providerHeight,
RevisionHeight: uint64(providerHeight),
RevisionNumber: clienttypes.ParseChainID(providerCfg.ChainID),
},
commitmenttypes.GetSDKSpecs(),
Expand Down Expand Up @@ -1399,12 +1406,12 @@ func (c *CosmosChain) StartConsumer(testName string, ctx context.Context, additi
}

// Height implements ibc.Chain
func (c *CosmosChain) Height(ctx context.Context) (uint64, error) {
func (c *CosmosChain) Height(ctx context.Context) (int64, error) {
return c.getFullNode().Height(ctx)
}

// Acknowledgements implements ibc.Chain, returning all acknowledgments in block at height
func (c *CosmosChain) Acknowledgements(ctx context.Context, height uint64) ([]ibc.PacketAcknowledgement, error) {
func (c *CosmosChain) Acknowledgements(ctx context.Context, height int64) ([]ibc.PacketAcknowledgement, error) {
var acks []*chanTypes.MsgAcknowledgement
err := RangeBlockMessages(ctx, c.cfg.EncodingConfig.InterfaceRegistry, c.getFullNode().Client, height, func(msg types.Msg) bool {
found, ok := msg.(*chanTypes.MsgAcknowledgement)
Expand Down Expand Up @@ -1437,7 +1444,7 @@ func (c *CosmosChain) Acknowledgements(ctx context.Context, height uint64) ([]ib
}

// Timeouts implements ibc.Chain, returning all timeouts in block at height
func (c *CosmosChain) Timeouts(ctx context.Context, height uint64) ([]ibc.PacketTimeout, error) {
func (c *CosmosChain) Timeouts(ctx context.Context, height int64) ([]ibc.PacketTimeout, error) {
var timeouts []*chanTypes.MsgTimeout
err := RangeBlockMessages(ctx, c.cfg.EncodingConfig.InterfaceRegistry, c.getFullNode().Client, height, func(msg types.Msg) bool {
found, ok := msg.(*chanTypes.MsgTimeout)
Expand Down Expand Up @@ -1469,7 +1476,7 @@ func (c *CosmosChain) Timeouts(ctx context.Context, height uint64) ([]ibc.Packet
}

// FindTxs implements blockdb.BlockSaver.
func (c *CosmosChain) FindTxs(ctx context.Context, height uint64) ([]blockdb.Tx, error) {
func (c *CosmosChain) FindTxs(ctx context.Context, height int64) ([]blockdb.Tx, error) {
fn := c.getFullNode()
c.findTxMu.Lock()
defer c.findTxMu.Unlock()
Expand Down Expand Up @@ -1579,7 +1586,7 @@ func (c *CosmosChain) StartAllValSidecars(ctx context.Context) error {
return eg.Wait()
}

func (c *CosmosChain) VoteOnProposalAllValidators(ctx context.Context, proposalID string, vote string) error {
func (c *CosmosChain) VoteOnProposalAllValidators(ctx context.Context, proposalID int64, vote string) error {
var eg errgroup.Group
for _, n := range c.Nodes() {
if n.Validator {
Expand Down
77 changes: 77 additions & 0 deletions chain/cosmos/module_gov.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package cosmos

import (
"context"

govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

// GovQueryProposal returns the state and details of a v1beta1 governance proposal.
func (c *CosmosChain) GovQueryProposal(ctx context.Context, proposalID int64) (*govv1beta1.Proposal, error) {
res, err := govv1beta1.NewQueryClient(c.GetNode().GrpcConn).Proposal(ctx, &govv1beta1.QueryProposalRequest{ProposalId: uint64(proposalID)})
if err != nil {
return nil, err
}

return &res.Proposal, nil
}

// GovQueryProposalV1 returns the state and details of a v1 governance proposal.
func (c *CosmosChain) GovQueryProposalV1(ctx context.Context, proposalID int64) (*govv1.Proposal, error) {
res, err := govv1.NewQueryClient(c.GetNode().GrpcConn).Proposal(ctx, &govv1.QueryProposalRequest{ProposalId: uint64(proposalID)})
if err != nil {
return nil, err
}

return res.Proposal, nil
}

// GovQueryProposalsV1 returns all proposals with a given status.
func (c *CosmosChain) GovQueryProposalsV1(ctx context.Context, status govv1.ProposalStatus) ([]*govv1.Proposal, error) {
res, err := govv1.NewQueryClient(c.GetNode().GrpcConn).Proposals(ctx, &govv1.QueryProposalsRequest{
ProposalStatus: status,
})
if err != nil {
return nil, err
}

return res.Proposals, nil
}

// GovQueryVote returns the vote for a proposal from a specific voter.
func (c *CosmosChain) GovQueryVote(ctx context.Context, proposalID uint64, voter string) (*govv1.Vote, error) {
res, err := govv1.NewQueryClient(c.GetNode().GrpcConn).Vote(ctx, &govv1.QueryVoteRequest{
ProposalId: proposalID,
Voter: voter,
})
if err != nil {
return nil, err
}

return res.Vote, nil
}

// GovQueryVotes returns all votes for a proposal.
func (c *CosmosChain) GovQueryVotes(ctx context.Context, proposalID uint64) ([]*govv1.Vote, error) {
res, err := govv1.NewQueryClient(c.GetNode().GrpcConn).Votes(ctx, &govv1.QueryVotesRequest{
ProposalId: proposalID,
})
if err != nil {
return nil, err
}

return res.Votes, nil
}

// GovQueryParams returns the current governance parameters.
func (c *CosmosChain) GovQueryParams(ctx context.Context, paramsType string) (*govv1.Params, error) {
res, err := govv1.NewQueryClient(c.GetNode().GrpcConn).Params(ctx, &govv1.QueryParamsRequest{
ParamsType: paramsType,
})
if err != nil {
return nil, err
}

return res.Params, nil
}
42 changes: 32 additions & 10 deletions chain/cosmos/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,58 @@ import (
"errors"
"fmt"

govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
"github.com/strangelove-ventures/interchaintest/v7/testutil"
)

// PollForProposalStatus attempts to find a proposal with matching ID and status using gov v1.
func PollForProposalStatusV1(ctx context.Context, chain *CosmosChain, startHeight, maxHeight int64, proposalID int64, status govv1.ProposalStatus) (*govv1.Proposal, error) {
var pr *govv1.Proposal
doPoll := func(ctx context.Context, height int64) (*govv1.Proposal, error) {
p, err := chain.GovQueryProposalV1(ctx, proposalID)
if err != nil {
return pr, err
}

if p.Status.String() != status.String() {
return pr, fmt.Errorf("proposal status (%d / %s) does not match expected: (%d / %s)", p.Status, p.Status.String(), status, status.String())
}

return p, nil
}
bp := testutil.BlockPoller[*govv1.Proposal]{CurrentHeight: chain.Height, PollFunc: doPoll}
return bp.DoPoll(ctx, startHeight, maxHeight)
}

// PollForProposalStatus attempts to find a proposal with matching ID and status.
func PollForProposalStatus(ctx context.Context, chain *CosmosChain, startHeight, maxHeight uint64, proposalID string, status string) (ProposalResponse, error) {
var zero ProposalResponse
doPoll := func(ctx context.Context, height uint64) (ProposalResponse, error) {
p, err := chain.QueryProposal(ctx, proposalID)
func PollForProposalStatus(ctx context.Context, chain *CosmosChain, startHeight, maxHeight, proposalID int64, status govv1beta1.ProposalStatus) (*govv1beta1.Proposal, error) {
var zero *govv1beta1.Proposal
doPoll := func(ctx context.Context, height int64) (*govv1beta1.Proposal, error) {
p, err := chain.GovQueryProposal(ctx, proposalID)
if err != nil {
return zero, err
}
if p.Status != status {
return zero, fmt.Errorf("proposal status (%s) does not match expected: (%s)", p.Status, status)
}
return *p, nil
return p, nil
}
bp := testutil.BlockPoller[ProposalResponse]{CurrentHeight: chain.Height, PollFunc: doPoll}
bp := testutil.BlockPoller[*govv1beta1.Proposal]{CurrentHeight: chain.Height, PollFunc: doPoll}
return bp.DoPoll(ctx, startHeight, maxHeight)
}

// PollForMessage searches every transaction for a message. Must pass a coded registry capable of decoding the cosmos transaction.
// fn is optional. Return true from the fn to stop polling and return the found message. If fn is nil, returns the first message to match type T.
func PollForMessage[T any](ctx context.Context, chain *CosmosChain, registry codectypes.InterfaceRegistry, startHeight, maxHeight uint64, fn func(found T) bool) (T, error) {
func PollForMessage[T any](ctx context.Context, chain *CosmosChain, registry codectypes.InterfaceRegistry, startHeight, maxHeight int64, fn func(found T) bool) (T, error) {
var zero T
if fn == nil {
fn = func(T) bool { return true }
}
doPoll := func(ctx context.Context, height uint64) (T, error) {
doPoll := func(ctx context.Context, height int64) (T, error) {
h := int64(height)
block, err := chain.getFullNode().Client.Block(ctx, &h)
if err != nil {
Expand All @@ -61,12 +83,12 @@ func PollForMessage[T any](ctx context.Context, chain *CosmosChain, registry cod
}

// PollForBalance polls until the balance matches
func PollForBalance(ctx context.Context, chain *CosmosChain, deltaBlocks uint64, balance ibc.WalletAmount) error {
func PollForBalance(ctx context.Context, chain *CosmosChain, deltaBlocks int64, balance ibc.WalletAmount) error {
h, err := chain.Height(ctx)
if err != nil {
return fmt.Errorf("failed to get height: %w", err)
}
doPoll := func(ctx context.Context, height uint64) (any, error) {
doPoll := func(ctx context.Context, height int64) (any, error) {
bal, err := chain.GetBalance(ctx, balance.Address, balance.Denom)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion chain/cosmos/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type blockClient interface {

// RangeBlockMessages iterates through all a block's transactions and each transaction's messages yielding to f.
// Return true from f to stop iteration.
func RangeBlockMessages(ctx context.Context, interfaceRegistry codectypes.InterfaceRegistry, client blockClient, height uint64, done func(sdk.Msg) bool) error {
func RangeBlockMessages(ctx context.Context, interfaceRegistry codectypes.InterfaceRegistry, client blockClient, height int64, done func(sdk.Msg) bool) error {
h := int64(height)
block, err := client.Block(ctx, &h)
if err != nil {
Expand Down
Loading
Loading