@agoric/cosmos 0.34.2-dev-7ffae88.0 → 0.34.2-orchestration-dev-096c4e8.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/Makefile +7 -0
- package/ante/ante.go +6 -5
- package/ante/fee.go +8 -7
- package/ante/inbound_test.go +3 -2
- package/ante/vm_admission.go +2 -1
- package/app/app.go +107 -59
- package/app/export.go +13 -6
- package/cmd/libdaemon/main_test.go +2 -1
- package/daemon/cmd/root.go +12 -5
- 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 +15 -7
- package/go.sum +8 -5
- package/package.json +3 -3
- package/proto/agoric/vlocalchain/.clang-format +7 -0
- package/proto/agoric/vlocalchain/vlocalchain.proto +31 -0
- package/vm/action.go +5 -4
- package/vm/action_test.go +31 -11
- package/vm/controller.go +22 -1
- package/vm/server.go +1 -1
- package/x/swingset/abci.go +10 -10
- package/x/swingset/client/cli/tx.go +4 -0
- package/x/swingset/handler.go +2 -1
- package/x/swingset/keeper/keeper.go +6 -12
- package/x/swingset/keeper/msg_server.go +18 -18
- package/x/swingset/keeper/proposal.go +13 -3
- package/x/swingset/keeper/querier.go +12 -11
- package/x/swingset/keeper/swing_store_exports_handler.go +7 -3
- package/x/swingset/proposal_handler.go +2 -1
- package/x/swingset/types/expected_keepers.go +3 -2
- package/x/swingset/types/msgs.go +25 -24
- package/x/swingset/types/params.go +2 -1
- package/x/swingset/types/proposal.go +5 -4
- package/x/vbank/handler.go +2 -1
- package/x/vbank/keeper/querier.go +4 -3
- package/x/vbank/vbank.go +3 -3
- package/x/vibc/alias.go +3 -0
- package/x/vibc/handler.go +16 -9
- package/x/vibc/keeper/keeper.go +102 -65
- package/x/vibc/keeper/triggers.go +101 -0
- package/x/vibc/module.go +4 -2
- package/x/vibc/types/expected_keepers.go +13 -0
- package/x/vibc/types/ibc_module.go +335 -0
- package/x/vibc/types/receiver.go +160 -0
- package/x/vlocalchain/alias.go +19 -0
- package/x/vlocalchain/handler.go +20 -0
- package/x/vlocalchain/keeper/keeper.go +279 -0
- package/x/vlocalchain/keeper/keeper_test.go +32 -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 +109 -0
- package/x/vlocalchain/vlocalchain_test.go +305 -0
- package/x/vstorage/handler.go +2 -1
- package/x/vstorage/keeper/keeper.go +5 -4
- package/x/vstorage/keeper/querier.go +6 -5
- package/x/vstorage/keeper/querier_test.go +4 -3
- 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 -255
- package/x/lien/keeper/keeper_test.go +0 -623
- package/x/lien/lien.go +0 -205
- package/x/lien/lien_test.go +0 -533
- 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 -394
- /package/{src/index.cjs → index.cjs} +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
package vlocalchain
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"fmt"
|
|
7
|
+
|
|
8
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
9
|
+
"github.com/gogo/protobuf/jsonpb"
|
|
10
|
+
|
|
11
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
12
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain/keeper"
|
|
13
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain/types"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
var _ vm.PortHandler = (*portHandler)(nil)
|
|
17
|
+
|
|
18
|
+
type portHandler struct {
|
|
19
|
+
keeper keeper.Keeper
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type portMessage struct {
|
|
23
|
+
Type string `json:"type"`
|
|
24
|
+
Address string `json:"address,omitempty"`
|
|
25
|
+
Messages json.RawMessage `json:"messages,omitempty"`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
func NewReceiver(keeper keeper.Keeper) portHandler {
|
|
29
|
+
return portHandler{keeper: keeper}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func (h portHandler) Receive(cctx context.Context, str string) (ret string, err error) {
|
|
33
|
+
var msg portMessage
|
|
34
|
+
err = json.Unmarshal([]byte(str), &msg)
|
|
35
|
+
if err != nil {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
switch msg.Type {
|
|
40
|
+
case "VLOCALCHAIN_ALLOCATE_ADDRESS":
|
|
41
|
+
addr := h.keeper.AllocateAddress(cctx)
|
|
42
|
+
var bz []byte
|
|
43
|
+
if bz, err = json.Marshal(addr.String()); err != nil {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
ret = string(bz)
|
|
47
|
+
|
|
48
|
+
case "VLOCALCHAIN_QUERY":
|
|
49
|
+
// Copy the JSON messages string into a CosmosTx object so we can
|
|
50
|
+
// deserialize it with just proto3 JSON.
|
|
51
|
+
cosmosTxBz := []byte(`{"messages":` + string(msg.Messages) + `}`)
|
|
52
|
+
|
|
53
|
+
var qms []types.QueryRequest
|
|
54
|
+
qms, err = h.keeper.DeserializeRequests(cosmosTxBz)
|
|
55
|
+
if err != nil {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// We need jsonpb for its access to the global registry.
|
|
60
|
+
marshaller := jsonpb.Marshaler{EmitDefaults: true, OrigName: true}
|
|
61
|
+
|
|
62
|
+
var s string
|
|
63
|
+
resps := make([]json.RawMessage, len(qms))
|
|
64
|
+
for i, qm := range qms {
|
|
65
|
+
var qr *types.QueryResponse
|
|
66
|
+
qr, err = h.keeper.Query(cctx, qm)
|
|
67
|
+
if err != nil {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
if s, err = marshaller.MarshalToString(qr); err != nil {
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
resps[i] = []byte(s)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var bz []byte
|
|
77
|
+
if bz, err = json.Marshal(resps); err != nil {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
ret = string(bz)
|
|
81
|
+
|
|
82
|
+
case "VLOCALCHAIN_EXECUTE_TX":
|
|
83
|
+
origCtx := sdk.UnwrapSDKContext(cctx)
|
|
84
|
+
|
|
85
|
+
// Copy the JSON messages string into a CosmosTx object so we can
|
|
86
|
+
// deserialize it with just proto3 JSON.
|
|
87
|
+
cosmosTxBz := []byte(`{"messages":` + string(msg.Messages) + `}`)
|
|
88
|
+
|
|
89
|
+
var msgs []sdk.Msg
|
|
90
|
+
if msgs, err = h.keeper.DeserializeTxMessages(cosmosTxBz); err != nil {
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var resps []interface{}
|
|
95
|
+
resps, err = h.keeper.ExecuteTx(origCtx, msg.Address, msgs)
|
|
96
|
+
if err != nil {
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
var bz []byte
|
|
101
|
+
if bz, err = json.Marshal(resps); err != nil {
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
ret = string(bz)
|
|
105
|
+
default:
|
|
106
|
+
err = fmt.Errorf("unrecognized message type %s", msg.Type)
|
|
107
|
+
}
|
|
108
|
+
return
|
|
109
|
+
}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
package vlocalchain_test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
|
|
9
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/app/params"
|
|
10
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
11
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain"
|
|
12
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/x/vlocalchain/types"
|
|
13
|
+
|
|
14
|
+
"github.com/cosmos/cosmos-sdk/baseapp"
|
|
15
|
+
"github.com/cosmos/cosmos-sdk/store"
|
|
16
|
+
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
17
|
+
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
18
|
+
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
19
|
+
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
|
|
20
|
+
"github.com/tendermint/tendermint/libs/log"
|
|
21
|
+
|
|
22
|
+
"github.com/gogo/protobuf/jsonpb"
|
|
23
|
+
"github.com/gogo/protobuf/proto"
|
|
24
|
+
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
|
25
|
+
dbm "github.com/tendermint/tm-db"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
var (
|
|
29
|
+
vlocalchainStoreKey = sdk.NewKVStoreKey(types.StoreKey)
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const (
|
|
33
|
+
firstAddr = "cosmos1uupflqrldlpkktssnzgp3r03ff6kz4u4kzd92pjgsfddye7grrlqt9rmmt"
|
|
34
|
+
msgAllocateAddress = `{"type":"VLOCALCHAIN_ALLOCATE_ADDRESS"}`
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
type mockBank struct {
|
|
38
|
+
banktypes.UnimplementedQueryServer
|
|
39
|
+
banktypes.UnimplementedMsgServer
|
|
40
|
+
balances map[string]sdk.Coins
|
|
41
|
+
failToSend error
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var _ banktypes.QueryServer = (*mockBank)(nil)
|
|
45
|
+
var _ banktypes.MsgServer = (*mockBank)(nil)
|
|
46
|
+
|
|
47
|
+
func (b *mockBank) AllBalances(cctx context.Context, req *banktypes.QueryAllBalancesRequest) (*banktypes.QueryAllBalancesResponse, error) {
|
|
48
|
+
addr, err := sdk.AccAddressFromBech32(req.Address)
|
|
49
|
+
if err != nil {
|
|
50
|
+
return nil, err
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var resp banktypes.QueryAllBalancesResponse
|
|
54
|
+
resp.Balances = sdk.Coins{}
|
|
55
|
+
if coins, ok := b.balances[addr.String()]; ok {
|
|
56
|
+
resp.Balances = coins
|
|
57
|
+
}
|
|
58
|
+
return &resp, nil
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func (b *mockBank) Send(cctx context.Context, req *banktypes.MsgSend) (*banktypes.MsgSendResponse, error) {
|
|
62
|
+
if b.failToSend != nil {
|
|
63
|
+
return nil, b.failToSend
|
|
64
|
+
}
|
|
65
|
+
return &banktypes.MsgSendResponse{}, nil
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type mockTransfer struct {
|
|
69
|
+
transfertypes.UnimplementedQueryServer
|
|
70
|
+
transfertypes.UnimplementedMsgServer
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
var _ transfertypes.QueryServer = (*mockTransfer)(nil)
|
|
74
|
+
var _ transfertypes.MsgServer = (*mockTransfer)(nil)
|
|
75
|
+
|
|
76
|
+
func (t *mockTransfer) Transfer(cctx context.Context, msg *transfertypes.MsgTransfer) (*transfertypes.MsgTransferResponse, error) {
|
|
77
|
+
return &transfertypes.MsgTransferResponse{Sequence: 1}, nil
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// makeTestKit creates a minimal Keeper and Context for use in testing.
|
|
81
|
+
func makeTestKit(bank *mockBank, transfer *mockTransfer) (vm.PortHandler, context.Context) {
|
|
82
|
+
encodingConfig := params.MakeEncodingConfig()
|
|
83
|
+
cdc := encodingConfig.Marshaler
|
|
84
|
+
|
|
85
|
+
txRouter := baseapp.NewMsgServiceRouter()
|
|
86
|
+
txRouter.SetInterfaceRegistry(encodingConfig.InterfaceRegistry)
|
|
87
|
+
queryRouter := baseapp.NewGRPCQueryRouter()
|
|
88
|
+
queryRouter.SetInterfaceRegistry(encodingConfig.InterfaceRegistry)
|
|
89
|
+
|
|
90
|
+
banktypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
91
|
+
banktypes.RegisterMsgServer(txRouter, bank)
|
|
92
|
+
banktypes.RegisterQueryServer(queryRouter, bank)
|
|
93
|
+
transfertypes.RegisterInterfaces(encodingConfig.InterfaceRegistry)
|
|
94
|
+
transfertypes.RegisterMsgServer(txRouter, transfer)
|
|
95
|
+
transfertypes.RegisterQueryServer(queryRouter, transfer)
|
|
96
|
+
|
|
97
|
+
// create a new Keeper
|
|
98
|
+
keeper := vlocalchain.NewKeeper(cdc, vlocalchainStoreKey, txRouter, queryRouter)
|
|
99
|
+
|
|
100
|
+
db := dbm.NewMemDB()
|
|
101
|
+
ms := store.NewCommitMultiStore(db)
|
|
102
|
+
ms.MountStoreWithDB(vlocalchainStoreKey, storetypes.StoreTypeIAVL, db)
|
|
103
|
+
err := ms.LoadLatestVersion()
|
|
104
|
+
if err != nil {
|
|
105
|
+
panic(err)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// create a new SDK Context
|
|
109
|
+
ctx := sdk.NewContext(ms, tmproto.Header{}, false, log.NewNopLogger()).WithBlockHeight(998)
|
|
110
|
+
|
|
111
|
+
handler := vm.NewProtectedPortHandler(vlocalchain.NewReceiver(keeper))
|
|
112
|
+
|
|
113
|
+
// create a new Go context
|
|
114
|
+
cctx := sdk.WrapSDKContext(ctx)
|
|
115
|
+
return handler, cctx
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
func TestAllocateAddress(t *testing.T) {
|
|
119
|
+
bank := &mockBank{}
|
|
120
|
+
transfer := &mockTransfer{}
|
|
121
|
+
handler, cctx := makeTestKit(bank, transfer)
|
|
122
|
+
|
|
123
|
+
addrs := map[string]bool{
|
|
124
|
+
firstAddr: false,
|
|
125
|
+
"cosmos1yj40fakym8kf4wvgz9tky7k9f3v9msm3t7frscrmkjsdkxkpsfkqgeczkg": false,
|
|
126
|
+
"cosmos1s76vryj7m8k8nm9le65a4plhf5rym5sumtt2n0vwnk5l6k4cwuhsj56ujj": false,
|
|
127
|
+
"cosmos1c5hplwyxk5jr2dsygjqepzfqvfukwduq9c4660aah76krf99m6gs0k7hvl": false,
|
|
128
|
+
"cosmos1ys3a7mtna3cad0wxcs4ddukn37stexjdvns8jfdn4uerlr95y4xqnrypf6": false,
|
|
129
|
+
}
|
|
130
|
+
numToTest := len(addrs)
|
|
131
|
+
for i := 0; i < numToTest; i++ {
|
|
132
|
+
// receive the message
|
|
133
|
+
ret, err := handler.Receive(cctx, msgAllocateAddress)
|
|
134
|
+
if err != nil {
|
|
135
|
+
t.Fatalf("unexpected error[%d]: %v", i, err)
|
|
136
|
+
}
|
|
137
|
+
if ret == "" {
|
|
138
|
+
t.Fatalf("expected non-empty address[%d]", i)
|
|
139
|
+
}
|
|
140
|
+
var addr string
|
|
141
|
+
if err := json.Unmarshal([]byte(ret), &addr); err != nil {
|
|
142
|
+
t.Fatalf("unexpected error unmarshalling address string[%d]: %v: %v", i, ret, err)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
already, ok := addrs[addr]
|
|
146
|
+
if !ok {
|
|
147
|
+
t.Fatalf("unexpected address[%d]: %v", i, addr)
|
|
148
|
+
}
|
|
149
|
+
if already {
|
|
150
|
+
t.Fatalf("unexpected duplicate address[%d]: %v", i, addr)
|
|
151
|
+
}
|
|
152
|
+
addrs[addr] = true
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
func TestQuery(t *testing.T) {
|
|
157
|
+
alreadyAddr := sdk.MustBech32ifyAddressBytes("cosmos", []byte("already"))
|
|
158
|
+
nonexistentAddr := sdk.MustBech32ifyAddressBytes("cosmos", []byte("nonexistent"))
|
|
159
|
+
bank := &mockBank{balances: map[string]sdk.Coins{
|
|
160
|
+
firstAddr: []sdk.Coin{sdk.NewCoin("fresh", sdk.NewInt(123))},
|
|
161
|
+
alreadyAddr: []sdk.Coin{sdk.NewCoin("stale", sdk.NewInt(321))},
|
|
162
|
+
}}
|
|
163
|
+
transfer := &mockTransfer{}
|
|
164
|
+
handler, cctx := makeTestKit(bank, transfer)
|
|
165
|
+
|
|
166
|
+
// get balances
|
|
167
|
+
testCases := []struct {
|
|
168
|
+
name string
|
|
169
|
+
addr string
|
|
170
|
+
failure string
|
|
171
|
+
expected sdk.Coins
|
|
172
|
+
}{
|
|
173
|
+
{"nonexistent", nonexistentAddr, "", sdk.Coins{}},
|
|
174
|
+
{"already", alreadyAddr, "", bank.balances[alreadyAddr]},
|
|
175
|
+
{"first", firstAddr, "", bank.balances[firstAddr]},
|
|
176
|
+
{"badaddr", "cosmos11111111111", "decoding bech32 failed: invalid separator index 16", sdk.Coins{}},
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
for _, tc := range testCases {
|
|
180
|
+
tc := tc
|
|
181
|
+
ctx := sdk.UnwrapSDKContext(cctx)
|
|
182
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
183
|
+
msgGetBalances := `{"type":"VLOCALCHAIN_QUERY","messages":[{"@type":"/cosmos.bank.v1beta1.QueryAllBalancesRequest","address":"` + tc.addr + `"}]}`
|
|
184
|
+
t.Logf("query request: %v", msgGetBalances)
|
|
185
|
+
ret, err := handler.Receive(cctx, msgGetBalances)
|
|
186
|
+
t.Logf("query response: %v", ret)
|
|
187
|
+
if tc.failure != "" {
|
|
188
|
+
if err == nil {
|
|
189
|
+
t.Fatalf("expected error %v, not nil with return %v", tc.failure, ret)
|
|
190
|
+
} else if err.Error() != tc.failure {
|
|
191
|
+
t.Fatalf("expected error %v, not %v", tc.failure, err)
|
|
192
|
+
}
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
if err != nil {
|
|
196
|
+
t.Fatalf("unexpected error: %v", err)
|
|
197
|
+
}
|
|
198
|
+
if err == nil && ret == "" {
|
|
199
|
+
t.Fatalf("expected non-empty json")
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Unmarshal the responses.
|
|
203
|
+
s := `{"responses":` + ret + `}`
|
|
204
|
+
|
|
205
|
+
unmarshaler := jsonpb.Unmarshaler{}
|
|
206
|
+
var qrs types.QueryResponses
|
|
207
|
+
if err = unmarshaler.Unmarshal(strings.NewReader(s), &qrs); err != nil {
|
|
208
|
+
t.Fatalf("unexpected error unmarshalling reply: %v: %v", ret, err)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
resps := qrs.Responses
|
|
212
|
+
if len(resps) != 1 {
|
|
213
|
+
t.Fatalf("expected responses length 1, got %v", len(resps))
|
|
214
|
+
}
|
|
215
|
+
if resps[0].Error != "" {
|
|
216
|
+
t.Fatalf("unexpected error response: %v", resps[0].Error)
|
|
217
|
+
}
|
|
218
|
+
if resps[0].Height != ctx.BlockHeight() {
|
|
219
|
+
t.Fatalf("expected height %v, got %v", ctx.BlockHeight(), resps[0].Height)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Unmarshal the Any.
|
|
223
|
+
var pb banktypes.QueryAllBalancesResponse
|
|
224
|
+
if err = proto.Unmarshal(resps[0].Reply.Value, &pb); err != nil {
|
|
225
|
+
t.Fatalf("unexpected error unmarshalling reply: %v: %v", ret, err)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if !pb.Balances.IsEqual(tc.expected) {
|
|
229
|
+
t.Errorf("unexpected balance: expected %v, got %v", tc.expected, pb.Balances)
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
func TestExecuteTx(t *testing.T) {
|
|
236
|
+
alreadyAddr := sdk.MustBech32ifyAddressBytes("cosmos", []byte("already"))
|
|
237
|
+
bank := &mockBank{balances: map[string]sdk.Coins{
|
|
238
|
+
firstAddr: []sdk.Coin{sdk.NewCoin("fresh", sdk.NewInt(123))},
|
|
239
|
+
alreadyAddr: []sdk.Coin{sdk.NewCoin("stale", sdk.NewInt(321))},
|
|
240
|
+
}}
|
|
241
|
+
transfer := &mockTransfer{}
|
|
242
|
+
handler, cctx := makeTestKit(bank, transfer)
|
|
243
|
+
|
|
244
|
+
// create a new message
|
|
245
|
+
msg := `{"type":"VLOCALCHAIN_ALLOCATE_ADDRESS"}`
|
|
246
|
+
ret, err := handler.Receive(cctx, msg)
|
|
247
|
+
if err != nil {
|
|
248
|
+
t.Fatalf("unexpected error: %s", err)
|
|
249
|
+
}
|
|
250
|
+
if ret == "" {
|
|
251
|
+
t.Fatalf("expected non-empty json")
|
|
252
|
+
}
|
|
253
|
+
var addr string
|
|
254
|
+
if err := json.Unmarshal([]byte(ret), &addr); err != nil {
|
|
255
|
+
t.Fatalf("unexpected error unmarshalling address string: %v: %s", ret, err)
|
|
256
|
+
}
|
|
257
|
+
if addr != firstAddr {
|
|
258
|
+
t.Fatalf("expected address %v, got %v", firstAddr, addr)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
testCases := []struct {
|
|
262
|
+
name string
|
|
263
|
+
signerAddress string
|
|
264
|
+
fromAddress string
|
|
265
|
+
toAddress string
|
|
266
|
+
failure string
|
|
267
|
+
}{
|
|
268
|
+
{"valid", addr, addr, alreadyAddr, ""},
|
|
269
|
+
{"parse error", `"` + addr, firstAddr, alreadyAddr, "invalid character 'c' after object key:value pair"},
|
|
270
|
+
{"invalid address", addr, alreadyAddr, alreadyAddr, "required signer cosmos1v9k8yetpv3us7src8u does not match actual signer"},
|
|
271
|
+
{"unauth", alreadyAddr, addr, alreadyAddr, "required signer cosmos1uupflqrldlpkktssnzgp3r03ff6kz4u4kzd92pjgsfddye7grrlqt9rmmt does not match actual signer"},
|
|
272
|
+
}
|
|
273
|
+
for _, tc := range testCases {
|
|
274
|
+
tc := tc
|
|
275
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
276
|
+
|
|
277
|
+
// create a new message
|
|
278
|
+
msg := `{"type":"VLOCALCHAIN_EXECUTE_TX","address":"` + tc.signerAddress +
|
|
279
|
+
`","messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"` +
|
|
280
|
+
tc.fromAddress + `","to_address":"` + tc.toAddress +
|
|
281
|
+
`","amount":[{"denom":"fresh","amount":"100"}]}]}`
|
|
282
|
+
|
|
283
|
+
ret, err = handler.Receive(cctx, msg)
|
|
284
|
+
if tc.failure != "" {
|
|
285
|
+
if err == nil {
|
|
286
|
+
t.Fatalf("expected error %v, not nil with return %v", tc.failure, ret)
|
|
287
|
+
}
|
|
288
|
+
if err.Error() != tc.failure {
|
|
289
|
+
t.Fatalf("expected error %v, not %v", tc.failure, err)
|
|
290
|
+
}
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if err != nil {
|
|
295
|
+
t.Fatalf("unexpected error: %s", err)
|
|
296
|
+
}
|
|
297
|
+
if ret == "" {
|
|
298
|
+
t.Fatalf("expected non-empty json")
|
|
299
|
+
}
|
|
300
|
+
if ret != "[{}]" {
|
|
301
|
+
t.Fatalf("expected response [{}], not %v", ret)
|
|
302
|
+
}
|
|
303
|
+
})
|
|
304
|
+
}
|
|
305
|
+
}
|
package/x/vstorage/handler.go
CHANGED
|
@@ -3,6 +3,7 @@ package vstorage
|
|
|
3
3
|
import (
|
|
4
4
|
"fmt"
|
|
5
5
|
|
|
6
|
+
sdkioerrors "cosmossdk.io/errors"
|
|
6
7
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
7
8
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
8
9
|
)
|
|
@@ -11,6 +12,6 @@ import (
|
|
|
11
12
|
func NewHandler(k Keeper) sdk.Handler {
|
|
12
13
|
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
|
|
13
14
|
errMsg := fmt.Sprintf("Unrecognized vstorage Msg type: %T", msg)
|
|
14
|
-
return nil,
|
|
15
|
+
return nil, sdkioerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
|
|
15
16
|
}
|
|
16
17
|
}
|
|
@@ -10,6 +10,7 @@ import (
|
|
|
10
10
|
"strconv"
|
|
11
11
|
"strings"
|
|
12
12
|
|
|
13
|
+
sdkmath "cosmossdk.io/math"
|
|
13
14
|
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
14
15
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
15
16
|
db "github.com/tendermint/tm-db"
|
|
@@ -428,7 +429,7 @@ func (k Keeper) GetNoDataValue() []byte {
|
|
|
428
429
|
return types.EncodedNoDataValue
|
|
429
430
|
}
|
|
430
431
|
|
|
431
|
-
func (k Keeper) getIntValue(ctx sdk.Context, path string) (
|
|
432
|
+
func (k Keeper) getIntValue(ctx sdk.Context, path string) (sdkmath.Int, error) {
|
|
432
433
|
indexEntry := k.GetEntry(ctx, path)
|
|
433
434
|
if !indexEntry.HasValue() {
|
|
434
435
|
return sdk.NewInt(0), nil
|
|
@@ -441,14 +442,14 @@ func (k Keeper) getIntValue(ctx sdk.Context, path string) (sdk.Int, error) {
|
|
|
441
442
|
return index, nil
|
|
442
443
|
}
|
|
443
444
|
|
|
444
|
-
func (k Keeper) GetQueueLength(ctx sdk.Context, queuePath string) (
|
|
445
|
+
func (k Keeper) GetQueueLength(ctx sdk.Context, queuePath string) (sdkmath.Int, error) {
|
|
445
446
|
head, err := k.getIntValue(ctx, queuePath+".head")
|
|
446
447
|
if err != nil {
|
|
447
|
-
return
|
|
448
|
+
return sdkmath.NewInt(0), err
|
|
448
449
|
}
|
|
449
450
|
tail, err := k.getIntValue(ctx, queuePath+".tail")
|
|
450
451
|
if err != nil {
|
|
451
|
-
return
|
|
452
|
+
return sdkmath.NewInt(0), err
|
|
452
453
|
}
|
|
453
454
|
// The tail index is exclusive
|
|
454
455
|
return tail.Sub(head), nil
|
|
@@ -3,6 +3,7 @@ package keeper
|
|
|
3
3
|
import (
|
|
4
4
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
5
5
|
|
|
6
|
+
sdkioerrors "cosmossdk.io/errors"
|
|
6
7
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
7
8
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
8
9
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
@@ -20,7 +21,7 @@ const (
|
|
|
20
21
|
// entry path with no extra data, and returns the path of that vstorage entry.
|
|
21
22
|
func getVstorageEntryPath(urlPathSegments []string) (string, error) {
|
|
22
23
|
if len(urlPathSegments) != 1 || types.ValidatePath(urlPathSegments[0]) != nil {
|
|
23
|
-
return "",
|
|
24
|
+
return "", sdkioerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid vstorage entry path")
|
|
24
25
|
}
|
|
25
26
|
return urlPathSegments[0], nil
|
|
26
27
|
}
|
|
@@ -51,7 +52,7 @@ func NewQuerier(keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier
|
|
|
51
52
|
}
|
|
52
53
|
return queryChildren(ctx, entryPath, req, keeper, legacyQuerierCdc)
|
|
53
54
|
default:
|
|
54
|
-
return nil,
|
|
55
|
+
return nil, sdkioerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown vstorage query path")
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -60,12 +61,12 @@ func NewQuerier(keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier
|
|
|
60
61
|
func queryData(ctx sdk.Context, path string, req abci.RequestQuery, keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) (res []byte, err error) {
|
|
61
62
|
entry := keeper.GetEntry(ctx, path)
|
|
62
63
|
if !entry.HasValue() {
|
|
63
|
-
return nil,
|
|
64
|
+
return nil, sdkioerrors.Wrap(sdkerrors.ErrNotFound, "no data for vstorage path")
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
bz, marshalErr := codec.MarshalJSONIndent(legacyQuerierCdc, types.Data{Value: entry.StringValue()})
|
|
67
68
|
if marshalErr != nil {
|
|
68
|
-
return nil,
|
|
69
|
+
return nil, sdkioerrors.Wrap(sdkerrors.ErrJSONMarshal, marshalErr.Error())
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
return bz, nil
|
|
@@ -82,7 +83,7 @@ func queryChildren(ctx sdk.Context, path string, req abci.RequestQuery, keeper K
|
|
|
82
83
|
|
|
83
84
|
bz, err2 := codec.MarshalJSONIndent(legacyQuerierCdc, types.Children{Children: klist})
|
|
84
85
|
if err2 != nil {
|
|
85
|
-
return nil,
|
|
86
|
+
return nil, sdkioerrors.Wrap(sdkerrors.ErrJSONMarshal, err2.Error())
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
return bz, nil
|
|
@@ -8,6 +8,7 @@ import (
|
|
|
8
8
|
|
|
9
9
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
10
10
|
|
|
11
|
+
sdkioerrors "cosmossdk.io/errors"
|
|
11
12
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
12
13
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
13
14
|
)
|
|
@@ -26,7 +27,7 @@ func TestQuerier(t *testing.T) {
|
|
|
26
27
|
label string
|
|
27
28
|
path []string
|
|
28
29
|
expected []byte
|
|
29
|
-
err *
|
|
30
|
+
err *sdkioerrors.Error
|
|
30
31
|
}
|
|
31
32
|
testCases := []testCase{}
|
|
32
33
|
|
|
@@ -77,7 +78,7 @@ func TestQuerier(t *testing.T) {
|
|
|
77
78
|
}...)
|
|
78
79
|
|
|
79
80
|
// Ensure stability of cosmos-sdk error codes
|
|
80
|
-
if codespace, code, _ :=
|
|
81
|
+
if codespace, code, _ := sdkioerrors.ABCIInfo(sdkerrors.ErrNotFound, true); codespace != "sdk" || code != 38 {
|
|
81
82
|
t.Errorf("cosmos-sdk ErrNotFound has codespace %s, code %d, expected sdk/38", codespace, code)
|
|
82
83
|
}
|
|
83
84
|
|
|
@@ -102,7 +103,7 @@ func TestQuerier(t *testing.T) {
|
|
|
102
103
|
if desc.err != nil {
|
|
103
104
|
if err == nil {
|
|
104
105
|
t.Errorf("%s: got no error, want error %q", desc.label, *desc.err)
|
|
105
|
-
} else if codespace, code, _ :=
|
|
106
|
+
} else if codespace, code, _ := sdkioerrors.ABCIInfo(err, true); codespace != desc.err.Codespace() || code != desc.err.ABCICode() {
|
|
106
107
|
t.Errorf("%s: got error %v, want error %q", desc.label, err, *desc.err)
|
|
107
108
|
}
|
|
108
109
|
} else if !bytes.Equal(res, desc.expected) {
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
syntax = "proto3";
|
|
2
|
-
package agoric.lien;
|
|
3
|
-
|
|
4
|
-
import "gogoproto/gogo.proto";
|
|
5
|
-
import "agoric/lien/lien.proto";
|
|
6
|
-
|
|
7
|
-
option go_package = "github.com/Agoric/agoric-sdk/golang/cosmos/x/lien/types";
|
|
8
|
-
|
|
9
|
-
// The initial or exported state.
|
|
10
|
-
message GenesisState {
|
|
11
|
-
option (gogoproto.equal) = false;
|
|
12
|
-
|
|
13
|
-
repeated AccountLien liens = 1 [
|
|
14
|
-
(gogoproto.nullable) = false
|
|
15
|
-
];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// The lien on a particular account
|
|
19
|
-
message AccountLien {
|
|
20
|
-
// Account address, bech32-encoded.
|
|
21
|
-
string address = 1;
|
|
22
|
-
|
|
23
|
-
// The liened amount. Should be nonzero.
|
|
24
|
-
Lien lien = 2;
|
|
25
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
syntax = "proto3";
|
|
2
|
-
package agoric.lien;
|
|
3
|
-
|
|
4
|
-
import "gogoproto/gogo.proto";
|
|
5
|
-
import "cosmos/base/v1beta1/coin.proto";
|
|
6
|
-
|
|
7
|
-
option go_package = "github.com/Agoric/agoric-sdk/golang/cosmos/x/lien/types";
|
|
8
|
-
|
|
9
|
-
// Lien contains the lien state of a particular account.
|
|
10
|
-
message Lien {
|
|
11
|
-
// coins holds the amount liened
|
|
12
|
-
repeated cosmos.base.v1beta1.Coin coins = 1 [
|
|
13
|
-
(gogoproto.nullable) = false,
|
|
14
|
-
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
|
|
15
|
-
(gogoproto.moretags) = "yaml:\"coins\""
|
|
16
|
-
];
|
|
17
|
-
// delegated tracks the net amount delegated for non-vesting accounts,
|
|
18
|
-
// or zero coins for vesting accounts.
|
|
19
|
-
// (Vesting accounts have their own fields to track delegation.)
|
|
20
|
-
repeated cosmos.base.v1beta1.Coin delegated = 2 [
|
|
21
|
-
(gogoproto.nullable) = false,
|
|
22
|
-
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
|
|
23
|
-
(gogoproto.moretags) = "yaml:\"delegated\""
|
|
24
|
-
];
|
|
25
|
-
}
|
package/x/lien/alias.go
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
package lien
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"github.com/Agoric/agoric-sdk/golang/cosmos/x/lien/keeper"
|
|
5
|
-
"github.com/Agoric/agoric-sdk/golang/cosmos/x/lien/types"
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
var (
|
|
9
|
-
ModuleName = types.ModuleName
|
|
10
|
-
NewKeeper = keeper.NewKeeper
|
|
11
|
-
NewWrappedAccountKeeper = types.NewWrappedAccountKeeper
|
|
12
|
-
StoreKey = types.StoreKey
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
type (
|
|
16
|
-
Keeper = keeper.Keeper
|
|
17
|
-
)
|
package/x/lien/genesis.go
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
package lien
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"github.com/Agoric/agoric-sdk/golang/cosmos/x/lien/types"
|
|
5
|
-
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
// DefaultGenesisState returns an empty GenesisState.
|
|
9
|
-
func DefaultGenesisState() types.GenesisState {
|
|
10
|
-
return types.GenesisState{}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// ValidateGenesis returns whether genesisState is well-formed.
|
|
14
|
-
// Since liens can apply to otherwise empty accounts and the source of truth
|
|
15
|
-
// is stored at the Swingset level, we can only validate the addresses.
|
|
16
|
-
func ValidateGenesis(genesisState types.GenesisState) error {
|
|
17
|
-
for _, accountLien := range genesisState.Liens {
|
|
18
|
-
_, err := sdk.AccAddressFromBech32(accountLien.Address)
|
|
19
|
-
if err != nil {
|
|
20
|
-
return err
|
|
21
|
-
}
|
|
22
|
-
err = accountLien.Lien.Coins.Validate()
|
|
23
|
-
if err != nil {
|
|
24
|
-
return err
|
|
25
|
-
}
|
|
26
|
-
err = accountLien.Lien.Delegated.Validate()
|
|
27
|
-
if err != nil {
|
|
28
|
-
return err
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return nil
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// InitGenesis uses the genesisState to initialize the store.
|
|
35
|
-
func InitGenesis(ctx sdk.Context, keeper Keeper, genesisState types.GenesisState) {
|
|
36
|
-
for _, accLien := range genesisState.Liens {
|
|
37
|
-
addr, err := sdk.AccAddressFromBech32(accLien.GetAddress())
|
|
38
|
-
if err != nil {
|
|
39
|
-
panic(err) // not possible if genesis state was validated
|
|
40
|
-
}
|
|
41
|
-
lien := accLien.GetLien()
|
|
42
|
-
keeper.SetLien(ctx, addr, *lien)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// ExportGenesis reads the store and returns an equivalent GenesisState.
|
|
47
|
-
func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState {
|
|
48
|
-
genesisState := types.GenesisState{}
|
|
49
|
-
keeper.IterateLiens(ctx, func(addr sdk.AccAddress, lien types.Lien) bool {
|
|
50
|
-
accLien := types.AccountLien{
|
|
51
|
-
Address: addr.String(),
|
|
52
|
-
Lien: &lien,
|
|
53
|
-
}
|
|
54
|
-
genesisState.Liens = append(genesisState.Liens, accLien)
|
|
55
|
-
return false
|
|
56
|
-
})
|
|
57
|
-
return genesisState
|
|
58
|
-
}
|