Defensive Programming in Substrate Reference Document (#2615)

_This PR is being continued from
https://github.com/paritytech/polkadot-sdk/pull/2206, which was closed
when the developer_hub was merged._
closes https://github.com/paritytech/polkadot-sdk-docs/issues/44

---
# Description

This PR adds a reference document to the `developer-hub` crate (see
https://github.com/paritytech/polkadot-sdk/pull/2102). This specific
reference document covers defensive programming practices common within
the context of developing a runtime with Substrate.

In particular, this covers the following areas: 

- Default behavior of how Rust deals with numbers in general
- How to deal with floating point numbers in runtime / fixed point
arithmetic
- How to deal with Integer overflows
- General "safe math" / defensive programming practices for common
pallet development scenarios
- Defensive traits that exist within Substrate, i.e.,
`defensive_saturating_add `, `defensive_unwrap_or`
- More general defensive programming examples (keep it concise)
- Link to relevant examples where these practices are actually in
production / being used
- Unwrapping (or rather lack thereof) 101

todo
-- 
- [x] Apply feedback from previous PR
- [x] This may warrant a PR to append some of these docs to
`sp_arithmetic`

---------

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Gonçalo Pestana <g6pestana@gmail.com>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
Co-authored-by: Radha <86818441+DrW3RK@users.noreply.github.com>
This commit is contained in:
bader y
2024-03-20 09:26:59 -04:00
committed by GitHub
parent 7241a8db7b
commit b686bfefba
10 changed files with 586 additions and 32 deletions
@@ -15,6 +15,42 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//! Types that implement [`PerThing`](PerThing) can be used as a floating-point alternative for
//! numbers that operate within the realm of `[0, 1]`. The primary types may you encounter in
//! Substrate would be the following:
//! - [`Percent`](Percent) - parts of one hundred.
//! - [`Permill`](Permill) - parts of a million.
//! - [`Perbill`](Perbill) - parts of a billion.
//!
//! In use, you may see them being used as follows:
//!
//! > **[`Perbill`](Perbill), parts of a billion**
#![doc = docify::embed!("./src/lib.rs", perbill_example)]
//! > **[`Percent`](Percent), parts of a hundred**
#![doc = docify::embed!("./src/lib.rs", percent_example)]
//!
//! Note that `Percent` is represented as a _rounded down_, fixed point
//! number (see the example above). Unlike primitive types, types that implement
//! [`PerThing`](PerThing) will also not overflow, and are therefore safe to use.
//! They adopt the same behavior that a saturated calculation would provide, meaning that if one is
//! to go over "100%", it wouldn't overflow, but simply stop at the upper or lower bound.
//!
//! For use cases which require precision beyond the range of `[0, 1]`, there are fixed-point types
//! which can be used.
//!
//! Each of these can be used to construct and represent ratios within our runtime.
//! You will find types like [`Perbill`](Perbill) being used often in pallet
//! development. `pallet_referenda` is a good example of a pallet which makes good use of fixed
//! point arithmetic, as it relies on representing various curves and thresholds relating to
//! governance.
//!
//! #### Fixed Point Arithmetic with [`PerThing`](PerThing)
//!
//! As stated, one can also perform mathematics using these types directly. For example, finding the
//! percentage of a particular item:
#![doc = docify::embed!("./src/lib.rs", percent_mult)]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};