diff --git a/chia/_tests/core/full_node/test_full_node.py b/chia/_tests/core/full_node/test_full_node.py index 2e7cfd3aa829..b4d7e8e041d4 100644 --- a/chia/_tests/core/full_node/test_full_node.py +++ b/chia/_tests/core/full_node/test_full_node.py @@ -7,7 +7,7 @@ import random import time from collections.abc import Awaitable, Coroutine -from typing import Optional +from typing import Any, Optional import pytest from chia_rs import ( @@ -28,9 +28,10 @@ from chia._tests.core.make_block_generator import make_spend_bundle from chia._tests.core.node_height import node_height_at_least from chia._tests.util.misc import wallet_height_at_least -from chia._tests.util.setup_nodes import SimulatorsAndWalletsServices +from chia._tests.util.setup_nodes import OldSimulatorsAndWallets, SimulatorsAndWalletsServices from chia._tests.util.time_out_assert import time_out_assert, time_out_assert_custom_interval, time_out_messages from chia.consensus.block_body_validation import ForkInfo +from chia.consensus.blockchain import Blockchain from chia.consensus.multiprocess_validation import PreValidationResult, pre_validate_block from chia.consensus.pot_iterations import is_overflow_block from chia.full_node.coin_store import CoinStore @@ -40,11 +41,12 @@ from chia.full_node.sync_store import Peak from chia.protocols import full_node_protocol, timelord_protocol, wallet_protocol from chia.protocols import full_node_protocol as fnp -from chia.protocols.full_node_protocol import RespondTransaction +from chia.protocols.full_node_protocol import NewTransaction, RespondTransaction from chia.protocols.protocol_message_types import ProtocolMessageTypes from chia.protocols.shared_protocol import Capability, default_capabilities from chia.protocols.wallet_protocol import SendTransaction, TransactionAck from chia.server.address_manager import AddressManager +from chia.server.node_discovery import FullNodePeers from chia.server.outbound_message import Message, NodeType from chia.server.server import ChiaServer from chia.simulator.add_blocks_in_batches import add_blocks_in_batches @@ -91,7 +93,9 @@ from chia.util.recursive_replace import recursive_replace from chia.util.task_referencer import create_referenced_task from chia.util.vdf_prover import get_vdf_info_and_proof +from chia.wallet.transaction_record import TransactionRecord from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG +from chia.wallet.wallet_node import WalletNode from chia.wallet.wallet_spend_bundle import WalletSpendBundle @@ -105,7 +109,7 @@ def test_pre_validation_result() -> None: assert results.validated_signature is False -async def new_transaction_not_requested(incoming, new_spend): +async def new_transaction_not_requested(incoming: asyncio.Queue[Message], new_spend: NewTransaction) -> bool: await asyncio.sleep(3) while not incoming.empty(): response = await incoming.get() @@ -120,7 +124,7 @@ async def new_transaction_not_requested(incoming, new_spend): return True -async def new_transaction_requested(incoming, new_spend): +async def new_transaction_requested(incoming: asyncio.Queue[Message], new_spend: NewTransaction) -> bool: await asyncio.sleep(1) while not incoming.empty(): response = await incoming.get() @@ -137,11 +141,11 @@ async def new_transaction_requested(incoming, new_spend): @pytest.mark.anyio async def test_sync_no_farmer( - setup_two_nodes_and_wallet, + setup_two_nodes_and_wallet: OldSimulatorsAndWallets, default_1000_blocks: list[FullBlock], self_hostname: str, seeded_random: random.Random, -): +) -> None: nodes, _wallets, _bt = setup_two_nodes_and_wallet server_1 = nodes[0].full_node.server server_2 = nodes[1].full_node.server @@ -159,7 +163,7 @@ async def test_sync_no_farmer( # connect the nodes and wait for node 2 to sync up to node 1 await connect_and_get_peer(server_1, server_2, self_hostname) - def check_nodes_in_sync(): + def check_nodes_in_sync() -> bool: p1 = full_node_2.full_node.blockchain.get_peak() p2 = full_node_1.full_node.blockchain.get_peak() return p1 == p2 @@ -171,8 +175,10 @@ def check_nodes_in_sync(): @pytest.mark.anyio -@pytest.mark.parametrize("tx_size", [3000000000000]) -async def test_block_compression(setup_two_nodes_and_wallet, empty_blockchain, tx_size, self_hostname): +@pytest.mark.parametrize("tx_size", [3_000_000_000_000]) +async def test_block_compression( + setup_two_nodes_and_wallet: OldSimulatorsAndWallets, empty_blockchain: Blockchain, tx_size: int, self_hostname: str +) -> None: nodes, wallets, bt = setup_two_nodes_and_wallet server_1 = nodes[0].full_node.server server_2 = nodes[1].full_node.server @@ -200,7 +206,7 @@ async def test_block_compression(setup_two_nodes_and_wallet, empty_blockchain, t # Send a transaction to mempool async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope: await wallet.generate_signed_transaction( - [tx_size], + [uint64(tx_size)], [ph], action_scope, ) @@ -219,8 +225,9 @@ async def test_block_compression(setup_two_nodes_and_wallet, empty_blockchain, t await time_out_assert(30, wallet_height_at_least, True, wallet_node_1, 5) await full_node_1.wait_for_wallet_synced(wallet_node=wallet_node_1, timeout=30) - async def check_transaction_confirmed(transaction) -> bool: + async def check_transaction_confirmed(transaction: TransactionRecord) -> bool: tx = await wallet_node_1.wallet_state_manager.get_transaction(transaction.name) + assert tx is not None return tx.confirmed await time_out_assert(30, check_transaction_confirmed, True, tr) @@ -233,7 +240,7 @@ async def check_transaction_confirmed(transaction) -> bool: # Send another tx async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope: await wallet.generate_signed_transaction( - [20000], + [uint64(20_000)], [ph], action_scope, ) @@ -255,7 +262,7 @@ async def check_transaction_confirmed(transaction) -> bool: await time_out_assert(10, check_transaction_confirmed, True, tr) # Confirm generator is compressed - program: Optional[SerializedProgram] = (await full_node_1.get_all_full_blocks())[-1].transactions_generator + program = (await full_node_1.get_all_full_blocks())[-1].transactions_generator assert program is not None num_blocks = len((await full_node_1.get_all_full_blocks())[-1].transactions_generator_ref_list) # since the hard fork, we don't use this compression mechanism @@ -273,7 +280,7 @@ async def check_transaction_confirmed(transaction) -> bool: # Send another 2 tx async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope: await wallet.generate_signed_transaction( - [30000], + [uint64(30_000)], [ph], action_scope, ) @@ -286,7 +293,7 @@ async def check_transaction_confirmed(transaction) -> bool: ) async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope: await wallet.generate_signed_transaction( - [40000], + [uint64(40_000)], [ph], action_scope, ) @@ -300,7 +307,7 @@ async def check_transaction_confirmed(transaction) -> bool: async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope: await wallet.generate_signed_transaction( - [50000], + [uint64(50_000)], [ph], action_scope, ) @@ -314,7 +321,7 @@ async def check_transaction_confirmed(transaction) -> bool: async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope: await wallet.generate_signed_transaction( - [3000000000000], + [uint64(3_000_000_000_000)], [ph], action_scope, ) @@ -336,7 +343,7 @@ async def check_transaction_confirmed(transaction) -> bool: await time_out_assert(10, check_transaction_confirmed, True, tr) # Confirm generator is compressed - program: Optional[SerializedProgram] = (await full_node_1.get_all_full_blocks())[-1].transactions_generator + program = (await full_node_1.get_all_full_blocks())[-1].transactions_generator assert program is not None num_blocks = len((await full_node_1.get_all_full_blocks())[-1].transactions_generator_ref_list) # since the hard fork, we don't use this compression mechanism @@ -346,11 +353,12 @@ async def check_transaction_confirmed(transaction) -> bool: # Creates a standard_transaction and an anyone-can-spend tx async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope: await wallet.generate_signed_transaction( - [30000], + [uint64(30_000)], [Program.to(1).get_tree_hash()], action_scope, ) [tr] = action_scope.side_effects.transactions + assert tr.spend_bundle is not None extra_spend = WalletSpendBundle( [ make_spend( @@ -369,6 +377,7 @@ async def check_transaction_confirmed(transaction) -> bool: removals=new_spend_bundle.removals(), ) [new_tr] = await wallet.wallet_state_manager.add_pending_transactions([new_tr]) + assert new_tr.spend_bundle is not None await time_out_assert( 10, full_node_2.full_node.mempool_manager.get_spendbundle, @@ -387,18 +396,19 @@ async def check_transaction_confirmed(transaction) -> bool: # Confirm generator is not compressed, #CAT creation has a cat spend all_blocks = await full_node_1.get_all_full_blocks() - program: Optional[SerializedProgram] = all_blocks[-1].transactions_generator + program = all_blocks[-1].transactions_generator assert program is not None assert len(all_blocks[-1].transactions_generator_ref_list) == 0 # Make a standard transaction and an anyone-can-spend transaction async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope: await wallet.generate_signed_transaction( - [30000], + [uint64(30_000)], [Program.to(1).get_tree_hash()], action_scope, ) [tr] = action_scope.side_effects.transactions + assert tr.spend_bundle is not None extra_spend = WalletSpendBundle( [ make_spend( @@ -417,6 +427,7 @@ async def check_transaction_confirmed(transaction) -> bool: removals=new_spend_bundle.removals(), ) [new_tr] = await wallet.wallet_state_manager.add_pending_transactions([new_tr]) + assert new_tr.spend_bundle is not None await time_out_assert( 10, full_node_2.full_node.mempool_manager.get_spendbundle, @@ -432,14 +443,16 @@ async def check_transaction_confirmed(transaction) -> bool: await full_node_1.wait_for_wallet_synced(wallet_node=wallet_node_1, timeout=30) # Confirm generator is not compressed - program: Optional[SerializedProgram] = (await full_node_1.get_all_full_blocks())[-1].transactions_generator + program = (await full_node_1.get_all_full_blocks())[-1].transactions_generator assert program is not None assert len((await full_node_1.get_all_full_blocks())[-1].transactions_generator_ref_list) == 0 - height = full_node_1.full_node.blockchain.get_peak().height + peak = full_node_1.full_node.blockchain.get_peak() + assert peak is not None + height = peak.height blockchain = empty_blockchain - all_blocks: list[FullBlock] = await full_node_1.get_all_full_blocks() + all_blocks = await full_node_1.get_all_full_blocks() assert height == len(all_blocks) - 1 if test_reorgs: @@ -487,14 +500,14 @@ async def check_transaction_confirmed(transaction) -> bool: @pytest.mark.anyio -async def test_spendbundle_serialization(): +async def test_spendbundle_serialization() -> None: sb: SpendBundle = make_spend_bundle(1) protocol_message = RespondTransaction(sb) assert bytes(sb) == bytes(protocol_message) @pytest.mark.anyio -async def test_inbound_connection_limit(setup_four_nodes, self_hostname): +async def test_inbound_connection_limit(setup_four_nodes: OldSimulatorsAndWallets, self_hostname: str) -> None: nodes, _, _ = setup_four_nodes server_1 = nodes[0].full_node.server server_1.config["target_peer_count"] = 2 @@ -507,29 +520,45 @@ async def test_inbound_connection_limit(setup_four_nodes, self_hostname): @pytest.mark.anyio -async def test_request_peers(wallet_nodes, self_hostname): +async def test_request_peers( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, _ = wallet_nodes + assert full_node_2.full_node.full_node_peers is not None + assert full_node_2.full_node.full_node_peers.address_manager is not None full_node_2.full_node.full_node_peers.address_manager.make_private_subnets_valid() await server_2.start_client(PeerInfo(self_hostname, server_1.get_port())) - async def have_msgs(): - await full_node_2.full_node.full_node_peers.address_manager.add_to_new_table( - [TimestampedPeerInfo("127.0.0.1", uint16(1000), uint64(int(time.time())) - 1000)], + async def have_msgs(full_node_peers: FullNodePeers) -> bool: + assert full_node_peers.address_manager is not None + await full_node_peers.address_manager.add_to_new_table( + [TimestampedPeerInfo("127.0.0.1", uint16(1000), uint64(int(time.time()) - 1000))], None, ) - msg_bytes = await full_node_2.full_node.full_node_peers.request_peers(PeerInfo("::1", server_2._port)) + assert server_2._port is not None + msg_bytes = await full_node_peers.request_peers(PeerInfo("::1", server_2._port)) + assert msg_bytes is not None msg = fnp.RespondPeers.from_bytes(msg_bytes.data) if msg is not None and not (len(msg.peer_list) == 1): return False peer = msg.peer_list[0] return (peer.host in {self_hostname, "127.0.0.1"}) and peer.port == 1000 - await time_out_assert_custom_interval(10, 1, have_msgs, True) + await time_out_assert_custom_interval(10, 1, have_msgs, True, full_node_2.full_node.full_node_peers) + assert full_node_1.full_node.full_node_peers is not None full_node_1.full_node.full_node_peers.address_manager = AddressManager() @pytest.mark.anyio -async def test_basic_chain(wallet_nodes, self_hostname): +async def test_basic_chain( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes incoming_queue, _ = await add_dummy_connection(server_1, self_hostname, 12312) @@ -544,17 +573,26 @@ async def test_basic_chain(wallet_nodes, self_hostname): await time_out_assert(10, time_out_messages(incoming_queue, "new_peak", 1)) - assert full_node_1.full_node.blockchain.get_peak().height == 0 + peak = full_node_1.full_node.blockchain.get_peak() + assert peak is not None + assert peak.height == 0 fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE) for block in bt.get_consecutive_blocks(30): await full_node_1.full_node.add_block(block, peer, fork_info=fork_info) - assert full_node_1.full_node.blockchain.get_peak().height == 29 + peak = full_node_1.full_node.blockchain.get_peak() + assert peak is not None + assert peak.height == 29 @pytest.mark.anyio -async def test_respond_end_of_sub_slot(wallet_nodes, self_hostname): +async def test_respond_end_of_sub_slot( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes incoming_queue, _dummy_node_id = await add_dummy_connection(server_1, self_hostname, 12312) @@ -613,7 +651,12 @@ async def test_respond_end_of_sub_slot(wallet_nodes, self_hostname): @pytest.mark.anyio -async def test_respond_end_of_sub_slot_no_reorg(wallet_nodes, self_hostname): +async def test_respond_end_of_sub_slot_no_reorg( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes incoming_queue, _dummy_node_id = await add_dummy_connection(server_1, self_hostname, 12312) @@ -651,7 +694,12 @@ async def test_respond_end_of_sub_slot_no_reorg(wallet_nodes, self_hostname): @pytest.mark.anyio -async def test_respond_end_of_sub_slot_race(wallet_nodes, self_hostname): +async def test_respond_end_of_sub_slot_race( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes incoming_queue, _dummy_node_id = await add_dummy_connection(server_1, self_hostname, 12312) @@ -682,7 +730,12 @@ async def test_respond_end_of_sub_slot_race(wallet_nodes, self_hostname): @pytest.mark.anyio -async def test_respond_unfinished(wallet_nodes, self_hostname): +async def test_respond_unfinished( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, wallet_a, wallet_receiver, bt = wallet_nodes incoming_queue, _dummy_node_id = await add_dummy_connection(server_1, self_hostname, 12312) @@ -767,6 +820,7 @@ async def test_respond_unfinished(wallet_nodes, self_hostname): assert full_node_1.full_node.full_node_store.get_unfinished_block(unf.partial_hash) is None await full_node_1.full_node.add_unfinished_block(unf, None) assert full_node_1.full_node.full_node_store.get_unfinished_block(unf.partial_hash) is not None + assert unf.foliage.foliage_transaction_block_hash is not None entry = full_node_1.full_node.full_node_store.get_unfinished_block_result( unf.partial_hash, unf.foliage.foliage_transaction_block_hash ) @@ -786,7 +840,12 @@ async def test_respond_unfinished(wallet_nodes, self_hostname): @pytest.mark.anyio -async def test_new_peak(wallet_nodes, self_hostname): +async def test_new_peak( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes incoming_queue, dummy_node_id = await add_dummy_connection(server_1, self_hostname, 12312) @@ -819,7 +878,7 @@ async def test_new_peak(wallet_nodes, self_hostname): await time_out_assert(10, time_out_messages(incoming_queue, "request_block", 0)) task_2.cancel() - async def suppress_value_error(coro: Coroutine) -> None: + async def suppress_value_error(coro: Coroutine[Any, Any, None]) -> None: with contextlib.suppress(ValueError): await coro @@ -847,7 +906,13 @@ async def suppress_value_error(coro: Coroutine) -> None: @pytest.mark.anyio -async def test_new_transaction_and_mempool(wallet_nodes, self_hostname, seeded_random: random.Random): +async def test_new_transaction_and_mempool( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, + seeded_random: random.Random, +) -> None: full_node_1, full_node_2, server_1, server_2, wallet_a, wallet_receiver, bt = wallet_nodes wallet_ph = wallet_a.get_new_puzzlehash() blocks = bt.get_consecutive_blocks( @@ -859,18 +924,15 @@ async def test_new_transaction_and_mempool(wallet_nodes, self_hostname, seeded_r for block in blocks: await full_node_1.full_node.add_block(block) - start_height = ( - full_node_1.full_node.blockchain.get_peak().height - if full_node_1.full_node.blockchain.get_peak() is not None - else -1 - ) + peak = full_node_1.full_node.blockchain.get_peak() + start_height = peak.height if peak is not None else -1 peer = await connect_and_get_peer(server_1, server_2, self_hostname) incoming_queue, node_id = await add_dummy_connection(server_1, self_hostname, 12312) fake_peer = server_1.all_connections[node_id] puzzle_hashes = [] # Makes a bunch of coins - conditions_dict: dict = {ConditionOpcode.CREATE_COIN: []} + conditions_dict: dict[ConditionOpcode, list[ConditionWithArgs]] = {ConditionOpcode.CREATE_COIN: []} # This should fit in one transaction for _ in range(100): receiver_puzzlehash = wallet_receiver.get_new_puzzlehash() @@ -880,7 +942,7 @@ async def test_new_transaction_and_mempool(wallet_nodes, self_hostname, seeded_r conditions_dict[ConditionOpcode.CREATE_COIN].append(output) spend_bundle = wallet_a.generate_signed_transaction( - 100, + uint64(100), puzzle_hashes[0], get_future_reward_coins(blocks[1])[0], condition_dic=conditions_dict, @@ -949,7 +1011,7 @@ async def test_new_transaction_and_mempool(wallet_nodes, self_hostname, seeded_r fee_rate_for_med = full_node_1.full_node.mempool_manager.mempool.get_min_fee_rate(5000000) fee_rate_for_large = full_node_1.full_node.mempool_manager.mempool.get_min_fee_rate(50000000) - if fee_rate_for_large > fee_rate_for_med: + if fee_rate_for_med is not None and fee_rate_for_large is not None and fee_rate_for_large > fee_rate_for_med: seen_bigger_transaction_has_high_fee = True if req is not None and req.data == bytes(fnp.RespondTransaction(spend_bundle)): @@ -961,7 +1023,8 @@ async def test_new_transaction_and_mempool(wallet_nodes, self_hostname, seeded_r successful_bundle = spend_bundle else: assert full_node_1.full_node.mempool_manager.mempool.at_full_capacity(10500000 * group_size) - assert full_node_1.full_node.mempool_manager.mempool.get_min_fee_rate(10500000 * group_size) > 0 + min_fee_rate = full_node_1.full_node.mempool_manager.mempool.get_min_fee_rate(10500000 * group_size) + assert min_fee_rate is not None and min_fee_rate > 0 assert not force_high_fee not_included_tx += 1 assert successful_bundle is not None @@ -993,6 +1056,7 @@ async def test_new_transaction_and_mempool(wallet_nodes, self_hostname, seeded_r # Resubmission through wallet is also fine response_msg = await full_node_1.send_transaction(SendTransaction(successful_bundle), test=True) + assert response_msg is not None assert TransactionAck.from_bytes(response_msg.data).status == MempoolInclusionStatus.SUCCESS.value # Farm one block to clear mempool @@ -1028,7 +1092,13 @@ async def test_new_transaction_and_mempool(wallet_nodes, self_hostname, seeded_r @pytest.mark.anyio -async def test_request_respond_transaction(wallet_nodes, self_hostname, seeded_random: random.Random): +async def test_request_respond_transaction( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, + seeded_random: random.Random, +) -> None: full_node_1, full_node_2, server_1, server_2, wallet_a, wallet_receiver, bt = wallet_nodes wallet_ph = wallet_a.get_new_puzzlehash() blocks = await full_node_1.get_all_full_blocks() @@ -1060,7 +1130,7 @@ async def test_request_respond_transaction(wallet_nodes, self_hostname, seeded_r receiver_puzzlehash = wallet_receiver.get_new_puzzlehash() spend_bundle = wallet_a.generate_signed_transaction( - 100, receiver_puzzlehash, blocks[-1].get_included_reward_coins()[0] + uint64(100), receiver_puzzlehash, blocks[-1].get_included_reward_coins()[0] ) assert spend_bundle is not None respond_transaction = fnp.RespondTransaction(spend_bundle) @@ -1077,7 +1147,13 @@ async def test_request_respond_transaction(wallet_nodes, self_hostname, seeded_r @pytest.mark.anyio -async def test_respond_transaction_fail(wallet_nodes, self_hostname, seeded_random: random.Random): +async def test_respond_transaction_fail( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, + seeded_random: random.Random, +) -> None: full_node_1, _full_node_2, server_1, server_2, wallet_a, wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() cb_ph = wallet_a.get_new_puzzlehash() @@ -1110,7 +1186,7 @@ async def test_respond_transaction_fail(wallet_nodes, self_hostname, seeded_rand await time_out_assert(10, time_out_messages(incoming_queue, "new_peak", 3)) # Invalid transaction does not propagate spend_bundle = wallet_a.generate_signed_transaction( - 100000000000000, + uint64(100_000_000_000_000), receiver_puzzlehash, blocks_new[-1].get_included_reward_coins()[0], ) @@ -1125,7 +1201,11 @@ async def test_respond_transaction_fail(wallet_nodes, self_hostname, seeded_rand @pytest.mark.anyio -async def test_request_block(wallet_nodes): +async def test_request_block( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], +) -> None: full_node_1, _full_node_2, _server_1, _server_2, wallet_a, wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() @@ -1137,7 +1217,7 @@ async def test_request_block(wallet_nodes): pool_reward_puzzle_hash=wallet_a.get_new_puzzlehash(), ) spend_bundle = wallet_a.generate_signed_transaction( - 1123, + uint64(1123), wallet_receiver.get_new_puzzlehash(), blocks[-1].get_included_reward_coins()[0], ) @@ -1150,25 +1230,33 @@ async def test_request_block(wallet_nodes): # Don't have height res = await full_node_1.request_block(fnp.RequestBlock(uint32(1248921), False)) + assert res is not None assert res.type == ProtocolMessageTypes.reject_block.value # Ask without transactions res = await full_node_1.request_block(fnp.RequestBlock(blocks[-1].height, False)) + assert res is not None assert res.type != ProtocolMessageTypes.reject_block.value assert fnp.RespondBlock.from_bytes(res.data).block.transactions_generator is None # Ask with transactions res = await full_node_1.request_block(fnp.RequestBlock(blocks[-1].height, True)) + assert res is not None assert res.type != ProtocolMessageTypes.reject_block.value assert fnp.RespondBlock.from_bytes(res.data).block.transactions_generator is not None # Ask for another one - res = await full_node_1.request_block(fnp.RequestBlock(blocks[-1].height - 1, True)) + res = await full_node_1.request_block(fnp.RequestBlock(uint32(blocks[-1].height - 1), True)) + assert res is not None assert res.type != ProtocolMessageTypes.reject_block.value @pytest.mark.anyio -async def test_request_blocks(wallet_nodes): +async def test_request_blocks( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], +) -> None: full_node_1, _full_node_2, _server_1, _server_2, wallet_a, wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() @@ -1182,7 +1270,7 @@ async def test_request_blocks(wallet_nodes): ) spend_bundle = wallet_a.generate_signed_transaction( - 1123, + uint64(1123), wallet_receiver.get_new_puzzlehash(), blocks[-1].get_included_reward_coins()[0], ) @@ -1202,18 +1290,21 @@ async def test_request_blocks(wallet_nodes): assert len(fetched_blocks) == 1 assert fetched_blocks[0].header_hash == blocks[4].header_hash res = await full_node_1.request_blocks(fnp.RequestBlocks(uint32(5), uint32(4), False)) + assert res is not None assert res.type == ProtocolMessageTypes.reject_blocks.value # Invalid range res = await full_node_1.request_blocks(fnp.RequestBlocks(uint32(peak_height - 5), uint32(peak_height + 5), False)) + assert res is not None assert res.type == ProtocolMessageTypes.reject_blocks.value # Try fetching more blocks than constants.MAX_BLOCK_COUNT_PER_REQUESTS res = await full_node_1.request_blocks(fnp.RequestBlocks(uint32(0), uint32(33), False)) + assert res is not None assert res.type == ProtocolMessageTypes.reject_blocks.value # Ask without transactions res = await full_node_1.request_blocks(fnp.RequestBlocks(uint32(peak_height - 5), uint32(peak_height), False)) - + assert res is not None fetched_blocks = fnp.RespondBlocks.from_bytes(res.data).blocks assert len(fetched_blocks) == 6 for b in fetched_blocks: @@ -1221,6 +1312,7 @@ async def test_request_blocks(wallet_nodes): # Ask with transactions res = await full_node_1.request_blocks(fnp.RequestBlocks(uint32(peak_height - 5), uint32(peak_height), True)) + assert res is not None fetched_blocks = fnp.RespondBlocks.from_bytes(res.data).blocks assert len(fetched_blocks) == 6 assert fetched_blocks[-1].transactions_generator is not None @@ -1230,7 +1322,14 @@ async def test_request_blocks(wallet_nodes): @pytest.mark.anyio @pytest.mark.parametrize("peer_version", ["0.0.35", "0.0.36"]) @pytest.mark.parametrize("requesting", [0, 1, 2]) -async def test_new_unfinished_block(wallet_nodes, peer_version: str, requesting: int, self_hostname: str): +async def test_new_unfinished_block( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + peer_version: str, + requesting: int, + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() @@ -1285,7 +1384,13 @@ async def test_new_unfinished_block(wallet_nodes, peer_version: str, requesting: @pytest.mark.anyio @pytest.mark.parametrize("requesting", [0, 1, 2]) -async def test_new_unfinished_block2(wallet_nodes, requesting: int, self_hostname: str): +async def test_new_unfinished_block2( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + requesting: int, + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() @@ -1325,7 +1430,12 @@ async def test_new_unfinished_block2(wallet_nodes, requesting: int, self_hostnam @pytest.mark.anyio -async def test_new_unfinished_block2_forward_limit(wallet_nodes, self_hostname: str): +async def test_new_unfinished_block2_forward_limit( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, wallet_a, wallet_receiver, bt = wallet_nodes blocks = bt.get_consecutive_blocks(3, guarantee_transaction_block=True) for block in blocks: @@ -1348,7 +1458,7 @@ async def test_new_unfinished_block2_forward_limit(wallet_nodes, self_hostname: for idx in range(0, 6): # we include a different transaction in each block. This makes the # foliage different in each of them, but the reward block (plot) the same - tx = wallet_a.generate_signed_transaction(100 * (idx + 1), puzzle_hash, coin) + tx = wallet_a.generate_signed_transaction(uint64(100 * (idx + 1)), puzzle_hash, coin) # note that we use the same chain to build the new block on top of every time block = bt.get_consecutive_blocks( @@ -1399,7 +1509,14 @@ def sort_key(b: UnfinishedBlock) -> bytes32: (7, Err.TOO_MANY_GENERATOR_REFS), ], ) -async def test_unfinished_block_with_replaced_generator(wallet_nodes, self_hostname, committment, expected): +async def test_unfinished_block_with_replaced_generator( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, + committment: int, + expected: Err, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() @@ -1413,6 +1530,7 @@ async def test_unfinished_block_with_replaced_generator(wallet_nodes, self_hostn if committment > 0: tr = block.transactions_info + assert tr is not None transactions_info = TransactionsInfo( std_hash(bytes(replaced_generator)), tr.generator_refs_root, @@ -1422,10 +1540,12 @@ async def test_unfinished_block_with_replaced_generator(wallet_nodes, self_hostn tr.reward_claims_incorporated, ) else: + assert block.transactions_info is not None transactions_info = block.transactions_info if committment > 1: tb = block.foliage_transaction_block + assert tb is not None transaction_block = FoliageTransactionBlock( tb.prev_transaction_block_hash, tb.timestamp, @@ -1435,6 +1555,7 @@ async def test_unfinished_block_with_replaced_generator(wallet_nodes, self_hostn transactions_info.get_hash(), ) else: + assert block.foliage_transaction_block is not None transaction_block = block.foliage_transaction_block if committment > 2: @@ -1540,7 +1661,12 @@ async def test_unfinished_block_with_replaced_generator(wallet_nodes, self_hostn @pytest.mark.anyio -async def test_double_blocks_same_pospace(wallet_nodes, self_hostname): +async def test_double_blocks_same_pospace( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, full_node_2, server_1, server_2, wallet_a, wallet_receiver, bt = wallet_nodes incoming_queue, dummy_node_id = await add_dummy_connection(server_1, self_hostname, 12315) @@ -1554,7 +1680,7 @@ async def test_double_blocks_same_pospace(wallet_nodes, self_hostname): blocks: list[FullBlock] = await full_node_1.get_all_full_blocks() coin = blocks[-1].get_included_reward_coins()[0] - tx = wallet_a.generate_signed_transaction(10000, wallet_receiver.get_new_puzzlehash(), coin) + tx = wallet_a.generate_signed_transaction(uint64(10_000), wallet_receiver.get_new_puzzlehash(), coin) blocks = bt.get_consecutive_blocks( 1, block_list_input=blocks, guarantee_transaction_block=True, transaction_data=tx @@ -1565,6 +1691,7 @@ async def test_double_blocks_same_pospace(wallet_nodes, self_hostname): await full_node_1.full_node.add_unfinished_block(unf, dummy_peer) assert full_node_1.full_node.full_node_store.get_unfinished_block(unf.partial_hash) + assert unf.foliage_transaction_block is not None block_2 = recursive_replace( blocks[-1], "foliage_transaction_block.timestamp", unf.foliage_transaction_block.timestamp + 1 ) @@ -1580,14 +1707,19 @@ async def test_double_blocks_same_pospace(wallet_nodes, self_hostname): @pytest.mark.anyio -async def test_request_unfinished_block(wallet_nodes, self_hostname): +async def test_request_unfinished_block( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() peer = await connect_and_get_peer(server_1, server_2, self_hostname) blocks = bt.get_consecutive_blocks(10, block_list_input=blocks, seed=b"12345") for block in blocks[:-1]: await full_node_1.full_node.add_block(block) - block: FullBlock = blocks[-1] + block = blocks[-1] unf = make_unfinished_block(block, bt.constants) # Don't have @@ -1600,7 +1732,12 @@ async def test_request_unfinished_block(wallet_nodes, self_hostname): @pytest.mark.anyio -async def test_request_unfinished_block2(wallet_nodes, self_hostname): +async def test_request_unfinished_block2( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, wallet_a, wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() blocks = bt.get_consecutive_blocks(3, guarantee_transaction_block=True) @@ -1618,7 +1755,7 @@ async def test_request_unfinished_block2(wallet_nodes, self_hostname): for idx in range(0, 6): # we include a different transaction in each block. This makes the # foliage different in each of them, but the reward block (plot) the same - tx = wallet_a.generate_signed_transaction(100 * (idx + 1), puzzle_hash, coin) + tx = wallet_a.generate_signed_transaction(uint64(100 * (idx + 1)), puzzle_hash, coin) # note that we use the same chain to build the new block on top of every time block = bt.get_consecutive_blocks( @@ -1646,17 +1783,25 @@ async def test_request_unfinished_block2(wallet_nodes, self_hostname): res = await full_node_1.request_unfinished_block2( fnp.RequestUnfinishedBlock2(unf.partial_hash, unf.foliage.foliage_transaction_block_hash) ) + assert res is not None assert res.data == bytes(fnp.RespondUnfinishedBlock(unf)) res = await full_node_1.request_unfinished_block(fnp.RequestUnfinishedBlock(unf.partial_hash)) + assert res is not None assert res.data == bytes(fnp.RespondUnfinishedBlock(best_unf)) res = await full_node_1.request_unfinished_block2(fnp.RequestUnfinishedBlock2(unf.partial_hash, None)) + assert res is not None assert res.data == bytes(fnp.RespondUnfinishedBlock(best_unf)) @pytest.mark.anyio -async def test_new_signage_point_or_end_of_sub_slot(wallet_nodes, self_hostname): +async def test_new_signage_point_or_end_of_sub_slot( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + self_hostname: str, +) -> None: full_node_1, full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() @@ -1667,7 +1812,7 @@ async def test_new_signage_point_or_end_of_sub_slot(wallet_nodes, self_hostname) blockchain = full_node_1.full_node.blockchain peak = blockchain.get_peak() - + assert peak is not None sp = get_signage_point( bt.constants, blockchain, @@ -1677,11 +1822,14 @@ async def test_new_signage_point_or_end_of_sub_slot(wallet_nodes, self_hostname) [], peak.sub_slot_iters, ) + assert sp.cc_vdf is not None + assert sp.rc_vdf is not None peer = await connect_and_get_peer(server_1, server_2, self_hostname) res = await full_node_1.new_signage_point_or_end_of_sub_slot( fnp.NewSignagePointOrEndOfSubSlot(None, sp.cc_vdf.challenge, uint8(11), sp.rc_vdf.challenge), peer ) + assert res is not None assert res.type == ProtocolMessageTypes.request_signage_point_or_end_of_sub_slot.value assert fnp.RequestSignagePointOrEndOfSubSlot.from_bytes(res.data).index_from_challenge == uint8(11) @@ -1705,14 +1853,20 @@ async def test_new_signage_point_or_end_of_sub_slot(wallet_nodes, self_hostname) assert len(full_node_1.full_node.full_node_store.finished_sub_slots) >= num_slots - def caught_up_slots(): + def caught_up_slots() -> bool: return len(full_node_2.full_node.full_node_store.finished_sub_slots) >= num_slots await time_out_assert(20, caught_up_slots) @pytest.mark.anyio -async def test_new_signage_point_caching(wallet_nodes, empty_blockchain, self_hostname): +async def test_new_signage_point_caching( + wallet_nodes: tuple[ + FullNodeSimulator, FullNodeSimulator, ChiaServer, ChiaServer, WalletTool, WalletTool, BlockTools + ], + empty_blockchain: Blockchain, + self_hostname: str, +) -> None: full_node_1, _full_node_2, server_1, server_2, _wallet_a, _wallet_receiver, bt = wallet_nodes blocks = await full_node_1.get_all_full_blocks() @@ -1728,7 +1882,7 @@ async def test_new_signage_point_caching(wallet_nodes, empty_blockchain, self_ho blocks = bt.get_consecutive_blocks(1, block_list_input=blocks, skip_slots=1, force_overflow=True) for ss in blocks[-1].finished_sub_slots: challenge_chain = ss.challenge_chain.replace( - new_difficulty=20, + new_difficulty=uint64(20), ) slot2 = ss.replace( challenge_chain=challenge_chain, @@ -1741,6 +1895,7 @@ async def test_new_signage_point_caching(wallet_nodes, empty_blockchain, self_ho # Creates a signage point based on the last block peak_2 = second_blockchain.get_peak() + assert peak_2 is not None sp: SignagePoint = get_signage_point( bt.constants, blockchain, @@ -1750,13 +1905,17 @@ async def test_new_signage_point_caching(wallet_nodes, empty_blockchain, self_ho [], peak_2.sub_slot_iters, ) + assert sp.cc_vdf is not None + assert sp.cc_proof is not None + assert sp.rc_vdf is not None + assert sp.rc_proof is not None # Submits the signage point, cannot add because don't have block await full_node_1.respond_signage_point( - fnp.RespondSignagePoint(4, sp.cc_vdf, sp.cc_proof, sp.rc_vdf, sp.rc_proof), peer + fnp.RespondSignagePoint(uint8(4), sp.cc_vdf, sp.cc_proof, sp.rc_vdf, sp.rc_proof), peer ) # Should not add duplicates to cache though await full_node_1.respond_signage_point( - fnp.RespondSignagePoint(4, sp.cc_vdf, sp.cc_proof, sp.rc_vdf, sp.rc_proof), peer + fnp.RespondSignagePoint(uint8(4), sp.cc_vdf, sp.cc_proof, sp.rc_vdf, sp.rc_proof), peer ) assert full_node_1.full_node.full_node_store.get_signage_point(sp.cc_vdf.output.get_hash()) is None assert len(full_node_1.full_node.full_node_store.future_sp_cache[sp.rc_vdf.challenge]) == 1 @@ -1765,12 +1924,14 @@ async def test_new_signage_point_caching(wallet_nodes, empty_blockchain, self_ho await full_node_1.full_node.add_block(blocks[-1], peer) # Now signage point should be added - sp = full_node_1.full_node.full_node_store.get_signage_point(sp.cc_vdf.output.get_hash()) - assert sp is not None + assert full_node_1.full_node.full_node_store.get_signage_point(sp.cc_vdf.output.get_hash()) is not None @pytest.mark.anyio -async def test_slot_catch_up_genesis(setup_two_nodes_fixture, self_hostname): +async def test_slot_catch_up_genesis( + setup_two_nodes_fixture: tuple[list[FullNodeSimulator], list[tuple[WalletNode, ChiaServer]], BlockTools], + self_hostname: str, +) -> None: nodes, _, bt = setup_two_nodes_fixture server_1 = nodes[0].full_node.server server_2 = nodes[1].full_node.server @@ -1795,14 +1956,16 @@ async def test_slot_catch_up_genesis(setup_two_nodes_fixture, self_hostname): assert len(full_node_1.full_node.full_node_store.finished_sub_slots) >= num_slots - def caught_up_slots(): + def caught_up_slots() -> bool: return len(full_node_2.full_node.full_node_store.finished_sub_slots) >= num_slots await time_out_assert(20, caught_up_slots) @pytest.mark.anyio -async def test_compact_protocol(setup_two_nodes_fixture): +async def test_compact_protocol( + setup_two_nodes_fixture: tuple[list[FullNodeSimulator], list[tuple[WalletNode, ChiaServer]], BlockTools], +) -> None: nodes, _, bt = setup_two_nodes_fixture full_node_1 = nodes[0] full_node_2 = nodes[1] @@ -1827,7 +1990,7 @@ async def test_compact_protocol(setup_two_nodes_fixture): vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_EOS_VDF, + uint8(CompressibleVDFField.CC_EOS_VDF), ) ) blocks_2 = bt.get_consecutive_blocks(num_blocks=10, block_list_input=blocks, skip_slots=3) @@ -1851,7 +2014,7 @@ async def test_compact_protocol(setup_two_nodes_fixture): vdf_proof, block.header_hash, block.height, - CompressibleVDFField.ICC_EOS_VDF, + uint8(CompressibleVDFField.ICC_EOS_VDF), ) ) assert block.reward_chain_block.challenge_chain_sp_vdf is not None @@ -1868,7 +2031,7 @@ async def test_compact_protocol(setup_two_nodes_fixture): vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_SP_VDF, + uint8(CompressibleVDFField.CC_SP_VDF), ) ) vdf_info, vdf_proof = get_vdf_info_and_proof( @@ -1884,7 +2047,7 @@ async def test_compact_protocol(setup_two_nodes_fixture): vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_IP_VDF, + uint8(CompressibleVDFField.CC_IP_VDF), ) ) @@ -1917,11 +2080,16 @@ async def test_compact_protocol(setup_two_nodes_fixture): assert has_compact_cc_ip_vdf for height, block in enumerate(stored_blocks): await full_node_2.full_node.add_block(block) - assert full_node_2.full_node.blockchain.get_peak().height == height + peak = full_node_2.full_node.blockchain.get_peak() + assert peak is not None + assert peak.height == height @pytest.mark.anyio -async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_hostname): +async def test_compact_protocol_invalid_messages( + setup_two_nodes_fixture: tuple[list[FullNodeSimulator], list[tuple[WalletNode, ChiaServer]], BlockTools], + self_hostname: str, +) -> None: nodes, _, bt = setup_two_nodes_fixture full_node_1 = nodes[0] full_node_2 = nodes[1] @@ -1929,7 +2097,9 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h blocks_2 = bt.get_consecutive_blocks(num_blocks=3, block_list_input=blocks, skip_slots=3) for block in blocks_2[:2]: await full_node_1.full_node.add_block(block) - assert full_node_1.full_node.blockchain.get_peak().height == 1 + peak = full_node_1.full_node.blockchain.get_peak() + assert peak is not None + assert peak.height == 1 # (wrong_vdf_info, wrong_vdf_proof) pair verifies, but it's not present in the blockchain at all. block = blocks_2[2] wrong_vdf_info, wrong_vdf_proof = get_vdf_info_and_proof( @@ -1939,8 +2109,8 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h block.reward_chain_block.challenge_chain_ip_vdf.number_of_iterations, True, ) - timelord_protocol_invalid_messages = [] - full_node_protocol_invalid_messaages = [] + timelord_protocol_invalid_messages: list[timelord_protocol.RespondCompactProofOfTime] = [] + full_node_protocol_invalid_messages: list[fnp.RespondCompactVDF] = [] for block in blocks_2[:2]: for sub_slot in block.finished_sub_slots: vdf_info, correct_vdf_proof = get_vdf_info_and_proof( @@ -1957,14 +2127,14 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h wrong_vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_EOS_VDF, + uint8(CompressibleVDFField.CC_EOS_VDF), ) ) - full_node_protocol_invalid_messaages.append( + full_node_protocol_invalid_messages.append( fnp.RespondCompactVDF( block.height, block.header_hash, - CompressibleVDFField.CC_EOS_VDF, + uint8(CompressibleVDFField.CC_EOS_VDF), vdf_info, wrong_vdf_proof, ) @@ -1984,14 +2154,14 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h wrong_vdf_proof, block.header_hash, block.height, - CompressibleVDFField.ICC_EOS_VDF, + uint8(CompressibleVDFField.ICC_EOS_VDF), ) ) - full_node_protocol_invalid_messaages.append( + full_node_protocol_invalid_messages.append( fnp.RespondCompactVDF( block.height, block.header_hash, - CompressibleVDFField.ICC_EOS_VDF, + uint8(CompressibleVDFField.ICC_EOS_VDF), vdf_info, wrong_vdf_proof, ) @@ -2015,14 +2185,14 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h sp_vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_SP_VDF, + uint8(CompressibleVDFField.CC_SP_VDF), ) ) - full_node_protocol_invalid_messaages.append( + full_node_protocol_invalid_messages.append( fnp.RespondCompactVDF( block.height, block.header_hash, - CompressibleVDFField.CC_SP_VDF, + uint8(CompressibleVDFField.CC_SP_VDF), vdf_info, sp_vdf_proof, ) @@ -2045,14 +2215,14 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h ip_vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_IP_VDF, + uint8(CompressibleVDFField.CC_IP_VDF), ) ) - full_node_protocol_invalid_messaages.append( + full_node_protocol_invalid_messages.append( fnp.RespondCompactVDF( block.height, block.header_hash, - CompressibleVDFField.CC_IP_VDF, + uint8(CompressibleVDFField.CC_IP_VDF), vdf_info, ip_vdf_proof, ) @@ -2064,7 +2234,7 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h wrong_vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_EOS_VDF, + uint8(CompressibleVDFField.CC_EOS_VDF), ) ) timelord_protocol_invalid_messages.append( @@ -2073,7 +2243,7 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h wrong_vdf_proof, block.header_hash, block.height, - CompressibleVDFField.ICC_EOS_VDF, + uint8(CompressibleVDFField.ICC_EOS_VDF), ) ) timelord_protocol_invalid_messages.append( @@ -2082,7 +2252,7 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h wrong_vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_SP_VDF, + uint8(CompressibleVDFField.CC_SP_VDF), ) ) timelord_protocol_invalid_messages.append( @@ -2091,41 +2261,41 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h wrong_vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_IP_VDF, + uint8(CompressibleVDFField.CC_IP_VDF), ) ) - full_node_protocol_invalid_messaages.append( + full_node_protocol_invalid_messages.append( fnp.RespondCompactVDF( block.height, block.header_hash, - CompressibleVDFField.CC_EOS_VDF, + uint8(CompressibleVDFField.CC_EOS_VDF), wrong_vdf_info, wrong_vdf_proof, ) ) - full_node_protocol_invalid_messaages.append( + full_node_protocol_invalid_messages.append( fnp.RespondCompactVDF( block.height, block.header_hash, - CompressibleVDFField.ICC_EOS_VDF, + uint8(CompressibleVDFField.ICC_EOS_VDF), wrong_vdf_info, wrong_vdf_proof, ) ) - full_node_protocol_invalid_messaages.append( + full_node_protocol_invalid_messages.append( fnp.RespondCompactVDF( block.height, block.header_hash, - CompressibleVDFField.CC_SP_VDF, + uint8(CompressibleVDFField.CC_SP_VDF), wrong_vdf_info, wrong_vdf_proof, ) ) - full_node_protocol_invalid_messaages.append( + full_node_protocol_invalid_messages.append( fnp.RespondCompactVDF( block.height, block.header_hash, - CompressibleVDFField.CC_IP_VDF, + uint8(CompressibleVDFField.CC_IP_VDF), wrong_vdf_info, wrong_vdf_proof, ) @@ -2135,8 +2305,8 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h peer = await connect_and_get_peer(server_1, server_2, self_hostname) for invalid_compact_proof in timelord_protocol_invalid_messages: await full_node_1.full_node.add_compact_proof_of_time(invalid_compact_proof) - for invalid_compact_proof in full_node_protocol_invalid_messaages: - await full_node_1.full_node.add_compact_vdf(invalid_compact_proof, peer) + for invalid_compact_vdf in full_node_protocol_invalid_messages: + await full_node_1.full_node.add_compact_vdf(invalid_compact_vdf, peer) stored_blocks = await full_node_1.get_all_full_blocks() for block in stored_blocks: for sub_slot in block.finished_sub_slots: @@ -2149,7 +2319,9 @@ async def test_compact_protocol_invalid_messages(setup_two_nodes_fixture, self_h @pytest.mark.anyio -async def test_respond_compact_proof_message_limit(setup_two_nodes_fixture): +async def test_respond_compact_proof_message_limit( + setup_two_nodes_fixture: tuple[list[FullNodeSimulator], list[tuple[WalletNode, ChiaServer]], BlockTools], +) -> None: nodes, _, bt = setup_two_nodes_fixture full_node_1 = nodes[0] full_node_2 = nodes[1] @@ -2174,11 +2346,11 @@ async def test_respond_compact_proof_message_limit(setup_two_nodes_fixture): vdf_proof, block.header_hash, block.height, - CompressibleVDFField.CC_IP_VDF, + uint8(CompressibleVDFField.CC_IP_VDF), ) ) - async def coro(full_node, compact_proof): + async def coro(full_node: FullNodeSimulator, compact_proof: timelord_protocol.RespondCompactProofOfTime) -> None: await full_node.respond_compact_proof_of_time(compact_proof) full_node_1.full_node._compact_vdf_sem = LimitedSemaphore.create(active_limit=1, waiting_limit=2) @@ -2366,12 +2538,12 @@ async def validate_coin_set(coin_store: CoinStore, blocks: list[FullBlock]) -> N @pytest.mark.parametrize("light_blocks", [True, False]) async def test_long_reorg( light_blocks: bool, - one_node_one_block, + one_node_one_block: tuple[FullNodeSimulator, ChiaServer, BlockTools], default_10000_blocks: list[FullBlock], test_long_reorg_1500_blocks: list[FullBlock], test_long_reorg_1500_blocks_light: list[FullBlock], seeded_random: random.Random, -): +) -> None: node, _server, _bt = one_node_one_block fork_point = 1499 @@ -2386,6 +2558,7 @@ async def test_long_reorg( await add_blocks_in_batches(blocks, node.full_node) peak = node.full_node.blockchain.get_peak() + assert peak is not None chain_1_height = peak.height chain_1_weight = peak.weight chain_1_peak = peak.header_hash @@ -2393,6 +2566,7 @@ async def test_long_reorg( assert reorg_blocks[fork_point] == default_10000_blocks[fork_point] assert reorg_blocks[fork_point + 1] != default_10000_blocks[fork_point + 1] + assert node.full_node._coin_store is not None await validate_coin_set(node.full_node._coin_store, blocks) # one aspect of this test is to make sure we can reorg blocks that are @@ -2402,6 +2576,7 @@ async def test_long_reorg( await add_blocks_in_batches(reorg_blocks, node.full_node) # if these asserts fires, there was no reorg peak = node.full_node.blockchain.get_peak() + assert peak is not None assert peak.header_hash != chain_1_peak assert peak.weight > chain_1_weight chain_2_weight = peak.weight @@ -2420,7 +2595,7 @@ async def test_long_reorg( # this exercises the case where we have some of the blocks in the DB already node.full_node.blockchain.clean_block_records() # when using add_block manualy we must warmup the cache - await node.full_node.blockchain.warmup(fork_point - 100) + await node.full_node.blockchain.warmup(uint32(fork_point - 100)) if light_blocks: blocks = default_10000_blocks[fork_point - 100 : 3200] else: @@ -2428,6 +2603,7 @@ async def test_long_reorg( await add_blocks_in_batches(blocks, node.full_node) # if these asserts fires, there was no reorg back to the original chain peak = node.full_node.blockchain.get_peak() + assert peak is not None assert peak.header_hash != chain_2_peak assert peak.weight > chain_2_weight @@ -2443,7 +2619,7 @@ async def test_long_reorg_nodes( light_blocks: bool, chain_length: int, fork_point: int, - three_nodes, + three_nodes: list[FullNodeAPI], default_10000_blocks: list[FullBlock], test_long_reorg_blocks: list[FullBlock], test_long_reorg_blocks_light: list[FullBlock], @@ -2451,9 +2627,13 @@ async def test_long_reorg_nodes( test_long_reorg_1500_blocks_light: list[FullBlock], self_hostname: str, seeded_random: random.Random, -): +) -> None: full_node_1, full_node_2, full_node_3 = three_nodes + assert full_node_1.full_node._coin_store is not None + assert full_node_2.full_node._coin_store is not None + assert full_node_3.full_node._coin_store is not None + if fork_point == 1500: blocks = default_10000_blocks[: 3600 - chain_length] else: @@ -2488,13 +2668,14 @@ async def test_long_reorg_nodes( start = time.monotonic() - def check_nodes_in_sync(): + def check_nodes_in_sync() -> bool: p1 = full_node_2.full_node.blockchain.get_peak() p2 = full_node_1.full_node.blockchain.get_peak() return p1 == p2 await time_out_assert(100, check_nodes_in_sync) peak = full_node_2.full_node.blockchain.get_peak() + assert peak is not None print(f"peak: {str(peak.header_hash)[:6]}") reorg1_timing = time.monotonic() - start @@ -2502,7 +2683,9 @@ def check_nodes_in_sync(): p1 = full_node_1.full_node.blockchain.get_peak() p2 = full_node_2.full_node.blockchain.get_peak() + assert p1 is not None assert p1.header_hash == reorg_blocks[-1].header_hash + assert p2 is not None assert p2.header_hash == reorg_blocks[-1].header_hash await validate_coin_set(full_node_1.full_node._coin_store, reorg_blocks) @@ -2522,7 +2705,7 @@ def check_nodes_in_sync(): start = time.monotonic() - def check_nodes_in_sync2(): + def check_nodes_in_sync2() -> bool: p1 = full_node_1.full_node.blockchain.get_peak() p2 = full_node_2.full_node.blockchain.get_peak() p3 = full_node_3.full_node.blockchain.get_peak() @@ -2536,8 +2719,11 @@ def check_nodes_in_sync2(): p2 = full_node_2.full_node.blockchain.get_peak() p3 = full_node_3.full_node.blockchain.get_peak() + assert p1 is not None assert p1.header_hash == blocks[-1].header_hash + assert p2 is not None assert p2.header_hash == blocks[-1].header_hash + assert p3 is not None assert p3.header_hash == blocks[-1].header_hash print(f"reorg1 timing: {reorg1_timing:0.2f}s") @@ -2549,11 +2735,7 @@ def check_nodes_in_sync2(): @pytest.mark.anyio -async def test_shallow_reorg_nodes( - three_nodes, - self_hostname: str, - bt: BlockTools, -): +async def test_shallow_reorg_nodes(three_nodes: list[FullNodeAPI], self_hostname: str, bt: BlockTools) -> None: full_node_1, full_node_2, _ = three_nodes # node 1 has chan A, then we replace the top block and ensure @@ -2580,7 +2762,7 @@ async def test_shallow_reorg_nodes( if coin.puzzle_hash == coinbase_puzzlehash: all_coins.append(coin) - def check_nodes_in_sync(): + def check_nodes_in_sync() -> bool: p1 = full_node_2.full_node.blockchain.get_peak() p2 = full_node_1.full_node.blockchain.get_peak() return p1 == p2 @@ -2625,7 +2807,9 @@ def check_nodes_in_sync(): await add_blocks_in_batches(chain_b[-1:], full_node_1.full_node) # make sure node 1 reorged onto chain B - assert full_node_1.full_node.blockchain.get_peak().header_hash == chain_b[-1].header_hash + peak = full_node_1.full_node.blockchain.get_peak() + assert peak is not None + assert peak.header_hash == chain_b[-1].header_hash await time_out_assert(10, check_nodes_in_sync) await validate_coin_set(full_node_1.full_node.blockchain.coin_store, chain_b) diff --git a/mypy-exclusions.txt b/mypy-exclusions.txt index 7500a8d4d98b..e380c9ac6fa9 100644 --- a/mypy-exclusions.txt +++ b/mypy-exclusions.txt @@ -56,7 +56,6 @@ chia._tests.core.daemon.test_daemon chia._tests.core.full_node.full_sync.test_full_sync chia._tests.core.full_node.stores.test_sync_store chia._tests.core.full_node.test_address_manager -chia._tests.core.full_node.test_full_node chia._tests.core.full_node.test_node_load chia._tests.core.full_node.test_performance chia._tests.core.full_node.test_transactions