aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2020-04-10 10:10:23 -0400
committerMarcoFalke <falke.marco@gmail.com>2020-04-10 10:12:46 -0400
commit29893ec8751f51f281f694453bd439f92ccf3ab2 (patch)
tree5c6355258e8699c81156ccc82fdfc2d924852b11
parent2b9a4a13324ac3f0adf712d01fb8f2ba914cdc8f (diff)
parentfa1da3d4bfc0511a89f5b19d5a4d89e55ff7ccde (diff)
downloadbitcoin-29893ec8751f51f281f694453bd439f92ccf3ab2.tar.xz
Merge #18454: net: Make addr relay mockable, add test
fa1da3d4bfc0511a89f5b19d5a4d89e55ff7ccde test: Add basic addr relay test (MarcoFalke) fa1793c1c44a3f75a09f9c636467b8274c541bdd net: Pass connman const when relaying address (MarcoFalke) fa47a0b003f53708b6d5df1ed4e7f8a7c68aa3ac net: Make addr relay mockable (MarcoFalke) Pull request description: As usual: * Switch to std::chrono time to be type-safe and mockable * Add basic test that relies on mocktime to add code coverage ACKs for top commit: naumenkogs: utACK fa1da3d promag: ACK fa1da3d4bfc0511a89f5b19d5a4d89e55ff7ccde (fabe56e44b6f683e24e37246a7a8851190947cb3 before https://github.com/bitcoin/bitcoin/pull/18454#issuecomment-607866453), fa5bf23d527a450e72c2bf13d013e5393b664ca3 was dropped since last review. Tree-SHA512: 0552bf8fcbe375baa3cab62acd8c23b2994efa47daff818ad1116d0ffaa0b9e520dc1bca2bbc68369b25584e85e54861fe6fd0968de4f503b95439c099df9bd7
-rw-r--r--src/net.h4
-rw-r--r--src/net_processing.cpp24
-rwxr-xr-xtest/functional/p2p_addr_relay.py71
-rwxr-xr-xtest/functional/test_runner.py1
4 files changed, 86 insertions, 14 deletions
diff --git a/src/net.h b/src/net.h
index a72af83eef..0dbd5e0549 100644
--- a/src/net.h
+++ b/src/net.h
@@ -797,8 +797,8 @@ public:
std::vector<CAddress> vAddrToSend;
const std::unique_ptr<CRollingBloomFilter> m_addr_known;
bool fGetAddr{false};
- int64_t nNextAddrSend GUARDED_BY(cs_sendProcessing){0};
- int64_t nNextLocalAddrSend GUARDED_BY(cs_sendProcessing){0};
+ std::chrono::microseconds m_next_addr_send GUARDED_BY(cs_sendProcessing){0};
+ std::chrono::microseconds m_next_local_addr_send GUARDED_BY(cs_sendProcessing){0};
bool IsAddrRelayPeer() const { return m_addr_known != nullptr; }
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index f63d048aac..d3089c4176 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -97,10 +97,10 @@ void EraseOrphansFor(NodeId peer);
/** Increase a node's misbehavior score. */
void Misbehaving(NodeId nodeid, int howmuch, const std::string& message="") EXCLUSIVE_LOCKS_REQUIRED(cs_main);
-/** Average delay between local address broadcasts in seconds. */
-static constexpr unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 60 * 60;
-/** Average delay between peer address broadcasts in seconds. */
-static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30;
+/** Average delay between local address broadcasts */
+static constexpr std::chrono::hours AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL{24};
+/** Average delay between peer address broadcasts */
+static constexpr std::chrono::seconds AVG_ADDRESS_BROADCAST_INTERVAL{30};
/** Average delay between trickled inventory transmissions in seconds.
* Blocks and whitelisted receivers bypass this, outbound peers get half this delay. */
static const unsigned int INVENTORY_BROADCAST_INTERVAL = 5;
@@ -1365,7 +1365,7 @@ void RelayTransaction(const uint256& txid, const CConnman& connman)
});
}
-static void RelayAddress(const CAddress& addr, bool fReachable, CConnman* connman)
+static void RelayAddress(const CAddress& addr, bool fReachable, const CConnman& connman)
{
unsigned int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
@@ -1373,7 +1373,7 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman* connma
// Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the m_addr_knowns of the chosen nodes prevent repeats
uint64_t hashAddr = addr.GetHash();
- const CSipHasher hasher = connman->GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
+ const CSipHasher hasher = connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24 * 60 * 60));
FastRandomContext insecure_rand;
std::array<std::pair<uint64_t, CNode*>,2> best{{{0, nullptr}, {0, nullptr}}};
@@ -1398,7 +1398,7 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman* connma
}
};
- connman->ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
+ connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
}
void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, const CInv& inv, CConnman* connman)
@@ -2192,7 +2192,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
{
// Relay to a limited number of other nodes
- RelayAddress(addr, fReachable, connman);
+ RelayAddress(addr, fReachable, *connman);
}
// Do not store addresses outside our network
if (fReachable)
@@ -3583,16 +3583,16 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
int64_t nNow = GetTimeMicros();
auto current_time = GetTime<std::chrono::microseconds>();
- if (pto->IsAddrRelayPeer() && !::ChainstateActive().IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
+ if (pto->IsAddrRelayPeer() && !::ChainstateActive().IsInitialBlockDownload() && pto->m_next_local_addr_send < current_time) {
AdvertiseLocal(pto);
- pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
+ pto->m_next_local_addr_send = PoissonNextSend(current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
}
//
// Message: addr
//
- if (pto->IsAddrRelayPeer() && pto->nNextAddrSend < nNow) {
- pto->nNextAddrSend = PoissonNextSend(nNow, AVG_ADDRESS_BROADCAST_INTERVAL);
+ if (pto->IsAddrRelayPeer() && pto->m_next_addr_send < current_time) {
+ pto->m_next_addr_send = PoissonNextSend(current_time, AVG_ADDRESS_BROADCAST_INTERVAL);
std::vector<CAddress> vAddr;
vAddr.reserve(pto->vAddrToSend.size());
assert(pto->m_addr_known);
diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py
new file mode 100755
index 0000000000..6046237101
--- /dev/null
+++ b/test/functional/p2p_addr_relay.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+# Copyright (c) 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.
+"""
+Test addr relay
+"""
+
+from test_framework.messages import (
+ CAddress,
+ NODE_NETWORK,
+ NODE_WITNESS,
+ msg_addr,
+)
+from test_framework.mininode import (
+ P2PInterface,
+)
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (
+ assert_equal,
+)
+import time
+
+ADDRS = []
+for i in range(10):
+ addr = CAddress()
+ addr.time = int(time.time()) + i
+ addr.nServices = NODE_NETWORK | NODE_WITNESS
+ addr.ip = "123.123.123.{}".format(i % 256)
+ addr.port = 8333 + i
+ ADDRS.append(addr)
+
+
+class AddrReceiver(P2PInterface):
+ def on_addr(self, message):
+ for addr in message.addrs:
+ assert_equal(addr.nServices, 9)
+ assert addr.ip.startswith('123.123.123.')
+ assert (8333 <= addr.port < 8343)
+
+
+class AddrTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.setup_clean_chain = False
+ self.num_nodes = 1
+
+ def run_test(self):
+ self.log.info('Create connection that sends addr messages')
+ addr_source = self.nodes[0].add_p2p_connection(P2PInterface())
+ msg = msg_addr()
+
+ self.log.info('Send too large addr message')
+ msg.addrs = ADDRS * 101
+ with self.nodes[0].assert_debug_log(['message addr size() = 1010']):
+ addr_source.send_and_ping(msg)
+
+ self.log.info('Check that addr message content is relayed and added to addrman')
+ addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver())
+ msg.addrs = ADDRS
+ with self.nodes[0].assert_debug_log([
+ 'Added 10 addresses from 127.0.0.1: 0 tried',
+ 'received: addr (301 bytes) peer=0',
+ 'sending addr (301 bytes) peer=1',
+ ]):
+ addr_source.send_and_ping(msg)
+ self.nodes[0].setmocktime(int(time.time()) + 30 * 60)
+ addr_receiver.sync_with_ping()
+
+
+if __name__ == '__main__':
+ AddrTest().main()
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 2f307750a9..faa2dee4ed 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -144,6 +144,7 @@ BASE_SCRIPTS = [
'rpc_blockchain.py',
'rpc_deprecated.py',
'wallet_disable.py',
+ 'p2p_addr_relay.py',
'rpc_net.py',
'wallet_keypool.py',
'p2p_mempool.py',