From 90b553376b4d9f787b2b49a8685ba9de5b56374b Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 26 Jul 2024 04:47:54 -0400 Subject: [PATCH] Add `from_mel` for `Footprint` with a Test (#5132) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may want to construct a `Footprint` by taking the `max_encoded_len` of a type, without having to construct the type. This impl allows easy access to that. --------- Co-authored-by: Bastian Köcher Co-authored-by: command-bot <> --- prdoc/pr_5132.prdoc | 15 ++++++++++++ substrate/frame/support/src/traits/storage.rs | 23 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 prdoc/pr_5132.prdoc 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 }); + } }