[CHIA-3987] New cost model for 3.0 hard fork - #818
Conversation
… types as well as num-bigint
…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
…o_g2 and op_bls_verify
|
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.
|
Coverage Report for CI Build 29605670847Coverage decreased (-0.03%) to 88.087%Details
Uncovered Changes
Coverage Regressions3 previously-covered lines in 2 files lost coverage.
Coverage Stats
💛 - Coveralls |
|
@cursor review |
There was a problem hiding this comment.
✅ 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.
This PR is best reviewed one commit at a time.
It has two major parts:
benchmark-clvm-costtool. 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)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_COINandAGG_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. Thens/costis 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:
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
modpowit'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,divmodandmod. However, I also discovered thatsha256also 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 thetoolsproject.New cost model
It's described in docs/cost-model.md
Measurements
rpi5-measurements.zip
sha256 tree
CLVM operators
Some highlights:
You can see the L1, L2 and L3 cache boundaries on large strings used with

substr:The cost of
multiply:modpowhas 3 dimensions, base-value, exponent and modulus:>sbytes:>:eqis most expensive when every byte matches:divmod: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_MODELdialect 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.mddescribing measurement methodology and the new formulas (accumulator-based arithmetic, pairing per-arg rebalance, etc.). Fuzz targets now exerciseClvmFlags::NEW_COST_MODELfor operators and fullrun_programruns.Expands regression coverage with
*-v2op-tests (core, BLS G1/G2/hash/pairing/verify, zk sample) wired intest_ops.rsunder the new flag; BLS golden files are emitted in parallel bytools/generate-bls-tests.py. Tooling deps swaplinregforgnuplot(and related lockfile churn); CI installscargo-audit --locked.Reviewed by Cursor Bugbot for commit f4a19d0. Bugbot is set up for automated code reviews on this repo. Configure here.