@agoric/cosmos 0.34.2-upgrade-16-dev-8879538.0 → 0.34.2-upgrade-16-dev-24665a9.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/app/app.go +121 -46
- package/cmd/agd/main.go +4 -4
- package/cmd/libdaemon/main.go +6 -6
- package/daemon/cmd/root.go +3 -7
- package/daemon/main.go +3 -2
- package/git-revision.txt +1 -1
- package/go.mod +3 -0
- package/go.sum +2 -2
- package/package.json +2 -2
- package/proto/agoric/vtransfer/genesis.proto +18 -0
- package/vm/client_test.go +6 -8
- package/vm/controller.go +3 -0
- package/vm/proto_json.go +38 -0
- package/vm/proto_json_test.go +103 -0
- package/x/swingset/alias.go +2 -0
- package/x/swingset/keeper/keeper.go +8 -20
- package/x/swingset/keeper/test_utils.go +16 -0
- package/x/swingset/module.go +7 -2
- package/x/swingset/testing/queue.go +17 -0
- package/x/swingset/types/msgs.go +19 -0
- package/x/vbank/genesis.go +0 -2
- package/x/vbank/types/msgs.go +0 -12
- package/x/vbank/vbank.go +6 -6
- package/x/vbank/vbank_test.go +2 -2
- package/x/vibc/alias.go +1 -1
- package/x/vibc/types/receiver.go +17 -7
- package/x/vlocalchain/handler.go +2 -1
- package/x/vlocalchain/keeper/keeper_test.go +66 -1
- package/x/vlocalchain/vlocalchain.go +26 -21
- package/x/vlocalchain/vlocalchain_test.go +133 -4
- package/x/vstorage/keeper/keeper.go +5 -5
- package/x/vstorage/testing/queue.go +27 -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 +448 -0
- package/x/vtransfer/keeper/keeper.go +281 -0
- package/x/vtransfer/module.go +124 -0
- package/x/vtransfer/types/expected_keepers.go +38 -0
- package/x/vtransfer/types/genesis.pb.go +327 -0
- package/x/vtransfer/types/key.go +9 -0
- package/x/vtransfer/types/msgs.go +9 -0
|
@@ -5,6 +5,7 @@ import (
|
|
|
5
5
|
"encoding/json"
|
|
6
6
|
"strings"
|
|
7
7
|
"testing"
|
|
8
|
+
"time"
|
|
8
9
|
|
|
9
10
|
"github.com/Agoric/agoric-sdk/golang/cosmos/app/params"
|
|
10
11
|
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
@@ -16,6 +17,7 @@ import (
|
|
|
16
17
|
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
17
18
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
18
19
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
20
|
+
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
19
21
|
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
|
|
20
22
|
"github.com/tendermint/tendermint/libs/log"
|
|
21
23
|
|
|
@@ -77,8 +79,36 @@ func (t *mockTransfer) Transfer(cctx context.Context, msg *transfertypes.MsgTran
|
|
|
77
79
|
return &transfertypes.MsgTransferResponse{Sequence: 1}, nil
|
|
78
80
|
}
|
|
79
81
|
|
|
82
|
+
type mockStaking struct {
|
|
83
|
+
stakingtypes.UnimplementedMsgServer
|
|
84
|
+
stakingtypes.UnimplementedQueryServer
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var _ stakingtypes.MsgServer = (*mockStaking)(nil)
|
|
88
|
+
var _ stakingtypes.QueryServer = (*mockStaking)(nil)
|
|
89
|
+
|
|
90
|
+
func (s *mockStaking) Undelegate(cctx context.Context, msg *stakingtypes.MsgUndelegate) (*stakingtypes.MsgUndelegateResponse, error) {
|
|
91
|
+
return &stakingtypes.MsgUndelegateResponse{CompletionTime: time.Now().UTC()}, nil
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
func (s *mockStaking) UnbondingDelegation(cctx context.Context, req *stakingtypes.QueryUnbondingDelegationRequest) (*stakingtypes.QueryUnbondingDelegationResponse, error) {
|
|
95
|
+
unbondingDelegation := stakingtypes.UnbondingDelegation{
|
|
96
|
+
DelegatorAddress: req.DelegatorAddr,
|
|
97
|
+
ValidatorAddress: "cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj",
|
|
98
|
+
Entries: []stakingtypes.UnbondingDelegationEntry{
|
|
99
|
+
{
|
|
100
|
+
CreationHeight: 100,
|
|
101
|
+
CompletionTime: time.Now().UTC().Add(time.Hour * 24 * 7),
|
|
102
|
+
InitialBalance: sdk.NewInt(1000),
|
|
103
|
+
Balance: sdk.NewInt(500),
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
return &stakingtypes.QueryUnbondingDelegationResponse{Unbond: unbondingDelegation}, nil
|
|
108
|
+
}
|
|
109
|
+
|
|
80
110
|
// makeTestKit creates a minimal Keeper and Context for use in testing.
|
|
81
|
-
func makeTestKit(bank *mockBank, transfer *mockTransfer) (vm.PortHandler, context.Context) {
|
|
111
|
+
func makeTestKit(bank *mockBank, transfer *mockTransfer, staking *mockStaking) (vm.PortHandler, context.Context) {
|
|
82
112
|
encodingConfig := params.MakeEncodingConfig()
|
|
83
113
|
cdc := encodingConfig.Marshaler
|
|
84
114
|
|
|
@@ -93,6 +123,10 @@ func makeTestKit(bank *mockBank, transfer *mockTransfer) (vm.PortHandler, contex
|
|
|
93
123
|
transfertypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
94
124
|
transfertypes.RegisterMsgServer(txRouter, transfer)
|
|
95
125
|
transfertypes.RegisterQueryServer(queryRouter, transfer)
|
|
126
|
+
stakingtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
127
|
+
stakingtypes.RegisterMsgServer(txRouter, staking)
|
|
128
|
+
stakingtypes.RegisterQueryServer(queryRouter, staking)
|
|
129
|
+
|
|
96
130
|
|
|
97
131
|
// create a new Keeper
|
|
98
132
|
keeper := vlocalchain.NewKeeper(cdc, vlocalchainStoreKey, txRouter, queryRouter)
|
|
@@ -118,7 +152,8 @@ func makeTestKit(bank *mockBank, transfer *mockTransfer) (vm.PortHandler, contex
|
|
|
118
152
|
func TestAllocateAddress(t *testing.T) {
|
|
119
153
|
bank := &mockBank{}
|
|
120
154
|
transfer := &mockTransfer{}
|
|
121
|
-
|
|
155
|
+
staking := &mockStaking{}
|
|
156
|
+
handler, cctx := makeTestKit(bank, transfer, staking)
|
|
122
157
|
|
|
123
158
|
addrs := map[string]bool{
|
|
124
159
|
firstAddr: false,
|
|
@@ -161,7 +196,8 @@ func TestQuery(t *testing.T) {
|
|
|
161
196
|
alreadyAddr: []sdk.Coin{sdk.NewCoin("stale", sdk.NewInt(321))},
|
|
162
197
|
}}
|
|
163
198
|
transfer := &mockTransfer{}
|
|
164
|
-
|
|
199
|
+
staking := &mockStaking{}
|
|
200
|
+
handler, cctx := makeTestKit(bank, transfer, staking)
|
|
165
201
|
|
|
166
202
|
// get balances
|
|
167
203
|
testCases := []struct {
|
|
@@ -230,6 +266,68 @@ func TestQuery(t *testing.T) {
|
|
|
230
266
|
}
|
|
231
267
|
})
|
|
232
268
|
}
|
|
269
|
+
|
|
270
|
+
t.Run("UnbondingDelegation", func(t *testing.T) {
|
|
271
|
+
// create a new message
|
|
272
|
+
msg := `{"type":"VLOCALCHAIN_QUERY_MANY","messages":[{"@type":"/cosmos.staking.v1beta1.QueryUnbondingDelegationRequest","delegator_addr":"` + firstAddr + `","validator_addr":"cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj"}]}`
|
|
273
|
+
t.Logf("query request: %v", msg)
|
|
274
|
+
ret, err := handler.Receive(cctx, msg)
|
|
275
|
+
t.Logf("query response: %v", ret)
|
|
276
|
+
if err != nil {
|
|
277
|
+
t.Fatalf("unexpected error: %v", err)
|
|
278
|
+
}
|
|
279
|
+
if ret == "" {
|
|
280
|
+
t.Fatalf("expected non-empty json")
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Unmarshal the JSON response
|
|
284
|
+
var respJSON []map[string]interface{}
|
|
285
|
+
if err := json.Unmarshal([]byte(ret), &respJSON); err != nil {
|
|
286
|
+
t.Fatalf("unexpected error unmarshalling JSON response: %v", err)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Check the response fields
|
|
290
|
+
if len(respJSON) != 1 {
|
|
291
|
+
t.Fatalf("expected 1 response, got %d", len(respJSON))
|
|
292
|
+
}
|
|
293
|
+
resp := respJSON[0]
|
|
294
|
+
|
|
295
|
+
replyAny, ok := resp["reply"].(map[string]interface{})
|
|
296
|
+
if !ok {
|
|
297
|
+
t.Fatalf("expected reply field to be a map, got %v", resp["reply"])
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
unbond, ok := replyAny["unbond"].(map[string]interface{})
|
|
301
|
+
if !ok {
|
|
302
|
+
t.Fatalf("expected unbond field to be a map, got %v", replyAny["unbond"])
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Check the field names and values
|
|
306
|
+
if unbond["delegatorAddress"] != firstAddr {
|
|
307
|
+
t.Errorf("expected delegatorAddress %s, got %v", firstAddr, unbond["delegator_address"])
|
|
308
|
+
}
|
|
309
|
+
if unbond["validatorAddress"] != "cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj" {
|
|
310
|
+
t.Errorf("expected validatorAddress cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj, got %v", unbond["validator_address"])
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
entries, ok := unbond["entries"].([]interface{})
|
|
314
|
+
if !ok || len(entries) != 1 {
|
|
315
|
+
t.Fatalf("expected 1 unbonding delegation entry, got %v", entries)
|
|
316
|
+
}
|
|
317
|
+
entry, ok := entries[0].(map[string]interface{})
|
|
318
|
+
if !ok {
|
|
319
|
+
t.Fatalf("expected unbonding delegation entry to be a map, got %v", entries[0])
|
|
320
|
+
}
|
|
321
|
+
if entry["creationHeight"] != "100" {
|
|
322
|
+
t.Errorf("expected creationHeight \"100\", got %v", entry["creation_height"])
|
|
323
|
+
}
|
|
324
|
+
if entry["balance"] != "500" {
|
|
325
|
+
t.Errorf("expected balance \"500\", got %v", entry["balance"])
|
|
326
|
+
}
|
|
327
|
+
if _, ok := entry["completionTime"]; !ok {
|
|
328
|
+
t.Error("expected completionTime field in the response")
|
|
329
|
+
}
|
|
330
|
+
})
|
|
233
331
|
}
|
|
234
332
|
|
|
235
333
|
func TestExecuteTx(t *testing.T) {
|
|
@@ -239,7 +337,8 @@ func TestExecuteTx(t *testing.T) {
|
|
|
239
337
|
alreadyAddr: []sdk.Coin{sdk.NewCoin("stale", sdk.NewInt(321))},
|
|
240
338
|
}}
|
|
241
339
|
transfer := &mockTransfer{}
|
|
242
|
-
|
|
340
|
+
staking := &mockStaking{}
|
|
341
|
+
handler, cctx := makeTestKit(bank, transfer, staking)
|
|
243
342
|
|
|
244
343
|
// create a new message
|
|
245
344
|
msg := `{"type":"VLOCALCHAIN_ALLOCATE_ADDRESS"}`
|
|
@@ -302,4 +401,34 @@ func TestExecuteTx(t *testing.T) {
|
|
|
302
401
|
}
|
|
303
402
|
})
|
|
304
403
|
}
|
|
404
|
+
|
|
405
|
+
t.Run("MsgUndelegate", func(t *testing.T) {
|
|
406
|
+
// create a new message
|
|
407
|
+
msg := `{"type":"VLOCALCHAIN_EXECUTE_TX","address":"` + addr +
|
|
408
|
+
`","messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegatorAddress":"` +
|
|
409
|
+
addr + `","validatorAddress":"cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj","amount":{"denom":"stake","amount":"100"}}]}`
|
|
410
|
+
|
|
411
|
+
ret, err := handler.Receive(cctx, msg)
|
|
412
|
+
if err != nil {
|
|
413
|
+
t.Fatalf("unexpected error: %s", err)
|
|
414
|
+
}
|
|
415
|
+
if ret == "" {
|
|
416
|
+
t.Fatalf("expected non-empty json")
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Unmarshal the response
|
|
420
|
+
var resp []map[string]interface{}
|
|
421
|
+
if err := json.Unmarshal([]byte(ret), &resp); err != nil {
|
|
422
|
+
t.Fatalf("unexpected error unmarshalling response: %v", err)
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Check the response fields
|
|
426
|
+
if len(resp) != 1 {
|
|
427
|
+
t.Fatalf("expected 1 response, got %d", len(resp))
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if _, ok := resp[0]["completionTime"]; !ok {
|
|
431
|
+
t.Error("expected 'completionTime' field in response")
|
|
432
|
+
}
|
|
433
|
+
})
|
|
305
434
|
}
|
|
@@ -421,7 +421,7 @@ func (k Keeper) GetNoDataValue() []byte {
|
|
|
421
421
|
return types.EncodedNoDataValue
|
|
422
422
|
}
|
|
423
423
|
|
|
424
|
-
func (k Keeper)
|
|
424
|
+
func (k Keeper) GetIntValue(ctx sdk.Context, path string) (sdkmath.Int, error) {
|
|
425
425
|
indexEntry := k.GetEntry(ctx, path)
|
|
426
426
|
if !indexEntry.HasValue() {
|
|
427
427
|
return sdk.NewInt(0), nil
|
|
@@ -435,11 +435,11 @@ func (k Keeper) getIntValue(ctx sdk.Context, path string) (sdkmath.Int, error) {
|
|
|
435
435
|
}
|
|
436
436
|
|
|
437
437
|
func (k Keeper) GetQueueLength(ctx sdk.Context, queuePath string) (sdkmath.Int, error) {
|
|
438
|
-
head, err := k.
|
|
438
|
+
head, err := k.GetIntValue(ctx, queuePath+".head")
|
|
439
439
|
if err != nil {
|
|
440
440
|
return sdkmath.NewInt(0), err
|
|
441
441
|
}
|
|
442
|
-
tail, err := k.
|
|
442
|
+
tail, err := k.GetIntValue(ctx, queuePath+".tail")
|
|
443
443
|
if err != nil {
|
|
444
444
|
return sdkmath.NewInt(0), err
|
|
445
445
|
}
|
|
@@ -450,12 +450,12 @@ func (k Keeper) GetQueueLength(ctx sdk.Context, queuePath string) (sdkmath.Int,
|
|
|
450
450
|
func (k Keeper) PushQueueItem(ctx sdk.Context, queuePath string, value string) error {
|
|
451
451
|
// Get the current queue tail, defaulting to zero if its vstorage doesn't exist.
|
|
452
452
|
// The `tail` is the value of the next index to be inserted
|
|
453
|
-
tail, err := k.
|
|
453
|
+
tail, err := k.GetIntValue(ctx, queuePath+".tail")
|
|
454
454
|
if err != nil {
|
|
455
455
|
return err
|
|
456
456
|
}
|
|
457
457
|
|
|
458
|
-
if tail.
|
|
458
|
+
if tail.GTE(MaxSDKInt) {
|
|
459
459
|
return errors.New(queuePath + " overflow")
|
|
460
460
|
}
|
|
461
461
|
nextTail := tail.Add(sdk.NewInt(1))
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
package testing
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
|
|
6
|
+
keeper "github.com/Agoric/agoric-sdk/golang/cosmos/x/vstorage/keeper"
|
|
7
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
func GetQueueItems(ctx sdk.Context, vstorageKeeper keeper.Keeper, queuePath string) ([]string, error) {
|
|
11
|
+
head, err := vstorageKeeper.GetIntValue(ctx, queuePath+".head")
|
|
12
|
+
if err != nil {
|
|
13
|
+
return nil, err
|
|
14
|
+
}
|
|
15
|
+
tail, err := vstorageKeeper.GetIntValue(ctx, queuePath+".tail")
|
|
16
|
+
if err != nil {
|
|
17
|
+
return nil, err
|
|
18
|
+
}
|
|
19
|
+
length := tail.Sub(head).Int64()
|
|
20
|
+
values := make([]string, length)
|
|
21
|
+
var i int64
|
|
22
|
+
for i = 0; i < length; i++ {
|
|
23
|
+
path := fmt.Sprintf("%s.%s", queuePath, head.Add(sdk.NewInt(i)).String())
|
|
24
|
+
values[i] = vstorageKeeper.GetEntry(ctx, path).StringValue()
|
|
25
|
+
}
|
|
26
|
+
return values, nil
|
|
27
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package vtransfer
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vtransfer/keeper"
|
|
5
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vtransfer/types"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
const (
|
|
9
|
+
ModuleName = types.ModuleName
|
|
10
|
+
StoreKey = types.StoreKey
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
type Keeper = keeper.Keeper
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
package vtransfer
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
|
|
6
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vtransfer/types"
|
|
7
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
8
|
+
abci "github.com/tendermint/tendermint/abci/types"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
func NewGenesisState() *types.GenesisState {
|
|
12
|
+
return &types.GenesisState{}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
func ValidateGenesis(data *types.GenesisState) error {
|
|
16
|
+
if data == nil {
|
|
17
|
+
return fmt.Errorf("vtransfer genesis data cannot be nil")
|
|
18
|
+
}
|
|
19
|
+
return nil
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
func DefaultGenesisState() *types.GenesisState {
|
|
23
|
+
return &types.GenesisState{}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
func InitGenesis(ctx sdk.Context, keeper Keeper, data *types.GenesisState) []abci.ValidatorUpdate {
|
|
27
|
+
keeper.SetWatchedAddresses(ctx, data.GetWatchedAddresses())
|
|
28
|
+
return []abci.ValidatorUpdate{}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
func ExportGenesis(ctx sdk.Context, k Keeper) *types.GenesisState {
|
|
32
|
+
var gs types.GenesisState
|
|
33
|
+
addresses, err := k.GetWatchedAddresses(ctx)
|
|
34
|
+
if err != nil {
|
|
35
|
+
panic(err)
|
|
36
|
+
}
|
|
37
|
+
gs.WatchedAddresses = addresses
|
|
38
|
+
return &gs
|
|
39
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package vtransfer
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
func TestDefaultGenesis(t *testing.T) {
|
|
8
|
+
defaultGenesisState := DefaultGenesisState()
|
|
9
|
+
if err := ValidateGenesis(defaultGenesisState); err != nil {
|
|
10
|
+
t.Errorf("DefaultGenesisState did not validate %v: %e", defaultGenesisState, err)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package vtransfer
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
|
|
6
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vtransfer/keeper"
|
|
7
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
8
|
+
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// NewHandler returns a handler for "vtransfer" type messages.
|
|
12
|
+
func NewHandler(keeper keeper.Keeper) sdk.Handler {
|
|
13
|
+
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
|
14
|
+
switch msg := msg.(type) {
|
|
15
|
+
default:
|
|
16
|
+
errMsg := fmt.Sprintf("Unrecognized vtransfer Msg type: %T", msg)
|
|
17
|
+
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
package vtransfer
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vtransfer/keeper"
|
|
5
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
6
|
+
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
|
7
|
+
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
|
|
8
|
+
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
|
|
9
|
+
porttypes "github.com/cosmos/ibc-go/v6/modules/core/05-port/types"
|
|
10
|
+
"github.com/cosmos/ibc-go/v6/modules/core/exported"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
// IBCMiddleware (https://ibc.cosmos.network/main/ibc/apps/ibcmodule) forwards
|
|
14
|
+
// most of its methods to the next layer in the stack (which may be the ibc-go
|
|
15
|
+
// transfer application or another middleware), but hooks the packet-related
|
|
16
|
+
// methods and sends them to vtransferKeeper for async interception by the
|
|
17
|
+
// associated VM:
|
|
18
|
+
//
|
|
19
|
+
// 1. IBCModule channel handshake callbacks (OnChanOpenInit, OnChanOpenTry,
|
|
20
|
+
// OnChanOpenAck, and OnChanOpenConfirm)—handled by the wrapped IBCModule.
|
|
21
|
+
//
|
|
22
|
+
// 2. IBCModule channel closing callbacks (OnChanCloseInit and
|
|
23
|
+
// OnChanCloseConfirm)—handled by the wrapped IBCModule.
|
|
24
|
+
//
|
|
25
|
+
// 3. IBCModule packet callbacks (OnRecvPacket, OnAcknowledgementPacket, and
|
|
26
|
+
// OnTimeoutPacket)—intercepted by vtransfer.
|
|
27
|
+
//
|
|
28
|
+
// 4. ICS4Wrapper packet initiation methods (SendPacket, WriteAcknowledgement
|
|
29
|
+
// and GetAppVersion)—delegated by vtransfer to vibc.
|
|
30
|
+
|
|
31
|
+
var _ porttypes.Middleware = (*IBCMiddleware)(nil)
|
|
32
|
+
|
|
33
|
+
// IBCMiddleware implements the ICS26 callbacks for the middleware given the
|
|
34
|
+
// underlying IBCModule and the keeper.
|
|
35
|
+
type IBCMiddleware struct {
|
|
36
|
+
ibcModule porttypes.IBCModule
|
|
37
|
+
vtransferKeeper keeper.Keeper
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// NewIBCMiddleware creates a new IBCMiddleware given the underlying IBCModule and keeper.
|
|
41
|
+
func NewIBCMiddleware(ibcModule porttypes.IBCModule, vtransferKeeper keeper.Keeper) IBCMiddleware {
|
|
42
|
+
return IBCMiddleware{
|
|
43
|
+
ibcModule: ibcModule,
|
|
44
|
+
vtransferKeeper: vtransferKeeper,
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
///////////////////////////////////
|
|
49
|
+
// The following channel handshake events are all directly forwarded to the
|
|
50
|
+
// wrapped IBCModule. They are not performed in the context of a packet, and so
|
|
51
|
+
// do not need to be intercepted.
|
|
52
|
+
|
|
53
|
+
// OnChanCloseInit implements the IBCModule interface.
|
|
54
|
+
func (im IBCMiddleware) OnChanOpenInit(
|
|
55
|
+
ctx sdk.Context,
|
|
56
|
+
order channeltypes.Order,
|
|
57
|
+
connectionHops []string,
|
|
58
|
+
portID string,
|
|
59
|
+
channelID string,
|
|
60
|
+
chanCap *capabilitytypes.Capability,
|
|
61
|
+
counterparty channeltypes.Counterparty,
|
|
62
|
+
version string,
|
|
63
|
+
) (string, error) {
|
|
64
|
+
return im.ibcModule.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// OnChanOpenTry implements the IBCModule interface.
|
|
68
|
+
func (im IBCMiddleware) OnChanOpenTry(
|
|
69
|
+
ctx sdk.Context,
|
|
70
|
+
order channeltypes.Order,
|
|
71
|
+
connectionHops []string,
|
|
72
|
+
portID,
|
|
73
|
+
channelID string,
|
|
74
|
+
chanCap *capabilitytypes.Capability,
|
|
75
|
+
counterparty channeltypes.Counterparty,
|
|
76
|
+
counterpartyVersion string,
|
|
77
|
+
) (string, error) {
|
|
78
|
+
return im.ibcModule.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, counterpartyVersion)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// OnChanOpenAck implements the IBCModule interface.
|
|
82
|
+
func (im IBCMiddleware) OnChanOpenAck(
|
|
83
|
+
ctx sdk.Context,
|
|
84
|
+
portID,
|
|
85
|
+
channelID string,
|
|
86
|
+
counterpartyChannelID string,
|
|
87
|
+
counterpartyVersion string,
|
|
88
|
+
) error {
|
|
89
|
+
return im.ibcModule.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// OnChanOpenConfirm implements the IBCModule interface.
|
|
93
|
+
func (im IBCMiddleware) OnChanOpenConfirm(
|
|
94
|
+
ctx sdk.Context,
|
|
95
|
+
portID,
|
|
96
|
+
channelID string,
|
|
97
|
+
) error {
|
|
98
|
+
return im.ibcModule.OnChanOpenConfirm(ctx, portID, channelID)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// OnChanCloseInit implements the IBCModule interface.
|
|
102
|
+
func (im IBCMiddleware) OnChanCloseInit(
|
|
103
|
+
ctx sdk.Context,
|
|
104
|
+
portID,
|
|
105
|
+
channelID string,
|
|
106
|
+
) error {
|
|
107
|
+
return im.ibcModule.OnChanCloseInit(ctx, portID, channelID)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// OnChanCloseConfirm implements the IBCModule interface.
|
|
111
|
+
func (im IBCMiddleware) OnChanCloseConfirm(
|
|
112
|
+
ctx sdk.Context,
|
|
113
|
+
portID,
|
|
114
|
+
channelID string,
|
|
115
|
+
) error {
|
|
116
|
+
return im.ibcModule.OnChanCloseConfirm(ctx, portID, channelID)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
///////////////////////////////////
|
|
120
|
+
// The following packet methods are all implemented by
|
|
121
|
+
// im.vtransferKeeper.Intercept*, so named because those methods are "tee"s
|
|
122
|
+
// combining the middleware stack with an interception of the packet event
|
|
123
|
+
// (On*Packet) or packet method (WriteAcknowledgment) by the async VM.
|
|
124
|
+
|
|
125
|
+
// OnRecvPacket implements the IBCModule interface.
|
|
126
|
+
func (im IBCMiddleware) OnRecvPacket(
|
|
127
|
+
ctx sdk.Context,
|
|
128
|
+
packet channeltypes.Packet,
|
|
129
|
+
relayer sdk.AccAddress,
|
|
130
|
+
) exported.Acknowledgement {
|
|
131
|
+
return im.vtransferKeeper.InterceptOnRecvPacket(ctx, im.ibcModule, packet, relayer)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// OnAcknowledgementPacket implements the IBCModule interface.
|
|
135
|
+
func (im IBCMiddleware) OnAcknowledgementPacket(
|
|
136
|
+
ctx sdk.Context,
|
|
137
|
+
packet channeltypes.Packet,
|
|
138
|
+
acknowledgement []byte,
|
|
139
|
+
relayer sdk.AccAddress,
|
|
140
|
+
) error {
|
|
141
|
+
return im.vtransferKeeper.InterceptOnAcknowledgementPacket(ctx, im.ibcModule, packet, acknowledgement, relayer)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// OnTimeoutPacket implements the IBCModule interface.
|
|
145
|
+
func (im IBCMiddleware) OnTimeoutPacket(
|
|
146
|
+
ctx sdk.Context,
|
|
147
|
+
packet channeltypes.Packet,
|
|
148
|
+
relayer sdk.AccAddress,
|
|
149
|
+
) error {
|
|
150
|
+
return im.vtransferKeeper.InterceptOnTimeoutPacket(ctx, im.ibcModule, packet, relayer)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// WriteAcknowledgement implements the ICS4 Wrapper interface.
|
|
154
|
+
// Unlike implementations of IBCModule interface methods, implementations of
|
|
155
|
+
// ICS4 Wrapper interface methods do not pass along the wrapped IBC module
|
|
156
|
+
// because they support packet initiation.
|
|
157
|
+
func (im IBCMiddleware) WriteAcknowledgement(
|
|
158
|
+
ctx sdk.Context,
|
|
159
|
+
chanCap *capabilitytypes.Capability,
|
|
160
|
+
packet exported.PacketI,
|
|
161
|
+
ack exported.Acknowledgement,
|
|
162
|
+
) error {
|
|
163
|
+
return im.vtransferKeeper.InterceptWriteAcknowledgement(ctx, chanCap, packet, ack)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
///////////////////////////////////
|
|
167
|
+
// The following methods are directly implemented by the ICS4Wrapper outside of
|
|
168
|
+
// us, whether the ibc-go stack or another middleware.
|
|
169
|
+
|
|
170
|
+
// SendPacket implements the ICS4 Wrapper interface.
|
|
171
|
+
func (im IBCMiddleware) SendPacket(
|
|
172
|
+
ctx sdk.Context,
|
|
173
|
+
chanCap *capabilitytypes.Capability,
|
|
174
|
+
sourcePort string,
|
|
175
|
+
sourceChannel string,
|
|
176
|
+
timeoutHeight clienttypes.Height,
|
|
177
|
+
timeoutTimestamp uint64,
|
|
178
|
+
data []byte,
|
|
179
|
+
) (uint64, error) {
|
|
180
|
+
return im.vtransferKeeper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// GetAppVersion implements the ICS4 Wrapper interface.
|
|
184
|
+
func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) {
|
|
185
|
+
return im.vtransferKeeper.GetAppVersion(ctx, portID, channelID)
|
|
186
|
+
}
|