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