An append-only log that commits in 1040 bytes, however long it gets

A Merkle Mountain Range on Solana devnet: the account keeps at most 32 peak hashes and a count — never the leaves, never the interior nodes — so a log of ten entries and a log of a million cost the same 1040 bytes. A Solidity verifier on Base Sepolia checks the same proofs from the same specification. Both were deployed by us, to devnet and Base Sepolia.

The log account is BxrToumKoEDmnCbVfXSbr8Vz9U6rVU9YWYAAhHxx5Jv9. It holds 1023 leaves and its commitment is 0x3fe25b476b431746b5357fcced1bca1493f5bc86ef7a32a1e9ee30d142570727. The program's upgrade authority has been revoked — it is immutable, set in this transaction.

What the compute cost actually does

An append merges as many peaks as the new leaf count has trailing zeros, so the cost is a sawtooth: appending at n = 7 runs three merges and appending at n = 8 runs none. Every figure below was measured once against devnet and committed to the repository; this page performs no chain call, because a compute-unit cost is a property of a run and re-measuring on each visit would put a different number under a fixed prediction.

The predicted column comes from a cost model committed before a single measurement existed, so it could not be fitted to the results. Its shape held: cost rises monotonically with the hash count, the measured-to-predicted ratio spreads only 1.463× against the model's own 2× threshold for declaring the shape wrong, and 8, 16 and 32 are local minima. Its constants did not: the model said 1500 CU of overhead and 350 CU per hash; the measurements say 2437.8 and 165.8.

Compute units per append, measured on Solana devnet. Every row links to its transaction.
n merges hashes predicted measured naive rebuild tx
7 → 8 3 5 3250 3266 4925 explorer
8 → 9 0 3 2550 2926 5256 explorer
9 → 10 1 4 2900 3100 5588 explorer
15 → 16 4 6 3600 3436 7578 explorer
16 → 17 0 3 2550 2930 7909 explorer
17 → 18 1 4 2900 3100 8241 explorer
31 → 32 5 7 3950 3602 12883 explorer
32 → 33 0 3 2550 2930 13215 explorer
33 → 34 1 4 2900 3100 13547 explorer
63 → 64 6 8 4300 3768 23495 explorer
64 → 65 0 3 2550 2930 23826 explorer
127 → 128 7 9 4650 3945 44717 explorer
128 → 129 0 3 2550 2941 45049 explorer
255 → 256 8 10 5000 4111 87163 explorer
256 → 257 0 3 2550 2941 87494 explorer
511 → 512 9 11 5350 4277 172053 explorer
512 → 513 0 3 2550 2941 172385 explorer
1022 → 1023 0 11 5350 4217 341502 explorer

The naive-rebuild column is computed, not measured. naive_rebuild_cu uses the MODEL constants; naive_rebuild_cu_fitted uses the measured ones. Both are computed, neither is measured: at n=1023 a rebuild needs 2045 hashes, which exceeds the 1,400,000 CU per-instruction ceiling under the fitted cost and would also need account space for every leaf.

Where the model was wrong

The model said: MODEL.md, section 'The naive baseline': at n=1023 a rebuild is 'over Solana's per-instruction ceiling even with the compute budget raised to its 1,400,000 maximum'.

WRONG, and wrong on the model's own arithmetic as well as on the measured constants. With the model's own PER_HASH=350 the figure is 717,250 CU, which is already under 1,400,000 - so the sentence did not follow from the numbers printed two lines above it.

A naive rebuild at n=1023 costs about 341,499 CU, roughly 81x the MMR append, and DOES fit under the raised ceiling. It stops fitting at around n = 4,215 leaves. The compute argument is therefore a ratio argument at this size, not a possibility argument.

The SPACE argument, which was never in doubt: the MMR account is 1040 bytes at any length, while storing 1023 leaves needs 32,736 bytes for the leaves alone. Solana's 10 MB account ceiling caps a leaf-storing log near 327,000 entries; the peaks-only log has no such bound below 2^32.

The model file was not edited to match the results. A prediction quietly corrected after the data arrives is worth nothing, so the correction lives beside the measurements that forced it.

One finding nobody planned

Two appends in the table perform the same number of hashes and cost different amounts. At n = 511 the work is 4277 CU across nine merges; at n = 1022 it is 4217 CU across nine bagging hashes. The 60 CU between them is loop overhead the model had assumed was identical.

What this does not claim

  • The Base Sepolia verifier proves a proof is consistent with a root it is handed. It has no view of Solana and cannot confirm that root is the one the devnet account holds — the operator supplies it. This is not cross-chain verification.
  • The log stores no leaves. Recovering them means replaying the transactions that appended them, which is what the repository's CLI does.
  • Appends are permissionless in this build. There is no access control, because the property on show is the commitment structure and an authority check would demonstrate something else.
  • It is not a rollup, a bridge or a light client.

The two repositories

  • pigfox/mmr-log — the specification, the no_std Rust crate, the native Solana program, the CLI and the benchmark.
  • pigfox/mmr-verifier — the Solidity verifier, with a differential gate that runs the Rust reference over FFI and requires byte-identical roots and proofs.