Repository: Chia-Network/chia-blockchain
File: chia/_tests/blockchain/test_blockchain.py (Python)

Code before:
    blocks_reorg_chain = bt.get_consecutive_blocks(
        4, blocks_reorg_chain, seed=b"2", block_refs=[uint32(5), uint32(11)], transaction_data=spend_bundle2
    )
    blocks_reorg_chain = bt.get_consecutive_blocks(4, blocks_reorg_chain, seed=b"2")

    fork_info = ForkInfo(-1, -1, b.constants.GENESIS_CHALLENGE)
    for i, block in enumerate(blocks_reorg_chain):
        if i < 10:
            expected = AddBlockResult.ALREADY_HAVE_BLOCK
        elif i < 19:
            expected = AddBlockResult.ADDED_AS_ORPHAN
        elif i == 19:
            # same height as peak decide by iterations
            peak = b.get_peak()
            assert peak is not None
            # same height as peak should be ADDED_AS_ORPHAN if block.total_iters >= peak.total_iters
            if block.total_iters < peak.total_iters:
                expected = AddBlockResult.NEW_PEAK
            else:
                expected = AddBlockResult.ADDED_AS_ORPHAN
        else:
            expected = AddBlockResult.NEW_PEAK
        await _validate_and_add_block(b, block, expected_result=expected, fork_info=fork_info)
    peak = b.get_peak()
    assert peak is not None
    assert peak.height == 20


# this test doesn't reorg, but _reconsider_peak() is passed a stale
# "fork_height" to make it look like it's in a reorg, but all the same blocks
# are just added back.
@pytest.mark.anyio
@pytest.mark.limit_consensus_modes(
    allowed=[ConsensusMode.HARD_FORK_2_0], reason="after hard fork 2 we no longer allow block references"
)
async def test_reorg_stale_fork_height(empty_blockchain: Blockchain, bt: BlockTools) -> None:
    b = empty_blockchain
    wallet_a = WalletTool(b.constants)
    WALLET_A_PUZZLE_HASHES = [wallet_a.get_new_puzzlehash() for _ in range(5)]
    coinbase_puzzlehash = WALLET_A_PUZZLE_HASHES[0]
    receiver_puzzlehash = WALLET_A_PUZZLE_HASHES[1]

    blocks = bt.get_consecutive_blocks(
        5,
        farmer_reward_puzzle_hash=coinbase_puzzlehash,
        pool_reward_puzzle_hash=receiver_puzzlehash,
        guarantee_transaction_block=True,
    )

    all_coins = []
    for spend_block in blocks:

Review comment (suggestion):
the reason this check is here is to make sure the test actually triggers a reorg. As far as I can tell, with this change, we wouldn't ensure that happens.

Would it not be possible to make the check against `19` above instead depend on which chain we're using, but still with a hard coded height.

Code after:
        blocks_reorg_chain,
        seed=b"2",
        farmer_reward_puzzle_hash=coinbase_puzzlehash,
        pool_reward_puzzle_hash=receiver_puzzlehash,
        transaction_data=spend_bundle,
        guarantee_transaction_block=True,
    )

    spend_bundle2 = wallet_a.generate_signed_transaction(uint64(1_000), receiver_puzzlehash, all_coins.pop())
    blocks_reorg_chain = bt.get_consecutive_blocks(
        4, blocks_reorg_chain, seed=b"2", block_refs=[uint32(5), uint32(11)], transaction_data=spend_bundle2
    )
    blocks_reorg_chain = bt.get_consecutive_blocks(4, blocks_reorg_chain, seed=b"2")

    fork_info = ForkInfo(-1, -1, b.constants.GENESIS_CHALLENGE)
    for i, block in enumerate(blocks_reorg_chain):
        if i < 10:
            expected = AddBlockResult.ALREADY_HAVE_BLOCK
        elif i < 19:
            expected = AddBlockResult.ADDED_AS_ORPHAN
        elif i == 19:
            # same height as peak decide by iterations
            peak = b.get_peak()
            assert peak is not None
            # same height as peak should be ADDED_AS_ORPHAN if block.total_iters >= peak.total_iters
            if block.total_iters < peak.total_iters:
                expected = AddBlockResult.NEW_PEAK
            else:
                expected = AddBlockResult.ADDED_AS_ORPHAN
            # todo_v2_plots we are checking that are desierd case got executed, hard to create with the new pos2 plots
            if consensus_mode < ConsensusMode.HARD_FORK_3_0:
                assert expected == AddBlockResult.NEW_PEAK
        else:
            expected = AddBlockResult.NEW_PEAK
        await _validate_and_add_block(b, block, expected_result=expected, fork_info=fork_info)
    peak = b.get_peak()
    assert peak is not None
    assert peak.height == 20


# this test doesn't reorg, but _reconsider_peak() is passed a stale
# "fork_height" to make it look like it's in a reorg, but all the same blocks
# are just added back.
@pytest.mark.anyio
@pytest.mark.limit_consensus_modes(
    allowed=[ConsensusMode.HARD_FORK_2_0], reason="after hard fork 2 we no longer allow block references"
)
async def test_reorg_stale_fork_height(empty_blockchain: Blockchain, bt: BlockTools) -> None:
    b = empty_blockchain
    wallet_a = WalletTool(b.constants)
    WALLET_A_PUZZLE_HASHES = [wallet_a.get_new_puzzlehash() for _ in range(5)]