genesis                 1 
genesis                 2 
genesis                 3 
genesis                 4 
genesis                 5 #ifndef BITCOIN_NET_H
genesis                 6 #define BITCOIN_NET_H
genesis                 7 
genesis                 8 #include <deque>
genesis                 9 #include <boost/array.hpp>
genesis                10 #include <boost/foreach.hpp>
genesis                11 #include <openssl/rand.h>
genesis                12 
genesis                13 #ifndef WIN32
genesis                14 #include <arpa/inet.h>
genesis                15 #endif
genesis                16 
genesis                17 #include "protocol.h"
genesis                18 
genesis                19 class CAddrDB;
genesis                20 class CRequestTracker;
genesis                21 class CNode;
genesis                22 class CBlockIndex;
genesis                23 extern int nBestHeight;
genesis                24 extern int nConnectTimeout;
genesis                25 
genesis                26 
genesis                27 
genesis                28 inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
genesis                29 inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
genesis                30 static const unsigned int PUBLISH_HOPS = 5;
genesis                31 
genesis                32 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
genesis                33 bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
genesis                34 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
genesis                35 bool GetMyExternalIP(unsigned int& ipRet);
genesis                36 bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL);
genesis                37 void AddressCurrentlyConnected(const CAddress& addr);
genesis                38 CNode* FindNode(unsigned int ip);
genesis                39 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
genesis                40 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
genesis                41 bool AnySubscribed(unsigned int nChannel);
genesis                42 void MapPort(bool fMapPort);
genesis                43 bool BindListenPort(std::string& strError=REF(std::string()));
genesis                44 void StartNode(void* parg);
genesis                45 bool StopNode();
genesis                46 
genesis                47 enum
genesis                48 {
genesis                49     MSG_TX = 1,
genesis                50     MSG_BLOCK,
genesis                51 };
genesis                52 
genesis                53 class CRequestTracker
genesis                54 {
genesis                55 public:
genesis                56     void (*fn)(void*, CDataStream&);
genesis                57     void* param1;
genesis                58 
genesis                59     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
genesis                60     {
genesis                61         fn = fnIn;
genesis                62         param1 = param1In;
genesis                63     }
genesis                64 
genesis                65     bool IsNull()
genesis                66     {
genesis                67         return fn == NULL;
genesis                68     }
genesis                69 };
genesis                70 
genesis                71 
genesis                72 
genesis                73 
genesis                74 
genesis                75 extern bool fClient;
genesis                76 extern bool fAllowDNS;
genesis                77 extern uint64 nLocalServices;
genesis                78 extern CAddress addrLocalHost;
genesis                79 extern uint64 nLocalHostNonce;
genesis                80 extern boost::array<int, 10> vnThreadsRunning;
genesis                81 
genesis                82 extern std::vector<CNode*> vNodes;
genesis                83 extern CCriticalSection cs_vNodes;
genesis                84 extern std::map<std::vector<unsigned char>, CAddress> mapAddresses;
genesis                85 extern CCriticalSection cs_mapAddresses;
genesis                86 extern std::map<CInv, CDataStream> mapRelay;
genesis                87 extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
genesis                88 extern CCriticalSection cs_mapRelay;
genesis                89 extern std::map<CInv, int64> mapAlreadyAskedFor;
genesis                90 
genesis                91 
genesis                92 extern int fUseProxy;
genesis                93 extern CAddress addrProxy;
genesis                94 
genesis                95 
genesis                96 
genesis                97 
genesis                98 
genesis                99 
genesis               100 class CNode
genesis               101 {
genesis               102 public:
genesis               103     
genesis               104     uint64 nServices;
genesis               105     SOCKET hSocket;
genesis               106     CDataStream vSend;
genesis               107     CDataStream vRecv;
genesis               108     CCriticalSection cs_vSend;
genesis               109     CCriticalSection cs_vRecv;
genesis               110     int64 nLastSend;
genesis               111     int64 nLastRecv;
genesis               112     int64 nLastSendEmpty;
genesis               113     int64 nTimeConnected;
genesis               114     unsigned int nHeaderStart;
genesis               115     unsigned int nMessageStart;
genesis               116     CAddress addr;
genesis               117     int nVersion;
genesis               118     std::string strSubVer;
genesis               119     bool fClient;
genesis               120     bool fInbound;
genesis               121     bool fNetworkNode;
genesis               122     bool fSuccessfullyConnected;
genesis               123     bool fDisconnect;
genesis               124 protected:
genesis               125     int nRefCount;
genesis               126 
genesis               127     
genesis               128     
genesis               129     static std::map<unsigned int, int64> setBanned;
genesis               130     static CCriticalSection cs_setBanned;
genesis               131     int nMisbehavior;
genesis               132 
genesis               133 public:
genesis               134     int64 nReleaseTime;
genesis               135     std::map<uint256, CRequestTracker> mapRequests;
genesis               136     CCriticalSection cs_mapRequests;
genesis               137     uint256 hashContinue;
genesis               138     CBlockIndex* pindexLastGetBlocksBegin;
genesis               139     uint256 hashLastGetBlocksEnd;
genesis               140     int nStartingHeight;
genesis               141 
genesis               142     
genesis               143     std::vector<CAddress> vAddrToSend;
genesis               144     std::set<CAddress> setAddrKnown;
genesis               145     bool fGetAddr;
genesis               146     std::set<uint256> setKnown;
genesis               147 
genesis               148     
genesis               149     std::set<CInv> setInventoryKnown;
genesis               150     std::vector<CInv> vInventoryToSend;
genesis               151     CCriticalSection cs_inventory;
genesis               152     std::multimap<int64, CInv> mapAskFor;
genesis               153 
genesis               154     
genesis               155     std::vector<char> vfSubscribe;
genesis               156 
genesis               157     CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
genesis               158     {
genesis               159         nServices = 0;
genesis               160         hSocket = hSocketIn;
genesis               161         vSend.SetType(SER_NETWORK);
genesis               162         vSend.SetVersion(0);
genesis               163         vRecv.SetType(SER_NETWORK);
genesis               164         vRecv.SetVersion(0);
genesis               165         
genesis               166         if (GetTime() > 1329696000)
genesis               167         {
genesis               168             vSend.SetVersion(209);
genesis               169             vRecv.SetVersion(209);
genesis               170         }
genesis               171         nLastSend = 0;
genesis               172         nLastRecv = 0;
genesis               173         nLastSendEmpty = GetTime();
genesis               174         nTimeConnected = GetTime();
genesis               175         nHeaderStart = -1;
genesis               176         nMessageStart = -1;
genesis               177         addr = addrIn;
genesis               178         nVersion = 0;
genesis               179         strSubVer = "";
genesis               180         fClient = false; 
genesis               181         fInbound = fInboundIn;
genesis               182         fNetworkNode = false;
genesis               183         fSuccessfullyConnected = false;
genesis               184         fDisconnect = false;
genesis               185         nRefCount = 0;
genesis               186         nReleaseTime = 0;
genesis               187         hashContinue = 0;
genesis               188         pindexLastGetBlocksBegin = 0;
genesis               189         hashLastGetBlocksEnd = 0;
genesis               190         nStartingHeight = -1;
genesis               191         fGetAddr = false;
genesis               192         vfSubscribe.assign(256, false);
genesis               193         nMisbehavior = 0;
genesis               194 
genesis               195         
genesis               196         if (!fInbound)
genesis               197             PushVersion();
genesis               198     }
genesis               199 
genesis               200     ~CNode()
genesis               201     {
genesis               202         if (hSocket != INVALID_SOCKET)
genesis               203         {
genesis               204             closesocket(hSocket);
genesis               205             hSocket = INVALID_SOCKET;
genesis               206         }
genesis               207     }
genesis               208 
genesis               209 private:
genesis               210     CNode(const CNode&);
genesis               211     void operator=(const CNode&);
genesis               212 public:
genesis               213 
genesis               214 
genesis               215     int GetRefCount()
genesis               216     {
genesis               217         return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
genesis               218     }
genesis               219 
genesis               220     CNode* AddRef(int64 nTimeout=0)
genesis               221     {
genesis               222         if (nTimeout != 0)
genesis               223             nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
genesis               224         else
genesis               225             nRefCount++;
genesis               226         return this;
genesis               227     }
genesis               228 
genesis               229     void Release()
genesis               230     {
genesis               231         nRefCount--;
genesis               232     }
genesis               233 
genesis               234 
genesis               235 
genesis               236     void AddAddressKnown(const CAddress& addr)
genesis               237     {
genesis               238         setAddrKnown.insert(addr);
genesis               239     }
genesis               240 
genesis               241     void PushAddress(const CAddress& addr)
genesis               242     {
genesis               243         
genesis               244         
genesis               245         
genesis               246         if (addr.IsValid() && !setAddrKnown.count(addr))
genesis               247             vAddrToSend.push_back(addr);
genesis               248     }
genesis               249 
genesis               250 
genesis               251     void AddInventoryKnown(const CInv& inv)
genesis               252     {
genesis               253         CRITICAL_BLOCK(cs_inventory)
genesis               254             setInventoryKnown.insert(inv);
genesis               255     }
genesis               256 
genesis               257     void PushInventory(const CInv& inv)
genesis               258     {
genesis               259         CRITICAL_BLOCK(cs_inventory)
genesis               260             if (!setInventoryKnown.count(inv))
genesis               261                 vInventoryToSend.push_back(inv);
genesis               262     }
genesis               263 
genesis               264     void AskFor(const CInv& inv)
genesis               265     {
genesis               266         
genesis               267         
genesis               268         int64& nRequestTime = mapAlreadyAskedFor[inv];
genesis               269         printf("askfor %s   %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
genesis               270 
genesis               271         
genesis               272         int64 nNow = (GetTime() - 1) * 1000000;
genesis               273         static int64 nLastTime;
genesis               274         ++nLastTime;
genesis               275         nNow = std::max(nNow, nLastTime);
genesis               276         nLastTime = nNow;
genesis               277 
genesis               278         
genesis               279         nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
genesis               280         mapAskFor.insert(std::make_pair(nRequestTime, inv));
genesis               281     }
genesis               282 
genesis               283 
genesis               284 
genesis               285     void BeginMessage(const char* pszCommand)
genesis               286     {
genesis               287         ENTER_CRITICAL_SECTION(cs_vSend);
genesis               288         if (nHeaderStart != -1)
genesis               289             AbortMessage();
genesis               290         nHeaderStart = vSend.size();
genesis               291         vSend << CMessageHeader(pszCommand, 0);
genesis               292         nMessageStart = vSend.size();
genesis               293         if (fDebug) {
genesis               294             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
genesis               295             printf("sending: %s ", pszCommand);
genesis               296         }
genesis               297     }
genesis               298 
genesis               299     void AbortMessage()
genesis               300     {
genesis               301         if (nHeaderStart == -1)
genesis               302             return;
genesis               303         vSend.resize(nHeaderStart);
genesis               304         nHeaderStart = -1;
genesis               305         nMessageStart = -1;
genesis               306         LEAVE_CRITICAL_SECTION(cs_vSend);
genesis               307 
genesis               308         if (fDebug)
genesis               309             printf("(aborted)\n");
genesis               310     }
genesis               311 
genesis               312     void EndMessage()
genesis               313     {
genesis               314         if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
genesis               315         {
genesis               316             printf("dropmessages DROPPING SEND MESSAGE\n");
genesis               317             AbortMessage();
genesis               318             return;
genesis               319         }
genesis               320 
genesis               321         if (nHeaderStart == -1)
genesis               322             return;
genesis               323 
genesis               324         
genesis               325         unsigned int nSize = vSend.size() - nMessageStart;
genesis               326         memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
genesis               327 
genesis               328         
genesis               329         if (vSend.GetVersion() >= 209)
genesis               330         {
genesis               331             uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
genesis               332             unsigned int nChecksum = 0;
genesis               333             memcpy(&nChecksum, &hash, sizeof(nChecksum));
genesis               334             assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum));
genesis               335             memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum));
genesis               336         }
genesis               337 
genesis               338         if (fDebug) {
genesis               339             printf("(%d bytes)\n", nSize);
genesis               340         }
genesis               341 
genesis               342         nHeaderStart = -1;
genesis               343         nMessageStart = -1;
genesis               344         LEAVE_CRITICAL_SECTION(cs_vSend);
genesis               345     }
genesis               346 
genesis               347     void EndMessageAbortIfEmpty()
genesis               348     {
genesis               349         if (nHeaderStart == -1)
genesis               350             return;
genesis               351         int nSize = vSend.size() - nMessageStart;
genesis               352         if (nSize > 0)
genesis               353             EndMessage();
genesis               354         else
genesis               355             AbortMessage();
genesis               356     }
genesis               357 
genesis               358 
genesis               359 
genesis               360     void PushVersion()
genesis               361     {
genesis               362         
genesis               363         int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
genesis               364         CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
genesis               365         CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress("0.0.0.0") : addrLocalHost);
genesis               366         RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
genesis               367         PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
genesis               368                     nLocalHostNonce, std::string(pszSubVer), nBestHeight);
genesis               369     }
genesis               370 
genesis               371 
genesis               372 
genesis               373 
genesis               374     void PushMessage(const char* pszCommand)
genesis               375     {
genesis               376         try
genesis               377         {
genesis               378             BeginMessage(pszCommand);
genesis               379             EndMessage();
genesis               380         }
genesis               381         catch (...)
genesis               382         {
genesis               383             AbortMessage();
genesis               384             throw;
genesis               385         }
genesis               386     }
genesis               387 
genesis               388     template<typename T1>
genesis               389     void PushMessage(const char* pszCommand, const T1& a1)
genesis               390     {
genesis               391         try
genesis               392         {
genesis               393             BeginMessage(pszCommand);
genesis               394             vSend << a1;
genesis               395             EndMessage();
genesis               396         }
genesis               397         catch (...)
genesis               398         {
genesis               399             AbortMessage();
genesis               400             throw;
genesis               401         }
genesis               402     }
genesis               403 
genesis               404     template<typename T1, typename T2>
genesis               405     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
genesis               406     {
genesis               407         try
genesis               408         {
genesis               409             BeginMessage(pszCommand);
genesis               410             vSend << a1 << a2;
genesis               411             EndMessage();
genesis               412         }
genesis               413         catch (...)
genesis               414         {
genesis               415             AbortMessage();
genesis               416             throw;
genesis               417         }
genesis               418     }
genesis               419 
genesis               420     template<typename T1, typename T2, typename T3>
genesis               421     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
genesis               422     {
genesis               423         try
genesis               424         {
genesis               425             BeginMessage(pszCommand);
genesis               426             vSend << a1 << a2 << a3;
genesis               427             EndMessage();
genesis               428         }
genesis               429         catch (...)
genesis               430         {
genesis               431             AbortMessage();
genesis               432             throw;
genesis               433         }
genesis               434     }
genesis               435 
genesis               436     template<typename T1, typename T2, typename T3, typename T4>
genesis               437     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
genesis               438     {
genesis               439         try
genesis               440         {
genesis               441             BeginMessage(pszCommand);
genesis               442             vSend << a1 << a2 << a3 << a4;
genesis               443             EndMessage();
genesis               444         }
genesis               445         catch (...)
genesis               446         {
genesis               447             AbortMessage();
genesis               448             throw;
genesis               449         }
genesis               450     }
genesis               451 
genesis               452     template<typename T1, typename T2, typename T3, typename T4, typename T5>
genesis               453     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
genesis               454     {
genesis               455         try
genesis               456         {
genesis               457             BeginMessage(pszCommand);
genesis               458             vSend << a1 << a2 << a3 << a4 << a5;
genesis               459             EndMessage();
genesis               460         }
genesis               461         catch (...)
genesis               462         {
genesis               463             AbortMessage();
genesis               464             throw;
genesis               465         }
genesis               466     }
genesis               467 
genesis               468     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
genesis               469     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
genesis               470     {
genesis               471         try
genesis               472         {
genesis               473             BeginMessage(pszCommand);
genesis               474             vSend << a1 << a2 << a3 << a4 << a5 << a6;
genesis               475             EndMessage();
genesis               476         }
genesis               477         catch (...)
genesis               478         {
genesis               479             AbortMessage();
genesis               480             throw;
genesis               481         }
genesis               482     }
genesis               483 
genesis               484     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
genesis               485     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7)
genesis               486     {
genesis               487         try
genesis               488         {
genesis               489             BeginMessage(pszCommand);
genesis               490             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
genesis               491             EndMessage();
genesis               492         }
genesis               493         catch (...)
genesis               494         {
genesis               495             AbortMessage();
genesis               496             throw;
genesis               497         }
genesis               498     }
genesis               499 
genesis               500     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
genesis               501     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8)
genesis               502     {
genesis               503         try
genesis               504         {
genesis               505             BeginMessage(pszCommand);
genesis               506             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
genesis               507             EndMessage();
genesis               508         }
genesis               509         catch (...)
genesis               510         {
genesis               511             AbortMessage();
genesis               512             throw;
genesis               513         }
genesis               514     }
genesis               515 
genesis               516     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
genesis               517     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
genesis               518     {
genesis               519         try
genesis               520         {
genesis               521             BeginMessage(pszCommand);
genesis               522             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
genesis               523             EndMessage();
genesis               524         }
genesis               525         catch (...)
genesis               526         {
genesis               527             AbortMessage();
genesis               528             throw;
genesis               529         }
genesis               530     }
genesis               531 
genesis               532 
genesis               533     void PushRequest(const char* pszCommand,
genesis               534                      void (*fn)(void*, CDataStream&), void* param1)
genesis               535     {
genesis               536         uint256 hashReply;
genesis               537         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis               538 
genesis               539         CRITICAL_BLOCK(cs_mapRequests)
genesis               540             mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis               541 
genesis               542         PushMessage(pszCommand, hashReply);
genesis               543     }
genesis               544 
genesis               545     template<typename T1>
genesis               546     void PushRequest(const char* pszCommand, const T1& a1,
genesis               547                      void (*fn)(void*, CDataStream&), void* param1)
genesis               548     {
genesis               549         uint256 hashReply;
genesis               550         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis               551 
genesis               552         CRITICAL_BLOCK(cs_mapRequests)
genesis               553             mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis               554 
genesis               555         PushMessage(pszCommand, hashReply, a1);
genesis               556     }
genesis               557 
genesis               558     template<typename T1, typename T2>
genesis               559     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
genesis               560                      void (*fn)(void*, CDataStream&), void* param1)
genesis               561     {
genesis               562         uint256 hashReply;
genesis               563         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
genesis               564 
genesis               565         CRITICAL_BLOCK(cs_mapRequests)
genesis               566             mapRequests[hashReply] = CRequestTracker(fn, param1);
genesis               567 
genesis               568         PushMessage(pszCommand, hashReply, a1, a2);
genesis               569     }
genesis               570 
genesis               571 
genesis               572 
genesis               573     void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
genesis               574     bool IsSubscribed(unsigned int nChannel);
genesis               575     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
genesis               576     void CancelSubscribe(unsigned int nChannel);
genesis               577     void CloseSocketDisconnect();
genesis               578     void Cleanup();
genesis               579 
genesis               580 
genesis               581     
genesis               582     
genesis               583     
genesis               584     
genesis               585     
genesis               586     
genesis               587     
genesis               588     
genesis               589     
genesis               590     
genesis               591     
genesis               592     
genesis               593     
genesis               594     
genesis               595     static void ClearBanned(); 
genesis               596     static bool IsBanned(unsigned int ip);
genesis               597     bool Misbehaving(int howmuch); 
genesis               598 };
genesis               599 
genesis               600 
genesis               601 
genesis               602 
genesis               603 
genesis               604 
genesis               605 
genesis               606 
genesis               607 
genesis               608 
genesis               609 inline void RelayInventory(const CInv& inv)
genesis               610 {
genesis               611     
genesis               612     CRITICAL_BLOCK(cs_vNodes)
genesis               613         BOOST_FOREACH(CNode* pnode, vNodes)
genesis               614             pnode->PushInventory(inv);
genesis               615 }
genesis               616 
genesis               617 template<typename T>
genesis               618 void RelayMessage(const CInv& inv, const T& a)
genesis               619 {
genesis               620     CDataStream ss(SER_NETWORK);
genesis               621     ss.reserve(10000);
genesis               622     ss << a;
genesis               623     RelayMessage(inv, ss);
genesis               624 }
genesis               625 
genesis               626 template<>
genesis               627 inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
genesis               628 {
genesis               629     CRITICAL_BLOCK(cs_mapRelay)
genesis               630     {
genesis               631         
genesis               632         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
genesis               633         {
genesis               634             mapRelay.erase(vRelayExpiration.front().second);
genesis               635             vRelayExpiration.pop_front();
genesis               636         }
genesis               637 
genesis               638         
genesis               639         mapRelay[inv] = ss;
genesis               640         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
genesis               641     }
genesis               642 
genesis               643     RelayInventory(inv);
genesis               644 }
genesis               645 
genesis               646 
genesis               647 
genesis               648 
genesis               649 
genesis               650 
genesis               651 
genesis               652 
genesis               653 
genesis               654 
genesis               655 
genesis               656 
genesis               657 
genesis               658 
genesis               659 
genesis               660 
genesis               661 template<typename T>
genesis               662 void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis               663 {
genesis               664     
genesis               665     obj.setSources.insert(pfrom->addr.ip);
genesis               666 
genesis               667     if (!AdvertInsert(obj))
genesis               668         return;
genesis               669 
genesis               670     
genesis               671     CRITICAL_BLOCK(cs_vNodes)
genesis               672         BOOST_FOREACH(CNode* pnode, vNodes)
genesis               673             if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
genesis               674                 pnode->PushMessage("publish", nChannel, nHops, obj);
genesis               675 }
genesis               676 
genesis               677 template<typename T>
genesis               678 void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis               679 {
genesis               680     uint256 hash = obj.GetHash();
genesis               681 
genesis               682     CRITICAL_BLOCK(cs_vNodes)
genesis               683         BOOST_FOREACH(CNode* pnode, vNodes)
genesis               684             if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel)))
genesis               685                 pnode->PushMessage("pub-cancel", nChannel, nHops, hash);
genesis               686 
genesis               687     AdvertErase(obj);
genesis               688 }
genesis               689 
genesis               690 template<typename T>
genesis               691 void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj)
genesis               692 {
genesis               693     
genesis               694     obj.setSources.erase(pfrom->addr.ip);
genesis               695 
genesis               696     
genesis               697     if (obj.setSources.empty())
genesis               698         AdvertStopPublish(pfrom, nChannel, nHops, obj);
genesis               699 }
genesis               700 
genesis               701 #endif