Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pallet_contracts] Modify the storage host function benchmarks to run on an unbalanced storage trie. #5036

Merged
merged 20 commits into from
Jul 29, 2024

Conversation

smiasojed
Copy link
Contributor

@smiasojed smiasojed commented Jul 16, 2024

This PR modifies the storage host function benchmarks. Previously, they were run on an empty storage trie.
Now, they are run on an unbalanced storage trie to reflect worst case scenario.
This approach increases the storage host function weights and decreases the probability of DoS attacks.

@smiasojed smiasojed added the T7-smart_contracts This PR/Issue is related to smart contracts. label Jul 16, 2024
@smiasojed
Copy link
Contributor Author

bot bench substrate-pallet --pallet=pallet_contracts

@command-bot
Copy link

command-bot bot commented Jul 16, 2024

@smiasojed https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6713254 was started for your command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts. Check out https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/pipelines?page=1&scope=all&username=group_605_bot to know what else is being executed currently.

Comment bot cancel 3-5c742ade-6a7f-427e-b303-8f736f581c9d to cancel this command or bot cancel to cancel all commands in this pull request.

Copy link

We are migrating the command bot to be a GitHub Action

Please, see the documentation on how to use it

@command-bot
Copy link

command-bot bot commented Jul 16, 2024

@smiasojed Command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts has finished. Result: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6713254 has finished. If any artifacts were generated, you can download them from https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6713254/artifacts/download.

@smiasojed
Copy link
Contributor Author

bot bench substrate-pallet --pallet=pallet_contracts

@command-bot
Copy link

command-bot bot commented Jul 16, 2024

@smiasojed https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6714033 was started for your command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts. Check out https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/pipelines?page=1&scope=all&username=group_605_bot to know what else is being executed currently.

Comment bot cancel 5-7104e56e-dfb9-4277-a83c-40e0998a7678 to cancel this command or bot cancel to cancel all commands in this pull request.

Copy link

We are migrating the command bot to be a GitHub Action

Please, see the documentation on how to use it

@command-bot
Copy link

command-bot bot commented Jul 16, 2024

@smiasojed Command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts has finished. Result: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6714033 has finished. If any artifacts were generated, you can download them from https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6714033/artifacts/download.

@smiasojed
Copy link
Contributor Author

bot bench substrate-pallet --pallet=pallet_contracts

@command-bot
Copy link

command-bot bot commented Jul 17, 2024

@smiasojed https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6715024 was started for your command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts. Check out https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/pipelines?page=1&scope=all&username=group_605_bot to know what else is being executed currently.

Comment bot cancel 1-0444d9ce-352d-468e-a732-d9f066c69dde to cancel this command or bot cancel to cancel all commands in this pull request.

Copy link

We are migrating the command bot to be a GitHub Action

Please, see the documentation on how to use it

…=dev --target_dir=substrate --pallet=pallet_contracts
@command-bot
Copy link

command-bot bot commented Jul 17, 2024

@smiasojed Command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts has finished. Result: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6715024 has finished. If any artifacts were generated, you can download them from https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6715024/artifacts/download.

@smiasojed smiasojed marked this pull request as ready for review July 17, 2024 10:14
@smiasojed smiasojed requested a review from athei as a code owner July 17, 2024 10:14
/// Update a storage entry into a contract's kv storage.
/// Function used in benchmarks, which can simulate prefix collision in keys.
#[cfg(feature = "runtime-benchmarks")]
pub fn bench_write_raw(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this call we could add and use Key::Raw variant, but I am not sure if it is better option, WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't call child::put_raw enough for the benchmark?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest keeping it this way. We can't use child::put_raw directly because that wouldn't include the read which is also part of every write due to storage deposits.

@paritytech-cicd-pr
Copy link

The CI pipeline was cancelled due to failure one of the required jobs.
Job name: cargo-clippy
Logs: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6720939

@smiasojed
Copy link
Contributor Author

bot bench substrate-pallet --pallet=pallet_contracts

@command-bot
Copy link

command-bot bot commented Jul 17, 2024

@smiasojed Command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts has finished. Result: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6722336 has finished. If any artifacts were generated, you can download them from https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6722336/artifacts/download.

@smiasojed smiasojed changed the title Add benchmarks with unbalanced trie [pallet_contracts] Modify the storage host function benchmarks to run on an unbalanced storage trie. Jul 17, 2024
@smiasojed
Copy link
Contributor Author

bot bench substrate-pallet --pallet=pallet_contracts

@command-bot
Copy link

command-bot bot commented Jul 17, 2024

@smiasojed https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6728111 was started for your command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts. Check out https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/pipelines?page=1&scope=all&username=group_605_bot to know what else is being executed currently.

Comment bot cancel 8-d69649a5-81b9-43ca-b2db-342523416327 to cancel this command or bot cancel to cancel all commands in this pull request.

Copy link

We are migrating the command bot to be a GitHub Action

Please, see the documentation on how to use it

@command-bot
Copy link

command-bot bot commented Jul 17, 2024

@smiasojed Command "$PIPELINE_SCRIPTS_DIR/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts has finished. Result: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6728111 has finished. If any artifacts were generated, you can download them from https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6728111/artifacts/download.

@smiasojed smiasojed removed request for a team July 17, 2024 19:45
result = child::get_raw(&child_trie_info, &key);
}

assert_eq!(result, Some(value));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we somehow verify that we did hit unbalanced_trie_layer nodes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we are providing a key as a parameter, we can be sure that we will hit it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean is there a way to assert that hitting this storage is traversing 20 nodes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are constructing the trie around the provided key. Assuming the trie construction is done correctly, we should hit 20 layers by writing to this key. I am not sure if we can assert this somehow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right looks like it can't be done, the weights results make sense, and I just doubled check by writing the proof to disk that the storage_full has indeed 20 keys more

This PR modifies the storage host function benchmarks. Previously, they were run
on an empty storage trie. Now, they are run on an unbalanced storage trie
to reflect the worst-case scenario. This approach increases the storage host
function weights and decreases the probability of DoS attacks.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts can write in storage in a way that produces an unbalanced trie? I expected this to be impossible/prevented.

Copy link
Contributor Author

@smiasojed smiasojed Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the keys for stored values are hashed using Blake2, so it is unlikely that this will happen in normal use. Main issue here is that we used empty trie for benchmarks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A contract can't create unbalanced tries because we hash the key from the contract. However, a contract could have a balanced but very big trie. The unbalanced trie is just use to simulate a deep trie for benchmarking.

Comment on lines +169 to +186
child::put_raw(&child_trie_info, &key, &value);
for l in 0..UNBALANCED_TRIE_LAYERS {
let pos = l as usize / 2;
let mut key_new = key.to_vec();
for i in 0u8..16 {
key_new[pos] = if l % 2 == 0 {
(key_new[pos] & 0xF0) | i
} else {
(key_new[pos] & 0x0F) | (i << 4)
};

if key == &key_new {
continue
}
child::put_raw(&child_trie_info, &key_new, &value);
}
}
Ok(contract)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite hard to scan, might be nice to add some explanation on how you construct the tree

Copy link
Contributor

@pgherveou pgherveou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after reviewing last comments

/// Update a storage entry into a contract's kv storage.
/// Function used in benchmarks, which can simulate prefix collision in keys.
#[cfg(feature = "runtime-benchmarks")]
pub fn bench_write_raw(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest keeping it this way. We can't use child::put_raw directly because that wouldn't include the read which is also part of every write due to storage deposits.

This PR modifies the storage host function benchmarks. Previously, they were run
on an empty storage trie. Now, they are run on an unbalanced storage trie
to reflect the worst-case scenario. This approach increases the storage host
function weights and decreases the probability of DoS attacks.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A contract can't create unbalanced tries because we hash the key from the contract. However, a contract could have a balanced but very big trie. The unbalanced trie is just use to simulate a deep trie for benchmarking.

@smiasojed smiasojed added this pull request to the merge queue Jul 29, 2024
Merged via the queue into master with commit cb9fdb5 Jul 29, 2024
157 of 161 checks passed
@smiasojed smiasojed deleted the sm/storage-pov branch July 29, 2024 08:57
TarekkMA pushed a commit to moonbeam-foundation/polkadot-sdk that referenced this pull request Aug 2, 2024
… on an unbalanced storage trie. (paritytech#5036)

This PR modifies the storage host function benchmarks. Previously, they
were run on an empty storage trie.
Now, they are run on an unbalanced storage trie to reflect worst case
scenario.
This approach increases the storage host function weights and decreases
the probability of DoS attacks.

---------

Co-authored-by: command-bot <>
Co-authored-by: PG Herveou <pgherveou@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T7-smart_contracts This PR/Issue is related to smart contracts.
Projects
Status: Audited
Development

Successfully merging this pull request may close these issues.

5 participants