Beispiel #1
0
    def handleTxStatusReq(self, txid: str, peer: Peer):
        def _txn_iterator(chain):
            return ((txn, block, height)
                    for height, block in enumerate(chain, 1)
                    for txn in block.txns)

        if txid in self.mempool.mempool:
            status = 0  # f'txn {txid} found in_mempool'
            message = Message(Actions.TxStatusRev, status, Params.PORT_CURRENT)
            # print(message)
            self.request.sendall(Utils.encode_socket_data(message))
            return
        for tx, block, height in _txn_iterator(self.active_chain.chain):
            if tx.id == txid:
                status = (
                    # f'txn {txid} is mined in block {block.id} at height {height}'
                    1)
                message = Message(Actions.TxStatusRev, status,
                                  Params.PORT_CURRENT)
                self.request.sendall(Utils.encode_socket_data(message))
                return
        status = 2  # f'txn {txid}:not_found'
        message = Message(Actions.TxStatusRev, status, Params.PORT_CURRENT)

        self.request.sendall(Utils.encode_socket_data(message))
Beispiel #2
0
    def getUTXO4Addr(self, wallet_addr: str = None) -> Iterable[UnspentTxOut]:
        with self.chain_lock:
            if wallet_addr is None:
                wallet_addr = self.wallet.my_address
            peer, port = self._getPort()
            message = Message(Actions.UTXO4Addr, wallet_addr, port)

            with socket.create_connection(peer, timeout=25) as s:
                s.sendall(Utils.encode_socket_data(message))
                logger.info(f'[EdgeHand] succeed to send UTXO4Addr 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)

                message = Utils.deserialize(data.decode(),
                                            self.gs) if data else None
                if message:
                    logger.info(
                        f'[EdgeHand] received UTXO4Addr from peer {peer}')
                    return message.data
                else:
                    logger.info(
                        f'[EdgeHand] recv nothing for UTXO4Addr from peer {peer}'
                    )
                    return None
Beispiel #3
0
 def sendPeerExtend(self):
     peers = self.peerManager.getPeers()
     if len(peers) > 0:
         for _peer in peers:
             if random.random() < 0.2:
                 continue
             peer_samples = random.sample(peers, min(5, len(peers)))
             #logger.info(f"[p2p] sending {len(peer_samples)} peers to {_peer}")
             ret = Utils.send_to_peer(
                 Message(Actions.PeerExtend, peer_samples,
                         Params.PORT_CURRENT), _peer)
             if ret == 1:
                 if _peer in peers:
                     try:
                         with self.peers_lock:
                             self.peerManager.block(_peer)
                     except:
                         pass
                     return
             elif ret != 0:
                 with self.peers_lock:
                     self.peerManager.addLog(_peer, 1)
             else:
                 with self.peers_lock:
                     self.peerManager.addLog(_peer, 0)
Beispiel #4
0
    def getTxStatus(self, txid: str) -> str:
        with self.chain_lock:
            peer, port = self._getPort()
            message = Message(Actions.TxStatusReq, txid, port)

            with socket.create_connection(peer(), timeout=25) as s:
                s.sendall(Utils.encode_socket_data(message))
                logger.info(f'[EdgeHand] succeed to send TxStatus 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)

                message = Utils.deserialize(data.decode(),
                                            self.gs) if data else None
                if message:
                    logger.info(
                        f'[EdgeHand] received TxStatus from peer {peer}')
                    return message.data
                else:
                    logger.info(
                        f'[EdgeHand] recv nothing for TxStatus from peer {peer}'
                    )
                    return None
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #7
0
 def send_replicas(self):
     for server_id in self.neighbour_servers:
         for sensor_id in self.data.keys():
             msg = Message(sensor_id, self.default_gateway,
                           self.data[sensor_id], True)
             self.log('Sending replicas to:', server_id)
             self.send_message(server_id, msg)
     threading.Timer(30.0, self.send_replicas).start()
Beispiel #8
0
 def try_to_send_data(self, server_id, data):
     try:
         msg = Message(self.id, self.default_gateway, data, False)
         self.log('Sending message to ' + server_id + ':', msg)
         conn = rpyc.connect(server_id, 9600)
         conn.root.receive_data(self.id, self.default_gateway, data, False)
         return True
     except Exception as ex:
         self.log('RPC failed:', ex)
         return False
Beispiel #9
0
    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)
Beispiel #10
0
 def send_recoveries(self):
     for server_id in self.neighbour_servers:
         if server_id in self.recovery_data:
             for sensor_id in self.recovery_data[server_id]:
                 while self.recovery_data[server_id][sensor_id]:
                     data = self.recovery_data[server_id][sensor_id].pop()
                     msg = Message(sensor_id, server_id, data, False)
                     self.log('Sending recovery data to:', server_id)
                     self.send_message(server_id, msg)
             self.recovery_data.pop(server_id)
     threading.Timer(30.0, self.send_recoveries).start()
Beispiel #11
0
    def handleBlockAtHeightReq(self, height: int, peer: Peer):
        logger.info(f'[p2p] receive BlockAtHeightReq from peer {peer}')

        with self.chain_lock:
            if height > self.active_chain.height:
                height = self.active_chain.height
            block = copy.deepcopy(self.active_chain.chain[height - 1])
        message = Message(Actions.BlockRev, block, Params.PORT_CURRENT)
        ret = self.request.sendall(Utils.encode_socket_data(message))
        logger.info(
            f"[p2p] sent block at height {height} in handleBlockAtHeight to {peer}"
        )
Beispiel #12
0
    def handleBlockstatsReq(self, peer):
        with self.chain_lock:
            height = self.active_chain.height
            difficulty = str(self.active_chain.chain[-1].nonce / 1000 /
                             (self.active_chain.chain[-1].timestamp -
                              self.active_chain.chain[-2].timestamp))
            tx_pool_size = len(self.mempool.mempool)

        blockStats = BlockStats(height, difficulty, tx_pool_size)
        message = Message(Actions.BlocksSyncGet, blockStats,
                          Params.PORT_CURRENT)
        ret = self.request.sendall(Utils.encode_socket_data(message))
        logger.info(f"[p2p] sent blockstats to {peer}")
Beispiel #13
0
    def sendTransaction(self, txinType, to_addr, value):
        with self.chain_lock:
            txn = self._makeTransaction(txinType, to_addr, value)
            logger.info(f'[EdgeHand] built txn {txn}')

            peer, port = self._getPort()
            message = Message(Actions.TxRev, txn, port)
            if Utils.send_to_peer(message, peer):
                logger.info(
                    f'[EdgeHand] succeed to send a transaction to {peer}')
                return txn
            else:
                logger.info(f'[EdgeHand] failed to send TxRev to {peer}')
            return None
Beispiel #14
0
    def handleBalance4Addr(self, addr: str, peer: Peer):

        # with self.chain_lock:
        logger.info(f'handle Balance4Addr request from {peer}')
        utxos4addr = [
            u for u in self.utxo_set.utxoSet.values()
            if scriptBuild.get_address_from_pk_script(u.to_address) == addr
        ]

        val = sum(utxo.value for utxo in utxos4addr)
        # logger.info(f'return Balance4Addr request and get value {self.utxo_set.utxoSet.values()}')

        message = Message(Actions.Balance4AddrRev, val, Params.PORT_CURRENT)
        self.request.sendall(Utils.encode_socket_data(message))
Beispiel #15
0
    def handleUTXO4Addr(self, addr: str, peer: Peer):
        # with self.chain_lock:
        logger.info(f'handle UTXO4Addr request from {peer}')
        # for u in self.utxo_set.utxoSet.values():
        #     print(scriptBuild.get_address_from_pk_script(u.to_address))

        utxos4addr = [
            u for u in self.utxo_set.utxoSet.values()
            if scriptBuild.get_address_from_pk_script(u.to_address) == addr
        ]

        message = Message(Actions.UTXO4AddrRev, utxos4addr,
                          Params.PORT_CURRENT)

        self.request.sendall(Utils.encode_socket_data(message))
Beispiel #16
0
            def broadcast_new_mined_block(block_to_broadcast):
                peers = self.peerManager.getPeers()
                for _peer in peers:
                    ret = Utils.send_to_peer(
                        Message(Actions.BlockRev, block_to_broadcast,
                                Params.PORT_CURRENT), _peer)
                    if ret == 1:
                        if _peer in peers:
                            with self.peers_lock:
                                #self.peerManager.remove(_peer)
                                self.peerManager.block(_peer)

                    elif ret != 0:
                        with self.peers_lock:
                            self.peerManager.addLog(_peer, 1)
                    else:
                        with self.peers_lock:
                            self.peerManager.addLog(_peer, 0)
Beispiel #17
0
    def handleTxRev(self, txn: Transaction, peer: Peer):
        if isinstance(txn, Transaction):
            logger.info(f"[p2p] >>>>  received txn {txn.id} from peer {peer}")
            with self.chain_lock:
                #chain_use_id = [str(number).split('.')[0] + '.' + str(number).split('.')[1][:5] for number in [random.random()]][0]
                #logger.info(f'####### into chain_lock: {chain_use_id} of handleTxRev')
                mempool_ret = self.mempool.add_txn_to_mempool(
                    txn, self.utxo_set)
                #logger.info(f'####### out of chain_lock: {chain_use_id} of handleTxRev')
            if mempool_ret:
                peers = self.peerManager.getPeers()
                if len(peers) > 0:
                    for _peer in random.sample(peers, min(len(peers), 5)):
                        if _peer != peer:
                            ret = Utils.send_to_peer(
                                Message(Actions.TxRev, txn,
                                        Params.PORT_CURRENT), _peer)
                            if ret == 1:
                                if _peer in peers:
                                    try:
                                        with self.peers_lock:
                                            #self.peerManager.remove(_peer)#self.peers.remove(_peer)
                                            self.peerManager.block(_peer)
                                    except:
                                        pass

                            elif ret != 0:
                                with self.peers_lock:
                                    self.peerManager.addLog(_peer, 1)
                            else:
                                with self.peers_lock:
                                    self.peerManager.addLog(_peer, 0)
            else:
                logger.info(
                    f"[p2p] received txn {txn.id}, but validate failed.")

        else:
            logger.info(
                f'[p2p] {txn} is not a Transaction object in handleTxRev')
            return
Beispiel #18
0
    def initial_block_download(self):
        self.ibd_done.clear()
        peers = self.peerManager.getPeers()
        if peers:
            logger.info(
                f'start initial block download from {len(peers)} peers')
            peer_sample = random.sample(peers, min(len(peers), 6))

            message = Message(Actions.BlocksSyncReq,
                              self.active_chain.chain[-1].id,
                              Params.PORT_CURRENT)
            for peer in peer_sample:
                try:
                    with socket.socket(socket.AF_INET,
                                       socket.SOCK_STREAM) as s:
                        s.settimeout(70)
                        s.connect(peer())
                        s.sendall(Utils.encode_socket_data(message))
                        logger.info(
                            f'sending BLockSyncReq successfully at {self.active_chain.chain[-1].id} 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()
                    message = Utils.deserialize(data.decode(),
                                                self.gs) if data else None
                    if message:
                        logger.info(
                            f'[EdgenceChain] received blocks in initial_block_download 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'cannot send data to itself, and its port is {Params.PORT_CURRENT}'
                            )
                    else:
                        logger.info(
                            f'[EdgenceChain] recv no new blocks when in initial_block_download from peer {peer}, and waiting for finishing'
                        )
                        time.sleep(Params.TIME_BETWEEN_BLOCKS_IN_SECS_TARGET)
                        self.ibd_done.set()
                        break
                except Exception as e:
                    #logger.exception(f'Error: {repr(e)}, and remove dead peer {peer}')
                    if peer in peers:
                        try:
                            with self.peers_lock:
                                self.peerManager.addLog(peer, 1)
                        except:
                            pass

        else:
            logger.info(f'no peer nodes existed, ibd_done is set')
            self.ibd_done.set()
Beispiel #19
0
 def exposed_receive_data(self, sensor_id, server_id, data, is_replica):
     msg = Message(sensor_id, server_id, data, is_replica)
     self.queue.append(msg)
     return True
Beispiel #20
0
    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}')
Beispiel #21
0
def test_log():
    h = """
    Szerverek es szenzorok logolasanak tesztelese
    """
    print(h)

    if not LOGGING_ENABLED:
        print(
            "Logolas ki van kapcsolva a config file-ban, a teszt futtatasahoz be kell kapcsolni"
        )
    assert (LOGGING_ENABLED)

    # stdout atallitasa
    captureOutput = StringIO()
    sys.stdout = captureOutput
    expected = []

    # logolas:
    mainServerID = 1000
    mainServer = StorageServer(alive=True, id=mainServerID)
    sensorID = mainServerID + 1
    sensor = Sensor(id=sensorID, servers=[])
    mainServer.add_sensor(sensor=sensor)
    expected.append("Server " + str(mainServerID) + ": Sensor added: " +
                    str(sensor))

    neighbourServerID = 2000
    neighbourServer = StorageServer(alive=True, id=neighbourServerID)
    mainServer.add_neighbour_server(neighbourServer)
    expected.append("Sensor " + str(sensorID) + ": New server list: " +
                    str(sensor.servers))
    expected.append("Server " + str(mainServerID) +
                    ": Neighbour server added: " + str(neighbourServer))

    data_ = "Data sent from sensor to own server"
    msg = Message(sensor_id=sensorID,
                  server_id=mainServerID,
                  content=data_,
                  is_replica=None)
    sensor.send_data(data=data_)
    expected.append("Sensor " + str(sensorID) + ": Sending data " + data_ +
                    " to " + str(mainServer))
    expected.append("Server " + str(mainServerID) + ": Received own data " +
                    str(msg))
    msg.is_replica = True
    expected.append("Server " + str(neighbourServerID) +
                    ": Received other data " + str(msg))

    mainServer.change_alive_state(alive=False)
    expected.append("Server " + str(mainServerID) +
                    ": Alive state changed to False")
    data_dead = "sending data to dead server"
    sensor.send_data(data_dead)
    msg_dead = Message(sensor_id=sensorID,
                       server_id=mainServerID,
                       content=data_dead,
                       is_replica=None)
    expected.append("Server " + str(neighbourServerID) +
                    ": Received dead data " + str(msg_dead))

    mainServer.change_alive_state(False)
    neighbourServer.change_alive_state(False)
    data_notsent = "Data is unable to send"
    try:
        sensor.send_data(data_notsent)
    except:
        print("exception")
    expected.append("Sensor " + str(sensorID) + ": Sending was unsuccessful.")
    expected.append("Sensor " + str(sensorID) +
                    ": Could not send data to any server.")

    # stdout visszaallitas
    sys.stdout = sys.__stdout__

    for expect in expected:
        if (expect not in captureOutput.getvalue()):
            print(expect)
        assert (expect in captureOutput.getvalue())
Beispiel #22
0
    def initial_block_download(self):
        """
        Download blocks from peers in peerManager.
        """

        self.ibd_done.clear()
        peers = self.peerManager.getPeers()
        if peers:
            logger.info(
                f"start initial block download from {len(peers)} peers")
            # Select max 6 peers.
            peer_sample = random.sample(peers, min(len(peers), 6))

            message = Message(
                Actions.BlocksSyncReq,
                self.active_chain.chain[-1].id,
                Params.PORT_CURRENT,
            )

            for peer in peer_sample:
                try:
                    with socket.socket(socket.AF_INET,
                                       socket.SOCK_STREAM) as s:
                        s.settimeout(70)
                        s.connect(peer())
                        s.sendall(Utils.encode_socket_data(message))
                        logger.info(
                            f"sending BLockSyncReq successfully at {self.active_chain.chain[-1].id} 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)

                    # Useless below.
                    # s.close()

                    message = (Utils.deserialize(data.decode(), self.gs)
                               if data else None)

                    if message:
                        logger.info(
                            f"[EdgenceChain] received blocks in initial_block_download from peer {peer}"
                        )
                        message = Message(message.action, message.data,
                                          Params.PORT_CURRENT, peer)

                        # TODO: simplify it.
                        # Send received data to its TCP server, TCP handler will process received block.
                        ret = Utils.send_to_peer(message,
                                                 Peer("127.0.0.1",
                                                      Params.PORT_CURRENT),
                                                 itself=True)

                        if ret != 0:
                            logger.info(
                                f"cannot send data to itself, and its port is {Params.PORT_CURRENT}"
                            )
                    else:
                        logger.info(
                            f"[EdgenceChain] recv no new blocks when in initial_block_download from peer {peer}, and waiting for finishing"
                        )
                        time.sleep(Params.TIME_BETWEEN_BLOCKS_IN_SECS_TARGET)
                        self.ibd_done.set()
                        break

                except Exception as e:
                    # logger.exception(f'Error: {repr(e)}, and remove dead peer {peer}')
                    if peer in peers:
                        try:
                            with self.peers_lock:
                                # This peer is not success this time, add log: 1 to its log.
                                self.peerManager.addLog(peer, 1)
                        except:
                            pass

        else:
            logger.info(f"no peer nodes existed, ibd_done is set")
            self.ibd_done.set()
Beispiel #23
0
    def handleBlockRev(self, block: Block, peer: Peer):
        if not isinstance(block, Block):
            logger.info(f'[p2p] {block} is not a Block')
            return
        else:
            if peer != Peer('127.0.0.1', Params.PORT_CURRENT):
                logger.info(
                    f"[p2p] received block {block.id} from peer {peer}")
            with self.chain_lock:

                chain_idx  = TCPHandler.check_block_place(block, self.active_chain, self.utxo_set, self.mempool, \
                                                          self.side_branches)
                ret_outside_lock = False
                if chain_idx is not None and chain_idx >= 0:
                    ret_outside_lock = TCPHandler.do_connect_block_and_after(block, chain_idx, self.active_chain, self.side_branches, \
                                                       self.mempool, self.utxo_set, self.mine_interrupt)
                    if not ret_outside_lock:
                        #logger.info(f'####### out of chain_lock: {chain_use_id} of handleBlockRev')
                        return
                    if not Block.locate_block(block.id, self.active_chain,
                                              self.side_branches)[0]:
                        return

                #logger.info(f'####### out of chain_lock: {chain_use_id} of handleBlockRev')

            if ret_outside_lock is True:
                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)

            if chain_idx is not None and chain_idx >= 0:
                peers = self.peerManager.getPeers()
                if len(peers) > 0:
                    for _peer in random.sample(peers, min(len(peers), 5)):
                        if _peer != peer:
                            ret = Utils.send_to_peer(
                                Message(Actions.BlockRev, block,
                                        Params.PORT_CURRENT), _peer)
                            if ret == 1:
                                if _peer in peers:
                                    try:
                                        with self.peers_lock:
                                            self.peerManager.block(_peer)
                                    except:
                                        pass
                            elif ret != 0:
                                with self.peers_lock:
                                    self.peerManager.addLog(_peer, 1)
                            else:
                                with self.peers_lock:
                                    self.peerManager.addLog(_peer, 0)

                self.sendPeerExtend()

            elif chain_idx is None:
                logger.info(
                    f'[p2p] already seen block {block.id}, and do nothing')
            elif chain_idx == -1:
                # case of orphan block
                message = Message(Actions.TopBlocksSyncReq, 50,
                                  Params.PORT_CURRENT)
                if peer == Peer('127.0.0.1', Params.PORT_CURRENT):
                    getpeers = self.peerManager.getPeers(2)
                    if len(getpeers) > 0:
                        peer = random.sample(getpeers, 1)[0]
                    else:
                        return

                try:
                    with socket.socket(
                            socket.AF_INET, socket.SOCK_STREAM
                    ) as s:  #socket.create_connection(peer(), timeout=25) as s:
                        s.connect(peer())
                        s.sendall(Utils.encode_socket_data(message))
                        logger.info(
                            f'[p2p] succeed to send TopBlocksSyncReq 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:
                        blocks = message.data
                        if blocks[0].prev_block_hash:
                            if not Block.locate_block(
                                    blocks[0].prev_block_hash,
                                    self.active_chain, self.side_branches)[0]:
                                logger.info(
                                    f"received sync blocks for the orphan block in handleBlockRev, but the first blocks's pre_block_hash cannot be seen on the chains"
                                )
                                self.peerManager.block(peer)
                                return
                        else:
                            blocks.pop(0)
                            if not Block.locate_block(
                                    blocks[0].prev_block_hash,
                                    self.active_chain, self.side_branches)[0]:
                                logger.info(
                                    f"received sync blocks for the orphan block in handleBlockRev, but the first blocks's pre_block_hash cannot be seen on the chains"
                                )
                                self.peerManager.block(peer)
                                return

                        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] send BlocksSyncGet to itself')
                            pass
                    else:
                        logger.info(f'[p2p] recv nothing from peer {peer}')
Beispiel #24
0
            def work_to_do():
                logger.info(
                    f'begin to work in another new thread of initiative_sync')
                try:
                    with self.peers_lock:
                        self.peerManager.update()
                        peers = self.peerManager.getPeers()
                        Peer.save_peers(peers, Params.PEERS_FILE)
                except:
                    pass

                try:

                    time_now = time.time()
                    with self.chain_lock:
                        for block in self.orphan_blocks:
                            if time_now - block.timestamp > Params.MAXIMUM_ALLOWABLE_HEIGHT_DIFF * Params.TIME_BETWEEN_BLOCKS_IN_SECS_TARGET:
                                self.orphan_blocks.remove(block)
                except:
                    pass

                getpeers = self.peerManager.getPeers(2)
                if len(getpeers) > 0:
                    peer = random.sample(getpeers, 1)[0]
                    try:
                        message = Message(Actions.TopBlockReq, None,
                                          Params.PORT_CURRENT)

                        with socket.socket(
                                socket.AF_INET, socket.SOCK_STREAM
                        ) as s:  #socket.create_connection(peer(), timeout=25) as s:
                            #logger.info(f'[EdgenceChain] begin to connect to {peer}')
                            s.connect(peer())
                            #logger.info(f'[EdgenceChain] succeed to create socket connection with {peer}, and begin to send data ...')
                            s.sendall(Utils.encode_socket_data(message))
                            logger.info(
                                f'[EdgenceChain] succeed to send TopBlockReq 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()
                        message = Utils.deserialize(data.decode(),
                                                    self.gs) if data else None
                        if message:
                            logger.info(
                                f'[EdgenceChain] received top block from peer {peer}'
                            )
                            message = Message(Actions.BlockRev, 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'cannot send data to itself, and its port is {Params.PORT_CURRENT}'
                                )
                            else:
                                #logger.info(f'[EdgenceChain] send BlockRev to itself')
                                pass
                        else:
                            logger.info(
                                f'[EdgenceChain] recv nothing from peer {peer}'
                            )

                    except:
                        self.peerManager.addLog(peer, 1)
from p2p.Message import Message
from p2p.Message import Actions

message = Message(0, '22', 9991)

print(hasattr(message, "action"))

print(Actions.num2name[str(Actions.BlockRev)])