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