Sequential-chain proof: make miner work unparallelisable and duration unforgeable - #16
Open
elasticLove1 wants to merge 1 commit into
Open
Sequential-chain proof: make miner work unparallelisable and duration unforgeable#16elasticLove1 wants to merge 1 commit into
elasticLove1 wants to merge 1 commit into
Conversation
The v1 proof is a set of independent leaves, which means the work parallelises, a farm amortises one CPU across every account it owns, and the claimed duration is whatever the miner writes into a leaf. Measurements in acki-nacki#2591: an attacker pays ~1/40 of what an honest client pays for the same reward, and the ~3 cores that buys serve 98k accounts. Here step i consumes the state of step i-1, so the chain cannot be parallelised and producing it costs wall-clock time no amount of hardware removes. Keeping every state would cost gigabytes at the lengths that matter, so the miner keeps one state per `stride` steps and commits those. Making the spot-checked window exactly one checkpoint interval is what keeps verification cheap: the verifier replays `stride` steps between two committed endpoints, so its cost does not grow with the chain. The build cost can then be raised without touching what runs inside a block. A miner that computed only a fraction f of the chain passes only if every checked interval falls inside the part it did compute, so the odds are f^intervals -- 1% at f=10% with the two intervals the contract asks for. bee_verifier (v1) is untouched: its binary is whitelisted on the nodes and v1 miners still call it. v2 is a separate component with its own hash, so both can be live while miners migrate. Artifact sha256 62c3e9c1af291100969d84943d99ca3dea6899c1dd069f4ad68aa96989e27d59, reproduced by a clean rebuild. It goes into Miner_V2's _wasm_hash and the node's wasm whitelist.
Member
Author
|
Research and measurements behind this change: gosh-sh/acki-nacki#2591. Contract side: gosh-sh/acki-nacki#2592 — the two have to ship together, the node must whitelist |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the work in gosh-sh/acki-nacki#2591.
Pairs with the contract side in
acki-nackibranchresearch/miner-pow-cost(Miner_V2).Why
The v1 proof is a set of independent leaves. Three consequences, all measured
in the issue:
timestampfields the miner hashes itself andnothing checks against block time;
Together an attacker pays ~1/40 of what an honest client pays for the same
reward, and the ~3 cores that buys serve 98k accounts. Honest users complete
9.6% of their sessions.
Raising the difficulty does not help — it multiplies the honest client's cost 40×
harder than the farm's.
What changes
Step
iconsumes the state of stepi-1:A chain cannot be parallelised, so producing it costs wall-clock time that no
amount of hardware removes — only clock speed, worth under 2×. Every account
needs its own seconds.
Keeping verification cheap
Holding every state would cost gigabytes, so the miner keeps one state per
stridesteps — a checkpoint — and commits those as merkle leaves. Thespot-checked window is exactly one checkpoint interval: the verifier replays
stridesteps from checkpointkand must land on checkpointk+1, with bothendpoints proven against the root.
So verification costs
intervals × stridehashes plus two merkle paths —independent of chain length. The miner's work can be raised arbitrarily
without making in-block verification more expensive.
Measured at
stride = 256, 2 intervals: 40 µs on M3 and 93.7 µs on then14 box, against 42 µs / 62–103 µs for v1 on the same hardware. No regression.
Cheating
A miner that walked only a fraction
fpasses only if every checkedinterval lands inside the part it did walk — odds
f^intervals, so 1% atf = 10%with two intervals.Layout
bee_shared/src/miner/chain.rsbee_miner/src/core/chain.rsbee_verifier_v2/bee_verifier(v1) is untouched: its binary is whitelisted on the nodes andv1 miners keep calling it. v2 is a separate component with its own hash, so both
are live while miners migrate.
Artifact
Reproduced by a clean rebuild — the build is deterministic. This hash goes into
Miner_V2._wasm_hashand the node's wasm whitelist; the node has to know itbefore the contract is deployed, or every proof fails to run.
Tests
26 unit tests across the three crates. The ones that matter:
real overflow on
u64::MAX);Run with
cargo test -p bee-shared -p bee-miner;bee-verifier-v2needscdylibremoved from itsCargo.tomlfirst, same as v1.Not in this PR — read before reviewing
The client does not use the chain yet.
bee_miner/src/wasm/worker.rsstilldrives
MiningCore(v1 independent leaves);ChainCoreis built and tested butnot wired into the mining session. Switching it over needs
Miner_V2's ABI inackinacki-kit—setCommitDatatakes a checkpoint count instead of easy/hardleaf counts, and
GetIntervalcarries checkpoint indices — and the kit is atagged git dependency here (
v5.1.1). So the full path isackinacki-kit → bee-engine → contract, and this PR is the middle piece plus the
verifier.
What this PR does give you: the proof format, the on-device builder, and the
in-block verifier, all tested, with a reproducible artifact hash the contract and
the node can already be pointed at.
spawn_localcoroutine on the JS main thread, which is why
worker.rshas a 10 ms timer andthe device sits at ~2% of one core. The chain is single-core by nature, so the
worker is what lets it use the budget without touching the UI thread.
Non real devices (start 15–30 M steps).