@rootzero/contracts 1.5.0 → 1.7.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 +49 -0
- package/Core.sol +4 -2
- package/Endpoints.sol +14 -13
- package/Events.sol +3 -1
- package/README.md +9 -9
- package/blocks/Cursors.sol +60 -49
- package/blocks/Keys.sol +5 -5
- package/blocks/Schema.sol +4 -2
- package/blocks/Writers.sol +0 -35
- package/commands/Deposit.sol +2 -2
- package/commands/Provision.sol +2 -2
- package/commands/Recover.sol +48 -0
- package/commands/Relay.sol +4 -4
- package/commands/admin/AllowAssets.sol +2 -3
- package/commands/admin/Allowance.sol +2 -3
- package/commands/admin/Appoint.sol +2 -3
- package/commands/admin/Authorize.sol +2 -3
- package/commands/admin/Base.sol +9 -0
- package/commands/admin/DenyAssets.sol +2 -3
- package/commands/admin/Destroy.sol +2 -3
- package/commands/admin/Dismiss.sol +2 -3
- package/commands/admin/Execute.sol +3 -4
- package/commands/admin/Init.sol +2 -3
- package/commands/admin/Label.sol +2 -3
- package/commands/admin/Unauthorize.sol +2 -3
- package/core/Commitments.sol +19 -0
- package/core/Escrows.sol +34 -0
- package/core/Payable.sol +15 -28
- package/core/Pipeline.sol +1 -1
- package/core/Runtime.sol +8 -3
- package/docs/Schema.md +13 -2
- package/events/Commitment.sol +19 -0
- package/events/Dispatch.sol +20 -0
- package/events/Port.sol +22 -0
- package/package.json +1 -1
- package/ports/AllowAssets.sol +44 -0
- package/ports/Allowance.sol +41 -0
- package/ports/Base.sol +41 -0
- package/ports/Credit.sol +39 -0
- package/ports/Debit.sol +39 -0
- package/ports/DenyAssets.sol +44 -0
- package/{peer → ports}/Dispatch.sol +13 -13
- package/ports/Pipe.sol +43 -0
- package/{peer → ports}/Redeem.sol +13 -13
- package/ports/Settle.sol +41 -0
- package/utils/Layout.sol +3 -3
- package/utils/Nodes.sol +21 -21
- package/utils/Value.sol +12 -5
- package/events/Peer.sol +0 -22
- package/peer/AllowAssets.sol +0 -44
- package/peer/Allowance.sol +0 -41
- package/peer/Base.sol +0 -41
- package/peer/Credit.sol +0 -39
- package/peer/Debit.sol +0 -39
- package/peer/DenyAssets.sol +0 -44
- package/peer/Pipe.sol +0 -44
- package/peer/Recover.sol +0 -51
- package/peer/Settle.sol +0 -41
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,55 @@
|
|
|
3
3
|
Until the protocol reaches integration-stable status, minor versions may include
|
|
4
4
|
breaking API changes. Breaking changes are called out explicitly.
|
|
5
5
|
|
|
6
|
+
## 1.7.0
|
|
7
|
+
|
|
8
|
+
### Breaking Changes
|
|
9
|
+
|
|
10
|
+
- Renamed peer callable surfaces to ports:
|
|
11
|
+
- `contracts/peer` moved to `contracts/ports`.
|
|
12
|
+
- `PeerEvent` / `event Peer` became `PortEvent` / `event Port`.
|
|
13
|
+
- `PeerBase`, `IPeer*`, and `Peer*` endpoint contracts became `PortBase`,
|
|
14
|
+
`IPort*`, and `Port*`.
|
|
15
|
+
- Peer endpoint functions and labels now use `port*` names, such as
|
|
16
|
+
`portPipePayable`, `portDispatchPayable`, and `portSettle`.
|
|
17
|
+
- Node helpers and layout tags now use `Port` terminology:
|
|
18
|
+
`Nodes.toPort`, `Nodes.isPort`, `Nodes.port`, and
|
|
19
|
+
`Nodes.portSelector`.
|
|
20
|
+
- Removed the generic `PortRecoverContextPayable`; recovery is now routed by
|
|
21
|
+
the command-level `recoverContextPayable` to concrete ports such as
|
|
22
|
+
`portPipePayable`.
|
|
23
|
+
- Renamed the `#contextRecovery` handler field from `target` to `port`.
|
|
24
|
+
- Changed port entrypoint calldata parameter naming to `data` to avoid
|
|
25
|
+
clashing with nested context `request` fields.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- Added `RecoverContextPayable` and `#contextRecovery` for command-level
|
|
30
|
+
recovery routing with a commitment key, resources, handler port, and context
|
|
31
|
+
witness.
|
|
32
|
+
- Added `Dispatch(uint indexed host, uint chain, uint resources, bytes32 digest, bytes32 ref)`
|
|
33
|
+
as the discovery/event surface for dispatch tracking.
|
|
34
|
+
- Added `ContextRecovery` schema/cursor support and context schema aliases for
|
|
35
|
+
reusable nested block schemas.
|
|
36
|
+
- Added `Values.drain`, `Payable.openValue`, and `Payable.closeValue` to make
|
|
37
|
+
payable command budget lifecycles explicit.
|
|
38
|
+
|
|
39
|
+
## 1.6.0
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- Added `AdminBase` as the shared base for admin commands and exported it from
|
|
44
|
+
`Endpoints.sol`.
|
|
45
|
+
- Added `Cursors.read1` and `Cursors.read2` for unchecked byte-sized calldata
|
|
46
|
+
reads.
|
|
47
|
+
- Added `NativeAsset` as a reusable base for helpers that need the local native
|
|
48
|
+
asset ID without the full host runtime.
|
|
49
|
+
- Added `Escrows` as a keyed ledger for amounts reserved outside normal
|
|
50
|
+
balances.
|
|
51
|
+
- Added `Commitment(uint indexed host, bytes32 key, bytes32 digest, uint status)`
|
|
52
|
+
and the `Commitments` core mixin for digest commitments and witness/recovery
|
|
53
|
+
flows.
|
|
54
|
+
|
|
6
55
|
## 1.5.0
|
|
7
56
|
|
|
8
57
|
### Breaking Changes
|
package/Core.sol
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
// Aggregator: re-exports the core host, runtime, access, node-call, and validation layer.
|
|
4
|
+
// Aggregator: re-exports the core host, runtime, access, ledger, node-call, and validation layer.
|
|
5
5
|
// Import this file to bring the full rootzero host base layer into scope.
|
|
6
6
|
|
|
7
7
|
import { AccessControl } from "./core/Access.sol";
|
|
8
8
|
import { Balances, InsufficientFunds } from "./core/Balances.sol";
|
|
9
|
-
import {
|
|
9
|
+
import { Commitments } from "./core/Commitments.sol";
|
|
10
|
+
import { Escrows, InsufficientEscrow } from "./core/Escrows.sol";
|
|
11
|
+
import { NativeAsset, Runtime } from "./core/Runtime.sol";
|
|
10
12
|
import { Host, IHostIntroduction } from "./core/Host.sol";
|
|
11
13
|
import { FailedCall, NodeCalls } from "./core/Calls.sol";
|
|
12
14
|
import { Payable } from "./core/Payable.sol";
|
package/Endpoints.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
// Aggregator: re-exports command, admin,
|
|
4
|
+
// Aggregator: re-exports command, admin, port, guard, and query endpoint abstractions.
|
|
5
5
|
// Import this file to inherit from the full rootzero callable host surface without managing individual paths.
|
|
6
6
|
|
|
7
7
|
// Shared helpers
|
|
@@ -16,10 +16,12 @@ import { DebitAccount, DebitAccountHook } from "./commands/Debit.sol";
|
|
|
16
16
|
import { Deposit, DepositHook, DepositPayable, DepositPayableHook } from "./commands/Deposit.sol";
|
|
17
17
|
import { Payout, PayoutHook } from "./commands/Payout.sol";
|
|
18
18
|
import { Provision, ProvisionHook, ProvisionPayable, ProvisionPayableHook } from "./commands/Provision.sol";
|
|
19
|
+
import { RecoverContextPayable, RecoverContextPayableHook } from "./commands/Recover.sol";
|
|
19
20
|
import { RelayPayable, DispatchPayableHook } from "./commands/Relay.sol";
|
|
20
21
|
import { Withdraw, WithdrawHook } from "./commands/Withdraw.sol";
|
|
21
22
|
|
|
22
23
|
// Admin commands
|
|
24
|
+
import { AdminBase } from "./commands/admin/Base.sol";
|
|
23
25
|
import { AllowAssets, AllowAssetsHook } from "./commands/admin/AllowAssets.sol";
|
|
24
26
|
import { Allowance, AllowanceHook } from "./commands/admin/Allowance.sol";
|
|
25
27
|
import { Appoint } from "./commands/admin/Appoint.sol";
|
|
@@ -32,18 +34,17 @@ import { Init, InitHook } from "./commands/admin/Init.sol";
|
|
|
32
34
|
import { Label } from "./commands/admin/Label.sol";
|
|
33
35
|
import { Unauthorize } from "./commands/admin/Unauthorize.sol";
|
|
34
36
|
|
|
35
|
-
//
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import { PeerSettle, IPeerSettle } from "./peer/Settle.sol";
|
|
37
|
+
// Port endpoints
|
|
38
|
+
import { PortBase, encodePortCall } from "./ports/Base.sol";
|
|
39
|
+
import { PortAllowAssets, IPortAllowAssets } from "./ports/AllowAssets.sol";
|
|
40
|
+
import { PortAllowance, IPortAllowance } from "./ports/Allowance.sol";
|
|
41
|
+
import { PortRedeemBalance, RedeemBalanceHook, IPortRedeemBalance } from "./ports/Redeem.sol";
|
|
42
|
+
import { PortCreditAccount, IPortCreditAccount } from "./ports/Credit.sol";
|
|
43
|
+
import { PortDebitAccount, IPortDebitAccount } from "./ports/Debit.sol";
|
|
44
|
+
import { PortDenyAssets, IPortDenyAssets } from "./ports/DenyAssets.sol";
|
|
45
|
+
import { PortPipePayable, IPortPipePayable } from "./ports/Pipe.sol";
|
|
46
|
+
import { PortDispatchPayable, IPortDispatchPayable } from "./ports/Dispatch.sol";
|
|
47
|
+
import { PortSettle, IPortSettle } from "./ports/Settle.sol";
|
|
47
48
|
|
|
48
49
|
// Guard endpoints
|
|
49
50
|
import { GuardBase, encodeGuardCall } from "./guards/Base.sol";
|
package/Events.sol
CHANGED
|
@@ -10,6 +10,8 @@ import { Actions } from "./utils/Actions.sol";
|
|
|
10
10
|
import { BalanceEvent } from "./events/Balance.sol";
|
|
11
11
|
import { CommanderEvent } from "./events/Commander.sol";
|
|
12
12
|
import { CommandEvent } from "./events/Command.sol";
|
|
13
|
+
import { CommitmentEvent } from "./events/Commitment.sol";
|
|
14
|
+
import { DispatchEvent } from "./events/Dispatch.sol";
|
|
13
15
|
import { PositionEvent } from "./events/Position.sol";
|
|
14
16
|
import { ReceivedEvent } from "./events/Received.sol";
|
|
15
17
|
import { EventEmitter } from "./events/Emitter.sol";
|
|
@@ -19,7 +21,7 @@ import { IntroductionEvent } from "./events/Introduction.sol";
|
|
|
19
21
|
import { LabeledEvent } from "./events/Labeled.sol";
|
|
20
22
|
import { LockedEvent } from "./events/Locked.sol";
|
|
21
23
|
import { NodeEvent } from "./events/Node.sol";
|
|
22
|
-
import {
|
|
24
|
+
import { PortEvent } from "./events/Port.sol";
|
|
23
25
|
import { QueryEvent } from "./events/Query.sol";
|
|
24
26
|
import { RootedEvent } from "./events/Rooted.sol";
|
|
25
27
|
import { RouteEvent } from "./events/Route.sol";
|
package/README.md
CHANGED
|
@@ -271,8 +271,8 @@ blocks executed in order within one transaction:
|
|
|
271
271
|
|
|
272
272
|
Each step names a target command, the resources it may spend, and its request.
|
|
273
273
|
The state threads through: whatever one command returns becomes the input
|
|
274
|
-
state of the next, and the final state must be empty
|
|
275
|
-
|
|
274
|
+
state of the next, and the final state must be empty. This is the core of
|
|
275
|
+
`Pipeline.pipe`:
|
|
276
276
|
|
|
277
277
|
```solidity
|
|
278
278
|
while (input.i < input.len) {
|
|
@@ -304,19 +304,19 @@ response: #accountAmount { bytes32 account, bytes32 asset, uint amount }
|
|
|
304
304
|
Like commands, every query announces its request and response schemas at
|
|
305
305
|
deployment, so tooling knows how to call it without artifacts.
|
|
306
306
|
|
|
307
|
-
##
|
|
307
|
+
## Ports
|
|
308
308
|
|
|
309
|
-
|
|
309
|
+
Ports are the host-to-host surfaces, callable only by trusted peer hosts. The two
|
|
310
310
|
central ones are batches all the way down:
|
|
311
311
|
|
|
312
|
-
- `
|
|
312
|
+
- `portSettle` consumes `#transaction { bytes32 from, bytes32 to, bytes32 asset,
|
|
313
313
|
uint amount }` blocks, debiting `from` and crediting `to` per
|
|
314
314
|
block — how two hosts record settlement between their ledgers.
|
|
315
|
-
- `
|
|
315
|
+
- `portPipePayable` consumes `#context` blocks, each carrying an account, an
|
|
316
316
|
initial state, and a run of steps — a complete pipeline delivered by another
|
|
317
|
-
host, executed locally
|
|
317
|
+
host, executed locally against the peer call's shared value budget.
|
|
318
318
|
|
|
319
|
-
This is also the cross-chain mechanism. `relayPayable` (or `
|
|
319
|
+
This is also the cross-chain mechanism. `relayPayable` (or `portDispatchPayable`)
|
|
320
320
|
wraps a pipe and addresses it to a chain; a bridge adapter moves the **raw
|
|
321
321
|
bytes**; the destination host parses them with the same cursor rules and runs
|
|
322
322
|
the same pipeline loop. Nothing in the payload is EVM-specific — step targets
|
|
@@ -363,7 +363,7 @@ Repo layout:
|
|
|
363
363
|
|
|
364
364
|
- `contracts/core` — host, access control, balances, pipeline, validation
|
|
365
365
|
- `contracts/commands` — standard commands and admin commands
|
|
366
|
-
- `contracts/
|
|
366
|
+
- `contracts/ports` — peer surfaces for inter-host and cross-chain flows
|
|
367
367
|
- `contracts/guards` — guardian direct actions
|
|
368
368
|
- `contracts/queries` — read-only query endpoints
|
|
369
369
|
- `contracts/blocks` — block schema, cursor parsing, writers
|
package/blocks/Cursors.sol
CHANGED
|
@@ -548,28 +548,13 @@ library Cursors {
|
|
|
548
548
|
return createBlock(Keys.Context, bytes.concat(account, toBytesBlock(state), toBytesBlock(request)));
|
|
549
549
|
}
|
|
550
550
|
|
|
551
|
-
/// @notice Encode a PIPE block.
|
|
552
|
-
/// @param resources Chain resources assigned to the pipe.
|
|
553
|
-
/// @param account Command account identifier.
|
|
554
|
-
/// @param state Embedded state block stream.
|
|
555
|
-
/// @param steps Embedded step block stream.
|
|
556
|
-
/// @return Encoded PIPE block bytes.
|
|
557
|
-
function toPipeBlock(
|
|
558
|
-
uint resources,
|
|
559
|
-
bytes32 account,
|
|
560
|
-
bytes memory state,
|
|
561
|
-
bytes memory steps
|
|
562
|
-
) internal pure returns (bytes memory) {
|
|
563
|
-
return createBlock(Keys.Pipe, bytes.concat(bytes32(resources), toContextBlock(account, state, steps)));
|
|
564
|
-
}
|
|
565
|
-
|
|
566
551
|
/// @notice Encode a RELAY block.
|
|
567
552
|
/// @param chain Destination chain node ID.
|
|
568
|
-
/// @param resources Chain-adapter-specific resources for the destination
|
|
569
|
-
/// @param
|
|
553
|
+
/// @param resources Chain-adapter-specific resources for the destination context.
|
|
554
|
+
/// @param request Nested request block stream.
|
|
570
555
|
/// @return Encoded RELAY block bytes.
|
|
571
|
-
function toRelayBlock(uint chain, uint resources, bytes memory
|
|
572
|
-
return createBlock(Keys.Relay, bytes.concat(bytes32(chain), bytes32(resources), toBytesBlock(
|
|
556
|
+
function toRelayBlock(uint chain, uint resources, bytes memory request) internal pure returns (bytes memory) {
|
|
557
|
+
return createBlock(Keys.Relay, bytes.concat(bytes32(chain), bytes32(resources), toBytesBlock(request)));
|
|
573
558
|
}
|
|
574
559
|
|
|
575
560
|
/// @notice Encode a DISPATCH block.
|
|
@@ -599,6 +584,30 @@ library Cursors {
|
|
|
599
584
|
cur.i += n;
|
|
600
585
|
}
|
|
601
586
|
|
|
587
|
+
/// @notice Read the next byte from the cursor and advance by 1 byte.
|
|
588
|
+
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
589
|
+
/// @param cur Cursor whose current position is advanced by 1 byte.
|
|
590
|
+
/// @return value Loaded bytes1 value.
|
|
591
|
+
function read1(Cur memory cur) internal pure returns (bytes1 value) {
|
|
592
|
+
uint abs = cur.offset + cur.i;
|
|
593
|
+
assembly ("memory-safe") {
|
|
594
|
+
value := calldataload(abs)
|
|
595
|
+
}
|
|
596
|
+
cur.i += 1;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/// @notice Read the next 2 bytes from the cursor and advance by 2 bytes.
|
|
600
|
+
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
601
|
+
/// @param cur Cursor whose current position is advanced by 2 bytes.
|
|
602
|
+
/// @return value Loaded bytes2 value.
|
|
603
|
+
function read2(Cur memory cur) internal pure returns (bytes2 value) {
|
|
604
|
+
uint abs = cur.offset + cur.i;
|
|
605
|
+
assembly ("memory-safe") {
|
|
606
|
+
value := calldataload(abs)
|
|
607
|
+
}
|
|
608
|
+
cur.i += 2;
|
|
609
|
+
}
|
|
610
|
+
|
|
602
611
|
/// @notice Read the next 4 bytes from the cursor and advance by 4 bytes.
|
|
603
612
|
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
604
613
|
/// @param cur Cursor whose current position is advanced by 4 bytes.
|
|
@@ -1131,33 +1140,18 @@ library Cursors {
|
|
|
1131
1140
|
cur.exit(end);
|
|
1132
1141
|
}
|
|
1133
1142
|
|
|
1134
|
-
/// @notice Consume a
|
|
1135
|
-
/// @param cur Cursor; advanced past the block.
|
|
1136
|
-
/// @return resources Chain resources assigned to the pipe.
|
|
1137
|
-
/// @return account Command account identifier.
|
|
1138
|
-
/// @return state Embedded state block stream.
|
|
1139
|
-
/// @return steps Embedded step block stream.
|
|
1140
|
-
function unpackPipe(
|
|
1141
|
-
Cur memory cur
|
|
1142
|
-
) internal pure returns (uint resources, bytes32 account, bytes calldata state, bytes calldata steps) {
|
|
1143
|
-
uint end = cur.enter(Keys.Pipe, 32 + Sizes.Header + 32 + 2 * Sizes.Header, 0);
|
|
1144
|
-
resources = uint(cur.read32());
|
|
1145
|
-
(account, state, steps) = cur.unpackContext();
|
|
1146
|
-
cur.exit(end);
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
/// @notice Consume a RELAY block and return its destination chain, resources, and step stream.
|
|
1143
|
+
/// @notice Consume a RELAY block and return its destination chain, resources, and request stream.
|
|
1150
1144
|
/// @param cur Cursor; advanced past the block.
|
|
1151
1145
|
/// @return chain Destination chain node ID.
|
|
1152
|
-
/// @return resources Chain-adapter-specific resources for the destination
|
|
1153
|
-
/// @return
|
|
1146
|
+
/// @return resources Chain-adapter-specific resources for the destination context.
|
|
1147
|
+
/// @return request Embedded request block stream.
|
|
1154
1148
|
function unpackRelay(
|
|
1155
1149
|
Cur memory cur
|
|
1156
|
-
) internal pure returns (uint chain, uint resources, bytes calldata
|
|
1150
|
+
) internal pure returns (uint chain, uint resources, bytes calldata request) {
|
|
1157
1151
|
uint end = cur.enter(Keys.Relay, 64 + Sizes.Header, 0);
|
|
1158
1152
|
chain = cur.readUint();
|
|
1159
1153
|
resources = cur.readUint();
|
|
1160
|
-
|
|
1154
|
+
request = cur.unpackBytes();
|
|
1161
1155
|
cur.exit(end);
|
|
1162
1156
|
}
|
|
1163
1157
|
|
|
@@ -1176,6 +1170,23 @@ library Cursors {
|
|
|
1176
1170
|
cur.exit(end);
|
|
1177
1171
|
}
|
|
1178
1172
|
|
|
1173
|
+
/// @notice Consume a CONTEXT_RECOVERY block and return its port, key, resources, and embedded context cursor.
|
|
1174
|
+
/// @param cur Cursor; advanced past the block.
|
|
1175
|
+
/// @return port Recovery handler port node ID.
|
|
1176
|
+
/// @return key Commitment or recovery lookup key.
|
|
1177
|
+
/// @return resources Chain resources assigned to the recovery attempt.
|
|
1178
|
+
/// @return context Cursor scoped to the embedded CONTEXT witness block.
|
|
1179
|
+
function unpackContextRecovery(
|
|
1180
|
+
Cur memory cur
|
|
1181
|
+
) internal pure returns (uint port, bytes32 key, uint resources, Cur memory context) {
|
|
1182
|
+
uint end = cur.enter(Keys.ContextRecovery, 96 + Sizes.Header, 0);
|
|
1183
|
+
port = cur.readUint();
|
|
1184
|
+
key = cur.read32();
|
|
1185
|
+
resources = cur.readUint();
|
|
1186
|
+
context = cur.take(Keys.Context);
|
|
1187
|
+
cur.exit(end);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1179
1190
|
// Type-specific validators
|
|
1180
1191
|
|
|
1181
1192
|
/// @notice Validate an AUTH block at position `i` and extract deadline and proof.
|
|
@@ -1364,21 +1375,21 @@ library Cursors {
|
|
|
1364
1375
|
// Transform helpers
|
|
1365
1376
|
// -------------------------------------------------------------------------
|
|
1366
1377
|
|
|
1367
|
-
/// @notice Consume a RELAY block and encode its destination
|
|
1378
|
+
/// @notice Consume a RELAY block and encode its destination context payload.
|
|
1368
1379
|
/// @param cur Cursor; advanced past the RELAY block.
|
|
1369
|
-
/// @param account Account identifier to embed in the destination
|
|
1370
|
-
/// @param state State block stream to embed in the destination
|
|
1380
|
+
/// @param account Account identifier to embed in the destination context.
|
|
1381
|
+
/// @param state State block stream to embed in the destination context.
|
|
1371
1382
|
/// @return chain Destination chain node ID.
|
|
1372
|
-
/// @return resources Chain resources assigned to the destination
|
|
1373
|
-
/// @return
|
|
1374
|
-
function
|
|
1383
|
+
/// @return resources Chain resources assigned to the destination context.
|
|
1384
|
+
/// @return context Encoded CONTEXT block containing `account`, `state`, and relay request.
|
|
1385
|
+
function relayToContext(
|
|
1375
1386
|
Cur memory cur,
|
|
1376
1387
|
bytes32 account,
|
|
1377
1388
|
bytes calldata state
|
|
1378
|
-
) internal pure returns (uint chain, uint resources, bytes memory
|
|
1379
|
-
bytes calldata
|
|
1380
|
-
(chain, resources,
|
|
1381
|
-
|
|
1389
|
+
) internal pure returns (uint chain, uint resources, bytes memory context) {
|
|
1390
|
+
bytes calldata request;
|
|
1391
|
+
(chain, resources, request) = cur.unpackRelay();
|
|
1392
|
+
context = toContextBlock(account, bytes(state), bytes(request));
|
|
1382
1393
|
}
|
|
1383
1394
|
|
|
1384
1395
|
// -------------------------------------------------------------------------
|
package/blocks/Keys.sol
CHANGED
|
@@ -41,16 +41,16 @@ library Keys {
|
|
|
41
41
|
bytes4 constant Transaction = bytes4(keccak256("#transaction"));
|
|
42
42
|
/// @dev Sub-command invocation - (uint target, uint resources, #bytes as request)
|
|
43
43
|
bytes4 constant Step = bytes4(keccak256("#step"));
|
|
44
|
-
/// @dev Cross-chain
|
|
44
|
+
/// @dev Cross-chain relay request - (uint chain, uint resources, #bytes as request)
|
|
45
45
|
bytes4 constant Relay = bytes4(keccak256("#relay"));
|
|
46
|
+
/// @dev Command context transport - (bytes32 account, #bytes as state, #bytes as request)
|
|
47
|
+
bytes4 constant Context = bytes4(keccak256("#context"));
|
|
48
|
+
/// @dev Recoverable context witness - (uint port, bytes32 key, uint resources, #context)
|
|
49
|
+
bytes4 constant ContextRecovery = bytes4(keccak256("#contextRecovery"));
|
|
46
50
|
/// @dev Cross-chain encoded payload dispatch - (uint chain, uint resources, #bytes as payload)
|
|
47
51
|
bytes4 constant Dispatch = bytes4(keccak256("#dispatch"));
|
|
48
52
|
/// @dev Raw external call - (uint target, uint resources, #bytes as payload)
|
|
49
53
|
bytes4 constant Call = bytes4(keccak256("#call"));
|
|
50
|
-
/// @dev Command context transport - (bytes32 account, #bytes as state, #bytes as request)
|
|
51
|
-
bytes4 constant Context = bytes4(keccak256("#context"));
|
|
52
|
-
/// @dev Pipeline invocation - (uint resources, #context)
|
|
53
|
-
bytes4 constant Pipe = bytes4(keccak256("#pipe"));
|
|
54
54
|
/// @dev Authentication proof - (uint cid, uint deadline, #bytes as proof); must appear last in its segment
|
|
55
55
|
bytes4 constant Auth = bytes4(keccak256("#auth"));
|
|
56
56
|
/// @dev Asset descriptor without amount - (bytes32 asset)
|
package/blocks/Schema.sol
CHANGED
|
@@ -21,6 +21,8 @@ pragma solidity ^0.8.33;
|
|
|
21
21
|
// stable format everywhere. EVM resources use the low 128 bits as native value.
|
|
22
22
|
// - dotted field names and aliases, e.g. `dst.chain` or `#bytes as dst.payload`,
|
|
23
23
|
// are offchain projection metadata only and do not change runtime encoding
|
|
24
|
+
// - a child block without an inline body, e.g. `#context as witness`, may resolve
|
|
25
|
+
// to a known schema in the active schema context; unresolved aliases are invalid
|
|
24
26
|
// - fixed fields are packed in declaration order
|
|
25
27
|
// - blocks have fixed fields followed by a dynamic child-block tail
|
|
26
28
|
// - child block tails are embedded directly, without an extra stream wrapper
|
|
@@ -69,10 +71,10 @@ library Schemas {
|
|
|
69
71
|
string constant Allowance = "#allowance { uint host, bytes32 asset, uint amount }";
|
|
70
72
|
string constant Transaction = "#transaction { bytes32 from, bytes32 to, bytes32 asset, uint amount }";
|
|
71
73
|
string constant Context = "#context { bytes32 account, #bytes as state, #bytes as request }";
|
|
72
|
-
string constant
|
|
74
|
+
string constant ContextRecovery = "#contextRecovery { uint port, bytes32 key, uint resources, #context as witness }";
|
|
73
75
|
string constant Call = "#call { uint target, uint resources, #bytes as payload }";
|
|
74
76
|
string constant Step = "#step { uint target, uint resources, #bytes as request }";
|
|
75
|
-
string constant Relay = "#relay { uint chain, uint resources, #bytes as
|
|
77
|
+
string constant Relay = "#relay { uint chain, uint resources, #bytes as request }";
|
|
76
78
|
string constant Dispatch = "#dispatch { uint chain, uint resources, #bytes as payload }";
|
|
77
79
|
string constant Bounty = "#bounty { uint amount, bytes32 relayer }";
|
|
78
80
|
string constant Fee = "#fee { uint amount }";
|
package/blocks/Writers.sol
CHANGED
|
@@ -28,7 +28,6 @@ library Hints {
|
|
|
28
28
|
uint constant Step = 256;
|
|
29
29
|
uint constant Call = 256;
|
|
30
30
|
uint constant Context = 512;
|
|
31
|
-
uint constant Pipe = 608;
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
/// @title Writers
|
|
@@ -233,14 +232,6 @@ library Writers {
|
|
|
233
232
|
return allocFromHint(count, Hints.Context);
|
|
234
233
|
}
|
|
235
234
|
|
|
236
|
-
/// @notice Allocate a writer for `count` PIPE blocks using a per-block capacity hint.
|
|
237
|
-
/// @dev The backing buffer expands automatically if encoded pipes exceed the initial hint.
|
|
238
|
-
/// @param count Number of pipe blocks to allocate space for.
|
|
239
|
-
/// @return writer Allocated growable writer.
|
|
240
|
-
function allocPipes(uint count) internal pure returns (Writer memory writer) {
|
|
241
|
-
return allocFromHint(count, Hints.Pipe);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
235
|
// -------------------------------------------------------------------------
|
|
245
236
|
// Fixed-width write helpers
|
|
246
237
|
// -------------------------------------------------------------------------
|
|
@@ -905,32 +896,6 @@ library Writers {
|
|
|
905
896
|
appendBlock32BytesBytes(writer, Keys.Context, account, state, request);
|
|
906
897
|
}
|
|
907
898
|
|
|
908
|
-
/// @notice Append a PIPE block with a nested CONTEXT block.
|
|
909
|
-
/// @param writer Destination writer; `i` is advanced by the encoded PIPE block length.
|
|
910
|
-
/// @param resources Chain resources assigned to the pipe.
|
|
911
|
-
/// @param account Command account identifier.
|
|
912
|
-
/// @param state Raw nested state payload.
|
|
913
|
-
/// @param steps Raw nested step payload.
|
|
914
|
-
function appendPipe(
|
|
915
|
-
Writer memory writer,
|
|
916
|
-
uint resources,
|
|
917
|
-
bytes32 account,
|
|
918
|
-
bytes memory state,
|
|
919
|
-
bytes memory steps
|
|
920
|
-
) internal pure {
|
|
921
|
-
uint i = writer.i;
|
|
922
|
-
uint len = 64 + 3 * Sizes.Header + state.length + steps.length;
|
|
923
|
-
uint next = i + Sizes.Header + len;
|
|
924
|
-
i = reserve(writer, next, next);
|
|
925
|
-
|
|
926
|
-
uint p = writeHeader(writer.dst, i, Keys.Pipe, uint32(max32(len)));
|
|
927
|
-
assembly ("memory-safe") {
|
|
928
|
-
mstore(add(p, 0x08), resources)
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
writeBlock32BytesBytes(writer.dst, i + Sizes.Header + 32, Keys.Context, account, state, steps);
|
|
932
|
-
}
|
|
933
|
-
|
|
934
899
|
/// @notice Append a STATUS form block.
|
|
935
900
|
/// @param writer Destination writer; `i` is advanced by `Sizes.Status`.
|
|
936
901
|
/// @param code Status code to encode.
|
package/commands/Deposit.sol
CHANGED
|
@@ -81,7 +81,7 @@ abstract contract DepositPayable is CommandBase, Payable, DepositPayableHook {
|
|
|
81
81
|
) external payable onlyCommand returns (bytes memory) {
|
|
82
82
|
(Cur memory request, uint groups, ) = Cursors.init(c.request, 1);
|
|
83
83
|
Writer memory writer = Writers.allocBalances(groups);
|
|
84
|
-
Budget memory budget =
|
|
84
|
+
Budget memory budget = openValue();
|
|
85
85
|
|
|
86
86
|
while (request.i < request.len) {
|
|
87
87
|
(bytes32 asset, uint amount) = request.unpackAmount();
|
|
@@ -89,7 +89,7 @@ abstract contract DepositPayable is CommandBase, Payable, DepositPayableHook {
|
|
|
89
89
|
writer.appendBalance(asset, amount);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
closeValue(c.account, budget);
|
|
93
93
|
request.complete();
|
|
94
94
|
return writer.finish();
|
|
95
95
|
}
|
package/commands/Provision.sol
CHANGED
|
@@ -78,7 +78,7 @@ abstract contract ProvisionPayable is CommandBase, Payable, ProvisionPayableHook
|
|
|
78
78
|
) external payable onlyCommand returns (bytes memory) {
|
|
79
79
|
(Cur memory request, uint groups, ) = Cursors.init(c.request, 1);
|
|
80
80
|
Writer memory writer = Writers.allocCustodies(groups);
|
|
81
|
-
Budget memory budget =
|
|
81
|
+
Budget memory budget = openValue();
|
|
82
82
|
|
|
83
83
|
while (request.i < request.len) {
|
|
84
84
|
HostAmount memory allocation = request.unpackAllocationValue();
|
|
@@ -86,7 +86,7 @@ abstract contract ProvisionPayable is CommandBase, Payable, ProvisionPayableHook
|
|
|
86
86
|
writer.appendCustody(allocation);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
closeValue(c.account, budget);
|
|
90
90
|
request.complete();
|
|
91
91
|
return writer.finish();
|
|
92
92
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {CommandBase, CommandContext, Keys} from "./Base.sol";
|
|
5
|
+
import {Payable} from "../core/Payable.sol";
|
|
6
|
+
import {Cursors, Cur, Schemas} from "../Cursors.sol";
|
|
7
|
+
import {Budget} from "../utils/Value.sol";
|
|
8
|
+
|
|
9
|
+
using Cursors for Cur;
|
|
10
|
+
|
|
11
|
+
abstract contract RecoverContextPayableHook {
|
|
12
|
+
/// @notice Override to recover one committed context witness.
|
|
13
|
+
/// @param port Recovery handler port node ID.
|
|
14
|
+
/// @param key Commitment or recovery lookup key.
|
|
15
|
+
/// @param resources Chain resources assigned to the recovery attempt.
|
|
16
|
+
/// @param context Cursor scoped to the embedded CONTEXT witness block.
|
|
17
|
+
/// @param budget Mutable native-value budget available to the recovery attempt.
|
|
18
|
+
function recoverContext(uint port, bytes32 key, uint resources, Cur memory context, Budget memory budget) internal virtual;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// @title RecoverContextPayable
|
|
22
|
+
/// @notice Command that forwards ContextRecovery request blocks to a virtual hook.
|
|
23
|
+
/// Produces no output state.
|
|
24
|
+
abstract contract RecoverContextPayable is CommandBase, Payable, RecoverContextPayableHook {
|
|
25
|
+
uint internal immutable recoverContextPayableId = commandId(this.recoverContextPayable.selector);
|
|
26
|
+
|
|
27
|
+
constructor() {
|
|
28
|
+
emit Command(host, recoverContextPayableId, "1:0:0", Schemas.ContextRecovery, Keys.Empty, Keys.Empty, true);
|
|
29
|
+
emit Labeled(recoverContextPayableId, bytes32(0), "recoverContextPayable");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// @notice Recover each ContextRecovery block in the command request.
|
|
33
|
+
/// @param c Command context; `c.request` must contain ContextRecovery blocks.
|
|
34
|
+
/// @return Empty output state.
|
|
35
|
+
function recoverContextPayable(CommandContext calldata c) external payable onlyCommand returns (bytes memory) {
|
|
36
|
+
(Cur memory request, , ) = Cursors.init(c.request, 1);
|
|
37
|
+
Budget memory budget = openValue();
|
|
38
|
+
|
|
39
|
+
while (request.i < request.len) {
|
|
40
|
+
(uint port, bytes32 key, uint resources, Cur memory context) = request.unpackContextRecovery();
|
|
41
|
+
recoverContext(port, key, resources, context, budget);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
closeValue(c.account, budget);
|
|
45
|
+
request.complete();
|
|
46
|
+
return "";
|
|
47
|
+
}
|
|
48
|
+
}
|
package/commands/Relay.sol
CHANGED
|
@@ -37,12 +37,12 @@ abstract contract RelayPayable is CommandBase, Payable, DispatchPayableHook {
|
|
|
37
37
|
/// @return output Empty output state.
|
|
38
38
|
function relayPayable(CommandContext calldata c) external payable onlyCommand returns (bytes memory output) {
|
|
39
39
|
(Cur memory request, ) = Cursors.init(c.request, 1, 1);
|
|
40
|
-
Budget memory budget =
|
|
40
|
+
Budget memory budget = openValue();
|
|
41
41
|
|
|
42
|
-
(uint chain, uint resources, bytes memory
|
|
43
|
-
dispatch(chain, resources,
|
|
42
|
+
(uint chain, uint resources, bytes memory context) = request.relayToContext(c.account, c.state);
|
|
43
|
+
dispatch(chain, resources, context, budget);
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
closeValue(c.account, budget);
|
|
46
46
|
request.complete();
|
|
47
47
|
return "";
|
|
48
48
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { AdminBase, CommandContext, Keys } from "./Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
|
-
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
6
|
using Cursors for Cur;
|
|
8
7
|
|
|
9
8
|
abstract contract AllowAssetsHook {
|
|
@@ -16,7 +15,7 @@ abstract contract AllowAssetsHook {
|
|
|
16
15
|
/// @title AllowAssets
|
|
17
16
|
/// @notice Admin command that permits a list of assets via a virtual hook.
|
|
18
17
|
/// Each ASSET block in the request calls `allowAsset`. Only callable by the admin account.
|
|
19
|
-
abstract contract AllowAssets is
|
|
18
|
+
abstract contract AllowAssets is AdminBase, AllowAssetsHook {
|
|
20
19
|
uint internal immutable allowAssetsId = commandId(this.allowAssets.selector);
|
|
21
20
|
|
|
22
21
|
constructor() {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {AdminBase, CommandContext, Keys} from "./Base.sol";
|
|
5
5
|
import {Cursors, Cur, Schemas} from "../../Cursors.sol";
|
|
6
|
-
import {AdminEvent} from "../../events/Admin.sol";
|
|
7
6
|
using Cursors for Cur;
|
|
8
7
|
|
|
9
8
|
abstract contract AllowanceHook {
|
|
@@ -20,7 +19,7 @@ abstract contract AllowanceHook {
|
|
|
20
19
|
/// @title Allowance
|
|
21
20
|
/// @notice Admin command that applies cross-host allowance entries via a virtual hook.
|
|
22
21
|
/// Each ALLOWANCE block grants or updates a host-scoped asset cap. Only callable by the admin account.
|
|
23
|
-
abstract contract Allowance is
|
|
22
|
+
abstract contract Allowance is AdminBase, AllowanceHook {
|
|
24
23
|
uint internal immutable allowanceId = commandId(this.allowance.selector);
|
|
25
24
|
|
|
26
25
|
constructor() {
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { AdminBase, CommandContext, Keys } from "./Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
|
-
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
6
|
using Cursors for Cur;
|
|
8
7
|
|
|
9
8
|
/// @title Appoint
|
|
10
9
|
/// @notice Admin command that grants guardian status to a list of account IDs.
|
|
11
10
|
/// Each ACCOUNT block in the request is enabled as a guardian on the host.
|
|
12
11
|
/// Only callable by the admin account.
|
|
13
|
-
abstract contract Appoint is
|
|
12
|
+
abstract contract Appoint is AdminBase {
|
|
14
13
|
uint internal immutable appointId = commandId(this.appoint.selector);
|
|
15
14
|
|
|
16
15
|
constructor() {
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { AdminBase, CommandContext, Keys } from "./Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
|
-
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
6
|
using Cursors for Cur;
|
|
8
7
|
|
|
9
8
|
/// @title Authorize
|
|
10
9
|
/// @notice Admin command that grants authorization to a list of node IDs.
|
|
11
10
|
/// Each NODE block in the request is authorized on the host.
|
|
12
11
|
/// Only callable by the admin account.
|
|
13
|
-
abstract contract Authorize is
|
|
12
|
+
abstract contract Authorize is AdminBase {
|
|
14
13
|
uint internal immutable authorizeId = commandId(this.authorize.selector);
|
|
15
14
|
|
|
16
15
|
constructor() {
|