Line data Source code
1 : // Copyright (c) 2014-2020 The Dash Core developers 2 : // Copyright (c) 2022 The PIVX Core developers 3 : // Distributed under the MIT software license, see the accompanying 4 : // file COPYING or https://www.opensource.org/licenses/mit-license.php. 5 : 6 : #include "tiertwo/netfulfilledman.h" 7 : #include "chainparams.h" 8 : #include "netaddress.h" 9 : #include "shutdown.h" 10 : #include "utiltime.h" 11 : 12 : CNetFulfilledRequestManager g_netfulfilledman(DEFAULT_ITEMS_FILTER_SIZE); 13 : 14 487 : CNetFulfilledRequestManager::CNetFulfilledRequestManager(unsigned int _itemsFilterSize) 15 : { 16 487 : itemsFilterSize = _itemsFilterSize; 17 487 : if (itemsFilterSize != 0) { 18 480 : itemsFilter = std::make_unique<CBloomFilter>(itemsFilterSize, 0.001, 0, BLOOM_UPDATE_ALL); 19 : } 20 487 : } 21 : 22 1485 : void CNetFulfilledRequestManager::AddFulfilledRequest(const CService& addr, const std::string& strRequest) 23 : { 24 1485 : LOCK(cs_mapFulfilledRequests); 25 1485 : mapFulfilledRequests[addr][strRequest] = GetTime() + Params().FulfilledRequestExpireTime(); 26 1485 : } 27 : 28 3 : bool CNetFulfilledRequestManager::HasFulfilledRequest(const CService& addr, const std::string& strRequest) const 29 : { 30 6 : LOCK(cs_mapFulfilledRequests); 31 3 : auto it = mapFulfilledRequests.find(addr); 32 3 : if (it != mapFulfilledRequests.end()) { 33 2 : auto itReq = it->second.find(strRequest); 34 2 : if (itReq != it->second.end()) { 35 2 : return itReq->second > GetTime(); 36 : } 37 : } 38 : return false; 39 : } 40 : 41 612 : static std::vector<unsigned char> convertElement(const CService& addr, const uint256& itemHash) 42 : { 43 612 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); 44 1224 : stream << addr.GetAddrBytes(); 45 612 : stream << itemHash; 46 612 : return {stream.begin(), stream.end()}; 47 : } 48 : 49 304 : void CNetFulfilledRequestManager::AddItemRequest(const CService& addr, const uint256& itemHash) 50 : { 51 304 : LOCK(cs_mapFulfilledRequests); 52 304 : assert(itemsFilter); 53 304 : itemsFilter->insert(convertElement(addr, itemHash)); 54 304 : itemsFilterCount++; 55 304 : } 56 : 57 308 : bool CNetFulfilledRequestManager::HasItemRequest(const CService& addr, const uint256& itemHash) const 58 : { 59 308 : LOCK(cs_mapFulfilledRequests); 60 308 : assert(itemsFilter); 61 924 : return itemsFilter->contains(convertElement(addr, itemHash)); 62 : } 63 : 64 231 : void CNetFulfilledRequestManager::CheckAndRemove() 65 : { 66 231 : LOCK(cs_mapFulfilledRequests); 67 231 : int64_t now = GetTime(); 68 231 : for (auto it = mapFulfilledRequests.begin(); it != mapFulfilledRequests.end();) { 69 1322 : for (auto it_entry = it->second.begin(); it_entry != it->second.end();) { 70 2641 : if (now > it_entry->second) { 71 25 : it_entry = it->second.erase(it_entry); 72 : } else { 73 6579 : it_entry++; 74 : } 75 : } 76 1322 : if (it->second.empty()) { 77 13 : it = mapFulfilledRequests.erase(it); 78 : } else { 79 2862 : it++; 80 : } 81 : } 82 : 83 231 : if (now > lastFilterCleanup || itemsFilterCount >= itemsFilterSize) { 84 113 : itemsFilter->clear(); 85 113 : itemsFilterCount = 0; 86 113 : lastFilterCleanup = now + filterCleanupTime; 87 : } 88 231 : } 89 : 90 221 : void CNetFulfilledRequestManager::Clear() 91 : { 92 221 : LOCK(cs_mapFulfilledRequests); 93 221 : mapFulfilledRequests.clear(); 94 221 : } 95 : 96 461 : std::string CNetFulfilledRequestManager::ToString() const 97 : { 98 461 : LOCK(cs_mapFulfilledRequests); 99 922 : std::ostringstream info; 100 461 : info << "Nodes with fulfilled requests: " << (int)mapFulfilledRequests.size(); 101 922 : return info.str(); 102 : } 103 : 104 229 : void CNetFulfilledRequestManager::DoMaintenance() 105 : { 106 229 : if (ShutdownRequested()) return; 107 228 : CheckAndRemove(); 108 : }