Changeset View
Changeset View
Standalone View
Standalone View
src/seeder/bitcoin.cpp
// Copyright (c) 2017-2019 The Bitcoin developers | // Copyright (c) 2017-2020 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <seeder/bitcoin.h> | #include <seeder/bitcoin.h> | ||||
#include <hash.h> | #include <hash.h> | ||||
#include <netbase.h> | #include <netbase.h> | ||||
#include <seeder/db.h> | #include <seeder/db.h> | ||||
#include <seeder/messagewriter.h> | |||||
#include <serialize.h> | #include <serialize.h> | ||||
#include <uint256.h> | #include <uint256.h> | ||||
#include <algorithm> | #include <algorithm> | ||||
#define BITCOIN_SEED_NONCE 0x0539a019ca550825ULL | #define BITCOIN_SEED_NONCE 0x0539a019ca550825ULL | ||||
static const uint32_t allones(-1); | |||||
void CSeederNode::BeginMessage(const char *pszCommand) { | |||||
if (nHeaderStart != allones) { | |||||
AbortMessage(); | |||||
} | |||||
nHeaderStart = vSend.size(); | |||||
vSend << CMessageHeader(Params().NetMagic(), pszCommand, 0); | |||||
nMessageStart = vSend.size(); | |||||
// tfm::format(std::cout, "%s: SEND %s\n", ToString(you), | |||||
// pszCommand); | |||||
} | |||||
void CSeederNode::AbortMessage() { | |||||
if (nHeaderStart == allones) { | |||||
return; | |||||
} | |||||
vSend.resize(nHeaderStart); | |||||
nHeaderStart = allones; | |||||
nMessageStart = allones; | |||||
} | |||||
void CSeederNode::EndMessage() { | |||||
if (nHeaderStart == allones) { | |||||
return; | |||||
} | |||||
uint32_t nSize = vSend.size() - nMessageStart; | |||||
memcpy((char *)&vSend[nHeaderStart] + | |||||
offsetof(CMessageHeader, nMessageSize), | |||||
&nSize, sizeof(nSize)); | |||||
if (vSend.GetVersion() >= 209) { | |||||
uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); | |||||
unsigned int nChecksum = 0; | |||||
memcpy(&nChecksum, &hash, sizeof(nChecksum)); | |||||
assert(nMessageStart - nHeaderStart >= | |||||
offsetof(CMessageHeader, pchChecksum) + sizeof(nChecksum)); | |||||
memcpy((char *)&vSend[nHeaderStart] + | |||||
offsetof(CMessageHeader, pchChecksum), | |||||
&nChecksum, sizeof(nChecksum)); | |||||
} | |||||
nHeaderStart = allones; | |||||
nMessageStart = allones; | |||||
} | |||||
void CSeederNode::Send() { | void CSeederNode::Send() { | ||||
if (sock == INVALID_SOCKET) { | if (sock == INVALID_SOCKET) { | ||||
return; | return; | ||||
} | } | ||||
if (vSend.empty()) { | if (vSend.empty()) { | ||||
return; | return; | ||||
} | } | ||||
int nBytes = send(sock, &vSend[0], vSend.size(), 0); | int nBytes = send(sock, &vSend[0], vSend.size(), 0); | ||||
if (nBytes > 0) { | if (nBytes > 0) { | ||||
vSend.erase(vSend.begin(), vSend.begin() + nBytes); | vSend.erase(vSend.begin(), vSend.begin() + nBytes); | ||||
} else { | } else { | ||||
close(sock); | close(sock); | ||||
sock = INVALID_SOCKET; | sock = INVALID_SOCKET; | ||||
} | } | ||||
} | } | ||||
void CSeederNode::PushVersion() { | |||||
int64_t nTime = time(nullptr); | |||||
uint64_t nLocalNonce = BITCOIN_SEED_NONCE; | |||||
int64_t nLocalServices = 0; | |||||
CService myService; | |||||
CAddress me(myService, ServiceFlags(NODE_NETWORK)); | |||||
BeginMessage(NetMsgType::VERSION); | |||||
int nBestHeight = GetRequireHeight(); | |||||
std::string ver = "/bitcoin-cash-seeder:0.15/"; | |||||
vSend << PROTOCOL_VERSION << nLocalServices << nTime << you << me | |||||
<< nLocalNonce << ver << nBestHeight; | |||||
EndMessage(); | |||||
} | |||||
PeerMessagingState CSeederNode::ProcessMessage(std::string strCommand, | PeerMessagingState CSeederNode::ProcessMessage(std::string strCommand, | ||||
CDataStream &recv) { | CDataStream &recv) { | ||||
// tfm::format(std::cout, "%s: RECV %s\n", ToString(you), | // tfm::format(std::cout, "%s: RECV %s\n", ToString(you), | ||||
// strCommand); | // strCommand); | ||||
if (strCommand == NetMsgType::VERSION) { | if (strCommand == NetMsgType::VERSION) { | ||||
int64_t nTime; | int64_t nTime; | ||||
CAddress addrMe; | CAddress addrMe; | ||||
CAddress addrFrom; | CAddress addrFrom; | ||||
uint64_t nNonce = 1; | uint64_t nNonce = 1; | ||||
uint64_t nServiceInt; | uint64_t nServiceInt; | ||||
recv >> nVersion >> nServiceInt >> nTime >> addrMe; | recv >> nVersion >> nServiceInt >> nTime >> addrMe; | ||||
you.nServices = ServiceFlags(nServiceInt); | you.nServices = ServiceFlags(nServiceInt); | ||||
recv >> addrFrom >> nNonce; | recv >> addrFrom >> nNonce; | ||||
recv >> strSubVer; | recv >> strSubVer; | ||||
recv >> nStartingHeight; | recv >> nStartingHeight; | ||||
BeginMessage(NetMsgType::VERACK); | |||||
EndMessage(); | |||||
vSend.SetVersion(std::min(nVersion, PROTOCOL_VERSION)); | vSend.SetVersion(std::min(nVersion, PROTOCOL_VERSION)); | ||||
MessageWriter::WriteMessage(vSend, NetMsgType::VERACK); | |||||
return PeerMessagingState::AwaitingMessages; | return PeerMessagingState::AwaitingMessages; | ||||
} | } | ||||
if (strCommand == NetMsgType::VERACK) { | if (strCommand == NetMsgType::VERACK) { | ||||
vRecv.SetVersion(std::min(nVersion, PROTOCOL_VERSION)); | vRecv.SetVersion(std::min(nVersion, PROTOCOL_VERSION)); | ||||
// tfm::format(std::cout, "\n%s: version %i\n", ToString(you), | // tfm::format(std::cout, "\n%s: version %i\n", ToString(you), | ||||
// nVersion); | // nVersion); | ||||
if (vAddr) { | if (vAddr) { | ||||
BeginMessage(NetMsgType::GETADDR); | MessageWriter::WriteMessage(vSend, NetMsgType::GETADDR); | ||||
EndMessage(); | |||||
doneAfter = time(nullptr) + GetTimeout(); | doneAfter = time(nullptr) + GetTimeout(); | ||||
} else { | } else { | ||||
doneAfter = time(nullptr) + 1; | doneAfter = time(nullptr) + 1; | ||||
} | } | ||||
return PeerMessagingState::AwaitingMessages; | return PeerMessagingState::AwaitingMessages; | ||||
} | } | ||||
if (strCommand == NetMsgType::ADDR && vAddr) { | if (strCommand == NetMsgType::ADDR && vAddr) { | ||||
▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | bool CSeederNode::Run() { | ||||
if (!connected) { | if (!connected) { | ||||
// tfm::format(std::cout, "Cannot connect to %s\n", | // tfm::format(std::cout, "Cannot connect to %s\n", | ||||
// ToString(you)); | // ToString(you)); | ||||
CloseSocket(sock); | CloseSocket(sock); | ||||
return false; | return false; | ||||
} | } | ||||
PushVersion(); | // Push version; | ||||
uint64_t nLocalServices = 0; | |||||
uint64_t nLocalNonce = BITCOIN_SEED_NONCE; | |||||
CService myService; | |||||
CAddress me(myService, ServiceFlags(NODE_NETWORK)); | |||||
std::string ver = "/bitcoin-cash-seeder:0.15/"; | |||||
MessageWriter::WriteMessage(vSend, NetMsgType::VERSION, PROTOCOL_VERSION, | |||||
nLocalServices, time(nullptr), you, me, | |||||
nLocalNonce, ver, GetRequireHeight()); | |||||
Send(); | Send(); | ||||
bool res = true; | bool res = true; | ||||
int64_t now; | int64_t now; | ||||
while (now = time(nullptr), ban == 0 && | while (now = time(nullptr), ban == 0 && | ||||
(doneAfter == 0 || doneAfter > now) && | (doneAfter == 0 || doneAfter > now) && | ||||
sock != INVALID_SOCKET) { | sock != INVALID_SOCKET) { | ||||
char pchBuf[0x10000]; | char pchBuf[0x10000]; | ||||
▲ Show 20 Lines • Show All 48 Lines • Show Last 20 Lines |