diff --git a/prdoc/pr_5132.prdoc b/prdoc/pr_5132.prdoc new file mode 100644 index 000000000000..f23574e04b79 --- /dev/null +++ b/prdoc/pr_5132.prdoc @@ -0,0 +1,15 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Add `from_mel` for `Footprint` + +doc: + - audience: Runtime Dev + description: | + This introduces a new way to generate the `Footprint` type by calculating the max encoded + length of some generic type. This allows you to generate a `Footprint` of a type without + actually constructing that type. + +crates: + - name: frame-support + bump: patch diff --git a/substrate/frame/support/src/traits/storage.rs b/substrate/frame/support/src/traits/storage.rs index 22fb28e4c0e7..a954af14d259 100644 --- a/substrate/frame/support/src/traits/storage.rs +++ b/substrate/frame/support/src/traits/storage.rs @@ -170,13 +170,20 @@ pub struct Footprint { } impl Footprint { + /// Construct a footprint directly from `items` and `len`. pub fn from_parts(items: usize, len: usize) -> Self { Self { count: items as u64, size: len as u64 } } + /// Construct a footprint with one item, and size equal to the encoded size of `e`. pub fn from_encodable(e: impl Encode) -> Self { Self::from_parts(1, e.encoded_size()) } + + /// Construct a footprint with one item, and size equal to the max encoded length of `E`. + pub fn from_mel() -> Self { + Self::from_parts(1, E::max_encoded_len()) + } } /// A storage price that increases linearly with the number of elements and their size. @@ -288,7 +295,8 @@ impl_incrementable!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128); #[cfg(test)] mod tests { use super::*; - use sp_core::ConstU64; + use crate::BoundedVec; + use sp_core::{ConstU32, ConstU64}; #[test] fn linear_storage_price_works() { @@ -305,4 +313,17 @@ mod tests { assert_eq!(p(u64::MAX, u64::MAX), u64::MAX); } + + #[test] + fn footprint_from_mel_works() { + let footprint = Footprint::from_mel::<(u8, BoundedVec>)>(); + let expected_size = BoundedVec::>::max_encoded_len() as u64; + assert_eq!(expected_size, 10); + assert_eq!(footprint, Footprint { count: 1, size: expected_size + 1 }); + + let footprint = Footprint::from_mel::<(u8, BoundedVec>)>(); + let expected_size = BoundedVec::>::max_encoded_len() as u64; + assert_eq!(expected_size, 1001); + assert_eq!(footprint, Footprint { count: 1, size: expected_size + 1 }); + } }