Skip to content

dgb: M3 §7b scrypt-digest conversion + retarget no-op + MTP guard (tail, rebased on master post-#153) - #158

Merged
frstrtr merged 4 commits into
masterfrom
dgb/m3-scrypt-tail
Jun 19, 2026
Merged

dgb: M3 §7b scrypt-digest conversion + retarget no-op + MTP guard (tail, rebased on master post-#153)#158
frstrtr merged 4 commits into
masterfrom
dgb/m3-scrypt-tail

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Consolidated §7b ingest-validation tail, rebased clean onto master after #153 merged (81fef6a). Supersedes #155 (its base branch dgb/m3-scrypt-window-walk is now stale/pre-#153-squash).

4 commits, all GPG-signed, touch only src/impl/dgb/coin/header_chain.hpp + test/header_chain_test.cpp (single-coin tree, DGB-smoke gated):

  • 04f1da6 scrypt digest -> pow_hash little-endian conversion (u256::from_le_bytes, limb[0]=LSB8 == UintToArith256)
  • 4d62bbc prove conversion vs REAL scrypt_1024_1_1_256 (self-derived KAT pin + live satisfaction gate)
  • 0847bdf demote nBits-exact retarget gate to V36 no-op (keep daemon-independent CheckProofOfWork halves: pow_limit floor + scrypt(header) <= declared target; do NOT re-derive single-algo DigiShield for a multi-algo chain — that is V37 MultiShield-V4 scope). Integrator-accepted (UID 1390).
  • e895f4a MTP monotonicity ingest guard (nTime > median-of-last-11; Scrypt-path-only reject, continuity headers feed the median but bypass the gate; genesis unconstrained). Integrator-accepted (UID 1391).

header_chain_test: 27/27 PASS, build EXIT=0. Tests folded INTO header_chain_test (no new gtest target — avoids #143 NOT_BUILT allowlist trap). HOLD merge — integrator merges on operator approval.

frstrtr added 4 commits June 19, 2026 10:40
…:from_le_bytes)

Add u256::from_le_bytes: builds a 256-bit value from a 32-byte little-endian
digest (the scrypt_1024_1_1_256 PoW output), limb[0] = least-significant 8
bytes, mirroring bitcoin UintToArith256. This is the bytes->field half of
dropping the embedded DigiByte Core Scrypt digest into HeaderSample::pow_hash
at the ingest boundary; the scrypt CALL itself (btclibs) lands next slice.

Header-only, depends only on <cstdint>/builtin unsigned char, so the standalone
header_chain guard keeps linking with NO btclibs scrypt dependency. +1 vector
folded INTO header_chain_test (no new gtest target; #143 NOT_BUILT trap avoided):
pins LE limb mapping, zero/max boundaries, and proves a converted digest feeds
the existing full-width PoW-satisfaction gate (not a low64 proxy). 22/22 PASS.

(cherry picked from commit b1e7bc7)
…024_1_1_256

Links the btclibs Scrypt PoW TU set (scrypt.cpp + SHA256 family) into
header_chain_test and adds an end-to-end test that runs the real
scrypt_1024_1_1_256 over an 80-byte header, converts the 32-byte LE digest
via u256::from_le_bytes, pins it as a self-derived KAT, and feeds it through
the live full-width satisfaction gate (accept vs pow_limit, reject vs a
tiny target -> proves full-width ordering, not a low64 proxy). Compiles only
the scrypt + SHA256 crypto TUs directly (not the full btclibs archive, whose
siphash TU needs the removed base_uint<256> symbol, and not core/the dgb
OBJECT lib) -- linking an existing scrypt.cpp, no shared source modified.
Same target name, still in both build.yml --target allowlists.

Proves the conversion primitive end-to-end against a genuine Scrypt digest;
does NOT wire scrypt into the production node.cpp ingest path (that lands in
embedded-daemon Phase A, scoped with an exe-smoke).

(cherry picked from commit f49a89e)
The ingest path no longer re-derives the required next-work and rejects on
an nBits-exact mismatch. V36's defining constraint is p2pool-merged-v36
compatibility, and that reference never recomputes parent difficulty -- it
trusts the parent header's declared nBits and checks PoW against it. The
two daemon-independent CheckProofOfWork halves (pow_limit floor +
scrypt(header) <= target) remain and ARE the correct, complete V36
parent-difficulty validation.

Re-derivation is also structurally impossible in a Scrypt-only walk:
DigiByte's live retarget is MultiShield V4, whose averaging window is
GLOBAL across all 5 algos with per-algo adjust + MedianTimePast deltas + /4
damping -- reconstructing it needs full multi-algo header tracking == V37
(5-algo validation). digishield_next_target()/next_retarget_window() are
retained as test scaffolding and a reference for the V37 embedded-daemon
port; the ingest path deliberately no longer calls them.

Test IngestGateEnforcesDigiShieldNextTarget -> IngestRetargetGateDemotedTo-
NoOpForV36: a target != the single-algo DigiShield reference is now ACCEPTED;
the reference value stays computable as scaffolding; PoW + ceiling halves
still reject. header_chain_test 21/21 PASS.

(cherry picked from commit 62398af)
Add the daemon-independent, Scrypt-only-walk-safe half of header time
validation: a Scrypt header's nTime must be STRICTLY GREATER than the median
timestamp of the tip and its (up to) 10 nearest ancestors (DigiByte Core
ContextualCheckBlockHeader "time-too-old"). This is the monotonicity floor
the demoted nBits re-derivation gate used to imply, recovered without any
difficulty recompute -- it reads only timestamps already in the local header
chain, so it is safe on a Scrypt-only walk and needs no V4-MultiShield
multi-algo window.

median_time_past() walks ALL appended headers regardless of algo, mirroring
DGB Core's GetMedianTimePast over the block index: continuity (non-Scrypt)
headers DO contribute their timestamps to the median even though their PoW is
never validated and they are never rejected on the gate (accept-by-continuity
is preserved). Genesis (empty chain) returns INT64_MIN -> unconstrained. A
rejection never mutates the chain (checked before push_back).

+4 tests INTO header_chain_test (no new gtest target -> no build.yml
allowlist change, #143 trap avoided): genesis-unconstrained, strict-greater
rejection at/below median, continuity timestamps feed the median, continuity
header itself bypasses the gate. header_chain_test 25/25 PASS, build EXIT=0.

(cherry picked from commit b084acd)
@frstrtr
frstrtr force-pushed the dgb/m3-scrypt-tail branch from a5f04ab to f01f390 Compare June 19, 2026 11:07
@frstrtr
frstrtr merged commit b98912f into master Jun 19, 2026
19 checks passed
@frstrtr
frstrtr deleted the dgb/m3-scrypt-tail branch June 19, 2026 11:50
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