@rootzero/contracts 1.13.0 → 1.15.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 (86) hide show
  1. package/CHANGELOG.md +87 -3
  2. package/Codec.sol +21 -0
  3. package/Commands.sol +14 -0
  4. package/Core.sol +8 -6
  5. package/Endpoints.sol +2 -7
  6. package/Events.sol +1 -2
  7. package/README.md +70 -37
  8. package/Utils.sol +2 -4
  9. package/annotations/Action.sol +17 -0
  10. package/annotations/Label.sol +23 -0
  11. package/annotations/Schema.sol +53 -0
  12. package/codec/Blocks.sol +1643 -0
  13. package/codec/Buffers.sol +165 -0
  14. package/codec/Decoders.sol +570 -0
  15. package/codec/Descriptors.sol +124 -0
  16. package/{blocks → codec}/Keys.sol +10 -18
  17. package/codec/Readers.sol +114 -0
  18. package/{blocks → codec}/Schema.sol +43 -80
  19. package/codec/Specs.sol +240 -0
  20. package/codec/Writers.sol +485 -0
  21. package/commands/Allocate.sol +21 -20
  22. package/commands/Base.sol +83 -45
  23. package/commands/Burn.sol +23 -14
  24. package/commands/Credit.sol +21 -20
  25. package/commands/Debit.sol +25 -28
  26. package/commands/Deposit.sol +41 -36
  27. package/commands/Payout.sol +26 -16
  28. package/commands/Provision.sol +37 -38
  29. package/commands/Recover.sol +20 -19
  30. package/commands/Relay.sol +24 -22
  31. package/commands/Withdraw.sol +20 -19
  32. package/commands/admin/AllowAssets.sol +19 -16
  33. package/commands/admin/Allowance.sol +18 -13
  34. package/commands/admin/Annotate.sol +36 -0
  35. package/commands/admin/Appoint.sol +19 -16
  36. package/commands/admin/Authorize.sol +23 -14
  37. package/commands/admin/Base.sol +9 -2
  38. package/commands/admin/DenyAssets.sol +19 -16
  39. package/commands/admin/Dismiss.sol +19 -16
  40. package/commands/admin/Execute.sol +21 -19
  41. package/commands/admin/Unauthorize.sol +23 -14
  42. package/core/Access.sol +91 -49
  43. package/core/Calls.sol +30 -33
  44. package/core/Endpoint.sol +46 -143
  45. package/core/Host.sol +63 -21
  46. package/core/Pipeline.sol +16 -15
  47. package/core/Types.sol +1 -1
  48. package/docs/Schema.md +48 -31
  49. package/events/Annotation.sol +24 -0
  50. package/events/Endpoint.sol +2 -2
  51. package/events/Guardian.sol +2 -2
  52. package/events/Introduction.sol +3 -2
  53. package/execution/Budget.sol +40 -0
  54. package/execution/Execution.sol +1104 -0
  55. package/guards/Base.sol +11 -12
  56. package/guards/Revoke.sol +11 -9
  57. package/package.json +1 -1
  58. package/ports/AllowAssets.sol +12 -15
  59. package/ports/Allowance.sol +11 -9
  60. package/ports/Base.sol +35 -16
  61. package/ports/Credit.sol +11 -9
  62. package/ports/Debit.sol +11 -9
  63. package/ports/DenyAssets.sol +10 -13
  64. package/ports/Dispatch.sol +13 -15
  65. package/ports/Pipe.sol +14 -12
  66. package/ports/Redeem.sol +12 -9
  67. package/ports/Settle.sol +16 -10
  68. package/queries/Assets.sol +15 -15
  69. package/queries/Balances.sol +17 -17
  70. package/queries/Base.sol +26 -12
  71. package/utils/Accounts.sol +0 -23
  72. package/utils/Actions.sol +1 -0
  73. package/utils/Cursors.sol +367 -0
  74. package/utils/Lanes.sol +14 -0
  75. package/utils/Layout.sol +0 -2
  76. package/utils/Selectors.sol +2 -2
  77. package/utils/Utils.sol +46 -0
  78. package/Cursors.sol +0 -16
  79. package/blocks/Cursors.sol +0 -1529
  80. package/blocks/Writers.sol +0 -1036
  81. package/commands/admin/Label.sol +0 -32
  82. package/commands/admin/Schemas.sol +0 -32
  83. package/core/Payable.sol +0 -53
  84. package/events/Labeled.sol +0 -21
  85. package/events/Schema.sol +0 -23
  86. package/utils/Value.sol +0 -43
@@ -1,41 +1,44 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import { AdminBase, CommandContext, Keys } from "./Base.sol";
5
- import { Cursors, Cur } from "../../Cursors.sol";
6
- using Cursors for Cur;
4
+ import { AdminBase, Execution, Executions, Lanes, Specs } from "./Base.sol";
5
+ using Executions for Execution;
7
6
 
7
+ /// @notice Hook implemented by hosts that deny assets.
8
8
  abstract contract DenyAssetsHook {
9
9
  /// @dev Override to deny a single asset.
10
- /// Called once per ASSET block in the request.
10
+ /// Called once per ASSET block in the input.
11
11
  /// @param asset Asset identifier.
12
12
  function denyAsset(bytes32 asset) internal virtual;
13
13
  }
14
14
 
15
15
  /// @title DenyAssets
16
16
  /// @notice Admin command that blocks a list of assets via a virtual hook.
17
- /// Each ASSET block in the request calls `denyAsset`. Only callable by the admin account.
17
+ /// Each ASSET block in the input calls `denyAsset`. Only callable by the admin account.
18
18
  abstract contract DenyAssets is AdminBase, DenyAssetsHook {
19
- bytes32 private immutable descriptor;
19
+ uint private immutable descriptor;
20
20
 
21
21
  constructor() {
22
- (, descriptor) = command("denyAssets", Keys.Empty, Keys.Asset, Keys.Empty, 0, false, true);
22
+ (, descriptor) = command("denyAssets", Specs.Empty, Specs.Asset, Specs.Empty, 0, false, true);
23
23
  }
24
24
 
25
- /// @notice Deny each ASSET block in the admin request.
26
- /// @param c Admin command context; `c.input` must contain ASSET blocks.
25
+ /// @notice Deny each ASSET block in the admin input.
26
+ /// @param input ASSET block stream.
27
27
  /// @return Empty output state.
28
28
  /// @return Empty transaction stream.
29
29
  function denyAssets(
30
- CommandContext calldata c
31
- ) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
32
- (Cur memory input, ) = openInput(c.input, descriptor);
33
-
34
- while (input.i < input.len) {
35
- bytes32 asset = input.unpackAsset();
30
+ bytes32 account,
31
+ bytes calldata,
32
+ bytes calldata input
33
+ ) external onlyAdmin(account) returns (bytes memory, bytes memory) {
34
+ Execution memory exec = openInput(input, descriptor, 0);
35
+
36
+ while (exec.more()) {
37
+ bytes32 asset = exec.unpackAsset(Lanes.Input);
36
38
  denyAsset(asset);
37
39
  }
38
- return ("", "");
40
+
41
+ return close(exec, account);
39
42
  }
40
43
  }
41
44
 
@@ -1,34 +1,37 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import { AdminBase, CommandContext, Keys } from "./Base.sol";
5
- import { Cursors, Cur } from "../../Cursors.sol";
6
- using Cursors for Cur;
4
+ import { AdminBase, Execution, Executions, Lanes, Specs } from "./Base.sol";
5
+ import { GuardianAccess } from "../../core/Access.sol";
6
+ using Executions for Execution;
7
7
 
8
8
  /// @title Dismiss
9
9
  /// @notice Admin command that revokes guardian status from a list of account IDs.
10
- /// Each ACCOUNT block in the request is disabled as a guardian on the host.
10
+ /// Each USER ACCOUNT block in the input loses the guardian role on the host.
11
11
  /// Only callable by the admin account.
12
- abstract contract Dismiss is AdminBase {
13
- bytes32 private immutable descriptor;
12
+ abstract contract Dismiss is GuardianAccess, AdminBase {
13
+ uint private immutable descriptor;
14
14
 
15
15
  constructor() {
16
- (, descriptor) = command("dismiss", Keys.Empty, Keys.Account, Keys.Empty, 0, false, true);
16
+ (, descriptor) = command("dismiss", Specs.Empty, Specs.Account, Specs.Empty, 0, false, true);
17
17
  }
18
18
 
19
- /// @notice Dismiss each ACCOUNT block in the admin request from guardian status.
20
- /// @param c Admin command context; `c.input` must contain ACCOUNT blocks.
19
+ /// @notice Dismiss each user ACCOUNT block in the admin input from guardian status.
20
+ /// @param input ACCOUNT block stream.
21
21
  /// @return Empty output state.
22
22
  /// @return Empty transaction stream.
23
23
  function dismiss(
24
- CommandContext calldata c
25
- ) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
26
- (Cur memory input, ) = openInput(c.input, descriptor);
24
+ bytes32 account,
25
+ bytes calldata,
26
+ bytes calldata input
27
+ ) external onlyAdmin(account) returns (bytes memory, bytes memory) {
28
+ Execution memory exec = openInput(input, descriptor, 0);
27
29
 
28
- while (input.i < input.len) {
29
- bytes32 account = input.unpackAccount();
30
- setGuardian(account, false);
30
+ while (exec.more()) {
31
+ bytes32 guardian = exec.unpackAccount(Lanes.Input);
32
+ setGuardian(guardian, false);
31
33
  }
32
- return ("", "");
34
+
35
+ return close(exec, account);
33
36
  }
34
37
  }
@@ -1,37 +1,39 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import {AdminBase, CommandContext, Keys} from "./Base.sol";
5
- import {Payable} from "../../core/Payable.sol";
6
- import {Cursors, Cur} from "../../Cursors.sol";
7
- import {Budget} from "../../utils/Value.sol";
4
+ import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
5
+ import {RawNodeCalls} from "../../core/Calls.sol";
8
6
 
9
- using Cursors for Cur;
7
+ using Executions for Execution;
10
8
 
11
9
  /// @title ExecutePayable
12
10
  /// @notice Admin command that forwards raw calldata to one or more target nodes.
13
11
  /// Each CALL block specifies a target node ID, packed resources, and raw calldata payload.
14
12
  /// Only callable by the admin account.
15
- /// Unspent top-level `msg.value` remains on this host.
16
- abstract contract ExecutePayable is AdminBase, Payable {
17
- bytes32 private immutable descriptor;
13
+ /// Unspent top-level `msg.value` is returned as a refund transaction.
14
+ abstract contract ExecutePayable is RawNodeCalls, AdminBase {
15
+ uint private immutable descriptor;
18
16
 
19
17
  constructor() {
20
- (, descriptor) = command("executePayable", Keys.Empty, Keys.Call, Keys.Empty, 0, true, true);
18
+ (, descriptor) = command("executePayable", Specs.Empty, Specs.Call, Specs.Empty, 0, true, true);
21
19
  }
22
20
 
23
- /// @notice Execute each CALL block in the admin request.
24
- /// @param c Admin command context; `c.input` must contain CALL blocks.
21
+ /// @notice Execute each CALL block in the admin input.
22
+ /// @param input CALL block stream.
25
23
  /// @return Empty output state.
26
- /// @return Empty transaction stream.
27
- function executePayable(CommandContext calldata c) external payable onlyAdmin(c.account) returns (bytes memory, bytes memory) {
28
- (Cur memory input, ) = openInput(c.input, descriptor);
29
- Budget memory budget = openValue();
24
+ /// @return Remaining native value as a refund transaction stream.
25
+ function executePayable(
26
+ bytes32 account,
27
+ bytes calldata,
28
+ bytes calldata input
29
+ ) external payable onlyAdmin(account) returns (bytes memory, bytes memory) {
30
+ Execution memory exec = openInput(input, descriptor, 0);
30
31
 
31
- while (input.i < input.len) {
32
- (uint target, uint resources, bytes calldata data) = input.unpackCall();
33
- rawCall(target, useValue(budget, resources), data);
32
+ while (exec.more()) {
33
+ (uint target, uint resources, bytes calldata data) = exec.unpackCall(Lanes.Input);
34
+ rawCall(target, exec.useValue(resources), data);
34
35
  }
35
- return ("", "");
36
+
37
+ return close(exec, account);
36
38
  }
37
39
  }
@@ -1,33 +1,42 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import {AdminBase, CommandContext, Keys} from "./Base.sol";
5
- import {Cursors, Cur} from "../../Cursors.sol";
6
- using Cursors for Cur;
4
+ import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
5
+ using Executions for Execution;
7
6
 
8
7
  /// @title Unauthorize
9
8
  /// @notice Admin command that revokes authorization from a list of node IDs.
10
- /// Each NODE block in the request is deauthorized on the host.
9
+ /// Each NODE block in the input is deauthorized on the host.
11
10
  /// Only callable by the admin account.
12
11
  abstract contract Unauthorize is AdminBase {
13
- bytes32 private immutable descriptor;
14
- uint internal immutable unauthorizeId;
12
+ uint private immutable descriptor;
13
+ uint private immutable id;
15
14
 
16
15
  constructor() {
17
- (unauthorizeId, descriptor) = command("unauthorize", Keys.Empty, Keys.Node, Keys.Empty, 0, false, true);
16
+ (id, descriptor) = command("unauthorize", Specs.Empty, Specs.Node, Specs.Empty, 0, false, true);
18
17
  }
19
18
 
20
- /// @notice Unauthorize each NODE block in the admin request.
21
- /// @param c Admin command context; `c.input` must contain NODE blocks.
19
+ /// @notice Return the registered UNAUTHORIZE command ID.
20
+ function unauthorizeId() internal view returns (uint) {
21
+ return id;
22
+ }
23
+
24
+ /// @notice Unauthorize each NODE block in the admin input.
25
+ /// @param input NODE block stream.
22
26
  /// @return Empty output state.
23
27
  /// @return Empty transaction stream.
24
- function unauthorize(CommandContext calldata c) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
25
- (Cur memory input, ) = openInput(c.input, descriptor);
28
+ function unauthorize(
29
+ bytes32 account,
30
+ bytes calldata,
31
+ bytes calldata input
32
+ ) external onlyAdmin(account) returns (bytes memory, bytes memory) {
33
+ Execution memory exec = openInput(input, descriptor, 0);
26
34
 
27
- while (input.i < input.len) {
28
- uint node = input.unpackNode();
35
+ while (exec.more()) {
36
+ uint node = exec.unpackNode(Lanes.Input);
29
37
  setNode(node, false);
30
38
  }
31
- return ("", "");
39
+
40
+ return close(exec, account);
32
41
  }
33
42
  }
package/core/Access.sol CHANGED
@@ -8,34 +8,75 @@ import {Accounts} from "../utils/Accounts.sol";
8
8
  import {Nodes} from "../utils/Nodes.sol";
9
9
  import {addrOr} from "../utils/Utils.sol";
10
10
 
11
- /// @title AccessControl
12
- /// @notice Host access control layer.
13
- /// Tracks an immutable trusted commander, the host's own node ID, and a
14
- /// mapping of externally trusted node IDs. Inbound trust is host-based:
15
- /// trusted hosts, the commander, and this contract itself may interact
16
- /// with the host through the guarded command and peer entrypoints.
17
- abstract contract AccessControl is Runtime, NodeEvent, GuardianEvent {
18
- /// @dev Trusted commander address. All calls from this address are implicitly trusted.
19
- /// Defaults to `address(this)` when no external commander is provided.
20
- address internal immutable commander;
21
- /// @dev Admin account ID derived from the commander address at construction time.
22
- bytes32 internal immutable admin;
11
+ /// @dev Thrown when a caller, account, or node lacks required access.
12
+ error AccessDenied();
13
+ error CommanderNotAllowed();
23
14
 
24
- /// @dev Mapping from guardian account ID to guardian status.
25
- mapping(bytes32 account => bool) internal guardians;
15
+ /// @title CallerAccess
16
+ /// @notice Authorization capability required by command entrypoints.
17
+ abstract contract CallerAccess is Runtime {
18
+ /// @notice Assert that `caller` may invoke a command and return it.
19
+ function enforceCaller(address caller) internal view virtual returns (address);
20
+ }
26
21
 
27
- /// @dev Mapping from node ID to trust status.
28
- mapping(uint node => bool) internal nodes;
22
+ /// @title TrustAccess
23
+ /// @notice Authorization capability required by trusted outbound node calls.
24
+ abstract contract TrustAccess {
25
+ /// @notice Assert that `node` is trusted and return it.
26
+ function ensureTrusted(uint node) internal view virtual returns (uint);
27
+ }
29
28
 
30
- /// @dev Thrown when a caller, account, or node lacks required access.
31
- error AccessDenied();
29
+ /// @title CommanderAccess
30
+ /// @notice Minimal commander-based access control shared by host access policies.
31
+ abstract contract CommanderAccess is Runtime {
32
+ /// @dev Trusted commander address.
33
+ /// Defaults to `address(this)` when no external commander is provided.
34
+ address internal immutable commander;
32
35
 
33
36
  /// @param cmdr Commander address, or zero to make this contract self-managed.
34
37
  constructor(address cmdr) {
35
38
  commander = addrOr(cmdr, address(this));
39
+ }
40
+
41
+ /// @notice Assert that `caller` is the commander and return it.
42
+ /// @param caller Address to validate.
43
+ /// @return The same `caller` value if it is the commander.
44
+ function enforceCommander(address caller) internal view returns (address) {
45
+ if (caller == address(0) || caller != commander) {
46
+ revert AccessDenied();
47
+ }
48
+ return caller;
49
+ }
50
+
51
+ }
52
+
53
+ /// @title AdminAccess
54
+ /// @notice Commander access with the admin account derived from the commander.
55
+ abstract contract AdminAccess is CommanderAccess {
56
+ /// @dev Admin account ID derived from the commander address at construction time.
57
+ bytes32 internal immutable admin;
58
+
59
+ constructor() {
36
60
  admin = Accounts.toAdmin(commander);
37
61
  }
38
62
 
63
+ /// @notice Assert that `account` is the admin account and `caller` is the commander.
64
+ function enforceAdmin(bytes32 account, address caller) internal view returns (bytes32) {
65
+ if (account != admin) revert AccessDenied();
66
+ enforceCommander(caller);
67
+ return account;
68
+ }
69
+ }
70
+
71
+ /// @title NodeAccess
72
+ /// @notice Admin access extended with externally trusted node IDs.
73
+ /// Inbound trust is host-based:
74
+ /// trusted hosts, the commander, and this contract itself may interact
75
+ /// with the host through the guarded command and peer entrypoints.
76
+ abstract contract NodeAccess is AdminAccess, TrustAccess, NodeEvent {
77
+ /// @dev Mapping from node ID to trust status.
78
+ mapping(uint node => bool) internal nodes;
79
+
39
80
  /// @notice Set authorization status for a node.
40
81
  /// @param node Node ID to update.
41
82
  /// @param active True to authorize the node, false to revoke it.
@@ -44,58 +85,59 @@ abstract contract AccessControl is Runtime, NodeEvent, GuardianEvent {
44
85
  emit Node(host, node, active);
45
86
  }
46
87
 
47
- /// @notice Set guardian status for an account.
48
- /// @param account Guardian account ID to update.
49
- /// @param active True to enable the guardian, false to revoke it.
50
- function setGuardian(bytes32 account, bool active) internal {
51
- Accounts.guardian(account);
52
- guardians[account] = active;
53
- emit Guardian(host, account, active);
54
- }
55
-
56
- /// @notice Return true if `addr` is an active guardian.
57
- /// @param addr EVM address to check as a guardian account.
58
- function isGuardian(address addr) internal view returns (bool) {
59
- return guardians[Accounts.toGuardian(addr)];
60
- }
61
-
62
88
  /// @notice Return true if `caller` is an implicitly trusted address.
63
89
  /// Trusted callers: the commander, this contract itself, or any address
64
90
  /// whose host ID has been explicitly authorized.
65
91
  /// @param caller Address to check.
66
- function isTrusted(address caller) internal view returns (bool) {
92
+ function isTrustedCaller(address caller) internal view returns (bool) {
67
93
  return caller == commander || caller == address(this) || nodes[Nodes.toHost(caller)];
68
94
  }
69
95
 
70
96
  /// @notice Assert that `node` is in the trusted set and return it.
71
97
  /// @param node Node ID to validate.
72
98
  /// @return The same `node` value if trusted.
73
- function ensureTrusted(uint node) internal view returns (uint) {
99
+ function ensureTrusted(uint node) internal view override returns (uint) {
74
100
  if (node == 0 || !nodes[node]) {
75
101
  revert AccessDenied();
76
102
  }
77
103
  return node;
78
104
  }
79
105
 
80
- /// @notice Assert that `caller` is trusted and return it.
81
- /// Used by command and peer modifiers to gate execution to authorized senders.
82
- /// @param caller Address to validate.
83
- /// @return The same `caller` value if trusted.
84
- function enforceCaller(address caller) internal view returns (address) {
85
- if (caller == address(0) || !isTrusted(caller)) {
106
+ /// @notice Assert that `caller` is a trusted peer other than the commander.
107
+ function enforcePeer(address caller) internal view returns (address) {
108
+ if (caller == commander) revert CommanderNotAllowed();
109
+ if (caller == address(0) || !isTrustedCaller(caller)) {
86
110
  revert AccessDenied();
87
111
  }
88
112
  return caller;
89
113
  }
90
114
 
91
- /// @notice Assert that `caller` is the commander and return it.
92
- /// Used by admin modifiers to keep governance authority separate from peer trust.
93
- /// @param caller Address to validate.
94
- /// @return The same `caller` value if it is the commander.
95
- function enforceCommander(address caller) internal view returns (address) {
96
- if (caller == address(0) || caller != commander) {
97
- revert AccessDenied();
98
- }
115
+ }
116
+
117
+ /// @title GuardianAccess
118
+ /// @notice Node access extended with guardian identity and authorization.
119
+ abstract contract GuardianAccess is NodeAccess, GuardianEvent {
120
+ /// @dev Mapping from user account ID to guardian status.
121
+ mapping(bytes32 account => bool) internal guardians;
122
+
123
+ /// @notice Set guardian status for an account.
124
+ /// @param account User account ID whose guardian role is updated.
125
+ /// @param active True to enable the guardian, false to revoke it.
126
+ function setGuardian(bytes32 account, bool active) internal {
127
+ account = Accounts.user(account);
128
+ guardians[account] = active;
129
+ emit Guardian(host, account, active);
130
+ }
131
+
132
+ /// @notice Return true if `addr` is an active guardian.
133
+ /// @param addr EVM address to check for the guardian role.
134
+ function isGuardian(address addr) internal view returns (bool) {
135
+ return guardians[Accounts.toUser(addr)];
136
+ }
137
+
138
+ /// @notice Assert that `caller` is an active guardian and return it.
139
+ function enforceGuardian(address caller) internal view returns (address) {
140
+ if (caller == address(0) || !isGuardian(caller)) revert AccessDenied();
99
141
  return caller;
100
142
  }
101
143
  }
package/core/Calls.sol CHANGED
@@ -1,8 +1,7 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
2
  pragma solidity ^0.8.33;
3
3
 
4
- import {AccessControl} from "./Access.sol";
5
- import {CommandContext} from "../commands/Base.sol";
4
+ import {TrustAccess} from "./Access.sol";
6
5
  import {Nodes} from "../utils/Nodes.sol";
7
6
 
8
7
  /// @dev Emitted when a trusted inter-node call fails.
@@ -11,16 +10,9 @@ import {Nodes} from "../utils/Nodes.sol";
11
10
  /// @param err Revert data returned by the failed call.
12
11
  error FailedCall(address addr, bytes4 selector, bytes err);
13
12
 
14
- /// @title NodeCalls
15
- /// @notice Shared low-level inter-node call helpers for contracts that can talk to other nodes.
16
- abstract contract NodeCalls is AccessControl {
17
- /// @notice Return the host node ID corresponding to the current caller.
18
- /// @dev Encodes `msg.sender` as a host ID using the local-chain host layout.
19
- /// @return Host node ID for `msg.sender`.
20
- function caller() internal view returns (uint) {
21
- return Nodes.toHost(msg.sender);
22
- }
23
-
13
+ /// @title RawNodeCalls
14
+ /// @notice Low-level inter-node call helpers without target authorization.
15
+ abstract contract RawNodeCalls {
24
16
  /// @notice Try a raw low-level call to another node and return whether it succeeded.
25
17
  /// @param node Node ID of the callee.
26
18
  /// @param value Native value to forward in wei.
@@ -31,15 +23,6 @@ abstract contract NodeCalls is AccessControl {
31
23
  (success, ) = payable(addr).call{value: value}(data);
32
24
  }
33
25
 
34
- /// @notice Try a trusted low-level call to another node and return whether it succeeded.
35
- /// @param node Node ID of the callee.
36
- /// @param value Native value to forward in wei.
37
- /// @param data Encoded calldata to send.
38
- /// @return success True if the low-level call succeeded.
39
- function tryTrustedCall(uint node, uint128 value, bytes memory data) internal returns (bool success) {
40
- return tryRawCall(ensureTrusted(node), value, data);
41
- }
42
-
43
26
  /// @notice Make a raw low-level call to another node and revert when it fails.
44
27
  /// @param node Node ID of the callee.
45
28
  /// @param value Native value to forward in wei.
@@ -52,15 +35,6 @@ abstract contract NodeCalls is AccessControl {
52
35
  if (!success) revert FailedCall(addr, bytes4(data), out);
53
36
  }
54
37
 
55
- /// @notice Make a trusted low-level call to another node and revert when it fails.
56
- /// @param node Node ID of the callee.
57
- /// @param value Native value to forward in wei.
58
- /// @param data Encoded calldata to send.
59
- /// @return out Return data from the successful call.
60
- function trustedCall(uint node, uint128 value, bytes memory data) internal returns (bytes memory out) {
61
- return rawCall(ensureTrusted(node), value, data);
62
- }
63
-
64
38
  /// @notice Make a raw low-level read-only query to another node and revert when it fails.
65
39
  /// @param node Node ID of the callee.
66
40
  /// @param data Encoded calldata to send.
@@ -72,6 +46,29 @@ abstract contract NodeCalls is AccessControl {
72
46
  if (!success) revert FailedCall(addr, bytes4(data), out);
73
47
  }
74
48
 
49
+ }
50
+
51
+ /// @title NodeCalls
52
+ /// @notice Trusted low-level inter-node calls backed by a host-provided node policy.
53
+ abstract contract NodeCalls is RawNodeCalls, TrustAccess {
54
+ /// @notice Try a trusted low-level call to another node and return whether it succeeded.
55
+ /// @param node Node ID of the callee.
56
+ /// @param value Native value to forward in wei.
57
+ /// @param data Encoded calldata to send.
58
+ /// @return success True if the low-level call succeeded.
59
+ function tryTrustedCall(uint node, uint128 value, bytes memory data) internal returns (bool success) {
60
+ return tryRawCall(ensureTrusted(node), value, data);
61
+ }
62
+
63
+ /// @notice Make a trusted low-level call to another node and revert when it fails.
64
+ /// @param node Node ID of the callee.
65
+ /// @param value Native value to forward in wei.
66
+ /// @param data Encoded calldata to send.
67
+ /// @return out Return data from the successful call.
68
+ function trustedCall(uint node, uint128 value, bytes memory data) internal returns (bytes memory out) {
69
+ return rawCall(ensureTrusted(node), value, data);
70
+ }
71
+
75
72
  /// @notice Make a trusted low-level read-only query to another node and revert when it fails.
76
73
  /// @param node Node ID of the callee.
77
74
  /// @param data Encoded calldata to send.
@@ -89,7 +86,7 @@ abstract contract CommandCalls is NodeCalls {
89
86
  /// @param value Native value to forward in wei.
90
87
  /// @param account Command account identifier.
91
88
  /// @param state Current command state block stream.
92
- /// @param request Command input block stream.
89
+ /// @param input Command input block stream.
93
90
  /// @return nextState Decoded command output state block stream.
94
91
  /// @return transactions Decoded command transaction block stream.
95
92
  function callCommand(
@@ -97,10 +94,10 @@ abstract contract CommandCalls is NodeCalls {
97
94
  uint128 value,
98
95
  bytes32 account,
99
96
  bytes memory state,
100
- bytes calldata request
97
+ bytes calldata input
101
98
  ) internal returns (bytes memory nextState, bytes memory transactions) {
102
99
  bytes4 selector = Nodes.commandSelector(command);
103
- bytes memory data = abi.encodeWithSelector(selector, CommandContext(account, state, request));
100
+ bytes memory data = abi.encodeWithSelector(selector, account, state, input);
104
101
  return abi.decode(trustedCall(command, value, data), (bytes, bytes));
105
102
  }
106
103
  }