rpcmining.cpp remove CBigNum from code
[novacoin.git] / src / net.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_NET_H
6 #define BITCOIN_NET_H
7
8 #include <limits>
9 #include <deque>
10 #ifndef Q_MOC_RUN
11 #endif
12 #include <openssl/rand.h>
13
14 #include "mruset.h"
15 #include "netbase.h"
16 #include "addrman.h"
17 #include "hash.h"
18
19
20 class CRequestTracker;
21 class CNode;
22 class CBlockIndex;
23 extern int nBestHeight;
24
25 const uint16_t nSocksDefault = 9050;
26 const uint16_t nPortZero = 0;
27
28
29 inline uint64_t ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
30 inline uint64_t SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
31
32 void AddOneShot(std::string strDest);
33 bool RecvLine(SOCKET hSocket, std::string& strLine);
34 bool GetMyExternalIP(CNetAddr& ipRet);
35 void AddressCurrentlyConnected(const CService& addr);
36 CNode* FindNode(const CNetAddr& ip);
37 CNode* FindNode(const CService& ip);
38 CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64_t nTimeout=0);
39 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
40 uint16_t GetListenPort();
41 bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
42 void StartNode(void* parg);
43 bool StopNode();
44
45 enum
46 {
47     LOCAL_NONE,   // unknown
48     LOCAL_IF,     // address a local interface listens on
49     LOCAL_BIND,   // address explicit bound to
50     LOCAL_IRC,    // address reported by IRC (deprecated)
51     LOCAL_HTTP,   // address reported by whatismyip.com and similar
52     LOCAL_MANUAL, // address explicitly specified (-externalip=)
53
54     LOCAL_MAX
55 };
56
57
58 bool IsPeerAddrLocalGood(CNode *pnode);
59 void AdvertiseLocal(CNode *pnode);
60 void SetLimited(enum Network net, bool fLimited = true);
61 bool IsLimited(enum Network net);
62 bool IsLimited(const CNetAddr& addr);
63 bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
64 bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
65 bool SeenLocal(const CService& addr);
66 bool IsLocal(const CService& addr);
67 bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
68 bool IsReachable(const CNetAddr &addr);
69 void SetReachable(enum Network net, bool fFlag = true);
70 CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
71
72
73 enum
74 {
75     MSG_TX = 1,
76     MSG_BLOCK
77 };
78
79 class CRequestTracker
80 {
81 public:
82     void (*fn)(void*, CDataStream&);
83     void* param1;
84
85     explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL)
86     {
87         fn = fnIn;
88         param1 = param1In;
89     }
90
91     bool IsNull()
92     {
93         return fn == NULL;
94     }
95 };
96
97
98 /** Thread types */
99 enum threadId
100 {
101     THREAD_SOCKETHANDLER,
102     THREAD_OPENCONNECTIONS,
103     THREAD_MESSAGEHANDLER,
104     THREAD_RPCLISTENER,
105     THREAD_DNSSEED,
106     THREAD_ADDEDCONNECTIONS,
107     THREAD_DUMPADDRESS,
108     THREAD_RPCHANDLER,
109     THREAD_MINTER,
110     THREAD_SCRIPTCHECK,
111     THREAD_NTP,
112     THREAD_IPCOLLECTOR,
113
114     THREAD_MAX
115 };
116
117 extern bool fClient;
118 extern bool fDiscover;
119 extern bool fNoListen;
120
121 extern bool fDiscover;
122 extern uint64_t nLocalServices;
123 extern uint64_t nLocalHostNonce;
124 extern CAddress addrSeenByPeer;
125 extern std::array<int, THREAD_MAX> vnThreadsRunning;
126 extern CAddrMan addrman;
127
128 extern std::vector<CNode*> vNodes;
129 extern CCriticalSection cs_vNodes;
130 extern std::vector<std::string> vAddedNodes;
131 extern CCriticalSection cs_vAddedNodes;
132 extern std::map<CInv, CDataStream> mapRelay;
133 extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
134 extern CCriticalSection cs_mapRelay;
135 extern std::map<CInv, int64_t> mapAlreadyAskedFor;
136
137
138 class CNodeStats
139 {
140 public:
141     uint64_t nServices;
142     int64_t nLastSend;
143     int64_t nLastRecv;
144     int64_t nTimeConnected;
145     std::string addrName;
146     int32_t nVersion;
147     std::string strSubVer;
148     bool fInbound;
149     int64_t nReleaseTime;
150     int32_t nStartingHeight;
151     int32_t nMisbehavior;
152     uint64_t nSendBytes;
153     uint64_t nRecvBytes;
154     bool fSyncNode;
155 };
156
157
158 // Information about a peer
159 class CNode
160 {
161 public:
162     // socket
163     uint64_t nServices;
164     SOCKET hSocket;
165     CDataStream vSend;
166     CDataStream vRecv;
167     uint64_t nSendBytes;
168     uint64_t nRecvBytes;
169     CCriticalSection cs_vSend;
170     CCriticalSection cs_vRecv;
171     int64_t nLastSend;
172     int64_t nLastRecv;
173     int64_t nLastSendEmpty;
174     int64_t nTimeConnected;
175     int32_t nHeaderStart;
176     uint32_t nMessageStart;
177     CAddress addr;
178     std::string addrName;
179     CService addrLocal;
180     int32_t nVersion;
181     std::string strSubVer;
182     bool fOneShot;
183     bool fClient;
184     bool fInbound;
185     bool fNetworkNode;
186     bool fSuccessfullyConnected;
187     bool fDisconnect;
188     CSemaphoreGrant grantOutbound;
189 protected:
190     int nRefCount;
191
192     // Denial-of-service detection/prevention
193     // Key is IP address, value is banned-until-time
194     static std::map<CNetAddr, int64_t> setBanned;
195     static CCriticalSection cs_setBanned;
196     int nMisbehavior;
197
198 public:
199     int64_t nReleaseTime;
200     std::map<uint256, CRequestTracker> mapRequests;
201     CCriticalSection cs_mapRequests;
202     uint256 hashContinue;
203     CBlockIndex* pindexLastGetBlocksBegin;
204     uint256 hashLastGetBlocksEnd;
205     int32_t nStartingHeight;
206     bool fStartSync;
207
208     // flood relay
209     std::vector<CAddress> vAddrToSend;
210     std::set<CAddress> setAddrKnown;
211     bool fGetAddr;
212     std::set<uint256> setKnown;
213     uint256 hashCheckpointKnown; // ppcoin: known sent sync-checkpoint
214     int64_t nNextAddrSend;
215     int64_t nNextLocalAddrSend;
216     int64_t nNextInvSend;
217
218     // inventory based relay
219     mruset<CInv> setInventoryKnown;
220     std::vector<CInv> vInventoryToSend;
221     CCriticalSection cs_inventory;
222     std::multimap<int64_t, CInv> mapAskFor;
223
224     CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false);
225     ~CNode();
226
227 private:
228     // Network usage totals
229     static CCriticalSection cs_totalBytesRecv;
230     static CCriticalSection cs_totalBytesSent;
231     static uint64_t nTotalBytesRecv;
232     static uint64_t nTotalBytesSent;
233     CNode(const CNode&);
234     void operator=(const CNode&);
235
236 public:
237
238     int GetRefCount();
239     CNode* AddRef(int64_t nTimeout=0);
240     void Release();
241     void AddAddressKnown(const CAddress& addr);
242     void PushAddress(const CAddress& addr);
243     void AddInventoryKnown(const CInv& inv);
244     void PushInventory(const CInv& inv);
245     void AskFor(const CInv& inv);
246     void BeginMessage(const char* pszCommand);
247     void AbortMessage();
248     void EndMessage();
249     void EndMessageAbortIfEmpty();
250     void PushVersion();
251
252     void PushMessage(const char* pszCommand)
253     {
254         try
255         {
256             BeginMessage(pszCommand);
257             EndMessage();
258         }
259         catch (...)
260         {
261             AbortMessage();
262             throw;
263         }
264     }
265
266     template<typename T1>
267     void PushMessage(const char* pszCommand, const T1& a1)
268     {
269         try
270         {
271             BeginMessage(pszCommand);
272             vSend << a1;
273             EndMessage();
274         }
275         catch (...)
276         {
277             AbortMessage();
278             throw;
279         }
280     }
281
282     template<typename T1, typename T2>
283     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
284     {
285         try
286         {
287             BeginMessage(pszCommand);
288             vSend << a1 << a2;
289             EndMessage();
290         }
291         catch (...)
292         {
293             AbortMessage();
294             throw;
295         }
296     }
297
298     template<typename T1, typename T2, typename T3>
299     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
300     {
301         try
302         {
303             BeginMessage(pszCommand);
304             vSend << a1 << a2 << a3;
305             EndMessage();
306         }
307         catch (...)
308         {
309             AbortMessage();
310             throw;
311         }
312     }
313
314     template<typename T1, typename T2, typename T3, typename T4>
315     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
316     {
317         try
318         {
319             BeginMessage(pszCommand);
320             vSend << a1 << a2 << a3 << a4;
321             EndMessage();
322         }
323         catch (...)
324         {
325             AbortMessage();
326             throw;
327         }
328     }
329
330     template<typename T1, typename T2, typename T3, typename T4, typename T5>
331     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
332     {
333         try
334         {
335             BeginMessage(pszCommand);
336             vSend << a1 << a2 << a3 << a4 << a5;
337             EndMessage();
338         }
339         catch (...)
340         {
341             AbortMessage();
342             throw;
343         }
344     }
345
346     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
347     void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
348     {
349         try
350         {
351             BeginMessage(pszCommand);
352             vSend << a1 << a2 << a3 << a4 << a5 << a6;
353             EndMessage();
354         }
355         catch (...)
356         {
357             AbortMessage();
358             throw;
359         }
360     }
361
362     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
363     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)
364     {
365         try
366         {
367             BeginMessage(pszCommand);
368             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
369             EndMessage();
370         }
371         catch (...)
372         {
373             AbortMessage();
374             throw;
375         }
376     }
377
378     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
379     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)
380     {
381         try
382         {
383             BeginMessage(pszCommand);
384             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
385             EndMessage();
386         }
387         catch (...)
388         {
389             AbortMessage();
390             throw;
391         }
392     }
393
394     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
395     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)
396     {
397         try
398         {
399             BeginMessage(pszCommand);
400             vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
401             EndMessage();
402         }
403         catch (...)
404         {
405             AbortMessage();
406             throw;
407         }
408     }
409
410
411     void PushRequest(const char* pszCommand,
412                      void (*fn)(void*, CDataStream&), void* param1)
413     {
414         uint256 hashReply;
415         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
416
417         {
418             LOCK(cs_mapRequests);
419             mapRequests[hashReply] = CRequestTracker(fn, param1);
420         }
421
422         PushMessage(pszCommand, hashReply);
423     }
424
425     template<typename T1>
426     void PushRequest(const char* pszCommand, const T1& a1,
427                      void (*fn)(void*, CDataStream&), void* param1)
428     {
429         uint256 hashReply;
430         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
431
432         {
433             LOCK(cs_mapRequests);
434             mapRequests[hashReply] = CRequestTracker(fn, param1);
435         }
436
437         PushMessage(pszCommand, hashReply, a1);
438     }
439
440     template<typename T1, typename T2>
441     void PushRequest(const char* pszCommand, const T1& a1, const T2& a2,
442                      void (*fn)(void*, CDataStream&), void* param1)
443     {
444         uint256 hashReply;
445         RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
446
447         {
448             LOCK(cs_mapRequests);
449             mapRequests[hashReply] = CRequestTracker(fn, param1);
450         }
451
452         PushMessage(pszCommand, hashReply, a1, a2);
453     }
454
455
456
457     void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd);
458     bool IsSubscribed(unsigned int nChannel);
459     void Subscribe(unsigned int nChannel, unsigned int nHops=0);
460     void CancelSubscribe(unsigned int nChannel);
461     void CloseSocketDisconnect();
462     void Cleanup();
463
464
465     // Denial-of-service detection/prevention
466     // The idea is to detect peers that are behaving
467     // badly and disconnect/ban them, but do it in a
468     // one-coding-mistake-won't-shatter-the-entire-network
469     // way.
470     // IMPORTANT:  There should be nothing I can give a
471     // node that it will forward on that will make that
472     // node's peers drop it. If there is, an attacker
473     // can isolate a node and/or try to split the network.
474     // Dropping a node for sending stuff that is invalid
475     // now but might be valid in a later version is also
476     // dangerous, because it can cause a network split
477     // between nodes running old code and nodes running
478     // new code.
479     static void ClearBanned(); // needed for unit testing
480     static bool IsBanned(CNetAddr ip);
481     bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
482     void copyStats(CNodeStats &stats);
483     // Network stats
484     static void RecordBytesRecv(uint64_t bytes);
485     static void RecordBytesSent(uint64_t bytes);
486
487     static uint64_t GetTotalBytesRecv();
488     static uint64_t GetTotalBytesSent();
489 };
490
491 class CTransaction;
492 void RelayTransaction(const CTransaction& tx, const uint256& hash);
493 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
494
495
496 /** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
497 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
498
499 #endif