Skip to content

Commit

Permalink
bring in changes from main branch to v3 (#366)
Browse files Browse the repository at this point in the history
* fix: Unable to build ibctest binary (#326)

* feat: Add cosmos message poller (#325)

* fix: change import paths from v6 to v3

* Make configutil public (#336)

* Make configutil public

* Rename test package to chainutil. Make util packages subpackages of util package

* Consolidate into single testutil package

* fix: formatting issue in doc

* fix: change import path from test to testutil

* fix: go mod tidy

* packet-forward-middleware packet memo, retry on timeout, and atomic forwards (#306)

* Make examples its own module

* Make cosmos specific module and run in CI in separate task

* Update e2e test for memo refactor

* Update test to chain-level params

* Use gaia with pfm with configurable timeout and retries

* Update SendIBCTransfer uses

* fix interchain test

* Add GetClients method to Relayer and helper for getting transfer channel between chains

* Update packet forward test for multi-hop, add multi-hop refund test

* Update tests for atomic forwards

* Wait for a block after ack before checking balances

* reduce wait to 1 block

* Add multi-hop flow with refund through chain with native denom. Add assertions for escrow accounts

* Remove stale comment

* handle feedback

* Add TransferOptions

* fix: remove extra argument to NewMsgTransfer call

* build: go mod tidy

* chore: update gaia image version for packet forward tests

* fix: fallback to old version of the interchain accounts demo binary

Co-authored-by: David Nix <[email protected]>
Co-authored-by: Andrew Gouin <[email protected]>
  • Loading branch information
3 people authored Jan 9, 2023
1 parent 96ea120 commit 11355c5
Show file tree
Hide file tree
Showing 60 changed files with 1,546 additions and 9,594 deletions.
13 changes: 7 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ jobs:
# run tests
- name: run unit tests
run: go test -race -timeout 30m -v -p 2 ./...
test-cmd-ibctest:
name: test-cmd-ibctest
# -short flag purposefully omitted because there are some longer unit tests
run: go test -race -timeout 10m -p 2 $(go list ./... | grep -v /cmd | grep -v /examples)
test-conformance:
name: test-conformance
runs-on: [self-hosted, linux]
steps:
# Install and setup go
Expand All @@ -52,7 +53,7 @@ jobs:
# run tests
- name: run conformance tests
run: (cd cmd/ibctest && go test -race -timeout 30m -v -p 2 ./...) || (echo "\n\n*****CHAIN and RELAYER LOGS*****" && cat "$HOME/.ibctest/logs/ibctest.log" && exit 1)
run: (go test -race -timeout 30m -v -p 2 ./cmd/ibctest) || (echo "\n\n*****CHAIN and RELAYER LOGS*****" && cat "$HOME/.ibctest/logs/ibctest.log" && exit 1)
test-ibc-examples:
name: test-ibc-examples
runs-on: [self-hosted, linux]
Expand All @@ -73,7 +74,7 @@ jobs:
# run tests
- name: run example ibc tests
run: cd examples/ibc && go test -race -timeout 30m -v -p 2 ./...
run: go test -race -timeout 30m -v -p 2 ./examples/ibc
test-cosmos-examples:
name: test-cosmos-examples
runs-on: [self-hosted, linux]
Expand All @@ -94,4 +95,4 @@ jobs:
# run tests
- name: run example cosmos tests
run: cd examples/cosmos && go test -race -timeout 30m -v -p 2 ./...
run: go test -race -timeout 30m -v -p 2 ./examples/cosmos
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ibctest: gen ## Build ibctest binary into ./bin

.PHONY: test
test: ## Run unit tests
@go test -cover -short -race -timeout=60s $(shell go list ./... | grep -v /cmd/)
@go test -cover -short -race -timeout=60s ./...

.PHONY: docker-reset
docker-reset: ## Attempt to delete all running containers. Useful if ibctest does not exit cleanly.
Expand Down
58 changes: 40 additions & 18 deletions chain/cosmos/chain_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ import (
"github.com/docker/go-connections/nat"
"github.com/strangelove-ventures/ibctest/v3/ibc"
"github.com/strangelove-ventures/ibctest/v3/internal/blockdb"
"github.com/strangelove-ventures/ibctest/v3/internal/configutil"
"github.com/strangelove-ventures/ibctest/v3/internal/dockerutil"
"github.com/strangelove-ventures/ibctest/v3/test"
"github.com/strangelove-ventures/ibctest/v3/testutil"
tmjson "github.com/tendermint/tendermint/libs/json"
"github.com/tendermint/tendermint/p2p"
rpcclient "github.com/tendermint/tendermint/rpc/client"
Expand Down Expand Up @@ -198,55 +197,69 @@ func (tn *ChainNode) HomeDir() string {

// SetTestConfig modifies the config to reasonable values for use within ibctest.
func (tn *ChainNode) SetTestConfig(ctx context.Context) error {
c := make(configutil.Toml)
c := make(testutil.Toml)

// Set Log Level to info
c["log_level"] = "info"

p2p := make(configutil.Toml)
p2p := make(testutil.Toml)

// Allow p2p strangeness
p2p["allow_duplicate_ip"] = true
p2p["addr_book_strict"] = false

c["p2p"] = p2p

consensus := make(configutil.Toml)
consensus := make(testutil.Toml)

blockT := (time.Duration(blockTime) * time.Second).String()
consensus["timeout_commit"] = blockT
consensus["timeout_propose"] = blockT

c["consensus"] = consensus

rpc := make(configutil.Toml)
rpc := make(testutil.Toml)

// Enable public RPC
rpc["laddr"] = "tcp://0.0.0.0:26657"

c["rpc"] = rpc

return configutil.ModifyTomlConfigFile(
if err := testutil.ModifyTomlConfigFile(
ctx,
tn.logger(),
tn.DockerClient,
tn.TestName,
tn.VolumeName,
"config/config.toml",
c,
); err != nil {
return err
}

a := make(testutil.Toml)
a["minimum-gas-prices"] = tn.Chain.Config().GasPrices
return testutil.ModifyTomlConfigFile(
ctx,
tn.logger(),
tn.DockerClient,
tn.TestName,
tn.VolumeName,
"config/app.toml",
a,
)
}

// SetPeers modifies the config persistent_peers for a node
func (tn *ChainNode) SetPeers(ctx context.Context, peers string) error {
c := make(configutil.Toml)
p2p := make(configutil.Toml)
c := make(testutil.Toml)
p2p := make(testutil.Toml)

// Set peers
p2p["persistent_peers"] = peers
c["p2p"] = p2p

return configutil.ModifyTomlConfigFile(
return testutil.ModifyTomlConfigFile(
ctx,
tn.logger(),
tn.DockerClient,
Expand Down Expand Up @@ -394,7 +407,7 @@ func (tn *ChainNode) ExecTx(ctx context.Context, keyName string, command ...stri
if output.Code != 0 {
return output.TxHash, fmt.Errorf("transaction failed with code %d: %s", output.Code, output.RawLog)
}
if err := test.WaitForBlocks(ctx, 2, tn); err != nil {
if err := testutil.WaitForBlocks(ctx, 2, tn); err != nil {
return "", err
}
return output.TxHash, nil
Expand Down Expand Up @@ -571,18 +584,27 @@ type CosmosTx struct {
RawLog string `json:"raw_log"`
}

func (tn *ChainNode) SendIBCTransfer(ctx context.Context, channelID string, keyName string, amount ibc.WalletAmount, timeout *ibc.IBCTimeout) (string, error) {
func (tn *ChainNode) SendIBCTransfer(
ctx context.Context,
channelID string,
keyName string,
amount ibc.WalletAmount,
options ibc.TransferOptions,
) (string, error) {
command := []string{
"ibc-transfer", "transfer", "transfer", channelID,
amount.Address, fmt.Sprintf("%d%s", amount.Amount, amount.Denom),
}
if timeout != nil {
if timeout.NanoSeconds > 0 {
command = append(command, "--packet-timeout-timestamp", fmt.Sprint(timeout.NanoSeconds))
} else if timeout.Height > 0 {
command = append(command, "--packet-timeout-height", fmt.Sprintf("0-%d", timeout.Height))
if options.Timeout != nil {
if options.Timeout.NanoSeconds > 0 {
command = append(command, "--packet-timeout-timestamp", fmt.Sprint(options.Timeout.NanoSeconds))
} else if options.Timeout.Height > 0 {
command = append(command, "--packet-timeout-height", fmt.Sprintf("0-%d", options.Timeout.Height))
}
}
if options.Memo != "" {
command = append(command, "--memo", options.Memo)
}
return tn.ExecTx(ctx, keyName, command...)
}

Expand Down Expand Up @@ -638,7 +660,7 @@ func (tn *ChainNode) StoreContract(ctx context.Context, keyName string, fileName
return "", err
}

err = test.WaitForBlocks(ctx, 5, tn.Chain)
err = testutil.WaitForBlocks(ctx, 5, tn.Chain)
if err != nil {
return "", fmt.Errorf("wait for blocks: %w", err)
}
Expand Down
27 changes: 16 additions & 11 deletions chain/cosmos/cosmos_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ import (
"github.com/strangelove-ventures/ibctest/v3/chain/internal/tendermint"
"github.com/strangelove-ventures/ibctest/v3/ibc"
"github.com/strangelove-ventures/ibctest/v3/internal/blockdb"
"github.com/strangelove-ventures/ibctest/v3/internal/configutil"
"github.com/strangelove-ventures/ibctest/v3/internal/dockerutil"
"github.com/strangelove-ventures/ibctest/v3/test"
"github.com/strangelove-ventures/ibctest/v3/testutil"
"go.uber.org/zap"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
Expand Down Expand Up @@ -124,11 +123,11 @@ func (c *CosmosChain) AddFullNodes(ctx context.Context, configFileOverrides map[
return err
}
for configFile, modifiedConfig := range configFileOverrides {
modifiedToml, ok := modifiedConfig.(configutil.Toml)
modifiedToml, ok := modifiedConfig.(testutil.Toml)
if !ok {
return fmt.Errorf("Provided toml override for file %s is of type (%T). Expected (DecodedToml)", configFile, modifiedConfig)
}
if err := configutil.ModifyTomlConfigFile(
if err := testutil.ModifyTomlConfigFile(
ctx,
fn.logger(),
fn.DockerClient,
Expand Down Expand Up @@ -228,8 +227,14 @@ func (c *CosmosChain) SendFunds(ctx context.Context, keyName string, amount ibc.
}

// Implements Chain interface
func (c *CosmosChain) SendIBCTransfer(ctx context.Context, channelID, keyName string, amount ibc.WalletAmount, timeout *ibc.IBCTimeout) (tx ibc.Tx, _ error) {
txHash, err := c.getFullNode().SendIBCTransfer(ctx, channelID, keyName, amount, timeout)
func (c *CosmosChain) SendIBCTransfer(
ctx context.Context,
channelID string,
keyName string,
amount ibc.WalletAmount,
options ibc.TransferOptions,
) (tx ibc.Tx, _ error) {
txHash, err := c.getFullNode().SendIBCTransfer(ctx, channelID, keyName, amount, options)
if err != nil {
return tx, fmt.Errorf("send ibc transfer: %w", err)
}
Expand Down Expand Up @@ -575,11 +580,11 @@ func (c *CosmosChain) Start(testName string, ctx context.Context, additionalGene
return err
}
for configFile, modifiedConfig := range configFileOverrides {
modifiedToml, ok := modifiedConfig.(configutil.Toml)
modifiedToml, ok := modifiedConfig.(testutil.Toml)
if !ok {
return fmt.Errorf("Provided toml override for file %s is of type (%T). Expected (DecodedToml)", configFile, modifiedConfig)
}
if err := configutil.ModifyTomlConfigFile(
if err := testutil.ModifyTomlConfigFile(
ctx,
v.logger(),
v.DockerClient,
Expand All @@ -604,11 +609,11 @@ func (c *CosmosChain) Start(testName string, ctx context.Context, additionalGene
return err
}
for configFile, modifiedConfig := range configFileOverrides {
modifiedToml, ok := modifiedConfig.(configutil.Toml)
modifiedToml, ok := modifiedConfig.(testutil.Toml)
if !ok {
return fmt.Errorf("Provided toml override for file %s is of type (%T). Expected (DecodedToml)", configFile, modifiedConfig)
}
if err := configutil.ModifyTomlConfigFile(
if err := testutil.ModifyTomlConfigFile(
ctx,
n.logger(),
n.DockerClient,
Expand Down Expand Up @@ -725,7 +730,7 @@ func (c *CosmosChain) Start(testName string, ctx context.Context, additionalGene
}

// Wait for 5 blocks before considering the chains "started"
return test.WaitForBlocks(ctx, 5, c.getFullNode())
return testutil.WaitForBlocks(ctx, 5, c.getFullNode())
}

// Height implements ibc.Chain
Expand Down
65 changes: 59 additions & 6 deletions chain/cosmos/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ package cosmos

import (
"context"
"errors"
"fmt"

"github.com/strangelove-ventures/ibctest/v3/test"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/strangelove-ventures/ibctest/v3/ibc"
"github.com/strangelove-ventures/ibctest/v3/testutil"
)

// 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) (any, error) {
doPoll := func(ctx context.Context, height uint64) (ProposalResponse, error) {
p, err := chain.QueryProposal(ctx, proposalID)
if err != nil {
return zero, err
Expand All @@ -20,10 +23,60 @@ func PollForProposalStatus(ctx context.Context, chain *CosmosChain, startHeight,
}
return *p, nil
}
bp := test.BlockPoller{CurrentHeight: chain.Height, PollFunc: doPoll}
p, err := bp.DoPoll(ctx, startHeight, maxHeight)
bp := testutil.BlockPoller[ProposalResponse]{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) {
var zero T
if fn == nil {
fn = func(T) bool { return true }
}
doPoll := func(ctx context.Context, height uint64) (T, error) {
h := int64(height)
block, err := chain.getFullNode().Client.Block(ctx, &h)
if err != nil {
return zero, err
}
for _, tx := range block.Block.Txs {
sdkTx, err := decodeTX(registry, tx)
if err != nil {
return zero, err
}
for _, msg := range sdkTx.GetMsgs() {
if found, ok := msg.(T); ok {
if fn(found) {
return found, nil
}
}
}
}
return zero, errors.New("not found")
}

bp := testutil.BlockPoller[T]{CurrentHeight: chain.Height, PollFunc: doPoll}
return bp.DoPoll(ctx, startHeight, maxHeight)
}

// PollForBalance polls until the balance matches
func PollForBalance(ctx context.Context, chain *CosmosChain, deltaBlocks uint64, balance ibc.WalletAmount) error {
h, err := chain.Height(ctx)
if err != nil {
return zero, err
return fmt.Errorf("failed to get height: %w", err)
}
doPoll := func(ctx context.Context, height uint64) (any, error) {
bal, err := chain.GetBalance(ctx, balance.Address, balance.Denom)
if err != nil {
return nil, err
}
if bal != balance.Amount {
return nil, fmt.Errorf("balance (%d) does not match expected: (%d)", bal, balance.Amount)
}
return nil, nil
}
return p.(ProposalResponse), nil
bp := testutil.BlockPoller[any]{CurrentHeight: chain.Height, PollFunc: doPoll}
_, err = bp.DoPoll(ctx, h, h+deltaBlocks)
return err
}
Loading

0 comments on commit 11355c5

Please sign in to comment.