Merge #19697: Improvements on ADDR caching

0d04784af1 Refactor the functional test (Gleb Naumenko)
83ad65f31b Address nits in ADDR caching (Gleb Naumenko)
81b00f8780 Add indexing ADDR cache by local socket addr (Gleb Naumenko)
42ec558542 Justify the choice of ADDR cache lifetime (Gleb Naumenko)

Pull request description:

  This is a follow-up on #18991 which does 3 things:
  - improves privacy of a node listening to multiple addresses via adding cache index by local socket addr (suggested [here](https://github.com/bitcoin/bitcoin/pull/18991#issuecomment-668219345))
  - documents on the choice of 24h cache lifetime
  - addresses nits from #18991

ACKs for top commit:
  jnewbery:
    utACK 0d04784af1
  vasild:
    ACK 0d04784
  jonatack:
    Code review ACK 0d04784

Tree-SHA512: bb65a34dd1ce2811186d3e4469bc33e8399cebaaa494ce13041c7cff23275870e4176a719f7a72f8d779c49f8b2344bf4fa1aeb3ea4e2626d5ae76514f00a750
This commit is contained in:
Wladimir J. van der Laan
2020-09-21 18:46:52 +02:00
4 changed files with 64 additions and 46 deletions

View File

@@ -5,13 +5,8 @@
"""Test addr response caching"""
import time
from test_framework.messages import (
CAddress,
NODE_NETWORK,
NODE_WITNESS,
msg_addr,
msg_getaddr,
)
from test_framework.messages import msg_getaddr
from test_framework.p2p import (
P2PInterface,
p2p_lock
@@ -21,21 +16,9 @@ from test_framework.util import (
assert_equal,
)
# As defined in net_processing.
MAX_ADDR_TO_SEND = 1000
def gen_addrs(n):
addrs = []
for i in range(n):
addr = CAddress()
addr.time = int(time.time())
addr.nServices = NODE_NETWORK | NODE_WITNESS
# Use first octets to occupy different AddrMan buckets
first_octet = i >> 8
second_octet = i % 256
addr.ip = "{}.{}.1.1".format(first_octet, second_octet)
addr.port = 8333
addrs.append(addr)
return addrs
MAX_PCT_ADDR_TO_SEND = 23
class AddrReceiver(P2PInterface):
@@ -62,18 +45,16 @@ class AddrTest(BitcoinTestFramework):
self.num_nodes = 1
def run_test(self):
self.log.info('Create connection that sends and requests addr messages')
addr_source = self.nodes[0].add_p2p_connection(P2PInterface())
msg_send_addrs = msg_addr()
self.log.info('Fill peer AddrMan with a lot of records')
# Since these addrs are sent from the same source, not all of them will be stored,
# because we allocate a limited number of AddrMan buckets per addr source.
total_addrs = 10000
addrs = gen_addrs(total_addrs)
for i in range(int(total_addrs/MAX_ADDR_TO_SEND)):
msg_send_addrs.addrs = addrs[i * MAX_ADDR_TO_SEND:(i + 1) * MAX_ADDR_TO_SEND]
addr_source.send_and_ping(msg_send_addrs)
for i in range(10000):
first_octet = i >> 8
second_octet = i % 256
a = "{}.{}.1.1".format(first_octet, second_octet)
self.nodes[0].addpeeraddress(a, 8333)
# Need to make sure we hit MAX_ADDR_TO_SEND records in the addr response later because
# 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 = []
self.log.info('Send many addr requests within short time to receive same response')
@@ -89,7 +70,7 @@ class AddrTest(BitcoinTestFramework):
responses.append(addr_receiver.get_received_addrs())
for response in responses[1:]:
assert_equal(response, responses[0])
assert(len(response) < MAX_ADDR_TO_SEND)
assert(len(response) == MAX_ADDR_TO_SEND)
cur_mock_time += 3 * 24 * 60 * 60
self.nodes[0].setmocktime(cur_mock_time)