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 1501 : void CNetFulfilledRequestManager::AddFulfilledRequest(const CService& addr, const std::string& strRequest) 23 : { 24 1501 : LOCK(cs_mapFulfilledRequests); 25 1501 : mapFulfilledRequests[addr][strRequest] = GetTime() + Params().FulfilledRequestExpireTime(); 26 1501 : } 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 615 : static std::vector<unsigned char> convertElement(const CService& addr, const uint256& itemHash) 42 : { 43 615 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); 44 1230 : stream << addr.GetAddrBytes(); 45 615 : stream << itemHash; 46 615 : return {stream.begin(), stream.end()}; 47 : } 48 : 49 305 : void CNetFulfilledRequestManager::AddItemRequest(const CService& addr, const uint256& itemHash) 50 : { 51 305 : LOCK(cs_mapFulfilledRequests); 52 305 : assert(itemsFilter); 53 305 : itemsFilter->insert(convertElement(addr, itemHash)); 54 305 : itemsFilterCount++; 55 305 : } 56 : 57 310 : bool CNetFulfilledRequestManager::HasItemRequest(const CService& addr, const uint256& itemHash) const 58 : { 59 310 : LOCK(cs_mapFulfilledRequests); 60 310 : assert(itemsFilter); 61 930 : return itemsFilter->contains(convertElement(addr, itemHash)); 62 : } 63 : 64 210 : void CNetFulfilledRequestManager::CheckAndRemove() 65 : { 66 210 : LOCK(cs_mapFulfilledRequests); 67 210 : int64_t now = GetTime(); 68 210 : for (auto it = mapFulfilledRequests.begin(); it != mapFulfilledRequests.end();) { 69 1198 : for (auto it_entry = it->second.begin(); it_entry != it->second.end();) { 70 2394 : if (now > it_entry->second) { 71 25 : it_entry = it->second.erase(it_entry); 72 : } else { 73 5961 : it_entry++; 74 : } 75 : } 76 1198 : if (it->second.empty()) { 77 13 : it = mapFulfilledRequests.erase(it); 78 : } else { 79 2593 : it++; 80 : } 81 : } 82 : 83 210 : if (now > lastFilterCleanup || itemsFilterCount >= itemsFilterSize) { 84 108 : itemsFilter->clear(); 85 108 : itemsFilterCount = 0; 86 108 : lastFilterCleanup = now + filterCleanupTime; 87 : } 88 210 : } 89 : 90 185 : void CNetFulfilledRequestManager::Clear() 91 : { 92 185 : LOCK(cs_mapFulfilledRequests); 93 185 : mapFulfilledRequests.clear(); 94 185 : } 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 207 : void CNetFulfilledRequestManager::DoMaintenance() 105 : { 106 207 : if (ShutdownRequested()) return; 107 207 : CheckAndRemove(); 108 : }