-
Notifications
You must be signed in to change notification settings - Fork 693
feat: added ics27-2 gmp application #8352
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
Draft
srdtrk
wants to merge
41
commits into
main
Choose a base branch
from
serdar/xxx-contract-calls
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
2b8ebde
feat: added proto types
srdtrk e64d4b8
chore: ran proto-all
srdtrk 33760e8
Merge branch 'main' into serdar/xxx-contract-calls
srdtrk 7f98428
chore: generate proto
srdtrk 2b29b85
imp: added type helpers
srdtrk 5b198c7
imp: added new proto
srdtrk c7289d5
imp: added query.proto
srdtrk add062d
Merge branch 'main' into serdar/xxx-contract-calls
srdtrk 83be763
chore: gen proto types
srdtrk 0394e66
imp: regen proto
srdtrk 0f5dbfb
imp: save progress
srdtrk 4fed4b9
feat: implemented basic module with autocli
srdtrk 2d21a1e
imp: added ibc boilerplate
srdtrk 7dfb3e6
feat: add module to simapp
srdtrk 5cd5bce
imp: added account keeper
srdtrk d0a7742
imp: remoce ics4wrapper
srdtrk 918f808
imp: implemented first message server
srdtrk 23366e8
imp: verify autocli
srdtrk 230ef6a
imp: implemented OnSendPacket
srdtrk 032dd63
imp: implemented ack and timeout entry points
srdtrk 707fa58
imp: more boilerplate
srdtrk 06495a4
imp: added ack to proto
srdtrk eceb5b1
imp: added ack helpers
srdtrk 2bd764d
imp: more boilerplate
srdtrk d3a9cd9
feat: added account gen
srdtrk 0fab11f
imp: added cosmos tx
srdtrk 134b82a
imp: implemented receive
srdtrk ef9559a
imp: implemented query
srdtrk fa61151
lint
srdtrk 0926c7d
imp: added gmp to wasm simapp
srdtrk c6203a9
style: lint
srdtrk 18c8157
style: lint
srdtrk be8367e
chore: bump go version
srdtrk 7df1aab
Merge branch 'main' into serdar/xxx-contract-calls
srdtrk ee75f8b
imp: attempt to improve module wiring
srdtrk e6c856e
imp: fix attempt
srdtrk d84336d
imp: removed gmp from unused simapp
srdtrk cc9968d
fix: keeper wiring
srdtrk a841ca9
imp: allow receiver to be empty
srdtrk 62159d4
imp: added logger
srdtrk 6151f8f
imp: no err if acc already exists
srdtrk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package gmp | ||
|
||
import ( | ||
"fmt" | ||
|
||
errorsmod "cosmossdk.io/errors" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
||
"github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" | ||
"github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" | ||
clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" | ||
channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" | ||
"github.com/cosmos/ibc-go/v10/modules/core/api" | ||
ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" | ||
) | ||
|
||
var _ api.IBCModule = (*IBCModule)(nil) | ||
|
||
// IBCModule implements the ICS26 interface for transfer given the transfer keeper. | ||
type IBCModule struct { | ||
keeper keeper.Keeper | ||
} | ||
|
||
// NewIBCModule creates a new IBCModule given the keeper | ||
func NewIBCModule(k keeper.Keeper) *IBCModule { | ||
return &IBCModule{ | ||
keeper: k, | ||
} | ||
} | ||
|
||
func (*IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error { | ||
if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { | ||
return errorsmod.Wrapf(channeltypesv2.ErrInvalidPacket, "payload port ID is invalid: expected %s, got sourcePort: %s destPort: %s", types.PortID, payload.SourcePort, payload.DestinationPort) | ||
} | ||
if !clienttypes.IsValidClientID(sourceChannel) || !clienttypes.IsValidClientID(destinationChannel) { | ||
return errorsmod.Wrapf(channeltypesv2.ErrInvalidPacket, "client IDs must be in valid format: {string}-{number}") | ||
} | ||
|
||
data, err := types.UnmarshalPacketData(payload.Value, payload.Version, payload.Encoding) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err := data.ValidateBasic(); err != nil { | ||
return errorsmod.Wrapf(err, "failed to validate %s packet data", types.Version) | ||
} | ||
|
||
sender, err := sdk.AccAddressFromBech32(data.Sender) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !signer.Equals(sender) { | ||
return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "sender %s is different from signer %s", sender, signer) | ||
} | ||
|
||
// TODO: emit event and telemetry | ||
|
||
return nil | ||
} | ||
|
||
func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult { | ||
if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { | ||
return channeltypesv2.RecvPacketResult{ | ||
Status: channeltypesv2.PacketStatus_Failure, | ||
} | ||
} | ||
if payload.Version != types.Version { | ||
return channeltypesv2.RecvPacketResult{ | ||
Status: channeltypesv2.PacketStatus_Failure, | ||
} | ||
} | ||
|
||
packetData, ackErr := types.UnmarshalPacketData(payload.Value, payload.Version, payload.Encoding) | ||
if ackErr != nil { | ||
im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) | ||
return channeltypesv2.RecvPacketResult{ | ||
Status: channeltypesv2.PacketStatus_Failure, | ||
} | ||
} | ||
|
||
if ackErr := packetData.ValidateBasic(); ackErr != nil { | ||
im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) | ||
return channeltypesv2.RecvPacketResult{ | ||
Status: channeltypesv2.PacketStatus_Failure, | ||
} | ||
} | ||
|
||
result, ackErr := im.keeper.OnRecvPacket( | ||
ctx, | ||
packetData, | ||
payload.SourcePort, | ||
sourceChannel, | ||
payload.DestinationPort, | ||
destinationChannel, | ||
) | ||
if ackErr != nil { | ||
im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) | ||
return channeltypesv2.RecvPacketResult{ | ||
Status: channeltypesv2.PacketStatus_Failure, | ||
} | ||
} | ||
|
||
ack := types.NewAcknowledgement(result) | ||
ackBz, ackErr := types.MarshalAcknowledgement(&ack, types.Version, payload.Encoding) | ||
if ackErr != nil { | ||
im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) | ||
return channeltypesv2.RecvPacketResult{ | ||
Status: channeltypesv2.PacketStatus_Failure, | ||
} | ||
} | ||
|
||
im.keeper.Logger(ctx).Info("successfully handled ICS-27 GMP packet", "sequence", sequence) | ||
|
||
// TODO: implement telemetry | ||
|
||
return channeltypesv2.RecvPacketResult{ | ||
Status: channeltypesv2.PacketStatus_Success, | ||
Acknowledgement: ackBz, | ||
} | ||
} | ||
|
||
func (*IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { | ||
return nil | ||
} | ||
|
||
func (*IBCModule) OnAcknowledgementPacket(_ sdk.Context, _, _ string, _ uint64, _ []byte, _ channeltypesv2.Payload, _ sdk.AccAddress) error { | ||
return nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package keeper | ||
|
||
import ( | ||
"context" | ||
|
||
"cosmossdk.io/collections" | ||
errorsmod "cosmossdk.io/errors" | ||
|
||
"github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" | ||
) | ||
|
||
// getOrCreateICS27Account retrieves an existing ICS27 account or creates a new one if it doesn't exist. | ||
func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountID *types.AccountIdentifier) (*types.ICS27Account, error) { | ||
existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you have this additional storage out of state? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems redundant with accountKeeper |
||
if err == nil { | ||
return &existingIcs27Account, nil | ||
} else if !errorsmod.IsOf(err, collections.ErrNotFound) { | ||
return nil, err | ||
} | ||
|
||
// Create a new account | ||
newAddr, err := types.BuildAddressPredictable(accountID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
existingAcc := k.accountKeeper.GetAccount(ctx, newAddr) | ||
if existingAcc != nil { | ||
// TODO: ensure this cannot be abused (refactor after this is resolved) | ||
ics27Account := types.NewICS27Account(existingAcc.GetAddress().String(), accountID) | ||
if err := k.Accounts.Set(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt), ics27Account); err != nil { | ||
return nil, errorsmod.Wrapf(err, "failed to set account %s in store", ics27Account) | ||
} | ||
|
||
return &ics27Account, nil | ||
} | ||
|
||
newAcc := k.accountKeeper.NewAccountWithAddress(ctx, newAddr) | ||
k.accountKeeper.SetAccount(ctx, newAcc) | ||
|
||
ics27Account := types.NewICS27Account(newAcc.GetAddress().String(), accountID) | ||
if err := k.Accounts.Set(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt), ics27Account); err != nil { | ||
return nil, errorsmod.Wrapf(err, "failed to set account %s in store", ics27Account) | ||
} | ||
|
||
k.Logger(ctx).Info("Created new ICS27 account", "account", ics27Account) | ||
return &ics27Account, nil | ||
} | ||
|
||
// getOrComputeICS27Adderss retrieves an existing ICS27 account address or computes it if it doesn't exist. This doesn't modify the store. | ||
func (k Keeper) getOrComputeICS27Address(ctx context.Context, accountID *types.AccountIdentifier) (string, error) { | ||
existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt)) | ||
if err == nil { | ||
return existingIcs27Account.Address, nil | ||
} else if !errorsmod.IsOf(err, collections.ErrNotFound) { | ||
return "", err | ||
} | ||
|
||
// Compute a new address | ||
newAddr, err := types.BuildAddressPredictable(accountID) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return newAddr.String(), nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package keeper | ||
|
||
import ( | ||
"context" | ||
|
||
"cosmossdk.io/collections" | ||
errorsmod "cosmossdk.io/errors" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
||
"github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" | ||
ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" | ||
) | ||
|
||
// InitGenesis initializes the module state from a genesis state. | ||
func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { | ||
for _, account := range data.Ics27Accounts { | ||
if _, err := sdk.AccAddressFromBech32(account.AccountAddress); err != nil { | ||
return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) | ||
} | ||
if _, err := sdk.AccAddressFromBech32(account.AccountId.Sender); err != nil { | ||
return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) | ||
} | ||
|
||
if err := k.Accounts.Set(ctx, collections.Join3(account.AccountId.ClientId, account.AccountId.Sender, account.AccountId.Salt), types.ICS27Account{ | ||
Address: account.AccountAddress, | ||
AccountId: &account.AccountId, | ||
}); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// ExportGenesis exports the module state to a genesis state. | ||
func (k *Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) { | ||
var accounts []types.RegisteredICS27Account | ||
if err := k.Accounts.Walk(ctx, nil, func(key collections.Triple[string, string, []byte], value types.ICS27Account) (bool, error) { | ||
accounts = append(accounts, types.RegisteredICS27Account{ | ||
AccountAddress: value.Address, | ||
AccountId: *value.AccountId, | ||
}) | ||
|
||
return false, nil | ||
}); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &types.GenesisState{ | ||
Ics27Accounts: accounts, | ||
}, nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package keeper | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"strings" | ||
|
||
"cosmossdk.io/collections" | ||
storetypes "cosmossdk.io/core/store" | ||
"cosmossdk.io/log" | ||
|
||
"github.com/cosmos/cosmos-sdk/codec" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
||
"github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" | ||
"github.com/cosmos/ibc-go/v10/modules/core/exported" | ||
) | ||
|
||
// Keeper defines the IBC fungible transfer keeper | ||
type Keeper struct { | ||
cdc codec.Codec | ||
|
||
msgRouter types.MessageRouter | ||
|
||
accountKeeper types.AccountKeeper | ||
|
||
// the address capable of executing a MsgUpdateParams message. Typically, this | ||
// should be the x/gov module account. | ||
authority string | ||
|
||
// state management | ||
Schema collections.Schema | ||
// Accounts is a map of (ClientID, Sender, Salt) to ICS27Account | ||
Accounts collections.Map[collections.Triple[string, string, []byte], types.ICS27Account] | ||
} | ||
|
||
// NewKeeper creates a new Keeper instance | ||
func NewKeeper( | ||
cdc codec.Codec, storeService storetypes.KVStoreService, | ||
accountKeeper types.AccountKeeper, msgRouter types.MessageRouter, | ||
authority string, | ||
) Keeper { | ||
if strings.TrimSpace(authority) == "" { | ||
panic(errors.New("authority must be non-empty")) | ||
} | ||
|
||
sb := collections.NewSchemaBuilder(storeService) | ||
k := Keeper{ | ||
cdc: cdc, | ||
msgRouter: msgRouter, | ||
accountKeeper: accountKeeper, | ||
authority: authority, | ||
Accounts: collections.NewMap(sb, types.AccountsKey, "accounts", collections.TripleKeyCodec(collections.StringKey, collections.StringKey, collections.BytesKey), codec.CollValue[types.ICS27Account](cdc)), | ||
} | ||
|
||
schema, err := sb.Build() | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
k.Schema = schema | ||
|
||
return k | ||
} | ||
|
||
// GetAuthority returns the module's authority. | ||
func (k Keeper) GetAuthority() string { | ||
return k.authority | ||
} | ||
|
||
// Logger returns a module-specific logger. | ||
func (Keeper) Logger(goCtx context.Context) log.Logger { | ||
return sdk.UnwrapSDKContext(goCtx).Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName) | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this check exist in
SendPacket