Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_p2p_getavaaddr.py
Show All 30 Lines | |||||
# The interval between avalanche statistics computation | # The interval between avalanche statistics computation | ||||
AVALANCHE_STATISTICS_INTERVAL = 10 * 60 | AVALANCHE_STATISTICS_INTERVAL = 10 * 60 | ||||
# The getavaaddr messages are sent every 2 to 5 minutes | # The getavaaddr messages are sent every 2 to 5 minutes | ||||
MAX_GETAVAADDR_DELAY = 5 * 60 | MAX_GETAVAADDR_DELAY = 5 * 60 | ||||
class AddrReceiver(P2PInterface): | class AddrReceiver(P2PInterface): | ||||
def __init__(self): | def __init__(self): | ||||
super().__init__() | super().__init__() | ||||
self.received_addrs = None | self.received_addrs = None | ||||
def get_received_addrs(self): | def get_received_addrs(self): | ||||
with p2p_lock: | with p2p_lock: | ||||
return self.received_addrs | return self.received_addrs | ||||
Show All 37 Lines | |||||
class AvaAddrTest(BitcoinTestFramework): | class AvaAddrTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.setup_clean_chain = False | self.setup_clean_chain = False | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
self.extra_args = [['-enableavalanche=1', | self.extra_args = [['-enableavalanche=1', | ||||
'-avacooldown=0', '-whitelist=noban@127.0.0.1']] | '-avacooldown=0', '-whitelist=noban@127.0.0.1']] | ||||
def check_all_peers_received_getavaaddr_once(self, avapeers): | |||||
def received_all_getavaaddr(avapeers): | |||||
with p2p_lock: | |||||
return all([p.last_message.get("getavaaddr") | |||||
for p in avapeers]) | |||||
self.wait_until(lambda: received_all_getavaaddr(avapeers)) | |||||
with p2p_lock: | |||||
assert all([p.message_count.get( | |||||
"getavaaddr", 0) == 1 for p in avapeers]) | |||||
def getavaaddr_interval_test(self): | def getavaaddr_interval_test(self): | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
# Init mock time | # Init mock time | ||||
mock_time = int(time.time()) | mock_time = int(time.time()) | ||||
node.setmocktime(mock_time) | node.setmocktime(mock_time) | ||||
master_privkey, proof = gen_proof(node) | master_privkey, proof = gen_proof(node) | ||||
master_pubkey = master_privkey.get_pubkey().get_bytes().hex() | master_pubkey = master_privkey.get_pubkey().get_bytes().hex() | ||||
proof_hex = proof.serialize().hex() | proof_hex = proof.serialize().hex() | ||||
# Add some avalanche peers to the node | # Add some avalanche peers to the node | ||||
for n in range(10): | for _ in range(10): | ||||
node.add_p2p_connection(AllYesAvaP2PInterface(master_privkey)) | node.add_p2p_connection(AllYesAvaP2PInterface(master_privkey)) | ||||
assert node.addavalanchenode( | assert node.addavalanchenode( | ||||
node.getpeerinfo()[-1]['id'], master_pubkey, proof_hex) | node.getpeerinfo()[-1]['id'], master_pubkey, proof_hex) | ||||
# Build some statistics to ensure some addresses will be returned | # Build some statistics to ensure some addresses will be returned | ||||
self.wait_until(lambda: all( | def all_peers_received_poll(): | ||||
[avanode.poll_received > 0 for avanode in node.p2ps])) | with p2p_lock: | ||||
return all([avanode.poll_received > | |||||
0 for avanode in node.p2ps]) | |||||
self.wait_until(all_peers_received_poll) | |||||
node.mockscheduler(AVALANCHE_STATISTICS_INTERVAL) | node.mockscheduler(AVALANCHE_STATISTICS_INTERVAL) | ||||
requester = node.add_p2p_connection(AddrReceiver()) | requester = node.add_p2p_connection(AddrReceiver()) | ||||
requester.send_message(msg_getavaaddr()) | requester.send_message(msg_getavaaddr()) | ||||
# Remember the time we sent the getavaaddr message | # Remember the time we sent the getavaaddr message | ||||
getavaddr_time = mock_time | getavaddr_time = mock_time | ||||
# Spamming more get getavaaddr has no effect | # Spamming more get getavaaddr has no effect | ||||
for i in range(10): | for _ in range(10): | ||||
with node.assert_debug_log(["Ignoring repeated getavaaddr from peer"]): | with node.assert_debug_log(["Ignoring repeated getavaaddr from peer"]): | ||||
requester.send_message(msg_getavaaddr()) | requester.send_message(msg_getavaaddr()) | ||||
# Move the time so we get an addr response | # Move the time so we get an addr response | ||||
mock_time += MAX_ADDR_SEND_DELAY | mock_time += MAX_ADDR_SEND_DELAY | ||||
node.setmocktime(mock_time) | node.setmocktime(mock_time) | ||||
requester.wait_until(requester.addr_received) | requester.wait_until(requester.addr_received) | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | def address_test(self, maxaddrtosend, num_proof, num_avanode): | ||||
assert_equal(len(avapeers), num_proof) | assert_equal(len(avapeers), num_proof) | ||||
for avapeer in avapeers: | for avapeer in avapeers: | ||||
assert_equal(len(avapeer['nodes']), num_avanode) | assert_equal(len(avapeer['nodes']), num_avanode) | ||||
# Force the availability score to diverge between the responding and the | # Force the availability score to diverge between the responding and the | ||||
# muted nodes. | # muted nodes. | ||||
def poll_all_for_block(): | def poll_all_for_block(): | ||||
node.generate(1) | node.generate(1) | ||||
with p2p_lock: | |||||
return all([avanode.poll_received > ( | return all([avanode.poll_received > ( | ||||
10 if avanode.is_responding else 0) for avanode in avanodes]) | 10 if avanode.is_responding else 0) for avanode in avanodes]) | ||||
self.wait_until(poll_all_for_block) | self.wait_until(poll_all_for_block) | ||||
# Move the scheduler time 10 minutes forward so that so that our peers | # Move the scheduler time 10 minutes forward so that so that our peers | ||||
# get an availability score computed. | # get an availability score computed. | ||||
node.mockscheduler(AVALANCHE_STATISTICS_INTERVAL) | node.mockscheduler(AVALANCHE_STATISTICS_INTERVAL) | ||||
requester = node.add_p2p_connection(AddrReceiver()) | requester = node.add_p2p_connection(AddrReceiver()) | ||||
requester.send_and_ping(msg_getavaaddr()) | requester.send_and_ping(msg_getavaaddr()) | ||||
Show All 35 Lines | def getavaaddr_outbound_test(self): | ||||
node.add_outbound_p2p_connection( | node.add_outbound_p2p_connection( | ||||
avapeer, | avapeer, | ||||
p2p_idx=i, | p2p_idx=i, | ||||
connection_type="avalanche", | connection_type="avalanche", | ||||
services=NODE_NETWORK | NODE_AVALANCHE, | services=NODE_NETWORK | NODE_AVALANCHE, | ||||
) | ) | ||||
avapeers.append(avapeer) | avapeers.append(avapeer) | ||||
self.wait_until( | self.check_all_peers_received_getavaaddr_once(avapeers) | ||||
lambda: all([p.last_message.get("getavaaddr") for p in avapeers])) | |||||
assert all([p.message_count.get( | |||||
"getavaaddr", 0) == 1 for p in avapeers]) | |||||
# Generate some block to poll for | # Generate some block to poll for | ||||
node.generate(1) | node.generate(1) | ||||
# Because none of the avalanche peers is responding, our node should | # Because none of the avalanche peers is responding, our node should | ||||
# fail out of option shortly and send a getavaaddr message to one of its | # fail out of option shortly and send a getavaaddr message to one of its | ||||
# outbound avalanche peers. | # outbound avalanche peers. | ||||
node.mockscheduler(MAX_GETAVAADDR_DELAY) | node.mockscheduler(MAX_GETAVAADDR_DELAY) | ||||
self.wait_until( | |||||
lambda: any([p.message_count.get("getavaaddr", 0) > 1 for p in avapeers])) | def any_peer_received_getavaaddr(): | ||||
with p2p_lock: | |||||
return any([p.message_count.get( | |||||
"getavaaddr", 0) > 1 for p in avapeers]) | |||||
self.wait_until(any_peer_received_getavaaddr) | |||||
def getavaaddr_manual_test(self): | def getavaaddr_manual_test(self): | ||||
self.log.info( | self.log.info( | ||||
"Check we send a getavaaddr message to our manually connected peers that support avalanche") | "Check we send a getavaaddr message to our manually connected peers that support avalanche") | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
# Get rid of previously connected nodes | # Get rid of previously connected nodes | ||||
node.disconnect_p2ps() | node.disconnect_p2ps() | ||||
Show All 18 Lines | def getavaaddr_manual_test(self): | ||||
ip_port = f"127.0.01:{p2p_port(MAX_NODES - p2p_idx)}" | ip_port = f"127.0.01:{p2p_port(MAX_NODES - p2p_idx)}" | ||||
node.addnode(node=ip_port, command="add") | node.addnode(node=ip_port, command="add") | ||||
self.wait_until(lambda: added_node_connected(ip_port)) | self.wait_until(lambda: added_node_connected(ip_port)) | ||||
assert_equal(node.getpeerinfo()[-1]['addr'], ip_port) | assert_equal(node.getpeerinfo()[-1]['addr'], ip_port) | ||||
assert_equal(node.getpeerinfo()[-1]['connection_type'], 'manual') | assert_equal(node.getpeerinfo()[-1]['connection_type'], 'manual') | ||||
self.wait_until(lambda: p.last_message.get("getavaaddr")) | p.wait_until(lambda: p.last_message.get("getavaaddr")) | ||||
# Generate some block to poll for | # Generate some block to poll for | ||||
node.generate(1) | node.generate(1) | ||||
# Because our avalanche peers is not responding, our node should fail | # Because our avalanche peer is not responding, our node should fail | ||||
# out of option shortly and send another getavaaddr message. | # out of option shortly and send another getavaaddr message. | ||||
node.mockscheduler(MAX_GETAVAADDR_DELAY) | node.mockscheduler(MAX_GETAVAADDR_DELAY) | ||||
self.wait_until(lambda: p.message_count.get("getavaaddr", 0) > 1) | p.wait_until(lambda: p.message_count.get("getavaaddr", 0) > 1) | ||||
def getavaaddr_noquorum(self): | def getavaaddr_noquorum(self): | ||||
self.log.info( | self.log.info( | ||||
"Check we send a getavaaddr message while our quorum is not established") | "Check we send a getavaaddr message while our quorum is not established") | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
self.restart_node(0, extra_args=self.extra_args[0] + [ | self.restart_node(0, extra_args=self.extra_args[0] + [ | ||||
'-avaminquorumstake=100000000', | '-avaminquorumstake=100000000', | ||||
Show All 11 Lines | def getavaaddr_noquorum(self): | ||||
connection_type="avalanche", | connection_type="avalanche", | ||||
services=NODE_NETWORK | NODE_AVALANCHE, | services=NODE_NETWORK | NODE_AVALANCHE, | ||||
) | ) | ||||
avapeers.append(avapeer) | avapeers.append(avapeer) | ||||
peerinfo = node.getpeerinfo()[-1] | peerinfo = node.getpeerinfo()[-1] | ||||
avapeer.set_addr(peerinfo["addr"]) | avapeer.set_addr(peerinfo["addr"]) | ||||
self.wait_until( | self.check_all_peers_received_getavaaddr_once(avapeers) | ||||
lambda: all([p.last_message.get("getavaaddr") for p in avapeers])) | |||||
assert all([p.message_count.get( | |||||
"getavaaddr", 0) == 1 for p in avapeers]) | |||||
def total_getavaaddr_msg(): | def total_getavaaddr_msg(): | ||||
with p2p_lock: | |||||
return sum([p.message_count.get("getavaaddr", 0) | return sum([p.message_count.get("getavaaddr", 0) | ||||
for p in avapeers]) | for p in avapeers]) | ||||
# Because we have not enough stake to start polling, we keep requesting | # Because we have not enough stake to start polling, we keep requesting | ||||
# more addresses | # more addresses | ||||
total_getavaaddr = total_getavaaddr_msg() | total_getavaaddr = total_getavaaddr_msg() | ||||
for i in range(5): | for i in range(5): | ||||
node.mockscheduler(MAX_GETAVAADDR_DELAY) | node.mockscheduler(MAX_GETAVAADDR_DELAY) | ||||
self.wait_until(lambda: total_getavaaddr_msg() > total_getavaaddr) | self.wait_until(lambda: total_getavaaddr_msg() > total_getavaaddr) | ||||
total_getavaaddr = total_getavaaddr_msg() | total_getavaaddr = total_getavaaddr_msg() | ||||
▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines |