@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
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
|
}
|
|
@@ -28,6 +28,7 @@ type Keeper struct {
|
|
|
28
28
|
cdc codec.Codec
|
|
29
29
|
msgRouter types.MsgRouter
|
|
30
30
|
queryRouter types.GRPCQueryRouter
|
|
31
|
+
acctKeeper types.AccountKeeper
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
// NewKeeper creates a new dIBC Keeper instance
|
|
@@ -36,12 +37,14 @@ func NewKeeper(
|
|
|
36
37
|
key storetypes.StoreKey,
|
|
37
38
|
msgRouter types.MsgRouter,
|
|
38
39
|
queryRouter types.GRPCQueryRouter,
|
|
40
|
+
acctKeeper types.AccountKeeper,
|
|
39
41
|
) Keeper {
|
|
40
42
|
return Keeper{
|
|
41
43
|
key: key,
|
|
42
44
|
cdc: cdc,
|
|
43
45
|
msgRouter: msgRouter,
|
|
44
46
|
queryRouter: queryRouter,
|
|
47
|
+
acctKeeper: acctKeeper,
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -266,14 +269,27 @@ func (k Keeper) AllocateAddress(cctx context.Context) sdk.AccAddress {
|
|
|
266
269
|
localchainModuleAcc := sdkaddress.Module(types.ModuleName, []byte("localchain"))
|
|
267
270
|
header := ctx.BlockHeader()
|
|
268
271
|
|
|
269
|
-
//
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
// Loop until we find an unused address.
|
|
273
|
+
for {
|
|
274
|
+
// Increment our sequence number.
|
|
275
|
+
seq := store.Get(types.KeyLastSequence)
|
|
276
|
+
seq = types.NextSequence(seq)
|
|
277
|
+
store.Set(types.KeyLastSequence, seq)
|
|
273
278
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
279
|
+
buf := seq
|
|
280
|
+
buf = append(buf, header.AppHash...)
|
|
281
|
+
buf = append(buf, header.DataHash...)
|
|
277
282
|
|
|
278
|
-
|
|
283
|
+
addr := sdkaddress.Derive(localchainModuleAcc, buf)
|
|
284
|
+
if k.acctKeeper.HasAccount(ctx, addr) {
|
|
285
|
+
continue
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// We found an unused address, so create an account for it.
|
|
289
|
+
acct := k.acctKeeper.NewAccountWithAddress(ctx, addr)
|
|
290
|
+
k.acctKeeper.SetAccount(ctx, acct)
|
|
291
|
+
|
|
292
|
+
// All good, return the address.
|
|
293
|
+
return addr
|
|
294
|
+
}
|
|
279
295
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
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
|
+
)
|
|
4
12
|
|
|
5
13
|
func TestKeeper_ParseRequestTypeURL(t *testing.T) {
|
|
6
14
|
testCases := []struct {
|
|
@@ -30,3 +38,59 @@ func TestKeeper_ParseRequestTypeURL(t *testing.T) {
|
|
|
30
38
|
})
|
|
31
39
|
}
|
|
32
40
|
}
|
|
41
|
+
|
|
42
|
+
func TestKeeper_DeserializeTxMessages(t *testing.T) {
|
|
43
|
+
encodingConfig := params.MakeEncodingConfig()
|
|
44
|
+
cdc := encodingConfig.Marshaler
|
|
45
|
+
|
|
46
|
+
banktypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
47
|
+
|
|
48
|
+
keeper := NewKeeper(cdc, nil, nil, nil, nil)
|
|
49
|
+
|
|
50
|
+
expectedMsgSend := []sdk.Msg{
|
|
51
|
+
&banktypes.MsgSend{
|
|
52
|
+
FromAddress: "cosmos1abc",
|
|
53
|
+
ToAddress: "cosmos1xyz",
|
|
54
|
+
Amount: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100))),
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
testCases := []struct {
|
|
59
|
+
name string
|
|
60
|
+
json string
|
|
61
|
+
expected []sdk.Msg
|
|
62
|
+
wantErr bool
|
|
63
|
+
}{
|
|
64
|
+
{
|
|
65
|
+
name: "camelCase keys",
|
|
66
|
+
json: `{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","fromAddress":"cosmos1abc","toAddress":"cosmos1xyz","amount":[{"denom":"stake","amount":"100"}]}]}`,
|
|
67
|
+
expected: expectedMsgSend,
|
|
68
|
+
wantErr: false,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "snake_case keys",
|
|
72
|
+
json: `{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1abc","to_address":"cosmos1xyz","amount":[{"denom":"stake","amount":"100"}]}]}`,
|
|
73
|
+
expected: expectedMsgSend,
|
|
74
|
+
wantErr: false,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "misspelled key",
|
|
78
|
+
json: `{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_addresss":"cosmos1abc","to_address":"cosmos1xyz","amount":[{"denom":"stake","amount":"100"}]}]}`,
|
|
79
|
+
expected: expectedMsgSend,
|
|
80
|
+
wantErr: true,
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for _, tc := range testCases {
|
|
85
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
86
|
+
msgs, err := keeper.DeserializeTxMessages([]byte(tc.json))
|
|
87
|
+
|
|
88
|
+
if tc.wantErr {
|
|
89
|
+
require.Error(t, err)
|
|
90
|
+
} else {
|
|
91
|
+
require.NoError(t, err)
|
|
92
|
+
require.Equal(t, tc.expected, msgs)
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package types
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
5
|
+
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
type AccountKeeper interface {
|
|
9
|
+
NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
|
|
10
|
+
HasAccount(ctx sdk.Context, addr sdk.AccAddress) bool
|
|
11
|
+
SetAccount(ctx sdk.Context, acc authtypes.AccountI)
|
|
12
|
+
}
|
|
@@ -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"
|
|
@@ -45,7 +44,7 @@ func (h portHandler) Receive(cctx context.Context, str string) (ret string, err
|
|
|
45
44
|
}
|
|
46
45
|
ret = string(bz)
|
|
47
46
|
|
|
48
|
-
case "
|
|
47
|
+
case "VLOCALCHAIN_QUERY_MANY":
|
|
49
48
|
// Copy the JSON messages string into a CosmosTx object so we can
|
|
50
49
|
// deserialize it with just proto3 JSON.
|
|
51
50
|
cosmosTxBz := []byte(`{"messages":` + string(msg.Messages) + `}`)
|
|
@@ -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
|
}
|
|
@@ -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"
|
|
@@ -15,7 +16,9 @@ import (
|
|
|
15
16
|
"github.com/cosmos/cosmos-sdk/store"
|
|
16
17
|
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
17
18
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
19
|
+
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
18
20
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
21
|
+
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
19
22
|
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
|
|
20
23
|
"github.com/tendermint/tendermint/libs/log"
|
|
21
24
|
|
|
@@ -34,6 +37,25 @@ const (
|
|
|
34
37
|
msgAllocateAddress = `{"type":"VLOCALCHAIN_ALLOCATE_ADDRESS"}`
|
|
35
38
|
)
|
|
36
39
|
|
|
40
|
+
type mockAccounts struct {
|
|
41
|
+
existing map[string]bool
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var _ types.AccountKeeper = (*mockAccounts)(nil)
|
|
45
|
+
|
|
46
|
+
func (a *mockAccounts) NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI {
|
|
47
|
+
return authtypes.NewBaseAccountWithAddress(addr)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func (a *mockAccounts) HasAccount(ctx sdk.Context, addr sdk.AccAddress) bool {
|
|
51
|
+
existing := a.existing[addr.String()]
|
|
52
|
+
return existing
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
func (a *mockAccounts) SetAccount(ctx sdk.Context, acc authtypes.AccountI) {
|
|
56
|
+
a.existing[acc.GetAddress().String()] = true
|
|
57
|
+
}
|
|
58
|
+
|
|
37
59
|
type mockBank struct {
|
|
38
60
|
banktypes.UnimplementedQueryServer
|
|
39
61
|
banktypes.UnimplementedMsgServer
|
|
@@ -77,8 +99,36 @@ func (t *mockTransfer) Transfer(cctx context.Context, msg *transfertypes.MsgTran
|
|
|
77
99
|
return &transfertypes.MsgTransferResponse{Sequence: 1}, nil
|
|
78
100
|
}
|
|
79
101
|
|
|
102
|
+
type mockStaking struct {
|
|
103
|
+
stakingtypes.UnimplementedMsgServer
|
|
104
|
+
stakingtypes.UnimplementedQueryServer
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
var _ stakingtypes.MsgServer = (*mockStaking)(nil)
|
|
108
|
+
var _ stakingtypes.QueryServer = (*mockStaking)(nil)
|
|
109
|
+
|
|
110
|
+
func (s *mockStaking) Undelegate(cctx context.Context, msg *stakingtypes.MsgUndelegate) (*stakingtypes.MsgUndelegateResponse, error) {
|
|
111
|
+
return &stakingtypes.MsgUndelegateResponse{CompletionTime: time.Now().UTC()}, nil
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
func (s *mockStaking) UnbondingDelegation(cctx context.Context, req *stakingtypes.QueryUnbondingDelegationRequest) (*stakingtypes.QueryUnbondingDelegationResponse, error) {
|
|
115
|
+
unbondingDelegation := stakingtypes.UnbondingDelegation{
|
|
116
|
+
DelegatorAddress: req.DelegatorAddr,
|
|
117
|
+
ValidatorAddress: "cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj",
|
|
118
|
+
Entries: []stakingtypes.UnbondingDelegationEntry{
|
|
119
|
+
{
|
|
120
|
+
CreationHeight: 100,
|
|
121
|
+
CompletionTime: time.Now().UTC().Add(time.Hour * 24 * 7),
|
|
122
|
+
InitialBalance: sdk.NewInt(1000),
|
|
123
|
+
Balance: sdk.NewInt(500),
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
return &stakingtypes.QueryUnbondingDelegationResponse{Unbond: unbondingDelegation}, nil
|
|
128
|
+
}
|
|
129
|
+
|
|
80
130
|
// makeTestKit creates a minimal Keeper and Context for use in testing.
|
|
81
|
-
func makeTestKit(bank *mockBank, transfer *mockTransfer) (vm.PortHandler, context.Context) {
|
|
131
|
+
func makeTestKit(bank *mockBank, transfer *mockTransfer, staking *mockStaking, accts *mockAccounts) (vm.PortHandler, context.Context) {
|
|
82
132
|
encodingConfig := params.MakeEncodingConfig()
|
|
83
133
|
cdc := encodingConfig.Marshaler
|
|
84
134
|
|
|
@@ -93,9 +143,12 @@ func makeTestKit(bank *mockBank, transfer *mockTransfer) (vm.PortHandler, contex
|
|
|
93
143
|
transfertypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
94
144
|
transfertypes.RegisterMsgServer(txRouter, transfer)
|
|
95
145
|
transfertypes.RegisterQueryServer(queryRouter, transfer)
|
|
146
|
+
stakingtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
147
|
+
stakingtypes.RegisterMsgServer(txRouter, staking)
|
|
148
|
+
stakingtypes.RegisterQueryServer(queryRouter, staking)
|
|
96
149
|
|
|
97
150
|
// create a new Keeper
|
|
98
|
-
keeper := vlocalchain.NewKeeper(cdc, vlocalchainStoreKey, txRouter, queryRouter)
|
|
151
|
+
keeper := vlocalchain.NewKeeper(cdc, vlocalchainStoreKey, txRouter, queryRouter, accts)
|
|
99
152
|
|
|
100
153
|
db := dbm.NewMemDB()
|
|
101
154
|
ms := store.NewCommitMultiStore(db)
|
|
@@ -118,13 +171,16 @@ func makeTestKit(bank *mockBank, transfer *mockTransfer) (vm.PortHandler, contex
|
|
|
118
171
|
func TestAllocateAddress(t *testing.T) {
|
|
119
172
|
bank := &mockBank{}
|
|
120
173
|
transfer := &mockTransfer{}
|
|
121
|
-
|
|
174
|
+
staking := &mockStaking{}
|
|
175
|
+
acct := &mockAccounts{existing: map[string]bool{
|
|
176
|
+
firstAddr: true,
|
|
177
|
+
"cosmos1c5hplwyxk5jr2dsygjqepzfqvfukwduq9c4660aah76krf99m6gs0k7hvl": true,
|
|
178
|
+
}}
|
|
179
|
+
handler, cctx := makeTestKit(bank, transfer, staking, acct)
|
|
122
180
|
|
|
123
181
|
addrs := map[string]bool{
|
|
124
|
-
firstAddr: false,
|
|
125
182
|
"cosmos1yj40fakym8kf4wvgz9tky7k9f3v9msm3t7frscrmkjsdkxkpsfkqgeczkg": false,
|
|
126
183
|
"cosmos1s76vryj7m8k8nm9le65a4plhf5rym5sumtt2n0vwnk5l6k4cwuhsj56ujj": false,
|
|
127
|
-
"cosmos1c5hplwyxk5jr2dsygjqepzfqvfukwduq9c4660aah76krf99m6gs0k7hvl": false,
|
|
128
184
|
"cosmos1ys3a7mtna3cad0wxcs4ddukn37stexjdvns8jfdn4uerlr95y4xqnrypf6": false,
|
|
129
185
|
}
|
|
130
186
|
numToTest := len(addrs)
|
|
@@ -150,6 +206,9 @@ func TestAllocateAddress(t *testing.T) {
|
|
|
150
206
|
t.Fatalf("unexpected duplicate address[%d]: %v", i, addr)
|
|
151
207
|
}
|
|
152
208
|
addrs[addr] = true
|
|
209
|
+
if !acct.existing[addr] {
|
|
210
|
+
t.Fatalf("expected address[%d]: %v to be added to accounts", i, addr)
|
|
211
|
+
}
|
|
153
212
|
}
|
|
154
213
|
}
|
|
155
214
|
|
|
@@ -161,7 +220,9 @@ func TestQuery(t *testing.T) {
|
|
|
161
220
|
alreadyAddr: []sdk.Coin{sdk.NewCoin("stale", sdk.NewInt(321))},
|
|
162
221
|
}}
|
|
163
222
|
transfer := &mockTransfer{}
|
|
164
|
-
|
|
223
|
+
staking := &mockStaking{}
|
|
224
|
+
accts := &mockAccounts{existing: map[string]bool{}}
|
|
225
|
+
handler, cctx := makeTestKit(bank, transfer, staking, accts)
|
|
165
226
|
|
|
166
227
|
// get balances
|
|
167
228
|
testCases := []struct {
|
|
@@ -180,7 +241,7 @@ func TestQuery(t *testing.T) {
|
|
|
180
241
|
tc := tc
|
|
181
242
|
ctx := sdk.UnwrapSDKContext(cctx)
|
|
182
243
|
t.Run(tc.name, func(t *testing.T) {
|
|
183
|
-
msgGetBalances := `{"type":"
|
|
244
|
+
msgGetBalances := `{"type":"VLOCALCHAIN_QUERY_MANY","messages":[{"@type":"/cosmos.bank.v1beta1.QueryAllBalancesRequest","address":"` + tc.addr + `"}]}`
|
|
184
245
|
t.Logf("query request: %v", msgGetBalances)
|
|
185
246
|
ret, err := handler.Receive(cctx, msgGetBalances)
|
|
186
247
|
t.Logf("query response: %v", ret)
|
|
@@ -230,6 +291,68 @@ func TestQuery(t *testing.T) {
|
|
|
230
291
|
}
|
|
231
292
|
})
|
|
232
293
|
}
|
|
294
|
+
|
|
295
|
+
t.Run("UnbondingDelegation", func(t *testing.T) {
|
|
296
|
+
// create a new message
|
|
297
|
+
msg := `{"type":"VLOCALCHAIN_QUERY_MANY","messages":[{"@type":"/cosmos.staking.v1beta1.QueryUnbondingDelegationRequest","delegator_addr":"` + firstAddr + `","validator_addr":"cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj"}]}`
|
|
298
|
+
t.Logf("query request: %v", msg)
|
|
299
|
+
ret, err := handler.Receive(cctx, msg)
|
|
300
|
+
t.Logf("query response: %v", ret)
|
|
301
|
+
if err != nil {
|
|
302
|
+
t.Fatalf("unexpected error: %v", err)
|
|
303
|
+
}
|
|
304
|
+
if ret == "" {
|
|
305
|
+
t.Fatalf("expected non-empty json")
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Unmarshal the JSON response
|
|
309
|
+
var respJSON []map[string]interface{}
|
|
310
|
+
if err := json.Unmarshal([]byte(ret), &respJSON); err != nil {
|
|
311
|
+
t.Fatalf("unexpected error unmarshalling JSON response: %v", err)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Check the response fields
|
|
315
|
+
if len(respJSON) != 1 {
|
|
316
|
+
t.Fatalf("expected 1 response, got %d", len(respJSON))
|
|
317
|
+
}
|
|
318
|
+
resp := respJSON[0]
|
|
319
|
+
|
|
320
|
+
replyAny, ok := resp["reply"].(map[string]interface{})
|
|
321
|
+
if !ok {
|
|
322
|
+
t.Fatalf("expected reply field to be a map, got %v", resp["reply"])
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
unbond, ok := replyAny["unbond"].(map[string]interface{})
|
|
326
|
+
if !ok {
|
|
327
|
+
t.Fatalf("expected unbond field to be a map, got %v", replyAny["unbond"])
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Check the field names and values
|
|
331
|
+
if unbond["delegatorAddress"] != firstAddr {
|
|
332
|
+
t.Errorf("expected delegatorAddress %s, got %v", firstAddr, unbond["delegator_address"])
|
|
333
|
+
}
|
|
334
|
+
if unbond["validatorAddress"] != "cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj" {
|
|
335
|
+
t.Errorf("expected validatorAddress cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj, got %v", unbond["validator_address"])
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
entries, ok := unbond["entries"].([]interface{})
|
|
339
|
+
if !ok || len(entries) != 1 {
|
|
340
|
+
t.Fatalf("expected 1 unbonding delegation entry, got %v", entries)
|
|
341
|
+
}
|
|
342
|
+
entry, ok := entries[0].(map[string]interface{})
|
|
343
|
+
if !ok {
|
|
344
|
+
t.Fatalf("expected unbonding delegation entry to be a map, got %v", entries[0])
|
|
345
|
+
}
|
|
346
|
+
if entry["creationHeight"] != "100" {
|
|
347
|
+
t.Errorf("expected creationHeight \"100\", got %v", entry["creation_height"])
|
|
348
|
+
}
|
|
349
|
+
if entry["balance"] != "500" {
|
|
350
|
+
t.Errorf("expected balance \"500\", got %v", entry["balance"])
|
|
351
|
+
}
|
|
352
|
+
if _, ok := entry["completionTime"]; !ok {
|
|
353
|
+
t.Error("expected completionTime field in the response")
|
|
354
|
+
}
|
|
355
|
+
})
|
|
233
356
|
}
|
|
234
357
|
|
|
235
358
|
func TestExecuteTx(t *testing.T) {
|
|
@@ -239,7 +362,9 @@ func TestExecuteTx(t *testing.T) {
|
|
|
239
362
|
alreadyAddr: []sdk.Coin{sdk.NewCoin("stale", sdk.NewInt(321))},
|
|
240
363
|
}}
|
|
241
364
|
transfer := &mockTransfer{}
|
|
242
|
-
|
|
365
|
+
staking := &mockStaking{}
|
|
366
|
+
accts := &mockAccounts{existing: map[string]bool{}}
|
|
367
|
+
handler, cctx := makeTestKit(bank, transfer, staking, accts)
|
|
243
368
|
|
|
244
369
|
// create a new message
|
|
245
370
|
msg := `{"type":"VLOCALCHAIN_ALLOCATE_ADDRESS"}`
|
|
@@ -302,4 +427,34 @@ func TestExecuteTx(t *testing.T) {
|
|
|
302
427
|
}
|
|
303
428
|
})
|
|
304
429
|
}
|
|
430
|
+
|
|
431
|
+
t.Run("MsgUndelegate", func(t *testing.T) {
|
|
432
|
+
// create a new message
|
|
433
|
+
msg := `{"type":"VLOCALCHAIN_EXECUTE_TX","address":"` + addr +
|
|
434
|
+
`","messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegatorAddress":"` +
|
|
435
|
+
addr + `","validatorAddress":"cosmosvaloper1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj","amount":{"denom":"stake","amount":"100"}}]}`
|
|
436
|
+
|
|
437
|
+
ret, err := handler.Receive(cctx, msg)
|
|
438
|
+
if err != nil {
|
|
439
|
+
t.Fatalf("unexpected error: %s", err)
|
|
440
|
+
}
|
|
441
|
+
if ret == "" {
|
|
442
|
+
t.Fatalf("expected non-empty json")
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Unmarshal the response
|
|
446
|
+
var resp []map[string]interface{}
|
|
447
|
+
if err := json.Unmarshal([]byte(ret), &resp); err != nil {
|
|
448
|
+
t.Fatalf("unexpected error unmarshalling response: %v", err)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Check the response fields
|
|
452
|
+
if len(resp) != 1 {
|
|
453
|
+
t.Fatalf("expected 1 response, got %d", len(resp))
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if _, ok := resp[0]["completionTime"]; !ok {
|
|
457
|
+
t.Error("expected 'completionTime' field in response")
|
|
458
|
+
}
|
|
459
|
+
})
|
|
305
460
|
}
|
|
@@ -94,7 +94,6 @@ var capDataRemotableValueFormats = map[string]string{
|
|
|
94
94
|
// }
|
|
95
95
|
//
|
|
96
96
|
// ```
|
|
97
|
-
// cf. https://github.com/Agoric/agoric-sdk/blob/6e5b422b80e47c4dac151404f43faea5ab41e9b0/scripts/get-flattened-publication.sh
|
|
98
97
|
func flatten(input interface{}, output map[string]interface{}, key string, top bool) error {
|
|
99
98
|
// Act on the raw representation of a Remotable.
|
|
100
99
|
if remotable, ok := input.(*capdata.CapdataRemotable); ok {
|
|
@@ -22,8 +22,8 @@ import (
|
|
|
22
22
|
// StreamCell is an envelope representing a sequence of values written at a path in a single block.
|
|
23
23
|
// It is persisted to storage as a { "blockHeight": "<digits>", "values": ["...", ...] } JSON text
|
|
24
24
|
// that off-chain consumers rely upon.
|
|
25
|
-
// Many of those consumers *also* rely upon the strings of "values" being valid JSON text
|
|
26
|
-
//
|
|
25
|
+
// Many of those consumers *also* rely upon the strings of "values" being valid JSON text,
|
|
26
|
+
// but we do not enforce that in this package.
|
|
27
27
|
type StreamCell struct {
|
|
28
28
|
BlockHeight string `json:"blockHeight"`
|
|
29
29
|
Values []string `json:"values"`
|
|
@@ -52,14 +52,6 @@ var _ ChangeManager = (*BatchingChangeManager)(nil)
|
|
|
52
52
|
// 2 ** 256 - 1
|
|
53
53
|
var MaxSDKInt = sdk.NewIntFromBigInt(new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil), big.NewInt(1)))
|
|
54
54
|
|
|
55
|
-
// TODO: Use bytes.CutPrefix once we can rely upon go >= 1.20.
|
|
56
|
-
func cutPrefix(s, prefix []byte) (after []byte, found bool) {
|
|
57
|
-
if !bytes.HasPrefix(s, prefix) {
|
|
58
|
-
return s, false
|
|
59
|
-
}
|
|
60
|
-
return s[len(prefix):], true
|
|
61
|
-
}
|
|
62
|
-
|
|
63
55
|
// Keeper maintains the link to data storage and exposes getter/setter methods
|
|
64
56
|
// for the various parts of the state machine
|
|
65
57
|
type Keeper struct {
|
|
@@ -164,7 +156,7 @@ func (k Keeper) ExportStorageFromPrefix(ctx sdk.Context, pathPrefix string) []*t
|
|
|
164
156
|
if !strings.HasPrefix(path, pathPrefix) {
|
|
165
157
|
continue
|
|
166
158
|
}
|
|
167
|
-
value, hasPrefix :=
|
|
159
|
+
value, hasPrefix := bytes.CutPrefix(rawValue, types.EncodedDataPrefix)
|
|
168
160
|
if !hasPrefix {
|
|
169
161
|
panic(fmt.Errorf("value at path %q starts with unexpected prefix", path))
|
|
170
162
|
}
|
|
@@ -266,7 +258,7 @@ func (k Keeper) GetEntry(ctx sdk.Context, path string) agoric.KVEntry {
|
|
|
266
258
|
if bytes.Equal(rawValue, types.EncodedNoDataValue) {
|
|
267
259
|
return agoric.NewKVEntryWithNoValue(path)
|
|
268
260
|
}
|
|
269
|
-
value, hasPrefix :=
|
|
261
|
+
value, hasPrefix := bytes.CutPrefix(rawValue, types.EncodedDataPrefix)
|
|
270
262
|
if !hasPrefix {
|
|
271
263
|
panic(fmt.Errorf("value at path %q starts with unexpected prefix", path))
|
|
272
264
|
}
|
|
@@ -429,7 +421,7 @@ func (k Keeper) GetNoDataValue() []byte {
|
|
|
429
421
|
return types.EncodedNoDataValue
|
|
430
422
|
}
|
|
431
423
|
|
|
432
|
-
func (k Keeper)
|
|
424
|
+
func (k Keeper) GetIntValue(ctx sdk.Context, path string) (sdkmath.Int, error) {
|
|
433
425
|
indexEntry := k.GetEntry(ctx, path)
|
|
434
426
|
if !indexEntry.HasValue() {
|
|
435
427
|
return sdk.NewInt(0), nil
|
|
@@ -443,11 +435,11 @@ func (k Keeper) getIntValue(ctx sdk.Context, path string) (sdkmath.Int, error) {
|
|
|
443
435
|
}
|
|
444
436
|
|
|
445
437
|
func (k Keeper) GetQueueLength(ctx sdk.Context, queuePath string) (sdkmath.Int, error) {
|
|
446
|
-
head, err := k.
|
|
438
|
+
head, err := k.GetIntValue(ctx, queuePath+".head")
|
|
447
439
|
if err != nil {
|
|
448
440
|
return sdkmath.NewInt(0), err
|
|
449
441
|
}
|
|
450
|
-
tail, err := k.
|
|
442
|
+
tail, err := k.GetIntValue(ctx, queuePath+".tail")
|
|
451
443
|
if err != nil {
|
|
452
444
|
return sdkmath.NewInt(0), err
|
|
453
445
|
}
|
|
@@ -458,12 +450,12 @@ func (k Keeper) GetQueueLength(ctx sdk.Context, queuePath string) (sdkmath.Int,
|
|
|
458
450
|
func (k Keeper) PushQueueItem(ctx sdk.Context, queuePath string, value string) error {
|
|
459
451
|
// Get the current queue tail, defaulting to zero if its vstorage doesn't exist.
|
|
460
452
|
// The `tail` is the value of the next index to be inserted
|
|
461
|
-
tail, err := k.
|
|
453
|
+
tail, err := k.GetIntValue(ctx, queuePath+".tail")
|
|
462
454
|
if err != nil {
|
|
463
455
|
return err
|
|
464
456
|
}
|
|
465
457
|
|
|
466
|
-
if tail.
|
|
458
|
+
if tail.GTE(MaxSDKInt) {
|
|
467
459
|
return errors.New(queuePath + " overflow")
|
|
468
460
|
}
|
|
469
461
|
nextTail := tail.Add(sdk.NewInt(1))
|
package/x/vstorage/module.go
CHANGED
|
@@ -4,7 +4,6 @@ import (
|
|
|
4
4
|
"context"
|
|
5
5
|
"encoding/json"
|
|
6
6
|
|
|
7
|
-
"github.com/gorilla/mux"
|
|
8
7
|
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
|
9
8
|
"github.com/spf13/cobra"
|
|
10
9
|
|
|
@@ -57,10 +56,6 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod
|
|
|
57
56
|
return ValidateGenesis(&data)
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
// Register rest routes
|
|
61
|
-
func (AppModuleBasic) RegisterRESTRoutes(ctx client.Context, rtr *mux.Router) {
|
|
62
|
-
}
|
|
63
|
-
|
|
64
59
|
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
|
|
65
60
|
_ = types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
|
|
66
61
|
}
|