chia-blockchain 2.5.0rc2__py3-none-any.whl → 2.5.1rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/_tests/README.md +1 -1
- chia/_tests/blockchain/blockchain_test_utils.py +24 -26
- chia/_tests/blockchain/test_augmented_chain.py +6 -8
- chia/_tests/blockchain/test_blockchain.py +409 -307
- chia/_tests/blockchain/test_blockchain_transactions.py +56 -75
- chia/_tests/blockchain/test_build_chains.py +11 -13
- chia/_tests/blockchain/test_get_block_generator.py +8 -8
- chia/_tests/blockchain/test_lookup_fork_chain.py +3 -4
- chia/_tests/build-init-files.py +3 -4
- chia/_tests/build-job-matrix.py +9 -9
- chia/_tests/check_sql_statements.py +2 -3
- chia/_tests/clvm/benchmark_costs.py +1 -1
- chia/_tests/clvm/coin_store.py +7 -5
- chia/_tests/clvm/test_chialisp_deserialization.py +8 -8
- chia/_tests/clvm/test_condition_codes.py +2 -2
- chia/_tests/clvm/test_curry_and_treehash.py +2 -4
- chia/_tests/clvm/test_message_conditions.py +184 -0
- chia/_tests/clvm/test_puzzle_compression.py +1 -2
- chia/_tests/clvm/test_puzzle_drivers.py +3 -3
- chia/_tests/clvm/test_puzzles.py +13 -18
- chia/_tests/clvm/test_singletons.py +17 -17
- chia/_tests/clvm/test_spend_sim.py +7 -7
- chia/_tests/cmds/cmd_test_utils.py +42 -45
- chia/_tests/cmds/conftest.py +2 -2
- chia/_tests/cmds/test_click_types.py +21 -16
- chia/_tests/cmds/test_cmd_framework.py +255 -35
- chia/_tests/cmds/test_cmds_util.py +2 -2
- chia/_tests/cmds/test_daemon.py +3 -3
- chia/_tests/cmds/test_dev_gh.py +131 -0
- chia/_tests/cmds/test_farm_cmd.py +1 -2
- chia/_tests/cmds/test_show.py +6 -6
- chia/_tests/cmds/test_tx_config_args.py +2 -1
- chia/_tests/cmds/wallet/test_dao.py +23 -23
- chia/_tests/cmds/wallet/test_did.py +29 -29
- chia/_tests/cmds/wallet/test_nft.py +24 -23
- chia/_tests/cmds/wallet/test_notifications.py +8 -8
- chia/_tests/cmds/wallet/test_tx_decorators.py +3 -3
- chia/_tests/cmds/wallet/test_vcs.py +97 -73
- chia/_tests/cmds/wallet/test_wallet.py +74 -75
- chia/_tests/cmds/wallet/test_wallet_check.py +5 -7
- chia/_tests/conftest.py +153 -38
- chia/_tests/connection_utils.py +7 -6
- chia/_tests/core/cmds/test_beta.py +3 -3
- chia/_tests/core/cmds/test_keys.py +6 -6
- chia/_tests/core/cmds/test_wallet.py +3 -3
- chia/_tests/core/consensus/test_block_creation.py +3 -5
- chia/_tests/core/custom_types/test_coin.py +1 -3
- chia/_tests/core/custom_types/test_spend_bundle.py +3 -4
- chia/_tests/core/daemon/test_daemon.py +58 -58
- chia/_tests/core/daemon/test_keychain_proxy.py +2 -1
- chia/_tests/core/data_layer/conftest.py +4 -3
- chia/_tests/core/data_layer/test_data_cli.py +1 -2
- chia/_tests/core/data_layer/test_data_layer.py +5 -5
- chia/_tests/core/data_layer/test_data_layer_util.py +8 -9
- chia/_tests/core/data_layer/test_data_rpc.py +75 -93
- chia/_tests/core/data_layer/test_data_store.py +38 -37
- chia/_tests/core/data_layer/test_data_store_schema.py +11 -11
- chia/_tests/core/data_layer/util.py +11 -10
- chia/_tests/core/farmer/test_farmer_api.py +6 -4
- chia/_tests/core/full_node/full_sync/test_full_sync.py +5 -10
- chia/_tests/core/full_node/ram_db.py +2 -2
- chia/_tests/core/full_node/stores/test_block_store.py +113 -11
- chia/_tests/core/full_node/stores/test_coin_store.py +37 -28
- chia/_tests/core/full_node/stores/test_full_node_store.py +34 -30
- chia/_tests/core/full_node/stores/test_hint_store.py +3 -4
- chia/_tests/core/full_node/test_address_manager.py +2 -2
- chia/_tests/core/full_node/test_block_height_map.py +1 -1
- chia/_tests/core/full_node/test_conditions.py +10 -12
- chia/_tests/core/full_node/test_full_node.py +2077 -1822
- chia/_tests/core/full_node/test_generator_tools.py +4 -4
- chia/_tests/core/full_node/test_hint_management.py +2 -2
- chia/_tests/core/full_node/test_performance.py +2 -5
- chia/_tests/core/full_node/test_subscriptions.py +4 -4
- chia/_tests/core/full_node/test_tx_processing_queue.py +5 -4
- chia/_tests/core/make_block_generator.py +5 -7
- chia/_tests/core/mempool/test_mempool.py +205 -208
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +5 -5
- chia/_tests/core/mempool/test_mempool_item_queries.py +2 -4
- chia/_tests/core/mempool/test_mempool_manager.py +109 -80
- chia/_tests/core/mempool/test_mempool_performance.py +3 -4
- chia/_tests/core/mempool/test_singleton_fast_forward.py +12 -12
- chia/_tests/core/server/flood.py +6 -4
- chia/_tests/core/server/serve.py +10 -7
- chia/_tests/core/server/test_api_protocol.py +21 -0
- chia/_tests/core/server/test_capabilities.py +3 -5
- chia/_tests/core/server/test_dos.py +15 -16
- chia/_tests/core/server/test_loop.py +14 -10
- chia/_tests/core/server/test_node_discovery.py +1 -2
- chia/_tests/core/server/test_rate_limits.py +156 -44
- chia/_tests/core/server/test_server.py +8 -7
- chia/_tests/core/services/test_services.py +59 -37
- chia/_tests/core/ssl/test_ssl.py +5 -3
- chia/_tests/core/test_cost_calculation.py +5 -6
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_db_conversion.py +5 -4
- chia/_tests/core/test_db_validation.py +6 -5
- chia/_tests/core/test_farmer_harvester_rpc.py +8 -7
- chia/_tests/core/test_filter.py +3 -5
- chia/_tests/core/test_full_node_rpc.py +64 -90
- chia/_tests/core/test_merkle_set.py +10 -10
- chia/_tests/core/test_program.py +2 -4
- chia/_tests/core/test_rpc_util.py +1 -2
- chia/_tests/core/test_seeder.py +124 -12
- chia/_tests/core/util/test_block_cache.py +5 -5
- chia/_tests/core/util/test_cached_bls.py +3 -3
- chia/_tests/core/util/test_config.py +13 -13
- chia/_tests/core/util/test_files.py +2 -2
- chia/_tests/core/util/test_jsonify.py +9 -9
- chia/_tests/core/util/test_keychain.py +13 -5
- chia/_tests/core/util/test_keyring_wrapper.py +6 -5
- chia/_tests/core/util/test_log_exceptions.py +3 -3
- chia/_tests/core/util/test_streamable.py +38 -38
- chia/_tests/db/test_db_wrapper.py +13 -12
- chia/_tests/environments/common.py +2 -2
- chia/_tests/environments/full_node.py +2 -2
- chia/_tests/environments/wallet.py +109 -48
- chia/_tests/farmer_harvester/test_farmer.py +35 -35
- chia/_tests/farmer_harvester/test_farmer_harvester.py +17 -17
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +73 -46
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +8 -8
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +47 -47
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +6 -7
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +11 -11
- chia/_tests/generator/test_compression.py +13 -30
- chia/_tests/generator/test_generator_types.py +3 -3
- chia/_tests/generator/test_rom.py +7 -9
- chia/_tests/plot_sync/test_delta.py +2 -3
- chia/_tests/plot_sync/test_plot_sync.py +25 -24
- chia/_tests/plot_sync/test_receiver.py +9 -9
- chia/_tests/plot_sync/test_sender.py +1 -1
- chia/_tests/plot_sync/test_sync_simulated.py +27 -26
- chia/_tests/plot_sync/util.py +2 -1
- chia/_tests/plotting/test_plot_manager.py +54 -11
- chia/_tests/plotting/util.py +2 -3
- chia/_tests/pools/test_pool_cli_parsing.py +128 -0
- chia/_tests/pools/test_pool_cmdline.py +993 -15
- chia/_tests/pools/test_pool_config.py +3 -5
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +10 -11
- chia/_tests/pools/test_pool_rpc.py +203 -90
- chia/_tests/pools/test_pool_wallet.py +12 -8
- chia/_tests/pools/test_wallet_pool_store.py +3 -3
- chia/_tests/process_junit.py +16 -17
- chia/_tests/rpc/test_rpc_client.py +59 -2
- chia/_tests/rpc/test_rpc_server.py +183 -0
- chia/_tests/simulation/test_simulation.py +5 -5
- chia/_tests/simulation/test_simulator.py +8 -10
- chia/_tests/simulation/test_start_simulator.py +5 -4
- chia/_tests/timelord/test_new_peak.py +19 -19
- chia/_tests/tools/test_run_block.py +1 -2
- chia/_tests/tools/test_virtual_project.py +591 -0
- chia/_tests/util/benchmark_cost.py +9 -9
- chia/_tests/util/benchmarks.py +1 -2
- chia/_tests/util/blockchain.py +12 -11
- chia/_tests/util/blockchain_mock.py +15 -15
- chia/_tests/util/build_network_protocol_files.py +12 -12
- chia/_tests/util/db_connection.py +3 -2
- chia/_tests/util/full_sync.py +14 -6
- chia/_tests/util/gen_ssl_certs.py +4 -5
- chia/_tests/util/generator_tools_testing.py +5 -7
- chia/_tests/util/get_name_puzzle_conditions.py +52 -0
- chia/_tests/util/key_tool.py +2 -3
- chia/_tests/util/misc.py +59 -106
- chia/_tests/util/network_protocol_data.py +7 -9
- chia/_tests/util/protocol_messages_json.py +112 -111
- chia/_tests/util/rpc.py +3 -0
- chia/_tests/util/run_block.py +16 -16
- chia/_tests/util/setup_nodes.py +25 -23
- chia/{clvm → _tests/util}/spend_sim.py +59 -55
- chia/_tests/util/split_managers.py +12 -9
- chia/_tests/util/temp_file.py +1 -1
- chia/_tests/util/test_action_scope.py +2 -1
- chia/_tests/util/test_async_pool.py +8 -8
- chia/_tests/util/test_build_job_matrix.py +2 -3
- chia/_tests/util/test_condition_tools.py +4 -6
- chia/_tests/util/test_config.py +5 -5
- chia/_tests/util/test_dump_keyring.py +1 -1
- chia/_tests/util/test_full_block_utils.py +19 -11
- chia/_tests/util/test_limited_semaphore.py +4 -3
- chia/_tests/util/test_logging_filter.py +2 -3
- chia/_tests/util/test_misc.py +29 -28
- chia/_tests/util/test_network.py +32 -31
- chia/_tests/util/test_network_protocol_files.py +2 -3
- chia/_tests/util/test_network_protocol_json.py +1 -0
- chia/_tests/util/test_network_protocol_test.py +18 -19
- chia/_tests/util/test_paginator.py +3 -4
- chia/_tests/util/test_pprint.py +1 -1
- chia/_tests/util/test_priority_mutex.py +18 -17
- chia/_tests/util/test_recursive_replace.py +2 -2
- chia/_tests/util/test_testnet_overrides.py +3 -3
- chia/_tests/util/test_timing.py +1 -1
- chia/_tests/util/test_trusted_peer.py +2 -2
- chia/_tests/util/time_out_assert.py +43 -6
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +13 -13
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +117 -29
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +15 -15
- chia/_tests/wallet/cat_wallet/test_trades.py +50 -28
- chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -5
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +6 -6
- chia/_tests/wallet/clawback/test_clawback_metadata.py +1 -2
- chia/_tests/wallet/conftest.py +135 -74
- chia/_tests/wallet/dao_wallet/test_dao_clvm.py +25 -17
- chia/_tests/wallet/dao_wallet/test_dao_wallets.py +75 -75
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +10 -12
- chia/_tests/wallet/db_wallet/test_dl_offers.py +6 -6
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +18 -18
- chia/_tests/wallet/did_wallet/test_did.py +1277 -474
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +12 -11
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +115 -105
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +6 -7
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +16 -16
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +3 -3
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +38 -12
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +1 -1
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +31 -33
- chia/_tests/wallet/rpc/test_wallet_rpc.py +218 -171
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +36 -37
- chia/_tests/wallet/sync/test_wallet_sync.py +241 -78
- chia/_tests/wallet/test_address_type.py +20 -20
- chia/_tests/wallet/test_clvm_streamable.py +5 -5
- chia/_tests/wallet/test_coin_management.py +354 -0
- chia/_tests/wallet/test_coin_selection.py +34 -35
- chia/_tests/wallet/test_conditions.py +28 -16
- chia/_tests/wallet/test_debug_spend_bundle.py +156 -14
- chia/_tests/wallet/test_new_wallet_protocol.py +29 -31
- chia/_tests/wallet/test_nft_store.py +1 -2
- chia/_tests/wallet/test_notifications.py +2 -2
- chia/_tests/wallet/test_offer_parsing_performance.py +1 -1
- chia/_tests/wallet/test_puzzle_store.py +2 -3
- chia/_tests/wallet/test_sign_coin_spends.py +3 -3
- chia/_tests/wallet/test_signer_protocol.py +33 -34
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +29 -29
- chia/_tests/wallet/test_taproot.py +1 -1
- chia/_tests/wallet/test_transaction_store.py +23 -19
- chia/_tests/wallet/test_util.py +36 -32
- chia/_tests/wallet/test_wallet.py +37 -37
- chia/_tests/wallet/test_wallet_action_scope.py +8 -8
- chia/_tests/wallet/test_wallet_blockchain.py +4 -6
- chia/_tests/wallet/test_wallet_coin_store.py +34 -34
- chia/_tests/wallet/test_wallet_node.py +69 -72
- chia/_tests/wallet/test_wallet_retry.py +3 -3
- chia/_tests/wallet/test_wallet_state_manager.py +12 -5
- chia/_tests/wallet/test_wallet_trade_store.py +2 -2
- chia/_tests/wallet/test_wallet_utils.py +5 -4
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -3
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +18 -18
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +69 -40
- chia/_tests/wallet/wallet_block_tools.py +27 -27
- chia/_tests/weight_proof/test_weight_proof.py +30 -30
- chia/apis.py +19 -0
- chia/cmds/beta.py +8 -7
- chia/cmds/beta_funcs.py +15 -11
- chia/cmds/check_wallet_db.py +29 -27
- chia/cmds/chia.py +17 -9
- chia/cmds/cmd_classes.py +87 -79
- chia/cmds/cmd_helpers.py +242 -0
- chia/cmds/cmds_util.py +56 -66
- chia/cmds/coin_funcs.py +168 -153
- chia/cmds/coins.py +156 -194
- chia/cmds/configure.py +4 -3
- chia/cmds/dao.py +89 -33
- chia/cmds/dao_funcs.py +55 -33
- chia/cmds/data.py +7 -6
- chia/cmds/data_funcs.py +26 -21
- chia/cmds/db.py +4 -3
- chia/cmds/db_backup_func.py +2 -2
- chia/cmds/db_upgrade_func.py +3 -3
- chia/cmds/db_validate_func.py +2 -2
- chia/cmds/dev.py +2 -0
- chia/cmds/farm.py +18 -5
- chia/cmds/farm_funcs.py +17 -24
- chia/cmds/gh.py +275 -0
- chia/cmds/init.py +4 -11
- chia/cmds/init_funcs.py +9 -9
- chia/cmds/installers.py +5 -3
- chia/cmds/keys.py +56 -39
- chia/cmds/keys_funcs.py +30 -31
- chia/cmds/netspace.py +6 -3
- chia/cmds/netspace_funcs.py +3 -2
- chia/cmds/param_types.py +16 -6
- chia/cmds/passphrase.py +8 -7
- chia/cmds/passphrase_funcs.py +7 -61
- chia/cmds/peer.py +2 -1
- chia/cmds/peer_funcs.py +5 -5
- chia/cmds/plotnft.py +207 -153
- chia/cmds/plotnft_funcs.py +205 -174
- chia/cmds/plots.py +14 -6
- chia/cmds/plotters.py +2 -1
- chia/cmds/rpc.py +48 -28
- chia/cmds/show.py +2 -1
- chia/cmds/show_funcs.py +7 -6
- chia/cmds/signer.py +50 -58
- chia/cmds/sim.py +22 -14
- chia/cmds/sim_funcs.py +11 -11
- chia/cmds/start.py +3 -3
- chia/cmds/start_funcs.py +9 -12
- chia/cmds/stop.py +4 -3
- chia/cmds/units.py +1 -3
- chia/cmds/wallet.py +252 -96
- chia/cmds/wallet_funcs.py +217 -143
- chia/consensus/block_body_validation.py +133 -86
- chia/consensus/block_creation.py +42 -21
- chia/consensus/block_header_validation.py +32 -37
- chia/consensus/block_record.py +1 -2
- chia/consensus/blockchain.py +167 -180
- chia/consensus/blockchain_interface.py +10 -10
- chia/consensus/constants.py +2 -2
- chia/consensus/default_constants.py +3 -4
- chia/consensus/difficulty_adjustment.py +5 -5
- chia/consensus/find_fork_point.py +5 -5
- chia/consensus/full_block_to_block_record.py +4 -4
- chia/consensus/get_block_challenge.py +2 -2
- chia/consensus/get_block_generator.py +4 -3
- chia/consensus/multiprocess_validation.py +207 -304
- chia/consensus/vdf_info_computation.py +3 -3
- chia/daemon/client.py +46 -27
- chia/daemon/keychain_proxy.py +10 -9
- chia/daemon/keychain_server.py +18 -18
- chia/daemon/server.py +103 -113
- chia/daemon/windows_signal.py +2 -2
- chia/data_layer/data_layer.py +64 -76
- chia/data_layer/data_layer_api.py +8 -0
- chia/data_layer/data_layer_errors.py +3 -3
- chia/data_layer/data_layer_server.py +2 -2
- chia/data_layer/data_layer_util.py +71 -71
- chia/data_layer/data_layer_wallet.py +63 -67
- chia/data_layer/data_store.py +72 -72
- chia/data_layer/dl_wallet_store.py +10 -10
- chia/data_layer/download_data.py +5 -5
- chia/data_layer/s3_plugin_service.py +9 -9
- chia/data_layer/util/benchmark.py +0 -1
- chia/data_layer/util/plugin.py +2 -3
- chia/farmer/farmer.py +46 -43
- chia/farmer/farmer_api.py +27 -21
- chia/full_node/block_height_map.py +6 -6
- chia/full_node/block_store.py +41 -35
- chia/full_node/coin_store.py +42 -41
- chia/full_node/fee_estimate.py +2 -2
- chia/full_node/fee_estimation.py +1 -2
- chia/full_node/fee_history.py +5 -6
- chia/full_node/fee_tracker.py +24 -24
- chia/full_node/full_node.py +574 -300
- chia/full_node/full_node_api.py +181 -130
- chia/full_node/full_node_store.py +43 -43
- chia/full_node/hint_management.py +4 -4
- chia/full_node/hint_store.py +9 -10
- chia/full_node/mempool.py +25 -19
- chia/full_node/mempool_check_conditions.py +11 -42
- chia/full_node/mempool_manager.py +48 -53
- chia/full_node/pending_tx_cache.py +9 -9
- chia/full_node/subscriptions.py +23 -24
- chia/full_node/sync_store.py +8 -7
- chia/full_node/tx_processing_queue.py +3 -3
- chia/full_node/util/__init__.py +0 -0
- chia/full_node/weight_proof.py +79 -78
- chia/harvester/harvester.py +9 -8
- chia/harvester/harvester_api.py +19 -13
- chia/introducer/introducer.py +7 -5
- chia/introducer/introducer_api.py +9 -3
- chia/legacy/keyring.py +6 -5
- chia/plot_sync/delta.py +8 -8
- chia/plot_sync/receiver.py +12 -11
- chia/plot_sync/sender.py +15 -12
- chia/plotters/bladebit.py +12 -12
- chia/plotters/chiapos.py +2 -2
- chia/plotters/madmax.py +8 -8
- chia/plotters/plotters.py +6 -6
- chia/plotters/plotters_util.py +6 -4
- chia/plotting/cache.py +8 -7
- chia/plotting/check_plots.py +8 -8
- chia/plotting/create_plots.py +6 -6
- chia/plotting/manager.py +22 -22
- chia/plotting/util.py +31 -19
- chia/pools/pool_config.py +7 -7
- chia/pools/pool_puzzles.py +16 -16
- chia/pools/pool_wallet.py +64 -57
- chia/pools/pool_wallet_info.py +3 -3
- chia/protocols/full_node_protocol.py +3 -3
- chia/protocols/harvester_protocol.py +12 -12
- chia/protocols/introducer_protocol.py +1 -2
- chia/protocols/protocol_message_types.py +4 -4
- chia/protocols/protocol_state_machine.py +2 -2
- chia/protocols/protocol_timing.py +1 -0
- chia/protocols/shared_protocol.py +3 -3
- chia/protocols/timelord_protocol.py +2 -2
- chia/protocols/wallet_protocol.py +33 -33
- chia/rpc/crawler_rpc_api.py +12 -7
- chia/rpc/data_layer_rpc_api.py +49 -44
- chia/rpc/data_layer_rpc_client.py +41 -41
- chia/rpc/data_layer_rpc_util.py +7 -11
- chia/rpc/farmer_rpc_api.py +32 -27
- chia/rpc/farmer_rpc_client.py +14 -14
- chia/rpc/full_node_rpc_api.py +53 -48
- chia/rpc/full_node_rpc_client.py +30 -30
- chia/rpc/harvester_rpc_api.py +16 -11
- chia/rpc/harvester_rpc_client.py +6 -6
- chia/rpc/rpc_client.py +34 -14
- chia/rpc/rpc_server.py +117 -43
- chia/rpc/timelord_rpc_api.py +9 -4
- chia/rpc/util.py +11 -211
- chia/rpc/wallet_request_types.py +276 -60
- chia/rpc/wallet_rpc_api.py +563 -399
- chia/rpc/wallet_rpc_client.py +220 -250
- chia/seeder/crawl_store.py +6 -8
- chia/seeder/crawler.py +23 -36
- chia/seeder/crawler_api.py +28 -22
- chia/seeder/dns_server.py +99 -50
- chia/seeder/start_crawler.py +13 -9
- chia/server/address_manager.py +19 -19
- chia/server/address_manager_store.py +17 -17
- chia/server/api_protocol.py +106 -1
- chia/server/capabilities.py +3 -3
- chia/server/chia_policy.py +17 -16
- chia/server/introducer_peers.py +3 -3
- chia/server/node_discovery.py +34 -38
- chia/server/rate_limit_numbers.py +26 -16
- chia/server/rate_limits.py +67 -27
- chia/server/server.py +52 -31
- chia/server/signal_handlers.py +6 -3
- chia/server/ssl_context.py +5 -5
- chia/server/start_data_layer.py +37 -23
- chia/server/start_farmer.py +28 -16
- chia/server/start_full_node.py +29 -23
- chia/server/start_harvester.py +28 -15
- chia/server/start_introducer.py +27 -15
- chia/server/start_service.py +17 -29
- chia/server/start_timelord.py +25 -18
- chia/server/start_wallet.py +22 -18
- chia/server/upnp.py +4 -3
- chia/server/ws_connection.py +68 -54
- chia/simulator/add_blocks_in_batches.py +54 -0
- chia/simulator/block_tools.py +65 -64
- chia/simulator/full_node_simulator.py +66 -74
- chia/simulator/setup_services.py +10 -9
- chia/simulator/simulator_full_node_rpc_api.py +12 -14
- chia/simulator/simulator_full_node_rpc_client.py +3 -5
- chia/simulator/simulator_test_tools.py +8 -7
- chia/simulator/socket.py +1 -4
- chia/simulator/ssl_certs.py +5 -5
- chia/simulator/ssl_certs_1.py +2 -4
- chia/simulator/ssl_certs_10.py +2 -4
- chia/simulator/ssl_certs_2.py +2 -4
- chia/simulator/ssl_certs_3.py +2 -4
- chia/simulator/ssl_certs_4.py +2 -4
- chia/simulator/ssl_certs_5.py +2 -4
- chia/simulator/ssl_certs_6.py +2 -4
- chia/simulator/ssl_certs_7.py +2 -4
- chia/simulator/ssl_certs_8.py +2 -4
- chia/simulator/ssl_certs_9.py +2 -4
- chia/simulator/start_simulator.py +14 -6
- chia/simulator/wallet_tools.py +21 -20
- chia/ssl/create_ssl.py +11 -11
- chia/timelord/iters_from_block.py +2 -2
- chia/timelord/timelord.py +57 -33
- chia/timelord/timelord_api.py +12 -6
- chia/timelord/timelord_launcher.py +10 -8
- chia/timelord/timelord_state.py +5 -5
- chia/types/block_protocol.py +2 -2
- chia/types/blockchain_format/coin.py +3 -3
- chia/types/blockchain_format/program.py +17 -18
- chia/types/blockchain_format/tree_hash.py +9 -9
- chia/types/coin_spend.py +8 -8
- chia/types/condition_with_args.py +1 -2
- chia/types/eligible_coin_spends.py +16 -15
- chia/types/generator_types.py +1 -2
- chia/types/internal_mempool_item.py +1 -2
- chia/types/mempool_item.py +7 -7
- chia/types/mempool_submission_status.py +2 -2
- chia/types/peer_info.py +1 -1
- chia/types/spend_bundle.py +1 -2
- chia/types/transaction_queue_entry.py +2 -2
- chia/types/unfinished_header_block.py +2 -2
- chia/types/validation_state.py +14 -0
- chia/types/weight_proof.py +5 -6
- chia/util/action_scope.py +8 -8
- chia/util/async_pool.py +6 -4
- chia/util/augmented_chain.py +13 -9
- chia/util/batches.py +5 -2
- chia/util/bech32m.py +14 -11
- chia/util/beta_metrics.py +5 -4
- chia/util/block_cache.py +5 -5
- chia/util/byte_types.py +2 -0
- chia/util/check_fork_next_block.py +3 -2
- chia/util/chia_logging.py +41 -21
- chia/util/collection.py +3 -3
- chia/util/condition_tools.py +18 -18
- chia/util/config.py +26 -25
- chia/util/cpu.py +2 -0
- chia/util/db_synchronous.py +2 -0
- chia/util/db_version.py +2 -0
- chia/util/db_wrapper.py +13 -10
- chia/util/default_root.py +17 -0
- chia/util/dump_keyring.py +6 -6
- chia/util/errors.py +5 -3
- chia/util/file_keyring.py +22 -33
- chia/util/files.py +2 -0
- chia/util/full_block_utils.py +31 -7
- chia/util/generator_tools.py +18 -8
- chia/util/hash.py +3 -1
- chia/util/initial-config.yaml +19 -0
- chia/util/inline_executor.py +2 -0
- chia/util/ip_address.py +39 -0
- chia/util/json_util.py +0 -4
- chia/util/keychain.py +27 -24
- chia/util/keyring_wrapper.py +65 -4
- chia/util/limited_semaphore.py +3 -1
- chia/util/lock.py +4 -2
- chia/util/log_exceptions.py +5 -2
- chia/util/logging.py +3 -1
- chia/util/lru_cache.py +2 -0
- chia/util/math.py +4 -4
- chia/util/network.py +15 -73
- chia/util/paginator.py +3 -1
- chia/util/path.py +2 -0
- chia/util/permissions.py +3 -2
- chia/util/prev_transaction_block.py +1 -3
- chia/util/priority_mutex.py +6 -3
- chia/util/profiler.py +7 -4
- chia/util/recursive_replace.py +2 -0
- chia/util/safe_cancel_task.py +2 -0
- chia/util/service_groups.py +2 -2
- chia/util/setproctitle.py +2 -0
- chia/util/significant_bits.py +2 -0
- chia/util/ssl_check.py +11 -11
- chia/util/streamable.py +44 -56
- chia/util/task_referencer.py +59 -0
- chia/util/task_timing.py +22 -18
- chia/util/timing.py +4 -1
- chia/util/vdf_prover.py +2 -3
- chia/util/virtual_project_analysis.py +540 -0
- chia/util/ws_message.py +6 -6
- chia/wallet/cat_wallet/cat_info.py +3 -3
- chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -3
- chia/wallet/cat_wallet/cat_utils.py +5 -4
- chia/wallet/cat_wallet/cat_wallet.py +56 -70
- chia/wallet/cat_wallet/dao_cat_info.py +3 -3
- chia/wallet/cat_wallet/dao_cat_wallet.py +18 -18
- chia/wallet/cat_wallet/lineage_store.py +2 -2
- chia/wallet/coin_selection.py +15 -15
- chia/wallet/conditions.py +257 -71
- chia/wallet/dao_wallet/dao_info.py +4 -4
- chia/wallet/dao_wallet/dao_utils.py +43 -42
- chia/wallet/dao_wallet/dao_wallet.py +66 -68
- chia/wallet/db_wallet/db_wallet_puzzles.py +12 -8
- chia/wallet/derive_keys.py +11 -11
- chia/wallet/did_wallet/did_info.py +3 -3
- chia/wallet/did_wallet/did_wallet.py +56 -47
- chia/wallet/did_wallet/did_wallet_puzzles.py +7 -6
- chia/wallet/lineage_proof.py +4 -4
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/nft_info.py +4 -4
- chia/wallet/nft_wallet/nft_puzzles.py +16 -16
- chia/wallet/nft_wallet/nft_wallet.py +90 -89
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/transfer_program_puzzle.py +2 -2
- chia/wallet/nft_wallet/uncurry_nft.py +2 -2
- chia/wallet/notification_manager.py +5 -5
- chia/wallet/notification_store.py +6 -6
- chia/wallet/outer_puzzles.py +2 -2
- chia/wallet/payment.py +4 -5
- chia/wallet/puzzle_drivers.py +4 -4
- chia/wallet/puzzles/clawback/drivers.py +5 -5
- chia/wallet/puzzles/clawback/puzzle_decorator.py +7 -7
- chia/wallet/puzzles/load_clvm.py +2 -3
- chia/wallet/puzzles/p2_conditions.py +1 -2
- chia/wallet/puzzles/p2_delegated_conditions.py +1 -2
- chia/wallet/puzzles/p2_delegated_puzzle.py +2 -3
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -4
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +1 -2
- chia/wallet/puzzles/p2_puzzle_hash.py +1 -2
- chia/wallet/puzzles/puzzle_utils.py +7 -7
- chia/wallet/puzzles/singleton_top_layer.py +6 -5
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +6 -5
- chia/wallet/puzzles/tails.py +34 -30
- chia/wallet/signer_protocol.py +7 -8
- chia/wallet/singleton.py +4 -4
- chia/wallet/trade_manager.py +155 -141
- chia/wallet/trade_record.py +5 -5
- chia/wallet/trading/offer.py +100 -101
- chia/wallet/trading/trade_store.py +14 -14
- chia/wallet/transaction_record.py +31 -16
- chia/wallet/util/address_type.py +4 -4
- chia/wallet/util/blind_signer_tl.py +8 -12
- chia/wallet/util/clvm_streamable.py +15 -15
- chia/wallet/util/compute_hints.py +5 -5
- chia/wallet/util/compute_memos.py +4 -6
- chia/wallet/util/curry_and_treehash.py +3 -2
- chia/wallet/util/debug_spend_bundle.py +6 -8
- chia/wallet/util/merkle_tree.py +10 -10
- chia/wallet/util/merkle_utils.py +10 -10
- chia/wallet/util/new_peak_queue.py +3 -3
- chia/wallet/util/peer_request_cache.py +8 -8
- chia/{util → wallet/util}/pprint.py +2 -3
- chia/wallet/util/puzzle_compression.py +3 -4
- chia/wallet/util/puzzle_decorator.py +10 -10
- chia/wallet/util/query_filter.py +9 -10
- chia/wallet/util/tx_config.py +12 -12
- chia/wallet/util/wallet_sync_utils.py +24 -21
- chia/wallet/util/wallet_types.py +9 -2
- chia/wallet/vc_wallet/cr_cat_drivers.py +28 -27
- chia/wallet/vc_wallet/cr_cat_wallet.py +42 -40
- chia/wallet/vc_wallet/cr_outer_puzzle.py +4 -4
- chia/wallet/vc_wallet/vc_drivers.py +16 -16
- chia/wallet/vc_wallet/vc_store.py +9 -9
- chia/wallet/vc_wallet/vc_wallet.py +35 -35
- chia/wallet/wallet.py +54 -54
- chia/wallet/wallet_action_scope.py +14 -13
- chia/wallet/wallet_blockchain.py +10 -10
- chia/wallet/wallet_coin_record.py +2 -2
- chia/wallet/wallet_coin_store.py +10 -10
- chia/wallet/wallet_info.py +1 -2
- chia/wallet/wallet_interested_store.py +5 -5
- chia/wallet/wallet_nft_store.py +6 -6
- chia/wallet/wallet_node.py +72 -76
- chia/wallet/wallet_node_api.py +33 -27
- chia/wallet/wallet_pool_store.py +1 -2
- chia/wallet/wallet_protocol.py +15 -15
- chia/wallet/wallet_puzzle_store.py +35 -4
- chia/wallet/wallet_retry_store.py +2 -2
- chia/wallet/wallet_singleton_store.py +10 -9
- chia/wallet/wallet_spend_bundle.py +4 -20
- chia/wallet/wallet_state_manager.py +223 -224
- chia/wallet/wallet_transaction_store.py +44 -18
- chia/wallet/wallet_user_store.py +2 -2
- chia/wallet/wallet_weight_proof_handler.py +2 -2
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/LICENSE +1 -1
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/METADATA +67 -72
- chia_blockchain-2.5.1rc2.dist-info/RECORD +1042 -0
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/WHEEL +1 -1
- mozilla-ca/cacert.pem +32 -87
- chia/_tests/cmds/wallet/test_coins.py +0 -195
- chia/consensus/block_root_validation.py +0 -46
- chia/util/api_decorators.py +0 -89
- chia_blockchain-2.5.0rc2.dist-info/RECORD +0 -1028
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/entry_points.txt +0 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import logging
|
|
4
5
|
import random
|
|
5
6
|
import time
|
|
7
|
+
from collections.abc import AsyncIterator, Awaitable
|
|
6
8
|
from contextlib import asynccontextmanager
|
|
7
9
|
from dataclasses import replace
|
|
8
|
-
from typing import
|
|
10
|
+
from typing import Optional
|
|
9
11
|
|
|
10
12
|
import pytest
|
|
11
13
|
from chia_rs import AugSchemeMPL, G2Element, MerkleSet
|
|
@@ -20,6 +22,7 @@ from chia._tests.blockchain.blockchain_test_utils import (
|
|
|
20
22
|
)
|
|
21
23
|
from chia._tests.conftest import ConsensusMode
|
|
22
24
|
from chia._tests.util.blockchain import create_blockchain
|
|
25
|
+
from chia._tests.util.get_name_puzzle_conditions import get_name_puzzle_conditions
|
|
23
26
|
from chia.consensus.block_body_validation import ForkInfo
|
|
24
27
|
from chia.consensus.block_header_validation import validate_finished_header_block
|
|
25
28
|
from chia.consensus.block_record import BlockRecord
|
|
@@ -27,11 +30,11 @@ from chia.consensus.block_rewards import calculate_base_farmer_reward
|
|
|
27
30
|
from chia.consensus.blockchain import AddBlockResult, Blockchain
|
|
28
31
|
from chia.consensus.coinbase import create_farmer_coin
|
|
29
32
|
from chia.consensus.constants import ConsensusConstants
|
|
33
|
+
from chia.consensus.find_fork_point import lookup_fork_chain
|
|
30
34
|
from chia.consensus.full_block_to_block_record import block_to_block_record
|
|
31
35
|
from chia.consensus.get_block_generator import get_block_generator
|
|
32
|
-
from chia.consensus.multiprocess_validation import PreValidationResult,
|
|
36
|
+
from chia.consensus.multiprocess_validation import PreValidationResult, pre_validate_block
|
|
33
37
|
from chia.consensus.pot_iterations import is_overflow_block
|
|
34
|
-
from chia.full_node.mempool_check_conditions import get_name_puzzle_conditions
|
|
35
38
|
from chia.simulator.block_tools import BlockTools, create_block_tools_async
|
|
36
39
|
from chia.simulator.keyring import TempKeyring
|
|
37
40
|
from chia.simulator.wallet_tools import WalletTool
|
|
@@ -49,7 +52,8 @@ from chia.types.full_block import FullBlock
|
|
|
49
52
|
from chia.types.generator_types import BlockGenerator
|
|
50
53
|
from chia.types.spend_bundle import SpendBundle
|
|
51
54
|
from chia.types.unfinished_block import UnfinishedBlock
|
|
52
|
-
from chia.
|
|
55
|
+
from chia.types.validation_state import ValidationState
|
|
56
|
+
from chia.util.augmented_chain import AugmentedBlockchain
|
|
53
57
|
from chia.util.errors import Err
|
|
54
58
|
from chia.util.generator_tools import get_block_header
|
|
55
59
|
from chia.util.hash import std_hash
|
|
@@ -72,14 +76,14 @@ async def make_empty_blockchain(constants: ConsensusConstants) -> AsyncIterator[
|
|
|
72
76
|
Provides a list of 10 valid blocks, as well as a blockchain with 9 blocks added to it.
|
|
73
77
|
"""
|
|
74
78
|
|
|
75
|
-
async with create_blockchain(constants, 2) as (bc,
|
|
79
|
+
async with create_blockchain(constants, 2) as (bc, _):
|
|
76
80
|
yield bc
|
|
77
81
|
|
|
78
82
|
|
|
79
83
|
class TestGenesisBlock:
|
|
80
84
|
@pytest.mark.anyio
|
|
81
85
|
async def test_block_tools_proofs_400(
|
|
82
|
-
self, default_400_blocks:
|
|
86
|
+
self, default_400_blocks: list[FullBlock], blockchain_constants: ConsensusConstants
|
|
83
87
|
) -> None:
|
|
84
88
|
vdf, proof = get_vdf_info_and_proof(
|
|
85
89
|
blockchain_constants,
|
|
@@ -92,7 +96,7 @@ class TestGenesisBlock:
|
|
|
92
96
|
|
|
93
97
|
@pytest.mark.anyio
|
|
94
98
|
async def test_block_tools_proofs_1000(
|
|
95
|
-
self, default_1000_blocks:
|
|
99
|
+
self, default_1000_blocks: list[FullBlock], blockchain_constants: ConsensusConstants
|
|
96
100
|
) -> None:
|
|
97
101
|
vdf, proof = get_vdf_info_and_proof(
|
|
98
102
|
blockchain_constants,
|
|
@@ -149,8 +153,9 @@ class TestGenesisBlock:
|
|
|
149
153
|
class TestBlockHeaderValidation:
|
|
150
154
|
@pytest.mark.limit_consensus_modes(reason="save time")
|
|
151
155
|
@pytest.mark.anyio
|
|
152
|
-
async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_blocks:
|
|
156
|
+
async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_blocks: list[FullBlock]) -> None:
|
|
153
157
|
blocks = default_1000_blocks
|
|
158
|
+
fork_info = ForkInfo(blocks[0].height - 1, blocks[0].height - 1, blocks[0].prev_header_hash)
|
|
154
159
|
for block in blocks:
|
|
155
160
|
if (
|
|
156
161
|
len(block.finished_sub_slots) > 0
|
|
@@ -165,23 +170,21 @@ class TestBlockHeaderValidation:
|
|
|
165
170
|
block_bad = recursive_replace(
|
|
166
171
|
block, "finished_sub_slots", [new_finished_ss] + block.finished_sub_slots[1:]
|
|
167
172
|
)
|
|
168
|
-
header_block_bad = get_block_header(block_bad
|
|
173
|
+
header_block_bad = get_block_header(block_bad)
|
|
169
174
|
# TODO: Inspect these block values as they are currently None
|
|
170
175
|
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
|
|
171
176
|
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
|
|
177
|
+
expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
|
|
172
178
|
_, error = validate_finished_header_block(
|
|
173
|
-
empty_blockchain.constants,
|
|
174
|
-
empty_blockchain,
|
|
175
|
-
header_block_bad,
|
|
176
|
-
False,
|
|
177
|
-
expected_difficulty,
|
|
178
|
-
expected_sub_slot_iters,
|
|
179
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs
|
|
179
180
|
)
|
|
180
181
|
assert error is not None
|
|
181
182
|
assert error.code == Err.INVALID_NEW_SUB_SLOT_ITERS
|
|
182
183
|
|
|
183
184
|
# Also fails calling the outer methods, but potentially with a different error
|
|
184
|
-
await _validate_and_add_block(
|
|
185
|
+
await _validate_and_add_block(
|
|
186
|
+
empty_blockchain, block_bad, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info
|
|
187
|
+
)
|
|
185
188
|
|
|
186
189
|
new_finished_ss_2 = recursive_replace(
|
|
187
190
|
block.finished_sub_slots[0],
|
|
@@ -192,24 +195,20 @@ class TestBlockHeaderValidation:
|
|
|
192
195
|
block, "finished_sub_slots", [new_finished_ss_2] + block.finished_sub_slots[1:]
|
|
193
196
|
)
|
|
194
197
|
|
|
195
|
-
header_block_bad_2 = get_block_header(block_bad_2
|
|
198
|
+
header_block_bad_2 = get_block_header(block_bad_2)
|
|
196
199
|
# TODO: Inspect these block values as they are currently None
|
|
197
200
|
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
|
|
198
201
|
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
|
|
202
|
+
expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
|
|
199
203
|
_, error = validate_finished_header_block(
|
|
200
|
-
empty_blockchain.constants,
|
|
201
|
-
empty_blockchain,
|
|
202
|
-
header_block_bad_2,
|
|
203
|
-
False,
|
|
204
|
-
expected_difficulty,
|
|
205
|
-
expected_sub_slot_iters,
|
|
204
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad_2, False, expected_vs
|
|
206
205
|
)
|
|
207
206
|
assert error is not None
|
|
208
207
|
assert error.code == Err.INVALID_NEW_DIFFICULTY
|
|
209
208
|
|
|
210
209
|
# Also fails calling the outer methods, but potentially with a different error
|
|
211
210
|
await _validate_and_add_block(
|
|
212
|
-
empty_blockchain, block_bad_2, expected_result=AddBlockResult.INVALID_BLOCK
|
|
211
|
+
empty_blockchain, block_bad_2, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info
|
|
213
212
|
)
|
|
214
213
|
|
|
215
214
|
# 3c
|
|
@@ -226,24 +225,20 @@ class TestBlockHeaderValidation:
|
|
|
226
225
|
log.warning(f"Number of slots: {len(block.finished_sub_slots)}")
|
|
227
226
|
block_bad_3 = recursive_replace(block, "finished_sub_slots", [new_finished_ss_3])
|
|
228
227
|
|
|
229
|
-
header_block_bad_3 = get_block_header(block_bad_3
|
|
228
|
+
header_block_bad_3 = get_block_header(block_bad_3)
|
|
230
229
|
# TODO: Inspect these block values as they are currently None
|
|
231
230
|
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
|
|
232
231
|
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
|
|
232
|
+
expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
|
|
233
233
|
_, error = validate_finished_header_block(
|
|
234
|
-
empty_blockchain.constants,
|
|
235
|
-
empty_blockchain,
|
|
236
|
-
header_block_bad_3,
|
|
237
|
-
False,
|
|
238
|
-
expected_difficulty,
|
|
239
|
-
expected_sub_slot_iters,
|
|
234
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad_3, False, expected_vs
|
|
240
235
|
)
|
|
241
236
|
assert error is not None
|
|
242
237
|
assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY
|
|
243
238
|
|
|
244
239
|
# Also fails calling the outer methods, but potentially with a different error
|
|
245
240
|
await _validate_and_add_block(
|
|
246
|
-
empty_blockchain, block_bad_3, expected_result=AddBlockResult.INVALID_BLOCK
|
|
241
|
+
empty_blockchain, block_bad_3, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info
|
|
247
242
|
)
|
|
248
243
|
|
|
249
244
|
# 3d
|
|
@@ -259,26 +254,22 @@ class TestBlockHeaderValidation:
|
|
|
259
254
|
)
|
|
260
255
|
block_bad_4 = recursive_replace(block, "finished_sub_slots", [new_finished_ss_4])
|
|
261
256
|
|
|
262
|
-
header_block_bad_4 = get_block_header(block_bad_4
|
|
257
|
+
header_block_bad_4 = get_block_header(block_bad_4)
|
|
263
258
|
# TODO: Inspect these block values as they are currently None
|
|
264
259
|
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
|
|
265
260
|
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
|
|
261
|
+
expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
|
|
266
262
|
_, error = validate_finished_header_block(
|
|
267
|
-
empty_blockchain.constants,
|
|
268
|
-
empty_blockchain,
|
|
269
|
-
header_block_bad_4,
|
|
270
|
-
False,
|
|
271
|
-
expected_difficulty,
|
|
272
|
-
expected_sub_slot_iters,
|
|
263
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad_4, False, expected_vs
|
|
273
264
|
)
|
|
274
265
|
assert error is not None
|
|
275
266
|
assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY
|
|
276
267
|
|
|
277
268
|
# Also fails calling the outer methods, but potentially with a different error
|
|
278
269
|
await _validate_and_add_block(
|
|
279
|
-
empty_blockchain, block_bad_4, expected_result=AddBlockResult.INVALID_BLOCK
|
|
270
|
+
empty_blockchain, block_bad_4, expected_result=AddBlockResult.INVALID_BLOCK, fork_info=fork_info
|
|
280
271
|
)
|
|
281
|
-
await _validate_and_add_block(empty_blockchain, block)
|
|
272
|
+
await _validate_and_add_block(empty_blockchain, block, fork_info=fork_info)
|
|
282
273
|
log.info(
|
|
283
274
|
f"Added block {block.height} total iters {block.total_iters} "
|
|
284
275
|
f"new slot? {len(block.finished_sub_slots)}"
|
|
@@ -370,7 +361,7 @@ class TestBlockHeaderValidation:
|
|
|
370
361
|
async def test_one_sb_per_slot(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
371
362
|
blockchain = empty_blockchain
|
|
372
363
|
num_blocks = 20
|
|
373
|
-
blocks:
|
|
364
|
+
blocks: list[FullBlock] = []
|
|
374
365
|
for _ in range(num_blocks):
|
|
375
366
|
blocks = bt.get_consecutive_blocks(1, block_list_input=blocks, skip_slots=1)
|
|
376
367
|
await _validate_and_add_block(empty_blockchain, blocks[-1])
|
|
@@ -382,7 +373,7 @@ class TestBlockHeaderValidation:
|
|
|
382
373
|
async def test_all_overflow(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
383
374
|
blockchain = empty_blockchain
|
|
384
375
|
num_rounds = 5
|
|
385
|
-
blocks:
|
|
376
|
+
blocks: list[FullBlock] = []
|
|
386
377
|
num_blocks = 0
|
|
387
378
|
for i in range(1, num_rounds):
|
|
388
379
|
num_blocks += i
|
|
@@ -399,7 +390,7 @@ class TestBlockHeaderValidation:
|
|
|
399
390
|
) -> None:
|
|
400
391
|
blockchain = empty_blockchain
|
|
401
392
|
|
|
402
|
-
blocks:
|
|
393
|
+
blocks: list[FullBlock] = []
|
|
403
394
|
while True:
|
|
404
395
|
# This creates an overflow block, then a normal block, and then an overflow in the next sub-slot
|
|
405
396
|
# blocks = bt.get_consecutive_blocks(1, block_list_input=blocks, force_overflow=True)
|
|
@@ -447,7 +438,7 @@ class TestBlockHeaderValidation:
|
|
|
447
438
|
async def test_one_sb_per_two_slots(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
448
439
|
blockchain = empty_blockchain
|
|
449
440
|
num_blocks = 20
|
|
450
|
-
blocks:
|
|
441
|
+
blocks: list[FullBlock] = []
|
|
451
442
|
for _ in range(num_blocks): # Same thing, but 2 sub-slots per block
|
|
452
443
|
blocks = bt.get_consecutive_blocks(1, block_list_input=blocks, skip_slots=2)
|
|
453
444
|
await _validate_and_add_block(blockchain, blocks[-1])
|
|
@@ -459,7 +450,7 @@ class TestBlockHeaderValidation:
|
|
|
459
450
|
async def test_one_sb_per_five_slots(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
460
451
|
blockchain = empty_blockchain
|
|
461
452
|
num_blocks = 10
|
|
462
|
-
blocks:
|
|
453
|
+
blocks: list[FullBlock] = []
|
|
463
454
|
for _ in range(num_blocks): # Same thing, but 5 sub-slots per block
|
|
464
455
|
blocks = bt.get_consecutive_blocks(1, block_list_input=blocks, skip_slots=5)
|
|
465
456
|
await _validate_and_add_block(blockchain, blocks[-1])
|
|
@@ -480,7 +471,7 @@ class TestBlockHeaderValidation:
|
|
|
480
471
|
async def test_one_sb_per_two_slots_force_overflow(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
481
472
|
blockchain = empty_blockchain
|
|
482
473
|
num_blocks = 10
|
|
483
|
-
blocks:
|
|
474
|
+
blocks: list[FullBlock] = []
|
|
484
475
|
for _ in range(num_blocks):
|
|
485
476
|
blocks = bt.get_consecutive_blocks(1, block_list_input=blocks, skip_slots=2, force_overflow=True)
|
|
486
477
|
await _validate_and_add_block(blockchain, blocks[-1])
|
|
@@ -519,14 +510,12 @@ class TestBlockHeaderValidation:
|
|
|
519
510
|
blocks[0], "finished_sub_slots", [new_finished_ss] + blocks[0].finished_sub_slots[1:]
|
|
520
511
|
)
|
|
521
512
|
|
|
522
|
-
header_block_bad = get_block_header(block_0_bad
|
|
513
|
+
header_block_bad = get_block_header(block_0_bad)
|
|
514
|
+
expected_vs = ValidationState(
|
|
515
|
+
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING, empty_blockchain.constants.DIFFICULTY_STARTING, None
|
|
516
|
+
)
|
|
523
517
|
_, error = validate_finished_header_block(
|
|
524
|
-
empty_blockchain.constants,
|
|
525
|
-
empty_blockchain,
|
|
526
|
-
header_block_bad,
|
|
527
|
-
False,
|
|
528
|
-
empty_blockchain.constants.DIFFICULTY_STARTING,
|
|
529
|
-
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING,
|
|
518
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs
|
|
530
519
|
)
|
|
531
520
|
|
|
532
521
|
assert error is not None
|
|
@@ -550,17 +539,13 @@ class TestBlockHeaderValidation:
|
|
|
550
539
|
)
|
|
551
540
|
|
|
552
541
|
await _validate_and_add_block(empty_blockchain, blocks[0])
|
|
553
|
-
header_block_bad = get_block_header(block_1_bad
|
|
542
|
+
header_block_bad = get_block_header(block_1_bad)
|
|
554
543
|
# TODO: Inspect these block values as they are currently None
|
|
555
544
|
expected_difficulty = blocks[1].finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
|
|
556
545
|
expected_sub_slot_iters = blocks[1].finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
|
|
546
|
+
expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
|
|
557
547
|
_, error = validate_finished_header_block(
|
|
558
|
-
empty_blockchain.constants,
|
|
559
|
-
empty_blockchain,
|
|
560
|
-
header_block_bad,
|
|
561
|
-
False,
|
|
562
|
-
expected_difficulty,
|
|
563
|
-
expected_sub_slot_iters,
|
|
548
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs
|
|
564
549
|
)
|
|
565
550
|
assert error is not None
|
|
566
551
|
assert error.code == Err.INVALID_PREV_CHALLENGE_SLOT_HASH
|
|
@@ -581,17 +566,13 @@ class TestBlockHeaderValidation:
|
|
|
581
566
|
)
|
|
582
567
|
await _validate_and_add_block(empty_blockchain, blocks[0])
|
|
583
568
|
|
|
584
|
-
header_block_bad = get_block_header(block_1_bad
|
|
569
|
+
header_block_bad = get_block_header(block_1_bad)
|
|
585
570
|
# TODO: Inspect these block values as they are currently None
|
|
586
571
|
expected_difficulty = blocks[1].finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
|
|
587
572
|
expected_sub_slot_iters = blocks[1].finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
|
|
573
|
+
expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
|
|
588
574
|
_, error = validate_finished_header_block(
|
|
589
|
-
empty_blockchain.constants,
|
|
590
|
-
empty_blockchain,
|
|
591
|
-
header_block_bad,
|
|
592
|
-
False,
|
|
593
|
-
expected_difficulty,
|
|
594
|
-
expected_sub_slot_iters,
|
|
575
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs
|
|
595
576
|
)
|
|
596
577
|
assert error is not None
|
|
597
578
|
assert error.code == Err.INVALID_PREV_CHALLENGE_SLOT_HASH
|
|
@@ -606,7 +587,7 @@ class TestBlockHeaderValidation:
|
|
|
606
587
|
"infused_challenge_chain",
|
|
607
588
|
InfusedChallengeChainSubSlot(
|
|
608
589
|
VDFInfo(
|
|
609
|
-
bytes32
|
|
590
|
+
bytes32.zeros,
|
|
610
591
|
uint64(1200),
|
|
611
592
|
ClassgroupElement.get_default_element(),
|
|
612
593
|
)
|
|
@@ -627,7 +608,7 @@ class TestBlockHeaderValidation:
|
|
|
627
608
|
),
|
|
628
609
|
keychain=keychain,
|
|
629
610
|
)
|
|
630
|
-
async with create_blockchain(bt_high_iters.constants, db_version) as (bc1,
|
|
611
|
+
async with create_blockchain(bt_high_iters.constants, db_version) as (bc1, _):
|
|
631
612
|
blocks = bt_high_iters.get_consecutive_blocks(10)
|
|
632
613
|
for block in blocks:
|
|
633
614
|
if (
|
|
@@ -677,7 +658,7 @@ class TestBlockHeaderValidation:
|
|
|
677
658
|
block.finished_sub_slots[
|
|
678
659
|
-1
|
|
679
660
|
].infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf.replace(
|
|
680
|
-
challenge=bytes32
|
|
661
|
+
challenge=bytes32.zeros
|
|
681
662
|
)
|
|
682
663
|
),
|
|
683
664
|
)
|
|
@@ -740,17 +721,13 @@ class TestBlockHeaderValidation:
|
|
|
740
721
|
block, "finished_sub_slots", block.finished_sub_slots[:-1] + [new_finished_ss]
|
|
741
722
|
)
|
|
742
723
|
|
|
743
|
-
header_block_bad = get_block_header(block_bad
|
|
724
|
+
header_block_bad = get_block_header(block_bad)
|
|
744
725
|
# TODO: Inspect these block values as they are currently None
|
|
745
726
|
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
|
|
746
727
|
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
|
|
728
|
+
expected_vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
|
|
747
729
|
_, error = validate_finished_header_block(
|
|
748
|
-
empty_blockchain.constants,
|
|
749
|
-
empty_blockchain,
|
|
750
|
-
header_block_bad,
|
|
751
|
-
False,
|
|
752
|
-
expected_difficulty,
|
|
753
|
-
expected_sub_slot_iters,
|
|
730
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs
|
|
754
731
|
)
|
|
755
732
|
assert error is not None
|
|
756
733
|
assert error.code == Err.INVALID_ICC_HASH_CC
|
|
@@ -815,14 +792,12 @@ class TestBlockHeaderValidation:
|
|
|
815
792
|
blocks[-1], "finished_sub_slots", blocks[-1].finished_sub_slots[:-1] + [new_finished_ss]
|
|
816
793
|
)
|
|
817
794
|
|
|
818
|
-
header_block_bad = get_block_header(block_bad
|
|
795
|
+
header_block_bad = get_block_header(block_bad)
|
|
796
|
+
expected_vs = ValidationState(
|
|
797
|
+
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING, empty_blockchain.constants.DIFFICULTY_STARTING, None
|
|
798
|
+
)
|
|
819
799
|
_, error = validate_finished_header_block(
|
|
820
|
-
empty_blockchain.constants,
|
|
821
|
-
empty_blockchain,
|
|
822
|
-
header_block_bad,
|
|
823
|
-
False,
|
|
824
|
-
empty_blockchain.constants.DIFFICULTY_STARTING,
|
|
825
|
-
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING,
|
|
800
|
+
empty_blockchain.constants, empty_blockchain, header_block_bad, False, expected_vs
|
|
826
801
|
)
|
|
827
802
|
assert error is not None
|
|
828
803
|
assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY_HASH
|
|
@@ -830,7 +805,7 @@ class TestBlockHeaderValidation:
|
|
|
830
805
|
|
|
831
806
|
@pytest.mark.anyio
|
|
832
807
|
async def test_empty_sub_slots_epoch(
|
|
833
|
-
self, empty_blockchain: Blockchain, default_400_blocks:
|
|
808
|
+
self, empty_blockchain: Blockchain, default_400_blocks: list[FullBlock], bt: BlockTools
|
|
834
809
|
) -> None:
|
|
835
810
|
# 2m
|
|
836
811
|
# Tests adding an empty sub slot after the sub-epoch / epoch.
|
|
@@ -871,7 +846,7 @@ class TestBlockHeaderValidation:
|
|
|
871
846
|
@pytest.mark.anyio
|
|
872
847
|
async def test_invalid_cc_sub_slot_vdf(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
873
848
|
# 2q
|
|
874
|
-
blocks:
|
|
849
|
+
blocks: list[FullBlock] = []
|
|
875
850
|
found_overflow_slot: bool = False
|
|
876
851
|
|
|
877
852
|
while not found_overflow_slot:
|
|
@@ -969,7 +944,7 @@ class TestBlockHeaderValidation:
|
|
|
969
944
|
@pytest.mark.anyio
|
|
970
945
|
async def test_invalid_rc_sub_slot_vdf(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
971
946
|
# 2p
|
|
972
|
-
blocks:
|
|
947
|
+
blocks: list[FullBlock] = []
|
|
973
948
|
found_block: bool = False
|
|
974
949
|
|
|
975
950
|
while not found_block:
|
|
@@ -1099,7 +1074,7 @@ class TestBlockHeaderValidation:
|
|
|
1099
1074
|
recursive_replace(
|
|
1100
1075
|
block.finished_sub_slots[0].challenge_chain,
|
|
1101
1076
|
"subepoch_summary_hash",
|
|
1102
|
-
bytes32
|
|
1077
|
+
bytes32.zeros,
|
|
1103
1078
|
),
|
|
1104
1079
|
)
|
|
1105
1080
|
|
|
@@ -1134,7 +1109,7 @@ class TestBlockHeaderValidation:
|
|
|
1134
1109
|
recursive_replace(
|
|
1135
1110
|
blocks[-1].finished_sub_slots[0].challenge_chain,
|
|
1136
1111
|
"subepoch_summary_hash",
|
|
1137
|
-
bytes32
|
|
1112
|
+
bytes32.zeros,
|
|
1138
1113
|
),
|
|
1139
1114
|
)
|
|
1140
1115
|
|
|
@@ -1222,7 +1197,7 @@ class TestBlockHeaderValidation:
|
|
|
1222
1197
|
@pytest.mark.anyio
|
|
1223
1198
|
async def test_sp_0_no_sp(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
1224
1199
|
# 7
|
|
1225
|
-
blocks:
|
|
1200
|
+
blocks: list[FullBlock] = []
|
|
1226
1201
|
case_1, case_2 = False, False
|
|
1227
1202
|
while not case_1 or not case_2:
|
|
1228
1203
|
blocks = bt.get_consecutive_blocks(1, block_list_input=blocks)
|
|
@@ -1819,67 +1794,63 @@ class TestPreValidation:
|
|
|
1819
1794
|
block_bad = recursive_replace(
|
|
1820
1795
|
blocks[-1], "reward_chain_block.total_iters", blocks[-1].reward_chain_block.total_iters + 1
|
|
1821
1796
|
)
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1797
|
+
futures = []
|
|
1798
|
+
vs = ValidationState(ssi, difficulty, None)
|
|
1799
|
+
chain = AugmentedBlockchain(empty_blockchain)
|
|
1800
|
+
for block in [blocks[0], block_bad]:
|
|
1801
|
+
futures.append(
|
|
1802
|
+
await pre_validate_block(
|
|
1803
|
+
empty_blockchain.constants,
|
|
1804
|
+
chain,
|
|
1805
|
+
block,
|
|
1806
|
+
empty_blockchain.pool,
|
|
1807
|
+
None,
|
|
1808
|
+
vs,
|
|
1809
|
+
)
|
|
1810
|
+
)
|
|
1811
|
+
res: list[PreValidationResult] = list(await asyncio.gather(*futures))
|
|
1833
1812
|
assert res[0].error is None
|
|
1834
1813
|
assert res[1].error is not None
|
|
1835
1814
|
|
|
1836
1815
|
@pytest.mark.anyio
|
|
1837
1816
|
async def test_pre_validation(
|
|
1838
|
-
self, empty_blockchain: Blockchain, default_1000_blocks:
|
|
1817
|
+
self, empty_blockchain: Blockchain, default_1000_blocks: list[FullBlock], bt: BlockTools
|
|
1839
1818
|
) -> None:
|
|
1840
1819
|
blocks = default_1000_blocks[:100]
|
|
1841
1820
|
start = time.time()
|
|
1842
|
-
n_at_a_time = min(available_logical_cores(), 32)
|
|
1843
|
-
times_pv = []
|
|
1844
|
-
times_rb = []
|
|
1845
1821
|
ssi = empty_blockchain.constants.SUB_SLOT_ITERS_STARTING
|
|
1846
1822
|
difficulty = empty_blockchain.constants.DIFFICULTY_STARTING
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
validate_signatures=True,
|
|
1861
|
-
)
|
|
1862
|
-
end_pv = time.time()
|
|
1863
|
-
times_pv.append(end_pv - start_pv)
|
|
1864
|
-
assert res is not None
|
|
1865
|
-
for n in range(end_i - i):
|
|
1866
|
-
assert res[n] is not None
|
|
1867
|
-
assert res[n].error is None
|
|
1868
|
-
block = blocks_to_validate[n]
|
|
1869
|
-
start_rb = time.time()
|
|
1870
|
-
result, err, _ = await empty_blockchain.add_block(block, res[n], None, ssi)
|
|
1871
|
-
end_rb = time.time()
|
|
1872
|
-
times_rb.append(end_rb - start_rb)
|
|
1873
|
-
assert err is None
|
|
1874
|
-
assert result == AddBlockResult.NEW_PEAK
|
|
1875
|
-
log.info(
|
|
1876
|
-
f"Added block {block.height} total iters {block.total_iters} "
|
|
1877
|
-
f"new slot? {len(block.finished_sub_slots)}, time {end_rb - start_rb}"
|
|
1823
|
+
blockchain = AugmentedBlockchain(empty_blockchain)
|
|
1824
|
+
vs = ValidationState(ssi, difficulty, None)
|
|
1825
|
+
futures: list[Awaitable[PreValidationResult]] = []
|
|
1826
|
+
start = time.monotonic()
|
|
1827
|
+
for block in blocks:
|
|
1828
|
+
futures.append(
|
|
1829
|
+
await pre_validate_block(
|
|
1830
|
+
bt.constants,
|
|
1831
|
+
blockchain,
|
|
1832
|
+
block,
|
|
1833
|
+
empty_blockchain.pool,
|
|
1834
|
+
None,
|
|
1835
|
+
vs,
|
|
1878
1836
|
)
|
|
1879
|
-
|
|
1837
|
+
)
|
|
1838
|
+
|
|
1839
|
+
results = await asyncio.gather(*futures)
|
|
1840
|
+
end = time.monotonic()
|
|
1841
|
+
validation_time = start - end
|
|
1842
|
+
db_start = end
|
|
1843
|
+
|
|
1844
|
+
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
|
1845
|
+
for block, res in zip(blocks, results):
|
|
1846
|
+
assert res.error is None
|
|
1847
|
+
result, err, _ = await empty_blockchain.add_block(block, res, ssi, fork_info=fork_info)
|
|
1848
|
+
assert err is None
|
|
1849
|
+
assert result == AddBlockResult.NEW_PEAK
|
|
1850
|
+
end = time.monotonic()
|
|
1880
1851
|
log.info(f"Total time: {end - start} seconds")
|
|
1881
|
-
log.info(f"Average
|
|
1882
|
-
log.info(f"Average
|
|
1852
|
+
log.info(f"Average validation: {validation_time / len(blocks)}")
|
|
1853
|
+
log.info(f"Average database: {(end - db_start) / (len(blocks))}")
|
|
1883
1854
|
|
|
1884
1855
|
|
|
1885
1856
|
class TestBodyValidation:
|
|
@@ -1939,7 +1910,7 @@ class TestBodyValidation:
|
|
|
1939
1910
|
else:
|
|
1940
1911
|
assert False
|
|
1941
1912
|
|
|
1942
|
-
conditions:
|
|
1913
|
+
conditions: dict[ConditionOpcode, list[ConditionWithArgs]] = {
|
|
1943
1914
|
opcode: [ConditionWithArgs(opcode, args + ([b"garbage"] if with_garbage else []))]
|
|
1944
1915
|
}
|
|
1945
1916
|
|
|
@@ -1956,20 +1927,20 @@ class TestBodyValidation:
|
|
|
1956
1927
|
)
|
|
1957
1928
|
ssi = b.constants.SUB_SLOT_ITERS_STARTING
|
|
1958
1929
|
diff = b.constants.DIFFICULTY_STARTING
|
|
1959
|
-
|
|
1930
|
+
block = blocks[-1]
|
|
1931
|
+
future = await pre_validate_block(
|
|
1960
1932
|
b.constants,
|
|
1961
|
-
b,
|
|
1962
|
-
|
|
1933
|
+
AugmentedBlockchain(b),
|
|
1934
|
+
block,
|
|
1963
1935
|
b.pool,
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
difficulty=diff,
|
|
1967
|
-
prev_ses_block=None,
|
|
1968
|
-
validate_signatures=False,
|
|
1936
|
+
None,
|
|
1937
|
+
ValidationState(ssi, diff, None),
|
|
1969
1938
|
)
|
|
1939
|
+
pre_validation_result: PreValidationResult = await future
|
|
1970
1940
|
# Ignore errors from pre-validation, we are testing block_body_validation
|
|
1971
|
-
repl_preval_results = replace(
|
|
1972
|
-
|
|
1941
|
+
repl_preval_results = replace(pre_validation_result, error=None, required_iters=uint64(1))
|
|
1942
|
+
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
|
|
1943
|
+
code, err, state_change = await b.add_block(block, repl_preval_results, sub_slot_iters=ssi, fork_info=fork_info)
|
|
1973
1944
|
assert code == AddBlockResult.NEW_PEAK
|
|
1974
1945
|
assert err is None
|
|
1975
1946
|
assert state_change is not None
|
|
@@ -2080,19 +2051,20 @@ class TestBodyValidation:
|
|
|
2080
2051
|
)
|
|
2081
2052
|
ssi = b.constants.SUB_SLOT_ITERS_STARTING
|
|
2082
2053
|
diff = b.constants.DIFFICULTY_STARTING
|
|
2083
|
-
|
|
2054
|
+
block = blocks[-1]
|
|
2055
|
+
future = await pre_validate_block(
|
|
2084
2056
|
b.constants,
|
|
2085
|
-
b,
|
|
2086
|
-
|
|
2057
|
+
AugmentedBlockchain(b),
|
|
2058
|
+
block,
|
|
2087
2059
|
b.pool,
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
difficulty=diff,
|
|
2091
|
-
prev_ses_block=None,
|
|
2092
|
-
validate_signatures=True,
|
|
2060
|
+
None,
|
|
2061
|
+
ValidationState(ssi, diff, None),
|
|
2093
2062
|
)
|
|
2094
|
-
|
|
2095
|
-
|
|
2063
|
+
pre_validation_result: PreValidationResult = await future
|
|
2064
|
+
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
|
|
2065
|
+
assert (await b.add_block(block, pre_validation_result, sub_slot_iters=ssi, fork_info=fork_info))[
|
|
2066
|
+
0
|
|
2067
|
+
] == expected
|
|
2096
2068
|
|
|
2097
2069
|
if expected == AddBlockResult.NEW_PEAK:
|
|
2098
2070
|
# ensure coin was in fact spent
|
|
@@ -2161,20 +2133,22 @@ class TestBodyValidation:
|
|
|
2161
2133
|
)
|
|
2162
2134
|
ssi = b.constants.SUB_SLOT_ITERS_STARTING
|
|
2163
2135
|
diff = b.constants.DIFFICULTY_STARTING
|
|
2164
|
-
|
|
2136
|
+
block = blocks[-1]
|
|
2137
|
+
future = await pre_validate_block(
|
|
2165
2138
|
b.constants,
|
|
2166
|
-
b,
|
|
2167
|
-
|
|
2139
|
+
AugmentedBlockchain(b),
|
|
2140
|
+
block,
|
|
2168
2141
|
b.pool,
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
difficulty=diff,
|
|
2172
|
-
prev_ses_block=None,
|
|
2173
|
-
validate_signatures=False,
|
|
2142
|
+
None,
|
|
2143
|
+
ValidationState(ssi, diff, None),
|
|
2174
2144
|
)
|
|
2145
|
+
pre_validation_result: PreValidationResult = await future
|
|
2175
2146
|
# Ignore errors from pre-validation, we are testing block_body_validation
|
|
2176
|
-
repl_preval_results = replace(
|
|
2177
|
-
|
|
2147
|
+
repl_preval_results = replace(pre_validation_result, error=None, required_iters=uint64(1))
|
|
2148
|
+
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
|
|
2149
|
+
res, error, state_change = await b.add_block(
|
|
2150
|
+
block, repl_preval_results, sub_slot_iters=ssi, fork_info=fork_info
|
|
2151
|
+
)
|
|
2178
2152
|
assert res == AddBlockResult.NEW_PEAK
|
|
2179
2153
|
assert error is None
|
|
2180
2154
|
assert state_change is not None and state_change.fork_height == uint32(2)
|
|
@@ -2287,19 +2261,20 @@ class TestBodyValidation:
|
|
|
2287
2261
|
)
|
|
2288
2262
|
ssi = b.constants.SUB_SLOT_ITERS_STARTING
|
|
2289
2263
|
diff = b.constants.DIFFICULTY_STARTING
|
|
2290
|
-
|
|
2264
|
+
block = blocks[-1]
|
|
2265
|
+
future = await pre_validate_block(
|
|
2291
2266
|
b.constants,
|
|
2292
|
-
b,
|
|
2293
|
-
|
|
2267
|
+
AugmentedBlockchain(b),
|
|
2268
|
+
block,
|
|
2294
2269
|
b.pool,
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
difficulty=diff,
|
|
2298
|
-
prev_ses_block=None,
|
|
2299
|
-
validate_signatures=True,
|
|
2270
|
+
None,
|
|
2271
|
+
ValidationState(ssi, diff, None),
|
|
2300
2272
|
)
|
|
2301
|
-
|
|
2302
|
-
|
|
2273
|
+
pre_validation_result: PreValidationResult = await future
|
|
2274
|
+
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
|
|
2275
|
+
assert (await b.add_block(block, pre_validation_result, sub_slot_iters=ssi, fork_info=fork_info))[
|
|
2276
|
+
0
|
|
2277
|
+
] == expected
|
|
2303
2278
|
|
|
2304
2279
|
if expected == AddBlockResult.NEW_PEAK:
|
|
2305
2280
|
# ensure coin1 was in fact spent
|
|
@@ -2432,8 +2407,9 @@ class TestBodyValidation:
|
|
|
2432
2407
|
|
|
2433
2408
|
# Too many
|
|
2434
2409
|
h = std_hash(b"")
|
|
2435
|
-
too_many_reward_claims =
|
|
2436
|
-
|
|
2410
|
+
too_many_reward_claims = [
|
|
2411
|
+
*block.transactions_info.reward_claims_incorporated,
|
|
2412
|
+
Coin(h, h, too_few_reward_claims[0].amount),
|
|
2437
2413
|
]
|
|
2438
2414
|
block_2 = recursive_replace(block, "transactions_info.reward_claims_incorporated", too_many_reward_claims)
|
|
2439
2415
|
assert block_2.transactions_info is not None
|
|
@@ -2452,8 +2428,9 @@ class TestBodyValidation:
|
|
|
2452
2428
|
await _validate_and_add_block(b, block_2, expected_error=Err.INVALID_REWARD_COINS, skip_prevalidation=True)
|
|
2453
2429
|
|
|
2454
2430
|
# Duplicates
|
|
2455
|
-
duplicate_reward_claims =
|
|
2456
|
-
block.transactions_info.reward_claims_incorporated
|
|
2431
|
+
duplicate_reward_claims = [
|
|
2432
|
+
*block.transactions_info.reward_claims_incorporated,
|
|
2433
|
+
block.transactions_info.reward_claims_incorporated[-1],
|
|
2457
2434
|
]
|
|
2458
2435
|
block_2 = recursive_replace(block, "transactions_info.reward_claims_incorporated", duplicate_reward_claims)
|
|
2459
2436
|
assert block_2.transactions_info is not None
|
|
@@ -2615,7 +2592,7 @@ class TestBodyValidation:
|
|
|
2615
2592
|
|
|
2616
2593
|
wt: WalletTool = bt.get_pool_wallet_tool()
|
|
2617
2594
|
|
|
2618
|
-
condition_dict:
|
|
2595
|
+
condition_dict: dict[ConditionOpcode, list[ConditionWithArgs]] = {ConditionOpcode.CREATE_COIN: []}
|
|
2619
2596
|
for i in range(7_000):
|
|
2620
2597
|
output = ConditionWithArgs(ConditionOpcode.CREATE_COIN, [bt.pool_ph, int_to_bytes(i)])
|
|
2621
2598
|
condition_dict[ConditionOpcode.CREATE_COIN].append(output)
|
|
@@ -2629,6 +2606,7 @@ class TestBodyValidation:
|
|
|
2629
2606
|
)
|
|
2630
2607
|
|
|
2631
2608
|
assert blocks[-1].transactions_generator is not None
|
|
2609
|
+
assert blocks[-1].transactions_info is not None
|
|
2632
2610
|
block_generator = BlockGenerator(blocks[-1].transactions_generator, [])
|
|
2633
2611
|
npc_result = get_name_puzzle_conditions(
|
|
2634
2612
|
block_generator,
|
|
@@ -2637,30 +2615,30 @@ class TestBodyValidation:
|
|
|
2637
2615
|
height=softfork_height,
|
|
2638
2616
|
constants=bt.constants,
|
|
2639
2617
|
)
|
|
2618
|
+
assert npc_result.conds is not None
|
|
2640
2619
|
ssi = b.constants.SUB_SLOT_ITERS_STARTING
|
|
2641
2620
|
diff = b.constants.DIFFICULTY_STARTING
|
|
2621
|
+
block = blocks[-1]
|
|
2622
|
+
fork_info = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
|
|
2642
2623
|
err = (
|
|
2643
2624
|
await b.add_block(
|
|
2644
2625
|
blocks[-1],
|
|
2645
|
-
PreValidationResult(None, uint64(1), npc_result.conds
|
|
2646
|
-
None,
|
|
2626
|
+
PreValidationResult(None, uint64(1), npc_result.conds.replace(validated_signature=True), uint32(0)),
|
|
2647
2627
|
sub_slot_iters=ssi,
|
|
2628
|
+
fork_info=fork_info,
|
|
2648
2629
|
)
|
|
2649
2630
|
)[1]
|
|
2650
|
-
assert err
|
|
2651
|
-
|
|
2631
|
+
assert err == Err.BLOCK_COST_EXCEEDS_MAX
|
|
2632
|
+
future = await pre_validate_block(
|
|
2652
2633
|
b.constants,
|
|
2653
|
-
b,
|
|
2654
|
-
|
|
2634
|
+
AugmentedBlockchain(b),
|
|
2635
|
+
blocks[-1],
|
|
2655
2636
|
b.pool,
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
difficulty=diff,
|
|
2659
|
-
prev_ses_block=None,
|
|
2660
|
-
validate_signatures=False,
|
|
2637
|
+
None,
|
|
2638
|
+
ValidationState(ssi, diff, None),
|
|
2661
2639
|
)
|
|
2662
|
-
|
|
2663
|
-
assert Err(
|
|
2640
|
+
result: PreValidationResult = await future
|
|
2641
|
+
assert Err(result.error) == Err.BLOCK_COST_EXCEEDS_MAX
|
|
2664
2642
|
|
|
2665
2643
|
@pytest.mark.anyio
|
|
2666
2644
|
async def test_clvm_must_not_fail(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
@@ -2718,9 +2696,14 @@ class TestBodyValidation:
|
|
|
2718
2696
|
height=softfork_height,
|
|
2719
2697
|
constants=bt.constants,
|
|
2720
2698
|
)
|
|
2699
|
+
assert npc_result.conds is not None
|
|
2721
2700
|
ssi = b.constants.SUB_SLOT_ITERS_STARTING
|
|
2701
|
+
fork_info = ForkInfo(block_2.height - 1, block_2.height - 1, block_2.prev_header_hash)
|
|
2722
2702
|
_, err, _ = await b.add_block(
|
|
2723
|
-
block_2,
|
|
2703
|
+
block_2,
|
|
2704
|
+
PreValidationResult(None, uint64(1), npc_result.conds.replace(validated_signature=True), uint32(0)),
|
|
2705
|
+
sub_slot_iters=ssi,
|
|
2706
|
+
fork_info=fork_info,
|
|
2724
2707
|
)
|
|
2725
2708
|
assert err == Err.INVALID_BLOCK_COST
|
|
2726
2709
|
|
|
@@ -2748,8 +2731,13 @@ class TestBodyValidation:
|
|
|
2748
2731
|
height=softfork_height,
|
|
2749
2732
|
constants=bt.constants,
|
|
2750
2733
|
)
|
|
2734
|
+
assert npc_result.conds is not None
|
|
2735
|
+
fork_info = ForkInfo(block_2.height - 1, block_2.height - 1, block_2.prev_header_hash)
|
|
2751
2736
|
_, err, _ = await b.add_block(
|
|
2752
|
-
block_2,
|
|
2737
|
+
block_2,
|
|
2738
|
+
PreValidationResult(None, uint64(1), npc_result.conds.replace(validated_signature=True), uint32(0)),
|
|
2739
|
+
sub_slot_iters=ssi,
|
|
2740
|
+
fork_info=fork_info,
|
|
2753
2741
|
)
|
|
2754
2742
|
assert err == Err.INVALID_BLOCK_COST
|
|
2755
2743
|
|
|
@@ -2776,11 +2764,19 @@ class TestBodyValidation:
|
|
|
2776
2764
|
else b.constants.MAX_BLOCK_COST_CLVM * 1000
|
|
2777
2765
|
)
|
|
2778
2766
|
npc_result = get_name_puzzle_conditions(
|
|
2779
|
-
block_generator,
|
|
2767
|
+
block_generator,
|
|
2768
|
+
max_cost,
|
|
2769
|
+
mempool_mode=False,
|
|
2770
|
+
height=softfork_height,
|
|
2771
|
+
constants=bt.constants,
|
|
2780
2772
|
)
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2773
|
+
assert npc_result.conds is not None
|
|
2774
|
+
fork_info = ForkInfo(block_2.height - 1, block_2.height - 1, block_2.prev_header_hash)
|
|
2775
|
+
_result, err, _ = await b.add_block(
|
|
2776
|
+
block_2,
|
|
2777
|
+
PreValidationResult(None, uint64(1), npc_result.conds.replace(validated_signature=True), uint32(0)),
|
|
2778
|
+
sub_slot_iters=ssi,
|
|
2779
|
+
fork_info=fork_info,
|
|
2784
2780
|
)
|
|
2785
2781
|
assert err == Err.INVALID_BLOCK_COST
|
|
2786
2782
|
|
|
@@ -2817,7 +2813,7 @@ class TestBodyValidation:
|
|
|
2817
2813
|
|
|
2818
2814
|
# wt: WalletTool = bt_2.get_pool_wallet_tool()
|
|
2819
2815
|
|
|
2820
|
-
# condition_dict:
|
|
2816
|
+
# condition_dict: dict[ConditionOpcode, list[ConditionWithArgs]] = {ConditionOpcode.CREATE_COIN: []}
|
|
2821
2817
|
# output = ConditionWithArgs(ConditionOpcode.CREATE_COIN, [bt_2.pool_ph, int_to_bytes(2 ** 64)])
|
|
2822
2818
|
# condition_dict[ConditionOpcode.CREATE_COIN].append(output)
|
|
2823
2819
|
|
|
@@ -2935,7 +2931,7 @@ class TestBodyValidation:
|
|
|
2935
2931
|
|
|
2936
2932
|
wt: WalletTool = bt.get_pool_wallet_tool()
|
|
2937
2933
|
|
|
2938
|
-
condition_dict:
|
|
2934
|
+
condition_dict: dict[ConditionOpcode, list[ConditionWithArgs]] = {ConditionOpcode.CREATE_COIN: []}
|
|
2939
2935
|
for _ in range(2):
|
|
2940
2936
|
output = ConditionWithArgs(ConditionOpcode.CREATE_COIN, [bt.pool_ph, int_to_bytes(1)])
|
|
2941
2937
|
condition_dict[ConditionOpcode.CREATE_COIN].append(output)
|
|
@@ -3048,27 +3044,40 @@ class TestBodyValidation:
|
|
|
3048
3044
|
await _validate_and_add_block(b, block)
|
|
3049
3045
|
|
|
3050
3046
|
blocks_reorg = bt.get_consecutive_blocks(2, block_list_input=blocks[:-7], guarantee_transaction_block=True)
|
|
3051
|
-
|
|
3052
|
-
await _validate_and_add_block(
|
|
3047
|
+
fork_info = ForkInfo(blocks[-8].height, blocks[-8].height, blocks[-8].header_hash)
|
|
3048
|
+
await _validate_and_add_block(
|
|
3049
|
+
b, blocks_reorg[-2], expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info
|
|
3050
|
+
)
|
|
3051
|
+
await _validate_and_add_block(
|
|
3052
|
+
b, blocks_reorg[-1], expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info
|
|
3053
|
+
)
|
|
3053
3054
|
|
|
3054
3055
|
# Coin does not exist in reorg
|
|
3055
3056
|
blocks_reorg = bt.get_consecutive_blocks(
|
|
3056
3057
|
1, block_list_input=blocks_reorg, guarantee_transaction_block=True, transaction_data=tx_2
|
|
3057
3058
|
)
|
|
3058
|
-
|
|
3059
|
-
|
|
3059
|
+
peak = b.get_peak()
|
|
3060
|
+
assert peak is not None
|
|
3061
|
+
await _validate_and_add_block(b, blocks_reorg[-1], expected_error=Err.UNKNOWN_UNSPENT, fork_info=fork_info)
|
|
3060
3062
|
|
|
3061
3063
|
# Finally add the block to the fork (spending both in same bundle, this is ephemeral)
|
|
3062
3064
|
agg = SpendBundle.aggregate([tx, tx_2])
|
|
3063
3065
|
blocks_reorg = bt.get_consecutive_blocks(
|
|
3064
3066
|
1, block_list_input=blocks_reorg[:-1], guarantee_transaction_block=True, transaction_data=agg
|
|
3065
3067
|
)
|
|
3066
|
-
|
|
3068
|
+
|
|
3069
|
+
peak = b.get_peak()
|
|
3070
|
+
assert peak is not None
|
|
3071
|
+
await _validate_and_add_block(
|
|
3072
|
+
b, blocks_reorg[-1], expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info
|
|
3073
|
+
)
|
|
3067
3074
|
|
|
3068
3075
|
blocks_reorg = bt.get_consecutive_blocks(
|
|
3069
3076
|
1, block_list_input=blocks_reorg, guarantee_transaction_block=True, transaction_data=tx_2
|
|
3070
3077
|
)
|
|
3071
|
-
|
|
3078
|
+
peak = b.get_peak()
|
|
3079
|
+
assert peak is not None
|
|
3080
|
+
await _validate_and_add_block(b, blocks_reorg[-1], expected_error=Err.DOUBLE_SPEND_IN_FORK, fork_info=fork_info)
|
|
3072
3081
|
|
|
3073
3082
|
rewards_ph = wt.get_new_puzzlehash()
|
|
3074
3083
|
blocks_reorg = bt.get_consecutive_blocks(
|
|
@@ -3077,9 +3086,12 @@ class TestBodyValidation:
|
|
|
3077
3086
|
guarantee_transaction_block=True,
|
|
3078
3087
|
farmer_reward_puzzle_hash=rewards_ph,
|
|
3079
3088
|
)
|
|
3089
|
+
|
|
3090
|
+
peak = b.get_peak()
|
|
3091
|
+
assert peak is not None
|
|
3080
3092
|
for block in blocks_reorg[-10:]:
|
|
3081
3093
|
await _validate_and_add_block_multi_result(
|
|
3082
|
-
b, block, expected_result=[AddBlockResult.ADDED_AS_ORPHAN, AddBlockResult.NEW_PEAK]
|
|
3094
|
+
b, block, expected_result=[AddBlockResult.ADDED_AS_ORPHAN, AddBlockResult.NEW_PEAK], fork_info=fork_info
|
|
3083
3095
|
)
|
|
3084
3096
|
|
|
3085
3097
|
# ephemeral coin is spent
|
|
@@ -3221,25 +3233,20 @@ class TestBodyValidation:
|
|
|
3221
3233
|
|
|
3222
3234
|
# Bad signature fails during add_block
|
|
3223
3235
|
await _validate_and_add_block(b, last_block, expected_error=Err.BAD_AGGREGATE_SIGNATURE)
|
|
3224
|
-
# Also test the same case but when using BLSCache
|
|
3225
|
-
await _validate_and_add_block(b, last_block, expected_error=Err.BAD_AGGREGATE_SIGNATURE, use_bls_cache=True)
|
|
3226
3236
|
|
|
3227
3237
|
# Bad signature also fails in prevalidation
|
|
3228
3238
|
ssi = b.constants.SUB_SLOT_ITERS_STARTING
|
|
3229
3239
|
diff = b.constants.DIFFICULTY_STARTING
|
|
3230
|
-
|
|
3240
|
+
future = await pre_validate_block(
|
|
3231
3241
|
b.constants,
|
|
3232
|
-
b,
|
|
3233
|
-
|
|
3242
|
+
AugmentedBlockchain(b),
|
|
3243
|
+
last_block,
|
|
3234
3244
|
b.pool,
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
difficulty=diff,
|
|
3238
|
-
prev_ses_block=None,
|
|
3239
|
-
validate_signatures=True,
|
|
3245
|
+
None,
|
|
3246
|
+
ValidationState(ssi, diff, None),
|
|
3240
3247
|
)
|
|
3241
|
-
|
|
3242
|
-
assert
|
|
3248
|
+
preval_result: PreValidationResult = await future
|
|
3249
|
+
assert preval_result.error == Err.BAD_AGGREGATE_SIGNATURE.value
|
|
3243
3250
|
|
|
3244
3251
|
|
|
3245
3252
|
def maybe_header_hash(block: Optional[BlockRecord]) -> Optional[bytes32]:
|
|
@@ -3261,13 +3268,18 @@ class TestReorgs:
|
|
|
3261
3268
|
assert peak.height == 14
|
|
3262
3269
|
|
|
3263
3270
|
blocks_reorg_chain = bt.get_consecutive_blocks(7, blocks[:10], seed=b"2")
|
|
3271
|
+
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
|
3264
3272
|
for reorg_block in blocks_reorg_chain:
|
|
3265
3273
|
if reorg_block.height < 10:
|
|
3266
|
-
await _validate_and_add_block(
|
|
3274
|
+
await _validate_and_add_block(
|
|
3275
|
+
b, reorg_block, expected_result=AddBlockResult.ALREADY_HAVE_BLOCK, fork_info=fork_info
|
|
3276
|
+
)
|
|
3267
3277
|
elif reorg_block.height < 15:
|
|
3268
|
-
await _validate_and_add_block(
|
|
3278
|
+
await _validate_and_add_block(
|
|
3279
|
+
b, reorg_block, expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info
|
|
3280
|
+
)
|
|
3269
3281
|
elif reorg_block.height >= 15:
|
|
3270
|
-
await _validate_and_add_block(b, reorg_block)
|
|
3282
|
+
await _validate_and_add_block(b, reorg_block, fork_info=fork_info)
|
|
3271
3283
|
peak = b.get_peak()
|
|
3272
3284
|
assert peak is not None
|
|
3273
3285
|
assert peak.height == 16
|
|
@@ -3296,16 +3308,19 @@ class TestReorgs:
|
|
|
3296
3308
|
assert maybe_header_hash(b.get_tx_peak()) == last_tx_block
|
|
3297
3309
|
|
|
3298
3310
|
reorg_last_tx_block: Optional[bytes32] = None
|
|
3299
|
-
|
|
3311
|
+
fork_block = blocks[9]
|
|
3312
|
+
fork_info = ForkInfo(fork_block.height, fork_block.height, fork_block.header_hash)
|
|
3300
3313
|
blocks_reorg_chain = bt.get_consecutive_blocks(7, blocks[:10], seed=b"2")
|
|
3301
3314
|
assert blocks_reorg_chain[reorg_point].is_transaction_block() is False
|
|
3302
3315
|
for reorg_block in blocks_reorg_chain:
|
|
3303
3316
|
if reorg_block.height < 10:
|
|
3304
3317
|
await _validate_and_add_block(b, reorg_block, expected_result=AddBlockResult.ALREADY_HAVE_BLOCK)
|
|
3305
3318
|
elif reorg_block.height < reorg_point:
|
|
3306
|
-
await _validate_and_add_block(
|
|
3319
|
+
await _validate_and_add_block(
|
|
3320
|
+
b, reorg_block, expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info
|
|
3321
|
+
)
|
|
3307
3322
|
elif reorg_block.height >= reorg_point:
|
|
3308
|
-
await _validate_and_add_block(b, reorg_block)
|
|
3323
|
+
await _validate_and_add_block(b, reorg_block, fork_info=fork_info)
|
|
3309
3324
|
|
|
3310
3325
|
if reorg_block.is_transaction_block():
|
|
3311
3326
|
reorg_last_tx_block = reorg_block.header_hash
|
|
@@ -3324,9 +3339,9 @@ class TestReorgs:
|
|
|
3324
3339
|
self,
|
|
3325
3340
|
light_blocks: bool,
|
|
3326
3341
|
empty_blockchain: Blockchain,
|
|
3327
|
-
default_10000_blocks:
|
|
3328
|
-
test_long_reorg_blocks:
|
|
3329
|
-
test_long_reorg_blocks_light:
|
|
3342
|
+
default_10000_blocks: list[FullBlock],
|
|
3343
|
+
test_long_reorg_blocks: list[FullBlock],
|
|
3344
|
+
test_long_reorg_blocks_light: list[FullBlock],
|
|
3330
3345
|
) -> None:
|
|
3331
3346
|
if light_blocks:
|
|
3332
3347
|
reorg_blocks = test_long_reorg_blocks_light[:1650]
|
|
@@ -3345,17 +3360,21 @@ class TestReorgs:
|
|
|
3345
3360
|
print(f"pre-validating {len(blocks)} blocks")
|
|
3346
3361
|
ssi = b.constants.SUB_SLOT_ITERS_STARTING
|
|
3347
3362
|
diff = b.constants.DIFFICULTY_STARTING
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3363
|
+
chain = AugmentedBlockchain(b)
|
|
3364
|
+
vs = ValidationState(ssi, diff, None)
|
|
3365
|
+
futures = []
|
|
3366
|
+
for block in blocks:
|
|
3367
|
+
futures.append(
|
|
3368
|
+
await pre_validate_block(
|
|
3369
|
+
b.constants,
|
|
3370
|
+
chain,
|
|
3371
|
+
block,
|
|
3372
|
+
b.pool,
|
|
3373
|
+
None,
|
|
3374
|
+
vs,
|
|
3375
|
+
)
|
|
3376
|
+
)
|
|
3377
|
+
pre_validation_results: list[PreValidationResult] = list(await asyncio.gather(*futures))
|
|
3359
3378
|
for i, block in enumerate(blocks):
|
|
3360
3379
|
if block.height != 0 and len(block.finished_sub_slots) > 0:
|
|
3361
3380
|
if block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters is not None:
|
|
@@ -3363,7 +3382,12 @@ class TestReorgs:
|
|
|
3363
3382
|
assert pre_validation_results[i].error is None
|
|
3364
3383
|
if (block.height % 100) == 0:
|
|
3365
3384
|
print(f"main chain: {block.height:4} weight: {block.weight}")
|
|
3366
|
-
|
|
3385
|
+
|
|
3386
|
+
fork_info: ForkInfo = ForkInfo(block.height - 1, block.height - 1, block.prev_header_hash)
|
|
3387
|
+
assert fork_info is not None
|
|
3388
|
+
(result, err, _) = await b.add_block(
|
|
3389
|
+
block, pre_validation_results[i], sub_slot_iters=ssi, fork_info=fork_info
|
|
3390
|
+
)
|
|
3367
3391
|
await check_block_store_invariant(b)
|
|
3368
3392
|
assert err is None
|
|
3369
3393
|
assert result == AddBlockResult.NEW_PEAK
|
|
@@ -3388,7 +3412,7 @@ class TestReorgs:
|
|
|
3388
3412
|
b.clean_block_records()
|
|
3389
3413
|
|
|
3390
3414
|
first_peak = b.get_peak()
|
|
3391
|
-
|
|
3415
|
+
fork_info2 = None
|
|
3392
3416
|
for reorg_block in reorg_blocks:
|
|
3393
3417
|
if (reorg_block.height % 100) == 0:
|
|
3394
3418
|
peak = b.get_peak()
|
|
@@ -3402,14 +3426,14 @@ class TestReorgs:
|
|
|
3402
3426
|
if reorg_block.height < num_blocks_chain_2_start:
|
|
3403
3427
|
await _validate_and_add_block(b, reorg_block, expected_result=AddBlockResult.ALREADY_HAVE_BLOCK)
|
|
3404
3428
|
elif reorg_block.weight <= chain_1_weight:
|
|
3405
|
-
if
|
|
3406
|
-
|
|
3429
|
+
if fork_info2 is None:
|
|
3430
|
+
fork_info2 = ForkInfo(reorg_block.height - 1, reorg_block.height - 1, reorg_block.prev_header_hash)
|
|
3407
3431
|
await _validate_and_add_block(
|
|
3408
|
-
b, reorg_block, expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=
|
|
3432
|
+
b, reorg_block, expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info2
|
|
3409
3433
|
)
|
|
3410
3434
|
elif reorg_block.weight > chain_1_weight:
|
|
3411
3435
|
await _validate_and_add_block(
|
|
3412
|
-
b, reorg_block, expected_result=AddBlockResult.NEW_PEAK, fork_info=
|
|
3436
|
+
b, reorg_block, expected_result=AddBlockResult.NEW_PEAK, fork_info=fork_info2
|
|
3413
3437
|
)
|
|
3414
3438
|
|
|
3415
3439
|
# if these asserts fires, there was no reorg
|
|
@@ -3448,7 +3472,7 @@ class TestReorgs:
|
|
|
3448
3472
|
|
|
3449
3473
|
# start the fork point a few blocks back, to test that the blockchain
|
|
3450
3474
|
# can catch up
|
|
3451
|
-
fork_block = default_10000_blocks[num_blocks_chain_2_start -
|
|
3475
|
+
fork_block = default_10000_blocks[num_blocks_chain_2_start - 101]
|
|
3452
3476
|
fork_info = ForkInfo(fork_block.height, fork_block.height, fork_block.header_hash)
|
|
3453
3477
|
await b.warmup(fork_block.height)
|
|
3454
3478
|
for block in blocks:
|
|
@@ -3476,7 +3500,7 @@ class TestReorgs:
|
|
|
3476
3500
|
|
|
3477
3501
|
@pytest.mark.anyio
|
|
3478
3502
|
async def test_long_compact_blockchain(
|
|
3479
|
-
self, empty_blockchain: Blockchain, default_2000_blocks_compact:
|
|
3503
|
+
self, empty_blockchain: Blockchain, default_2000_blocks_compact: list[FullBlock]
|
|
3480
3504
|
) -> None:
|
|
3481
3505
|
b = empty_blockchain
|
|
3482
3506
|
for block in default_2000_blocks_compact:
|
|
@@ -3499,22 +3523,34 @@ class TestReorgs:
|
|
|
3499
3523
|
|
|
3500
3524
|
# Reorg to alternate chain that is 1 height longer
|
|
3501
3525
|
blocks_reorg_chain = bt.get_consecutive_blocks(16, [], seed=b"2")
|
|
3526
|
+
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
|
3502
3527
|
for reorg_block in blocks_reorg_chain:
|
|
3503
3528
|
if reorg_block.height < 15:
|
|
3504
3529
|
await _validate_and_add_block_multi_result(
|
|
3505
3530
|
b,
|
|
3506
3531
|
reorg_block,
|
|
3507
3532
|
expected_result=[AddBlockResult.ADDED_AS_ORPHAN, AddBlockResult.ALREADY_HAVE_BLOCK],
|
|
3533
|
+
fork_info=fork_info,
|
|
3508
3534
|
)
|
|
3509
3535
|
elif reorg_block.height >= 15:
|
|
3510
|
-
await _validate_and_add_block(b, reorg_block)
|
|
3536
|
+
await _validate_and_add_block(b, reorg_block, fork_info=fork_info)
|
|
3511
3537
|
|
|
3512
3538
|
# Back to original chain
|
|
3513
3539
|
blocks_reorg_chain_2 = bt.get_consecutive_blocks(3, blocks, seed=b"3")
|
|
3514
3540
|
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3541
|
+
# we start from the beginning to make sure fork_info is built correctly
|
|
3542
|
+
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
|
3543
|
+
for reorg_block in blocks_reorg_chain_2:
|
|
3544
|
+
if reorg_block.height < 15:
|
|
3545
|
+
await _validate_and_add_block(
|
|
3546
|
+
b, reorg_block, expected_result=AddBlockResult.ALREADY_HAVE_BLOCK, fork_info=fork_info
|
|
3547
|
+
)
|
|
3548
|
+
elif reorg_block.height < 16:
|
|
3549
|
+
await _validate_and_add_block(
|
|
3550
|
+
b, reorg_block, expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info
|
|
3551
|
+
)
|
|
3552
|
+
else:
|
|
3553
|
+
await _validate_and_add_block(b, reorg_block, fork_info=fork_info)
|
|
3518
3554
|
|
|
3519
3555
|
peak = b.get_peak()
|
|
3520
3556
|
assert peak is not None
|
|
@@ -3562,9 +3598,10 @@ class TestReorgs:
|
|
|
3562
3598
|
)
|
|
3563
3599
|
for block in blocks:
|
|
3564
3600
|
await _validate_and_add_block(b, block)
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3601
|
+
fork_block = blocks[11]
|
|
3602
|
+
fork_info = ForkInfo(fork_block.height, fork_block.height, fork_block.header_hash)
|
|
3603
|
+
for block in blocks_fork[12:]:
|
|
3604
|
+
await _validate_and_add_block_no_error(b, block, fork_info=fork_info)
|
|
3568
3605
|
|
|
3569
3606
|
@pytest.mark.anyio
|
|
3570
3607
|
async def test_get_header_blocks_in_range_tx_filter(self, empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
@@ -3600,7 +3637,7 @@ class TestReorgs:
|
|
|
3600
3637
|
assert blocks_with_filter[header_hash].header_hash == blocks_without_filter[header_hash].header_hash
|
|
3601
3638
|
|
|
3602
3639
|
@pytest.mark.anyio
|
|
3603
|
-
async def test_get_blocks_at(self, empty_blockchain: Blockchain, default_1000_blocks:
|
|
3640
|
+
async def test_get_blocks_at(self, empty_blockchain: Blockchain, default_1000_blocks: list[FullBlock]) -> None:
|
|
3604
3641
|
b = empty_blockchain
|
|
3605
3642
|
heights = []
|
|
3606
3643
|
for block in default_1000_blocks[:200]:
|
|
@@ -3678,8 +3715,8 @@ async def test_reorg_new_ref(empty_blockchain: Blockchain, bt: BlockTools) -> No
|
|
|
3678
3715
|
)
|
|
3679
3716
|
blocks_reorg_chain = bt.get_consecutive_blocks(4, blocks_reorg_chain, seed=b"2")
|
|
3680
3717
|
|
|
3718
|
+
fork_info = ForkInfo(-1, -1, b.constants.GENESIS_CHALLENGE)
|
|
3681
3719
|
for i, block in enumerate(blocks_reorg_chain):
|
|
3682
|
-
fork_info: Optional[ForkInfo] = None
|
|
3683
3720
|
if i < 10:
|
|
3684
3721
|
expected = AddBlockResult.ALREADY_HAVE_BLOCK
|
|
3685
3722
|
elif i < 19:
|
|
@@ -3693,8 +3730,6 @@ async def test_reorg_new_ref(empty_blockchain: Blockchain, bt: BlockTools) -> No
|
|
|
3693
3730
|
expected = AddBlockResult.NEW_PEAK
|
|
3694
3731
|
else:
|
|
3695
3732
|
expected = AddBlockResult.NEW_PEAK
|
|
3696
|
-
if fork_info is None:
|
|
3697
|
-
fork_info = ForkInfo(blocks[1].height, blocks[1].height, blocks[1].header_hash)
|
|
3698
3733
|
await _validate_and_add_block(b, block, expected_result=expected, fork_info=fork_info)
|
|
3699
3734
|
peak = b.get_peak()
|
|
3700
3735
|
assert peak is not None
|
|
@@ -3746,7 +3781,7 @@ async def test_reorg_stale_fork_height(empty_blockchain: Blockchain, bt: BlockTo
|
|
|
3746
3781
|
await _validate_and_add_block(b, block, expected_result=AddBlockResult.NEW_PEAK)
|
|
3747
3782
|
|
|
3748
3783
|
# fake the fork_info to make every new block look like a reorg
|
|
3749
|
-
fork_info = ForkInfo(blocks[
|
|
3784
|
+
fork_info = ForkInfo(blocks[4].height, blocks[4].height, blocks[4].header_hash)
|
|
3750
3785
|
for block in blocks[5:]:
|
|
3751
3786
|
await _validate_and_add_block(b, block, expected_result=AddBlockResult.NEW_PEAK, fork_info=fork_info)
|
|
3752
3787
|
peak = b.get_peak()
|
|
@@ -3796,8 +3831,10 @@ async def test_chain_failed_rollback(empty_blockchain: Blockchain, bt: BlockTool
|
|
|
3796
3831
|
guarantee_transaction_block=True,
|
|
3797
3832
|
)
|
|
3798
3833
|
|
|
3834
|
+
fork_block = blocks_reorg_chain[9]
|
|
3835
|
+
fork_info = ForkInfo(fork_block.height, fork_block.height, fork_block.header_hash)
|
|
3799
3836
|
for block in blocks_reorg_chain[10:-1]:
|
|
3800
|
-
await _validate_and_add_block(b, block, expected_result=AddBlockResult.ADDED_AS_ORPHAN)
|
|
3837
|
+
await _validate_and_add_block(b, block, expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info)
|
|
3801
3838
|
|
|
3802
3839
|
# Incorrectly set the height as spent in DB to trigger an error
|
|
3803
3840
|
print(f"{await b.coin_store.get_coin_record(spend_bundle.coin_spends[0].coin.name())}")
|
|
@@ -3806,8 +3843,10 @@ async def test_chain_failed_rollback(empty_blockchain: Blockchain, bt: BlockTool
|
|
|
3806
3843
|
await b.coin_store.rollback_to_block(2)
|
|
3807
3844
|
print(f"{await b.coin_store.get_coin_record(spend_bundle.coin_spends[0].coin.name())}")
|
|
3808
3845
|
|
|
3846
|
+
fork_block = blocks_reorg_chain[10 - 1]
|
|
3847
|
+
# fork_info = ForkInfo(fork_block.height, fork_block.height, fork_block.header_hash)
|
|
3809
3848
|
with pytest.raises(ValueError, match="Invalid operation to set spent"):
|
|
3810
|
-
await _validate_and_add_block(b, blocks_reorg_chain[-1])
|
|
3849
|
+
await _validate_and_add_block(b, blocks_reorg_chain[-1], fork_info=fork_info)
|
|
3811
3850
|
|
|
3812
3851
|
peak = b.get_peak()
|
|
3813
3852
|
assert peak is not None
|
|
@@ -3906,31 +3945,37 @@ async def test_reorg_flip_flop(empty_blockchain: Blockchain, bt: BlockTools) ->
|
|
|
3906
3945
|
block1, block2 = b1, b2
|
|
3907
3946
|
counter += 1
|
|
3908
3947
|
|
|
3909
|
-
preval
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
validate_signatures=False,
|
|
3948
|
+
preval = await (
|
|
3949
|
+
await pre_validate_block(
|
|
3950
|
+
b.constants,
|
|
3951
|
+
AugmentedBlockchain(b),
|
|
3952
|
+
block1,
|
|
3953
|
+
b.pool,
|
|
3954
|
+
None,
|
|
3955
|
+
ValidationState(ssi, diff, None),
|
|
3956
|
+
)
|
|
3919
3957
|
)
|
|
3920
|
-
|
|
3958
|
+
peak = b.get_peak()
|
|
3959
|
+
if peak is None:
|
|
3960
|
+
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
|
3961
|
+
else:
|
|
3962
|
+
fork_info = await get_fork_info(b, block1, peak)
|
|
3963
|
+
_, err, _ = await b.add_block(block1, preval, sub_slot_iters=ssi, fork_info=fork_info)
|
|
3921
3964
|
assert err is None
|
|
3922
|
-
preval = await
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
validate_signatures=False,
|
|
3965
|
+
preval = await (
|
|
3966
|
+
await pre_validate_block(
|
|
3967
|
+
b.constants,
|
|
3968
|
+
AugmentedBlockchain(b),
|
|
3969
|
+
block2,
|
|
3970
|
+
b.pool,
|
|
3971
|
+
None,
|
|
3972
|
+
ValidationState(ssi, diff, None),
|
|
3973
|
+
)
|
|
3932
3974
|
)
|
|
3933
|
-
|
|
3975
|
+
peak = b.get_peak()
|
|
3976
|
+
assert peak is not None
|
|
3977
|
+
fork_info = await get_fork_info(b, block2, peak)
|
|
3978
|
+
_, err, _ = await b.add_block(block2, preval, sub_slot_iters=ssi, fork_info=fork_info)
|
|
3934
3979
|
assert err is None
|
|
3935
3980
|
|
|
3936
3981
|
peak = b.get_peak()
|
|
@@ -3949,27 +3994,33 @@ async def test_reorg_flip_flop(empty_blockchain: Blockchain, bt: BlockTools) ->
|
|
|
3949
3994
|
await _validate_and_add_block(b, block)
|
|
3950
3995
|
|
|
3951
3996
|
|
|
3952
|
-
async def test_get_tx_peak(default_400_blocks:
|
|
3997
|
+
async def test_get_tx_peak(default_400_blocks: list[FullBlock], empty_blockchain: Blockchain) -> None:
|
|
3953
3998
|
bc = empty_blockchain
|
|
3954
3999
|
test_blocks = default_400_blocks[:100]
|
|
3955
4000
|
ssi = bc.constants.SUB_SLOT_ITERS_STARTING
|
|
3956
4001
|
diff = bc.constants.DIFFICULTY_STARTING
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
4002
|
+
futures: list[Awaitable[PreValidationResult]] = []
|
|
4003
|
+
chain = AugmentedBlockchain(bc)
|
|
4004
|
+
vs = ValidationState(ssi, diff, None)
|
|
4005
|
+
for block in test_blocks:
|
|
4006
|
+
futures.append(
|
|
4007
|
+
await pre_validate_block(
|
|
4008
|
+
bc.constants,
|
|
4009
|
+
chain,
|
|
4010
|
+
block,
|
|
4011
|
+
bc.pool,
|
|
4012
|
+
None,
|
|
4013
|
+
vs,
|
|
4014
|
+
)
|
|
4015
|
+
)
|
|
4016
|
+
|
|
4017
|
+
res: list[PreValidationResult] = list(await asyncio.gather(*futures))
|
|
3968
4018
|
|
|
3969
4019
|
last_tx_block_record = None
|
|
3970
4020
|
for b, prevalidation_res in zip(test_blocks, res):
|
|
3971
4021
|
assert bc.get_tx_peak() == last_tx_block_record
|
|
3972
|
-
|
|
4022
|
+
fork_info = ForkInfo(b.height - 1, b.height - 1, b.prev_header_hash)
|
|
4023
|
+
_, err, _ = await bc.add_block(b, prevalidation_res, sub_slot_iters=ssi, fork_info=fork_info)
|
|
3973
4024
|
assert err is None
|
|
3974
4025
|
|
|
3975
4026
|
if b.is_transaction_block():
|
|
@@ -3995,8 +4046,8 @@ def to_bytes(gen: Optional[SerializedProgram]) -> bytes:
|
|
|
3995
4046
|
@pytest.mark.limit_consensus_modes(reason="block heights for generators differ between test chains in different modes")
|
|
3996
4047
|
@pytest.mark.parametrize("clear_cache", [True, False])
|
|
3997
4048
|
async def test_lookup_block_generators(
|
|
3998
|
-
default_10000_blocks:
|
|
3999
|
-
test_long_reorg_blocks_light:
|
|
4049
|
+
default_10000_blocks: list[FullBlock],
|
|
4050
|
+
test_long_reorg_blocks_light: list[FullBlock],
|
|
4000
4051
|
bt: BlockTools,
|
|
4001
4052
|
empty_blockchain: Blockchain,
|
|
4002
4053
|
clear_cache: bool,
|
|
@@ -4020,11 +4071,13 @@ async def test_lookup_block_generators(
|
|
|
4020
4071
|
# 507, 516, 527, 535, 539, 543, 547
|
|
4021
4072
|
|
|
4022
4073
|
# start with adding some blocks to test lookups from the mainchain
|
|
4074
|
+
fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
|
|
4023
4075
|
for block in blocks_2[:550]:
|
|
4024
|
-
await _validate_and_add_block(b, block, expected_result=AddBlockResult.NEW_PEAK)
|
|
4076
|
+
await _validate_and_add_block(b, block, expected_result=AddBlockResult.NEW_PEAK, fork_info=fork_info)
|
|
4025
4077
|
|
|
4078
|
+
fork_info = ForkInfo(blocks_1[500].height - 1, blocks_1[500].height - 1, blocks_1[500].prev_header_hash)
|
|
4026
4079
|
for block in blocks_1[500:550]:
|
|
4027
|
-
await _validate_and_add_block(b, block, expected_result=AddBlockResult.ADDED_AS_ORPHAN)
|
|
4080
|
+
await _validate_and_add_block(b, block, expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info)
|
|
4028
4081
|
|
|
4029
4082
|
# now we have a blockchain with two forks, the peak is at blocks_2[550] and
|
|
4030
4083
|
# the leight weight peak is at blocks_1[550]
|
|
@@ -4098,3 +4151,52 @@ async def test_lookup_block_generators(
|
|
|
4098
4151
|
b.clean_block_records()
|
|
4099
4152
|
with pytest.raises(AssertionError):
|
|
4100
4153
|
await b.lookup_block_generators(blocks_1[600].prev_header_hash, {uint32(3)})
|
|
4154
|
+
|
|
4155
|
+
|
|
4156
|
+
async def get_fork_info(blockchain: Blockchain, block: FullBlock, peak: BlockRecord) -> ForkInfo:
|
|
4157
|
+
fork_chain, fork_hash = await lookup_fork_chain(
|
|
4158
|
+
blockchain,
|
|
4159
|
+
(peak.height, peak.header_hash),
|
|
4160
|
+
(block.height - 1, block.prev_header_hash),
|
|
4161
|
+
blockchain.constants,
|
|
4162
|
+
)
|
|
4163
|
+
# now we know how long the fork is, and can compute the fork
|
|
4164
|
+
# height.
|
|
4165
|
+
fork_height = block.height - len(fork_chain) - 1
|
|
4166
|
+
fork_info = ForkInfo(fork_height, fork_height, fork_hash)
|
|
4167
|
+
|
|
4168
|
+
# now run all the blocks of the fork to compute the additions
|
|
4169
|
+
# and removals. They are recorded in the fork_info object
|
|
4170
|
+
counter = 0
|
|
4171
|
+
start = time.monotonic()
|
|
4172
|
+
for height in range(fork_info.fork_height + 1, block.height):
|
|
4173
|
+
fork_block: Optional[FullBlock] = await blockchain.block_store.get_full_block(fork_chain[uint32(height)])
|
|
4174
|
+
assert fork_block is not None
|
|
4175
|
+
assert fork_block.height - 1 == fork_info.peak_height
|
|
4176
|
+
assert fork_block.height == 0 or fork_block.prev_header_hash == fork_info.peak_hash
|
|
4177
|
+
await blockchain.run_single_block(fork_block, fork_info)
|
|
4178
|
+
counter += 1
|
|
4179
|
+
end = time.monotonic()
|
|
4180
|
+
log.info(
|
|
4181
|
+
f"executed {counter} block generators in {end - start:2f} s. "
|
|
4182
|
+
f"{len(fork_info.additions_since_fork)} additions, "
|
|
4183
|
+
f"{len(fork_info.removals_since_fork)} removals"
|
|
4184
|
+
)
|
|
4185
|
+
|
|
4186
|
+
return fork_info
|
|
4187
|
+
|
|
4188
|
+
|
|
4189
|
+
@pytest.mark.anyio
|
|
4190
|
+
async def test_get_header_blocks_in_range_tx_filter_non_tx_block(empty_blockchain: Blockchain, bt: BlockTools) -> None:
|
|
4191
|
+
"""
|
|
4192
|
+
Covers the case of calling `get_header_blocks_in_range`, requesting
|
|
4193
|
+
transactions filter, on a non transaction block.
|
|
4194
|
+
"""
|
|
4195
|
+
b = empty_blockchain
|
|
4196
|
+
blocks = bt.get_consecutive_blocks(2)
|
|
4197
|
+
for block in blocks:
|
|
4198
|
+
await _validate_and_add_block(b, block)
|
|
4199
|
+
non_tx_block = next(block for block in blocks if not block.is_transaction_block())
|
|
4200
|
+
blocks_with_filter = await b.get_header_blocks_in_range(0, 42, tx_filter=True)
|
|
4201
|
+
empty_tx_filter = b"\x00"
|
|
4202
|
+
assert blocks_with_filter[non_tx_block.header_hash].transactions_filter == empty_tx_filter
|