Exemple #1
0
    def start_mining(self, parent_block: Block, parent_difficulty):
        try:
            logger.debug('start_mining - TRY LOCK')
            with self.lock:
                logger.debug('start_mining - LOCKED')
                self.cancel()

                mining_blob = self._mining_block.mining_blob
                nonce_offset = self._mining_block.mining_nonce_offset

                logger.debug('!!! Mine #{} | {} ({}) | {} -> {} | {} '.format(
                    self._mining_block.block_number, self._measurement,
                    self._mining_block.timestamp - parent_block.timestamp,
                    UInt256ToString(parent_difficulty),
                    UInt256ToString(self._current_difficulty),
                    bin2hstr(bytearray(self._current_target))))
                logger.debug('!!! Mine #{} | blob: {}'.format(
                    self._mining_block.block_number,
                    bin2hstr(bytearray(mining_blob))))

                work_seq_id = self.start(
                    input=mining_blob,
                    nonceOffset=nonce_offset,
                    target=self._current_target,
                    thread_count=self._mining_thread_count)

                logger.debug("MINING START [{}]".format(work_seq_id))

        except Exception as e:
            logger.warning("Exception in start_mining")
            logger.exception(e)

        logger.debug('start_mining - UNLOCKED')
    def start_mining(self, parent_block: Block, parent_difficulty):

        mining_xmss = self.get_mining_xmss()
        if not mining_xmss:
            logger.warning('No Mining XMSS Found')
            return

        try:
            self.cancel()

            mining_blob = self._mining_block.mining_blob
            nonce_offset = self._mining_block.mining_nonce_offset

            logger.debug('!!! Mine #{} | {} ({}) | {} -> {} | {}'.format(
                self._mining_block.block_number, self._measurement,
                self._mining_block.timestamp - parent_block.timestamp,
                UInt256ToString(parent_difficulty),
                UInt256ToString(self._current_difficulty),
                self._current_target))

            self.start(input=mining_blob,
                       nonceOffset=nonce_offset,
                       target=self._current_target,
                       thread_count=self._mining_thread_count)
        except Exception as e:
            logger.warning("Exception in start_mining")
            logger.exception(e)
Exemple #3
0
    def _add_block_metadata(self, headerhash, block_timestamp,
                            parent_headerhash, batch):
        block_metadata = self._state.get_block_metadata(headerhash)
        if not block_metadata:
            block_metadata = BlockMetadata.create()

        parent_metadata = self._state.get_block_metadata(parent_headerhash)

        parent_block_difficulty = parent_metadata.block_difficulty
        parent_cumulative_difficulty = parent_metadata.cumulative_difficulty

        block_metadata.update_last_headerhashes(
            parent_metadata.last_N_headerhashes, parent_headerhash)
        measurement = self._state.get_measurement(block_timestamp,
                                                  parent_headerhash,
                                                  parent_metadata)

        block_difficulty, _ = DifficultyTracker.get(
            measurement=measurement, parent_difficulty=parent_block_difficulty)

        block_cumulative_difficulty = StringToUInt256(
            str(
                int(UInt256ToString(block_difficulty)) +
                int(UInt256ToString(parent_cumulative_difficulty))))

        block_metadata.set_block_difficulty(block_difficulty)
        block_metadata.set_cumulative_difficulty(block_cumulative_difficulty)

        parent_metadata.add_child_headerhash(headerhash)
        self._state.put_block_metadata(parent_headerhash, parent_metadata,
                                       batch)
        self._state.put_block_metadata(headerhash, block_metadata, batch)

        return block_metadata
Exemple #4
0
    def validate_mining_nonce(self, block, enable_logging=False):
        parent_metadata = self.state.get_block_metadata(block.prev_headerhash)
        parent_block = self.state.get_block(block.prev_headerhash)

        measurement = self.state.get_measurement(block.timestamp,
                                                 block.prev_headerhash,
                                                 parent_metadata)
        diff, target = DifficultyTracker.get(
            measurement=measurement,
            parent_difficulty=parent_metadata.block_difficulty)

        if enable_logging:
            logger.debug('-----------------START--------------------')
            logger.debug('Validate #%s', block.block_number)
            logger.debug('block.timestamp %s', block.timestamp)
            logger.debug('parent_block.timestamp %s', parent_block.timestamp)
            logger.debug('parent_block.difficulty %s',
                         UInt256ToString(parent_metadata.block_difficulty))
            logger.debug('diff : %s | target : %s', UInt256ToString(diff),
                         target)
            logger.debug('-------------------END--------------------')

        if not self.verify_input_cached(block.mining_blob, target):
            if enable_logging:
                logger.warning("PoW verification failed")
                qn = Qryptonight()
                tmp_hash = qn.hash(block.mining_blob)
                logger.warning("{}".format(tmp_hash))
                logger.debug('%s', block.to_json())
            return False

        return True
Exemple #5
0
 def start_mining(self, parent_block: Block, parent_difficulty,
                  dev_config: DevConfig):
     logger.debug('!!! Mine #{} | {} ({}) | {} -> {} | {} '.format(
         self._mining_block.block_number, self._measurement,
         self._mining_block.timestamp - parent_block.timestamp,
         UInt256ToString(parent_difficulty),
         UInt256ToString(self._current_difficulty),
         bin2hstr(bytearray(self._current_target))))
     logger.debug('!!! Mine #{} | blob: {}'.format(
         self._mining_block.block_number,
         bin2hstr(bytearray(self._mining_block.mining_blob(dev_config)))))
     miner = self.get_miner(parent_block.block_number + 1, dev_config)
     miner.start_mining(self._mining_block, self._current_target,
                        dev_config)
Exemple #6
0
    def get_better_difficulty(self, current_cumulative_difficulty):
        best_cumulative_difficulty = int(UInt256ToString(current_cumulative_difficulty))
        local_best = best_cumulative_difficulty
        best_channel = None

        for channel in self._peer_node_status:
            node_chain_state = self._peer_node_status[channel]
            node_cumulative_difficulty = int(UInt256ToString(node_chain_state.cumulative_difficulty))
            if node_cumulative_difficulty > best_cumulative_difficulty:
                best_cumulative_difficulty = node_cumulative_difficulty
                best_channel = channel
        logger.debug('Local Best Diff : %s', local_best)
        logger.debug('Remote Best Diff : %s', best_cumulative_difficulty)
        return best_channel
Exemple #7
0
    def _try_branch_add_block(self,
                              block,
                              batch,
                              check_stale=True) -> (bool, bool):
        """
        This function returns list of bool types. The first bool represent
        if the block has been added successfully and the second bool
        represent the fork_flag, which becomes true when a block triggered
        into fork recovery.
        :param block:
        :param batch:
        :return: [Added successfully, fork_flag]
        """
        if self._last_block.headerhash == block.prev_headerhash:
            if not self._apply_block(block, batch):
                return False, False

        self._state.put_block(block, batch)

        last_block_metadata = self._state.get_block_metadata(
            self._last_block.headerhash)
        if last_block_metadata is None:
            logger.warning("Could not find log metadata for %s",
                           bin2hstr(self._last_block.headerhash))
            return False, False

        last_block_difficulty = int(
            UInt256ToString(last_block_metadata.cumulative_difficulty))

        new_block_metadata = self._add_block_metadata(block.headerhash,
                                                      block.timestamp,
                                                      block.prev_headerhash,
                                                      batch)
        new_block_difficulty = int(
            UInt256ToString(new_block_metadata.cumulative_difficulty))

        if new_block_difficulty > last_block_difficulty:
            if self._last_block.headerhash != block.prev_headerhash:
                fork_state = qrlstateinfo_pb2.ForkState(
                    initiator_headerhash=block.headerhash)
                self._state.put_fork_state(fork_state, batch)
                self._state.write_batch(batch)
                return self._fork_recovery(block, fork_state), True

            self._update_chainstate(block, batch)
            if check_stale:
                self.tx_pool.check_stale_txn(self._state, block.block_number)
            self.trigger_miner = True

        return True, False
Exemple #8
0
    def _try_branch_add_block(self, block, batch=None) -> bool:
        parent_block = self.state.get_block(block.prev_headerhash)
        if not block.validate_parent_child_relation(parent_block):
            logger.warning('Failed to validate blocks parent child relation')
            return False

        address_set = self.state.prepare_address_list(
            block)  # Prepare list for current block
        if self.last_block.headerhash == block.prev_headerhash:
            address_txn = self.state.get_state_mainchain(address_set)
        else:
            address_txn = self.state.get_state(block.prev_headerhash,
                                               address_set)

        if self.validate_block(block, address_txn):
            self.state.put_block(block, None)
            self.add_block_metadata(block.headerhash, block.timestamp,
                                    block.prev_headerhash, None)

            last_block_metadata = self.state.get_block_metadata(
                self.last_block.headerhash)
            new_block_metadata = self.state.get_block_metadata(
                block.headerhash)
            last_block_difficulty = int(
                UInt256ToString(last_block_metadata.cumulative_difficulty))
            new_block_difficulty = int(
                UInt256ToString(new_block_metadata.cumulative_difficulty))

            self.trigger_miner = False
            if new_block_difficulty > last_block_difficulty:
                if self.last_block.headerhash != block.prev_headerhash:
                    self.rollback(block)
                    return True

                self.state.update_mainchain_state(address_txn,
                                                  block.block_number,
                                                  block.headerhash)
                self.last_block = block
                self._update_mainchain(block, batch)
                self.tx_pool.remove_tx_in_block_from_pool(block)
                self.state.update_mainchain_height(block.block_number, batch)
                self.state.update_tx_metadata(block, batch)

                self.trigger_miner = True

            return True

        return False
Exemple #9
0
    def get_block_datapoint(self, headerhash):
        block = self.get_block(headerhash)
        if block is None:
            return None

        block_metadata = self.get_block_metadata(headerhash)
        prev_block_metadata = self.get_block_metadata(block.prev_headerhash)
        prev_block = self.get_block(block.prev_headerhash)

        data_point = qrl_pb2.BlockDataPoint()
        data_point.number = block.block_number
        data_point.header_hash = headerhash
        if prev_block is not None:
            data_point.header_hash_prev = prev_block.headerhash
        data_point.timestamp = block.timestamp
        data_point.time_last = 0
        data_point.time_movavg = 0
        data_point.difficulty = UInt256ToString(
            block_metadata.block_difficulty)

        if prev_block is not None:
            data_point.time_last = block.timestamp - prev_block.timestamp
            if prev_block.block_number == 0:
                data_point.time_last = config.dev.mining_setpoint_blocktime

            movavg = self.get_measurement(block.timestamp,
                                          block.prev_headerhash,
                                          prev_block_metadata)
            data_point.time_movavg = movavg

            # FIXME: need to consider average difficulty here
            data_point.hash_power = int(data_point.difficulty) * (
                config.dev.mining_setpoint_blocktime / movavg)

        return data_point
Exemple #10
0
    def handle_block_height(self, source,
                            message: xrdlegacy_pb2.LegacyMessage):
        """
        Sends / Receives Blockheight
        :param source:
        :param message:
        :return:
        """
        if message.bhData.block_number == 0:
            block = source.factory.last_block
            cumulative_difficulty = source.factory.get_cumulative_difficulty()
            if block.block_number == 0:
                return
            bhdata = xrd_pb2.BlockHeightData(
                block_number=block.block_number,
                block_headerhash=block.headerhash,
                cumulative_difficulty=bytes(cumulative_difficulty))
            msg = xrdlegacy_pb2.LegacyMessage(
                func_name=xrdlegacy_pb2.LegacyMessage.BH, bhData=bhdata)
            source.send(msg)
            return

        try:
            UInt256ToString(message.bhData.cumulative_difficulty)
        except ValueError:
            logger.warning('Invalid Block Height Data')
            source.loseConnection()
            return

        source.factory.update_peer_blockheight(
            source.peer.full_address, message.bhData.block_number,
            message.bhData.block_headerhash,
            message.bhData.cumulative_difficulty)
Exemple #11
0
 def update_peer_blockheight(self, addr_remote, block_number, headerhash,
                             cumulative_difficulty):
     # FIXME: Use a named tuple to improve readability?
     self.peer_blockheight[addr_remote] = [
         block_number, headerhash,
         int(UInt256ToString(cumulative_difficulty))
     ]
Exemple #12
0
def main():
    ph = PoWHelper()
    qm = CustomQMiner()

    input_bytes = [0x03, 0x05, 0x07, 0x09, 0x19]
    difficulty = StringToUInt256("5000")

    for i in range(10):
        boundary = ph.getBoundary(difficulty)

        #       print("difficulty     ", difficulty)
        print("difficulty str ", UInt256ToString(difficulty))
        print("boundary       ", boundary)
        #        print("boundary str   ", UInt256ToString(boundary))

        start = time.time()

        # Set input bytes, nonce
        qm.setInput(input=input_bytes, nonceOffset=0, target=boundary)

        qm.start(thread_count=2)

        while not qm.solutionFound():
            time.sleep(1)

        print("time           ", qm.end - start)
        print("hash           ", qm.solutionHash())
        print()

        # Set a new difficulty
        difficulty = ph.getDifficulty(int(qm.end), int(start), difficulty)
Exemple #13
0
    def add_block_metadata(self, headerhash, block_timestamp,
                           parent_headerhash, batch):
        block_metadata = self.state.get_block_metadata(headerhash)
        if not block_metadata:
            block_metadata = BlockMetadata.create()

        parent_metadata = self.state.get_block_metadata(parent_headerhash)
        block_difficulty = (0, ) * 32  # 32 bytes to represent 256 bit of 0
        block_cumulative_difficulty = (
            0, ) * 32  # 32 bytes to represent 256 bit of 0
        if not parent_metadata:
            parent_metadata = BlockMetadata.create()
        else:
            parent_block = self.state.get_block(parent_headerhash)
            if parent_block:
                parent_block_difficulty = parent_metadata.block_difficulty
                parent_cumulative_difficulty = parent_metadata.cumulative_difficulty

                if not parent_metadata.is_orphan:
                    block_metadata.update_last_headerhashes(
                        parent_metadata.last_N_headerhashes, parent_headerhash)
                    measurement = self.state.get_measurement(
                        block_timestamp, parent_headerhash, parent_metadata)

                    block_difficulty, _ = DifficultyTracker.get(
                        measurement=measurement,
                        parent_difficulty=parent_block_difficulty)

                    block_cumulative_difficulty = StringToUInt256(
                        str(
                            int(UInt256ToString(block_difficulty)) +
                            int(UInt256ToString(parent_cumulative_difficulty)))
                    )

        block_metadata.set_orphan(parent_metadata.is_orphan)
        block_metadata.set_block_difficulty(block_difficulty)
        block_metadata.set_cumulative_difficulty(block_cumulative_difficulty)

        parent_metadata.add_child_headerhash(headerhash)
        self.state.put_block_metadata(parent_headerhash, parent_metadata,
                                      batch)
        self.state.put_block_metadata(headerhash, block_metadata, batch)

        # Call once to populate the cache
        self.state.get_block_datapoint(headerhash)
Exemple #14
0
    def validate_mining_nonce(self,
                              blockheader: BlockHeader,
                              enable_logging=True):
        with self.lock:
            parent_metadata = self.get_block_metadata(
                blockheader.prev_headerhash)
            parent_block = self._state.get_block(blockheader.prev_headerhash)

            measurement = self.get_measurement(blockheader.timestamp,
                                               blockheader.prev_headerhash,
                                               parent_metadata)
            diff, target = DifficultyTracker.get(
                measurement=measurement,
                parent_difficulty=parent_metadata.block_difficulty)

            if enable_logging:
                logger.debug('-----------------START--------------------')
                logger.debug('Validate                #%s',
                             blockheader.block_number)
                logger.debug('block.timestamp         %s',
                             blockheader.timestamp)
                logger.debug('parent_block.timestamp  %s',
                             parent_block.timestamp)
                logger.debug('parent_block.difficulty %s',
                             UInt256ToString(parent_metadata.block_difficulty))
                logger.debug('diff                    %s',
                             UInt256ToString(diff))
                logger.debug('target                  %s', bin2hstr(target))
                logger.debug('-------------------END--------------------')

            if not PoWValidator().verify_input(blockheader.mining_blob,
                                               target):
                if enable_logging:
                    logger.warning("PoW verification failed")
                    qn = Qryptonight()
                    tmp_hash = qn.hash(blockheader.mining_blob)
                    logger.warning("{}".format(bin2hstr(tmp_hash)))
                    logger.debug('%s', blockheader.to_json())
                return False

            return True
Exemple #15
0
    def _try_branch_add_block(self, block, batch=None) -> bool:
        address_set = self.state.prepare_address_list(
            block)  # Prepare list for current block
        if self.last_block.headerhash == block.prev_headerhash:
            address_txn = self.state.get_state_mainchain(address_set)
        else:
            address_txn, rollback_headerhash, hash_path = self.state.get_state(
                block.prev_headerhash, address_set)

        if block.apply_state_changes(address_txn):
            self.state.put_block(block, None)
            self.add_block_metadata(block.headerhash, block.timestamp,
                                    block.prev_headerhash, None)

            last_block_metadata = self.state.get_block_metadata(
                self.last_block.headerhash)
            new_block_metadata = self.state.get_block_metadata(
                block.headerhash)
            last_block_difficulty = int(
                UInt256ToString(last_block_metadata.cumulative_difficulty))
            new_block_difficulty = int(
                UInt256ToString(new_block_metadata.cumulative_difficulty))

            if new_block_difficulty > last_block_difficulty:
                if self.last_block.headerhash != block.prev_headerhash:
                    self.rollback(rollback_headerhash, hash_path,
                                  block.block_number)

                self.state.put_addresses_state(address_txn)
                self.last_block = block
                self._update_mainchain(block, batch)
                self.tx_pool.remove_tx_in_block_from_pool(block)
                self.tx_pool.check_stale_txn(block.block_number)
                self.state.update_mainchain_height(block.block_number, batch)
                self.state.update_tx_metadata(block, batch)

                self.trigger_miner = True

            return True

        return False
Exemple #16
0
    def test_adaptive_target(self):
        ph = PoWHelper()

        parent_difficulty = StringToUInt256("5000")

        current_difficulty = ph.getDifficulty(
            measurement=104, parent_difficulty=parent_difficulty)

        expected_difficulty = '4644'

        print(parent_difficulty)
        print(expected_difficulty)
        print(current_difficulty)

        self.assertEqual(expected_difficulty,
                         UInt256ToString(current_difficulty))

        target = ph.getTarget(current_difficulty)
        expected_target = "12766941454368345787240450318120704813017110301439674670851728194227068997120"

        self.assertEqual(expected_target, UInt256ToString(target))
Exemple #17
0
    def handle_chain_state(self, source, message: qrllegacy_pb2.LegacyMessage):
        P2PBaseObserver._validate_message(message, qrllegacy_pb2.LegacyMessage.CHAINSTATE)

        message.chainStateData.timestamp = ntp.getTime()  # Receiving time

        try:
            UInt256ToString(message.chainStateData.cumulative_difficulty)
        except ValueError:
            logger.warning('Invalid Cumulative Difficulty sent by peer')
            source.loseConnection()
            return

        self._peer_node_status[source] = message.chainStateData
Exemple #18
0
def main():
    persistent_state = State()
    chain_manager = ChainManager(state=persistent_state)
    chain_manager.load(GenesisBlock())

    ph = PoWHelper()
    difficulty = StringToUInt256('5000')

    filename = os.path.expanduser(
        "~/crypto/qryptonight/modeling/blockdata.csv")

    with open(filename, 'w') as f:
        f.write("i,timestamp,prev_timestamp,delta,difficulty,target\n")
        prev_timestamp = None
        for i in range(chain_manager.height):
            block = chain_manager.get_block_by_number(i)

            if i == 0:
                prev_timestamp = block.blockheader.timestamp
                continue

            target = ph.getTarget(difficulty)
            delta = block.blockheader.timestamp - prev_timestamp

            outs = "{},{},{},{},{},{}\n".format(i, block.blockheader.timestamp,
                                                prev_timestamp, delta,
                                                UInt256ToString(difficulty),
                                                UInt256ToString(target))

            f.write(outs)

            difficulty = ph.getDifficulty(block.blockheader.timestamp,
                                          prev_timestamp, difficulty)
            difficulty = StringToUInt256(
                str(max(2, int(UInt256ToString(difficulty)))))
            prev_timestamp = block.blockheader.timestamp
Exemple #19
0
    def handle_chain_state(self, source, message: qrllegacy_pb2.LegacyMessage):
        P2PBaseObserver._validate_message(message, qrllegacy_pb2.LegacyMessage.CHAINSTATE)

        message.chainStateData.timestamp = ntp.getTime()  # Receiving time

        try:
            UInt256ToString(message.chainStateData.cumulative_difficulty)
        except ValueError:
            logger.warning('Invalid Cumulative Difficulty sent by peer')
            source.loseConnection()
            return

        self._peer_node_status[source] = message.chainStateData

        if not self._get_version_compatibility(message.chainStateData.version):
            logger.warning("Disconnecting from Peer %s running incompatible node version %s",
                           source.peer.ip,
                           message.veData.version)
            source.loseConnection()
            return
Exemple #20
0
    def test_numberBack(self):
        input_vector = (
            122,
            19,
            248,
            230,
            14,
            172,
            65,
            216,
            102,
            28,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
        )

        value = UInt256ToString(input_vector)

        expected_value = "55217455456816260776929245529948378455782781241038999928326084774751073468416"

        self.assertEqual(expected_value, value)
Exemple #21
0
 def test_empty(self):
     with self.assertRaises(TypeError):
         UInt256ToString(None)
     with self.assertRaises(ValueError):
         UInt256ToString(b'')
Exemple #22
0
 def update_peer_blockheight(self, connection_id, block_number, headerhash,
                             cumulative_difficulty):
     self.peer_blockheight[connection_id] = [
         block_number, headerhash,
         int(UInt256ToString(cumulative_difficulty))
     ]
Exemple #23
0
difficulty = StringToUInt256('5000')
delta = 0

filename = os.path.expanduser("~/crypto/qryptonight/modeling/blockdata.csv")

with open(filename, 'w') as f:
    f.write("i,timestamp,prev_timestamp,delta,difficulty,boundary\n")
    prev_timestamp = None
    for i in range(chain_manager.height):
        block = chain_manager.get_block_by_number(i)

        if i == 0:
            prev_timestamp = block.blockheader.timestamp
            continue

        boundary = ph.getBoundary(difficulty)
        delta = block.blockheader.timestamp - prev_timestamp

        outs = "{},{},{},{},{},{}\n".format(i,
                                            block.blockheader.timestamp,
                                            prev_timestamp,
                                            delta,
                                            UInt256ToString(difficulty),
                                            UInt256ToString(boundary))

        f.write(outs)

        difficulty = ph.getDifficulty(block.blockheader.timestamp, prev_timestamp, difficulty)
        difficulty = StringToUInt256(str(max(2, int(UInt256ToString(difficulty)))))
        prev_timestamp = block.blockheader.timestamp
Exemple #24
0
difficulty = StringToUInt256('5000')
delta = 0

filename = os.path.expanduser("~/crypto/qryptonight/modeling/blockdata.csv")

with open(filename, 'w') as f:
    f.write("i,timestamp,prev_timestamp,delta,difficulty,target\n")
    prev_timestamp = None
    for i in range(chain_manager.height):
        block = chain_manager.get_block_by_number(i)

        if i == 0:
            prev_timestamp = block.blockheader.timestamp
            continue

        target = ph.getTarget(difficulty)
        delta = block.blockheader.timestamp - prev_timestamp

        outs = "{},{},{},{},{},{}\n".format(i, block.blockheader.timestamp,
                                            prev_timestamp, delta,
                                            UInt256ToString(difficulty),
                                            UInt256ToString(target))

        f.write(outs)

        difficulty = ph.getDifficulty(block.blockheader.timestamp,
                                      prev_timestamp, difficulty)
        difficulty = StringToUInt256(
            str(max(2, int(UInt256ToString(difficulty)))))
        prev_timestamp = block.blockheader.timestamp