aboutsummaryrefslogtreecommitdiff
path: root/src/test/addrman_tests.cpp
diff options
context:
space:
mode:
authorJohn Newbery <john@johnnewbery.com>2021-08-17 13:44:39 +0100
committerJohn Newbery <john@johnnewbery.com>2021-08-17 13:44:54 +0100
commitaaa6ad54554abd1666cb60285ed6f890698ca620 (patch)
tree9a4e94f6dcb1c5c1d472891257fb3df0636fcd6d /src/test/addrman_tests.cpp
parentfdd80b0a53b4af0b29cb6e03118e2456d053a757 (diff)
[MOVEONLY] [tests] Move addrman ser/deser tests to addrman_tests.cpp
Addrman serialization/deserialization tests are currently in net_tests.cpp. Move them to addrman_tests.cpp with the rest of the addrman tests. Reviewer hint: review using `git diff --color-moved=dimmed-zebra`
Diffstat (limited to 'src/test/addrman_tests.cpp')
-rw-r--r--src/test/addrman_tests.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index cead0489b0..c52baa4e8b 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -1,7 +1,10 @@
// Copyright (c) 2012-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <addrdb.h>
#include <addrman.h>
+#include <chainparams.h>
#include <test/data/asmap.raw.h>
#include <test/util/setup_common.h>
#include <util/asmap.h>
@@ -15,6 +18,63 @@
#include <optional>
#include <string>
+using namespace std::literals;
+
+class CAddrManSerializationMock : public CAddrMan
+{
+public:
+ virtual void Serialize(CDataStream& s) const = 0;
+
+ CAddrManSerializationMock()
+ : CAddrMan(/* deterministic */ true, /* consistency_check_ratio */ 100)
+ {}
+};
+
+class CAddrManUncorrupted : public CAddrManSerializationMock
+{
+public:
+ void Serialize(CDataStream& s) const override
+ {
+ CAddrMan::Serialize(s);
+ }
+};
+
+class CAddrManCorrupted : public CAddrManSerializationMock
+{
+public:
+ void Serialize(CDataStream& s) const override
+ {
+ // Produces corrupt output that claims addrman has 20 addrs when it only has one addr.
+ unsigned char nVersion = 1;
+ s << nVersion;
+ s << ((unsigned char)32);
+ s << nKey;
+ s << 10; // nNew
+ s << 10; // nTried
+
+ int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
+ s << nUBuckets;
+
+ CService serv;
+ BOOST_CHECK(Lookup("252.1.1.1", serv, 7777, false));
+ CAddress addr = CAddress(serv, NODE_NONE);
+ CNetAddr resolved;
+ BOOST_CHECK(LookupHost("252.2.2.2", resolved, false));
+ CAddrInfo info = CAddrInfo(addr, resolved);
+ s << info;
+ }
+};
+
+static CDataStream AddrmanToStream(const CAddrManSerializationMock& _addrman)
+{
+ CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
+ ssPeersIn << Params().MessageStart();
+ ssPeersIn << _addrman;
+ std::string str = ssPeersIn.str();
+ std::vector<unsigned char> vchData(str.begin(), str.end());
+ return CDataStream(vchData, SER_DISK, CLIENT_VERSION);
+}
+
class CAddrManTest : public CAddrMan
{
private:
@@ -958,5 +1018,79 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks)
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
}
+BOOST_AUTO_TEST_CASE(caddrdb_read)
+{
+ CAddrManUncorrupted addrmanUncorrupted;
+
+ CService addr1, addr2, addr3;
+ BOOST_CHECK(Lookup("250.7.1.1", addr1, 8333, false));
+ BOOST_CHECK(Lookup("250.7.2.2", addr2, 9999, false));
+ BOOST_CHECK(Lookup("250.7.3.3", addr3, 9999, false));
+ BOOST_CHECK(Lookup("250.7.3.3"s, addr3, 9999, false));
+ BOOST_CHECK(!Lookup("250.7.3.3\0example.com"s, addr3, 9999, false));
+
+ // Add three addresses to new table.
+ CService source;
+ BOOST_CHECK(Lookup("252.5.1.1", source, 8333, false));
+ std::vector<CAddress> addresses{CAddress(addr1, NODE_NONE), CAddress(addr2, NODE_NONE), CAddress(addr3, NODE_NONE)};
+ BOOST_CHECK(addrmanUncorrupted.Add(addresses, source));
+ BOOST_CHECK(addrmanUncorrupted.size() == 3);
+
+ // Test that the de-serialization does not throw an exception.
+ CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
+ bool exceptionThrown = false;
+ CAddrMan addrman1(/* deterministic */ false, /* consistency_check_ratio */ 100);
+
+ BOOST_CHECK(addrman1.size() == 0);
+ try {
+ unsigned char pchMsgTmp[4];
+ ssPeers1 >> pchMsgTmp;
+ ssPeers1 >> addrman1;
+ } catch (const std::exception&) {
+ exceptionThrown = true;
+ }
+
+ BOOST_CHECK(addrman1.size() == 3);
+ BOOST_CHECK(exceptionThrown == false);
+
+ // Test that CAddrDB::Read creates an addrman with the correct number of addrs.
+ CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted);
+
+ CAddrMan addrman2(/* deterministic */ false, /* consistency_check_ratio */ 100);
+ BOOST_CHECK(addrman2.size() == 0);
+ BOOST_CHECK(CAddrDB::Read(addrman2, ssPeers2));
+ BOOST_CHECK(addrman2.size() == 3);
+}
+
+
+BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
+{
+ CAddrManCorrupted addrmanCorrupted;
+
+ // Test that the de-serialization of corrupted addrman throws an exception.
+ CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted);
+ bool exceptionThrown = false;
+ CAddrMan addrman1(/* deterministic */ false, /* consistency_check_ratio */ 100);
+ BOOST_CHECK(addrman1.size() == 0);
+ try {
+ unsigned char pchMsgTmp[4];
+ ssPeers1 >> pchMsgTmp;
+ ssPeers1 >> addrman1;
+ } catch (const std::exception&) {
+ exceptionThrown = true;
+ }
+ // Even through de-serialization failed addrman is not left in a clean state.
+ BOOST_CHECK(addrman1.size() == 1);
+ BOOST_CHECK(exceptionThrown);
+
+ // Test that CAddrDB::Read leaves addrman in a clean state if de-serialization fails.
+ CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted);
+
+ CAddrMan addrman2(/* deterministic */ false, /* consistency_check_ratio */ 100);
+ BOOST_CHECK(addrman2.size() == 0);
+ BOOST_CHECK(!CAddrDB::Read(addrman2, ssPeers2));
+ BOOST_CHECK(addrman2.size() == 0);
+}
+
BOOST_AUTO_TEST_SUITE_END()