55 "fmt"
66 "time"
77
8+ errorsmod "cosmossdk.io/errors"
89 "github.com/cometbft/cometbft/libs/log"
910 "github.com/cosmos/cosmos-sdk/codec"
1011 storetypes "github.com/cosmos/cosmos-sdk/store/types"
@@ -13,6 +14,9 @@ import (
1314 capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
1415 icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper"
1516 icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"
17+ clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
18+ porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types"
19+ host "github.com/cosmos/ibc-go/v7/modules/core/24-host"
1620 "github.com/crypto-org-chain/cronos/v2/x/icaauth/types"
1721 "google.golang.org/grpc/codes"
1822 "google.golang.org/grpc/status"
@@ -24,8 +28,10 @@ type (
2428 storeKey storetypes.StoreKey
2529 memKey storetypes.StoreKey
2630
27- icaControllerKeeper icacontrollerkeeper.Keeper
28- scopedKeeper capabilitykeeper.ScopedKeeper
31+ icaControllerKeeper icacontrollerkeeper.Keeper
32+ ics4Wrapper porttypes.ICS4Wrapper
33+ scopedKeeper capabilitykeeper.ScopedKeeper
34+ controllerScopedKeeper capabilitykeeper.ScopedKeeper
2935 }
3036)
3137
@@ -35,17 +41,22 @@ func NewKeeper(
3541 memKey storetypes.StoreKey ,
3642 icaControllerKeeper icacontrollerkeeper.Keeper ,
3743 scopedKeeper capabilitykeeper.ScopedKeeper ,
44+ controllerScopedKeeper capabilitykeeper.ScopedKeeper ,
3845) * Keeper {
3946 return & Keeper {
40- cdc : cdc ,
41- storeKey : storeKey ,
42- memKey : memKey ,
43-
44- icaControllerKeeper : icaControllerKeeper ,
45- scopedKeeper : scopedKeeper ,
47+ cdc : cdc ,
48+ storeKey : storeKey ,
49+ memKey : memKey ,
50+ icaControllerKeeper : icaControllerKeeper ,
51+ scopedKeeper : scopedKeeper ,
52+ controllerScopedKeeper : controllerScopedKeeper ,
4653 }
4754}
4855
56+ func (k * Keeper ) WithICS4Wrapper (ics4Wrapper porttypes.ICS4Wrapper ) {
57+ k .ics4Wrapper = ics4Wrapper
58+ }
59+
4960// SubmitTx submits a transaction to the host chain on behalf of interchain account
5061func (k * Keeper ) SubmitTx (goCtx context.Context , msg * types.MsgSubmitTx ) (* types.MsgSubmitTxResponse , error ) {
5162 msgs , err := msg .GetMessages ()
@@ -62,26 +73,53 @@ func (k *Keeper) SubmitTx(goCtx context.Context, msg *types.MsgSubmitTx) (*types
6273 Type : icatypes .EXECUTE_TX ,
6374 Data : data ,
6475 }
65- return k .SubmitTxWithArgs (goCtx , msg .Owner , msg .ConnectionId , * msg .TimeoutDuration , packetData )
76+ _ , rsp , err := k .SubmitTxWithArgs (goCtx , msg .Owner , msg .ConnectionId , * msg .TimeoutDuration , packetData )
77+ return rsp , err
6678}
6779
68- func (k * Keeper ) SubmitTxWithArgs (goCtx context.Context , owner , connectionId string , timeoutDuration time.Duration , packetData icatypes.InterchainAccountPacketData ) (* types.MsgSubmitTxResponse , error ) {
80+ func (k * Keeper ) sendTx (ctx sdk.Context , connectionID , portID string , icaPacketData icatypes.InterchainAccountPacketData , timeoutTimestamp uint64 ) (string , uint64 , error ) {
81+ activeChannelID , found := k .icaControllerKeeper .GetOpenActiveChannel (ctx , connectionID , portID )
82+ if ! found {
83+ return "" , 0 , errorsmod .Wrapf (icatypes .ErrActiveChannelNotFound , "failed to retrieve active channel on connection %s for port %s" , connectionID , portID )
84+ }
85+
86+ chanCap , found := k .controllerScopedKeeper .GetCapability (ctx , host .ChannelCapabilityPath (portID , activeChannelID ))
87+ if ! found {
88+ return "" , 0 , errorsmod .Wrapf (capabilitytypes .ErrCapabilityNotFound , "failed to find capability: %s" , host .ChannelCapabilityPath (portID , activeChannelID ))
89+ }
90+
91+ if uint64 (ctx .BlockTime ().UnixNano ()) >= timeoutTimestamp {
92+ return "" , 0 , icatypes .ErrInvalidTimeoutTimestamp
93+ }
94+
95+ if err := icaPacketData .ValidateBasic (); err != nil {
96+ return "" , 0 , errorsmod .Wrap (err , "invalid interchain account packet data" )
97+ }
98+
99+ sequence , err := k .ics4Wrapper .SendPacket (ctx , chanCap , portID , activeChannelID , clienttypes .ZeroHeight (), timeoutTimestamp , icaPacketData .GetBytes ())
100+ if err != nil {
101+ return "" , 0 , err
102+ }
103+ return activeChannelID , sequence , nil
104+ }
105+
106+ func (k * Keeper ) SubmitTxWithArgs (goCtx context.Context , owner , connectionId string , timeoutDuration time.Duration , packetData icatypes.InterchainAccountPacketData ) (string , * types.MsgSubmitTxResponse , error ) {
69107 ctx := sdk .UnwrapSDKContext (goCtx )
70108 portID , err := icatypes .NewControllerPortID (owner )
71109 if err != nil {
72- return nil , err
110+ return "" , nil , err
73111 }
74112 minTimeoutDuration := k .MinTimeoutDuration (ctx )
75113 // timeoutDuration should be constraited by MinTimeoutDuration parameter.
76114 timeoutTimestamp := ctx .BlockTime ().Add (
77115 types.MsgSubmitTx {
78116 TimeoutDuration : & timeoutDuration ,
79117 }.CalculateTimeoutDuration (minTimeoutDuration )).UnixNano ()
80- res , err := k .icaControllerKeeper . SendTx (ctx , nil , connectionId , portID , packetData , uint64 (timeoutTimestamp )) //nolint:staticcheck
118+ activeChannelID , res , err := k .sendTx (ctx , connectionId , portID , packetData , uint64 (timeoutTimestamp ))
81119 if err != nil {
82- return nil , err
120+ return "" , nil , err
83121 }
84- return & types.MsgSubmitTxResponse {
122+ return activeChannelID , & types.MsgSubmitTxResponse {
85123 Sequence : res ,
86124 }, nil
87125}
0 commit comments