diff options
| author | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-02 16:12:13 +0000 |
|---|---|---|
| committer | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-02 16:12:13 +0000 |
| commit | 42c840036f35a52beec27422d92457e7e530bdb1 (patch) | |
| tree | 645ef92493b08cb4132e7f3011e9e458b80cb4e8 /src/main.cpp | |
| parent | cd6edfc2c234db71d9b68f96702ad08a56cc3127 (diff) | |
net: stop the failover log naming a peer on every re-request
The line was unconditional on the argument that failover firing is the
pathology of #33 and nobody could otherwise see it. That much is right.
Printing a peer address every time it fires is not: a peer decides how
often the line is written, by announcing hashes it will not serve, and
an address is the one thing the .btf transport otherwise takes trouble
not to spread around. Sustained, that was tens of lines a minute, each
naming a peer, driven entirely from outside.
Split it. The per-peer detail -- which block, how long, which peer is
being tried next -- moves behind the net category, where the rest of the
getdata logging already is. What stays unconditional is a count with no
addresses in it, over a window no peer can shorten: the first failover
after a quiet spell still prints immediately, because the change from
"blocks arrive" to "blocks are announced and not served" is the event
worth seeing, and everything after it is summarised once a minute.
Worst case is now one line per minute regardless of what a peer does,
instead of one per re-request.
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/src/main.cpp b/src/main.cpp index be89416..a51b5ae 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -101,6 +101,21 @@ static const int BLOCK_FETCH_TRACK_MAX = 8; | |||
| 101 | // forever; a re-announcement recreates it. | 101 | // forever; a re-announcement recreates it. |
| 102 | static const int BLOCK_FETCH_GIVEUP_SECS = 10 * 60; | 102 | static const int BLOCK_FETCH_GIVEUP_SECS = 10 * 60; |
| 103 | 103 | ||
| 104 | // Failover firing at all is worth saying out loud: it means peers are | ||
| 105 | // announcing blocks they then do not serve, which is the pathology of #33 and | ||
| 106 | // the thing nobody could otherwise see. Naming the peer on every re-request is | ||
| 107 | // a different matter. A peer can drive that line as often as it likes by | ||
| 108 | // announcing hashes it will not serve, and what it prints is a peer address, | ||
| 109 | // which is the one thing the .btf transport otherwise takes trouble not to | ||
| 110 | // spread around. So the per-peer detail sits behind the net category and the | ||
| 111 | // unconditional line is a count over a window no peer can shorten: the first | ||
| 112 | // failover after a quiet spell prints at once, because the change from "blocks | ||
| 113 | // arrive" to "blocks are announced and not served" is the event worth seeing, | ||
| 114 | // and everything after it is summarised once a minute. | ||
| 115 | static const int BLOCK_FETCH_REPORT_SECS = 60; | ||
| 116 | static int64 nBlockFetchWindowStart = 0; | ||
| 117 | static int nBlockFetchFailovers = 0; | ||
| 118 | |||
| 104 | // How stale our own best block may be before we stop calling this the tip. | 119 | // How stale our own best block may be before we stop calling this the tip. |
| 105 | // Blocks target two minutes, so this is thirty intervals: far longer than any | 120 | // Blocks target two minutes, so this is thirty intervals: far longer than any |
| 106 | // stall worth failing over from -- the one in #33 ran sixteen minutes -- and | 121 | // stall worth failing over from -- the one in #33 ran sixteen minutes -- and |
| @@ -3637,12 +3652,29 @@ bool SendMessages(CNode* pto) | |||
| 3637 | fetch.setAsked.clear(); | 3652 | fetch.setAsked.clear(); |
| 3638 | if (!fetch.setAsked.count(pto->addr)) | 3653 | if (!fetch.setAsked.count(pto->addr)) |
| 3639 | { | 3654 | { |
| 3640 | // Deliberately not behind a debug category: this line | 3655 | // Which block, how long, and which peer we are trying |
| 3641 | // firing is a peer announcing blocks it does not | 3656 | // next. Behind the category because it names a peer |
| 3642 | // serve, which is the pathology of #33. | 3657 | // and a peer decides how often it is written. |
| 3643 | printf("block fetch failover: %s unanswered for %d s, re-requesting from %s\n", | 3658 | if (LogAcceptsCategory("net")) |
| 3644 | inv.ToString().c_str(), (int)(nNowSecs - fetch.nTimeAsked), | 3659 | printf("block fetch failover: %s unanswered for %d s, re-requesting from %s\n", |
| 3645 | pto->addr.ToString().c_str()); | 3660 | inv.ToString().c_str(), (int)(nNowSecs - fetch.nTimeAsked), |
| 3661 | pto->addr.ToString().c_str()); | ||
| 3662 | |||
| 3663 | // The unconditional half: no addresses, and at most | ||
| 3664 | // one line per BLOCK_FETCH_REPORT_SECS however hard a | ||
| 3665 | // peer tries. See the counters for the reasoning. | ||
| 3666 | nBlockFetchFailovers++; | ||
| 3667 | if (nNowSecs - nBlockFetchWindowStart >= BLOCK_FETCH_REPORT_SECS) | ||
| 3668 | { | ||
| 3669 | printf("block fetch: %d block request%s went unanswered and %s been " | ||
| 3670 | "re-asked of other peers (%d tracked)\n", | ||
| 3671 | nBlockFetchFailovers, nBlockFetchFailovers == 1 ? "" : "s", | ||
| 3672 | nBlockFetchFailovers == 1 ? "has" : "have", | ||
| 3673 | (int)mapBlockFetch.size()); | ||
| 3674 | nBlockFetchWindowStart = nNowSecs; | ||
| 3675 | nBlockFetchFailovers = 0; | ||
| 3676 | } | ||
| 3677 | |||
| 3646 | vFailover.push_back(inv); | 3678 | vFailover.push_back(inv); |
| 3647 | fetch.nTimeAsked = nNowSecs; | 3679 | fetch.nTimeAsked = nNowSecs; |
| 3648 | fetch.setAsked.insert(pto->addr); | 3680 | fetch.setAsked.insert(pto->addr); |