@rootzero/contracts 0.9.2 → 0.9.4
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/Commands.sol +4 -3
- package/Core.sol +3 -0
- package/Cursors.sol +1 -1
- package/README.md +18 -24
- package/blocks/Cursors.sol +332 -335
- package/blocks/Keys.sol +38 -57
- package/blocks/Schema.sol +55 -114
- package/blocks/Writers.sol +361 -255
- package/commands/Base.sol +6 -48
- package/commands/Burn.sol +4 -4
- package/commands/Credit.sol +5 -4
- package/commands/Debit.sol +6 -5
- package/commands/Deposit.sol +17 -14
- package/commands/Provision.sol +17 -14
- package/commands/Transfer.sol +4 -4
- package/commands/Withdraw.sol +5 -4
- package/commands/admin/AllowAssets.sol +3 -3
- package/commands/admin/Allowance.sol +3 -3
- package/commands/admin/Authorize.sol +3 -3
- package/commands/admin/DenyAssets.sol +3 -3
- package/commands/admin/Destroy.sol +1 -1
- package/commands/admin/Execute.sol +9 -8
- package/commands/admin/Init.sol +1 -1
- package/commands/admin/Unauthorize.sol +3 -3
- package/core/Access.sol +11 -0
- package/core/Context.sol +11 -13
- package/core/Payable.sol +57 -0
- package/core/Pipeline.sol +55 -0
- package/docs/Schema.md +194 -0
- package/events/Admin.sol +5 -1
- package/events/Command.sol +6 -2
- package/events/Listing.sol +3 -4
- package/events/Peer.sol +5 -3
- package/events/Query.sol +5 -2
- package/package.json +2 -2
- package/peer/AllowAssets.sol +3 -3
- package/peer/Allowance.sol +3 -3
- package/peer/BalancePull.sol +43 -0
- package/peer/DenyAssets.sol +3 -3
- package/peer/Pipe.sol +38 -0
- package/peer/Settle.sol +3 -3
- package/queries/Assets.sol +7 -6
- package/queries/Balances.sol +5 -4
- package/queries/Positions.sol +14 -14
- package/utils/Value.sol +8 -14
- package/commands/Pipe.sol +0 -67
- package/docs/GETTING_STARTED.md +0 -294
- package/peer/AssetPull.sol +0 -43
package/blocks/Cursors.sol
CHANGED
|
@@ -4,7 +4,6 @@ pragma solidity ^0.8.33;
|
|
|
4
4
|
import {AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, Tx} from "../core/Types.sol";
|
|
5
5
|
import {Sizes} from "./Schema.sol";
|
|
6
6
|
import {Keys} from "./Keys.sol";
|
|
7
|
-
import {ALLOC_SCALE, Writer, Writers} from "./Writers.sol";
|
|
8
7
|
|
|
9
8
|
/// @notice Zero-copy view into a calldata block stream.
|
|
10
9
|
/// All positions (`i`, `bound`) are byte offsets relative to the start of the source region.
|
|
@@ -45,8 +44,9 @@ library Cursors {
|
|
|
45
44
|
error ZeroNode();
|
|
46
45
|
/// @dev A field value did not match the expected value.
|
|
47
46
|
error UnexpectedValue();
|
|
48
|
-
/// @dev
|
|
47
|
+
/// @dev Prime block counts are not divisible by, or do not match, their declared group sizes.
|
|
49
48
|
error BadRatio();
|
|
49
|
+
|
|
50
50
|
// -------------------------------------------------------------------------
|
|
51
51
|
// Cursor construction and navigation
|
|
52
52
|
// -------------------------------------------------------------------------
|
|
@@ -65,6 +65,17 @@ library Cursors {
|
|
|
65
65
|
cur.len = source.length;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/// @notice Create a cursor and prime it for a grouped iteration pass.
|
|
69
|
+
/// Equivalent to `open(source)` followed by `primeRun(group)`.
|
|
70
|
+
/// @param source Calldata slice that forms the block stream.
|
|
71
|
+
/// @param group Expected block group size (e.g. 1 for single, 2 for paired).
|
|
72
|
+
/// @return cur Cursor with `bound` set to the end of the first run.
|
|
73
|
+
/// @return groups Number of block groups in the run (`prime block count / group`).
|
|
74
|
+
function init(bytes calldata source, uint group) internal pure returns (Cur memory cur, uint groups) {
|
|
75
|
+
cur = open(source);
|
|
76
|
+
(, groups) = cur.primeRun(group);
|
|
77
|
+
}
|
|
78
|
+
|
|
68
79
|
/// @notice Move the cursor to an absolute position within the source region.
|
|
69
80
|
/// @param cur Cursor to update.
|
|
70
81
|
/// @param i New read position (byte offset relative to source start).
|
|
@@ -75,6 +86,26 @@ library Cursors {
|
|
|
75
86
|
return cur;
|
|
76
87
|
}
|
|
77
88
|
|
|
89
|
+
/// @notice Advance the cursor by `n` bytes within the source region.
|
|
90
|
+
/// Reverts with `IncompleteCursor` if `n` exceeds the remaining cursor region length.
|
|
91
|
+
/// @param cur Cursor to advance.
|
|
92
|
+
/// @param n Number of bytes to skip from the current read position.
|
|
93
|
+
function skip(Cur memory cur, uint n) internal pure returns (Cur memory) {
|
|
94
|
+
if (n > cur.len - cur.i) revert IncompleteCursor();
|
|
95
|
+
cur.i += n;
|
|
96
|
+
return cur;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/// @notice Advance the cursor to a later absolute position within the source region.
|
|
100
|
+
/// Reverts with `IncompleteCursor` if `i` exceeds the cursor region length or is before `cur.i`.
|
|
101
|
+
/// @param cur Cursor to advance.
|
|
102
|
+
/// @param i New read position (byte offset relative to source start).
|
|
103
|
+
function skipTo(Cur memory cur, uint i) internal pure returns (Cur memory) {
|
|
104
|
+
if (i > cur.len || cur.i > i) revert IncompleteCursor();
|
|
105
|
+
cur.i = i;
|
|
106
|
+
return cur;
|
|
107
|
+
}
|
|
108
|
+
|
|
78
109
|
/// @notice Create a subcursor over the half-open range `[from, to)` within the source region.
|
|
79
110
|
/// The returned cursor starts at position zero within that sliced region.
|
|
80
111
|
/// @param cur Source cursor.
|
|
@@ -87,17 +118,48 @@ library Cursors {
|
|
|
87
118
|
out.len = to - from;
|
|
88
119
|
}
|
|
89
120
|
|
|
121
|
+
/// @notice Return the full cursor region as a calldata slice.
|
|
122
|
+
/// Does not advance the cursor; `cur.i` and `cur.bound` are ignored.
|
|
123
|
+
/// @param cur Cursor whose backing region should be returned.
|
|
124
|
+
/// @return data Calldata view over `[cur.offset, cur.offset + cur.len)`.
|
|
125
|
+
function raw(Cur memory cur) internal pure returns (bytes calldata data) {
|
|
126
|
+
if (cur.len > msg.data.length || cur.offset > msg.data.length - cur.len) revert MalformedBlocks();
|
|
127
|
+
data = msg.data[cur.offset:cur.offset + cur.len];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// @notice Return a sub-range of the cursor region as a calldata slice.
|
|
131
|
+
/// Does not advance the cursor; `cur.i` and `cur.bound` are ignored.
|
|
132
|
+
/// @param cur Source cursor.
|
|
133
|
+
/// @param from Start byte offset within the source region (inclusive).
|
|
134
|
+
/// @param to End byte offset within the source region (exclusive).
|
|
135
|
+
/// @return data Calldata view over the requested sub-range.
|
|
136
|
+
function raw(Cur memory cur, uint from, uint to) internal pure returns (bytes calldata data) {
|
|
137
|
+
if (from > to || to > cur.len) revert MalformedBlocks();
|
|
138
|
+
if (cur.len > msg.data.length || cur.offset > msg.data.length - cur.len) revert MalformedBlocks();
|
|
139
|
+
data = msg.data[cur.offset + from:cur.offset + to];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/// @notice Hash a sub-range of the cursor region.
|
|
143
|
+
/// Does not advance the cursor; `from` and `to` are relative to the source region.
|
|
144
|
+
/// @param cur Source cursor.
|
|
145
|
+
/// @param from Start byte offset within the source region (inclusive).
|
|
146
|
+
/// @param to End byte offset within the source region (exclusive).
|
|
147
|
+
/// @return digest Keccak256 hash of the requested sub-range.
|
|
148
|
+
function hash(Cur memory cur, uint from, uint to) internal pure returns (bytes32 digest) {
|
|
149
|
+
digest = keccak256(cur.raw(from, to));
|
|
150
|
+
}
|
|
151
|
+
|
|
90
152
|
/// @notice Read a block header at position `i` without advancing the cursor.
|
|
91
153
|
/// @param cur Source cursor.
|
|
92
154
|
/// @param i Byte offset of the block header within the source region.
|
|
93
155
|
/// @return key Four-byte block type identifier.
|
|
94
156
|
/// @return len Payload byte length declared in the header.
|
|
95
157
|
function peek(Cur memory cur, uint i) internal pure returns (bytes4 key, uint len) {
|
|
96
|
-
if (i +
|
|
158
|
+
if (i + Sizes.Header > cur.len) revert MalformedBlocks();
|
|
97
159
|
uint abs = cur.offset + i;
|
|
98
160
|
key = bytes4(msg.data[abs:abs + 4]);
|
|
99
161
|
len = uint32(bytes4(msg.data[abs + 4:abs + 8]));
|
|
100
|
-
if (i +
|
|
162
|
+
if (i + Sizes.Header + len > cur.len) revert MalformedBlocks();
|
|
101
163
|
}
|
|
102
164
|
|
|
103
165
|
/// @notice Return the byte offset immediately past the block at the current cursor position.
|
|
@@ -109,21 +171,49 @@ library Cursors {
|
|
|
109
171
|
return cur.i + Sizes.Header + len;
|
|
110
172
|
}
|
|
111
173
|
|
|
112
|
-
/// @notice Return true if
|
|
174
|
+
/// @notice Return true if position `i` is at a block header with the given key.
|
|
175
|
+
/// Returns false when `i` is out of bounds or the key differs.
|
|
176
|
+
/// @param cur Source cursor.
|
|
177
|
+
/// @param i Byte offset of the block header within the source region.
|
|
178
|
+
/// @param key Expected block type identifier.
|
|
179
|
+
/// @return Whether the block header at `i` uses `key`.
|
|
180
|
+
function hasAt(Cur memory cur, uint i, bytes4 key) internal pure returns (bool) {
|
|
181
|
+
if (i > cur.len || Sizes.Header > cur.len - i) return false;
|
|
182
|
+
uint abs = cur.offset + i;
|
|
183
|
+
return bytes4(msg.data[abs:abs + 4]) == key;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/// @notice Return true if the current cursor position is at a block header with the given key.
|
|
113
187
|
/// Returns false when `cur.i` is out of bounds or the key differs.
|
|
114
188
|
/// @param cur Source cursor.
|
|
115
189
|
/// @param key Expected block type identifier.
|
|
116
190
|
/// @return Whether the block header at `cur.i` uses `key`.
|
|
117
|
-
function
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
191
|
+
function isAt(Cur memory cur, bytes4 key) internal pure returns (bool) {
|
|
192
|
+
return cur.hasAt(cur.i, key);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/// @notice Enter a block at the current position and return its next offset.
|
|
196
|
+
/// Advances `cur.i` past the block header so the payload can be parsed
|
|
197
|
+
/// directly from the same cursor. The returned `next` is the byte offset
|
|
198
|
+
/// immediately after the block payload, relative to the current cursor region.
|
|
199
|
+
/// @param cur Cursor positioned at the expected block; advanced past the 8-byte header.
|
|
200
|
+
/// @param key Expected block key.
|
|
201
|
+
/// @param min Minimum acceptable payload length.
|
|
202
|
+
/// @param max Maximum acceptable payload length; 0 means unbounded.
|
|
203
|
+
/// @return next Byte offset immediately after the block payload.
|
|
204
|
+
function enter(Cur memory cur, bytes4 key, uint min, uint max) internal pure returns (uint next) {
|
|
205
|
+
(bytes4 current, uint len) = peek(cur, cur.i);
|
|
206
|
+
if (current != key) revert InvalidBlock();
|
|
207
|
+
if (len < min || (max != 0 && len > max)) revert InvalidBlock();
|
|
208
|
+
next = cur.i + Sizes.Header + len;
|
|
209
|
+
cur.i += Sizes.Header;
|
|
121
210
|
}
|
|
122
211
|
|
|
123
212
|
/// @notice Validate a block at position `i` and return its payload location.
|
|
124
213
|
/// Does not advance the cursor.
|
|
125
214
|
/// @param cur Source cursor.
|
|
126
215
|
/// @param i Byte offset of the block within the source region.
|
|
216
|
+
/// @param end Required next offset after the block; 0 means no exact-end check.
|
|
127
217
|
/// @param key Expected block type key; reverts if actual key differs.
|
|
128
218
|
/// @param min Minimum acceptable payload length (inclusive).
|
|
129
219
|
/// @param max Maximum acceptable payload length (inclusive); 0 means unbounded.
|
|
@@ -132,15 +222,30 @@ library Cursors {
|
|
|
132
222
|
function expect(
|
|
133
223
|
Cur memory cur,
|
|
134
224
|
uint i,
|
|
225
|
+
uint end,
|
|
135
226
|
bytes4 key,
|
|
136
227
|
uint min,
|
|
137
228
|
uint max
|
|
138
229
|
) internal pure returns (uint abs, uint next) {
|
|
139
230
|
(bytes4 current, uint len) = peek(cur, i);
|
|
140
231
|
if (current != key) revert InvalidBlock();
|
|
141
|
-
abs = cur.offset + i + 8;
|
|
142
|
-
next = i + 8 + len;
|
|
143
232
|
if (len < min || (max != 0 && len > max)) revert InvalidBlock();
|
|
233
|
+
abs = cur.offset + i + Sizes.Header;
|
|
234
|
+
next = i + Sizes.Header + len;
|
|
235
|
+
if (end != 0 && next != end) revert IncompleteCursor();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/// @notice Validate and consume the current block, advancing `cur.i` past it.
|
|
239
|
+
/// @param cur Cursor to advance.
|
|
240
|
+
/// @param end Required next offset after the block; 0 means no exact-end check.
|
|
241
|
+
/// @param key Expected block type key.
|
|
242
|
+
/// @param min Minimum payload length.
|
|
243
|
+
/// @param max Maximum payload length (0 = unbounded).
|
|
244
|
+
/// @return abs Absolute calldata offset of the payload start.
|
|
245
|
+
function consume(Cur memory cur, uint end, bytes4 key, uint min, uint max) internal pure returns (uint abs) {
|
|
246
|
+
uint next;
|
|
247
|
+
(abs, next) = expect(cur, cur.i, end, key, min, max);
|
|
248
|
+
cur.i = next;
|
|
144
249
|
}
|
|
145
250
|
|
|
146
251
|
/// @notice Count consecutive blocks of the same key starting at `i`.
|
|
@@ -154,7 +259,7 @@ library Cursors {
|
|
|
154
259
|
while (next < cur.len) {
|
|
155
260
|
(bytes4 current, uint len) = peek(cur, next);
|
|
156
261
|
if (current != key) break;
|
|
157
|
-
next +=
|
|
262
|
+
next += Sizes.Header + len;
|
|
158
263
|
|
|
159
264
|
unchecked {
|
|
160
265
|
++total;
|
|
@@ -165,20 +270,19 @@ library Cursors {
|
|
|
165
270
|
/// @notice Initialise the cursor for a grouped iteration pass.
|
|
166
271
|
/// Reads the key of the first block, counts the consecutive run of that key,
|
|
167
272
|
/// stores the run end in `cur.bound`, validates that the count is a
|
|
168
|
-
/// multiple of `group`, and returns
|
|
169
|
-
/// normalized quotient (`count / group`).
|
|
273
|
+
/// multiple of `group`, and returns the run key and normalized group count.
|
|
170
274
|
/// @param cur Cursor to prime; `cur.bound` is updated in place.
|
|
171
275
|
/// @param group Expected group size (e.g. 1 for single-asset, 2 for paired input/output).
|
|
172
276
|
/// @return key Block type identifier of the run.
|
|
173
|
-
/// @return
|
|
174
|
-
|
|
175
|
-
function primeRun(Cur memory cur, uint group) internal pure returns (bytes4 key, uint count, uint quotient) {
|
|
277
|
+
/// @return groups Number of groups represented by the run (`block count / group`).
|
|
278
|
+
function primeRun(Cur memory cur, uint group) internal pure returns (bytes4 key, uint groups) {
|
|
176
279
|
if (group == 0) revert ZeroGroup();
|
|
177
280
|
key = cur.i + 4 > cur.len ? bytes4(0) : bytes4(msg.data[cur.offset + cur.i:cur.offset + cur.i + 4]);
|
|
281
|
+
uint count;
|
|
178
282
|
(count, cur.bound) = countRun(cur, cur.i, key);
|
|
179
283
|
if (count == 0) revert ZeroCursor();
|
|
180
284
|
if (count % group != 0) revert BadRatio();
|
|
181
|
-
|
|
285
|
+
groups = count / group;
|
|
182
286
|
}
|
|
183
287
|
|
|
184
288
|
/// @notice Scan forward from `i` for the first block matching `key`.
|
|
@@ -190,7 +294,7 @@ library Cursors {
|
|
|
190
294
|
while (i < cur.len) {
|
|
191
295
|
(bytes4 current, uint len) = peek(cur, i);
|
|
192
296
|
if (current == key) return i;
|
|
193
|
-
i +=
|
|
297
|
+
i += Sizes.Header + len;
|
|
194
298
|
}
|
|
195
299
|
return cur.len;
|
|
196
300
|
}
|
|
@@ -203,29 +307,6 @@ library Cursors {
|
|
|
203
307
|
return find(cur, cur.i, key);
|
|
204
308
|
}
|
|
205
309
|
|
|
206
|
-
/// @notice Validate and consume the current block, advancing `cur.i` past it.
|
|
207
|
-
/// @param cur Cursor to advance.
|
|
208
|
-
/// @param key Expected block type key.
|
|
209
|
-
/// @param min Minimum payload length.
|
|
210
|
-
/// @param max Maximum payload length (0 = unbounded).
|
|
211
|
-
/// @return abs Absolute calldata offset of the payload start.
|
|
212
|
-
function consume(Cur memory cur, bytes4 key, uint min, uint max) internal pure returns (uint abs) {
|
|
213
|
-
uint next;
|
|
214
|
-
(abs, next) = expect(cur, cur.i, key, min, max);
|
|
215
|
-
cur.i = next;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/// @notice Enter a Bundle block at the current position and return the next offset.
|
|
219
|
-
/// Advances `cur.i` past the bundle header so the bundled members can be parsed
|
|
220
|
-
/// directly from the same cursor. The returned `next` is the byte offset
|
|
221
|
-
/// immediately after the bundle payload, relative to the current cursor region.
|
|
222
|
-
/// @param cur Cursor positioned at a bundle block; advanced past the 8-byte header.
|
|
223
|
-
/// @return next Byte offset immediately after the bundle payload.
|
|
224
|
-
function bundle(Cur memory cur) internal pure returns (uint next) {
|
|
225
|
-
(, next) = expect(cur, cur.i, Keys.Bundle, 0, 0);
|
|
226
|
-
cur.i += 8;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
310
|
/// @notice Enter a List block at the current position and return the next offset.
|
|
230
311
|
/// Advances `cur.i` past the list header so the list members can be parsed
|
|
231
312
|
/// directly from the same cursor. The returned `next` is the byte offset
|
|
@@ -233,8 +314,7 @@ library Cursors {
|
|
|
233
314
|
/// @param cur Cursor positioned at a list block; advanced past the 8-byte header.
|
|
234
315
|
/// @return next Byte offset immediately after the list payload.
|
|
235
316
|
function list(Cur memory cur) internal pure returns (uint next) {
|
|
236
|
-
|
|
237
|
-
cur.i += 8;
|
|
317
|
+
next = enter(cur, Keys.List, 0, 0);
|
|
238
318
|
}
|
|
239
319
|
|
|
240
320
|
/// @notice Consume a block with the given key at the current position and return a cursor over the full block slice.
|
|
@@ -244,77 +324,89 @@ library Cursors {
|
|
|
244
324
|
/// @param key Expected block type key.
|
|
245
325
|
/// @return out Cursor scoped to the full block.
|
|
246
326
|
function take(Cur memory cur, bytes4 key) internal pure returns (Cur memory out) {
|
|
247
|
-
(, uint next) = expect(cur, cur.i, key, 0, 0);
|
|
327
|
+
(, uint next) = expect(cur, cur.i, 0, key, 0, 0);
|
|
248
328
|
out = cur.slice(cur.i, next);
|
|
249
329
|
cur.i = next;
|
|
250
330
|
}
|
|
251
331
|
|
|
252
|
-
/// @notice
|
|
253
|
-
///
|
|
254
|
-
///
|
|
255
|
-
/// @param cur
|
|
256
|
-
/// @
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
332
|
+
/// @notice Return whether the remaining cursor region is empty or exactly one block with `key`.
|
|
333
|
+
/// Returns false for an empty remaining region. Reverts if the next block has another key or
|
|
334
|
+
/// if a matching block is followed by trailing bytes.
|
|
335
|
+
/// @param cur Source cursor.
|
|
336
|
+
/// @param key Expected optional block key.
|
|
337
|
+
/// @return Whether the remaining region contains exactly one block with `key`.
|
|
338
|
+
function maybeOnly(Cur memory cur, bytes4 key) internal pure returns (bool) {
|
|
339
|
+
if (cur.i == cur.len) return false;
|
|
340
|
+
if (!cur.isAt(key)) revert InvalidBlock();
|
|
341
|
+
if (cur.past() != cur.len) revert IncompleteCursor();
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/// @notice Consume an optional block with the given key and return a cursor over the full block slice.
|
|
346
|
+
/// If the current block key does not match, returns an empty cursor and leaves `cur.i` unchanged.
|
|
347
|
+
/// Otherwise behaves like `take(cur, key)`.
|
|
348
|
+
/// @param cur Cursor positioned at an optional block.
|
|
349
|
+
/// @param key Optional block type key.
|
|
350
|
+
/// @return out Cursor scoped to the full matching block, or empty when no matching block is present.
|
|
351
|
+
function maybeTake(Cur memory cur, bytes4 key) internal pure returns (Cur memory out) {
|
|
352
|
+
return cur.isAt(key) ? take(cur, key) : cur.slice(cur.i, cur.i);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/// @notice Consume an optional DATA block at the current position and return a cursor over the full block slice.
|
|
356
|
+
/// If the current block is not DATA, returns an empty cursor and leaves `cur.i` unchanged.
|
|
357
|
+
/// Otherwise behaves like `take(cur, Keys.Data)`.
|
|
358
|
+
/// @param cur Cursor positioned at an optional DATA block.
|
|
359
|
+
/// @return out Cursor scoped to the full DATA block, or empty when no DATA block is present.
|
|
360
|
+
function maybeData(Cur memory cur) internal pure returns (Cur memory out) {
|
|
361
|
+
return maybeTake(cur, Keys.Data);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/// @notice Enter a List block, prime its member run, and return the group count.
|
|
262
365
|
/// @param cur Cursor positioned at a list block; advanced past the 8-byte header.
|
|
263
366
|
/// @param group Expected block group size for the list item stream.
|
|
264
|
-
/// @return
|
|
367
|
+
/// @return groups Number of block groups in the list payload.
|
|
265
368
|
/// @return next Byte offset immediately after the list payload.
|
|
266
|
-
function list(Cur memory cur, uint group) internal pure returns (uint
|
|
369
|
+
function list(Cur memory cur, uint group) internal pure returns (uint groups, uint next) {
|
|
267
370
|
next = list(cur);
|
|
268
|
-
(,
|
|
371
|
+
(, groups) = cur.primeRun(group);
|
|
269
372
|
if (cur.bound != next) revert IncompleteCursor();
|
|
270
373
|
}
|
|
271
374
|
|
|
375
|
+
/// @notice Exit a nested region at an exact boundary.
|
|
376
|
+
/// Reverts with `IncompleteCursor` if `end` exceeds the cursor region length
|
|
377
|
+
/// or `cur.i != end`.
|
|
378
|
+
/// @param cur Cursor to check.
|
|
379
|
+
/// @param end Relative end offset of the nested region.
|
|
380
|
+
function exit(Cur memory cur, uint end) internal pure {
|
|
381
|
+
if (end > cur.len || cur.i != end) revert IncompleteCursor();
|
|
382
|
+
}
|
|
383
|
+
|
|
272
384
|
/// @notice Assert that the cursor has consumed exactly up to `bound`.
|
|
273
385
|
/// Reverts with `IncompleteCursor` if `bound` is zero or `cur.i != cur.bound`.
|
|
274
386
|
/// @param cur Cursor to check.
|
|
275
|
-
function
|
|
387
|
+
function close(Cur memory cur) internal pure {
|
|
276
388
|
if (cur.bound == 0 || cur.i != cur.bound) revert IncompleteCursor();
|
|
277
389
|
}
|
|
278
390
|
|
|
279
391
|
/// @notice Assert that the cursor has consumed its entire source region.
|
|
280
392
|
/// Reverts with `IncompleteCursor` when `cur.i != cur.len`.
|
|
281
393
|
/// @param cur Cursor to check.
|
|
282
|
-
function
|
|
394
|
+
function complete(Cur memory cur) internal pure {
|
|
283
395
|
if (cur.i != cur.len) revert IncompleteCursor();
|
|
284
396
|
}
|
|
285
397
|
|
|
286
|
-
/// @notice Resume parsing after a nested region delimited by `resumeAt`.
|
|
287
|
-
/// Reverts with `IncompleteCursor` if `cur.i` has advanced past `resumeAt` or `resumeAt`
|
|
288
|
-
/// exceeds the cursor region length. Otherwise moves `cur.i` to `end`.
|
|
289
|
-
/// @param cur Cursor to advance.
|
|
290
|
-
/// @param resumeAt Relative end offset of the nested region to resume after.
|
|
291
|
-
function resume(Cur memory cur, uint resumeAt) internal pure {
|
|
292
|
-
if (resumeAt > cur.len || cur.i > resumeAt) revert IncompleteCursor();
|
|
293
|
-
cur.i = resumeAt;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/// @notice Ensure that parsing has reached an exact nested-region boundary.
|
|
297
|
-
/// Reverts with `IncompleteCursor` if `ensureAt` exceeds the cursor region length
|
|
298
|
-
/// or `cur.i != ensureAt`.
|
|
299
|
-
/// @param cur Cursor to check.
|
|
300
|
-
/// @param ensureAt Relative offset that `cur.i` must match exactly.
|
|
301
|
-
function ensure(Cur memory cur, uint ensureAt) internal pure {
|
|
302
|
-
if (ensureAt > cur.len || cur.i != ensureAt) revert IncompleteCursor();
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
/// @notice Assert completion and finalise a writer in one step.
|
|
306
|
-
/// @param cur Cursor to check.
|
|
307
|
-
/// @param writer Writer to finalise.
|
|
308
|
-
/// @return Trimmed output bytes from the writer.
|
|
309
|
-
function complete(Cur memory cur, Writer memory writer) internal pure returns (bytes memory) {
|
|
310
|
-
if (cur.bound == 0 || cur.i != cur.bound) revert IncompleteCursor();
|
|
311
|
-
return Writers.finish(writer);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
398
|
// -------------------------------------------------------------------------
|
|
315
399
|
// Block factory helpers
|
|
316
400
|
// -------------------------------------------------------------------------
|
|
317
401
|
|
|
402
|
+
/// @notice Encode a block with a raw payload.
|
|
403
|
+
/// @param key Block type key.
|
|
404
|
+
/// @param data Raw payload bytes.
|
|
405
|
+
/// @return Encoded block bytes.
|
|
406
|
+
function createBlock(bytes4 key, bytes memory data) internal pure returns (bytes memory) {
|
|
407
|
+
return bytes.concat(key, bytes4(uint32(data.length)), data);
|
|
408
|
+
}
|
|
409
|
+
|
|
318
410
|
/// @notice Encode a block with a single 32-byte payload word.
|
|
319
411
|
/// @param key Block type key.
|
|
320
412
|
/// @param value 32-byte payload.
|
|
@@ -378,28 +470,11 @@ library Cursors {
|
|
|
378
470
|
return bytes.concat(key, bytes4(uint32(0xa0)), a, b, c, d, e);
|
|
379
471
|
}
|
|
380
472
|
|
|
381
|
-
/// @notice Encode a block with a
|
|
382
|
-
/// @param
|
|
383
|
-
/// @
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
function createBlockHead32(bytes4 key, bytes32 head, bytes memory tail) internal pure returns (bytes memory) {
|
|
387
|
-
return bytes.concat(key, bytes4(uint32(0x20 + tail.length)), head, tail);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/// @notice Encode a block with a 64-byte fixed head followed by a variable-length tail.
|
|
391
|
-
/// @param key Block type key.
|
|
392
|
-
/// @param a First fixed payload word.
|
|
393
|
-
/// @param b Second fixed payload word.
|
|
394
|
-
/// @param tail Variable-length payload bytes appended after the fixed head.
|
|
395
|
-
/// @return Encoded block bytes.
|
|
396
|
-
function createBlockHead64(
|
|
397
|
-
bytes4 key,
|
|
398
|
-
bytes32 a,
|
|
399
|
-
bytes32 b,
|
|
400
|
-
bytes memory tail
|
|
401
|
-
) internal pure returns (bytes memory) {
|
|
402
|
-
return bytes.concat(key, bytes4(uint32(0x40 + tail.length)), a, b, tail);
|
|
473
|
+
/// @notice Encode a BYTES block with a raw payload.
|
|
474
|
+
/// @param data Raw payload bytes.
|
|
475
|
+
/// @return Encoded BYTES block bytes.
|
|
476
|
+
function toBytesBlock(bytes memory data) internal pure returns (bytes memory) {
|
|
477
|
+
return createBlock(Keys.Bytes, data);
|
|
403
478
|
}
|
|
404
479
|
|
|
405
480
|
/// @notice Encode a BOUNTY block.
|
|
@@ -410,24 +485,6 @@ library Cursors {
|
|
|
410
485
|
return createBlock64(Keys.Bounty, bytes32(bounty), relayer);
|
|
411
486
|
}
|
|
412
487
|
|
|
413
|
-
/// @notice Encode a STEP block.
|
|
414
|
-
/// @param target Command target identifier.
|
|
415
|
-
/// @param value Native value forwarded with the step.
|
|
416
|
-
/// @param request Variable-length nested request payload.
|
|
417
|
-
/// @return Encoded STEP block bytes.
|
|
418
|
-
function toStepBlock(uint target, uint value, bytes memory request) internal pure returns (bytes memory) {
|
|
419
|
-
return createBlockHead64(Keys.Step, bytes32(target), bytes32(value), request);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/// @notice Encode a CALL block.
|
|
423
|
-
/// @param target Target node identifier.
|
|
424
|
-
/// @param value Native value forwarded with the call.
|
|
425
|
-
/// @param data Raw calldata payload for the target.
|
|
426
|
-
/// @return Encoded CALL block bytes.
|
|
427
|
-
function toCallBlock(uint target, uint value, bytes memory data) internal pure returns (bytes memory) {
|
|
428
|
-
return createBlockHead64(Keys.Call, bytes32(target), bytes32(value), data);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
488
|
/// @notice Encode a BALANCE block.
|
|
432
489
|
/// @param asset Asset identifier.
|
|
433
490
|
/// @param meta Asset metadata slot.
|
|
@@ -443,87 +500,121 @@ library Cursors {
|
|
|
443
500
|
/// @param meta Asset metadata slot.
|
|
444
501
|
/// @param amount Token amount.
|
|
445
502
|
/// @return Encoded CUSTODY block bytes.
|
|
446
|
-
function toCustodyBlock(
|
|
447
|
-
uint host,
|
|
448
|
-
bytes32 asset,
|
|
449
|
-
bytes32 meta,
|
|
450
|
-
uint amount
|
|
451
|
-
) internal pure returns (bytes memory) {
|
|
503
|
+
function toCustodyBlock(uint host, bytes32 asset, bytes32 meta, uint amount) internal pure returns (bytes memory) {
|
|
452
504
|
return createBlock128(Keys.Custody, bytes32(host), asset, meta, bytes32(amount));
|
|
453
505
|
}
|
|
454
506
|
|
|
507
|
+
/// @notice Encode a STEP block.
|
|
508
|
+
/// @param target Command target identifier.
|
|
509
|
+
/// @param value Native value forwarded with the step.
|
|
510
|
+
/// @param request Raw nested request payload.
|
|
511
|
+
/// @return Encoded STEP block bytes.
|
|
512
|
+
function toStepBlock(uint target, uint value, bytes memory request) internal pure returns (bytes memory) {
|
|
513
|
+
return createBlock(Keys.Step, bytes.concat(bytes32(target), bytes32(value), toBytesBlock(request)));
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/// @notice Encode a CALL block.
|
|
517
|
+
/// @param target Target node identifier.
|
|
518
|
+
/// @param value Native value forwarded with the call.
|
|
519
|
+
/// @param data Raw calldata payload for the target.
|
|
520
|
+
/// @return Encoded CALL block bytes.
|
|
521
|
+
function toCallBlock(uint target, uint value, bytes memory data) internal pure returns (bytes memory) {
|
|
522
|
+
return createBlock(Keys.Call, bytes.concat(bytes32(target), bytes32(value), toBytesBlock(data)));
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/// @notice Encode a CONTEXT block.
|
|
526
|
+
/// @param account Command account identifier.
|
|
527
|
+
/// @param value Native value budget assigned to the context.
|
|
528
|
+
/// @param state Embedded state block stream.
|
|
529
|
+
/// @param request Embedded request block stream.
|
|
530
|
+
/// @return Encoded CONTEXT block bytes.
|
|
531
|
+
function toContextBlock(
|
|
532
|
+
bytes32 account,
|
|
533
|
+
uint value,
|
|
534
|
+
bytes memory state,
|
|
535
|
+
bytes memory request
|
|
536
|
+
) internal pure returns (bytes memory) {
|
|
537
|
+
return createBlock(Keys.Context, bytes.concat(account, bytes32(value), toBytesBlock(state), toBytesBlock(request)));
|
|
538
|
+
}
|
|
539
|
+
|
|
455
540
|
// -------------------------------------------------------------------------
|
|
456
541
|
// Raw calldata loaders
|
|
457
542
|
// -------------------------------------------------------------------------
|
|
458
543
|
|
|
459
|
-
/// @notice
|
|
460
|
-
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
461
|
-
///
|
|
462
|
-
/// @
|
|
463
|
-
|
|
544
|
+
/// @notice Read the next calldata word from the cursor and advance by `n` bytes.
|
|
545
|
+
/// @dev Performs no bounds, key, length, or cursor checks. Always loads 32 bytes;
|
|
546
|
+
/// callers may cast the returned word to `bytesN` when `n < 32`.
|
|
547
|
+
/// @param cur Cursor whose current position is advanced by `n` bytes.
|
|
548
|
+
/// @param n Number of bytes to advance.
|
|
549
|
+
/// @return value Loaded word.
|
|
550
|
+
function read(Cur memory cur, uint n) internal pure returns (bytes32 value) {
|
|
551
|
+
uint abs = cur.offset + cur.i;
|
|
464
552
|
assembly ("memory-safe") {
|
|
465
|
-
|
|
553
|
+
value := calldataload(abs)
|
|
466
554
|
}
|
|
555
|
+
cur.i += n;
|
|
467
556
|
}
|
|
468
557
|
|
|
469
|
-
/// @notice
|
|
558
|
+
/// @notice Read the next 16 bytes from the cursor and advance by 16 bytes.
|
|
470
559
|
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
471
|
-
/// @param
|
|
472
|
-
/// @return
|
|
473
|
-
|
|
474
|
-
|
|
560
|
+
/// @param cur Cursor whose current position is advanced by 16 bytes.
|
|
561
|
+
/// @return value Loaded bytes16 value.
|
|
562
|
+
function read16(Cur memory cur) internal pure returns (bytes16 value) {
|
|
563
|
+
uint abs = cur.offset + cur.i;
|
|
475
564
|
assembly ("memory-safe") {
|
|
476
|
-
|
|
477
|
-
b := calldataload(add(abs, 0x20))
|
|
565
|
+
value := calldataload(abs)
|
|
478
566
|
}
|
|
567
|
+
cur.i += 16;
|
|
479
568
|
}
|
|
480
569
|
|
|
481
|
-
/// @notice
|
|
570
|
+
/// @notice Read the next 32-byte word from the cursor and advance by one word.
|
|
482
571
|
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
483
|
-
/// @param
|
|
484
|
-
/// @return
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
function load96(uint abs) internal pure returns (bytes32 a, bytes32 b, bytes32 c) {
|
|
572
|
+
/// @param cur Cursor whose current position is advanced by 32 bytes.
|
|
573
|
+
/// @return value Loaded word.
|
|
574
|
+
function read32(Cur memory cur) internal pure returns (bytes32 value) {
|
|
575
|
+
uint abs = cur.offset + cur.i;
|
|
488
576
|
assembly ("memory-safe") {
|
|
489
|
-
|
|
490
|
-
b := calldataload(add(abs, 0x20))
|
|
491
|
-
c := calldataload(add(abs, 0x40))
|
|
577
|
+
value := calldataload(abs)
|
|
492
578
|
}
|
|
579
|
+
cur.i += 32;
|
|
493
580
|
}
|
|
494
581
|
|
|
495
|
-
/// @notice
|
|
582
|
+
/// @notice Read the next two 32-byte words from the cursor and advance by 64 bytes.
|
|
496
583
|
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
497
|
-
/// @param
|
|
584
|
+
/// @param cur Cursor whose current position is advanced by 64 bytes.
|
|
498
585
|
/// @return a First loaded word.
|
|
499
586
|
/// @return b Second loaded word.
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
function load128(uint abs) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d) {
|
|
587
|
+
function read64(Cur memory cur) internal pure returns (bytes32 a, bytes32 b) {
|
|
588
|
+
uint abs = cur.offset + cur.i;
|
|
503
589
|
assembly ("memory-safe") {
|
|
504
590
|
a := calldataload(abs)
|
|
505
591
|
b := calldataload(add(abs, 0x20))
|
|
506
|
-
c := calldataload(add(abs, 0x40))
|
|
507
|
-
d := calldataload(add(abs, 0x60))
|
|
508
592
|
}
|
|
593
|
+
cur.i += 64;
|
|
509
594
|
}
|
|
510
595
|
|
|
511
|
-
/// @notice
|
|
596
|
+
/// @notice Read the next three 32-byte words from the cursor and advance by 96 bytes.
|
|
512
597
|
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
513
|
-
/// @param
|
|
598
|
+
/// @param cur Cursor whose current position is advanced by 96 bytes.
|
|
514
599
|
/// @return a First loaded word.
|
|
515
600
|
/// @return b Second loaded word.
|
|
516
601
|
/// @return c Third loaded word.
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
function load160(uint abs) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e) {
|
|
602
|
+
function read96(Cur memory cur) internal pure returns (bytes32 a, bytes32 b, bytes32 c) {
|
|
603
|
+
uint abs = cur.offset + cur.i;
|
|
520
604
|
assembly ("memory-safe") {
|
|
521
605
|
a := calldataload(abs)
|
|
522
606
|
b := calldataload(add(abs, 0x20))
|
|
523
607
|
c := calldataload(add(abs, 0x40))
|
|
524
|
-
d := calldataload(add(abs, 0x60))
|
|
525
|
-
e := calldataload(add(abs, 0x80))
|
|
526
608
|
}
|
|
609
|
+
cur.i += 96;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/// @notice Consume the next 32-byte word and require it to match `expected`.
|
|
613
|
+
/// @dev Performs no bounds, key, length, or cursor checks beyond the value comparison.
|
|
614
|
+
/// @param cur Cursor whose current position is advanced by 32 bytes.
|
|
615
|
+
/// @param expected Required word value.
|
|
616
|
+
function require32(Cur memory cur, bytes32 expected) internal pure {
|
|
617
|
+
if (read32(cur) != expected) revert UnexpectedValue();
|
|
527
618
|
}
|
|
528
619
|
|
|
529
620
|
// -------------------------------------------------------------------------
|
|
@@ -538,17 +629,24 @@ library Cursors {
|
|
|
538
629
|
/// @param key Expected dynamic block key.
|
|
539
630
|
/// @return data Raw block payload bytes.
|
|
540
631
|
function unpackRaw(Cur memory cur, bytes4 key) internal pure returns (bytes calldata data) {
|
|
541
|
-
(uint abs, uint next) = expect(cur, cur.i, key, 0, 0);
|
|
632
|
+
(uint abs, uint next) = expect(cur, cur.i, 0, key, 0, 0);
|
|
542
633
|
data = msg.data[abs:cur.offset + next];
|
|
543
634
|
cur.i = next;
|
|
544
635
|
}
|
|
545
636
|
|
|
637
|
+
/// @notice Consume a reserved BYTES block and return its raw payload.
|
|
638
|
+
/// @param cur Cursor; advanced past the BYTES block.
|
|
639
|
+
/// @return data Raw BYTES payload.
|
|
640
|
+
function unpackBytes(Cur memory cur) internal pure returns (bytes calldata data) {
|
|
641
|
+
return unpackRaw(cur, Keys.Bytes);
|
|
642
|
+
}
|
|
643
|
+
|
|
546
644
|
/// @notice Consume a dynamic block with a single bytes32 payload.
|
|
547
645
|
/// @param cur Cursor; advanced past the block.
|
|
548
646
|
/// @param key Expected dynamic block key.
|
|
549
647
|
/// @return value Decoded bytes32.
|
|
550
648
|
function unpack32(Cur memory cur, bytes4 key) internal pure returns (bytes32 value) {
|
|
551
|
-
uint abs = consume(cur, key, 32, 32);
|
|
649
|
+
uint abs = consume(cur, 0, key, 32, 32);
|
|
552
650
|
value = bytes32(msg.data[abs:abs + 32]);
|
|
553
651
|
}
|
|
554
652
|
|
|
@@ -558,7 +656,7 @@ library Cursors {
|
|
|
558
656
|
/// @return a First decoded bytes32.
|
|
559
657
|
/// @return b Second decoded bytes32.
|
|
560
658
|
function unpack64(Cur memory cur, bytes4 key) internal pure returns (bytes32 a, bytes32 b) {
|
|
561
|
-
uint abs = consume(cur, key, 64, 64);
|
|
659
|
+
uint abs = consume(cur, 0, key, 64, 64);
|
|
562
660
|
a = bytes32(msg.data[abs:abs + 32]);
|
|
563
661
|
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
564
662
|
}
|
|
@@ -570,7 +668,7 @@ library Cursors {
|
|
|
570
668
|
/// @return b Second decoded bytes32.
|
|
571
669
|
/// @return c Third decoded bytes32.
|
|
572
670
|
function unpack96(Cur memory cur, bytes4 key) internal pure returns (bytes32 a, bytes32 b, bytes32 c) {
|
|
573
|
-
uint abs = consume(cur, key, 96, 96);
|
|
671
|
+
uint abs = consume(cur, 0, key, 96, 96);
|
|
574
672
|
a = bytes32(msg.data[abs:abs + 32]);
|
|
575
673
|
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
576
674
|
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -583,11 +681,8 @@ library Cursors {
|
|
|
583
681
|
/// @return b Second decoded bytes32.
|
|
584
682
|
/// @return c Third decoded bytes32.
|
|
585
683
|
/// @return d Fourth decoded bytes32.
|
|
586
|
-
function unpack128(
|
|
587
|
-
|
|
588
|
-
bytes4 key
|
|
589
|
-
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d) {
|
|
590
|
-
uint abs = consume(cur, key, 128, 128);
|
|
684
|
+
function unpack128(Cur memory cur, bytes4 key) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d) {
|
|
685
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
591
686
|
a = bytes32(msg.data[abs:abs + 32]);
|
|
592
687
|
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
593
688
|
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -606,7 +701,7 @@ library Cursors {
|
|
|
606
701
|
Cur memory cur,
|
|
607
702
|
bytes4 key
|
|
608
703
|
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e) {
|
|
609
|
-
uint abs = consume(cur, key, 160, 160);
|
|
704
|
+
uint abs = consume(cur, 0, key, 160, 160);
|
|
610
705
|
a = bytes32(msg.data[abs:abs + 32]);
|
|
611
706
|
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
612
707
|
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -614,102 +709,6 @@ library Cursors {
|
|
|
614
709
|
e = bytes32(msg.data[abs + 128:abs + 160]);
|
|
615
710
|
}
|
|
616
711
|
|
|
617
|
-
/// @notice Consume a dynamic block with a single uint payload.
|
|
618
|
-
/// @param cur Cursor; advanced past the block.
|
|
619
|
-
/// @param key Expected dynamic block key.
|
|
620
|
-
/// @return value Decoded uint value.
|
|
621
|
-
function unpackUint(Cur memory cur, bytes4 key) internal pure returns (uint value) {
|
|
622
|
-
value = uint(unpack32(cur, key));
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
/// @notice Consume a dynamic block with two uint payload words.
|
|
626
|
-
/// @param cur Cursor; advanced past the block.
|
|
627
|
-
/// @param key Expected dynamic block key.
|
|
628
|
-
/// @return a First decoded uint.
|
|
629
|
-
/// @return b Second decoded uint.
|
|
630
|
-
function unpack2Uint(Cur memory cur, bytes4 key) internal pure returns (uint a, uint b) {
|
|
631
|
-
(bytes32 x, bytes32 y) = unpack64(cur, key);
|
|
632
|
-
return (uint(x), uint(y));
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
/// @notice Consume a dynamic block with three uint payload words.
|
|
636
|
-
/// @param cur Cursor; advanced past the block.
|
|
637
|
-
/// @param key Expected dynamic block key.
|
|
638
|
-
/// @return a First decoded uint.
|
|
639
|
-
/// @return b Second decoded uint.
|
|
640
|
-
/// @return c Third decoded uint.
|
|
641
|
-
function unpack3Uint(Cur memory cur, bytes4 key) internal pure returns (uint a, uint b, uint c) {
|
|
642
|
-
(bytes32 x, bytes32 y, bytes32 z) = unpack96(cur, key);
|
|
643
|
-
return (uint(x), uint(y), uint(z));
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
// Generic fixed-head decoders
|
|
647
|
-
|
|
648
|
-
/// @notice Consume a dynamic block with a 32-byte fixed head followed by a variable-length tail.
|
|
649
|
-
/// @param cur Cursor; advanced past the block.
|
|
650
|
-
/// @param key Expected dynamic block key.
|
|
651
|
-
/// @return head Fixed 32-byte head.
|
|
652
|
-
/// @return tail Variable-length payload bytes after the fixed head.
|
|
653
|
-
function unpackHead32(Cur memory cur, bytes4 key) internal pure returns (bytes32 head, bytes calldata tail) {
|
|
654
|
-
uint abs = consume(cur, key, 32, 0);
|
|
655
|
-
head = bytes32(msg.data[abs:abs + 32]);
|
|
656
|
-
tail = msg.data[abs + 32:cur.offset + cur.i];
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
/// @notice Consume a dynamic block with a 64-byte fixed head followed by a variable-length tail.
|
|
660
|
-
/// @param cur Cursor; advanced past the block.
|
|
661
|
-
/// @param key Expected dynamic block key.
|
|
662
|
-
/// @return a First fixed head word.
|
|
663
|
-
/// @return b Second fixed head word.
|
|
664
|
-
/// @return tail Variable-length payload bytes after the fixed head.
|
|
665
|
-
function unpackHead64(
|
|
666
|
-
Cur memory cur,
|
|
667
|
-
bytes4 key
|
|
668
|
-
) internal pure returns (bytes32 a, bytes32 b, bytes calldata tail) {
|
|
669
|
-
uint abs = consume(cur, key, 64, 0);
|
|
670
|
-
a = bytes32(msg.data[abs:abs + 32]);
|
|
671
|
-
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
672
|
-
tail = msg.data[abs + 64:cur.offset + cur.i];
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
/// @notice Consume a dynamic block with a 96-byte fixed head followed by a variable-length tail.
|
|
676
|
-
/// @param cur Cursor; advanced past the block.
|
|
677
|
-
/// @param key Expected dynamic block key.
|
|
678
|
-
/// @return a First fixed head word.
|
|
679
|
-
/// @return b Second fixed head word.
|
|
680
|
-
/// @return c Third fixed head word.
|
|
681
|
-
/// @return tail Variable-length payload bytes after the fixed head.
|
|
682
|
-
function unpackHead96(
|
|
683
|
-
Cur memory cur,
|
|
684
|
-
bytes4 key
|
|
685
|
-
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes calldata tail) {
|
|
686
|
-
uint abs = consume(cur, key, 96, 0);
|
|
687
|
-
a = bytes32(msg.data[abs:abs + 32]);
|
|
688
|
-
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
689
|
-
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
690
|
-
tail = msg.data[abs + 96:cur.offset + cur.i];
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
/// @notice Consume a dynamic block with a 128-byte fixed head followed by a variable-length tail.
|
|
694
|
-
/// @param cur Cursor; advanced past the block.
|
|
695
|
-
/// @param key Expected dynamic block key.
|
|
696
|
-
/// @return a First fixed head word.
|
|
697
|
-
/// @return b Second fixed head word.
|
|
698
|
-
/// @return c Third fixed head word.
|
|
699
|
-
/// @return d Fourth fixed head word.
|
|
700
|
-
/// @return tail Variable-length payload bytes after the fixed head.
|
|
701
|
-
function unpackHead128(
|
|
702
|
-
Cur memory cur,
|
|
703
|
-
bytes4 key
|
|
704
|
-
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes calldata tail) {
|
|
705
|
-
uint abs = consume(cur, key, 128, 0);
|
|
706
|
-
a = bytes32(msg.data[abs:abs + 32]);
|
|
707
|
-
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
708
|
-
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
709
|
-
d = bytes32(msg.data[abs + 96:abs + 128]);
|
|
710
|
-
tail = msg.data[abs + 128:cur.offset + cur.i];
|
|
711
|
-
}
|
|
712
|
-
|
|
713
712
|
// Generic typed-shape decoders
|
|
714
713
|
|
|
715
714
|
/// @notice Consume a fixed-size asset amount block and return asset, meta, and amount.
|
|
@@ -722,7 +721,7 @@ library Cursors {
|
|
|
722
721
|
Cur memory cur,
|
|
723
722
|
bytes4 key
|
|
724
723
|
) internal pure returns (bytes32 asset, bytes32 meta, uint amount) {
|
|
725
|
-
uint abs = consume(cur, key, 96, 96);
|
|
724
|
+
uint abs = consume(cur, 0, key, 96, 96);
|
|
726
725
|
asset = bytes32(msg.data[abs:abs + 32]);
|
|
727
726
|
meta = bytes32(msg.data[abs + 32:abs + 64]);
|
|
728
727
|
amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
@@ -739,7 +738,7 @@ library Cursors {
|
|
|
739
738
|
Cur memory cur,
|
|
740
739
|
bytes4 key
|
|
741
740
|
) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta, uint amount) {
|
|
742
|
-
uint abs = consume(cur, key, 128, 128);
|
|
741
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
743
742
|
account = bytes32(msg.data[abs:abs + 32]);
|
|
744
743
|
asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
745
744
|
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -757,7 +756,7 @@ library Cursors {
|
|
|
757
756
|
Cur memory cur,
|
|
758
757
|
bytes4 key
|
|
759
758
|
) internal pure returns (uint host, bytes32 asset, bytes32 meta, uint amount) {
|
|
760
|
-
uint abs = consume(cur, key, 128, 128);
|
|
759
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
761
760
|
host = uint(bytes32(msg.data[abs:abs + 32]));
|
|
762
761
|
asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
763
762
|
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -775,7 +774,7 @@ library Cursors {
|
|
|
775
774
|
Cur memory cur,
|
|
776
775
|
bytes4 key
|
|
777
776
|
) internal pure returns (uint host, bytes32 account, bytes32 asset, bytes32 meta) {
|
|
778
|
-
uint abs = consume(cur, key, 128, 128);
|
|
777
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
779
778
|
host = uint(bytes32(msg.data[abs:abs + 32]));
|
|
780
779
|
account = bytes32(msg.data[abs + 32:abs + 64]);
|
|
781
780
|
asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -794,7 +793,7 @@ library Cursors {
|
|
|
794
793
|
Cur memory cur,
|
|
795
794
|
bytes4 key
|
|
796
795
|
) internal pure returns (bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount) {
|
|
797
|
-
uint abs = consume(cur, key, 160, 160);
|
|
796
|
+
uint abs = consume(cur, 0, key, 160, 160);
|
|
798
797
|
from = bytes32(msg.data[abs:abs + 32]);
|
|
799
798
|
to = bytes32(msg.data[abs + 32:abs + 64]);
|
|
800
799
|
asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -818,20 +817,6 @@ library Cursors {
|
|
|
818
817
|
node = uint(unpack32(cur, Keys.Node));
|
|
819
818
|
}
|
|
820
819
|
|
|
821
|
-
/// @notice Consume a RATE block and return the value.
|
|
822
|
-
/// @param cur Cursor; advanced past the block.
|
|
823
|
-
/// @return value Encoded ratio or rate.
|
|
824
|
-
function unpackRate(Cur memory cur) internal pure returns (uint value) {
|
|
825
|
-
value = uint(unpack32(cur, Keys.Rate));
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
/// @notice Consume a QUANTITY block and return the amount.
|
|
829
|
-
/// @param cur Cursor; advanced past the block.
|
|
830
|
-
/// @return amount Scalar quantity value.
|
|
831
|
-
function unpackQuantity(Cur memory cur) internal pure returns (uint amount) {
|
|
832
|
-
amount = uint(unpack32(cur, Keys.Quantity));
|
|
833
|
-
}
|
|
834
|
-
|
|
835
820
|
/// @notice Consume a FEE block and return the amount.
|
|
836
821
|
/// @param cur Cursor; advanced past the block.
|
|
837
822
|
/// @return amount Fee amount.
|
|
@@ -853,7 +838,7 @@ library Cursors {
|
|
|
853
838
|
/// @return asset Asset identifier.
|
|
854
839
|
/// @return meta Asset metadata slot.
|
|
855
840
|
function unpackAccountAsset(Cur memory cur) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta) {
|
|
856
|
-
uint abs = consume(cur, Keys.AccountAsset, 96, 96);
|
|
841
|
+
uint abs = consume(cur, 0, Keys.AccountAsset, 96, 96);
|
|
857
842
|
account = bytes32(msg.data[abs:abs + 32]);
|
|
858
843
|
asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
859
844
|
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -876,18 +861,6 @@ library Cursors {
|
|
|
876
861
|
relayer = y;
|
|
877
862
|
}
|
|
878
863
|
|
|
879
|
-
/// @notice Consume a BOUNDS block and return the signed min and max values.
|
|
880
|
-
/// @param cur Cursor; advanced past the block.
|
|
881
|
-
/// @return min Lower signed bound.
|
|
882
|
-
/// @return max Upper signed bound.
|
|
883
|
-
function unpackBounds(Cur memory cur) internal pure returns (int min, int max) {
|
|
884
|
-
uint abs = consume(cur, Keys.Bounds, 64, 64);
|
|
885
|
-
assembly ("memory-safe") {
|
|
886
|
-
min := calldataload(abs)
|
|
887
|
-
max := calldataload(add(abs, 0x20))
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
|
|
891
864
|
/// @notice Consume an AMOUNT block and return its fields as separate values.
|
|
892
865
|
/// @param cur Cursor; advanced past the block.
|
|
893
866
|
/// @return asset Asset identifier.
|
|
@@ -1053,9 +1026,7 @@ library Cursors {
|
|
|
1053
1026
|
/// @return asset Asset identifier.
|
|
1054
1027
|
/// @return meta Asset metadata slot.
|
|
1055
1028
|
/// @return amount Token amount.
|
|
1056
|
-
function unpackCustody(
|
|
1057
|
-
Cur memory cur
|
|
1058
|
-
) internal pure returns (uint host, bytes32 asset, bytes32 meta, uint amount) {
|
|
1029
|
+
function unpackCustody(Cur memory cur) internal pure returns (uint host, bytes32 asset, bytes32 meta, uint amount) {
|
|
1059
1030
|
return unpackHostAmount(cur, Keys.Custody);
|
|
1060
1031
|
}
|
|
1061
1032
|
|
|
@@ -1089,25 +1060,49 @@ library Cursors {
|
|
|
1089
1060
|
// Type-specific dynamic decoders
|
|
1090
1061
|
|
|
1091
1062
|
/// @notice Consume a STEP block and return its sub-command invocation fields.
|
|
1092
|
-
/// The `req` slice
|
|
1063
|
+
/// The `req` slice is the raw payload of the block's required BYTES child.
|
|
1093
1064
|
/// @param cur Cursor; advanced past the block.
|
|
1094
1065
|
/// @return target Destination node ID for the sub-command.
|
|
1095
1066
|
/// @return value Native value to forward with the call.
|
|
1096
1067
|
/// @return req Embedded request bytes for the sub-command.
|
|
1097
1068
|
function unpackStep(Cur memory cur) internal pure returns (uint target, uint value, bytes calldata req) {
|
|
1098
|
-
|
|
1099
|
-
|
|
1069
|
+
uint end = cur.enter(Keys.Step, 64 + Sizes.Header, 0);
|
|
1070
|
+
target = uint(cur.read32());
|
|
1071
|
+
value = uint(cur.read32());
|
|
1072
|
+
req = cur.unpackBytes();
|
|
1073
|
+
cur.exit(end);
|
|
1100
1074
|
}
|
|
1101
1075
|
|
|
1102
1076
|
/// @notice Consume a CALL block and return its target invocation fields.
|
|
1103
|
-
/// The `data` slice
|
|
1077
|
+
/// The `data` slice is the raw payload of the block's required BYTES child.
|
|
1104
1078
|
/// @param cur Cursor; advanced past the block.
|
|
1105
1079
|
/// @return target Target node ID to call.
|
|
1106
1080
|
/// @return value Native value to forward with the call.
|
|
1107
1081
|
/// @return data Raw calldata payload for the target.
|
|
1108
1082
|
function unpackCall(Cur memory cur) internal pure returns (uint target, uint value, bytes calldata data) {
|
|
1109
|
-
|
|
1110
|
-
|
|
1083
|
+
uint end = cur.enter(Keys.Call, 64 + Sizes.Header, 0);
|
|
1084
|
+
target = uint(cur.read32());
|
|
1085
|
+
value = uint(cur.read32());
|
|
1086
|
+
data = cur.unpackBytes();
|
|
1087
|
+
cur.exit(end);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/// @notice Consume a CONTEXT block and return its command context fields.
|
|
1091
|
+
/// The `state` and `request` slices are the raw payloads of the required BYTES children.
|
|
1092
|
+
/// @param cur Cursor; advanced past the block.
|
|
1093
|
+
/// @return account Command account identifier.
|
|
1094
|
+
/// @return value Native value budget assigned to the context.
|
|
1095
|
+
/// @return state Embedded state block stream.
|
|
1096
|
+
/// @return request Embedded request block stream.
|
|
1097
|
+
function unpackContext(
|
|
1098
|
+
Cur memory cur
|
|
1099
|
+
) internal pure returns (bytes32 account, uint value, bytes calldata state, bytes calldata request) {
|
|
1100
|
+
uint end = cur.enter(Keys.Context, 64 + 2 * Sizes.Header, 0);
|
|
1101
|
+
account = cur.read32();
|
|
1102
|
+
value = uint(cur.read32());
|
|
1103
|
+
state = cur.unpackBytes();
|
|
1104
|
+
request = cur.unpackBytes();
|
|
1105
|
+
cur.exit(end);
|
|
1111
1106
|
}
|
|
1112
1107
|
|
|
1113
1108
|
// Type-specific validators
|
|
@@ -1120,10 +1115,12 @@ library Cursors {
|
|
|
1120
1115
|
/// @return deadline Expiry timestamp.
|
|
1121
1116
|
/// @return proof Raw proof bytes (layout: `[bytes20 signer][bytes65 sig]`).
|
|
1122
1117
|
function expectAuth(Cur memory cur, uint i, uint cid) internal pure returns (uint deadline, bytes calldata proof) {
|
|
1123
|
-
(uint abs, uint next) = expect(cur, i, Keys.Auth,
|
|
1118
|
+
(uint abs, uint next) = expect(cur, i, 0, Keys.Auth, 64 + Sizes.Header + Sizes.Proof, 0);
|
|
1124
1119
|
if (uint(bytes32(msg.data[abs:abs + 32])) != cid) revert UnexpectedValue();
|
|
1125
1120
|
deadline = uint(bytes32(msg.data[abs + 32:abs + 64]));
|
|
1126
|
-
|
|
1121
|
+
|
|
1122
|
+
(abs, ) = expect(cur, i + Sizes.Header + 64, next, Keys.Bytes, Sizes.Proof, Sizes.Proof);
|
|
1123
|
+
proof = msg.data[abs:abs + Sizes.Proof];
|
|
1127
1124
|
}
|
|
1128
1125
|
|
|
1129
1126
|
// -------------------------------------------------------------------------
|
|
@@ -1141,7 +1138,7 @@ library Cursors {
|
|
|
1141
1138
|
bytes4 key,
|
|
1142
1139
|
bytes32 asset
|
|
1143
1140
|
) internal pure returns (bytes32 meta, uint amount) {
|
|
1144
|
-
uint abs = consume(cur, key, 96, 96);
|
|
1141
|
+
uint abs = consume(cur, 0, key, 96, 96);
|
|
1145
1142
|
if (bytes32(msg.data[abs:abs + 32]) != asset) revert UnexpectedValue();
|
|
1146
1143
|
meta = bytes32(msg.data[abs + 32:abs + 64]);
|
|
1147
1144
|
amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
@@ -1159,7 +1156,7 @@ library Cursors {
|
|
|
1159
1156
|
bytes32 asset,
|
|
1160
1157
|
bytes32 meta
|
|
1161
1158
|
) internal pure returns (uint amount) {
|
|
1162
|
-
uint abs = consume(cur, key, 96, 96);
|
|
1159
|
+
uint abs = consume(cur, 0, key, 96, 96);
|
|
1163
1160
|
if (bytes32(msg.data[abs:abs + 32]) != asset) revert UnexpectedValue();
|
|
1164
1161
|
if (bytes32(msg.data[abs + 32:abs + 64]) != meta) revert UnexpectedValue();
|
|
1165
1162
|
amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
@@ -1171,7 +1168,7 @@ library Cursors {
|
|
|
1171
1168
|
/// @param asset Expected asset identifier.
|
|
1172
1169
|
/// @return meta Metadata slot from the block.
|
|
1173
1170
|
function requireUnitAssetAmount(Cur memory cur, bytes4 key, bytes32 asset) internal pure returns (bytes32 meta) {
|
|
1174
|
-
uint abs = consume(cur, key, 96, 96);
|
|
1171
|
+
uint abs = consume(cur, 0, key, 96, 96);
|
|
1175
1172
|
if (bytes32(msg.data[abs:abs + 32]) != asset) revert UnexpectedValue();
|
|
1176
1173
|
meta = bytes32(msg.data[abs + 32:abs + 64]);
|
|
1177
1174
|
if (uint(bytes32(msg.data[abs + 64:abs + 96])) != 1) revert UnexpectedValue();
|
|
@@ -1198,7 +1195,7 @@ library Cursors {
|
|
|
1198
1195
|
bytes4 key,
|
|
1199
1196
|
uint host
|
|
1200
1197
|
) internal pure returns (bytes32 asset, bytes32 meta, uint amount) {
|
|
1201
|
-
uint abs = consume(cur, key, 128, 128);
|
|
1198
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
1202
1199
|
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1203
1200
|
asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
1204
1201
|
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -1218,7 +1215,7 @@ library Cursors {
|
|
|
1218
1215
|
uint host,
|
|
1219
1216
|
bytes32 asset
|
|
1220
1217
|
) internal pure returns (bytes32 meta, uint amount) {
|
|
1221
|
-
uint abs = consume(cur, key, 128, 128);
|
|
1218
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
1222
1219
|
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1223
1220
|
if (bytes32(msg.data[abs + 32:abs + 64]) != asset) revert UnexpectedValue();
|
|
1224
1221
|
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -1237,7 +1234,7 @@ library Cursors {
|
|
|
1237
1234
|
uint host,
|
|
1238
1235
|
bytes32 asset
|
|
1239
1236
|
) internal pure returns (bytes32 meta) {
|
|
1240
|
-
uint abs = consume(cur, key, 128, 128);
|
|
1237
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
1241
1238
|
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1242
1239
|
if (bytes32(msg.data[abs + 32:abs + 64]) != asset) revert UnexpectedValue();
|
|
1243
1240
|
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -1257,7 +1254,7 @@ library Cursors {
|
|
|
1257
1254
|
uint host,
|
|
1258
1255
|
bytes32 account
|
|
1259
1256
|
) internal pure returns (bytes32 asset, bytes32 meta) {
|
|
1260
|
-
uint abs = consume(cur, key, 128, 128);
|
|
1257
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
1261
1258
|
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1262
1259
|
if (bytes32(msg.data[abs + 32:abs + 64]) != account) revert UnexpectedValue();
|
|
1263
1260
|
asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -1276,7 +1273,7 @@ library Cursors {
|
|
|
1276
1273
|
bytes4 key,
|
|
1277
1274
|
uint host
|
|
1278
1275
|
) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta) {
|
|
1279
|
-
uint abs = consume(cur, key, 128, 128);
|
|
1276
|
+
uint abs = consume(cur, 0, key, 128, 128);
|
|
1280
1277
|
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1281
1278
|
account = bytes32(msg.data[abs + 32:abs + 64]);
|
|
1282
1279
|
asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
@@ -1303,7 +1300,7 @@ library Cursors {
|
|
|
1303
1300
|
/// @return proof Raw proof bytes.
|
|
1304
1301
|
function requireAuth(Cur memory cur, uint cid) internal pure returns (uint deadline, bytes calldata proof) {
|
|
1305
1302
|
(deadline, proof) = expectAuth(cur, cur.i, cid);
|
|
1306
|
-
cur.i += Sizes.
|
|
1303
|
+
cur.i += Sizes.Auth;
|
|
1307
1304
|
}
|
|
1308
1305
|
|
|
1309
1306
|
// -------------------------------------------------------------------------
|
|
@@ -1320,7 +1317,7 @@ library Cursors {
|
|
|
1320
1317
|
uint i = find(cur, 0, Keys.Node);
|
|
1321
1318
|
if (i == cur.len) return backup;
|
|
1322
1319
|
|
|
1323
|
-
(uint abs, ) = expect(cur, i, Keys.Node, 32, 32);
|
|
1320
|
+
(uint abs, ) = expect(cur, i, 0, Keys.Node, 32, 32);
|
|
1324
1321
|
return uint(bytes32(msg.data[abs:abs + 32]));
|
|
1325
1322
|
}
|
|
1326
1323
|
|
|
@@ -1344,7 +1341,7 @@ library Cursors {
|
|
|
1344
1341
|
uint i = find(cur, 0, Keys.Account);
|
|
1345
1342
|
if (i == cur.len) return backup;
|
|
1346
1343
|
|
|
1347
|
-
(uint abs, ) = expect(cur, i, Keys.Account, 32, 32);
|
|
1344
|
+
(uint abs, ) = expect(cur, i, 0, Keys.Account, 32, 32);
|
|
1348
1345
|
return bytes32(msg.data[abs:abs + 32]);
|
|
1349
1346
|
}
|
|
1350
1347
|
|
|
@@ -1357,7 +1354,7 @@ library Cursors {
|
|
|
1357
1354
|
uint i = find(cur, cur.bound, Keys.Node);
|
|
1358
1355
|
if (i == cur.len) return backup;
|
|
1359
1356
|
|
|
1360
|
-
(uint abs, ) = expect(cur, i, Keys.Node, 32, 32);
|
|
1357
|
+
(uint abs, ) = expect(cur, i, 0, Keys.Node, 32, 32);
|
|
1361
1358
|
return uint(bytes32(msg.data[abs:abs + 32]));
|
|
1362
1359
|
}
|
|
1363
1360
|
|
|
@@ -1370,7 +1367,7 @@ library Cursors {
|
|
|
1370
1367
|
uint i = find(cur, cur.bound, Keys.Account);
|
|
1371
1368
|
if (i == cur.len) return backup;
|
|
1372
1369
|
|
|
1373
|
-
(uint abs, ) = expect(cur, i, Keys.Account, 32, 32);
|
|
1370
|
+
(uint abs, ) = expect(cur, i, 0, Keys.Account, 32, 32);
|
|
1374
1371
|
return bytes32(msg.data[abs:abs + 32]);
|
|
1375
1372
|
}
|
|
1376
1373
|
|
|
@@ -1380,19 +1377,19 @@ library Cursors {
|
|
|
1380
1377
|
/// The signed slice covers from `cur.i` up to (but not including) the AUTH proof bytes.
|
|
1381
1378
|
/// @param cur Source cursor; `bound` marks the end of the primary data region.
|
|
1382
1379
|
/// @param cid Command ID that the signature must be bound to.
|
|
1383
|
-
/// @return
|
|
1380
|
+
/// @return digest keccak256 of the signed message slice.
|
|
1384
1381
|
/// @return deadline Expiry timestamp from the AUTH block.
|
|
1385
1382
|
/// @return proof Raw proof bytes (layout: `[bytes20 signer][bytes65 sig]`).
|
|
1386
1383
|
function authLast(
|
|
1387
1384
|
Cur memory cur,
|
|
1388
1385
|
uint cid
|
|
1389
|
-
) internal pure returns (bytes32
|
|
1386
|
+
) internal pure returns (bytes32 digest, uint deadline, bytes calldata proof) {
|
|
1390
1387
|
if (cur.len - cur.i < Sizes.Auth) revert MalformedBlocks();
|
|
1391
1388
|
|
|
1392
1389
|
uint i = cur.len - Sizes.Auth;
|
|
1393
1390
|
if (i < cur.bound) revert MalformedBlocks();
|
|
1394
1391
|
|
|
1395
1392
|
(deadline, proof) = expectAuth(cur, i, cid);
|
|
1396
|
-
|
|
1393
|
+
digest = cur.hash(cur.i, cur.len - Sizes.Proof);
|
|
1397
1394
|
}
|
|
1398
1395
|
}
|