Skip to content

ltc(underfill): guard near-empty template on non-empty mempool (v36 cutover deploy gate)#663

Merged
frstrtr merged 2 commits into
masterfrom
ltc-doge/underfill-guard
Jul 11, 2026
Merged

ltc(underfill): guard near-empty template on non-empty mempool (v36 cutover deploy gate)#663
frstrtr merged 2 commits into
masterfrom
ltc-doge/underfill-guard

Conversation

@frstrtr

@frstrtr frstrtr commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Net-new c2pool-side underfill guard for the v36 contabo cutover deploy build (1 of the 2 gate ports; DOA-under-load is the other, still blocked on a portable fix-shape).

What

Single commit 9e06ef6 (GPG 50AB1379), +33 lines in src/impl/ltc/coin/template_builder.hpp. After tx selection at the pinned seam, sums wire bytes actually packed and, if fill < UNDERFILL_MIN_FILL_BYTES (50kB legacy p2pool near-empty floor) while the local mempool still holds fee-paying backlog > UNDERFILL_BACKLOG_SLACK (50kB) beyond what was selected, emits a loud WARNING for contabo-prod-watch/operator. Genuinely empty mempools never trip it.

What it is NOT

  • NOT the byte-parity KAT axis — threshold guard, not a byte-mirror.
  • NOT DOA-under-load — that half has no portable btc/DGB fix-shape yet (both are diagnostic-only), still blocked.

Scope / classification

  • Chain-agnostic V37-standardizable shape (thresholds are constexpr, reviewable by btc-heap-opt/Director). DOGE aux inherits via merged-mining.
  • Gates the CUTOVER BUILD only, not a fleet freeze.

Reviewer: dash-consensus-pay-replay. Merge: integrator (I do not merge).

frstrtr added 2 commits July 10, 2026 17:01
Net-new c2pool-side template-fill safety net for the v36 cutover deploy
path. After tx selection at the pinned seam (template_builder.hpp), sum
the wire bytes actually packed into the template and, if that fill is
under UNDERFILL_MIN_FILL_BYTES (50 kB, the legacy p2pool near-empty
floor) while the local mempool still holds fee-paying backlog exceeding
UNDERFILL_BACKLOG_SLACK (50 kB) beyond what was selected, emit a loud
WARNING for contabo-prod-watch / operator. Detects the near-empty-block-
on-a-full-mempool regression that gates the cutover; genuinely empty
mempools never trip it. Thresholds reviewable by btc-heap-opt/Director.

NOT the byte-parity KAT axis — this is a threshold guard, not a
byte-mirror. DOGE aux inherits via merged-mining.
DOGE runs its OWN embedded GBT template and selects its OWN transactions,
so it can produce a near-empty block on a non-empty DOGE mempool
independently of LTC. Merged-mining makes the aux inherit the parent PoW,
not the tx-fill, so the LTC parent guard does NOT cover this path — the
guard must live in the DOGE builder directly. This refines the earlier
LTC commit note ("DOGE aux inherits via merged-mining"): that is true
for work, not for template fill.

Byte-identical logic to the LTC guard (9e06ef6): after tx selection at
the pinned seam, sum wire bytes packed; if fill < UNDERFILL_MIN_FILL_BYTES
(50 kB legacy floor) while the DOGE mempool holds fee-paying backlog
> UNDERFILL_BACKLOG_SLACK beyond what was selected, emit a loud WARNING
for contabo-prod-watch / operator. Genuinely empty mempools never trip.
Thresholds are a bucket-2 v36-native shared structure (standardize
cross-coin). Completes the underfill-guard deploy-gate slice for LTC+DOGE.
@frstrtr

frstrtr commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Added the DOGE-aux mirror (3af519f, GPG-signed): DOGE runs its own embedded GBT template and selects its own txs, so it can go near-empty on a non-empty DOGE mempool independently — merged-mining shares the parent PoW, not the tx-fill, so the LTC guard does not cover this path. Byte-identical guard logic, [EMB-DOGE] tag. PR #663 now delivers the underfill guard for LTC+DOGE together.

frstrtr added a commit that referenced this pull request Jul 10, 2026
Close the underfill KAT axis that the DOA commit (346ee19) deferred
pending the constant's canonical name+default. Per integrator [s=contabo-gate]
2026-07-10, the threshold already landed in #663: UNDERFILL_MIN_FILL_BYTES =
50000, an operational near-empty floor (not a consensus byte-parity constant).
DOA is stats-only and unthresholded, so there was never a DOA threshold to
wait on -- the two were conflated.

Extract the underfill predicate + its pinned defaults out of the two inlined
build_template() guards into core::underfill (SSOT header), so the live LTC
parent path (src/impl/ltc/coin/template_builder.hpp build_template ~L271) and
the DOGE embedded-aux path (src/impl/doge/coin/template_builder.hpp ~L140) and
the KAT all assert on the SAME is_underfill() + MIN_FILL_BYTES/BACKLOG_SLACK --
not a re-implementation (non-hollow, mirrors the DOA is_doa_share() pattern).
Both per-coin UNDERFILL_* constants now derive from the SSOT: bucket-2 v36-native
shared-structure standardization, values unchanged (50000, semantics-preserving).

KAT (core_test, gtest) pins the contract: MIN_FILL_BYTES/BACKLOG_SLACK == 50000
(static_assert + runtime); genuinely-empty and zero-fee-backlog mempools never
trip; healthy full blocks never trip; near-empty-on-fee-paying-backlog trips;
near-empty edge is strict < and backlog edge is strict >. 7/7 green, full
core_test 68/68 (61 pre-DOA + 5 DOA + 7 underfill). Offline deterministic,
gates the cutover build only (behind natural-vote, operator-gated cutover).
@frstrtr frstrtr merged commit b86663f into master Jul 11, 2026
27 checks passed
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