Skip to content

params%feat!: apply the reference chain-params options - #105

Closed
PastaPastaPasta wants to merge 4 commits into
pasta/params-setupfrom
pasta/params-options
Closed

PastaPastaPasta wants to merge 4 commits into
pasta/params-setupfrom
pasta/params-options

Conversation

@PastaPastaPasta

Copy link
Copy Markdown
Member

Motivation

Stacked on #104. ChainSetup gives a network's chain parameters at a release, but only with the defaults. Regtest and devnet nodes are usually started with options that change them: activation heights, version-bits deployments, LLMQ types and sizes, budget and DIP3 heights, a named devnet, spork signers. A client that follows such a chain has to apply the same options and refuse the same values.

This pull request applies the reference implementation's chain-params options to a ChainSetup, as v23.1.8 and v24.0.0-rc.5 do. Each option is applied in the reference's order, and each refused value returns the reference's error text. The dump tool from #104 now also takes options, so every case in a new case list is checked against both releases.

Additional Information

Description Notes
Apply the reference chain-params options ChainParamsBuilder takes the options of ChainOption, the two spork options of the next row and these 19 (-testactivationheight, -vbparams, -dip3params, -budgetparams, -powtargetspacing, -devnet, -fastprune, the -llmq* type and size options, -highsubsidyblocks, -highsubsidyfactor and -minimumdifficultyblocks), typed with arg and negate or raw with parse_arg, which keeps the argument's spelling for the error text. parse_arg gives the builder back unchanged as Err for an argument that names no chain option, so a node's whole command line can be fed through it. build returns Result<ChainSetup, ParamsError>. Options write the one ChainParams a ChainSetup holds, so everything read through it, ConsensusParams::llmq included, has the options applied. LLMQ size options live in the new Copy field ConsensusParams::llmq_sizes. A named devnet's genesis block becomes its height-1 checkpoint, which ChainParams::all_checkpoints adds to the static checkpoints.
Resolve spork signers -sporkaddr and -minsporkkeys resolve to SporkSigners, with key IDs read by base58ck. v23.1 takes -minsporkkeys only. A dash-script test checks the key ID reader against Recipient::from_base58c on every network at both releases.
Check the options against the reference dumps The dump prints the spork signers, the derived LLMQ values and the error text of a refused option. gen.py runs the 212 cases that chainparams_cases.json5 lists at each release, and the corpora gain a cases section. dash-params replays every case, and dash-primitives checks the genesis and devnet genesis blocks of the cases that change them.
Record the chain-params options in the changelog

Rerunning gen.py with both releases' dumps and the case list reproduces the corpora byte for byte, and contrib/params/README.md gives the recipe. A repeated -devnet is refused by the reference at startup, outside its chain parameters, so devnet_name takes one name and the builder does not check for repeats.

Breaking Changes

  • ChainParamsBuilder::build returns Result<ChainSetup, ParamsError> instead of ChainSetup, since options can be refused.
  • ConsensusParams has the new public field llmq_sizes, so a ConsensusParams literal must set it. The network tables use LlmqSizes::NONE.
  • The devnet table's checkpoints holds height 0 only. Use ChainParams::all_checkpoints for a devnet's height-1 checkpoint.
  • dash-params now depends on base58ck and thiserror.

How Has This Been Tested?

  • Each of the 212 cases per release is replayed against the corpora from both releases' dumps, and every refused case must return the reference's error text.
  • Unit tests in tests/builder.rs cover the typed and raw entry points, negation and the refusals the dump cannot reach, where the reference aborts.
  • CI (just test lint fuzz::test, CodeQL included) is green on each commit.

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional tests
  • I have made corresponding changes to the documentation
  • I did not use agentic assistance (i.e. LLMs, AI) except as disclosed and can answer questions,
    comments and concerns without said assistance. I assume authorship of the code submitted.
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

Agent disclosure

Code, commit messages and this description were generated with Claude Code using Claude Opus 5.5, running autonomously as an agent on behalf of the author. The agent also built both releases and generated the corpora with the tools in contrib/params. The change was reviewed by a Claude Code agent using Opus 5.5 and a Codex agent using GPT-6.1.

🤖 Generated with Claude Code

ChainParamsBuilder takes the regtest and devnet options, typed or raw;
build returns a Result. Options write the one ChainParams, LLMQ sizes
included, and all_checkpoints adds a named devnet's checkpoint.
-sporkaddr and v23.1's -minsporkkeys resolve to SporkSigners, with key
IDs read by base58ck. A dash-script test checks the reader against
Recipient::from_base58c.
The dump prints the spork signers and derived LLMQ values and takes the
spork options. gen.py writes the cases chainparams_cases.json5 lists,
and dash-params and dash-primitives replay them.
The builder takes the reference options and build returns a Result.
@coderabbitai

coderabbitai Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 28 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between b93d4bb and cdd6e24.

Files ignored due to path filters: 6
  • Cargo.lock is excluded by !**/*.lock, !**/*.lock
  • MODULE.bazel.lock is excluded by !**/*.lock, !**/*.lock
  • pkgs/params/corpus/brr_payments.json5 is excluded by !**/*.json5
  • pkgs/params/corpus/chainparams_cases.json5 is excluded by !**/*.json5
  • pkgs/params/corpus/chainparams_v23_1.json5 is excluded by !**/*.json5
  • pkgs/params/corpus/chainparams_v24_0.json5 is excluded by !**/*.json5
Files selected for processing: 29
  • contrib/params/README.md
  • contrib/params/chainparams_dump.cpp
  • contrib/params/gen.py
  • pkgs/params/CHANGELOG.md
  • pkgs/params/Cargo.toml
  • pkgs/params/src/builder.rs
  • pkgs/params/src/chain.rs
  • pkgs/params/src/consensus.rs
  • pkgs/params/src/deployment.rs
  • pkgs/params/src/error.rs
  • pkgs/params/src/lib.rs
  • pkgs/params/src/llmq.rs
  • pkgs/params/src/params/devnet.rs
  • pkgs/params/src/params/mainnet.rs
  • pkgs/params/src/params/regtest.rs
  • pkgs/params/src/params/test3.rs
  • pkgs/params/src/parse.rs
  • pkgs/params/src/prelude.rs
  • pkgs/params/src/release.rs
  • pkgs/params/src/setup.rs
  • pkgs/params/src/spork.rs
  • pkgs/params/tests/brr_payments.rs
  • pkgs/params/tests/builder.rs
  • pkgs/params/tests/reference_dumps.rs
  • pkgs/params/tests/setup.rs
  • pkgs/primitives/tests/chainparams_blocks.rs
  • pkgs/primitives/tests/genesis_valid.rs
  • pkgs/script/Cargo.toml
  • pkgs/script/tests/spork_key_ids.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@thepastaclaw

thepastaclaw commented Nov 1, 2026 •

Copy link
Copy Markdown

⛔ Final review complete — 1 blocking finding(s) (commit cdd6e24) · triage: critical

@codecov

codecov Bot commented Nov 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.18434% with 5 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
pkgs/params/src/builder.rs 99.53% 2 Missing ⚠️
pkgs/params/src/llmq.rs 93.54% 2 Missing ⚠️
pkgs/params/src/setup.rs 95.23% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Final validation — Phase 1 + Phase 2

Verified the supplied findings against cdd6e24 and both pinned Dash Core parsers: Windows option-key normalization is missing and can silently discard consensus overrides. The checkpoint suggestion is unnecessary because the current table, its adjacent comment, and regression tests establish the ordering invariant. This was static-only validation; current CI has all build, test, lint, and cross-build checks passing, with only the non-blocking codecov/project/dash-num coverage check failing.

🔴 1 blocking

Review provenance

Source: reviewer 1: gpt-6.1-sol (agent: phase2-reviewer, role: general); reviewer 2: gpt-6.1-sol (agent: phase2-reviewer, role: rust-quality); reviewer 3: gpt-6.1-sol (agent: phase2-reviewer, role: security-auditor); reviewer 4: gpt-6-astra (agent: phase2-reviewer, role: general); reviewer 5: gpt-6-astra (agent: phase2-reviewer, role: rust-quality); reviewer 6: gpt-6-astra (agent: phase2-reviewer, role: security-auditor); reviewer 7: muse-spark-1.3-contributor (agent: phase1-reviewer, role: general); reviewer 8: muse-spark-1.3-contributor (agent: phase1-reviewer, role: rust-quality); final verifier: gpt-6.1-sol (agent: sol-verifier, role: final-verifier)

  • Triage: critical by gpt-6.1-sol (effort low) — The intricate option application in pkgs/params/src/builder.rs changes effective consensus activation heights, version-bits deployments, quorum parameters and devnet genesis checkpoints, meeting both the complexity and critical-surface criteria.
  • Phase 1 reviewers: muse-spark-1.3-contributor — general (completed, effort xhigh); agent phase1-reviewer, muse-spark-1.3-contributor — rust-quality (completed, effort xhigh); agent phase1-reviewer
  • Phase 1 model: muse-spark-1.3-contributor — not quota-gated; passed over gemini-3.8-flash-high (antigravity quota lookup failed), glm-5.3-flash (not used above high effort; tier asks max)
  • Single stage: Phase 1 and Phase 2 reviewed this head side by side, with no blocker gate between them (triage tier)
  • Fresh verifier: gpt-6.1-sol — final-verifier; agent sol-verifier
  • Phase 2 reviewers: gpt-6.1-sol — general (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6.1-sol — security-auditor (completed, effort xhigh); agent phase2-reviewer, gpt-6-astra — general (completed, effort xhigh); agent phase2-reviewer, gpt-6-astra — rust-quality (completed, effort xhigh); agent phase2-reviewer, gpt-6-astra — security-auditor (completed, effort xhigh); agent phase2-reviewer
  • Model comparison: every Phase-2 reviewer also ran on gpt-6-astra; the verifier weighed both sets without knowing which model wrote which
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `pkgs/params/src/builder.rs`:
- [BLOCKING] pkgs/params/src/builder.rs:257-265: Match Core's Windows option-key normalization
  Both pinned Core releases lowercase option keys and translate an initial `/` to `-` on Windows before resolving the option ([v23.1.8](https://github.com/dashpay/dash/blob/728f5055836c6d29806412fc7223ac8fe05af991/src/util/system.cpp#L330-L340), [v24.0.0-rc.5](https://github.com/dashpay/dash/blob/8163290aa0307ed4bc2fc0ba15b78c20d61dfa88/src/util/system.cpp#L250-L260)). This parser instead requires a dash and an exact lowercase name on every platform. Consequently, valid Windows arguments such as `/dip3params=105:106` and `-DIP3PARAMS=105:106` return the builder unchanged as `Err`. With the documented whole-command-line pattern, which keeps the returned builder and continues, `build()` succeeds with regtest's default DIP3 heights 432/500 rather than the node's 105/106. Apply Core's Windows key normalization, or expose an explicit source-platform parsing mode, without lowercasing values or losing the original argument used in diagnostics. Add regression cases for slash-prefixed and mixed-case keys, including negations.

Comment on lines +257 to +265
let Some(name) = key.strip_prefix("--").or_else(|| key.strip_prefix('-')) else {
return Err(self);
};
let (negated, name) = match name.strip_prefix("no") {
Some(name) => (true, name),
None => (false, name),
};
let Some(option) = ChainOption::from_name(&format!("-{name}")) else {
return Err(self);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Blocking: Match Core's Windows option-key normalization

Both pinned Core releases lowercase option keys and translate an initial / to - on Windows before resolving the option (v23.1.8, v24.0.0-rc.5). This parser instead requires a dash and an exact lowercase name on every platform. Consequently, valid Windows arguments such as /dip3params=105:106 and -DIP3PARAMS=105:106 return the builder unchanged as Err. With the documented whole-command-line pattern, which keeps the returned builder and continues, build() succeeds with regtest's default DIP3 heights 432/500 rather than the node's 105/106. Apply Core's Windows key normalization, or expose an explicit source-platform parsing mode, without lowercasing values or losing the original argument used in diagnostics. Add regression cases for slash-prefixed and mixed-case keys, including negations.

source: gpt-6-astra (phase2-reviewer: general)

@kwvg kwvg left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The whole premise of having a builder doesn't fit the SDK, see comment.

@PastaPastaPasta

Copy link
Copy Markdown
Member Author

Closing, together with #104 (see #104 (comment)). Applying the reference chain-params options sets up regtest and devnet chains through tunables, which is outside the scope of a stateless SDK. That work belongs in rust-dashcore.


🤖 Posted autonomously by Claude on behalf of pasta.

@kwvg
kwvg deleted the pasta/params-options branch November 1, 2026 09:46
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