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:
Diffstat (limited to 'src/net.h')
-rw-r--r--src/net.h73
1 files changed, 66 insertions, 7 deletions
diff --git a/src/net.h b/src/net.h
index 9f3c7e4..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,13 +810,51 @@ 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
803 844
804 845
846 // "sending: tx (N bytes)" alone was ~71% of a 13-hour production
847 // debug.log (issue #35), so tx sends are demoted to the /debugrelay-gated
848 // "relay" category; every other command's send trace stays on "net".
849 // The line is emitted in pieces across BeginMessage/EndMessage/
850 // AbortMessage, so all three must agree on the category or orphaned
851 // "(N bytes)" fragments would leak into a plain -debug log.
852 // Valid only mid-message (nPushPos != -1).
853 const char* SendLogCategory() const
854 {
855 return strcmp(GetMessageCommand(), "tx") == 0 ? "relay" : "net";
856 }
857
805 void BeginMessage(const char* pszCommand) 858 void BeginMessage(const char* pszCommand)
806 { 859 {
807 EnterCriticalSection(&cs_vSend); 860 EnterCriticalSection(&cs_vSend);
@@ -809,17 +862,19 @@ public:
809 AbortMessage(); 862 AbortMessage();
810 nPushPos = vSend.size(); 863 nPushPos = vSend.size();
811 vSend << CMessageHeader(pszCommand, 0); 864 vSend << CMessageHeader(pszCommand, 0);
812 if (LogAcceptsCategory("net")) printf("sending: %-12s ", pszCommand); 865 if (LogAcceptsCategory(SendLogCategory())) printf("sending: %-12s ", pszCommand);
813 } 866 }
814 867
815 void AbortMessage() 868 void AbortMessage()
816 { 869 {
817 if (nPushPos == -1) 870 if (nPushPos == -1)
818 return; 871 return;
872 // Capture before nPushPos is cleared; GetMessageCommand() needs it.
873 const char* pszCategory = SendLogCategory();
819 vSend.resize(nPushPos); 874 vSend.resize(nPushPos);
820 nPushPos = -1; 875 nPushPos = -1;
821 LeaveCriticalSection(&cs_vSend); 876 LeaveCriticalSection(&cs_vSend);
822 if (LogAcceptsCategory("net")) printf("(aborted)\n"); 877 if (LogAcceptsCategory(pszCategory)) printf("(aborted)\n");
823 } 878 }
824 879
825 void EndMessage() 880 void EndMessage()
@@ -827,7 +882,11 @@ public:
827 extern int nDropMessagesTest; 882 extern int nDropMessagesTest;
828 if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) 883 if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
829 { 884 {
830 if (LogAcceptsCategory("net")) printf("dropmessages DROPPING SEND MESSAGE\n"); 885 // Same category as the "sending: " this line interrupts, so a tx
886 // does not announce its own drop under "net" having been gated
887 // off under "relay". nPushPos can be -1 here, and then
888 // GetMessageCommand() returns "" and this is "net" as before.
889 if (LogAcceptsCategory(SendLogCategory())) printf("dropmessages DROPPING SEND MESSAGE\n");
831 AbortMessage(); 890 AbortMessage();
832 return; 891 return;
833 } 892 }
@@ -839,10 +898,10 @@ public:
839 unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); 898 unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
840 memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); 899 memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
841 900
842 if (LogAcceptsCategory("net")) printf("(%d bytes) ", nSize); 901 if (LogAcceptsCategory(SendLogCategory())) printf("(%d bytes) ", nSize);
843 //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) 902 //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++)
844 // printf("%02x ", vSend[i] & 0xff); 903 // printf("%02x ", vSend[i] & 0xff);
845 if (LogAcceptsCategory("net")) printf("\n"); 904 if (LogAcceptsCategory(SendLogCategory())) printf("\n");
846 905
847 nPushPos = -1; 906 nPushPos = -1;
848 LeaveCriticalSection(&cs_vSend); 907 LeaveCriticalSection(&cs_vSend);