Skip to content

Commit 994d82a

Browse files
serban300bkontur
authored andcommitted
Add test method for growing storage proof size (#2224)
1 parent 3bbb436 commit 994d82a

File tree

4 files changed

+63
-5
lines changed

4 files changed

+63
-5
lines changed

bridges/modules/messages/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ sp-std = { path = "../../../substrate/primitives/std", default-features = false
3232
sp-trie = { path = "../../../substrate/primitives/trie", default-features = false, optional = true }
3333

3434
[dev-dependencies]
35+
bp-runtime = { path = "../../primitives/runtime", features = ["test-helpers"] }
3536
bp-test-utils = { path = "../../primitives/test-utils" }
3637
pallet-bridge-grandpa = { path = "../grandpa" }
3738
pallet-balances = { path = "../../../substrate/frame/balances" }
@@ -71,4 +72,5 @@ try-runtime = [
7172
]
7273
test-helpers = [
7374
"sp-trie",
75+
"bp-runtime/test-helpers"
7476
]

bridges/primitives/runtime/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,4 @@ std = [
5353
"sp-trie/std",
5454
"trie-db/std",
5555
]
56+
test-helpers = []

bridges/primitives/runtime/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ pub use chain::{
4040
};
4141
pub use frame_support::storage::storage_prefix as storage_value_final_key;
4242
use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero};
43-
pub use storage_proof::{
44-
grow_storage_value, StorageProofError, StorageProofSize, UnverifiedStorageProof,
45-
VerifiedStorageProof,
46-
};
43+
#[cfg(feature = "test-helpers")]
44+
pub use storage_proof::{grow_storage_proof, grow_storage_value, StorageProofSize};
45+
pub use storage_proof::{StorageProofError, UnverifiedStorageProof, VerifiedStorageProof};
4746
pub use storage_types::BoundedStorageValue;
4847

4948
pub mod extensions;

bridges/primitives/runtime/src/storage_proof.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ use codec::{Decode, Encode};
2929
use hash_db::Hasher;
3030
use scale_info::TypeInfo;
3131
use trie_db::{DBValue, Recorder, Trie};
32+
#[cfg(feature = "test-helpers")]
33+
use trie_db::{TrieConfiguration, TrieDBMut};
3234

3335
use crate::Size;
3436

@@ -95,7 +97,7 @@ impl UnverifiedStorageProof {
9597
/// Creates a new instance of `UnverifiedStorageProof` from the provided entries.
9698
///
9799
/// **This function is used only in tests and benchmarks.**
98-
#[cfg(feature = "std")]
100+
#[cfg(any(all(feature = "std", feature = "test-helpers"), test))]
99101
pub fn try_from_entries<H: Hasher>(
100102
state_version: StateVersion,
101103
entries: &[(RawStorageKey, Option<DBValue>)],
@@ -116,6 +118,7 @@ impl UnverifiedStorageProof {
116118
/// Creates a new instance of `UnverifiedStorageProof` from the provided db.
117119
///
118120
/// **This function is used only in tests and benchmarks.**
121+
#[cfg(any(feature = "test-helpers", test))]
119122
pub fn try_from_db<H: Hasher, DB>(
120123
db: &DB,
121124
root: H::Out,
@@ -249,6 +252,7 @@ impl VerifiedStorageProof {
249252
/// Storage proof size requirements.
250253
///
251254
/// This is currently used by benchmarks when generating storage proofs.
255+
#[cfg(feature = "test-helpers")]
252256
#[derive(Clone, Copy, Debug)]
253257
pub enum StorageProofSize {
254258
/// The storage proof is expected to be minimal. If value size may be changed, then it is
@@ -260,6 +264,7 @@ pub enum StorageProofSize {
260264
}
261265

262266
/// Add extra data to the storage value so that it'll be of given size.
267+
#[cfg(feature = "test-helpers")]
263268
pub fn grow_storage_value(mut value: Vec<u8>, size: StorageProofSize) -> Vec<u8> {
264269
match size {
265270
StorageProofSize::Minimal(_) => (),
@@ -271,6 +276,57 @@ pub fn grow_storage_value(mut value: Vec<u8>, size: StorageProofSize) -> Vec<u8>
271276
value
272277
}
273278

279+
/// Insert values in the provided trie at common-prefix keys in order to inflate the resulting
280+
/// storage proof.
281+
///
282+
/// This function can add at most 15 common-prefix keys per prefix nibble (4 bits).
283+
/// Each such key adds about 33 bytes (a node) to the proof.
284+
#[cfg(feature = "test-helpers")]
285+
pub fn grow_storage_proof<L: TrieConfiguration>(
286+
trie: &mut TrieDBMut<L>,
287+
prefix: Vec<u8>,
288+
num_extra_nodes: usize,
289+
) {
290+
use sp_trie::TrieMut;
291+
292+
let mut added_nodes = 0;
293+
for i in 0..prefix.len() {
294+
let mut prefix = prefix[0..=i].to_vec();
295+
// 1 byte has 2 nibbles (4 bits each)
296+
let first_nibble = (prefix[i] & 0xf0) >> 4;
297+
let second_nibble = prefix[i] & 0x0f;
298+
299+
// create branches at the 1st nibble
300+
for branch in 1..=15 {
301+
if added_nodes >= num_extra_nodes {
302+
return
303+
}
304+
305+
// create branches at the 1st nibble
306+
prefix[i] = (first_nibble.wrapping_add(branch) % 16) << 4;
307+
trie.insert(&prefix, &[0; 32])
308+
.map_err(|_| "TrieMut::insert has failed")
309+
.expect("TrieMut::insert should not fail in benchmarks");
310+
added_nodes += 1;
311+
}
312+
313+
// create branches at the 2nd nibble
314+
for branch in 1..=15 {
315+
if added_nodes >= num_extra_nodes {
316+
return
317+
}
318+
319+
prefix[i] = (first_nibble << 4) | (second_nibble.wrapping_add(branch) % 16);
320+
trie.insert(&prefix, &[0; 32])
321+
.map_err(|_| "TrieMut::insert has failed")
322+
.expect("TrieMut::insert should not fail in benchmarks");
323+
added_nodes += 1;
324+
}
325+
}
326+
327+
assert_eq!(added_nodes, num_extra_nodes)
328+
}
329+
274330
#[cfg(test)]
275331
mod tests {
276332
use super::*;

0 commit comments

Comments
 (0)