@rootzero/contracts 1.25.0 → 1.26.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 +101 -0
- package/Codec.sol +1 -2
- package/Endpoints.sol +2 -0
- package/README.md +61 -51
- package/Utils.sol +2 -1
- package/codec/Blocks.sol +276 -88
- package/codec/Buffers.sol +24 -20
- package/codec/Decoders.sol +35 -37
- package/codec/Descriptors.sol +75 -72
- package/codec/Keys.sol +5 -1
- package/codec/Schema.sol +5 -1
- package/codec/Specs.sol +19 -9
- package/codec/Writers.sol +14 -19
- package/commands/Allocate.sol +8 -7
- package/commands/Base.sol +14 -49
- package/commands/Bootstrap.sol +95 -0
- package/commands/Burn.sol +7 -7
- package/commands/Cashout.sol +85 -0
- package/commands/Credit.sol +18 -16
- package/commands/Debit.sol +23 -19
- package/commands/Deposit.sol +13 -13
- package/commands/Payout.sol +8 -8
- package/commands/Provision.sol +13 -13
- package/commands/Recover.sol +7 -7
- package/commands/Relay.sol +22 -23
- package/commands/Repay.sol +36 -34
- package/commands/Settle.sol +24 -22
- package/commands/Withdraw.sol +7 -7
- package/commands/admin/AllowAssets.sol +7 -7
- package/commands/admin/Allowance.sol +7 -7
- package/commands/admin/Annotate.sol +7 -7
- package/commands/admin/Appoint.sol +7 -7
- package/commands/admin/Authorize.sol +7 -7
- package/commands/admin/Base.sol +5 -8
- package/commands/admin/DenyAssets.sol +7 -7
- package/commands/admin/Dismiss.sol +7 -7
- package/commands/admin/Execute.sol +8 -8
- package/commands/admin/Unauthorize.sol +7 -7
- package/core/Calls.sol +3 -3
- package/core/Endpoint.sol +7 -7
- package/core/Pipeline.sol +19 -20
- package/execution/Budget.sol +2 -3
- package/execution/Execution.sol +271 -509
- package/guards/Base.sol +1 -1
- package/guards/Revoke.sol +7 -7
- package/package.json +1 -1
- package/ports/Allowance.sol +3 -3
- package/ports/Assets.sol +7 -7
- package/ports/Base.sol +1 -1
- package/ports/Credit.sol +3 -3
- package/ports/Debit.sol +3 -3
- package/ports/Dispatch.sol +3 -3
- package/ports/Pipe.sol +3 -3
- package/ports/Post.sol +3 -3
- package/ports/Redeem.sol +3 -3
- package/queries/Assets.sol +3 -3
- package/queries/Balances.sol +3 -3
- package/queries/Base.sol +1 -1
- package/utils/Accounts.sol +1 -3
- package/utils/Actions.sol +2 -0
- package/utils/Assets.sol +1 -10
- package/utils/Cursors.sol +60 -116
- package/utils/Errors.sol +50 -0
- package/utils/Ids.sol +2 -5
- package/utils/Lanes.sol +0 -2
- package/utils/Nodes.sol +1 -3
- package/utils/Utils.sol +2 -9
- package/codec/Readers.sol +0 -190
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Flags,
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @notice Hook implemented by hosts that configure peer asset allowances.
|
|
@@ -23,23 +23,23 @@ abstract contract Allowance is AdminBase, AllowanceHook {
|
|
|
23
23
|
uint private immutable descriptor;
|
|
24
24
|
|
|
25
25
|
constructor() {
|
|
26
|
-
(, descriptor) = command("allowance", Specs.Empty, Specs.Allowance, Specs.Empty,
|
|
26
|
+
(, descriptor) = command("allowance", Specs.Empty, Specs.Allowance, Specs.Empty, Flags.Admin);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/// @notice Apply each ALLOWANCE block in the admin input.
|
|
30
30
|
/// @param context Admin command context carrying the ALLOWANCE input stream.
|
|
31
31
|
/// @return Empty output state.
|
|
32
|
-
/// @return
|
|
32
|
+
/// @return Zero native budget credit.
|
|
33
33
|
function allowance(
|
|
34
34
|
bytes calldata context
|
|
35
|
-
) external returns (bytes memory,
|
|
36
|
-
Execution memory exec = openAdminCommand(context, descriptor
|
|
35
|
+
) external returns (bytes memory, uint) {
|
|
36
|
+
Execution memory exec = openAdminCommand(context, descriptor);
|
|
37
37
|
|
|
38
38
|
while (exec.more()) {
|
|
39
|
-
(uint peer, bytes32 asset, uint amount) = exec.unpackAllowance(
|
|
39
|
+
(uint peer, bytes32 asset, uint amount) = exec.unpackAllowance();
|
|
40
40
|
allowance(peer, asset, amount);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
return
|
|
43
|
+
return exec.close();
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Flags,
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @title Annotate
|
|
@@ -12,23 +12,23 @@ abstract contract Annotate is AdminBase {
|
|
|
12
12
|
uint private immutable descriptor;
|
|
13
13
|
|
|
14
14
|
constructor() {
|
|
15
|
-
(, descriptor) = command("annotate", Specs.Empty, Specs.Annotation, Specs.Empty,
|
|
15
|
+
(, descriptor) = command("annotate", Specs.Empty, Specs.Annotation, Specs.Empty, Flags.Admin);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/// @notice Publish each ANNOTATION block in the admin input.
|
|
19
19
|
/// @param context Admin command context carrying the ANNOTATION input stream.
|
|
20
20
|
/// @return Empty output state.
|
|
21
|
-
/// @return
|
|
21
|
+
/// @return Zero native budget credit.
|
|
22
22
|
function annotate(
|
|
23
23
|
bytes calldata context
|
|
24
|
-
) external returns (bytes memory,
|
|
25
|
-
Execution memory exec = openAdminCommand(context, descriptor
|
|
24
|
+
) external returns (bytes memory, uint) {
|
|
25
|
+
Execution memory exec = openAdminCommand(context, descriptor);
|
|
26
26
|
|
|
27
27
|
while (exec.more()) {
|
|
28
|
-
(uint entity, bytes calldata data) = exec.unpackAnnotation(
|
|
28
|
+
(uint entity, bytes calldata data) = exec.unpackAnnotation();
|
|
29
29
|
emit Annotation(entity, data);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
return
|
|
32
|
+
return exec.close();
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { AdminBase, Execution, Executions, Flags,
|
|
4
|
+
import { AdminBase, Execution, Executions, Flags, Specs } from "./Base.sol";
|
|
5
5
|
import { GuardianAccess } from "../../core/Access.sol";
|
|
6
6
|
using Executions for Execution;
|
|
7
7
|
|
|
@@ -13,23 +13,23 @@ abstract contract Appoint is GuardianAccess, AdminBase {
|
|
|
13
13
|
uint private immutable descriptor;
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
|
-
(, descriptor) = command("appoint", Specs.Empty, Specs.Account, Specs.Empty,
|
|
16
|
+
(, descriptor) = command("appoint", Specs.Empty, Specs.Account, Specs.Empty, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Appoint each user ACCOUNT block in the admin input as a guardian.
|
|
20
20
|
/// @param context Admin command context carrying the ACCOUNT input stream.
|
|
21
21
|
/// @return Empty output state.
|
|
22
|
-
/// @return
|
|
22
|
+
/// @return Zero native budget credit.
|
|
23
23
|
function appoint(
|
|
24
24
|
bytes calldata context
|
|
25
|
-
) external returns (bytes memory,
|
|
26
|
-
Execution memory exec = openAdminCommand(context, descriptor
|
|
25
|
+
) external returns (bytes memory, uint) {
|
|
26
|
+
Execution memory exec = openAdminCommand(context, descriptor);
|
|
27
27
|
|
|
28
28
|
while (exec.more()) {
|
|
29
|
-
bytes32 guardian = exec.unpackAccount(
|
|
29
|
+
bytes32 guardian = exec.unpackAccount();
|
|
30
30
|
setGuardian(guardian, true);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
return
|
|
33
|
+
return exec.close();
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Flags,
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @title Authorize
|
|
@@ -13,7 +13,7 @@ abstract contract Authorize is AdminBase {
|
|
|
13
13
|
uint private immutable id;
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
|
-
(id, descriptor) = command("authorize", Specs.Empty, Specs.Node, Specs.Empty,
|
|
16
|
+
(id, descriptor) = command("authorize", Specs.Empty, Specs.Node, Specs.Empty, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Return the registered AUTHORIZE command ID.
|
|
@@ -24,17 +24,17 @@ abstract contract Authorize is AdminBase {
|
|
|
24
24
|
/// @notice Authorize each NODE block in the admin input.
|
|
25
25
|
/// @param context Admin command context carrying the NODE input stream.
|
|
26
26
|
/// @return Empty output state.
|
|
27
|
-
/// @return
|
|
27
|
+
/// @return Zero native budget credit.
|
|
28
28
|
function authorize(
|
|
29
29
|
bytes calldata context
|
|
30
|
-
) external returns (bytes memory,
|
|
31
|
-
Execution memory exec = openAdminCommand(context, descriptor
|
|
30
|
+
) external returns (bytes memory, uint) {
|
|
31
|
+
Execution memory exec = openAdminCommand(context, descriptor);
|
|
32
32
|
|
|
33
33
|
while (exec.more()) {
|
|
34
|
-
uint node = exec.unpackNode(
|
|
34
|
+
uint node = exec.unpackNode();
|
|
35
35
|
setNode(node, true);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
return
|
|
38
|
+
return exec.close();
|
|
39
39
|
}
|
|
40
40
|
}
|
package/commands/admin/Base.sol
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {CommandBase, Execution, Executions, Flags,
|
|
4
|
+
import {CommandBase, Execution, Executions, Flags, Specs} from "../Base.sol";
|
|
5
5
|
import {NodeAccess} from "../../core/Access.sol";
|
|
6
6
|
|
|
7
7
|
/// @title AdminBase
|
|
8
8
|
/// @notice Shared base for admin commands.
|
|
9
9
|
abstract contract AdminBase is NodeAccess, CommandBase {
|
|
10
|
-
/// @notice
|
|
10
|
+
/// @notice Open and authorize one admin command context.
|
|
11
11
|
function openAdminCommand(
|
|
12
12
|
bytes calldata context,
|
|
13
|
-
uint descriptor
|
|
14
|
-
uint batches
|
|
13
|
+
uint descriptor
|
|
15
14
|
) internal view returns (Execution memory exec) {
|
|
16
|
-
|
|
17
|
-
enforceAdmin(account, msg.sender);
|
|
18
|
-
exec = Executions.open(state, input, descriptor, batches);
|
|
19
|
-
exec.account = account;
|
|
15
|
+
exec = openCommand(context, descriptor);
|
|
16
|
+
enforceAdmin(exec.account, msg.sender);
|
|
20
17
|
}
|
|
21
18
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Flags,
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @notice Hook implemented by hosts that deny assets.
|
|
@@ -19,23 +19,23 @@ abstract contract DenyAssets is AdminBase, DenyAssetsHook {
|
|
|
19
19
|
uint private immutable descriptor;
|
|
20
20
|
|
|
21
21
|
constructor() {
|
|
22
|
-
(, descriptor) = command("denyAssets", Specs.Empty, Specs.Asset, Specs.Empty,
|
|
22
|
+
(, descriptor) = command("denyAssets", Specs.Empty, Specs.Asset, Specs.Empty, Flags.Admin);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/// @notice Deny each ASSET block in the admin input.
|
|
26
26
|
/// @param context Admin command context carrying the ASSET input stream.
|
|
27
27
|
/// @return Empty output state.
|
|
28
|
-
/// @return
|
|
28
|
+
/// @return Zero native budget credit.
|
|
29
29
|
function denyAssets(
|
|
30
30
|
bytes calldata context
|
|
31
|
-
) external returns (bytes memory,
|
|
32
|
-
Execution memory exec = openAdminCommand(context, descriptor
|
|
31
|
+
) external returns (bytes memory, uint) {
|
|
32
|
+
Execution memory exec = openAdminCommand(context, descriptor);
|
|
33
33
|
|
|
34
34
|
while (exec.more()) {
|
|
35
|
-
bytes32 asset = exec.unpackAsset(
|
|
35
|
+
bytes32 asset = exec.unpackAsset();
|
|
36
36
|
denyAsset(asset);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
return
|
|
39
|
+
return exec.close();
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { AdminBase, Execution, Executions, Flags,
|
|
4
|
+
import { AdminBase, Execution, Executions, Flags, Specs } from "./Base.sol";
|
|
5
5
|
import { GuardianAccess } from "../../core/Access.sol";
|
|
6
6
|
using Executions for Execution;
|
|
7
7
|
|
|
@@ -13,23 +13,23 @@ abstract contract Dismiss is GuardianAccess, AdminBase {
|
|
|
13
13
|
uint private immutable descriptor;
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
|
-
(, descriptor) = command("dismiss", Specs.Empty, Specs.Account, Specs.Empty,
|
|
16
|
+
(, descriptor) = command("dismiss", Specs.Empty, Specs.Account, Specs.Empty, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Dismiss each user ACCOUNT block in the admin input from guardian status.
|
|
20
20
|
/// @param context Admin command context carrying the ACCOUNT input stream.
|
|
21
21
|
/// @return Empty output state.
|
|
22
|
-
/// @return
|
|
22
|
+
/// @return Zero native budget credit.
|
|
23
23
|
function dismiss(
|
|
24
24
|
bytes calldata context
|
|
25
|
-
) external returns (bytes memory,
|
|
26
|
-
Execution memory exec = openAdminCommand(context, descriptor
|
|
25
|
+
) external returns (bytes memory, uint) {
|
|
26
|
+
Execution memory exec = openAdminCommand(context, descriptor);
|
|
27
27
|
|
|
28
28
|
while (exec.more()) {
|
|
29
|
-
bytes32 guardian = exec.unpackAccount(
|
|
29
|
+
bytes32 guardian = exec.unpackAccount();
|
|
30
30
|
setGuardian(guardian, false);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
return
|
|
33
|
+
return exec.close();
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Flags,
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Specs} from "./Base.sol";
|
|
5
5
|
import {RawNodeCalls} from "../../core/Calls.sol";
|
|
6
6
|
|
|
7
7
|
using Executions for Execution;
|
|
@@ -10,28 +10,28 @@ using Executions for Execution;
|
|
|
10
10
|
/// @notice Admin command that forwards raw calldata to one or more target nodes.
|
|
11
11
|
/// Each CALL block specifies a target node ID, packed resources, and raw calldata payload.
|
|
12
12
|
/// Only callable by the admin account.
|
|
13
|
-
/// Unspent top-level `msg.value` is returned as
|
|
13
|
+
/// Unspent top-level `msg.value` is returned as native budget credit.
|
|
14
14
|
abstract contract ExecutePayable is RawNodeCalls, AdminBase {
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
|
18
|
-
(, descriptor) = command("executePayable", Specs.Empty, Specs.Call, Specs.Empty,
|
|
18
|
+
(, descriptor) = command("executePayable", Specs.Empty, Specs.Call, Specs.Empty, Flags.AdminFunded);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/// @notice Execute each CALL block in the admin input.
|
|
22
22
|
/// @param context Admin command context carrying the CALL input stream.
|
|
23
23
|
/// @return Empty output state.
|
|
24
|
-
/// @return
|
|
24
|
+
/// @return Native value to add to the caller's budget.
|
|
25
25
|
function executePayable(
|
|
26
26
|
bytes calldata context
|
|
27
|
-
) external payable returns (bytes memory,
|
|
28
|
-
Execution memory exec = openAdminCommand(context, descriptor
|
|
27
|
+
) external payable returns (bytes memory, uint) {
|
|
28
|
+
Execution memory exec = openAdminCommand(context, descriptor);
|
|
29
29
|
|
|
30
30
|
while (exec.more()) {
|
|
31
|
-
(uint target, uint resources, bytes calldata data) = exec.unpackCall(
|
|
31
|
+
(uint target, uint resources, bytes calldata data) = exec.unpackCall();
|
|
32
32
|
rawCall(target, exec.useResourceValue(resources), data);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
return
|
|
35
|
+
return exec.close();
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Flags,
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @title Unauthorize
|
|
@@ -13,7 +13,7 @@ abstract contract Unauthorize is AdminBase {
|
|
|
13
13
|
uint private immutable id;
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
|
-
(id, descriptor) = command("unauthorize", Specs.Empty, Specs.Node, Specs.Empty,
|
|
16
|
+
(id, descriptor) = command("unauthorize", Specs.Empty, Specs.Node, Specs.Empty, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Return the registered UNAUTHORIZE command ID.
|
|
@@ -24,17 +24,17 @@ abstract contract Unauthorize is AdminBase {
|
|
|
24
24
|
/// @notice Unauthorize each NODE block in the admin input.
|
|
25
25
|
/// @param context Admin command context carrying the NODE input stream.
|
|
26
26
|
/// @return Empty output state.
|
|
27
|
-
/// @return
|
|
27
|
+
/// @return Zero native budget credit.
|
|
28
28
|
function unauthorize(
|
|
29
29
|
bytes calldata context
|
|
30
|
-
) external returns (bytes memory,
|
|
31
|
-
Execution memory exec = openAdminCommand(context, descriptor
|
|
30
|
+
) external returns (bytes memory, uint) {
|
|
31
|
+
Execution memory exec = openAdminCommand(context, descriptor);
|
|
32
32
|
|
|
33
33
|
while (exec.more()) {
|
|
34
|
-
uint node = exec.unpackNode(
|
|
34
|
+
uint node = exec.unpackNode();
|
|
35
35
|
setNode(node, false);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
return
|
|
38
|
+
return exec.close();
|
|
39
39
|
}
|
|
40
40
|
}
|
package/core/Calls.sol
CHANGED
|
@@ -135,17 +135,17 @@ abstract contract CommandCalls is NodeCalls {
|
|
|
135
135
|
/// @param state Current command state block stream.
|
|
136
136
|
/// @param input Command input block stream.
|
|
137
137
|
/// @return nextState Decoded command output state block stream.
|
|
138
|
-
/// @return
|
|
138
|
+
/// @return credit Trusted native value to add to the caller's execution budget.
|
|
139
139
|
function callCommand(
|
|
140
140
|
uint command,
|
|
141
141
|
uint128 value,
|
|
142
142
|
bytes32 account,
|
|
143
143
|
bytes memory state,
|
|
144
144
|
bytes calldata input
|
|
145
|
-
) internal returns (bytes memory nextState,
|
|
145
|
+
) internal returns (bytes memory nextState, uint credit) {
|
|
146
146
|
bytes4 selector = Nodes.commandSelector(command);
|
|
147
147
|
bytes memory data = encodeCommandCall(selector, account, state, input);
|
|
148
|
-
return abi.decode(trustedCall(command, value, data), (bytes,
|
|
148
|
+
return abi.decode(trustedCall(command, value, data), (bytes, uint));
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
package/core/Endpoint.sol
CHANGED
|
@@ -7,6 +7,8 @@ import {Label} from "../annotations/Label.sol";
|
|
|
7
7
|
import {Schema} from "../annotations/Schema.sol";
|
|
8
8
|
import {Descriptors} from "../codec/Descriptors.sol";
|
|
9
9
|
|
|
10
|
+
using Descriptors for uint;
|
|
11
|
+
|
|
10
12
|
/// @title EndpointBase
|
|
11
13
|
/// @notice Shared endpoint metadata helpers.
|
|
12
14
|
abstract contract EndpointBase is EndpointEvent, Label, Schema {
|
|
@@ -16,7 +18,6 @@ abstract contract EndpointBase is EndpointEvent, Label, Schema {
|
|
|
16
18
|
/// @param state State block specification.
|
|
17
19
|
/// @param input Input block specification.
|
|
18
20
|
/// @param output Output block specification.
|
|
19
|
-
/// @param transactions Number of transaction blocks produced per batch, or zero for none.
|
|
20
21
|
/// @param flags Packed endpoint behavior flags.
|
|
21
22
|
/// @return descriptor Packed endpoint lane metadata and flags.
|
|
22
23
|
function endpoint(
|
|
@@ -25,10 +26,9 @@ abstract contract EndpointBase is EndpointEvent, Label, Schema {
|
|
|
25
26
|
uint state,
|
|
26
27
|
uint input,
|
|
27
28
|
uint output,
|
|
28
|
-
uint8 transactions,
|
|
29
29
|
uint8 flags
|
|
30
30
|
) internal returns (uint descriptor) {
|
|
31
|
-
descriptor = Descriptors.create(state, input, output,
|
|
31
|
+
descriptor = Descriptors.create(state, input, output, flags);
|
|
32
32
|
return endpoint(id, name, descriptor);
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -56,12 +56,12 @@ abstract contract EndpointBase is EndpointEvent, Label, Schema {
|
|
|
56
56
|
/// Commands intentionally do not inherit this base because they must open state
|
|
57
57
|
/// and input together through `openCommand`.
|
|
58
58
|
abstract contract InputEndpointBase is EndpointBase {
|
|
59
|
-
/// @notice Open
|
|
59
|
+
/// @notice Open a bounded endpoint input stream.
|
|
60
60
|
function openInput(
|
|
61
61
|
bytes calldata input,
|
|
62
|
-
uint descriptor
|
|
63
|
-
uint batches
|
|
62
|
+
uint descriptor
|
|
64
63
|
) internal view returns (Execution memory exec) {
|
|
65
|
-
|
|
64
|
+
exec.budget = msg.value;
|
|
65
|
+
(exec.decoders, exec.writer) = descriptor.openInput(input);
|
|
66
66
|
}
|
|
67
67
|
}
|
package/core/Pipeline.sol
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
using Decoders for Cur;
|
|
9
|
-
using Readers for Reader;
|
|
4
|
+
import {Blocks} from "../codec/Blocks.sol";
|
|
5
|
+
import {Cursors} from "../utils/Cursors.sol";
|
|
6
|
+
import {InsufficientValue, OutOfBounds} from "../utils/Errors.sol";
|
|
10
7
|
|
|
11
8
|
/// @notice Hook implemented by hosts that execute encoded step streams.
|
|
12
9
|
abstract contract PipeHook {
|
|
@@ -21,28 +18,28 @@ abstract contract PipeHook {
|
|
|
21
18
|
|
|
22
19
|
/// @title Pipeline
|
|
23
20
|
/// @notice Core pipeline functionality shared by higher-level surfaces.
|
|
24
|
-
abstract contract Pipeline is PipeHook
|
|
21
|
+
abstract contract Pipeline is PipeHook {
|
|
25
22
|
/// @dev Thrown when the pipeline finishes with non-empty threaded state.
|
|
26
23
|
error UnexpectedState();
|
|
27
24
|
|
|
28
25
|
/// @notice Override to dispatch one piped step.
|
|
29
26
|
/// Called once per STEP block. The returned state becomes the state passed to
|
|
30
27
|
/// the next step, and the final returned state must be empty. Returned
|
|
31
|
-
///
|
|
28
|
+
/// credit is added to the shared native-value budget before the next step runs.
|
|
32
29
|
/// @param cmd Command node ID to invoke or handle.
|
|
33
30
|
/// @param account Account identifier for the piped context.
|
|
34
31
|
/// @param state Current threaded state block stream.
|
|
35
32
|
/// @param input Step input block stream.
|
|
36
33
|
/// @param value Native EVM value assigned to this step.
|
|
37
34
|
/// @return output Updated state block stream for the next step.
|
|
38
|
-
/// @return
|
|
35
|
+
/// @return credit Trusted native value to add to the pipeline budget.
|
|
39
36
|
function dispatch(
|
|
40
37
|
uint cmd,
|
|
41
38
|
bytes32 account,
|
|
42
39
|
bytes memory state,
|
|
43
40
|
bytes calldata input,
|
|
44
41
|
uint128 value
|
|
45
|
-
) internal virtual returns (bytes memory output,
|
|
42
|
+
) internal virtual returns (bytes memory output, uint credit);
|
|
46
43
|
|
|
47
44
|
/// @notice Execute a STEP block stream through the pipeline.
|
|
48
45
|
/// @dev Reverts with `UnexpectedState` if the final threaded state is non-empty.
|
|
@@ -58,19 +55,21 @@ abstract contract Pipeline is PipeHook, PostHook {
|
|
|
58
55
|
bytes calldata steps,
|
|
59
56
|
uint budget
|
|
60
57
|
) internal virtual override returns (uint remaining) {
|
|
61
|
-
|
|
58
|
+
(uint abs, uint end) = Cursors.bounds(steps);
|
|
62
59
|
|
|
63
|
-
while (
|
|
64
|
-
|
|
60
|
+
while (abs < end) {
|
|
61
|
+
uint cmd;
|
|
65
62
|
uint128 value;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
post(from, to, asset, amount);
|
|
63
|
+
bytes calldata input;
|
|
64
|
+
(cmd, value, input, abs) = Blocks.unpackStep(abs);
|
|
65
|
+
if (abs > end) revert OutOfBounds();
|
|
66
|
+
if (value > budget) revert InsufficientValue();
|
|
67
|
+
unchecked {
|
|
68
|
+
budget -= value;
|
|
73
69
|
}
|
|
70
|
+
uint credit;
|
|
71
|
+
(state, credit) = dispatch(cmd, account, state, input, value);
|
|
72
|
+
budget += credit;
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
if (state.length != 0) revert UnexpectedState();
|
package/execution/Budget.sol
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
+
import {InsufficientValue} from "../utils/Errors.sol";
|
|
5
|
+
|
|
4
6
|
/// @notice Mutable native-value budget shared across internal calls.
|
|
5
7
|
struct Budget {
|
|
6
8
|
/// @dev Remaining unspent native value in wei.
|
|
@@ -10,9 +12,6 @@ struct Budget {
|
|
|
10
12
|
/// @title Budgets
|
|
11
13
|
/// @notice Opening and mutation helpers for standalone native-value budgets.
|
|
12
14
|
library Budgets {
|
|
13
|
-
/// @dev Thrown when an operation attempts to spend more value than remains.
|
|
14
|
-
error InsufficientValue();
|
|
15
|
-
|
|
16
15
|
/// @notice Open a standalone budget containing the current call value.
|
|
17
16
|
/// @return budget Budget initialized with `msg.value`.
|
|
18
17
|
function open() internal view returns (Budget memory budget) {
|