async def eth_submitHashrate(hashrate: str, miner_wallet: str,
                                 worker_name: str="") -> bool:
        hashrate_int, miner_wallet_bytes = h2i(hashrate), h2b(miner_wallet)
        worker_name = valid_worker_name(worker_name)

        hr_record = miner.HashRate.log(hashrate_int, miner_wallet, worker_name)
        if not hr_record:
            return False

        return True
Beispiel #2
0
    def test_vectors(self):
        vectors = json.load(
            open(os.path.join(cur_dir, "schnorr.fixtures.json")))
        for vector in random.choices(vectors, k=50):
            for key in vector:
                vector[key] = h2b(vector[key])

            sign = schnorr.sign_with_k(vector["msg"], vector["priv"],
                                       b2i(vector["k"]))
            assert not not sign

            r, s = schnorr.decode_signature(sign)
            assert r == b2i(vector["r"])
            assert s == b2i(vector["s"])

            sign = schnorr.encode_signature(r, s)

            assert schnorr.verify(vector["msg"], sign, vector["pub"])
Beispiel #3
0
    async def eth_submitWork(request,
                             nonce: str,
                             header: str,
                             mix_digest: str,
                             boundary: str = "",
                             miner_wallet: str = "",
                             worker_name: str = "") -> bool:
        assert (len(nonce) == 18 and len(header) == 66
                and len(mix_digest) == 66 and len(boundary) in [0, 66]
                and len(miner_wallet) in [0, 40, 42] and len(worker_name) < 64)

        if not miner_wallet:
            miner_wallet = default_miner

        if config["zilliqa"]["enabled"]:
            if not blockchain.Zilliqa.is_pow_window():
                return False

        # 1. validate user input parameters
        nonce_int = h2i(nonce)
        worker_name = valid_worker_name(worker_name)
        miner_wallet_bytes = h2b(miner_wallet)
        mix_digest_bytes = h2b(mix_digest)

        # 2. get or create miner/worker
        _miner = miner.Miner.get_or_create(miner_wallet, worker_name)
        _worker = miner.Worker.get_or_create(miner_wallet, worker_name)
        if not _miner or not _worker:
            logging.warning(
                "miner/worker not found, {worker_name}@{miner_wallet}")
            return False

        if _worker is not None:
            _worker.update_stat(inc_submitted=1)

        # 3. check work existing
        work = pow.PowWork.find_work_by_header_boundary(header=header,
                                                        boundary=boundary,
                                                        check_expired=True)
        if not work:
            logging.warning(f"work not found or expired, {header} {boundary}")
            _worker.update_stat(inc_failed=1)
            return False

        # 4. verify result
        seed, header = h2b(work.seed), h2b(work.header)
        boundary_bytes = h2b(work.boundary)
        block_num = ethash.seed_to_block_num(seed)
        hash_result = ethash.verify_pow_work(block_num, header,
                                             mix_digest_bytes, nonce_int,
                                             boundary_bytes)
        if not hash_result:
            logging.warning(
                f"wrong result from miner {miner_wallet}-{worker_name}, {work}"
            )
            _worker.update_stat(inc_failed=1)
            return False

        # 5. check the result if lesser than old one
        if work.finished:
            prev_result = pow.PowResult.get_pow_result(work.header,
                                                       work.boundary)
            if prev_result:
                if prev_result.verified:
                    logging.info(
                        f"submitted too late, work is verified. {work.header} {work.boundary}"
                    )
                    _worker.update_stat(inc_failed=1)
                    return False

                if ethash.is_less_or_equal(prev_result.hash_result,
                                           hash_result):
                    logging.info(
                        f"submitted result > old result, ignored. {work.header} {work.boundary}"
                    )
                    _worker.update_stat(inc_failed=1)
                    return False

        # 6. save to database
        hash_result_str = b2h(hash_result, prefix="0x")
        if not work.save_result(nonce, mix_digest, hash_result_str,
                                miner_wallet, worker_name):
            logging.warning(f"failed to save result for miner "
                            f"{miner_wallet}-{worker_name}, {work}")
            return False

        logging.critical(f"Work submitted, {work.header} {work.boundary}")

        _worker.update_stat(inc_finished=1)

        # 6. todo: miner reward
        return True
    def process_submit(self, jsonMsg):
        work = None
        mix_digest = None
        miner_wallet = self.miner_wallet
        worker_name = None
        hash_result = None
        _worker = None
        if jsonMsg["id"] is None:
            logging.warning("Submitted result message without id")
            return

        id = jsonMsg["id"]
        if self.stratumMiner._stratusVersion == STRATUM_BASIC:
            nonce = jsonMsg["params"][2]
            nonce_int = h2i(nonce)
            header = jsonMsg["params"][3]
            mix_digest = jsonMsg["params"][4]
            boundary = self.stratumMiner._boundary
            mix_digest_bytes = h2b(mix_digest)
            worker_name = jsonMsg["worker"]
            _worker = miner.Worker.get_or_create(miner_wallet, worker_name)

            # 3. check work existing
            work = pow.PowWork.find_work_by_header_boundary(header=header,
                                                            boundary=boundary,
                                                            check_expired=True)
            if not work:
                logging.warning(
                    f"work not found or expired, {header} {boundary}")
                _worker.update_stat(inc_failed=1)
                return False

            # 4. verify result
            seed, header = h2b(work.seed), h2b(work.header)
            boundary_bytes = h2b(work.boundary)
            block_num = ethash.seed_to_block_num(seed)
            hash_result = ethash.verify_pow_work(block_num, header,
                                                 mix_digest_bytes, nonce_int,
                                                 boundary_bytes)
            if not hash_result:
                logging.warning(
                    f"wrong result from miner {miner_wallet}-{worker_name}, {work}"
                )
                _worker.update_stat(inc_failed=1)
                return False

        elif self.stratumMiner._stratusVersion == STRATUM_NICEHASH:
            if jsonMsg["params"] is None:
                logging.critical("The message is without params section")
                return False

            worker_name = jsonMsg["params"][0]
            strJobId = jsonMsg["params"][1]
            joibId = ObjectId(strJobId)
            nonce = jsonMsg["params"][2]
            if self.strExtraNonceHex is not None:
                nonce = self.strExtraNonceHex + nonce
            nonce_int = h2i(nonce)
            logging.info(f"worker_name {worker_name}")
            _worker = miner.Worker.get_or_create(miner_wallet, worker_name)

            # 3. check work existing
            work = pow.PowWork.find_work_by_id(joibId, check_expired=True)
            if not work:
                logging.warning(f"work not found or expired, {strJobId}")
                _worker.update_stat(inc_failed=1)
                return False

            # 4. verify result
            seed, header = h2b(work.seed), h2b(work.header)
            calc_mix_digest, calc_result = ethash.pow_hash(
                work.block_num, header, nonce_int)
            boundary_bytes = h2b(work.boundary)
            block_num = ethash.seed_to_block_num(seed)
            hash_result = ethash.verify_pow_work(block_num, header,
                                                 calc_mix_digest, nonce_int,
                                                 boundary_bytes)
            if not hash_result:
                logging.warning(
                    f"wrong result from miner {miner_wallet}-{worker_name}, {work}"
                )
                _worker.update_stat(inc_failed=1)
                return False

            mix_digest = b2h(calc_mix_digest)

        # 5. check the result if lesser than old one
        if work.finished:
            prev_result = pow.PowResult.get_pow_result(work.header,
                                                       work.boundary)
            if prev_result:
                if prev_result.verified:
                    logging.info(
                        f"submitted too late, work is verified. {work.header} {work.boundary}"
                    )
                    _worker.update_stat(inc_failed=1)
                    return False

                if ethash.is_less_or_equal(prev_result.hash_result,
                                           hash_result):
                    logging.info(
                        f"submitted result > old result, ignored. {work.header} {work.boundary}"
                    )
                    _worker.update_stat(inc_failed=1)
                    return False

        # 6. save to database
        hash_result_str = b2h(hash_result, prefix="0x")
        if not work.save_result(nonce, mix_digest, hash_result_str,
                                miner_wallet, worker_name):
            logging.warning(f"failed to save result for miner "
                            f"{miner_wallet}-{worker_name}, {work}")
            return False

        logging.critical(f"Work submitted, {work.header} {work.boundary}")

        self.send_success_reply(id)

        _worker.update_stat(inc_finished=1)
        self.stratumMiner.set_workDone(work)
        # 6. todo: miner reward
        return True