def get_headerhash_list(self, current_block_height): start_blocknumber = max(0, current_block_height - config.dev.reorg_limit) node_header_hash = qrl_pb2.NodeHeaderHash(block_number=start_blocknumber, headerhashes=[]) msg = qrllegacy_pb2.LegacyMessage(func_name=qrllegacy_pb2.LegacyMessage.HEADERHASHES, nodeHeaderHash=node_header_hash) self.send(msg)
def get_headerhashes(self, start_blocknumber): start_blocknumber = max(0, start_blocknumber) end_blocknumber = min(self.last_block.block_number, start_blocknumber + 2 * config.dev.reorg_limit) total_expected_headerhash = end_blocknumber - start_blocknumber + 1 node_header_hash = qrl_pb2.NodeHeaderHash() node_header_hash.block_number = start_blocknumber block = self.state.get_block_by_number(end_blocknumber) block_headerhash = block.headerhash node_header_hash.headerhashes.append(block_headerhash) end_blocknumber -= 1 while end_blocknumber >= start_blocknumber: block_metadata = self.state.get_block_metadata(block_headerhash) for headerhash in block_metadata.last_N_headerhashes[-1::-1]: node_header_hash.headerhashes.append(headerhash) end_blocknumber -= len(block_metadata.last_N_headerhashes) if len(block_metadata.last_N_headerhashes) == 0: break block_headerhash = block_metadata.last_N_headerhashes[0] node_header_hash.headerhashes[:] = node_header_hash.headerhashes[-1::-1] del node_header_hash.headerhashes[:len(node_header_hash.headerhashes) - total_expected_headerhash] return node_header_hash
def setUp(self): port = '9000' self.m_qrlnode = Mock(autospec=QRLNode, name='Fake QRLNode') self.channel_1 = Mock(autospec=P2PProtocol, name='mock Channel 1', peer_ip='1.1.1.1', peer_port=port) self.channel_2 = Mock(autospec=P2PProtocol, name='mock Channel 2', peer_ip='2.2.2.2', peer_port=port) self.channel_3 = Mock(autospec=P2PProtocol, name='mock Channel 3', peer_ip='3.3.3.3', peer_port=port) self.factory = P2PFactory(chain_manager=Mock(autospec=ChainManager), sync_state=None, qrl_node=self.m_qrlnode) self.factory.pow = Mock(autospec=POW) self.m_qrlnode.is_banned.return_value = False self.factory.add_connection(self.channel_1) self.factory.add_connection(self.channel_2) self.factory.add_connection(self.channel_3) # The peer has two blocks. It has sent a list of their hashes, and block_number indicates that the first hash # in the list is for block_number 1. self.factory._target_node_header_hash = qrl_pb2.NodeHeaderHash( block_number=1, headerhashes=[bhstr2bin('123456'), bhstr2bin('deadbeef')] ) # This mocking ensures that the Block gets added to the Chain, and that the next block is requested. self.factory._target_peer = self.channel_1 self.factory._last_requested_block_number = 1 self.factory._chain_manager.add_block.return_value = True self.factory.peer_fetch_block = Mock(autospec=P2PFactory.peer_fetch_block)
def test_handle_node_headerhash_peer_has_headerhashes(self, m_logger): """ This function also handles requests and responses of NodeHeaderHashes. A NodeHeaderHash is a list of blockhashes that a particular node has. If the incoming nodeHeaderHash message object has headerhashes, compare our headerhash list and possibly sync. """ incoming_info = make_message( func_name=qrllegacy_pb2.LegacyMessage.HEADERHASHES, nodeHeaderHash=qrl_pb2.NodeHeaderHash(block_number=3, headerhashes=(b'0', b'1', b'2'))) self.manager.handle_node_headerhash(self.channel, incoming_info) self.channel.factory.compare_and_sync.assert_called()
def test_compare_and_sync_detect_fork(self, m_reactor, m_logger): """ There is a fork at block_number 2. peer_fetch_block() should be called. """ # Mess with the expected headerhash value self.node_header_hash = qrl_pb2.NodeHeaderHash( block_number=1, headerhashes=[bhstr2bin('123456'), bhstr2bin('000000'), bhstr2bin('deadbeef')] ) # Set our state as being on the 2nd block of the NodeHeaderHash self.factory._chain_manager._last_block = self.blocks[1] self.factory.compare_and_sync(self.channel_1, self.node_header_hash) self.factory.peer_fetch_block.assert_called_once()
def setUp(self): def replacement_get_block_by_number(i): return self.blocks[i - 1] port = '9000' self.m_qrlnode = Mock(autospec=QRLNode, name='Fake QRLNode') self.factory = P2PFactory( chain_manager=ChainManager(state=Mock(autospec=State)), sync_state=None, qrl_node=self.m_qrlnode) self.factory.peer_fetch_block = Mock( autospec=P2PFactory.peer_fetch_block) self.factory._chain_manager.get_block_by_number = replacement_get_block_by_number self.channel_1 = Mock(autospec=P2PProtocol, name='mock Channel 1', peer_ip='1.1.1.1', peer_port=port) self.factory.add_connection(self.channel_1) self.blocks = [ Mock(autospec=Block, name='0th Block', block_number=1, headerhash=bhstr2bin('123456')), Mock(autospec=Block, name='1st Block', block_number=2, headerhash=bhstr2bin('7890ab')), Mock(autospec=Block, name='2nd Block', block_number=3, headerhash=bhstr2bin('deadbeef')) ] self.node_header_hash = qrl_pb2.NodeHeaderHash( block_number=1, headerhashes=[ bhstr2bin('123456'), bhstr2bin('7890ab'), bhstr2bin('deadbeef') ])
def setUp(self): port = '9000' self.m_qrlnode = Mock(autospec=QRLNode, name='Fake QRLNode') self.channel_1 = Mock(autospec=P2PProtocol, name='mock Channel 1', peer_ip='1.1.1.1', peer_port=port) self.channel_2 = Mock(autospec=P2PProtocol, name='mock Channel 2', peer_ip='2.2.2.2', peer_port=port) self.channel_3 = Mock(autospec=P2PProtocol, name='mock Channel 3', peer_ip='3.3.3.3', peer_port=port) self.factory = P2PFactory( chain_manager=ChainManager(state=Mock(autospec=State)), sync_state=None, qrl_node=self.m_qrlnode) self.factory.pow = Mock(autospec=POW) self.m_qrlnode.is_banned.return_value = False self.factory.add_connection(self.channel_1) self.factory.add_connection(self.channel_2) self.factory.add_connection(self.channel_3) self.factory._target_channel = self.channel_1 self.factory.is_syncing_finished = Mock( return_value=False, autospec=P2PFactory.is_syncing_finished) self.factory._target_node_header_hash = qrl_pb2.NodeHeaderHash( block_number=1, headerhashes=[ bhstr2bin('123456'), bhstr2bin('deadbeef'), bhstr2bin('abcdef') ]) self.factory._last_requested_block_number = 1