@rootzero/contracts 1.20.0 → 1.21.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 +34 -0
- package/Codec.sol +1 -1
- package/Commands.sol +1 -0
- package/Endpoints.sol +1 -0
- package/Events.sol +2 -2
- package/README.md +16 -10
- package/codec/Decoders.sol +9 -1
- package/codec/Descriptors.sol +28 -28
- package/codec/Schema.sol +5 -5
- package/codec/Specs.sol +9 -27
- package/commands/Allocate.sol +1 -1
- package/commands/Base.sol +3 -8
- package/commands/Burn.sol +1 -1
- package/commands/Credit.sol +1 -1
- package/commands/Debit.sol +1 -1
- package/commands/Deposit.sol +3 -10
- package/commands/Payout.sol +1 -1
- package/commands/Provision.sol +3 -3
- package/commands/Recover.sol +3 -3
- package/commands/Relay.sol +3 -3
- package/commands/Repay.sol +3 -3
- package/commands/Settle.sol +3 -3
- package/commands/Withdraw.sol +1 -1
- package/commands/admin/AllowAssets.sol +2 -2
- package/commands/admin/Allowance.sol +2 -2
- package/commands/admin/Annotate.sol +2 -2
- package/commands/admin/Appoint.sol +2 -2
- package/commands/admin/Authorize.sol +2 -2
- package/commands/admin/Base.sol +1 -1
- package/commands/admin/DenyAssets.sol +2 -8
- package/commands/admin/Dismiss.sol +2 -2
- package/commands/admin/Execute.sol +2 -2
- package/commands/admin/Unauthorize.sol +2 -2
- package/core/Portal.sol +11 -8
- package/docs/Schema.md +53 -29
- package/events/Resolved.sol +17 -0
- package/events/Unresolved.sol +18 -0
- package/execution/Execution.sol +10 -1
- package/package.json +1 -1
- package/ports/AllowAssets.sol +1 -1
- package/ports/Allowance.sol +1 -1
- package/ports/Base.sol +3 -3
- package/ports/Credit.sol +1 -1
- package/ports/Debit.sol +1 -1
- package/ports/DenyAssets.sol +1 -1
- package/ports/Dispatch.sol +2 -1
- package/ports/Pipe.sol +2 -1
- package/ports/Post.sol +1 -1
- package/ports/Redeem.sol +1 -1
- package/events/Recovered.sol +0 -17
- package/events/Undelivered.sol +0 -18
package/commands/Settle.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {Execution, Executions, CommandBase, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
import {SettleHook} from "../core/Settlement.sol";
|
|
6
6
|
import {Action} from "../annotations/Action.sol";
|
|
7
7
|
import {Actions} from "../utils/Actions.sol";
|
|
@@ -37,7 +37,7 @@ abstract contract Settle is CommandBase, SettleHook, Action {
|
|
|
37
37
|
uint private immutable id;
|
|
38
38
|
|
|
39
39
|
constructor() {
|
|
40
|
-
(id, descriptor) = command("settle", Specs.Position, Specs.Empty, Specs.Empty, 0,
|
|
40
|
+
(id, descriptor) = command("settle", Specs.Position, Specs.Empty, Specs.Empty, 0, 0);
|
|
41
41
|
action(id, Actions.Settle);
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -73,7 +73,7 @@ abstract contract SettlePayable is CommandBase, SettlePayableHook, Action {
|
|
|
73
73
|
|
|
74
74
|
constructor() {
|
|
75
75
|
uint id;
|
|
76
|
-
(id, descriptor) = command("settlePayable", Specs.Position, Specs.Empty, Specs.Empty, 0,
|
|
76
|
+
(id, descriptor) = command("settlePayable", Specs.Position, Specs.Empty, Specs.Empty, 0, Flags.Funded);
|
|
77
77
|
action(id, Actions.Settle);
|
|
78
78
|
}
|
|
79
79
|
|
package/commands/Withdraw.sol
CHANGED
|
@@ -25,7 +25,7 @@ abstract contract Withdraw is CommandBase, WithdrawHook, Action {
|
|
|
25
25
|
|
|
26
26
|
constructor() {
|
|
27
27
|
uint id;
|
|
28
|
-
(id, descriptor) = command("withdraw", Specs.Balance, Specs.Empty, Specs.Empty, 0,
|
|
28
|
+
(id, descriptor) = command("withdraw", Specs.Balance, Specs.Empty, Specs.Empty, 0, 0);
|
|
29
29
|
action(id, Actions.Withdraw);
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -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, Lanes, Specs } from "./Base.sol";
|
|
4
|
+
import { AdminBase, Execution, Executions, Flags, Lanes, Specs } from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @notice Hook implemented by hosts that allow assets.
|
|
@@ -19,7 +19,7 @@ abstract contract AllowAssets is AdminBase, AllowAssetsHook {
|
|
|
19
19
|
uint private immutable descriptor;
|
|
20
20
|
|
|
21
21
|
constructor() {
|
|
22
|
-
(, descriptor) = command("allowAssets", Specs.Empty, Specs.Asset, Specs.Empty, 0,
|
|
22
|
+
(, descriptor) = command("allowAssets", Specs.Empty, Specs.Asset, Specs.Empty, 0, Flags.Admin);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/// @notice Allow each ASSET block in the admin input.
|
|
@@ -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, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, 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,7 +23,7 @@ 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, 0,
|
|
26
|
+
(, descriptor) = command("allowance", Specs.Empty, Specs.Allowance, Specs.Empty, 0, Flags.Admin);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/// @notice Apply each ALLOWANCE block in the admin input.
|
|
@@ -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, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @title Annotate
|
|
@@ -12,7 +12,7 @@ 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, 0,
|
|
15
|
+
(, descriptor) = command("annotate", Specs.Empty, Specs.Annotation, Specs.Empty, 0, Flags.Admin);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/// @notice Publish each ANNOTATION block in the admin input.
|
|
@@ -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, Lanes, Specs } from "./Base.sol";
|
|
4
|
+
import { AdminBase, Execution, Executions, Flags, Lanes, Specs } from "./Base.sol";
|
|
5
5
|
import { GuardianAccess } from "../../core/Access.sol";
|
|
6
6
|
using Executions for Execution;
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ 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, 0,
|
|
16
|
+
(, descriptor) = command("appoint", Specs.Empty, Specs.Account, Specs.Empty, 0, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Appoint each user ACCOUNT block in the admin input as a guardian.
|
|
@@ -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, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, 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, 0,
|
|
16
|
+
(id, descriptor) = command("authorize", Specs.Empty, Specs.Node, Specs.Empty, 0, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Return the registered AUTHORIZE command ID.
|
package/commands/admin/Base.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {CommandBase, Execution, Executions, Lanes, Specs} from "../Base.sol";
|
|
4
|
+
import {CommandBase, Execution, Executions, Flags, Lanes, Specs} from "../Base.sol";
|
|
5
5
|
import {NodeAccess} from "../../core/Access.sol";
|
|
6
6
|
|
|
7
7
|
/// @title AdminBase
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @notice Hook implemented by hosts that deny assets.
|
|
@@ -19,7 +19,7 @@ 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, 0,
|
|
22
|
+
(, descriptor) = command("denyAssets", Specs.Empty, Specs.Asset, Specs.Empty, 0, Flags.Admin);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/// @notice Deny each ASSET block in the admin input.
|
|
@@ -41,9 +41,3 @@ abstract contract DenyAssets is AdminBase, DenyAssetsHook {
|
|
|
41
41
|
return close(exec, account);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
@@ -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, Lanes, Specs } from "./Base.sol";
|
|
4
|
+
import { AdminBase, Execution, Executions, Flags, Lanes, Specs } from "./Base.sol";
|
|
5
5
|
import { GuardianAccess } from "../../core/Access.sol";
|
|
6
6
|
using Executions for Execution;
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ 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, 0,
|
|
16
|
+
(, descriptor) = command("dismiss", Specs.Empty, Specs.Account, Specs.Empty, 0, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Dismiss each user ACCOUNT block in the admin input from guardian status.
|
|
@@ -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, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
import {RawNodeCalls} from "../../core/Calls.sol";
|
|
6
6
|
|
|
7
7
|
using Executions for Execution;
|
|
@@ -15,7 +15,7 @@ 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, 0,
|
|
18
|
+
(, descriptor) = command("executePayable", Specs.Empty, Specs.Call, Specs.Empty, 0, Flags.AdminFunded);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/// @notice Execute each CALL block in the admin input.
|
|
@@ -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, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, 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, 0,
|
|
16
|
+
(id, descriptor) = command("unauthorize", Specs.Empty, Specs.Node, Specs.Empty, 0, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Return the registered UNAUTHORIZE command ID.
|
package/core/Portal.sol
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {PortCalls} from "./Calls.sol";
|
|
5
|
+
import {NodeAccess} from "./Access.sol";
|
|
6
|
+
import {ResolvedEvent} from "../events/Resolved.sol";
|
|
7
|
+
import {UnresolvedEvent} from "../events/Unresolved.sol";
|
|
5
8
|
|
|
6
9
|
/// @title Portal
|
|
7
10
|
/// @notice Base contract for hosts that route payloads through portal adapters.
|
|
8
|
-
abstract contract Portal is PortCalls {
|
|
11
|
+
abstract contract Portal is PortCalls, NodeAccess, UnresolvedEvent, ResolvedEvent {
|
|
9
12
|
error BadWitness();
|
|
10
13
|
|
|
11
|
-
mapping(bytes32 key => bytes32 digest) internal
|
|
14
|
+
mapping(bytes32 key => bytes32 digest) internal unresolved;
|
|
12
15
|
|
|
13
16
|
/// @notice Try to forward `message` to `port`.
|
|
14
17
|
/// @dev Records and returns `keccak256(message)` under `key` only when forwarding fails.
|
|
@@ -21,19 +24,19 @@ abstract contract Portal is PortCalls {
|
|
|
21
24
|
if (tryCallPort(port, value, message)) return bytes32(0);
|
|
22
25
|
|
|
23
26
|
miss = keccak256(message);
|
|
24
|
-
|
|
27
|
+
unresolved[key] = miss;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
/// @notice
|
|
30
|
+
/// @notice Resolve a previously unresolved witness through `port`.
|
|
28
31
|
/// @dev The witness must hash to the digest stored under `key`.
|
|
29
32
|
/// @param port Port that should attempt recovery.
|
|
30
33
|
/// @param key Recovery lookup key.
|
|
31
34
|
/// @param witness Witness payload used to prove and replay recovery.
|
|
32
|
-
/// @param value Native EVM value assigned to the
|
|
33
|
-
function
|
|
34
|
-
if (
|
|
35
|
+
/// @param value Native EVM value assigned to the resolution attempt.
|
|
36
|
+
function resolve(uint port, bytes32 key, bytes calldata witness, uint128 value) internal virtual {
|
|
37
|
+
if (unresolved[key] != keccak256(witness)) revert BadWitness();
|
|
35
38
|
|
|
36
|
-
delete
|
|
39
|
+
delete unresolved[key];
|
|
37
40
|
callPort(port, value, witness);
|
|
38
41
|
}
|
|
39
42
|
}
|
package/docs/Schema.md
CHANGED
|
@@ -50,8 +50,16 @@ overloaded in the relevant host/schema context.
|
|
|
50
50
|
|
|
51
51
|
## Block Syntax
|
|
52
52
|
|
|
53
|
-
A block definition has an event alias and a schema body.
|
|
54
|
-
|
|
53
|
+
A block definition has an event alias and a schema body. A schema body is one
|
|
54
|
+
of three forms:
|
|
55
|
+
|
|
56
|
+
```txt
|
|
57
|
+
"" empty or raw payload
|
|
58
|
+
{ fields } structured payload
|
|
59
|
+
many #item top-level custom list payload
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Fixed fields are written in braces:
|
|
55
63
|
|
|
56
64
|
```txt
|
|
57
65
|
alias: amount
|
|
@@ -66,9 +74,11 @@ A block body can reference another block alias as a child item with `#`:
|
|
|
66
74
|
|
|
67
75
|
The empty schema string `""` means the block has no structured payload. This is
|
|
68
76
|
used for zero-payload blocks such as `#unit` and raw dynamic blocks such as
|
|
69
|
-
`#bytes`.
|
|
77
|
+
`#bytes`. A root `many #item` body is reserved for an emitted custom schema
|
|
78
|
+
whose own key identifies the outer list block.
|
|
70
79
|
|
|
71
|
-
A schema body is a comma-separated list of items. Order is
|
|
80
|
+
A structured schema body is a comma-separated list of items. Order is
|
|
81
|
+
significant.
|
|
72
82
|
|
|
73
83
|
```txt
|
|
74
84
|
{ #amount, maybe #account as recipient }
|
|
@@ -110,11 +120,30 @@ maybe many #balance
|
|
|
110
120
|
|
|
111
121
|
- no prefix: one required item
|
|
112
122
|
- `maybe`: optional item
|
|
113
|
-
- `many`:
|
|
123
|
+
- `many`: a list whose payload contains repeated items
|
|
114
124
|
- `maybe many`: optional `#list` block
|
|
115
125
|
|
|
116
|
-
`maybe` emits no placeholder when absent.
|
|
117
|
-
generic list block; it does not repeat the
|
|
126
|
+
`maybe` emits no placeholder when absent. Inside a structured schema body,
|
|
127
|
+
`many` wraps repeated items in one generic `#list` block; it does not repeat the
|
|
128
|
+
item in place:
|
|
129
|
+
|
|
130
|
+
```txt
|
|
131
|
+
{ uint id, many #asset as assets }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
When an emitted custom schema consists entirely of a top-level `many` item, the
|
|
135
|
+
custom schema key identifies the outer list block instead. Its payload contains
|
|
136
|
+
the repeated items directly:
|
|
137
|
+
|
|
138
|
+
```txt
|
|
139
|
+
schema key: 0x00000001
|
|
140
|
+
schema body: many #asset
|
|
141
|
+
wire value: [0x00000001][length][ASSET][ASSET]...
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This convention gives a top-level list a discoverable, context-local type while
|
|
145
|
+
retaining the generic `#list` key for lists whose type is supplied by an
|
|
146
|
+
enclosing schema.
|
|
118
147
|
|
|
119
148
|
## Endpoint Lanes
|
|
120
149
|
|
|
@@ -128,33 +157,28 @@ The packed descriptor uses these lane layouts:
|
|
|
128
157
|
|
|
129
158
|
```txt
|
|
130
159
|
state [key:4][group:1]
|
|
131
|
-
input [key:4][
|
|
132
|
-
output [key:4][min:4][max:4][hint:
|
|
160
|
+
input [key:4][group:1]
|
|
161
|
+
output [key:4][min:4][max:4][hint:3][group:1]
|
|
162
|
+
reserve [reserved:4]
|
|
163
|
+
tx [transactions:1]
|
|
164
|
+
flags [flags:1]
|
|
133
165
|
```
|
|
134
166
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
spec
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
output decoder returns this as a left-aligned, writer-ready spec that retains
|
|
143
|
-
its encoded group. Its container and reserved fields are cleared. `Specs.group`
|
|
144
|
-
returns the effective group, interpreting an encoded zero as one for a
|
|
145
|
-
non-empty spec.
|
|
167
|
+
Each lane directly identifies its top-level block key. Output lanes retain their
|
|
168
|
+
size bounds and allocation hint so execution can reconstruct the output spec and
|
|
169
|
+
initialize its writer directly. Four descriptor-level bytes are reserved after
|
|
170
|
+
the lane metadata. The Solidity output decoder returns a left-aligned,
|
|
171
|
+
writer-ready spec that retains its encoded group and clears its reserved fields.
|
|
172
|
+
`Specs.group` returns the effective group, interpreting an encoded zero as one
|
|
173
|
+
for a non-empty spec.
|
|
146
174
|
|
|
147
175
|
Any non-empty lane resolves its key to a block alias and schema body through the
|
|
148
|
-
active schema context.
|
|
149
|
-
|
|
150
|
-
discovery metadata because it does not say what the list contains; indexers
|
|
151
|
-
should reject it for self-describing endpoints.
|
|
176
|
+
active schema context. A top-level list lane uses the key of its emitted custom
|
|
177
|
+
`many` schema; the descriptor treats it like every other direct lane spec.
|
|
152
178
|
|
|
153
179
|
The lane key is the prime item. Prime items may repeat at the top level for
|
|
154
|
-
batching.
|
|
155
|
-
|
|
156
|
-
top-level items are globals for the whole batch and are not counted as
|
|
157
|
-
per-operation prime blocks.
|
|
180
|
+
batching. Later top-level items are globals for the whole batch and are not
|
|
181
|
+
counted as per-operation prime blocks.
|
|
158
182
|
|
|
159
183
|
The prime item cannot be optional. If an endpoint needs a per-operation marker
|
|
160
184
|
with no payload, use a zero-payload block such as `#unit`.
|
|
@@ -369,7 +393,7 @@ invalid in any path segment.
|
|
|
369
393
|
|
|
370
394
|
- `#bytes`: raw dynamic bytes, written without a body
|
|
371
395
|
- `#string`: UTF-8 string bytes, written without a body
|
|
372
|
-
- `#list`: generic list wrapper emitted by `many`
|
|
396
|
+
- `#list`: generic list wrapper emitted by nested `many`
|
|
373
397
|
|
|
374
398
|
Custom input shapes should define their own context-local block spec and publish
|
|
375
399
|
it with a `#schema` annotation. Endpoint contracts can use `schema(...)` to
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {EventEmitter} from "./Emitter.sol";
|
|
5
|
+
|
|
6
|
+
/// @notice Emitted when a host resolves a previously recorded key.
|
|
7
|
+
abstract contract ResolvedEvent is EventEmitter {
|
|
8
|
+
string private constant ABI = "event Resolved(uint indexed host, bytes32 key)";
|
|
9
|
+
|
|
10
|
+
/// @param host Host node ID that owns the resolved key.
|
|
11
|
+
/// @param key Resolution lookup key.
|
|
12
|
+
event Resolved(uint indexed host, bytes32 key);
|
|
13
|
+
|
|
14
|
+
constructor() {
|
|
15
|
+
emit EventAbi(ABI);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {EventEmitter} from "./Emitter.sol";
|
|
5
|
+
|
|
6
|
+
/// @notice Emitted when a host records a portal message awaiting resolution.
|
|
7
|
+
abstract contract UnresolvedEvent is EventEmitter {
|
|
8
|
+
string private constant ABI = "event Unresolved(uint indexed host, bytes32 key, bytes32 digest)";
|
|
9
|
+
|
|
10
|
+
/// @param host Host node ID that owns the unresolved message.
|
|
11
|
+
/// @param key Resolution lookup key.
|
|
12
|
+
/// @param digest Digest of the unresolved message.
|
|
13
|
+
event Unresolved(uint indexed host, bytes32 key, bytes32 digest);
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
emit EventAbi(ABI);
|
|
17
|
+
}
|
|
18
|
+
}
|
package/execution/Execution.sol
CHANGED
|
@@ -227,7 +227,16 @@ library Executions {
|
|
|
227
227
|
/// @param lane Decoder lane containing the LIST block.
|
|
228
228
|
/// @return items Cursor over the nested list items.
|
|
229
229
|
function list(Execution memory exec, uint8 lane) internal pure returns (Cur memory items) {
|
|
230
|
-
|
|
230
|
+
return list(exec, Specs.List, lane);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/// @notice Consume a list block described by `spec` and return a cursor scoped to its payload.
|
|
234
|
+
/// @param exec Execution whose decoder is advanced.
|
|
235
|
+
/// @param spec Custom list block specification.
|
|
236
|
+
/// @param lane Decoder lane containing the list block.
|
|
237
|
+
/// @return items Cursor over the nested list items.
|
|
238
|
+
function list(Execution memory exec, uint spec, uint8 lane) internal pure returns (Cur memory items) {
|
|
239
|
+
(uint abs, uint end) = consume(exec, lane, spec);
|
|
231
240
|
items.state = Cursors.create(abs, end - abs, 0, 0, 0);
|
|
232
241
|
}
|
|
233
242
|
|
package/package.json
CHANGED
package/ports/AllowAssets.sol
CHANGED
|
@@ -15,7 +15,7 @@ abstract contract AllowAssetsPort is PortBase, AllowAssetsHook {
|
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
|
18
|
-
(, descriptor) = port("portAllowAssets", Specs.Asset, Specs.Empty,
|
|
18
|
+
(, descriptor) = port("portAllowAssets", Specs.Asset, Specs.Empty, 0);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/// @notice Execute the allow-assets peer call.
|
package/ports/Allowance.sol
CHANGED
|
@@ -16,7 +16,7 @@ abstract contract AllowancePort is PortBase, AllowanceHook {
|
|
|
16
16
|
uint private immutable descriptor;
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
|
-
(, descriptor) = port("portAllowance", Specs.Amount, Specs.Empty,
|
|
19
|
+
(, descriptor) = port("portAllowance", Specs.Amount, Specs.Empty, 0);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/// @notice Execute the allowance port call.
|
package/ports/Base.sol
CHANGED
|
@@ -32,16 +32,16 @@ abstract contract PortBase is NodeCalls, NodeAccess, InputEndpointBase {
|
|
|
32
32
|
/// match the Solidity port function name used by the canonical ABI.
|
|
33
33
|
/// @param input Input block specification.
|
|
34
34
|
/// @param output Output block specification.
|
|
35
|
-
/// @param
|
|
35
|
+
/// @param flags Packed port behavior flags.
|
|
36
36
|
/// @return id Port node ID.
|
|
37
37
|
/// @return descriptor Packed endpoint lane metadata and flags.
|
|
38
38
|
function port(
|
|
39
39
|
string memory name,
|
|
40
40
|
uint input,
|
|
41
41
|
uint output,
|
|
42
|
-
|
|
42
|
+
uint8 flags
|
|
43
43
|
) internal returns (uint id, uint descriptor) {
|
|
44
|
-
descriptor = Descriptors.create(Specs.Empty, input, output, 0,
|
|
44
|
+
descriptor = Descriptors.create(Specs.Empty, input, output, 0, flags);
|
|
45
45
|
return port(name, descriptor);
|
|
46
46
|
}
|
|
47
47
|
|
package/ports/Credit.sol
CHANGED
|
@@ -15,7 +15,7 @@ abstract contract CreditAccountPort is PortBase, CreditAccountHook {
|
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
|
18
|
-
(, descriptor) = port("portCreditAccount", Specs.AccountAmount, Specs.Empty,
|
|
18
|
+
(, descriptor) = port("portCreditAccount", Specs.AccountAmount, Specs.Empty, 0);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/// @notice Execute the port-credit call.
|
package/ports/Debit.sol
CHANGED
|
@@ -15,7 +15,7 @@ abstract contract DebitAccountPort is PortBase, DebitAccountHook {
|
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
|
18
|
-
(, descriptor) = port("portDebitAccount", Specs.AccountAmount, Specs.Empty,
|
|
18
|
+
(, descriptor) = port("portDebitAccount", Specs.AccountAmount, Specs.Empty, 0);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/// @notice Execute the port-debit call.
|
package/ports/DenyAssets.sol
CHANGED
|
@@ -15,7 +15,7 @@ abstract contract DenyAssetsPort is PortBase, DenyAssetsHook {
|
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
|
18
|
-
(, descriptor) = port("portDenyAssets", Specs.Asset, Specs.Empty,
|
|
18
|
+
(, descriptor) = port("portDenyAssets", Specs.Asset, Specs.Empty, 0);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/// @notice Execute the deny-assets peer call.
|
package/ports/Dispatch.sol
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {PortBase} from "./Base.sol";
|
|
5
|
+
import {Flags} from "../codec/Descriptors.sol";
|
|
5
6
|
import {Specs} from "../Codec.sol";
|
|
6
7
|
import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
7
8
|
|
|
@@ -25,7 +26,7 @@ abstract contract DispatchPayablePort is PortBase, DispatchPayableHook {
|
|
|
25
26
|
uint private immutable descriptor;
|
|
26
27
|
|
|
27
28
|
constructor() {
|
|
28
|
-
(, descriptor) = port("portDispatchPayable", Specs.Dispatch, Specs.Empty,
|
|
29
|
+
(, descriptor) = port("portDispatchPayable", Specs.Dispatch, Specs.Empty, Flags.Funded);
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
/// @notice Forward peer-supplied dispatches to the host-defined dispatch hook.
|
package/ports/Pipe.sol
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {PortBase} from "./Base.sol";
|
|
5
|
+
import {Flags} from "../codec/Descriptors.sol";
|
|
5
6
|
import {Pipeline} from "../core/Pipeline.sol";
|
|
6
7
|
import {Specs} from "../Codec.sol";
|
|
7
8
|
import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
@@ -16,7 +17,7 @@ abstract contract PipePayablePort is PortBase, Pipeline {
|
|
|
16
17
|
uint private immutable descriptor;
|
|
17
18
|
|
|
18
19
|
constructor() {
|
|
19
|
-
(, descriptor) = port("portPipePayable", Specs.Context, Specs.Empty,
|
|
20
|
+
(, descriptor) = port("portPipePayable", Specs.Context, Specs.Empty, Flags.Funded);
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/// @notice Execute peer-supplied contexts through the shared payable pipe.
|
package/ports/Post.sol
CHANGED
|
@@ -18,7 +18,7 @@ abstract contract PostPort is PortBase, PostHook, Action {
|
|
|
18
18
|
|
|
19
19
|
constructor() {
|
|
20
20
|
uint id;
|
|
21
|
-
(id, descriptor) = port("portPost", Specs.Transaction, Specs.Empty,
|
|
21
|
+
(id, descriptor) = port("portPost", Specs.Transaction, Specs.Empty, 0);
|
|
22
22
|
action(id, Actions.Post);
|
|
23
23
|
}
|
|
24
24
|
|
package/ports/Redeem.sol
CHANGED
|
@@ -24,7 +24,7 @@ abstract contract RedeemBalancePort is PortBase, RedeemBalanceHook {
|
|
|
24
24
|
uint private immutable descriptor;
|
|
25
25
|
|
|
26
26
|
constructor() {
|
|
27
|
-
(, descriptor) = port("portRedeemBalance", Specs.Balance, Specs.Empty,
|
|
27
|
+
(, descriptor) = port("portRedeemBalance", Specs.Balance, Specs.Empty, 0);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/// @notice Execute the balance redemption port call.
|
package/events/Recovered.sol
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
-
pragma solidity ^0.8.33;
|
|
3
|
-
|
|
4
|
-
import {EventEmitter} from "./Emitter.sol";
|
|
5
|
-
|
|
6
|
-
/// @notice Emitted when a host recovers a previously recorded key.
|
|
7
|
-
abstract contract RecoveredEvent is EventEmitter {
|
|
8
|
-
string private constant ABI = "event Recovered(uint indexed host, bytes32 key)";
|
|
9
|
-
|
|
10
|
-
/// @param host Host node ID that owns the recovered key.
|
|
11
|
-
/// @param key Recovery lookup key.
|
|
12
|
-
event Recovered(uint indexed host, bytes32 key);
|
|
13
|
-
|
|
14
|
-
constructor() {
|
|
15
|
-
emit EventAbi(ABI);
|
|
16
|
-
}
|
|
17
|
-
}
|
package/events/Undelivered.sol
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
-
pragma solidity ^0.8.33;
|
|
3
|
-
|
|
4
|
-
import {EventEmitter} from "./Emitter.sol";
|
|
5
|
-
|
|
6
|
-
/// @notice Emitted when a host records an undelivered portal message.
|
|
7
|
-
abstract contract UndeliveredEvent is EventEmitter {
|
|
8
|
-
string private constant ABI = "event Undelivered(uint indexed host, bytes32 key, bytes32 digest)";
|
|
9
|
-
|
|
10
|
-
/// @param host Host node ID that owns the undelivered message.
|
|
11
|
-
/// @param key Delivery lookup key.
|
|
12
|
-
/// @param digest Digest of the undelivered message.
|
|
13
|
-
event Undelivered(uint indexed host, bytes32 key, bytes32 digest);
|
|
14
|
-
|
|
15
|
-
constructor() {
|
|
16
|
-
emit EventAbi(ABI);
|
|
17
|
-
}
|
|
18
|
-
}
|