@rootzero/contracts 1.13.0 → 1.14.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +45 -3
  2. package/Codec.sol +21 -0
  3. package/Commands.sol +14 -0
  4. package/Core.sol +2 -3
  5. package/Endpoints.sol +1 -5
  6. package/README.md +34 -30
  7. package/Utils.sol +2 -4
  8. package/codec/Blocks.sol +1606 -0
  9. package/codec/Buffers.sol +165 -0
  10. package/codec/Decoders.sol +558 -0
  11. package/codec/Descriptors.sol +124 -0
  12. package/{blocks → codec}/Keys.sol +4 -16
  13. package/codec/Readers.sol +114 -0
  14. package/{blocks → codec}/Schema.sol +38 -80
  15. package/codec/Specs.sol +218 -0
  16. package/codec/Writers.sol +487 -0
  17. package/commands/Allocate.sol +21 -20
  18. package/commands/Base.sol +71 -37
  19. package/commands/Burn.sol +18 -13
  20. package/commands/Credit.sol +21 -20
  21. package/commands/Debit.sol +25 -28
  22. package/commands/Deposit.sol +34 -35
  23. package/commands/Payout.sol +21 -15
  24. package/commands/Provision.sol +37 -38
  25. package/commands/Recover.sol +20 -19
  26. package/commands/Relay.sol +24 -22
  27. package/commands/Withdraw.sol +15 -18
  28. package/commands/admin/AllowAssets.sol +19 -16
  29. package/commands/admin/Allowance.sol +18 -13
  30. package/commands/admin/Appoint.sol +17 -15
  31. package/commands/admin/Authorize.sol +23 -14
  32. package/commands/admin/Base.sol +1 -1
  33. package/commands/admin/DenyAssets.sol +19 -16
  34. package/commands/admin/Dismiss.sol +17 -15
  35. package/commands/admin/Execute.sol +20 -19
  36. package/commands/admin/Label.sol +17 -13
  37. package/commands/admin/Schemas.sol +18 -14
  38. package/commands/admin/Unauthorize.sol +23 -14
  39. package/core/Calls.sol +3 -11
  40. package/core/Endpoint.sol +42 -127
  41. package/core/Pipeline.sol +16 -15
  42. package/core/Types.sol +1 -1
  43. package/docs/Schema.md +35 -29
  44. package/events/Endpoint.sol +2 -2
  45. package/events/Schema.sol +5 -5
  46. package/execution/Budget.sol +40 -0
  47. package/execution/Execution.sol +1083 -0
  48. package/guards/Base.sol +8 -9
  49. package/guards/Revoke.sol +11 -9
  50. package/package.json +1 -1
  51. package/ports/AllowAssets.sol +12 -15
  52. package/ports/Allowance.sol +11 -9
  53. package/ports/Base.sol +18 -11
  54. package/ports/Credit.sol +11 -9
  55. package/ports/Debit.sol +11 -9
  56. package/ports/DenyAssets.sol +10 -13
  57. package/ports/Dispatch.sol +13 -15
  58. package/ports/Pipe.sol +14 -12
  59. package/ports/Redeem.sol +12 -9
  60. package/ports/Settle.sol +11 -9
  61. package/queries/Assets.sol +15 -15
  62. package/queries/Balances.sol +17 -17
  63. package/queries/Base.sol +11 -12
  64. package/utils/Actions.sol +1 -0
  65. package/utils/Cursors.sol +308 -0
  66. package/utils/Lanes.sol +14 -0
  67. package/utils/Selectors.sol +2 -2
  68. package/utils/Utils.sol +46 -0
  69. package/Cursors.sol +0 -16
  70. package/blocks/Cursors.sol +0 -1529
  71. package/blocks/Writers.sol +0 -1036
  72. package/core/Payable.sol +0 -53
  73. package/utils/Value.sol +0 -43
package/guards/Base.sol CHANGED
@@ -3,6 +3,7 @@ pragma solidity ^0.8.33;
3
3
 
4
4
  import {AccessControl} from "../core/Access.sol";
5
5
  import {EndpointBase} from "../core/Endpoint.sol";
6
+ import {Specs} from "../codec/Specs.sol";
6
7
  import {Nodes} from "../utils/Nodes.sol";
7
8
  import {Selectors} from "../utils/Selectors.sol";
8
9
 
@@ -17,18 +18,16 @@ abstract contract GuardBase is AccessControl, EndpointBase {
17
18
  }
18
19
 
19
20
  /// @notice Publish guard metadata and a default label.
20
- /// @param name Default human-readable guard label and selector name.
21
- /// @param input Packed input lane plus optional group byte.
22
- /// @param selector Guard ABI selector, or zero to derive it from `name`.
21
+ /// @param name Guard entrypoint name and default label. It must exactly
22
+ /// match the Solidity guard function name used by the canonical ABI.
23
+ /// @param input Input block specification.
23
24
  /// @return id Guard action node ID.
24
25
  /// @return descriptor Packed endpoint lane metadata and flags.
25
26
  function guard(
26
27
  string memory name,
27
- bytes9 input,
28
- bytes4 selector
29
- ) internal returns (uint id, bytes32 descriptor) {
30
- selector = selector == bytes4(0) ? Selectors.guard(name) : selector;
31
- id = Nodes.toGuard(selector, address(this));
32
- descriptor = endpoint(id, name, bytes9(0), input, bytes9(0), false, false);
28
+ uint input
29
+ ) internal returns (uint id, uint descriptor) {
30
+ id = Nodes.toGuard(Selectors.guard(name), address(this));
31
+ descriptor = endpoint(id, name, Specs.Empty, input, Specs.Empty, 0, 0);
33
32
  }
34
33
  }
package/guards/Revoke.sol CHANGED
@@ -2,25 +2,27 @@
2
2
  pragma solidity ^0.8.33;
3
3
 
4
4
  import {GuardBase} from "./Base.sol";
5
- import {Cursors, Cur, Keys} from "../Cursors.sol";
6
- using Cursors for Cur;
5
+ import {Specs} from "../Codec.sol";
6
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
7
+ using Executions for Execution;
7
8
 
8
9
  /// @title Revoke
9
10
  /// @notice Guardian action that quickly revokes authorization from a list of node IDs.
10
- /// Each NODE block in the request is deauthorized on the host.
11
+ /// Each NODE block in the input is deauthorized on the host.
11
12
  /// Only callable by active guardian addresses.
12
13
  abstract contract Revoke is GuardBase {
13
- bytes32 private immutable descriptor;
14
+ uint private immutable descriptor;
14
15
 
15
16
  constructor() {
16
- (, descriptor) = guard("revoke", Keys.Node, 0);
17
+ (, descriptor) = guard("revoke", Specs.Node);
17
18
  }
18
19
 
19
- function revoke(bytes calldata request) external onlyGuardian {
20
- (Cur memory input, ) = openInput(request, descriptor);
20
+ /// @notice Revoke every NODE block in `input` as the active guardian.
21
+ function revoke(bytes calldata input) external onlyGuardian {
22
+ Execution memory exec = openInput(input, descriptor, 0);
21
23
 
22
- while (input.i < input.len) {
23
- uint node = input.unpackNode();
24
+ while (exec.more()) {
25
+ uint node = exec.unpackNode(Lanes.Input);
24
26
  setNode(node, false);
25
27
  }
26
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rootzero/contracts",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "description": "Solidity contracts and protocol building blocks for rootzero hosts and commands.",
5
5
  "private": false,
6
6
  "license": "GPL-3.0-only",
@@ -1,37 +1,34 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import { PortBase } from "./Base.sol";
5
- import { AllowAssetsHook } from "../commands/admin/AllowAssets.sol";
6
- import { Cursors, Cur, Keys } from "../Cursors.sol";
4
+ import {PortBase} from "./Base.sol";
5
+ import {AllowAssetsHook} from "../commands/admin/AllowAssets.sol";
6
+ import {Specs} from "../Codec.sol";
7
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
7
8
 
8
- using Cursors for Cur;
9
+ using Executions for Execution;
9
10
 
10
11
  /// @title PortAllowAssets
11
12
  /// @notice Port that permits a list of assets on behalf of a peer host.
12
- /// Each ASSET block in the request calls `allowAsset`. Restricted to trusted peers.
13
+ /// Each ASSET block in the input calls `allowAsset`. Restricted to trusted peers.
13
14
  abstract contract PortAllowAssets is PortBase, AllowAssetsHook {
14
- bytes32 private immutable descriptor;
15
+ uint private immutable descriptor;
15
16
 
16
17
  constructor() {
17
- (, descriptor) = port("portAllowAssets", Keys.Asset, Keys.Empty, 0, false);
18
+ (, descriptor) = port("portAllowAssets", Specs.Asset, Specs.Empty, false);
18
19
  }
19
20
 
20
21
  /// @notice Execute the allow-assets peer call.
21
22
  /// @param data ASSET block stream supplied by the trusted peer.
22
23
  /// @return Empty response bytes.
23
24
  function portAllowAssets(bytes calldata data) external onlyPeer returns (bytes memory) {
24
- (Cur memory input, ) = openInput(data, descriptor);
25
+ Execution memory exec = openInput(data, descriptor, 0);
25
26
 
26
- while (input.i < input.len) {
27
- bytes32 asset = input.unpackAsset();
27
+ while (exec.more()) {
28
+ bytes32 asset = exec.unpackAsset(Lanes.Input);
28
29
  allowAsset(asset);
29
30
  }
31
+
30
32
  return "";
31
33
  }
32
34
  }
33
-
34
-
35
-
36
-
37
-
@@ -3,32 +3,34 @@ pragma solidity ^0.8.33;
3
3
 
4
4
  import {PortBase} from "./Base.sol";
5
5
  import {AllowanceHook} from "../commands/admin/Allowance.sol";
6
- import {Cursors, Cur, Keys} from "../Cursors.sol";
6
+ import {Specs} from "../Codec.sol";
7
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
7
8
 
8
- using Cursors for Cur;
9
+ using Executions for Execution;
9
10
 
10
11
  /// @title PortAllowance
11
- /// @notice Port that lets a trusted peer host request or refresh its own allowance.
12
- /// Each AMOUNT block in the request is scoped to the peer host and passed to the
12
+ /// @notice Port that lets a trusted peer host input or refresh its own allowance.
13
+ /// Each AMOUNT block in the input is scoped to the peer host and passed to the
13
14
  /// shared allowance hook as a host-scoped allowance. Restricted to trusted peers.
14
15
  abstract contract PortAllowance is PortBase, AllowanceHook {
15
- bytes32 private immutable descriptor;
16
+ uint private immutable descriptor;
16
17
 
17
18
  constructor() {
18
- (, descriptor) = port("portAllowance", Keys.Amount, Keys.Empty, 0, false);
19
+ (, descriptor) = port("portAllowance", Specs.Amount, Specs.Empty, false);
19
20
  }
20
21
 
21
22
  /// @notice Execute the allowance port call.
22
23
  /// @param data AMOUNT block stream requested by the trusted peer.
23
24
  /// @return Empty response bytes.
24
25
  function portAllowance(bytes calldata data) external onlyPeer returns (bytes memory) {
25
- (Cur memory input, ) = openInput(data, descriptor);
26
+ Execution memory exec = openInput(data, descriptor, 0);
26
27
  uint peer = caller();
27
28
 
28
- while (input.i < input.len) {
29
- (bytes32 asset, uint amount) = input.unpackAmount();
29
+ while (exec.more()) {
30
+ (bytes32 asset, uint amount) = exec.unpackAmount(Lanes.Input);
30
31
  allowance(peer, asset, amount);
31
32
  }
33
+
32
34
  return "";
33
35
  }
34
36
  }
package/ports/Base.sol CHANGED
@@ -2,9 +2,11 @@
2
2
  pragma solidity ^0.8.33;
3
3
 
4
4
  import { NodeCalls } from "../core/Calls.sol";
5
+ import { Specs } from "../codec/Specs.sol";
5
6
  import { EndpointBase } from "../core/Endpoint.sol";
6
7
  import { Nodes } from "../utils/Nodes.sol";
7
8
  import { Selectors } from "../utils/Selectors.sol";
9
+ import { Descriptors } from "../codec/Descriptors.sol";
8
10
 
9
11
  /// @title PortBase
10
12
  /// @notice Abstract base for peer-facing rootzero ports.
@@ -21,23 +23,28 @@ abstract contract PortBase is NodeCalls, EndpointBase {
21
23
  _;
22
24
  }
23
25
 
26
+ /// @notice Return the host node ID corresponding to the current caller.
27
+ /// @dev Encodes `msg.sender` as a host ID using the local-chain host layout.
28
+ /// @return Host node ID for `msg.sender`.
29
+ function caller() internal view returns (uint) {
30
+ return Nodes.toHost(msg.sender);
31
+ }
32
+
24
33
  /// @notice Publish port metadata and a default label.
25
- /// @param name Default human-readable port label and selector name.
26
- /// @param input Packed input lane plus optional group byte.
27
- /// @param output Packed output lane plus optional group byte.
28
- /// @param selector Port ABI selector, or zero to derive it from `name`.
34
+ /// @param name Port entrypoint name and default label. It must exactly
35
+ /// match the Solidity port function name used by the canonical ABI.
36
+ /// @param input Input block specification.
37
+ /// @param output Output block specification.
29
38
  /// @param funded Whether the port accepts nonzero native value.
30
39
  /// @return id Port node ID.
31
40
  /// @return descriptor Packed endpoint lane metadata and flags.
32
41
  function port(
33
42
  string memory name,
34
- bytes9 input,
35
- bytes9 output,
36
- bytes4 selector,
43
+ uint input,
44
+ uint output,
37
45
  bool funded
38
- ) internal returns (uint id, bytes32 descriptor) {
39
- selector = selector == bytes4(0) ? Selectors.port(name) : selector;
40
- id = Nodes.toPort(selector, address(this));
41
- descriptor = endpoint(id, name, bytes9(0), input, output, funded, false);
46
+ ) internal returns (uint id, uint descriptor) {
47
+ id = Nodes.toPort(Selectors.port(name), address(this));
48
+ descriptor = endpoint(id, name, Specs.Empty, input, output, 0, funded ? Descriptors.Funded : 0);
42
49
  }
43
50
  }
package/ports/Credit.sol CHANGED
@@ -1,32 +1,34 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import { PortBase } from "./Base.sol";
5
- import { CreditAccountHook } from "../core/Settlement.sol";
6
- import { Cursors, Cur, Keys } from "../Cursors.sol";
4
+ import {PortBase} from "./Base.sol";
5
+ import {CreditAccountHook} from "../core/Settlement.sol";
6
+ import {Specs} from "../Codec.sol";
7
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
7
8
 
8
- using Cursors for Cur;
9
+ using Executions for Execution;
9
10
 
10
11
  /// @title PortCreditAccount
11
12
  /// @notice Port that lets a trusted peer credit supplied accounts directly.
12
13
  /// Each ACCOUNT_AMOUNT block calls `creditAccount` for its account.
13
14
  abstract contract PortCreditAccount is PortBase, CreditAccountHook {
14
- bytes32 private immutable descriptor;
15
+ uint private immutable descriptor;
15
16
 
16
17
  constructor() {
17
- (, descriptor) = port("portCreditAccount", Keys.AccountAmount, Keys.Empty, 0, false);
18
+ (, descriptor) = port("portCreditAccount", Specs.AccountAmount, Specs.Empty, false);
18
19
  }
19
20
 
20
21
  /// @notice Execute the port-credit call.
21
22
  /// @param data ACCOUNT_AMOUNT block stream supplied by the trusted peer.
22
23
  /// @return Empty response bytes.
23
24
  function portCreditAccount(bytes calldata data) external onlyPeer returns (bytes memory) {
24
- (Cur memory input, ) = openInput(data, descriptor);
25
+ Execution memory exec = openInput(data, descriptor, 0);
25
26
 
26
- while (input.i < input.len) {
27
- (bytes32 account, bytes32 asset, uint amount) = input.unpackAccountAmount();
27
+ while (exec.more()) {
28
+ (bytes32 account, bytes32 asset, uint amount) = exec.unpackAccountAmount(Lanes.Input);
28
29
  creditAccount(account, asset, amount);
29
30
  }
31
+
30
32
  return "";
31
33
  }
32
34
  }
package/ports/Debit.sol CHANGED
@@ -1,32 +1,34 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import { PortBase } from "./Base.sol";
5
- import { DebitAccountHook } from "../core/Settlement.sol";
6
- import { Cursors, Cur, Keys } from "../Cursors.sol";
4
+ import {PortBase} from "./Base.sol";
5
+ import {DebitAccountHook} from "../core/Settlement.sol";
6
+ import {Specs} from "../Codec.sol";
7
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
7
8
 
8
- using Cursors for Cur;
9
+ using Executions for Execution;
9
10
 
10
11
  /// @title PortDebitAccount
11
12
  /// @notice Port that lets a trusted peer debit supplied accounts directly.
12
13
  /// Each ACCOUNT_AMOUNT block calls `debitAccount` for its account.
13
14
  abstract contract PortDebitAccount is PortBase, DebitAccountHook {
14
- bytes32 private immutable descriptor;
15
+ uint private immutable descriptor;
15
16
 
16
17
  constructor() {
17
- (, descriptor) = port("portDebitAccount", Keys.AccountAmount, Keys.Empty, 0, false);
18
+ (, descriptor) = port("portDebitAccount", Specs.AccountAmount, Specs.Empty, false);
18
19
  }
19
20
 
20
21
  /// @notice Execute the port-debit call.
21
22
  /// @param data ACCOUNT_AMOUNT block stream supplied by the trusted peer.
22
23
  /// @return Empty response bytes.
23
24
  function portDebitAccount(bytes calldata data) external onlyPeer returns (bytes memory) {
24
- (Cur memory input, ) = openInput(data, descriptor);
25
+ Execution memory exec = openInput(data, descriptor, 0);
25
26
 
26
- while (input.i < input.len) {
27
- (bytes32 account, bytes32 asset, uint amount) = input.unpackAccountAmount();
27
+ while (exec.more()) {
28
+ (bytes32 account, bytes32 asset, uint amount) = exec.unpackAccountAmount(Lanes.Input);
28
29
  debitAccount(account, asset, amount);
29
30
  }
31
+
30
32
  return "";
31
33
  }
32
34
  }
@@ -3,35 +3,32 @@ pragma solidity ^0.8.33;
3
3
 
4
4
  import {PortBase} from "./Base.sol";
5
5
  import {DenyAssetsHook} from "../commands/admin/DenyAssets.sol";
6
- import {Cursors, Cur, Keys} from "../Cursors.sol";
6
+ import {Specs} from "../Codec.sol";
7
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
7
8
 
8
- using Cursors for Cur;
9
+ using Executions for Execution;
9
10
 
10
11
  /// @title PortDenyAssets
11
12
  /// @notice Port that blocks a list of assets on behalf of a peer host.
12
- /// Each ASSET block in the request calls `denyAsset`. Restricted to trusted peers.
13
+ /// Each ASSET block in the input calls `denyAsset`. Restricted to trusted peers.
13
14
  abstract contract PortDenyAssets is PortBase, DenyAssetsHook {
14
- bytes32 private immutable descriptor;
15
+ uint private immutable descriptor;
15
16
 
16
17
  constructor() {
17
- (, descriptor) = port("portDenyAssets", Keys.Asset, Keys.Empty, 0, false);
18
+ (, descriptor) = port("portDenyAssets", Specs.Asset, Specs.Empty, false);
18
19
  }
19
20
 
20
21
  /// @notice Execute the deny-assets peer call.
21
22
  /// @param data ASSET block stream supplied by the trusted peer.
22
23
  /// @return Empty response bytes.
23
24
  function portDenyAssets(bytes calldata data) external onlyPeer returns (bytes memory) {
24
- (Cur memory input, ) = openInput(data, descriptor);
25
+ Execution memory exec = openInput(data, descriptor, 0);
25
26
 
26
- while (input.i < input.len) {
27
- bytes32 asset = input.unpackAsset();
27
+ while (exec.more()) {
28
+ bytes32 asset = exec.unpackAsset(Lanes.Input);
28
29
  denyAsset(asset);
29
30
  }
31
+
30
32
  return "";
31
33
  }
32
34
  }
33
-
34
-
35
-
36
-
37
-
@@ -1,21 +1,20 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import { PortBase } from "./Base.sol";
5
- import { Payable } from "../core/Payable.sol";
6
- import { RoutePayableHook } from "../commands/Relay.sol";
7
- import { Cursors, Cur, Keys } from "../Cursors.sol";
8
- import { Budget } from "../utils/Value.sol";
4
+ import {PortBase} from "./Base.sol";
5
+ import {RoutePayableHook} from "../commands/Relay.sol";
6
+ import {Specs} from "../Codec.sol";
7
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
9
8
 
10
- using Cursors for Cur;
9
+ using Executions for Execution;
11
10
 
12
11
  /// @title PortDispatchPayable
13
12
  /// @notice Port endpoint that forwards DISPATCH blocks to a host-defined route hook.
14
- abstract contract PortDispatchPayable is PortBase, Payable, RoutePayableHook {
15
- bytes32 private immutable descriptor;
13
+ abstract contract PortDispatchPayable is PortBase, RoutePayableHook {
14
+ uint private immutable descriptor;
16
15
 
17
16
  constructor() {
18
- (, descriptor) = port("portDispatchPayable", Keys.Dispatch, Keys.Empty, 0, true);
17
+ (, descriptor) = port("portDispatchPayable", Specs.Dispatch, Specs.Empty, true);
19
18
  }
20
19
 
21
20
  /// @notice Forward peer-supplied dispatches to the host-defined route hook.
@@ -24,14 +23,13 @@ abstract contract PortDispatchPayable is PortBase, Payable, RoutePayableHook {
24
23
  /// @param data DISPATCH block stream supplied by the trusted peer.
25
24
  /// @return Empty response bytes.
26
25
  function portDispatchPayable(bytes calldata data) external payable onlyPeer returns (bytes memory) {
27
- (Cur memory input, ) = openInput(data, descriptor);
28
- Budget memory budget = openValue();
26
+ Execution memory exec = openInput(data, descriptor, 0);
29
27
 
30
- while (input.i < input.len) {
31
- (uint portal, uint resources, bytes calldata payload) = input.unpackDispatch();
32
- route(portal, resources, bytes(payload), budget);
28
+ while (exec.more()) {
29
+ (uint portal, uint resources, bytes calldata payload) = exec.unpackDispatch(Lanes.Input);
30
+ route(portal, resources, bytes(payload), exec);
33
31
  }
32
+
34
33
  return "";
35
34
  }
36
-
37
35
  }
package/ports/Pipe.sol CHANGED
@@ -3,19 +3,20 @@ pragma solidity ^0.8.33;
3
3
 
4
4
  import {PortBase} from "./Base.sol";
5
5
  import {Pipeline} from "../core/Pipeline.sol";
6
- import {Cursors, Cur, Keys} from "../Cursors.sol";
7
- import {Budget} from "../utils/Value.sol";
6
+ import {Specs} from "../Codec.sol";
7
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
8
+ import {Budget} from "../execution/Budget.sol";
8
9
 
9
- using Cursors for Cur;
10
+ using Executions for Execution;
10
11
 
11
12
  /// @title PortPipePayable
12
- /// @notice Port that consumes CONTEXT blocks and executes each request as a step stream.
13
- /// Each context's request bytes are passed to the shared pipeline.
13
+ /// @notice Port that consumes CONTEXT blocks and executes each input as a step stream.
14
+ /// Each context's input bytes are passed to the shared pipeline.
14
15
  abstract contract PortPipePayable is PortBase, Pipeline {
15
- bytes32 private immutable descriptor;
16
+ uint private immutable descriptor;
16
17
 
17
18
  constructor() {
18
- (, descriptor) = port("portPipePayable", Keys.Context, Keys.Empty, 0, true);
19
+ (, descriptor) = port("portPipePayable", Specs.Context, Specs.Empty, true);
19
20
  }
20
21
 
21
22
  /// @notice Execute peer-supplied contexts through the shared payable pipe.
@@ -24,13 +25,14 @@ abstract contract PortPipePayable is PortBase, Pipeline {
24
25
  /// @param data CONTEXT block stream supplied by the trusted peer.
25
26
  /// @return Empty response bytes.
26
27
  function portPipePayable(bytes calldata data) external payable onlyPeer returns (bytes memory) {
27
- (Cur memory input, ) = openInput(data, descriptor);
28
- Budget memory budget = openValue();
28
+ Execution memory exec = openInput(data, descriptor, 0);
29
+ Budget memory budget = exec.takeBudget();
29
30
 
30
- while (input.i < input.len) {
31
- (bytes32 account, bytes calldata state, bytes calldata request) = input.unpackContext();
32
- pipe(account, state, request, budget);
31
+ while (exec.more()) {
32
+ (bytes32 account, bytes calldata state, bytes calldata input) = exec.unpackContext(Lanes.Input);
33
+ pipe(account, state, input, budget);
33
34
  }
35
+
34
36
  return "";
35
37
  }
36
38
  }
package/ports/Redeem.sol CHANGED
@@ -2,13 +2,15 @@
2
2
  pragma solidity ^0.8.33;
3
3
 
4
4
  import {PortBase} from "./Base.sol";
5
- import {Cursors, Cur, Keys} from "../Cursors.sol";
5
+ import {Specs} from "../Codec.sol";
6
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
6
7
 
7
- using Cursors for Cur;
8
+ using Executions for Execution;
8
9
 
10
+ /// @notice Hook implemented by hosts that redeem balances received through a port.
9
11
  abstract contract RedeemBalanceHook {
10
12
  /// @notice Override to redeem one balance claim from a peer host into local assets.
11
- /// @param peer Peer host node ID for this request.
13
+ /// @param peer Peer host node ID for this input.
12
14
  /// @param asset Asset identifier to redeem locally.
13
15
  /// @param amount Amount to redeem in the asset's native units.
14
16
  function redeemBalance(uint peer, bytes32 asset, uint amount) internal virtual;
@@ -16,26 +18,27 @@ abstract contract RedeemBalanceHook {
16
18
 
17
19
  /// @title PortRedeemBalance
18
20
  /// @notice Port that redeems balance state from a peer host into local assets.
19
- /// Each BALANCE block in the request calls `redeemBalance(peer, asset, amount)`.
21
+ /// Each BALANCE block in the input calls `redeemBalance(peer, asset, amount)`.
20
22
  /// Restricted to trusted peers.
21
23
  abstract contract PortRedeemBalance is PortBase, RedeemBalanceHook {
22
- bytes32 private immutable descriptor;
24
+ uint private immutable descriptor;
23
25
 
24
26
  constructor() {
25
- (, descriptor) = port("portRedeemBalance", Keys.Balance, Keys.Empty, 0, false);
27
+ (, descriptor) = port("portRedeemBalance", Specs.Balance, Specs.Empty, false);
26
28
  }
27
29
 
28
30
  /// @notice Execute the balance redemption port call.
29
31
  /// @param data BALANCE block stream supplied by the trusted peer.
30
32
  /// @return Empty response bytes.
31
33
  function portRedeemBalance(bytes calldata data) external onlyPeer returns (bytes memory) {
32
- (Cur memory input, ) = openInput(data, descriptor);
34
+ Execution memory exec = openInput(data, descriptor, 0);
33
35
  uint peer = caller();
34
36
 
35
- while (input.i < input.len) {
36
- (bytes32 asset, uint amount) = input.unpackBalance();
37
+ while (exec.more()) {
38
+ (bytes32 asset, uint amount) = exec.unpackBalance(Lanes.Input);
37
39
  redeemBalance(peer, asset, amount);
38
40
  }
41
+
39
42
  return "";
40
43
  }
41
44
  }
package/ports/Settle.sol CHANGED
@@ -1,32 +1,34 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import { PortBase } from "./Base.sol";
5
- import { Settlement } from "../core/Settlement.sol";
6
- import { Cursors, Cur, Keys } from "../Cursors.sol";
4
+ import {PortBase} from "./Base.sol";
5
+ import {Settlement} from "../core/Settlement.sol";
6
+ import {Specs} from "../Codec.sol";
7
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
7
8
 
8
- using Cursors for Cur;
9
+ using Executions for Execution;
9
10
 
10
11
  /// @title PortSettle
11
12
  /// @notice Port that consumes peer-supplied TRANSACTION blocks through debit and credit hooks.
12
13
  /// Each TRANSACTION block calls `debitAccount` for `from` and `creditAccount` for `to`.
13
14
  abstract contract PortSettle is PortBase, Settlement {
14
- bytes32 private immutable descriptor;
15
+ uint private immutable descriptor;
15
16
 
16
17
  constructor() {
17
- (, descriptor) = port("portSettle", Keys.Transaction, Keys.Empty, 0, false);
18
+ (, descriptor) = port("portSettle", Specs.Transaction, Specs.Empty, false);
18
19
  }
19
20
 
20
21
  /// @notice Execute the port-settle call.
21
22
  /// @param data TRANSACTION block stream supplied by the trusted peer.
22
23
  /// @return Empty response bytes.
23
24
  function portSettle(bytes calldata data) external onlyPeer returns (bytes memory) {
24
- (Cur memory input, ) = openInput(data, descriptor);
25
+ Execution memory exec = openInput(data, descriptor, 0);
25
26
 
26
- while (input.i < input.len) {
27
- (bytes32 from, bytes32 to, bytes32 asset, uint amount) = input.unpackTransaction();
27
+ while (exec.more()) {
28
+ (bytes32 from, bytes32 to, bytes32 asset, uint amount) = exec.unpackTransaction(Lanes.Input);
28
29
  settle(from, to, asset, amount);
29
30
  }
31
+
30
32
  return "";
31
33
  }
32
34
  }
@@ -1,12 +1,13 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import {Cur, Cursors, Keys, Writer, Writers} from "../Cursors.sol";
4
+ import {Specs} from "../Codec.sol";
5
+ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
5
6
  import {QueryBase} from "./Base.sol";
6
7
 
7
- using Cursors for Cur;
8
- using Writers for Writer;
8
+ using Executions for Execution;
9
9
 
10
+ /// @notice Hook implemented by hosts that expose asset status queries.
10
11
  abstract contract AssetStatusHook {
11
12
  /// @notice Resolve support status for one asset.
12
13
  /// Concrete implementations define the support policy and optional context codes.
@@ -17,28 +18,27 @@ abstract contract AssetStatusHook {
17
18
 
18
19
  /// @title AssetStatus
19
20
  /// @notice Rootzero query that checks support status for one or more assets.
20
- /// The request is a run of `ASSET` blocks.
21
- /// The response returns one `STATUS` form block per query entry, preserving request order.
21
+ /// The input is a run of `ASSET` blocks.
22
+ /// The response returns one `STATUS` form block per query entry, preserving input order.
22
23
  abstract contract AssetStatus is QueryBase, AssetStatusHook {
23
- bytes32 private immutable descriptor;
24
+ uint private immutable descriptor;
24
25
 
25
26
  constructor() {
26
- (, descriptor) = query("assetStatus", Keys.Asset, Keys.Status, 0);
27
+ (, descriptor) = query("assetStatus", Specs.Asset, Specs.Status);
27
28
  }
28
29
 
29
30
  /// @notice Resolve asset support status for a run of requested assets.
30
- /// @param request Block-stream request consisting of `asset { bytes32 asset }` blocks.
31
+ /// @param input Block-stream input consisting of `asset { bytes32 asset }` blocks.
31
32
  /// @return Block-stream response containing one `status { uint code }` form block per asset block.
32
- function assetStatus(bytes calldata request) external view returns (bytes memory) {
33
- (Cur memory input, uint outputs) = openInput(request, descriptor);
34
- Writer memory response = Writers.allocStatuses(outputs);
33
+ function assetStatus(bytes calldata input) external view returns (bytes memory) {
34
+ Execution memory exec = openInput(input, descriptor, 0);
35
35
 
36
- while (input.i < input.len) {
37
- bytes32 asset = input.unpackAsset();
36
+ while (exec.more()) {
37
+ bytes32 asset = exec.unpackAsset(Lanes.Input);
38
38
  uint status = assetStatus(asset);
39
- response.appendStatus(status);
39
+ exec.outputStatus(status);
40
40
  }
41
41
 
42
- return response.finish();
42
+ return close(exec);
43
43
  }
44
44
  }