Fix node abort (SIGABRT) when spending a post-founders-reward coinbase#23
Merged
wo01 merged 1 commit intoJun 21, 2026
Conversation
…heights CheckInputs() enforces "coinbase must be shielded" by permitting a coinbase to be spent to transparent outputs only when its output is the founders-reward script. It called CChainParams::GetFoundersRewardScriptAtHeight(coins->nHeight) unconditionally, but that function asserts the height is within the founders-reward period. Once the chain passes the last founders-reward block, spending any matured coinbase to transparent outputs (e.g. a mining pool spending its own coinbase) calls it with a post-period height and the assert aborts the entire node (SIGABRT). On mainnet (founders reward long ended, height ~4.45M) this crashes kotod ~whenever a pool-mined coinbase is spent. Guard the height before calling it: past the founders-reward period there is no founders reward, so the coinbase-must-be-shielded rule applies and the transparent spend is rejected (identical consensus outcome) without aborting. The other caller (ConnectBlock founders/dev-fee check) is already guarded.
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.
Summary
CheckInputs()aborts the node (SIGABRT) when a coinbase mined after the founders‑reward period is spent to/with transparent outputs.Details
To enforce "coinbase must be shielded",
CheckInputs()permits a coinbase to be spent to transparent outputs only when its output is the founders‑reward script:But
CChainParams::GetFoundersRewardScriptAtHeight()asserts the height is inside the founders‑reward period:Once the chain passes the last founders‑reward block,
coins->nHeightof a spent coinbase is beyond that period, the assert fails, andabort()kills the whole daemon.Impact
On current mainnet (founders reward ended long ago; tip ~4,450,000) this reproduces reliably: any node that spends a matured coinbase to/with transparent outputs crashes with
Main process exited, code=killed, status=6/ABRT. Mining pools spending their own coinbase hit it ~every time a coinbase matures — observed askotodcrashing roughly every couple of hours:Fix
Guard the height before calling
GetFoundersRewardScriptAtHeight()(via short‑circuit, so it is only called within the founders‑reward period). Past the period there is no founders reward, so the coinbase‑must‑be‑shielded rule simply applies and the transparent spend is rejected — the same consensus outcome, without the abort. The other caller (ConnectBlock()founders/dev‑fee check) is already height‑guarded.GetFoundersRewardScriptAtHeight()itself (and itsEXPECT_DEATHtests) is unchanged.日本語補足
Founders Reward 期間終了後に採掘されたコインベースを透明(transparent)出力へ使おうとすると、
CheckInputs()内のGetFoundersRewardScriptAtHeight(coins->nHeight)が「height は Founders Reward 期間内」という assert に違反し、abort()でノード全体が落ちます(SIGABRT /status=6/ABRT)。現行メインネット(Founders Reward は既に終了、tip ~445万)では確実に再現し、特にマイニングプールが自分のコインベースを使うたびにクラッシュします(実際に kotod が数時間ごとに落ちるのを確認)。
修正は、関数を呼ぶ前に height をガードするだけです(短絡評価で Founders 期間内のときのみ呼ぶ)。期間後は Founders Reward が存在しないため「コインベースは shielded 必須」のルールがそのまま適用され、透明使用は reject されます=consensus の結果は同一で、abort だけが無くなります。もう一方の呼び出し元(
ConnectBlockの Dev Fee 検証)は既に height ガード済みのため変更不要です。関数本体およびEXPECT_DEATHテストは変更していません。