mirror of
https://github.com/jwinterm/myriadcoin.git
synced 2026-11-12 08:54:02 +01:00
0.9.2
This commit is contained in:
+318
-141
@@ -1,30 +1,41 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Copyright (c) 2009-2014 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "db.h"
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "bitcoin-config.h"
|
||||
#endif
|
||||
|
||||
#include "net.h"
|
||||
#include "core.h"
|
||||
|
||||
#include "addrman.h"
|
||||
#include "chainparams.h"
|
||||
#include "core.h"
|
||||
#include "ui_interface.h"
|
||||
#include "script.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_UPNP
|
||||
#include <miniupnpc/miniwget.h>
|
||||
#include <miniupnpc/miniupnpc.h>
|
||||
#include <miniupnpc/miniwget.h>
|
||||
#include <miniupnpc/upnpcommands.h>
|
||||
#include <miniupnpc/upnperrors.h>
|
||||
#endif
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
// Dump addresses to peers.dat every 15 minutes (900s)
|
||||
#define DUMP_ADDRESSES_INTERVAL 900
|
||||
|
||||
#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
@@ -33,23 +44,18 @@ static const int MAX_OUTBOUND_CONNECTIONS = 8;
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
|
||||
|
||||
|
||||
struct LocalServiceInfo {
|
||||
int nScore;
|
||||
int nPort;
|
||||
};
|
||||
|
||||
//
|
||||
// Global state variables
|
||||
//
|
||||
bool fDiscover = true;
|
||||
uint64 nLocalServices = NODE_NETWORK;
|
||||
static CCriticalSection cs_mapLocalHost;
|
||||
static map<CNetAddr, LocalServiceInfo> mapLocalHost;
|
||||
uint64_t nLocalServices = NODE_NETWORK;
|
||||
CCriticalSection cs_mapLocalHost;
|
||||
map<CNetAddr, LocalServiceInfo> mapLocalHost;
|
||||
static bool vfReachable[NET_MAX] = {};
|
||||
static bool vfLimited[NET_MAX] = {};
|
||||
static CNode* pnodeLocalHost = NULL;
|
||||
static CNode* pnodeSync = NULL;
|
||||
uint64 nLocalHostNonce = 0;
|
||||
uint64_t nLocalHostNonce = 0;
|
||||
static std::vector<SOCKET> vhListenSocket;
|
||||
CAddrMan addrman;
|
||||
int nMaxConnections = 125;
|
||||
@@ -57,9 +63,9 @@ int nMaxConnections = 125;
|
||||
vector<CNode*> vNodes;
|
||||
CCriticalSection cs_vNodes;
|
||||
map<CInv, CDataStream> mapRelay;
|
||||
deque<pair<int64, CInv> > vRelayExpiration;
|
||||
deque<pair<int64_t, CInv> > vRelayExpiration;
|
||||
CCriticalSection cs_mapRelay;
|
||||
limitedmap<CInv, int64> mapAlreadyAskedFor(MAX_INV_SZ);
|
||||
limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
|
||||
|
||||
static deque<string> vOneShots;
|
||||
CCriticalSection cs_vOneShots;
|
||||
@@ -70,6 +76,9 @@ CCriticalSection cs_setservAddNodeAddresses;
|
||||
vector<std::string> vAddedNodes;
|
||||
CCriticalSection cs_vAddedNodes;
|
||||
|
||||
NodeId nLastNodeId = 0;
|
||||
CCriticalSection cs_nLastNodeId;
|
||||
|
||||
static CSemaphore *semOutbound = NULL;
|
||||
|
||||
// Signals for message handling
|
||||
@@ -129,7 +138,7 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer)
|
||||
bool RecvLine(SOCKET hSocket, string& strLine)
|
||||
{
|
||||
strLine = "";
|
||||
loop
|
||||
while (true)
|
||||
{
|
||||
char c;
|
||||
int nBytes = recv(hSocket, &c, 1, 0);
|
||||
@@ -162,14 +171,14 @@ bool RecvLine(SOCKET hSocket, string& strLine)
|
||||
if (nBytes == 0)
|
||||
{
|
||||
// socket closed
|
||||
printf("socket closed\n");
|
||||
LogPrint("net", "socket closed\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// socket error
|
||||
int nErr = WSAGetLastError();
|
||||
printf("recv failed: %d\n", nErr);
|
||||
LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -215,7 +224,7 @@ bool AddLocal(const CService& addr, int nScore)
|
||||
if (IsLimited(addr))
|
||||
return false;
|
||||
|
||||
printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
|
||||
LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
|
||||
|
||||
{
|
||||
LOCK(cs_mapLocalHost);
|
||||
@@ -292,7 +301,7 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha
|
||||
{
|
||||
SOCKET hSocket;
|
||||
if (!ConnectSocket(addrConnect, hSocket))
|
||||
return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
|
||||
return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString());
|
||||
|
||||
send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
|
||||
|
||||
@@ -301,7 +310,7 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha
|
||||
{
|
||||
if (strLine.empty()) // HTTP response is separated from headers by blank line
|
||||
{
|
||||
loop
|
||||
while (true)
|
||||
{
|
||||
if (!RecvLine(hSocket, strLine))
|
||||
{
|
||||
@@ -323,7 +332,7 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha
|
||||
while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
|
||||
strLine.resize(strLine.size()-1);
|
||||
CService addr(strLine,0,true);
|
||||
printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
|
||||
LogPrintf("GetMyExternalIP() received [%s] %s\n", strLine, addr.ToString());
|
||||
if (!addr.IsValid() || !addr.IsRoutable())
|
||||
return false;
|
||||
ipRet.SetIP(addr);
|
||||
@@ -398,7 +407,7 @@ void ThreadGetMyExternalIP()
|
||||
CNetAddr addrLocalHost;
|
||||
if (GetMyExternalIP(addrLocalHost))
|
||||
{
|
||||
printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
|
||||
LogPrintf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP());
|
||||
AddLocal(addrLocalHost, LOCAL_HTTP);
|
||||
}
|
||||
}
|
||||
@@ -415,8 +424,10 @@ void AddressCurrentlyConnected(const CService& addr)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint64_t CNode::nTotalBytesRecv = 0;
|
||||
uint64_t CNode::nTotalBytesSent = 0;
|
||||
CCriticalSection CNode::cs_totalBytesRecv;
|
||||
CCriticalSection CNode::cs_totalBytesSent;
|
||||
|
||||
CNode* FindNode(const CNetAddr& ip)
|
||||
{
|
||||
@@ -462,8 +473,8 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||
|
||||
|
||||
/// debug print
|
||||
printf("trying connection %s lastseen=%.1fhrs\n",
|
||||
pszDest ? pszDest : addrConnect.ToString().c_str(),
|
||||
LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
|
||||
pszDest ? pszDest : addrConnect.ToString(),
|
||||
pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
|
||||
|
||||
// Connect
|
||||
@@ -472,17 +483,16 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||
{
|
||||
addrman.Attempt(addrConnect);
|
||||
|
||||
/// debug print
|
||||
printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
|
||||
LogPrint("net", "connected %s\n", pszDest ? pszDest : addrConnect.ToString());
|
||||
|
||||
// Set to non-blocking
|
||||
#ifdef WIN32
|
||||
u_long nOne = 1;
|
||||
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
|
||||
printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
|
||||
LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %s\n", NetworkErrorString(WSAGetLastError()));
|
||||
#else
|
||||
if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
|
||||
printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
|
||||
LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %s\n", NetworkErrorString(errno));
|
||||
#endif
|
||||
|
||||
// Add node
|
||||
@@ -508,7 +518,7 @@ void CNode::CloseSocketDisconnect()
|
||||
fDisconnect = true;
|
||||
if (hSocket != INVALID_SOCKET)
|
||||
{
|
||||
printf("disconnecting node %s\n", addrName.c_str());
|
||||
LogPrint("net", "disconnecting node %s\n", addrName);
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
}
|
||||
@@ -530,12 +540,14 @@ void CNode::Cleanup()
|
||||
|
||||
void CNode::PushVersion()
|
||||
{
|
||||
int nBestHeight = g_signals.GetHeight().get_value_or(0);
|
||||
|
||||
/// when NTP implemented, change to just nTime = GetAdjustedTime()
|
||||
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
|
||||
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
|
||||
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
|
||||
CAddress addrMe = GetLocalAddress(&addr);
|
||||
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
|
||||
printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
|
||||
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), addr.ToString());
|
||||
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
|
||||
nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
|
||||
}
|
||||
@@ -544,7 +556,7 @@ void CNode::PushVersion()
|
||||
|
||||
|
||||
|
||||
std::map<CNetAddr, int64> CNode::setBanned;
|
||||
std::map<CNetAddr, int64_t> CNode::setBanned;
|
||||
CCriticalSection CNode::cs_setBanned;
|
||||
|
||||
void CNode::ClearBanned()
|
||||
@@ -557,10 +569,10 @@ bool CNode::IsBanned(CNetAddr ip)
|
||||
bool fResult = false;
|
||||
{
|
||||
LOCK(cs_setBanned);
|
||||
std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
|
||||
std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
|
||||
if (i != setBanned.end())
|
||||
{
|
||||
int64 t = (*i).second;
|
||||
int64_t t = (*i).second;
|
||||
if (GetTime() < t)
|
||||
fResult = true;
|
||||
}
|
||||
@@ -568,48 +580,51 @@ bool CNode::IsBanned(CNetAddr ip)
|
||||
return fResult;
|
||||
}
|
||||
|
||||
bool CNode::Misbehaving(int howmuch)
|
||||
{
|
||||
if (addr.IsLocal())
|
||||
bool CNode::Ban(const CNetAddr &addr) {
|
||||
int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
|
||||
{
|
||||
printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
|
||||
return false;
|
||||
LOCK(cs_setBanned);
|
||||
if (setBanned[addr] < banTime)
|
||||
setBanned[addr] = banTime;
|
||||
}
|
||||
|
||||
nMisbehavior += howmuch;
|
||||
if (nMisbehavior >= GetArg("-banscore", 100))
|
||||
{
|
||||
int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
|
||||
printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
|
||||
{
|
||||
LOCK(cs_setBanned);
|
||||
if (setBanned[addr] < banTime)
|
||||
setBanned[addr] = banTime;
|
||||
}
|
||||
CloseSocketDisconnect();
|
||||
return true;
|
||||
} else
|
||||
printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef X
|
||||
#define X(name) stats.name = name
|
||||
void CNode::copyStats(CNodeStats &stats)
|
||||
{
|
||||
stats.nodeid = this->GetId();
|
||||
X(nServices);
|
||||
X(nLastSend);
|
||||
X(nLastRecv);
|
||||
X(nTimeConnected);
|
||||
X(addrName);
|
||||
X(nVersion);
|
||||
X(strSubVer);
|
||||
X(cleanSubVer);
|
||||
X(fInbound);
|
||||
X(nStartingHeight);
|
||||
X(nMisbehavior);
|
||||
X(nSendBytes);
|
||||
X(nRecvBytes);
|
||||
stats.fSyncNode = (this == pnodeSync);
|
||||
|
||||
// It is common for nodes with good ping times to suddenly become lagged,
|
||||
// due to a new block arriving or other large transfer.
|
||||
// Merely reporting pingtime might fool the caller into thinking the node was still responsive,
|
||||
// since pingtime does not update until the ping is complete, which might take a while.
|
||||
// So, if a ping is taking an unusually long time in flight,
|
||||
// the caller can immediately detect that this is happening.
|
||||
int64_t nPingUsecWait = 0;
|
||||
if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
|
||||
nPingUsecWait = GetTimeMicros() - nPingUsecStart;
|
||||
}
|
||||
|
||||
// Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
|
||||
stats.dPingTime = (((double)nPingUsecTime) / 1e6);
|
||||
stats.dPingWait = (((double)nPingUsecWait) / 1e6);
|
||||
|
||||
// Leave string empty if addrLocal invalid (not filled in yet)
|
||||
stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
|
||||
}
|
||||
#undef X
|
||||
|
||||
@@ -706,6 +721,7 @@ void SocketSendData(CNode *pnode)
|
||||
pnode->nLastSend = GetTime();
|
||||
pnode->nSendBytes += nBytes;
|
||||
pnode->nSendOffset += nBytes;
|
||||
pnode->RecordBytesSent(nBytes);
|
||||
if (pnode->nSendOffset == data.size()) {
|
||||
pnode->nSendOffset = 0;
|
||||
pnode->nSendSize -= data.size();
|
||||
@@ -720,7 +736,7 @@ void SocketSendData(CNode *pnode)
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||
{
|
||||
printf("socket send error %d\n", nErr);
|
||||
LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
|
||||
pnode->CloseSocketDisconnect();
|
||||
}
|
||||
}
|
||||
@@ -741,7 +757,7 @@ static list<CNode*> vNodesDisconnected;
|
||||
void ThreadSocketHandler()
|
||||
{
|
||||
unsigned int nPrevNodeCount = 0;
|
||||
loop
|
||||
while (true)
|
||||
{
|
||||
//
|
||||
// Disconnect nodes
|
||||
@@ -771,7 +787,8 @@ void ThreadSocketHandler()
|
||||
vNodesDisconnected.push_back(pnode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
{
|
||||
// Delete disconnected nodes
|
||||
list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
|
||||
@@ -801,10 +818,9 @@ void ThreadSocketHandler()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vNodes.size() != nPrevNodeCount)
|
||||
{
|
||||
if(vNodes.size() != nPrevNodeCount) {
|
||||
nPrevNodeCount = vNodes.size();
|
||||
uiInterface.NotifyNumConnectionsChanged(vNodes.size());
|
||||
uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
|
||||
}
|
||||
|
||||
|
||||
@@ -880,7 +896,7 @@ void ThreadSocketHandler()
|
||||
if (have_fds)
|
||||
{
|
||||
int nErr = WSAGetLastError();
|
||||
printf("socket select error %d\n", nErr);
|
||||
LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
|
||||
for (unsigned int i = 0; i <= hSocketMax; i++)
|
||||
FD_SET(i, &fdsetRecv);
|
||||
}
|
||||
@@ -896,11 +912,7 @@ void ThreadSocketHandler()
|
||||
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
|
||||
if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
|
||||
{
|
||||
#ifdef USE_IPV6
|
||||
struct sockaddr_storage sockaddr;
|
||||
#else
|
||||
struct sockaddr sockaddr;
|
||||
#endif
|
||||
socklen_t len = sizeof(sockaddr);
|
||||
SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
|
||||
CAddress addr;
|
||||
@@ -908,7 +920,7 @@ void ThreadSocketHandler()
|
||||
|
||||
if (hSocket != INVALID_SOCKET)
|
||||
if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
|
||||
printf("Warning: Unknown socket family\n");
|
||||
LogPrintf("Warning: Unknown socket family\n");
|
||||
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
@@ -921,24 +933,20 @@ void ThreadSocketHandler()
|
||||
{
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr != WSAEWOULDBLOCK)
|
||||
printf("socket error accept failed: %d\n", nErr);
|
||||
LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
|
||||
}
|
||||
else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
|
||||
{
|
||||
{
|
||||
LOCK(cs_setservAddNodeAddresses);
|
||||
if (!setservAddNodeAddresses.count(addr))
|
||||
closesocket(hSocket);
|
||||
}
|
||||
closesocket(hSocket);
|
||||
}
|
||||
else if (CNode::IsBanned(addr))
|
||||
{
|
||||
printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
|
||||
LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
|
||||
closesocket(hSocket);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("accepted connection %s\n", addr.ToString().c_str());
|
||||
LogPrint("net", "accepted connection %s\n", addr.ToString());
|
||||
CNode* pnode = new CNode(hSocket, addr, "", true);
|
||||
pnode->AddRef();
|
||||
{
|
||||
@@ -983,12 +991,13 @@ void ThreadSocketHandler()
|
||||
pnode->CloseSocketDisconnect();
|
||||
pnode->nLastRecv = GetTime();
|
||||
pnode->nRecvBytes += nBytes;
|
||||
pnode->RecordBytesRecv(nBytes);
|
||||
}
|
||||
else if (nBytes == 0)
|
||||
{
|
||||
// socket closed gracefully
|
||||
if (!pnode->fDisconnect)
|
||||
printf("socket closed\n");
|
||||
LogPrint("net", "socket closed\n");
|
||||
pnode->CloseSocketDisconnect();
|
||||
}
|
||||
else if (nBytes < 0)
|
||||
@@ -998,7 +1007,7 @@ void ThreadSocketHandler()
|
||||
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||
{
|
||||
if (!pnode->fDisconnect)
|
||||
printf("socket recv error %d\n", nErr);
|
||||
LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
|
||||
pnode->CloseSocketDisconnect();
|
||||
}
|
||||
}
|
||||
@@ -1027,17 +1036,17 @@ void ThreadSocketHandler()
|
||||
{
|
||||
if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
|
||||
{
|
||||
printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
|
||||
LogPrint("net", "socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
|
||||
pnode->fDisconnect = true;
|
||||
}
|
||||
else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
|
||||
{
|
||||
printf("socket not sending\n");
|
||||
LogPrintf("socket not sending\n");
|
||||
pnode->fDisconnect = true;
|
||||
}
|
||||
else if (GetTime() - pnode->nLastRecv > 90*60)
|
||||
{
|
||||
printf("socket inactivity timeout\n");
|
||||
LogPrintf("socket inactivity timeout\n");
|
||||
pnode->fDisconnect = true;
|
||||
}
|
||||
}
|
||||
@@ -1089,23 +1098,23 @@ void ThreadMapPort()
|
||||
char externalIPAddress[40];
|
||||
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
|
||||
if(r != UPNPCOMMAND_SUCCESS)
|
||||
printf("UPnP: GetExternalIPAddress() returned %d\n", r);
|
||||
LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
|
||||
else
|
||||
{
|
||||
if(externalIPAddress[0])
|
||||
{
|
||||
printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
|
||||
LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
|
||||
AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
|
||||
}
|
||||
else
|
||||
printf("UPnP: GetExternalIPAddress failed.\n");
|
||||
LogPrintf("UPnP: GetExternalIPAddress failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
string strDesc = "Myriadcoin " + FormatFullVersion();
|
||||
|
||||
try {
|
||||
loop {
|
||||
while (true) {
|
||||
#ifndef UPNPDISCOVER_SUCCESS
|
||||
/* miniupnpc 1.5 */
|
||||
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
|
||||
@@ -1117,10 +1126,10 @@ void ThreadMapPort()
|
||||
#endif
|
||||
|
||||
if(r!=UPNPCOMMAND_SUCCESS)
|
||||
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
|
||||
port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
|
||||
LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
|
||||
port, port, lanaddr, r, strupnperror(r));
|
||||
else
|
||||
printf("UPnP Port Mapping successful.\n");;
|
||||
LogPrintf("UPnP Port Mapping successful.\n");;
|
||||
|
||||
MilliSleep(20*60*1000); // Refresh every 20 minutes
|
||||
}
|
||||
@@ -1128,13 +1137,13 @@ void ThreadMapPort()
|
||||
catch (boost::thread_interrupted)
|
||||
{
|
||||
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
|
||||
printf("UPNP_DeletePortMapping() returned : %d\n", r);
|
||||
LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
|
||||
freeUPNPDevlist(devlist); devlist = 0;
|
||||
FreeUPNPUrls(&urls);
|
||||
throw;
|
||||
}
|
||||
} else {
|
||||
printf("No valid UPnP IGDs found\n");
|
||||
LogPrintf("No valid UPnP IGDs found\n");
|
||||
freeUPNPDevlist(devlist); devlist = 0;
|
||||
if (r != 0)
|
||||
FreeUPNPUrls(&urls);
|
||||
@@ -1179,7 +1188,7 @@ void ThreadDNSAddressSeed()
|
||||
const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
|
||||
int found = 0;
|
||||
|
||||
printf("Loading addresses from DNS seeds (could take a while)\n");
|
||||
LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
|
||||
|
||||
BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
|
||||
if (HaveNameProxy()) {
|
||||
@@ -1202,7 +1211,7 @@ void ThreadDNSAddressSeed()
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d addresses found from DNS seeds\n", found);
|
||||
LogPrintf("%d addresses found from DNS seeds\n", found);
|
||||
}
|
||||
|
||||
|
||||
@@ -1218,12 +1227,12 @@ void ThreadDNSAddressSeed()
|
||||
|
||||
void DumpAddresses()
|
||||
{
|
||||
int64 nStart = GetTimeMillis();
|
||||
int64_t nStart = GetTimeMillis();
|
||||
|
||||
CAddrDB adb;
|
||||
adb.Write(addrman);
|
||||
|
||||
printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n",
|
||||
LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
|
||||
addrman.size(), GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
@@ -1250,7 +1259,7 @@ void ThreadOpenConnections()
|
||||
// Connect to specific addresses
|
||||
if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
|
||||
{
|
||||
for (int64 nLoop = 0;; nLoop++)
|
||||
for (int64_t nLoop = 0;; nLoop++)
|
||||
{
|
||||
ProcessOneShot();
|
||||
BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
|
||||
@@ -1267,8 +1276,8 @@ void ThreadOpenConnections()
|
||||
}
|
||||
|
||||
// Initiate network connections
|
||||
int64 nStart = GetTime();
|
||||
loop
|
||||
int64_t nStart = GetTime();
|
||||
while (true)
|
||||
{
|
||||
ProcessOneShot();
|
||||
|
||||
@@ -1281,7 +1290,7 @@ void ThreadOpenConnections()
|
||||
if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
|
||||
static bool done = false;
|
||||
if (!done) {
|
||||
printf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
|
||||
LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
|
||||
addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
|
||||
done = true;
|
||||
}
|
||||
@@ -1306,10 +1315,10 @@ void ThreadOpenConnections()
|
||||
}
|
||||
}
|
||||
|
||||
int64 nANow = GetAdjustedTime();
|
||||
int64_t nANow = GetAdjustedTime();
|
||||
|
||||
int nTries = 0;
|
||||
loop
|
||||
while (true)
|
||||
{
|
||||
// use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
|
||||
CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
|
||||
@@ -1449,13 +1458,15 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu
|
||||
|
||||
// for now, use a very simple selection metric: the node from which we received
|
||||
// most recently
|
||||
double static NodeSyncScore(const CNode *pnode) {
|
||||
return -pnode->nLastRecv;
|
||||
static int64_t NodeSyncScore(const CNode *pnode) {
|
||||
return pnode->nLastRecv;
|
||||
}
|
||||
|
||||
void static StartSync(const vector<CNode*> &vNodes) {
|
||||
CNode *pnodeNewSync = NULL;
|
||||
double dBestScore = 0;
|
||||
int64_t nBestScore = 0;
|
||||
|
||||
int nBestHeight = g_signals.GetHeight().get_value_or(0);
|
||||
|
||||
// Iterate over all nodes
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
@@ -1465,10 +1476,10 @@ void static StartSync(const vector<CNode*> &vNodes) {
|
||||
(pnode->nStartingHeight > (nBestHeight - 144)) &&
|
||||
(pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
|
||||
// if ok, compare node's score with the best so far
|
||||
double dScore = NodeSyncScore(pnode);
|
||||
if (pnodeNewSync == NULL || dScore > dBestScore) {
|
||||
int64_t nScore = NodeSyncScore(pnode);
|
||||
if (pnodeNewSync == NULL || nScore > nBestScore) {
|
||||
pnodeNewSync = pnode;
|
||||
dBestScore = dScore;
|
||||
nBestScore = nScore;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1504,6 +1515,9 @@ void ThreadMessageHandler()
|
||||
CNode* pnodeTrickle = NULL;
|
||||
if (!vNodesCopy.empty())
|
||||
pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
|
||||
|
||||
bool fSleep = true;
|
||||
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||
{
|
||||
if (pnode->fDisconnect)
|
||||
@@ -1513,8 +1527,18 @@ void ThreadMessageHandler()
|
||||
{
|
||||
TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
|
||||
if (lockRecv)
|
||||
{
|
||||
if (!g_signals.ProcessMessages(pnode))
|
||||
pnode->CloseSocketDisconnect();
|
||||
|
||||
if (pnode->nSendSize < SendBufferSize())
|
||||
{
|
||||
if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
|
||||
{
|
||||
fSleep = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
boost::this_thread::interruption_point();
|
||||
|
||||
@@ -1533,7 +1557,8 @@ void ThreadMessageHandler()
|
||||
pnode->Release();
|
||||
}
|
||||
|
||||
MilliSleep(20);
|
||||
if (fSleep)
|
||||
MilliSleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1548,24 +1573,20 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
||||
int nOne = 1;
|
||||
|
||||
// Create socket for listening for incoming connections
|
||||
#ifdef USE_IPV6
|
||||
struct sockaddr_storage sockaddr;
|
||||
#else
|
||||
struct sockaddr sockaddr;
|
||||
#endif
|
||||
socklen_t len = sizeof(sockaddr);
|
||||
if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
|
||||
{
|
||||
strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
|
||||
printf("%s\n", strError.c_str());
|
||||
strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString());
|
||||
LogPrintf("%s\n", strError);
|
||||
return false;
|
||||
}
|
||||
|
||||
SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (hListenSocket == INVALID_SOCKET)
|
||||
{
|
||||
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
|
||||
printf("%s\n", strError.c_str());
|
||||
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
|
||||
LogPrintf("%s\n", strError);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1588,12 +1609,11 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
||||
if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
|
||||
#endif
|
||||
{
|
||||
strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
|
||||
printf("%s\n", strError.c_str());
|
||||
strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %s)", NetworkErrorString(WSAGetLastError()));
|
||||
LogPrintf("%s\n", strError);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_IPV6
|
||||
// some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
|
||||
// and enable it by default or not. Try to enable it, if possible.
|
||||
if (addrBind.IsIPv6()) {
|
||||
@@ -1611,25 +1631,24 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
||||
setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
|
||||
{
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr == WSAEADDRINUSE)
|
||||
strError = strprintf(_("Unable to bind to %s on this computer. Myriadcoin is probably already running."), addrBind.ToString().c_str());
|
||||
strError = strprintf(_("Unable to bind to %s on this computer. Myriadcoin Core is probably already running."), addrBind.ToString());
|
||||
else
|
||||
strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
|
||||
printf("%s\n", strError.c_str());
|
||||
strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
|
||||
LogPrintf("%s\n", strError);
|
||||
return false;
|
||||
}
|
||||
printf("Bound to %s\n", addrBind.ToString().c_str());
|
||||
LogPrintf("Bound to %s\n", addrBind.ToString());
|
||||
|
||||
// Listen for incoming connections
|
||||
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
|
||||
{
|
||||
strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
|
||||
printf("%s\n", strError.c_str());
|
||||
strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
|
||||
LogPrintf("%s\n", strError);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1641,7 +1660,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
||||
return true;
|
||||
}
|
||||
|
||||
void static Discover()
|
||||
void static Discover(boost::thread_group& threadGroup)
|
||||
{
|
||||
if (!fDiscover)
|
||||
return;
|
||||
@@ -1676,17 +1695,15 @@ void static Discover()
|
||||
struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
|
||||
CNetAddr addr(s4->sin_addr);
|
||||
if (AddLocal(addr, LOCAL_IF))
|
||||
printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
|
||||
LogPrintf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString());
|
||||
}
|
||||
#ifdef USE_IPV6
|
||||
else if (ifa->ifa_addr->sa_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
|
||||
CNetAddr addr(s6->sin6_addr);
|
||||
if (AddLocal(addr, LOCAL_IF))
|
||||
printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
|
||||
LogPrintf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
freeifaddrs(myaddrs);
|
||||
}
|
||||
@@ -1694,7 +1711,7 @@ void static Discover()
|
||||
|
||||
// Don't use external IPv4 discovery, when -onlynet="IPv6"
|
||||
if (!IsLimited(NET_IPV4))
|
||||
boost::thread(boost::bind(&TraceThread<void (*)()>, "ext-ip", &ThreadGetMyExternalIP));
|
||||
threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "ext-ip", &ThreadGetMyExternalIP));
|
||||
}
|
||||
|
||||
void StartNode(boost::thread_group& threadGroup)
|
||||
@@ -1708,14 +1725,14 @@ void StartNode(boost::thread_group& threadGroup)
|
||||
if (pnodeLocalHost == NULL)
|
||||
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
|
||||
|
||||
Discover();
|
||||
Discover(threadGroup);
|
||||
|
||||
//
|
||||
// Start threads
|
||||
//
|
||||
|
||||
if (!GetBoolArg("-dnsseed", true))
|
||||
printf("DNS seeding disabled\n");
|
||||
LogPrintf("DNS seeding disabled\n");
|
||||
else
|
||||
threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
|
||||
|
||||
@@ -1742,7 +1759,7 @@ void StartNode(boost::thread_group& threadGroup)
|
||||
|
||||
bool StopNode()
|
||||
{
|
||||
printf("StopNode()\n");
|
||||
LogPrintf("StopNode()\n");
|
||||
MapPort(false);
|
||||
if (semOutbound)
|
||||
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
|
||||
@@ -1768,7 +1785,7 @@ public:
|
||||
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
|
||||
if (hListenSocket != INVALID_SOCKET)
|
||||
if (closesocket(hListenSocket) == SOCKET_ERROR)
|
||||
printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
|
||||
LogPrintf("closesocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
|
||||
|
||||
// clean up some globals (to help leak detection)
|
||||
BOOST_FOREACH(CNode *pnode, vNodes)
|
||||
@@ -1834,3 +1851,163 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt
|
||||
pnode->PushInventory(inv);
|
||||
}
|
||||
}
|
||||
|
||||
void CNode::RecordBytesRecv(uint64_t bytes)
|
||||
{
|
||||
LOCK(cs_totalBytesRecv);
|
||||
nTotalBytesRecv += bytes;
|
||||
}
|
||||
|
||||
void CNode::RecordBytesSent(uint64_t bytes)
|
||||
{
|
||||
LOCK(cs_totalBytesSent);
|
||||
nTotalBytesSent += bytes;
|
||||
}
|
||||
|
||||
uint64_t CNode::GetTotalBytesRecv()
|
||||
{
|
||||
LOCK(cs_totalBytesRecv);
|
||||
return nTotalBytesRecv;
|
||||
}
|
||||
|
||||
uint64_t CNode::GetTotalBytesSent()
|
||||
{
|
||||
LOCK(cs_totalBytesSent);
|
||||
return nTotalBytesSent;
|
||||
}
|
||||
|
||||
void CNode::Fuzz(int nChance)
|
||||
{
|
||||
if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
|
||||
if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
|
||||
|
||||
switch (GetRand(3))
|
||||
{
|
||||
case 0:
|
||||
// xor a random byte with a random value:
|
||||
if (!ssSend.empty()) {
|
||||
CDataStream::size_type pos = GetRand(ssSend.size());
|
||||
ssSend[pos] ^= (unsigned char)(GetRand(256));
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// delete a random byte:
|
||||
if (!ssSend.empty()) {
|
||||
CDataStream::size_type pos = GetRand(ssSend.size());
|
||||
ssSend.erase(ssSend.begin()+pos);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// insert a random byte at a random position
|
||||
{
|
||||
CDataStream::size_type pos = GetRand(ssSend.size());
|
||||
char ch = (char)GetRand(256);
|
||||
ssSend.insert(ssSend.begin()+pos, ch);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Chance of more than one change half the time:
|
||||
// (more changes exponentially less likely):
|
||||
Fuzz(2);
|
||||
}
|
||||
|
||||
//
|
||||
// CAddrDB
|
||||
//
|
||||
|
||||
CAddrDB::CAddrDB()
|
||||
{
|
||||
pathAddr = GetDataDir() / "peers.dat";
|
||||
}
|
||||
|
||||
bool CAddrDB::Write(const CAddrMan& addr)
|
||||
{
|
||||
// Generate random temporary filename
|
||||
unsigned short randv = 0;
|
||||
RAND_bytes((unsigned char *)&randv, sizeof(randv));
|
||||
std::string tmpfn = strprintf("peers.dat.%04x", randv);
|
||||
|
||||
// serialize addresses, checksum data up to that point, then append csum
|
||||
CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
|
||||
ssPeers << FLATDATA(Params().MessageStart());
|
||||
ssPeers << addr;
|
||||
uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
|
||||
ssPeers << hash;
|
||||
|
||||
// open temp output file, and associate with CAutoFile
|
||||
boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
|
||||
FILE *file = fopen(pathTmp.string().c_str(), "wb");
|
||||
CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION);
|
||||
if (!fileout)
|
||||
return error("%s : Failed to open file %s", __func__, pathTmp.string());
|
||||
|
||||
// Write and commit header, data
|
||||
try {
|
||||
fileout << ssPeers;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
return error("%s : Serialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
FileCommit(fileout);
|
||||
fileout.fclose();
|
||||
|
||||
// replace existing peers.dat, if any, with new peers.dat.XXXX
|
||||
if (!RenameOver(pathTmp, pathAddr))
|
||||
return error("%s : Rename-into-place failed", __func__);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAddrDB::Read(CAddrMan& addr)
|
||||
{
|
||||
// open input file, and associate with CAutoFile
|
||||
FILE *file = fopen(pathAddr.string().c_str(), "rb");
|
||||
CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION);
|
||||
if (!filein)
|
||||
return error("%s : Failed to open file %s", __func__, pathAddr.string());
|
||||
|
||||
// use file size to size memory buffer
|
||||
int fileSize = boost::filesystem::file_size(pathAddr);
|
||||
int dataSize = fileSize - sizeof(uint256);
|
||||
// Don't try to resize to a negative number if file is small
|
||||
if (dataSize < 0)
|
||||
dataSize = 0;
|
||||
vector<unsigned char> vchData;
|
||||
vchData.resize(dataSize);
|
||||
uint256 hashIn;
|
||||
|
||||
// read data and checksum from file
|
||||
try {
|
||||
filein.read((char *)&vchData[0], dataSize);
|
||||
filein >> hashIn;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
filein.fclose();
|
||||
|
||||
CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
|
||||
|
||||
// verify stored checksum matches input data
|
||||
uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
|
||||
if (hashIn != hashTmp)
|
||||
return error("%s : Checksum mismatch, data corrupted", __func__);
|
||||
|
||||
unsigned char pchMsgTmp[4];
|
||||
try {
|
||||
// de-serialize file header (network specific magic number) and ..
|
||||
ssPeers >> FLATDATA(pchMsgTmp);
|
||||
|
||||
// ... verify the network matches ours
|
||||
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
|
||||
return error("%s : Invalid network magic number", __func__);
|
||||
|
||||
// de-serialize address data into one CAddrMan object
|
||||
ssPeers >> addr;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user