upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/script.cpp
diff options
context:
space:
mode:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-08-23 07:40:33 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-08-23 07:40:33 +0000
commitc4754fb505be75b8eedee3ce230a8991762e18c5 (patch)
tree4d9e0007b1b56f6fac69fe143f40d9c58ef18c8d /src/script.cpp
parent489be141ee3be1c355650e1429c3f830eb8e442d (diff)
payout: recognise a payment a pre-upgrade build already made
FindRecordedPoolPayout matches on pool_payout_id / pool_payout_address / pool_payout_amount. That metadata is written only by this build. Every payout the pool has actually sent, in the wallet right now, carries nothing but a "comment". So the first boot after this upgrade is the dangerous one: swap the binary after an unclean shutdown with payments in flight, and the recovery probe finds no evidence for any of them and pays every one of those recipients a second time. The deleted WalletAlreadyPaid() matched on what the payment WAS -- the comment plus an output paying exactly that amount to exactly that script -- and that evidence is still sitting in the wallet. It just stopped being read. The probe now answers with which kind of evidence it found, and the legacy form is restored as a fallback under three constraints that keep it from answering for a round that is not the one being asked about: 1. it is consulted only when the structured lookup found nothing, so the exact path stays primary and strictly better going forward; 2. any transaction carrying pool_payout_id is excluded from it outright. That key means this build wrote the transaction, and this build's transactions are adjudicated exactly -- so a newer round's payment can never be offered as proof for an older one. Only pre-upgrade transactions, which is the entire population the fallback exists for, are eligible; 3. a txid already credited to a DIFFERENT (round, address) is excluded -- from the ledger's paidTxids, which is durable across restarts, and from what this process has already claimed. One legacy transaction therefore settles at most one debt, so N transactions can never discharge more than N obligations. Two debts with one transaction pays the second, which is the correct reading of the evidence. What cannot be resolved from a comment alone is two PRE-UPGRADE rounds at the same height paying the same address the same amount, because the comment carries only the height. That requires a reorg, and the losing round's ledger entry is voided by the orphan check before it can be paid, so the two cannot both be live. Where the evidence genuinely runs out the fallback does not match and the payment is made: paying a debt that cannot be proven settled is the correct default for a pool, and it is the direction that does not keep a miner's money. Recovery on legacy evidence logs loudly and says exactly what it matched on, because it is a judgement made about a binary that is no longer running. The two lookups share one pass over mapWallet. The structured path used to scan alone; adding a second scan would have doubled a linear walk taken under cs_mapWallet, which the whole node contends on. No on-disk format change.
Diffstat (limited to 'src/script.cpp')
0 files changed, 0 insertions, 0 deletions