dash(embedded): pin the mainnet masternode-set anchor at height 2513000 — the last thing blocking daemonless cold start - #972
Merged
Conversation
The daemonless embedded arm cold-starts its payout-bearing masternode set from a release-pinned checkpoint, because that set is not obtainable over P2P: the Simplified MN List omits scriptPayout and nLastPaidHeight, and neither is committed in merkleRootMNList. Until now no anchor had ever been pinned, so the shipped .inc was a placeholder and the runtime refused it: gen_mn_checkpoint: REFUSED: UNPINNED: this build carries no masternode-set anchor That refusal is correct behaviour and it is also why daemonless cold start could not work at all. Anchor: network mainnet height 2513000 blockhash 000000000000002114d621d90f28b52c07746414491cbffc7cd373b3a56bc950 count 2068 masternodes digest dc34d0fb112dd2d509dcc7837e308d5444bd1390a712db708a276f3911e3e16f generated 2026-07-30T00:17:53Z source dashd protx list valid true 2513000 (Dash Core 23.1.7) Produced offline with tools/dash/gen_mn_checkpoint.py from a captured `protx list valid true` array, so no RPC credentials were involved in generating it. The capture was verified end to end before pinning: 2068 entries, 2970603 bytes, byte counts matched across transfer. The height is 204 blocks behind the tip at capture time, deep enough to be settled. The tool's own verify pass re-derives the digest from the written file and confirms every structural rule the runtime parser enforces; it reports OK with the digest matching. Acceptance for this change is NOT that CI is green. It is that a node built from it, started with --embedded-mainnet and no coin-RPC configured, leaves the CHECKPOINT REFUSED state and builds a template. That has not been demonstrated yet and is the next step.
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.
Follows #956 (the generator). One generated file; no code changes.
Why this was blocking
The daemonless embedded arm cold-starts its payout-bearing masternode set from a release-pinned checkpoint. That set cannot be obtained over P2P — the Simplified MN List omits
scriptPayoutandnLastPaidHeight, and neither is committed inmerkleRootMNList. So the checkpoint is not a workaround, it is inherent to the protocol.No anchor had ever been pinned. The shipped
.incwas a 999-byte placeholder and the runtime refused it:Correct fail-closed behaviour — and also why daemonless cold start could not work at all.
The anchor
2087 lines, 828 KB.
Provenance and integrity
Produced offline with
tools/dash/gen_mn_checkpoint.pyfrom a capturedprotx list valid truearray, so no RPC credentials were involved. The capture was integrity-checked across transfer — 2068 entries, 2970603 bytes, matching byte counts at both ends.Height 2513000 was 204 blocks behind the tip at capture, deep enough to be settled.
gen_mn_checkpoint.py verifyon the written file:SPDX
AGPL-3.0-or-laterpresent; file markedGENERATED FILE -- DO NOT EDIT BY HAND.Acceptance — deliberately not "CI is green"
Green CI proves the parser accepts the format. It does not prove daemonless cold start works.
The real gate: a node built from this, started with
--embedded-mainnetand no coin-RPC configured, must leave the CHECKPOINT REFUSED state and build a template. That has not been demonstrated and is the next step. I would rather state that plainly than let a green tick imply more than it covers — the "armed but never exercised" pattern has cost this project three separate false milestones (#940, #952, #963).Reward safety
Does not change share bytes, coinbase construction, or payout weighting. It supplies the MN set the embedded arm uses when building a DIP4 coinbase; a wrong anchor would fail closed at the per-template viability gates rather than produce a bad payee. Production nodes remain on
arm=dashd-fallbackand are unaffected by this file until--embedded-mainnetis deliberately enabled.