Exemple #1
0
 def update_counters(self):
     time_diff = ntp.getTime() - self.last_rate_limit_update
     if time_diff > 60:
         self.out_counter = 0
         self.in_counter = 0
         self.last_rate_limit_update = ntp.getTime()
         return
Exemple #2
0
    def block_received(self, source, block: Block):
        self.pow.last_pb_time = ntp.getTime()
        logger.info('>>> Received Block #%d %s', block.block_number,
                    bin2hstr(block.headerhash))

        if source != self._target_channel:
            if self._target_channel is None:
                logger.warning('Received block and target channel is None')
            else:
                logger.warning('Received block from unexpected peer')
                logger.warning('Expected peer: %s', self._target_channel.peer)
                logger.warning('Found peer: %s', source.peer)
            return

        if block.block_number != self._last_requested_block_number:
            logger.warning('Did not match %s',
                           self._last_requested_block_number)
            self._xrd_node.peer_manager.ban_channel(source)
            return

        target_start_blocknumber = self._target_node_header_hash.block_number
        expected_headerhash = self._target_node_header_hash.headerhashes[
            block.block_number - target_start_blocknumber]
        if block.headerhash != expected_headerhash:
            logger.warning('Did not match headerhash')
            logger.warning('Expected headerhash %s', expected_headerhash)
            logger.warning('Found headerhash %s', block.headerhash)
            self._xrd_node.peer_manager.ban_channel(source)
            return

        if not block.validate(self._chain_manager, self.pow.future_blocks):
            logger.warning('Syncing Failed: Block Validation Failed')
            self._xrd_node.peer_manager.ban_channel(source)
            return

        if self._chain_manager.add_block(block, check_stale=False):
            if self._chain_manager.last_block.headerhash == block.headerhash:
                self.pow.suspend_mining_timestamp = ntp.getTime(
                ) + config.dev.sync_delay_mining
        else:
            logger.warning('Failed to Add Block')
            self._xrd_node.peer_manager.ban_channel(source)
            return

        try:
            reactor.download_monitor.cancel()
        except Exception as e:
            logger.warning("PB: %s", e)

        if self.is_syncing_finished():
            return

        self._last_requested_block_number += 1

        self.peer_fetch_block()
Exemple #3
0
    def handle_message_received(source, message: xrdlegacy_pb2.LegacyMessage):
        """
        Message Receipt
        This function accepts message receipt from peer,
        checks if the message hash already been received or not.
        In case its a already received message, it is ignored.
        Otherwise the request is made to get the full message.
        :return:
        """
        mr_data = message.mrData
        msg_hash = mr_data.hash

        # FIXME: Separate into respective message handlers

        if mr_data.type not in MessageReceipt.allowed_types:
            return

        if mr_data.type == xrdlegacy_pb2.LegacyMessage.TX and source.factory.sync_state.state != ESyncState.synced:
            return

        if mr_data.type == xrdlegacy_pb2.LegacyMessage.TX:
            if ntp.getTime() < source.factory.pow.suspend_mining_timestamp:
                return

            if source.factory._chain_manager.tx_pool.is_full_pending_transaction_pool(
            ):
                logger.warning(
                    'TX pool size full, incoming tx dropped. mr hash: %s',
                    bin2hstr(msg_hash))
                return

        if mr_data.type == xrdlegacy_pb2.LegacyMessage.BK:
            if mr_data.block_number > source.factory.chain_height + config.dev.max_margin_block_number:
                logger.debug('Skipping block #%s as beyond lead limit',
                             mr_data.block_number)
                return
            if mr_data.block_number < source.factory.chain_height - config.dev.min_margin_block_number:
                logger.debug('Skipping block #%s as beyond the limit',
                             mr_data.block_number)
                return

            if not source.factory.is_block_present(mr_data.prev_headerhash):
                logger.debug('Skipping block #%s as prev_headerhash not found',
                             mr_data.block_number)
                return

        if source.factory.master_mr.contains(msg_hash, mr_data.type):
            return

        source.factory.master_mr.add_peer(msg_hash, mr_data.type, source,
                                          mr_data)

        if source.factory.master_mr.is_callLater_active(
                msg_hash):  # Ignore if already requested
            return

        source.factory.request_full_message(mr_data)
Exemple #4
0
    def monitor_bk(self):
        # FIXME: Too many magic numbers / timing constants
        # FIXME: This is obsolete
        time_diff1 = ntp.getTime() - self.last_pow_cycle
        if 90 < time_diff1:
            if self.sync_state.state == ESyncState.unsynced:
                if ntp.getTime() - self.last_bk_time > 120:
                    self.last_pow_cycle = ntp.getTime()
                    logger.info(' POW cycle activated by monitor_bk() ')
                    self.update_node_state(ESyncState.synced)
                reactor.monitor_bk = reactor.callLater(60, self.monitor_bk)
                return

        time_diff2 = ntp.getTime() - self.last_pb_time
        if self.sync_state.state == ESyncState.syncing and time_diff2 > 60:
            self.update_node_state(ESyncState.unsynced)
            self.epoch_diff = -1

        reactor.monitor_bk = reactor.callLater(60, self.monitor_bk)
Exemple #5
0
    def _refresh(self):
        # TODO: refactored from banned peers. Rework to use a priority queue instead
        current_time = ntp.getTime()

        len_before = len(self._data)
        self._data = {k: v for k, v in self._data.items() if v > current_time}
        len_after = len(self._data)

        # FIXME: Drop peers beyond configuration limit

        if len_before != len_after:
            self._store()
Exemple #6
0
    def monitor_chain_state(self):
        self.peer_manager.monitor_chain_state()

        last_block = self._chain_manager.last_block
        block_metadata = self._chain_manager.get_block_metadata(last_block.headerhash)
        node_chain_state = xrd_pb2.NodeChainState(block_number=last_block.block_number,
                                                  header_hash=last_block.headerhash,
                                                  cumulative_difficulty=bytes(block_metadata.cumulative_difficulty),
                                                  version=config.dev.version,
                                                  timestamp=ntp.getTime())

        self.peer_manager.broadcast_chain_state(node_chain_state=node_chain_state)
        channel = self.peer_manager.get_better_difficulty(block_metadata.cumulative_difficulty)
        logger.debug('Got better difficulty %s', channel)
        if channel:
            logger.debug('Connection id >> %s', channel.peer)
            channel.send_get_headerhash_list(self._chain_manager.height)
        reactor.callLater(config.user.chain_state_broadcast_period, self.monitor_chain_state)
Exemple #7
0
    def __init__(self):
        self._buffer = bytes()

        # Need to use composition instead of inheritance here
        self._observable = P2PObservable(self)

        self.last_rate_limit_update = 0
        self.rate_limit = config.user.peer_rate_limit
        self.in_counter = 0
        self.out_counter = 0

        self.bytes_sent = 0
        self.outgoing_queue = PriorityQueue(maxsize=config.user.p2p_q_size)

        self._connected_at = ntp.getTime()
        self._valid_message_count = 0

        self._public_port = 0
Exemple #8
0
    def __init__(self, mining_address: bytes):
        self.start_time = ntp.getTime()
        self._sync_state = SyncState()

        self.peer_manager = P2PPeerManager()
        self.peer_manager.load_peer_addresses()

        self.p2pchain_manager = P2PChainManager()

        self.tx_manager = P2PTxManagement()

        self._chain_manager = None  # FIXME: REMOVE. This is temporary
        self._p2pfactory = None  # FIXME: REMOVE. This is temporary

        self._pow = None

        self.mining_address = mining_address

        reactor.callLater(10, self.monitor_chain_state)
Exemple #9
0
    def _mine_next(self, parent_block):
        if ntp.getTime() < self.suspend_mining_timestamp:
            return

        if config.user.mining_enabled:
            logger.debug('try get_block_metadata')
            parent_metadata = self.chain_manager.get_block_metadata(
                parent_block.headerhash)
            logger.debug('try prepare_next_unmined_block_template')
            dev_config = self.chain_manager.get_config_by_block_number(
                parent_block.block_number + 1)
            self.miner.prepare_next_unmined_block_template(
                mining_address=self.mining_address,
                tx_pool=self.chain_manager.tx_pool,
                parent_block=parent_block,
                parent_difficulty=parent_metadata.block_difficulty,
                dev_config=dev_config)
            logger.info('Mining Block #%s', parent_block.block_number + 1)
            self.miner.start_mining(parent_block,
                                    parent_metadata.block_difficulty,
                                    dev_config)
Exemple #10
0
    def pre_block_logic(self, block: Block):
        logger.debug('LOCK - TRY - pre_block_logic')
        with self.miner.lock:
            logger.debug('LOCK - LOCKED - pre_block_logic')

            if not block.validate(self.chain_manager, self.future_blocks):
                logger.warning('Block Validation failed for #%s %s',
                               block.block_number, bin2hstr(block.headerhash))
                return False

            dev_config = self.chain_manager.get_config_by_block_number(
                block.block_number)
            if block.is_future_block(dev_config):
                delay = abs(block.timestamp - ntp.getTime()) + 1
                reactor.callLater(delay, self.process_future_blocks)
                self.add_future_block(block)
                return True

            logger.debug('Inside add_block')
            result = self.chain_manager.add_block(block)

            logger.debug('trigger_miner %s', self.chain_manager.trigger_miner)
            if self.chain_manager.trigger_miner:
                logger.debug('try last block')
                last_block = self.chain_manager.last_block
                logger.debug('got last block')
                self._mine_next(last_block)

            if not result:
                logger.debug('Block Rejected %s %s', block.block_number,
                             bin2hstr(block.headerhash))
                return False

            reactor.callLater(0, self.broadcast_block, block)
        logger.debug('LOCK - RELEASE - pre_block_logic')

        return result
Exemple #11
0
 def _handler_state_synced(self):
     self.last_pow_cycle = ntp.getTime()
     last_block = self.chain_manager.last_block
     self._mine_next(last_block)
Exemple #12
0
 def _handler_state_syncing(self):
     self.last_pb_time = ntp.getTime()
Exemple #13
0
 def _handler_state_unsynced(self):
     self.miner.cancel()
     self.last_bk_time = ntp.getTime()
     self.restart_unsynced_logic()
Exemple #14
0
 def isSynced(self, block_timestamp) -> bool:
     if block_timestamp + config.dev.minimum_minting_delay > ntp.getTime():
         self.update_node_state(ESyncState.synced)
         return True
     return False
Exemple #15
0
    def is_future_block(self, dev_config: DevConfig) -> bool:
        if self.timestamp > ntp.getTime() + dev_config.block_max_drift:
            return True

        return False
Exemple #16
0
 def connection_time(self):
     return ntp.getTime() - self._connected_at
Exemple #17
0
 def is_expired(self):
     return self.timestamp - ntp.getTime() > config.user.outgoing_message_expiry
Exemple #18
0
 def __init__(self, priority, message):
     self.priority = priority
     self.timestamp = int(ntp.getTime())
     self.message = message
Exemple #19
0
 def uptime(self):
     return ntp.getTime() - self.start_time
Exemple #20
0
 def test_getTime(self):
     setDrift()
     time = getTime()
     self.assertIsNotNone(time)
Exemple #21
0
 def add(self, x):
     current_time = ntp.getTime()
     self._data[x] = current_time + self.expiration_time
     self._store()
Exemple #22
0
 def uptime_network(self):
     block_one = self._chain_manager.get_block_by_number(1)
     network_uptime = 0
     if block_one:
         network_uptime = ntp.getTime() - block_one.timestamp
     return network_uptime
Exemple #23
0
 def __init__(self, tx: Transaction, block_number: int, timestamp: int=None):
     self._transaction = tx
     self._block_number = block_number
     self._timestamp = timestamp
     if not self._timestamp:
         self._timestamp = ntp.getTime()