diff --git a/src/seeder/bitcoin.h b/src/seeder/bitcoin.h --- a/src/seeder/bitcoin.h +++ b/src/seeder/bitcoin.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_SEEDER_BITCOIN_H #define BITCOIN_SEEDER_BITCOIN_H +#include #include #include diff --git a/src/seeder/bitcoin.cpp b/src/seeder/bitcoin.cpp --- a/src/seeder/bitcoin.cpp +++ b/src/seeder/bitcoin.cpp @@ -172,6 +172,21 @@ return false; } + // Node has chainparams and should not be filtered out + if (strCommand == NetMsgType::HEADERS) { + // fprintf(stderr, "%s: not banned\n", ToString(you).c_str()); + GotVersion(); + return false; + } + + // Chain params not found, so we ban the node + if (strCommand == NetMsgType::NOTFOUND) { + // fprintf(stderr, "%s: chainparams not found, banned\n", + // ToString(you).c_str()); + ban = 100000; + return false; + } + return false; } diff --git a/src/seeder/test/seeder_tests.cpp b/src/seeder/test/seeder_tests.cpp --- a/src/seeder/test/seeder_tests.cpp +++ b/src/seeder/test/seeder_tests.cpp @@ -4,6 +4,7 @@ #define BOOST_TEST_MODULE Bitcoin Seeder Test Suite +#include #include #include #include @@ -38,6 +39,9 @@ const std::string VERACK_COMMAND = "verack"; const std::string VERSION_COMMAND = "version"; const std::string ADDR_COMMAND = "addr"; +const std::string NOTFOUND_COMMAND = "notfound"; +const std::string SENDHEADERS_COMMAND = "sendheaders"; +const std::string HEADERS_COMMAND = "headers"; const std::string SEED = "seed.bitcoinabc.org"; // Builds dummy DNS query message @@ -93,10 +97,16 @@ } else if (strCommand == VERACK_COMMAND) { CreateVerackMessage(); return CSeederNode::ProcessMessage(VERACK_COMMAND, message); - } else { - // strCommand == ADDR_COMMAND + } else if (strCommand == ADDR_COMMAND) { CreateAddrMessage(); return CSeederNode::ProcessMessage(ADDR_COMMAND, message); + } else if (strCommand == NOTFOUND_COMMAND) { + CreateAddrMessage(); + return CSeederNode::ProcessMessage(NOTFOUND_COMMAND, message); + } else { + // strCommand == HEADERS_COMMAND + CreateHeadersMessage(); + return CSeederNode::ProcessMessage(HEADERS_COMMAND, message); } } @@ -157,6 +167,48 @@ memcpy(header.pchChecksum, &hash, header.CHECKSUM_SIZE); } + void CreateNotFoundMessage() { + CDataStream payload(SER_NETWORK, 0); + payload.SetVersion(nVersion); + payload << static_cast(1); + payload << static_cast(MSG_BLOCK) + << ChainParamsConstants::MAINNET_DEFAULT_ASSUME_VALID; + message.erase(message.begin(), message.end()); + message += payload; + + header.nMessageSize = payload.size(); + uint256 hash = Hash(payload.begin(), payload.end()); + memcpy(header.pchChecksum, &hash, header.CHECKSUM_SIZE); + } + + void CreateHeadersMessage() { + CDataStream payload(SER_NETWORK, 0); + payload.SetVersion(nVersion); + payload << static_cast(1); + uint256 garbageHash = Hash(payload.begin(), payload.end()); + // The actual header can be garbage data, Seeder only cares that it got + // a specific type of message. + payload << nVersion; + // prev_block + payload << garbageHash; + // merkle_root + payload << garbageHash; + // timestamp + payload << static_cast(0); + // bits + payload << static_cast(0); + // nonce + payload << static_cast(0); + // txn_count + payload << static_cast(0); + message.erase(message.begin(), message.end()); + message += payload; + + header.nMessageSize = payload.size(); + uint256 hash = Hash(payload.begin(), payload.end()); + memcpy(header.pchChecksum, &hash, header.CHECKSUM_SIZE); + } + std::vector vAddr; int32_t nVersion; CDataStream message; @@ -249,6 +301,14 @@ testNode.setVersion(106); ret = testNode.TestProcessMessage(VERSION_COMMAND); BOOST_CHECK_EQUAL(ret, false); + + testNode.setVersion(209); + ret = testNode.TestProcessMessage(NOTFOUND_COMMAND); + BOOST_CHECK_EQUAL(ret, false); + BOOST_CHECK_EQUAL(100000, testNode.GetBan()); + + ret = testNode.TestProcessMessage(HEADERS_COMMAND); + BOOST_CHECK_EQUAL(ret, false); } BOOST_AUTO_TEST_SUITE_END()