Skip to content

Commit

Permalink
Duplicate SimApp into callbacks directory (backport #4337) (#4461)
Browse files Browse the repository at this point in the history
* Duplicate SimApp into callbacks directory (#4337)

(cherry picked from commit 6610409)

# Conflicts:
#	modules/apps/callbacks/fee_transfer_test.go
#	modules/apps/callbacks/ica_test.go

* fix: fixed backport conflicts

* imp: removed unneeded functions from test_helpers.go

---------

Co-authored-by: Cian Hatton <[email protected]>
Co-authored-by: srdtrk <[email protected]>
  • Loading branch information
3 people authored Aug 25, 2023
1 parent b4766b0 commit 8b6fc4a
Show file tree
Hide file tree
Showing 17 changed files with 1,707 additions and 70 deletions.
61 changes: 45 additions & 16 deletions modules/apps/callbacks/callbacks_test.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,55 @@
package ibccallbacks_test

import (
"encoding/json"
"fmt"
"testing"

"github.com/stretchr/testify/suite"

sdkmath "cosmossdk.io/math"

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

dbm "github.com/cometbft/cometbft-db"
"github.com/cometbft/cometbft/libs/log"

icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"
icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"
feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types"
simapp "github.com/cosmos/ibc-go/v7/modules/apps/callbacks/testing/simapp"
"github.com/cosmos/ibc-go/v7/modules/apps/callbacks/types"
transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
ibctesting "github.com/cosmos/ibc-go/v7/testing"
ibcmock "github.com/cosmos/ibc-go/v7/testing/mock"
simapp "github.com/cosmos/ibc-go/v7/testing/simapp"
)

const maxCallbackGas = uint64(1000000)

func init() {
ibctesting.DefaultTestingAppInit = SetupTestingApp
}

// SetupTestingApp provides the duplicated simapp which is specific to the callbacks module on chain creation.
func SetupTestingApp() (ibctesting.TestingApp, map[string]json.RawMessage) {
db := dbm.NewMemDB()
encCdc := simapp.MakeTestEncodingConfig()
app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, simtestutil.EmptyAppOptions{})
return app, simapp.NewDefaultGenesisState(encCdc.Codec)
}

// GetSimApp returns the duplicated SimApp from within the callbacks directory.
// This must be used instead of chain.GetSimApp() for tests within this directory.
func GetSimApp(chain *ibctesting.TestChain) *simapp.SimApp {
app, ok := chain.App.(*simapp.SimApp)
if !ok {
panic("chain is not a simapp.SimApp")
}
return app
}

// CallbacksTestSuite defines the needed instances and methods to test callbacks
type CallbacksTestSuite struct {
suite.Suite
Expand All @@ -41,6 +68,10 @@ func (s *CallbacksTestSuite) setupChains() {
s.chainA = s.coordinator.GetChain(ibctesting.GetChainID(1))
s.chainB = s.coordinator.GetChain(ibctesting.GetChainID(2))
s.path = ibctesting.NewPath(s.chainA, s.chainB)

// override the SendMsgs function to not require a successful transaction
overrideSendMsg(s.chainA)
overrideSendMsg(s.chainB)
}

// SetupTransferTest sets up a transfer channel between chainA and chainB
Expand Down Expand Up @@ -105,7 +136,7 @@ func (s *CallbacksTestSuite) SetupICATest() string {
err = s.path.EndpointB.ChanOpenConfirm()
s.Require().NoError(err)

interchainAccountAddr, found := s.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(s.chainB.GetContext(), s.path.EndpointA.ConnectionID, s.path.EndpointA.ChannelConfig.PortID)
interchainAccountAddr, found := GetSimApp(s.chainB).ICAHostKeeper.GetInterchainAccountAddress(s.chainB.GetContext(), s.path.EndpointA.ConnectionID, s.path.EndpointA.ChannelConfig.PortID)
s.Require().True(found)

// fund the interchain account on chainB
Expand Down Expand Up @@ -146,8 +177,8 @@ func (s *CallbacksTestSuite) AssertHasExecutedExpectedCallback(callbackType type
expStatefulEntries = 1
}

sourceStatefulCounter := s.chainA.GetSimApp().MockContractKeeper.GetStateEntryCounter(s.chainA.GetContext())
destStatefulCounter := s.chainB.GetSimApp().MockContractKeeper.GetStateEntryCounter(s.chainB.GetContext())
sourceStatefulCounter := GetSimApp(s.chainA).MockContractKeeper.GetStateEntryCounter(s.chainA.GetContext())
destStatefulCounter := GetSimApp(s.chainB).MockContractKeeper.GetStateEntryCounter(s.chainB.GetContext())

switch callbackType {
case "none":
Expand Down Expand Up @@ -175,8 +206,8 @@ func (s *CallbacksTestSuite) AssertHasExecutedExpectedCallback(callbackType type
}

func (s *CallbacksTestSuite) AssertCallbackCounters(callbackType types.CallbackType) {
sourceCounters := s.chainA.GetSimApp().MockContractKeeper.Counters
destCounters := s.chainB.GetSimApp().MockContractKeeper.Counters
sourceCounters := GetSimApp(s.chainA).MockContractKeeper.Counters
destCounters := GetSimApp(s.chainB).MockContractKeeper.Counters

switch callbackType {
case "none":
Expand Down Expand Up @@ -232,13 +263,13 @@ func (s *CallbacksTestSuite) AssertHasExecutedExpectedCallbackWithFee(
// check forward relay balance
s.Require().Equal(
fee.RecvFee,
sdk.NewCoins(s.chainA.GetSimApp().BankKeeper.GetBalance(s.chainA.GetContext(), s.chainB.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom)),
sdk.NewCoins(GetSimApp(s.chainA).BankKeeper.GetBalance(s.chainA.GetContext(), s.chainB.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom)),
)

s.Require().Equal(
fee.AckFee.Add(fee.TimeoutFee...), // ack fee paid, timeout fee refunded
sdk.NewCoins(
s.chainA.GetSimApp().BankKeeper.GetBalance(
GetSimApp(s.chainA).BankKeeper.GetBalance(
s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(),
ibctesting.TestCoin.Denom),
).Sub(originalSenderBalance[0]),
Expand All @@ -247,14 +278,14 @@ func (s *CallbacksTestSuite) AssertHasExecutedExpectedCallbackWithFee(
// forward relay balance should be 0
s.Require().Equal(
sdk.NewCoin(ibctesting.TestCoin.Denom, sdkmath.ZeroInt()),
s.chainA.GetSimApp().BankKeeper.GetBalance(s.chainA.GetContext(), s.chainB.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom),
GetSimApp(s.chainA).BankKeeper.GetBalance(s.chainA.GetContext(), s.chainB.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom),
)

// all fees should be returned as sender is the reverse relayer
s.Require().Equal(
fee.Total(),
sdk.NewCoins(
s.chainA.GetSimApp().BankKeeper.GetBalance(
GetSimApp(s.chainA).BankKeeper.GetBalance(
s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(),
ibctesting.TestCoin.Denom),
).Sub(originalSenderBalance[0]),
Expand All @@ -263,23 +294,21 @@ func (s *CallbacksTestSuite) AssertHasExecutedExpectedCallbackWithFee(
s.AssertHasExecutedExpectedCallback(callbackType, isSuccessful)
}

// OverrideSendMsgWithAssertion overrides both chains' SendMsgsOverride function to assert whether the
// transaction is successful or not.
func OverrideSendMsgWithAssertion(chain *ibctesting.TestChain, expPass bool) {
// overrideSendMsg overrides both chains' SendMsgs function to a version that doesn't require
// that the transaction is successful.
func overrideSendMsg(chain *ibctesting.TestChain) {
chain.SendMsgsOverride = func(msgs ...sdk.Msg) (*sdk.Result, error) {
// ensure the chain has the latest time
chain.Coordinator.UpdateTimeForChain(chain)

_, r, err := simapp.SignAndDeliver(
chain.T,
chain.TxConfig,
chain.App.GetBaseApp(),
chain.GetContext().BlockHeader(),
msgs,
chain.ChainID,
[]uint64{chain.SenderAccount.GetAccountNumber()},
[]uint64{chain.SenderAccount.GetSequence()},
true, expPass, chain.SenderPrivKey,
chain.SenderPrivKey,
)
if err != nil {
return nil, err
Expand Down
16 changes: 6 additions & 10 deletions modules/apps/callbacks/fee_transfer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,8 @@ func (s *CallbacksTestSuite) TestIncentivizedTransferCallbacks() {
fee := feetypes.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee)

s.ExecutePayPacketFeeMsg(fee)
preRelaySenderBalance := sdk.NewCoins(s.chainA.GetSimApp().BankKeeper.GetBalance(s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom))

expSendFailure := !tc.expSuccess && (tc.expCallback == types.CallbackTypeSendPacket)
s.ExecuteTransfer(tc.transferMemo, expSendFailure)
preRelaySenderBalance := sdk.NewCoins(GetSimApp(s.chainA).BankKeeper.GetBalance(s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom))
s.ExecuteTransfer(tc.transferMemo)
// we manually subtract the transfer amount from the preRelaySenderBalance because ExecuteTransfer
// also relays the packet, which will trigger the fee payments.
preRelaySenderBalance = preRelaySenderBalance.Sub(ibctesting.TestCoin)
Expand Down Expand Up @@ -160,10 +158,8 @@ func (s *CallbacksTestSuite) TestIncentivizedTransferTimeoutCallbacks() {
fee := feetypes.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee)

s.ExecutePayPacketFeeMsg(fee)
preRelaySenderBalance := sdk.NewCoins(s.chainA.GetSimApp().BankKeeper.GetBalance(s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom))

expSendFailure := !tc.expSuccess && (tc.expCallback == types.CallbackTypeSendPacket)
s.ExecuteTransferTimeout(tc.transferMemo, expSendFailure)
preRelaySenderBalance := sdk.NewCoins(GetSimApp(s.chainA).BankKeeper.GetBalance(s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom))
s.ExecuteTransferTimeout(tc.transferMemo)

// after incentivizing the packets
s.AssertHasExecutedExpectedCallbackWithFee(tc.expCallback, tc.expSuccess, true, preRelaySenderBalance, fee)
Expand All @@ -178,13 +174,13 @@ func (s *CallbacksTestSuite) ExecutePayPacketFeeMsg(fee feetypes.Fee) {
)

// fetch the account balance before fees are escrowed and assert the difference below
preEscrowBalance := s.chainA.GetSimApp().BankKeeper.GetBalance(s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
preEscrowBalance := GetSimApp(s.chainA).BankKeeper.GetBalance(s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)

res, err := s.chainA.SendMsgs(msg)
s.Require().NoError(err)
s.Require().NotNil(res)

postEscrowBalance := s.chainA.GetSimApp().BankKeeper.GetBalance(s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
postEscrowBalance := GetSimApp(s.chainA).BankKeeper.GetBalance(s.chainA.GetContext(), s.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom)
s.Require().Equal(postEscrowBalance.AddAmount(fee.Total().AmountOf(sdk.DefaultBondDenom)), preEscrowBalance)

// register counterparty address on chainB
Expand Down
12 changes: 6 additions & 6 deletions modules/apps/callbacks/ibc_middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,8 @@ func (s *CallbacksTestSuite) TestOnAcknowledgementPacket() {
s.Require().ErrorIs(tc.expError, err)
}

sourceStatefulCounter := s.chainA.GetSimApp().MockContractKeeper.GetStateEntryCounter(s.chainA.GetContext())
sourceCounters := s.chainA.GetSimApp().MockContractKeeper.Counters
sourceStatefulCounter := GetSimApp(s.chainA).MockContractKeeper.GetStateEntryCounter(s.chainA.GetContext())
sourceCounters := GetSimApp(s.chainA).MockContractKeeper.Counters

switch tc.expResult {
case noExecution:
Expand Down Expand Up @@ -471,8 +471,8 @@ func (s *CallbacksTestSuite) TestOnTimeoutPacket() {
s.Require().ErrorIs(tc.expError, err)
}

sourceStatefulCounter := s.chainA.GetSimApp().MockContractKeeper.GetStateEntryCounter(s.chainA.GetContext())
sourceCounters := s.chainA.GetSimApp().MockContractKeeper.Counters
sourceStatefulCounter := GetSimApp(s.chainA).MockContractKeeper.GetStateEntryCounter(s.chainA.GetContext())
sourceCounters := GetSimApp(s.chainA).MockContractKeeper.Counters

// account for SendPacket succeeding
switch tc.expResult {
Expand Down Expand Up @@ -614,8 +614,8 @@ func (s *CallbacksTestSuite) TestOnRecvPacket() {
s.Require().Equal(tc.expAck, ack)
}

destStatefulCounter := s.chainB.GetSimApp().MockContractKeeper.GetStateEntryCounter(s.chainB.GetContext())
destCounters := s.chainB.GetSimApp().MockContractKeeper.Counters
destStatefulCounter := GetSimApp(s.chainB).MockContractKeeper.GetStateEntryCounter(s.chainB.GetContext())
destCounters := GetSimApp(s.chainB).MockContractKeeper.Counters

switch tc.expResult {
case noExecution:
Expand Down
24 changes: 6 additions & 18 deletions modules/apps/callbacks/ica_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ func (s *CallbacksTestSuite) TestICACallbacks() {
s.Run(tc.name, func() {
icaAddr := s.SetupICATest()

expSendFailure := !tc.expSuccess && (tc.expCallback == types.CallbackTypeSendPacket)
s.ExecuteICATx(icaAddr, tc.icaMemo, expSendFailure)
s.ExecuteICATx(icaAddr, tc.icaMemo)
s.AssertHasExecutedExpectedCallback(tc.expCallback, tc.expSuccess)
})
}
Expand Down Expand Up @@ -119,28 +118,22 @@ func (s *CallbacksTestSuite) TestICATimeoutCallbacks() {
s.Run(tc.name, func() {
icaAddr := s.SetupICATest()

expSendFailure := !tc.expSuccess && (tc.expCallback == types.CallbackTypeSendPacket)
s.ExecuteICATimeout(icaAddr, tc.icaMemo, expSendFailure)
s.ExecuteICATimeout(icaAddr, tc.icaMemo)
s.AssertHasExecutedExpectedCallback(tc.expCallback, tc.expSuccess)
})
}
}

// ExecuteICATx executes a stakingtypes.MsgDelegate on chainB by sending a packet containing the msg to chainB
func (s *CallbacksTestSuite) ExecuteICATx(icaAddress, memo string, expSendFailure bool) {
func (s *CallbacksTestSuite) ExecuteICATx(icaAddress, memo string) {
timeoutTimestamp := uint64(s.chainA.GetContext().BlockTime().Add(time.Minute).UnixNano())
icaOwner := s.chainA.SenderAccount.GetAddress().String()
connectionID := s.path.EndpointA.ConnectionID
// build the interchain accounts packet data
packetData := s.buildICAMsgDelegatePacketData(icaAddress, memo)
msg := icacontrollertypes.NewMsgSendTx(icaOwner, connectionID, timeoutTimestamp, packetData)

if expSendFailure {
OverrideSendMsgWithAssertion(s.chainA, false)
}

res, err := s.chainA.SendMsgs(msg)
s.chainA.SendMsgsOverride = nil // undo override
if err != nil {
return // we return if send packet is rejected
}
Expand All @@ -153,20 +146,15 @@ func (s *CallbacksTestSuite) ExecuteICATx(icaAddress, memo string, expSendFailur
}

// ExecuteICATx sends and times out an ICA tx
func (s *CallbacksTestSuite) ExecuteICATimeout(icaAddress, memo string, expSendFailure bool) {
func (s *CallbacksTestSuite) ExecuteICATimeout(icaAddress, memo string) {
relativeTimeout := uint64(1)
icaOwner := s.chainA.SenderAccount.GetAddress().String()
connectionID := s.path.EndpointA.ConnectionID
// build the interchain accounts packet data
packetData := s.buildICAMsgDelegatePacketData(icaAddress, memo)
msg := icacontrollertypes.NewMsgSendTx(icaOwner, connectionID, relativeTimeout, packetData)

if expSendFailure {
OverrideSendMsgWithAssertion(s.chainA, false)
}

res, err := s.chainA.SendMsgs(msg)
s.chainA.SendMsgsOverride = nil // undo override
if err != nil {
return // we return if send packet is rejected
}
Expand Down Expand Up @@ -194,9 +182,9 @@ func (s *CallbacksTestSuite) buildICAMsgDelegatePacketData(icaAddress string, me

// ensure chainB is allowed to execute stakingtypes.MsgDelegate
params := icahosttypes.NewParams(true, []string{sdk.MsgTypeURL(msgDelegate)})
s.chainB.GetSimApp().ICAHostKeeper.SetParams(s.chainB.GetContext(), params)
GetSimApp(s.chainB).ICAHostKeeper.SetParams(s.chainB.GetContext(), params)

data, err := icatypes.SerializeCosmosTx(s.chainA.GetSimApp().AppCodec(), []proto.Message{msgDelegate})
data, err := icatypes.SerializeCosmosTx(GetSimApp(s.chainA).AppCodec(), []proto.Message{msgDelegate})
s.Require().NoError(err)

icaPacketData := icatypes.InterchainAccountPacketData{
Expand Down
50 changes: 50 additions & 0 deletions modules/apps/callbacks/testing/simapp/ante_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package simapp

import (
errorsmod "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/ante"

ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante"
ibcerrors "github.com/cosmos/ibc-go/v7/modules/core/errors"
"github.com/cosmos/ibc-go/v7/modules/core/keeper"
)

// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC keeper.
type HandlerOptions struct {
ante.HandlerOptions

IBCKeeper *keeper.Keeper
}

// NewAnteHandler creates a new ante handler
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
if options.AccountKeeper == nil {
return nil, errorsmod.Wrap(ibcerrors.ErrLogic, "account keeper is required for AnteHandler")
}
if options.BankKeeper == nil {
return nil, errorsmod.Wrap(ibcerrors.ErrLogic, "bank keeper is required for AnteHandler")
}
if options.SignModeHandler == nil {
return nil, errorsmod.Wrap(ibcerrors.ErrLogic, "sign mode handler is required for AnteHandler")
}

anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
ante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
ante.NewValidateSigCountDecorator(options.AccountKeeper),
ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer),
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
ibcante.NewRedundantRelayDecorator(options.IBCKeeper),
}

return sdk.ChainAnteDecorators(anteDecorators...), nil
}
Loading

0 comments on commit 8b6fc4a

Please sign in to comment.