@agoric/cosmos 0.35.0-u18.4 → 0.35.0-u18a.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 +40 -0
- package/ante/inbound_test.go +2 -2
- package/app/app.go +26 -9
- package/app/upgrade.go +47 -134
- package/daemon/cmd/root.go +48 -15
- package/git-revision.txt +1 -1
- package/go.mod +82 -71
- package/go.sum +200 -167
- package/package.json +2 -2
- package/proto/agoric/swingset/swingset.proto +25 -0
- package/proto/agoric/vbank/vbank.proto +7 -0
- package/types/address_hooks.go +242 -0
- package/types/address_hooks_test.go +221 -0
- package/x/swingset/genesis.go +99 -21
- package/x/swingset/keeper/keeper.go +16 -7
- package/x/swingset/module.go +17 -2
- package/x/swingset/testing/queue.go +8 -0
- package/x/swingset/types/default-params.go +31 -5
- package/x/swingset/types/expected_keepers.go +2 -2
- package/x/swingset/types/msgs.go +34 -12
- package/x/swingset/types/params.go +53 -43
- package/x/swingset/types/params_test.go +75 -9
- package/x/swingset/types/swingset.pb.go +386 -56
- package/x/vbank/README.md +6 -1
- package/x/vbank/keeper/keeper.go +4 -9
- package/x/vbank/keeper/migrations.go +30 -0
- package/x/vbank/module.go +8 -2
- package/x/vbank/types/params.go +43 -2
- package/x/vbank/types/vbank.pb.go +105 -36
- package/x/vbank/vbank_test.go +12 -7
- package/x/vibc/keeper/keeper.go +2 -5
- package/x/vibc/keeper/triggers.go +3 -6
- package/x/vibc/types/receiver.go +11 -5
- package/x/vstorage/testing/queue.go +10 -3
- package/x/vtransfer/ibc_middleware.go +5 -1
- package/x/vtransfer/ibc_middleware_test.go +511 -145
- package/x/vtransfer/keeper/keeper.go +215 -50
- package/x/vtransfer/types/genesis.pb.go +1 -0
- package/x/vtransfer/utils_test.go +111 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/cosmos",
|
|
3
|
-
"version": "0.35.0-
|
|
3
|
+
"version": "0.35.0-u18a.0",
|
|
4
4
|
"description": "Connect JS to the Cosmos blockchain SDK",
|
|
5
5
|
"parsers": {
|
|
6
6
|
"js": "mjs"
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"typeCoverage": {
|
|
40
40
|
"atLeast": 0
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "4e4d2b4dedc5a268178712fc6beb89496518480a"
|
|
43
43
|
}
|
|
@@ -82,6 +82,18 @@ message Params {
|
|
|
82
82
|
repeated QueueSize queue_max = 5 [
|
|
83
83
|
(gogoproto.nullable) = false
|
|
84
84
|
];
|
|
85
|
+
|
|
86
|
+
// Vat cleanup budget values.
|
|
87
|
+
// These values are used by SwingSet to control the pace of removing data
|
|
88
|
+
// associated with a terminated vat as described at
|
|
89
|
+
// https://github.com/Agoric/agoric-sdk/blob/master/packages/SwingSet/docs/run-policy.md#terminated-vat-cleanup
|
|
90
|
+
//
|
|
91
|
+
// There is no required order to this list of entries, but all the chain
|
|
92
|
+
// nodes must all serialize and deserialize the existing order without
|
|
93
|
+
// permuting it.
|
|
94
|
+
repeated UintMapEntry vat_cleanup_budget = 6 [
|
|
95
|
+
(gogoproto.nullable) = false
|
|
96
|
+
];
|
|
85
97
|
}
|
|
86
98
|
|
|
87
99
|
// The current state of the module.
|
|
@@ -119,6 +131,7 @@ message PowerFlagFee {
|
|
|
119
131
|
}
|
|
120
132
|
|
|
121
133
|
// Map element of a string key to a size.
|
|
134
|
+
// TODO: Replace with UintMapEntry?
|
|
122
135
|
message QueueSize {
|
|
123
136
|
option (gogoproto.equal) = true;
|
|
124
137
|
|
|
@@ -129,6 +142,18 @@ message QueueSize {
|
|
|
129
142
|
int32 size = 2;
|
|
130
143
|
}
|
|
131
144
|
|
|
145
|
+
// Map element of a string key to an unsigned integer.
|
|
146
|
+
// The value uses cosmos-sdk Uint rather than a native Go type to ensure that
|
|
147
|
+
// zeroes survive "omitempty" JSON serialization.
|
|
148
|
+
message UintMapEntry {
|
|
149
|
+
option (gogoproto.equal) = true;
|
|
150
|
+
string key = 1;
|
|
151
|
+
string value = 2 [
|
|
152
|
+
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint",
|
|
153
|
+
(gogoproto.nullable) = false
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
|
+
|
|
132
157
|
// Egress is the format for a swingset egress.
|
|
133
158
|
message Egress {
|
|
134
159
|
option (gogoproto.equal) = false;
|
|
@@ -33,6 +33,13 @@ message Params {
|
|
|
33
33
|
int64 reward_smoothing_blocks = 3 [
|
|
34
34
|
(gogoproto.moretags) = "yaml:\"reward_smoothing_blocks\""
|
|
35
35
|
];
|
|
36
|
+
|
|
37
|
+
// allowed_monitoring_accounts is an array of account addresses that can be
|
|
38
|
+
// monitored for sends and receives. An element of `"*"` will permit any
|
|
39
|
+
// address.
|
|
40
|
+
repeated string allowed_monitoring_accounts = 4 [
|
|
41
|
+
(gogoproto.moretags) = "yaml:\"allowed_monitoring_accounts\""
|
|
42
|
+
];
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
// The current state of the module.
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
package types
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"fmt"
|
|
6
|
+
|
|
7
|
+
"github.com/cosmos/cosmos-sdk/codec"
|
|
8
|
+
"github.com/cosmos/cosmos-sdk/types/bech32"
|
|
9
|
+
|
|
10
|
+
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
|
|
11
|
+
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
|
|
12
|
+
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
|
|
13
|
+
ibcexported "github.com/cosmos/ibc-go/v6/modules/core/exported"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
type AddressRole string
|
|
17
|
+
type PacketOrigin string
|
|
18
|
+
|
|
19
|
+
const (
|
|
20
|
+
RoleSender AddressRole = "Sender"
|
|
21
|
+
RoleReceiver AddressRole = "Receiver"
|
|
22
|
+
|
|
23
|
+
PacketSrc PacketOrigin = "src"
|
|
24
|
+
PacketDst PacketOrigin = "dst"
|
|
25
|
+
|
|
26
|
+
AddressHookVersion = 0
|
|
27
|
+
BaseAddressLengthBytes = 2
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
// AddressHookBytePrefix is a magic prefix that identifies a hooked address.
|
|
31
|
+
// Chosen to make bech32 address hooks that look like "agoric10rch..."
|
|
32
|
+
var AddressHookBytePrefix = []byte{0x78, 0xf1, 0x70 /* | AddressHookVersion */}
|
|
33
|
+
|
|
34
|
+
func init() {
|
|
35
|
+
if AddressHookVersion&0x0f != AddressHookVersion {
|
|
36
|
+
panic(fmt.Sprintf("AddressHookVersion must be less than 0x10, got 0x%x", AddressHookVersion))
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ExtractBaseAddress extracts the base address from an Address Hook. It
|
|
41
|
+
// returns addr verbatim if it is not an Address Hook.
|
|
42
|
+
func ExtractBaseAddress(addr string) (string, error) {
|
|
43
|
+
baseAddr, _, err := SplitHookedAddress(addr)
|
|
44
|
+
if err != nil {
|
|
45
|
+
return "", err
|
|
46
|
+
}
|
|
47
|
+
return baseAddr, nil
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// SplitHookedAddress splits a hooked address into its base address and hook data.
|
|
51
|
+
// For the JS implementation, look at @agoric/cosmic-proto/src/address-hooks.js.
|
|
52
|
+
func SplitHookedAddress(addr string) (string, []byte, error) {
|
|
53
|
+
prefix, payload, err := bech32.DecodeAndConvert(addr)
|
|
54
|
+
if err != nil {
|
|
55
|
+
return "", []byte{}, err
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
lastPrefixHighNibble := AddressHookBytePrefix[len(AddressHookBytePrefix)-1]
|
|
59
|
+
bz := bytes.TrimPrefix(payload, AddressHookBytePrefix[:len(AddressHookBytePrefix)-1])
|
|
60
|
+
if len(bz) == len(payload) || len(bz) == 0 || bz[0]&0xf0 != lastPrefixHighNibble {
|
|
61
|
+
// Return an unhooked address.
|
|
62
|
+
return addr, []byte{}, nil
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
version := bz[0] & 0x0f
|
|
66
|
+
bz = bz[1:]
|
|
67
|
+
if version != AddressHookVersion {
|
|
68
|
+
return "", []byte{}, fmt.Errorf("unsupported address hook version %d", version)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if len(bz) < BaseAddressLengthBytes {
|
|
72
|
+
return "", []byte{}, fmt.Errorf("hooked address must have at least %d bytes", BaseAddressLengthBytes)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
b := 0
|
|
76
|
+
for i := BaseAddressLengthBytes - 1; i >= 0; i -= 1 {
|
|
77
|
+
byteVal := bz[len(bz)-1-i]
|
|
78
|
+
b <<= 8
|
|
79
|
+
b |= int(byteVal)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
payloadEnd := len(bz) - BaseAddressLengthBytes
|
|
83
|
+
if b > payloadEnd {
|
|
84
|
+
return "", []byte{}, fmt.Errorf("base address length 0x%x is longer than payload end 0x%x", b, payloadEnd)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
baseAddressBuf := bz[0:b]
|
|
88
|
+
baseAddress, err := bech32.ConvertAndEncode(prefix, baseAddressBuf)
|
|
89
|
+
if err != nil {
|
|
90
|
+
return "", []byte{}, err
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return baseAddress, bz[b:payloadEnd], nil
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// JoinHookedAddress joins a base bech32 address with hook data to create a
|
|
97
|
+
// hooked bech32 address.
|
|
98
|
+
// For the JS implementation, look at @agoric/cosmic-proto/src/address-hooks.js
|
|
99
|
+
func JoinHookedAddress(baseAddr string, hookData []byte) (string, error) {
|
|
100
|
+
prefix, bz, err := bech32.DecodeAndConvert(baseAddr)
|
|
101
|
+
if err != nil {
|
|
102
|
+
return "", err
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
b := len(bz)
|
|
106
|
+
maxB := 1<<(8*BaseAddressLengthBytes-1) + 1
|
|
107
|
+
if b > maxB {
|
|
108
|
+
return "", fmt.Errorf("base address length 0x%x is longer than the maximum 0x%x", b, maxB)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
payload := make([]byte, 0, len(AddressHookBytePrefix)+b+len(hookData)+BaseAddressLengthBytes)
|
|
112
|
+
payload = append(payload, AddressHookBytePrefix...)
|
|
113
|
+
payload[len(payload)-1] |= byte(AddressHookVersion)
|
|
114
|
+
payload = append(payload, bz...)
|
|
115
|
+
payload = append(payload, hookData...)
|
|
116
|
+
baLen := make([]byte, BaseAddressLengthBytes)
|
|
117
|
+
for i := BaseAddressLengthBytes - 1; i >= 0; i -= 1 {
|
|
118
|
+
baLen[i] = byte(b)
|
|
119
|
+
b >>= 8
|
|
120
|
+
}
|
|
121
|
+
payload = append(payload, baLen...)
|
|
122
|
+
|
|
123
|
+
return bech32.ConvertAndEncode(prefix, payload)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// extractBaseTransferData returns the base address from the transferData.Sender
|
|
127
|
+
// (if RoleSender) or transferData.Receiver (if RoleReceiver). Errors in
|
|
128
|
+
// determining the base address are ignored... we then assume the base address
|
|
129
|
+
// is exactly the original address. If newTransferData is not nil, it will be
|
|
130
|
+
// populated with a new FungibleTokenPacketData consisting of the role replaced
|
|
131
|
+
// with its base address.
|
|
132
|
+
func extractBaseTransferData(transferData transfertypes.FungibleTokenPacketData, role AddressRole, newTransferData *transfertypes.FungibleTokenPacketData) (string, error) {
|
|
133
|
+
var target string
|
|
134
|
+
sender := transferData.Sender
|
|
135
|
+
receiver := transferData.Receiver
|
|
136
|
+
|
|
137
|
+
switch role {
|
|
138
|
+
case RoleSender:
|
|
139
|
+
baseSender, err := ExtractBaseAddress(sender)
|
|
140
|
+
if err == nil {
|
|
141
|
+
sender = baseSender
|
|
142
|
+
}
|
|
143
|
+
target = sender
|
|
144
|
+
|
|
145
|
+
case RoleReceiver:
|
|
146
|
+
baseReceiver, err := ExtractBaseAddress(receiver)
|
|
147
|
+
if err == nil {
|
|
148
|
+
receiver = baseReceiver
|
|
149
|
+
}
|
|
150
|
+
target = receiver
|
|
151
|
+
|
|
152
|
+
default:
|
|
153
|
+
err := fmt.Errorf("invalid address role: %s", role)
|
|
154
|
+
return target, err
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if newTransferData == nil {
|
|
158
|
+
return target, nil
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Create the new transfer data.
|
|
162
|
+
*newTransferData = transfertypes.NewFungibleTokenPacketData(
|
|
163
|
+
transferData.Denom,
|
|
164
|
+
transferData.Amount,
|
|
165
|
+
sender, receiver,
|
|
166
|
+
transferData.Memo,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
return target, nil
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ExtractBaseAddressFromPacket returns the base address from a transfer
|
|
173
|
+
// packet's data, either Sender (if role is RoleSender) or Receiver (if role is
|
|
174
|
+
// RoleReceiver).
|
|
175
|
+
// Errors in determining the base address are ignored... we then assume the base
|
|
176
|
+
// address is exactly the original address.
|
|
177
|
+
// If newPacket is not nil, it is populated with a new transfer packet whose
|
|
178
|
+
// corresponding Sender or Receiver is replaced with the extracted base address.
|
|
179
|
+
func ExtractBaseAddressFromPacket(cdc codec.Codec, packet ibcexported.PacketI, role AddressRole, newPacket *channeltypes.Packet) (string, error) {
|
|
180
|
+
var newDataP *[]byte
|
|
181
|
+
if newPacket != nil {
|
|
182
|
+
// Capture the data for the new packet.
|
|
183
|
+
newDataP = new([]byte)
|
|
184
|
+
}
|
|
185
|
+
target, err := ExtractBaseAddressFromData(cdc, packet.GetData(), role, newDataP)
|
|
186
|
+
if err != nil {
|
|
187
|
+
return target, err
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if newPacket == nil {
|
|
191
|
+
return target, nil
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Create a new packet with the new transfer packet data.
|
|
195
|
+
*newPacket = channeltypes.NewPacket(
|
|
196
|
+
*newDataP, packet.GetSequence(),
|
|
197
|
+
packet.GetSourcePort(), packet.GetSourceChannel(),
|
|
198
|
+
packet.GetDestPort(), packet.GetDestChannel(),
|
|
199
|
+
clienttypes.MustParseHeight(packet.GetTimeoutHeight().String()),
|
|
200
|
+
packet.GetTimeoutTimestamp(),
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
return target, nil
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ExtractBaseAddressFromData returns the base address from a transfer packet's data,
|
|
207
|
+
// either Sender (if role is RoleSender) or Receiver (if role is RoleReceiver).
|
|
208
|
+
// Errors in determining the base address are ignored... we then assume the base
|
|
209
|
+
// address is exactly the original address.
|
|
210
|
+
// If newDataP is not nil, it is populated with new transfer packet data whose
|
|
211
|
+
// corresponding Sender or Receiver is replaced with the extracted base address.
|
|
212
|
+
func ExtractBaseAddressFromData(cdc codec.Codec, data []byte, role AddressRole, newDataP *[]byte) (string, error) {
|
|
213
|
+
transferData := transfertypes.FungibleTokenPacketData{}
|
|
214
|
+
|
|
215
|
+
if err := cdc.UnmarshalJSON(data, &transferData); err != nil {
|
|
216
|
+
return "", err
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
var newTransferData *transfertypes.FungibleTokenPacketData
|
|
220
|
+
if newDataP != nil {
|
|
221
|
+
// Capture the transfer data for the new packet data.
|
|
222
|
+
newTransferData = &transfertypes.FungibleTokenPacketData{}
|
|
223
|
+
}
|
|
224
|
+
target, err := extractBaseTransferData(transferData, role, newTransferData)
|
|
225
|
+
if err != nil {
|
|
226
|
+
return target, err
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if newDataP == nil {
|
|
230
|
+
return target, nil
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Reuse the original data if we didn't transform it.
|
|
234
|
+
if transferData == *newTransferData {
|
|
235
|
+
*newDataP = bytes.Clone(data)
|
|
236
|
+
} else {
|
|
237
|
+
// Re-serialize the packet data with the new base address.
|
|
238
|
+
*newDataP = newTransferData.GetBytes()
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return target, nil
|
|
242
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
package types_test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"testing"
|
|
5
|
+
|
|
6
|
+
"github.com/stretchr/testify/require"
|
|
7
|
+
|
|
8
|
+
codec "github.com/cosmos/cosmos-sdk/codec"
|
|
9
|
+
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
|
|
10
|
+
|
|
11
|
+
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
|
|
12
|
+
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
|
|
13
|
+
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
|
|
14
|
+
|
|
15
|
+
"github.com/Agoric/agoric-sdk/golang/cosmos/types"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
func TestSplitHookedAddress(t *testing.T) {
|
|
19
|
+
cases := []struct {
|
|
20
|
+
name string
|
|
21
|
+
hook string
|
|
22
|
+
baseAddr string
|
|
23
|
+
hookData []byte
|
|
24
|
+
err string
|
|
25
|
+
}{
|
|
26
|
+
{"empty", "", "", []byte{}, "decoding bech32 failed: invalid bech32 string length 0"},
|
|
27
|
+
{"no hook", "agoric1qqp0e5ys", "agoric1qqp0e5ys", []byte{}, ""},
|
|
28
|
+
{"Fast USDC", "agoric10rchp4vc53apxn32q42c3zryml8xq3xshyzuhjk6405wtxy7tl3d7e0f8az423padaek6me38qekget2vdhx66mtvy6kg7nrw5uhsaekd4uhwufswqex6dtsv44hxv3cd4jkuqpqvduyhf",
|
|
29
|
+
"agoric16kv2g7snfc4q24vg3pjdlnnqgngtjpwtetd2h689nz09lcklvh5s8u37ek",
|
|
30
|
+
[]byte("?EUD=osmo183dejcnmkka5dzcu9xw6mywq0p2m5peks28men"),
|
|
31
|
+
""},
|
|
32
|
+
{"version 0",
|
|
33
|
+
"agoric10rchqqqpqgpsgpgxquyqjzstpsxsurcszyfpxpqrqgqsq9qx0p9wp",
|
|
34
|
+
"agoric1qqqsyqcyq5rqwzqfpg9scrgwpugpzysn3tn9p0",
|
|
35
|
+
[]byte{4, 3, 2, 1},
|
|
36
|
+
""},
|
|
37
|
+
{"version 1 reject",
|
|
38
|
+
"agoric10rchzqqpqgpsgpgxquyqjzstpsxsurcszyfpxpqrqgqsq9q04n2fg",
|
|
39
|
+
"",
|
|
40
|
+
[]byte{},
|
|
41
|
+
"unsupported address hook version 1"},
|
|
42
|
+
{"version 15 reject",
|
|
43
|
+
"agoric10rch7qqpqgpsgpgxquyqjzstpsxsurcszyfpxpqrqgqsq9q25ez2d",
|
|
44
|
+
"",
|
|
45
|
+
[]byte{},
|
|
46
|
+
"unsupported address hook version 15"},
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for _, tc := range cases {
|
|
50
|
+
tc := tc
|
|
51
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
52
|
+
baseAddr, hookData, err := types.SplitHookedAddress(tc.hook)
|
|
53
|
+
if len(tc.err) > 0 {
|
|
54
|
+
require.Error(t, err)
|
|
55
|
+
require.Equal(t, tc.err, err.Error())
|
|
56
|
+
} else {
|
|
57
|
+
require.NoError(t, err)
|
|
58
|
+
require.Equal(t, tc.baseAddr, baseAddr)
|
|
59
|
+
require.Equal(t, string(tc.hookData), string(hookData))
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func TestExtractBaseAddress(t *testing.T) {
|
|
66
|
+
bases := []struct {
|
|
67
|
+
name string
|
|
68
|
+
addr string
|
|
69
|
+
}{
|
|
70
|
+
{"agoric address", "agoric1qqp0e5ys"},
|
|
71
|
+
{"cosmos address", "cosmos1qqxuevtt"},
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
suffixes := []struct {
|
|
75
|
+
hookStr string
|
|
76
|
+
baseIsWrong bool
|
|
77
|
+
isErr bool
|
|
78
|
+
}{
|
|
79
|
+
{"", false, false},
|
|
80
|
+
{"/", false, false},
|
|
81
|
+
{"/sub/account", false, false},
|
|
82
|
+
{"?query=something&k=v&k2=v2", false, false},
|
|
83
|
+
{"?query=something&k=v&k2=v2#fragment", false, false},
|
|
84
|
+
{"unexpected", false, false},
|
|
85
|
+
{"\x01", false, false},
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for _, b := range bases {
|
|
89
|
+
b := b
|
|
90
|
+
for _, s := range suffixes {
|
|
91
|
+
s := s
|
|
92
|
+
t.Run(b.name+" "+s.hookStr, func(t *testing.T) {
|
|
93
|
+
addrHook, err := types.JoinHookedAddress(b.addr, []byte(s.hookStr))
|
|
94
|
+
require.NoError(t, err)
|
|
95
|
+
addr, err := types.ExtractBaseAddress(addrHook)
|
|
96
|
+
if s.isErr {
|
|
97
|
+
require.Error(t, err)
|
|
98
|
+
} else {
|
|
99
|
+
require.NoError(t, err)
|
|
100
|
+
if s.baseIsWrong {
|
|
101
|
+
require.NotEqual(t, b.addr, addr)
|
|
102
|
+
} else {
|
|
103
|
+
require.Equal(t, b.addr, addr)
|
|
104
|
+
addr, hookData, err := types.SplitHookedAddress(addrHook)
|
|
105
|
+
require.NoError(t, err)
|
|
106
|
+
require.Equal(t, b.addr, addr)
|
|
107
|
+
require.Equal(t, s.hookStr, string(hookData))
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
func TestExtractBaseAddressFromPacket(t *testing.T) {
|
|
116
|
+
ir := cdctypes.NewInterfaceRegistry()
|
|
117
|
+
cdc := codec.NewProtoCodec(ir)
|
|
118
|
+
transfertypes.RegisterInterfaces(ir)
|
|
119
|
+
channeltypes.RegisterInterfaces(ir)
|
|
120
|
+
clienttypes.RegisterInterfaces(ir)
|
|
121
|
+
|
|
122
|
+
cosmosAddr := "cosmos1qqxuevtt"
|
|
123
|
+
cosmosHookStr := "?foo=bar&baz=bot#fragment"
|
|
124
|
+
cosmosHook, err := types.JoinHookedAddress(cosmosAddr, []byte(cosmosHookStr))
|
|
125
|
+
require.NoError(t, err)
|
|
126
|
+
addr, hookData, err := types.SplitHookedAddress(cosmosHook)
|
|
127
|
+
require.NoError(t, err)
|
|
128
|
+
require.Equal(t, cosmosAddr, addr)
|
|
129
|
+
require.Equal(t, cosmosHookStr, string(hookData))
|
|
130
|
+
|
|
131
|
+
agoricAddr := "agoric1qqp0e5ys"
|
|
132
|
+
agoricHookStr := "?bingo=again"
|
|
133
|
+
agoricHook, err := types.JoinHookedAddress(agoricAddr, []byte(agoricHookStr))
|
|
134
|
+
require.NoError(t, err)
|
|
135
|
+
addr, hookData, err = types.SplitHookedAddress(agoricHook)
|
|
136
|
+
require.NoError(t, err)
|
|
137
|
+
require.Equal(t, agoricAddr, addr)
|
|
138
|
+
require.Equal(t, agoricHookStr, string(hookData))
|
|
139
|
+
|
|
140
|
+
cases := []struct {
|
|
141
|
+
name string
|
|
142
|
+
addrs map[types.AddressRole]struct{ addr, baseAddr string }
|
|
143
|
+
}{
|
|
144
|
+
{"sender has params",
|
|
145
|
+
map[types.AddressRole]struct{ addr, baseAddr string }{
|
|
146
|
+
types.RoleSender: {cosmosHook, "cosmos1qqxuevtt"},
|
|
147
|
+
types.RoleReceiver: {"agoric1qqp0e5ys", "agoric1qqp0e5ys"},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{"receiver has params",
|
|
151
|
+
map[types.AddressRole]struct{ addr, baseAddr string }{
|
|
152
|
+
types.RoleSender: {"cosmos1qqxuevtt", "cosmos1qqxuevtt"},
|
|
153
|
+
types.RoleReceiver: {agoricHook, "agoric1qqp0e5ys"},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{"both are base",
|
|
157
|
+
map[types.AddressRole]struct{ addr, baseAddr string }{
|
|
158
|
+
types.RoleSender: {"cosmos1qqxuevtt", "cosmos1qqxuevtt"},
|
|
159
|
+
types.RoleReceiver: {"agoric1qqp0e5ys", "agoric1qqp0e5ys"},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
{"both have params",
|
|
163
|
+
map[types.AddressRole]struct{ addr, baseAddr string }{
|
|
164
|
+
types.RoleSender: {agoricHook, "agoric1qqp0e5ys"},
|
|
165
|
+
types.RoleReceiver: {cosmosHook, "cosmos1qqxuevtt"},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
for _, tc := range cases {
|
|
171
|
+
tc := tc
|
|
172
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
173
|
+
ftPacketData := transfertypes.NewFungibleTokenPacketData("denom", "100", tc.addrs[types.RoleSender].addr, tc.addrs[types.RoleReceiver].addr, "my-favourite-memo")
|
|
174
|
+
packetBz := ftPacketData.GetBytes()
|
|
175
|
+
packet := channeltypes.NewPacket(packetBz, 1234, "my-port", "my-channel", "their-port", "their-channel", clienttypes.NewHeight(133, 445), 10999)
|
|
176
|
+
|
|
177
|
+
for role, addrs := range tc.addrs {
|
|
178
|
+
addrs := addrs
|
|
179
|
+
role := role
|
|
180
|
+
|
|
181
|
+
t.Run(string(role), func(t *testing.T) {
|
|
182
|
+
baseAddr, err := types.ExtractBaseAddress(addrs.addr)
|
|
183
|
+
require.NoError(t, err)
|
|
184
|
+
require.Equal(t, addrs.baseAddr, baseAddr)
|
|
185
|
+
|
|
186
|
+
packetBaseAddr0, err := types.ExtractBaseAddressFromData(cdc, packet.GetData(), role, nil)
|
|
187
|
+
require.NoError(t, err)
|
|
188
|
+
require.Equal(t, addrs.baseAddr, packetBaseAddr0)
|
|
189
|
+
|
|
190
|
+
packetBaseAddr1, err := types.ExtractBaseAddressFromPacket(cdc, packet, role, nil)
|
|
191
|
+
require.NoError(t, err)
|
|
192
|
+
require.Equal(t, addrs.baseAddr, packetBaseAddr1)
|
|
193
|
+
|
|
194
|
+
var newPacket channeltypes.Packet
|
|
195
|
+
packetBaseAddr2, err := types.ExtractBaseAddressFromPacket(cdc, packet, role, &newPacket)
|
|
196
|
+
require.NoError(t, err)
|
|
197
|
+
require.Equal(t, addrs.baseAddr, packetBaseAddr2)
|
|
198
|
+
|
|
199
|
+
var basePacketData transfertypes.FungibleTokenPacketData
|
|
200
|
+
err = cdc.UnmarshalJSON(newPacket.GetData(), &basePacketData)
|
|
201
|
+
require.NoError(t, err)
|
|
202
|
+
|
|
203
|
+
// Check that the only difference between the packet data is the baseAddr.
|
|
204
|
+
packetData := basePacketData
|
|
205
|
+
switch role {
|
|
206
|
+
case types.RoleSender:
|
|
207
|
+
require.Equal(t, addrs.baseAddr, basePacketData.Sender)
|
|
208
|
+
packetData.Sender = addrs.addr
|
|
209
|
+
case types.RoleReceiver:
|
|
210
|
+
require.Equal(t, addrs.baseAddr, basePacketData.Receiver)
|
|
211
|
+
packetData.Receiver = addrs.addr
|
|
212
|
+
default:
|
|
213
|
+
t.Fatal("unexpected role", role)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
require.Equal(t, ftPacketData, packetData)
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
}
|