[test] Test addr cache for multiple onion binds

This commit is contained in:
dergoegge 2022-05-09 17:25:16 +02:00
parent 3382905bef
commit 292828cd77

View File

@ -14,6 +14,8 @@ from test_framework.p2p import (
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
PORT_MIN,
PORT_RANGE,
)
# As defined in net_processing.
@ -42,6 +44,13 @@ class AddrReceiver(P2PInterface):
class AddrTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
# Start onion ports after p2p and rpc ports.
port = PORT_MIN + 2 * PORT_RANGE
self.onion_port1 = port
self.onion_port2 = port + 1
self.extra_args = [
[f"-bind=127.0.0.1:{self.onion_port1}=onion", f"-bind=127.0.0.1:{self.onion_port2}=onion"],
]
def run_test(self):
self.log.info('Fill peer AddrMan with a lot of records')
@ -55,35 +64,66 @@ class AddrTest(BitcoinTestFramework):
# only a fraction of all known addresses can be cached and returned.
assert(len(self.nodes[0].getnodeaddresses(0)) > int(MAX_ADDR_TO_SEND / (MAX_PCT_ADDR_TO_SEND / 100)))
responses = []
last_response_on_local_bind = None
last_response_on_onion_bind1 = None
last_response_on_onion_bind2 = None
self.log.info('Send many addr requests within short time to receive same response')
N = 5
cur_mock_time = int(time.time())
for i in range(N):
addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver())
addr_receiver.send_and_ping(msg_getaddr())
addr_receiver_local = self.nodes[0].add_p2p_connection(AddrReceiver())
addr_receiver_local.send_and_ping(msg_getaddr())
addr_receiver_onion1 = self.nodes[0].add_p2p_connection(AddrReceiver(), dstport=self.onion_port1)
addr_receiver_onion1.send_and_ping(msg_getaddr())
addr_receiver_onion2 = self.nodes[0].add_p2p_connection(AddrReceiver(), dstport=self.onion_port2)
addr_receiver_onion2.send_and_ping(msg_getaddr())
# Trigger response
cur_mock_time += 5 * 60
self.nodes[0].setmocktime(cur_mock_time)
addr_receiver.wait_until(addr_receiver.addr_received)
responses.append(addr_receiver.get_received_addrs())
for response in responses[1:]:
assert_equal(response, responses[0])
assert(len(response) == MAX_ADDR_TO_SEND)
addr_receiver_local.wait_until(addr_receiver_local.addr_received)
addr_receiver_onion1.wait_until(addr_receiver_onion1.addr_received)
addr_receiver_onion2.wait_until(addr_receiver_onion2.addr_received)
if i > 0:
# Responses from different binds should be unique
assert(last_response_on_local_bind != addr_receiver_onion1.get_received_addrs())
assert(last_response_on_local_bind != addr_receiver_onion2.get_received_addrs())
assert(last_response_on_onion_bind1 != addr_receiver_onion2.get_received_addrs())
# Responses on from the same bind should be the same
assert_equal(last_response_on_local_bind, addr_receiver_local.get_received_addrs())
assert_equal(last_response_on_onion_bind1, addr_receiver_onion1.get_received_addrs())
assert_equal(last_response_on_onion_bind2, addr_receiver_onion2.get_received_addrs())
last_response_on_local_bind = addr_receiver_local.get_received_addrs()
last_response_on_onion_bind1 = addr_receiver_onion1.get_received_addrs()
last_response_on_onion_bind2 = addr_receiver_onion2.get_received_addrs()
for response in [last_response_on_local_bind, last_response_on_onion_bind1, last_response_on_onion_bind2]:
assert_equal(len(response), MAX_ADDR_TO_SEND)
cur_mock_time += 3 * 24 * 60 * 60
self.nodes[0].setmocktime(cur_mock_time)
self.log.info('After time passed, see a new response to addr request')
last_addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver())
last_addr_receiver.send_and_ping(msg_getaddr())
addr_receiver_local = self.nodes[0].add_p2p_connection(AddrReceiver())
addr_receiver_local.send_and_ping(msg_getaddr())
addr_receiver_onion1 = self.nodes[0].add_p2p_connection(AddrReceiver(), dstport=self.onion_port1)
addr_receiver_onion1.send_and_ping(msg_getaddr())
addr_receiver_onion2 = self.nodes[0].add_p2p_connection(AddrReceiver(), dstport=self.onion_port2)
addr_receiver_onion2.send_and_ping(msg_getaddr())
# Trigger response
cur_mock_time += 5 * 60
self.nodes[0].setmocktime(cur_mock_time)
last_addr_receiver.wait_until(last_addr_receiver.addr_received)
# new response is different
assert(set(responses[0]) != set(last_addr_receiver.get_received_addrs()))
addr_receiver_local.wait_until(addr_receiver_local.addr_received)
addr_receiver_onion1.wait_until(addr_receiver_onion1.addr_received)
addr_receiver_onion2.wait_until(addr_receiver_onion2.addr_received)
# new response is different
assert(set(last_response_on_local_bind) != set(addr_receiver_local.get_received_addrs()))
assert(set(last_response_on_onion_bind1) != set(addr_receiver_onion1.get_received_addrs()))
assert(set(last_response_on_onion_bind2) != set(addr_receiver_onion2.get_received_addrs()))
if __name__ == '__main__':
AddrTest().main()