def handleTopBlockSyncReq(self, topN: int, peer: Peer): #with self.chain_lock: logger.info( f"[p2p] to handle TopBlockSyncReq with length {topN} from peer {peer}" ) with self.chain_lock: blocks = copy.deepcopy(self.active_chain.chain[-topN:]) message = Message(Actions.BlocksSyncGet, blocks, Params.PORT_CURRENT) ret = self.request.sendall(Utils.encode_socket_data(message)) logger.info( f"[p2p] sent {len(blocks)} blocks in handleTopBlockSyncReq to {peer}" ) if ret is None: if peer not in self.peerManager.getAllPeers(): if peer== Peer('127.0.0.1', Params.PORT_CURRENT) or \ peer == Peer('localhost', Params.PORT_CURRENT) or \ peer.ip == '0.0.0.0' or \ peer == Peer(Params.PUBLIC_IP, Params.PORT_CURRENT): return if Utils.is_peer_valid(peer): with self.peers_lock: self.peerManager.add(peer) #self.peers.append(peer) #Peer.save_peers(self.peers) self.sendPeerExtend() else: self.peerManager.block(peer)
def handleTopBlockReq(self, peer: Peer): logger.info(f"[p2p] to handle TopBlokReq from peer {peer}") with self.chain_lock: block = copy.deepcopy(self.active_chain.chain[-1]) message = Message(Actions.BlockRev, block, Params.PORT_CURRENT) ret = self.request.sendall(Utils.encode_socket_data(message)) logger.info(f"[p2p] sent top block in handleTopBlockReq to {peer}") if ret is None: #if self.request.sendall(Utils.encode_socket_data(message)) is None: if peer not in self.peerManager.getAllPeers(): if peer== Peer('127.0.0.1', Params.PORT_CURRENT) or \ peer == Peer('localhost', Params.PORT_CURRENT) or \ peer.ip == '0.0.0.0' or \ peer == Peer(Params.PUBLIC_IP, Params.PORT_CURRENT): return if Utils.is_peer_valid(peer): with self.peers_lock: self.peerManager.add(peer) #self.peers.append(peer) #logger.info(f'[p2p] add peer {peer} into peer list') #Peer.save_peers(self.peers) self.sendPeerExtend() else: self.peerManager.block(peer)
def handlePeerExtendGet(self, peer_samples: Iterable[Peer], peer: Peer): peer_samples.append(peer) for peer_sample in peer_samples: if not isinstance(peer_sample, Peer): continue if peer_sample == Peer('127.0.0.1', Params.PORT_CURRENT) or \ peer_sample == Peer('localhost', Params.PORT_CURRENT) or \ peer_sample.ip == '0.0.0.0' or \ peer_sample == Peer(Params.PUBLIC_IP, Params.PORT_CURRENT): continue if peer_sample in self.peerManager.getAllPeers(): continue if Utils.is_peer_valid(peer_sample): with self.peers_lock: self.peerManager.add(peer_sample) else: self.peerManager.block(peer_sample)
def handleBlockSyncReq(self, blockid: str, peer: Peer): logger.info(f"[p2p] receive BlockSyncReq from peer {peer}") #with self.chain_lock: height = Block.locate_block(blockid, self.active_chain)[1] if height is None: logger.info( f'[p2p] cannot find blockid {blockid}, and do nothing for this BlockSyncReq from peer {peer}' ) with self.chain_lock: block = copy.deepcopy(self.active_chain.chain[-1]) message = Message(Actions.BlockRev, block, Params.PORT_CURRENT) self.request.sendall(Utils.encode_socket_data(message)) return else: logger.info( f"[p2p] receive BlockSyncReq at height {height} from peer {peer}" ) with self.chain_lock: blocks = copy.deepcopy( self.active_chain.chain[height:(height + Params.CHUNK_SIZE)]) logger.info(f"[p2p] sending {len(blocks)} blocks to {peer}") message = Message(Actions.BlocksSyncGet, blocks, Params.PORT_CURRENT) self.request.sendall(Utils.encode_socket_data(message)) if (peer not in self.peerManager.getAllPeers()) and not (peer == Peer('127.0.0.1', Params.PORT_CURRENT) or \ peer == Peer('localhost', Params.PORT_CURRENT) or \ peer.ip == '0.0.0.0' or \ peer == Peer(Params.PUBLIC_IP, Params.PORT_CURRENT)): if Utils.is_peer_valid(peer): with self.peers_lock: self.peerManager.add(peer) self.sendPeerExtend() else: self.peerManager.block(peer)
def handleBlockSyncGet(self, blocks: Iterable[Block], peer: Peer): if peer != Peer('127.0.0.1', Params.PORT_CURRENT): logger.info( f"[p2p] receive {len(blocks)} blocks for BlockSyncGet from {peer}" ) new_blocks = [ block for block in blocks if not Block.locate_block( block.id, self.active_chain, self.side_branches)[0] ] logger.info( f'[p2p] {len(new_blocks)} of {len(blocks)} blocks from {peer} is new' ) #if not new_blocks: # logger.info('[p2p] initial block download complete') # self.ibd_done.set() # return #else: # self.ibd_done.clear() if not TCPHandler.check_blocks_headers(new_blocks): return with self.chain_lock: for block in new_blocks: if Block.locate_block(block.id, self.active_chain, self.side_branches)[0]: new_blocks.pop(0) else: break if not new_blocks: return chain_idx = TCPHandler.check_block_place(new_blocks[0], self.active_chain, self.utxo_set, \ self.mempool, self.side_branches) if chain_idx is None: logger.info( f'received blocks have been seen in BlockSyncGet, do nothing and return' ) return if chain_idx <= -1: logger.info(f'[p2p] orphan or wrong blocks') if peer != Peer('127.0.0.1', Params.PORT_CURRENT): with self.peers_lock: self.peerManager.block(peer) return if chain_idx >= 1: # if is side branches, append the blocks (one block left) to the side branches directly logger.info( f'[p2p] just append {len(new_blocks)-1} blocks to side branch {chain_idx}, leaving one block to ' f'be coped with method do_connect_block_and_after') while len(new_blocks) >= 2: self.side_branches[chain_idx - 1].chain.append( new_blocks.pop(0)) for block in new_blocks: if not TCPHandler.do_connect_block_and_after(block, chain_idx, self.active_chain, self.side_branches, \ self.mempool, self.utxo_set, self.mine_interrupt): return if chain_idx == Params.ACTIVE_CHAIN_IDX: if len(self.active_chain.chain) % Params.SAVE_PER_SIZE == 0 or len( self.active_chain.chain) <= 5: Persistence.save_to_disk(self.active_chain) logger.info( f'[p2p] current chain height {self.active_chain.height}, and continue initial block download ... ' ) if peer not in self.peerManager.getAllPeers(): if peer== Peer('127.0.0.1', Params.PORT_CURRENT) or \ peer == Peer('localhost', Params.PORT_CURRENT) or \ peer.ip == '0.0.0.0' or \ peer == Peer(Params.PUBLIC_IP, Params.PORT_CURRENT): return if Utils.is_peer_valid(peer): with self.peers_lock: self.peerManager.add(peer) #self.peers.append(peer) self.sendPeerExtend() else: self.peerManager.block(peer) if peer == Peer('127.0.0.1', Params.PORT_CURRENT): logger.info(f'peer in handleBlockSyncGet cannot be itself') return top_id_chain_idx = new_blocks[-1].id message = Message(Actions.BlocksSyncReq, top_id_chain_idx, Params.PORT_CURRENT) try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect(peer()) s.sendall(Utils.encode_socket_data(message)) logger.info(f'[p2p] succeed to send BlocksSyncReq to {peer}') msg_len = int(binascii.hexlify(s.recv(4) or b'\x00'), 16) data = b'' while msg_len > 0: tdat = s.recv(1024) data += tdat msg_len -= len(tdat) s.close() except ConnectionRefusedError: self.peerManager.block(peer) except: self.peerManager.addLog(peer, 1) else: self.peerManager.addLog(peer, 0) message = Utils.deserialize(data.decode(), self.gs) if data else None if message: logger.info( f'[p2p] received blocks for sync blocks from peer {peer}') message = Message(message.action, message.data, Params.PORT_CURRENT, peer) ret = Utils.send_to_peer(message, Peer('127.0.0.1', Params.PORT_CURRENT), itself=True) if ret != 0: logger.info( f'[p2p] cannot send data to itself, and its current port is {Params.PORT_CURRENT}' ) else: logger.info(f'[p2p] recv nothing from peer {peer}')