feat(platform): define protocol-versioned smart-contract computation limits and their gas representation - #4705
DCG-Claude wants to merge 9 commits into
Conversation
…imits Introduce `SystemLimits::smart_contract_computation`, an optional group holding the per-invocation and per-block computation limits in one contract-only unit (`ComputationUnits`), and `SYSTEM_LIMITS_V5` carrying the provisional numbers from the DashVM allocation register (25 million units per outer invocation, 250 million per block). Every shipped table and the hand-written mock carry `None`, so no shipped protocol version changes behaviour. A compile-time assertion pins the one invariant that must survive measurement: both limits are non-zero and one maximal invocation fits in a block. `system_limits` becomes a public module so the unit alias and the limits struct are nameable from dpp, drive-abci and the future runtime crate. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Add the optional `dashvm` group to `FeeVersion` with one row for now, the credits charged per computation unit, and `FEE_VERSION3` carrying the provisional register price (1 credit per unit) on top of `FEE_VERSION2`. `FEE_VERSION1`, `FEE_VERSION2` and the pre-1.4 saved-state conversion carry `None`, so a schedule without contract pricing can never price computation at zero by accident. `fee_version_number` stays 1 because no storage, processing, hashing or signature rate changes, and for the same reason the new schedule is not appended to `FEE_VERSIONS`: the registry holds one entry per number and the persisted fee history keys nothing new. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
….0 version Register protocol versions 15 (4.3 placeholder), 16 (4.4 placeholder) and 17 (5.0) following the DashVM allocation register. The two placeholders are struct updates over their predecessor so that a forward merge of the real 4.3 or 4.4 version file is resolved by taking the incoming file and every table it changes flows into 17 without a second edit. Version 17 overrides only `system_limits` (`SYSTEM_LIMITS_V5`, the computation limits) and `fee_version` (`FEE_VERSION3`, the computation price); nothing dispatches on either yet, so a node at 17 behaves exactly like one at 16. `LATEST_VERSION` and `LATEST_PLATFORM_VERSION` move to 17. Three tests guard the registry: the existing length assertion, a cross-table invariant that limits and price activate together and only from 17, and an inheritance test pinning that 17 differs from 16 in exactly those two tables. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Add `dpp::fee::smart_contract_computation` with `computation_units_to_credits`: checked multiplication of the units an invocation consumed by the fee schedule's `dashvm` price, a corrupted code execution error when the schedule has no contract pricing and an overflow error when the charge does not fit in credits. The module documents the gas mapping: the charge enters the invocation's processing fee, which is what Tenderdash's gas fields already report in credits, so no new gas unit and no unit equivalence with Tenderdash gas is introduced. The unit alias and the limits struct are re-exported from platform-version for dpp consumers. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Add `execution::types::block_computation_budget` with `BlockComputationBudget`, the deterministic per-block accounting proposal creation and proposal validation will share: reserve an invocation's admitted bound against the block before it runs, settle the actual consumption afterwards and release the unused part. Exhaustion is an admission outcome that leaves the ledger unchanged, settling more than the reserved bound is a corrupted code execution error, and every operation uses checked arithmetic. `ComputationReservation` is `#[must_use]`, not `Clone`, and consumed by settlement, so a reservation cannot be spent twice. `for_platform_version` returns `None` before the 5.0 protocol version so callers skip the contract path entirely. Nothing wires the ledger into the block loop yet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ping Document in the platform book what a computation unit is, the per-invocation and per-block limits in the system limits, the price in the fee schedule, why the fee version number stays 1, how the charge reaches Tenderdash gas through the processing fee, and why the 5.0 branch carries placeholder protocol versions 15 and 16 as struct updates. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rotocol version The persisted epoch fee history is keyed by `fee_version_number`, records a schedule only when that number changes, and is restored from saved state through `FeeVersion::get(number)`. It serves the storage, processing, hashing and signature groups and the storage refund rates, and nothing else, so it never carries the `dashvm` group, exactly as it never carried the contract registration, minimum fee or vote resolution groups. `computation_units_to_credits` now takes `&PlatformVersion` and reads `fee_version.dashvm` from the active protocol version, so a history entry cannot be passed to it by mistake; the field, group and schedule docs state the rule. Two tests pin it: `FEE_VERSION3` agrees with the registered generation its number resolves to on every group the history serves, and an upgrade from protocol version 16 to 17 on an epoch change through the real hook records no new history entry, survives a save and reload with the history unchanged, and prices computation from the active version on both sides of the restart. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
📖 Book Preview built successfully. Download the preview from the workflow artifacts. Updated at 2026-09-12T20:22:54.680Z |
|
✅ Final review complete — no blockers (commit 43e23ec) · triage: normal · Phase 2 only (queue backlog) |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## v5.0-dev #4705 +/- ##
============================================
- Coverage 86.36% 84.78% -1.59%
============================================
Files 2766 2798 +32
Lines 366105 375781 +9676
============================================
+ Hits 316191 318609 +2418
- Misses 49914 57172 +7258
🚀 New features to boost your workflow:
|
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Phase 2 only (queue backlog)
Verified the supplied Phase-2 findings against exact head b0ec338 and consolidated the two overlapping reports into one confirmed suggestion. The new ledger accepts foreign reservations, violating its documented accounting invariant; no production callers currently expose this as a consensus failure. Verification used source and caller inspection; no tests were run during this verification.
🟡 1 suggestion(s)
Review provenance
Source: reviewer 1: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 2: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); reviewer 3: gpt-6-astra (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6-astra (agent: astra-verifier, role: final-verifier)
- Triage:
criticalbygpt-6-astra(effort low) — This is a large, intricate diff that directly changes consensus-critical protocol-versioned smart-contract computation limits, block execution budgeting, fee-to-gas mapping, and protocol upgrade behavior in rs-drive-abci and rs-platform-version. - Phase 1 reviewers: not run (skipped for throughput: 19 PRs queued, above the 10 limit)
- Fresh verifier:
gpt-6-astra— final-verifier; agentastra-verifier - Phase 2 reviewers:
gpt-6-astra— general (completed, effort xhigh); agentphase2-reviewer,gpt-6-astra— rust-quality (completed, effort xhigh); agentphase2-reviewer,gpt-6-astra— security-auditor (completed, effort xhigh); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-drive-abci/src/execution/types/block_computation_budget.rs`:
- [SUGGESTION] packages/rs-drive-abci/src/execution/types/block_computation_budget.rs:127-134: Bind computation reservations to their originating ledger
A reservation stores only its bound, so `settle` cannot establish that the receiving ledger reserved those units. For example, create budgets A and B with `with_limit(100)`, reserve 80 from A, then call `B.settle(reservation, 0)`: settlement succeeds and B reports 180 remaining, allowing it to admit more than its limit. Checked arithmetic prevents integer overflow, not this accounting violation, and making the token non-Clone only prevents repeated settlement. Bind reservations to their issuing ledger and reject foreign reservations before changing counters, with explicit ownership semantics for `BlockComputationBudget::clone`. Add regression coverage for independent ledgers and cloned budgets. This is a correctness gap in the API introduced here, not a current production consensus failure: the ledger is not yet wired into block execution.
…ued them A reservation carried only its bound, so settling it into a different `BlockComputationBudget` credited that ledger with units it never held and let it admit more than its limit. Each ledger now has a process-local identity that its reservations carry, and `settle` rejects a foreign reservation as a corrupted code execution before touching any counter. Cloning a ledger copies the counters into a ledger with its own identity, so reservations issued before the clone settle only into the original. The identity is never serialised and never consensus-visible. Two regression tests cover independent ledgers and cloned budgets. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
The red 🤖 Posted autonomously by DashVM (Claude Fable 5.1) on behalf of pasta. |
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Phase 2 only (queue backlog)
Verified the Phase-2 findings against head 97584ea. The reservation-provenance issue is fixed; one non-blocking Clone/Eq trait-contract issue remains. Runtime enforcement is explicitly deferred by this metadata-and-ledger PR and does not justify expanding its scope.
🟡 1 suggestion(s)
Review provenance
Source: reviewer 1: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 2: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); reviewer 3: gpt-6-astra (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6-astra (agent: astra-verifier, role: final-verifier)
- Triage:
normalbygpt-6-astra(effort low) — The cross-crate additions define versioned limits, pricing helpers and a reservation ledger, but packages/rs-platform-version/src/version/v17.rs explicitly leaves enforcement unwired and the protocol-upgrade changes are tests, so the diff does not introduce intricate changes to active consensus enforcement or funds movement. - Phase 1 reviewers: not run (skipped for throughput: 12 PRs queued, above the 10 limit)
- Fresh verifier:
gpt-6-astra— final-verifier; agentastra-verifier - Phase 2 reviewers:
gpt-6-astra— general (completed, effort high); agentphase2-reviewer,gpt-6-astra— rust-quality (completed, effort high); agentphase2-reviewer,gpt-6-astra— security-auditor (completed, effort high); agentphase2-reviewer
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-drive-abci/src/execution/types/block_computation_budget.rs`:
- [SUGGESTION] packages/rs-drive-abci/src/execution/types/block_computation_budget.rs:90-98: Keep the ledger's Clone and equality implementations consistent
The fresh ledger identity correctly isolates reservations, but BlockComputationBudget derives PartialEq/Eq over that identity as well as its counters. Consequently, a budget compares unequal to its own clone; the regression test explicitly asserts this at line 358. This violates Clone's documented requirement that cloning an Eq value preserves equality, so comparing a ledger against a cloned snapshot reports a difference even when its accounting is unchanged. Preserve the fresh identity, but remove PartialEq/Eq from BlockComputationBudget and compare identities and counters explicitly in tests, or implement equality consistently with Clone. This is a public API contract issue, not a current consensus failure.
With a per-ledger identity, the derived `PartialEq` made a ledger unequal to its own clone, which `Clone` and `Eq` together promise not to happen. Two ledgers with the same counters are still different ledgers, so the type has no equality; tests compare the counters and the identity explicitly. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Phase 2 only (queue backlog)
Verified the supplied findings against head 43e23ec: both prior ledger issues are fixed, and no remaining in-scope findings were identified. The source supports the reviewers' conclusions about active-version pricing, unchanged fee-history generations, and deliberately deferred runtime integration. Regression tests were inspected but not rerun during this verification.
Review provenance
Source: reviewer 1: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 2: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); reviewer 3: gpt-6-astra (agent: phase2-reviewer, role: security-auditor); final verifier: gpt-6-astra (agent: astra-verifier, role: final-verifier)
- Triage:
normalbygpt-6-astra(effort low) — Although cross-cutting and substantial, the diff adds versioned computation tables, conversion helpers, and an isolated reservation ledger without wiring them into runtime admission or charging, while the protocol-upgrade changes are tests rather than changes to consensus execution. - Phase 1 reviewers: not run (skipped for throughput: 13 PRs queued, above the 10 limit)
- Fresh verifier:
gpt-6-astra— final-verifier; agentastra-verifier - Phase 2 reviewers:
gpt-6-astra— general (completed, effort high); agentphase2-reviewer,gpt-6-astra— rust-quality (completed, effort high); agentphase2-reviewer,gpt-6-astra— security-auditor (completed, effort high); agentphase2-reviewer
Issue being fixed or feature implemented
Smart contracts need consensus limits on the computation one invocation and one block may perform, a deterministic unit to count that computation in, a protocol-versioned price that turns units into credits, and a defined path from that charge to the gas figures Tenderdash sees. None of this existed: the version tables had no field for it, the fee schedule had no price, and the 5.0 protocol version did not exist on the branch.
This is task R06-01 of the smart-contract plan in #4626 (section 6.1, "Smart-contract computation budget"). The owner review delegated the numbers (Q40): supply provisional limits and prices now from the shared allocation register, measure and revise before activation, and keep the engine profile pin and unmeasured native costs open.
Refs #4689
Dash-Tasks: R06-01
What was done?
Limits in the version tables (
packages/rs-platform-version/src/version/system_limits/)smart_contract.rs(new):pub type ComputationUnits = u64andSmartContractComputationLimits { max_computation_units_per_invocation, max_computation_units_per_block }. The doc comment defines a unit (a deterministic count of admitted guest operations and host work under the active metering generation, never wall-clock), the single-counter rule for the per-invocation limit (nested calls, predicates, module initialisation and host entries all charge one counter, nothing is counted twice), the ordinary-plus-scheduled scope of the per-block limit, the credits mapping and the runtime interface.is_well_formed()(both limits non-zero, one invocation fits in a block) is the one invariant that must survive measurement.SystemLimitsgainssmart_contract_computation: Option<SmartContractComputationLimits>,NoneonSYSTEM_LIMITS_V1toV4and on the hand-written mock inmocks/v2_test.rs.SystemLimitsadditionally derivesPartialEq, Eqfor the inheritance test below.v5.rs(new):SYSTEM_LIMITS_V5 = { smart_contract_computation: Some(25_000_000 per invocation, 250_000_000 per block), ..SYSTEM_LIMITS_V4 }with a compile-time assertion onis_well_formed().system_limitsbecomes a public module so the alias and the struct are nameable fromdpp,drive-abciand the future runtime crate (nothing outside the crate named asystem_limitspath before).Price in the fee schedule (
packages/rs-platform-version/src/version/fee/)dashvm/mod.rsanddashvm/v1.rs(new):FeeDashVmVersion { credits_per_computation_unit: u64 }with the same derive stack as the other groups, andFEE_DASHVM_VERSION1at 1 credit per unit. The remaining register rows (deployment validation, readiness verification, host entry, per-byte copy) are added to this group in place by the pricing task.FeeVersiongainsdashvm: Option<FeeDashVmVersion>as its last field.FEE_VERSION1,FEE_VERSION2and the pre-1.4 saved-state conversion carryNone, so a schedule without contract pricing can never price computation at zero by accident.v3.rs(new):FEE_VERSION3 = { dashvm: Some(FEE_DASHVM_VERSION1), ..FEE_VERSION2 }.fee_version_numberstays 1 because no storage, processing, hashing or signature rate changes; for the same reason the schedule is not appended toFEE_VERSIONS, which holds one entry per number. This is the rule the fee-registry repair on the 4.3 branch documents (a schedule that only changes a group the history never serves keeps the number of the generation it agrees with).Protocol versions 15, 16 and 17 (
packages/rs-platform-version/src/version/)v15.rsandv16.rs(new) are placeholders for the 4.3 and 4.4 protocol versions reserved by the allocation register. They are struct updates over their predecessor (PlatformVersion { protocol_version: PROTOCOL_VERSION_15, ..PLATFORM_V14 }), not file copies, so that the forward merge of the real 4.3 or 4.4 file is an add/add conflict resolved by taking the incoming file, after which every table it changes flows into 16 and 17 without a second edit.v17.rs(new) is the 5.0 protocol version:PLATFORM_V17 = { fee_version: FEE_VERSION3, system_limits: SYSTEM_LIMITS_V5, ..PLATFORM_V16 }. No method version changes, no migration hook; a node at 17 behaves exactly like one at 16 until the enforcement tasks wire the runtime in.LATEST_VERSION = PROTOCOL_VERSION_17,LATEST_PLATFORM_VERSION = &PLATFORM_V17, all three appended toPLATFORM_VERSIONS.DESIRED_PLATFORM_VERSIONfollowsLATEST, as for every protocol version introduced on a development branch.Units to credits (
packages/rs-dpp/src/fee/smart_contract_computation.rs, new)computation_units_to_credits(units, &PlatformVersion) -> Result<Credits, ProtocolError>:checked_mulbyplatform_version.fee_version.dashvm.credits_per_computation_unit;ProtocolError::CorruptedCodeExecutionwhen the protocol version has nodashvmgroup (same shape asdaily_withdrawal_limit_v2reading a missing table entry),ProtocolError::Overflowwhen the charge does not fit in credits. The table is the versioned part; a formula change would earn aDPPMethodVersionsslot then, not now.previous_fee_versions) is keyed byfee_version_number, records a schedule only when the number changes, is saved as numbers and restored throughFeeVersion::get(number), and serves only the storage, processing, hashing and signature groups (KnownCostItem) plus the storage refund rates. Thedashvmgroup is read likedata_contract_registration,state_transition_min_feesandvote_resolution_fund_fees, which the history never carried either. The function takes&PlatformVersionso a history entry cannot be passed to it; the field, group and schedule docs state the rule.FeeResult.processing_fee, which is whatgas_used(abci/app/execution_result.rs) andgas_wanted(abci/handler/check_tx.rs) already report throughtotal_base_fee(). Gas stays credits; computation units are never reported to Tenderdash and no unit equivalence with Tenderdash gas is introduced. The Tenderdash blockmax_gasin dashmate is unchanged.ComputationUnitsandSmartContractComputationLimitsfordppconsumers.Per-block ledger (
packages/rs-drive-abci/src/execution/types/block_computation_budget.rs, new)BlockComputationBudget::for_platform_version(&PlatformVersion) -> Option<Self>(Nonebefore the 5.0 version so callers skip the contract path),reserve(bound) -> Result<ComputationReservation, BlockComputationBudgetExceeded>(an admission outcome that leaves the ledger unchanged),settle(reservation, actual) -> Result<released, Error>(actual > boundisExecutionError::CorruptedCodeExecution, because the runtime cannot legally exceed the budget it was given),limit(),consumed(),remaining().ComputationReservationis#[must_use], notClone, consumed bysettle, and bound to the ledger that issued it (a process-local identity, never serialised), so a reservation can neither be spent twice nor settled into another ledger, which would credit that ledger with units it never held; a foreign reservation isExecutionError::CorruptedCodeExecutionwith the ledger unchanged. Cloning a ledger (the block execution context isClone) copies the counters into a ledger with its own identity, so reservations issued before the clone settle only into the original; the ledger therefore has noPartialEq(equality over the identity would make a ledger unequal to its own clone), callers compare the counters. Reserving the admitted bound rather than the actual consumption means per-block exhaustion is never a mid-execution paid failure and an invocation's outcome does not depend on its position in the block. Every operation uses checked arithmetic. No version wrapper: the ledger is in-memory block state, never serialised.Book (
book/src/fees/overview.md,book/src/versioning/feature-versions.md,book/src/versioning/platform-version.md): the unit, the two limits, the price, why the fee version number stays 1, the gas mapping, the nested optional limits group, and the placeholder versions with their forward-merge rule.What stays byte-identical:
PLATFORM_V1toPLATFORM_V14behaviour (their tables gain onlyNonefields),FEE_VERSION1andFEE_VERSION2on every value the fee history serves,FEE_VERSIONS, everyvNmethod module indpp,driveanddrive-abci,process_raw_state_transitions,check_tx,execution_result.rs,BlockExecutionContextV0,NotExecutedReason, and every native budget (proposer timer, withdrawal and shielded per-block caps, Tenderdashmax_gas). Replay of every block at protocol versions 1 to 14 is unchanged because no shipped table changes a non-Nonevalue and no code path reads the new fields.What stays open (owned by later tasks, deliberately not here): opcode weights and the metering generation (R03-07, R08-01), the remaining price rows (R12-03), enforcement in the block loop and CheckTx (R06-02, R08-05, R11-04: the
NotExecutedReasonvariant, the ledger's place on the block execution context, affordability), scheduled-work admission (R06-09), consensus error codes for exhaustion (R12-07), the engine/profile pin (A04), and any native-event budget change (rejected by policy).How Has This Been Tested?
New tests, all next to the code they exercise:
packages/rs-platform-version/src/version/system_limits/mod.rssmart_contract_computation_limits_and_pricing_activate_together: for every registered version, limits and price are bothSomeor bothNone, everySomelimits value is well formed, everySomeprice is non-zero, and every version below 17 isNone. A cross-table invariant (limits without a price would meter for free, a price without limits would refuse every invocation), not a restated literal.the_5_0_protocol_version_changes_only_the_smart_contract_computation_tables:PLATFORM_V17minus the two new groups equalsPLATFORM_V16. Pins the delta the 5.0 version adds and fails when a forward merge changes 16 without 17 inheriting it or keeps this branch's generation over an incoming one.mock_platform_versions_have_no_smart_contract_computation_limits(mock-versions): the mock registry staysNone.packages/rs-platform-version/src/version/fee/v3.rs:should_agree_with_its_registered_fee_history_generation_on_every_group_the_history_serves:FEE_VERSION3and the registered generation its number resolves to agree on storage, processing, hashing and signature (the condition under which sharing the number is sound), and the registered generation carries nodashvmgroup.packages/rs-dpp/src/fee/smart_contract_computation.rs: pricing at the active version's rate againstPlatformVersion::latest(), zero units, overflow atu64::MAXunits with a 2-credit schedule, and the corrupted-code-execution error on protocol version 14.packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/upgrade_protocol_version/v0/mod.rs:test_upgrade_to_the_5_0_protocol_version_keeps_the_fee_history_and_prices_computation_from_the_active_version: a platform at protocol version 16 with one history entry upgrades to 17 on an epoch change through the real hook; the history gains no entry and still resolves (throughEpochCosts::active_fee_version) to number 1 without contract pricing with the same storage rates the upgraded version charges; the state is serialized through the saving format and deserialized; the reloaded history is unchanged and the price is obtained fromcurrent_platform_version()on both sides of the restart with the same result.packages/rs-drive-abci/src/execution/types/block_computation_budget.rs:Nonebefore 5.0 and the per-block limit asremainingatlatest(); exact-limit fits and one more unit is refused with the ledger unchanged; settle releases the unused bound; settling above the bound is rejected with the bound still held; a sequence of reserve/settle pairs keepsconsumed + held + remaining == limitat every step and cannot re-spend released-then-consumed units; an unsettled reservation keeps its bound held until settled with zero; checked arithmetic atu64::MAX; a reservation issued by another ledger is rejected without changing either ledger; a clone starts from the same counters with its own identity and neither ledger sees the other's settlements.Local gate (each command's output redirected to a file, exit code checked):
The verify-only cut is not affected (no
drive/src/verifychange).Breaking Changes
None observable. Every shipped protocol version's tables gain only
Nonefields, no method version changes, and no code path reads the new values. The new protocol versions are development-branch versions no network has run. TheEncode/Decodederives ofFeeVersionchange shape, which matters nowhere: saved state V1 stores fee version numbers and saved state V0 decodes the separate legacy struct.Decisions taken (provisional values)
SYSTEM_LIMITS_V5): the "Compute" row of the DashVM allocation register, marked provisional in a code comment. Measured and revised by the workload measurement task (R12-04) before activation.FEE_DASHVM_VERSION1): the register's "Provisional price", marked provisional in a code comment. Revised together with the limits.v17.rs,PROTOCOL_VERSION_17andPLATFORM_V17.v15.rsorv16.rs: take the incoming file, keepv17.rs. (b) add/add onsystem_limits/v5.rsorfee/v3.rs: keep the incoming generation, renumber this branch's constant to the next free number, rebase it on the incoming one and pointv17.rsat it. The three registry tests fail if a merge gets any of this wrong.Option<u64>fields, so consumers pass one value and later limits of the same family (host calls per invocation, returned read bytes) extend the group.dashvmgroup and is never consulted for it; registeringFEE_VERSION3under a new number would not put the price into the history, it would switch every storage refund at protocol version 17 onto the epoch-history refund path for rates that did not change.dppordrive-abci; the engine takes the limit as its budget and reports consumption inComputationUnits.Checklist:
For repository code-owners and collaborators only
🤖 Generated with Claude Code
🤖 Posted autonomously by DashVM (Claude Fable 5.1) on behalf of pasta.