Skip to content

Commit

Permalink
IBC Testing Package v2 (#114)
Browse files Browse the repository at this point in the history
* create global time under coordinator

* fix test

* various fixes to testing package

* initial design work for testing package v2

* add channel support

* fix handshake endpoint functions, SetupNew now works

* fix build

* update simapp func

* add configs

* fix tests, remove unnecessary code

* fix tests

* add send, recv, ack funcs for endpoint, add lots of todos

* apply review comments

* update all light clients to use testing package v2

* refactor handle recv in msg server

* finish msg server tests

* ibc testing part 2 (#127)

* remove old testing code, update light client tests, update part of transfer tests

* fix transfer tests

* remove old code from testing package

* refactor 02-client tests

* refactor 03-connection

* all tests passing

* self review fixes

* ignore testing package for codecov

* Update modules/core/03-connection/keeper/verify_test.go

* IBC Testing Refactor Part 3 (#129)

* IBCKeeper reference into an interface function

* move to testing app interface wip

* add rest of interface functions, fix tests

* finish making testing app modular

* ibc testing refactor part 4 (#133)

* update README

* test modularity with transfer, update README, minor fixes
  • Loading branch information
colin-axner authored Apr 22, 2021
1 parent 3a61a65 commit db6f316
Show file tree
Hide file tree
Showing 55 changed files with 3,290 additions and 2,908 deletions.
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ ignore:
- "modules/**/**/**/*.pb.go"
- "modules/**/**/**/*.pb.gw.go"
- "modules/**/**/**/test_common.go"
- "testing/"
- "scripts/"
63 changes: 37 additions & 26 deletions modules/apps/transfer/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/cosmos/ibc-go/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/modules/core/04-channel/types"
"github.com/cosmos/ibc-go/modules/core/exported"
ibctesting "github.com/cosmos/ibc-go/testing"
)

Expand All @@ -31,90 +30,102 @@ func (suite *TransferTestSuite) SetupTest() {
suite.chainC = suite.coordinator.GetChain(ibctesting.GetChainID(2))
}

func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path {
path := ibctesting.NewPath(chainA, chainB)
path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort
path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort

return path
}

// constructs a send from chainA to chainB on the established channel/connection
// and sends the same coin back from chainB to chainA.
func (suite *TransferTestSuite) TestHandleMsgTransfer() {
// setup between chainA and chainB
clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
channelA, channelB := suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connA, connB, channeltypes.UNORDERED)
// originalBalance := suite.chainA.App.BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
path := NewTransferPath(suite.chainA, suite.chainB)
suite.coordinator.Setup(path)

// originalBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
timeoutHeight := clienttypes.NewHeight(0, 110)

coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))

// send from chainA to chainB
msg := types.NewMsgTransfer(channelA.PortID, channelA.ID, coinToSendToB, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0)
msg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coinToSendToB, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0)

err := suite.coordinator.SendMsg(suite.chainA, suite.chainB, clientB, msg)
_, err := suite.chainA.SendMsgs(msg)
suite.Require().NoError(err) // message committed

// relay send
fungibleTokenPacket := types.NewFungibleTokenPacketData(coinToSendToB.Denom, coinToSendToB.Amount.Uint64(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String())
packet := channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0)
packet := channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0)
ack := channeltypes.NewResultAcknowledgement([]byte{byte(1)})
err = suite.coordinator.RelayPacket(suite.chainA, suite.chainB, clientA, clientB, packet, ack.Acknowledgement())
err = path.RelayPacket(packet, ack.Acknowledgement())
suite.Require().NoError(err) // relay committed

// check that voucher exists on chain B
voucherDenomTrace := types.ParseDenomTrace(types.GetPrefixedDenom(packet.GetDestPort(), packet.GetDestChannel(), sdk.DefaultBondDenom))
balance := suite.chainB.App.BankKeeper.GetBalance(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), voucherDenomTrace.IBCDenom())
balance := suite.chainB.GetSimApp().BankKeeper.GetBalance(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), voucherDenomTrace.IBCDenom())

coinSentFromAToB := types.GetTransferCoin(channelB.PortID, channelB.ID, sdk.DefaultBondDenom, 100)
coinSentFromAToB := types.GetTransferCoin(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, sdk.DefaultBondDenom, 100)
suite.Require().Equal(coinSentFromAToB, balance)

// setup between chainB to chainC
clientOnBForC, clientOnCForB, connOnBForC, connOnCForB := suite.coordinator.SetupClientConnections(suite.chainB, suite.chainC, exported.Tendermint)
channelOnBForC, channelOnCForB := suite.coordinator.CreateTransferChannels(suite.chainB, suite.chainC, connOnBForC, connOnCForB, channeltypes.UNORDERED)
// NOTE:
// pathBtoC.EndpointA = endpoint on chainB
// pathBtoC.EndpointB = endpoint on chainC
pathBtoC := NewTransferPath(suite.chainB, suite.chainC)
suite.coordinator.Setup(pathBtoC)

// send from chainB to chainC
msg = types.NewMsgTransfer(channelOnBForC.PortID, channelOnBForC.ID, coinSentFromAToB, suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String(), timeoutHeight, 0)
msg = types.NewMsgTransfer(pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, coinSentFromAToB, suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String(), timeoutHeight, 0)

err = suite.coordinator.SendMsg(suite.chainB, suite.chainC, clientOnCForB, msg)
_, err = suite.chainB.SendMsgs(msg)
suite.Require().NoError(err) // message committed

// relay send
// NOTE: fungible token is prefixed with the full trace in order to verify the packet commitment
fullDenomPath := types.GetPrefixedDenom(channelOnCForB.PortID, channelOnCForB.ID, voucherDenomTrace.GetFullDenomPath())
fullDenomPath := types.GetPrefixedDenom(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, voucherDenomTrace.GetFullDenomPath())
fungibleTokenPacket = types.NewFungibleTokenPacketData(voucherDenomTrace.GetFullDenomPath(), coinSentFromAToB.Amount.Uint64(), suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String())
packet = channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, channelOnBForC.PortID, channelOnBForC.ID, channelOnCForB.PortID, channelOnCForB.ID, timeoutHeight, 0)
err = suite.coordinator.RelayPacket(suite.chainB, suite.chainC, clientOnBForC, clientOnCForB, packet, ack.Acknowledgement())
packet = channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, timeoutHeight, 0)
err = pathBtoC.RelayPacket(packet, ack.Acknowledgement())
suite.Require().NoError(err) // relay committed

coinSentFromBToC := sdk.NewInt64Coin(types.ParseDenomTrace(fullDenomPath).IBCDenom(), 100)
balance = suite.chainC.App.BankKeeper.GetBalance(suite.chainC.GetContext(), suite.chainC.SenderAccount.GetAddress(), coinSentFromBToC.Denom)
balance = suite.chainC.GetSimApp().BankKeeper.GetBalance(suite.chainC.GetContext(), suite.chainC.SenderAccount.GetAddress(), coinSentFromBToC.Denom)

// check that the balance is updated on chainC
suite.Require().Equal(coinSentFromBToC, balance)

// check that balance on chain B is empty
balance = suite.chainB.App.BankKeeper.GetBalance(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), coinSentFromBToC.Denom)
balance = suite.chainB.GetSimApp().BankKeeper.GetBalance(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), coinSentFromBToC.Denom)
suite.Require().Zero(balance.Amount.Int64())

// send from chainC back to chainB
msg = types.NewMsgTransfer(channelOnCForB.PortID, channelOnCForB.ID, coinSentFromBToC, suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0)
msg = types.NewMsgTransfer(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, coinSentFromBToC, suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0)

err = suite.coordinator.SendMsg(suite.chainC, suite.chainB, clientOnBForC, msg)
_, err = suite.chainC.SendMsgs(msg)
suite.Require().NoError(err) // message committed

// relay send
// NOTE: fungible token is prefixed with the full trace in order to verify the packet commitment
fungibleTokenPacket = types.NewFungibleTokenPacketData(fullDenomPath, coinSentFromBToC.Amount.Uint64(), suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String())
packet = channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, channelOnCForB.PortID, channelOnCForB.ID, channelOnBForC.PortID, channelOnBForC.ID, timeoutHeight, 0)
err = suite.coordinator.RelayPacket(suite.chainC, suite.chainB, clientOnCForB, clientOnBForC, packet, ack.Acknowledgement())
packet = channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, timeoutHeight, 0)
err = pathBtoC.RelayPacket(packet, ack.Acknowledgement())
suite.Require().NoError(err) // relay committed

balance = suite.chainB.App.BankKeeper.GetBalance(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), coinSentFromAToB.Denom)
balance = suite.chainB.GetSimApp().BankKeeper.GetBalance(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), coinSentFromAToB.Denom)

// check that the balance on chainA returned back to the original state
suite.Require().Equal(coinSentFromAToB, balance)

// check that module account escrow address is empty
escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel())
balance = suite.chainB.App.BankKeeper.GetBalance(suite.chainB.GetContext(), escrowAddress, sdk.DefaultBondDenom)
balance = suite.chainB.GetSimApp().BankKeeper.GetBalance(suite.chainB.GetContext(), escrowAddress, sdk.DefaultBondDenom)
suite.Require().Equal(sdk.NewCoin(sdk.DefaultBondDenom, sdk.ZeroInt()), balance)

// check that balance on chain B is empty
balance = suite.chainC.App.BankKeeper.GetBalance(suite.chainC.GetContext(), suite.chainC.SenderAccount.GetAddress(), voucherDenomTrace.IBCDenom())
balance = suite.chainC.GetSimApp().BankKeeper.GetBalance(suite.chainC.GetContext(), suite.chainC.SenderAccount.GetAddress(), voucherDenomTrace.IBCDenom())
suite.Require().Zero(balance.Amount.Int64())
}

Expand Down
6 changes: 3 additions & 3 deletions modules/apps/transfer/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ func (suite *KeeperTestSuite) TestGenesis() {
Path: path,
}
traces = append(types.Traces{denomTrace}, traces...)
suite.chainA.App.TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), denomTrace)
suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), denomTrace)
}

genesis := suite.chainA.App.TransferKeeper.ExportGenesis(suite.chainA.GetContext())
genesis := suite.chainA.GetSimApp().TransferKeeper.ExportGenesis(suite.chainA.GetContext())

suite.Require().Equal(types.PortID, genesis.PortId)
suite.Require().Equal(traces.Sort(), genesis.DenomTraces)

suite.Require().NotPanics(func() {
suite.chainA.App.TransferKeeper.InitGenesis(suite.chainA.GetContext(), *genesis)
suite.chainA.GetSimApp().TransferKeeper.InitGenesis(suite.chainA.GetContext(), *genesis)
})
}
4 changes: 2 additions & 2 deletions modules/apps/transfer/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (suite *KeeperTestSuite) TestQueryDenomTrace() {
func() {
expTrace.Path = "transfer/channelToA/transfer/channelToB"
expTrace.BaseDenom = "uatom"
suite.chainA.App.TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), expTrace)
suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), expTrace)

req = &types.QueryDenomTraceRequest{
Hash: expTrace.Hash().String(),
Expand Down Expand Up @@ -100,7 +100,7 @@ func (suite *KeeperTestSuite) TestQueryDenomTraces() {
expTraces = append(expTraces, types.DenomTrace{Path: "transfer/channelToA/transfer/channelToB", BaseDenom: "uatom"})

for _, trace := range expTraces {
suite.chainA.App.TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), trace)
suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), trace)
}

req = &types.QueryDenomTracesRequest{
Expand Down
14 changes: 11 additions & 3 deletions modules/apps/transfer/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,23 @@ func (suite *KeeperTestSuite) SetupTest() {
suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1))
suite.chainC = suite.coordinator.GetChain(ibctesting.GetChainID(2))

queryHelper := baseapp.NewQueryServerTestHelper(suite.chainA.GetContext(), suite.chainA.App.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, suite.chainA.App.TransferKeeper)
queryHelper := baseapp.NewQueryServerTestHelper(suite.chainA.GetContext(), suite.chainA.GetSimApp().InterfaceRegistry())
types.RegisterQueryServer(queryHelper, suite.chainA.GetSimApp().TransferKeeper)
suite.queryClient = types.NewQueryClient(queryHelper)
}

func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path {
path := ibctesting.NewPath(chainA, chainB)
path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort
path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort

return path
}

func (suite *KeeperTestSuite) TestGetTransferAccount() {
expectedMaccAddr := sdk.AccAddress(crypto.AddressHash([]byte(types.ModuleName)))

macc := suite.chainA.App.TransferKeeper.GetTransferAccount(suite.chainA.GetContext())
macc := suite.chainA.GetSimApp().TransferKeeper.GetTransferAccount(suite.chainA.GetContext())

suite.Require().NotNil(macc)
suite.Require().Equal(types.ModuleName, macc.GetName())
Expand Down
27 changes: 13 additions & 14 deletions modules/apps/transfer/keeper/mbt_relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"github.com/cosmos/ibc-go/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/modules/core/04-channel/types"
"github.com/cosmos/ibc-go/modules/core/exported"
ibctesting "github.com/cosmos/ibc-go/testing"
)

Expand Down Expand Up @@ -251,10 +250,10 @@ func (bank *Bank) NonZeroString() string {
// Construct a bank out of the chain bank
func BankOfChain(chain *ibctesting.TestChain) Bank {
bank := MakeBank()
chain.App.BankKeeper.IterateAllBalances(chain.GetContext(), func(address sdk.AccAddress, coin sdk.Coin) (stop bool) {
chain.GetSimApp().BankKeeper.IterateAllBalances(chain.GetContext(), func(address sdk.AccAddress, coin sdk.Coin) (stop bool) {
fullDenom := coin.Denom
if strings.HasPrefix(coin.Denom, "ibc/") {
fullDenom, _ = chain.App.TransferKeeper.DenomPathFromHash(chain.GetContext(), coin.Denom)
fullDenom, _ = chain.GetSimApp().TransferKeeper.DenomPathFromHash(chain.GetContext(), coin.Denom)
}
bank.SetBalance(address.String(), fullDenom, coin.Amount)
return false
Expand Down Expand Up @@ -295,18 +294,18 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() {
}

suite.SetupTest()
_, _, connAB, connBA := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
_, _, connBC, connCB := suite.coordinator.SetupClientConnections(suite.chainB, suite.chainC, exported.Tendermint)
suite.coordinator.CreateTransferChannels(suite.chainA, suite.chainB, connAB, connBA, channeltypes.UNORDERED)
suite.coordinator.CreateTransferChannels(suite.chainB, suite.chainC, connBC, connCB, channeltypes.UNORDERED)
pathAtoB := NewTransferPath(suite.chainA, suite.chainB)
pathBtoC := NewTransferPath(suite.chainB, suite.chainC)
suite.coordinator.Setup(pathAtoB)
suite.coordinator.Setup(pathBtoC)

for i, tlaTc := range tlaTestCases {
tc := OnRecvPacketTestCaseFromTla(tlaTc)
registerDenom := func() {
denomTrace := types.ParseDenomTrace(tc.packet.Data.Denom)
traceHash := denomTrace.Hash()
if !suite.chainB.App.TransferKeeper.HasDenomTrace(suite.chainB.GetContext(), traceHash) {
suite.chainB.App.TransferKeeper.SetDenomTrace(suite.chainB.GetContext(), denomTrace)
if !suite.chainB.GetSimApp().TransferKeeper.HasDenomTrace(suite.chainB.GetContext(), traceHash) {
suite.chainB.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainB.GetContext(), denomTrace)
}
}

Expand Down Expand Up @@ -334,7 +333,7 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() {
denom := denomTrace.IBCDenom()
err = sdk.ValidateDenom(denom)
if err == nil {
err = suite.chainB.App.TransferKeeper.SendTransfer(
err = suite.chainB.GetSimApp().TransferKeeper.SendTransfer(
suite.chainB.GetContext(),
tc.packet.SourcePort,
tc.packet.SourceChannel,
Expand All @@ -345,17 +344,17 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() {
0)
}
case "OnRecvPacket":
err = suite.chainB.App.TransferKeeper.OnRecvPacket(suite.chainB.GetContext(), packet, tc.packet.Data)
err = suite.chainB.GetSimApp().TransferKeeper.OnRecvPacket(suite.chainB.GetContext(), packet, tc.packet.Data)
case "OnTimeoutPacket":
registerDenom()
err = suite.chainB.App.TransferKeeper.OnTimeoutPacket(suite.chainB.GetContext(), packet, tc.packet.Data)
err = suite.chainB.GetSimApp().TransferKeeper.OnTimeoutPacket(suite.chainB.GetContext(), packet, tc.packet.Data)
case "OnRecvAcknowledgementResult":
err = suite.chainB.App.TransferKeeper.OnAcknowledgementPacket(
err = suite.chainB.GetSimApp().TransferKeeper.OnAcknowledgementPacket(
suite.chainB.GetContext(), packet, tc.packet.Data,
channeltypes.NewResultAcknowledgement(nil))
case "OnRecvAcknowledgementError":
registerDenom()
err = suite.chainB.App.TransferKeeper.OnAcknowledgementPacket(
err = suite.chainB.GetSimApp().TransferKeeper.OnAcknowledgementPacket(
suite.chainB.GetContext(), packet, tc.packet.Data,
channeltypes.NewErrorAcknowledgement("MBT Error Acknowledgement"))
default:
Expand Down
6 changes: 3 additions & 3 deletions modules/apps/transfer/keeper/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import "github.com/cosmos/ibc-go/modules/apps/transfer/types"
func (suite *KeeperTestSuite) TestParams() {
expParams := types.DefaultParams()

params := suite.chainA.App.TransferKeeper.GetParams(suite.chainA.GetContext())
params := suite.chainA.GetSimApp().TransferKeeper.GetParams(suite.chainA.GetContext())
suite.Require().Equal(expParams, params)

expParams.SendEnabled = false
suite.chainA.App.TransferKeeper.SetParams(suite.chainA.GetContext(), expParams)
params = suite.chainA.App.TransferKeeper.GetParams(suite.chainA.GetContext())
suite.chainA.GetSimApp().TransferKeeper.SetParams(suite.chainA.GetContext(), expParams)
params = suite.chainA.GetSimApp().TransferKeeper.GetParams(suite.chainA.GetContext())
suite.Require().Equal(expParams, params)
}
Loading

0 comments on commit db6f316

Please sign in to comment.