diff --git a/chia/_tests/blockchain/test_blockchain.py b/chia/_tests/blockchain/test_blockchain.py index e0de389d4d3a..503a7b10f3c8 100644 --- a/chia/_tests/blockchain/test_blockchain.py +++ b/chia/_tests/blockchain/test_blockchain.py @@ -160,124 +160,126 @@ async def test_genesis_validate_1(self, empty_blockchain: Blockchain, bt: BlockT class TestBlockHeaderValidation: - @pytest.mark.limit_consensus_modes(reason="save time") @pytest.mark.anyio async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_blocks: list[FullBlock]) -> None: blocks = default_1000_blocks fork_info = ForkInfo(blocks[0].height - 1, blocks[0].height - 1, blocks[0].prev_header_hash) for block in blocks: if ( - len(block.finished_sub_slots) > 0 - and block.finished_sub_slots[0].challenge_chain.subepoch_summary_hash is not None + len(block.finished_sub_slots) == 0 + or block.finished_sub_slots[0].challenge_chain.subepoch_summary_hash is None ): - # Sub/Epoch. Try using a bad ssi and difficulty to test 2m and 2n - new_finished_ss = recursive_replace( - block.finished_sub_slots[0], - "challenge_chain.new_sub_slot_iters", - uint64(10_000_000), - ) - block_bad = recursive_replace( - block, "finished_sub_slots", [new_finished_ss, *block.finished_sub_slots[1:]] - ) - header_block_bad = get_block_header(block_bad) - # TODO: Inspect these block values as they are currently None - expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0) - expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0) - expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None) - _, error = validate_finished_header_block( - empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs - ) - assert error is not None - assert error.code == Err.INVALID_NEW_SUB_SLOT_ITERS + await _validate_and_add_block(empty_blockchain, block, fork_info=fork_info) + continue - # Also fails calling the outer methods, but potentially with a different error - await _validate_and_add_block( - empty_blockchain, block_bad, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info - ) + # TODO: deduplicate the test code, perhaps by parameterizing the + # test - new_finished_ss_2 = recursive_replace( - block.finished_sub_slots[0], - "challenge_chain.new_difficulty", - uint64(10_000_000), - ) - block_bad_2 = recursive_replace( - block, "finished_sub_slots", [new_finished_ss_2, *block.finished_sub_slots[1:]] - ) + # Sub/Epoch. Try using a bad ssi and difficulty to test 2m and 2n + new_finished_ss = recursive_replace( + block.finished_sub_slots[0], + "challenge_chain.new_sub_slot_iters", + uint64(10_000_000), + ) + block_bad = recursive_replace(block, "finished_sub_slots", [new_finished_ss, *block.finished_sub_slots[1:]]) + header_block_bad = get_block_header(block_bad) + # TODO: Inspect these block values as they are currently None + expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0) + expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0) + expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None) + _, error = validate_finished_header_block( + empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs + ) + assert error is not None + assert error.code == Err.INVALID_NEW_SUB_SLOT_ITERS - header_block_bad_2 = get_block_header(block_bad_2) - # TODO: Inspect these block values as they are currently None - expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0) - expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0) - expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None) - _, error = validate_finished_header_block( - empty_blockchain.constants, empty_blockchain, header_block_bad_2, False, expected_vs - ) - assert error is not None - assert error.code == Err.INVALID_NEW_DIFFICULTY + # Also fails calling the outer methods, but potentially with a different error + await _validate_and_add_block( + empty_blockchain, block_bad, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info + ) - # Also fails calling the outer methods, but potentially with a different error - await _validate_and_add_block( - empty_blockchain, block_bad_2, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info - ) + new_finished_ss = recursive_replace( + block.finished_sub_slots[0], + "challenge_chain.new_difficulty", + uint64(10_000_000), + ) + block_bad = recursive_replace(block, "finished_sub_slots", [new_finished_ss, *block.finished_sub_slots[1:]]) + + header_block_bad = get_block_header(block_bad) + # TODO: Inspect these block values as they are currently None + expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0) + expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0) + expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None) + _, error = validate_finished_header_block( + empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs + ) + assert error is not None + assert error.code == Err.INVALID_NEW_DIFFICULTY - # 3c - new_finished_ss_3: EndOfSubSlotBundle = recursive_replace( - block.finished_sub_slots[0], - "challenge_chain.subepoch_summary_hash", - bytes([0] * 32), - ) - new_finished_ss_3 = recursive_replace( - new_finished_ss_3, - "reward_chain.challenge_chain_sub_slot_hash", - new_finished_ss_3.challenge_chain.get_hash(), - ) - log.warning(f"Number of slots: {len(block.finished_sub_slots)}") - block_bad_3 = recursive_replace(block, "finished_sub_slots", [new_finished_ss_3]) + # Also fails calling the outer methods, but potentially with a different error + await _validate_and_add_block( + empty_blockchain, block_bad, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info + ) - header_block_bad_3 = get_block_header(block_bad_3) - # TODO: Inspect these block values as they are currently None - expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0) - expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0) - expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None) - _, error = validate_finished_header_block( - empty_blockchain.constants, empty_blockchain, header_block_bad_3, False, expected_vs - ) - assert error is not None - assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY + # 3c + new_finished_ss = recursive_replace( + block.finished_sub_slots[0], + "challenge_chain.subepoch_summary_hash", + bytes([0] * 32), + ) + new_finished_ss = recursive_replace( + new_finished_ss, + "reward_chain.challenge_chain_sub_slot_hash", + new_finished_ss.challenge_chain.get_hash(), + ) + log.warning(f"Number of slots: {len(block.finished_sub_slots)}") + block_bad = recursive_replace(block, "finished_sub_slots", [new_finished_ss]) + + header_block_bad = get_block_header(block_bad) + # TODO: Inspect these block values as they are currently None + expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0) + expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0) + expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None) + _, error = validate_finished_header_block( + empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs + ) + assert error is not None + assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY - # Also fails calling the outer methods, but potentially with a different error - await _validate_and_add_block( - empty_blockchain, block_bad_3, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info - ) + # Also fails calling the outer methods, but potentially with a different error + await _validate_and_add_block( + empty_blockchain, block_bad, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info + ) - # 3d - new_finished_ss_4 = recursive_replace( - block.finished_sub_slots[0], - "challenge_chain.subepoch_summary_hash", - std_hash(b"123"), - ) - new_finished_ss_4 = recursive_replace( - new_finished_ss_4, - "reward_chain.challenge_chain_sub_slot_hash", - new_finished_ss_4.challenge_chain.get_hash(), - ) - block_bad_4 = recursive_replace(block, "finished_sub_slots", [new_finished_ss_4]) + # 3d + new_finished_ss = recursive_replace( + block.finished_sub_slots[0], + "challenge_chain.subepoch_summary_hash", + std_hash(b"123"), + ) + new_finished_ss = recursive_replace( + new_finished_ss, + "reward_chain.challenge_chain_sub_slot_hash", + new_finished_ss.challenge_chain.get_hash(), + ) + block_bad = recursive_replace(block, "finished_sub_slots", [new_finished_ss]) + + header_block_bad = get_block_header(block_bad) + # TODO: Inspect these block values as they are currently None + expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0) + expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0) + expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None) + _, error = validate_finished_header_block( + empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs + ) + assert error is not None + assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY - header_block_bad_4 = get_block_header(block_bad_4) - # TODO: Inspect these block values as they are currently None - expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0) - expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0) - expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None) - _, error = validate_finished_header_block( - empty_blockchain.constants, empty_blockchain, header_block_bad_4, False, expected_vs - ) - assert error is not None - assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY + # Also fails calling the outer methods, but potentially with a different error + await _validate_and_add_block( + empty_blockchain, block_bad, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info + ) - # Also fails calling the outer methods, but potentially with a different error - await _validate_and_add_block( - empty_blockchain, block_bad_4, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info - ) await _validate_and_add_block(empty_blockchain, block, fork_info=fork_info) log.info( f"Added block {block.height} total iters {block.total_iters} new slot? {len(block.finished_sub_slots)}" @@ -1443,7 +1445,7 @@ async def test_pool_target_contract( new_fsb_sig = bt.get_plot_signature(new_m, blocks[-1].reward_chain_block.proof_of_space.plot_public_key) block_bad = recursive_replace(block_bad, "foliage.foliage_block_data_signature", new_fsb_sig) await _validate_and_add_block(empty_blockchain, block_bad, expected_error=Err.INVALID_POOL_TARGET) - return None + return attempts += 1 @pytest.mark.anyio