upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-08-11 20:52:09 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-08-19 22:48:27 +0000
commite236d013e973fd00cbdbed4bea1e5f373c0d1236 (patch)
treeb184641daad4310cdef51dff8bece2743af29f8a /src/net.cpp
parentdb2692dcd8984fe0e5a2a6a796f7b3cbee216c32 (diff)
pool: refuse jobs when no peer has reported a height for 20 minutes
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)
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 5cf2f8c..964097b 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1700,6 +1700,13 @@ void ThreadMessageHandler(void* parg)
1700 } 1700 }
1701} 1701}
1702 1702
1703// When any peer last told us a height. A wedged node -- one that still has
1704// peers but has stopped hearing them -- is exactly a node where this stops
1705// advancing, and that is the one thing the height comparison itself cannot
1706// see: there is no height to compare.
1707static int64 nLastPeerHeightSeen = 0;
1708static int64 nPeerHeightFirstAsked = 0;
1709
1703int GetPeerMedianHeight() 1710int GetPeerMedianHeight()
1704{ 1711{
1705 vector<int> vHeights; 1712 vector<int> vHeights;
@@ -1711,10 +1718,26 @@ int GetPeerMedianHeight()
1711 if (vHeights.empty()) 1718 if (vHeights.empty())
1712 return -1; 1719 return -1;
1713 1720
1721 nLastPeerHeightSeen = GetTime();
1714 sort(vHeights.begin(), vHeights.end()); 1722 sort(vHeights.begin(), vHeights.end());
1715 return vHeights[vHeights.size() / 2]; 1723 return vHeights[vHeights.size() / 2];
1716} 1724}
1717 1725
1726// Seconds since any peer last reported a height.
1727//
1728// Before ever hearing one, measure from the first time somebody asked rather
1729// than from the epoch -- otherwise a node refuses jobs the instant it starts,
1730// before it has had a chance to complete a single handshake.
1731int64 GetPeerHeightAgeSecs()
1732{
1733 int64 nNow = GetTime();
1734 if (nPeerHeightFirstAsked == 0)
1735 nPeerHeightFirstAsked = nNow;
1736 if (nLastPeerHeightSeen == 0)
1737 return nNow - nPeerHeightFirstAsked;
1738 return nNow - nLastPeerHeightSeen;
1739}
1740
1718 1741
1719// Say out loud when we are behind the network. 1742// Say out loud when we are behind the network.
1720// 1743//