@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.
- package/CHANGELOG.md +45 -3
- package/Codec.sol +21 -0
- package/Commands.sol +14 -0
- package/Core.sol +2 -3
- package/Endpoints.sol +1 -5
- package/README.md +34 -30
- package/Utils.sol +2 -4
- package/codec/Blocks.sol +1606 -0
- package/codec/Buffers.sol +165 -0
- package/codec/Decoders.sol +558 -0
- package/codec/Descriptors.sol +124 -0
- package/{blocks → codec}/Keys.sol +4 -16
- package/codec/Readers.sol +114 -0
- package/{blocks → codec}/Schema.sol +38 -80
- package/codec/Specs.sol +218 -0
- package/codec/Writers.sol +487 -0
- package/commands/Allocate.sol +21 -20
- package/commands/Base.sol +71 -37
- package/commands/Burn.sol +18 -13
- package/commands/Credit.sol +21 -20
- package/commands/Debit.sol +25 -28
- package/commands/Deposit.sol +34 -35
- package/commands/Payout.sol +21 -15
- package/commands/Provision.sol +37 -38
- package/commands/Recover.sol +20 -19
- package/commands/Relay.sol +24 -22
- package/commands/Withdraw.sol +15 -18
- package/commands/admin/AllowAssets.sol +19 -16
- package/commands/admin/Allowance.sol +18 -13
- package/commands/admin/Appoint.sol +17 -15
- package/commands/admin/Authorize.sol +23 -14
- package/commands/admin/Base.sol +1 -1
- package/commands/admin/DenyAssets.sol +19 -16
- package/commands/admin/Dismiss.sol +17 -15
- package/commands/admin/Execute.sol +20 -19
- package/commands/admin/Label.sol +17 -13
- package/commands/admin/Schemas.sol +18 -14
- package/commands/admin/Unauthorize.sol +23 -14
- package/core/Calls.sol +3 -11
- package/core/Endpoint.sol +42 -127
- package/core/Pipeline.sol +16 -15
- package/core/Types.sol +1 -1
- package/docs/Schema.md +35 -29
- package/events/Endpoint.sol +2 -2
- package/events/Schema.sol +5 -5
- package/execution/Budget.sol +40 -0
- package/execution/Execution.sol +1083 -0
- package/guards/Base.sol +8 -9
- package/guards/Revoke.sol +11 -9
- package/package.json +1 -1
- package/ports/AllowAssets.sol +12 -15
- package/ports/Allowance.sol +11 -9
- package/ports/Base.sol +18 -11
- package/ports/Credit.sol +11 -9
- package/ports/Debit.sol +11 -9
- package/ports/DenyAssets.sol +10 -13
- package/ports/Dispatch.sol +13 -15
- package/ports/Pipe.sol +14 -12
- package/ports/Redeem.sol +12 -9
- package/ports/Settle.sol +11 -9
- package/queries/Assets.sol +15 -15
- package/queries/Balances.sol +17 -17
- package/queries/Base.sol +11 -12
- package/utils/Actions.sol +1 -0
- package/utils/Cursors.sol +308 -0
- package/utils/Lanes.sol +14 -0
- package/utils/Selectors.sol +2 -2
- package/utils/Utils.sol +46 -0
- package/Cursors.sol +0 -16
- package/blocks/Cursors.sol +0 -1529
- package/blocks/Writers.sol +0 -1036
- package/core/Payable.sol +0 -53
- 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
|
|
21
|
-
///
|
|
22
|
-
/// @param
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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 {
|
|
6
|
-
|
|
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
|
|
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
|
-
|
|
14
|
+
uint private immutable descriptor;
|
|
14
15
|
|
|
15
16
|
constructor() {
|
|
16
|
-
(, descriptor) = guard("revoke",
|
|
17
|
+
(, descriptor) = guard("revoke", Specs.Node);
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
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 (
|
|
23
|
-
uint node =
|
|
24
|
+
while (exec.more()) {
|
|
25
|
+
uint node = exec.unpackNode(Lanes.Input);
|
|
24
26
|
setNode(node, false);
|
|
25
27
|
}
|
|
26
28
|
|
package/package.json
CHANGED
package/ports/AllowAssets.sol
CHANGED
|
@@ -1,37 +1,34 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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
|
|
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
|
|
13
|
+
/// Each ASSET block in the input calls `allowAsset`. Restricted to trusted peers.
|
|
13
14
|
abstract contract PortAllowAssets is PortBase, AllowAssetsHook {
|
|
14
|
-
|
|
15
|
+
uint private immutable descriptor;
|
|
15
16
|
|
|
16
17
|
constructor() {
|
|
17
|
-
(, descriptor) = port("portAllowAssets",
|
|
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
|
-
|
|
25
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
25
26
|
|
|
26
|
-
while (
|
|
27
|
-
bytes32 asset =
|
|
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
|
-
|
package/ports/Allowance.sol
CHANGED
|
@@ -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 {
|
|
6
|
+
import {Specs} from "../Codec.sol";
|
|
7
|
+
import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
7
8
|
|
|
8
|
-
using
|
|
9
|
+
using Executions for Execution;
|
|
9
10
|
|
|
10
11
|
/// @title PortAllowance
|
|
11
|
-
/// @notice Port that lets a trusted peer host
|
|
12
|
-
/// Each AMOUNT block in 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
|
-
|
|
16
|
+
uint private immutable descriptor;
|
|
16
17
|
|
|
17
18
|
constructor() {
|
|
18
|
-
(, descriptor) = port("portAllowance",
|
|
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
|
-
|
|
26
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
26
27
|
uint peer = caller();
|
|
27
28
|
|
|
28
|
-
while (
|
|
29
|
-
(bytes32 asset, uint amount) =
|
|
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
|
|
26
|
-
///
|
|
27
|
-
/// @param
|
|
28
|
-
/// @param
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
bytes4 selector,
|
|
43
|
+
uint input,
|
|
44
|
+
uint output,
|
|
37
45
|
bool funded
|
|
38
|
-
) internal returns (uint id,
|
|
39
|
-
|
|
40
|
-
|
|
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 {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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
|
|
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
|
-
|
|
15
|
+
uint private immutable descriptor;
|
|
15
16
|
|
|
16
17
|
constructor() {
|
|
17
|
-
(, descriptor) = port("portCreditAccount",
|
|
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
|
-
|
|
25
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
25
26
|
|
|
26
|
-
while (
|
|
27
|
-
(bytes32 account, bytes32 asset, uint amount) =
|
|
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 {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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
|
|
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
|
-
|
|
15
|
+
uint private immutable descriptor;
|
|
15
16
|
|
|
16
17
|
constructor() {
|
|
17
|
-
(, descriptor) = port("portDebitAccount",
|
|
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
|
-
|
|
25
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
25
26
|
|
|
26
|
-
while (
|
|
27
|
-
(bytes32 account, bytes32 asset, uint amount) =
|
|
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
|
}
|
package/ports/DenyAssets.sol
CHANGED
|
@@ -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 {
|
|
6
|
+
import {Specs} from "../Codec.sol";
|
|
7
|
+
import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
7
8
|
|
|
8
|
-
using
|
|
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
|
|
13
|
+
/// Each ASSET block in the input calls `denyAsset`. Restricted to trusted peers.
|
|
13
14
|
abstract contract PortDenyAssets is PortBase, DenyAssetsHook {
|
|
14
|
-
|
|
15
|
+
uint private immutable descriptor;
|
|
15
16
|
|
|
16
17
|
constructor() {
|
|
17
|
-
(, descriptor) = port("portDenyAssets",
|
|
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
|
-
|
|
25
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
25
26
|
|
|
26
|
-
while (
|
|
27
|
-
bytes32 asset =
|
|
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
|
-
|
package/ports/Dispatch.sol
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
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
|
-
import {
|
|
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
|
|
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,
|
|
15
|
-
|
|
13
|
+
abstract contract PortDispatchPayable is PortBase, RoutePayableHook {
|
|
14
|
+
uint private immutable descriptor;
|
|
16
15
|
|
|
17
16
|
constructor() {
|
|
18
|
-
(, descriptor) = port("portDispatchPayable",
|
|
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
|
-
|
|
28
|
-
Budget memory budget = openValue();
|
|
26
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
29
27
|
|
|
30
|
-
while (
|
|
31
|
-
(uint portal, uint resources, bytes calldata payload) =
|
|
32
|
-
route(portal, resources, bytes(payload),
|
|
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 {
|
|
7
|
-
import {
|
|
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
|
|
10
|
+
using Executions for Execution;
|
|
10
11
|
|
|
11
12
|
/// @title PortPipePayable
|
|
12
|
-
/// @notice Port that consumes CONTEXT blocks and executes each
|
|
13
|
-
/// Each context's
|
|
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
|
-
|
|
16
|
+
uint private immutable descriptor;
|
|
16
17
|
|
|
17
18
|
constructor() {
|
|
18
|
-
(, descriptor) = port("portPipePayable",
|
|
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
|
-
|
|
28
|
-
Budget memory budget =
|
|
28
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
29
|
+
Budget memory budget = exec.takeBudget();
|
|
29
30
|
|
|
30
|
-
while (
|
|
31
|
-
(bytes32 account, bytes calldata state, bytes calldata
|
|
32
|
-
pipe(account, state,
|
|
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 {
|
|
5
|
+
import {Specs} from "../Codec.sol";
|
|
6
|
+
import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
6
7
|
|
|
7
|
-
using
|
|
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
|
|
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
|
|
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
|
-
|
|
24
|
+
uint private immutable descriptor;
|
|
23
25
|
|
|
24
26
|
constructor() {
|
|
25
|
-
(, descriptor) = port("portRedeemBalance",
|
|
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
|
-
|
|
34
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
33
35
|
uint peer = caller();
|
|
34
36
|
|
|
35
|
-
while (
|
|
36
|
-
(bytes32 asset, uint amount) =
|
|
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 {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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
|
|
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
|
-
|
|
15
|
+
uint private immutable descriptor;
|
|
15
16
|
|
|
16
17
|
constructor() {
|
|
17
|
-
(, descriptor) = port("portSettle",
|
|
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
|
-
|
|
25
|
+
Execution memory exec = openInput(data, descriptor, 0);
|
|
25
26
|
|
|
26
|
-
while (
|
|
27
|
-
(bytes32 from, bytes32 to, bytes32 asset, uint amount) =
|
|
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
|
}
|
package/queries/Assets.sol
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
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
|
|
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
|
|
21
|
-
/// The response returns one `STATUS` form block per query entry, preserving
|
|
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
|
-
|
|
24
|
+
uint private immutable descriptor;
|
|
24
25
|
|
|
25
26
|
constructor() {
|
|
26
|
-
(, descriptor) = query("assetStatus",
|
|
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
|
|
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
|
|
33
|
-
|
|
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 (
|
|
37
|
-
bytes32 asset =
|
|
36
|
+
while (exec.more()) {
|
|
37
|
+
bytes32 asset = exec.unpackAsset(Lanes.Input);
|
|
38
38
|
uint status = assetStatus(asset);
|
|
39
|
-
|
|
39
|
+
exec.outputStatus(status);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
return
|
|
42
|
+
return close(exec);
|
|
43
43
|
}
|
|
44
44
|
}
|