diff options
| author | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-02 08:29:44 +0000 |
|---|---|---|
| committer | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-02 08:29:44 +0000 |
| commit | 73e77c3bc259a4c8e0a4cc5c376f1a9545439bdd (patch) | |
| tree | 6672c8cddc3127d18d7d2a5a1700fd04e97d59c0 | |
| parent | e4f898c4a6b9900553c64b9804889b5fdae3e55f (diff) | |
net: retry block fetches every 15s, not every two minutes
AskFor keys its retry spacing off mapAlreadyAskedFor, which is global to
the inv, so the two-minute gap does more than pace re-requests to one
peer: it strings the getdatas for one block across its announcers two
minutes apart. When the first peer asked does not serve the body, the
second candidate is not asked for 120s and the ninth for 960s -- the
observed 16-minute tip stall of #33, during which the pool kept
broadcasting jobs against the stale tip and 5 of 12 found blocks
orphaned.
A block body is at most 1 MB and somebody demonstrably has it -- they
announced it -- so on this timescale "not here yet" means "not coming
from that peer". Blocks now retry on BLOCK_FETCH_RETRY_SECS (15s);
transactions keep the two-minute pacing, which for them is the point.
| -rw-r--r-- | src/net.h | 21 |
1 files changed, 19 insertions, 2 deletions
| @@ -89,6 +89,15 @@ static const int BTF_RECV_TIMEOUT_SECS = 30 * 60; | |||
| 89 | static const int BTF_SEND_STALL_SECS = 10 * 60; | 89 | static const int BTF_SEND_STALL_SECS = 10 * 60; |
| 90 | static const int BTF_HANDSHAKE_GRACE_SECS = 60; | 90 | static const int BTF_HANDSHAKE_GRACE_SECS = 60; |
| 91 | 91 | ||
| 92 | // How long a requested block gets before it is asked for again, in seconds. | ||
| 93 | // Used twice: CNode::AskFor spaces the queued per-announcer block retries this | ||
| 94 | // far apart instead of the two minutes transactions get, and the failover | ||
| 95 | // sweep in main.cpp re-issues a getdata to a different peer once a sent | ||
| 96 | // request has gone unanswered this long. A block body is at most 1 MB and | ||
| 97 | // somebody demonstrably has it -- they announced it -- so on this timescale | ||
| 98 | // "not here yet" means "not coming from that peer", not "still in transit". | ||
| 99 | static const int BLOCK_FETCH_RETRY_SECS = 15; | ||
| 100 | |||
| 92 | // A serialized object cannot be larger than MAX_SIZE, so no valid network | 101 | // 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 | 102 | // 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 | 103 | // what the deserializer can accept. How long a peer may sit on a partial |
| @@ -795,8 +804,16 @@ public: | |||
| 795 | static int64 nLastTime; | 804 | static int64 nLastTime; |
| 796 | nLastTime = nNow = max(nNow, ++nLastTime); | 805 | nLastTime = nNow = max(nNow, ++nLastTime); |
| 797 | 806 | ||
| 798 | // Each retry is 2 minutes after the last | 807 | // Each retry is 2 minutes after the last -- and because nRequestTime |
| 799 | nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); | 808 | // is shared across peers, the same spacing is what strings requests |
| 809 | // for one inv across its announcers. For transactions that is pacing; | ||
| 810 | // for a new block it was the stall of issue #33: nine peers announce | ||
| 811 | // the block, the first one asked does not serve it, and the ninth | ||
| 812 | // candidate is not even asked until sixteen minutes in, with the pool | ||
| 813 | // mining on the stale tip the whole time. Blocks retry on the fetch | ||
| 814 | // timescale instead. | ||
| 815 | int64 nRetryUsecs = (inv.type == MSG_BLOCK ? BLOCK_FETCH_RETRY_SECS : 2 * 60) * 1000000LL; | ||
| 816 | nRequestTime = max(nRequestTime + nRetryUsecs, nNow); | ||
| 800 | mapAskFor.insert(make_pair(nRequestTime, inv)); | 817 | mapAskFor.insert(make_pair(nRequestTime, inv)); |
| 801 | } | 818 | } |
| 802 | 819 | ||