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

feat: pallet benchmarking interactive UI #420

Open
wants to merge 176 commits into
base: chungquantin/feat-pop_bench_command
Choose a base branch
from

Conversation

chungquantin
Copy link
Collaborator

@chungquantin chungquantin commented Feb 19, 2025

Description

The PR is a part of a bigger PR #424. It implements the full flow of the pop bench pallet including new key features:

  • Interactive UI to manage parameters before running the benchmark.
  • Sourcing the frame-omni-bencher binary feat: add code to source omni bencher #428. This is required to list pallets and extrinsics. Explained here
  • Refactor to use our own version of PalletCmd (called BenchmarkPallet) instead of frame-benchmarking-cli::PalletCmd due to required parameters issue. Explained here

How to test the PR?

pop bench pallet

If arguments are provided like

pop bench pallet --runtime=path-to-runtime --pallet= --extrinsic=

We skip the runtime, the pallet and the extrinsic.

To skip the parameter menu, user can specify flag --skip then the parameter menu can be skipped and go directly to run the bencmarking.

pop bench pallet --skip

Test single line command

pop bench pallet --pallet=pallet_balances --extrinsic=burn_allow_death,burn_keep_alive --steps=50 --repeat=20 --external-repeat=1 --db-cache=1024 --map-size=1000000 --additional-trie-layers=2 --output-pov-analysis=median-slopes --runtime=/Users/chungquantin/Developer/pop-network/pop-cli/tests/runtimes/base_parachain_benchmark.wasm --genesis-builder=runtime --genesis-builder-preset=development

Help command

Screenshot 2025-03-05 at 11 56 16

Full flow breakdown

Note: If --list or --json-output is provided, we run the command by frame-benchmarking-cli directly instead of go through the implementation in pop-cli.

Stage 1: Locate runtime or input runtime path manually

Screenshot 2025-02-28 at 17 05 25 Screenshot 2025-02-28 at 17 03 33
  • 1.3. Inputting the runtime manually. User can input the path to parachain project or path to WASM binary file directly.

NOTE: After the path is located and there is no WASM file found in the target/<profile>/wbuild/<runtime-name>.wasm, we will build the runtime with runtime-benchmarks feature first.

Stage 2: Select genesis builder policy & preset

See full breakdown in #411

Stage 3: Select pallets (Single Select) & extrinsics (Multiple Select)

At this stage, we will check if the binary of frame-omni-bencher exists on the user's machine. Explained here

Note: We only call frame-omni-bencher to load pallets and extrinsics once a session.

  • 3.1. "🔎 Search for pallets by name": User can specify the pallet name to search for the pallets (fuzzy searching).

For the extrinsic selection, we only allow user to select if there are pallet specified. If all pallet are selected (--pallet=*), we skip the next step.

  • 3.2. "🔎 Search for extrinsics by name": User can specify the extrinsic name to search for the extrinsics (fuzzy searching).
Screenshot 2025-03-05 at 11 50 10 Screenshot 2025-03-05 at 11 51 05

Stage 4: Parameter menu

User can update the parameters by selecting an option in the parameter menu. Some arguments will be disabled depend on the status of other parameters. See is_disabled method. For example:

  • we don't allow selecting extrinsics if all pallets are selected.
  • we don't allow update the genesis builder preset if policy is equal to GenesisBuilderPolicy::None
Screenshot 2025-02-28 at 17 15 29

Stage 5: Input the output path

This stage is optional, if no value is provided, we don't write to any file.

Screenshot 2025-02-28 at 17 19 30

Stage 6: Print the single line command

Screenshot 2025-02-28 at 17 20 08

[sc-2882]

* feat: add bench subcommand

* feat: integrates frame-benchmarking-cli

* refactor: PalletCmd run with spec

* feat: set RUST_LOG=info for benchmarking display

* feat: add CLI messages and tests

* feat: add benchmark runtime wasm test

* chore: fix comment

* fix: operator cannot be applied to type

* chore: display error and refactor test file

* chore: rename `bench` file

* chore: clippy warning

* refactor: parachain feature in bench command

* feat: add bench subcommand

* feat: integrates frame-benchmarking-cli

* refactor: PalletCmd run with spec

* feat: add CLI messages and tests

* feat: add benchmark runtime wasm test

* chore: fix comment

* fix: operator cannot be applied to type

* chore: display error and refactor test file

* chore: rename `bench` file

* chore: clippy warning

* refactor: parachain feature in bench command

* chore: revert mod.rs

* feat: add bench subcommand

* chore: revert mod.rs

* feat: add bench subcommand

* feat: integrates frame-benchmarking-cli

* refactor: PalletCmd run with spec

* feat: set RUST_LOG=info for benchmarking display

* feat: add CLI messages and tests

* feat: add benchmark runtime wasm test

* chore: fix comment

* fix: operator cannot be applied to type

* chore: display error and refactor test file

* chore: rename `bench` file

* chore: clippy warning

* refactor: parachain feature in bench command

* feat: add bench subcommand

* feat: integrates frame-benchmarking-cli

* refactor: PalletCmd run with spec

* feat: add CLI messages and tests

* feat: add benchmark runtime wasm test

* chore: fix comment

* fix: operator cannot be applied to type

* chore: display error and refactor test file

* chore: rename `bench` file

* chore: clippy warning

* refactor: parachain feature in bench command

* chore: revert mod.rs

* feat: add bench subcommand

* chore: revert mod.rs

* chore: revert changes

* feat: benchmark existing runtime binary and select policy, presets (#411)

* feat: add bench subcommand

* feat: integrates frame-benchmarking-cli

* refactor: PalletCmd run with spec

* feat: set RUST_LOG=info for benchmarking display

* feat: add CLI messages and tests

* feat: add benchmark runtime wasm test

* chore: fix comment

* fix: operator cannot be applied to type

* chore: display error and refactor test file

* feat: auto detect wasm blob and build runtime

* feat: build runtime wasm blob

* refactor: build binary path method

* fix: runtime path test

* refactor: feature gating for benchmarking feature

* chore: remove unused argument

* fix: comment

* chore: rename `bench` file

* chore: rename `bench` file

* feat: auto detect wasm blob and build runtime

* feat: build runtime wasm blob

* refactor: build binary path method

* feat: list and select runtimes

* chore: remove unused code

* feat: auto detect wasm blob and build runtime

* feat: build runtime wasm blob

* refactor: build binary path method

* chore: removed duplicate code

* chore: remove spinner

* chore: clippy warning

* chore: clippy warning

* refactor: parachain feature in bench command

* chore: reorder imports

* feat: select genesis builder

* refactor: test helpers

* chore: remove output display

* chore: update parse genesis builder comment

* fix: locate runtime and help command

* chore: clippy warning

* chore: display error message on binary check

* fix: comment

* feat: add genesis preset check (#422)

* feat: add genesis preset check

* feat: update_genesis_preset

* refactor: constant name & add tests for preset

* refactor: get_runtime_path

* refactor: code order

* refactor: test files

* chore: clippy warning

* refactor: list presets instead of manual input

* feat: default to `none` if no presets found

* refactor: build project test instead of runtime
* refactor: use filter_mode to fuzzy search pallets

* chore: update cargo-deny-action@v2

* chore: rebase

* chore: revert not relevant changes

* chore: delete conflicting file

* feat: add confirm input to extrinsics selection
Some(temp_file.as_file()),
vec![
&format!("--runtime={}", runtime_path.display()),
"--genesis-builder=none",
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We need this flag otherwise error thrown in the child process.

@@ -37,6 +37,7 @@ zombienet-sdk.workspace = true
# Benchmarking
cumulus-primitives-proof-size-hostfunction.workspace = true
frame-benchmarking-cli.workspace = true
fuzzy-matcher = "0.3.7"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed this crate in #442

.default_input("./runtime")
.placeholder("./runtime")
.interact()
.map(PathBuf::from)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Resolved!

.input("Please provide the path to the runtime or parachain project.")
.required(true)
.default_input("./runtime")
.placeholder("./runtime")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Resolved!

@chungquantin chungquantin requested a review from AlexD10S March 5, 2025 05:10
@chungquantin chungquantin force-pushed the chungquantin/feat-pallet_bench_ui branch from 2fb9adf to 5181c5a Compare March 5, 2025 06:05
Copy link
Collaborator

@Daanvdplas Daanvdplas left a comment

Choose a reason for hiding this comment

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

Thanks for the super clear information provided! I was able to immediately start reviewing without any hurdles, fantastic!!!

Also well done on the PR and research that you have put into it!

I have a question and some commands that were failing for me, I have gone through all the code but haven't been able to test the functionality yet so that will come next time.

Why pop bench pallet and not pop bench?

Some commands that were failing:

  • pop bench pallet --list not so clear error:
Screenshot 2025-03-05 at 15 36 21

Resolved by not throwing error anymore. Listing pallets for non runtime-benchmarks feature runtime binary works normally.

  • pop bench pallet:
Screenshot 2025-03-05 at 16 30 59

@chungquantin Resolved:
Screenshot 2025-03-06 at 19 02 56

  • pop bench pallet --runtime=runtime --pallet= --extrinsic= in pop-node folder:
Screenshot 2025-03-05 at 16 40 23

@chungquantin Resolved:
Screenshot 2025-03-06 at 19 07 22


/// Comma separated list of pallets that should be excluded from the benchmark.
#[arg(long, value_parser, num_args = 1.., value_delimiter = ',')]
pub exclude_pallets: Vec<String>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I assume this one is used in combination with the below flag or pallet=* ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes correct, this is only used when pallet=*

Copy link
Collaborator

Choose a reason for hiding this comment

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

And with the flag all? If that is not allowed we could add the conflicts_with

Copy link
Collaborator

@AlexD10S AlexD10S left a comment

Choose a reason for hiding this comment

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

Great work, Tin! The searcher is running smoothly, so cool!

I left a few comments, but they’re all minor and not blockers. Approved! 🎉

match option.update_arguments(self, &mut registry, cli).await {
Ok(true) => break,
Ok(false) => continue,
Err(e) => cli.info(e)?,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not requesting a change, just a question, an info message here is better than an error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Throws error here would panic and cancel the loop. The idea is whenever there's an error, we log the error and display the menu again.

Copy link
Collaborator

@AlexD10S AlexD10S Mar 7, 2025

Choose a reason for hiding this comment

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

I didn't mean to throw an error, it was more about the message cliclack::log::error or maybe a cliclack::log::warning instead of an info.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah I see, apologies I did not aware of the feature in cliclack

@chungquantin chungquantin requested a review from Daanvdplas March 6, 2025 12:08
@Daanvdplas
Copy link
Collaborator

  • I did pop bench pallet and gave input to points 0 to 4, now in the parameter menu they are asked again:
Screenshot 2025-03-07 at 16 19 28 If it is an easy fix, can we eliminate the things that are provided by the user from the menu?
  • Could we ask if the user would like to go through the parameter menu? The skip flag is already a great flag!
  • Loading the menu is also slow, do we know why?
  • Can we remove the word FRAME here?
Screenshot 2025-03-07 at 16 25 09

Could we add a newline before outputting the generated command (great feature!):
Screenshot 2025-03-07 at 16 39 25

When we can choose the extrinsics to benchmark, can we add (select with space)?
Screenshot 2025-03-07 at 16 42 29

Copy link
Collaborator

@Daanvdplas Daanvdplas left a comment

Choose a reason for hiding this comment

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

I left some UX improvements / suggestions, but wow what an amazing PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-for-final-review The PR is ready for final review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants