@@ -68,13 +68,13 @@ static constexpr int32_t MAX_PEER_TX_IN_FLIGHT = 100;
68
68
/* * Maximum number of announced transactions from a peer */
69
69
static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS = 2 * MAX_INV_SZ;
70
70
/* * How many microseconds to delay requesting transactions from inbound peers */
71
- static constexpr int64_t INBOUND_PEER_TX_DELAY = 2 * 1000000 ; // 2 seconds
71
+ static constexpr std::chrono::microseconds INBOUND_PEER_TX_DELAY{std::chrono::seconds{ 2 }};
72
72
/* * How long to wait (in microseconds) before downloading a transaction from an additional peer */
73
- static constexpr int64_t GETDATA_TX_INTERVAL = 60 * 1000000 ; // 1 minute
73
+ static constexpr std::chrono::microseconds GETDATA_TX_INTERVAL{std::chrono::seconds{ 60 }};
74
74
/* * Maximum delay (in microseconds) for transaction requests to avoid biasing some peers over others. */
75
- static constexpr int64_t MAX_GETDATA_RANDOM_DELAY = 2 * 1000000 ; // 2 seconds
75
+ static constexpr std::chrono::microseconds MAX_GETDATA_RANDOM_DELAY{std::chrono::seconds{ 2 }};
76
76
/* * How long to wait (in microseconds) before expiring an in-flight getdata request to a peer */
77
- static constexpr int64_t TX_EXPIRY_INTERVAL = 10 * GETDATA_TX_INTERVAL ;
77
+ static constexpr std::chrono::microseconds TX_EXPIRY_INTERVAL{GETDATA_TX_INTERVAL * 10 } ;
78
78
static_assert (INBOUND_PEER_TX_DELAY >= MAX_GETDATA_RANDOM_DELAY,
79
79
" To preserve security, MAX_GETDATA_RANDOM_DELAY should not exceed INBOUND_PEER_DELAY" );
80
80
/* * Limit to avoid sending big packets. Not used in processing incoming GETDATA for compatibility */
@@ -340,16 +340,16 @@ struct CNodeState {
340
340
/* Track when to attempt download of announced transactions (process
341
341
* time in micros -> txid)
342
342
*/
343
- std::multimap<int64_t , uint256> m_tx_process_time;
343
+ std::multimap<std::chrono::microseconds , uint256> m_tx_process_time;
344
344
345
345
// ! Store all the transactions a peer has recently announced
346
346
std::set<uint256> m_tx_announced;
347
347
348
348
// ! Store transactions which were requested by us, with timestamp
349
- std::map<uint256, int64_t > m_tx_in_flight;
349
+ std::map<uint256, std::chrono::microseconds > m_tx_in_flight;
350
350
351
351
// ! Periodically check for stuck getdata requests
352
- int64_t m_check_expiry_timer{0 };
352
+ std::chrono::microseconds m_check_expiry_timer{0 };
353
353
};
354
354
355
355
TxDownloadState m_tx_download;
@@ -391,7 +391,7 @@ struct CNodeState {
391
391
};
392
392
393
393
// Keeps track of the time (in microseconds) when transactions were requested last time
394
- limitedmap<uint256, int64_t > g_already_asked_for GUARDED_BY (cs_main)(MAX_INV_SZ);
394
+ limitedmap<uint256, std::chrono::microseconds > g_already_asked_for GUARDED_BY (cs_main)(MAX_INV_SZ);
395
395
396
396
/* * Map maintaining per-node state. */
397
397
static std::map<NodeId, CNodeState> mapNodeState GUARDED_BY (cs_main);
@@ -688,16 +688,16 @@ void EraseTxRequest(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
688
688
g_already_asked_for.erase (txid);
689
689
}
690
690
691
- int64_t GetTxRequestTime (const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
691
+ std::chrono::microseconds GetTxRequestTime (const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
692
692
{
693
693
auto it = g_already_asked_for.find (txid);
694
694
if (it != g_already_asked_for.end ()) {
695
695
return it->second ;
696
696
}
697
- return 0 ;
697
+ return {} ;
698
698
}
699
699
700
- void UpdateTxRequestTime (const uint256& txid, int64_t request_time) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
700
+ void UpdateTxRequestTime (const uint256& txid, std::chrono::microseconds request_time) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
701
701
{
702
702
auto it = g_already_asked_for.find (txid);
703
703
if (it == g_already_asked_for.end ()) {
@@ -707,17 +707,17 @@ void UpdateTxRequestTime(const uint256& txid, int64_t request_time) EXCLUSIVE_LO
707
707
}
708
708
}
709
709
710
- int64_t CalculateTxGetDataTime (const uint256& txid, int64_t current_time, bool use_inbound_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
710
+ std::chrono::microseconds CalculateTxGetDataTime (const uint256& txid, std::chrono::microseconds current_time, bool use_inbound_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
711
711
{
712
- int64_t process_time;
713
- int64_t last_request_time = GetTxRequestTime (txid);
712
+ std::chrono::microseconds process_time;
713
+ const auto last_request_time = GetTxRequestTime (txid);
714
714
// First time requesting this tx
715
- if (last_request_time == 0 ) {
715
+ if (last_request_time. count () == 0 ) {
716
716
process_time = current_time;
717
717
} else {
718
718
// Randomize the delay to avoid biasing some peers over others (such as due to
719
719
// fixed ordering of peer processing in ThreadMessageHandler)
720
- process_time = last_request_time + GETDATA_TX_INTERVAL + GetRand (MAX_GETDATA_RANDOM_DELAY);
720
+ process_time = last_request_time + GETDATA_TX_INTERVAL + GetRandMicros (MAX_GETDATA_RANDOM_DELAY);
721
721
}
722
722
723
723
// We delay processing announcements from inbound peers
@@ -726,7 +726,7 @@ int64_t CalculateTxGetDataTime(const uint256& txid, int64_t current_time, bool u
726
726
return process_time;
727
727
}
728
728
729
- void RequestTx (CNodeState* state, const uint256& txid, int64_t nNow ) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
729
+ void RequestTx (CNodeState* state, const uint256& txid, std::chrono::microseconds current_time ) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
730
730
{
731
731
CNodeState::TxDownloadState& peer_download_state = state->m_tx_download ;
732
732
if (peer_download_state.m_tx_announced .size () >= MAX_PEER_TX_ANNOUNCEMENTS ||
@@ -740,7 +740,7 @@ void RequestTx(CNodeState* state, const uint256& txid, int64_t nNow) EXCLUSIVE_L
740
740
741
741
// Calculate the time to try requesting this transaction. Use
742
742
// fPreferredDownload as a proxy for outbound peers.
743
- int64_t process_time = CalculateTxGetDataTime (txid, nNow , !state->fPreferredDownload );
743
+ const auto process_time = CalculateTxGetDataTime (txid, current_time , !state->fPreferredDownload );
744
744
745
745
peer_download_state.m_tx_process_time .emplace (process_time, txid);
746
746
}
@@ -2223,7 +2223,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2223
2223
LOCK (cs_main);
2224
2224
2225
2225
uint32_t nFetchFlags = GetFetchFlags (pfrom);
2226
- int64_t nNow = GetTimeMicros ();
2226
+ const auto current_time = GetTime<std::chrono::microseconds> ();
2227
2227
2228
2228
for (CInv &inv : vInv)
2229
2229
{
@@ -2255,7 +2255,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2255
2255
if (fBlocksOnly ) {
2256
2256
LogPrint (BCLog::NET, " transaction (%s) inv sent in violation of protocol peer=%d\n " , inv.hash .ToString (), pfrom->GetId ());
2257
2257
} else if (!fAlreadyHave && !fImporting && !fReindex && !::ChainstateActive ().IsInitialBlockDownload ()) {
2258
- RequestTx (State (pfrom->GetId ()), inv.hash , nNow );
2258
+ RequestTx (State (pfrom->GetId ()), inv.hash , current_time );
2259
2259
}
2260
2260
}
2261
2261
}
@@ -2529,12 +2529,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2529
2529
}
2530
2530
if (!fRejectedParents ) {
2531
2531
uint32_t nFetchFlags = GetFetchFlags (pfrom);
2532
- int64_t nNow = GetTimeMicros ();
2532
+ const auto current_time = GetTime<std::chrono::microseconds> ();
2533
2533
2534
2534
for (const CTxIn& txin : tx.vin ) {
2535
2535
CInv _inv (MSG_TX | nFetchFlags, txin.prevout .hash );
2536
2536
pfrom->AddInventoryKnown (_inv);
2537
- if (!AlreadyHave (_inv)) RequestTx (State (pfrom->GetId ()), _inv.hash , nNow );
2537
+ if (!AlreadyHave (_inv)) RequestTx (State (pfrom->GetId ()), _inv.hash , current_time );
2538
2538
}
2539
2539
AddOrphanTx (ptx, pfrom->GetId ());
2540
2540
@@ -3906,6 +3906,9 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
3906
3906
connman->PushMessage (pto, msgMaker.Make (NetMsgType::INV, vInv));
3907
3907
3908
3908
// Detect whether we're stalling
3909
+ const auto current_time = GetTime<std::chrono::microseconds>();
3910
+ // nNow is the current system time (GetTimeMicros is not mockable) and
3911
+ // should be replaced by the mockable current_time eventually
3909
3912
nNow = GetTimeMicros ();
3910
3913
if (state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
3911
3914
// Stalling only triggers when the block download window cannot move. During normal steady state,
@@ -3998,9 +4001,9 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
3998
4001
// were unresponsive in the past.
3999
4002
// Eventually we should consider disconnecting peers, but this is
4000
4003
// conservative.
4001
- if (state.m_tx_download .m_check_expiry_timer <= nNow ) {
4004
+ if (state.m_tx_download .m_check_expiry_timer <= current_time ) {
4002
4005
for (auto it=state.m_tx_download .m_tx_in_flight .begin (); it != state.m_tx_download .m_tx_in_flight .end ();) {
4003
- if (it->second <= nNow - TX_EXPIRY_INTERVAL) {
4006
+ if (it->second <= current_time - TX_EXPIRY_INTERVAL) {
4004
4007
LogPrint (BCLog::NET, " timeout of inflight tx %s from peer=%d\n " , it->first .ToString (), pto->GetId ());
4005
4008
state.m_tx_download .m_tx_announced .erase (it->first );
4006
4009
state.m_tx_download .m_tx_in_flight .erase (it++);
@@ -4010,11 +4013,11 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
4010
4013
}
4011
4014
// On average, we do this check every TX_EXPIRY_INTERVAL. Randomize
4012
4015
// so that we're not doing this for all peers at the same time.
4013
- state.m_tx_download .m_check_expiry_timer = nNow + TX_EXPIRY_INTERVAL/ 2 + GetRand (TX_EXPIRY_INTERVAL);
4016
+ state.m_tx_download .m_check_expiry_timer = current_time + TX_EXPIRY_INTERVAL / 2 + GetRandMicros (TX_EXPIRY_INTERVAL);
4014
4017
}
4015
4018
4016
4019
auto & tx_process_time = state.m_tx_download .m_tx_process_time ;
4017
- while (!tx_process_time.empty () && tx_process_time.begin ()->first <= nNow && state.m_tx_download .m_tx_in_flight .size () < MAX_PEER_TX_IN_FLIGHT) {
4020
+ while (!tx_process_time.empty () && tx_process_time.begin ()->first <= current_time && state.m_tx_download .m_tx_in_flight .size () < MAX_PEER_TX_IN_FLIGHT) {
4018
4021
const uint256 txid = tx_process_time.begin ()->second ;
4019
4022
// Erase this entry from tx_process_time (it may be added back for
4020
4023
// processing at a later time, see below)
@@ -4023,22 +4026,22 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
4023
4026
if (!AlreadyHave (inv)) {
4024
4027
// If this transaction was last requested more than 1 minute ago,
4025
4028
// then request.
4026
- int64_t last_request_time = GetTxRequestTime (inv.hash );
4027
- if (last_request_time <= nNow - GETDATA_TX_INTERVAL) {
4029
+ const auto last_request_time = GetTxRequestTime (inv.hash );
4030
+ if (last_request_time <= current_time - GETDATA_TX_INTERVAL) {
4028
4031
LogPrint (BCLog::NET, " Requesting %s peer=%d\n " , inv.ToString (), pto->GetId ());
4029
4032
vGetData.push_back (inv);
4030
4033
if (vGetData.size () >= MAX_GETDATA_SZ) {
4031
4034
connman->PushMessage (pto, msgMaker.Make (NetMsgType::GETDATA, vGetData));
4032
4035
vGetData.clear ();
4033
4036
}
4034
- UpdateTxRequestTime (inv.hash , nNow );
4035
- state.m_tx_download .m_tx_in_flight .emplace (inv.hash , nNow );
4037
+ UpdateTxRequestTime (inv.hash , current_time );
4038
+ state.m_tx_download .m_tx_in_flight .emplace (inv.hash , current_time );
4036
4039
} else {
4037
4040
// This transaction is in flight from someone else; queue
4038
4041
// up processing to happen after the download times out
4039
4042
// (with a slight delay for inbound peers, to prefer
4040
4043
// requests to outbound peers).
4041
- int64_t next_process_time = CalculateTxGetDataTime (txid, nNow , !state.fPreferredDownload );
4044
+ const auto next_process_time = CalculateTxGetDataTime (txid, current_time , !state.fPreferredDownload );
4042
4045
tx_process_time.emplace (next_process_time, txid);
4043
4046
}
4044
4047
} else {
0 commit comments