@rootzero/contracts 1.11.0 → 1.13.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 +52 -0
- package/Core.sol +2 -1
- package/Cursors.sol +2 -2
- package/Endpoints.sol +5 -2
- package/README.md +40 -17
- package/blocks/Cursors.sol +142 -0
- package/blocks/Keys.sol +2 -10
- package/blocks/Schema.sol +4 -3
- package/blocks/Writers.sol +17 -9
- package/commands/Allocate.sol +49 -0
- package/commands/Burn.sol +3 -2
- package/commands/Credit.sol +6 -18
- package/commands/Debit.sol +6 -18
- package/commands/Deposit.sol +6 -5
- package/commands/Payout.sol +3 -2
- package/commands/Provision.sol +6 -5
- package/commands/Recover.sol +3 -3
- package/commands/Relay.sol +3 -3
- package/commands/Withdraw.sol +3 -2
- package/commands/admin/AllowAssets.sol +3 -2
- package/commands/admin/Allowance.sol +3 -2
- package/commands/admin/Appoint.sol +3 -2
- package/commands/admin/Authorize.sol +7 -12
- package/commands/admin/DenyAssets.sol +3 -2
- package/commands/admin/Dismiss.sol +3 -2
- package/commands/admin/Execute.sol +3 -2
- package/commands/admin/Label.sol +3 -2
- package/commands/admin/Schemas.sol +32 -0
- package/commands/admin/Unauthorize.sol +7 -12
- package/core/Calls.sol +4 -3
- package/core/Endpoint.sol +31 -22
- package/core/Host.sol +11 -3
- package/core/Payable.sol +19 -19
- package/core/Pipeline.sol +17 -14
- package/core/Settlement.sol +39 -0
- package/docs/Schema.md +17 -11
- package/events/Introduction.sol +4 -3
- package/package.json +1 -1
- package/ports/Credit.sol +1 -1
- package/ports/Debit.sol +1 -1
- package/ports/Settle.sol +3 -5
package/commands/Debit.sol
CHANGED
|
@@ -3,34 +3,21 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import { CommandContext, CommandBase, Keys } from "./Base.sol";
|
|
5
5
|
import { Cursors, Cur, Writer, Writers } from "../Cursors.sol";
|
|
6
|
+
import { DebitAccountHook } from "../core/Settlement.sol";
|
|
6
7
|
|
|
7
8
|
using Cursors for Cur;
|
|
8
9
|
using Writers for Writer;
|
|
9
10
|
|
|
10
|
-
abstract contract DebitAccountHook {
|
|
11
|
-
/// @notice Override to debit externally managed funds from `account`.
|
|
12
|
-
/// Called once per AMOUNT block before a matching BALANCE is emitted.
|
|
13
|
-
/// @param account Source account identifier.
|
|
14
|
-
/// @param asset Asset identifier.
|
|
15
|
-
/// @param amount Amount to debit.
|
|
16
|
-
function debitAccount(bytes32 account, bytes32 asset, uint amount) internal virtual;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
11
|
/// @title DebitAccount
|
|
20
12
|
/// @notice Command that deducts AMOUNT blocks from an account and emits matching BALANCE state.
|
|
21
13
|
/// Use for internally recording debits. The virtual `debitAccount` hook is called once per
|
|
22
14
|
/// AMOUNT block; the default batch implementation handles the full request loop.
|
|
23
15
|
abstract contract DebitAccount is CommandBase, DebitAccountHook {
|
|
24
16
|
bytes32 private immutable descriptor;
|
|
25
|
-
uint
|
|
17
|
+
uint internal immutable debitAccountId;
|
|
26
18
|
|
|
27
19
|
constructor() {
|
|
28
|
-
(
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/// @notice Return true if `candidate` is this command's debit account ID.
|
|
32
|
-
function isDebitAccount(uint candidate) internal view returns (bool) {
|
|
33
|
-
return candidate == id;
|
|
20
|
+
(debitAccountId, descriptor) = command("debitAccount", Keys.Empty, Keys.Amount, Keys.Balance, 0, false, false);
|
|
34
21
|
}
|
|
35
22
|
|
|
36
23
|
/// @notice Override to customize request parsing or batching for debits.
|
|
@@ -52,10 +39,11 @@ abstract contract DebitAccount is CommandBase, DebitAccountHook {
|
|
|
52
39
|
/// @notice Debit AMOUNT request blocks from the command account and output matching BALANCE blocks.
|
|
53
40
|
/// @param c Command context; `c.input` must contain AMOUNT blocks.
|
|
54
41
|
/// @return BALANCE block stream matching the debited amounts.
|
|
42
|
+
/// @return Empty transaction stream.
|
|
55
43
|
function debitAccount(
|
|
56
44
|
CommandContext calldata c
|
|
57
|
-
) external onlyCommand returns (bytes memory) {
|
|
58
|
-
return debitAccount(c.account, c.input);
|
|
45
|
+
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
46
|
+
return (debitAccount(c.account, c.input), "");
|
|
59
47
|
}
|
|
60
48
|
}
|
|
61
49
|
|
package/commands/Deposit.sol
CHANGED
|
@@ -44,9 +44,10 @@ abstract contract Deposit is CommandBase, DepositHook {
|
|
|
44
44
|
/// @notice Deposit AMOUNT request blocks into the command account and output matching BALANCE blocks.
|
|
45
45
|
/// @param c Command context; `c.input` must contain AMOUNT blocks.
|
|
46
46
|
/// @return BALANCE block stream matching the deposited amounts.
|
|
47
|
+
/// @return Empty transaction stream.
|
|
47
48
|
function deposit(
|
|
48
49
|
CommandContext calldata c
|
|
49
|
-
) external onlyCommand returns (bytes memory) {
|
|
50
|
+
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
50
51
|
(Cur memory input, uint outputs) = openInput(c.input, descriptor);
|
|
51
52
|
Writer memory output = Writers.allocBalances(outputs);
|
|
52
53
|
|
|
@@ -56,7 +57,7 @@ abstract contract Deposit is CommandBase, DepositHook {
|
|
|
56
57
|
output.appendBalance(asset, amount);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
return output.finish();
|
|
60
|
+
return (output.finish(), "");
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -73,9 +74,10 @@ abstract contract DepositPayable is CommandBase, Payable, DepositPayableHook {
|
|
|
73
74
|
/// @notice Deposit AMOUNT request blocks with access to a mutable native-value budget.
|
|
74
75
|
/// @param c Command context; `c.input` must contain AMOUNT blocks.
|
|
75
76
|
/// @return BALANCE block stream matching the deposited amounts.
|
|
77
|
+
/// @return Remaining native value as a refund transaction stream.
|
|
76
78
|
function depositPayable(
|
|
77
79
|
CommandContext calldata c
|
|
78
|
-
) external payable onlyCommand returns (bytes memory) {
|
|
80
|
+
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
79
81
|
(Cur memory input, uint outputs) = openInput(c.input, descriptor);
|
|
80
82
|
Writer memory output = Writers.allocBalances(outputs);
|
|
81
83
|
Budget memory budget = openValue();
|
|
@@ -86,8 +88,7 @@ abstract contract DepositPayable is CommandBase, Payable, DepositPayableHook {
|
|
|
86
88
|
output.appendBalance(asset, amount);
|
|
87
89
|
}
|
|
88
90
|
|
|
89
|
-
closeValue(c.account
|
|
90
|
-
return output.finish();
|
|
91
|
+
return (output.finish(), closeValue(budget, c.account));
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
|
package/commands/Payout.sol
CHANGED
|
@@ -29,13 +29,14 @@ abstract contract Payout is CommandBase, PayoutHook {
|
|
|
29
29
|
/// @notice Pay out BALANCE state blocks to matching ACCOUNT request blocks.
|
|
30
30
|
/// @param c Command context; `c.state` must contain BALANCE blocks and `c.input` matching ACCOUNT blocks.
|
|
31
31
|
/// @return Empty output state.
|
|
32
|
-
|
|
32
|
+
/// @return Empty transaction stream.
|
|
33
|
+
function payout(CommandContext calldata c) external onlyCommand returns (bytes memory, bytes memory) {
|
|
33
34
|
(Cur memory input, Cur memory state, ) = openCommand(c, descriptor);
|
|
34
35
|
|
|
35
36
|
while (state.i < state.len) {
|
|
36
37
|
(bytes32 asset, uint amount) = state.unpackBalance();
|
|
37
38
|
payout(c.account, input.unpackAccount(), asset, amount);
|
|
38
39
|
}
|
|
39
|
-
return "";
|
|
40
|
+
return ("", "");
|
|
40
41
|
}
|
|
41
42
|
}
|
package/commands/Provision.sol
CHANGED
|
@@ -42,7 +42,8 @@ abstract contract Provision is CommandBase, ProvisionHook {
|
|
|
42
42
|
/// @notice Provision ALLOCATION request blocks and output matching CUSTODY state blocks.
|
|
43
43
|
/// @param c Command context; `c.input` must contain ALLOCATION blocks.
|
|
44
44
|
/// @return CUSTODY block stream matching the provisioned allocations.
|
|
45
|
-
|
|
45
|
+
/// @return Empty transaction stream.
|
|
46
|
+
function provision(CommandContext calldata c) external onlyCommand returns (bytes memory, bytes memory) {
|
|
46
47
|
(Cur memory input, uint outputs) = openInput(c.input, descriptor);
|
|
47
48
|
Writer memory output = Writers.allocCustodies(outputs);
|
|
48
49
|
|
|
@@ -52,7 +53,7 @@ abstract contract Provision is CommandBase, ProvisionHook {
|
|
|
52
53
|
output.appendCustody(allocation);
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
return output.finish();
|
|
56
|
+
return (output.finish(), "");
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
@@ -70,9 +71,10 @@ abstract contract ProvisionPayable is CommandBase, Payable, ProvisionPayableHook
|
|
|
70
71
|
/// @notice Provision ALLOCATION request blocks with access to a mutable native-value budget.
|
|
71
72
|
/// @param c Command context; `c.input` must contain ALLOCATION blocks.
|
|
72
73
|
/// @return CUSTODY block stream matching the provisioned allocations.
|
|
74
|
+
/// @return Remaining native value as a refund transaction stream.
|
|
73
75
|
function provisionPayable(
|
|
74
76
|
CommandContext calldata c
|
|
75
|
-
) external payable onlyCommand returns (bytes memory) {
|
|
77
|
+
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
76
78
|
(Cur memory input, uint outputs) = openInput(c.input, descriptor);
|
|
77
79
|
Writer memory output = Writers.allocCustodies(outputs);
|
|
78
80
|
Budget memory budget = openValue();
|
|
@@ -83,8 +85,7 @@ abstract contract ProvisionPayable is CommandBase, Payable, ProvisionPayableHook
|
|
|
83
85
|
output.appendCustody(allocation);
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
closeValue(c.account
|
|
87
|
-
return output.finish();
|
|
88
|
+
return (output.finish(), closeValue(budget, c.account));
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
|
package/commands/Recover.sol
CHANGED
|
@@ -32,7 +32,8 @@ abstract contract RecoverPayable is CommandBase, Payable, RecoverHook {
|
|
|
32
32
|
/// @notice Recover each recover block in the command request.
|
|
33
33
|
/// @param c Command context; `c.input` must contain Recover blocks.
|
|
34
34
|
/// @return Empty output state.
|
|
35
|
-
|
|
35
|
+
/// @return Remaining native value as a refund transaction stream.
|
|
36
|
+
function recoverPayable(CommandContext calldata c) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
36
37
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
37
38
|
Budget memory budget = openValue();
|
|
38
39
|
|
|
@@ -41,7 +42,6 @@ abstract contract RecoverPayable is CommandBase, Payable, RecoverHook {
|
|
|
41
42
|
recover(handler, key, witness, useValue(budget, resources));
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
closeValue(c.account
|
|
45
|
-
return "";
|
|
45
|
+
return ("", closeValue(budget, c.account));
|
|
46
46
|
}
|
|
47
47
|
}
|
package/commands/Relay.sol
CHANGED
|
@@ -35,14 +35,14 @@ abstract contract RelayPayable is CommandBase, Payable, RoutePayableHook {
|
|
|
35
35
|
/// @notice Relay one RELAY request block with the command account and current state.
|
|
36
36
|
/// @param c Command context; `c.input` must contain exactly one RELAY block.
|
|
37
37
|
/// @return Empty output state.
|
|
38
|
-
|
|
38
|
+
/// @return Remaining native value as a refund transaction stream.
|
|
39
|
+
function relayPayable(CommandContext calldata c) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
39
40
|
(Cur memory input, , ) = openLane(c.input, descriptor, Lane.Input, 1);
|
|
40
41
|
(uint portal, uint resources, bytes memory context) = input.relayToContext(c.account, c.state);
|
|
41
42
|
|
|
42
43
|
Budget memory budget = openValue();
|
|
43
44
|
route(portal, resources, context, budget);
|
|
44
45
|
|
|
45
|
-
closeValue(c.account
|
|
46
|
-
return "";
|
|
46
|
+
return ("", closeValue(budget, c.account));
|
|
47
47
|
}
|
|
48
48
|
}
|
package/commands/Withdraw.sol
CHANGED
|
@@ -28,16 +28,17 @@ abstract contract Withdraw is CommandBase, WithdrawHook {
|
|
|
28
28
|
/// @notice Withdraw each BALANCE block from the command state to the command account.
|
|
29
29
|
/// @param c Command context; `c.state` must contain BALANCE blocks.
|
|
30
30
|
/// @return Empty output state.
|
|
31
|
+
/// @return Empty transaction stream.
|
|
31
32
|
function withdraw(
|
|
32
33
|
CommandContext calldata c
|
|
33
|
-
) external onlyCommand returns (bytes memory) {
|
|
34
|
+
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
34
35
|
(Cur memory state, ) = openState(c.state, descriptor);
|
|
35
36
|
|
|
36
37
|
while (state.i < state.len) {
|
|
37
38
|
(bytes32 asset, uint amount) = state.unpackBalance();
|
|
38
39
|
withdraw(c.account, asset, amount);
|
|
39
40
|
}
|
|
40
|
-
return "";
|
|
41
|
+
return ("", "");
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -25,16 +25,17 @@ abstract contract AllowAssets is AdminBase, AllowAssetsHook {
|
|
|
25
25
|
/// @notice Allow each ASSET block in the admin request.
|
|
26
26
|
/// @param c Admin command context; `c.input` must contain ASSET blocks.
|
|
27
27
|
/// @return Empty output state.
|
|
28
|
+
/// @return Empty transaction stream.
|
|
28
29
|
function allowAssets(
|
|
29
30
|
CommandContext calldata c
|
|
30
|
-
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
31
|
+
) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
31
32
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
32
33
|
|
|
33
34
|
while (input.i < input.len) {
|
|
34
35
|
bytes32 asset = input.unpackAsset();
|
|
35
36
|
allowAsset(asset);
|
|
36
37
|
}
|
|
37
|
-
return "";
|
|
38
|
+
return ("", "");
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -29,13 +29,14 @@ abstract contract Allowance is AdminBase, AllowanceHook {
|
|
|
29
29
|
/// @notice Apply each ALLOWANCE block in the admin request.
|
|
30
30
|
/// @param c Admin command context; `c.input` must contain ALLOWANCE blocks.
|
|
31
31
|
/// @return Empty output state.
|
|
32
|
-
|
|
32
|
+
/// @return Empty transaction stream.
|
|
33
|
+
function allowance(CommandContext calldata c) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
33
34
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
34
35
|
|
|
35
36
|
while (input.i < input.len) {
|
|
36
37
|
(uint peer, bytes32 asset, uint amount) = input.unpackAllowance();
|
|
37
38
|
allowance(peer, asset, amount);
|
|
38
39
|
}
|
|
39
|
-
return "";
|
|
40
|
+
return ("", "");
|
|
40
41
|
}
|
|
41
42
|
}
|
|
@@ -19,15 +19,16 @@ abstract contract Appoint is AdminBase {
|
|
|
19
19
|
/// @notice Appoint each ACCOUNT block in the admin request as a guardian.
|
|
20
20
|
/// @param c Admin command context; `c.input` must contain ACCOUNT blocks.
|
|
21
21
|
/// @return Empty output state.
|
|
22
|
+
/// @return Empty transaction stream.
|
|
22
23
|
function appoint(
|
|
23
24
|
CommandContext calldata c
|
|
24
|
-
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
25
|
+
) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
25
26
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
26
27
|
|
|
27
28
|
while (input.i < input.len) {
|
|
28
29
|
bytes32 account = input.unpackAccount();
|
|
29
30
|
setGuardian(account, true);
|
|
30
31
|
}
|
|
31
|
-
return "";
|
|
32
|
+
return ("", "");
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import {AdminBase, CommandContext, Keys} from "./Base.sol";
|
|
5
|
+
import {Cursors, Cur} from "../../Cursors.sol";
|
|
6
6
|
using Cursors for Cur;
|
|
7
7
|
|
|
8
8
|
/// @title Authorize
|
|
@@ -11,28 +11,23 @@ using Cursors for Cur;
|
|
|
11
11
|
/// Only callable by the admin account.
|
|
12
12
|
abstract contract Authorize is AdminBase {
|
|
13
13
|
bytes32 private immutable descriptor;
|
|
14
|
+
uint internal immutable authorizeId;
|
|
14
15
|
|
|
15
16
|
constructor() {
|
|
16
|
-
(, descriptor) = command("authorize", Keys.Empty, Keys.Node, Keys.Empty, 0, false, true);
|
|
17
|
+
(authorizeId, descriptor) = command("authorize", Keys.Empty, Keys.Node, Keys.Empty, 0, false, true);
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/// @notice Authorize each NODE block in the admin request.
|
|
20
21
|
/// @param c Admin command context; `c.input` must contain NODE blocks.
|
|
21
22
|
/// @return Empty output state.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
23
|
+
/// @return Empty transaction stream.
|
|
24
|
+
function authorize(CommandContext calldata c) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
25
25
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
26
26
|
|
|
27
27
|
while (input.i < input.len) {
|
|
28
28
|
uint node = input.unpackNode();
|
|
29
29
|
setNode(node, true);
|
|
30
30
|
}
|
|
31
|
-
return "";
|
|
31
|
+
return ("", "");
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
@@ -25,16 +25,17 @@ abstract contract DenyAssets is AdminBase, DenyAssetsHook {
|
|
|
25
25
|
/// @notice Deny each ASSET block in the admin request.
|
|
26
26
|
/// @param c Admin command context; `c.input` must contain ASSET blocks.
|
|
27
27
|
/// @return Empty output state.
|
|
28
|
+
/// @return Empty transaction stream.
|
|
28
29
|
function denyAssets(
|
|
29
30
|
CommandContext calldata c
|
|
30
|
-
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
31
|
+
) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
31
32
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
32
33
|
|
|
33
34
|
while (input.i < input.len) {
|
|
34
35
|
bytes32 asset = input.unpackAsset();
|
|
35
36
|
denyAsset(asset);
|
|
36
37
|
}
|
|
37
|
-
return "";
|
|
38
|
+
return ("", "");
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -19,15 +19,16 @@ abstract contract Dismiss is AdminBase {
|
|
|
19
19
|
/// @notice Dismiss each ACCOUNT block in the admin request from guardian status.
|
|
20
20
|
/// @param c Admin command context; `c.input` must contain ACCOUNT blocks.
|
|
21
21
|
/// @return Empty output state.
|
|
22
|
+
/// @return Empty transaction stream.
|
|
22
23
|
function dismiss(
|
|
23
24
|
CommandContext calldata c
|
|
24
|
-
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
25
|
+
) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
25
26
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
26
27
|
|
|
27
28
|
while (input.i < input.len) {
|
|
28
29
|
bytes32 account = input.unpackAccount();
|
|
29
30
|
setGuardian(account, false);
|
|
30
31
|
}
|
|
31
|
-
return "";
|
|
32
|
+
return ("", "");
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -23,7 +23,8 @@ abstract contract ExecutePayable is AdminBase, Payable {
|
|
|
23
23
|
/// @notice Execute each CALL block in the admin request.
|
|
24
24
|
/// @param c Admin command context; `c.input` must contain CALL blocks.
|
|
25
25
|
/// @return Empty output state.
|
|
26
|
-
|
|
26
|
+
/// @return Empty transaction stream.
|
|
27
|
+
function executePayable(CommandContext calldata c) external payable onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
27
28
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
28
29
|
Budget memory budget = openValue();
|
|
29
30
|
|
|
@@ -31,6 +32,6 @@ abstract contract ExecutePayable is AdminBase, Payable {
|
|
|
31
32
|
(uint target, uint resources, bytes calldata data) = input.unpackCall();
|
|
32
33
|
rawCall(target, useValue(budget, resources), data);
|
|
33
34
|
}
|
|
34
|
-
return "";
|
|
35
|
+
return ("", "");
|
|
35
36
|
}
|
|
36
37
|
}
|
package/commands/admin/Label.sol
CHANGED
|
@@ -19,13 +19,14 @@ abstract contract Label is AdminBase {
|
|
|
19
19
|
/// @notice Publish each LABEL block in the admin request.
|
|
20
20
|
/// @param c Admin command context; `c.input` must contain LABEL blocks.
|
|
21
21
|
/// @return Empty output state.
|
|
22
|
-
|
|
22
|
+
/// @return Empty transaction stream.
|
|
23
|
+
function label(CommandContext calldata c) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
23
24
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
24
25
|
|
|
25
26
|
while (input.i < input.len) {
|
|
26
27
|
(uint node, bytes32 namespace, string memory name) = input.unpackLabel();
|
|
27
28
|
emit Labeled(node, namespace, name);
|
|
28
29
|
}
|
|
29
|
-
return "";
|
|
30
|
+
return ("", "");
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {AdminBase, CommandContext, Keys} from "./Base.sol";
|
|
5
|
+
import {Cursors, Cur} from "../../Cursors.sol";
|
|
6
|
+
using Cursors for Cur;
|
|
7
|
+
|
|
8
|
+
/// @title PublishSchema
|
|
9
|
+
/// @notice Admin command that publishes block schemas for keys.
|
|
10
|
+
/// Each SCHEMA block in the request emits one `Schema` event. Only callable by
|
|
11
|
+
/// the admin account.
|
|
12
|
+
abstract contract PublishSchema is AdminBase {
|
|
13
|
+
bytes32 private immutable descriptor;
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
(, descriptor) = command("publishSchema", Keys.Empty, Keys.Schema, Keys.Empty, 0, false, true);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/// @notice Publish each SCHEMA block in the admin request.
|
|
20
|
+
/// @param c Admin command context; `c.input` must contain SCHEMA blocks.
|
|
21
|
+
/// @return Empty output state.
|
|
22
|
+
/// @return Empty transaction stream.
|
|
23
|
+
function publishSchema(CommandContext calldata c) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
24
|
+
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
25
|
+
|
|
26
|
+
while (input.i < input.len) {
|
|
27
|
+
(bytes4 key, string memory body, bytes32 name) = input.unpackSchema();
|
|
28
|
+
emit Schema(host, key, body, name);
|
|
29
|
+
}
|
|
30
|
+
return ("", "");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import {AdminBase, CommandContext, Keys} from "./Base.sol";
|
|
5
|
+
import {Cursors, Cur} from "../../Cursors.sol";
|
|
6
6
|
using Cursors for Cur;
|
|
7
7
|
|
|
8
8
|
/// @title Unauthorize
|
|
@@ -11,28 +11,23 @@ using Cursors for Cur;
|
|
|
11
11
|
/// Only callable by the admin account.
|
|
12
12
|
abstract contract Unauthorize is AdminBase {
|
|
13
13
|
bytes32 private immutable descriptor;
|
|
14
|
+
uint internal immutable unauthorizeId;
|
|
14
15
|
|
|
15
16
|
constructor() {
|
|
16
|
-
(, descriptor) = command("unauthorize", Keys.Empty, Keys.Node, Keys.Empty, 0, false, true);
|
|
17
|
+
(unauthorizeId, descriptor) = command("unauthorize", Keys.Empty, Keys.Node, Keys.Empty, 0, false, true);
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/// @notice Unauthorize each NODE block in the admin request.
|
|
20
21
|
/// @param c Admin command context; `c.input` must contain NODE blocks.
|
|
21
22
|
/// @return Empty output state.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
23
|
+
/// @return Empty transaction stream.
|
|
24
|
+
function unauthorize(CommandContext calldata c) external onlyAdmin(c.account) returns (bytes memory, bytes memory) {
|
|
25
25
|
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
26
26
|
|
|
27
27
|
while (input.i < input.len) {
|
|
28
28
|
uint node = input.unpackNode();
|
|
29
29
|
setNode(node, false);
|
|
30
30
|
}
|
|
31
|
-
return "";
|
|
31
|
+
return ("", "");
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
package/core/Calls.sol
CHANGED
|
@@ -90,17 +90,18 @@ abstract contract CommandCalls is NodeCalls {
|
|
|
90
90
|
/// @param account Command account identifier.
|
|
91
91
|
/// @param state Current command state block stream.
|
|
92
92
|
/// @param request Command input block stream.
|
|
93
|
-
/// @return Decoded command output block stream.
|
|
93
|
+
/// @return nextState Decoded command output state block stream.
|
|
94
|
+
/// @return transactions Decoded command transaction block stream.
|
|
94
95
|
function callCommand(
|
|
95
96
|
uint command,
|
|
96
97
|
uint128 value,
|
|
97
98
|
bytes32 account,
|
|
98
99
|
bytes memory state,
|
|
99
100
|
bytes calldata request
|
|
100
|
-
) internal returns (bytes memory) {
|
|
101
|
+
) internal returns (bytes memory nextState, bytes memory transactions) {
|
|
101
102
|
bytes4 selector = Nodes.commandSelector(command);
|
|
102
103
|
bytes memory data = abi.encodeWithSelector(selector, CommandContext(account, state, request));
|
|
103
|
-
return abi.decode(trustedCall(command, value, data), (bytes));
|
|
104
|
+
return abi.decode(trustedCall(command, value, data), (bytes, bytes));
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
|
package/core/Endpoint.sol
CHANGED
|
@@ -58,21 +58,6 @@ abstract contract EndpointBase is Runtime, EndpointEvent, LabeledEvent, SchemaEv
|
|
|
58
58
|
if (size == 0) size = 1;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
/// @notice Return an 8-byte lane value for a generic LIST containing `item`.
|
|
62
|
-
/// @param item Block key expected inside each LIST payload.
|
|
63
|
-
/// @return Packed lane key `[Keys.List][item]`.
|
|
64
|
-
function many(bytes4 item) internal pure returns (bytes8) {
|
|
65
|
-
return bytes8(bytes.concat(Keys.List, item));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/// @notice Append an explicit group size to an 8-byte lane value.
|
|
69
|
-
/// @param value Packed lane key `[key][item]`.
|
|
70
|
-
/// @param size Explicit per-operation group size for the lane.
|
|
71
|
-
/// @return Packed lane key plus group byte.
|
|
72
|
-
function group(bytes8 value, uint8 size) internal pure returns (bytes9) {
|
|
73
|
-
return bytes9(bytes.concat(value, bytes1(size)));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
61
|
/// @dev Open a descriptor lane and return its effective group and output counts.
|
|
77
62
|
/// An absent lane inherits `expected`; a present lane must match it when nonzero.
|
|
78
63
|
/// @param source Block stream to open for the requested lane.
|
|
@@ -118,14 +103,38 @@ abstract contract EndpointBase is Runtime, EndpointEvent, LabeledEvent, SchemaEv
|
|
|
118
103
|
(input, , outputs) = openLane(source, descriptor, Lane.Input, 0);
|
|
119
104
|
}
|
|
120
105
|
|
|
121
|
-
/// @notice
|
|
122
|
-
/// @param
|
|
106
|
+
/// @notice Return an 8-byte lane value for a generic LIST containing `item`.
|
|
107
|
+
/// @param item Block key expected inside each LIST payload.
|
|
108
|
+
/// @return Packed lane key `[Keys.List][item]`.
|
|
109
|
+
function many(bytes4 item) internal pure returns (bytes8) {
|
|
110
|
+
return bytes8(bytes.concat(Keys.List, item));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/// @notice Append an explicit group size to an 8-byte lane value.
|
|
114
|
+
/// @param value Packed lane key `[key][item]`.
|
|
115
|
+
/// @param size Explicit per-operation group size for the lane.
|
|
116
|
+
/// @return Packed lane key plus group byte.
|
|
117
|
+
function group(bytes8 value, uint8 size) internal pure returns (bytes9) {
|
|
118
|
+
return bytes9(bytes.concat(value, bytes1(size)));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// @notice Publish a context-local block schema and return its key.
|
|
122
|
+
/// @param key Context-local key value.
|
|
123
|
+
/// @param body Schema DSL string describing the block payload body.
|
|
124
|
+
/// @return The context-local block key.
|
|
125
|
+
function schema(uint32 key, string memory body) internal returns (bytes4) {
|
|
126
|
+
return schema(key, body, bytes32(0));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/// @notice Publish a named context-local block schema and return its key.
|
|
130
|
+
/// @param key Context-local key value.
|
|
123
131
|
/// @param body Schema DSL string describing the block payload body.
|
|
124
|
-
/// @param name
|
|
125
|
-
/// @return The
|
|
126
|
-
function schema(
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
/// @param name Schema alias name, or zero for unnamed schemas.
|
|
133
|
+
/// @return The context-local block key.
|
|
134
|
+
function schema(uint32 key, string memory body, bytes32 name) internal returns (bytes4) {
|
|
135
|
+
bytes4 k = bytes4(key);
|
|
136
|
+
emit Schema(host, k, body, name);
|
|
137
|
+
return k;
|
|
129
138
|
}
|
|
130
139
|
|
|
131
140
|
/// @notice Create and publish endpoint metadata with a default label.
|
package/core/Host.sol
CHANGED
|
@@ -23,7 +23,7 @@ interface IHostIntroduction {
|
|
|
23
23
|
|
|
24
24
|
/// @title Host
|
|
25
25
|
/// @notice Abstract base contract for rootzero host implementations.
|
|
26
|
-
/// Inherits admin command support (authorize, unauthorize, executePayable),
|
|
26
|
+
/// Inherits admin command support (authorize, unauthorize, label, executePayable),
|
|
27
27
|
/// guardian management, the default guardian revoke action, and
|
|
28
28
|
/// optionally introduces itself to a commander host at deployment.
|
|
29
29
|
/// Accepts native ETH payments via the `receive` function.
|
|
@@ -43,7 +43,15 @@ abstract contract Host is
|
|
|
43
43
|
/// on it during construction.
|
|
44
44
|
constructor(address cmdr) AccessControl(cmdr) {
|
|
45
45
|
if (cmdr == address(0) || cmdr == address(this) || cmdr.code.length == 0) return;
|
|
46
|
-
|
|
46
|
+
introduceTo(Nodes.toHost(cmdr));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// @notice Introduce this host to the contract address embedded in a local EVM node ID.
|
|
50
|
+
/// @dev Accepts host and endpoint IDs such as commands, ports, queries, and guards.
|
|
51
|
+
/// Reverts when `node` is not local or embeds the zero address.
|
|
52
|
+
/// @param node Local EVM node ID whose underlying contract receives the introduction.
|
|
53
|
+
function introduceTo(uint node) internal {
|
|
54
|
+
IHostIntroduction(Nodes.addr(node)).introduce(host, block.number);
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
/// @notice Record a host introduction claim.
|
|
@@ -51,7 +59,7 @@ abstract contract Host is
|
|
|
51
59
|
/// @param peer Host node ID being introduced.
|
|
52
60
|
/// @param blocknum Block number at which the host was deployed.
|
|
53
61
|
function introduce(uint peer, uint blocknum) external {
|
|
54
|
-
emit Introduction(Nodes.matchHost(peer, msg.sender), blocknum);
|
|
62
|
+
emit Introduction(host, Nodes.matchHost(peer, msg.sender), blocknum);
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
/// @notice Accept native ETH transfers (e.g. from command value flows).
|