6

Often times you'll see Perbill used throughout substrate. It stands for Parts per billion, and here's an example of it being used:

parameter_types! {
    pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
}

How should one interpret this though?

3
  • 1
    Is the name the confusing bit? for me it was initially until I realized the Per_something are all just "percentages" but with different resolution.
    – olanod
    Feb 10, 2022 at 17:42
  • If you are doing a calculation on a Balance (u128), I assume you should use the highest resolution Perbill? Oct 7, 2022 at 20:17
  • It has nothing to do with the value, but the percentage you are after. 1% of a u128 will be the same with percent, permill, or perbill. But you cannot do .001% with percent for example. You should use perbill where you want maximum flexibility for the percentage you want to specify.
    – Shawn Tabrizi
    Oct 8, 2022 at 5:02

3 Answers 3

6

To add to the other answers here, the simple fact is that all of the per_things are the same: some representation of a percentage, but at different resolutions.

You have:

  • Percent: Parts per hundred - represents [0, 1] from [0, 100], and thus you have a resolution of up to 1%.
  • Permill: Parts per million - represents [0, 1] from [0, 1_000_000], and thus you have a resolution of up to .00001%.
  • Perbill: Parts per billion - represents [0, 1] from [0, 1_000_000_000], and thus you have a resolution of up to .00000001%.

So, why use Perbill instead of Permill or Percent?

Because your scenario may need a higher resolution percentage. However, using a Perbill will end up being a 64-bit value, where as a Permill is just a 32-bit value, and a Percent is an 8-bit value... so precision comes at a cost.

Also note that all of these types use fixed point arithmetic, which is critical for determinism in the runtime, versus using a normal floating point values.

5

Blockchains require deterministic results. With arithmetic, we use fixed point numbers (integers typically) to ensure this. It is very convenient to use things like .from_percent() more commonly used in association with floating point numbers, so this is just a handy tool with many others in sp_arithmetic::per_things to help you use correct implementations for Substrate, with various levels of overall precision (if your primitive type using Perthing can support this accuracy, typically accommodated by larger types like u128 or more).

Here is the constants.rs file for Kusama for reference and an example of such use:

/// Fee-related.
pub mod fee { ... };
    // -- SNIP --
    /// The block saturation level. Fees will be updates based on this value.
    pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25);
    // -- SNIP --

Our goal is to fill 25% of the block, without needing to reason about the correct implementation of arithmetic. Using some std typical math that may lead to non-determinism in your runtime.

5

It's a concrete way of representing a part of a whole with more or less resolution.

As you point out when you use any of the per_things structs, what you are expressing a part of a whole.

In case of percent ( as you might be more used to) when you refer to 100%, that's the unit, the total of the whole. So 100 out of 100 parts, that is the whole amount of units, which is the 100%. This way you can do a division of something in 100 parts and you can express a subset of it, being the half (50 parts out of 100 parts in this case) 50% and so on.

Example time! - Imagine you have cake:

If you want to divide the cake (the whole/ the unit) in 25 parts and you want to express it in percent terms, having 10 parts would be the 40% of the cake.

Then, if for your use case happens to need higher precision for expressing a subset out of the whole you might go with something different than percent, that being perthousand, permill or perbill.

Then, going back to the cake example, if you divide it in 1 billion parts, the precision goes up, but you can still express a sub set of all the parts of the cake by saying, I have the Perbill::from_percent(40); of the total of the cake. The amount of cake you have is the same than in the previous example, but is expressed with a crazy big precision for a cake (?)

If you check the documentation, you will see that Perbill::one() and Perbill::zero() exist. And as stated

Re-export top-level arithmetic stuff. A fixed point representation of a number in the range [0, 1]

  • Perbill::one() will reference the total of the unit, all the parts of the cake.
  • Perbill::zero() will reference an empty set containing no parts at all from the total of parts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.