Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reward converter - add trade route ID to portId #1011

Merged
merged 7 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/apptesting/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,10 @@ func (s *AppTestHelper) CreateICAChannel(owner string) (channelID, portID string
_, transferChannelExists := s.App.IBCKeeper.ChannelKeeper.GetChannel(s.Ctx, ibctesting.TransferPort, ibctesting.FirstChannelID)
if !transferChannelExists {
ownerSplit := strings.Split(owner, ".")
s.Require().Equal(2, len(ownerSplit), "owner should be of the form: {HostZone}.{AccountName}")
isHostZoneICA := len(ownerSplit) == 2
isTradeRouteICA := len(ownerSplit) == 3
s.Require().True(isHostZoneICA || isTradeRouteICA,
"owner should be either of the form: {chainId}.{AccountName} or {chainId}.{rewarDenom}-{hostDenom}.{accountName}")
ethan-stride marked this conversation as resolved.
Show resolved Hide resolved

hostChainID := ownerSplit[0]
s.CreateTransferChannel(hostChainID)
Expand Down
61 changes: 33 additions & 28 deletions x/stakeibc/keeper/ibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,32 +57,32 @@ func (k Keeper) StoreHostZoneIcaAddress(ctx sdk.Context, chainId, portId, addres
}

// expected port IDs for each ICA account type
delegationOwner := types.FormatICAAccountOwner(chainId, types.ICAAccountType_DELEGATION)
delegationOwner := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_DELEGATION)
delegationPortID, err := icatypes.NewControllerPortID(delegationOwner)
if err != nil {
return err
}
withdrawalOwner := types.FormatICAAccountOwner(chainId, types.ICAAccountType_WITHDRAWAL)
withdrawalOwner := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_WITHDRAWAL)
withdrawalPortID, err := icatypes.NewControllerPortID(withdrawalOwner)
if err != nil {
return err
}
feeOwner := types.FormatICAAccountOwner(chainId, types.ICAAccountType_FEE)
feeOwner := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_FEE)
feePortID, err := icatypes.NewControllerPortID(feeOwner)
if err != nil {
return err
}
redemptionOwner := types.FormatICAAccountOwner(chainId, types.ICAAccountType_REDEMPTION)
redemptionOwner := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_REDEMPTION)
redemptionPortID, err := icatypes.NewControllerPortID(redemptionOwner)
if err != nil {
return err
}
communityPoolDepositOwner := types.FormatICAAccountOwner(chainId, types.ICAAccountType_COMMUNITY_POOL_DEPOSIT)
communityPoolDepositOwner := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_COMMUNITY_POOL_DEPOSIT)
communityPoolDepositPortID, err := icatypes.NewControllerPortID(communityPoolDepositOwner)
if err != nil {
return err
}
communityPoolReturnOwner := types.FormatICAAccountOwner(chainId, types.ICAAccountType_COMMUNITY_POOL_RETURN)
communityPoolReturnOwner := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_COMMUNITY_POOL_RETURN)
communityPoolReturnPortID, err := icatypes.NewControllerPortID(communityPoolReturnOwner)
if err != nil {
return err
Expand Down Expand Up @@ -155,34 +155,39 @@ func (k Keeper) StoreHostZoneIcaAddress(ctx sdk.Context, chainId, portId, addres

// Checks if the port matches an ICA account on the trade route, and if so, stores the
// relevant ICA address on the trade route
func (k Keeper) StoreTradeRouteIcaAddress(ctx sdk.Context, chainId, portId, address string) error {
// Get the expected port Id for each ICA account type (using the chainId)
tradeOwner := types.FormatICAAccountOwner(chainId, types.ICAAccountType_CONVERTER_TRADE)
tradePortID, err := icatypes.NewControllerPortID(tradeOwner)
if err != nil {
return err
}
unwindOwner := types.FormatICAAccountOwner(chainId, types.ICAAccountType_CONVERTER_UNWIND)
unwindPortID, err := icatypes.NewControllerPortID(unwindOwner)
if err != nil {
return err
}

func (k Keeper) StoreTradeRouteIcaAddress(ctx sdk.Context, callbackChainId, callbackPortId, address string) error {
// Check if the port Id matches either the trade or unwind ICA on the tradeRoute
// If the chainId and port Id from the callback match the account
// on a trade route, set the ICA address in the relevant places,
// including the from/to addresses on each hop
for _, tradeRoute := range k.GetAllTradeRoutes(ctx) {
if tradeRoute.RewardAccount.ChainId == chainId && portId == unwindPortID {
k.Logger(ctx).Info(fmt.Sprintf("ICA Address %s found for Unwind ICA on %s", address, tradeRoute.Description()))
tradeRoute.RewardAccount.Address = address

} else if tradeRoute.TradeAccount.ChainId == chainId && portId == tradePortID {
k.Logger(ctx).Info(fmt.Sprintf("ICA Address %s found for Trade ICA on %s", address, tradeRoute.Description()))
tradeRoute.TradeAccount.Address = address
for _, route := range k.GetAllTradeRoutes(ctx) {
// Build the expected port ID for the reward and trade accounts,
// using the chainId and route ID
rewardAccount := route.RewardAccount
rewardOwner := types.FormatTradeRouteICAOwnerFromRouteId(rewardAccount.ChainId, route.GetRouteId(), rewardAccount.Type)
rewardPortId, err := icatypes.NewControllerPortID(rewardOwner)
if err != nil {
return err
}

tradeAccount := route.TradeAccount
tradeOwner := types.FormatTradeRouteICAOwnerFromRouteId(tradeAccount.ChainId, route.GetRouteId(), tradeAccount.Type)
tradePortId, err := icatypes.NewControllerPortID(tradeOwner)
if err != nil {
return err
}

// Check if route IDs match the callback chainId/portId
if route.RewardAccount.ChainId == callbackChainId && callbackPortId == rewardPortId {
k.Logger(ctx).Info(fmt.Sprintf("ICA Address %s found for Unwind ICA on %s", address, route.Description()))
route.RewardAccount.Address = address

} else if route.TradeAccount.ChainId == callbackChainId && callbackPortId == tradePortId {
k.Logger(ctx).Info(fmt.Sprintf("ICA Address %s found for Trade ICA on %s", address, route.Description()))
route.TradeAccount.Address = address
}

k.SetTradeRoute(ctx, tradeRoute)
k.SetTradeRoute(ctx, route)
}

return nil
Expand Down
13 changes: 8 additions & 5 deletions x/stakeibc/keeper/ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ func (s *KeeperTestSuite) TestOnChanOpenAck() {
HostDenomOnHostZone: HostDenom,
TradeAccount: types.ICAAccount{
ChainId: tradeChainId,
Type: types.ICAAccountType_CONVERTER_TRADE,
},
})

// Create the ICA channels for both the delegation and trade accounts
delegationOwner := types.FormatICAAccountOwner(delegationChainId, types.ICAAccountType_DELEGATION)
delegationOwner := types.FormatHostZoneICAOwner(delegationChainId, types.ICAAccountType_DELEGATION)
delegationPortId, _ := icatypes.NewControllerPortID(delegationOwner)

tradeOwner := types.FormatICAAccountOwner(tradeChainId, types.ICAAccountType_CONVERTER_TRADE)
tradeOwner := types.FormatTradeRouteICAOwner(tradeChainId, RewardDenom, HostDenom, types.ICAAccountType_CONVERTER_TRADE)
tradePortId, _ := icatypes.NewControllerPortID(tradeOwner)

// Mock out an ICA address for each
Expand Down Expand Up @@ -188,7 +189,7 @@ func (s *KeeperTestSuite) TestStoreHostZoneIcaAddress() {
// If the portId is -1, pass a non-ica port
portId := "not-ica-port"
if accountType != -1 {
owner := types.FormatICAAccountOwner(HostChainId, accountType)
owner := types.FormatHostZoneICAOwner(HostChainId, accountType)
portId, _ = icatypes.NewControllerPortID(owner)
}

Expand Down Expand Up @@ -247,9 +248,11 @@ func (s *KeeperTestSuite) TestStoreTradeRouteIcaAddress() {
HostDenomOnHostZone: HostDenom,
RewardAccount: types.ICAAccount{
ChainId: HostChainId,
Type: types.ICAAccountType_CONVERTER_UNWIND,
},
TradeAccount: types.ICAAccount{
ChainId: HostChainId,
Type: types.ICAAccountType_CONVERTER_TRADE,
},
}

Expand All @@ -261,7 +264,7 @@ func (s *KeeperTestSuite) TestStoreTradeRouteIcaAddress() {
// If the portId is -1, pass a non-ica port
portId := "not-ica-port"
if accountType != -1 {
owner := types.FormatICAAccountOwner(HostChainId, accountType)
owner := types.FormatTradeRouteICAOwner(HostChainId, RewardDenom, HostDenom, accountType)
portId, _ = icatypes.NewControllerPortID(owner)
}

Expand All @@ -277,7 +280,7 @@ func (s *KeeperTestSuite) TestStoreTradeRouteIcaAddress() {

// Check with a matching port, but no matching chainId
accountType := types.ICAAccountType_CONVERTER_TRADE
owner := types.FormatICAAccountOwner(HostChainId, accountType)
owner := types.FormatTradeRouteICAOwner(HostChainId, RewardDenom, HostDenom, accountType)
portId, _ := icatypes.NewControllerPortID(owner)
address := accountType.String()

Expand Down
2 changes: 1 addition & 1 deletion x/stakeibc/keeper/lsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ func (k Keeper) DetokenizeAllLSMDeposits(ctx sdk.Context) {
// Submit detokenization ICAs for each active host zone
for _, hostZone := range k.GetAllActiveHostZone(ctx) {
// Get the host zone's delegation ICA portID
delegationICAOwner := types.FormatICAAccountOwner(hostZone.ChainId, types.ICAAccountType_DELEGATION)
delegationICAOwner := types.FormatHostZoneICAOwner(hostZone.ChainId, types.ICAAccountType_DELEGATION)
delegationICAPortID, err := icatypes.NewControllerPortID(delegationICAOwner)
if err != nil {
k.Logger(ctx).Error(fmt.Sprintf("Unable to get delegation port ID for %s: %s", hostZone.ChainId, err))
Expand Down
4 changes: 2 additions & 2 deletions x/stakeibc/keeper/lsm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ func (s *KeeperTestSuite) TestTransferAllLSMDeposits() {

func (s *KeeperTestSuite) TestDetokenizeLSMDeposit() {
// Create the delegation ICA
owner := types.FormatICAAccountOwner(HostChainId, types.ICAAccountType_DELEGATION)
owner := types.FormatHostZoneICAOwner(HostChainId, types.ICAAccountType_DELEGATION)
s.CreateICAChannel(owner)
portId, err := icatypes.NewControllerPortID(owner)
s.Require().NoError(err, "no error expected when formatting portId")
Expand Down Expand Up @@ -649,7 +649,7 @@ func (s *KeeperTestSuite) TestDetokenizeLSMDeposit() {

func (s *KeeperTestSuite) TestDetokenizeAllLSMDeposits() {
// Create an open delegation ICA channel
owner := types.FormatICAAccountOwner(HostChainId, types.ICAAccountType_DELEGATION)
owner := types.FormatHostZoneICAOwner(HostChainId, types.ICAAccountType_DELEGATION)
s.CreateICAChannel(owner)
portId, err := icatypes.NewControllerPortID(owner)
s.Require().NoError(err, "no error expected when formatting portId")
Expand Down
14 changes: 11 additions & 3 deletions x/stakeibc/keeper/msg_server_create_trade_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,24 @@ func (ms msgServer) CreateTradeRoute(goCtx context.Context, msg *types.MsgCreate
}

// Register the new ICA accounts
tradeRouteId := types.GetTradeRouteId(msg.RewardDenomOnReward, msg.HostDenomOnHost)
hostICA := types.ICAAccount{
ChainId: msg.HostChainId,
Type: types.ICAAccountType_WITHDRAWAL,
ConnectionId: hostZone.ConnectionId,
Address: hostZone.WithdrawalIcaAddress,
}
unwindICA, err := ms.Keeper.RegisterTradeRouteICAAccount(ctx, msg.StrideToRewardConnectionId, types.ICAAccountType_CONVERTER_UNWIND)

unwindConnectionId := msg.StrideToRewardConnectionId
unwindICAType := types.ICAAccountType_CONVERTER_UNWIND
unwindICA, err := ms.Keeper.RegisterTradeRouteICAAccount(ctx, tradeRouteId, unwindConnectionId, unwindICAType)
if err != nil {
return nil, errorsmod.Wrapf(err, "unable to register the unwind ICA account")
}
tradeICA, err := ms.Keeper.RegisterTradeRouteICAAccount(ctx, msg.StrideToTradeConnectionId, types.ICAAccountType_CONVERTER_TRADE)

tradeConnectionId := msg.StrideToTradeConnectionId
tradeICAType := types.ICAAccountType_CONVERTER_TRADE
tradeICA, err := ms.Keeper.RegisterTradeRouteICAAccount(ctx, tradeRouteId, tradeConnectionId, tradeICAType)
if err != nil {
return nil, errorsmod.Wrapf(err, "unable to register the trade ICA account")
}
Expand Down Expand Up @@ -143,6 +150,7 @@ func (ms msgServer) CreateTradeRoute(goCtx context.Context, msg *types.MsgCreate
// Stores down the connection and chainId now, and the address upon callback
func (k Keeper) RegisterTradeRouteICAAccount(
ctx sdk.Context,
tradeRouteId string,
connectionId string,
icaAccountType types.ICAAccountType,
) (account types.ICAAccount, err error) {
Expand All @@ -165,7 +173,7 @@ func (k Keeper) RegisterTradeRouteICAAccount(
Encoding: icatypes.EncodingProtobuf,
TxType: icatypes.TxTypeSDKMultiMsg,
}))
owner := types.FormatICAAccountOwner(chainId, icaAccountType)
owner := types.FormatTradeRouteICAOwnerFromRouteId(chainId, tradeRouteId, icaAccountType)
portID, err := icatypes.NewControllerPortID(owner)
if err != nil {
return account, err
Expand Down
12 changes: 6 additions & 6 deletions x/stakeibc/keeper/msg_server_register_host_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,45 +128,45 @@ func (k msgServer) RegisterHostZone(goCtx context.Context, msg *types.MsgRegiste

// generate delegate account
// NOTE: in the future, if we implement proxy governance, we'll need many more delegate accounts
delegateAccount := types.FormatICAAccountOwner(chainId, types.ICAAccountType_DELEGATION)
delegateAccount := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_DELEGATION)
if err := k.ICAControllerKeeper.RegisterInterchainAccount(ctx, zone.ConnectionId, delegateAccount, appVersion); err != nil {
errMsg := fmt.Sprintf("unable to register delegation account, err: %s", err.Error())
k.Logger(ctx).Error(errMsg)
return nil, errorsmod.Wrapf(types.ErrFailedToRegisterHostZone, errMsg)
}

// generate fee account
feeAccount := types.FormatICAAccountOwner(chainId, types.ICAAccountType_FEE)
feeAccount := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_FEE)
if err := k.ICAControllerKeeper.RegisterInterchainAccount(ctx, zone.ConnectionId, feeAccount, appVersion); err != nil {
errMsg := fmt.Sprintf("unable to register fee account, err: %s", err.Error())
k.Logger(ctx).Error(errMsg)
return nil, errorsmod.Wrapf(types.ErrFailedToRegisterHostZone, errMsg)
}

// generate withdrawal account
withdrawalAccount := types.FormatICAAccountOwner(chainId, types.ICAAccountType_WITHDRAWAL)
withdrawalAccount := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_WITHDRAWAL)
if err := k.ICAControllerKeeper.RegisterInterchainAccount(ctx, zone.ConnectionId, withdrawalAccount, appVersion); err != nil {
errMsg := fmt.Sprintf("unable to register withdrawal account, err: %s", err.Error())
k.Logger(ctx).Error(errMsg)
return nil, errorsmod.Wrapf(types.ErrFailedToRegisterHostZone, errMsg)
}

// generate redemption account
redemptionAccount := types.FormatICAAccountOwner(chainId, types.ICAAccountType_REDEMPTION)
redemptionAccount := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_REDEMPTION)
if err := k.ICAControllerKeeper.RegisterInterchainAccount(ctx, zone.ConnectionId, redemptionAccount, appVersion); err != nil {
errMsg := fmt.Sprintf("unable to register redemption account, err: %s", err.Error())
k.Logger(ctx).Error(errMsg)
return nil, errorsmod.Wrapf(types.ErrFailedToRegisterHostZone, errMsg)
}

// create community pool deposit account
communityPoolDepositAccount := types.FormatICAAccountOwner(chainId, types.ICAAccountType_COMMUNITY_POOL_DEPOSIT)
communityPoolDepositAccount := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_COMMUNITY_POOL_DEPOSIT)
if err := k.ICAControllerKeeper.RegisterInterchainAccount(ctx, zone.ConnectionId, communityPoolDepositAccount, appVersion); err != nil {
return nil, errorsmod.Wrapf(types.ErrFailedToRegisterHostZone, "failed to register community pool deposit ICA")
}

// create community pool return account
communityPoolReturnAccount := types.FormatICAAccountOwner(chainId, types.ICAAccountType_COMMUNITY_POOL_RETURN)
communityPoolReturnAccount := types.FormatHostZoneICAOwner(chainId, types.ICAAccountType_COMMUNITY_POOL_RETURN)
if err := k.ICAControllerKeeper.RegisterInterchainAccount(ctx, zone.ConnectionId, communityPoolReturnAccount, appVersion); err != nil {
return nil, errorsmod.Wrapf(types.ErrFailedToRegisterHostZone, "failed to register community pool return ICA")
}
Expand Down
2 changes: 1 addition & 1 deletion x/stakeibc/keeper/msg_server_restore_interchain_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (k msgServer) RestoreInterchainAccount(goCtx context.Context, msg *types.Ms
counterpartyConnection := connectionEnd.Counterparty

// only allow restoring an account if it already exists
owner := types.FormatICAAccountOwner(msg.ChainId, msg.AccountType)
owner := types.FormatHostZoneICAOwner(msg.ChainId, msg.AccountType)
portID, err := icatypes.NewControllerPortID(owner)
if err != nil {
errMsg := fmt.Sprintf("could not create portID for ICA controller account address: %s", owner)
Expand Down
18 changes: 6 additions & 12 deletions x/stakeibc/keeper/msg_server_submit_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import (
func (k Keeper) DelegateOnHost(ctx sdk.Context, hostZone types.HostZone, amt sdk.Coin, depositRecord recordstypes.DepositRecord) error {
// TODO: Remove this block and use connection-id from host zone
// the relevant ICA is the delegate account
owner := types.FormatICAAccountOwner(hostZone.ChainId, types.ICAAccountType_DELEGATION)
owner := types.FormatHostZoneICAOwner(hostZone.ChainId, types.ICAAccountType_DELEGATION)
portID, err := icatypes.NewControllerPortID(owner)
if err != nil {
return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "%s has no associated portId", owner)
Expand Down Expand Up @@ -117,7 +117,7 @@ func (k Keeper) DelegateOnHost(ctx sdk.Context, hostZone types.HostZone, amt sdk
func (k Keeper) SetWithdrawalAddressOnHost(ctx sdk.Context, hostZone types.HostZone) error {
// TODO: Remove this block and use connection-id from host zone
// The relevant ICA is the delegate account
owner := types.FormatICAAccountOwner(hostZone.ChainId, types.ICAAccountType_DELEGATION)
owner := types.FormatHostZoneICAOwner(hostZone.ChainId, types.ICAAccountType_DELEGATION)
portID, err := icatypes.NewControllerPortID(owner)
if err != nil {
return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "%s has no associated portId", owner)
Expand Down Expand Up @@ -261,6 +261,7 @@ func (k Keeper) SubmitTxsEpoch(
}

// SubmitTxs submits an ICA transaction containing multiple messages
// This function only supports messages to ICAs on the host zone
func (k Keeper) SubmitTxs(
ctx sdk.Context,
connectionId string,
Expand All @@ -274,7 +275,7 @@ func (k Keeper) SubmitTxs(
if err != nil {
return 0, err
}
owner := types.FormatICAAccountOwner(chainId, icaAccountType)
owner := types.FormatHostZoneICAOwner(chainId, icaAccountType)
portID, err := icatypes.NewControllerPortID(owner)
if err != nil {
return 0, err
Expand Down Expand Up @@ -332,17 +333,10 @@ func (k Keeper) SubmitTxs(
func (k Keeper) SubmitICATxWithoutCallback(
ctx sdk.Context,
connectionId string,
icaAccountType types.ICAAccountType,
icaAccountOwner string,
msgs []proto.Message,
timeoutTimestamp uint64,
) error {
// Compute useful connection properties to avoid needing them as params
chainId, err := k.GetChainIdFromConnectionId(ctx, connectionId)
if err != nil {
return err
}
owner := types.FormatICAAccountOwner(chainId, icaAccountType)

// Serialize tx messages
txBz, err := icatypes.SerializeCosmosTx(k.cdc, msgs)
if err != nil {
Expand All @@ -356,7 +350,7 @@ func (k Keeper) SubmitICATxWithoutCallback(

// Submit ICA, no need to store callback data or register callback function
icaMsgServer := icacontrollerkeeper.NewMsgServerImpl(&k.ICAControllerKeeper)
msgSendTx := icacontrollertypes.NewMsgSendTx(owner, connectionId, relativeTimeoutOffset, packetData)
msgSendTx := icacontrollertypes.NewMsgSendTx(icaAccountOwner, connectionId, relativeTimeoutOffset, packetData)
_, err = icaMsgServer.SendTx(ctx, msgSendTx)
if err != nil {
return errorsmod.Wrapf(err, "unable to send ICA tx")
Expand Down
Loading