From e8c3e451e192fbf33934d0ee5a721b7c5298c2a0 Mon Sep 17 00:00:00 2001 From: QuantumExplorer Date: Thu, 5 Nov 2026 00:14:13 +0700 Subject: [PATCH] docs(platform): note that fee version numbers must stay contiguous FeeVersion::get and get_optional resolve a number by its position in FEE_VERSIONS, which is correct only while the registry is numbered 1, 2, 3, ... in order. The registry doc now states that rule, when a schedule needs a new number (a change to the storage, processing, hashing or signature costs the fee history serves), and that new storage rates also need refunds priced at the storage epoch's rate. Co-Authored-By: Claude Opus 5.5 --- .../rs-platform-version/src/version/fee/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/rs-platform-version/src/version/fee/mod.rs b/packages/rs-platform-version/src/version/fee/mod.rs index 6abb19f52ae..fcacff7b8df 100644 --- a/packages/rs-platform-version/src/version/fee/mod.rs +++ b/packages/rs-platform-version/src/version/fee/mod.rs @@ -39,6 +39,20 @@ pub mod vote_resolution_fund_fees; pub type FeeVersionNumber = u32; +/// The fee versions a node can resolve from a `fee_version_number` stored in platform state. +/// +/// Entries must be numbered contiguously from 1, in order: the entry at index `i` carries +/// `fee_version_number` `i + 1`. [`FeeVersion::get`] and [`FeeVersion::get_optional`] look a +/// number up by that position, which is correct exactly while this holds, so a new entry is +/// appended with the next number and never skips or reuses one. +/// +/// A new number is needed only when a value the fee history serves changes (the storage, +/// processing, hashing or signature costs), because saved state keeps only the number and +/// reloads the entry registered here. Schedules that change other groups keep the previous +/// number, which is why `FEE_VERSION2` to `FEE_VERSION4` all carry 1 and are not listed. +/// Registering different storage rates also requires refunds priced at the rate active when the +/// bytes were stored; `calculate_fee` generation 0 prices them at the removal epoch's rate +/// (dashpay/platform#4703 has a version of that rule). pub const FEE_VERSIONS: &[FeeVersion] = &[FEE_VERSION1]; #[derive(Clone, Debug, Encode, Decode, Default, PartialEq, Eq)] @@ -68,6 +82,7 @@ impl FeeVersion { pub fn as_static(&self) -> &'static FeeVersion { FeeVersion::get(self.fee_version_number).expect("expected fee version to exist") } + /// Looks `version` up by position in [`FEE_VERSIONS`], which is numbered contiguously from 1. pub fn get<'a>(version: FeeVersionNumber) -> Result<&'a Self, PlatformVersionError> { if version > 0 { FEE_VERSIONS.get(version as usize - 1).ok_or_else(|| { @@ -80,6 +95,7 @@ impl FeeVersion { } } + /// Looks `version` up by position in [`FEE_VERSIONS`], which is numbered contiguously from 1. pub fn get_optional<'a>(version: FeeVersionNumber) -> Option<&'a Self> { if version > 0 { FEE_VERSIONS.get(version as usize - 1)