async def go(): nonlocal mock_tip work, _ = await miner.get_work(EMPTY_ADDR, now=now) self.assertEqual(work.height, 43) self.assertEqual(work.difficulty, 5) # submitted block doesn't exist res = await miner.submit_work(b"lolwut", 0, sha3_256(b"")) self.assertFalse(res) solver = DoubleSHA256(work) sol = solver.mine(200, 300).nonce self.assertGreater(sol, 200) # ensure non-solution is tried non_sol = sol - 1 # invalid pow proof res = await miner.submit_work(work.hash, non_sol, sha3_256(b"")) self.assertFalse(res) # valid submission, but tip updated so should fail mock_tip.height += 1 res = await miner.submit_work(work.hash, sol, sha3_256(b"")) self.assertFalse(res) self.assertEqual(miner.work_map, {}) # bring tip back and regenerate the work mock_tip.height -= 1 work, _ = await miner.get_work(EMPTY_ADDR, now=now) # valid submission, also check internal state afterwards res = await miner.submit_work(work.hash, sol, sha3_256(b"")) self.assertTrue(res) self.assertEqual(miner.work_map, {}) self.assertEqual(len(self.added_blocks), 1)
def test_getWork_and_submitWork(self): id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_key=0) with ClusterContext( 1, acc1, remote_mining=True, shard_size=1, small_coinbase=True) as clusters, jrpc_server_context( clusters[0].master): master = clusters[0].master slaves = clusters[0].slave_list tx = create_transfer_transaction( shard_state=clusters[0].get_shard_state(1 | 0), key=id1.get_key(), from_address=acc1, to_address=acc1, value=0, gas_price=12, ) self.assertTrue(slaves[0].add_tx(tx)) for shard_id in ["0x0", None]: # shard, then root resp = send_request("getWork", [shard_id]) self.assertEqual(resp[1:], ["0x1", "0xa"]) # height and diff header_hash_hex = resp[0] if shard_id is not None: # shard 0 miner_address = Address.create_from( master.env.quark_chain_config.shards[1]. COINBASE_ADDRESS) else: # root miner_address = Address.create_from( master.env.quark_chain_config.ROOT.COINBASE_ADDRESS) block = call_async( master.get_next_block_to_mine(address=miner_address, branch_value=shard_id and 0b01)) # solve it and submit work = MiningWork(bytes.fromhex(header_hash_hex[2:]), 1, 10) solver = DoubleSHA256(work) nonce = solver.mine(0, 10000).nonce mixhash = "0x" + sha3_256(b"").hex() resp = send_request( "submitWork", [ shard_id, header_hash_hex, hex(nonce), mixhash, "0x" + bytes(65).hex(), ], ) self.assertTrue(resp) # show progress on shard 0 self.assertEqual( clusters[0].get_shard_state(1 | 0).get_tip().header.height, 1)
def test_getWork_and_submitWork(self): id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_id=0) with ClusterContext( 1, acc1, remote_mining=True, shard_size=1 ) as clusters, jrpc_server_context(clusters[0].master): master = clusters[0].master slaves = clusters[0].slave_list branch = Branch.create(1, 0) tx = create_transfer_transaction( shard_state=slaves[0].shards[branch].state, key=id1.get_key(), from_address=acc1, to_address=acc1, value=0, gas_price=12, ) self.assertTrue(slaves[0].add_tx(tx)) for shard_id in ["0x0", None]: # shard, then root resp = send_request("getWork", shard_id) self.assertEqual(resp[1:], ["0x1", "0xa"]) # height and diff header_hash_hex = resp[0] _, block = call_async( master.get_next_block_to_mine( address=master.env.quark_chain_config.miner_address, prefer_root=shard_id is None, ) ) self.assertEqual( header_hash_hex[2:], block.header.get_hash_for_mining().hex() ) # solve it and submit work = MiningWork(bytes.fromhex(resp[0][2:]), 1, 10) solver = DoubleSHA256(work) nonce = solver.mine(0, 10000).nonce mixhash = "0x" + sha3_256(b"").hex() resp = send_request( "submitWork", shard_id, header_hash_hex, hex(nonce), mixhash ) self.assertTrue(resp) # show progress _, new_block = call_async(master.get_next_block_to_mine(address=acc1)) self.assertIsInstance(new_block, MinorBlock) self.assertEqual(new_block.header.height, 2)
def test_getWork_and_submitWork(self): id1 = Identity.create_random_identity() acc1 = Address.create_from_identity(id1, full_shard_id=0) with ClusterContext(1, acc1, remote_mining=True, shard_size=1) as clusters, jrpc_server_context( clusters[0].master): master = clusters[0].master slaves = clusters[0].slave_list branch = Branch.create(1, 0) tx = create_transfer_transaction( shard_state=slaves[0].shards[branch].state, key=id1.get_key(), from_address=acc1, to_address=acc1, value=0, gas_price=12, ) self.assertTrue(slaves[0].add_tx(tx)) for shard_id in ["0x0", None]: # shard, then root resp = send_request("getWork", shard_id) self.assertEqual(resp[1:], ["0x1", "0xa"]) # height and diff header_hash_hex = resp[0] _, block = call_async( master.get_next_block_to_mine(address=acc1)) self.assertEqual(header_hash_hex[2:], block.header.get_hash_for_mining().hex()) # solve it and submit solver = DoubleSHA256(block) mined = solver.mine(0, 1000) self.assertTrue(mined) nonce_found = "0x" + solver.nonce_found.hex() mixhash = "0x" + sha3_256(b"").hex() resp = send_request("submitWork", shard_id, header_hash_hex, nonce_found, mixhash) # FIXME: also verify root chain block addition after fixing https://github.com/QuarkChain/pyquarkchain/issues/130 if shard_id is not None: self.assertTrue(resp)
async def go(): work, _ = await miner.get_work(now=now) self.assertEqual(work.height, 0) self.assertEqual(work.difficulty, 5) # submitted block doesn't exist res = await miner.submit_work(b"lolwut", 0, sha3_256(b"")) self.assertFalse(res) solver = DoubleSHA256(work) sol = solver.mine(100, 200).nonce self.assertGreater(sol, 100) # ensure non-solution is tried non_sol = sol - 1 # invalid pow proof res = await miner.submit_work(work.hash, non_sol, sha3_256(b"")) self.assertFalse(res) # valid submission, also check internal state afterwards res = await miner.submit_work(work.hash, sol, sha3_256(b"")) self.assertTrue(res) self.assertEqual(miner.work_map, {}) self.assertEqual(len(self.added_blocks), 1) self.assertIsNone(miner.current_work)