solidity-scale-codec 0.3.4 → 1.0.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 +31 -3
- package/package.json +1 -1
- package/src/Utils/BytesUtils.sol +26 -0
- package/src/Utils/UnsignedUtils.sol +52 -0
- package/src/Xcm/VersionedXcm/VersionedXcm.sol +4 -1
- package/src/Xcm/VersionedXcm/VersionedXcmCodec.sol +11 -0
- package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCode.sol +8 -7
- package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCodeCodec.sol +18 -19
- package/src/Xcm/v5/AssetFilter/AssetFilter.sol +8 -8
- package/src/Xcm/v5/AssetFilter/AssetFilterCodec.sol +47 -34
- package/src/Xcm/v5/AssetInstance/AssetInstance.sol +13 -12
- package/src/Xcm/v5/AssetInstance/AssetInstanceCodec.sol +53 -56
- package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilter.sol +12 -12
- package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilterCodec.sol +48 -20
- package/src/Xcm/v5/Assets/Assets.sol +16 -0
- package/src/Xcm/v5/Assets/AssetsCodec.sol +3 -3
- package/src/Xcm/v5/BodyId/BodyId.sol +24 -24
- package/src/Xcm/v5/BodyId/BodyIdCodec.sol +41 -48
- package/src/Xcm/v5/BodyPart/BodyPart.sol +44 -28
- package/src/Xcm/v5/BodyPart/BodyPartCodec.sol +70 -37
- package/src/Xcm/v5/Constants.sol +2 -2
- package/src/Xcm/v5/Fungibility/Fungibility.sol +6 -6
- package/src/Xcm/v5/Fungibility/FungibilityCodec.sol +40 -36
- package/src/Xcm/v5/Hint/Hint.sol +5 -5
- package/src/Xcm/v5/Hint/HintCodec.sol +24 -20
- package/src/Xcm/v5/Instruction/Instruction.sol +81 -55
- package/src/Xcm/v5/Instruction/InstructionCodec.sol +1047 -73
- package/src/Xcm/v5/Junction/Junction.sol +55 -69
- package/src/Xcm/v5/Junction/JunctionCodec.sol +72 -135
- package/src/Xcm/v5/Junctions/Junctions.sol +34 -0
- package/src/Xcm/v5/Junctions/JunctionsCodec.sol +0 -18
- package/src/Xcm/v5/Location/Location.sol +8 -0
- package/src/Xcm/v5/NetworkId/NetworkId.sol +15 -16
- package/src/Xcm/v5/NetworkId/NetworkIdCodec.sol +57 -34
- package/src/Xcm/v5/OriginKind/OriginKindCodec.sol +1 -1
- package/src/Xcm/v5/Response/Response.sol +49 -40
- package/src/Xcm/v5/Response/ResponseCodec.sol +64 -54
- package/src/Xcm/v5/Weight/WeightCodec.sol +3 -2
- package/src/Xcm/v5/WeightLimit/WeightLimit.sol +6 -6
- package/src/Xcm/v5/WeightLimit/WeightLimitCodec.sol +32 -23
- package/src/Xcm/v5/WildAsset/WildAsset.sol +17 -25
- package/src/Xcm/v5/WildAsset/WildAssetCodec.sol +35 -38
- package/src/Xcm/v5/WildFungibility/WildFungibilityCodec.sol +6 -6
- package/src/Xcm/v5/Xcm/XcmBuilder.sol +689 -0
- package/src/Xcm/v5/XcmError/XcmError.sol +7 -7
- package/src/Xcm/v5/XcmError/XcmErrorCodec.sol +25 -22
|
@@ -12,7 +12,7 @@ import {Address} from "../../../Scale/Address.sol";
|
|
|
12
12
|
import {Compact} from "../../../Scale/Compact.sol";
|
|
13
13
|
|
|
14
14
|
/// @dev Discriminant for the different types of junctions in XCM v5. Each variant corresponds to a specific structure of the payload.
|
|
15
|
-
enum
|
|
15
|
+
enum JunctionVariant {
|
|
16
16
|
/// @custom:variant An indexed parachain belonging to and operated by the context.
|
|
17
17
|
Parachain,
|
|
18
18
|
/// @custom:variantA 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within the context.
|
|
@@ -35,6 +35,12 @@ enum JunctionType {
|
|
|
35
35
|
GlobalConsensus
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/// @notice Parameters for a `Parachain` junction.
|
|
39
|
+
struct ParachainParams {
|
|
40
|
+
/// @custom:property The parachain identifier.
|
|
41
|
+
uint32 parachainId;
|
|
42
|
+
}
|
|
43
|
+
|
|
38
44
|
/// @notice Parameters for an `AccountId32` junction, containing optional network information and a 32-byte account identifier.
|
|
39
45
|
struct AccountId32Params {
|
|
40
46
|
/// @custom:property Indicates whether the junction includes network information. If true, the `network` field contains valid data; if false, the `network` field should be ignored.
|
|
@@ -81,12 +87,6 @@ struct GeneralKeyParams {
|
|
|
81
87
|
bytes32 key;
|
|
82
88
|
}
|
|
83
89
|
|
|
84
|
-
/// @notice Parameters for a `Parachain` junction.
|
|
85
|
-
struct ParachainParams {
|
|
86
|
-
/// @custom:property The parachain identifier.
|
|
87
|
-
uint32 parachainId;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
90
|
/// @notice Parameters for a `PalletInstance` junction.
|
|
91
91
|
struct PalletInstanceParams {
|
|
92
92
|
/// @custom:property The pallet instance index.
|
|
@@ -101,9 +101,9 @@ struct GeneralIndexParams {
|
|
|
101
101
|
|
|
102
102
|
/// @notice A single item in a path to describe the relative location of a consensus system. Each item assumes a pre-existing location as its context and is defined in terms of it.
|
|
103
103
|
struct Junction {
|
|
104
|
-
/// @custom:property
|
|
105
|
-
|
|
106
|
-
/// @custom:property payload The SCALE-encoded data specific to the junction type. The structure of this data varies based on `
|
|
104
|
+
/// @custom:property variant The type of the junction, determining how to interpret the payload. See `JunctionVariant` enum for possible values.
|
|
105
|
+
JunctionVariant variant;
|
|
106
|
+
/// @custom:property payload The SCALE-encoded data specific to the junction type. The structure of this data varies based on `variant`.
|
|
107
107
|
bytes payload;
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -123,68 +123,52 @@ function parachain(
|
|
|
123
123
|
) pure returns (Junction memory) {
|
|
124
124
|
return
|
|
125
125
|
Junction({
|
|
126
|
-
|
|
126
|
+
variant: JunctionVariant.Parachain,
|
|
127
127
|
payload: Compact.encode(params.parachainId)
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
/// @notice Creates an `AccountId32` junction with the specified parameters.
|
|
132
|
-
/// @param
|
|
133
|
-
/// @param network The `NetworkId` associated with the account, if `hasNetwork` is true.
|
|
134
|
-
/// @param id The 32-byte identifier for the account.
|
|
132
|
+
/// @param params Parameters for the account-id-32 variant.
|
|
135
133
|
/// @return A `Junction` struct representing the `AccountId32` junction with the provided parameters.
|
|
136
134
|
function accountId32(
|
|
137
|
-
|
|
138
|
-
NetworkId memory network,
|
|
139
|
-
bytes32 id
|
|
135
|
+
AccountId32Params memory params
|
|
140
136
|
) pure returns (Junction memory) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
bytes memory payload = abi.encodePacked(params.hasNetwork);
|
|
138
|
+
if (params.hasNetwork) {
|
|
139
|
+
payload = abi.encodePacked(payload, params.network.encode());
|
|
140
|
+
}
|
|
141
|
+
payload = abi.encodePacked(payload, params.id);
|
|
142
|
+
return Junction({variant: JunctionVariant.AccountId32, payload: payload});
|
|
146
143
|
}
|
|
147
144
|
|
|
148
145
|
/// @notice Creates an `AccountIndex64` junction with the specified parameters.
|
|
149
|
-
/// @param
|
|
150
|
-
/// @param network The `NetworkId` associated with the account, if `hasNetwork` is true.
|
|
151
|
-
/// @param index The 64-bit index identifier for the account.
|
|
146
|
+
/// @param params Parameters for the account-index-64 variant.
|
|
152
147
|
/// @return A `Junction` struct representing the `AccountIndex64` junction with the provided parameters.
|
|
153
148
|
function accountIndex64(
|
|
154
|
-
|
|
155
|
-
NetworkId memory network,
|
|
156
|
-
uint64 index
|
|
149
|
+
AccountIndex64Params memory params
|
|
157
150
|
) pure returns (Junction memory) {
|
|
151
|
+
bytes memory payload = abi.encodePacked(params.hasNetwork);
|
|
152
|
+
if (params.hasNetwork) {
|
|
153
|
+
payload = abi.encodePacked(payload, params.network.encode());
|
|
154
|
+
}
|
|
155
|
+
payload = abi.encodePacked(payload, Compact.encode(params.index));
|
|
158
156
|
return
|
|
159
|
-
Junction({
|
|
160
|
-
jType: JunctionType.AccountIndex64,
|
|
161
|
-
payload: abi.encodePacked(
|
|
162
|
-
hasNetwork,
|
|
163
|
-
network.encode(),
|
|
164
|
-
Compact.encode(index)
|
|
165
|
-
)
|
|
166
|
-
});
|
|
157
|
+
Junction({variant: JunctionVariant.AccountIndex64, payload: payload});
|
|
167
158
|
}
|
|
168
159
|
|
|
169
160
|
/// @notice Creates an `AccountKey20` junction with the specified parameters.
|
|
170
|
-
/// @param
|
|
171
|
-
/// @param network The `NetworkId` associated with the account, if `hasNetwork` is true.
|
|
172
|
-
/// @param key The 20-byte key identifier for the account, represented as an `address` in Solidity.
|
|
161
|
+
/// @param params Parameters for the account-key-20 variant.
|
|
173
162
|
/// @return A `Junction` struct representing the `AccountKey20` junction with the provided parameters.
|
|
174
163
|
function accountKey20(
|
|
175
|
-
|
|
176
|
-
NetworkId memory network,
|
|
177
|
-
address key
|
|
164
|
+
AccountKey20Params memory params
|
|
178
165
|
) pure returns (Junction memory) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
key.encode()
|
|
186
|
-
)
|
|
187
|
-
});
|
|
166
|
+
bytes memory payload = abi.encodePacked(params.hasNetwork);
|
|
167
|
+
if (params.hasNetwork) {
|
|
168
|
+
payload = abi.encodePacked(payload, params.network.encode());
|
|
169
|
+
}
|
|
170
|
+
payload = abi.encodePacked(payload, params.key.encode());
|
|
171
|
+
return Junction({variant: JunctionVariant.AccountKey20, payload: payload});
|
|
188
172
|
}
|
|
189
173
|
|
|
190
174
|
/// @notice Creates a `PalletInstance` junction with the given instance index.
|
|
@@ -195,7 +179,7 @@ function palletInstance(
|
|
|
195
179
|
) pure returns (Junction memory) {
|
|
196
180
|
return
|
|
197
181
|
Junction({
|
|
198
|
-
|
|
182
|
+
variant: JunctionVariant.PalletInstance,
|
|
199
183
|
payload: abi.encodePacked(params.instance)
|
|
200
184
|
});
|
|
201
185
|
}
|
|
@@ -208,45 +192,47 @@ function generalIndex(
|
|
|
208
192
|
) pure returns (Junction memory) {
|
|
209
193
|
return
|
|
210
194
|
Junction({
|
|
211
|
-
|
|
195
|
+
variant: JunctionVariant.GeneralIndex,
|
|
212
196
|
payload: Compact.encode(params.index)
|
|
213
197
|
});
|
|
214
198
|
}
|
|
215
199
|
|
|
216
200
|
/// @notice Creates a `GeneralKey` junction with the given key.
|
|
217
|
-
/// @param
|
|
218
|
-
/// @param key The byte array acting as a key within the context location, represented as a `bytes32` in Solidity. Only the first `length` bytes will be used.
|
|
201
|
+
/// @param params Parameters for the general-key variant.
|
|
219
202
|
/// @return A `Junction` struct representing the general key junction with the provided parameters.
|
|
220
|
-
function generalKey(
|
|
221
|
-
|
|
222
|
-
|
|
203
|
+
function generalKey(
|
|
204
|
+
GeneralKeyParams memory params
|
|
205
|
+
) pure returns (Junction memory) {
|
|
206
|
+
if (
|
|
207
|
+
params.length == 0 ||
|
|
208
|
+
params.length > 32 ||
|
|
209
|
+
params.key.length != params.length
|
|
210
|
+
) revert InvalidJunctionPayload();
|
|
223
211
|
return
|
|
224
212
|
Junction({
|
|
225
|
-
|
|
226
|
-
payload: abi.encodePacked(length, key)
|
|
213
|
+
variant: JunctionVariant.GeneralKey,
|
|
214
|
+
payload: abi.encodePacked(params.length, params.key)
|
|
227
215
|
});
|
|
228
216
|
}
|
|
229
217
|
|
|
230
218
|
/// @notice Creates an `OnlyChild` junction, which represents the unambiguous child in the context.
|
|
231
219
|
/// @return A `Junction` struct representing the `OnlyChild` junction, with an empty payload.
|
|
232
220
|
function onlyChild() pure returns (Junction memory) {
|
|
233
|
-
return Junction({
|
|
221
|
+
return Junction({variant: JunctionVariant.OnlyChild, payload: ""});
|
|
234
222
|
}
|
|
235
223
|
|
|
236
224
|
/// @notice Creates a `Plurality` junction with the specified body ID and body part.
|
|
237
|
-
/// @param
|
|
238
|
-
/// @param part The part of the body that is relevant for this junction, represented as a `BodyPart` struct.
|
|
225
|
+
/// @param params Parameters for the plurality variant.
|
|
239
226
|
/// @return A `Junction` struct representing the `Plurality` junction with the provided parameters.
|
|
240
227
|
function plurality(
|
|
241
|
-
|
|
242
|
-
BodyPart memory part
|
|
228
|
+
PluralityParams memory params
|
|
243
229
|
) pure returns (Junction memory) {
|
|
244
230
|
return
|
|
245
231
|
Junction({
|
|
246
|
-
|
|
232
|
+
variant: JunctionVariant.Plurality,
|
|
247
233
|
payload: abi.encodePacked(
|
|
248
|
-
BodyIdCodec.encode(id),
|
|
249
|
-
BodyPartCodec.encode(part)
|
|
234
|
+
BodyIdCodec.encode(params.id),
|
|
235
|
+
BodyPartCodec.encode(params.part)
|
|
250
236
|
)
|
|
251
237
|
});
|
|
252
238
|
}
|
|
@@ -254,5 +240,5 @@ function plurality(
|
|
|
254
240
|
/// @notice Creates a `GlobalConsensus` junction, which represents a global network capable of externalizing its own consensus.
|
|
255
241
|
/// @return A `Junction` struct representing the `GlobalConsensus` junction, with an empty payload.
|
|
256
242
|
function globalConsensus() pure returns (Junction memory) {
|
|
257
|
-
return Junction({
|
|
243
|
+
return Junction({variant: JunctionVariant.GlobalConsensus, payload: ""});
|
|
258
244
|
}
|
|
@@ -12,13 +12,18 @@ import {Address} from "../../../Scale/Address.sol";
|
|
|
12
12
|
import {Compact} from "../../../Scale/Compact.sol";
|
|
13
13
|
import {
|
|
14
14
|
Junction,
|
|
15
|
-
|
|
15
|
+
JunctionVariant,
|
|
16
|
+
ParachainParams,
|
|
16
17
|
AccountId32Params,
|
|
17
18
|
PluralityParams,
|
|
18
19
|
AccountIndex64Params,
|
|
19
20
|
AccountKey20Params,
|
|
20
|
-
GeneralKeyParams
|
|
21
|
+
GeneralKeyParams,
|
|
22
|
+
PalletInstanceParams,
|
|
23
|
+
GeneralIndexParams
|
|
21
24
|
} from "./Junction.sol";
|
|
25
|
+
import {BytesUtils} from "../../../Utils/BytesUtils.sol";
|
|
26
|
+
import {UnsignedUtils} from "../../../Utils/UnsignedUtils.sol";
|
|
22
27
|
|
|
23
28
|
/// @title SCALE Codec for XCM v5 `Junction`
|
|
24
29
|
/// @notice SCALE-compliant encoder/decoder for the `Junction` type.
|
|
@@ -26,7 +31,7 @@ import {
|
|
|
26
31
|
/// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/index.html
|
|
27
32
|
library JunctionCodec {
|
|
28
33
|
error InvalidJunctionLength();
|
|
29
|
-
error
|
|
34
|
+
error InvalidJunctionVariant(uint8 variant);
|
|
30
35
|
error InvalidJunctionPayload();
|
|
31
36
|
|
|
32
37
|
/// @notice Encodes a `Junction` struct into a byte array suitable for SCALE encoding.
|
|
@@ -35,7 +40,7 @@ library JunctionCodec {
|
|
|
35
40
|
function encode(
|
|
36
41
|
Junction memory junction
|
|
37
42
|
) internal pure returns (bytes memory) {
|
|
38
|
-
return abi.encodePacked(uint8(junction.
|
|
43
|
+
return abi.encodePacked(uint8(junction.variant), junction.payload);
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
/// @notice Returns the number of bytes that a `Junction` struct would occupy when SCALE-encoded, starting from the specified offset.
|
|
@@ -47,44 +52,41 @@ library JunctionCodec {
|
|
|
47
52
|
uint256 offset
|
|
48
53
|
) internal pure returns (uint256) {
|
|
49
54
|
if (offset >= data.length) revert InvalidJunctionLength();
|
|
50
|
-
uint8
|
|
51
|
-
assembly {
|
|
52
|
-
jType := shr(248, mload(add(add(data, 32), offset)))
|
|
53
|
-
}
|
|
55
|
+
uint8 variant = uint8(data[offset]);
|
|
54
56
|
uint256 payloadLength;
|
|
55
57
|
++offset; // Move past the type byte
|
|
56
|
-
if (
|
|
58
|
+
if (variant == uint8(JunctionVariant.Parachain)) {
|
|
57
59
|
payloadLength = Compact.encodedSizeAt(data, offset);
|
|
58
|
-
} else if (
|
|
60
|
+
} else if (variant == uint8(JunctionVariant.AccountId32)) {
|
|
59
61
|
payloadLength = _innerNetworkIdSize(data, offset) + 32; // for the account ID;
|
|
60
|
-
} else if (
|
|
62
|
+
} else if (variant == uint8(JunctionVariant.AccountIndex64)) {
|
|
61
63
|
payloadLength = _innerNetworkIdSize(data, offset);
|
|
62
64
|
payloadLength += Compact.encodedSizeAt(
|
|
63
65
|
data,
|
|
64
66
|
offset + payloadLength
|
|
65
67
|
); // for the account index
|
|
66
|
-
} else if (
|
|
68
|
+
} else if (variant == uint8(JunctionVariant.AccountKey20)) {
|
|
67
69
|
payloadLength = _innerNetworkIdSize(data, offset) + 20; // for the account key;
|
|
68
|
-
} else if (
|
|
70
|
+
} else if (variant == uint8(JunctionVariant.PalletInstance)) {
|
|
69
71
|
payloadLength = 1;
|
|
70
|
-
} else if (
|
|
72
|
+
} else if (variant == uint8(JunctionVariant.GeneralIndex)) {
|
|
71
73
|
payloadLength = Compact.encodedSizeAt(data, offset);
|
|
72
|
-
} else if (
|
|
74
|
+
} else if (variant == uint8(JunctionVariant.GeneralKey)) {
|
|
73
75
|
if (offset >= data.length) revert InvalidJunctionLength();
|
|
74
76
|
uint8 length = uint8(data[offset]);
|
|
75
77
|
payloadLength = 1 + length; // 1 byte for the length + the key bytes
|
|
76
78
|
} else if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
variant == uint8(JunctionVariant.OnlyChild) ||
|
|
80
|
+
variant == uint8(JunctionVariant.GlobalConsensus)
|
|
79
81
|
) {
|
|
80
82
|
payloadLength = 0;
|
|
81
|
-
} else if (
|
|
83
|
+
} else if (variant == uint8(JunctionVariant.Plurality)) {
|
|
82
84
|
uint256 innerLength = BodyIdCodec.encodedSizeAt(data, offset);
|
|
83
85
|
payloadLength =
|
|
84
86
|
innerLength +
|
|
85
87
|
BodyPartCodec.encodedSizeAt(data, offset + innerLength);
|
|
86
88
|
} else {
|
|
87
|
-
revert
|
|
89
|
+
revert InvalidJunctionVariant(variant);
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
return 1 + payloadLength; // 1 byte for the type + payload length
|
|
@@ -109,36 +111,25 @@ library JunctionCodec {
|
|
|
109
111
|
bytes memory data,
|
|
110
112
|
uint256 offset
|
|
111
113
|
) internal pure returns (Junction memory junction, uint256 bytesRead) {
|
|
112
|
-
if (offset >= data.length) revert InvalidJunctionLength();
|
|
113
|
-
uint8 jType;
|
|
114
|
-
assembly {
|
|
115
|
-
jType := shr(248, mload(add(add(data, 32), offset)))
|
|
116
|
-
}
|
|
117
114
|
uint256 payloadLength = encodedSizeAt(data, offset) - 1; // Subtract 1 byte for the type
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
115
|
+
uint8 variant = uint8(data[offset]);
|
|
116
|
+
bytes memory payload = BytesUtils.copy(data, offset + 1, payloadLength);
|
|
117
|
+
junction = Junction({
|
|
118
|
+
variant: JunctionVariant(variant),
|
|
119
|
+
payload: payload
|
|
120
|
+
});
|
|
123
121
|
bytesRead = 1 + payload.length;
|
|
124
122
|
}
|
|
125
123
|
|
|
126
124
|
/// @notice Decodes a `Parachain` junction from a given `Junction` struct, extracting the parachain ID.
|
|
127
125
|
/// @param junction The `Junction` struct to decode, which should represent a `Parachain` junction.
|
|
128
|
-
/// @return
|
|
126
|
+
/// @return params A `ParachainParams` struct containing the decoded parachain ID.
|
|
129
127
|
function asParachain(
|
|
130
128
|
Junction memory junction
|
|
131
|
-
) internal pure returns (
|
|
132
|
-
|
|
133
|
-
revert InvalidJunctionType(uint8(junction.jType));
|
|
134
|
-
if (junction.payload.length != 4) revert InvalidJunctionPayload();
|
|
129
|
+
) internal pure returns (ParachainParams memory params) {
|
|
130
|
+
_assertVariant(junction, JunctionVariant.Parachain);
|
|
135
131
|
(uint256 decodedParachain, ) = Compact.decode(junction.payload);
|
|
136
|
-
|
|
137
|
-
revert InvalidJunctionPayload();
|
|
138
|
-
}
|
|
139
|
-
unchecked {
|
|
140
|
-
parachainId = uint32(decodedParachain);
|
|
141
|
-
}
|
|
132
|
+
params.parachainId = UnsignedUtils.toU32(decodedParachain);
|
|
142
133
|
}
|
|
143
134
|
|
|
144
135
|
/// @notice Decodes an `AccountId32` junction from a given `Junction` struct, extracting the network information and account ID.
|
|
@@ -147,28 +138,18 @@ library JunctionCodec {
|
|
|
147
138
|
function asAccountId32(
|
|
148
139
|
Junction memory junction
|
|
149
140
|
) internal pure returns (AccountId32Params memory params) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (junction.payload.length != 33 && junction.payload.length != 34)
|
|
153
|
-
revert InvalidJunctionPayload();
|
|
154
|
-
bool hasNetwork = junction.payload[0] != 0;
|
|
141
|
+
_assertVariant(junction, JunctionVariant.AccountId32);
|
|
142
|
+
params.hasNetwork = junction.payload[0] != 0;
|
|
155
143
|
uint256 offset = 1;
|
|
156
|
-
NetworkId memory network;
|
|
157
144
|
uint256 bytesRead;
|
|
158
|
-
if (hasNetwork) {
|
|
159
|
-
(network, bytesRead) = NetworkIdCodec.decodeAt(
|
|
145
|
+
if (params.hasNetwork) {
|
|
146
|
+
(params.network, bytesRead) = NetworkIdCodec.decodeAt(
|
|
160
147
|
junction.payload,
|
|
161
148
|
offset
|
|
162
149
|
);
|
|
163
150
|
offset += bytesRead;
|
|
164
151
|
}
|
|
165
|
-
|
|
166
|
-
return
|
|
167
|
-
AccountId32Params({
|
|
168
|
-
hasNetwork: hasNetwork,
|
|
169
|
-
network: network,
|
|
170
|
-
id: id
|
|
171
|
-
});
|
|
152
|
+
params.id = Bytes32.decodeAt(junction.payload, offset);
|
|
172
153
|
}
|
|
173
154
|
|
|
174
155
|
/// @notice Decodes an `AccountIndex64` junction from a given `Junction` struct, extracting the network information and account index.
|
|
@@ -177,35 +158,19 @@ library JunctionCodec {
|
|
|
177
158
|
function asAccountIndex64(
|
|
178
159
|
Junction memory junction
|
|
179
160
|
) internal pure returns (AccountIndex64Params memory params) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (junction.payload.length != 9 && junction.payload.length != 10)
|
|
183
|
-
revert InvalidJunctionPayload();
|
|
184
|
-
bool hasNetwork = junction.payload[0] != 0;
|
|
161
|
+
_assertVariant(junction, JunctionVariant.AccountIndex64);
|
|
162
|
+
params.hasNetwork = junction.payload[0] != 0;
|
|
185
163
|
uint256 offset = 1;
|
|
186
|
-
NetworkId memory network;
|
|
187
164
|
uint256 bytesRead;
|
|
188
|
-
if (hasNetwork) {
|
|
189
|
-
(network, bytesRead) = NetworkIdCodec.decodeAt(
|
|
165
|
+
if (params.hasNetwork) {
|
|
166
|
+
(params.network, bytesRead) = NetworkIdCodec.decodeAt(
|
|
190
167
|
junction.payload,
|
|
191
168
|
offset
|
|
192
169
|
);
|
|
193
170
|
offset += bytesRead;
|
|
194
171
|
}
|
|
195
172
|
(uint256 decodedIndex, ) = Compact.decodeAt(junction.payload, offset);
|
|
196
|
-
|
|
197
|
-
revert InvalidJunctionPayload();
|
|
198
|
-
}
|
|
199
|
-
uint64 index;
|
|
200
|
-
unchecked {
|
|
201
|
-
index = uint64(decodedIndex);
|
|
202
|
-
}
|
|
203
|
-
return
|
|
204
|
-
AccountIndex64Params({
|
|
205
|
-
hasNetwork: hasNetwork,
|
|
206
|
-
network: network,
|
|
207
|
-
index: index
|
|
208
|
-
});
|
|
173
|
+
params.index = UnsignedUtils.toU64(decodedIndex);
|
|
209
174
|
}
|
|
210
175
|
|
|
211
176
|
/// @notice Decodes an `AccountKey20` junction from a given `Junction` struct, extracting the network information and account key.
|
|
@@ -214,58 +179,39 @@ library JunctionCodec {
|
|
|
214
179
|
function asAccountKey20(
|
|
215
180
|
Junction memory junction
|
|
216
181
|
) internal pure returns (AccountKey20Params memory params) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (junction.payload.length != 21 && junction.payload.length != 22)
|
|
220
|
-
revert InvalidJunctionPayload();
|
|
221
|
-
bool hasNetwork = junction.payload[0] != 0;
|
|
182
|
+
_assertVariant(junction, JunctionVariant.AccountKey20);
|
|
183
|
+
params.hasNetwork = junction.payload[0] != 0;
|
|
222
184
|
uint256 offset = 1;
|
|
223
|
-
NetworkId memory network;
|
|
224
185
|
uint256 bytesRead;
|
|
225
|
-
if (hasNetwork) {
|
|
226
|
-
(network, bytesRead) = NetworkIdCodec.decodeAt(
|
|
186
|
+
if (params.hasNetwork) {
|
|
187
|
+
(params.network, bytesRead) = NetworkIdCodec.decodeAt(
|
|
227
188
|
junction.payload,
|
|
228
189
|
offset
|
|
229
190
|
);
|
|
230
191
|
offset += bytesRead;
|
|
231
192
|
}
|
|
232
|
-
|
|
233
|
-
return
|
|
234
|
-
AccountKey20Params({
|
|
235
|
-
hasNetwork: hasNetwork,
|
|
236
|
-
network: network,
|
|
237
|
-
key: key
|
|
238
|
-
});
|
|
193
|
+
params.key = Address.decodeAt(junction.payload, offset);
|
|
239
194
|
}
|
|
240
195
|
|
|
241
196
|
/// @notice Decodes a `PalletInstance` junction from a given `Junction` struct, extracting the pallet instance index.
|
|
242
197
|
/// @param junction The `Junction` struct to decode, which should represent a `PalletInstance` junction.
|
|
243
|
-
/// @return
|
|
198
|
+
/// @return params A `PalletInstanceParams` struct containing the decoded pallet instance index.
|
|
244
199
|
function asPalletInstance(
|
|
245
200
|
Junction memory junction
|
|
246
|
-
) internal pure returns (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (junction.payload.length != 1) revert InvalidJunctionPayload();
|
|
250
|
-
return uint8(junction.payload[0]);
|
|
201
|
+
) internal pure returns (PalletInstanceParams memory params) {
|
|
202
|
+
_assertVariant(junction, JunctionVariant.PalletInstance);
|
|
203
|
+
params.instance = uint8(junction.payload[0]);
|
|
251
204
|
}
|
|
252
205
|
|
|
253
206
|
/// @notice Decodes a `GeneralIndex` junction from a given `Junction` struct, extracting the general index.
|
|
254
207
|
/// @param junction The `Junction` struct to decode, which should represent a `GeneralIndex` junction.
|
|
255
|
-
/// @return
|
|
208
|
+
/// @return params A `GeneralIndexParams` struct containing the decoded general index.
|
|
256
209
|
function asGeneralIndex(
|
|
257
210
|
Junction memory junction
|
|
258
|
-
) internal pure returns (
|
|
259
|
-
|
|
260
|
-
revert InvalidJunctionType(uint8(junction.jType));
|
|
261
|
-
if (junction.payload.length == 0) revert InvalidJunctionPayload();
|
|
211
|
+
) internal pure returns (GeneralIndexParams memory params) {
|
|
212
|
+
_assertVariant(junction, JunctionVariant.GeneralIndex);
|
|
262
213
|
(uint256 decodedIndex, ) = Compact.decode(junction.payload);
|
|
263
|
-
|
|
264
|
-
revert InvalidJunctionPayload();
|
|
265
|
-
}
|
|
266
|
-
unchecked {
|
|
267
|
-
index = uint128(decodedIndex);
|
|
268
|
-
}
|
|
214
|
+
params.index = UnsignedUtils.toU128(decodedIndex);
|
|
269
215
|
}
|
|
270
216
|
|
|
271
217
|
/// @notice Decodes a `GeneralKey` junction from a given `Junction` struct, extracting the key.
|
|
@@ -274,14 +220,9 @@ library JunctionCodec {
|
|
|
274
220
|
function asGeneralKey(
|
|
275
221
|
Junction memory junction
|
|
276
222
|
) internal pure returns (GeneralKeyParams memory params) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
uint8 length = uint8(junction.payload[0]);
|
|
281
|
-
if (length == 0 || length > 32 || junction.payload.length != length + 1)
|
|
282
|
-
revert InvalidJunctionPayload();
|
|
283
|
-
bytes32 key = Bytes32.decodeAt(junction.payload, 1);
|
|
284
|
-
return GeneralKeyParams({length: length, key: key});
|
|
223
|
+
_assertVariant(junction, JunctionVariant.GeneralKey);
|
|
224
|
+
params.length = uint8(junction.payload[0]);
|
|
225
|
+
params.key = Bytes32.decodeAt(junction.payload, 1);
|
|
285
226
|
}
|
|
286
227
|
|
|
287
228
|
/// @notice Decodes a `Plurality` junction from a given `Junction` struct, extracting the body ID and body part.
|
|
@@ -290,28 +231,15 @@ library JunctionCodec {
|
|
|
290
231
|
function asPlurality(
|
|
291
232
|
Junction memory junction
|
|
292
233
|
) internal pure returns (PluralityParams memory params) {
|
|
293
|
-
|
|
294
|
-
revert InvalidJunctionType(uint8(junction.jType));
|
|
295
|
-
if (junction.payload.length == 0) revert InvalidJunctionPayload();
|
|
234
|
+
_assertVariant(junction, JunctionVariant.Plurality);
|
|
296
235
|
uint256 offset = 0;
|
|
297
|
-
BodyId memory id;
|
|
298
236
|
uint256 bytesRead;
|
|
299
|
-
(id, bytesRead) = BodyIdCodec.decodeAt(junction.payload, offset);
|
|
237
|
+
(params.id, bytesRead) = BodyIdCodec.decodeAt(junction.payload, offset);
|
|
300
238
|
offset += bytesRead;
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
/// @notice Decodes an `GlobalConsensus` junction from a given `Junction` struct and extracts the `NetworkId`.
|
|
307
|
-
/// @param junction The `Junction` struct to decode, which should represent a `GlobalConsensus` junction.
|
|
308
|
-
/// @return networkId The `NetworkId` extracted from the junction's payload, representing the global network's consensus.
|
|
309
|
-
function asGlobalConsensus(
|
|
310
|
-
Junction memory junction
|
|
311
|
-
) internal pure returns (NetworkId memory networkId) {
|
|
312
|
-
if (junction.jType != JunctionType.GlobalConsensus)
|
|
313
|
-
revert InvalidJunctionType(uint8(junction.jType));
|
|
314
|
-
(networkId, ) = NetworkIdCodec.decode(junction.payload);
|
|
239
|
+
(params.part, bytesRead) = BodyPartCodec.decodeAt(
|
|
240
|
+
junction.payload,
|
|
241
|
+
offset
|
|
242
|
+
);
|
|
315
243
|
}
|
|
316
244
|
|
|
317
245
|
function _innerNetworkIdSize(
|
|
@@ -326,4 +254,13 @@ library JunctionCodec {
|
|
|
326
254
|
}
|
|
327
255
|
return size;
|
|
328
256
|
}
|
|
257
|
+
|
|
258
|
+
function _assertVariant(
|
|
259
|
+
Junction memory junction,
|
|
260
|
+
JunctionVariant expected
|
|
261
|
+
) private pure {
|
|
262
|
+
if (junction.variant != expected) {
|
|
263
|
+
revert InvalidJunctionVariant(uint8(junction.variant));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
329
266
|
}
|
|
@@ -10,3 +10,37 @@ struct Junctions {
|
|
|
10
10
|
/// @custom:property The actual junction data
|
|
11
11
|
Junction[] items;
|
|
12
12
|
}
|
|
13
|
+
|
|
14
|
+
error InvalidJunctionsCount(uint8 count);
|
|
15
|
+
|
|
16
|
+
/// @notice Creates a `Here` junctions struct.
|
|
17
|
+
/// @return A `Junctions` struct representing the `Here` variant.
|
|
18
|
+
function here() pure returns (Junctions memory) {
|
|
19
|
+
return Junctions({count: 0, items: new Junction[](0)});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// @notice Creates a `Junctions` struct from a single `Junction`, representing the `X1` variant.
|
|
23
|
+
/// @param junction The `Junction` to include in the `Junctions`.
|
|
24
|
+
/// @return A `Junctions` struct containing the provided `Junction`.
|
|
25
|
+
function fromJunction(
|
|
26
|
+
Junction memory junction
|
|
27
|
+
) pure returns (Junctions memory) {
|
|
28
|
+
Junction[] memory js = new Junction[](1);
|
|
29
|
+
js[0] = junction;
|
|
30
|
+
return Junctions({count: 1, items: js});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// @notice Creates a `Junctions` struct with the given junctions.
|
|
34
|
+
/// @param junctions An array of `Junction` structs to include in the `Junctions`.
|
|
35
|
+
/// @return A `Junctions` struct containing the provided junctions.
|
|
36
|
+
function fromJunctionArr(
|
|
37
|
+
Junction[] memory junctions
|
|
38
|
+
) pure returns (Junctions memory) {
|
|
39
|
+
if (junctions.length == 0) {
|
|
40
|
+
return here();
|
|
41
|
+
}
|
|
42
|
+
if (junctions.length > 8) {
|
|
43
|
+
revert InvalidJunctionsCount(uint8(junctions.length));
|
|
44
|
+
}
|
|
45
|
+
return Junctions({count: uint8(junctions.length), items: junctions});
|
|
46
|
+
}
|
|
@@ -13,24 +13,6 @@ library JunctionsCodec {
|
|
|
13
13
|
error InvalidJunctionsLength(uint8 count);
|
|
14
14
|
error InvalidJunctionsCount(uint8 count);
|
|
15
15
|
|
|
16
|
-
/// @notice Creates a `Here` junctions struct.
|
|
17
|
-
function here() internal pure returns (Junctions memory) {
|
|
18
|
-
return Junctions({count: 0, items: new Junction[](0)});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/// @notice Creates a `Junctions` struct with the given junctions.
|
|
22
|
-
function junction(
|
|
23
|
-
Junction[] memory junctions
|
|
24
|
-
) internal pure returns (Junctions memory) {
|
|
25
|
-
if (junctions.length == 0) {
|
|
26
|
-
return here();
|
|
27
|
-
}
|
|
28
|
-
if (junctions.length > 8) {
|
|
29
|
-
revert InvalidJunctionsCount(uint8(junctions.length));
|
|
30
|
-
}
|
|
31
|
-
return Junctions({count: uint8(junctions.length), items: junctions});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
16
|
/// @notice Encodes a Junctions struct into bytes.
|
|
35
17
|
/// @param junctions The Junctions struct to encode.
|
|
36
18
|
/// @return SCALE-encoded byte sequence representing the Junctions.
|
|
@@ -3,6 +3,8 @@ pragma solidity ^0.8.28;
|
|
|
3
3
|
|
|
4
4
|
import {Junctions} from "../Junctions/Junctions.sol";
|
|
5
5
|
|
|
6
|
+
import {here} from "../Junctions/Junctions.sol";
|
|
7
|
+
|
|
6
8
|
/// @notice A relative path between state-bearing consensus systems.
|
|
7
9
|
struct Location {
|
|
8
10
|
/// @custom:property The number of parent junctions at the beginning of this Location.
|
|
@@ -10,3 +12,9 @@ struct Location {
|
|
|
10
12
|
/// @custom:property The interior (i.e. non-parent) junctions that this Location contains. See `Junctions` struct for details.
|
|
11
13
|
Junctions interior;
|
|
12
14
|
}
|
|
15
|
+
|
|
16
|
+
/// @notice Creates a `Location` struct representing the parent location (i.e., one level up in the hierarchy).
|
|
17
|
+
/// @return A `Location` struct with `parents` set to 1 and an empty `interior`.
|
|
18
|
+
function parent() pure returns (Location memory) {
|
|
19
|
+
return Location({parents: 1, interior: here()});
|
|
20
|
+
}
|