Skip to content

Commit

Permalink
Add more testing, remove redundant (#772)
Browse files Browse the repository at this point in the history
* Add a "misc" test example for cosmos_node

* backup: wip (adding node, wallet keys, sending, FindTxs, and PollForBal)

* enable more and cleanup

* feat: SetSDKConfig(bech32prefix) for configuration

* testBroadcaster with bank multimsg send

* qol: NewGenesisKV(key, value)

* more wallet checks

* queryCmd, HashCommand

* rm duplicate test, add outside references

* rm SDK 45 test, same logic applies to 47

* Add light client verification to the IBC example

* Add more IBC examples

* fix: wasm icq StartupFlags

* Add more buffer to the conformance test
  • Loading branch information
Reecepbcups authored Oct 17, 2023
1 parent baccb64 commit 8caf914
Show file tree
Hide file tree
Showing 15 changed files with 314 additions and 1,441 deletions.
23 changes: 23 additions & 0 deletions chain/cosmos/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cosmos

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

func SetSDKConfig(bech32Prefix string) *sdk.Config {
var (
bech32MainPrefix = bech32Prefix
bech32PrefixAccAddr = bech32MainPrefix
bech32PrefixAccPub = bech32MainPrefix + sdk.PrefixPublic
bech32PrefixValAddr = bech32MainPrefix + sdk.PrefixValidator + sdk.PrefixOperator
bech32PrefixValPub = bech32MainPrefix + sdk.PrefixValidator + sdk.PrefixOperator + sdk.PrefixPublic
bech32PrefixConsAddr = bech32MainPrefix + sdk.PrefixValidator + sdk.PrefixConsensus
bech32PrefixConsPub = bech32MainPrefix + sdk.PrefixValidator + sdk.PrefixConsensus + sdk.PrefixPublic
)

cfg := sdk.GetConfig()
cfg.SetBech32PrefixForAccount(bech32PrefixAccAddr, bech32PrefixAccPub)
cfg.SetBech32PrefixForValidator(bech32PrefixValAddr, bech32PrefixValPub)
cfg.SetBech32PrefixForConsensusNode(bech32PrefixConsAddr, bech32PrefixConsPub)
return cfg
}
4 changes: 2 additions & 2 deletions chain/cosmos/cosmos_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ func (c *CosmosChain) Height(ctx context.Context) (uint64, error) {
// Acknowledgements implements ibc.Chain, returning all acknowledgments in block at height
func (c *CosmosChain) Acknowledgements(ctx context.Context, height uint64) ([]ibc.PacketAcknowledgement, error) {
var acks []*chanTypes.MsgAcknowledgement
err := rangeBlockMessages(ctx, c.cfg.EncodingConfig.InterfaceRegistry, c.getFullNode().Client, height, func(msg types.Msg) bool {
err := RangeBlockMessages(ctx, c.cfg.EncodingConfig.InterfaceRegistry, c.getFullNode().Client, height, func(msg types.Msg) bool {
found, ok := msg.(*chanTypes.MsgAcknowledgement)
if ok {
acks = append(acks, found)
Expand Down Expand Up @@ -1092,7 +1092,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) {
var timeouts []*chanTypes.MsgTimeout
err := rangeBlockMessages(ctx, c.cfg.EncodingConfig.InterfaceRegistry, c.getFullNode().Client, height, func(msg types.Msg) bool {
err := RangeBlockMessages(ctx, c.cfg.EncodingConfig.InterfaceRegistry, c.getFullNode().Client, height, func(msg types.Msg) bool {
found, ok := msg.(*chanTypes.MsgTimeout)
if ok {
timeouts = append(timeouts, found)
Expand Down
4 changes: 2 additions & 2 deletions chain/cosmos/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ type blockClient interface {
Block(ctx context.Context, height *int64) (*tmtypes.ResultBlock, error)
}

// rangeBlockMessages iterates through all a block's transactions and each transaction's messages yielding to f.
// 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 uint64, done func(sdk.Msg) bool) error {
h := int64(height)
block, err := client.Block(ctx, &h)
if err != nil {
Expand Down
10 changes: 9 additions & 1 deletion conformance/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,10 @@ func testPacketRelaySuccess(
req.NoError(err, "failed to get acknowledgement on destination chain")
req.NoError(dstAck.Validate(), "invalid acknowledgement on destination chain")

// Even though we poll for the ack, there may be timing issues where balances are not fully reconciled yet.
// So we have a small buffer here.
require.NoError(t, testutil.WaitForBlocks(ctx, 5, srcChain, dstChain))

// get ibc denom for dst denom on src chain
dstDenomTrace := transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom(channels[i].PortID, channels[i].ChannelID, dstDenom))
srcIbcDenom := dstDenomTrace.IBCDenom()
Expand Down Expand Up @@ -496,7 +500,7 @@ func testPacketRelayFail(

// Even though we poll for the timeout, there may be timing issues where balances are not fully reconciled yet.
// So we have a small buffer here.
require.NoError(t, testutil.WaitForBlocks(ctx, 2, srcChain, dstChain))
require.NoError(t, testutil.WaitForBlocks(ctx, 5, srcChain, dstChain))

// get ibc denom for src denom on dst chain
srcDenomTrace := transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom(channels[i].Counterparty.PortID, channels[i].Counterparty.ChannelID, srcDenom))
Expand Down Expand Up @@ -525,6 +529,10 @@ func testPacketRelayFail(
req.NoError(err, "failed to get timeout packet on destination chain")
req.NoError(timeout.Validate(), "invalid timeout packet on destination chain")

// Even though we poll for the timeout, there may be timing issues where balances are not fully reconciled yet.
// So we have a small buffer here.
require.NoError(t, testutil.WaitForBlocks(ctx, 5, srcChain, dstChain))

// get ibc denom for dst denom on src chain
dstDenomTrace := transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom(channels[i].PortID, channels[i].ChannelID, dstDenom))
srcIbcDenom := dstDenomTrace.IBCDenom()
Expand Down
3 changes: 3 additions & 0 deletions examples/cosmos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# More Examples

[State Sync](https://github.com/CosmosContracts/juno/blob/reece/add-state-sync-test/interchaintest/state_sync_test.go)
4 changes: 1 addition & 3 deletions examples/cosmos/chain_export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ import (
)

func TestJunoStateExport(t *testing.T) {
// SDK v45
CosmosChainStateExportTest(t, "juno", "v15.0.0")
// SDK v47
CosmosChainStateExportTest(t, "juno", "v16.0.0")
CosmosChainStateExportTest(t, "juno", "v17.0.0")
}

func CosmosChainStateExportTest(t *testing.T, name, version string) {
Expand Down
245 changes: 234 additions & 11 deletions examples/cosmos/chain_miscellaneous_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ package cosmos_test

import (
"context"
"fmt"
"testing"

"cosmossdk.io/math"

banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
Expand All @@ -16,10 +21,6 @@ func TestICTestMiscellaneous(t *testing.T) {
CosmosChainTestMiscellaneous(t, "juno", "v16.0.0")
}

const (
initialBalance = 100_000_000
)

func CosmosChainTestMiscellaneous(t *testing.T, name, version string) {
if testing.Short() {
t.Skip("skipping in short mode")
Expand All @@ -28,13 +29,25 @@ func CosmosChainTestMiscellaneous(t *testing.T, name, version string) {
numVals := 1
numFullNodes := 0

cosmos.SetSDKConfig("juno")

sdk47Genesis := []cosmos.GenesisKV{
cosmos.NewGenesisKV("app_state.gov.params.voting_period", "15s"),
cosmos.NewGenesisKV("app_state.gov.params.max_deposit_period", "10s"),
cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.denom", "ujuno"),
cosmos.NewGenesisKV("app_state.gov.params.min_deposit.0.amount", "1"),
}

cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{
{
Name: name,
ChainName: name,
Version: version,
ChainConfig: ibc.ChainConfig{
Denom: "ujuno",
Denom: "ujuno",
Bech32Prefix: "juno",
CoinType: "118",
ModifyGenesis: cosmos.ModifyGenesis(sdk47Genesis),
},
NumValidators: &numVals,
NumFullNodes: &numFullNodes,
Expand Down Expand Up @@ -62,13 +75,22 @@ func CosmosChainTestMiscellaneous(t *testing.T, name, version string) {
_ = ic.Close()
})

users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(initialBalance), chain, chain)

TokenFactory(ctx, t, chain, users)
BuildDependencies(ctx, t, chain)
users := interchaintest.GetAndFundTestUsers(t, ctx, "default", int64(10_000_000_000), chain, chain)

testBuildDependencies(ctx, t, chain)
testWalletKeys(ctx, t, chain)
testSendingTokens(ctx, t, chain, users)
testFindTxs(ctx, t, chain, users)
testPollForBalance(ctx, t, chain, users)
testRangeBlockMessages(ctx, t, chain, users)
testBroadcaster(ctx, t, chain, users)
testQueryCmd(ctx, t, chain)
testHasCommand(ctx, t, chain)
testTokenFactory(ctx, t, chain, users)
testAddingNode(ctx, t, chain)
}

func BuildDependencies(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain) {
func testBuildDependencies(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain) {
deps := chain.Validators[0].GetBuildInformation(ctx)

sdkVer := "v0.47.3"
Expand Down Expand Up @@ -106,7 +128,193 @@ func BuildDependencies(ctx context.Context, t *testing.T, chain *cosmos.CosmosCh
}
}

func TokenFactory(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users []ibc.Wallet) {
func testWalletKeys(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain) {
// create a general key
randKey := "randkey123"
err := chain.CreateKey(ctx, randKey)
require.NoError(t, err)

// verify key was created properly
_, err = chain.GetAddress(ctx, randKey)
require.NoError(t, err)

// recover a key
// juno1hj5fveer5cjtn4wd6wstzugjfdxzl0xps73ftl
keyName := "key-abc"
testMnemonic := "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"
wallet, err := chain.BuildWallet(ctx, keyName, testMnemonic)
require.NoError(t, err)

// verify
addr, err := chain.GetAddress(ctx, keyName)
require.NoError(t, err)
require.Equal(t, wallet.Address(), addr)

tn := chain.Validators[0]
a, err := tn.KeyBech32(ctx, "key-abc", "val")
require.NoError(t, err)
require.Equal(t, a, "junovaloper1hj5fveer5cjtn4wd6wstzugjfdxzl0xp0r8xsx")

a, err = tn.KeyBech32(ctx, "key-abc", "acc")
require.NoError(t, err)
require.Equal(t, a, wallet.FormattedAddress())

a, err = tn.AccountKeyBech32(ctx, "key-abc")
require.NoError(t, err)
require.Equal(t, a, wallet.FormattedAddress())
}

func testSendingTokens(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users []ibc.Wallet) {
_, err := chain.GetBalance(ctx, users[0].FormattedAddress(), chain.Config().Denom)
require.NoError(t, err)
b2, err := chain.GetBalance(ctx, users[1].FormattedAddress(), chain.Config().Denom)
require.NoError(t, err)

sendAmt := int64(1)
_, err = sendTokens(ctx, chain, users[0], users[1], "", sendAmt)
require.NoError(t, err)

b2New, err := chain.GetBalance(ctx, users[1].FormattedAddress(), chain.Config().Denom)
require.NoError(t, err)

require.Equal(t, b2.Add(math.NewInt(sendAmt)), b2New)
}

func testFindTxs(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users []ibc.Wallet) {
height, _ := chain.Height(ctx)

_, err := sendTokens(ctx, chain, users[0], users[1], "", 1)
require.NoError(t, err)

txs, err := chain.FindTxs(ctx, height+1)
require.NoError(t, err)
require.NotEmpty(t, txs)
require.Equal(t, txs[0].Events[0].Type, "coin_spent")
}

func testPollForBalance(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users []ibc.Wallet) {
bal2, err := chain.GetBalance(ctx, users[1].FormattedAddress(), chain.Config().Denom)
require.NoError(t, err)

amt := ibc.WalletAmount{
Address: users[1].FormattedAddress(),
Denom: chain.Config().Denom,
Amount: math.NewInt(1),
}

delta := uint64(3)

ch := make(chan error)
go func() {
new := amt
new.Amount = bal2.Add(math.NewInt(1))
ch <- cosmos.PollForBalance(ctx, chain, delta, new)
}()

err = chain.SendFunds(ctx, users[0].KeyName(), amt)
require.NoError(t, err)
require.NoError(t, <-ch)
}

func testRangeBlockMessages(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users []ibc.Wallet) {
height, _ := chain.Height(ctx)

_, err := sendTokens(ctx, chain, users[0], users[1], "", 1)
require.NoError(t, err)

var bankMsgs []*banktypes.MsgSend
err = cosmos.RangeBlockMessages(ctx, chain.Config().EncodingConfig.InterfaceRegistry, chain.Validators[0].Client, height+1, func(msg sdk.Msg) bool {
found, ok := msg.(*banktypes.MsgSend)
if ok {
bankMsgs = append(bankMsgs, found)
}
return false
})
require.NoError(t, err)
}

func testAddingNode(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain) {
// This should be tested last or else Txs will fail on the new full node.
nodesAmt := len(chain.Nodes())
chain.AddFullNodes(ctx, nil, 1)
require.Equal(t, nodesAmt+1, len(chain.Nodes()))
}

func testBroadcaster(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users []ibc.Wallet) {
from := users[0].FormattedAddress()
addr1 := "juno190g5j8aszqhvtg7cprmev8xcxs6csra7xnk3n3"
addr2 := "juno1a53udazy8ayufvy0s434pfwjcedzqv34q7p7vj"

c1 := sdk.NewCoins(sdk.NewCoin(chain.Config().Denom, math.NewInt(1)))
c2 := sdk.NewCoins(sdk.NewCoin(chain.Config().Denom, math.NewInt(2)))

b := cosmos.NewBroadcaster(t, chain)

in := banktypes.Input{
Address: from,
Coins: c1.Add(c2[0]),
}
out := []banktypes.Output{
{
Address: addr1,
Coins: c1,
},
{
Address: addr2,
Coins: c2,
},
}

txResp, err := cosmos.BroadcastTx(
ctx,
b,
users[0],
banktypes.NewMsgMultiSend(in, out),
)
require.NoError(t, err)
require.NotEmpty(t, txResp.TxHash)
fmt.Printf("txResp: %+v\n", txResp)

updatedBal1, err := chain.GetBalance(ctx, addr1, chain.Config().Denom)
require.NoError(t, err)
require.Equal(t, math.NewInt(1), updatedBal1)

updatedBal2, err := chain.GetBalance(ctx, addr2, chain.Config().Denom)
require.NoError(t, err)
require.Equal(t, math.NewInt(2), updatedBal2)
}

func testQueryCmd(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain) {
tn := chain.Validators[0]
stdout, stderr, err := tn.ExecQuery(ctx, "slashing", "params")
require.NoError(t, err)
require.NotEmpty(t, stdout)
require.Empty(t, stderr)
}

func testHasCommand(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain) {
tn := chain.Validators[0]
res := tn.HasCommand(ctx, "query")
require.True(t, res)

if tn.IsAboveSDK47(ctx) {
require.True(t, tn.HasCommand(ctx, "genesis"))
} else {
// 45 does not have this
require.False(t, tn.HasCommand(ctx, "genesis"))
}

require.True(t, tn.HasCommand(ctx, "tx", "ibc"))
require.True(t, tn.HasCommand(ctx, "q", "ibc"))
require.True(t, tn.HasCommand(ctx, "keys"))
require.True(t, tn.HasCommand(ctx, "help"))
require.True(t, tn.HasCommand(ctx, "tx", "bank", "send"))

require.False(t, tn.HasCommand(ctx, "tx", "bank", "send2notrealcmd"))
require.False(t, tn.HasCommand(ctx, "incorrectcmd"))
}

func testTokenFactory(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, users []ibc.Wallet) {
user := users[0]
user2 := users[1]

Expand Down Expand Up @@ -168,6 +376,21 @@ func TokenFactory(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain,

}

// helpers
func sendTokens(ctx context.Context, chain *cosmos.CosmosChain, from, to ibc.Wallet, token string, amount int64) (ibc.WalletAmount, error) {
if token == "" {
token = chain.Config().Denom
}

sendAmt := ibc.WalletAmount{
Address: to.FormattedAddress(),
Denom: token,
Amount: math.NewInt(amount),
}
err := chain.SendFunds(ctx, from.KeyName(), sendAmt)
return sendAmt, err
}

func validateBalance(ctx context.Context, t *testing.T, chain *cosmos.CosmosChain, user ibc.Wallet, tfDenom string, expected int64) {
balance, err := chain.GetBalance(ctx, user.FormattedAddress(), tfDenom)
require.NoError(t, err)
Expand Down
Loading

0 comments on commit 8caf914

Please sign in to comment.