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

feat: add force ica send governance message type #1712

Closed
wants to merge 1 commit into from
Closed
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
71 changes: 71 additions & 0 deletions docs/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2337,6 +2337,77 @@ paths:
type: string
tags:
- Msg
/quicksilver/tx/v1/interchainstaking/force_send:
post:
summary: >-
SignalIntent defines a method for signalling voting intent for one or
more

validators.
operationId: GovForceSend
responses:
'200':
description: A successful response.
schema:
type: object
description: MsgForceICASendResponse defines the MsgForceICASend response type.
default:
description: An unexpected error response.
schema:
type: object
properties:
error:
type: string
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
properties:
type_url:
type: string
value:
type: string
format: byte
parameters:
- name: body
in: body
required: true
schema:
type: object
properties:
source_address:
type: string
destination_address:
type: string
amount:
type: object
properties:
denom:
type: string
amount:
type: string
description: >-
Coin defines a token with a denomination and an amount.


NOTE: The amount field is an Int which implements the custom
method

signatures required by gogoproto.
from_address:
type: string
description: >-
MsgForceICASend represents a governance-only message that causes a
transfer

of tokens from one ICA to another address.
tags:
- Msg
/quicksilver/tx/v1/interchainstaking/intent:
post:
summary: >-
Expand Down
27 changes: 27 additions & 0 deletions proto/quicksilver/interchainstaking/v1/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ service Msg {
};
}

// SignalIntent defines a method for signalling voting intent for one or more
// validators.
rpc GovForceSend(MsgForceICASend) returns (MsgForceICASendResponse) {
option (google.api.http) = {
post: "/quicksilver/tx/v1/interchainstaking/force_send"
body: "*"
};
}

// SignalIntent defines a method for signalling voting intent for one or more
// validators.
rpc GovCloseChannel(MsgGovCloseChannel) returns (MsgGovCloseChannelResponse) {
Expand Down Expand Up @@ -166,3 +175,21 @@ message MsgSignalIntent {

// MsgSignalIntentResponse defines the MsgSignalIntent response type.
message MsgSignalIntentResponse {}

// MsgForceICASend represents a governance-only message that causes a transfer
// of tokens from one ICA to another address.
message MsgForceICASend {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

string source_address = 1;
string destination_address = 2;
cosmos.base.v1beta1.Coin amount = 3 [
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"coin\""
];
string from_address = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}

// MsgForceICASendResponse defines the MsgForceICASend response type.
message MsgForceICASendResponse {}
43 changes: 43 additions & 0 deletions x/interchainstaking/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"

"github.com/quicksilver-zone/quicksilver/utils/addressutils"
Expand Down Expand Up @@ -496,3 +497,45 @@

return &types.MsgGovRemoveValidatorDenyListResponse{}, nil
}

func (k msgServer) GovForceSend(goCtx context.Context, msg *types.MsgForceICASend) (*types.MsgForceICASendResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

Check warning on line 502 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L501-L502

Added lines #L501 - L502 were not covered by tests

// checking msg authority is the gov module address
if k.Keeper.GetGovAuthority(ctx) != msg.FromAddress {
return nil,
govtypes.ErrInvalidSigner.Wrapf(
"invalid authority: expected %s, got %s",
k.Keeper.GetGovAuthority(ctx), msg.FromAddress,
)

Check warning on line 510 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L505-L510

Added lines #L505 - L510 were not covered by tests
}

zone, found := k.GetZoneForAccount(ctx, msg.FromAddress)
if !found {
return nil, fmt.Errorf("source address is not a valid ICA address %s", msg.FromAddress)

Check warning on line 515 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L513-L515

Added lines #L513 - L515 were not covered by tests
}

sourceAddress, err := addressutils.AccAddressFromBech32(msg.SourceAddress, zone.GetAccountPrefix())
if err != nil {
return nil, err

Check warning on line 520 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L518-L520

Added lines #L518 - L520 were not covered by tests
}

destinationAddress, err := addressutils.AccAddressFromBech32(msg.DestinationAddress, zone.GetAccountPrefix())
if err != nil {
return nil, err

Check warning on line 525 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L523-L525

Added lines #L523 - L525 were not covered by tests
}

sendMsg := banktypes.NewMsgSend(sourceAddress, destinationAddress, sdk.NewCoins(msg.Amount))

Check warning on line 528 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L528

Added line #L528 was not covered by tests

icaAccount, err := k.GetICAAccount(ctx, zone, msg.FromAddress)
if err != nil {
return nil, err

Check warning on line 532 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L530-L532

Added lines #L530 - L532 were not covered by tests
}

err = k.SubmitTx(ctx, []sdk.Msg{sendMsg}, icaAccount, "governance send", 1)
if err != nil {
return nil, err

Check warning on line 537 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L535-L537

Added lines #L535 - L537 were not covered by tests
}

return &types.MsgForceICASendResponse{}, nil

Check warning on line 540 in x/interchainstaking/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/msg_server.go#L540

Added line #L540 was not covered by tests
}
37 changes: 19 additions & 18 deletions x/interchainstaking/keeper/zones.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package keeper

import (
"errors"
"fmt"
"math"

Expand Down Expand Up @@ -310,20 +309,7 @@
return nil
}

// SetAccountBalance triggers provable KV queries to prove an AllBalances query.
func (k *Keeper) SetAccountBalance(ctx sdk.Context, zone types.Zone, address string, queryResult []byte) error {
queryRes := banktypes.QueryAllBalancesResponse{}
err := k.cdc.Unmarshal(queryResult, &queryRes)
if err != nil {
k.Logger(ctx).Error("unable to unmarshal balance", "zone", zone.ChainId, "err", err)
return err
}
_, addr, err := bech32.DecodeAndConvert(address)
if err != nil {
return err
}
data := banktypes.CreateAccountBalancesPrefix(addr)

func (k *Keeper) GetICAAccount(ctx sdk.Context, zone *types.Zone, address string) (*types.ICAAccount, error) {
var icaAccount *types.ICAAccount

switch {
Expand All @@ -336,12 +322,27 @@
case zone.PerformanceAddress != nil && address == zone.PerformanceAddress.Address:
icaAccount = zone.PerformanceAddress
default:
return errors.New("unexpected address")
return nil, fmt.Errorf("unable to determine account for address %s", address)

Check warning on line 325 in x/interchainstaking/keeper/zones.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/zones.go#L325

Added line #L325 was not covered by tests
}

if icaAccount == nil {
return fmt.Errorf("unable to determine account for address %s", address)
return icaAccount, nil
}

// SetAccountBalance triggers provable KV queries to prove an AllBalances query.
func (k *Keeper) SetAccountBalance(ctx sdk.Context, zone types.Zone, address string, queryResult []byte) error {
queryRes := banktypes.QueryAllBalancesResponse{}
err := k.cdc.Unmarshal(queryResult, &queryRes)
if err != nil {
k.Logger(ctx).Error("unable to unmarshal balance", "zone", zone.ChainId, "err", err)
return err

Check warning on line 337 in x/interchainstaking/keeper/zones.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/zones.go#L336-L337

Added lines #L336 - L337 were not covered by tests
}
_, addr, err := bech32.DecodeAndConvert(address)
if err != nil {
return err

Check warning on line 341 in x/interchainstaking/keeper/zones.go

View check run for this annotation

Codecov / codecov/patch

x/interchainstaking/keeper/zones.go#L341

Added line #L341 was not covered by tests
}
data := banktypes.CreateAccountBalancesPrefix(addr)

icaAccount, err := k.GetICAAccount(ctx, &zone, address)

Check failure on line 345 in x/interchainstaking/keeper/zones.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to err (ineffassign)

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning

This definition of err is never used.

for _, coin := range icaAccount.Balance {
if queryRes.Balances.AmountOf(coin.Denom).Equal(sdk.ZeroInt()) {
Expand Down
Loading
Loading