upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/net.h
diff options
context:
space:
mode:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-09-03 21:49:35 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-09-03 21:49:35 +0000
commit944f93f163cb560f095556834b6eb75bfde60c9c (patch)
tree11fd7dc0ccacb644a8b775d99795f656c4283da7 /src/net.h
parent424da766b76ba572cc9a93c4dd03736dace04d80 (diff)
parent42c840036f35a52beec27422d92457e7e530bdb1 (diff)
merge: !7 fix/block-fetch-failover into deploy/all-2026-08-24
Diffstat (limited to 'src/net.h')
-rw-r--r--src/net.h45
1 files changed, 43 insertions, 2 deletions
diff --git a/src/net.h b/src/net.h
index 600922a..fc48d0b 100644
--- a/src/net.h
+++ b/src/net.h
@@ -23,6 +23,12 @@ enum
23 23
24 24
25 25
26// Defined in main.cpp. True while this node is tracking the tip rather than
27// still catching up, measured off the age of our own best block -- see there
28// for why that and not a peer-reported height. Declared here because net.h is
29// parsed before main.h and CNode::AskFor needs it.
30bool IsBlockFetchNearTip();
31
26bool GetMyExternalIP(unsigned int& ipRet); 32bool GetMyExternalIP(unsigned int& ipRet);
27CNode* ConnectNodeBtf(const string& strBtfAddr); 33CNode* ConnectNodeBtf(const string& strBtfAddr);
28CNode* ConnectNodeBtfResolved(const string& strBtfAddr, const string& strMeeting, 34CNode* ConnectNodeBtfResolved(const string& strBtfAddr, const string& strMeeting,
@@ -89,6 +95,15 @@ static const int BTF_RECV_TIMEOUT_SECS = 30 * 60;
89static const int BTF_SEND_STALL_SECS = 10 * 60; 95static const int BTF_SEND_STALL_SECS = 10 * 60;
90static const int BTF_HANDSHAKE_GRACE_SECS = 60; 96static const int BTF_HANDSHAKE_GRACE_SECS = 60;
91 97
98// How long a requested block gets before it is asked for again, in seconds.
99// Used twice: CNode::AskFor spaces the queued per-announcer block retries this
100// far apart instead of the two minutes transactions get, and the failover
101// sweep in main.cpp re-issues a getdata to a different peer once a sent
102// request has gone unanswered this long. A block body is at most 1 MB and
103// somebody demonstrably has it -- they announced it -- so on this timescale
104// "not here yet" means "not coming from that peer", not "still in transit".
105static const int BLOCK_FETCH_RETRY_SECS = 15;
106
92// A serialized object cannot be larger than MAX_SIZE, so no valid network 107// A serialized object cannot be larger than MAX_SIZE, so no valid network
93// message needs the old 256 MB header allowance. Keep the wire cap aligned with 108// message needs the old 256 MB header allowance. Keep the wire cap aligned with
94// what the deserializer can accept. How long a peer may sit on a partial 109// what the deserializer can accept. How long a peer may sit on a partial
@@ -795,8 +810,34 @@ public:
795 static int64 nLastTime; 810 static int64 nLastTime;
796 nLastTime = nNow = max(nNow, ++nLastTime); 811 nLastTime = nNow = max(nNow, ++nLastTime);
797 812
798 // Each retry is 2 minutes after the last 813 // Each retry is 2 minutes after the last -- and because nRequestTime
799 nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); 814 // is shared across peers, the same spacing is what strings requests
815 // for one inv across its announcers. For transactions that is pacing;
816 // for a new block it was the stall of issue #33: nine peers announce
817 // the block, the first one asked does not serve it, and the ninth
818 // candidate is not even asked until sixteen minutes in, with the pool
819 // mining on the stale tip the whole time.
820 //
821 // Blocks retry on the fetch timescale, but only while we are at the
822 // tip. That is where the stall costs something -- the pool keeps
823 // handing out jobs against a dead tip -- and it is also where the
824 // spacing is nearly free: one block is in flight, and its body has
825 // almost always arrived before the second announcer's turn comes
826 // round, so AlreadyHave drops the duplicate before a getdata is sent.
827 //
828 // While catching up neither half holds. A peer working through a
829 // 500-deep queue can be minutes away from block N without anything
830 // being wrong, so at 15s the second announcer is asked at +15s, the
831 // third at +30s, and the bulk download arrives once per announcer --
832 // up to eight times over. Nothing caps that: the eight-entry cap is on
833 // mapBlockFetch, which is a different mechanism from this spacing.
834 // Two minutes is the right number there, and it is what this line did
835 // before. Failover at the tip does not depend on this being 15s in any
836 // case: mapBlockFetch re-issues a stalled getdata to the next peer on
837 // its own timer, which is what actually fixes #33.
838 bool fFast = (inv.type == MSG_BLOCK && IsBlockFetchNearTip());
839 int64 nRetryUsecs = (fFast ? BLOCK_FETCH_RETRY_SECS : 2 * 60) * 1000000LL;
840 nRequestTime = max(nRequestTime + nRetryUsecs, nNow);
800 mapAskFor.insert(make_pair(nRequestTime, inv)); 841 mapAskFor.insert(make_pair(nRequestTime, inv));
801 } 842 }
802 843