@agoric/cosmos 0.34.2-orchestration-dev-096c4e8.0 → 0.34.2-other-dev-3eb1a1d.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MAINTAINERS.md +3 -0
- package/Makefile +38 -34
- package/ante/ante.go +1 -4
- package/ante/inbound_test.go +2 -2
- package/app/app.go +198 -137
- package/app/upgrade.go +248 -0
- package/cmd/agd/agvm.go +3 -3
- package/cmd/agd/find_binary.go +2 -2
- package/cmd/agd/main.go +9 -10
- package/cmd/libdaemon/main.go +13 -13
- package/daemon/cmd/root.go +235 -92
- package/daemon/cmd/root_test.go +189 -1
- package/daemon/main.go +3 -2
- package/git-revision.txt +1 -1
- package/go.mod +14 -11
- package/go.sum +20 -19
- package/index.cjs +1 -1
- package/package.json +4 -3
- package/proto/agoric/swingset/genesis.proto +4 -0
- package/proto/agoric/swingset/swingset.proto +26 -1
- package/proto/agoric/vbank/vbank.proto +7 -0
- package/proto/agoric/vtransfer/genesis.proto +18 -0
- package/scripts/protocgen.sh +7 -8
- package/types/kv_entry_helpers.go +42 -0
- package/upgradegaia.sh +8 -8
- package/util/util.go +21 -0
- package/vm/action.go +1 -1
- package/vm/client.go +15 -13
- package/vm/client_test.go +34 -36
- package/vm/controller.go +3 -38
- package/vm/core_proposals.go +22 -2
- package/vm/proto_json.go +38 -0
- package/vm/proto_json_test.go +103 -0
- package/vm/server.go +106 -5
- package/x/swingset/alias.go +2 -0
- package/x/swingset/config.go +234 -0
- package/x/swingset/genesis.go +178 -40
- package/x/swingset/keeper/extension_snapshotter.go +2 -2
- package/x/swingset/keeper/keeper.go +24 -27
- package/x/swingset/keeper/swing_store_exports_handler.go +14 -3
- package/x/swingset/keeper/test_utils.go +16 -0
- package/x/swingset/module.go +24 -9
- package/x/swingset/testing/queue.go +17 -0
- package/x/swingset/types/default-params.go +31 -5
- package/x/swingset/types/expected_keepers.go +2 -2
- package/x/swingset/types/genesis.pb.go +78 -25
- package/x/swingset/types/msgs.go +53 -12
- package/x/swingset/types/params.go +53 -43
- package/x/swingset/types/params_test.go +75 -9
- package/x/swingset/types/swingset.pb.go +387 -57
- package/x/vbank/README.md +6 -1
- package/x/vbank/genesis.go +0 -2
- package/x/vbank/keeper/keeper.go +4 -9
- package/x/vbank/keeper/migrations.go +30 -0
- package/x/vbank/module.go +8 -7
- package/x/vbank/types/key.go +3 -3
- package/x/vbank/types/msgs.go +0 -12
- package/x/vbank/types/params.go +43 -2
- package/x/vbank/types/vbank.pb.go +105 -36
- package/x/vbank/vbank.go +8 -13
- package/x/vbank/vbank_test.go +14 -9
- package/x/vibc/alias.go +1 -1
- package/x/vibc/module.go +2 -7
- package/x/vibc/types/ibc_module.go +9 -3
- package/x/vibc/types/receiver.go +17 -7
- package/x/vlocalchain/handler.go +2 -1
- package/x/vlocalchain/keeper/keeper.go +24 -8
- package/x/vlocalchain/keeper/keeper_test.go +65 -1
- package/x/vlocalchain/types/expected_keepers.go +12 -0
- package/x/vlocalchain/vlocalchain.go +27 -22
- package/x/vlocalchain/vlocalchain_test.go +163 -8
- package/x/vstorage/keeper/grpc_query.go +0 -1
- package/x/vstorage/keeper/keeper.go +9 -17
- package/x/vstorage/module.go +0 -5
- package/x/vstorage/testing/queue.go +28 -0
- package/x/vtransfer/alias.go +13 -0
- package/x/vtransfer/genesis.go +39 -0
- package/x/vtransfer/genesis_test.go +12 -0
- package/x/vtransfer/handler.go +20 -0
- package/x/vtransfer/ibc_middleware.go +186 -0
- package/x/vtransfer/ibc_middleware_test.go +449 -0
- package/x/vtransfer/keeper/keeper.go +282 -0
- package/x/vtransfer/module.go +124 -0
- package/x/vtransfer/types/baseaddr.go +156 -0
- package/x/vtransfer/types/baseaddr_test.go +167 -0
- package/x/vtransfer/types/expected_keepers.go +38 -0
- package/x/vtransfer/types/genesis.pb.go +328 -0
- package/x/vtransfer/types/key.go +9 -0
- package/x/vtransfer/types/msgs.go +9 -0
- package/ante/fee.go +0 -97
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
package keeper
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
|
|
7
|
+
"github.com/cosmos/cosmos-sdk/codec"
|
|
8
|
+
"github.com/cosmos/cosmos-sdk/store/prefix"
|
|
9
|
+
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
10
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
11
|
+
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
12
|
+
|
|
13
|
+
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
|
|
14
|
+
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
|
15
|
+
|
|
16
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
17
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vibc"
|
|
18
|
+
vibctypes "github.com/Agoric/agoric-sdk/golang/cosmos/x/vibc/types"
|
|
19
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vtransfer/types"
|
|
20
|
+
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
|
|
21
|
+
porttypes "github.com/cosmos/ibc-go/v6/modules/core/05-port/types"
|
|
22
|
+
host "github.com/cosmos/ibc-go/v6/modules/core/24-host"
|
|
23
|
+
ibcexported "github.com/cosmos/ibc-go/v6/modules/core/exported"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
var _ porttypes.ICS4Wrapper = (*Keeper)(nil)
|
|
27
|
+
var _ vibctypes.ReceiverImpl = (*Keeper)(nil)
|
|
28
|
+
var _ vm.PortHandler = (*Keeper)(nil)
|
|
29
|
+
|
|
30
|
+
// "watched addresses" is logically a set and physically a collection of
|
|
31
|
+
// KVStore entries in which each key is a concatenation of a fixed prefix and
|
|
32
|
+
// the address, and its corresponding value is a non-empty but otherwise irrelevant
|
|
33
|
+
// sentinel.
|
|
34
|
+
const (
|
|
35
|
+
watchedAddressStoreKeyPrefix = "watchedAddress/"
|
|
36
|
+
watchedAddressSentinel = "y"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
// Keeper handles the interceptions from the vtransfer IBC middleware, passing
|
|
40
|
+
// them to the embedded vibc keeper if they involve a targeted address (which is
|
|
41
|
+
// an address associated with a VM listener). The embedded vibc keeper is used
|
|
42
|
+
// to bridge calls to swingset, but with a special wrapper on the bridge
|
|
43
|
+
// controller to use distinct action types. The keeper keeps a store of
|
|
44
|
+
// "targeted addresses", managed from Swingset by bridge messages.
|
|
45
|
+
type Keeper struct {
|
|
46
|
+
porttypes.ICS4Wrapper
|
|
47
|
+
vibctypes.ReceiverImpl
|
|
48
|
+
|
|
49
|
+
vibcKeeper vibc.Keeper
|
|
50
|
+
|
|
51
|
+
key storetypes.StoreKey
|
|
52
|
+
cdc codec.Codec
|
|
53
|
+
|
|
54
|
+
vibcModule porttypes.IBCModule
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// NewKeeper creates a new vtransfer Keeper instance
|
|
58
|
+
func NewKeeper(
|
|
59
|
+
cdc codec.Codec,
|
|
60
|
+
key storetypes.StoreKey,
|
|
61
|
+
prototypeVibcKeeper vibc.Keeper,
|
|
62
|
+
scopedTransferKeeper capabilitykeeper.ScopedKeeper,
|
|
63
|
+
pushAction vm.ActionPusher,
|
|
64
|
+
) Keeper {
|
|
65
|
+
wrappedPushAction := wrapActionPusher(pushAction)
|
|
66
|
+
|
|
67
|
+
// This vibcKeeper is used to send notifications from the vtransfer middleware
|
|
68
|
+
// to the VM.
|
|
69
|
+
vibcKeeper := prototypeVibcKeeper.WithScope(nil, scopedTransferKeeper, wrappedPushAction)
|
|
70
|
+
return Keeper{
|
|
71
|
+
ICS4Wrapper: vibcKeeper,
|
|
72
|
+
ReceiverImpl: vibcKeeper,
|
|
73
|
+
|
|
74
|
+
vibcKeeper: vibcKeeper,
|
|
75
|
+
key: key,
|
|
76
|
+
vibcModule: vibc.NewIBCModule(vibcKeeper),
|
|
77
|
+
cdc: cdc,
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// wrapActionPusher wraps an ActionPusher to prefix the action type with
|
|
82
|
+
// "VTRANSFER_".
|
|
83
|
+
func wrapActionPusher(pusher vm.ActionPusher) vm.ActionPusher {
|
|
84
|
+
return func(ctx sdk.Context, action vm.Action) error {
|
|
85
|
+
action = vm.PopulateAction(ctx, action)
|
|
86
|
+
|
|
87
|
+
// Prefix the action type.
|
|
88
|
+
ah := action.GetActionHeader()
|
|
89
|
+
ah.Type = "VTRANSFER_" + ah.Type
|
|
90
|
+
|
|
91
|
+
// fmt.Println("@@@ vtransfer action", action)
|
|
92
|
+
return pusher(ctx, action)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
func (k Keeper) GetICS4Wrapper() porttypes.ICS4Wrapper {
|
|
97
|
+
return k
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
func (k Keeper) GetReceiverImpl() vibctypes.ReceiverImpl {
|
|
101
|
+
return k
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// InterceptOnRecvPacket runs the ibcModule and eventually acknowledges a packet.
|
|
105
|
+
// Many error acknowledgments are sent synchronously, but most cases instead return nil
|
|
106
|
+
// to tell the IBC system that acknowledgment is async (i.e., that WriteAcknowledgement
|
|
107
|
+
// will be called later, after the VM has dealt with the packet).
|
|
108
|
+
func (k Keeper) InterceptOnRecvPacket(ctx sdk.Context, ibcModule porttypes.IBCModule, packet channeltypes.Packet, relayer sdk.AccAddress) ibcexported.Acknowledgement {
|
|
109
|
+
// Pass every (stripped-receiver) inbound packet to the wrapped IBC module.
|
|
110
|
+
var strippedPacket channeltypes.Packet
|
|
111
|
+
_, err := types.ExtractBaseAddressFromPacket(k.cdc, packet, types.RoleReceiver, &strippedPacket)
|
|
112
|
+
if err != nil {
|
|
113
|
+
return channeltypes.NewErrorAcknowledgement(err)
|
|
114
|
+
}
|
|
115
|
+
ack := ibcModule.OnRecvPacket(ctx, strippedPacket, relayer)
|
|
116
|
+
|
|
117
|
+
if ack == nil {
|
|
118
|
+
// Already declared to be an async ack.
|
|
119
|
+
return nil
|
|
120
|
+
}
|
|
121
|
+
portID := packet.GetDestPort()
|
|
122
|
+
channelID := packet.GetDestChannel()
|
|
123
|
+
capName := host.ChannelCapabilityPath(portID, channelID)
|
|
124
|
+
chanCap, ok := k.vibcKeeper.GetCapability(ctx, capName)
|
|
125
|
+
if !ok {
|
|
126
|
+
err := sdkerrors.Wrapf(channeltypes.ErrChannelCapabilityNotFound, "could not retrieve channel capability at: %s", capName)
|
|
127
|
+
return channeltypes.NewErrorAcknowledgement(err)
|
|
128
|
+
}
|
|
129
|
+
// Give the VM a chance to write (or override) the ack.
|
|
130
|
+
if err := k.InterceptWriteAcknowledgement(ctx, chanCap, packet, ack); err != nil {
|
|
131
|
+
return channeltypes.NewErrorAcknowledgement(err)
|
|
132
|
+
}
|
|
133
|
+
return nil
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// InterceptOnAcknowledgementPacket checks to see if the packet sender is a
|
|
137
|
+
// targeted account, and if so, delegates to the VM.
|
|
138
|
+
func (k Keeper) InterceptOnAcknowledgementPacket(
|
|
139
|
+
ctx sdk.Context,
|
|
140
|
+
ibcModule porttypes.IBCModule,
|
|
141
|
+
packet channeltypes.Packet,
|
|
142
|
+
acknowledgement []byte,
|
|
143
|
+
relayer sdk.AccAddress,
|
|
144
|
+
) error {
|
|
145
|
+
// Pass every (stripped-sender) acknowledgement to the wrapped IBC module.
|
|
146
|
+
var strippedPacket channeltypes.Packet
|
|
147
|
+
baseSender, err := types.ExtractBaseAddressFromPacket(k.cdc, packet, types.RoleSender, &strippedPacket)
|
|
148
|
+
if err != nil {
|
|
149
|
+
return err
|
|
150
|
+
}
|
|
151
|
+
modErr := ibcModule.OnAcknowledgementPacket(ctx, strippedPacket, acknowledgement, relayer)
|
|
152
|
+
|
|
153
|
+
// If the sender is not a watched account, we're done.
|
|
154
|
+
if !k.targetIsWatched(ctx, baseSender) {
|
|
155
|
+
return modErr
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Trigger VM with the original packet, regardless of errors in the ibcModule.
|
|
159
|
+
vmErr := k.vibcKeeper.TriggerOnAcknowledgementPacket(ctx, baseSender, packet, acknowledgement, relayer)
|
|
160
|
+
|
|
161
|
+
// Any error from the VM is trumped by one from the wrapped IBC module.
|
|
162
|
+
if modErr != nil {
|
|
163
|
+
return modErr
|
|
164
|
+
}
|
|
165
|
+
return vmErr
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// InterceptOnTimeoutPacket checks to see if the packet sender is a targeted
|
|
169
|
+
// account, and if so, delegates to the VM.
|
|
170
|
+
func (k Keeper) InterceptOnTimeoutPacket(
|
|
171
|
+
ctx sdk.Context,
|
|
172
|
+
ibcModule porttypes.IBCModule,
|
|
173
|
+
packet channeltypes.Packet,
|
|
174
|
+
relayer sdk.AccAddress,
|
|
175
|
+
) error {
|
|
176
|
+
// Pass every (stripped-sender) timeout to the wrapped IBC module.
|
|
177
|
+
var strippedPacket channeltypes.Packet
|
|
178
|
+
baseSender, err := types.ExtractBaseAddressFromPacket(k.cdc, packet, types.RoleSender, &strippedPacket)
|
|
179
|
+
if err != nil {
|
|
180
|
+
return err
|
|
181
|
+
}
|
|
182
|
+
modErr := ibcModule.OnTimeoutPacket(ctx, strippedPacket, relayer)
|
|
183
|
+
|
|
184
|
+
// If the sender is not a watched account, we're done.
|
|
185
|
+
if !k.targetIsWatched(ctx, baseSender) {
|
|
186
|
+
return modErr
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Trigger VM with the original packet, regardless of errors in the app.
|
|
190
|
+
vmErr := k.vibcKeeper.TriggerOnTimeoutPacket(ctx, baseSender, packet, relayer)
|
|
191
|
+
|
|
192
|
+
// Any error from the VM is trumped by one from the wrapped IBC module.
|
|
193
|
+
if modErr != nil {
|
|
194
|
+
return modErr
|
|
195
|
+
}
|
|
196
|
+
return vmErr
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// InterceptWriteAcknowledgement checks to see if the packet's receiver is a
|
|
200
|
+
// targeted account, and if so, delegates to the VM.
|
|
201
|
+
func (k Keeper) InterceptWriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, ack ibcexported.Acknowledgement) error {
|
|
202
|
+
// Get the base baseReceiver from the packet, without computing a stripped packet.
|
|
203
|
+
baseReceiver, err := types.ExtractBaseAddressFromPacket(k.cdc, packet, types.RoleReceiver, nil)
|
|
204
|
+
if err != nil || !k.targetIsWatched(ctx, baseReceiver) {
|
|
205
|
+
// We can't parse, or not watching, but that means just to ack directly.
|
|
206
|
+
return k.WriteAcknowledgement(ctx, chanCap, packet, ack)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Trigger VM with the original packet.
|
|
210
|
+
if err = k.vibcKeeper.TriggerWriteAcknowledgement(ctx, baseReceiver, packet, ack); err != nil {
|
|
211
|
+
errAck := channeltypes.NewErrorAcknowledgement(err)
|
|
212
|
+
return k.WriteAcknowledgement(ctx, chanCap, packet, errAck)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return nil
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// targetIsWatched checks if a target address has been watched by the VM.
|
|
219
|
+
func (k Keeper) targetIsWatched(ctx sdk.Context, target string) bool {
|
|
220
|
+
prefixStore := prefix.NewStore(
|
|
221
|
+
ctx.KVStore(k.key),
|
|
222
|
+
[]byte(watchedAddressStoreKeyPrefix),
|
|
223
|
+
)
|
|
224
|
+
return prefixStore.Has([]byte(target))
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// GetWatchedAdresses returns the watched addresses from the keeper as a slice
|
|
228
|
+
// of account addresses.
|
|
229
|
+
func (k Keeper) GetWatchedAddresses(ctx sdk.Context) ([]sdk.AccAddress, error) {
|
|
230
|
+
addresses := make([]sdk.AccAddress, 0)
|
|
231
|
+
prefixStore := prefix.NewStore(ctx.KVStore(k.key), []byte(watchedAddressStoreKeyPrefix))
|
|
232
|
+
iterator := sdk.KVStorePrefixIterator(prefixStore, []byte{})
|
|
233
|
+
defer iterator.Close()
|
|
234
|
+
for ; iterator.Valid(); iterator.Next() {
|
|
235
|
+
addr, err := sdk.AccAddressFromBech32(string(iterator.Key()))
|
|
236
|
+
if err != nil {
|
|
237
|
+
return nil, err
|
|
238
|
+
}
|
|
239
|
+
addresses = append(addresses, addr)
|
|
240
|
+
}
|
|
241
|
+
return addresses, nil
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// SetWatchedAddresses sets the watched addresses in the keeper from a slice of
|
|
245
|
+
// SDK account addresses.
|
|
246
|
+
func (k Keeper) SetWatchedAddresses(ctx sdk.Context, addresses []sdk.AccAddress) {
|
|
247
|
+
prefixStore := prefix.NewStore(
|
|
248
|
+
ctx.KVStore(k.key),
|
|
249
|
+
[]byte(watchedAddressStoreKeyPrefix),
|
|
250
|
+
)
|
|
251
|
+
for _, addr := range addresses {
|
|
252
|
+
prefixStore.Set([]byte(addr.String()), []byte(watchedAddressSentinel))
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
type registrationAction struct {
|
|
257
|
+
Type string `json:"type"` // BRIDGE_TARGET_REGISTER or BRIDGE_TARGET_UNREGISTER
|
|
258
|
+
Target string `json:"target"`
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Receive implements the vm.PortHandler interface.
|
|
262
|
+
func (k Keeper) Receive(cctx context.Context, jsonRequest string) (jsonReply string, err error) {
|
|
263
|
+
ctx := sdk.UnwrapSDKContext(cctx)
|
|
264
|
+
var msg registrationAction
|
|
265
|
+
if err := json.Unmarshal([]byte(jsonRequest), &msg); err != nil {
|
|
266
|
+
return "", err
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
prefixStore := prefix.NewStore(
|
|
270
|
+
ctx.KVStore(k.key),
|
|
271
|
+
[]byte(watchedAddressStoreKeyPrefix),
|
|
272
|
+
)
|
|
273
|
+
switch msg.Type {
|
|
274
|
+
case "BRIDGE_TARGET_REGISTER":
|
|
275
|
+
prefixStore.Set([]byte(msg.Target), []byte(watchedAddressSentinel))
|
|
276
|
+
case "BRIDGE_TARGET_UNREGISTER":
|
|
277
|
+
prefixStore.Delete([]byte(msg.Target))
|
|
278
|
+
default:
|
|
279
|
+
return "", sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown action type: %s", msg.Type)
|
|
280
|
+
}
|
|
281
|
+
return "true", nil
|
|
282
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
package vtransfer
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
|
|
6
|
+
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
|
7
|
+
"github.com/spf13/cobra"
|
|
8
|
+
|
|
9
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vtransfer/types"
|
|
10
|
+
"github.com/cosmos/cosmos-sdk/client"
|
|
11
|
+
"github.com/cosmos/cosmos-sdk/codec"
|
|
12
|
+
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
|
|
13
|
+
"github.com/cosmos/cosmos-sdk/types/module"
|
|
14
|
+
|
|
15
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
16
|
+
abci "github.com/tendermint/tendermint/abci/types"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
// type check to ensure the interface is properly implemented
|
|
20
|
+
var (
|
|
21
|
+
_ module.AppModule = AppModule{}
|
|
22
|
+
_ module.AppModuleBasic = AppModuleBasic{}
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
// app module Basics object
|
|
26
|
+
type AppModuleBasic struct {
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func (AppModuleBasic) Name() string {
|
|
30
|
+
return ModuleName
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// RegisterInterfaces registers the module's interface types
|
|
37
|
+
func (b AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// DefaultGenesis returns default genesis state as raw bytes for the deployment
|
|
41
|
+
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
|
|
42
|
+
return cdc.MustMarshalJSON(DefaultGenesisState())
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Validation check of the Genesis
|
|
46
|
+
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error {
|
|
47
|
+
var data types.GenesisState
|
|
48
|
+
err := cdc.UnmarshalJSON(bz, &data)
|
|
49
|
+
if err != nil {
|
|
50
|
+
return err
|
|
51
|
+
}
|
|
52
|
+
// Once json successfully marshalled, passes along to genesis.go
|
|
53
|
+
return ValidateGenesis(&data)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Get the root query command of this module
|
|
60
|
+
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
|
|
61
|
+
return nil
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Get the root tx command of this module
|
|
65
|
+
func (AppModuleBasic) GetTxCmd() *cobra.Command {
|
|
66
|
+
return nil
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type AppModule struct {
|
|
70
|
+
AppModuleBasic
|
|
71
|
+
keeper Keeper
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// NewAppModule creates a new AppModule Object
|
|
75
|
+
func NewAppModule(k Keeper) AppModule {
|
|
76
|
+
am := AppModule{
|
|
77
|
+
AppModuleBasic: AppModuleBasic{},
|
|
78
|
+
keeper: k,
|
|
79
|
+
}
|
|
80
|
+
return am
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
func (AppModule) Name() string {
|
|
84
|
+
return ModuleName
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {}
|
|
88
|
+
|
|
89
|
+
func (am AppModule) Route() sdk.Route {
|
|
90
|
+
return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
func (am AppModule) QuerierRoute() string {
|
|
94
|
+
return ModuleName
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// LegacyQuerierHandler returns the sdk.Querier for module
|
|
98
|
+
func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
|
|
99
|
+
return nil
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
func (AppModule) ConsensusVersion() uint64 { return 1 }
|
|
106
|
+
|
|
107
|
+
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
|
|
111
|
+
// Prevent Cosmos SDK internal errors.
|
|
112
|
+
return []abci.ValidatorUpdate{}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
|
|
116
|
+
var genesisState types.GenesisState
|
|
117
|
+
cdc.MustUnmarshalJSON(data, &genesisState)
|
|
118
|
+
return InitGenesis(ctx, am.keeper, &genesisState)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
|
|
122
|
+
gs := ExportGenesis(ctx, am.keeper)
|
|
123
|
+
return cdc.MustMarshalJSON(gs)
|
|
124
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
package types
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"net/url"
|
|
6
|
+
"strings"
|
|
7
|
+
|
|
8
|
+
"github.com/cosmos/cosmos-sdk/codec"
|
|
9
|
+
|
|
10
|
+
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
|
|
11
|
+
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
|
|
12
|
+
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
|
|
13
|
+
ibcexported "github.com/cosmos/ibc-go/v6/modules/core/exported"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
type AddressRole string
|
|
17
|
+
|
|
18
|
+
const (
|
|
19
|
+
RoleSender AddressRole = "Sender"
|
|
20
|
+
RoleReceiver AddressRole = "Receiver"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
func trimSlashPrefix(s string) string {
|
|
24
|
+
return strings.TrimPrefix(s, "/")
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ExtractBaseAddress extracts the base address from a parameterized address.
|
|
28
|
+
// It removes all subpath and query components from addr.
|
|
29
|
+
func ExtractBaseAddress(addr string) (string, error) {
|
|
30
|
+
parsed, err := url.Parse(addr)
|
|
31
|
+
if err != nil {
|
|
32
|
+
return "", err
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Specify the fields and values we expect. Unspecified fields will only
|
|
36
|
+
// match if they are zero values in order to be robust against extensions to
|
|
37
|
+
// the url.URL struct.
|
|
38
|
+
//
|
|
39
|
+
// Remove leading slashes from the path fields so that only parsed relative
|
|
40
|
+
// paths match the expected test.
|
|
41
|
+
expected := url.URL{
|
|
42
|
+
Path: trimSlashPrefix(parsed.Path),
|
|
43
|
+
RawPath: trimSlashPrefix(parsed.RawPath),
|
|
44
|
+
RawQuery: parsed.RawQuery,
|
|
45
|
+
Fragment: parsed.Fragment,
|
|
46
|
+
RawFragment: parsed.RawFragment,
|
|
47
|
+
|
|
48
|
+
// Skip over parsing control flags.
|
|
49
|
+
ForceQuery: parsed.ForceQuery,
|
|
50
|
+
OmitHost: parsed.OmitHost,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if *parsed != expected {
|
|
54
|
+
return "", fmt.Errorf("address must be relative path with optional query and fragment, got %s", addr)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
baseAddr, _, _ := strings.Cut(expected.Path, "/")
|
|
58
|
+
if baseAddr == "" {
|
|
59
|
+
return "", fmt.Errorf("base address cannot be empty")
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return baseAddr, nil
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// extractBaseTransferData returns the base address from the transferData.Sender
|
|
66
|
+
// (if RoleSender) or transferData.Receiver (if RoleReceiver). Errors in
|
|
67
|
+
// determining the base address are ignored... we then assume the base address
|
|
68
|
+
// is exactly the original address. If newTransferData is not nil, it will be
|
|
69
|
+
// populated with a new FungibleTokenPacketData consisting of the role replaced
|
|
70
|
+
// with its base address.
|
|
71
|
+
func extractBaseTransferData(transferData transfertypes.FungibleTokenPacketData, role AddressRole, newTransferData *transfertypes.FungibleTokenPacketData) (string, error) {
|
|
72
|
+
var target string
|
|
73
|
+
sender := transferData.Sender
|
|
74
|
+
receiver := transferData.Receiver
|
|
75
|
+
|
|
76
|
+
switch role {
|
|
77
|
+
case RoleSender:
|
|
78
|
+
baseSender, err := ExtractBaseAddress(sender)
|
|
79
|
+
if err == nil {
|
|
80
|
+
sender = baseSender
|
|
81
|
+
}
|
|
82
|
+
target = sender
|
|
83
|
+
|
|
84
|
+
case RoleReceiver:
|
|
85
|
+
baseReceiver, err := ExtractBaseAddress(receiver)
|
|
86
|
+
if err == nil {
|
|
87
|
+
receiver = baseReceiver
|
|
88
|
+
}
|
|
89
|
+
target = receiver
|
|
90
|
+
|
|
91
|
+
default:
|
|
92
|
+
err := fmt.Errorf("invalid address role: %s", role)
|
|
93
|
+
return target, err
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if newTransferData == nil {
|
|
97
|
+
return target, nil
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Create the new transfer data.
|
|
101
|
+
*newTransferData = transfertypes.NewFungibleTokenPacketData(
|
|
102
|
+
transferData.Denom,
|
|
103
|
+
transferData.Amount,
|
|
104
|
+
sender, receiver,
|
|
105
|
+
transferData.Memo,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
return target, nil
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ExtractBaseAddressFromPacket returns the base address from a transfer
|
|
112
|
+
// packet's data, either Sender (if role is RoleSender) or Receiver (if role is
|
|
113
|
+
// RoleReceiver).
|
|
114
|
+
// Errors in determining the base address are ignored... we then assume the base
|
|
115
|
+
// address is exactly the original address.
|
|
116
|
+
// If newPacket is not nil, it is populated with a new transfer packet whose
|
|
117
|
+
// corresponding Sender or Receiver is replaced with the extracted base address.
|
|
118
|
+
func ExtractBaseAddressFromPacket(cdc codec.Codec, packet ibcexported.PacketI, role AddressRole, newPacket *channeltypes.Packet) (string, error) {
|
|
119
|
+
transferData := transfertypes.FungibleTokenPacketData{}
|
|
120
|
+
if err := cdc.UnmarshalJSON(packet.GetData(), &transferData); err != nil {
|
|
121
|
+
return "", err
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
var newTransferData *transfertypes.FungibleTokenPacketData
|
|
125
|
+
if newPacket != nil {
|
|
126
|
+
// Capture the transfer data for the new packet.
|
|
127
|
+
newTransferData = &transfertypes.FungibleTokenPacketData{}
|
|
128
|
+
}
|
|
129
|
+
target, err := extractBaseTransferData(transferData, role, newTransferData)
|
|
130
|
+
if err != nil {
|
|
131
|
+
return target, err
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if newPacket == nil {
|
|
135
|
+
return target, nil
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Create a new packet with the new transfer packet data.
|
|
139
|
+
// Re-serialize the packet data with the base addresses.
|
|
140
|
+
newData, err := cdc.MarshalJSON(newTransferData)
|
|
141
|
+
if err != nil {
|
|
142
|
+
return target, err
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Create the new packet.
|
|
146
|
+
th := packet.GetTimeoutHeight()
|
|
147
|
+
*newPacket = channeltypes.NewPacket(
|
|
148
|
+
newData, packet.GetSequence(),
|
|
149
|
+
packet.GetSourcePort(), packet.GetSourceChannel(),
|
|
150
|
+
packet.GetDestPort(), packet.GetDestChannel(),
|
|
151
|
+
clienttypes.NewHeight(th.GetRevisionNumber(), th.GetRevisionHeight()),
|
|
152
|
+
packet.GetTimeoutTimestamp(),
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
return target, nil
|
|
156
|
+
}
|