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

Fix the consensus chain benchmark command #3191

Merged
merged 2 commits into from
Oct 30, 2024
Merged

Conversation

NingLin-P
Copy link
Member

The benchmark command now requires the --genesis-builder-preset arg, which is a spec id that is used to load a JSON-encoded RuntimeGenesisConfig, if not specified "development" will be used. In our case, it will fail because we always return None despite the input:

fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
get_preset::<RuntimeGenesisConfig>(id, |_| None)
}

Ideally, we should follow the upstream practice of using spec id to load the responding RuntimeGenesisConfig for benchmark:
https://github.com/paritytech/polkadot-sdk/blob/cc4fe1ec1eee5d2141e8d6160d89bda2a9cf34b0/polkadot/runtime/westend/src/genesis_config_presets.rs#L412-L425
But because the domain runtime is also part of the consensus chain spec, which means the subspace-runtime will depend on all the domain runtime crates, doing so will increase the compile time a lot. cc @nazar-pc

This PR instead uses the default value of RuntimeGenesisConfig since each benchmark is coded for the worst scenario regardless of the RuntimeGenesisConfig value. The first commit is used to fix a deserialize issue about the default enable_rewards_at value because enable_rewards_at: EnableRewardsAt::Height(None) will encode as enable_rewards_at: {} and fail during decode.

Code contributor checklist:

@@ -307,7 +308,7 @@ pub mod pallet {
#[inline]
fn default() -> Self {
Self {
enable_rewards_at: EnableRewardsAt::Height(None),
enable_rewards_at: EnableRewardsAt::Height(Some(BlockNumberFor::<T>::one())),
Copy link
Member

Choose a reason for hiding this comment

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

Why exactly does it fail? It is a valid value, so it should be possible to serialize and deserialize.

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe an issue of serde_json, enable_rewards_at: EnableRewardsAt::Height(None) is encoded as "enable_rewards_at": {} and fail to decode EnableRewardsAt out of {}

Copy link
Member

Choose a reason for hiding this comment

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

Encoding and decoding should be symmetrical, if it is not then it is a bug and needs to be fixed, not hacked around 🤔

Copy link
Member Author

@NingLin-P NingLin-P Oct 29, 2024

Choose a reason for hiding this comment

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

I agree, I will report the issue to serde_json with a minimal reproducible example, but IMO it is not a hack for us since EnableRewardsAt::Height(None) is used as the same as EnableRewardsAt::Height(Some(1)) in genesis_build

Copy link
Member

@nazar-pc nazar-pc Oct 29, 2024

Choose a reason for hiding this comment

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

I'm pretty confident this is not a bug in serde_json or serde, it is something on our end. While I'm not opposed to this, I'd prefer to understand what would be a solution first.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe an issue of serde_json, enable_rewards_at: EnableRewardsAt::Height(None) is encoded as "enable_rewards_at": {} and fail to decode EnableRewardsAt out of {}

That’s not the encoding of Height(None), where did you get it from?
Here’s a playground which shows all the encodings:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5c363e2b04832edcdf06c569c2d34cdf

We derive the serde encoding on that enum, and don’t add any attributes:

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]

Then the pallet macro adds a camel case attribute:

https://github.com/paritytech/polkadot-sdk/blob/a42dcbf610336f691c335943ab146ebeda17ae36/substrate/frame/support/procedural/src/pallet/expand/genesis_config.rs#L101

So the encodings are:

Height(None) -> {"height":null}
Height(Some(5)) -> {"height":5}
SolutionRange(10) -> {"solutionRange":10}
Manually -> "manually"

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

@nazar-pc nazar-pc Oct 30, 2024

Choose a reason for hiding this comment

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

Please create a bug report with this, recursive dropping of null values is a very annoying behavior that makes values impossible to deserialize.

As to the fix, let's simply make EnableRewardsAt::Height contain BlockNumber rather than Option<BlockNumber>.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

I’m not sure what’s going wrong here, but that’s not the correct serde encoding.

@@ -307,7 +308,7 @@ pub mod pallet {
#[inline]
fn default() -> Self {
Self {
enable_rewards_at: EnableRewardsAt::Height(None),
enable_rewards_at: EnableRewardsAt::Height(Some(BlockNumberFor::<T>::one())),
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe an issue of serde_json, enable_rewards_at: EnableRewardsAt::Height(None) is encoded as "enable_rewards_at": {} and fail to decode EnableRewardsAt out of {}

That’s not the encoding of Height(None), where did you get it from?
Here’s a playground which shows all the encodings:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5c363e2b04832edcdf06c569c2d34cdf

We derive the serde encoding on that enum, and don’t add any attributes:

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]

Then the pallet macro adds a camel case attribute:

https://github.com/paritytech/polkadot-sdk/blob/a42dcbf610336f691c335943ab146ebeda17ae36/substrate/frame/support/procedural/src/pallet/expand/genesis_config.rs#L101

So the encodings are:

Height(None) -> {"height":null}
Height(Some(5)) -> {"height":5}
SolutionRange(10) -> {"solutionRange":10}
Manually -> "manually"

When using EnableRewardsAt::Height(None) deserialize json will fail

Signed-off-by: linning <[email protected]>
@NingLin-P NingLin-P added this pull request to the merge queue Oct 30, 2024
Merged via the queue into main with commit e12c829 Oct 30, 2024
8 checks passed
@NingLin-P NingLin-P deleted the fix-benchmark-genesis-build branch October 30, 2024 17:55
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.

3 participants