-
Notifications
You must be signed in to change notification settings - Fork 560
/
ics4_wrapper.go
106 lines (91 loc) · 4.03 KB
/
ics4_wrapper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package ibc_rate_limit
import (
errorsmod "cosmossdk.io/errors"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types"
"github.com/cosmos/ibc-go/v4/modules/core/exported"
"github.com/osmosis-labs/osmosis/v16/x/ibc-rate-limit/types"
)
var (
_ porttypes.Middleware = &IBCModule{}
_ porttypes.ICS4Wrapper = &ICS4Wrapper{}
)
type ICS4Wrapper struct {
channel porttypes.ICS4Wrapper
accountKeeper *authkeeper.AccountKeeper
bankKeeper *bankkeeper.BaseKeeper
ContractKeeper *wasmkeeper.PermissionedKeeper
paramSpace paramtypes.Subspace
}
func (i *ICS4Wrapper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) {
return i.channel.GetAppVersion(ctx, portID, channelID)
}
func NewICS4Middleware(
channel porttypes.ICS4Wrapper,
accountKeeper *authkeeper.AccountKeeper, contractKeeper *wasmkeeper.PermissionedKeeper,
bankKeeper *bankkeeper.BaseKeeper, paramSpace paramtypes.Subspace,
) ICS4Wrapper {
if !paramSpace.HasKeyTable() {
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
}
return ICS4Wrapper{
channel: channel,
accountKeeper: accountKeeper,
ContractKeeper: contractKeeper,
bankKeeper: bankKeeper,
paramSpace: paramSpace,
}
}
// SendPacket implements the ICS4 interface and is called when sending packets.
// This method retrieves the contract from the middleware's parameters and checks if the limits have been exceeded for
// the current transfer, in which case it returns an error preventing the IBC send from taking place.
// If the contract param is not configured, or the contract doesn't have a configuration for the (channel+denom) being
// used, transfers are not prevented and handled by the wrapped IBC app
func (i *ICS4Wrapper) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet exported.PacketI) error {
contract := i.GetContractAddress(ctx)
if contract == "" {
// The contract has not been configured. Continue as usual
return i.channel.SendPacket(ctx, chanCap, packet)
}
// We need the full packet so the contract can process it. If it can't be cast to a channeltypes.Packet, this
// should fail. The only reason that would happen is if another middleware is modifying the packet, though. In
// that case we can modify the middleware order or change this cast so we have all the data we need.
fullPacket, ok := packet.(channeltypes.Packet)
if !ok {
return sdkerrors.ErrInvalidRequest
}
err := CheckAndUpdateRateLimits(ctx, i.ContractKeeper, "send_packet", contract, fullPacket)
if err != nil {
return errorsmod.Wrap(err, "rate limit SendPacket failed to authorize transfer")
}
return i.channel.SendPacket(ctx, chanCap, packet)
}
func (i *ICS4Wrapper) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet exported.PacketI, ack exported.Acknowledgement) error {
return i.channel.WriteAcknowledgement(ctx, chanCap, packet, ack)
}
func (i *ICS4Wrapper) GetContractAddress(ctx sdk.Context) (contract string) {
return i.GetParams(ctx).ContractAddress
}
func (i *ICS4Wrapper) GetParams(ctx sdk.Context) (params types.Params) {
// This was previously done via i.paramSpace.GetParamSet(ctx, ¶ms). That will
// panic if the params don't exist. This is a workaround to avoid that panic.
// Params should be refactored to just use a raw kvstore.
empty := types.Params{}
for _, pair := range params.ParamSetPairs() {
i.paramSpace.GetIfExists(ctx, pair.Key, pair.Value)
}
if params == empty {
return types.DefaultParams()
}
return params
}
func (i *ICS4Wrapper) SetParams(ctx sdk.Context, params types.Params) {
i.paramSpace.SetParamSet(ctx, ¶ms)
}