@agoric/cosmos 0.34.2-upgrade-16-fi-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
package/vm/proto_json.go
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package vm
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
|
|
6
|
+
"github.com/gogo/protobuf/jsonpb"
|
|
7
|
+
"github.com/gogo/protobuf/proto"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// We need jsonpb for its access to the global registry.
|
|
11
|
+
var marshaller = jsonpb.Marshaler{EmitDefaults: true}
|
|
12
|
+
|
|
13
|
+
func ProtoJSONMarshal(val interface{}) ([]byte, error) {
|
|
14
|
+
if pm, ok := val.(proto.Message); ok {
|
|
15
|
+
var s string
|
|
16
|
+
s, err := marshaller.MarshalToString(pm)
|
|
17
|
+
return []byte(s), err
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Marshal a non-proto value to JSON.
|
|
21
|
+
return json.Marshal(val)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// ProtoJSONMarshalSlice marshals a slice of proto messages and non-proto values to
|
|
25
|
+
// a single JSON byte slice.
|
|
26
|
+
func ProtoJSONMarshalSlice(vals []interface{}) ([]byte, error) {
|
|
27
|
+
var err error
|
|
28
|
+
jsonSlice := make([]json.RawMessage, len(vals))
|
|
29
|
+
for i, val := range vals {
|
|
30
|
+
jsonSlice[i], err = ProtoJSONMarshal(val)
|
|
31
|
+
if err != nil {
|
|
32
|
+
return nil, err
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Marshal the JSON array to a single JSON byte slice.
|
|
37
|
+
return json.Marshal(jsonSlice)
|
|
38
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
package vm_test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"strings"
|
|
6
|
+
"testing"
|
|
7
|
+
|
|
8
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
9
|
+
|
|
10
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
11
|
+
|
|
12
|
+
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
13
|
+
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
func TestProtoJSONMarshal(t *testing.T) {
|
|
17
|
+
accAddr, err := sdk.AccAddressFromHexUnsafe("0123456789")
|
|
18
|
+
if err != nil {
|
|
19
|
+
panic(err)
|
|
20
|
+
}
|
|
21
|
+
valAddr, err := sdk.ValAddressFromHex("9876543210")
|
|
22
|
+
if err != nil {
|
|
23
|
+
panic(err)
|
|
24
|
+
}
|
|
25
|
+
coin := sdk.NewInt64Coin("uatom", 1234567)
|
|
26
|
+
|
|
27
|
+
testCases := []struct {
|
|
28
|
+
name string
|
|
29
|
+
create func() interface{}
|
|
30
|
+
expected string
|
|
31
|
+
}{
|
|
32
|
+
{
|
|
33
|
+
"nil",
|
|
34
|
+
func() interface{} {
|
|
35
|
+
return nil
|
|
36
|
+
},
|
|
37
|
+
`null`,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"primitive number",
|
|
41
|
+
func() interface{} {
|
|
42
|
+
return 12345
|
|
43
|
+
},
|
|
44
|
+
`12345`,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"MsgDelegate",
|
|
48
|
+
func() interface{} {
|
|
49
|
+
return stakingtypes.NewMsgDelegate(accAddr, valAddr, coin)
|
|
50
|
+
},
|
|
51
|
+
`{"delegatorAddress":"cosmos1qy352eufjjmc9c","validatorAddress":"cosmosvaloper1npm9gvss52mlmk","amount":{"denom":"uatom","amount":"1234567"}}`,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"QueryDenomOwnersResponse",
|
|
55
|
+
func() interface{} {
|
|
56
|
+
return &banktypes.QueryDenomOwnersResponse{
|
|
57
|
+
DenomOwners: []*banktypes.DenomOwner{
|
|
58
|
+
{
|
|
59
|
+
Address: accAddr.String(),
|
|
60
|
+
Balance: coin,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
Address: valAddr.String(),
|
|
64
|
+
Balance: coin.Add(coin),
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
`{"denomOwners":[{"address":"cosmos1qy352eufjjmc9c","balance":{"denom":"uatom","amount":"1234567"}},{"address":"cosmosvaloper1npm9gvss52mlmk","balance":{"denom":"uatom","amount":"2469134"}}],"pagination":null}`,
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for _, tc := range testCases {
|
|
74
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
75
|
+
val := tc.create()
|
|
76
|
+
bz, err := vm.ProtoJSONMarshal(val)
|
|
77
|
+
if err != nil {
|
|
78
|
+
t.Errorf("ProtoJSONMarshal of %q failed %v", val, err)
|
|
79
|
+
}
|
|
80
|
+
if !bytes.Equal(bz, []byte(tc.expected)) {
|
|
81
|
+
t.Errorf("ProtoJSONMarshal of %q returned %q, expected %q", val, string(bz), tc.expected)
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
t.Run("all in a slice", func(t *testing.T) {
|
|
87
|
+
vals := make([]interface{}, len(testCases))
|
|
88
|
+
expectedJson := make([]string, len(testCases))
|
|
89
|
+
for i, tc := range testCases {
|
|
90
|
+
vals[i] = tc.create()
|
|
91
|
+
expectedJson[i] = tc.expected
|
|
92
|
+
}
|
|
93
|
+
bz, err := vm.ProtoJSONMarshalSlice(vals)
|
|
94
|
+
if err != nil {
|
|
95
|
+
t.Errorf("ProtoJSONMarshalSlice of %q failed %v", vals, err)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
expected := "[" + strings.Join(expectedJson, ",") + "]"
|
|
99
|
+
if !bytes.Equal(bz, []byte(expected)) {
|
|
100
|
+
t.Errorf("ProtoJSONMarshalSlice of %q returned %q, expected %q", vals, string(bz), expected)
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
}
|
package/x/swingset/alias.go
CHANGED
|
@@ -24,6 +24,8 @@ type (
|
|
|
24
24
|
Keeper = keeper.Keeper
|
|
25
25
|
SwingStoreExportsHandler = keeper.SwingStoreExportsHandler
|
|
26
26
|
ExtensionSnapshotter = keeper.ExtensionSnapshotter
|
|
27
|
+
ActionContext = types.ActionContext
|
|
28
|
+
InboundQueueRecord = types.InboundQueueRecord
|
|
27
29
|
Egress = types.Egress
|
|
28
30
|
MsgDeliverInbound = types.MsgDeliverInbound
|
|
29
31
|
MsgProvision = types.MsgProvision
|
|
@@ -51,25 +51,6 @@ const (
|
|
|
51
51
|
swingStoreKeyPrefix = "swingStore."
|
|
52
52
|
)
|
|
53
53
|
|
|
54
|
-
// Contextual information about the message source of an action on an inbound queue.
|
|
55
|
-
// This context should be unique per inboundQueueRecord.
|
|
56
|
-
type actionContext struct {
|
|
57
|
-
// The block height in which the corresponding action was enqueued
|
|
58
|
-
BlockHeight int64 `json:"blockHeight"`
|
|
59
|
-
// The hash of the cosmos transaction that included the message
|
|
60
|
-
// If the action didn't result from a transaction message, a substitute value
|
|
61
|
-
// may be used. For example the VBANK_BALANCE_UPDATE actions use `x/vbank`.
|
|
62
|
-
TxHash string `json:"txHash"`
|
|
63
|
-
// The index of the message within the transaction. If the action didn't
|
|
64
|
-
// result from a cosmos transaction, a number should be chosen to make the
|
|
65
|
-
// actionContext unique. (for example a counter per block and source module).
|
|
66
|
-
MsgIdx int `json:"msgIdx"`
|
|
67
|
-
}
|
|
68
|
-
type inboundQueueRecord struct {
|
|
69
|
-
Action vm.Jsonable `json:"action"`
|
|
70
|
-
Context actionContext `json:"context"`
|
|
71
|
-
}
|
|
72
|
-
|
|
73
54
|
// Keeper maintains the link to data vstorage and exposes getter/setter methods for the various parts of the state machine
|
|
74
55
|
type Keeper struct {
|
|
75
56
|
storeKey storetypes.StoreKey
|
|
@@ -144,7 +125,14 @@ func (k Keeper) pushAction(ctx sdk.Context, inboundQueuePath string, action vm.A
|
|
|
144
125
|
if !txHashOk || !msgIdxOk {
|
|
145
126
|
stdlog.Printf("error while extracting context for action %q\n", action)
|
|
146
127
|
}
|
|
147
|
-
record :=
|
|
128
|
+
record := types.InboundQueueRecord{
|
|
129
|
+
Action: action,
|
|
130
|
+
Context: types.ActionContext{
|
|
131
|
+
BlockHeight: ctx.BlockHeight(),
|
|
132
|
+
TxHash: txHash,
|
|
133
|
+
MsgIdx: msgIdx,
|
|
134
|
+
},
|
|
135
|
+
}
|
|
148
136
|
bz, err := json.Marshal(record)
|
|
149
137
|
if err != nil {
|
|
150
138
|
return err
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package keeper
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
|
|
6
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vstorage"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// GetVstorageKeeper returns the vstorage keeper from the swingset keeper
|
|
10
|
+
// for testing purposes.
|
|
11
|
+
func GetVstorageKeeper(t *testing.T, k Keeper) vstorage.Keeper {
|
|
12
|
+
if t == nil {
|
|
13
|
+
panic("this function is reserved for testing")
|
|
14
|
+
}
|
|
15
|
+
return k.vstorageKeeper
|
|
16
|
+
}
|
package/x/swingset/module.go
CHANGED
|
@@ -99,6 +99,11 @@ func (AppModule) Name() string {
|
|
|
99
99
|
return ModuleName
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// For testing purposes
|
|
103
|
+
func (am *AppModule) SetSwingStoreExportDir(dir string) {
|
|
104
|
+
am.swingStoreExportDir = dir
|
|
105
|
+
}
|
|
106
|
+
|
|
102
107
|
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {}
|
|
103
108
|
|
|
104
109
|
func (am AppModule) Route() sdk.Route {
|
|
@@ -149,9 +154,9 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V
|
|
|
149
154
|
return []abci.ValidatorUpdate{}
|
|
150
155
|
}
|
|
151
156
|
|
|
152
|
-
func (am AppModule) checkSwingStoreExportSetup() {
|
|
157
|
+
func (am *AppModule) checkSwingStoreExportSetup() {
|
|
153
158
|
if am.swingStoreExportDir == "" {
|
|
154
|
-
|
|
159
|
+
am.swingStoreExportDir = "/tmp/swingset_export"
|
|
155
160
|
}
|
|
156
161
|
}
|
|
157
162
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package testing
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
|
|
6
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/keeper"
|
|
7
|
+
vstoragetesting "github.com/Agoric/agoric-sdk/golang/cosmos/x/vstorage/testing"
|
|
8
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// GetActionQueueRecords returns the records in the action queue.
|
|
12
|
+
// This is a testing utility function.
|
|
13
|
+
func GetActionQueueRecords(t *testing.T, ctx sdk.Context, swingsetKeeper keeper.Keeper) ([]string, error) {
|
|
14
|
+
vstorageKeeper := keeper.GetVstorageKeeper(t, swingsetKeeper)
|
|
15
|
+
actionQueueName := keeper.StoragePathActionQueue
|
|
16
|
+
return vstoragetesting.GetQueueItems(ctx, vstorageKeeper, actionQueueName)
|
|
17
|
+
}
|
package/x/swingset/types/msgs.go
CHANGED
|
@@ -29,6 +29,25 @@ var (
|
|
|
29
29
|
_ vm.ControllerAdmissionMsg = &MsgWalletSpendAction{}
|
|
30
30
|
)
|
|
31
31
|
|
|
32
|
+
// Contextual information about the message source of an action on an inbound queue.
|
|
33
|
+
// This context should be unique per inboundQueueRecord.
|
|
34
|
+
type ActionContext struct {
|
|
35
|
+
// The block height in which the corresponding action was enqueued
|
|
36
|
+
BlockHeight int64 `json:"blockHeight"`
|
|
37
|
+
// The hash of the cosmos transaction that included the message
|
|
38
|
+
// If the action didn't result from a transaction message, a substitute value
|
|
39
|
+
// may be used. For example the VBANK_BALANCE_UPDATE actions use `x/vbank`.
|
|
40
|
+
TxHash string `json:"txHash"`
|
|
41
|
+
// The index of the message within the transaction. If the action didn't
|
|
42
|
+
// result from a cosmos transaction, a number should be chosen to make the
|
|
43
|
+
// actionContext unique. (for example a counter per block and source module).
|
|
44
|
+
MsgIdx int `json:"msgIdx"`
|
|
45
|
+
}
|
|
46
|
+
type InboundQueueRecord struct {
|
|
47
|
+
Action vm.Jsonable `json:"action"`
|
|
48
|
+
Context ActionContext `json:"context"`
|
|
49
|
+
}
|
|
50
|
+
|
|
32
51
|
const (
|
|
33
52
|
// bundleUncompressedSizeLimit is the (exclusive) limit on uncompressed bundle size.
|
|
34
53
|
// We must ensure there is an exclusive int64 limit in order to detect an underflow.
|
package/x/vbank/genesis.go
CHANGED
package/x/vbank/types/msgs.go
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
1
|
package types
|
|
2
2
|
|
|
3
3
|
const RouterKey = ModuleName // this was defined in your key.go file
|
|
4
|
-
|
|
5
|
-
type VbankSingleBalanceUpdate struct {
|
|
6
|
-
Address string `json:"address"`
|
|
7
|
-
Denom string `json:"denom"`
|
|
8
|
-
Amount string `json:"amount"`
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type VbankBalanceUpdate struct {
|
|
12
|
-
Nonce uint64 `json:"nonce"`
|
|
13
|
-
Type string `json:"type"`
|
|
14
|
-
Updated []VbankSingleBalanceUpdate `json:"updated"`
|
|
15
|
-
}
|
package/x/vbank/vbank.go
CHANGED
|
@@ -34,14 +34,14 @@ func NewPortHandler(am AppModule, keeper Keeper) portHandler {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
type
|
|
37
|
+
type VbankSingleBalanceUpdate struct {
|
|
38
38
|
Address string `json:"address"`
|
|
39
39
|
Denom string `json:"denom"`
|
|
40
40
|
Amount string `json:"amount"`
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// Make vbankManyBalanceUpdates sortable
|
|
44
|
-
type vbankManyBalanceUpdates []
|
|
44
|
+
type vbankManyBalanceUpdates []VbankSingleBalanceUpdate
|
|
45
45
|
|
|
46
46
|
var _ sort.Interface = vbankManyBalanceUpdates{}
|
|
47
47
|
|
|
@@ -67,7 +67,7 @@ func (vbu vbankManyBalanceUpdates) Swap(i int, j int) {
|
|
|
67
67
|
vbu[i], vbu[j] = vbu[j], vbu[i]
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
type
|
|
70
|
+
type VbankBalanceUpdate struct {
|
|
71
71
|
*vm.ActionHeader `actionType:"VBANK_BALANCE_UPDATE"`
|
|
72
72
|
Nonce uint64 `json:"nonce"`
|
|
73
73
|
Updated vbankManyBalanceUpdates `json:"updated"`
|
|
@@ -83,9 +83,9 @@ func getBalanceUpdate(ctx sdk.Context, keeper Keeper, addressToUpdate map[string
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
nonce := keeper.GetNextSequence(ctx)
|
|
86
|
-
event :=
|
|
86
|
+
event := VbankBalanceUpdate{
|
|
87
87
|
Nonce: nonce,
|
|
88
|
-
Updated: make([]
|
|
88
|
+
Updated: make([]VbankSingleBalanceUpdate, 0, nentries),
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// Note that Golang randomises the order of iteration, so we have to sort
|
|
@@ -99,7 +99,7 @@ func getBalanceUpdate(ctx sdk.Context, keeper Keeper, addressToUpdate map[string
|
|
|
99
99
|
for _, coin := range coins {
|
|
100
100
|
// generate an update even when the current balance is zero
|
|
101
101
|
balance := keeper.GetBalance(ctx, account, coin.Denom)
|
|
102
|
-
update :=
|
|
102
|
+
update := VbankSingleBalanceUpdate{
|
|
103
103
|
Address: address,
|
|
104
104
|
Denom: coin.Denom,
|
|
105
105
|
Amount: balance.Amount.String(),
|
package/x/vbank/vbank_test.go
CHANGED
|
@@ -71,7 +71,7 @@ func newBalances(opts ...balancesOption) balances {
|
|
|
71
71
|
return bal
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
func validateBalanceUpdate(vbu
|
|
74
|
+
func validateBalanceUpdate(vbu VbankBalanceUpdate) error {
|
|
75
75
|
if vbu.Type != "VBANK_BALANCE_UPDATE" {
|
|
76
76
|
return fmt.Errorf("bad balance update type: %s", vbu.Type)
|
|
77
77
|
}
|
|
@@ -89,7 +89,7 @@ func decodeBalances(encoded []byte) (balances, uint64, error) {
|
|
|
89
89
|
if encoded == nil {
|
|
90
90
|
return nil, 0, nil
|
|
91
91
|
}
|
|
92
|
-
balanceUpdate :=
|
|
92
|
+
balanceUpdate := VbankBalanceUpdate{}
|
|
93
93
|
err := json.Unmarshal(encoded, &balanceUpdate)
|
|
94
94
|
if err != nil {
|
|
95
95
|
return nil, 0, err
|
package/x/vibc/alias.go
CHANGED
package/x/vibc/types/receiver.go
CHANGED
|
@@ -14,7 +14,7 @@ import (
|
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
var (
|
|
17
|
-
_ vm.PortHandler = Receiver
|
|
17
|
+
_ vm.PortHandler = (*Receiver)(nil)
|
|
18
18
|
_ exported.Acknowledgement = (*rawAcknowledgement)(nil)
|
|
19
19
|
)
|
|
20
20
|
|
|
@@ -83,18 +83,28 @@ func (r rawAcknowledgement) Success() bool {
|
|
|
83
83
|
return true
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
// Receive implements vm.PortHandler. It unmarshals the string as JSON text
|
|
87
|
+
// representing an IBC portMessage object. If the resulting type is
|
|
88
|
+
// "IBC_METHOD" it dispatches on method ("sendPacket"/"receiveExecuted"/etc.)
|
|
89
|
+
// and calls the corresponding method of the wrapped ReceiverImpl.
|
|
90
|
+
//
|
|
91
|
+
// Otherwise, it requires the wrapped ReceiverImpl to be a vm.PortHandler
|
|
92
|
+
// and delegates to the Receive method of that PortHandler.
|
|
93
|
+
func (ir Receiver) Receive(cctx context.Context, jsonRequest string) (jsonReply string, err error) {
|
|
87
94
|
ctx := sdk.UnwrapSDKContext(cctx)
|
|
88
95
|
impl := ir.impl
|
|
89
96
|
|
|
90
97
|
msg := new(portMessage)
|
|
91
|
-
err = json.Unmarshal([]byte(
|
|
98
|
+
err = json.Unmarshal([]byte(jsonRequest), &msg)
|
|
92
99
|
if err != nil {
|
|
93
100
|
return "", err
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
if msg.Type != "IBC_METHOD" {
|
|
97
|
-
|
|
104
|
+
if receiver, ok := impl.(vm.PortHandler); ok {
|
|
105
|
+
return receiver.Receive(cctx, jsonRequest)
|
|
106
|
+
}
|
|
107
|
+
return "", fmt.Errorf(`channel handler only accepts messages of "type": "IBC_METHOD"; got %q`, msg.Type)
|
|
98
108
|
}
|
|
99
109
|
|
|
100
110
|
switch msg.Method {
|
|
@@ -116,7 +126,7 @@ func (ir Receiver) Receive(cctx context.Context, str string) (ret string, err er
|
|
|
116
126
|
packet.Sequence = seq
|
|
117
127
|
bytes, err := json.Marshal(&packet)
|
|
118
128
|
if err == nil {
|
|
119
|
-
|
|
129
|
+
jsonReply = string(bytes)
|
|
120
130
|
}
|
|
121
131
|
}
|
|
122
132
|
|
|
@@ -153,8 +163,8 @@ func (ir Receiver) Receive(cctx context.Context, str string) (ret string, err er
|
|
|
153
163
|
err = fmt.Errorf("unrecognized method %s", msg.Method)
|
|
154
164
|
}
|
|
155
165
|
|
|
156
|
-
if
|
|
157
|
-
|
|
166
|
+
if jsonReply == "" && err == nil {
|
|
167
|
+
jsonReply = "true"
|
|
158
168
|
}
|
|
159
169
|
return
|
|
160
170
|
}
|
package/x/vlocalchain/handler.go
CHANGED
|
@@ -3,6 +3,7 @@ package vlocalchain
|
|
|
3
3
|
import (
|
|
4
4
|
"fmt"
|
|
5
5
|
|
|
6
|
+
sdkioerrors "cosmossdk.io/errors"
|
|
6
7
|
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain/keeper"
|
|
7
8
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
8
9
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
@@ -14,7 +15,7 @@ func NewHandler(keeper keeper.Keeper) sdk.Handler {
|
|
|
14
15
|
switch msg := msg.(type) {
|
|
15
16
|
default:
|
|
16
17
|
errMsg := fmt.Sprintf("Unrecognized vlocalchain Msg type: %T", msg)
|
|
17
|
-
return nil,
|
|
18
|
+
return nil, sdkioerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
package keeper
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
|
|
6
|
+
"github.com/stretchr/testify/require"
|
|
7
|
+
|
|
8
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/app/params"
|
|
9
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
10
|
+
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
11
|
+
)
|
|
12
|
+
|
|
4
13
|
|
|
5
14
|
func TestKeeper_ParseRequestTypeURL(t *testing.T) {
|
|
6
15
|
testCases := []struct {
|
|
@@ -30,3 +39,59 @@ func TestKeeper_ParseRequestTypeURL(t *testing.T) {
|
|
|
30
39
|
})
|
|
31
40
|
}
|
|
32
41
|
}
|
|
42
|
+
|
|
43
|
+
func TestKeeper_DeserializeTxMessages(t *testing.T) {
|
|
44
|
+
encodingConfig := params.MakeEncodingConfig()
|
|
45
|
+
cdc := encodingConfig.Marshaler
|
|
46
|
+
|
|
47
|
+
banktypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
48
|
+
|
|
49
|
+
keeper := NewKeeper(cdc, nil, nil, nil)
|
|
50
|
+
|
|
51
|
+
expectedMsgSend := []sdk.Msg{
|
|
52
|
+
&banktypes.MsgSend{
|
|
53
|
+
FromAddress: "cosmos1abc",
|
|
54
|
+
ToAddress: "cosmos1xyz",
|
|
55
|
+
Amount: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100))),
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
testCases := []struct {
|
|
60
|
+
name string
|
|
61
|
+
json string
|
|
62
|
+
expected []sdk.Msg
|
|
63
|
+
wantErr bool
|
|
64
|
+
}{
|
|
65
|
+
{
|
|
66
|
+
name: "camelCase keys",
|
|
67
|
+
json: `{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","fromAddress":"cosmos1abc","toAddress":"cosmos1xyz","amount":[{"denom":"stake","amount":"100"}]}]}`,
|
|
68
|
+
expected: expectedMsgSend,
|
|
69
|
+
wantErr: false,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "snake_case keys",
|
|
73
|
+
json: `{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1abc","to_address":"cosmos1xyz","amount":[{"denom":"stake","amount":"100"}]}]}`,
|
|
74
|
+
expected: expectedMsgSend,
|
|
75
|
+
wantErr: false,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "misspelled key",
|
|
79
|
+
json: `{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_addresss":"cosmos1abc","to_address":"cosmos1xyz","amount":[{"denom":"stake","amount":"100"}]}]}`,
|
|
80
|
+
expected: expectedMsgSend,
|
|
81
|
+
wantErr: true,
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for _, tc := range testCases {
|
|
86
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
87
|
+
msgs, err := keeper.DeserializeTxMessages([]byte(tc.json))
|
|
88
|
+
|
|
89
|
+
if tc.wantErr {
|
|
90
|
+
require.Error(t, err)
|
|
91
|
+
} else {
|
|
92
|
+
require.NoError(t, err)
|
|
93
|
+
require.Equal(t, tc.expected, msgs)
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -6,7 +6,6 @@ import (
|
|
|
6
6
|
"fmt"
|
|
7
7
|
|
|
8
8
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
9
|
-
"github.com/gogo/protobuf/jsonpb"
|
|
10
9
|
|
|
11
10
|
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
12
11
|
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain/keeper"
|
|
@@ -56,28 +55,36 @@ func (h portHandler) Receive(cctx context.Context, str string) (ret string, err
|
|
|
56
55
|
return
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
var s string
|
|
63
|
-
resps := make([]json.RawMessage, len(qms))
|
|
58
|
+
var errs []error
|
|
59
|
+
resps := make([]interface{}, len(qms))
|
|
64
60
|
for i, qm := range qms {
|
|
65
61
|
var qr *types.QueryResponse
|
|
66
62
|
qr, err = h.keeper.Query(cctx, qm)
|
|
67
|
-
if err
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
if err == nil {
|
|
64
|
+
// Only fill out the response if the query was successful.
|
|
65
|
+
resps[i] = qr
|
|
66
|
+
} else {
|
|
67
|
+
errs = append(errs, err) // Accumulate errors
|
|
68
|
+
resps[i] = &types.QueryResponse{Error: err.Error()}
|
|
72
69
|
}
|
|
73
|
-
resps[i] = []byte(s)
|
|
74
70
|
}
|
|
75
71
|
|
|
76
|
-
|
|
77
|
-
if
|
|
78
|
-
return
|
|
72
|
+
bz, err := vm.ProtoJSONMarshalSlice(resps)
|
|
73
|
+
if err != nil {
|
|
74
|
+
return "", err
|
|
79
75
|
}
|
|
80
|
-
|
|
76
|
+
|
|
77
|
+
switch len(errs) {
|
|
78
|
+
case 0:
|
|
79
|
+
err = nil
|
|
80
|
+
case 1:
|
|
81
|
+
err = errs[0]
|
|
82
|
+
case len(resps):
|
|
83
|
+
err = fmt.Errorf("all queries in batch failed: %v", errs)
|
|
84
|
+
default:
|
|
85
|
+
// Let them inspect the individual errors manually.
|
|
86
|
+
}
|
|
87
|
+
return string(bz), err
|
|
81
88
|
|
|
82
89
|
case "VLOCALCHAIN_EXECUTE_TX":
|
|
83
90
|
origCtx := sdk.UnwrapSDKContext(cctx)
|
|
@@ -97,11 +104,9 @@ func (h portHandler) Receive(cctx context.Context, str string) (ret string, err
|
|
|
97
104
|
return
|
|
98
105
|
}
|
|
99
106
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
ret = string(bz)
|
|
107
|
+
// Marshal the responses to proto3 JSON.
|
|
108
|
+
bz, e := vm.ProtoJSONMarshalSlice(resps)
|
|
109
|
+
return string(bz), e
|
|
105
110
|
default:
|
|
106
111
|
err = fmt.Errorf("unrecognized message type %s", msg.Type)
|
|
107
112
|
}
|