upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/net.cpp
AgeCommit message (Collapse)Author
2026-08-19net: one dead descriptor must not cost every peer its turnbitflash-maintainer
From the first of two wedges captured on the pool. It is a different proximate fault from the second one, and this is the part that turns a single bad socket into a node-wide outage. A failed select() zeroes both descriptor sets, so no peer is serviced on that pass. That is correct as far as it goes. What was missing is that nothing stopped the offending descriptor coming straight back: - the invalid socket was only marked fDisconnect, and a node is not removed from vNodes until it has drained or DISCONNECT_DRAIN_SECS has elapsed -- and it cannot drain, because its socket is gone; - the select set was rebuilt from vNodes with no check, so the same dead descriptor went back in on the very next pass and failed select() again. Measured in the capture: 1,027 consecutive 'its socket is no longer valid' passes across 61 seconds -- the full drain timeout -- one bad socket, and for the whole of it the node read nothing from anybody. The peer that caused it had 57 bytes unsent, so it took the slow path out. Now the descriptor is forgotten as soon as getsockopt says it is not ours: select() succeeds again on the next pass and every other peer is served normally while the dead node ages out as before. Deliberately forgotten rather than closed. getsockopt has just said this descriptor is no longer ours; calling close() on it is precisely how an unrelated socket gets closed instead, which is the fault fixed in e742d0b. (cherry picked from commit f14c513b4e39d6203b73584f6dc01acbb5a9546e)
2026-08-19pool: refuse jobs when no peer has reported a height for 20 minutesbitflash-maintainer
The peer-height gate replaced a tip-age check that was wrong in both directions. It is a strict improvement and it is still blind in the one case that matters most. When the node goes deaf -- peers still in vNodes, nothing arriving -- no peer announces anything, GetPeerMedianHeight() returns -1, and the fallback mines our best chain. That fallback is right for a node that has not been told yet and wrong for a node that has stopped being able to hear, and a height nobody sent cannot tell those apart. A wedged node is exactly a node with no peer height information, so the gate was silent for the whole of heights 3966-4085: 120 blocks, 5890.50 BTF voided. Time can tell them apart. GetPeerHeightAgeSecs() measures how long since any peer reported a height, counting from first use rather than the epoch so a starting node does not refuse jobs before its first handshake. Past 20 minutes the pool stops issuing jobs and says so unconditionally in the log. /poolmineblind overrides it: without an escape hatch a genuinely isolated pool that is 90% of the hashrate could never restart its own chain, which is the deadlock the tip-age check used to cause. Also stop nStartingHeight from going stale. It was a snapshot taken once during the version handshake and never touched again, so on a long-lived connection the median is built from heights the peers had hours ago, and the behind-the-network check drifts toward 'everyone is behind us' and quietly stops firing. A peer that hands us a block is demonstrably at least at that block's height. (cherry picked from commit 0800c18faf703b4acde1b131d0b742d37a86d92b)
2026-08-19pool: sync-gate job creation, retry failed payouts; widen nostr relay setbitflash-maintainer
- RebuildJob: no jobs with zero peers or a tip older than 30min; mining unsynced produced orphaned blocks and payouts that can never be paid (observed in production: 8 orphan 'found blocks') - payout exec: on SendMoney failure requeue with 60s backoff, up to 30 attempts, instead of silently forfeiting the payment - nostr: add oxtr.dev, nos.social, fmt.wiz.biz, current.fyi, nostr.bg (12 relays total) for announcement redundancy (cherry picked from commit f1986cd7e4a6f69469a2256eb96ff03f3f146792)
2026-08-04public commitbitflash-coin