Skip to content

Commit 770523f

Browse files
committed
docs: add PR description for engine reservations
1 parent 56c2695 commit 770523f

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

PR_tipset_reservations_engine.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# feat: add engine‑managed tipset gas reservations to ref‑fvm
2+
3+
This PR implements engine‑managed tipset‑scope gas reservations inside ref‑fvm, as described in `AGENTS.md` (Option A). Lotus orchestrates Begin/End sessions around explicit messages; ref‑fvm remains network‑version agnostic and treats reservations as an internal, tipset‑local ledger.
4+
5+
## Summary
6+
7+
- Add a reservation session ledger on the default executor keyed by `ActorID`.
8+
- Implement `begin_reservation_session` / `end_reservation_session` with affordability checks and invariants.
9+
- Rewrite preflight to assert coverage without pre‑deducting gas funds in reservation mode.
10+
- Enforce transfers against free balance `balance − reserved_remaining`.
11+
- Rewrite settlement to net‑charge gas and realize refunds via reservation release.
12+
- Add reservation telemetry and tests (unit + integration).
13+
14+
## Changes
15+
16+
### Executor: session lifecycle and preflight
17+
18+
- **`fvm/src/executor/mod.rs`**
19+
- Add:
20+
- `ReservationSession` struct (re‑exported from `default.rs`) and `ReservationError` enum:
21+
- `NotImplemented`
22+
- `InsufficientFundsAtBegin { sender }`
23+
- `SessionOpen`
24+
- `SessionClosed`
25+
- `NonZeroRemainder`
26+
- `PlanTooLarge`
27+
- `Overflow`
28+
- `ReservationInvariant(String)`
29+
30+
- **`fvm/src/executor/default.rs`**
31+
- Add `ReservationSession { reservations: HashMap<ActorID, TokenAmount>, open: bool }` and an `Arc<Mutex<_>>` on `DefaultExecutor`.
32+
- Implement:
33+
- `begin_reservation_session(&mut self, plan: &[(Address, TokenAmount)]) -> Result<(), ReservationError>`:
34+
- Empty plan = no‑op (do not enter reservation mode).
35+
- Enforce `MAX_SENDERS` (65,536) and track plan failures via telemetry.
36+
- Resolve senders via the state tree (robust or ID addresses → `ActorID`).
37+
- Aggregate Σ(plan) per actor and enforce `reserved_total <= balance` per sender.
38+
- Enforce single active session.
39+
- `end_reservation_session(&mut self) -> Result<(), ReservationError>`:
40+
- Require `open == true` and all reservation entries to be zero.
41+
- Clear the ledger and close the session; update telemetry.
42+
- Preflight:
43+
- Compute `gas_cost = gas_fee_cap * gas_limit` using big‑int; treat negative results as `ReservationError::Overflow`.
44+
- In reservation mode:
45+
- Assert coverage via `reservation_assert_coverage(sender, &gas_cost)`; do not pre‑deduct funds.
46+
- On prevalidation failures (invalid sender, bad nonce, inclusion gas > limit), call `reservation_prevalidation_decrement` so the ledger can end at zero.
47+
- Legacy mode:
48+
- Preserve existing behaviour (check balance ≥ gas_cost, pre‑deduct from sender).
49+
50+
### Transfer enforcement and settlement
51+
52+
- **`fvm/src/call_manager/default.rs` & `fvm/src/call_manager/mod.rs`**
53+
- Thread `Arc<Mutex<ReservationSession>>` into the default call manager.
54+
- In `transfer(from, to, value)`:
55+
- When the reservation session is open:
56+
- Compute `reserved_remaining = reservations.get(from).unwrap_or(0)`.
57+
- Enforce `value + reserved_remaining <= from.balance`; otherwise return `InsufficientFunds`.
58+
- When no session is open:
59+
- Preserve existing `value <= balance` semantics.
60+
61+
- **`fvm/src/executor/default.rs`**
62+
- Settlement (`finish_message`) in reservation mode:
63+
- Compute `GasOutputs` as today.
64+
- Define `consumption = base_fee_burn + over_estimation_burn + miner_tip`.
65+
- Deduct `consumption` from the sender’s actor balance.
66+
- Deposit burns and tip to the existing reward/burn actors.
67+
- Do not deposit `refund` to the sender; the “refund effect” is realized by releasing the reservation ledger.
68+
- Decrement `reservations[sender]` by `gas_cost` using `reservation_prevalidation_decrement`, update telemetry, and remove entries at zero.
69+
- Legacy mode settlement is unchanged.
70+
- Preserve the invariant:
71+
- `base_fee_burn + over_estimation_burn + refund + miner_tip == gas_cost`.
72+
73+
### Telemetry
74+
75+
- **`fvm/src/executor/telemetry.rs`**
76+
- Add `ReservationTelemetry` and helpers:
77+
- Track:
78+
- `reservations_open`
79+
- `reservation_begin_failed`
80+
- `settle_basefee_burn`
81+
- `settle_tip_credit`
82+
- `settle_overburn`
83+
- `settle_refund_virtual`
84+
- Per‑sender reservation totals and remaining amounts.
85+
- Expose `snapshot()` (for potential host export) and `reset()` under `#[cfg(test)]`.
86+
87+
### Kernel and test harness adjustments
88+
89+
- **`fvm/src/kernel/default.rs`**
90+
- Plumb the updated `CallManager` type where necessary so that all value‑moving operations (`SendOps`, SELFDESTRUCT, etc.) route through the reservation‑aware `transfer`.
91+
92+
- **`fvm/tests/dummy.rs`**
93+
- Update the dummy `CallManager` impl to accept the new `ReservationSession` argument in `CallManager::new`, keeping tests compiling against the updated trait.
94+
95+
### Tests
96+
97+
- Unit tests in `fvm/src/executor/default.rs`:
98+
- Session lifecycle: empty plan, begin twice, end with non‑zero remainder, plan too large, unknown actors.
99+
- Preflight behaviour under reservations:
100+
- Coverage assertion, no balance deduction.
101+
- Under‑reserved ledger → `ReservationError::Overflow`.
102+
- Transfer enforcement:
103+
- `transfer`, send to existing actors, SELFDESTRUCT, and implicit sends must respect free balance.
104+
- Settlement invariants:
105+
- Net sender delta equals `consumption`.
106+
- Reservation ledger clears so `end_reservation_session` succeeds.
107+
- Gas output property test (with `--features arb`) continues to assert:
108+
- All components non‑negative.
109+
- `base_fee_burn + over_estimation_burn + refund + miner_tip == gas_cost`.
110+
111+
- Integration tests:
112+
- `testing/integration/tests/reservation_transfer_enforcement.rs`:
113+
- Uses the integration tester to exercise reservation mode and confirm that:
114+
- Sends and actor creation fail when `value > free = balance − reserved_remaining`.
115+
- Failed transfers do not credit receivers.
116+
117+
## Activation and host behaviour
118+
119+
- ref‑fvm does not contain any network‑version logic for reservations.
120+
- Hosts (e.g., Lotus) control:
121+
- When to call `begin_reservation_session` / `end_reservation_session`.
122+
- How to treat `ReservationError` variants (legacy fallback, tipset invalid, node error) based on network version and feature flags.
123+
124+
## Notes
125+
126+
- This PR is designed to preserve receipts (`ExitCode`, `GasUsed`, events) and `GasOutputs` relative to pre‑reservation behaviour, while removing miner exposure to intra‑tipset underfunded messages when hosts enable reservations.
127+

0 commit comments

Comments
 (0)