@agoric/cosmos 0.35.0-u11wf.0 → 0.35.0-u13.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 +44 -0
- package/Makefile +1 -1
- package/ante/ante.go +2 -2
- package/ante/inbound_test.go +8 -0
- package/app/app.go +46 -131
- package/app/export.go +0 -3
- package/app/sim_test.go +4 -4
- package/daemon/cmd/root.go +0 -2
- package/git-revision.txt +1 -1
- package/go.mod +56 -46
- package/go.sum +453 -154
- package/package.json +2 -2
- package/x/lien/keeper/account.go +13 -8
- package/x/swingset/keeper/keeper.go +39 -0
- package/x/swingset/keeper/migrations.go +7 -2
- package/x/swingset/keeper/msg_server.go +52 -5
- package/x/swingset/types/default-params.go +22 -16
- package/x/swingset/types/expected_keepers.go +11 -0
- package/x/swingset/types/msgs.go +43 -2
- package/x/swingset/types/params.go +74 -0
- package/x/swingset/types/params_test.go +116 -0
- package/x/vibc/ibc.go +26 -27
- package/x/vibc/keeper/keeper.go +5 -19
- package/x/vibc/types/expected_keepers.go +5 -4
- package/x/vibc/types/msgs.go +1 -1
- package/x/vibc/types/msgs.pb.go +1 -1
- package/x/vstorage/keeper/querier.go +31 -11
- package/x/vstorage/keeper/querier_test.go +112 -0
- package/x/vstorage/types/path_keys.go +22 -10
- package/x/vstorage/types/path_keys_test.go +84 -18
- package/app/const.go +0 -6
- package/x/swingset/legacy/v32/params.go +0 -37
- package/x/swingset/legacy/v32/params_test.go +0 -133
package/x/vibc/ibc.go
CHANGED
|
@@ -7,11 +7,11 @@ import (
|
|
|
7
7
|
"github.com/Agoric/agoric-sdk/golang/cosmos/vm"
|
|
8
8
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
9
9
|
capability "github.com/cosmos/cosmos-sdk/x/capability/types"
|
|
10
|
-
channeltypes "github.com/cosmos/ibc-go/
|
|
11
|
-
porttypes "github.com/cosmos/ibc-go/
|
|
12
|
-
host "github.com/cosmos/ibc-go/
|
|
10
|
+
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
|
|
11
|
+
porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types"
|
|
12
|
+
host "github.com/cosmos/ibc-go/v4/modules/core/24-host"
|
|
13
13
|
|
|
14
|
-
"github.com/cosmos/ibc-go/
|
|
14
|
+
"github.com/cosmos/ibc-go/v4/modules/core/exported"
|
|
15
15
|
|
|
16
16
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
17
17
|
)
|
|
@@ -167,8 +167,8 @@ func (im IBCModule) OnChanOpenInit(
|
|
|
167
167
|
channelCap *capability.Capability,
|
|
168
168
|
counterparty channeltypes.Counterparty,
|
|
169
169
|
version string,
|
|
170
|
-
) error {
|
|
171
|
-
return sdkerrors.Wrap(
|
|
170
|
+
) (string, error) {
|
|
171
|
+
return "", sdkerrors.Wrap(
|
|
172
172
|
channeltypes.ErrChannelNotFound,
|
|
173
173
|
fmt.Sprintf("vibc does not allow synthetic channelOpenInit for port %s", portID),
|
|
174
174
|
)
|
|
@@ -224,16 +224,15 @@ func (im IBCModule) OnChanOpenTry(
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
type channelOpenAckEvent struct {
|
|
227
|
-
Type
|
|
228
|
-
Event
|
|
229
|
-
PortID
|
|
230
|
-
ChannelID
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
BlockTime int64 `json:"blockTime"`
|
|
227
|
+
Type string `json:"type"` // IBC
|
|
228
|
+
Event string `json:"event"` // channelOpenAck
|
|
229
|
+
PortID string `json:"portID"`
|
|
230
|
+
ChannelID string `json:"channelID"`
|
|
231
|
+
CounterpartyVersion string `json:"counterpartyVersion"`
|
|
232
|
+
Counterparty channeltypes.Counterparty `json:"counterparty"`
|
|
233
|
+
ConnectionHops []string `json:"connectionHops"`
|
|
234
|
+
BlockHeight int64 `json:"blockHeight"`
|
|
235
|
+
BlockTime int64 `json:"blockTime"`
|
|
237
236
|
}
|
|
238
237
|
|
|
239
238
|
func (im IBCModule) OnChanOpenAck(
|
|
@@ -247,17 +246,17 @@ func (im IBCModule) OnChanOpenAck(
|
|
|
247
246
|
// returns an empty channel object that we can still use without crashing.
|
|
248
247
|
channel, _ := im.keeper.GetChannel(ctx, portID, channelID)
|
|
249
248
|
|
|
249
|
+
channel.Counterparty.ChannelId = counterpartyChannelID
|
|
250
250
|
event := channelOpenAckEvent{
|
|
251
|
-
Type:
|
|
252
|
-
Event:
|
|
253
|
-
PortID:
|
|
254
|
-
ChannelID:
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
BlockTime: ctx.BlockTime().Unix(),
|
|
251
|
+
Type: "IBC_EVENT",
|
|
252
|
+
Event: "channelOpenAck",
|
|
253
|
+
PortID: portID,
|
|
254
|
+
ChannelID: channelID,
|
|
255
|
+
CounterpartyVersion: counterpartyVersion,
|
|
256
|
+
Counterparty: channel.Counterparty,
|
|
257
|
+
ConnectionHops: channel.ConnectionHops,
|
|
258
|
+
BlockHeight: ctx.BlockHeight(),
|
|
259
|
+
BlockTime: ctx.BlockTime().Unix(),
|
|
261
260
|
}
|
|
262
261
|
|
|
263
262
|
return im.PushAction(ctx, event)
|
|
@@ -374,7 +373,7 @@ func (im IBCModule) OnRecvPacket(
|
|
|
374
373
|
|
|
375
374
|
err := im.PushAction(ctx, event)
|
|
376
375
|
if err != nil {
|
|
377
|
-
return channeltypes.NewErrorAcknowledgement(err
|
|
376
|
+
return channeltypes.NewErrorAcknowledgement(err)
|
|
378
377
|
}
|
|
379
378
|
|
|
380
379
|
return nil
|
package/x/vibc/keeper/keeper.go
CHANGED
|
@@ -9,10 +9,10 @@ import (
|
|
|
9
9
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
10
10
|
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
|
|
11
11
|
capability "github.com/cosmos/cosmos-sdk/x/capability/types"
|
|
12
|
-
channeltypes "github.com/cosmos/ibc-go/
|
|
13
|
-
porttypes "github.com/cosmos/ibc-go/
|
|
14
|
-
host "github.com/cosmos/ibc-go/
|
|
15
|
-
ibcexported "github.com/cosmos/ibc-go/
|
|
12
|
+
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
|
|
13
|
+
porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types"
|
|
14
|
+
host "github.com/cosmos/ibc-go/v4/modules/core/24-host"
|
|
15
|
+
ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported"
|
|
16
16
|
|
|
17
17
|
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
|
18
18
|
|
|
@@ -92,13 +92,7 @@ func (k Keeper) ChanOpenInit(ctx sdk.Context, order channeltypes.Order, connecti
|
|
|
92
92
|
return err
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
ctx.EventManager().EmitEvents(sdk.Events{
|
|
97
|
-
sdk.NewEvent(
|
|
98
|
-
sdk.EventTypeMessage,
|
|
99
|
-
sdk.NewAttribute(sdk.AttributeKeyModule, channeltypes.AttributeValueCategory),
|
|
100
|
-
),
|
|
101
|
-
})
|
|
95
|
+
k.channelKeeper.WriteOpenInitChannel(ctx, portID, channelID, order, connectionHops, counterparty, version)
|
|
102
96
|
return nil
|
|
103
97
|
}
|
|
104
98
|
|
|
@@ -157,14 +151,6 @@ func (k Keeper) ChanCloseInit(ctx sdk.Context, portID, channelID string) error {
|
|
|
157
151
|
if err != nil {
|
|
158
152
|
return err
|
|
159
153
|
}
|
|
160
|
-
|
|
161
|
-
// We need to emit a channel event to notify the relayer.
|
|
162
|
-
ctx.EventManager().EmitEvents(sdk.Events{
|
|
163
|
-
sdk.NewEvent(
|
|
164
|
-
sdk.EventTypeMessage,
|
|
165
|
-
sdk.NewAttribute(sdk.AttributeKeyModule, channeltypes.AttributeValueCategory),
|
|
166
|
-
),
|
|
167
|
-
})
|
|
168
154
|
return nil
|
|
169
155
|
}
|
|
170
156
|
|
|
@@ -3,9 +3,9 @@ package types
|
|
|
3
3
|
import (
|
|
4
4
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
5
5
|
capability "github.com/cosmos/cosmos-sdk/x/capability/types"
|
|
6
|
-
connection "github.com/cosmos/ibc-go/
|
|
7
|
-
channel "github.com/cosmos/ibc-go/
|
|
8
|
-
ibcexported "github.com/cosmos/ibc-go/
|
|
6
|
+
connection "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"
|
|
7
|
+
channel "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
|
|
8
|
+
ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported"
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
// ChannelKeeper defines the expected IBC channel keeper
|
|
@@ -16,7 +16,8 @@ type ChannelKeeper interface {
|
|
|
16
16
|
WriteAcknowledgement(ctx sdk.Context, channelCap *capability.Capability, packet ibcexported.PacketI, acknowledgement ibcexported.Acknowledgement) error
|
|
17
17
|
ChanOpenInit(ctx sdk.Context, order channel.Order, connectionHops []string, portID string,
|
|
18
18
|
portCap *capability.Capability, counterparty channel.Counterparty, version string) (string, *capability.Capability, error)
|
|
19
|
-
|
|
19
|
+
WriteOpenInitChannel(ctx sdk.Context, portID, channelID string, order channel.Order,
|
|
20
|
+
connectionHops []string, counterparty channel.Counterparty, version string)
|
|
20
21
|
ChanCloseInit(ctx sdk.Context, portID, channelID string, chanCap *capability.Capability) error
|
|
21
22
|
TimeoutExecuted(ctx sdk.Context, channelCap *capability.Capability, packet ibcexported.PacketI) error
|
|
22
23
|
}
|
package/x/vibc/types/msgs.go
CHANGED
|
@@ -4,7 +4,7 @@ import (
|
|
|
4
4
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
5
5
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
6
6
|
|
|
7
|
-
chanTypes "github.com/cosmos/ibc-go/
|
|
7
|
+
chanTypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
|
|
8
8
|
)
|
|
9
9
|
|
|
10
10
|
const RouterKey = ModuleName // this was defined in your key.go file
|
package/x/vibc/types/msgs.pb.go
CHANGED
|
@@ -7,7 +7,7 @@ import (
|
|
|
7
7
|
context "context"
|
|
8
8
|
fmt "fmt"
|
|
9
9
|
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
|
|
10
|
-
types "github.com/cosmos/ibc-go/
|
|
10
|
+
types "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
|
|
11
11
|
_ "github.com/gogo/protobuf/gogoproto"
|
|
12
12
|
grpc1 "github.com/gogo/protobuf/grpc"
|
|
13
13
|
proto "github.com/gogo/protobuf/proto"
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
package keeper
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
"strings"
|
|
5
|
-
|
|
6
4
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
7
5
|
|
|
8
6
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
@@ -18,14 +16,36 @@ const (
|
|
|
18
16
|
QueryChildren = "children"
|
|
19
17
|
)
|
|
20
18
|
|
|
21
|
-
//
|
|
19
|
+
// getVstorageEntryPath validates that a request URL path represents a valid
|
|
20
|
+
// entry path with no extra data, and returns the path of that vstorage entry.
|
|
21
|
+
func getVstorageEntryPath(urlPathSegments []string) (string, error) {
|
|
22
|
+
if len(urlPathSegments) != 1 || types.ValidatePath(urlPathSegments[0]) != nil {
|
|
23
|
+
return "", sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid vstorage entry path")
|
|
24
|
+
}
|
|
25
|
+
return urlPathSegments[0], nil
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// NewQuerier returns the function for handling queries routed to this module.
|
|
29
|
+
// It performs its own routing based on the first slash-separated URL path
|
|
30
|
+
// segment (e.g., URL path `/data/foo.bar` is a request for the value associated
|
|
31
|
+
// with vstorage path "foo.bar", and `/children/foo.bar` is a request for the
|
|
32
|
+
// child path segments immediately underneath vstorage path "foo.bar" which may
|
|
33
|
+
// be used to extend it to a vstorage path such as "foo.bar.baz").
|
|
22
34
|
func NewQuerier(keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier {
|
|
23
|
-
return func(ctx sdk.Context,
|
|
24
|
-
switch
|
|
35
|
+
return func(ctx sdk.Context, urlPathSegments []string, req abci.RequestQuery) (res []byte, err error) {
|
|
36
|
+
switch urlPathSegments[0] {
|
|
25
37
|
case QueryData:
|
|
26
|
-
|
|
38
|
+
entryPath, entryPathErr := getVstorageEntryPath(urlPathSegments[1:])
|
|
39
|
+
if entryPathErr != nil {
|
|
40
|
+
return nil, entryPathErr
|
|
41
|
+
}
|
|
42
|
+
return queryData(ctx, entryPath, req, keeper, legacyQuerierCdc)
|
|
27
43
|
case QueryChildren:
|
|
28
|
-
|
|
44
|
+
entryPath, entryPathErr := getVstorageEntryPath(urlPathSegments[1:])
|
|
45
|
+
if entryPathErr != nil {
|
|
46
|
+
return nil, entryPathErr
|
|
47
|
+
}
|
|
48
|
+
return queryChildren(ctx, entryPath, req, keeper, legacyQuerierCdc)
|
|
29
49
|
default:
|
|
30
50
|
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown vstorage query endpoint")
|
|
31
51
|
}
|
|
@@ -36,12 +56,12 @@ func NewQuerier(keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) sdk.Querier
|
|
|
36
56
|
func queryData(ctx sdk.Context, path string, req abci.RequestQuery, keeper Keeper, legacyQuerierCdc *codec.LegacyAmino) (res []byte, err error) {
|
|
37
57
|
entry := keeper.GetEntry(ctx, path)
|
|
38
58
|
if !entry.HasValue() {
|
|
39
|
-
return nil, sdkerrors.Wrap(sdkerrors.
|
|
59
|
+
return nil, sdkerrors.Wrap(sdkerrors.ErrNotFound, "no data for vstorage path")
|
|
40
60
|
}
|
|
41
61
|
|
|
42
|
-
bz,
|
|
43
|
-
if
|
|
44
|
-
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal,
|
|
62
|
+
bz, marshalErr := codec.MarshalJSONIndent(legacyQuerierCdc, types.Data{Value: entry.StringValue()})
|
|
63
|
+
if marshalErr != nil {
|
|
64
|
+
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, marshalErr.Error())
|
|
45
65
|
}
|
|
46
66
|
|
|
47
67
|
return bz, nil
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
package keeper
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"testing"
|
|
6
|
+
|
|
7
|
+
agoric "github.com/Agoric/agoric-sdk/golang/cosmos/types"
|
|
8
|
+
|
|
9
|
+
abci "github.com/tendermint/tendermint/abci/types"
|
|
10
|
+
|
|
11
|
+
"github.com/cosmos/cosmos-sdk/codec"
|
|
12
|
+
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
func TestQuerier(t *testing.T) {
|
|
16
|
+
testKit := makeTestKit()
|
|
17
|
+
ctx, keeper := testKit.ctx, testKit.vstorageKeeper
|
|
18
|
+
legacyQuerierCdc := codec.NewAminoCodec(codec.NewLegacyAmino())
|
|
19
|
+
querier := NewQuerier(keeper, legacyQuerierCdc.LegacyAmino)
|
|
20
|
+
|
|
21
|
+
// Populate mock data
|
|
22
|
+
keeper.SetStorage(ctx, agoric.NewKVEntry("foo.bar", "42"))
|
|
23
|
+
keeper.SetStorage(ctx, agoric.NewKVEntry("foo.baz", "hello"))
|
|
24
|
+
|
|
25
|
+
type testCase struct {
|
|
26
|
+
label string
|
|
27
|
+
path []string
|
|
28
|
+
expected []byte
|
|
29
|
+
err *sdkerrors.Error
|
|
30
|
+
}
|
|
31
|
+
testCases := []testCase{}
|
|
32
|
+
|
|
33
|
+
// Test invalid endpoint
|
|
34
|
+
testCases = append(testCases, []testCase{
|
|
35
|
+
{label: "invalid endpoint",
|
|
36
|
+
path: []string{"foo"},
|
|
37
|
+
err: sdkerrors.ErrUnknownRequest,
|
|
38
|
+
},
|
|
39
|
+
}...)
|
|
40
|
+
|
|
41
|
+
// Test invalid arguments to valid data and children endpoints
|
|
42
|
+
for _, endpoint := range []string{"data", "children"} {
|
|
43
|
+
testCases = append(testCases, []testCase{
|
|
44
|
+
{label: endpoint + ": no entry path",
|
|
45
|
+
path: []string{endpoint},
|
|
46
|
+
err: sdkerrors.ErrInvalidRequest,
|
|
47
|
+
},
|
|
48
|
+
{label: endpoint + ": too many segments",
|
|
49
|
+
path: []string{endpoint, "foo", "bar"},
|
|
50
|
+
err: sdkerrors.ErrInvalidRequest,
|
|
51
|
+
},
|
|
52
|
+
{label: endpoint + ": invalid path",
|
|
53
|
+
path: []string{endpoint, ".", ""},
|
|
54
|
+
err: sdkerrors.ErrInvalidRequest,
|
|
55
|
+
},
|
|
56
|
+
}...)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Test data endpoint with valid vstorage path
|
|
60
|
+
testCases = append(testCases, []testCase{
|
|
61
|
+
{label: "data: non-existent path",
|
|
62
|
+
path: []string{"data", "bar"},
|
|
63
|
+
// DO NOT CHANGE
|
|
64
|
+
// The UI and CLI check for the specific cosmos-sdk error code & codespace
|
|
65
|
+
err: sdkerrors.ErrNotFound,
|
|
66
|
+
},
|
|
67
|
+
{label: "data: path with no data",
|
|
68
|
+
path: []string{"data", "foo"},
|
|
69
|
+
// DO NOT CHANGE
|
|
70
|
+
// The UI and CLI check for the specific cosmos-sdk error code & codespace
|
|
71
|
+
err: sdkerrors.ErrNotFound,
|
|
72
|
+
},
|
|
73
|
+
{label: "data: path with data",
|
|
74
|
+
path: []string{"data", "foo.bar"},
|
|
75
|
+
expected: []byte("{\n \"value\": \"42\"\n}"),
|
|
76
|
+
},
|
|
77
|
+
}...)
|
|
78
|
+
|
|
79
|
+
// Ensure stability of cosmos-sdk error codes
|
|
80
|
+
if codespace, code, _ := sdkerrors.ABCIInfo(sdkerrors.ErrNotFound, true); codespace != "sdk" || code != 38 {
|
|
81
|
+
t.Errorf("cosmos-sdk ErrNotFound has codespace %s, code %d, expected sdk/38", codespace, code)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Test children endpoint with valid vstorage path
|
|
85
|
+
testCases = append(testCases, []testCase{
|
|
86
|
+
{label: "children: non-existent path",
|
|
87
|
+
path: []string{"children", "bar"},
|
|
88
|
+
expected: []byte("{\n \"children\": []\n}"),
|
|
89
|
+
},
|
|
90
|
+
{label: "children: path with no children",
|
|
91
|
+
path: []string{"children", "foo.bar"},
|
|
92
|
+
expected: []byte("{\n \"children\": []\n}"),
|
|
93
|
+
},
|
|
94
|
+
{label: "children: path with children",
|
|
95
|
+
path: []string{"children", "foo"},
|
|
96
|
+
expected: []byte("{\n \"children\": [\n \"bar\",\n \"baz\"\n ]\n}"),
|
|
97
|
+
},
|
|
98
|
+
}...)
|
|
99
|
+
|
|
100
|
+
for _, desc := range testCases {
|
|
101
|
+
res, err := querier(ctx, desc.path, abci.RequestQuery{})
|
|
102
|
+
if desc.err != nil {
|
|
103
|
+
if err == nil {
|
|
104
|
+
t.Errorf("%s: got no error, want error %q", desc.label, *desc.err)
|
|
105
|
+
} else if codespace, code, _ := sdkerrors.ABCIInfo(err, true); codespace != desc.err.Codespace() || code != desc.err.ABCICode() {
|
|
106
|
+
t.Errorf("%s: got error %v, want error %q", desc.label, err, *desc.err)
|
|
107
|
+
}
|
|
108
|
+
} else if !bytes.Equal(res, desc.expected) {
|
|
109
|
+
t.Errorf("%s: wrong result: %#v, expected %#v", desc.label, string(res), string(desc.expected))
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -7,9 +7,17 @@ import (
|
|
|
7
7
|
"strings"
|
|
8
8
|
)
|
|
9
9
|
|
|
10
|
-
// - A "path" is a sequence of zero or more dot-separated nonempty
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// - A "path" is a sequence of zero or more dot-separated nonempty segments
|
|
11
|
+
// using a restricted alphabet of ASCII alphanumerics plus underscore and dash,
|
|
12
|
+
// consistent with packages/internal/src/lib-chainStorage.js but not currently
|
|
13
|
+
// enforcing a length restriction on path segments.
|
|
14
|
+
// So `""`, `"foo"`, and `"foo.bar__baz.qux--quux"` are paths but `"."`,
|
|
15
|
+
// `"foo/bar"`, `"fo\to"`, and `"foö"` are not.
|
|
16
|
+
// This alphabet might be expanded in the future, but such expansion SHOULD NOT
|
|
17
|
+
// include control characters (including those that are not ASCII, such as
|
|
18
|
+
// U+202E RIGHT-TO-LEFT OVERRIDE), slash `/` (which separates ABCI request path
|
|
19
|
+
// segments in e.g. `custom/vstorage/data/foo`), or backslash `\` (which should
|
|
20
|
+
// be reserved for adding escape sequences).
|
|
13
21
|
//
|
|
14
22
|
// - An encoded key for a path is the path prefixed with its length (in ASCII
|
|
15
23
|
// digits), separated by nul, followed by the path with dots replaced with nul.
|
|
@@ -42,22 +50,26 @@ func EncodedKeyToPath(key []byte) string {
|
|
|
42
50
|
return string(pathBytes)
|
|
43
51
|
}
|
|
44
52
|
|
|
45
|
-
var
|
|
53
|
+
var pathSegmentPattern = `[a-zA-Z0-9_-]+`
|
|
54
|
+
var pathSeparatorPattern = `\` + PathSeparator
|
|
55
|
+
var pathPattern = fmt.Sprintf(`^$|^%[1]s(%[2]s%[1]s)*$`, pathSegmentPattern, pathSeparatorPattern)
|
|
56
|
+
var pathMatcher = regexp.MustCompile(pathPattern)
|
|
46
57
|
|
|
47
58
|
func ValidatePath(path string) error {
|
|
48
|
-
if
|
|
49
|
-
return
|
|
50
|
-
}
|
|
51
|
-
if strings.Contains(path, PathSeparator+PathSeparator) {
|
|
52
|
-
return fmt.Errorf("path %q contains doubled separators", path)
|
|
59
|
+
if pathMatcher.MatchString(path) {
|
|
60
|
+
return nil
|
|
53
61
|
}
|
|
62
|
+
// Rescan the string to give a useful error message.
|
|
54
63
|
if strings.HasPrefix(path, PathSeparator) {
|
|
55
64
|
return fmt.Errorf("path %q starts with separator", path)
|
|
56
65
|
}
|
|
57
66
|
if strings.HasSuffix(path, PathSeparator) {
|
|
58
67
|
return fmt.Errorf("path %q ends with separator", path)
|
|
59
68
|
}
|
|
60
|
-
|
|
69
|
+
if strings.Contains(path, PathSeparator+PathSeparator) {
|
|
70
|
+
return fmt.Errorf("path %q contains doubled separators", path)
|
|
71
|
+
}
|
|
72
|
+
return fmt.Errorf("path %q contains invalid characters", path)
|
|
61
73
|
}
|
|
62
74
|
|
|
63
75
|
// PathToEncodedKey converts a path to a byte slice key
|
|
@@ -2,40 +2,106 @@ package types
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"bytes"
|
|
5
|
+
"fmt"
|
|
6
|
+
"strings"
|
|
5
7
|
"testing"
|
|
6
8
|
)
|
|
7
9
|
|
|
8
10
|
func Test_Key_Encoding(t *testing.T) {
|
|
9
11
|
tests := []struct {
|
|
10
|
-
name
|
|
11
|
-
|
|
12
|
-
key
|
|
12
|
+
name string
|
|
13
|
+
path string
|
|
14
|
+
key []byte
|
|
15
|
+
errContains string
|
|
13
16
|
}{
|
|
14
17
|
{
|
|
15
|
-
name:
|
|
16
|
-
|
|
17
|
-
key:
|
|
18
|
+
name: "empty path",
|
|
19
|
+
path: "",
|
|
20
|
+
key: []byte("0\x00"),
|
|
18
21
|
},
|
|
19
22
|
{
|
|
20
|
-
name:
|
|
21
|
-
|
|
22
|
-
key:
|
|
23
|
+
name: "single-segment path",
|
|
24
|
+
path: "some",
|
|
25
|
+
key: []byte("1\x00some"),
|
|
23
26
|
},
|
|
24
27
|
{
|
|
25
|
-
name:
|
|
26
|
-
|
|
27
|
-
key:
|
|
28
|
+
name: "multi-segment path",
|
|
29
|
+
path: "some.child.grandchild",
|
|
30
|
+
key: []byte("3\x00some\x00child\x00grandchild"),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "non-letters",
|
|
34
|
+
path: "-_0_-",
|
|
35
|
+
key: []byte("1\x00-_0_-"),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "lone dot",
|
|
39
|
+
path: ".",
|
|
40
|
+
errContains: "starts with separator",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "starts with dot",
|
|
44
|
+
path: ".foo",
|
|
45
|
+
errContains: "starts with separator",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "ends with dot",
|
|
49
|
+
path: "foo.",
|
|
50
|
+
errContains: "ends with separator",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "empty path segment",
|
|
54
|
+
path: "foo..bar",
|
|
55
|
+
errContains: "doubled separators",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "invalid path character U+0000 NUL",
|
|
59
|
+
path: "foo\x00bar",
|
|
60
|
+
errContains: "invalid character",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: "invalid path character U+002F SOLIDUS",
|
|
64
|
+
path: "foo/bar",
|
|
65
|
+
errContains: "invalid character",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "invalid path character U+005C REVERSE SOLIDUS",
|
|
69
|
+
path: "foo\\bar",
|
|
70
|
+
errContains: "invalid character",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "invalid path character U+007C VERTICAL LINE",
|
|
74
|
+
path: "foo|bar",
|
|
75
|
+
errContains: "invalid character",
|
|
28
76
|
},
|
|
29
77
|
}
|
|
30
78
|
|
|
31
79
|
for _, tt := range tests {
|
|
80
|
+
if tt.key != nil {
|
|
81
|
+
t.Run(tt.name, func(t *testing.T) {
|
|
82
|
+
if key := PathToEncodedKey(tt.path); !bytes.Equal(key, tt.key) {
|
|
83
|
+
t.Errorf("pathToKey(%q) = []byte(%q), want []byte(%q)", tt.path, key, tt.key)
|
|
84
|
+
}
|
|
85
|
+
if path := EncodedKeyToPath(tt.key); path != tt.path {
|
|
86
|
+
t.Errorf("keyToPath([]byte(%q)) = %q, want %q", tt.key, path, tt.path)
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
continue
|
|
90
|
+
}
|
|
91
|
+
expect := tt.errContains
|
|
32
92
|
t.Run(tt.name, func(t *testing.T) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
93
|
+
var key []byte
|
|
94
|
+
defer func() {
|
|
95
|
+
if err := recover(); err != nil {
|
|
96
|
+
errStr := fmt.Sprintf("%v", err)
|
|
97
|
+
if !strings.Contains(errStr, expect) {
|
|
98
|
+
t.Errorf("pathToKey(%q) = error %q, want error %v", tt.path, errStr, expect)
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
t.Errorf("pathToKey(%q) = []byte(%q), want error %v", tt.path, key, expect)
|
|
102
|
+
}
|
|
103
|
+
}()
|
|
104
|
+
key = PathToEncodedKey(tt.path)
|
|
39
105
|
})
|
|
40
106
|
}
|
|
41
107
|
}
|
package/app/const.go
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
package v32
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"fmt"
|
|
5
|
-
|
|
6
|
-
"github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/types"
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
// UpdateParams performs the parameter updates to migrate to version 2,
|
|
10
|
-
// returning the updated params or an error.
|
|
11
|
-
func UpdateParams(params types.Params) (types.Params, error) {
|
|
12
|
-
newBpu, err := addStorageBeanCost(params.BeansPerUnit)
|
|
13
|
-
if err != nil {
|
|
14
|
-
return params, err
|
|
15
|
-
}
|
|
16
|
-
params.BeansPerUnit = newBpu
|
|
17
|
-
return params, nil
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// addStorageBeanCost adds the default beans per storage byte cost,
|
|
21
|
-
// if it's not in the list of bean costs already, returning the possibly-updated list.
|
|
22
|
-
// or an error if there's no default storage cost.
|
|
23
|
-
func addStorageBeanCost(bpu []types.StringBeans) ([]types.StringBeans, error) {
|
|
24
|
-
for _, ob := range bpu {
|
|
25
|
-
if ob.Key == types.BeansPerStorageByte {
|
|
26
|
-
// success if there's already an entry
|
|
27
|
-
return bpu, nil
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
defaultParams := types.DefaultParams()
|
|
31
|
-
for _, b := range defaultParams.BeansPerUnit {
|
|
32
|
-
if b.Key == types.BeansPerStorageByte {
|
|
33
|
-
return append(bpu, b), nil
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return bpu, fmt.Errorf("no beans per storage byte in default params %v", defaultParams)
|
|
37
|
-
}
|