From 4ba0baca5c86069b640b8bab963c49abcb433bd9 Mon Sep 17 00:00:00 2001 From: ss-deshmukh Date: Wed, 1 Jul 2026 18:16:15 +0530 Subject: [PATCH] Fix Perbill/eras unit bugs in chain-state value formatters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The chain-state-values page rendered several values with the wrong scaling: - Validator/pool commission values are Perbill (1e9 = 100%) but were run through the `percentage` formatter (÷10000, valid only for Permill), inflating them 1000×. Added a `percentage_perbill` formatter (÷1e7) and switched the four commission calls to it: * Staking.MinCommission (Kusama) 15000% → 15% * NominationPools.GlobalMaxCommission 10000% → 10% - Staking.BondingDuration is denominated in eras, not blocks, but used `blocks_to_days`, rendering 0.0019 days. Added an `eras_to_days` helper and `eras_to_days_kusama` formatter → 7 days (matches the formula the page's own prose documents). The genuinely-Permill uses (Bounties.CuratorDepositMultiplier, Treasury.Burn) are unchanged. Values verified against live Polkadot/Kusama Asset Hub RPC. --- docs/general/chain-state-values.md | 10 +++++----- macros/rpc.py | 11 ++++++++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/general/chain-state-values.md b/docs/general/chain-state-values.md index cf866e2e1e67..574971fc094e 100644 --- a/docs/general/chain-state-values.md +++ b/docs/general/chain-state-values.md @@ -89,7 +89,7 @@ description: Explore chain constants and storage values for Polkadot, Kusama, an #### Minimum Validator Commission - The minimum commission a Polkadot Validator can set is {{ rpc("polkadot-assethub", "Staking", "MinCommission", 0, is_constant=false, readable="percentage") }}. [This does not guarantee entry into the active set and earning rewards](https://docs.polkadot.com/infrastructure/running-a-validator/#running-a-validator). + The minimum commission a Polkadot Validator can set is {{ rpc("polkadot-assethub", "Staking", "MinCommission", 0, is_constant=false, readable="percentage_perbill") }}. [This does not guarantee entry into the active set and earning rewards](https://docs.polkadot.com/infrastructure/running-a-validator/#running-a-validator). #### Multisig Deposit Base @@ -101,7 +101,7 @@ description: Explore chain constants and storage values for Polkadot, Kusama, an #### Nomination Pool Max Commission - The maximum commission that can be set for a Polkadot nomination pool is {{ rpc("polkadot-assethub", "NominationPools", "GlobalMaxCommission", 100000000, is_constant=false, readable="percentage") }}. + The maximum commission that can be set for a Polkadot nomination pool is {{ rpc("polkadot-assethub", "NominationPools", "GlobalMaxCommission", 100000000, is_constant=false, readable="percentage_perbill") }}. #### Nomination Pool Members @@ -245,7 +245,7 @@ description: Explore chain constants and storage values for Polkadot, Kusama, an #### Minimum Validator Commission - The minimum commission a Kusama Validator can set is {{ rpc("kusama-assethub", "Staking", "MinCommission", 0, is_constant=false, readable="percentage") }}. [This does not guarantee entry into the active set and earning rewards](https://docs.polkadot.com/infrastructure/running-a-validator/#running-a-validator). + The minimum commission a Kusama Validator can set is {{ rpc("kusama-assethub", "Staking", "MinCommission", 0, is_constant=false, readable="percentage_perbill") }}. [This does not guarantee entry into the active set and earning rewards](https://docs.polkadot.com/infrastructure/running-a-validator/#running-a-validator). #### Multisig Deposit Base @@ -257,7 +257,7 @@ description: Explore chain constants and storage values for Polkadot, Kusama, an #### Nomination Pool Max Commission - The maximum commission that can be set for a Kusama nomination pool is {{ rpc("kusama-assethub", "NominationPools", "GlobalMaxCommission", 100000000, is_constant=false, readable="percentage") }}. + The maximum commission that can be set for a Kusama nomination pool is {{ rpc("kusama-assethub", "NominationPools", "GlobalMaxCommission", 100000000, is_constant=false, readable="percentage_perbill") }}. #### Nomination Pool Members @@ -316,7 +316,7 @@ description: Explore chain constants and storage values for Polkadot, Kusama, an #### Unbonding Duration - The unbonding duration on Kusama is set to {{ rpc("kusama-assethub", "Staking", "BondingDuration", 0, is_constant=true, readable="blocks_to_days") }} days. This is + The unbonding duration on Kusama is set to {{ rpc("kusama-assethub", "Staking", "BondingDuration", 0, is_constant=true, readable="eras_to_days_kusama") }} days. This is calculated by taking the **bonding duration** (in eras), multiplying it by the **length of a single era** (in hours), and dividing by the **hours in a day** (24). Example: 28 × 6 ÷ 24 = 7 days. diff --git a/macros/rpc.py b/macros/rpc.py index f57b82c7ee7e..783a35d6414e 100644 --- a/macros/rpc.py +++ b/macros/rpc.py @@ -16,12 +16,16 @@ def format(value, filter): match filter: case "percentage": return f"{value / 10000}%" + case "percentage_perbill": + return f"{value / 10000000}%" # Perbill: 1e9 = 100% case "human_readable": return f"{human_readable(10, value)} DOT" case "human_readable_kusama": return f"{human_readable(12, value)} KSM" case "blocks_to_days": return str(blocks_to_days(value)) + case "eras_to_days_kusama": + return str(eras_to_days(value, 6)) # Kusama era = 6 hours case "precise_ksm": return f"{human_readable(12, value, rounded=False)} KSM" case "precise_dot": @@ -29,9 +33,14 @@ def format(value, filter): case _: return str(value) -def blocks_to_days(blocks): +def blocks_to_days(blocks): return (blocks * 6) / 86400 +def eras_to_days(eras, era_hours): + # BondingDuration is denominated in eras, not blocks: + # eras * era length (hours) / hours-per-day + return (eras * era_hours) / 24 + def get_network_url(network): match network: case "polkadot":