fix: calculate_top_up_lamports#2060
Conversation
WalkthroughThe pull request replaces the rent top-up calculation from a balance-driven approach to an epoch-based model: Changes
Sequence DiagramsequenceDiagram
participant Caller
participant calculate_top_up
participant get_last_funded_epoch
Caller->>calculate_top_up: calculate_top_up_lamports(current_slot,...)
activate calculate_top_up
calculate_top_up->>get_last_funded_epoch: get_last_funded_epoch()
activate get_last_funded_epoch
alt success
get_last_funded_epoch-->>calculate_top_up: last_funded_epoch_number
else error
get_last_funded_epoch--xcalculate_top_up: Err(...)
Note right of calculate_top_up: error propagated via `?`
end
deactivate get_last_funded_epoch
rect rgb(230,240,255)
Note over calculate_top_up: derive epochs and funding horizon
calculate_top_up->>calculate_top_up: current_epoch = current_slot / SLOTS_PER_EPOCH
calculate_top_up->>calculate_top_up: epochs_funded_ahead = (last_funded_epoch_number + 1) - current_epoch
end
alt epochs_funded_ahead >= max_funded_epochs
rect rgb(200,255,200)
calculate_top_up-->>Caller: 0 (no top-up)
end
else epochs_funded_ahead < max_funded_epochs
rect rgb(255,245,200)
calculate_top_up-->>Caller: lamports_per_write (top-up)
end
end
deactivate calculate_top_up
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (2)
🧰 Additional context used🧬 Code graph analysis (1)program-libs/compressible/src/compression_info.rs (1)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
🔇 Additional comments (3)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
program-libs/compressible/src/compression_info.rs (1)
92-131: Epoch-based top-up logic looks correct; small clarity nits onlyThe new flow—
is_compressiblecheck first, thenget_last_funded_epoch+slot_to_epochto deriveepochs_funded_ahead—is consistent and avoids the duplicated rent math from before:
last_funded_epoch_numbermatches the helper semantics (“paid through” epoch).epochs_funded_ahead = (last_funded_epoch + 1) - current_epochwithsaturating_add/saturating_subgives the expected counts:
- “exactly max_funded_epochs (2)” at epoch 0 →
epochs_funded_ahead = 2, top‑up 0.- “exact boundary - lagging claim” at epoch 1 with last_claimed at epoch 0 →
epochs_funded_ahead = 1, top‑uplamports_per_write.- “2 epochs at epoch 1 boundary” with
last_claimed_slot = SLOTS_PER_EPOCH→epochs_funded_ahead = 2, top‑up 0.The saturating math also makes the behind‑on‑rent case safe, since negative deltas clamp to 0 and such states should already fall into the compressible branch via
is_compressible.Two optional cleanups you might consider (not blockers):
- Inline comment above
epochs_funded_aheadcould explicitly restate the formula as “epochs funded fromcurrent_epoch(inclusive) throughlast_funded_epoch(inclusive)” to make the off‑by‑one intent obvious.- If you ever need to reuse
epochs_fundedoravailable_balance, a future refactor could letget_last_funded_epochreuse the existingAccountRentStateinstead of recomputing internally, but that’s purely an optimization / API-tidy follow‑up.Functionally, this change is solid and well-covered by the updated tests.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
program-libs/compressible/src/compression_info.rs(2 hunks)program-libs/compressible/tests/compression_info.rs(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
program-libs/compressible/src/compression_info.rs (1)
program-libs/compressible/src/rent/account_rent.rs (2)
get_last_funded_epoch(180-211)slot_to_epoch(174-176)
🔇 Additional comments (3)
program-libs/compressible/src/compression_info.rs (1)
11-14: Import ofSLOTS_PER_EPOCHis appropriate and used
SLOTS_PER_EPOCHis needed forclaim()’scompleted_epochs * SLOTS_PER_EPOCHupdate later in the file and for coherent epoch math across rent utilities, so having it in the rent prelude here is correct.program-libs/compressible/tests/compression_info.rs (2)
468-476: Updated max-funded description correctly captures epoch mathFor the “exactly max_funded_epochs (2)” case, the new description:
Epoch 0: last_claimed=epoch 0, funded through epoch 1, epochs_funded_ahead=2 >= max=2matches the implementation:
last_claimed_slot = 0→last_claimed_epoch = 0.- Two epochs of rent funded →
last_funded_epoch = 1.- With
current_epoch = 0,epochs_funded_ahead = (1 + 1) - 0 = 2, so the branch to return 0 is correct.Comment and expectation are consistent with
calculate_top_up_lamports.
487-494: Epoch-1 boundary test now cleanly distinguishes “up-to-date claim” from “lagging claim”Changing
last_claimed_slottoSLOTS_PER_EPOCHin “2 epochs at epoch 1 boundary” nicely complements the new lagging-claim test:
- Here
last_claimed_epoch = 1, two epochs funded →last_funded_epoch = 2.- At
current_epoch = 1,epochs_funded_ahead = (2 + 1) - 1 = 2, which meetsmax_funded_epochs = 2, soexpected_top_up: 0is correct.This gives you both scenarios:
- Epoch boundary with stale
last_claimed_slot→ needs top-up.- Epoch boundary with up-to-date
last_claimed_slot→ considered well-funded.Test coverage around the boundary behavior looks good.
00aed01 to
9524c49
Compare
Summary by CodeRabbit