Exemple #1
0
class Ethash(MiningAlgorithm):
    def __init__(self, block: Block, **kwargs):
        is_test = kwargs.get("is_test", False)
        self.miner = EthashMiner(
            block.header.height,
            block.header.difficulty,
            block.header.get_hash_for_mining(),
            is_test=is_test,
        )
        self.nonce_found, self.mixhash = None, None

    def mine(self, start_nonce: int, end_nonce: int) -> bool:
        nonce_found, mixhash = self.miner.mine(end_nonce - start_nonce, start_nonce)
        if not nonce_found:
            return False
        self.nonce_found = nonce_found
        self.mixhash = mixhash
        return True

    def post_process_mined_block(self, block: Block):
        if not self.nonce_found:
            raise RuntimeError("cannot post process since no nonce found")
        block.header.nonce = int.from_bytes(self.nonce_found, byteorder="big")
        block.header.mixhash = self.mixhash
        super().post_process_mined_block(block)
Exemple #2
0
class Ethash(MiningAlgorithm):
    def __init__(self, work: MiningWork, **kwargs):
        is_test = kwargs.get("is_test", False)
        self.miner = EthashMiner(work.height,
                                 work.difficulty,
                                 work.hash,
                                 is_test=is_test)

    def mine(self, start_nonce: int, end_nonce: int) -> Optional[MiningResult]:
        nonce_found, mixhash = self.miner.mine(end_nonce - start_nonce,
                                               start_nonce)
        if not nonce_found:
            return None
        return MiningResult(
            self.miner.header_hash,
            int.from_bytes(nonce_found, byteorder="big"),
            mixhash,
        )
Exemple #3
0
    def mine_ethash(
        block: Union[MinorBlock, RootBlock],
        input_q: MultiProcessingQueue,
        output_q: MultiProcessingQueue,
        mining_params: Dict,
    ):
        # TODO: maybe add rounds to config json
        rounds = mining_params.get("rounds", 100)
        is_test = mining_params.get("is_test", False)
        # outer loop for mining forever
        while True:
            # `None` block means termination
            if not block:
                output_q.put(None)
                return

            header_hash = block.header.get_hash_for_mining()
            block_number = block.header.height
            difficulty = block.header.difficulty
            miner = EthashMiner(block_number, difficulty, header_hash, is_test)
            start_nonce = 0
            # inner loop for iterating nonce
            while True:
                nonce_found, mixhash = miner.mine(rounds, start_nonce)
                # best case
                if nonce_found:
                    block.header.nonce = int.from_bytes(nonce_found,
                                                        byteorder="big")
                    block.header.mixhash = mixhash
                    Miner._post_process_mined_block(block)
                    output_q.put(block)
                    block, _ = input_q.get(block=True)  # blocking
                    break  # break inner loop to refresh mining params
                # check if new block arrives. if yes, discard current progress and restart
                try:
                    block, _ = input_q.get_nowait()
                    break  # break inner loop to refresh mining params
                except Exception:  # queue empty
                    pass
                # update param and keep mining
                start_nonce += rounds