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