Changeset View
Changeset View
Standalone View
Standalone View
test/functional/p2p_eviction.py
Show All 9 Lines | |||||
We cannot currently test the parts of the eviction logic that are based on | We cannot currently test the parts of the eviction logic that are based on | ||||
address/netgroup since in the current framework, all peers are connecting from | address/netgroup since in the current framework, all peers are connecting from | ||||
the same local address. See Issue #14210 for more info. | the same local address. See Issue #14210 for more info. | ||||
Therefore, this test is limited to the remaining protection criteria. | Therefore, this test is limited to the remaining protection criteria. | ||||
""" | """ | ||||
import time | import time | ||||
from test_framework.avatools import create_coinbase_stakes | |||||
from test_framework.blocktools import create_block, create_coinbase | from test_framework.blocktools import create_block, create_coinbase | ||||
from test_framework.messages import CTransaction, FromHex, msg_pong, msg_tx | from test_framework.key import ECKey | ||||
from test_framework.messages import ( | |||||
AvalancheProof, | |||||
CTransaction, | |||||
FromHex, | |||||
msg_avaproof, | |||||
msg_pong, | |||||
msg_tx, | |||||
) | |||||
from test_framework.p2p import P2PDataStore, P2PInterface | from test_framework.p2p import P2PDataStore, P2PInterface | ||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.util import assert_equal, wait_until | from test_framework.util import assert_equal, wait_until | ||||
class SlowP2PDataStore(P2PDataStore): | class SlowP2PDataStore(P2PDataStore): | ||||
def on_ping(self, message): | def on_ping(self, message): | ||||
time.sleep(0.1) | time.sleep(0.1) | ||||
self.send_message(msg_pong(message.nonce)) | self.send_message(msg_pong(message.nonce)) | ||||
class SlowP2PInterface(P2PInterface): | class SlowP2PInterface(P2PInterface): | ||||
def on_ping(self, message): | def on_ping(self, message): | ||||
time.sleep(0.1) | time.sleep(0.1) | ||||
self.send_message(msg_pong(message.nonce)) | self.send_message(msg_pong(message.nonce)) | ||||
class P2PEvict(BitcoinTestFramework): | class P2PEvict(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.setup_clean_chain = True | self.setup_clean_chain = True | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
# The choice of maxconnections=32 results in a maximum of 21 inbound connections | # The choice of maxconnections=36 results in a maximum of 25 inbound connections | ||||
# (32 - 10 outbound - 1 feeler). 20 inbound peers are protected from eviction: | # (36 - 10 outbound - 1 feeler). 20 inbound peers are protected from eviction: | ||||
# 4 by netgroup, 4 that sent us blocks, 4 that sent us transactions and | # 4 by netgroup, 4 that sent us blocks, 4 that sent us proofs, 4 that | ||||
# 8 via lowest ping time | # sent us transactions and 8 via lowest ping time | ||||
self.extra_args = [['-maxconnections=32']] | self.extra_args = [['-maxconnections=36', "-enableavalanche=1"]] | ||||
def run_test(self): | def run_test(self): | ||||
protected_peers = set() # peers that we expect to be protected from eviction | # peers that we expect to be protected from eviction | ||||
protected_peers = set() | |||||
current_peer = -1 | current_peer = -1 | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
node.generatetoaddress(101, node.get_deterministic_priv_key().address) | blocks = node.generatetoaddress( | ||||
101, node.get_deterministic_priv_key().address) | |||||
self.log.info( | self.log.info( | ||||
"Create 4 peers and protect them from eviction by sending us a block") | "Create 4 peers and protect them from eviction by sending us a block") | ||||
for _ in range(4): | for _ in range(4): | ||||
block_peer = node.add_p2p_connection(SlowP2PDataStore()) | block_peer = node.add_p2p_connection(SlowP2PDataStore()) | ||||
current_peer += 1 | current_peer += 1 | ||||
block_peer.sync_with_ping() | block_peer.sync_with_ping() | ||||
best_block = node.getbestblockhash() | best_block = node.getbestblockhash() | ||||
tip = int(best_block, 16) | tip = int(best_block, 16) | ||||
best_block_time = node.getblock(best_block)['time'] | best_block_time = node.getblock(best_block)['time'] | ||||
block = create_block( | block = create_block( | ||||
tip, | tip, | ||||
create_coinbase( | create_coinbase( | ||||
node.getblockcount() + 1), | node.getblockcount() + 1), | ||||
best_block_time + 1) | best_block_time + 1) | ||||
block.solve() | block.solve() | ||||
block_peer.send_blocks_and_test([block], node, success=True) | block_peer.send_blocks_and_test([block], node, success=True) | ||||
protected_peers.add(current_peer) | protected_peers.add(current_peer) | ||||
self.log.info( | self.log.info( | ||||
"Create 4 peers and protect them from eviction by sending us a proof") | |||||
privkey = ECKey() | |||||
privkey.generate() | |||||
pubkey = privkey.get_pubkey() | |||||
stakes = create_coinbase_stakes( | |||||
node, blocks, node.get_deterministic_priv_key().key) | |||||
for i in range(4): | |||||
proof_peer = node.add_p2p_connection(SlowP2PDataStore()) | |||||
current_peer += 1 | |||||
proof_peer.sync_with_ping() | |||||
proof = node.buildavalancheproof( | |||||
42, 2000000000, pubkey.get_bytes().hex(), [stakes[i]]) | |||||
avaproof_msg = msg_avaproof() | |||||
avaproof_msg.proof = FromHex(AvalancheProof(), proof) | |||||
proof_peer.send_message(avaproof_msg) | |||||
protected_peers.add(current_peer) | |||||
self.log.info( | |||||
"Create 5 slow-pinging peers, making them eviction candidates") | "Create 5 slow-pinging peers, making them eviction candidates") | ||||
for _ in range(5): | for _ in range(5): | ||||
node.add_p2p_connection(SlowP2PInterface()) | node.add_p2p_connection(SlowP2PInterface()) | ||||
current_peer += 1 | current_peer += 1 | ||||
self.log.info( | self.log.info( | ||||
"Create 4 peers and protect them from eviction by sending us a tx") | "Create 4 peers and protect them from eviction by sending us a tx") | ||||
for i in range(4): | for i in range(4): | ||||
▲ Show 20 Lines • Show All 71 Lines • Show Last 20 Lines |