chia-blockchain 2.5.7rc4__py3-none-any.whl → 2.6.0rc2__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/__init__.py +8 -4
- chia/_tests/blockchain/blockchain_test_utils.py +6 -8
- chia/_tests/blockchain/test_augmented_chain.py +4 -4
- chia/_tests/blockchain/test_blockchain.py +165 -190
- chia/_tests/blockchain/test_blockchain_transactions.py +5 -2
- chia/_tests/blockchain/test_build_chains.py +2 -4
- chia/_tests/blockchain/test_get_block_generator.py +2 -3
- chia/_tests/clvm/coin_store.py +4 -7
- chia/_tests/clvm/test_clvm_step.py +4 -4
- chia/_tests/clvm/test_puzzle_compression.py +2 -1
- chia/_tests/clvm/test_puzzle_drivers.py +2 -2
- chia/_tests/clvm/test_singletons.py +2 -4
- chia/_tests/clvm/test_spend_sim.py +2 -2
- chia/_tests/cmds/cmd_test_utils.py +27 -45
- chia/_tests/cmds/test_cmd_framework.py +6 -6
- chia/_tests/cmds/test_daemon.py +3 -3
- chia/_tests/cmds/test_show.py +4 -4
- chia/_tests/cmds/test_tx_config_args.py +1 -2
- chia/_tests/cmds/testing_classes.py +4 -5
- chia/_tests/cmds/wallet/test_did.py +24 -27
- chia/_tests/cmds/wallet/test_nft.py +12 -10
- chia/_tests/cmds/wallet/test_vcs.py +11 -12
- chia/_tests/cmds/wallet/test_wallet.py +134 -89
- chia/_tests/conftest.py +66 -31
- chia/_tests/connection_utils.py +2 -2
- chia/_tests/core/cmds/test_beta.py +4 -4
- chia/_tests/core/cmds/test_keys.py +2 -3
- chia/_tests/core/cmds/test_wallet.py +15 -15
- chia/_tests/core/consensus/test_pot_iterations.py +19 -73
- chia/_tests/core/custom_types/test_proof_of_space.py +124 -98
- chia/_tests/core/daemon/test_daemon.py +11 -11
- chia/_tests/core/data_layer/conftest.py +2 -2
- chia/_tests/core/data_layer/test_data_rpc.py +28 -14
- chia/_tests/core/data_layer/test_data_store.py +10 -10
- chia/_tests/core/data_layer/util.py +11 -11
- chia/_tests/core/farmer/test_farmer_api.py +2 -4
- chia/_tests/core/full_node/full_sync/test_full_sync.py +8 -7
- chia/_tests/core/full_node/stores/test_block_store.py +5 -4
- chia/_tests/core/full_node/stores/test_coin_store.py +5 -11
- chia/_tests/core/full_node/stores/test_full_node_store.py +8 -8
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/test_block_height_map.py +3 -4
- chia/_tests/core/full_node/test_conditions.py +21 -23
- chia/_tests/core/full_node/test_full_node.py +273 -70
- chia/_tests/core/full_node/test_hard_fork_utils.py +92 -0
- chia/_tests/core/full_node/test_hint_management.py +2 -4
- chia/_tests/core/full_node/test_performance.py +0 -1
- chia/_tests/core/full_node/test_prev_tx_block.py +88 -11
- chia/_tests/core/full_node/test_transactions.py +1 -2
- chia/_tests/core/full_node/test_tx_processing_queue.py +198 -30
- chia/_tests/core/mempool/test_mempool.py +54 -50
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +39 -39
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +2 -6
- chia/_tests/core/mempool/test_mempool_manager.py +988 -854
- chia/_tests/core/mempool/test_singleton_fast_forward.py +6 -6
- chia/_tests/core/server/serve.py +7 -7
- chia/_tests/core/server/test_dos.py +1 -2
- chia/_tests/core/server/test_event_loop.py +12 -4
- chia/_tests/core/server/test_loop.py +7 -8
- chia/_tests/core/server/test_rate_limits.py +9 -8
- chia/_tests/core/server/test_server.py +61 -1
- chia/_tests/core/services/test_services.py +2 -2
- chia/_tests/core/ssl/test_ssl.py +2 -2
- chia/_tests/core/test_cost_calculation.py +2 -6
- chia/_tests/core/test_farmer_harvester_rpc.py +3 -5
- chia/_tests/core/test_filter.py +0 -1
- chia/_tests/core/test_full_node_rpc.py +2 -2
- chia/_tests/core/test_merkle_set.py +1 -2
- chia/_tests/core/test_seeder.py +4 -4
- chia/_tests/core/util/test_config.py +4 -4
- chia/_tests/core/util/test_jsonify.py +2 -2
- chia/_tests/core/util/test_keychain.py +3 -3
- chia/_tests/core/util/test_lockfile.py +2 -1
- chia/_tests/core/util/test_log_exceptions.py +1 -2
- chia/_tests/core/util/test_streamable.py +17 -17
- chia/_tests/db/test_db_wrapper.py +3 -2
- chia/_tests/environments/wallet.py +14 -14
- chia/_tests/ether.py +4 -3
- chia/_tests/farmer_harvester/test_farmer.py +41 -24
- chia/_tests/farmer_harvester/test_farmer_harvester.py +50 -17
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +27 -27
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +21 -22
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +18 -18
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +11 -9
- chia/_tests/harvester/test_harvester_api.py +11 -4
- chia/_tests/plot_sync/test_plot_sync.py +13 -11
- chia/_tests/plot_sync/test_receiver.py +11 -10
- chia/_tests/plot_sync/test_sync_simulated.py +2 -2
- chia/_tests/plot_sync/util.py +1 -2
- chia/_tests/plotting/test_plot_manager.py +7 -6
- chia/_tests/plotting/test_prover.py +30 -38
- chia/_tests/pools/test_pool_cmdline.py +4 -6
- chia/_tests/pools/test_pool_rpc.py +203 -61
- chia/_tests/pools/test_pool_wallet.py +3 -3
- chia/_tests/pools/test_wallet_pool_store.py +1 -4
- chia/_tests/process_junit.py +2 -2
- chia/_tests/rpc/test_rpc_client.py +4 -4
- chia/_tests/rpc/test_rpc_server.py +3 -3
- chia/_tests/simulation/test_simulation.py +12 -25
- chia/_tests/solver/test_solver_service.py +13 -4
- chia/_tests/testconfig.py +2 -2
- chia/_tests/timelord/test_new_peak.py +22 -11
- chia/_tests/tools/test_run_block.py +0 -2
- chia/_tests/tools/test_virtual_project.py +2 -1
- chia/_tests/util/benchmarks.py +1 -0
- chia/_tests/util/blockchain.py +38 -36
- chia/_tests/util/blockchain_mock.py +11 -11
- chia/_tests/util/build_network_protocol_files.py +2 -1
- chia/_tests/util/coin_store.py +2 -1
- chia/_tests/util/config.py +1 -1
- chia/_tests/util/db_connection.py +2 -3
- chia/_tests/util/full_sync.py +9 -11
- chia/_tests/util/gen_ssl_certs.py +4 -5
- chia/_tests/util/get_name_puzzle_conditions.py +2 -0
- chia/_tests/util/misc.py +24 -24
- chia/_tests/util/network_protocol_data.py +20 -3
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +292 -3
- chia/_tests/util/setup_nodes.py +62 -47
- chia/_tests/util/spend_sim.py +57 -57
- chia/_tests/util/test_async_pool.py +2 -3
- chia/_tests/util/test_chia_version.py +1 -3
- chia/_tests/util/test_config.py +3 -3
- chia/_tests/util/test_full_block_utils.py +6 -3
- chia/_tests/util/test_limited_semaphore.py +1 -2
- chia/_tests/util/test_misc.py +2 -2
- chia/_tests/util/test_network.py +1 -2
- chia/_tests/util/test_priority_mutex.py +3 -3
- chia/_tests/util/test_recursive_replace.py +5 -6
- chia/_tests/util/test_replace_str_to_bytes.py +9 -10
- chia/_tests/util/test_testnet_overrides.py +3 -3
- chia/_tests/util/time_out_assert.py +2 -2
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +4 -6
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -4
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +19 -13
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +13 -13
- chia/_tests/wallet/cat_wallet/test_trades.py +40 -38
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -4
- chia/_tests/wallet/conftest.py +6 -6
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +1 -1
- chia/_tests/wallet/db_wallet/test_dl_offers.py +34 -34
- chia/_tests/wallet/did_wallet/test_did.py +16 -6
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +21 -21
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +20 -6
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +19 -21
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +1 -2
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +121 -2
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +6 -9
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +44 -1
- chia/_tests/wallet/rpc/test_wallet_rpc.py +1672 -896
- chia/_tests/wallet/sync/test_wallet_sync.py +63 -60
- chia/_tests/wallet/test_clvm_streamable.py +2 -3
- chia/_tests/wallet/test_coin_management.py +2 -2
- chia/_tests/wallet/test_conditions.py +45 -51
- chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
- chia/_tests/wallet/test_new_wallet_protocol.py +17 -17
- chia/_tests/wallet/test_notifications.py +14 -14
- chia/_tests/wallet/test_signer_protocol.py +5 -5
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +4 -3
- chia/_tests/wallet/test_transaction_store.py +20 -20
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +380 -228
- chia/_tests/wallet/test_wallet_action_scope.py +4 -4
- chia/_tests/wallet/test_wallet_blockchain.py +12 -12
- chia/_tests/wallet/test_wallet_coin_store.py +3 -4
- chia/_tests/wallet/test_wallet_node.py +16 -15
- chia/_tests/wallet/test_wallet_test_framework.py +2 -1
- chia/_tests/wallet/test_wallet_utils.py +2 -3
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -5
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +14 -15
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -24
- chia/_tests/wallet/wallet_block_tools.py +12 -11
- chia/_tests/weight_proof/config.py +1 -0
- chia/_tests/weight_proof/test_weight_proof.py +5 -4
- chia/apis/__init__.py +21 -0
- chia/apis/farmer_stub.py +102 -0
- chia/apis/full_node_stub.py +374 -0
- chia/apis/harvester_stub.py +57 -0
- chia/apis/introducer_stub.py +35 -0
- chia/apis/solver_stub.py +30 -0
- chia/apis/stub_protocol_registry.py +21 -0
- chia/apis/timelord_stub.py +39 -0
- chia/apis/wallet_stub.py +161 -0
- chia/cmds/beta.py +3 -4
- chia/cmds/beta_funcs.py +4 -3
- chia/cmds/check_wallet_db.py +4 -4
- chia/cmds/chia.py +1 -2
- chia/cmds/cmd_classes.py +11 -13
- chia/cmds/cmd_helpers.py +11 -11
- chia/cmds/cmds_util.py +15 -15
- chia/cmds/coin_funcs.py +6 -7
- chia/cmds/coins.py +2 -3
- chia/cmds/configure.py +1 -2
- chia/cmds/data.py +42 -42
- chia/cmds/data_funcs.py +81 -81
- chia/cmds/db.py +4 -5
- 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/data.py +4 -4
- chia/cmds/dev/gh.py +5 -5
- chia/cmds/dev/installers.py +2 -3
- chia/cmds/dev/mempool.py +3 -4
- chia/cmds/dev/mempool_funcs.py +4 -4
- chia/cmds/dev/sim.py +8 -8
- chia/cmds/dump_keyring.py +3 -3
- chia/cmds/farm.py +6 -8
- chia/cmds/farm_funcs.py +25 -24
- chia/cmds/init_funcs.py +4 -4
- chia/cmds/keys.py +16 -18
- chia/cmds/keys_funcs.py +36 -36
- chia/cmds/netspace.py +1 -3
- chia/cmds/netspace_funcs.py +1 -2
- chia/cmds/options.py +3 -2
- chia/cmds/param_types.py +17 -16
- chia/cmds/passphrase.py +6 -7
- chia/cmds/passphrase_funcs.py +11 -13
- chia/cmds/peer.py +1 -3
- chia/cmds/peer_funcs.py +3 -3
- chia/cmds/plotnft.py +6 -7
- chia/cmds/plotnft_funcs.py +37 -26
- chia/cmds/rpc.py +3 -3
- chia/cmds/show.py +3 -5
- chia/cmds/show_funcs.py +9 -9
- chia/cmds/sim_funcs.py +25 -26
- chia/cmds/solver.py +1 -3
- chia/cmds/solver_funcs.py +1 -2
- chia/cmds/start_funcs.py +2 -2
- chia/cmds/wallet.py +76 -81
- chia/cmds/wallet_funcs.py +206 -177
- chia/consensus/augmented_chain.py +6 -6
- chia/consensus/block_body_validation.py +19 -15
- chia/consensus/block_creation.py +25 -21
- chia/consensus/block_header_validation.py +27 -13
- chia/consensus/block_height_map.py +3 -6
- chia/consensus/block_height_map_protocol.py +2 -2
- chia/consensus/block_record.py +2 -4
- chia/consensus/blockchain.py +58 -40
- chia/consensus/blockchain_interface.py +7 -7
- chia/consensus/coin_store_protocol.py +5 -6
- chia/consensus/condition_tools.py +4 -4
- chia/consensus/cost_calculator.py +2 -3
- chia/consensus/default_constants.py +19 -13
- chia/consensus/deficit.py +1 -3
- chia/consensus/difficulty_adjustment.py +3 -5
- chia/consensus/find_fork_point.py +2 -4
- chia/consensus/full_block_to_block_record.py +11 -13
- chia/consensus/generator_tools.py +2 -3
- chia/consensus/get_block_challenge.py +50 -26
- chia/consensus/get_block_generator.py +2 -3
- chia/consensus/make_sub_epoch_summary.py +8 -7
- chia/consensus/multiprocess_validation.py +31 -20
- chia/consensus/pos_quality.py +6 -23
- chia/consensus/pot_iterations.py +17 -44
- chia/consensus/signage_point.py +4 -5
- chia/consensus/vdf_info_computation.py +2 -4
- chia/daemon/client.py +8 -8
- chia/daemon/keychain_proxy.py +31 -37
- chia/daemon/server.py +32 -33
- chia/daemon/windows_signal.py +4 -3
- chia/data_layer/data_layer.py +86 -77
- chia/data_layer/data_layer_rpc_api.py +9 -9
- chia/data_layer/data_layer_rpc_client.py +13 -15
- chia/data_layer/data_layer_server.py +3 -3
- chia/data_layer/data_layer_util.py +14 -14
- chia/data_layer/data_layer_wallet.py +94 -101
- chia/data_layer/data_store.py +50 -50
- chia/data_layer/dl_wallet_store.py +9 -12
- chia/data_layer/download_data.py +8 -9
- chia/data_layer/s3_plugin_service.py +5 -9
- chia/data_layer/start_data_layer.py +5 -5
- chia/farmer/farmer.py +31 -31
- chia/farmer/farmer_api.py +45 -33
- chia/farmer/farmer_rpc_api.py +5 -4
- chia/farmer/farmer_rpc_client.py +6 -6
- chia/farmer/start_farmer.py +6 -6
- chia/full_node/block_store.py +13 -16
- chia/full_node/check_fork_next_block.py +1 -2
- chia/full_node/coin_store.py +15 -16
- chia/full_node/eligible_coin_spends.py +3 -3
- chia/full_node/fee_estimate_store.py +2 -3
- chia/full_node/fee_tracker.py +1 -2
- chia/full_node/full_block_utils.py +4 -4
- chia/full_node/full_node.py +239 -223
- chia/full_node/full_node_api.py +197 -152
- chia/full_node/full_node_rpc_api.py +34 -32
- chia/full_node/full_node_rpc_client.py +18 -19
- chia/full_node/full_node_store.py +45 -43
- chia/full_node/hard_fork_utils.py +44 -0
- chia/full_node/hint_management.py +2 -2
- chia/full_node/mempool.py +17 -19
- chia/full_node/mempool_manager.py +89 -42
- chia/full_node/pending_tx_cache.py +2 -3
- chia/full_node/start_full_node.py +5 -5
- chia/full_node/sync_store.py +3 -4
- chia/full_node/tx_processing_queue.py +120 -36
- chia/full_node/weight_proof.py +61 -48
- chia/harvester/harvester.py +25 -24
- chia/harvester/harvester_api.py +61 -38
- chia/harvester/harvester_rpc_api.py +10 -10
- chia/harvester/start_harvester.py +4 -4
- chia/introducer/introducer.py +3 -3
- chia/introducer/introducer_api.py +6 -4
- chia/introducer/start_introducer.py +4 -4
- chia/legacy/keyring.py +3 -3
- chia/plot_sync/delta.py +1 -2
- chia/plot_sync/receiver.py +20 -17
- chia/plot_sync/sender.py +15 -10
- chia/plotters/bladebit.py +7 -7
- chia/plotters/chiapos.py +2 -2
- chia/plotters/madmax.py +4 -4
- chia/plotters/plotters.py +4 -4
- chia/plotters/plotters_util.py +3 -3
- chia/plotting/cache.py +20 -14
- chia/plotting/check_plots.py +26 -35
- chia/plotting/create_plots.py +22 -23
- chia/plotting/manager.py +21 -14
- chia/plotting/prover.py +59 -42
- chia/plotting/util.py +16 -16
- chia/pools/pool_config.py +2 -1
- chia/pools/pool_puzzles.py +11 -12
- chia/pools/pool_wallet.py +34 -57
- chia/pools/pool_wallet_info.py +39 -10
- chia/protocols/farmer_protocol.py +8 -9
- chia/protocols/fee_estimate.py +3 -4
- chia/protocols/full_node_protocol.py +3 -4
- chia/protocols/harvester_protocol.py +27 -15
- chia/protocols/outbound_message.py +3 -3
- chia/protocols/pool_protocol.py +8 -9
- chia/protocols/shared_protocol.py +1 -2
- chia/protocols/solver_protocol.py +9 -2
- chia/protocols/timelord_protocol.py +4 -7
- chia/protocols/wallet_protocol.py +11 -12
- chia/rpc/rpc_client.py +9 -9
- chia/rpc/rpc_server.py +17 -17
- chia/rpc/util.py +2 -2
- chia/seeder/crawler.py +8 -8
- chia/seeder/crawler_api.py +21 -27
- chia/seeder/crawler_rpc_api.py +2 -2
- chia/seeder/dns_server.py +21 -21
- chia/seeder/start_crawler.py +4 -4
- chia/server/address_manager.py +15 -16
- chia/server/api_protocol.py +11 -11
- chia/server/chia_policy.py +46 -26
- chia/server/introducer_peers.py +2 -3
- chia/server/node_discovery.py +19 -19
- chia/server/rate_limit_numbers.py +4 -5
- chia/server/rate_limits.py +4 -4
- chia/server/resolve_peer_info.py +4 -4
- chia/server/server.py +49 -52
- chia/server/signal_handlers.py +6 -6
- chia/server/start_service.py +17 -17
- chia/server/upnp.py +4 -6
- chia/server/ws_connection.py +52 -37
- chia/simulator/add_blocks_in_batches.py +1 -3
- chia/simulator/block_tools.py +312 -200
- chia/simulator/full_node_simulator.py +56 -35
- chia/simulator/keyring.py +2 -3
- chia/simulator/setup_services.py +15 -15
- chia/simulator/simulator_full_node_rpc_api.py +1 -2
- chia/simulator/simulator_full_node_rpc_client.py +1 -2
- chia/simulator/simulator_protocol.py +1 -2
- chia/simulator/simulator_test_tools.py +3 -3
- chia/simulator/start_simulator.py +7 -7
- chia/simulator/wallet_tools.py +10 -10
- chia/solver/solver.py +10 -10
- chia/solver/solver_api.py +10 -8
- chia/solver/solver_rpc_api.py +2 -2
- chia/solver/start_solver.py +4 -4
- chia/ssl/cacert.pem +148 -90
- chia/ssl/chia_ca.crt +14 -10
- chia/ssl/chia_ca_old.crt +19 -0
- chia/ssl/create_ssl.py +4 -4
- chia/ssl/renewedselfsignedca.conf +4 -0
- chia/ssl/ssl_check.py +1 -2
- chia/timelord/iters_from_block.py +1 -4
- chia/timelord/start_timelord.py +4 -4
- chia/timelord/timelord.py +44 -40
- chia/timelord/timelord_api.py +6 -4
- chia/timelord/timelord_launcher.py +2 -2
- chia/timelord/timelord_rpc_api.py +2 -2
- chia/timelord/timelord_state.py +11 -12
- chia/types/block_protocol.py +1 -3
- chia/types/blockchain_format/coin.py +1 -3
- chia/types/blockchain_format/program.py +11 -8
- chia/types/blockchain_format/proof_of_space.py +123 -76
- chia/types/blockchain_format/tree_hash.py +3 -3
- chia/types/blockchain_format/vdf.py +1 -2
- chia/types/coin_spend.py +3 -3
- chia/types/mempool_item.py +5 -5
- chia/types/mempool_submission_status.py +2 -3
- chia/types/peer_info.py +1 -2
- chia/types/unfinished_header_block.py +3 -4
- chia/types/validation_state.py +1 -2
- chia/util/action_scope.py +8 -8
- chia/util/async_pool.py +5 -5
- chia/util/bech32m.py +1 -2
- chia/util/beta_metrics.py +2 -2
- chia/util/block_cache.py +4 -4
- chia/util/chia_logging.py +2 -2
- chia/util/chia_version.py +1 -2
- chia/util/config.py +15 -16
- chia/util/db_wrapper.py +26 -27
- chia/util/default_root.py +1 -2
- chia/util/errors.py +3 -3
- chia/util/file_keyring.py +14 -14
- chia/util/files.py +2 -3
- chia/util/hash.py +4 -4
- chia/util/initial-config.yaml +4 -5
- chia/util/inline_executor.py +2 -1
- chia/util/ip_address.py +1 -2
- chia/util/keychain.py +25 -27
- chia/util/keyring_wrapper.py +18 -19
- chia/util/lock.py +3 -4
- chia/util/log_exceptions.py +1 -2
- chia/util/lru_cache.py +2 -2
- chia/util/network.py +6 -6
- chia/util/path.py +2 -3
- chia/util/priority_mutex.py +2 -2
- chia/util/profiler.py +1 -2
- chia/util/safe_cancel_task.py +1 -2
- chia/util/streamable.py +24 -10
- chia/util/task_referencer.py +1 -1
- chia/util/timing.py +3 -3
- chia/util/virtual_project_analysis.py +6 -5
- chia/util/ws_message.py +2 -2
- chia/wallet/cat_wallet/cat_info.py +3 -4
- chia/wallet/cat_wallet/cat_outer_puzzle.py +12 -11
- chia/wallet/cat_wallet/cat_utils.py +3 -4
- chia/wallet/cat_wallet/cat_wallet.py +61 -83
- chia/wallet/cat_wallet/lineage_store.py +3 -4
- chia/wallet/cat_wallet/r_cat_wallet.py +19 -22
- chia/wallet/coin_selection.py +9 -10
- chia/wallet/conditions.py +142 -106
- chia/wallet/db_wallet/db_wallet_puzzles.py +4 -5
- chia/wallet/derivation_record.py +1 -2
- chia/wallet/derive_keys.py +2 -4
- chia/wallet/did_wallet/did_info.py +10 -11
- chia/wallet/did_wallet/did_wallet.py +36 -82
- chia/wallet/did_wallet/did_wallet_puzzles.py +7 -8
- chia/wallet/driver_protocol.py +5 -7
- chia/wallet/lineage_proof.py +4 -4
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +11 -11
- chia/wallet/nft_wallet/nft_info.py +8 -9
- chia/wallet/nft_wallet/nft_puzzle_utils.py +8 -8
- chia/wallet/nft_wallet/nft_wallet.py +79 -116
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +14 -14
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +12 -11
- chia/wallet/nft_wallet/transfer_program_puzzle.py +11 -11
- chia/wallet/nft_wallet/uncurry_nft.py +10 -11
- chia/wallet/notification_manager.py +3 -3
- chia/wallet/notification_store.py +44 -61
- chia/wallet/outer_puzzles.py +6 -7
- chia/wallet/puzzle_drivers.py +34 -6
- chia/wallet/puzzles/clawback/drivers.py +6 -6
- chia/wallet/puzzles/deployed_puzzle_hashes.json +1 -54
- chia/wallet/puzzles/load_clvm.py +1 -1
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -2
- chia/wallet/puzzles/singleton_top_layer.py +2 -3
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +3 -4
- chia/wallet/puzzles/tails.py +3 -3
- chia/wallet/singleton.py +5 -7
- chia/wallet/singleton_record.py +3 -3
- chia/wallet/start_wallet.py +5 -5
- chia/wallet/trade_manager.py +37 -58
- chia/wallet/trade_record.py +4 -4
- chia/wallet/trading/offer.py +59 -46
- chia/wallet/trading/trade_store.py +8 -9
- chia/wallet/transaction_record.py +8 -8
- chia/wallet/uncurried_puzzle.py +1 -2
- chia/wallet/util/clvm_streamable.py +12 -12
- chia/wallet/util/compute_hints.py +4 -5
- chia/wallet/util/curry_and_treehash.py +1 -2
- chia/wallet/util/merkle_tree.py +2 -3
- chia/wallet/util/peer_request_cache.py +8 -8
- chia/wallet/util/signing.py +85 -0
- chia/wallet/util/tx_config.py +15 -6
- chia/wallet/util/wallet_sync_utils.py +14 -16
- chia/wallet/util/wallet_types.py +2 -2
- chia/wallet/vc_wallet/cr_cat_drivers.py +10 -11
- chia/wallet/vc_wallet/cr_cat_wallet.py +50 -68
- chia/wallet/vc_wallet/cr_outer_puzzle.py +14 -13
- chia/wallet/vc_wallet/vc_drivers.py +27 -27
- chia/wallet/vc_wallet/vc_store.py +5 -6
- chia/wallet/vc_wallet/vc_wallet.py +33 -61
- chia/wallet/wallet.py +50 -78
- chia/wallet/wallet_action_scope.py +11 -11
- chia/wallet/wallet_blockchain.py +12 -12
- chia/wallet/wallet_coin_record.py +12 -6
- chia/wallet/wallet_coin_store.py +24 -25
- chia/wallet/wallet_interested_store.py +3 -5
- chia/wallet/wallet_nft_store.py +10 -11
- chia/wallet/wallet_node.py +53 -61
- chia/wallet/wallet_node_api.py +5 -3
- chia/wallet/wallet_protocol.py +23 -23
- chia/wallet/wallet_puzzle_store.py +15 -18
- chia/wallet/wallet_request_types.py +778 -114
- chia/wallet/wallet_retry_store.py +1 -3
- chia/wallet/wallet_rpc_api.py +572 -909
- chia/wallet/wallet_rpc_client.py +87 -279
- chia/wallet/wallet_singleton_store.py +3 -4
- chia/wallet/wallet_state_manager.py +332 -106
- chia/wallet/wallet_transaction_store.py +11 -14
- chia/wallet/wallet_user_store.py +4 -6
- chia/wallet/wallet_weight_proof_handler.py +4 -4
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/METADATA +6 -5
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/RECORD +510 -517
- chia/apis.py +0 -21
- chia/consensus/check_time_locks.py +0 -57
- chia/data_layer/puzzles/__init__.py +0 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp +0 -100
- chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +0 -1
- chia/types/coin_record.py +0 -44
- chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +0 -6
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +0 -6
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +0 -30
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +0 -28
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +0 -100
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +0 -78
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +0 -74
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +0 -1
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/entry_points.txt +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from chia_rs import BlockRecord, get_flags_for_height_and_constants
|
|
5
|
+
from chia_rs.sized_bytes import bytes32
|
|
6
|
+
from chia_rs.sized_ints import uint32
|
|
7
|
+
|
|
8
|
+
from chia.consensus.get_block_challenge import pre_sp_tx_block_height
|
|
9
|
+
from chia.full_node.hard_fork_utils import get_flags
|
|
10
|
+
from chia.simulator.block_tools import BlockTools, load_block_list, test_constants
|
|
11
|
+
from chia.util.block_cache import BlockCache
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MockBlocksProtocol(BlockCache):
|
|
15
|
+
"""Mock implementation of BlocksProtocol for testing get_flags."""
|
|
16
|
+
|
|
17
|
+
async def get_block_record_from_db(self, header_hash: bytes32) -> BlockRecord | None:
|
|
18
|
+
return self.try_block_record(header_hash)
|
|
19
|
+
|
|
20
|
+
async def lookup_block_generators(self, header_hash: bytes32, generator_refs: set[uint32]) -> dict[uint32, bytes]:
|
|
21
|
+
return {}
|
|
22
|
+
|
|
23
|
+
def add_block_record(self, block_record: BlockRecord) -> None:
|
|
24
|
+
self.add_block(block_record)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@pytest.mark.anyio
|
|
28
|
+
async def test_get_flags_outside_transition_period(bt: BlockTools) -> None:
|
|
29
|
+
"""Test get_flags when block is outside the transition period."""
|
|
30
|
+
block_list = bt.get_consecutive_blocks(
|
|
31
|
+
10,
|
|
32
|
+
block_list_input=[],
|
|
33
|
+
guarantee_transaction_block=True,
|
|
34
|
+
)
|
|
35
|
+
_, _, blocks = load_block_list(block_list, bt.constants)
|
|
36
|
+
block = block_list[-1]
|
|
37
|
+
mock_blocks = MockBlocksProtocol(blocks)
|
|
38
|
+
|
|
39
|
+
# Before hard fork: block.height < HARD_FORK2_HEIGHT, expects 0
|
|
40
|
+
constants = test_constants.replace(HARD_FORK2_HEIGHT=uint32(1000))
|
|
41
|
+
assert block.height < constants.HARD_FORK2_HEIGHT
|
|
42
|
+
result = await get_flags(constants, mock_blocks, block)
|
|
43
|
+
assert result == 0
|
|
44
|
+
|
|
45
|
+
# After transition period: block.height >= HARD_FORK2_HEIGHT + SUB_EPOCH_BLOCKS
|
|
46
|
+
constants = test_constants.replace(
|
|
47
|
+
HARD_FORK2_HEIGHT=uint32(0),
|
|
48
|
+
SUB_EPOCH_BLOCKS=uint32(min(5, block.height)),
|
|
49
|
+
)
|
|
50
|
+
assert block.height >= constants.HARD_FORK2_HEIGHT + constants.SUB_EPOCH_BLOCKS
|
|
51
|
+
result = await get_flags(constants, mock_blocks, block)
|
|
52
|
+
assert result == get_flags_for_height_and_constants(block.height, constants)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@pytest.mark.anyio
|
|
56
|
+
async def test_get_flags_during_transition_period(bt: BlockTools) -> None:
|
|
57
|
+
"""When block.height is in the transition period, get_flags should walk
|
|
58
|
+
the chain and return flags based on the latest tx block before signage point."""
|
|
59
|
+
# We need more blocks to ensure we're in the transition period
|
|
60
|
+
block_list = bt.get_consecutive_blocks(
|
|
61
|
+
15,
|
|
62
|
+
block_list_input=[],
|
|
63
|
+
guarantee_transaction_block=True,
|
|
64
|
+
)
|
|
65
|
+
_, _, blocks = load_block_list(block_list, bt.constants)
|
|
66
|
+
mock_blocks = MockBlocksProtocol(blocks)
|
|
67
|
+
|
|
68
|
+
# Configure constants so that the block is in the transition period
|
|
69
|
+
# HARD_FORK2_HEIGHT <= block.height < HARD_FORK2_HEIGHT + SUB_EPOCH_BLOCKS
|
|
70
|
+
block = block_list[-1]
|
|
71
|
+
# Set HARD_FORK2_HEIGHT to be close to block height but leave room for transition
|
|
72
|
+
constants = test_constants.replace(
|
|
73
|
+
HARD_FORK2_HEIGHT=uint32(max(0, block.height - 5)),
|
|
74
|
+
SUB_EPOCH_BLOCKS=test_constants.SUB_EPOCH_BLOCKS,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Ensure we're in the transition period
|
|
78
|
+
assert block.height >= constants.HARD_FORK2_HEIGHT
|
|
79
|
+
assert block.height < constants.HARD_FORK2_HEIGHT + constants.SUB_EPOCH_BLOCKS
|
|
80
|
+
|
|
81
|
+
result = await get_flags(constants, mock_blocks, block)
|
|
82
|
+
|
|
83
|
+
# The result should be based on the height of the latest tx block before the signage point
|
|
84
|
+
expected_height = pre_sp_tx_block_height(
|
|
85
|
+
constants=constants,
|
|
86
|
+
blocks=mock_blocks,
|
|
87
|
+
prev_b_hash=block.prev_header_hash,
|
|
88
|
+
sp_index=block.reward_chain_block.signage_point_index,
|
|
89
|
+
finished_sub_slots=len(block.finished_sub_slots),
|
|
90
|
+
)
|
|
91
|
+
expected = get_flags_for_height_and_constants(expected_height, constants)
|
|
92
|
+
assert result == expected
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
3
|
import pytest
|
|
6
4
|
from chia_rs import BlockRecord
|
|
7
5
|
from chia_rs.sized_bytes import bytes32
|
|
@@ -38,7 +36,7 @@ async def test_hints_to_add(bt: BlockTools, empty_blockchain: Blockchain) -> Non
|
|
|
38
36
|
blocks = bt.get_consecutive_blocks(2)
|
|
39
37
|
await _validate_and_add_block(empty_blockchain, blocks[0])
|
|
40
38
|
await _validate_and_add_block(empty_blockchain, blocks[1])
|
|
41
|
-
br:
|
|
39
|
+
br: BlockRecord | None = empty_blockchain.get_peak()
|
|
42
40
|
assert br is not None
|
|
43
41
|
|
|
44
42
|
scs = StateChangeSummary(br, uint32(0), [], removals, additions, [])
|
|
@@ -56,7 +54,7 @@ async def test_lookup_coin_ids(bt: BlockTools, empty_blockchain: Blockchain) ->
|
|
|
56
54
|
blocks = bt.get_consecutive_blocks(2)
|
|
57
55
|
await _validate_and_add_block(empty_blockchain, blocks[0])
|
|
58
56
|
await _validate_and_add_block(empty_blockchain, blocks[1])
|
|
59
|
-
br:
|
|
57
|
+
br: BlockRecord | None = empty_blockchain.get_peak()
|
|
60
58
|
assert br is not None
|
|
61
59
|
|
|
62
60
|
rewards: list[Coin] = [
|
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from chia_rs
|
|
3
|
+
from chia_rs import FullBlock
|
|
4
|
+
from chia_rs.sized_ints import uint8, uint32
|
|
4
5
|
|
|
5
|
-
from chia.consensus.
|
|
6
|
-
from chia.
|
|
7
|
-
from chia.simulator.block_tools import BlockTools, load_block_list
|
|
6
|
+
from chia.consensus.get_block_challenge import pre_sp_tx_block_height
|
|
7
|
+
from chia.simulator.block_tools import BlockTools, load_block_list, test_constants
|
|
8
8
|
from chia.util.block_cache import BlockCache
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def test_prev_tx_block_none() -> None:
|
|
12
12
|
# If prev_b is None, should return 0
|
|
13
|
-
assert
|
|
13
|
+
assert pre_sp_tx_block_height(
|
|
14
|
+
constants=test_constants,
|
|
15
|
+
blocks=BlockCache({}),
|
|
16
|
+
prev_b_hash=test_constants.GENESIS_CHALLENGE,
|
|
17
|
+
sp_index=uint8(0),
|
|
18
|
+
finished_sub_slots=0,
|
|
19
|
+
) == uint32(0)
|
|
20
|
+
assert pre_sp_tx_block_height(
|
|
21
|
+
constants=test_constants,
|
|
22
|
+
blocks=BlockCache({}),
|
|
23
|
+
prev_b_hash=test_constants.GENESIS_CHALLENGE,
|
|
24
|
+
sp_index=uint8(1),
|
|
25
|
+
finished_sub_slots=1,
|
|
26
|
+
) == uint32(0)
|
|
14
27
|
|
|
15
28
|
|
|
16
29
|
def test_prev_tx_block_blockrecord_tx(bt: BlockTools) -> None:
|
|
@@ -21,9 +34,45 @@ def test_prev_tx_block_blockrecord_tx(bt: BlockTools) -> None:
|
|
|
21
34
|
guarantee_transaction_block=True,
|
|
22
35
|
)
|
|
23
36
|
_, _, blocks = load_block_list(block_list, bt.constants)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
assert
|
|
37
|
+
block = block_list[-1]
|
|
38
|
+
latest_tx_before_sp = find_tx_before_sp(block_list)
|
|
39
|
+
assert latest_tx_before_sp is not None
|
|
40
|
+
assert (
|
|
41
|
+
pre_sp_tx_block_height(
|
|
42
|
+
constants=test_constants,
|
|
43
|
+
blocks=BlockCache(blocks),
|
|
44
|
+
prev_b_hash=block.prev_header_hash,
|
|
45
|
+
sp_index=block.reward_chain_block.signage_point_index,
|
|
46
|
+
finished_sub_slots=len(block.finished_sub_slots),
|
|
47
|
+
)
|
|
48
|
+
== latest_tx_before_sp.height
|
|
49
|
+
)
|
|
50
|
+
block = block_list[-2]
|
|
51
|
+
latest_tx_before_sp = find_tx_before_sp(block_list[:-1])
|
|
52
|
+
assert latest_tx_before_sp is not None
|
|
53
|
+
assert (
|
|
54
|
+
pre_sp_tx_block_height(
|
|
55
|
+
constants=test_constants,
|
|
56
|
+
blocks=BlockCache(blocks),
|
|
57
|
+
prev_b_hash=block.prev_header_hash,
|
|
58
|
+
sp_index=block.reward_chain_block.signage_point_index,
|
|
59
|
+
finished_sub_slots=len(block.finished_sub_slots),
|
|
60
|
+
)
|
|
61
|
+
== latest_tx_before_sp.height
|
|
62
|
+
)
|
|
63
|
+
block = block_list[-3]
|
|
64
|
+
latest_tx_before_sp = find_tx_before_sp(block_list[:-2])
|
|
65
|
+
assert latest_tx_before_sp is not None
|
|
66
|
+
assert (
|
|
67
|
+
pre_sp_tx_block_height(
|
|
68
|
+
constants=test_constants,
|
|
69
|
+
blocks=BlockCache(blocks),
|
|
70
|
+
prev_b_hash=block.prev_header_hash,
|
|
71
|
+
sp_index=block.reward_chain_block.signage_point_index,
|
|
72
|
+
finished_sub_slots=len(block.finished_sub_slots),
|
|
73
|
+
)
|
|
74
|
+
== latest_tx_before_sp.height
|
|
75
|
+
)
|
|
27
76
|
|
|
28
77
|
|
|
29
78
|
def test_prev_tx_block_blockrecord_not_tx(bt: BlockTools) -> None:
|
|
@@ -38,6 +87,34 @@ def test_prev_tx_block_blockrecord_not_tx(bt: BlockTools) -> None:
|
|
|
38
87
|
block_list_input=block_list,
|
|
39
88
|
)
|
|
40
89
|
_, _, blocks = load_block_list(block_list, bt.constants)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
assert
|
|
90
|
+
block = block_list[-1]
|
|
91
|
+
latest_tx_before_sp = find_tx_before_sp(block_list)
|
|
92
|
+
assert latest_tx_before_sp is not None
|
|
93
|
+
assert pre_sp_tx_block_height(
|
|
94
|
+
constants=test_constants,
|
|
95
|
+
blocks=BlockCache(blocks),
|
|
96
|
+
prev_b_hash=block.prev_header_hash,
|
|
97
|
+
sp_index=block.reward_chain_block.signage_point_index,
|
|
98
|
+
finished_sub_slots=len(block.finished_sub_slots),
|
|
99
|
+
) == uint32(latest_tx_before_sp.height)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# get the latest infused transaction block before the signage point of the last block in the list
|
|
103
|
+
def find_tx_before_sp(block_list: list[FullBlock]) -> FullBlock | None:
|
|
104
|
+
before_slot = False
|
|
105
|
+
before_sp = False
|
|
106
|
+
if len(block_list[-1].finished_sub_slots) > 0:
|
|
107
|
+
before_slot = True
|
|
108
|
+
sp_index = block_list[-1].reward_chain_block.signage_point_index
|
|
109
|
+
idx = len(block_list) - 2
|
|
110
|
+
curr = None
|
|
111
|
+
while idx > 0:
|
|
112
|
+
curr = block_list[idx]
|
|
113
|
+
if curr.reward_chain_block.signage_point_index < sp_index:
|
|
114
|
+
before_sp = True
|
|
115
|
+
if curr.foliage_transaction_block is not None and (before_slot or before_sp):
|
|
116
|
+
break
|
|
117
|
+
if len(curr.finished_sub_slots) > 0:
|
|
118
|
+
before_slot = True
|
|
119
|
+
idx -= 1
|
|
120
|
+
return curr
|
|
@@ -2,7 +2,6 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import random
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
import pytest
|
|
8
7
|
from chia_rs import BlockRecord
|
|
@@ -77,7 +76,7 @@ async def test_tx_propagation(three_nodes_two_wallets, self_hostname, seeded_ran
|
|
|
77
76
|
await time_out_assert(20, wallet_0.wallet_state_manager.main_wallet.get_confirmed_balance, funds)
|
|
78
77
|
|
|
79
78
|
async def peak_height(fna: FullNodeAPI):
|
|
80
|
-
peak:
|
|
79
|
+
peak: BlockRecord | None = fna.full_node.blockchain.get_peak()
|
|
81
80
|
if peak is None:
|
|
82
81
|
return -1
|
|
83
82
|
peak_height = peak.height
|
|
@@ -2,35 +2,46 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
|
+
import math
|
|
5
6
|
import random
|
|
6
|
-
from dataclasses import dataclass
|
|
7
|
-
from typing import
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from typing import cast
|
|
8
9
|
|
|
9
10
|
import pytest
|
|
11
|
+
from chia_rs import G2Element, SpendBundle
|
|
10
12
|
from chia_rs.sized_bytes import bytes32
|
|
13
|
+
from chia_rs.sized_ints import uint64
|
|
11
14
|
|
|
12
|
-
from chia.full_node.tx_processing_queue import TransactionQueue, TransactionQueueEntry, TransactionQueueFull
|
|
15
|
+
from chia.full_node.tx_processing_queue import PeerWithTx, TransactionQueue, TransactionQueueEntry, TransactionQueueFull
|
|
16
|
+
from chia.simulator.block_tools import test_constants
|
|
13
17
|
from chia.util.task_referencer import create_referenced_task
|
|
14
18
|
|
|
15
19
|
log = logging.getLogger(__name__)
|
|
16
20
|
|
|
21
|
+
TEST_MAX_TX_CLVM_COST = uint64(test_constants.MAX_BLOCK_COST_CLVM // 2)
|
|
22
|
+
|
|
17
23
|
|
|
18
24
|
@dataclass(frozen=True)
|
|
19
25
|
class FakeTransactionQueueEntry:
|
|
20
|
-
index: int
|
|
21
|
-
peer_id:
|
|
26
|
+
index: int = field(compare=False)
|
|
27
|
+
peer_id: bytes32 | None = field(compare=False)
|
|
28
|
+
peers_with_tx: dict[bytes32, PeerWithTx] | None = field(compare=False)
|
|
22
29
|
|
|
23
30
|
|
|
24
|
-
def get_transaction_queue_entry(
|
|
25
|
-
|
|
31
|
+
def get_transaction_queue_entry(
|
|
32
|
+
peer_id: bytes32 | None, tx_index: int, peers_with_tx: dict[bytes32, PeerWithTx] | None = None
|
|
33
|
+
) -> TransactionQueueEntry: # easy shortcut
|
|
34
|
+
if peers_with_tx is None:
|
|
35
|
+
peers_with_tx = {}
|
|
36
|
+
return cast(TransactionQueueEntry, FakeTransactionQueueEntry(tx_index, peer_id, peers_with_tx))
|
|
26
37
|
|
|
27
38
|
|
|
28
39
|
@pytest.mark.anyio
|
|
29
40
|
async def test_local_txs(seeded_random: random.Random) -> None:
|
|
30
|
-
transaction_queue = TransactionQueue(1000, log)
|
|
41
|
+
transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
|
|
31
42
|
# test 1 tx
|
|
32
43
|
first_tx = get_transaction_queue_entry(None, 0)
|
|
33
|
-
|
|
44
|
+
transaction_queue.put(first_tx, None)
|
|
34
45
|
|
|
35
46
|
result1 = await transaction_queue.pop()
|
|
36
47
|
|
|
@@ -40,7 +51,7 @@ async def test_local_txs(seeded_random: random.Random) -> None:
|
|
|
40
51
|
num_txs = 2000
|
|
41
52
|
list_txs = [get_transaction_queue_entry(bytes32.random(seeded_random), i) for i in range(num_txs)]
|
|
42
53
|
for tx in list_txs:
|
|
43
|
-
|
|
54
|
+
transaction_queue.put(tx, None)
|
|
44
55
|
|
|
45
56
|
resulting_txs = []
|
|
46
57
|
for _ in range(num_txs):
|
|
@@ -52,18 +63,18 @@ async def test_local_txs(seeded_random: random.Random) -> None:
|
|
|
52
63
|
|
|
53
64
|
@pytest.mark.anyio
|
|
54
65
|
async def test_one_peer_and_await(seeded_random: random.Random) -> None:
|
|
55
|
-
transaction_queue = TransactionQueue(1000, log)
|
|
66
|
+
transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
|
|
56
67
|
num_txs = 100
|
|
57
68
|
peer_id = bytes32.random(seeded_random)
|
|
58
69
|
|
|
59
70
|
list_txs = [get_transaction_queue_entry(peer_id, i) for i in range(num_txs)]
|
|
60
71
|
for tx in list_txs:
|
|
61
|
-
|
|
72
|
+
transaction_queue.put(tx, peer_id)
|
|
62
73
|
|
|
63
74
|
# test transaction priority
|
|
64
75
|
local_txs = [get_transaction_queue_entry(None, i) for i in range(int(num_txs / 5))] # 20 txs
|
|
65
76
|
for tx in local_txs:
|
|
66
|
-
|
|
77
|
+
transaction_queue.put(tx, None)
|
|
67
78
|
|
|
68
79
|
resulting_txs = []
|
|
69
80
|
for _ in range(num_txs + len(local_txs)):
|
|
@@ -80,13 +91,13 @@ async def test_one_peer_and_await(seeded_random: random.Random) -> None:
|
|
|
80
91
|
with pytest.raises(asyncio.InvalidStateError): # task is not done, so we expect an error when getting result
|
|
81
92
|
task.result()
|
|
82
93
|
# add a tx to test task completion
|
|
83
|
-
|
|
94
|
+
transaction_queue.put(get_transaction_queue_entry(None, 0), None)
|
|
84
95
|
await asyncio.wait_for(task, 1) # we should never time out here
|
|
85
96
|
|
|
86
97
|
|
|
87
98
|
@pytest.mark.anyio
|
|
88
99
|
async def test_lots_of_peers(seeded_random: random.Random) -> None:
|
|
89
|
-
transaction_queue = TransactionQueue(1000, log)
|
|
100
|
+
transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
|
|
90
101
|
num_peers = 1000
|
|
91
102
|
num_txs = 100
|
|
92
103
|
total_txs = num_txs * num_peers
|
|
@@ -95,7 +106,7 @@ async def test_lots_of_peers(seeded_random: random.Random) -> None:
|
|
|
95
106
|
# 100 txs per peer
|
|
96
107
|
list_txs = [get_transaction_queue_entry(peer_id, i) for peer_id in peer_ids for i in range(num_txs)]
|
|
97
108
|
for tx in list_txs:
|
|
98
|
-
|
|
109
|
+
transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
|
|
99
110
|
|
|
100
111
|
resulting_txs = []
|
|
101
112
|
for _ in range(total_txs):
|
|
@@ -108,7 +119,7 @@ async def test_lots_of_peers(seeded_random: random.Random) -> None:
|
|
|
108
119
|
|
|
109
120
|
@pytest.mark.anyio
|
|
110
121
|
async def test_full_queue(seeded_random: random.Random) -> None:
|
|
111
|
-
transaction_queue = TransactionQueue(1000, log)
|
|
122
|
+
transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
|
|
112
123
|
num_peers = 100
|
|
113
124
|
num_txs = 1000
|
|
114
125
|
total_txs = num_txs * num_peers
|
|
@@ -117,11 +128,11 @@ async def test_full_queue(seeded_random: random.Random) -> None:
|
|
|
117
128
|
# 999 txs per peer then 1 to fail later
|
|
118
129
|
list_txs = [get_transaction_queue_entry(peer_id, i) for peer_id in peer_ids for i in range(num_txs)]
|
|
119
130
|
for tx in list_txs:
|
|
120
|
-
|
|
131
|
+
transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
|
|
121
132
|
|
|
122
133
|
# test failure case.
|
|
123
134
|
with pytest.raises(TransactionQueueFull):
|
|
124
|
-
|
|
135
|
+
transaction_queue.put(get_transaction_queue_entry(peer_ids[0], 1001), peer_ids[0])
|
|
125
136
|
|
|
126
137
|
resulting_txs = []
|
|
127
138
|
for _ in range(total_txs):
|
|
@@ -130,25 +141,182 @@ async def test_full_queue(seeded_random: random.Random) -> None:
|
|
|
130
141
|
|
|
131
142
|
@pytest.mark.anyio
|
|
132
143
|
async def test_queue_cleanup_and_fairness(seeded_random: random.Random) -> None:
|
|
133
|
-
transaction_queue = TransactionQueue(1000, log)
|
|
144
|
+
transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
|
|
134
145
|
peer_a = bytes32.random(seeded_random)
|
|
135
146
|
peer_b = bytes32.random(seeded_random)
|
|
136
147
|
peer_c = bytes32.random(seeded_random)
|
|
137
148
|
|
|
149
|
+
higher_tx_cost = uint64(20)
|
|
150
|
+
lower_tx_cost = uint64(10)
|
|
151
|
+
higher_tx_fee = uint64(5)
|
|
152
|
+
lower_tx_fee = uint64(1)
|
|
138
153
|
# 2 for a, 1 for b, 2 for c
|
|
139
|
-
peer_tx_a = [
|
|
140
|
-
|
|
141
|
-
|
|
154
|
+
peer_tx_a = [
|
|
155
|
+
get_transaction_queue_entry(peer_a, 0, {peer_a: PeerWithTx(str(peer_a), lower_tx_fee, higher_tx_cost)}),
|
|
156
|
+
get_transaction_queue_entry(peer_a, 1, {peer_a: PeerWithTx(str(peer_a), higher_tx_fee, lower_tx_cost)}),
|
|
157
|
+
]
|
|
158
|
+
peer_tx_b = [
|
|
159
|
+
get_transaction_queue_entry(peer_b, 0, {peer_b: PeerWithTx(str(peer_b), higher_tx_fee, lower_tx_cost)})
|
|
160
|
+
]
|
|
161
|
+
peer_tx_c = [
|
|
162
|
+
get_transaction_queue_entry(peer_c, 0, {peer_c: PeerWithTx(str(peer_c), higher_tx_fee, lower_tx_cost)}),
|
|
163
|
+
get_transaction_queue_entry(peer_c, 1, {peer_c: PeerWithTx(str(peer_c), lower_tx_fee, higher_tx_cost)}),
|
|
164
|
+
]
|
|
142
165
|
|
|
143
166
|
list_txs = peer_tx_a + peer_tx_b + peer_tx_c
|
|
144
167
|
for tx in list_txs:
|
|
145
|
-
|
|
168
|
+
transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
|
|
146
169
|
|
|
147
|
-
|
|
170
|
+
entries = []
|
|
148
171
|
for _ in range(3): # we validate we get one transaction per peer
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
172
|
+
entry = await transaction_queue.pop()
|
|
173
|
+
entries.append((entry.peer_id, entry.index)) # type: ignore[attr-defined]
|
|
174
|
+
assert [(peer_a, 1), (peer_b, 0), (peer_c, 0)] == entries # all peers have been properly included in the queue.
|
|
175
|
+
second_entries = []
|
|
152
176
|
for _ in range(2): # we validate that we properly queue the last 2 transactions
|
|
153
|
-
|
|
154
|
-
|
|
177
|
+
entry = await transaction_queue.pop()
|
|
178
|
+
second_entries.append((entry.peer_id, entry.index)) # type: ignore[attr-defined]
|
|
179
|
+
assert [(peer_a, 0), (peer_c, 1)] == second_entries
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_tx_queue_entry_order_compare() -> None:
|
|
183
|
+
"""
|
|
184
|
+
Tests that `TransactionQueueEntry` orders and compares using transaction
|
|
185
|
+
IDs regardless of other fields.
|
|
186
|
+
"""
|
|
187
|
+
# Let's create two items with the same transaction ID but different data
|
|
188
|
+
sb = SpendBundle([], G2Element())
|
|
189
|
+
sb_name = sb.name()
|
|
190
|
+
item1 = TransactionQueueEntry(
|
|
191
|
+
transaction=sb, transaction_bytes=bytes(sb), spend_name=sb_name, peer=None, test=False, peers_with_tx={}
|
|
192
|
+
)
|
|
193
|
+
item2 = TransactionQueueEntry(
|
|
194
|
+
transaction=sb, transaction_bytes=None, spend_name=sb_name, peer=None, test=True, peers_with_tx={}
|
|
195
|
+
)
|
|
196
|
+
# They should be ordered and compared (considered equal) by `spend_name`
|
|
197
|
+
# regardless of other fields.
|
|
198
|
+
assert (item1 < item2) is False
|
|
199
|
+
assert item1 == item2
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@pytest.mark.anyio
|
|
203
|
+
async def test_peer_queue_prioritization_fallback() -> None:
|
|
204
|
+
"""
|
|
205
|
+
Tests prioritization fallback, when `peer_id` is not in `peers_with_tx`.
|
|
206
|
+
"""
|
|
207
|
+
queue = TransactionQueue(42, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
|
|
208
|
+
peer1 = bytes32.random()
|
|
209
|
+
peer2 = bytes32.random()
|
|
210
|
+
# We'll be using this peer to test the fallback, so we don't include it in
|
|
211
|
+
# peers with transactions maps.
|
|
212
|
+
peer3 = bytes32.random()
|
|
213
|
+
peers_with_tx1 = {
|
|
214
|
+
# This has FPC of 5.0
|
|
215
|
+
peer1: PeerWithTx(str(peer1), uint64(10), uint64(2)),
|
|
216
|
+
# This has FPC of 2.0 but higher advertised cost
|
|
217
|
+
peer2: PeerWithTx(str(peer2), uint64(20), uint64(10)),
|
|
218
|
+
}
|
|
219
|
+
tx1 = get_transaction_queue_entry(peer3, 0, peers_with_tx1)
|
|
220
|
+
queue.put(tx1, peer3)
|
|
221
|
+
peers_with_tx2 = {
|
|
222
|
+
# This has FPC of 3.0
|
|
223
|
+
peer1: PeerWithTx(str(peer1), uint64(30), uint64(10)),
|
|
224
|
+
# This has FPC of 4.0 but lower advertised cost
|
|
225
|
+
peer2: PeerWithTx(str(peer2), uint64(20), uint64(5)),
|
|
226
|
+
# This has FPC of 1.0 but lower advertised cost
|
|
227
|
+
peer3: PeerWithTx(str(peer3), uint64(4), uint64(4)),
|
|
228
|
+
}
|
|
229
|
+
tx2 = get_transaction_queue_entry(peer3, 1, peers_with_tx2)
|
|
230
|
+
queue.put(tx2, peer3)
|
|
231
|
+
# tx2 gets top priority with FPC 1.0
|
|
232
|
+
assert math.isclose(queue._peers_transactions_queues[peer3].priority_queue.queue[0][0], -1.0)
|
|
233
|
+
entry = await queue.pop()
|
|
234
|
+
# NOTE: This whole test file uses `index` as an addition to
|
|
235
|
+
# `TransactionQueueEntry` for easier testing, hence this type ignore here
|
|
236
|
+
# and everywhere else.
|
|
237
|
+
assert entry.index == 1 # type: ignore[attr-defined]
|
|
238
|
+
# tx1 comes next due to lowest priority fallback
|
|
239
|
+
assert math.isinf(queue._peers_transactions_queues[peer3].priority_queue.queue[0][0])
|
|
240
|
+
entry = await queue.pop()
|
|
241
|
+
assert entry.index == 0 # type: ignore[attr-defined]
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
@pytest.mark.anyio
|
|
245
|
+
async def test_normal_queue_deficit_round_robin() -> None:
|
|
246
|
+
"""
|
|
247
|
+
Covers the deficit round robin behavior of the normal transaction queue where
|
|
248
|
+
we cycle through peers and pick their top transactions when their deficit
|
|
249
|
+
counters allow them to afford it, and we ensure that their deficit counters
|
|
250
|
+
adapt accordingly.
|
|
251
|
+
This also covers the case where a peer's top transaction does not advertise
|
|
252
|
+
cost, so that falls back to `max_tx_clvm_cost`.
|
|
253
|
+
This also covers the cleanup behavior where peers with no remaining
|
|
254
|
+
transactions are removed periodically (each 100 pop) from the queue.
|
|
255
|
+
"""
|
|
256
|
+
test_max_tx_clvm_cost = uint64(20)
|
|
257
|
+
queue = TransactionQueue(42, log, max_tx_clvm_cost=test_max_tx_clvm_cost)
|
|
258
|
+
peer1 = bytes32.random()
|
|
259
|
+
peer2 = bytes32.random()
|
|
260
|
+
peer3 = bytes32.random()
|
|
261
|
+
peer4 = bytes32.random()
|
|
262
|
+
test_fee = uint64(42)
|
|
263
|
+
# We give this one the highest cost
|
|
264
|
+
tx1 = get_transaction_queue_entry(peer1, 0, {peer1: PeerWithTx(str(peer1), test_fee, uint64(15))})
|
|
265
|
+
queue.put(tx1, peer1)
|
|
266
|
+
# And this one the lowest cost
|
|
267
|
+
tx2 = get_transaction_queue_entry(peer2, 1, {peer2: PeerWithTx(str(peer2), test_fee, uint64(5))})
|
|
268
|
+
queue.put(tx2, peer2)
|
|
269
|
+
# And this one a cost in between
|
|
270
|
+
tx3 = get_transaction_queue_entry(peer3, 2, {peer3: PeerWithTx(str(peer3), test_fee, uint64(10))})
|
|
271
|
+
queue.put(tx3, peer3)
|
|
272
|
+
# This one has no cost information so its top transaction's advertised cost
|
|
273
|
+
# falls back to `test_max_tx_clvm_cost`.
|
|
274
|
+
tx4 = get_transaction_queue_entry(peer4, 3, {})
|
|
275
|
+
queue.put(tx4, peer4)
|
|
276
|
+
# When we try to pop a transaction, none of the peers initially can
|
|
277
|
+
# afford to send their top transactions, so we add the lowest cost among
|
|
278
|
+
# transactions (5) to all the peers' deficit counters and try again. This
|
|
279
|
+
# makes peer2 able to send its transaction tx2.
|
|
280
|
+
entry = await queue.pop()
|
|
281
|
+
assert entry.index == 1 # type: ignore[attr-defined]
|
|
282
|
+
assert queue._list_cursor == 2
|
|
283
|
+
assert queue._peers_transactions_queues[peer1].deficit == 5
|
|
284
|
+
assert queue._peers_transactions_queues[peer2].deficit == 0
|
|
285
|
+
assert queue._peers_transactions_queues[peer3].deficit == 5
|
|
286
|
+
assert queue._peers_transactions_queues[peer4].deficit == 5
|
|
287
|
+
# Now peer3, peer4 and peer1 can't afford to send their top transactions so
|
|
288
|
+
# we add the lowest cost among transactions (10) to their deficit counters
|
|
289
|
+
# and try again. This makes peer3 able to send its transaction tx3.
|
|
290
|
+
entry = await queue.pop()
|
|
291
|
+
assert entry.index == 2 # type: ignore[attr-defined]
|
|
292
|
+
assert queue._list_cursor == 3
|
|
293
|
+
assert queue._peers_transactions_queues[peer1].deficit == 15
|
|
294
|
+
assert queue._peers_transactions_queues[peer2].deficit == 0
|
|
295
|
+
assert queue._peers_transactions_queues[peer3].deficit == 0
|
|
296
|
+
assert queue._peers_transactions_queues[peer4].deficit == 15
|
|
297
|
+
# Let's force cleanup to happen on the next pop
|
|
298
|
+
queue._cleanup_counter = 99
|
|
299
|
+
# Now peer4 can't afford to send its top transaction (20) but peer1 can
|
|
300
|
+
# send tx1 (15) so it does.
|
|
301
|
+
entry = await queue.pop()
|
|
302
|
+
assert entry.index == 0 # type: ignore[attr-defined]
|
|
303
|
+
# This pop triggers cleanup, so peer1, peer2 and peer3 are removed from
|
|
304
|
+
# the transaction queue (they have nothing left) and only peer4 remains.
|
|
305
|
+
for peer in [peer1, peer2, peer3]:
|
|
306
|
+
assert peer not in queue._index_to_peer_map
|
|
307
|
+
assert peer not in queue._peers_transactions_queues
|
|
308
|
+
assert len(queue._index_to_peer_map) == 1
|
|
309
|
+
assert peer4 in queue._index_to_peer_map
|
|
310
|
+
assert queue._list_cursor == 0
|
|
311
|
+
# At this point we didn't have to increment deficit counters because peer1
|
|
312
|
+
# could already afford to send its top transaction, so peer4's deficit
|
|
313
|
+
# counter stays the same.
|
|
314
|
+
assert queue._peers_transactions_queues[peer4].deficit == 15
|
|
315
|
+
# Finally, peer4 is tried but it can't send its top transaction, which has
|
|
316
|
+
# a fallback cost of `test_max_tx_clvm_cost` (20), so we add that to its
|
|
317
|
+
# deficit counter, making it 35, and upon retrying now it's able to send
|
|
318
|
+
# its transaction tx4.
|
|
319
|
+
entry = await queue.pop()
|
|
320
|
+
assert entry.index == 3 # type: ignore[attr-defined]
|
|
321
|
+
assert queue._peers_transactions_queues[peer4].deficit == 0
|
|
322
|
+
assert queue._list_cursor == 0
|