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

Balances: Configurable Number of Genesis Accounts with Specified Balances for Benchmarking #6267

Open
wants to merge 27 commits into
base: master
Choose a base branch
from

Conversation

runcomet
Copy link
Contributor

@runcomet runcomet commented Oct 28, 2024

Derived Dev Accounts

Resolves #6040

Description

This update introduces support for creating an arbitrary number of developer accounts at the genesis block based on a specified derivation path. This functionality is gated by the runtime-benchmarks feature, ensuring it is only enabled during benchmarking scenarios.

Key Features

  • Arbitrary Dev Accounts at Genesis: Developers can now specify any number of accounts to be generated at genesis using a derivation path. This enables more flexibility for benchmarking use cases.

  • Default Derivation Path: If no derivation path is provided (i.e., when dev_accounts: (..., None) is set at genesis), the system will default to the path //Sender/{}.

  • Default Single Dev Account: A single developer account is created by default using the path //Sender/{}.

  • No Impact on Total Token Issuance: Developer accounts are excluded from the total issuance of the token supply at genesis, ensuring they do not affect the overall balance or token distribution.

polkadot address: 14SRqZTC1d8rfxL8W1tBTnfUBPU23ACFVPzp61FyGf4ftUFg

@cla-bot-2021
Copy link

cla-bot-2021 bot commented Oct 28, 2024

User @runcomet, please sign the CLA here.

@runcomet runcomet marked this pull request as ready for review November 5, 2024 20:30
@runcomet runcomet requested review from cheme and a team as code owners November 5, 2024 20:30
@paritytech-review-bot paritytech-review-bot bot requested a review from a team November 5, 2024 20:31
@runcomet
Copy link
Contributor Author

Balances of dev_accounts should not be included in the total issuance? @ggwpez

@runcomet runcomet changed the title Balances: Allow Configurable Number of Genesis Accounts with Specified Balances for Benchmarking Balances: Configurable Number of Genesis Accounts with Specified Balances for Benchmarking Nov 30, 2024
substrate/frame/balances/src/lib.rs Outdated Show resolved Hide resolved
substrate/frame/balances/src/lib.rs Outdated Show resolved Hide resolved
substrate/frame/balances/src/lib.rs Outdated Show resolved Hide resolved
substrate/frame/balances/src/lib.rs Outdated Show resolved Hide resolved
Comment on lines 1304 to 1308
.expect(&format!("Failed to parse derivation string: {}", derivation_string));

// Convert the public key to AccountId.
let who = T::AccountId::decode(&mut &pair.public().encode()[..])
.expect(&format!("Failed to decode public key from pair: {:?}", pair.public()));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
.expect(&format!("Failed to parse derivation string: {}", derivation_string));
// Convert the public key to AccountId.
let who = T::AccountId::decode(&mut &pair.public().encode()[..])
.expect(&format!("Failed to decode public key from pair: {:?}", pair.public()));
.unwrap_or_else(|| format!("Failed to parse derivation string: {derivation_string}"));
// Convert the public key to AccountId.
let who = T::AccountId::decode(&mut &pair.public().encode()[..])
.unwrap_or_else(|| format!("Failed to decode public key from pair: {:?}", pair.public()));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This would expect a default value for the respective operations, .expect() can't be used at genesis?

@runcomet runcomet requested a review from bkchr December 28, 2024 13:15
let who = T::AccountId::decode(&mut &pair.public().encode()[..])
.expect(&format!("Failed to decode public key from pair: {:?}", pair.public()));

frame_system::Pallet::<T>::inc_providers(&who);
Copy link
Member

Choose a reason for hiding this comment

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

Why this instead of doing a force_set_balance or something?

The less cases where we manually modify account references, the better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Getting familiar with the codebase.

I prefer your suggestion.

Thanks for the review!

Copy link
Member

Choose a reason for hiding this comment

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

You can look at the tests of the balances pallet, it has plenty of examples on how to force-set the balance of an account 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I used mutate_account_handling_dust

Copy link
Member

@ggwpez ggwpez left a comment

Choose a reason for hiding this comment

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

Looks broadly good, thanks 😄

@runcomet
Copy link
Contributor Author

runcomet commented Jan 3, 2025

please review @ggwpez @bkchr

@runcomet
Copy link
Contributor Author

runcomet commented Jan 9, 2025

please review @michalkucharczyk @bkchr @ggwpez

@@ -281,7 +282,32 @@ pub fn info_from_weight(w: Weight) -> DispatchInfo {
pub fn ensure_ti_valid() {
let mut sum = 0;

// Fetch the dev accounts from Account Storage.
let dev_accounts = (1000, EXISTENTIAL_DEPOSIT, "//Sender/{}".to_string()); // You can customize this as needed
Copy link
Contributor

@michalkucharczyk michalkucharczyk Jan 10, 2025

Choose a reason for hiding this comment

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

Should we use default const here for derivation string?

Copy link
Contributor Author

@runcomet runcomet Jan 10, 2025

Choose a reason for hiding this comment

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

for uniformity, probably

Copy link
Contributor

@michalkucharczyk michalkucharczyk left a comment

Choose a reason for hiding this comment

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

Frame is not my main area, but from what I can say it looks good.

Self {
balances: Default::default(),
dev_accounts: (
One::one(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this one by default? Since this is now enabled without any feature flag, we should not have a dev account on all chains by default.

Copy link
Contributor

@michalkucharczyk michalkucharczyk Jan 10, 2025

Choose a reason for hiding this comment

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

Following up on this one - random thought: shouldn't we make entire tuple optional?
e.g:

`dev_accounts: Option<(...)>`

That would allow us to easily cut dev-accounts related logic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes for shorter code.

Having the whole field be optional is great, default in the instances will be None.

Testing the logic through ensure_ti_valid(i.e. omitting the dev accounts from total_issuance) would still valid.

@@ -189,6 +195,8 @@ pub use pallet::*;

const LOG_TARGET: &str = "runtime::balances";

const DEFAULT_ADDRESS_URI: &str = "//Sender/{}";
Copy link
Contributor

Choose a reason for hiding this comment

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

When trying to play with this feature in a local zombienet, I encountered:

2025-01-10 14:25:26 panicked at /home/sebastian/.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom_or_panic-0.0.3/src/lib.rs:29:55:
Attempted to use functionality that requires system randomness!!
Error: Service(Other("wasm call error Execution aborted due to trap: wasm trap: wasm `unreachable` instruction executed\nWASM backtrace:\nerror while executing at wasm backtrace:\n    0: 0x19cec2 - cumulus_test_runtime.wasm!rust_begin_unwind\n    1: 0xddd8 - cumulus_test_runtime.wasm!core::panicking::panic_fmt::hb2d62c8e031896d7\n    2: 0x17b0a9 - cumulus_test_runtime.wasm!<getrandom_or_panic::getrandom_or_panic::PanicRng as rand_core::RngCore>::fill_bytes::panic_cold_display::he88660074c870e5f\n    3: 0xa81e1 - cumulus_test_runtime.wasm!schnorrkel::derive::Derivation::derived_key_simple::h3bfc095ab0e4fa27\n    4: 0x8990c - cumulus_test_runtime.wasm!<alloc::vec::into_iter::IntoIter<T,A> as core::iter::traits::iterator::Iterator>::fold::he6b04a97ec042f96\n    5: 0x5d589 - cumulus_test_runtime.wasm!pallet_balances::pallet::Pallet<T,I>::derive_dev_account::h2e451dd4081837dd\n    6: 0x5a537 - cumulus_test_runtime.wasm!<pallet_balances::pallet::GenesisConfig<T,I> as frame_support::traits::hooks::BuildGenesisConfig>::build::h0f54c9a4dd70ffa7\n    7: 0x13ac9a - cumulus_test_runtime.wasm!<cumulus_test_runtime::RuntimeGenesisConfig as frame_support::traits::hooks::BuildGenesisConfig>::build::h2b96dd85273b8fbf\n    8: 0x1232f1 - cumulus_test_runtime.wasm!frame_support::genesis_builder_helper::build_state::h5de7317ba07c9598\n    9: 0x89143 - cumulus_test_runtime.wasm!GenesisBuilder_build_state"))

I think the problem is that we are using soft derivation here which afaik requires randomness, which we don't have in the runtime. We could use //Sender//{} instead. This should work.

Copy link
Contributor Author

@runcomet runcomet Jan 10, 2025

Choose a reason for hiding this comment

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

Failed to run this test in all honesty.

Thanks for the review @skunert

@runcomet
Copy link
Contributor Author

runcomet commented Jan 10, 2025

Could I possibly see the CI run @ggwpez @skunert @michalkucharczyk, so I know what to test for?

@runcomet runcomet requested a review from acatangiu as a code owner January 11, 2025 01:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Balances: Arbitrary number of genesis accounts
5 participants