Skip to content

fix(dpp)!: version-gate distribution function floating-point evaluation#3462

Draft
PastaPastaPasta wants to merge 1 commit intov3.1-devfrom
fix/version-gate-float-reward-evaluation
Draft

fix(dpp)!: version-gate distribution function floating-point evaluation#3462
PastaPastaPasta wants to merge 1 commit intov3.1-devfrom
fix/version-gate-float-reward-evaluation

Conversation

@PastaPastaPasta
Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

DistributionFunction::evaluate() uses f64 transcendental functions (powf/exp/ln) to compute consensus-critical token rewards. The std implementations are platform-dependent (varying across CPU architectures and libm versions), risking consensus divergence between nodes computing different integer rewards for the same claim.

Concrete proof: 125^(1/3) yields 4 on some platforms (std powf) vs 5 on others. The deterministic libm path always returns 5.

What was done?

Gate transcendental float operations behind distribution_function_evaluate_version in DPPTokenVersions:

  • Version 0 (all current protocol versions through v12): preserves original std behavior (.powf(), .exp(), .ln())
  • Version 1+: uses deterministic libm functions (pow, exp, log)

Changes:

  • Add distribution_function_evaluate_version field to DPPTokenVersions
  • Create TOKEN_VERSIONS_V3 with deterministic evaluation enabled (for use in a future protocol version)
  • Add libm = "0.2" dependency to rs-dpp
  • Thread platform_version through evaluate()evaluate_interval()rewards_in_interval() call chain
  • Version-gate 4 transcendental call sites: Polynomial (pow), Exponential (exp), Logarithmic (log), InvertedLogarithmic (log)
  • 5 unaffected variants use only integer math: FixedAmount, Random, StepDecreasingAmount, Stepwise, Linear

Note: TOKEN_VERSIONS_V3 is created but not yet assigned to a platform version. A future PR creating PLATFORM_V13 should reference it to activate deterministic evaluation on the network.

How Has This Been Tested?

  • All 50 evaluate() unit tests pass (47 existing + 3 new determinism tests)
  • All 82 validation.rs tests pass
  • All 72 evaluate_interval tests pass (with token-reward-explanations feature)
  • Determinism regression tests for all 4 affected variants using distribution_function_evaluate_version = 1
  • cargo check -p dpp -p drive compiles clean

Breaking Changes

Function signature changes (compile-time only, no behavioral change for existing protocol versions):

  • DistributionFunction::evaluate() now requires platform_version: &PlatformVersion
  • DistributionFunction::evaluate_interval() now requires platform_version: &PlatformVersion
  • RewardDistributionType::rewards_in_interval() now requires platform_version: &PlatformVersion

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/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

DistributionFunction::evaluate() uses f64 transcendental functions (pow/exp/log) to compute consensus-critical token rewards. The std implementations are platform-dependent, risking consensus divergence between nodes with different architectures or libm versions.

Gate these operations behind distribution_function_evaluate_version in DPPTokenVersions. Version 0 preserves the original std behavior (.powf/.exp/.ln) for existing protocol versions. Version 1+ uses deterministic libm functions for cross-platform consistency.

Changes: - Add distribution_function_evaluate_version field to DPPTokenVersions - Create TOKEN_VERSIONS_V3 with deterministic evaluation enabled - Add libm 0.2 dependency to rs-dpp - Thread platform_version through evaluate() -> evaluate_interval() -> rewards_in_interval() call chain - Version-gate 4 transcendental call sites: Polynomial (pow), Exponential (exp), Logarithmic (log), InvertedLogarithmic (log) - Add determinism regression tests for all 4 affected variants
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5653c523-5723-4025-a8e3-f67795dcbbcf

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/version-gate-float-reward-evaluation

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added this to the v3.1.0 milestone Apr 8, 2026
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.

1 participant