예제 #1
0
    def monitor(self) -> None:
        # Check if node is accessible
        live_check_unsafe(self.node.rpc_url + '/health', self._logger)
        self.node.set_as_up(self.channels, self.logger)

        # Get status
        status = get_cosmos_json(self.node.rpc_url + '/status', self._logger)

        # Set voting power
        voting_power = int(status['validator_info']['voting_power'])
        self._logger.debug('%s voting power: %s', self.node, voting_power)
        self.node.set_voting_power(voting_power, self.channels, self.logger)

        # Set catching-up
        catching_up = status['sync_info']['catching_up']
        self._logger.debug('%s catching up: %s', self.node, catching_up)
        self.node.set_catching_up(catching_up, self.channels, self.logger)

        # Get net_info
        net_info = get_cosmos_json(self.node.rpc_url + '/net_info',
                                   self._logger)

        # Set number of peers
        no_of_peers = int(net_info['n_peers'])
        self._logger.debug('%s no. of peers: %s', self.node, no_of_peers)
        self.node.set_no_of_peers(no_of_peers, self.channels, self.logger)

        # Output status
        self._logger.info('%s status: %s', self.node, self.node.status())
예제 #2
0
    def monitor(self) -> None:
        # Get abci_info and, from that, the last height to be checked
        abci_info = get_cosmos_json(self.node.rpc_url + '/abci_info',
                                    self._logger)
        last_height_to_check = int(abci_info['response']['last_block_height'])

        # If this is the first height being checked, ignore previous heights
        if self._last_height_checked is None:
            self._last_height_checked = last_height_to_check - 1

        # Consider any height that is after the previous last height
        height = self._last_height_checked + 1
        while height <= last_height_to_check:
            self._logger.info('%s obtaining data at height %s',
                              self._monitor_name, height)

            # Get block
            block = get_cosmos_json(
                self.node.rpc_url + '/block?height=' + str(height),
                self._logger)

            # Get validators participating in the precommits of last commit
            block_precommits = block['block']['last_commit']['precommits']
            non_null_precommits = filter(lambda p: p, block_precommits)
            block_precommits_validators = set(
                map(lambda p: p['validator_address'], non_null_precommits))
            total_no_of_missing_validators = \
                len(block_precommits) - len(block_precommits_validators)

            self._logger.debug('Precommit validators: %s',
                               block_precommits_validators)
            self._logger.debug('Total missing validators: %s',
                               total_no_of_missing_validators)

            # Call method based on whether block missed or not
            for v in self._all_validators:
                if v.pubkey not in block_precommits_validators:
                    block_time = block['block']['header']['time']
                    v.add_missed_block(
                        height -
                        1,  # '- 1' since it's actually previous height
                        dateutil.parser.parse(block_time, ignoretz=True),
                        total_no_of_missing_validators,
                        self.channels,
                        self.logger)
                else:
                    v.clear_missed_blocks(self.channels, self.logger)

            self._logger.debug('Moving to next height.')

            # Move to next block
            height += 1

            # If there is a next height to check, sleep for a bit
            if height <= last_height_to_check:
                self.logger.debug('Sleeping for 0.5 second between heights.')
                sleep(0.5)

        self._last_height_checked = last_height_to_check
예제 #3
0
    def monitor(self) -> None:
        # Get node status and, from that, the last height to be checked
        status = get_cosmos_json(self.node.rpc_url + '/status', self._logger)
        last_height_to_check = int(status['sync_info']['latest_block_height'])

        # If the chain has not started, return as there are no blocks to get
        if last_height_to_check == 0:
            return

        # If this is the first height being checked, ignore previous heights
        if self._last_height_checked is None:
            self._last_height_checked = last_height_to_check - 1

        # Consider any height that is after the previous last height
        height = self._last_height_checked + 1
        if last_height_to_check - self._last_height_checked > \
                self.network_monitor_max_catch_up_blocks:
            height = last_height_to_check - \
                     self.network_monitor_max_catch_up_blocks
            self._check_block(height)
            self._last_height_checked = height
        elif height <= last_height_to_check:
            self._check_block(height)
            self._last_height_checked = height

        if last_height_to_check - self._last_height_checked > 2:
            self._monitor_is_syncing = True
        else:
            self._monitor_is_syncing = False
예제 #4
0
def node_from_node_config(node_config: NodeConfig):
    # Test connection
    log_and_print('Trying to connect to {}/status'
                  ''.format(node_config.node_rpc_url))
    try:
        node_status = get_cosmos_json(node_config.node_rpc_url + '/status',
                                      logger_general)
        log_and_print('Success.')
    except Exception:
        raise InitialisationException('Failed to connect to {} at {}'.format(
            node_config.node_name, node_config.node_rpc_url))

    # Get node type
    node_type = NodeType.VALIDATOR_FULL_NODE \
        if node_config.node_is_validator \
        else NodeType.NON_VALIDATOR_FULL_NODE

    # Get pubkey if validator
    if node_config.node_is_validator:
        pubkey = node_status['validator_info']['address']
    else:
        pubkey = None

    # Get network
    network = node_status['node_info']['network']

    # Initialise node and load any state
    node = Node(node_config.node_name, node_config.node_rpc_url, node_type,
                pubkey, network, REDIS)
    node.load_state(logger_general)

    # Return node
    return node
예제 #5
0
    def _check_block(self, height: int) -> None:
        self._logger.info('%s obtaining data at height %s', self._monitor_name,
                          height)

        # Get block
        block = get_cosmos_json(
            self.node.rpc_url + '/block?height=' + str(height), self._logger)

        # Get validators participating in the precommits of last commit
        last_commit = block['block']['last_commit']
        if 'precommits' in last_commit:
            block_precommits = last_commit['precommits']  # tendermint <v0.33
            non_null_precommits = \
                filter(lambda p: p, block_precommits)
        else:
            block_precommits = last_commit['signatures']  # tendermint v0.33+
            non_null_precommits = \
                filter(lambda p: p['signature'], block_precommits)
        block_precommits_validators = set(
            map(lambda p: p['validator_address'], non_null_precommits))
        total_no_of_missing_validators = \
            len(block_precommits) - len(block_precommits_validators)

        self._logger.debug('Precommit validators: %s',
                           block_precommits_validators)
        self._logger.debug('Total missing validators: %s',
                           total_no_of_missing_validators)

        # Call method based on whether block missed or not
        for v in self._all_validators:
            if v.pubkey not in block_precommits_validators:
                block_time = block['block']['header']['time']
                v.add_missed_block(
                    height - 1,  # '- 1' since it's actually previous height
                    dateutil.parser.parse(block_time, ignoretz=True),
                    total_no_of_missing_validators,
                    self.channels,
                    self.logger)
            else:
                v.clear_missed_blocks(self.channels, self.logger)

        self._logger.debug('Moving to next height.')
예제 #6
0
 def test_get_cosmos_json_returns_result_of_get_json(self, _):
     self.assertEqual(RESULT, get_cosmos_json(ENDPOINT, LOGGER))