Skip to content

Commit

Permalink
fix: fix hooks and add tests (#719)
Browse files Browse the repository at this point in the history
* fix hooks and add tests

* lint

* refactor ica_tx.go.

* add tests to ibc, ica_tx..

* more tests for msg_server_test.go

* more tests for msg_server_test.go

* fix changelog

* more tests.
  • Loading branch information
puneet2019 authored Jan 11, 2024
1 parent 3166f38 commit d7b62b9
Show file tree
Hide file tree
Showing 7 changed files with 345 additions and 34 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ Ref: https://keepachangelog.com/en/1.0.0/

## Unreleased

### Bug Fixes

- [719](https://github.com/persistenceOne/pstake-native/pull/719) Fix afterEpoch hooks to take LiquidStake feature
instead of LiquidStakeIBC

## [v2.8.2] - 2024-01-09

### Bug Fixes
Expand All @@ -46,7 +51,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Bug Fixes

- [707](https://github.com/persistenceOne/pstake-native/pull/707) Fix liquidstakeibc redeem edge case for protecting cValue
- [707](https://github.com/persistenceOne/pstake-native/pull/707) Fix liquidstakeibc redeem edge case for protecting
cValue

## [v2.8.0] - 2023-12-20

Expand Down
2 changes: 1 addition & 1 deletion x/ratesync/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumb
for _, hc := range hcs {
if hc.Features.LiquidStake.Enabled && epochIdentifier == types.LiquidStakeEpoch {
// Add liquidstakekeeper and do stuff
err := k.ExecuteLiquidStakeRateTx(ctx, hc.Features.LiquidStakeIBC, liquidBondDenom, bondDenom, nas.MintRate, hc.ID, hc.ConnectionID, hc.ICAAccount)
err := k.ExecuteLiquidStakeRateTx(ctx, hc.Features.LiquidStake, liquidBondDenom, bondDenom, nas.MintRate, hc.ID, hc.ConnectionID, hc.ICAAccount)
if err != nil {
k.Logger(ctx).Error("cannot ExecuteLiquidStakeRateTx for host chain ",
"id", hc.ID,
Expand Down
34 changes: 34 additions & 0 deletions x/ratesync/keeper/hooks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package keeper_test

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

func (suite *IntegrationTestSuite) TestPostCValueUpdate() {
keeper, ctx := suite.app.RatesyncKeeper, suite.ctx
_ = createNChain(keeper, ctx, 10)
suite.Require().NoError(keeper.PostCValueUpdate(ctx, "uatom", "stk/uatom", sdk.OneDec()))
hc, _ := keeper.GetHostChain(ctx, 1)
hc.Features.LiquidStakeIBC.Enabled = true
hc.Features.LiquidStakeIBC.Denoms = []string{"*"}
keeper.SetHostChain(ctx, hc)
suite.Require().NoError(keeper.PostCValueUpdate(ctx, "uatom", "stk/uatom", sdk.OneDec()))

hc.ICAAccount.Address = "InvalidAddr" //outer functions do not return errors
keeper.SetHostChain(ctx, hc)
suite.Require().NoError(keeper.PostCValueUpdate(ctx, "uatom", "stk/uatom", sdk.OneDec()))

}

func (suite *IntegrationTestSuite) TestAfterEpochEnd() {
keeper, ctx := suite.app.RatesyncKeeper, suite.ctx
_ = createNChain(keeper, ctx, 10)
suite.Require().NoError(keeper.AfterEpochEnd(ctx, "hour", 1))
hc, _ := keeper.GetHostChain(ctx, 1)
hc.Features.LiquidStake.Enabled = true
hc.Features.LiquidStake.Denoms = []string{"*"}
keeper.SetHostChain(ctx, hc)
suite.Require().NoError(keeper.AfterEpochEnd(ctx, "hour", 1))

hc.ICAAccount.Address = "InvalidAddr" // outer functions do not return errors
keeper.SetHostChain(ctx, hc)
suite.Require().NoError(keeper.AfterEpochEnd(ctx, "hour", 1))
}
181 changes: 181 additions & 0 deletions x/ratesync/keeper/ibc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package keeper_test

import (
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/gogoproto/proto"
icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
"github.com/persistenceOne/pstake-native/v2/x/ratesync/keeper"
"github.com/persistenceOne/pstake-native/v2/x/ratesync/types"
)

func (suite *IntegrationTestSuite) TestOnChanOpenAck() {
k, ctx := suite.app.RatesyncKeeper, suite.ctx
_ = createNChain(k, ctx, 2)
hc, _ := k.GetHostChain(ctx, 1)
suite.Require().NoError(k.OnChanOpenAck(ctx, types.MustICAPortIDFromOwner(hc.ICAAccount.Owner),
suite.ratesyncPathAB.EndpointA.ChannelID, "", ""))
}

func (suite *IntegrationTestSuite) TestOnAcknowledgementPacket() {
k, ctx := suite.app.RatesyncKeeper, suite.ctx
_ = createNChain(k, ctx, 2)
hc, _ := k.GetHostChain(ctx, 1)
//case 1, instantiate msg.
{
msg, memo, err := keeper.GenerateInstantiateLiquidStakeContractMsg(hc.ICAAccount, hc.Features.LiquidStakeIBC, hc.ID)
suite.Require().NoError(err)
msgData, err := icatypes.SerializeCosmosTx(suite.app.AppCodec(), []proto.Message{msg})
suite.Require().NoError(err)
data := &icatypes.InterchainAccountPacketData{
Type: 0,
Data: msgData,
Memo: string(memo),
}
databz, err := suite.app.AppCodec().MarshalJSON(data)
suite.Require().NoError(err)
packet := channeltypes.Packet{
SourcePort: types.MustICAPortIDFromOwner(hc.ICAAccount.Owner),
Data: databz,
}
wasmResponse := &wasmtypes.MsgInstantiateContractResponse{
Address: authtypes.NewModuleAddress("Contract").String(),
Data: nil,
}

msgResult, _ := codectypes.NewAnyWithValue(wasmResponse)

result := &sdk.TxMsgData{MsgResponses: []*codectypes.Any{msgResult}}
resultbz, err := suite.app.AppCodec().Marshal(result)
suite.Require().NoError(err)
ack := channeltypes.NewResultAcknowledgement(resultbz)
ackbz, err := suite.app.AppCodec().MarshalJSON(&ack)
suite.Require().NoError(k.OnAcknowledgementPacket(ctx, packet,
ackbz, authtypes.NewModuleAddress("test")))
}
// case 2 instantiate failure
{
msg, memo, err := keeper.GenerateInstantiateLiquidStakeContractMsg(hc.ICAAccount, hc.Features.LiquidStakeIBC, hc.ID)
suite.Require().NoError(err)
msgData, err := icatypes.SerializeCosmosTx(suite.app.AppCodec(), []proto.Message{msg})
suite.Require().NoError(err)
data := &icatypes.InterchainAccountPacketData{
Type: 0,
Data: msgData,
Memo: string(memo),
}
databz, err := suite.app.AppCodec().MarshalJSON(data)
suite.Require().NoError(err)
packet := channeltypes.Packet{
SourcePort: types.MustICAPortIDFromOwner(hc.ICAAccount.Owner),
Data: databz,
}

ack := channeltypes.NewErrorAcknowledgement(types.ErrICATxFailure)
ackbz, err := suite.app.AppCodec().MarshalJSON(&ack)
suite.Require().NoError(k.OnAcknowledgementPacket(ctx, packet,
ackbz, authtypes.NewModuleAddress("test")))
}
//case 3, execute msg.
{
msg, memo, err := keeper.GenerateExecuteLiquidStakeRateTxMsg(ctx.BlockTime().Unix(), hc.Features.LiquidStake,
"stk/uatom", "uatom", sdk.OneDec(), hc.ID, hc.ICAAccount)
suite.Require().NoError(err)
msgData, err := icatypes.SerializeCosmosTx(suite.app.AppCodec(), []proto.Message{msg})
suite.Require().NoError(err)
data := &icatypes.InterchainAccountPacketData{
Type: 0,
Data: msgData,
Memo: string(memo),
}
databz, err := suite.app.AppCodec().MarshalJSON(data)
suite.Require().NoError(err)
packet := channeltypes.Packet{
SourcePort: types.MustICAPortIDFromOwner(hc.ICAAccount.Owner),
Data: databz,
}
wasmResponse := &wasmtypes.MsgExecuteContractResponse{Data: []byte{}}

msgResult, _ := codectypes.NewAnyWithValue(wasmResponse)

result := &sdk.TxMsgData{MsgResponses: []*codectypes.Any{msgResult}}
resultbz, err := suite.app.AppCodec().Marshal(result)
suite.Require().NoError(err)
ack := channeltypes.NewResultAcknowledgement(resultbz)
ackbz, err := suite.app.AppCodec().MarshalJSON(&ack)
suite.Require().NoError(k.OnAcknowledgementPacket(ctx, packet,
ackbz, authtypes.NewModuleAddress("test")))
}
// case 4 execute failure
{
msg, memo, err := keeper.GenerateExecuteLiquidStakeRateTxMsg(ctx.BlockTime().Unix(), hc.Features.LiquidStake,
"stk/uatom", "uatom", sdk.OneDec(), hc.ID, hc.ICAAccount)
suite.Require().NoError(err)
msgData, err := icatypes.SerializeCosmosTx(suite.app.AppCodec(), []proto.Message{msg})
suite.Require().NoError(err)
data := &icatypes.InterchainAccountPacketData{
Type: 0,
Data: msgData,
Memo: string(memo),
}
databz, err := suite.app.AppCodec().MarshalJSON(data)
suite.Require().NoError(err)
packet := channeltypes.Packet{
SourcePort: types.MustICAPortIDFromOwner(hc.ICAAccount.Owner),
Data: databz,
}

ack := channeltypes.NewErrorAcknowledgement(types.ErrICATxFailure)
ackbz, err := suite.app.AppCodec().MarshalJSON(&ack)
suite.Require().NoError(k.OnAcknowledgementPacket(ctx, packet,
ackbz, authtypes.NewModuleAddress("test")))
}
}

func (suite *IntegrationTestSuite) TestOnTimeoutPacket() {
k, ctx := suite.app.RatesyncKeeper, suite.ctx
_ = createNChain(k, ctx, 2)
hc, _ := k.GetHostChain(ctx, 1)
//case 1, instantiate msg.
{
msg, memo, err := keeper.GenerateInstantiateLiquidStakeContractMsg(hc.ICAAccount, hc.Features.LiquidStakeIBC, hc.ID)
suite.Require().NoError(err)
msgData, err := icatypes.SerializeCosmosTx(suite.app.AppCodec(), []proto.Message{msg})
suite.Require().NoError(err)
data := &icatypes.InterchainAccountPacketData{
Type: 0,
Data: msgData,
Memo: string(memo),
}
databz, err := suite.app.AppCodec().MarshalJSON(data)
suite.Require().NoError(err)
packet := channeltypes.Packet{
SourcePort: types.MustICAPortIDFromOwner(hc.ICAAccount.Owner),
Data: databz,
}
suite.Require().NoError(k.OnTimeoutPacket(ctx, packet, authtypes.NewModuleAddress("test")))
}
//case 2, execute msg.
{
msg, memo, err := keeper.GenerateExecuteLiquidStakeRateTxMsg(ctx.BlockTime().Unix(), hc.Features.LiquidStake,
"stk/uatom", "uatom", sdk.OneDec(), hc.ID, hc.ICAAccount)
suite.Require().NoError(err)
msgData, err := icatypes.SerializeCosmosTx(suite.app.AppCodec(), []proto.Message{msg})
suite.Require().NoError(err)
data := &icatypes.InterchainAccountPacketData{
Type: 0,
Data: msgData,
Memo: string(memo),
}
databz, err := suite.app.AppCodec().MarshalJSON(data)
suite.Require().NoError(err)
packet := channeltypes.Packet{
SourcePort: types.MustICAPortIDFromOwner(hc.ICAAccount.Owner),
Data: databz,
}
suite.Require().NoError(k.OnTimeoutPacket(ctx, packet, authtypes.NewModuleAddress("test")))
}
}
78 changes: 47 additions & 31 deletions x/ratesync/keeper/ica_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,32 +102,9 @@ func (k *Keeper) ExecuteLiquidStakeRateTx(ctx sdk.Context, feature types.LiquidS
mintDenom, hostDenom string, cValue sdk.Dec, hostchainId uint64,
connectionID string, icaAccount liquidstakeibctypes.ICAAccount) error {
if feature.AllowsDenom(mintDenom) {
contractMsg := types.ExecuteLiquidStakeRate{
LiquidStakeRate: types.LiquidStakeRate{
DefaultBondDenom: hostDenom,
StkDenom: mintDenom,
CValue: cValue,
ControllerChainTime: ctx.BlockTime().Unix(),
},
}
contractBz, err := json.Marshal(contractMsg)
if err != nil {
return err
}
msg := &wasmtypes.MsgExecuteContract{
Sender: icaAccount.Address,
Contract: feature.ContractAddress,
Msg: contractBz,
Funds: nil,
}
memo := types.ICAMemo{
FeatureType: feature.FeatureType,
HostChainID: hostchainId,
}
memoBz, err := json.Marshal(memo)
msg, memoBz, err := GenerateExecuteLiquidStakeRateTxMsg(ctx.BlockTime().Unix(), feature, mintDenom, hostDenom, cValue, hostchainId, icaAccount)
if err != nil {
return err

}
_, err = k.GenerateAndExecuteICATx(ctx, connectionID, icaAccount.Owner, []proto.Message{msg}, string(memoBz))
if err != nil {
Expand All @@ -137,15 +114,58 @@ func (k *Keeper) ExecuteLiquidStakeRateTx(ctx sdk.Context, feature types.LiquidS
return nil
}

func GenerateExecuteLiquidStakeRateTxMsg(blockTime int64, feature types.LiquidStake,
mintDenom, hostDenom string, cValue sdk.Dec, hostchainId uint64,
icaAccount liquidstakeibctypes.ICAAccount) (sdk.Msg, []byte, error) {
contractMsg := types.ExecuteLiquidStakeRate{
LiquidStakeRate: types.LiquidStakeRate{
DefaultBondDenom: hostDenom,
StkDenom: mintDenom,
CValue: cValue,
ControllerChainTime: blockTime,
},
}
contractBz, err := json.Marshal(contractMsg)
if err != nil {
return nil, nil, err
}
msg := &wasmtypes.MsgExecuteContract{
Sender: icaAccount.Address,
Contract: feature.ContractAddress,
Msg: contractBz,
Funds: nil,
}
memo := types.ICAMemo{
FeatureType: feature.FeatureType,
HostChainID: hostchainId,
}
memoBz, err := json.Marshal(memo)
if err != nil {
return nil, nil, err

}
return msg, memoBz, nil
}

func (k *Keeper) InstantiateLiquidStakeContract(ctx sdk.Context, icaAccount liquidstakeibctypes.ICAAccount,
feature types.LiquidStake, id uint64, connectionID string) error {
// generate contract msg{msg}
msg, memoBz, err := GenerateInstantiateLiquidStakeContractMsg(icaAccount, feature, id)
_, err = k.GenerateAndExecuteICATx(ctx, connectionID, icaAccount.Owner, []proto.Message{msg}, string(memoBz))
if err != nil {
return err
}
return nil
}

func GenerateInstantiateLiquidStakeContractMsg(icaAccount liquidstakeibctypes.ICAAccount,
feature types.LiquidStake, id uint64) (sdk.Msg, []byte, error) {
contractMsg := types.InstantiateLiquidStakeRateContract{
Admin: icaAccount.Address,
}
contractMsgBz, err := json.Marshal(contractMsg)
if err != nil {
return errorsmod.Wrapf(err, "unable to marshal InstantiateLiquidStakeRateContract")
return nil, nil, errorsmod.Wrapf(err, "unable to marshal InstantiateLiquidStakeRateContract")
}

msg := &wasmtypes.MsgInstantiateContract{
Expand All @@ -162,11 +182,7 @@ func (k *Keeper) InstantiateLiquidStakeContract(ctx sdk.Context, icaAccount liqu
}
memobz, err := json.Marshal(memo)
if err != nil {
return err
return nil, nil, err
}
_, err = k.GenerateAndExecuteICATx(ctx, connectionID, icaAccount.Owner, []proto.Message{msg}, string(memobz))
if err != nil {
return err
}
return nil
return msg, memobz, nil
}
15 changes: 15 additions & 0 deletions x/ratesync/keeper/ica_tx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package keeper_test

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

func (suite *IntegrationTestSuite) TestExecuteLiquidStakeRateTx() {
k, ctx := suite.app.RatesyncKeeper, suite.ctx
_ = createNChain(k, ctx, 2)
hc, _ := k.GetHostChain(ctx, 1)
suite.Require().NoError(k.ExecuteLiquidStakeRateTx(ctx, hc.Features.LiquidStakeIBC,
"stk/uatom", "uatom", sdk.OneDec(), hc.ID, suite.ratesyncPathAB.EndpointA.ConnectionID, hc.ICAAccount))
suite.Require().NoError(k.InstantiateLiquidStakeContract(ctx, hc.ICAAccount,
hc.Features.LiquidStake, hc.ID, suite.ratesyncPathAB.EndpointA.ConnectionID))
}
Loading

0 comments on commit d7b62b9

Please sign in to comment.