Skip to content

Commit 581ca29

Browse files
authored
test: account/keeper tests for ICA (#420)
* test: adding tests for account type * tests: adding test for keeper & account * fix: updating channel closing capabilities * fix: updating to use test library instead of hardcoded values * fix: updating error handling for account * test: adding test for account string comparison * fix: updating marshal yaml
1 parent c149317 commit 581ca29

File tree

8 files changed

+135
-51
lines changed

8 files changed

+135
-51
lines changed

modules/apps/27-interchain-accounts/keeper/account.go

-13
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,3 @@ func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, accAddr sdk.AccAddres
5656
k.accountKeeper.SetAccount(ctx, interchainAccount)
5757
k.SetInterchainAccountAddress(ctx, portID, interchainAccount.Address)
5858
}
59-
60-
func (k Keeper) GetInterchainAccount(ctx sdk.Context, addr sdk.AccAddress) (types.InterchainAccount, error) {
61-
acc := k.accountKeeper.GetAccount(ctx, addr)
62-
if acc == nil {
63-
return types.InterchainAccount{}, sdkerrors.Wrap(types.ErrInterchainAccountNotFound, "there is no account")
64-
}
65-
66-
interchainAccount, ok := acc.(*types.InterchainAccount)
67-
if !ok {
68-
return types.InterchainAccount{}, sdkerrors.Wrap(types.ErrInterchainAccountNotFound, "account is not an interchain account")
69-
}
70-
return *interchainAccount, nil
71-
}

modules/apps/27-interchain-accounts/keeper/account_test.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ func (suite *KeeperTestSuite) TestInitInterchainAccount() {
1717
malleate func()
1818
expPass bool
1919
}{
20-
2120
{
2221
"success", func() {}, true,
2322
},
@@ -31,6 +30,11 @@ func (suite *KeeperTestSuite) TestInitInterchainAccount() {
3130
}, false,
3231
},
3332
*/
33+
{
34+
"fails to generate port-id", func() {
35+
owner = ""
36+
}, false,
37+
},
3438
{
3539
"MsgChanOpenInit fails - channel is already active", func() {
3640
portID, err := types.GeneratePortID(owner, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID)

modules/apps/27-interchain-accounts/keeper/handshake.go

-20
Original file line numberDiff line numberDiff line change
@@ -130,23 +130,3 @@ func (k Keeper) OnChanOpenConfirm(
130130
) error {
131131
return nil
132132
}
133-
134-
// May want to use these for re-opening a channel when it is closed
135-
//// OnChanCloseInit implements the IBCModule interface
136-
//func (am AppModule) OnChanCloseInit(
137-
// ctx sdk.Context,
138-
// portID,
139-
// channelID string,
140-
//) error {
141-
// // Disallow user-initiated channel closing for transfer channels
142-
// return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel")
143-
//}
144-
145-
//// OnChanCloseConfirm implements the IBCModule interface
146-
//func (am AppModule) OnChanCloseConfirm(
147-
// ctx sdk.Context,
148-
// portID,
149-
// channelID string,
150-
//) error {
151-
// return nil
152-
//}

modules/apps/27-interchain-accounts/keeper/keeper_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,20 @@ func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() {
129129
suite.Require().Empty(retrievedAddr)
130130
}
131131

132+
func (suite *KeeperTestSuite) TestIsActiveChannel() {
133+
suite.SetupTest() // reset
134+
path := NewICAPath(suite.chainA, suite.chainB)
135+
owner := TestOwnerAddress
136+
suite.coordinator.SetupConnections(path)
137+
138+
err := suite.SetupICAPath(path, owner)
139+
suite.Require().NoError(err)
140+
portID := path.EndpointA.ChannelConfig.PortID
141+
142+
isActive := suite.chainA.GetSimApp().ICAKeeper.IsActiveChannel(suite.chainA.GetContext(), portID)
143+
suite.Require().Equal(isActive, true)
144+
}
145+
132146
func (suite *KeeperTestSuite) TestSetInterchainAccountAddress() {
133147
expectedAddr, portID := "address", "port"
134148
suite.chainA.GetSimApp().ICAKeeper.SetInterchainAccountAddress(suite.chainA.GetContext(), portID, expectedAddr)

modules/apps/27-interchain-accounts/module.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,15 @@ func (am AppModule) OnChanCloseInit(
187187
channelID string,
188188
) error {
189189
// Disallow user-initiated channel closing for interchain account channels
190-
return nil
190+
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel")
191191
}
192192

193193
func (am AppModule) OnChanCloseConfirm(
194194
ctx sdk.Context,
195195
portID,
196196
channelID string,
197197
) error {
198-
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel")
198+
return nil
199199
}
200200

201201
func (am AppModule) OnRecvPacket(

modules/apps/27-interchain-accounts/types/account.go

+25-15
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
1111
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
1212
"github.com/tendermint/tendermint/crypto/tmhash"
13-
yaml "gopkg.in/yaml.v2"
13+
"gopkg.in/yaml.v2"
1414

1515
connectiontypes "github.com/cosmos/ibc-go/v2/modules/core/03-connection/types"
1616
)
@@ -66,40 +66,44 @@ func NewInterchainAccount(ba *authtypes.BaseAccount, accountOwner string) *Inter
6666
}
6767

6868
// SetPubKey - Implements AccountI
69-
func (InterchainAccount) SetPubKey(pubKey crypto.PubKey) error {
70-
return fmt.Errorf("not supported for interchain accounts")
69+
func (ia InterchainAccount) SetPubKey(pubKey crypto.PubKey) error {
70+
return sdkerrors.Wrap(ErrUnsupported, "cannot set public key for interchain account")
7171
}
7272

7373
// SetSequence - Implements AccountI
74-
func (InterchainAccount) SetSequence(seq uint64) error {
75-
return fmt.Errorf("not supported for interchain accounts")
74+
func (ia InterchainAccount) SetSequence(seq uint64) error {
75+
return sdkerrors.Wrap(ErrUnsupported, "cannot set sequence number for interchain account")
7676
}
7777

7878
func (ia InterchainAccount) Validate() error {
79+
if strings.TrimSpace(ia.AccountOwner) == "" {
80+
return sdkerrors.Wrap(ErrInvalidAccountAddress, "AccountOwner cannot be empty")
81+
}
82+
7983
return ia.BaseAccount.Validate()
8084
}
8185

82-
type ibcAccountPretty struct {
86+
type InterchainAccountPretty struct {
8387
Address sdk.AccAddress `json:"address" yaml:"address"`
8488
PubKey string `json:"public_key" yaml:"public_key"`
8589
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
8690
Sequence uint64 `json:"sequence" yaml:"sequence"`
87-
AccountOwner string `json:"address" yaml:"account_owner"`
91+
AccountOwner string `json:"account_owner" yaml:"account_owner"`
8892
}
8993

9094
func (ia InterchainAccount) String() string {
9195
out, _ := ia.MarshalYAML()
92-
return out.(string)
96+
return string(out)
9397
}
9498

95-
// MarshalYAML returns the YAML representation of a InterchainAccount.
96-
func (ia InterchainAccount) MarshalYAML() (interface{}, error) {
99+
// MarshalYAML returns the YAML representation of an InterchainAccount
100+
func (ia InterchainAccount) MarshalYAML() ([]byte, error) {
97101
accAddr, err := sdk.AccAddressFromBech32(ia.Address)
98102
if err != nil {
99103
return nil, err
100104
}
101105

102-
bs, err := yaml.Marshal(ibcAccountPretty{
106+
bz, err := yaml.Marshal(InterchainAccountPretty{
103107
Address: accAddr,
104108
PubKey: "",
105109
AccountNumber: ia.AccountNumber,
@@ -111,28 +115,34 @@ func (ia InterchainAccount) MarshalYAML() (interface{}, error) {
111115
return nil, err
112116
}
113117

114-
return string(bs), nil
118+
return bz, nil
115119
}
116120

117-
// MarshalJSON returns the JSON representation of a InterchainAccount.
121+
// MarshalJSON returns the JSON representation of an InterchainAccount.
118122
func (ia InterchainAccount) MarshalJSON() ([]byte, error) {
119123
accAddr, err := sdk.AccAddressFromBech32(ia.Address)
120124
if err != nil {
121125
return nil, err
122126
}
123127

124-
return json.Marshal(ibcAccountPretty{
128+
bz, err := json.Marshal(InterchainAccountPretty{
125129
Address: accAddr,
126130
PubKey: "",
127131
AccountNumber: ia.AccountNumber,
128132
Sequence: ia.Sequence,
129133
AccountOwner: ia.AccountOwner,
130134
})
135+
136+
if err != nil {
137+
return nil, err
138+
}
139+
140+
return bz, nil
131141
}
132142

133143
// UnmarshalJSON unmarshals raw JSON bytes into a ModuleAccount.
134144
func (ia *InterchainAccount) UnmarshalJSON(bz []byte) error {
135-
var alias ibcAccountPretty
145+
var alias InterchainAccountPretty
136146
if err := json.Unmarshal(bz, &alias); err != nil {
137147
return err
138148
}

modules/apps/27-interchain-accounts/types/account_test.go

+88
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package types_test
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"testing"
67

8+
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
79
sdk "github.com/cosmos/cosmos-sdk/types"
10+
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
811
"github.com/stretchr/testify/suite"
12+
"gopkg.in/yaml.v2"
913

1014
"github.com/cosmos/ibc-go/v2/modules/apps/27-interchain-accounts/types"
1115
ibctesting "github.com/cosmos/ibc-go/v2/testing"
@@ -117,3 +121,87 @@ func (suite *TypesTestSuite) TestGeneratePortID() {
117121
})
118122
}
119123
}
124+
125+
func (suite *TypesTestSuite) TestInterchainAccount() {
126+
pubkey := secp256k1.GenPrivKey().PubKey()
127+
addr := sdk.AccAddress(pubkey.Address())
128+
baseAcc := authtypes.NewBaseAccountWithAddress(addr)
129+
interchainAcc := types.NewInterchainAccount(baseAcc, TestOwnerAddress)
130+
131+
// should fail when trying to set the public key or sequence of an interchain account
132+
err := interchainAcc.SetPubKey(pubkey)
133+
suite.Require().Error(err)
134+
err = interchainAcc.SetSequence(1)
135+
suite.Require().Error(err)
136+
}
137+
138+
func (suite *TypesTestSuite) TestGenesisAccountValidate() {
139+
pubkey := secp256k1.GenPrivKey().PubKey()
140+
addr := sdk.AccAddress(pubkey.Address())
141+
baseAcc := authtypes.NewBaseAccountWithAddress(addr)
142+
pubkey = secp256k1.GenPrivKey().PubKey()
143+
ownerAddr := sdk.AccAddress(pubkey.Address())
144+
145+
testCases := []struct {
146+
name string
147+
acc authtypes.GenesisAccount
148+
expPass bool
149+
}{
150+
{
151+
"success",
152+
types.NewInterchainAccount(baseAcc, ownerAddr.String()),
153+
true,
154+
},
155+
{
156+
"interchain account with empty AccountOwner field",
157+
types.NewInterchainAccount(baseAcc, ""),
158+
false,
159+
},
160+
}
161+
162+
for _, tc := range testCases {
163+
err := tc.acc.Validate()
164+
165+
if tc.expPass {
166+
suite.Require().NoError(err)
167+
} else {
168+
suite.Require().Error(err)
169+
}
170+
}
171+
}
172+
173+
func (suite *TypesTestSuite) TestInterchainAccountMarshalYAML() {
174+
addr := suite.chainA.SenderAccount.GetAddress()
175+
ba := authtypes.NewBaseAccountWithAddress(addr)
176+
177+
interchainAcc := types.NewInterchainAccount(ba, suite.chainB.SenderAccount.GetAddress().String())
178+
bz, err := yaml.Marshal(types.InterchainAccountPretty{
179+
Address: addr,
180+
PubKey: "",
181+
AccountNumber: interchainAcc.AccountNumber,
182+
Sequence: interchainAcc.Sequence,
183+
AccountOwner: interchainAcc.AccountOwner,
184+
})
185+
suite.Require().NoError(err)
186+
187+
bz1, err := interchainAcc.MarshalYAML()
188+
suite.Require().Equal(string(bz), string(bz1))
189+
}
190+
191+
func (suite *TypesTestSuite) TestInterchainAccountJSON() {
192+
addr := suite.chainA.SenderAccount.GetAddress()
193+
ba := authtypes.NewBaseAccountWithAddress(addr)
194+
195+
interchainAcc := types.NewInterchainAccount(ba, suite.chainB.SenderAccount.GetAddress().String())
196+
197+
bz, err := json.Marshal(interchainAcc)
198+
suite.Require().NoError(err)
199+
200+
bz1, err := interchainAcc.MarshalJSON()
201+
suite.Require().NoError(err)
202+
suite.Require().Equal(string(bz), string(bz1))
203+
204+
var a types.InterchainAccount
205+
suite.Require().NoError(json.Unmarshal(bz, &a))
206+
suite.Require().Equal(a.String(), interchainAcc.String())
207+
}

modules/apps/27-interchain-accounts/types/errors.go

+1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ var (
1616
ErrActiveChannelNotFound = sdkerrors.Register(ModuleName, 10, "no active channel for this owner")
1717
ErrInvalidVersion = sdkerrors.Register(ModuleName, 11, "invalid interchain accounts version")
1818
ErrInvalidAccountAddress = sdkerrors.Register(ModuleName, 12, "invalid account address")
19+
ErrUnsupported = sdkerrors.Register(ModuleName, 13, "interchain account does not support this action")
1920
)

0 commit comments

Comments
 (0)