@rootzero/contracts 1.15.0 → 1.17.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 +90 -0
- package/Codec.sol +1 -1
- package/Commands.sol +1 -1
- package/Core.sol +4 -4
- package/Endpoints.sol +9 -7
- package/Events.sol +0 -1
- package/README.md +88 -30
- package/Utils.sol +1 -1
- package/codec/Blocks.sol +111 -21
- package/codec/Buffers.sol +3 -3
- package/codec/Decoders.sol +48 -10
- package/codec/Descriptors.sol +0 -1
- package/codec/Keys.sol +4 -2
- package/codec/Readers.sol +25 -0
- package/codec/Schema.sol +6 -1
- package/codec/Specs.sol +7 -2
- package/codec/Writers.sol +28 -2
- package/commands/Base.sol +8 -15
- package/commands/Burn.sol +2 -2
- package/commands/Credit.sol +38 -3
- package/commands/Debit.sol +50 -14
- package/commands/Deposit.sol +4 -4
- package/commands/Provision.sol +4 -4
- package/commands/Recover.sol +15 -8
- package/commands/Relay.sol +37 -12
- package/commands/Settle.sol +130 -0
- package/commands/Withdraw.sol +2 -2
- package/commands/admin/AllowAssets.sol +2 -2
- package/commands/admin/Allowance.sol +3 -3
- package/commands/admin/Annotate.sol +2 -2
- package/commands/admin/Appoint.sol +2 -2
- package/commands/admin/Authorize.sol +2 -2
- package/commands/admin/DenyAssets.sol +2 -2
- package/commands/admin/Dismiss.sol +2 -2
- package/commands/admin/Execute.sol +3 -3
- package/commands/admin/Unauthorize.sol +2 -2
- package/core/Endpoint.sol +15 -13
- package/core/Pipeline.sol +6 -6
- package/core/Settlement.sol +37 -8
- package/core/Types.sol +21 -1
- package/docs/Schema.md +52 -2
- package/execution/Budget.sol +12 -4
- package/execution/Execution.sol +119 -11
- package/guards/Base.sol +2 -2
- package/guards/Revoke.sol +21 -0
- package/package.json +1 -1
- package/ports/Base.sol +2 -2
- package/ports/Dispatch.sol +6 -6
- package/ports/{Settle.sol → Post.sol} +10 -10
- package/queries/Base.sol +2 -2
- package/utils/Actions.sol +1 -0
- package/utils/Cursors.sol +16 -30
- package/events/Position.sol +0 -22
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,96 @@
|
|
|
3
3
|
Until the protocol reaches integration-stable status, minor versions may include
|
|
4
4
|
breaking API changes. Breaking changes are called out explicitly.
|
|
5
5
|
|
|
6
|
+
## 1.17.0
|
|
7
|
+
|
|
8
|
+
### Breaking Changes
|
|
9
|
+
|
|
10
|
+
- `executeDebitAccount`, `executeCreditAccount`, and `executeSettle` now require
|
|
11
|
+
the pipeline step's `uint128 value` argument and reject nonzero value inside
|
|
12
|
+
the internal adapter.
|
|
13
|
+
- `AllowanceHook` implementations must treat an amount of zero as revocation.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Added the `HostAsset` structural block and complete codec support for
|
|
18
|
+
host-scoped asset references.
|
|
19
|
+
- Added the opt-in `RevokeAllowance` guardian endpoint, which accepts
|
|
20
|
+
`HostAsset` entries and revokes each allowance through `AllowanceHook`.
|
|
21
|
+
- Added the funded `settlePayable` command and `SettlePayableHook` for settlement
|
|
22
|
+
implementations that require access to the command's native-value budget.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Completed the endpoint barrel with `CommandBase` and exported the new command,
|
|
27
|
+
guard, hook, internal adapter, and structural type surfaces from their
|
|
28
|
+
corresponding package barrels.
|
|
29
|
+
|
|
30
|
+
### Upgrade Compatibility
|
|
31
|
+
|
|
32
|
+
- Pipeline hosts using the internal debit, credit, or settle adapters must pass
|
|
33
|
+
each step's assigned value into the adapter. Existing non-funded steps should
|
|
34
|
+
continue to pass zero.
|
|
35
|
+
|
|
36
|
+
## 1.16.0
|
|
37
|
+
|
|
38
|
+
### Breaking Changes
|
|
39
|
+
|
|
40
|
+
- Removed the unused generic `Position` event and `PositionEvent` base contract.
|
|
41
|
+
- Renamed transaction handling from settlement to posting: the transaction
|
|
42
|
+
helper is now `post(...)`, and `portSettle(bytes)` is now `portPost(bytes)`.
|
|
43
|
+
The port selector and node ID change, and its action is now `Actions.Post`
|
|
44
|
+
(`14`) instead of `Actions.Settle` (`3`). The `Settlement` convenience base
|
|
45
|
+
implements both the transaction `PostHook` and position `SettleHook`.
|
|
46
|
+
- Removed `openInput` from `EndpointBase`. Port, query, and guard bases expose
|
|
47
|
+
`openInput` through the input-only `InputEndpointBase`, while custom commands
|
|
48
|
+
must pass both state and input through `openCommand`.
|
|
49
|
+
- Removed the wildcard `Specs.Any` state type. The stateful relay is now
|
|
50
|
+
`relayBalancePayable` and accepts `BALANCE` state blocks; `relayPayable`
|
|
51
|
+
explicitly accepts empty state.
|
|
52
|
+
- Renamed the numeric `Position` fields from `assets` and `liabilities` to
|
|
53
|
+
`amount` and `debt`.
|
|
54
|
+
- Renamed `Budget.use` to `useResourceValue` and split execution spending into
|
|
55
|
+
exact `useValue` and packed-resource `useResourceValue` helpers.
|
|
56
|
+
- Renamed `RoutePayableHook.route` to `RelayPayableHook.relayTo`. Recovery hooks
|
|
57
|
+
are now `RecoverPayableHook` implementations that receive the complete
|
|
58
|
+
resource word and mutable execution budget.
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
|
|
62
|
+
- Added the hostless `#position` state block for threading asset-liability pairs
|
|
63
|
+
between pipeline commands.
|
|
64
|
+
- Added the `settle` command, the position `SettleHook`, and the transaction
|
|
65
|
+
`PostHook`. The `Settlement` convenience base provides default implementations
|
|
66
|
+
of both through the debit and credit account hooks.
|
|
67
|
+
- Added `relayBalancePayable` for relaying required `BALANCE` state while
|
|
68
|
+
`relayPayable` now explicitly relays with empty state.
|
|
69
|
+
- Added memory-backed `InternalDebitAccount`, `InternalCreditAccount`, and
|
|
70
|
+
`InternalSettle` adapters for hosts that execute canonical commands directly
|
|
71
|
+
from their pipeline dispatcher.
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
|
|
75
|
+
- Documented the command state-safety invariant: every command must handle the
|
|
76
|
+
complete supplied state stream or revert, and commands with empty state lanes
|
|
77
|
+
must reject non-empty state.
|
|
78
|
+
- Endpoint decoder opening now requires the complete supplied lane to be one
|
|
79
|
+
homogeneous run of the descriptor's declared key; trailing block types are
|
|
80
|
+
rejected instead of silently left outside the decoder cursor.
|
|
81
|
+
- Block runs and cursors now retain raw block counts only. Descriptor stride
|
|
82
|
+
conversion and state/input group reconciliation happen once in execution
|
|
83
|
+
opening rather than in `Blocks` or `Cursors`.
|
|
84
|
+
- Pipeline transaction streams are posted before the next step, and position
|
|
85
|
+
state is settled separately through the scalar asset, amount, liability, and
|
|
86
|
+
debt hook.
|
|
87
|
+
- Completed the public barrel exports for internal command adapters,
|
|
88
|
+
input-only endpoint bases, access errors, and low-level utility helpers.
|
|
89
|
+
|
|
90
|
+
### Upgrade Compatibility
|
|
91
|
+
|
|
92
|
+
- Command and port selectors, block schemas, and hook signatures changed in
|
|
93
|
+
this release. Deploy fresh hosts and update pipeline builders and peer
|
|
94
|
+
integrations together.
|
|
95
|
+
|
|
6
96
|
## 1.15.0
|
|
7
97
|
|
|
8
98
|
### Breaking Changes
|
package/Codec.sol
CHANGED
|
@@ -4,7 +4,7 @@ pragma solidity ^0.8.33;
|
|
|
4
4
|
// Aggregator: re-exports the complete block encoding and decoding surface.
|
|
5
5
|
// Import this file for low-level codec extensions and direct stream processing.
|
|
6
6
|
|
|
7
|
-
import { AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Tx } from "./core/Types.sol";
|
|
7
|
+
import { AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx } from "./core/Types.sol";
|
|
8
8
|
import { Keys } from "./codec/Keys.sol";
|
|
9
9
|
import { Sizes, Specs } from "./codec/Specs.sol";
|
|
10
10
|
import { Descriptors } from "./codec/Descriptors.sol";
|
package/Commands.sol
CHANGED
|
@@ -11,4 +11,4 @@ import {Blocks} from "./codec/Blocks.sol";
|
|
|
11
11
|
import {Sizes, Specs} from "./codec/Specs.sol";
|
|
12
12
|
import {Decoders} from "./codec/Decoders.sol";
|
|
13
13
|
import {Cursors, Cur} from "./utils/Cursors.sol";
|
|
14
|
-
import {AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Tx} from "./core/Types.sol";
|
|
14
|
+
import {AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx} from "./core/Types.sol";
|
package/Core.sol
CHANGED
|
@@ -7,18 +7,18 @@ pragma solidity ^0.8.33;
|
|
|
7
7
|
import { Action } from "./annotations/Action.sol";
|
|
8
8
|
import { Label } from "./annotations/Label.sol";
|
|
9
9
|
import { Schema } from "./annotations/Schema.sol";
|
|
10
|
-
import { AdminAccess, CallerAccess, CommanderAccess, GuardianAccess, NodeAccess, TrustAccess } from "./core/Access.sol";
|
|
10
|
+
import { AccessDenied, AdminAccess, CallerAccess, CommanderAccess, CommanderNotAllowed, GuardianAccess, NodeAccess, TrustAccess } from "./core/Access.sol";
|
|
11
11
|
import { Balances, InsufficientFunds } from "./core/Balances.sol";
|
|
12
12
|
import { Escrows, InsufficientEscrow } from "./core/Escrows.sol";
|
|
13
13
|
import { NativeAsset, Runtime } from "./core/Runtime.sol";
|
|
14
14
|
import { Admins, CommandHost, Guardians, Host, HostIntroduction, IHostIntroduction } from "./core/Host.sol";
|
|
15
15
|
import { CommandCalls, FailedCall, NodeCalls, PortCalls, RawNodeCalls } from "./core/Calls.sol";
|
|
16
|
-
import { EndpointBase } from "./core/Endpoint.sol";
|
|
16
|
+
import { EndpointBase, InputEndpointBase } from "./core/Endpoint.sol";
|
|
17
17
|
import { Pipeline } from "./core/Pipeline.sol";
|
|
18
18
|
import { Budget, Budgets } from "./execution/Budget.sol";
|
|
19
|
-
import { CreditAccountHook, DebitAccountHook, Settlement } from "./core/Settlement.sol";
|
|
19
|
+
import { CreditAccountHook, DebitAccountHook, PostHook, SettleHook, Settlement } from "./core/Settlement.sol";
|
|
20
20
|
import { Portal } from "./core/Portal.sol";
|
|
21
|
-
import { AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Tx } from "./core/Types.sol";
|
|
21
|
+
import { AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx } from "./core/Types.sol";
|
|
22
22
|
import { Validator } from "./core/Validator.sol";
|
|
23
23
|
|
|
24
24
|
|
package/Endpoints.sol
CHANGED
|
@@ -5,18 +5,20 @@ pragma solidity ^0.8.33;
|
|
|
5
5
|
// Import this file to inherit from the full rootzero callable host surface without managing individual paths.
|
|
6
6
|
|
|
7
7
|
// Shared endpoint hooks
|
|
8
|
-
import { CreditAccountHook, DebitAccountHook } from "./core/Settlement.sol";
|
|
8
|
+
import { CreditAccountHook, DebitAccountHook, PostHook, SettleHook } from "./core/Settlement.sol";
|
|
9
9
|
|
|
10
10
|
// Commands
|
|
11
|
+
import { CommandBase } from "./commands/Base.sol";
|
|
11
12
|
import { Allocate, AllocateHook } from "./commands/Allocate.sol";
|
|
12
13
|
import { Burn, BurnHook } from "./commands/Burn.sol";
|
|
13
|
-
import { CreditAccount } from "./commands/Credit.sol";
|
|
14
|
-
import { DebitAccount } from "./commands/Debit.sol";
|
|
14
|
+
import { CreditAccount, InternalCreditAccount } from "./commands/Credit.sol";
|
|
15
|
+
import { DebitAccount, InternalDebitAccount } from "./commands/Debit.sol";
|
|
15
16
|
import { Deposit, DepositHook, DepositPayable, DepositPayableHook } from "./commands/Deposit.sol";
|
|
16
17
|
import { Payout, PayoutHook } from "./commands/Payout.sol";
|
|
17
18
|
import { Provision, ProvisionHook, ProvisionPayable, ProvisionPayableHook } from "./commands/Provision.sol";
|
|
18
|
-
import {
|
|
19
|
-
import { RelayPayable,
|
|
19
|
+
import { RecoverPayable, RecoverPayableHook } from "./commands/Recover.sol";
|
|
20
|
+
import { RelayPayable, RelayBalancePayable, RelayPayableHook } from "./commands/Relay.sol";
|
|
21
|
+
import { InternalSettle, Settle, SettlePayable, SettlePayableHook } from "./commands/Settle.sol";
|
|
20
22
|
import { Withdraw, WithdrawHook } from "./commands/Withdraw.sol";
|
|
21
23
|
|
|
22
24
|
// Admin commands
|
|
@@ -41,11 +43,11 @@ import { PortDebitAccount } from "./ports/Debit.sol";
|
|
|
41
43
|
import { PortDenyAssets } from "./ports/DenyAssets.sol";
|
|
42
44
|
import { PortPipePayable } from "./ports/Pipe.sol";
|
|
43
45
|
import { PortDispatchPayable } from "./ports/Dispatch.sol";
|
|
44
|
-
import {
|
|
46
|
+
import { PortPost } from "./ports/Post.sol";
|
|
45
47
|
|
|
46
48
|
// Guard endpoints
|
|
47
49
|
import { GuardBase } from "./guards/Base.sol";
|
|
48
|
-
import { Revoke } from "./guards/Revoke.sol";
|
|
50
|
+
import { Revoke, RevokeAllowance } from "./guards/Revoke.sol";
|
|
49
51
|
|
|
50
52
|
// Query endpoints
|
|
51
53
|
import { QueryBase } from "./queries/Base.sol";
|
package/Events.sol
CHANGED
|
@@ -11,7 +11,6 @@ import { BalanceEvent } from "./events/Balance.sol";
|
|
|
11
11
|
import { CommanderEvent } from "./events/Commander.sol";
|
|
12
12
|
import { DispatchEvent } from "./events/Dispatch.sol";
|
|
13
13
|
import { EndpointEvent } from "./events/Endpoint.sol";
|
|
14
|
-
import { PositionEvent } from "./events/Position.sol";
|
|
15
14
|
import { ReceivedEvent } from "./events/Received.sol";
|
|
16
15
|
import { RecoveredEvent } from "./events/Recovered.sol";
|
|
17
16
|
import { EventEmitter } from "./events/Emitter.sol";
|
package/README.md
CHANGED
|
@@ -149,7 +149,7 @@ const input = concat([
|
|
|
149
149
|
```
|
|
150
150
|
|
|
151
151
|
Everything downstream keeps this shape: commands loop over input blocks,
|
|
152
|
-
|
|
152
|
+
posting loops over transactions, pipelines loop over steps. Batching is
|
|
153
153
|
never a special case.
|
|
154
154
|
|
|
155
155
|
## IDs, Accounts, Assets, and Nodes
|
|
@@ -219,7 +219,10 @@ pipeline.
|
|
|
219
219
|
|
|
220
220
|
The built-in surface is also available as two independent feature bundles:
|
|
221
221
|
`Admins` provides annotate, authorize, unauthorize, and executePayable;
|
|
222
|
-
`Guardians` provides appoint, dismiss, and
|
|
222
|
+
`Guardians` provides appoint, dismiss, and node revocation. Hosts that implement
|
|
223
|
+
the allowance hook can additionally inherit the opt-in `RevokeAllowance` guard,
|
|
224
|
+
which accepts `hostAsset { uint host, bytes32 asset }` entries and always applies
|
|
225
|
+
a zero allowance. The full `Host` composes
|
|
223
226
|
both, while smaller hosts can inherit either bundle separately.
|
|
224
227
|
|
|
225
228
|
Trust is explicit and minimal. Each host has an immutable **commander**
|
|
@@ -248,30 +251,51 @@ struct CommandContext {
|
|
|
248
251
|
|
|
249
252
|
Every command returns two block streams: `state`, which is threaded into the
|
|
250
253
|
next pipeline step, and `transactions`, which contains `#transaction` blocks
|
|
251
|
-
for the pipeline host to
|
|
254
|
+
for the pipeline host to post outside the state lane. Either stream may be
|
|
252
255
|
empty.
|
|
253
256
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
+
State is linear, not optional ambient context. A command is responsible for
|
|
258
|
+
the entire state stream it receives: it must validate and consume it, transform
|
|
259
|
+
and return it, forward it intact, or revert. A command must never succeed while
|
|
260
|
+
silently ignoring or dropping supplied state. Commands that declare
|
|
261
|
+
`Specs.Empty` state therefore reject any non-empty state, while commands that
|
|
262
|
+
accept state validate the complete stream against their declared state schema.
|
|
263
|
+
This is especially important for `#position`, because dropping a position could
|
|
264
|
+
silently discard both live value and an outstanding debt requirement.
|
|
257
265
|
|
|
258
|
-
The
|
|
259
|
-
|
|
266
|
+
The input carries instructions; the state carries live value. While a
|
|
267
|
+
sequence of commands executes, `#balance`, `#custody`, and `#position` blocks
|
|
268
|
+
in the state are the value being moved — produced by one command, consumed by
|
|
269
|
+
the next. A position carries an asset-liability pair as
|
|
270
|
+
`{ asset, amount, liability, debt }`.
|
|
271
|
+
|
|
272
|
+
`#position` is general live state rather than a lending-specific debt record.
|
|
273
|
+
It pairs value acquired or controlled with value owed or required. A command
|
|
274
|
+
may preserve or replace either side and return the resulting position for the
|
|
275
|
+
next step; `settle` terminally consumes the pair. This supports swaps,
|
|
276
|
+
borrowing, refinancing, collateral changes, callback obligations, cross-host
|
|
277
|
+
claims, fees, netting, and other multi-step operations. A position is a
|
|
278
|
+
transient representation and does not itself create or erase an obligation
|
|
279
|
+
recorded by an external system.
|
|
280
|
+
|
|
281
|
+
The standard `Deposit` mixin shows the canonical shape: open and validate both
|
|
282
|
+
command lanes, loop the batch, call the hook, and write the output run:
|
|
260
283
|
|
|
261
284
|
```solidity
|
|
262
285
|
function deposit(
|
|
263
|
-
|
|
286
|
+
bytes32 account,
|
|
287
|
+
bytes calldata state,
|
|
288
|
+
bytes calldata input
|
|
264
289
|
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
265
|
-
|
|
266
|
-
Writer memory output = Writers.allocBalances(outputs);
|
|
290
|
+
Execution memory exec = openCommand(state, input, descriptor, 0);
|
|
267
291
|
|
|
268
|
-
while (
|
|
269
|
-
(bytes32 asset, uint amount) =
|
|
270
|
-
deposit(
|
|
271
|
-
|
|
292
|
+
while (exec.more()) {
|
|
293
|
+
(bytes32 asset, uint amount) = exec.unpackAmount(Lanes.Input);
|
|
294
|
+
deposit(account, asset, amount); // host policy hook
|
|
295
|
+
exec.outputBalance(asset, amount);
|
|
272
296
|
}
|
|
273
297
|
|
|
274
|
-
return (
|
|
298
|
+
return close(exec, account);
|
|
275
299
|
}
|
|
276
300
|
```
|
|
277
301
|
|
|
@@ -292,17 +316,26 @@ abstract contract MyCommand is CommandBase {
|
|
|
292
316
|
bytes calldata state,
|
|
293
317
|
bytes calldata input
|
|
294
318
|
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
295
|
-
|
|
319
|
+
Execution memory exec = openCommand(state, input, descriptor, 0);
|
|
320
|
+
while (exec.more()) {
|
|
321
|
+
(bytes32 asset, uint amount) = exec.unpackAmount(Lanes.Input);
|
|
322
|
+
// Apply command-specific behavior for this group.
|
|
323
|
+
exec.outputBalance(asset, amount);
|
|
324
|
+
}
|
|
325
|
+
return close(exec, account);
|
|
296
326
|
}
|
|
297
327
|
}
|
|
298
328
|
```
|
|
299
329
|
|
|
300
330
|
The standard commands cover the common ledger movements: `deposit` and
|
|
301
|
-
`depositPayable` (external funds in), `
|
|
331
|
+
`depositPayable` (external funds in), `settlePayable` (funded settlement),
|
|
332
|
+
`withdraw` and `burn` (funds out),
|
|
302
333
|
`debitAccount` and `creditAccount` (internal movements), `payout` (deliver
|
|
303
334
|
state to other accounts), `allocate` (turn balance state into custody),
|
|
304
|
-
`provision` (provision custody from an external allocation),
|
|
305
|
-
(
|
|
335
|
+
`provision` (provision custody from an external allocation), `settle` (consume
|
|
336
|
+
asset-liability position state), `relayPayable` (relay a pipeline without
|
|
337
|
+
state), and `relayBalancePayable` (relay balance state and a pipeline to another
|
|
338
|
+
portal).
|
|
306
339
|
|
|
307
340
|
## Pipelines
|
|
308
341
|
|
|
@@ -316,7 +349,7 @@ step { uint cmd, uint resources, #bytes as input }
|
|
|
316
349
|
Each step names a command, the resources it may spend, and its input.
|
|
317
350
|
The returned state threads into the next command and the final state must be
|
|
318
351
|
empty. Returned transactions do not enter the state lane; the pipeline passes
|
|
319
|
-
each decoded transaction to the shared
|
|
352
|
+
each decoded transaction to the shared posting implementation before
|
|
320
353
|
running the next step. This is the core of `Pipeline.pipe`:
|
|
321
354
|
|
|
322
355
|
```solidity
|
|
@@ -328,11 +361,11 @@ while (cur.more()) {
|
|
|
328
361
|
account,
|
|
329
362
|
state,
|
|
330
363
|
input,
|
|
331
|
-
budget.
|
|
364
|
+
budget.useResourceValue(resources)
|
|
332
365
|
);
|
|
333
366
|
while (transactions.more()) {
|
|
334
367
|
(bytes32 from, bytes32 to, bytes32 asset, uint amount) = transactions.unpackTransaction();
|
|
335
|
-
|
|
368
|
+
post(from, to, asset, amount);
|
|
336
369
|
}
|
|
337
370
|
}
|
|
338
371
|
if (state.length != 0) revert UnexpectedState();
|
|
@@ -345,6 +378,31 @@ command batching — and `resources` is a chain-specific word interpreted by the
|
|
|
345
378
|
portal adapter (on EVM, the low 128 bits are native value in wei, drawn from a
|
|
346
379
|
shared budget), so the same pipeline bytes are meaningful to every port.
|
|
347
380
|
|
|
381
|
+
Hosts that implement a pipeline locally can inherit `InternalDebitAccount`,
|
|
382
|
+
`InternalCreditAccount`, and `InternalSettle` to advertise the canonical command
|
|
383
|
+
endpoints while routing their local command IDs through `executeDebitAccount`,
|
|
384
|
+
`executeCreditAccount`, and `executeSettle`. These adapters consume the
|
|
385
|
+
memory-backed pipeline state directly and avoid an external self-call. Pass the
|
|
386
|
+
step value into each adapter; all three reject nonzero value because the
|
|
387
|
+
commands are non-funded.
|
|
388
|
+
|
|
389
|
+
Positions also support backward-composed pipelines. In an exact-output route,
|
|
390
|
+
the asset side can represent the desired result while the liability side
|
|
391
|
+
represents the value currently required upstream. Each hop consumes one
|
|
392
|
+
position, fulfills or transforms its current requirement, and returns the next
|
|
393
|
+
position:
|
|
394
|
+
|
|
395
|
+
```txt
|
|
396
|
+
position(C, 100, C, 100)
|
|
397
|
+
→ position(C, 100, B, 50)
|
|
398
|
+
→ position(C, 100, A, 25)
|
|
399
|
+
→ settle
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
This is backward composition, not backward execution: `#step` blocks still
|
|
403
|
+
execute forward in their encoded order. Exact-output routing is only one use;
|
|
404
|
+
other commands may transform the asset side, the liability side, or both.
|
|
405
|
+
|
|
348
406
|
## Queries
|
|
349
407
|
|
|
350
408
|
Queries are the read endpoints: view functions that take a block-stream input
|
|
@@ -365,15 +423,15 @@ the descriptor's lanes through the published block schemas.
|
|
|
365
423
|
Ports are the host-to-host surfaces, callable only by trusted peer hosts. The two
|
|
366
424
|
central ones are batches all the way down:
|
|
367
425
|
|
|
368
|
-
- `
|
|
426
|
+
- `portPost` consumes `transaction { bytes32 from, bytes32 to, bytes32 asset,
|
|
369
427
|
uint amount }` blocks, debiting `from` and crediting `to` per
|
|
370
|
-
block — how two hosts
|
|
428
|
+
block — how two hosts post transactions between their ledgers.
|
|
371
429
|
- `portPipePayable` consumes `context` blocks, each carrying an account, an
|
|
372
430
|
initial state, and a run of steps — a complete pipeline delivered by another
|
|
373
431
|
host, executed locally against the port call's shared value budget.
|
|
374
432
|
|
|
375
|
-
This is also the cross-portal mechanism. `relayPayable
|
|
376
|
-
wraps a pipe and addresses it to a portal, commonly the destination host ID;
|
|
433
|
+
This is also the cross-portal mechanism. `relayPayable`, `relayBalancePayable`,
|
|
434
|
+
or `portDispatchPayable` wraps a pipe and addresses it to a portal, commonly the destination host ID;
|
|
377
435
|
a bridge adapter moves the **raw
|
|
378
436
|
bytes**; the destination host parses them with the same cursor rules and runs
|
|
379
437
|
the same pipeline loop. Nothing in the payload is EVM-specific — step commands
|
|
@@ -386,9 +444,9 @@ bytes and produce the same output bytes for every endpoint.
|
|
|
386
444
|
|
|
387
445
|
Admin commands use the regular command shape but are gated to the host's admin
|
|
388
446
|
account: trust management (`authorize`, `unauthorize`), guardian management
|
|
389
|
-
(`appoint`, `dismiss`), metadata (`
|
|
390
|
-
`
|
|
391
|
-
|
|
447
|
+
(`appoint`, `dismiss`), metadata (`annotate`), optional asset gating
|
|
448
|
+
(`allowAssets`, `denyAssets`, `allowance`), and raw calls (`executePayable`).
|
|
449
|
+
Guards go the other way: direct actions guardians can take
|
|
392
450
|
without any command context — the default is `revoke`, which lets a guardian
|
|
393
451
|
drop a trusted node immediately.
|
|
394
452
|
|
package/Utils.sol
CHANGED
|
@@ -13,7 +13,7 @@ import { Ids } from "./utils/Ids.sol";
|
|
|
13
13
|
import { Nodes } from "./utils/Nodes.sol";
|
|
14
14
|
import { Selectors } from "./utils/Selectors.sol";
|
|
15
15
|
import { Layout } from "./utils/Layout.sol";
|
|
16
|
-
import { addrOr, applyBps, beforeBps, bytes32ToInt, bytes32ToString, divisible, hash32, intToBytes32, isFamily, matchesBase, MAX_BPS, max8, max16, max24, max32, max40, max64, max96, max128, max160, NotDivisible, retryTicket, toLocalBase, toUnspecifiedBase, ValueOverflow } from "./utils/Utils.sol";
|
|
16
|
+
import { addrOr, applyBps, beforeBps, bytes32ToInt, bytes32ToString, clear8, clear16, clear32, clear64, divisible, ensureAddr, hash32, intToBytes32, isFamily, matchesBase, MAX_BPS, max8, max16, max24, max32, max40, max64, max96, max128, max160, NotDivisible, replace8, replace16, replace32, replace64, retryTicket, toLocalBase, toUnspecifiedBase, ValueOverflow, ZeroAddress } from "./utils/Utils.sol";
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
package/codec/Blocks.sol
CHANGED
|
@@ -35,10 +35,6 @@ library Blocks {
|
|
|
35
35
|
error UnexpectedValue();
|
|
36
36
|
/// @dev A scoped block run contained no blocks.
|
|
37
37
|
error EmptyRun();
|
|
38
|
-
/// @dev A block run was scoped with a zero stride.
|
|
39
|
-
error ZeroStride();
|
|
40
|
-
/// @dev A block count is not divisible by its declared stride.
|
|
41
|
-
error BadRatio();
|
|
42
38
|
|
|
43
39
|
// -------------------------------------------------------------------------
|
|
44
40
|
// Calldata inspection and navigation
|
|
@@ -147,25 +143,16 @@ library Blocks {
|
|
|
147
143
|
}
|
|
148
144
|
}
|
|
149
145
|
|
|
150
|
-
/// @notice
|
|
146
|
+
/// @notice Count a run that must consume the complete region.
|
|
147
|
+
/// @dev Reverts when any well-formed trailing block has a different key.
|
|
151
148
|
/// @param abs Absolute start position.
|
|
152
149
|
/// @param limit Absolute region boundary.
|
|
153
|
-
/// @param key
|
|
154
|
-
/// @
|
|
155
|
-
/// @return
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
uint limit,
|
|
160
|
-
bytes4 key,
|
|
161
|
-
uint stride
|
|
162
|
-
) internal pure returns (uint groups, uint end) {
|
|
163
|
-
if (stride == 0) revert ZeroStride();
|
|
164
|
-
uint count;
|
|
165
|
-
(count, end) = run(abs, limit, key);
|
|
166
|
-
if (count == 0) revert EmptyRun();
|
|
167
|
-
if (count % stride != 0) revert BadRatio();
|
|
168
|
-
groups = count / stride;
|
|
150
|
+
/// @param key Required block key for the complete region.
|
|
151
|
+
/// @return total Number of matching blocks.
|
|
152
|
+
/// @return end Absolute position equal to `limit`.
|
|
153
|
+
function runExact(uint abs, uint limit, bytes4 key) internal pure returns (uint total, uint end) {
|
|
154
|
+
(total, end) = run(abs, limit, key);
|
|
155
|
+
if (end != limit) revert InvalidBlock();
|
|
169
156
|
}
|
|
170
157
|
|
|
171
158
|
// Generic block writes
|
|
@@ -348,6 +335,22 @@ library Blocks {
|
|
|
348
335
|
}
|
|
349
336
|
}
|
|
350
337
|
|
|
338
|
+
/// @notice Write a HOST_ASSET block at `i`.
|
|
339
|
+
/// @dev DANGER: Unchecked memory write. Reserve `Sizes.B64` bytes first.
|
|
340
|
+
/// @param dst Destination buffer.
|
|
341
|
+
/// @param i Relative write position.
|
|
342
|
+
/// @param host Host identifier to encode.
|
|
343
|
+
/// @param asset Asset identifier to encode.
|
|
344
|
+
function writeHostAsset(bytes memory dst, uint i, uint host, bytes32 asset) internal pure {
|
|
345
|
+
uint spec = Specs.HostAsset;
|
|
346
|
+
assembly ("memory-safe") {
|
|
347
|
+
let p := add(add(dst, 0x20), i)
|
|
348
|
+
mstore(p, spec)
|
|
349
|
+
mstore(add(p, 0x08), host)
|
|
350
|
+
mstore(add(p, 0x28), asset)
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
351
354
|
// Three-word payloads
|
|
352
355
|
|
|
353
356
|
/// @notice Write an ALLOCATION block at `i`.
|
|
@@ -460,6 +463,33 @@ library Blocks {
|
|
|
460
463
|
|
|
461
464
|
// Four-word payloads
|
|
462
465
|
|
|
466
|
+
/// @notice Write a POSITION block at `i`.
|
|
467
|
+
/// @dev DANGER: Unchecked memory write. Reserve `Sizes.B128` bytes first.
|
|
468
|
+
/// @param dst Destination buffer.
|
|
469
|
+
/// @param i Relative write position.
|
|
470
|
+
/// @param asset Identifier for the asset side.
|
|
471
|
+
/// @param amount Quantity on the asset side.
|
|
472
|
+
/// @param liability Identifier for the liability side.
|
|
473
|
+
/// @param debt Quantity owed on the liability side.
|
|
474
|
+
function writePosition(
|
|
475
|
+
bytes memory dst,
|
|
476
|
+
uint i,
|
|
477
|
+
bytes32 asset,
|
|
478
|
+
uint amount,
|
|
479
|
+
bytes32 liability,
|
|
480
|
+
uint debt
|
|
481
|
+
) internal pure {
|
|
482
|
+
uint spec = Specs.Position;
|
|
483
|
+
assembly ("memory-safe") {
|
|
484
|
+
let p := add(add(dst, 0x20), i)
|
|
485
|
+
mstore(p, spec)
|
|
486
|
+
mstore(add(p, 0x08), asset)
|
|
487
|
+
mstore(add(p, 0x28), amount)
|
|
488
|
+
mstore(add(p, 0x48), liability)
|
|
489
|
+
mstore(add(p, 0x68), debt)
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
463
493
|
/// @notice Write a TRANSACTION block at `i`.
|
|
464
494
|
/// @dev DANGER: Unchecked memory write. Reserve `Sizes.B128` bytes first.
|
|
465
495
|
/// @param dst Destination buffer.
|
|
@@ -1249,6 +1279,44 @@ library Blocks {
|
|
|
1249
1279
|
|
|
1250
1280
|
// Four-word payloads
|
|
1251
1281
|
|
|
1282
|
+
/// @notice Decode a low-level fixed-width POSITION block at `abs`.
|
|
1283
|
+
/// @param abs Absolute block position.
|
|
1284
|
+
/// @return asset Decoded asset-side identifier.
|
|
1285
|
+
/// @return amount Decoded asset-side quantity.
|
|
1286
|
+
/// @return liability Decoded liability-side identifier.
|
|
1287
|
+
/// @return debt Decoded liability-side debt.
|
|
1288
|
+
function unpackPosition(
|
|
1289
|
+
uint abs
|
|
1290
|
+
) internal pure returns (bytes32 asset, uint amount, bytes32 liability, uint debt) {
|
|
1291
|
+
uint head;
|
|
1292
|
+
assembly ("memory-safe") {
|
|
1293
|
+
head := calldataload(abs)
|
|
1294
|
+
}
|
|
1295
|
+
if (head >> 192 != Specs.Position >> 192) revert InvalidBlock();
|
|
1296
|
+
assembly ("memory-safe") {
|
|
1297
|
+
asset := calldataload(add(abs, 0x08))
|
|
1298
|
+
amount := calldataload(add(abs, 0x28))
|
|
1299
|
+
liability := calldataload(add(abs, 0x48))
|
|
1300
|
+
debt := calldataload(add(abs, 0x68))
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
/// @notice Decode a low-level fixed-width HOST_ASSET block at `abs`.
|
|
1305
|
+
/// @param abs Absolute block position.
|
|
1306
|
+
/// @return host Decoded host identifier.
|
|
1307
|
+
/// @return asset Decoded asset identifier.
|
|
1308
|
+
function unpackHostAsset(uint abs) internal pure returns (uint host, bytes32 asset) {
|
|
1309
|
+
uint head;
|
|
1310
|
+
assembly ("memory-safe") {
|
|
1311
|
+
head := calldataload(abs)
|
|
1312
|
+
}
|
|
1313
|
+
if (head >> 192 != Specs.HostAsset >> 192) revert InvalidBlock();
|
|
1314
|
+
assembly ("memory-safe") {
|
|
1315
|
+
host := calldataload(add(abs, 0x08))
|
|
1316
|
+
asset := calldataload(add(abs, 0x28))
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1252
1320
|
/// @notice Decode a low-level fixed-width TRANSACTION block at `abs`.
|
|
1253
1321
|
/// @param abs Absolute block position.
|
|
1254
1322
|
/// @return from Decoded debit account.
|
|
@@ -1577,6 +1645,28 @@ library Blocks {
|
|
|
1577
1645
|
return bytes.concat(Keys.Balance, bytes4(uint32(64)), asset, bytes32(amount));
|
|
1578
1646
|
}
|
|
1579
1647
|
|
|
1648
|
+
/// @notice Encode a POSITION block.
|
|
1649
|
+
/// @param asset Identifier for the asset side.
|
|
1650
|
+
/// @param amount Quantity on the asset side.
|
|
1651
|
+
/// @param liability Identifier for the liability side.
|
|
1652
|
+
/// @param debt Quantity owed on the liability side.
|
|
1653
|
+
/// @return Encoded POSITION block bytes.
|
|
1654
|
+
function position(
|
|
1655
|
+
bytes32 asset,
|
|
1656
|
+
uint amount,
|
|
1657
|
+
bytes32 liability,
|
|
1658
|
+
uint debt
|
|
1659
|
+
) internal pure returns (bytes memory) {
|
|
1660
|
+
return bytes.concat(
|
|
1661
|
+
Keys.Position,
|
|
1662
|
+
bytes4(uint32(128)),
|
|
1663
|
+
asset,
|
|
1664
|
+
bytes32(amount),
|
|
1665
|
+
liability,
|
|
1666
|
+
bytes32(debt)
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1580
1670
|
/// @notice Encode a CUSTODY block.
|
|
1581
1671
|
/// @param host Host node ID holding the custody.
|
|
1582
1672
|
/// @param asset Asset identifier.
|
package/codec/Buffers.sol
CHANGED
|
@@ -18,12 +18,12 @@ library Buffers {
|
|
|
18
18
|
|
|
19
19
|
/// @notice Create a packed buffer cursor at write position zero.
|
|
20
20
|
/// @param len Initial logical byte capacity.
|
|
21
|
-
/// @param
|
|
21
|
+
/// @param count Number of logical items represented by the buffer.
|
|
22
22
|
/// @param growable Whether writes may expand the logical capacity.
|
|
23
23
|
/// @param tag Cursor identity tag.
|
|
24
24
|
/// @return cur Packed buffer cursor.
|
|
25
|
-
function cursor(uint len, uint
|
|
26
|
-
cur = Cursors.create(0, len,
|
|
25
|
+
function cursor(uint len, uint count, bool growable, uint8 tag) internal pure returns (uint cur) {
|
|
26
|
+
cur = Cursors.create(0, len, count, growable ? Growable : 0, tag);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/// @notice Reserve relative write space and return the updated packed buffer cursor.
|