Skip to content

[CHIA-3987] New cost model for 3.0 hard fork - #818

Open
arvidn wants to merge 14 commits into
mainfrom
new-cost-model
Open

[CHIA-3987] New cost model for 3.0 hard fork#818
arvidn wants to merge 14 commits into
mainfrom
new-cost-model

Conversation

@arvidn

@arvidn arvidn commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

This PR is best reviewed one commit at a time.

It has two major parts:

  • Replace the existing benchmark-clvm-cost tool. The current tool attempts to deduce a reasonable cost model for operators, by measuring. This is difficult. The new tool validates the existing cost model for an operator. This clearly exposes the problematic operators (and some moderately problematic)
  • Introduce a new cost model that can be enabled by a ClvmFlag. The tool is then used to validate the new model.

Measuring the true cost of operators

Operators with many arguments are not trivial to develop a cost model for. The more dimensions to explore, the more difficult it is to be confident that all relevant interactions have been accounted for.

A block can fit 11billion cost. A significant portion of that cost is typically paid via size (in bytes) and conditions (like CREATE_COIN and AGG_SIG_*). The worst case scenario is that most of this cost is paid in CLVM execution, i.e. CPU time. The benchmark I've been aiming at is to keep block execution under 10 seconds. That's approximately 1 nanosecond per cost. The ns/cost is the main metric I'm using, and somewhere around 0.5 is good.

All of my measurements are done on a MacBook Pro M1, a RPi5 will take longer.

To run the benchmark tools:

cargo run --release --features openssl --bin benchmark-clvm-cost -- --threads 3 --operator <op>

Keep in mind that you don't want to use more threads than there are efficiency cores on your computer.

dimensions

For 0-dimension operators, we can just run it many times and look at a distribution of how long it takes. An example of this is g1_negate, You can only pass in a single argument and it must be of a fixed size.

For 1-dimension operator, we can plot a line of time over number of arguments, and time over size of arguments.

And so on. For 3 dimensional, such as modpow it's a bit more difficuly. We can plot a heatmap for 2 arguments at a time, but the 3rd is always fixed, so we can only see slices through the 3d space. We can have multiple slices along each axis. For modpow I picked a few. Typically the results from the first few can inform other slices that are interesting to look at.

Existing cost model

The most problematic operators, cost wise, are modpow, div, divmod and mod. However, I also discovered that sha256 also has a cost lower than it should be. However, this is also affected by whether you build against openssl or not. Part of this patch is enabling the openssl feature in the tools project.

New cost model

It's described in docs/cost-model.md

Measurements

rpi5-measurements.zip

sha256 tree

$ cargo run --release --features openssl --bin sha256tree-benching -- --new-cost-model
cost for hashing complete tree (leaf size: 0)
           time     cost  ns/cost
Native:   96018   238743  0.4022
CLVM:    927354  3184571  0.2912
ratio:    10.4%    7.5%

cost for hashing complete tree (leaf size: 2)
           time     cost  ns/cost
Native:  144759   244887  0.5911
CLVM:    991558  3190715  0.3108
ratio:    14.6%    7.7%

cost for hashing complete tree (leaf size: 1000)
           time     cost  ns/cost
Native:  477483  3310743  0.1442
CLVM:   1312651  6256571  0.2098
ratio:    36.4%    52.9%

cost for hashing complete tree (leaf size: 100000)
           time     cost  ns/cost
Native: 33510133  307438743  0.1090
CLVM:   34365153  310384571  0.1107
ratio:    97.5%    99.1%

CLVM operators

Some highlights:

You can see the L1, L2 and L3 cache boundaries on large strings used with substr:
substr-string-start=0

The cost of multiply:

multiply-a-b

modpow has 3 dimensions, base-value, exponent and modulus:

modpow-base-exponent-modulus=8 modpow-base-modulus-exponent=1 modpow-base-modulus-exponent=32

>s bytes:

gr_bytes-a-b

>:
gr-a-b

eq is most expensive when every byte matches:

eq-a-b

divmod:

divmod-dividend-divisor

Note

High Risk
Changes consensus-relevant CLVM execution costs across many operators; incorrect constants or flag gating would affect block limits, mempool validation, and fee economics at activation.

Overview
Introduces a NEW_COST_MODEL dialect flag (3.0 hard fork) that retunes operator costs from benchmarks so reported cost tracks CPU time more closely—especially for bigint add/sub/mul/div/modpow, bitwise ops with mixed signs, BLS pairing/verify/map/multiply, and several hash/compare primitives.

Adds docs/cost-model.md describing measurement methodology and the new formulas (accumulator-based arithmetic, pairing per-arg rebalance, etc.). Fuzz targets now exercise ClvmFlags::NEW_COST_MODEL for operators and full run_program runs.

Expands regression coverage with *-v2 op-tests (core, BLS G1/G2/hash/pairing/verify, zk sample) wired in test_ops.rs under the new flag; BLS golden files are emitted in parallel by tools/generate-bls-tests.py. Tooling deps swap linreg for gnuplot (and related lockfile churn); CI installs cargo-audit --locked.

Reviewed by Cursor Bugbot for commit f4a19d0. Bugbot is set up for automated code reviews on this repo. Configure here.

arvidn and others added 13 commits July 14, 2026 11:56
…ng cost model, rather than attempts to deduce what a reasonable cost model should be, based on measurements.
…ew ClvmFlag

bump new cost per byte for gr
tweak bls_g1_multiply costs
tweak cost for bls_g2_multiply
tweak keccak base cost
…extensions. The cost will not be enforced for those, since it's changing
…always pay a cost for the first operand as well as the the operations. fix limbs() vs. len_for_value() inconsistency
@socket-security

socket-security Bot commented Jul 17, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: cargo libc is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ?cargo/chia-sha2@0.38.2cargo/chia-bls@0.38.2cargo/rand@0.9.4cargo/k256@0.14.0-rc.9cargo/p256@0.14.0-rc.9cargo/pyo3@0.29.0cargo/rand_chacha@0.9.0cargo/criterion@0.5.1cargo/sha1@0.10.6cargo/sha3@0.10.8cargo/libfuzzer-sys@0.4.10cargo/libc@0.2.182

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore cargo/libc@0.2.182. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@arvidn arvidn changed the title New cost model for 3.0 hard fork [CHIA-3987] New cost model for 3.0 hard fork Jul 17, 2026
@coveralls-official

coveralls-official Bot commented Jul 17, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 29605670847

Coverage decreased (-0.03%) to 88.087%

Details

  • Coverage decreased (-0.03%) from the base build.
  • Patch coverage: 52 uncovered changes across 3 files (450 of 502 lines covered, 89.64%).
  • 3 coverage regressions across 2 files.

Uncovered Changes

File Changed Covered %
tools/src/bin/sha256tree-benching.rs 26 0 0.0%
src/more_ops.rs 344 319 92.73%
src/chia_dialect.rs 9 8 88.89%
Total (9 files) 502 450 89.64%

Coverage Regressions

3 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
src/more_ops.rs 2 92.5%
tools/src/bin/sha256tree-benching.rs 1 0.0%

Coverage Stats

Coverage Status
Relevant Lines: 9737
Covered Lines: 8577
Line Coverage: 88.09%
Coverage Strength: 21074723.56 hits per line

💛 - Coveralls

@arvidn

arvidn commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit f4a19d0. Configure here.

@arvidn
arvidn marked this pull request as ready for review July 17, 2026 20:47
@arvidn
arvidn requested a review from wjblanke July 27, 2026 16:59
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