35
35
# error "Bitcoin cannot be compiled without assertions."
36
36
#endif
37
37
38
- std::atomic<int64_t > nTimeBestReceived (0 ); // Used only to inform the wallet of when we last received a block
39
- bool g_enable_bip61 = DEFAULT_ENABLE_BIP61;
40
-
41
- struct IteratorComparator
42
- {
43
- template <typename I>
44
- bool operator ()(const I& a, const I& b) const
45
- {
46
- return &(*a) < &(*b);
47
- }
48
- };
38
+ /* * Expiration time for orphan transactions in seconds */
39
+ static constexpr int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60 ;
40
+ /* * Minimum time between orphan transactions expire time checks in seconds */
41
+ static constexpr int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60 ;
42
+ /* * Headers download timeout expressed in microseconds
43
+ * Timeout = base + per_header * (expected number of headers) */
44
+ static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000 ; // 15 minutes
45
+ static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER = 1000 ; // 1ms/header
46
+ /* * Protect at least this many outbound peers from disconnection due to slow/
47
+ * behind headers chain.
48
+ */
49
+ static constexpr int32_t MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT = 4 ;
50
+ /* * Timeout for (unprotected) outbound peers to sync to our chainwork, in seconds */
51
+ static constexpr int64_t CHAIN_SYNC_TIMEOUT = 20 * 60 ; // 20 minutes
52
+ /* * How frequently to check for stale tips, in seconds */
53
+ static constexpr int64_t STALE_CHECK_INTERVAL = 10 * 60 ; // 10 minutes
54
+ /* * How frequently to check for extra outbound peers and disconnect, in seconds */
55
+ static constexpr int64_t EXTRA_PEER_CHECK_INTERVAL = 45 ;
56
+ /* * Minimum time an outbound-peer-eviction candidate must be connected for, in order to evict, in seconds */
57
+ static constexpr int64_t MINIMUM_CONNECT_TIME = 30 ;
58
+ /* * SHA256("main address relay")[0:8] */
59
+ static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL ;
60
+ // / Age after which a stale block will no longer be served if requested as
61
+ // / protection against fingerprinting. Set to one month, denominated in seconds.
62
+ static constexpr int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60 ;
63
+ // / Age after which a block is considered historical for purposes of rate
64
+ // / limiting block relay. Set to one week, denominated in seconds.
65
+ static constexpr int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60 ;
49
66
50
67
struct COrphanTx {
51
68
// When modifying, adapt the copy of this definition in tests/DoS_tests.
@@ -55,21 +72,11 @@ struct COrphanTx {
55
72
};
56
73
static CCriticalSection g_cs_orphans;
57
74
std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY (g_cs_orphans);
58
- std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY (g_cs_orphans);
59
- void EraseOrphansFor (NodeId peer);
60
-
61
- static size_t vExtraTxnForCompactIt GUARDED_BY (g_cs_orphans) = 0;
62
- static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY (g_cs_orphans);
63
75
64
- static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL ; // SHA256("main address relay")[0:8]
65
-
66
- // / Age after which a stale block will no longer be served if requested as
67
- // / protection against fingerprinting. Set to one month, denominated in seconds.
68
- static const int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60 ;
76
+ void EraseOrphansFor (NodeId peer);
69
77
70
- // / Age after which a block is considered historical for purposes of rate
71
- // / limiting block relay. Set to one week, denominated in seconds.
72
- static const int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60 ;
78
+ /* * Increase a node's misbehavior score. */
79
+ void Misbehaving (NodeId nodeid, int howmuch, const std::string& message=" " );
73
80
74
81
// Internal stuff
75
82
namespace {
@@ -137,10 +144,24 @@ namespace {
137
144
MapRelay mapRelay;
138
145
/* * Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */
139
146
std::deque<std::pair<int64_t , MapRelay::iterator>> vRelayExpiration;
147
+
148
+ std::atomic<int64_t > nTimeBestReceived (0 ); // Used only to inform the wallet of when we last received a block
149
+
150
+ struct IteratorComparator
151
+ {
152
+ template <typename I>
153
+ bool operator ()(const I& a, const I& b) const
154
+ {
155
+ return &(*a) < &(*b);
156
+ }
157
+ };
158
+ std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY (g_cs_orphans);
159
+
160
+ static size_t vExtraTxnForCompactIt GUARDED_BY (g_cs_orphans) = 0;
161
+ static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY (g_cs_orphans);
140
162
} // namespace
141
163
142
164
namespace {
143
-
144
165
struct CBlockReject {
145
166
unsigned char chRejectCode;
146
167
std::string strRejectReason;
@@ -267,10 +288,10 @@ struct CNodeState {
267
288
};
268
289
269
290
/* * Map maintaining per-node state. Requires cs_main. */
270
- std::map<NodeId, CNodeState> mapNodeState;
291
+ static std::map<NodeId, CNodeState> mapNodeState;
271
292
272
293
// Requires cs_main.
273
- CNodeState *State (NodeId pnode) {
294
+ static CNodeState *State (NodeId pnode) {
274
295
std::map<NodeId, CNodeState>::iterator it = mapNodeState.find (pnode);
275
296
if (it == mapNodeState.end ())
276
297
return nullptr ;
@@ -809,7 +830,9 @@ static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Para
809
830
(GetBlockProofEquivalentTime (*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT);
810
831
}
811
832
812
- PeerLogicValidation::PeerLogicValidation (CConnman* connmanIn, CScheduler &scheduler) : connman(connmanIn), m_stale_tip_check_time(0 ) {
833
+ PeerLogicValidation::PeerLogicValidation (CConnman* connmanIn, CScheduler &scheduler, bool enable_bip61)
834
+ : connman(connmanIn), m_stale_tip_check_time(0 ), m_enable_bip61(enable_bip61) {
835
+
813
836
// Initialize global variables that cannot be constructed at startup.
814
837
recentRejects.reset (new CRollingBloomFilter (120000 , 0.000001 ));
815
838
@@ -866,7 +889,7 @@ static uint256 most_recent_block_hash;
866
889
static bool fWitnessesPresentInMostRecentCompactBlock ;
867
890
868
891
/* *
869
- * Maintain state about the best-seen block and fast-announce a compact block
892
+ * Maintain state about the best-seen block and fast-announce a compact block
870
893
* to compatible peers.
871
894
*/
872
895
void PeerLogicValidation::NewPoWValidBlock (const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& pblock) {
@@ -911,7 +934,7 @@ void PeerLogicValidation::NewPoWValidBlock(const CBlockIndex *pindex, const std:
911
934
}
912
935
913
936
/* *
914
- * Update our best height and announce any block hashes which weren't previously
937
+ * Update our best height and announce any block hashes which weren't previously
915
938
* in chainActive to our peers.
916
939
*/
917
940
void PeerLogicValidation::UpdatedBlockTip (const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload ) {
@@ -947,7 +970,7 @@ void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CB
947
970
}
948
971
949
972
/* *
950
- * Handle invalid block rejection and consequent peer banning, maintain which
973
+ * Handle invalid block rejection and consequent peer banning, maintain which
951
974
* peers announce compact blocks.
952
975
*/
953
976
void PeerLogicValidation::BlockChecked (const CBlock& block, const CValidationState& state) {
@@ -1534,7 +1557,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
1534
1557
return true ;
1535
1558
}
1536
1559
1537
- bool static ProcessMessage (CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman* connman, const std::atomic<bool >& interruptMsgProc)
1560
+ bool static ProcessMessage (CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman* connman, const std::atomic<bool >& interruptMsgProc, bool enable_bip61 )
1538
1561
{
1539
1562
LogPrint (BCLog::NET, " received: %s (%u bytes) peer=%d\n " , SanitizeString (strCommand), vRecv.size (), pfrom->GetId ());
1540
1563
if (gArgs .IsArgSet (" -dropmessagestest" ) && GetRand (gArgs .GetArg (" -dropmessagestest" , 0 )) == 0 )
@@ -1588,7 +1611,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
1588
1611
// Each connection can only send one version message
1589
1612
if (pfrom->nVersion != 0 )
1590
1613
{
1591
- if (g_enable_bip61 ) {
1614
+ if (enable_bip61 ) {
1592
1615
connman->PushMessage (pfrom, CNetMsgMaker (INIT_PROTO_VERSION).Make (NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, std::string (" Duplicate version message" )));
1593
1616
}
1594
1617
LOCK (cs_main);
@@ -1619,7 +1642,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
1619
1642
if (!pfrom->fInbound && !pfrom->fFeeler && !pfrom->m_manual_connection && !HasAllDesirableServiceFlags (nServices))
1620
1643
{
1621
1644
LogPrint (BCLog::NET, " peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n " , pfrom->GetId (), nServices, GetDesirableServiceFlags (nServices));
1622
- if (g_enable_bip61 ) {
1645
+ if (enable_bip61 ) {
1623
1646
connman->PushMessage (pfrom, CNetMsgMaker (INIT_PROTO_VERSION).Make (NetMsgType::REJECT, strCommand, REJECT_NONSTANDARD,
1624
1647
strprintf (" Expected to offer services %08x" , GetDesirableServiceFlags (nServices))));
1625
1648
}
@@ -1642,7 +1665,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
1642
1665
{
1643
1666
// disconnect from peers older than this proto version
1644
1667
LogPrint (BCLog::NET, " peer=%d using obsolete version %i; disconnecting\n " , pfrom->GetId (), nVersion);
1645
- if (g_enable_bip61 ) {
1668
+ if (enable_bip61 ) {
1646
1669
connman->PushMessage (pfrom, CNetMsgMaker (INIT_PROTO_VERSION).Make (NetMsgType::REJECT, strCommand, REJECT_OBSOLETE,
1647
1670
strprintf (" Version must be %d or greater" , MIN_PEER_PROTO_VERSION)));
1648
1671
}
@@ -2340,7 +2363,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2340
2363
LogPrint (BCLog::MEMPOOLREJ, " %s from peer=%d was not accepted: %s\n " , tx.GetHash ().ToString (),
2341
2364
pfrom->GetId (),
2342
2365
FormatStateMessage (state));
2343
- if (g_enable_bip61 && state.GetRejectCode () > 0 && state.GetRejectCode () < REJECT_INTERNAL) { // Never send AcceptToMemoryPool's internal codes over P2P
2366
+ if (enable_bip61 && state.GetRejectCode () > 0 && state.GetRejectCode () < REJECT_INTERNAL) { // Never send AcceptToMemoryPool's internal codes over P2P
2344
2367
connman->PushMessage (pfrom, msgMaker.Make (NetMsgType::REJECT, strCommand, (unsigned char )state.GetRejectCode (),
2345
2368
state.GetRejectReason ().substr (0 , MAX_REJECT_MESSAGE_LENGTH), inv.hash ));
2346
2369
}
@@ -2525,7 +2548,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2525
2548
} // cs_main
2526
2549
2527
2550
if (fProcessBLOCKTXN )
2528
- return ProcessMessage (pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, connman, interruptMsgProc);
2551
+ return ProcessMessage (pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, connman, interruptMsgProc, enable_bip61 );
2529
2552
2530
2553
if (fRevertToHeaderProcessing ) {
2531
2554
// Headers received from HB compact block peers are permitted to be
@@ -2911,12 +2934,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2911
2934
return true ;
2912
2935
}
2913
2936
2914
- static bool SendRejectsAndCheckIfBanned (CNode* pnode, CConnman* connman)
2937
+ static bool SendRejectsAndCheckIfBanned (CNode* pnode, CConnman* connman, bool enable_bip61 )
2915
2938
{
2916
2939
AssertLockHeld (cs_main);
2917
2940
CNodeState &state = *State (pnode->GetId ());
2918
2941
2919
- if (g_enable_bip61 ) {
2942
+ if (enable_bip61 ) {
2920
2943
for (const CBlockReject& reject : state.rejects ) {
2921
2944
connman->PushMessage (pnode, CNetMsgMaker (INIT_PROTO_VERSION).Make (NetMsgType::REJECT, std::string (NetMsgType::BLOCK), reject.chRejectCode , reject.strRejectReason , reject.hashBlock ));
2922
2945
}
@@ -3018,15 +3041,15 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter
3018
3041
bool fRet = false ;
3019
3042
try
3020
3043
{
3021
- fRet = ProcessMessage (pfrom, strCommand, vRecv, msg.nTime , chainparams, connman, interruptMsgProc);
3044
+ fRet = ProcessMessage (pfrom, strCommand, vRecv, msg.nTime , chainparams, connman, interruptMsgProc, m_enable_bip61 );
3022
3045
if (interruptMsgProc)
3023
3046
return false ;
3024
3047
if (!pfrom->vRecvGetData .empty ())
3025
3048
fMoreWork = true ;
3026
3049
}
3027
3050
catch (const std::ios_base::failure& e)
3028
3051
{
3029
- if (g_enable_bip61 ) {
3052
+ if (m_enable_bip61 ) {
3030
3053
connman->PushMessage (pfrom, CNetMsgMaker (INIT_PROTO_VERSION).Make (NetMsgType::REJECT, strCommand, REJECT_MALFORMED, std::string (" error parsing message" )));
3031
3054
}
3032
3055
if (strstr (e.what (), " end of data" ))
@@ -3060,7 +3083,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter
3060
3083
}
3061
3084
3062
3085
LOCK (cs_main);
3063
- SendRejectsAndCheckIfBanned (pfrom, connman);
3086
+ SendRejectsAndCheckIfBanned (pfrom, connman, m_enable_bip61 );
3064
3087
3065
3088
return fMoreWork ;
3066
3089
}
@@ -3195,6 +3218,7 @@ void PeerLogicValidation::CheckForStaleTipAndEvictPeers(const Consensus::Params
3195
3218
}
3196
3219
}
3197
3220
3221
+ namespace {
3198
3222
class CompareInvMempoolOrder
3199
3223
{
3200
3224
CTxMemPool *mp;
@@ -3211,6 +3235,7 @@ class CompareInvMempoolOrder
3211
3235
return mp->CompareDepthAndScore (*b, *a);
3212
3236
}
3213
3237
};
3238
+ }
3214
3239
3215
3240
bool PeerLogicValidation::SendMessages (CNode* pto)
3216
3241
{
@@ -3256,7 +3281,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
3256
3281
if (!lockMain)
3257
3282
return true ;
3258
3283
3259
- if (SendRejectsAndCheckIfBanned (pto, connman))
3284
+ if (SendRejectsAndCheckIfBanned (pto, connman, m_enable_bip61 ))
3260
3285
return true ;
3261
3286
CNodeState &state = *State (pto->GetId ());
3262
3287
0 commit comments