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 424 : CNetFulfilledRequestManager::CNetFulfilledRequestManager(unsigned int _itemsFilterSize) 15 : { 16 424 : itemsFilterSize = _itemsFilterSize; 17 424 : if (itemsFilterSize != 0) { 18 417 : itemsFilter = std::make_unique<CBloomFilter>(itemsFilterSize, 0.001, 0, BLOOM_UPDATE_ALL); 19 : } 20 424 : } 21 : 22 502 : void CNetFulfilledRequestManager::AddFulfilledRequest(const CService& addr, const std::string& strRequest) 23 : { 24 502 : LOCK(cs_mapFulfilledRequests); 25 502 : mapFulfilledRequests[addr][strRequest] = GetTime() + Params().FulfilledRequestExpireTime(); 26 502 : } 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 606 : static std::vector<unsigned char> convertElement(const CService& addr, const uint256& itemHash) 42 : { 43 606 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); 44 1212 : stream << addr.GetAddrBytes(); 45 606 : stream << itemHash; 46 606 : return {stream.begin(), stream.end()}; 47 : } 48 : 49 302 : void CNetFulfilledRequestManager::AddItemRequest(const CService& addr, const uint256& itemHash) 50 : { 51 302 : LOCK(cs_mapFulfilledRequests); 52 302 : assert(itemsFilter); 53 302 : itemsFilter->insert(convertElement(addr, itemHash)); 54 302 : itemsFilterCount++; 55 302 : } 56 : 57 304 : bool CNetFulfilledRequestManager::HasItemRequest(const CService& addr, const uint256& itemHash) const 58 : { 59 304 : LOCK(cs_mapFulfilledRequests); 60 304 : assert(itemsFilter); 61 912 : return itemsFilter->contains(convertElement(addr, itemHash)); 62 : } 63 : 64 130 : void CNetFulfilledRequestManager::CheckAndRemove() 65 : { 66 130 : LOCK(cs_mapFulfilledRequests); 67 130 : int64_t now = GetTime(); 68 130 : for (auto it = mapFulfilledRequests.begin(); it != mapFulfilledRequests.end();) { 69 282 : for (auto it_entry = it->second.begin(); it_entry != it->second.end();) { 70 555 : if (now > it_entry->second) { 71 3 : it_entry = it->second.erase(it_entry); 72 : } else { 73 1389 : it_entry++; 74 : } 75 : } 76 282 : if (it->second.empty()) { 77 1 : it = mapFulfilledRequests.erase(it); 78 : } else { 79 693 : it++; 80 : } 81 : } 82 : 83 130 : if (now > lastFilterCleanup || itemsFilterCount >= itemsFilterSize) { 84 52 : itemsFilter->clear(); 85 52 : itemsFilterCount = 0; 86 52 : lastFilterCleanup = now + filterCleanupTime; 87 : } 88 130 : } 89 : 90 118 : void CNetFulfilledRequestManager::Clear() 91 : { 92 118 : LOCK(cs_mapFulfilledRequests); 93 118 : mapFulfilledRequests.clear(); 94 118 : } 95 : 96 391 : std::string CNetFulfilledRequestManager::ToString() const 97 : { 98 391 : LOCK(cs_mapFulfilledRequests); 99 782 : std::ostringstream info; 100 391 : info << "Nodes with fulfilled requests: " << (int)mapFulfilledRequests.size(); 101 782 : return info.str(); 102 : } 103 : 104 129 : void CNetFulfilledRequestManager::DoMaintenance() 105 : { 106 129 : if (ShutdownRequested()) return; 107 127 : CheckAndRemove(); 108 : }