import pytest from app.rounds.draw import ( draw_winner, header_hex_to_block_hash, header_meets_its_own_target, header_prev_hash, ) # Real PLM mainnet block 477486: header from blockchain.block.header, hash # cross-checked against the blockhash reported by blockchain.transaction.get for a # tx confirmed in that block. _REAL_HEADER_HEX = ( "0020ed30fbc39ee45200d10214f5107c5f36e7bf753032fd1d3279810c170000000000" "009a4ea723f732be4c538f3a2490837dd6560103d73ece606aa7d578a66700447b28875" "e6a47a61b1ad8012582" ) def test_header_hex_to_block_hash_matches_known_mainnet_block(): known_block_hash = "00000000000008788b55ade13b74d54ceffda9e54315b802411be1ca65064e86" assert header_hex_to_block_hash(_REAL_HEADER_HEX) == known_block_hash def test_header_meets_its_own_target_accepts_a_real_mined_header(): """B-28: a genuinely mined mainnet header must pass its own self-consistency check — this isn't just a synthetic-header property.""" assert header_meets_its_own_target(_REAL_HEADER_HEX) is True def test_header_meets_its_own_target_rejects_a_tampered_header(): """Flipping a single nonce bit changes the hash completely (avalanche effect) without changing the claimed difficulty, so a tampered-but-otherwise-real header should almost certainly fail — this is what would catch a hostile/MITM'd server replaying a real header with a doctored field.""" tampered = bytearray(bytes.fromhex(_REAL_HEADER_HEX)) tampered[-1] ^= 0xFF # flip the last byte of the nonce assert header_meets_its_own_target(tampered.hex()) is False def test_header_meets_its_own_target_rejects_wrong_length(): assert header_meets_its_own_target("aa" * 10) is False def test_header_prev_hash_matches_the_known_previous_block(): # Block 477486's predecessor, 477485 — independently known from the same chain. assert header_prev_hash(_REAL_HEADER_HEX) == "000000000000170c8179321dfd323075bfe7365f7c10f51402d10052e49ec3fb" def test_draw_winner_is_deterministic_and_within_range(): participants = ["addrA", "addrB", "addrC"] block_hash = "00" * 31 + "05" # seed = 5, index = 5 % 3 = 2 assert draw_winner(participants, block_hash) == "addrC" def test_draw_winner_single_participant_always_wins(): block_hash = "ff" * 32 assert draw_winner(["only"], block_hash) == "only" def test_draw_winner_raises_on_empty_participants(): with pytest.raises(ValueError): draw_winner([], "00" * 32) # --- B-74 (ELC-11): the claimed target must not be easier than the powLimit ------------ def test_pow_limit_is_the_mainnet_constant(): """B-74, ELC-11: PLM mainnet's `consensus.powLimit`, 00000000ffff…ffff.""" from app.rounds import draw assert draw.MAINNET_POW_LIMIT == int("00000000" + "ff" * 28, 16) assert draw.MAINNET_POW_LIMIT == (1 << 224) - 1 def test_a_header_below_the_pow_limit_is_rejected_even_if_it_meets_its_own_target(monkeypatch): """B-74, ELC-11: a header whose hash satisfies the target *it declares* (bits = 0x207fffff, a target of about 2^255) used to pass — and whoever fabricates a header picks its bits, so a random header passed with probability 1/2. With the mainnet powLimit in force it is rejected however its hash falls.""" import struct from app.rounds import draw def build(nonce: int) -> str: return ( struct.pack("