@agoric/cosmos 0.35.0-upgrade-14-dev-0169c7e.0 → 0.35.0-upgrade-16-dev-07b0130.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/CHANGELOG.md +121 -77
- package/MAINTAINERS.md +3 -0
- package/Makefile +49 -26
- package/ante/ante.go +11 -11
- package/ante/inbound_test.go +3 -2
- package/ante/vm_admission.go +2 -1
- package/app/app.go +260 -175
- package/app/export.go +13 -6
- package/app/upgrade.go +76 -0
- package/cmd/agd/agvm.go +42 -0
- package/cmd/agd/main.go +132 -11
- package/cmd/libdaemon/main.go +67 -53
- package/cmd/libdaemon/main_test.go +2 -1
- package/daemon/cmd/genaccounts.go +13 -9
- package/daemon/cmd/root.go +186 -73
- package/daemon/cmd/root_test.go +190 -2
- package/daemon/cmd/testnet.go +17 -6
- package/daemon/main.go +6 -3
- package/e2e_test/Makefile +29 -0
- package/e2e_test/README.md +100 -0
- package/e2e_test/go.mod +217 -0
- package/e2e_test/go.sum +1323 -0
- package/e2e_test/ibc_conformance_test.go +56 -0
- package/e2e_test/pfm_test.go +613 -0
- package/e2e_test/util.go +271 -0
- package/git-revision.txt +1 -1
- package/go.mod +110 -68
- package/go.sum +601 -248
- package/package.json +9 -5
- package/proto/agoric/swingset/genesis.proto +4 -0
- package/proto/agoric/swingset/swingset.proto +1 -1
- package/proto/agoric/vlocalchain/.clang-format +7 -0
- package/proto/agoric/vlocalchain/vlocalchain.proto +31 -0
- package/proto/agoric/vstorage/query.proto +53 -1
- package/proto/agoric/vtransfer/genesis.proto +18 -0
- package/scripts/protocgen.sh +16 -6
- package/third_party/proto/buf.yaml +1 -0
- package/third_party/proto/cosmos/base/query/v1beta1/pagination.proto +4 -1
- package/third_party/proto/cosmos/base/v1beta1/coin.proto +7 -4
- package/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto +16 -6
- package/third_party/proto/cosmos_proto/cosmos.proto +97 -0
- package/third_party/proto/google/api/annotations.proto +1 -1
- package/third_party/proto/google/api/http.proto +181 -120
- package/third_party/proto/google/api/httpbody.proto +9 -6
- package/third_party/proto/google/protobuf/any.proto +1 -7
- package/third_party/proto/ibc/core/channel/v1/channel.proto +15 -1
- package/third_party/proto/ibc/core/client/v1/client.proto +9 -6
- package/types/kv_entry_helpers.go +42 -0
- package/upgradegaia.sh +21 -12
- package/vm/action.go +28 -24
- package/vm/action_test.go +36 -16
- package/vm/client.go +113 -0
- package/vm/client_test.go +182 -0
- package/vm/controller.go +18 -42
- package/vm/core_proposals.go +22 -2
- package/vm/jsonrpcconn/jsonrpcconn.go +160 -0
- package/vm/jsonrpcconn/jsonrpcconn_test.go +126 -0
- package/vm/proto_json.go +38 -0
- package/vm/proto_json_test.go +103 -0
- package/vm/server.go +124 -0
- package/x/swingset/abci.go +10 -10
- package/x/swingset/alias.go +2 -0
- package/x/swingset/client/cli/query.go +2 -2
- package/x/swingset/client/cli/tx.go +52 -33
- package/x/swingset/client/proposal_handler.go +2 -17
- package/x/swingset/genesis.go +84 -24
- package/x/swingset/handler.go +2 -1
- package/x/swingset/keeper/extension_snapshotter.go +2 -2
- package/x/swingset/keeper/keeper.go +21 -36
- package/x/swingset/keeper/keeper_test.go +1 -1
- package/x/swingset/keeper/msg_server.go +20 -22
- package/x/swingset/keeper/proposal.go +13 -3
- package/x/swingset/keeper/querier.go +23 -14
- package/x/swingset/keeper/swing_store_exports_handler.go +21 -6
- package/x/swingset/keeper/test_utils.go +16 -0
- package/x/swingset/module.go +7 -7
- package/x/swingset/proposal_handler.go +5 -4
- package/x/swingset/swingset.go +4 -2
- package/x/swingset/testing/queue.go +17 -0
- package/x/swingset/types/codec.go +2 -2
- package/x/swingset/types/default-params.go +1 -1
- package/x/swingset/types/expected_keepers.go +3 -2
- package/x/swingset/types/genesis.pb.go +78 -25
- package/x/swingset/types/msgs.go +44 -24
- package/x/swingset/types/msgs.pb.go +16 -16
- package/x/swingset/types/params.go +2 -1
- package/x/swingset/types/proposal.go +10 -9
- package/x/swingset/types/swingset.pb.go +1 -1
- package/x/swingset/types/types.go +30 -28
- package/x/vbank/genesis.go +0 -2
- package/x/vbank/handler.go +2 -1
- package/x/vbank/keeper/keeper.go +3 -2
- package/x/vbank/keeper/querier.go +9 -4
- package/x/vbank/keeper/rewards.go +1 -1
- package/x/vbank/module.go +0 -5
- package/x/vbank/types/msgs.go +0 -12
- package/x/vbank/vbank.go +20 -19
- package/x/vbank/vbank_test.go +10 -10
- package/x/vibc/alias.go +3 -0
- package/x/vibc/handler.go +16 -9
- package/x/vibc/keeper/keeper.go +112 -74
- package/x/vibc/keeper/triggers.go +101 -0
- package/x/vibc/module.go +5 -8
- package/x/vibc/types/expected_keepers.go +26 -5
- package/x/vibc/types/ibc_module.go +336 -0
- package/x/vibc/types/msgs.go +1 -1
- package/x/vibc/types/msgs.pb.go +1 -1
- package/x/vibc/types/receiver.go +170 -0
- package/x/vlocalchain/alias.go +19 -0
- package/x/vlocalchain/handler.go +21 -0
- package/x/vlocalchain/keeper/keeper.go +279 -0
- package/x/vlocalchain/keeper/keeper_test.go +97 -0
- package/x/vlocalchain/types/codec.go +34 -0
- package/x/vlocalchain/types/key.go +27 -0
- package/x/vlocalchain/types/msgs.go +16 -0
- package/x/vlocalchain/types/vlocalchain.pb.go +1072 -0
- package/x/vlocalchain/vlocalchain.go +114 -0
- package/x/vlocalchain/vlocalchain_test.go +434 -0
- package/x/vstorage/README.md +138 -0
- package/x/vstorage/capdata/capdata.go +298 -0
- package/x/vstorage/capdata/capdata_test.go +352 -0
- package/x/vstorage/client/cli/query.go +51 -4
- package/x/vstorage/handler.go +2 -1
- package/x/vstorage/keeper/grpc_query.go +220 -0
- package/x/vstorage/keeper/keeper.go +16 -22
- package/x/vstorage/keeper/keeper_grpc_test.go +300 -0
- package/x/vstorage/keeper/keeper_test.go +1 -1
- package/x/vstorage/keeper/querier.go +11 -6
- package/x/vstorage/keeper/querier_test.go +4 -3
- package/x/vstorage/module.go +0 -5
- package/x/vstorage/testing/queue.go +27 -0
- package/x/vstorage/types/query.pb.go +646 -36
- package/x/vstorage/types/query.pb.gw.go +119 -0
- package/x/vstorage/vstorage.go +16 -15
- package/x/vstorage/vstorage_test.go +5 -5
- 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/ante/fee.go +0 -96
- package/proto/agoric/lien/genesis.proto +0 -25
- package/proto/agoric/lien/lien.proto +0 -25
- package/x/lien/alias.go +0 -17
- package/x/lien/genesis.go +0 -58
- package/x/lien/genesis_test.go +0 -101
- package/x/lien/keeper/account.go +0 -290
- package/x/lien/keeper/keeper.go +0 -254
- package/x/lien/keeper/keeper_test.go +0 -623
- package/x/lien/lien.go +0 -203
- package/x/lien/lien_test.go +0 -529
- package/x/lien/module.go +0 -115
- package/x/lien/spec/01_concepts.md +0 -146
- package/x/lien/spec/02_messages.md +0 -96
- package/x/lien/types/accountkeeper.go +0 -81
- package/x/lien/types/accountstate.go +0 -27
- package/x/lien/types/expected_keepers.go +0 -18
- package/x/lien/types/genesis.pb.go +0 -567
- package/x/lien/types/key.go +0 -25
- package/x/lien/types/lien.pb.go +0 -403
- package/x/vibc/ibc.go +0 -393
- /package/{src/index.cjs → index.cjs} +0 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
package vlocalchain
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"fmt"
|
|
7
|
+
|
|
8
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
9
|
+
|
|
10
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
11
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain/keeper"
|
|
12
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain/types"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
var _ vm.PortHandler = (*portHandler)(nil)
|
|
16
|
+
|
|
17
|
+
type portHandler struct {
|
|
18
|
+
keeper keeper.Keeper
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type portMessage struct {
|
|
22
|
+
Type string `json:"type"`
|
|
23
|
+
Address string `json:"address,omitempty"`
|
|
24
|
+
Messages json.RawMessage `json:"messages,omitempty"`
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
func NewReceiver(keeper keeper.Keeper) portHandler {
|
|
28
|
+
return portHandler{keeper: keeper}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
func (h portHandler) Receive(cctx context.Context, str string) (ret string, err error) {
|
|
32
|
+
var msg portMessage
|
|
33
|
+
err = json.Unmarshal([]byte(str), &msg)
|
|
34
|
+
if err != nil {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
switch msg.Type {
|
|
39
|
+
case "VLOCALCHAIN_ALLOCATE_ADDRESS":
|
|
40
|
+
addr := h.keeper.AllocateAddress(cctx)
|
|
41
|
+
var bz []byte
|
|
42
|
+
if bz, err = json.Marshal(addr.String()); err != nil {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
ret = string(bz)
|
|
46
|
+
|
|
47
|
+
case "VLOCALCHAIN_QUERY_MANY":
|
|
48
|
+
// Copy the JSON messages string into a CosmosTx object so we can
|
|
49
|
+
// deserialize it with just proto3 JSON.
|
|
50
|
+
cosmosTxBz := []byte(`{"messages":` + string(msg.Messages) + `}`)
|
|
51
|
+
|
|
52
|
+
var qms []types.QueryRequest
|
|
53
|
+
qms, err = h.keeper.DeserializeRequests(cosmosTxBz)
|
|
54
|
+
if err != nil {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
var errs []error
|
|
59
|
+
resps := make([]interface{}, len(qms))
|
|
60
|
+
for i, qm := range qms {
|
|
61
|
+
var qr *types.QueryResponse
|
|
62
|
+
qr, err = h.keeper.Query(cctx, qm)
|
|
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()}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
bz, err := vm.ProtoJSONMarshalSlice(resps)
|
|
73
|
+
if err != nil {
|
|
74
|
+
return "", err
|
|
75
|
+
}
|
|
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
|
|
88
|
+
|
|
89
|
+
case "VLOCALCHAIN_EXECUTE_TX":
|
|
90
|
+
origCtx := sdk.UnwrapSDKContext(cctx)
|
|
91
|
+
|
|
92
|
+
// Copy the JSON messages string into a CosmosTx object so we can
|
|
93
|
+
// deserialize it with just proto3 JSON.
|
|
94
|
+
cosmosTxBz := []byte(`{"messages":` + string(msg.Messages) + `}`)
|
|
95
|
+
|
|
96
|
+
var msgs []sdk.Msg
|
|
97
|
+
if msgs, err = h.keeper.DeserializeTxMessages(cosmosTxBz); err != nil {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
var resps []interface{}
|
|
102
|
+
resps, err = h.keeper.ExecuteTx(origCtx, msg.Address, msgs)
|
|
103
|
+
if err != nil {
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Marshal the responses to proto3 JSON.
|
|
108
|
+
bz, e := vm.ProtoJSONMarshalSlice(resps)
|
|
109
|
+
return string(bz), e
|
|
110
|
+
default:
|
|
111
|
+
err = fmt.Errorf("unrecognized message type %s", msg.Type)
|
|
112
|
+
}
|
|
113
|
+
return
|
|
114
|
+
}
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
package vlocalchain_test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
"time"
|
|
9
|
+
|
|
10
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/app/params"
|
|
11
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
12
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain"
|
|
13
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain/types"
|
|
14
|
+
|
|
15
|
+
"github.com/cosmos/cosmos-sdk/baseapp"
|
|
16
|
+
"github.com/cosmos/cosmos-sdk/store"
|
|
17
|
+
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
18
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
19
|
+
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
20
|
+
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
21
|
+
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
|
|
22
|
+
"github.com/tendermint/tendermint/libs/log"
|
|
23
|
+
|
|
24
|
+
"github.com/gogo/protobuf/jsonpb"
|
|
25
|
+
"github.com/gogo/protobuf/proto"
|
|
26
|
+
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
|
27
|
+
dbm "github.com/tendermint/tm-db"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
var (
|
|
31
|
+
vlocalchainStoreKey = sdk.NewKVStoreKey(types.StoreKey)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
const (
|
|
35
|
+
firstAddr = "cosmos1uupflqrldlpkktssnzgp3r03ff6kz4u4kzd92pjgsfddye7grrlqt9rmmt"
|
|
36
|
+
msgAllocateAddress = `{"type":"VLOCALCHAIN_ALLOCATE_ADDRESS"}`
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
type mockBank struct {
|
|
40
|
+
banktypes.UnimplementedQueryServer
|
|
41
|
+
banktypes.UnimplementedMsgServer
|
|
42
|
+
balances map[string]sdk.Coins
|
|
43
|
+
failToSend error
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
var _ banktypes.QueryServer = (*mockBank)(nil)
|
|
47
|
+
var _ banktypes.MsgServer = (*mockBank)(nil)
|
|
48
|
+
|
|
49
|
+
func (b *mockBank) AllBalances(cctx context.Context, req *banktypes.QueryAllBalancesRequest) (*banktypes.QueryAllBalancesResponse, error) {
|
|
50
|
+
addr, err := sdk.AccAddressFromBech32(req.Address)
|
|
51
|
+
if err != nil {
|
|
52
|
+
return nil, err
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
var resp banktypes.QueryAllBalancesResponse
|
|
56
|
+
resp.Balances = sdk.Coins{}
|
|
57
|
+
if coins, ok := b.balances[addr.String()]; ok {
|
|
58
|
+
resp.Balances = coins
|
|
59
|
+
}
|
|
60
|
+
return &resp, nil
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
func (b *mockBank) Send(cctx context.Context, req *banktypes.MsgSend) (*banktypes.MsgSendResponse, error) {
|
|
64
|
+
if b.failToSend != nil {
|
|
65
|
+
return nil, b.failToSend
|
|
66
|
+
}
|
|
67
|
+
return &banktypes.MsgSendResponse{}, nil
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
type mockTransfer struct {
|
|
71
|
+
transfertypes.UnimplementedQueryServer
|
|
72
|
+
transfertypes.UnimplementedMsgServer
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var _ transfertypes.QueryServer = (*mockTransfer)(nil)
|
|
76
|
+
var _ transfertypes.MsgServer = (*mockTransfer)(nil)
|
|
77
|
+
|
|
78
|
+
func (t *mockTransfer) Transfer(cctx context.Context, msg *transfertypes.MsgTransfer) (*transfertypes.MsgTransferResponse, error) {
|
|
79
|
+
return &transfertypes.MsgTransferResponse{Sequence: 1}, nil
|
|
80
|
+
}
|
|
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
|
+
|
|
110
|
+
// makeTestKit creates a minimal Keeper and Context for use in testing.
|
|
111
|
+
func makeTestKit(bank *mockBank, transfer *mockTransfer, staking *mockStaking) (vm.PortHandler, context.Context) {
|
|
112
|
+
encodingConfig := params.MakeEncodingConfig()
|
|
113
|
+
cdc := encodingConfig.Marshaler
|
|
114
|
+
|
|
115
|
+
txRouter := baseapp.NewMsgServiceRouter()
|
|
116
|
+
txRouter.SetInterfaceRegistry(encodingConfig.InterfaceRegistry)
|
|
117
|
+
queryRouter := baseapp.NewGRPCQueryRouter()
|
|
118
|
+
queryRouter.SetInterfaceRegistry(encodingConfig.InterfaceRegistry)
|
|
119
|
+
|
|
120
|
+
banktypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
121
|
+
banktypes.RegisterMsgServer(txRouter, bank)
|
|
122
|
+
banktypes.RegisterQueryServer(queryRouter, bank)
|
|
123
|
+
transfertypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
124
|
+
transfertypes.RegisterMsgServer(txRouter, transfer)
|
|
125
|
+
transfertypes.RegisterQueryServer(queryRouter, transfer)
|
|
126
|
+
stakingtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
127
|
+
stakingtypes.RegisterMsgServer(txRouter, staking)
|
|
128
|
+
stakingtypes.RegisterQueryServer(queryRouter, staking)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
// create a new Keeper
|
|
132
|
+
keeper := vlocalchain.NewKeeper(cdc, vlocalchainStoreKey, txRouter, queryRouter)
|
|
133
|
+
|
|
134
|
+
db := dbm.NewMemDB()
|
|
135
|
+
ms := store.NewCommitMultiStore(db)
|
|
136
|
+
ms.MountStoreWithDB(vlocalchainStoreKey, storetypes.StoreTypeIAVL, db)
|
|
137
|
+
err := ms.LoadLatestVersion()
|
|
138
|
+
if err != nil {
|
|
139
|
+
panic(err)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// create a new SDK Context
|
|
143
|
+
ctx := sdk.NewContext(ms, tmproto.Header{}, false, log.NewNopLogger()).WithBlockHeight(998)
|
|
144
|
+
|
|
145
|
+
handler := vm.NewProtectedPortHandler(vlocalchain.NewReceiver(keeper))
|
|
146
|
+
|
|
147
|
+
// create a new Go context
|
|
148
|
+
cctx := sdk.WrapSDKContext(ctx)
|
|
149
|
+
return handler, cctx
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
func TestAllocateAddress(t *testing.T) {
|
|
153
|
+
bank := &mockBank{}
|
|
154
|
+
transfer := &mockTransfer{}
|
|
155
|
+
staking := &mockStaking{}
|
|
156
|
+
handler, cctx := makeTestKit(bank, transfer, staking)
|
|
157
|
+
|
|
158
|
+
addrs := map[string]bool{
|
|
159
|
+
firstAddr: false,
|
|
160
|
+
"cosmos1yj40fakym8kf4wvgz9tky7k9f3v9msm3t7frscrmkjsdkxkpsfkqgeczkg": false,
|
|
161
|
+
"cosmos1s76vryj7m8k8nm9le65a4plhf5rym5sumtt2n0vwnk5l6k4cwuhsj56ujj": false,
|
|
162
|
+
"cosmos1c5hplwyxk5jr2dsygjqepzfqvfukwduq9c4660aah76krf99m6gs0k7hvl": false,
|
|
163
|
+
"cosmos1ys3a7mtna3cad0wxcs4ddukn37stexjdvns8jfdn4uerlr95y4xqnrypf6": false,
|
|
164
|
+
}
|
|
165
|
+
numToTest := len(addrs)
|
|
166
|
+
for i := 0; i < numToTest; i++ {
|
|
167
|
+
// receive the message
|
|
168
|
+
ret, err := handler.Receive(cctx, msgAllocateAddress)
|
|
169
|
+
if err != nil {
|
|
170
|
+
t.Fatalf("unexpected error[%d]: %v", i, err)
|
|
171
|
+
}
|
|
172
|
+
if ret == "" {
|
|
173
|
+
t.Fatalf("expected non-empty address[%d]", i)
|
|
174
|
+
}
|
|
175
|
+
var addr string
|
|
176
|
+
if err := json.Unmarshal([]byte(ret), &addr); err != nil {
|
|
177
|
+
t.Fatalf("unexpected error unmarshalling address string[%d]: %v: %v", i, ret, err)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
already, ok := addrs[addr]
|
|
181
|
+
if !ok {
|
|
182
|
+
t.Fatalf("unexpected address[%d]: %v", i, addr)
|
|
183
|
+
}
|
|
184
|
+
if already {
|
|
185
|
+
t.Fatalf("unexpected duplicate address[%d]: %v", i, addr)
|
|
186
|
+
}
|
|
187
|
+
addrs[addr] = true
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
func TestQuery(t *testing.T) {
|
|
192
|
+
alreadyAddr := sdk.MustBech32ifyAddressBytes("cosmos", []byte("already"))
|
|
193
|
+
nonexistentAddr := sdk.MustBech32ifyAddressBytes("cosmos", []byte("nonexistent"))
|
|
194
|
+
bank := &mockBank{balances: map[string]sdk.Coins{
|
|
195
|
+
firstAddr: []sdk.Coin{sdk.NewCoin("fresh", sdk.NewInt(123))},
|
|
196
|
+
alreadyAddr: []sdk.Coin{sdk.NewCoin("stale", sdk.NewInt(321))},
|
|
197
|
+
}}
|
|
198
|
+
transfer := &mockTransfer{}
|
|
199
|
+
staking := &mockStaking{}
|
|
200
|
+
handler, cctx := makeTestKit(bank, transfer, staking)
|
|
201
|
+
|
|
202
|
+
// get balances
|
|
203
|
+
testCases := []struct {
|
|
204
|
+
name string
|
|
205
|
+
addr string
|
|
206
|
+
failure string
|
|
207
|
+
expected sdk.Coins
|
|
208
|
+
}{
|
|
209
|
+
{"nonexistent", nonexistentAddr, "", sdk.Coins{}},
|
|
210
|
+
{"already", alreadyAddr, "", bank.balances[alreadyAddr]},
|
|
211
|
+
{"first", firstAddr, "", bank.balances[firstAddr]},
|
|
212
|
+
{"badaddr", "cosmos11111111111", "decoding bech32 failed: invalid separator index 16", sdk.Coins{}},
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
for _, tc := range testCases {
|
|
216
|
+
tc := tc
|
|
217
|
+
ctx := sdk.UnwrapSDKContext(cctx)
|
|
218
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
219
|
+
msgGetBalances := `{"type":"VLOCALCHAIN_QUERY_MANY","messages":[{"@type":"/cosmos.bank.v1beta1.QueryAllBalancesRequest","address":"` + tc.addr + `"}]}`
|
|
220
|
+
t.Logf("query request: %v", msgGetBalances)
|
|
221
|
+
ret, err := handler.Receive(cctx, msgGetBalances)
|
|
222
|
+
t.Logf("query response: %v", ret)
|
|
223
|
+
if tc.failure != "" {
|
|
224
|
+
if err == nil {
|
|
225
|
+
t.Fatalf("expected error %v, not nil with return %v", tc.failure, ret)
|
|
226
|
+
} else if err.Error() != tc.failure {
|
|
227
|
+
t.Fatalf("expected error %v, not %v", tc.failure, err)
|
|
228
|
+
}
|
|
229
|
+
return
|
|
230
|
+
}
|
|
231
|
+
if err != nil {
|
|
232
|
+
t.Fatalf("unexpected error: %v", err)
|
|
233
|
+
}
|
|
234
|
+
if err == nil && ret == "" {
|
|
235
|
+
t.Fatalf("expected non-empty json")
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Unmarshal the responses.
|
|
239
|
+
s := `{"responses":` + ret + `}`
|
|
240
|
+
|
|
241
|
+
unmarshaler := jsonpb.Unmarshaler{}
|
|
242
|
+
var qrs types.QueryResponses
|
|
243
|
+
if err = unmarshaler.Unmarshal(strings.NewReader(s), &qrs); err != nil {
|
|
244
|
+
t.Fatalf("unexpected error unmarshalling reply: %v: %v", ret, err)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
resps := qrs.Responses
|
|
248
|
+
if len(resps) != 1 {
|
|
249
|
+
t.Fatalf("expected responses length 1, got %v", len(resps))
|
|
250
|
+
}
|
|
251
|
+
if resps[0].Error != "" {
|
|
252
|
+
t.Fatalf("unexpected error response: %v", resps[0].Error)
|
|
253
|
+
}
|
|
254
|
+
if resps[0].Height != ctx.BlockHeight() {
|
|
255
|
+
t.Fatalf("expected height %v, got %v", ctx.BlockHeight(), resps[0].Height)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Unmarshal the Any.
|
|
259
|
+
var pb banktypes.QueryAllBalancesResponse
|
|
260
|
+
if err = proto.Unmarshal(resps[0].Reply.Value, &pb); err != nil {
|
|
261
|
+
t.Fatalf("unexpected error unmarshalling reply: %v: %v", ret, err)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if !pb.Balances.IsEqual(tc.expected) {
|
|
265
|
+
t.Errorf("unexpected balance: expected %v, got %v", tc.expected, pb.Balances)
|
|
266
|
+
}
|
|
267
|
+
})
|
|
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
|
+
})
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
func TestExecuteTx(t *testing.T) {
|
|
334
|
+
alreadyAddr := sdk.MustBech32ifyAddressBytes("cosmos", []byte("already"))
|
|
335
|
+
bank := &mockBank{balances: map[string]sdk.Coins{
|
|
336
|
+
firstAddr: []sdk.Coin{sdk.NewCoin("fresh", sdk.NewInt(123))},
|
|
337
|
+
alreadyAddr: []sdk.Coin{sdk.NewCoin("stale", sdk.NewInt(321))},
|
|
338
|
+
}}
|
|
339
|
+
transfer := &mockTransfer{}
|
|
340
|
+
staking := &mockStaking{}
|
|
341
|
+
handler, cctx := makeTestKit(bank, transfer, staking)
|
|
342
|
+
|
|
343
|
+
// create a new message
|
|
344
|
+
msg := `{"type":"VLOCALCHAIN_ALLOCATE_ADDRESS"}`
|
|
345
|
+
ret, err := handler.Receive(cctx, msg)
|
|
346
|
+
if err != nil {
|
|
347
|
+
t.Fatalf("unexpected error: %s", err)
|
|
348
|
+
}
|
|
349
|
+
if ret == "" {
|
|
350
|
+
t.Fatalf("expected non-empty json")
|
|
351
|
+
}
|
|
352
|
+
var addr string
|
|
353
|
+
if err := json.Unmarshal([]byte(ret), &addr); err != nil {
|
|
354
|
+
t.Fatalf("unexpected error unmarshalling address string: %v: %s", ret, err)
|
|
355
|
+
}
|
|
356
|
+
if addr != firstAddr {
|
|
357
|
+
t.Fatalf("expected address %v, got %v", firstAddr, addr)
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
testCases := []struct {
|
|
361
|
+
name string
|
|
362
|
+
signerAddress string
|
|
363
|
+
fromAddress string
|
|
364
|
+
toAddress string
|
|
365
|
+
failure string
|
|
366
|
+
}{
|
|
367
|
+
{"valid", addr, addr, alreadyAddr, ""},
|
|
368
|
+
{"parse error", `"` + addr, firstAddr, alreadyAddr, "invalid character 'c' after object key:value pair"},
|
|
369
|
+
{"invalid address", addr, alreadyAddr, alreadyAddr, "required signer cosmos1v9k8yetpv3us7src8u does not match actual signer"},
|
|
370
|
+
{"unauth", alreadyAddr, addr, alreadyAddr, "required signer cosmos1uupflqrldlpkktssnzgp3r03ff6kz4u4kzd92pjgsfddye7grrlqt9rmmt does not match actual signer"},
|
|
371
|
+
}
|
|
372
|
+
for _, tc := range testCases {
|
|
373
|
+
tc := tc
|
|
374
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
375
|
+
|
|
376
|
+
// create a new message
|
|
377
|
+
msg := `{"type":"VLOCALCHAIN_EXECUTE_TX","address":"` + tc.signerAddress +
|
|
378
|
+
`","messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"` +
|
|
379
|
+
tc.fromAddress + `","to_address":"` + tc.toAddress +
|
|
380
|
+
`","amount":[{"denom":"fresh","amount":"100"}]}]}`
|
|
381
|
+
|
|
382
|
+
ret, err = handler.Receive(cctx, msg)
|
|
383
|
+
if tc.failure != "" {
|
|
384
|
+
if err == nil {
|
|
385
|
+
t.Fatalf("expected error %v, not nil with return %v", tc.failure, ret)
|
|
386
|
+
}
|
|
387
|
+
if err.Error() != tc.failure {
|
|
388
|
+
t.Fatalf("expected error %v, not %v", tc.failure, err)
|
|
389
|
+
}
|
|
390
|
+
return
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if err != nil {
|
|
394
|
+
t.Fatalf("unexpected error: %s", err)
|
|
395
|
+
}
|
|
396
|
+
if ret == "" {
|
|
397
|
+
t.Fatalf("expected non-empty json")
|
|
398
|
+
}
|
|
399
|
+
if ret != "[{}]" {
|
|
400
|
+
t.Fatalf("expected response [{}], not %v", ret)
|
|
401
|
+
}
|
|
402
|
+
})
|
|
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
|
+
})
|
|
434
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Virtual Storage
|
|
2
|
+
|
|
3
|
+
This module manages "[IAVL](https://github.com/cosmos/iavl)" chain storage data with a hierarchical keyspace in which each key is a "[path](./types/path_keys.go)" composed of zero or more dot-separated nonempty segments in a restricted alphabet. It exposes gRPC endpoints to arbitrary external clients for reading data, and internal read/write interfaces for use by SwingSet (which itself manages further subtree-scoped attenuation).
|
|
4
|
+
|
|
5
|
+
## Internal Go interface
|
|
6
|
+
|
|
7
|
+
[Keeper](./keeper/keeper.go)
|
|
8
|
+
* generic
|
|
9
|
+
* GetChildren
|
|
10
|
+
* GetEntry
|
|
11
|
+
* HasEntry
|
|
12
|
+
* HasStorage
|
|
13
|
+
* SetStorage[AndNotify]
|
|
14
|
+
* StreamCell-oriented (a StreamCell captures a block height and an array of values)
|
|
15
|
+
* AppendStorageValue[AndNotify]
|
|
16
|
+
* queue-oriented (a queue stores items at paths like "$prefix.$n", documenting
|
|
17
|
+
the n for the next item to be consumed at "$prefix.head" and the n for the next
|
|
18
|
+
next item to be pushed at "$prefix.tail" such that the queue is empty when both
|
|
19
|
+
head and tail store the same n)
|
|
20
|
+
* GetQueueLength
|
|
21
|
+
* PushQueueItem
|
|
22
|
+
|
|
23
|
+
## Internal JSON interface
|
|
24
|
+
|
|
25
|
+
This is used by the SwingSet "bridge".
|
|
26
|
+
|
|
27
|
+
[Receive](./vstorage.go) with input `{ "method": "...", "args": [...] }`
|
|
28
|
+
* generic
|
|
29
|
+
* method "entries", args path
|
|
30
|
+
* method "get"/"has", args path
|
|
31
|
+
* method "set"/"setWithoutNotify", args [[path, value?], ...]
|
|
32
|
+
* method "children", args path
|
|
33
|
+
* method "values", args path (returns values for children in the same order as method "children")
|
|
34
|
+
* method "size", args path (returns the count of children)
|
|
35
|
+
* StreamCell-oriented
|
|
36
|
+
* method "append", args [[path, value?], ...]
|
|
37
|
+
|
|
38
|
+
## CLI
|
|
39
|
+
|
|
40
|
+
A blockchain node may be interrogated by RPC using `agd [--node $url] query vstorage path` via [client/cli](./client/cli/query.go). (See command help for options and variants `data` and `children`.)
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
```sh
|
|
44
|
+
$ agd --node https://main.rpc.agoric.net:443/ query vstorage path published.reserve.
|
|
45
|
+
children:
|
|
46
|
+
- governance
|
|
47
|
+
- metrics
|
|
48
|
+
pagination: null
|
|
49
|
+
|
|
50
|
+
$ agd --node https://main.rpc.agoric.net:443/ query vstorage path -o json published.reserve.
|
|
51
|
+
{"children":["governance","metrics"],"pagination":null}
|
|
52
|
+
|
|
53
|
+
$ agd --node https://main.rpc.agoric.net:443/ query vstorage path published.reserve.metrics
|
|
54
|
+
value: '{"blockHeight":"11030240","values":["{\"body\":\"#{\\\"allocations\\\":{\\\"Fee\\\":{\\\"brand\\\":\\\"$0.Alleged:
|
|
55
|
+
IST brand\\\",\\\"value\\\":\\\"+20053582387\\\"}},\\\"shortfallBalance\\\":{\\\"brand\\\":\\\"$0\\\",\\\"value\\\":\\\"+0\\\"},\\\"totalFeeBurned\\\":{\\\"brand\\\":\\\"$0\\\",\\\"value\\\":\\\"+0\\\"},\\\"totalFeeMinted\\\":{\\\"brand\\\":\\\"$0\\\",\\\"value\\\":\\\"+0\\\"}}\",\"slots\":[\"board0257\"]}"]}'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## External protobuf interface
|
|
59
|
+
|
|
60
|
+
RPC via [Querier](./keeper/grpc_query.go),
|
|
61
|
+
and [CometBFT method "abci_query"](https://docs.cometbft.com/main/rpc/#/ABCI/abci_query)
|
|
62
|
+
with params `path` "/agoric.vstorage.Query/..."
|
|
63
|
+
and `data` \<serialized protobuf per [vstorage/query.proto](../../proto/agoric/vstorage/query.proto)>
|
|
64
|
+
(also via [Querier](./keeper/grpc_query.go))
|
|
65
|
+
* /agoric.vstorage.Query/CapData
|
|
66
|
+
* /agoric.vstorage.Query/Children
|
|
67
|
+
* /agoric.vstorage.Query/Data
|
|
68
|
+
|
|
69
|
+
Example:
|
|
70
|
+
```sh
|
|
71
|
+
$ curl -sS 'https://main.rpc.agoric.net/' -H 'Content-Type: application/json' -X POST --data "$(
|
|
72
|
+
jq -n --arg queryChildrenRequestHex 0a147075626c69736865642e636f6d6d697474656573 '{
|
|
73
|
+
id: 1,
|
|
74
|
+
method: "abci_query",
|
|
75
|
+
params: { path: "/agoric.vstorage.Query/Children", data: $queryChildrenRequestHex }
|
|
76
|
+
}' | \
|
|
77
|
+
tee /dev/stderr \
|
|
78
|
+
)" | \
|
|
79
|
+
jq . | \
|
|
80
|
+
tee /dev/stderr | \
|
|
81
|
+
jq -r '.result.response.value' | \
|
|
82
|
+
base64 -d | \
|
|
83
|
+
protoc -I golang/cosmos/proto/agoric/vstorage/ -I golang/cosmos/third_party/proto/ \
|
|
84
|
+
--decode=agoric.vstorage.QueryChildrenResponse golang/cosmos/proto/agoric/vstorage/query.proto
|
|
85
|
+
{
|
|
86
|
+
"id": 1,
|
|
87
|
+
"method": "abci_query",
|
|
88
|
+
"params": {
|
|
89
|
+
"path": "/agoric.vstorage.Query/Children",
|
|
90
|
+
"data": "0a147075626c69736865642e636f6d6d697474656573"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
{
|
|
94
|
+
"jsonrpc": "2.0",
|
|
95
|
+
"id": 1,
|
|
96
|
+
"result": {
|
|
97
|
+
"response": {
|
|
98
|
+
"code": 0,
|
|
99
|
+
"log": "",
|
|
100
|
+
"info": "",
|
|
101
|
+
"index": "0",
|
|
102
|
+
"key": null,
|
|
103
|
+
"value": "ChJFY29ub21pY19Db21taXR0ZWUKCWtyZWFkLWdvdg==",
|
|
104
|
+
"proofOps": null,
|
|
105
|
+
"height": "12222836",
|
|
106
|
+
"codespace": ""
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
children: "Economic_Committee"
|
|
111
|
+
children: "kread-gov"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## External JSON interface
|
|
115
|
+
|
|
116
|
+
As described at [Cosmos SDK: Using the REST Endpoints](https://docs.cosmos.network/main/run-node/interact-node#using-the-rest-endpoints), a blockchain node whose [`app.toml` configuration](https://docs.cosmos.network/main/run-node/run-node#configuring-the-node-using-apptoml-and-configtoml) enables the "REST" API server uses [gRPC-Gateway](https://grpc-ecosystem.github.io/grpc-gateway/) and `google.api.http` annotations in [vstorage/query.proto](../../proto/agoric/vstorage/query.proto) to automatically translate the protobuf-based RPC endpoints into URL paths that accept query parameters and emit JSON.
|
|
117
|
+
* /agoric/vstorage/capdata/$path?remotableValueFormat={object,string}[&mediaType=JSON%20Lines][&itemFormat=flat]
|
|
118
|
+
* /agoric/vstorage/children/$path
|
|
119
|
+
* /agoric/vstorage/data/$path
|
|
120
|
+
|
|
121
|
+
Example:
|
|
122
|
+
```sh
|
|
123
|
+
$ curl -sS 'https://main.api.agoric.net/agoric/vstorage/children/published.committees'
|
|
124
|
+
{
|
|
125
|
+
"children": [
|
|
126
|
+
"Economic_Committee"
|
|
127
|
+
],
|
|
128
|
+
"pagination": null
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Arbitrary-response HTTP interface
|
|
133
|
+
|
|
134
|
+
This depends upon appModule `LegacyQuerierHandler` functionality that is [removed from cosmos-sdk as of v0.47](https://github.com/cosmos/cosmos-sdk/blob/fa4d87ef7e6d87aaccc94c337ffd2fe90fcb7a9d/CHANGELOG.md#api-breaking-changes-3)
|
|
135
|
+
|
|
136
|
+
[legacy querier](./keeper/querier.go)
|
|
137
|
+
* /custom/vstorage/children/$path
|
|
138
|
+
* /custom/vstorage/data/$path
|