chia-blockchain 2.5.1rc1__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 +10 -0
- chia/__main__.py +5 -0
- chia/_tests/README.md +53 -0
- chia/_tests/__init__.py +0 -0
- chia/_tests/blockchain/__init__.py +0 -0
- chia/_tests/blockchain/blockchain_test_utils.py +195 -0
- chia/_tests/blockchain/config.py +4 -0
- chia/_tests/blockchain/test_augmented_chain.py +145 -0
- chia/_tests/blockchain/test_blockchain.py +4202 -0
- chia/_tests/blockchain/test_blockchain_transactions.py +1031 -0
- chia/_tests/blockchain/test_build_chains.py +59 -0
- chia/_tests/blockchain/test_get_block_generator.py +72 -0
- chia/_tests/blockchain/test_lookup_fork_chain.py +194 -0
- chia/_tests/build-init-files.py +92 -0
- chia/_tests/build-job-matrix.py +204 -0
- chia/_tests/check_pytest_monitor_output.py +34 -0
- chia/_tests/check_sql_statements.py +72 -0
- chia/_tests/chia-start-sim +42 -0
- chia/_tests/clvm/__init__.py +0 -0
- chia/_tests/clvm/benchmark_costs.py +23 -0
- chia/_tests/clvm/coin_store.py +149 -0
- chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
- chia/_tests/clvm/test_clvm_step.py +37 -0
- chia/_tests/clvm/test_condition_codes.py +13 -0
- chia/_tests/clvm/test_curry_and_treehash.py +55 -0
- chia/_tests/clvm/test_message_conditions.py +184 -0
- chia/_tests/clvm/test_program.py +150 -0
- chia/_tests/clvm/test_puzzle_compression.py +143 -0
- chia/_tests/clvm/test_puzzle_drivers.py +45 -0
- chia/_tests/clvm/test_puzzles.py +242 -0
- chia/_tests/clvm/test_singletons.py +540 -0
- chia/_tests/clvm/test_spend_sim.py +181 -0
- chia/_tests/cmds/__init__.py +0 -0
- chia/_tests/cmds/cmd_test_utils.py +469 -0
- chia/_tests/cmds/config.py +3 -0
- chia/_tests/cmds/conftest.py +23 -0
- chia/_tests/cmds/test_click_types.py +200 -0
- chia/_tests/cmds/test_cmd_framework.py +620 -0
- chia/_tests/cmds/test_cmds_util.py +97 -0
- chia/_tests/cmds/test_daemon.py +92 -0
- chia/_tests/cmds/test_dev_gh.py +131 -0
- chia/_tests/cmds/test_farm_cmd.py +66 -0
- chia/_tests/cmds/test_show.py +116 -0
- chia/_tests/cmds/test_sim.py +207 -0
- chia/_tests/cmds/test_timelock_args.py +75 -0
- chia/_tests/cmds/test_tx_config_args.py +154 -0
- chia/_tests/cmds/testing_classes.py +59 -0
- chia/_tests/cmds/wallet/__init__.py +0 -0
- chia/_tests/cmds/wallet/test_consts.py +47 -0
- chia/_tests/cmds/wallet/test_dao.py +565 -0
- chia/_tests/cmds/wallet/test_did.py +403 -0
- chia/_tests/cmds/wallet/test_nft.py +471 -0
- chia/_tests/cmds/wallet/test_notifications.py +124 -0
- chia/_tests/cmds/wallet/test_offer.toffer +1 -0
- chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
- chia/_tests/cmds/wallet/test_vcs.py +400 -0
- chia/_tests/cmds/wallet/test_wallet.py +1125 -0
- chia/_tests/cmds/wallet/test_wallet_check.py +109 -0
- chia/_tests/conftest.py +1419 -0
- chia/_tests/connection_utils.py +125 -0
- chia/_tests/core/__init__.py +0 -0
- chia/_tests/core/cmds/__init__.py +0 -0
- chia/_tests/core/cmds/test_beta.py +382 -0
- chia/_tests/core/cmds/test_keys.py +1734 -0
- chia/_tests/core/cmds/test_wallet.py +126 -0
- chia/_tests/core/config.py +3 -0
- chia/_tests/core/consensus/__init__.py +0 -0
- chia/_tests/core/consensus/test_block_creation.py +54 -0
- chia/_tests/core/consensus/test_pot_iterations.py +117 -0
- chia/_tests/core/custom_types/__init__.py +0 -0
- chia/_tests/core/custom_types/test_coin.py +107 -0
- chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
- chia/_tests/core/custom_types/test_spend_bundle.py +70 -0
- chia/_tests/core/daemon/__init__.py +0 -0
- chia/_tests/core/daemon/config.py +4 -0
- chia/_tests/core/daemon/test_daemon.py +2128 -0
- chia/_tests/core/daemon/test_daemon_register.py +109 -0
- chia/_tests/core/daemon/test_keychain_proxy.py +101 -0
- chia/_tests/core/data_layer/__init__.py +0 -0
- chia/_tests/core/data_layer/config.py +5 -0
- chia/_tests/core/data_layer/conftest.py +106 -0
- chia/_tests/core/data_layer/test_data_cli.py +56 -0
- chia/_tests/core/data_layer/test_data_layer.py +83 -0
- chia/_tests/core/data_layer/test_data_layer_util.py +218 -0
- chia/_tests/core/data_layer/test_data_rpc.py +3847 -0
- chia/_tests/core/data_layer/test_data_store.py +2424 -0
- chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
- chia/_tests/core/data_layer/test_plugin.py +91 -0
- chia/_tests/core/data_layer/util.py +233 -0
- chia/_tests/core/farmer/__init__.py +0 -0
- chia/_tests/core/farmer/config.py +3 -0
- chia/_tests/core/farmer/test_farmer_api.py +103 -0
- chia/_tests/core/full_node/__init__.py +0 -0
- chia/_tests/core/full_node/config.py +4 -0
- chia/_tests/core/full_node/dos/__init__.py +0 -0
- chia/_tests/core/full_node/dos/config.py +3 -0
- chia/_tests/core/full_node/full_sync/__init__.py +0 -0
- chia/_tests/core/full_node/full_sync/config.py +4 -0
- chia/_tests/core/full_node/full_sync/test_full_sync.py +443 -0
- chia/_tests/core/full_node/ram_db.py +27 -0
- chia/_tests/core/full_node/stores/__init__.py +0 -0
- chia/_tests/core/full_node/stores/config.py +4 -0
- chia/_tests/core/full_node/stores/test_block_store.py +590 -0
- chia/_tests/core/full_node/stores/test_coin_store.py +897 -0
- chia/_tests/core/full_node/stores/test_full_node_store.py +1219 -0
- chia/_tests/core/full_node/stores/test_hint_store.py +229 -0
- chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
- chia/_tests/core/full_node/test_address_manager.py +588 -0
- chia/_tests/core/full_node/test_block_height_map.py +556 -0
- chia/_tests/core/full_node/test_conditions.py +556 -0
- chia/_tests/core/full_node/test_full_node.py +2700 -0
- chia/_tests/core/full_node/test_generator_tools.py +82 -0
- chia/_tests/core/full_node/test_hint_management.py +104 -0
- chia/_tests/core/full_node/test_node_load.py +34 -0
- chia/_tests/core/full_node/test_performance.py +179 -0
- chia/_tests/core/full_node/test_subscriptions.py +492 -0
- chia/_tests/core/full_node/test_transactions.py +203 -0
- chia/_tests/core/full_node/test_tx_processing_queue.py +155 -0
- chia/_tests/core/large_block.py +2388 -0
- chia/_tests/core/make_block_generator.py +70 -0
- chia/_tests/core/mempool/__init__.py +0 -0
- chia/_tests/core/mempool/config.py +4 -0
- chia/_tests/core/mempool/test_mempool.py +3255 -0
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
- chia/_tests/core/mempool/test_mempool_item_queries.py +190 -0
- chia/_tests/core/mempool/test_mempool_manager.py +2084 -0
- chia/_tests/core/mempool/test_mempool_performance.py +64 -0
- chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
- chia/_tests/core/node_height.py +28 -0
- chia/_tests/core/server/__init__.py +0 -0
- chia/_tests/core/server/config.py +3 -0
- chia/_tests/core/server/flood.py +84 -0
- chia/_tests/core/server/serve.py +135 -0
- chia/_tests/core/server/test_api_protocol.py +21 -0
- chia/_tests/core/server/test_capabilities.py +66 -0
- chia/_tests/core/server/test_dos.py +319 -0
- chia/_tests/core/server/test_event_loop.py +109 -0
- chia/_tests/core/server/test_loop.py +294 -0
- chia/_tests/core/server/test_node_discovery.py +73 -0
- chia/_tests/core/server/test_rate_limits.py +482 -0
- chia/_tests/core/server/test_server.py +226 -0
- chia/_tests/core/server/test_upnp.py +8 -0
- chia/_tests/core/services/__init__.py +0 -0
- chia/_tests/core/services/config.py +3 -0
- chia/_tests/core/services/test_services.py +188 -0
- chia/_tests/core/ssl/__init__.py +0 -0
- chia/_tests/core/ssl/config.py +3 -0
- chia/_tests/core/ssl/test_ssl.py +202 -0
- chia/_tests/core/test_coins.py +33 -0
- chia/_tests/core/test_cost_calculation.py +313 -0
- chia/_tests/core/test_crawler.py +175 -0
- chia/_tests/core/test_crawler_rpc.py +53 -0
- chia/_tests/core/test_daemon_rpc.py +24 -0
- chia/_tests/core/test_db_conversion.py +130 -0
- chia/_tests/core/test_db_validation.py +162 -0
- chia/_tests/core/test_farmer_harvester_rpc.py +505 -0
- chia/_tests/core/test_filter.py +35 -0
- chia/_tests/core/test_full_node_rpc.py +768 -0
- chia/_tests/core/test_merkle_set.py +343 -0
- chia/_tests/core/test_program.py +47 -0
- chia/_tests/core/test_rpc_util.py +86 -0
- chia/_tests/core/test_seeder.py +420 -0
- chia/_tests/core/test_setproctitle.py +13 -0
- chia/_tests/core/util/__init__.py +0 -0
- chia/_tests/core/util/config.py +4 -0
- chia/_tests/core/util/test_block_cache.py +44 -0
- chia/_tests/core/util/test_cached_bls.py +57 -0
- chia/_tests/core/util/test_config.py +337 -0
- chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
- chia/_tests/core/util/test_files.py +391 -0
- chia/_tests/core/util/test_jsonify.py +146 -0
- chia/_tests/core/util/test_keychain.py +522 -0
- chia/_tests/core/util/test_keyring_wrapper.py +491 -0
- chia/_tests/core/util/test_lockfile.py +380 -0
- chia/_tests/core/util/test_log_exceptions.py +187 -0
- chia/_tests/core/util/test_lru_cache.py +56 -0
- chia/_tests/core/util/test_significant_bits.py +40 -0
- chia/_tests/core/util/test_streamable.py +883 -0
- chia/_tests/db/__init__.py +0 -0
- chia/_tests/db/test_db_wrapper.py +566 -0
- chia/_tests/environments/__init__.py +0 -0
- chia/_tests/environments/common.py +35 -0
- chia/_tests/environments/full_node.py +47 -0
- chia/_tests/environments/wallet.py +429 -0
- chia/_tests/ether.py +19 -0
- chia/_tests/farmer_harvester/__init__.py +0 -0
- chia/_tests/farmer_harvester/config.py +3 -0
- chia/_tests/farmer_harvester/test_farmer.py +1264 -0
- chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +131 -0
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +528 -0
- chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
- chia/_tests/fee_estimation/__init__.py +0 -0
- chia/_tests/fee_estimation/config.py +3 -0
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +144 -0
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
- chia/_tests/generator/__init__.py +0 -0
- chia/_tests/generator/puzzles/__init__.py +0 -0
- chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
- chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
- chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
- chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
- chia/_tests/generator/test_compression.py +201 -0
- chia/_tests/generator/test_generator_types.py +44 -0
- chia/_tests/generator/test_rom.py +180 -0
- chia/_tests/plot_sync/__init__.py +0 -0
- chia/_tests/plot_sync/config.py +3 -0
- chia/_tests/plot_sync/test_delta.py +101 -0
- chia/_tests/plot_sync/test_plot_sync.py +618 -0
- chia/_tests/plot_sync/test_receiver.py +451 -0
- chia/_tests/plot_sync/test_sender.py +116 -0
- chia/_tests/plot_sync/test_sync_simulated.py +451 -0
- chia/_tests/plot_sync/util.py +68 -0
- chia/_tests/plotting/__init__.py +0 -0
- chia/_tests/plotting/config.py +3 -0
- chia/_tests/plotting/test_plot_manager.py +781 -0
- chia/_tests/plotting/util.py +12 -0
- chia/_tests/pools/__init__.py +0 -0
- chia/_tests/pools/config.py +5 -0
- chia/_tests/pools/test_pool_cli_parsing.py +128 -0
- chia/_tests/pools/test_pool_cmdline.py +1001 -0
- chia/_tests/pools/test_pool_config.py +42 -0
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +397 -0
- chia/_tests/pools/test_pool_rpc.py +1123 -0
- chia/_tests/pools/test_pool_wallet.py +205 -0
- chia/_tests/pools/test_wallet_pool_store.py +161 -0
- chia/_tests/process_junit.py +348 -0
- chia/_tests/rpc/__init__.py +0 -0
- chia/_tests/rpc/test_rpc_client.py +138 -0
- chia/_tests/rpc/test_rpc_server.py +183 -0
- chia/_tests/simulation/__init__.py +0 -0
- chia/_tests/simulation/config.py +6 -0
- chia/_tests/simulation/test_simulation.py +501 -0
- chia/_tests/simulation/test_simulator.py +232 -0
- chia/_tests/simulation/test_start_simulator.py +107 -0
- chia/_tests/testconfig.py +13 -0
- chia/_tests/timelord/__init__.py +0 -0
- chia/_tests/timelord/config.py +3 -0
- chia/_tests/timelord/test_new_peak.py +437 -0
- chia/_tests/timelord/test_timelord.py +11 -0
- chia/_tests/tools/1315537.json +170 -0
- chia/_tests/tools/1315544.json +160 -0
- chia/_tests/tools/1315630.json +150 -0
- chia/_tests/tools/300000.json +105 -0
- chia/_tests/tools/442734.json +140 -0
- chia/_tests/tools/466212.json +130 -0
- chia/_tests/tools/__init__.py +0 -0
- chia/_tests/tools/config.py +5 -0
- chia/_tests/tools/test-blockchain-db.sqlite +0 -0
- chia/_tests/tools/test_full_sync.py +30 -0
- chia/_tests/tools/test_legacy_keyring.py +82 -0
- chia/_tests/tools/test_run_block.py +128 -0
- chia/_tests/tools/test_virtual_project.py +591 -0
- chia/_tests/util/__init__.py +0 -0
- chia/_tests/util/benchmark_cost.py +170 -0
- chia/_tests/util/benchmarks.py +153 -0
- chia/_tests/util/bip39_test_vectors.json +148 -0
- chia/_tests/util/blockchain.py +134 -0
- chia/_tests/util/blockchain_mock.py +132 -0
- chia/_tests/util/build_network_protocol_files.py +302 -0
- chia/_tests/util/clvm_generator.bin +0 -0
- chia/_tests/util/config.py +3 -0
- chia/_tests/util/constants.py +20 -0
- chia/_tests/util/db_connection.py +37 -0
- chia/_tests/util/full_sync.py +253 -0
- chia/_tests/util/gen_ssl_certs.py +114 -0
- chia/_tests/util/generator_tools_testing.py +45 -0
- chia/_tests/util/get_name_puzzle_conditions.py +52 -0
- chia/_tests/util/key_tool.py +36 -0
- chia/_tests/util/misc.py +675 -0
- chia/_tests/util/network_protocol_data.py +1072 -0
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +2701 -0
- chia/_tests/util/rpc.py +26 -0
- chia/_tests/util/run_block.py +163 -0
- chia/_tests/util/setup_nodes.py +481 -0
- chia/_tests/util/spend_sim.py +492 -0
- chia/_tests/util/split_managers.py +102 -0
- chia/_tests/util/temp_file.py +14 -0
- chia/_tests/util/test_action_scope.py +144 -0
- chia/_tests/util/test_async_pool.py +366 -0
- chia/_tests/util/test_build_job_matrix.py +42 -0
- chia/_tests/util/test_build_network_protocol_files.py +7 -0
- chia/_tests/util/test_chia_version.py +50 -0
- chia/_tests/util/test_collection.py +11 -0
- chia/_tests/util/test_condition_tools.py +229 -0
- chia/_tests/util/test_config.py +426 -0
- chia/_tests/util/test_dump_keyring.py +60 -0
- chia/_tests/util/test_errors.py +10 -0
- chia/_tests/util/test_full_block_utils.py +279 -0
- chia/_tests/util/test_installed.py +20 -0
- chia/_tests/util/test_limited_semaphore.py +53 -0
- chia/_tests/util/test_logging_filter.py +42 -0
- chia/_tests/util/test_misc.py +445 -0
- chia/_tests/util/test_network.py +73 -0
- chia/_tests/util/test_network_protocol_files.py +578 -0
- chia/_tests/util/test_network_protocol_json.py +267 -0
- chia/_tests/util/test_network_protocol_test.py +256 -0
- chia/_tests/util/test_paginator.py +71 -0
- chia/_tests/util/test_pprint.py +17 -0
- chia/_tests/util/test_priority_mutex.py +488 -0
- chia/_tests/util/test_recursive_replace.py +116 -0
- chia/_tests/util/test_replace_str_to_bytes.py +137 -0
- chia/_tests/util/test_service_groups.py +15 -0
- chia/_tests/util/test_ssl_check.py +31 -0
- chia/_tests/util/test_testnet_overrides.py +19 -0
- chia/_tests/util/test_tests_misc.py +38 -0
- chia/_tests/util/test_timing.py +37 -0
- chia/_tests/util/test_trusted_peer.py +51 -0
- chia/_tests/util/time_out_assert.py +191 -0
- chia/_tests/wallet/__init__.py +0 -0
- chia/_tests/wallet/cat_wallet/__init__.py +0 -0
- chia/_tests/wallet/cat_wallet/config.py +4 -0
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1826 -0
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
- chia/_tests/wallet/cat_wallet/test_trades.py +2600 -0
- chia/_tests/wallet/clawback/__init__.py +0 -0
- chia/_tests/wallet/clawback/config.py +3 -0
- chia/_tests/wallet/clawback/test_clawback_decorator.py +78 -0
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
- chia/_tests/wallet/clawback/test_clawback_metadata.py +50 -0
- chia/_tests/wallet/config.py +4 -0
- chia/_tests/wallet/conftest.py +278 -0
- chia/_tests/wallet/dao_wallet/__init__.py +0 -0
- chia/_tests/wallet/dao_wallet/config.py +3 -0
- chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1330 -0
- chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
- chia/_tests/wallet/db_wallet/__init__.py +0 -0
- chia/_tests/wallet/db_wallet/config.py +3 -0
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +141 -0
- chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
- chia/_tests/wallet/did_wallet/__init__.py +0 -0
- chia/_tests/wallet/did_wallet/config.py +4 -0
- chia/_tests/wallet/did_wallet/test_did.py +2284 -0
- chia/_tests/wallet/nft_wallet/__init__.py +0 -0
- chia/_tests/wallet/nft_wallet/config.py +4 -0
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1493 -0
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1024 -0
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +375 -0
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2584 -0
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
- chia/_tests/wallet/rpc/__init__.py +0 -0
- chia/_tests/wallet/rpc/config.py +4 -0
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +285 -0
- chia/_tests/wallet/rpc/test_wallet_rpc.py +3153 -0
- chia/_tests/wallet/simple_sync/__init__.py +0 -0
- chia/_tests/wallet/simple_sync/config.py +3 -0
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +718 -0
- chia/_tests/wallet/sync/__init__.py +0 -0
- chia/_tests/wallet/sync/config.py +4 -0
- chia/_tests/wallet/sync/test_wallet_sync.py +1692 -0
- chia/_tests/wallet/test_address_type.py +189 -0
- chia/_tests/wallet/test_bech32m.py +45 -0
- chia/_tests/wallet/test_clvm_streamable.py +244 -0
- chia/_tests/wallet/test_coin_management.py +354 -0
- chia/_tests/wallet/test_coin_selection.py +588 -0
- chia/_tests/wallet/test_conditions.py +400 -0
- chia/_tests/wallet/test_debug_spend_bundle.py +218 -0
- chia/_tests/wallet/test_new_wallet_protocol.py +1174 -0
- chia/_tests/wallet/test_nft_store.py +192 -0
- chia/_tests/wallet/test_notifications.py +196 -0
- chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
- chia/_tests/wallet/test_puzzle_store.py +132 -0
- chia/_tests/wallet/test_sign_coin_spends.py +159 -0
- chia/_tests/wallet/test_signer_protocol.py +947 -0
- chia/_tests/wallet/test_singleton.py +122 -0
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
- chia/_tests/wallet/test_singleton_store.py +152 -0
- chia/_tests/wallet/test_taproot.py +19 -0
- chia/_tests/wallet/test_transaction_store.py +945 -0
- chia/_tests/wallet/test_util.py +185 -0
- chia/_tests/wallet/test_wallet.py +2139 -0
- chia/_tests/wallet/test_wallet_action_scope.py +85 -0
- chia/_tests/wallet/test_wallet_blockchain.py +111 -0
- chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
- chia/_tests/wallet/test_wallet_interested_store.py +43 -0
- chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
- chia/_tests/wallet/test_wallet_node.py +780 -0
- chia/_tests/wallet/test_wallet_retry.py +95 -0
- chia/_tests/wallet/test_wallet_state_manager.py +259 -0
- chia/_tests/wallet/test_wallet_test_framework.py +275 -0
- chia/_tests/wallet/test_wallet_trade_store.py +218 -0
- chia/_tests/wallet/test_wallet_user_store.py +34 -0
- chia/_tests/wallet/test_wallet_utils.py +156 -0
- chia/_tests/wallet/vc_wallet/__init__.py +0 -0
- chia/_tests/wallet/vc_wallet/config.py +3 -0
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +830 -0
- chia/_tests/wallet/wallet_block_tools.py +327 -0
- chia/_tests/weight_proof/__init__.py +0 -0
- chia/_tests/weight_proof/config.py +3 -0
- chia/_tests/weight_proof/test_weight_proof.py +528 -0
- chia/apis.py +19 -0
- chia/clvm/__init__.py +0 -0
- chia/cmds/__init__.py +0 -0
- chia/cmds/beta.py +184 -0
- chia/cmds/beta_funcs.py +137 -0
- chia/cmds/check_wallet_db.py +420 -0
- chia/cmds/chia.py +151 -0
- chia/cmds/cmd_classes.py +323 -0
- chia/cmds/cmd_helpers.py +242 -0
- chia/cmds/cmds_util.py +488 -0
- chia/cmds/coin_funcs.py +275 -0
- chia/cmds/coins.py +182 -0
- chia/cmds/completion.py +49 -0
- chia/cmds/configure.py +332 -0
- chia/cmds/dao.py +1064 -0
- chia/cmds/dao_funcs.py +598 -0
- chia/cmds/data.py +708 -0
- chia/cmds/data_funcs.py +385 -0
- chia/cmds/db.py +87 -0
- chia/cmds/db_backup_func.py +77 -0
- chia/cmds/db_upgrade_func.py +452 -0
- chia/cmds/db_validate_func.py +184 -0
- chia/cmds/dev.py +18 -0
- chia/cmds/farm.py +100 -0
- chia/cmds/farm_funcs.py +200 -0
- chia/cmds/gh.py +275 -0
- chia/cmds/init.py +63 -0
- chia/cmds/init_funcs.py +367 -0
- chia/cmds/installers.py +131 -0
- chia/cmds/keys.py +527 -0
- chia/cmds/keys_funcs.py +863 -0
- chia/cmds/netspace.py +50 -0
- chia/cmds/netspace_funcs.py +54 -0
- chia/cmds/options.py +32 -0
- chia/cmds/param_types.py +238 -0
- chia/cmds/passphrase.py +131 -0
- chia/cmds/passphrase_funcs.py +292 -0
- chia/cmds/peer.py +51 -0
- chia/cmds/peer_funcs.py +129 -0
- chia/cmds/plotnft.py +260 -0
- chia/cmds/plotnft_funcs.py +405 -0
- chia/cmds/plots.py +230 -0
- chia/cmds/plotters.py +18 -0
- chia/cmds/rpc.py +208 -0
- chia/cmds/show.py +72 -0
- chia/cmds/show_funcs.py +215 -0
- chia/cmds/signer.py +296 -0
- chia/cmds/sim.py +225 -0
- chia/cmds/sim_funcs.py +509 -0
- chia/cmds/start.py +24 -0
- chia/cmds/start_funcs.py +109 -0
- chia/cmds/stop.py +62 -0
- chia/cmds/units.py +9 -0
- chia/cmds/wallet.py +1901 -0
- chia/cmds/wallet_funcs.py +1874 -0
- chia/consensus/__init__.py +0 -0
- chia/consensus/block_body_validation.py +562 -0
- chia/consensus/block_creation.py +546 -0
- chia/consensus/block_header_validation.py +1059 -0
- chia/consensus/block_record.py +31 -0
- chia/consensus/block_rewards.py +53 -0
- chia/consensus/blockchain.py +1087 -0
- chia/consensus/blockchain_interface.py +56 -0
- chia/consensus/coinbase.py +30 -0
- chia/consensus/condition_costs.py +9 -0
- chia/consensus/constants.py +49 -0
- chia/consensus/cost_calculator.py +15 -0
- chia/consensus/default_constants.py +89 -0
- chia/consensus/deficit.py +55 -0
- chia/consensus/difficulty_adjustment.py +412 -0
- chia/consensus/find_fork_point.py +111 -0
- chia/consensus/full_block_to_block_record.py +167 -0
- chia/consensus/get_block_challenge.py +106 -0
- chia/consensus/get_block_generator.py +27 -0
- chia/consensus/make_sub_epoch_summary.py +210 -0
- chia/consensus/multiprocess_validation.py +268 -0
- chia/consensus/pos_quality.py +19 -0
- chia/consensus/pot_iterations.py +67 -0
- chia/consensus/puzzles/__init__.py +0 -0
- chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
- chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
- chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
- chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
- chia/consensus/vdf_info_computation.py +156 -0
- chia/daemon/__init__.py +0 -0
- chia/daemon/client.py +252 -0
- chia/daemon/keychain_proxy.py +502 -0
- chia/daemon/keychain_server.py +365 -0
- chia/daemon/server.py +1606 -0
- chia/daemon/windows_signal.py +56 -0
- chia/data_layer/__init__.py +0 -0
- chia/data_layer/data_layer.py +1291 -0
- chia/data_layer/data_layer_api.py +33 -0
- chia/data_layer/data_layer_errors.py +50 -0
- chia/data_layer/data_layer_server.py +170 -0
- chia/data_layer/data_layer_util.py +985 -0
- chia/data_layer/data_layer_wallet.py +1311 -0
- chia/data_layer/data_store.py +2267 -0
- chia/data_layer/dl_wallet_store.py +407 -0
- chia/data_layer/download_data.py +389 -0
- chia/data_layer/puzzles/__init__.py +0 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
- chia/data_layer/s3_plugin_config.yml +33 -0
- chia/data_layer/s3_plugin_service.py +468 -0
- chia/data_layer/util/__init__.py +0 -0
- chia/data_layer/util/benchmark.py +107 -0
- chia/data_layer/util/plugin.py +40 -0
- chia/farmer/__init__.py +0 -0
- chia/farmer/farmer.py +923 -0
- chia/farmer/farmer_api.py +820 -0
- chia/full_node/__init__.py +0 -0
- chia/full_node/bitcoin_fee_estimator.py +85 -0
- chia/full_node/block_height_map.py +271 -0
- chia/full_node/block_store.py +576 -0
- chia/full_node/bundle_tools.py +19 -0
- chia/full_node/coin_store.py +647 -0
- chia/full_node/fee_estimate.py +54 -0
- chia/full_node/fee_estimate_store.py +24 -0
- chia/full_node/fee_estimation.py +92 -0
- chia/full_node/fee_estimator.py +90 -0
- chia/full_node/fee_estimator_constants.py +38 -0
- chia/full_node/fee_estimator_interface.py +42 -0
- chia/full_node/fee_history.py +25 -0
- chia/full_node/fee_tracker.py +564 -0
- chia/full_node/full_node.py +3327 -0
- chia/full_node/full_node_api.py +2025 -0
- chia/full_node/full_node_store.py +1033 -0
- chia/full_node/hint_management.py +56 -0
- chia/full_node/hint_store.py +93 -0
- chia/full_node/mempool.py +589 -0
- chia/full_node/mempool_check_conditions.py +146 -0
- chia/full_node/mempool_manager.py +853 -0
- chia/full_node/pending_tx_cache.py +112 -0
- chia/full_node/puzzles/__init__.py +0 -0
- chia/full_node/puzzles/block_program_zero.clsp +14 -0
- chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
- chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
- chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
- chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
- chia/full_node/signage_point.py +16 -0
- chia/full_node/subscriptions.py +247 -0
- chia/full_node/sync_store.py +146 -0
- chia/full_node/tx_processing_queue.py +78 -0
- chia/full_node/util/__init__.py +0 -0
- chia/full_node/weight_proof.py +1720 -0
- chia/harvester/__init__.py +0 -0
- chia/harvester/harvester.py +272 -0
- chia/harvester/harvester_api.py +380 -0
- chia/introducer/__init__.py +0 -0
- chia/introducer/introducer.py +122 -0
- chia/introducer/introducer_api.py +70 -0
- chia/legacy/__init__.py +0 -0
- chia/legacy/keyring.py +155 -0
- chia/plot_sync/__init__.py +0 -0
- chia/plot_sync/delta.py +61 -0
- chia/plot_sync/exceptions.py +56 -0
- chia/plot_sync/receiver.py +386 -0
- chia/plot_sync/sender.py +340 -0
- chia/plot_sync/util.py +43 -0
- chia/plotters/__init__.py +0 -0
- chia/plotters/bladebit.py +388 -0
- chia/plotters/chiapos.py +63 -0
- chia/plotters/madmax.py +224 -0
- chia/plotters/plotters.py +577 -0
- chia/plotters/plotters_util.py +133 -0
- chia/plotting/__init__.py +0 -0
- chia/plotting/cache.py +213 -0
- chia/plotting/check_plots.py +283 -0
- chia/plotting/create_plots.py +278 -0
- chia/plotting/manager.py +436 -0
- chia/plotting/util.py +336 -0
- chia/pools/__init__.py +0 -0
- chia/pools/pool_config.py +110 -0
- chia/pools/pool_puzzles.py +459 -0
- chia/pools/pool_wallet.py +933 -0
- chia/pools/pool_wallet_info.py +118 -0
- chia/pools/puzzles/__init__.py +0 -0
- chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
- chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
- chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
- chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
- chia/protocols/__init__.py +0 -0
- chia/protocols/farmer_protocol.py +102 -0
- chia/protocols/full_node_protocol.py +219 -0
- chia/protocols/harvester_protocol.py +216 -0
- chia/protocols/introducer_protocol.py +25 -0
- chia/protocols/pool_protocol.py +177 -0
- chia/protocols/protocol_message_types.py +139 -0
- chia/protocols/protocol_state_machine.py +87 -0
- chia/protocols/protocol_timing.py +8 -0
- chia/protocols/shared_protocol.py +86 -0
- chia/protocols/timelord_protocol.py +93 -0
- chia/protocols/wallet_protocol.py +401 -0
- chia/py.typed +0 -0
- chia/rpc/__init__.py +0 -0
- chia/rpc/crawler_rpc_api.py +80 -0
- chia/rpc/data_layer_rpc_api.py +644 -0
- chia/rpc/data_layer_rpc_client.py +188 -0
- chia/rpc/data_layer_rpc_util.py +58 -0
- chia/rpc/farmer_rpc_api.py +365 -0
- chia/rpc/farmer_rpc_client.py +86 -0
- chia/rpc/full_node_rpc_api.py +959 -0
- chia/rpc/full_node_rpc_client.py +292 -0
- chia/rpc/harvester_rpc_api.py +141 -0
- chia/rpc/harvester_rpc_client.py +54 -0
- chia/rpc/rpc_client.py +164 -0
- chia/rpc/rpc_server.py +521 -0
- chia/rpc/timelord_rpc_api.py +32 -0
- chia/rpc/util.py +93 -0
- chia/rpc/wallet_request_types.py +904 -0
- chia/rpc/wallet_rpc_api.py +4943 -0
- chia/rpc/wallet_rpc_client.py +1814 -0
- chia/seeder/__init__.py +0 -0
- chia/seeder/crawl_store.py +425 -0
- chia/seeder/crawler.py +410 -0
- chia/seeder/crawler_api.py +135 -0
- chia/seeder/dns_server.py +593 -0
- chia/seeder/peer_record.py +146 -0
- chia/seeder/start_crawler.py +92 -0
- chia/server/__init__.py +0 -0
- chia/server/address_manager.py +658 -0
- chia/server/address_manager_store.py +237 -0
- chia/server/api_protocol.py +116 -0
- chia/server/capabilities.py +24 -0
- chia/server/chia_policy.py +346 -0
- chia/server/introducer_peers.py +76 -0
- chia/server/node_discovery.py +714 -0
- chia/server/outbound_message.py +33 -0
- chia/server/rate_limit_numbers.py +214 -0
- chia/server/rate_limits.py +153 -0
- chia/server/server.py +741 -0
- chia/server/signal_handlers.py +120 -0
- chia/server/ssl_context.py +32 -0
- chia/server/start_data_layer.py +151 -0
- chia/server/start_farmer.py +98 -0
- chia/server/start_full_node.py +112 -0
- chia/server/start_harvester.py +93 -0
- chia/server/start_introducer.py +81 -0
- chia/server/start_service.py +316 -0
- chia/server/start_timelord.py +89 -0
- chia/server/start_wallet.py +113 -0
- chia/server/upnp.py +118 -0
- chia/server/ws_connection.py +766 -0
- chia/simulator/__init__.py +0 -0
- chia/simulator/add_blocks_in_batches.py +54 -0
- chia/simulator/block_tools.py +2054 -0
- chia/simulator/full_node_simulator.py +794 -0
- chia/simulator/keyring.py +128 -0
- chia/simulator/setup_services.py +506 -0
- chia/simulator/simulator_constants.py +13 -0
- chia/simulator/simulator_full_node_rpc_api.py +99 -0
- chia/simulator/simulator_full_node_rpc_client.py +60 -0
- chia/simulator/simulator_protocol.py +29 -0
- chia/simulator/simulator_test_tools.py +164 -0
- chia/simulator/socket.py +24 -0
- chia/simulator/ssl_certs.py +114 -0
- chia/simulator/ssl_certs_1.py +697 -0
- chia/simulator/ssl_certs_10.py +697 -0
- chia/simulator/ssl_certs_2.py +697 -0
- chia/simulator/ssl_certs_3.py +697 -0
- chia/simulator/ssl_certs_4.py +697 -0
- chia/simulator/ssl_certs_5.py +697 -0
- chia/simulator/ssl_certs_6.py +697 -0
- chia/simulator/ssl_certs_7.py +697 -0
- chia/simulator/ssl_certs_8.py +697 -0
- chia/simulator/ssl_certs_9.py +697 -0
- chia/simulator/start_simulator.py +143 -0
- chia/simulator/wallet_tools.py +246 -0
- chia/ssl/__init__.py +0 -0
- chia/ssl/chia_ca.crt +19 -0
- chia/ssl/chia_ca.key +28 -0
- chia/ssl/create_ssl.py +249 -0
- chia/ssl/dst_root_ca.pem +20 -0
- chia/timelord/__init__.py +0 -0
- chia/timelord/iters_from_block.py +50 -0
- chia/timelord/timelord.py +1226 -0
- chia/timelord/timelord_api.py +138 -0
- chia/timelord/timelord_launcher.py +190 -0
- chia/timelord/timelord_state.py +244 -0
- chia/timelord/types.py +22 -0
- chia/types/__init__.py +0 -0
- chia/types/aliases.py +35 -0
- chia/types/block_protocol.py +20 -0
- chia/types/blockchain_format/__init__.py +0 -0
- chia/types/blockchain_format/classgroup.py +5 -0
- chia/types/blockchain_format/coin.py +28 -0
- chia/types/blockchain_format/foliage.py +8 -0
- chia/types/blockchain_format/pool_target.py +5 -0
- chia/types/blockchain_format/program.py +269 -0
- chia/types/blockchain_format/proof_of_space.py +135 -0
- chia/types/blockchain_format/reward_chain_block.py +6 -0
- chia/types/blockchain_format/serialized_program.py +5 -0
- chia/types/blockchain_format/sized_bytes.py +11 -0
- chia/types/blockchain_format/slots.py +9 -0
- chia/types/blockchain_format/sub_epoch_summary.py +5 -0
- chia/types/blockchain_format/tree_hash.py +72 -0
- chia/types/blockchain_format/vdf.py +86 -0
- chia/types/clvm_cost.py +13 -0
- chia/types/coin_record.py +43 -0
- chia/types/coin_spend.py +115 -0
- chia/types/condition_opcodes.py +73 -0
- chia/types/condition_with_args.py +16 -0
- chia/types/eligible_coin_spends.py +365 -0
- chia/types/end_of_slot_bundle.py +5 -0
- chia/types/fee_rate.py +38 -0
- chia/types/full_block.py +5 -0
- chia/types/generator_types.py +13 -0
- chia/types/header_block.py +5 -0
- chia/types/internal_mempool_item.py +18 -0
- chia/types/mempool_inclusion_status.py +9 -0
- chia/types/mempool_item.py +85 -0
- chia/types/mempool_submission_status.py +30 -0
- chia/types/mojos.py +7 -0
- chia/types/peer_info.py +64 -0
- chia/types/signing_mode.py +29 -0
- chia/types/spend_bundle.py +30 -0
- chia/types/spend_bundle_conditions.py +7 -0
- chia/types/transaction_queue_entry.py +55 -0
- chia/types/unfinished_block.py +5 -0
- chia/types/unfinished_header_block.py +37 -0
- chia/types/validation_state.py +14 -0
- chia/types/weight_proof.py +49 -0
- chia/util/__init__.py +0 -0
- chia/util/action_scope.py +168 -0
- chia/util/async_pool.py +226 -0
- chia/util/augmented_chain.py +134 -0
- chia/util/batches.py +42 -0
- chia/util/bech32m.py +126 -0
- chia/util/beta_metrics.py +119 -0
- chia/util/block_cache.py +56 -0
- chia/util/byte_types.py +12 -0
- chia/util/check_fork_next_block.py +33 -0
- chia/util/chia_logging.py +144 -0
- chia/util/chia_version.py +33 -0
- chia/util/collection.py +17 -0
- chia/util/condition_tools.py +201 -0
- chia/util/config.py +367 -0
- chia/util/cpu.py +22 -0
- chia/util/db_synchronous.py +23 -0
- chia/util/db_version.py +32 -0
- chia/util/db_wrapper.py +430 -0
- chia/util/default_root.py +27 -0
- chia/util/dump_keyring.py +93 -0
- chia/util/english.txt +2048 -0
- chia/util/errors.py +353 -0
- chia/util/file_keyring.py +469 -0
- chia/util/files.py +97 -0
- chia/util/full_block_utils.py +345 -0
- chia/util/generator_tools.py +72 -0
- chia/util/hash.py +31 -0
- chia/util/initial-config.yaml +694 -0
- chia/util/inline_executor.py +26 -0
- chia/util/ints.py +19 -0
- chia/util/ip_address.py +39 -0
- chia/util/json_util.py +37 -0
- chia/util/keychain.py +676 -0
- chia/util/keyring_wrapper.py +327 -0
- chia/util/limited_semaphore.py +41 -0
- chia/util/lock.py +49 -0
- chia/util/log_exceptions.py +32 -0
- chia/util/logging.py +36 -0
- chia/util/lru_cache.py +31 -0
- chia/util/math.py +20 -0
- chia/util/network.py +182 -0
- chia/util/paginator.py +48 -0
- chia/util/path.py +31 -0
- chia/util/permissions.py +20 -0
- chia/util/prev_transaction_block.py +21 -0
- chia/util/priority_mutex.py +95 -0
- chia/util/profiler.py +197 -0
- chia/util/recursive_replace.py +24 -0
- chia/util/safe_cancel_task.py +16 -0
- chia/util/service_groups.py +47 -0
- chia/util/setproctitle.py +22 -0
- chia/util/significant_bits.py +32 -0
- chia/util/ssl_check.py +213 -0
- chia/util/streamable.py +642 -0
- chia/util/task_referencer.py +59 -0
- chia/util/task_timing.py +382 -0
- chia/util/timing.py +67 -0
- chia/util/vdf_prover.py +30 -0
- chia/util/virtual_project_analysis.py +540 -0
- chia/util/ws_message.py +66 -0
- chia/wallet/__init__.py +0 -0
- chia/wallet/cat_wallet/__init__.py +0 -0
- chia/wallet/cat_wallet/cat_constants.py +75 -0
- chia/wallet/cat_wallet/cat_info.py +47 -0
- chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
- chia/wallet/cat_wallet/cat_utils.py +164 -0
- chia/wallet/cat_wallet/cat_wallet.py +855 -0
- chia/wallet/cat_wallet/dao_cat_info.py +28 -0
- chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
- chia/wallet/cat_wallet/lineage_store.py +74 -0
- chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
- chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
- chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
- chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
- chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
- chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
- chia/wallet/coin_selection.py +188 -0
- chia/wallet/conditions.py +1512 -0
- chia/wallet/dao_wallet/__init__.py +0 -0
- chia/wallet/dao_wallet/dao_info.py +61 -0
- chia/wallet/dao_wallet/dao_utils.py +811 -0
- chia/wallet/dao_wallet/dao_wallet.py +2119 -0
- chia/wallet/db_wallet/__init__.py +0 -0
- chia/wallet/db_wallet/db_wallet_puzzles.py +111 -0
- chia/wallet/derivation_record.py +30 -0
- chia/wallet/derive_keys.py +146 -0
- chia/wallet/did_wallet/__init__.py +0 -0
- chia/wallet/did_wallet/did_info.py +39 -0
- chia/wallet/did_wallet/did_wallet.py +1494 -0
- chia/wallet/did_wallet/did_wallet_puzzles.py +221 -0
- chia/wallet/did_wallet/puzzles/__init__.py +0 -0
- chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
- chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
- chia/wallet/driver_protocol.py +26 -0
- chia/wallet/key_val_store.py +55 -0
- chia/wallet/lineage_proof.py +58 -0
- chia/wallet/nft_wallet/__init__.py +0 -0
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
- chia/wallet/nft_wallet/nft_info.py +120 -0
- chia/wallet/nft_wallet/nft_puzzles.py +305 -0
- chia/wallet/nft_wallet/nft_wallet.py +1687 -0
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
- chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
- chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
- chia/wallet/nft_wallet/uncurry_nft.py +217 -0
- chia/wallet/notification_manager.py +117 -0
- chia/wallet/notification_store.py +178 -0
- chia/wallet/outer_puzzles.py +84 -0
- chia/wallet/payment.py +33 -0
- chia/wallet/puzzle_drivers.py +118 -0
- chia/wallet/puzzles/__init__.py +0 -0
- chia/wallet/puzzles/augmented_condition.clsp +13 -0
- chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
- chia/wallet/puzzles/clawback/__init__.py +0 -0
- chia/wallet/puzzles/clawback/drivers.py +188 -0
- chia/wallet/puzzles/clawback/metadata.py +38 -0
- chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
- chia/wallet/puzzles/condition_codes.clib +77 -0
- chia/wallet/puzzles/curry-and-treehash.clib +102 -0
- chia/wallet/puzzles/curry.clib +135 -0
- chia/wallet/puzzles/curry_by_index.clib +16 -0
- chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
- chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
- chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
- chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
- chia/wallet/puzzles/dao_finished_state.clsp +35 -0
- chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
- chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_lockup.clsp +288 -0
- chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
- chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal.clsp +377 -0
- chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_treasury.clsp +115 -0
- chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
- chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
- chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
- chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
- chia/wallet/puzzles/json.clib +25 -0
- chia/wallet/puzzles/load_clvm.py +161 -0
- chia/wallet/puzzles/merkle_utils.clib +18 -0
- chia/wallet/puzzles/notification.clsp +7 -0
- chia/wallet/puzzles/notification.clsp.hex +1 -0
- chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
- chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
- chia/wallet/puzzles/p2_conditions.clsp +3 -0
- chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
- chia/wallet/puzzles/p2_conditions.py +26 -0
- chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
- chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_conditions.py +21 -0
- chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
- chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_puzzle.py +34 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +160 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +21 -0
- chia/wallet/puzzles/p2_parent.clsp +19 -0
- chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
- chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
- chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
- chia/wallet/puzzles/p2_puzzle_hash.py +27 -0
- chia/wallet/puzzles/p2_singleton.clsp +30 -0
- chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
- chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
- chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
- chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/puzzle_utils.py +34 -0
- chia/wallet/puzzles/settlement_payments.clsp +49 -0
- chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
- chia/wallet/puzzles/sha256tree.clib +11 -0
- chia/wallet/puzzles/singleton_launcher.clsp +16 -0
- chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
- chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer.py +296 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +345 -0
- chia/wallet/puzzles/singleton_truths.clib +21 -0
- chia/wallet/puzzles/tails.py +348 -0
- chia/wallet/puzzles/utility_macros.clib +48 -0
- chia/wallet/signer_protocol.py +125 -0
- chia/wallet/singleton.py +106 -0
- chia/wallet/singleton_record.py +30 -0
- chia/wallet/trade_manager.py +1102 -0
- chia/wallet/trade_record.py +67 -0
- chia/wallet/trading/__init__.py +0 -0
- chia/wallet/trading/offer.py +702 -0
- chia/wallet/trading/trade_status.py +13 -0
- chia/wallet/trading/trade_store.py +526 -0
- chia/wallet/transaction_record.py +158 -0
- chia/wallet/transaction_sorting.py +14 -0
- chia/wallet/uncurried_puzzle.py +17 -0
- chia/wallet/util/__init__.py +0 -0
- chia/wallet/util/address_type.py +55 -0
- chia/wallet/util/blind_signer_tl.py +164 -0
- chia/wallet/util/clvm_streamable.py +203 -0
- chia/wallet/util/compute_hints.py +66 -0
- chia/wallet/util/compute_memos.py +43 -0
- chia/wallet/util/curry_and_treehash.py +91 -0
- chia/wallet/util/debug_spend_bundle.py +232 -0
- chia/wallet/util/merkle_tree.py +100 -0
- chia/wallet/util/merkle_utils.py +102 -0
- chia/wallet/util/new_peak_queue.py +82 -0
- chia/wallet/util/notifications.py +12 -0
- chia/wallet/util/peer_request_cache.py +174 -0
- chia/wallet/util/pprint.py +39 -0
- chia/wallet/util/puzzle_compression.py +95 -0
- chia/wallet/util/puzzle_decorator.py +100 -0
- chia/wallet/util/puzzle_decorator_type.py +7 -0
- chia/wallet/util/query_filter.py +59 -0
- chia/wallet/util/transaction_type.py +23 -0
- chia/wallet/util/tx_config.py +158 -0
- chia/wallet/util/wallet_sync_utils.py +351 -0
- chia/wallet/util/wallet_types.py +72 -0
- chia/wallet/vc_wallet/__init__.py +0 -0
- chia/wallet/vc_wallet/cr_cat_drivers.py +664 -0
- chia/wallet/vc_wallet/cr_cat_wallet.py +877 -0
- chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
- chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
- chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
- chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
- chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
- chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
- chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
- chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_drivers.py +838 -0
- chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
- chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
- chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
- chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
- chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
- chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
- chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
- chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_store.py +263 -0
- chia/wallet/vc_wallet/vc_wallet.py +638 -0
- chia/wallet/wallet.py +698 -0
- chia/wallet/wallet_action_scope.py +96 -0
- chia/wallet/wallet_blockchain.py +244 -0
- chia/wallet/wallet_coin_record.py +72 -0
- chia/wallet/wallet_coin_store.py +351 -0
- chia/wallet/wallet_info.py +35 -0
- chia/wallet/wallet_interested_store.py +188 -0
- chia/wallet/wallet_nft_store.py +279 -0
- chia/wallet/wallet_node.py +1765 -0
- chia/wallet/wallet_node_api.py +207 -0
- chia/wallet/wallet_pool_store.py +119 -0
- chia/wallet/wallet_protocol.py +90 -0
- chia/wallet/wallet_puzzle_store.py +396 -0
- chia/wallet/wallet_retry_store.py +70 -0
- chia/wallet/wallet_singleton_store.py +259 -0
- chia/wallet/wallet_spend_bundle.py +25 -0
- chia/wallet/wallet_state_manager.py +2819 -0
- chia/wallet/wallet_transaction_store.py +496 -0
- chia/wallet/wallet_user_store.py +110 -0
- chia/wallet/wallet_weight_proof_handler.py +126 -0
- chia_blockchain-2.5.1rc1.dist-info/LICENSE +201 -0
- chia_blockchain-2.5.1rc1.dist-info/METADATA +156 -0
- chia_blockchain-2.5.1rc1.dist-info/RECORD +1042 -0
- chia_blockchain-2.5.1rc1.dist-info/WHEEL +4 -0
- chia_blockchain-2.5.1rc1.dist-info/entry_points.txt +17 -0
- mozilla-ca/cacert.pem +3611 -0
|
@@ -0,0 +1,1174 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from asyncio import Queue
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
from collections.abc import AsyncGenerator
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from random import Random
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
from chia_rs import AugSchemeMPL, Coin, CoinSpend, CoinState, Program
|
|
12
|
+
|
|
13
|
+
from chia._tests.connection_utils import add_dummy_connection
|
|
14
|
+
from chia.full_node.coin_store import CoinStore
|
|
15
|
+
from chia.full_node.full_node import FullNode
|
|
16
|
+
from chia.full_node.mempool import MempoolRemoveReason
|
|
17
|
+
from chia.protocols import wallet_protocol
|
|
18
|
+
from chia.protocols.protocol_message_types import ProtocolMessageTypes
|
|
19
|
+
from chia.protocols.shared_protocol import Capability
|
|
20
|
+
from chia.server.outbound_message import Message, NodeType
|
|
21
|
+
from chia.server.ws_connection import WSChiaConnection
|
|
22
|
+
from chia.simulator import simulator_protocol
|
|
23
|
+
from chia.simulator.block_tools import BlockTools
|
|
24
|
+
from chia.simulator.full_node_simulator import FullNodeSimulator
|
|
25
|
+
from chia.simulator.start_simulator import SimulatorFullNodeService
|
|
26
|
+
from chia.types.aliases import WalletService
|
|
27
|
+
from chia.types.blockchain_format.sized_bytes import bytes32
|
|
28
|
+
from chia.types.coin_record import CoinRecord
|
|
29
|
+
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
|
|
30
|
+
from chia.types.spend_bundle import SpendBundle
|
|
31
|
+
from chia.util.hash import std_hash
|
|
32
|
+
from chia.util.ints import uint8, uint16, uint32, uint64
|
|
33
|
+
|
|
34
|
+
IDENTITY_PUZZLE = Program.to(1)
|
|
35
|
+
IDENTITY_PUZZLE_HASH = IDENTITY_PUZZLE.get_tree_hash()
|
|
36
|
+
|
|
37
|
+
OneNode = tuple[list[SimulatorFullNodeService], list[WalletService], BlockTools]
|
|
38
|
+
Mpu = tuple[FullNodeSimulator, Queue[Message], WSChiaConnection]
|
|
39
|
+
|
|
40
|
+
ALL_FILTER = wallet_protocol.CoinStateFilters(True, True, True, uint64(0))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
async def connect_to_simulator(
|
|
44
|
+
one_node: OneNode, self_hostname: str, mempool_updates: bool = True
|
|
45
|
+
) -> tuple[FullNodeSimulator, Queue[Message], WSChiaConnection]:
|
|
46
|
+
[full_node_service], _, _ = one_node
|
|
47
|
+
|
|
48
|
+
full_node_api = full_node_service._api
|
|
49
|
+
fn_server = full_node_api.server
|
|
50
|
+
|
|
51
|
+
incoming_queue, peer_id = await add_dummy_connection(
|
|
52
|
+
fn_server,
|
|
53
|
+
self_hostname,
|
|
54
|
+
41723,
|
|
55
|
+
NodeType.WALLET,
|
|
56
|
+
additional_capabilities=[(uint16(Capability.MEMPOOL_UPDATES), "1")] if mempool_updates else [],
|
|
57
|
+
)
|
|
58
|
+
peer = fn_server.all_connections[peer_id]
|
|
59
|
+
|
|
60
|
+
return full_node_api, incoming_queue, peer
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@pytest.mark.anyio
|
|
64
|
+
async def test_puzzle_subscriptions(one_node: OneNode, self_hostname: str) -> None:
|
|
65
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
66
|
+
subs = simulator.full_node.subscriptions
|
|
67
|
+
genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
|
|
68
|
+
|
|
69
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
70
|
+
|
|
71
|
+
ph1 = bytes32(b"\x01" * 32)
|
|
72
|
+
ph2 = bytes32(b"\x02" * 32)
|
|
73
|
+
ph3 = bytes32(b"\x03" * 32)
|
|
74
|
+
|
|
75
|
+
# Add puzzle subscriptions, ignore duplicates
|
|
76
|
+
# Response can be in any order
|
|
77
|
+
resp = await simulator.request_puzzle_state(
|
|
78
|
+
wallet_protocol.RequestPuzzleState(
|
|
79
|
+
[ph1, ph2, ph2],
|
|
80
|
+
None,
|
|
81
|
+
genesis_challenge,
|
|
82
|
+
wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
|
|
83
|
+
True,
|
|
84
|
+
),
|
|
85
|
+
peer,
|
|
86
|
+
)
|
|
87
|
+
assert resp is not None
|
|
88
|
+
|
|
89
|
+
add_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
90
|
+
assert set(add_response.puzzle_hashes) == {ph1, ph2}
|
|
91
|
+
|
|
92
|
+
assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2}
|
|
93
|
+
|
|
94
|
+
# Add another puzzle hash and existing ones
|
|
95
|
+
resp = await simulator.request_puzzle_state(
|
|
96
|
+
wallet_protocol.RequestPuzzleState(
|
|
97
|
+
[ph1, ph2, ph3],
|
|
98
|
+
None,
|
|
99
|
+
genesis_challenge,
|
|
100
|
+
wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
|
|
101
|
+
True,
|
|
102
|
+
),
|
|
103
|
+
peer,
|
|
104
|
+
)
|
|
105
|
+
assert resp is not None
|
|
106
|
+
|
|
107
|
+
add_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
108
|
+
assert set(add_response.puzzle_hashes) == {ph1, ph2, ph3}
|
|
109
|
+
|
|
110
|
+
assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2, ph3}
|
|
111
|
+
|
|
112
|
+
# Remove puzzle subscriptions
|
|
113
|
+
# Ignore duplicates or missing subscriptions
|
|
114
|
+
resp = await simulator.request_remove_puzzle_subscriptions(
|
|
115
|
+
wallet_protocol.RequestRemovePuzzleSubscriptions([ph1, ph1, ph2]), peer
|
|
116
|
+
)
|
|
117
|
+
assert resp is not None
|
|
118
|
+
|
|
119
|
+
remove_response = wallet_protocol.RespondRemovePuzzleSubscriptions.from_bytes(resp.data)
|
|
120
|
+
assert set(remove_response.puzzle_hashes) == {ph1, ph2}
|
|
121
|
+
|
|
122
|
+
assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph3}
|
|
123
|
+
|
|
124
|
+
# Clear all puzzle subscriptions.
|
|
125
|
+
resp = await simulator.request_remove_puzzle_subscriptions(
|
|
126
|
+
wallet_protocol.RequestRemovePuzzleSubscriptions(None), peer
|
|
127
|
+
)
|
|
128
|
+
assert resp is not None
|
|
129
|
+
|
|
130
|
+
remove_response = wallet_protocol.RespondRemovePuzzleSubscriptions.from_bytes(resp.data)
|
|
131
|
+
assert set(remove_response.puzzle_hashes) == {ph3}
|
|
132
|
+
|
|
133
|
+
assert len(subs.puzzle_subscriptions(peer.peer_node_id)) == 0
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@pytest.mark.anyio
|
|
137
|
+
async def test_coin_subscriptions(one_node: OneNode, self_hostname: str) -> None:
|
|
138
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
139
|
+
subs = simulator.full_node.subscriptions
|
|
140
|
+
genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
|
|
141
|
+
|
|
142
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
143
|
+
|
|
144
|
+
coin1 = bytes32(b"\x01" * 32)
|
|
145
|
+
coin2 = bytes32(b"\x02" * 32)
|
|
146
|
+
coin3 = bytes32(b"\x03" * 32)
|
|
147
|
+
|
|
148
|
+
# Add coin subscriptions, ignore duplicates
|
|
149
|
+
# Response can be in any order
|
|
150
|
+
resp = await simulator.request_coin_state(
|
|
151
|
+
wallet_protocol.RequestCoinState([coin1, coin2, coin2], None, genesis_challenge, True), peer
|
|
152
|
+
)
|
|
153
|
+
assert resp is not None
|
|
154
|
+
|
|
155
|
+
add_response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
|
|
156
|
+
assert set(add_response.coin_ids) == {coin1, coin2}
|
|
157
|
+
|
|
158
|
+
assert subs.coin_subscriptions(peer.peer_node_id) == {coin1, coin2}
|
|
159
|
+
|
|
160
|
+
# Add another puzzle hash and existing ones
|
|
161
|
+
resp = await simulator.request_coin_state(
|
|
162
|
+
wallet_protocol.RequestCoinState([coin1, coin2, coin3], None, genesis_challenge, True), peer
|
|
163
|
+
)
|
|
164
|
+
assert resp is not None
|
|
165
|
+
|
|
166
|
+
add_response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
|
|
167
|
+
assert set(add_response.coin_ids) == {coin1, coin2, coin3}
|
|
168
|
+
|
|
169
|
+
assert subs.coin_subscriptions(peer.peer_node_id) == {coin1, coin2, coin3}
|
|
170
|
+
|
|
171
|
+
# Remove coin subscriptions
|
|
172
|
+
# Ignore duplicates or missing subscriptions
|
|
173
|
+
resp = await simulator.request_remove_coin_subscriptions(
|
|
174
|
+
wallet_protocol.RequestRemoveCoinSubscriptions([coin1, coin1, coin2]), peer
|
|
175
|
+
)
|
|
176
|
+
assert resp is not None
|
|
177
|
+
|
|
178
|
+
remove_response = wallet_protocol.RespondRemoveCoinSubscriptions.from_bytes(resp.data)
|
|
179
|
+
assert set(remove_response.coin_ids) == {coin1, coin2}
|
|
180
|
+
|
|
181
|
+
assert subs.coin_subscriptions(peer.peer_node_id) == {coin3}
|
|
182
|
+
|
|
183
|
+
# Clear all coin subscriptions.
|
|
184
|
+
resp = await simulator.request_remove_coin_subscriptions(wallet_protocol.RequestRemoveCoinSubscriptions(None), peer)
|
|
185
|
+
assert resp is not None
|
|
186
|
+
|
|
187
|
+
remove_response = wallet_protocol.RespondRemoveCoinSubscriptions.from_bytes(resp.data)
|
|
188
|
+
assert set(remove_response.coin_ids) == {coin3}
|
|
189
|
+
|
|
190
|
+
assert len(subs.coin_subscriptions(peer.peer_node_id)) == 0
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@pytest.mark.anyio
|
|
194
|
+
async def test_subscription_limits(one_node: OneNode, self_hostname: str) -> None:
|
|
195
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
196
|
+
subs = simulator.full_node.subscriptions
|
|
197
|
+
genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
|
|
198
|
+
|
|
199
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
200
|
+
|
|
201
|
+
# This is a safe limit for this test that will fit within the current maximum in `RequestPuzzleState`.
|
|
202
|
+
simulator.full_node.config["max_subscribe_items"] = CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE
|
|
203
|
+
|
|
204
|
+
max_subs = simulator.max_subscriptions(peer)
|
|
205
|
+
puzzle_hashes = [std_hash(i.to_bytes(4, byteorder="big", signed=False)) for i in range(max_subs + 100)]
|
|
206
|
+
|
|
207
|
+
# Add puzzle subscriptions to the limit
|
|
208
|
+
first_batch = puzzle_hashes[: CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE]
|
|
209
|
+
first_batch_set = set(first_batch)
|
|
210
|
+
|
|
211
|
+
resp = await simulator.request_puzzle_state(
|
|
212
|
+
wallet_protocol.RequestPuzzleState(
|
|
213
|
+
first_batch, None, genesis_challenge, wallet_protocol.CoinStateFilters(False, False, False, uint64(0)), True
|
|
214
|
+
),
|
|
215
|
+
peer,
|
|
216
|
+
)
|
|
217
|
+
assert resp is not None
|
|
218
|
+
|
|
219
|
+
add_ph_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
220
|
+
assert set(add_ph_response.puzzle_hashes) == first_batch_set
|
|
221
|
+
|
|
222
|
+
assert subs.puzzle_subscriptions(peer.peer_node_id) == first_batch_set
|
|
223
|
+
|
|
224
|
+
# Try to add the remaining subscriptions
|
|
225
|
+
resp = await simulator.request_puzzle_state(
|
|
226
|
+
wallet_protocol.RequestPuzzleState(
|
|
227
|
+
puzzle_hashes[CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE :],
|
|
228
|
+
None,
|
|
229
|
+
genesis_challenge,
|
|
230
|
+
wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
|
|
231
|
+
True,
|
|
232
|
+
),
|
|
233
|
+
peer,
|
|
234
|
+
)
|
|
235
|
+
assert resp is not None
|
|
236
|
+
|
|
237
|
+
overflow_ph_response = wallet_protocol.RejectPuzzleState.from_bytes(resp.data)
|
|
238
|
+
assert overflow_ph_response == wallet_protocol.RejectPuzzleState(
|
|
239
|
+
uint8(wallet_protocol.RejectStateReason.EXCEEDED_SUBSCRIPTION_LIMIT)
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
assert subs.puzzle_subscriptions(peer.peer_node_id) == first_batch_set
|
|
243
|
+
|
|
244
|
+
# Try to overflow with coin subscriptions
|
|
245
|
+
resp = await simulator.request_coin_state(
|
|
246
|
+
wallet_protocol.RequestCoinState([bytes32(b"coin" * 8)], None, genesis_challenge, True), peer
|
|
247
|
+
)
|
|
248
|
+
assert resp is not None
|
|
249
|
+
|
|
250
|
+
overflow_coin_response = wallet_protocol.RejectCoinState.from_bytes(resp.data)
|
|
251
|
+
assert overflow_coin_response == wallet_protocol.RejectCoinState(
|
|
252
|
+
uint8(wallet_protocol.RejectStateReason.EXCEEDED_SUBSCRIPTION_LIMIT)
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
@pytest.mark.anyio
|
|
257
|
+
async def test_request_coin_state(one_node: OneNode, self_hostname: str) -> None:
|
|
258
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
259
|
+
|
|
260
|
+
genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
|
|
261
|
+
assert genesis is not None
|
|
262
|
+
|
|
263
|
+
# Add coin records
|
|
264
|
+
coin_records = [
|
|
265
|
+
CoinRecord(
|
|
266
|
+
coin=Coin(bytes32.zeros, bytes32.zeros, uint64(i)),
|
|
267
|
+
confirmed_block_index=uint32(1),
|
|
268
|
+
spent_block_index=uint32(1 if i % 2 == 0 else 0),
|
|
269
|
+
coinbase=False,
|
|
270
|
+
timestamp=uint64(0),
|
|
271
|
+
)
|
|
272
|
+
for i in range(50)
|
|
273
|
+
]
|
|
274
|
+
ignored_coin = CoinRecord(
|
|
275
|
+
coin=Coin(bytes32(b"\1" * 32), bytes32(b"\1" * 32), uint64(1)),
|
|
276
|
+
confirmed_block_index=uint32(1),
|
|
277
|
+
spent_block_index=uint32(2),
|
|
278
|
+
coinbase=False,
|
|
279
|
+
timestamp=uint64(1),
|
|
280
|
+
)
|
|
281
|
+
await simulator.full_node.coin_store._add_coin_records([*coin_records, ignored_coin])
|
|
282
|
+
|
|
283
|
+
# Request no coin states
|
|
284
|
+
resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState([], None, genesis, False), peer)
|
|
285
|
+
assert resp is not None
|
|
286
|
+
|
|
287
|
+
response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
|
|
288
|
+
|
|
289
|
+
assert len(response.coin_ids) == 0
|
|
290
|
+
assert len(response.coin_states) == 0
|
|
291
|
+
|
|
292
|
+
# Request coin state
|
|
293
|
+
coin_ids = [cr.coin.name() for cr in coin_records]
|
|
294
|
+
|
|
295
|
+
resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState(coin_ids, None, genesis, False), peer)
|
|
296
|
+
assert resp is not None
|
|
297
|
+
|
|
298
|
+
response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
|
|
299
|
+
|
|
300
|
+
assert response.coin_ids == coin_ids
|
|
301
|
+
assert set(response.coin_states) == {cr.coin_state for cr in coin_records}
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
@pytest.mark.anyio
|
|
305
|
+
async def test_request_coin_state_and_subscribe(one_node: OneNode, self_hostname: str) -> None:
|
|
306
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
307
|
+
|
|
308
|
+
genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
|
|
309
|
+
assert genesis is not None
|
|
310
|
+
|
|
311
|
+
c1 = bytes32(b"1" * 32)
|
|
312
|
+
c2 = bytes32(b"2" * 32)
|
|
313
|
+
c3 = bytes32(b"3" * 32)
|
|
314
|
+
c4 = bytes32(b"4" * 32)
|
|
315
|
+
|
|
316
|
+
# Request initial state (empty in this case) and subscribe
|
|
317
|
+
resp = await simulator.request_coin_state(
|
|
318
|
+
wallet_protocol.RequestCoinState([c1, c2, c3, c3, c4], None, genesis, True), peer
|
|
319
|
+
)
|
|
320
|
+
assert resp is not None
|
|
321
|
+
|
|
322
|
+
response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
|
|
323
|
+
|
|
324
|
+
assert len(response.coin_ids) == 4
|
|
325
|
+
assert len(response.coin_states) == 0
|
|
326
|
+
|
|
327
|
+
# Make sure the subscriptions were added
|
|
328
|
+
assert simulator.full_node.subscriptions.coin_subscriptions(peer.peer_node_id) == {c1, c2, c3, c4}
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
@pytest.mark.anyio
|
|
332
|
+
async def test_request_coin_state_reorg(one_node: OneNode, self_hostname: str) -> None:
|
|
333
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
334
|
+
|
|
335
|
+
# Farm block
|
|
336
|
+
await simulator.farm_blocks_to_puzzlehash(8)
|
|
337
|
+
|
|
338
|
+
header_hash = simulator.full_node.blockchain.height_to_hash(uint32(5))
|
|
339
|
+
assert header_hash is not None
|
|
340
|
+
|
|
341
|
+
# Reorg
|
|
342
|
+
await simulator.reorg_from_index_to_new_index(
|
|
343
|
+
simulator_protocol.ReorgProtocol(uint32(3), uint32(10), bytes32(b"\1" * 32), bytes32.zeros)
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
# Request coin state, should reject due to reorg
|
|
347
|
+
resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState([], uint32(5), header_hash, False), peer)
|
|
348
|
+
assert resp is not None
|
|
349
|
+
|
|
350
|
+
assert wallet_protocol.RejectCoinState.from_bytes(resp.data) == wallet_protocol.RejectCoinState(
|
|
351
|
+
uint8(wallet_protocol.RejectStateReason.REORG)
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
@pytest.mark.anyio
|
|
356
|
+
async def test_request_coin_state_limit(one_node: OneNode, self_hostname: str) -> None:
|
|
357
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
358
|
+
|
|
359
|
+
# Farm blocks 0-11 and make sure the last one is farmed
|
|
360
|
+
await simulator.farm_blocks_to_puzzlehash(12)
|
|
361
|
+
|
|
362
|
+
h0 = simulator.full_node.blockchain.height_to_hash(uint32(0))
|
|
363
|
+
assert h0 is not None
|
|
364
|
+
|
|
365
|
+
h1 = simulator.full_node.blockchain.height_to_hash(uint32(1))
|
|
366
|
+
assert h1 is not None
|
|
367
|
+
|
|
368
|
+
# Add more than the max response coin records
|
|
369
|
+
coin_records: OrderedDict[bytes32, CoinRecord] = OrderedDict()
|
|
370
|
+
for height in range(1, 12):
|
|
371
|
+
for i in range(10000):
|
|
372
|
+
coin_record = CoinRecord(
|
|
373
|
+
coin=Coin(std_hash(i.to_bytes(4, "big")), std_hash(height.to_bytes(4, "big")), uint64(i)),
|
|
374
|
+
confirmed_block_index=uint32(height),
|
|
375
|
+
spent_block_index=uint32(0),
|
|
376
|
+
coinbase=False,
|
|
377
|
+
timestamp=uint64(472618),
|
|
378
|
+
)
|
|
379
|
+
coin_records[coin_record.coin.name()] = coin_record
|
|
380
|
+
|
|
381
|
+
await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
|
|
382
|
+
|
|
383
|
+
# Fetch the coin records using the wallet protocol,
|
|
384
|
+
# with more coin ids than the limit of 100,000, but only after height 10000.
|
|
385
|
+
resp = await simulator.request_coin_state(
|
|
386
|
+
wallet_protocol.RequestCoinState(list(coin_records.keys()), uint32(1), h1, False),
|
|
387
|
+
peer,
|
|
388
|
+
)
|
|
389
|
+
assert resp is not None
|
|
390
|
+
|
|
391
|
+
response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
|
|
392
|
+
|
|
393
|
+
assert response.coin_ids == list(coin_records.keys())[:100000]
|
|
394
|
+
assert len(response.coin_states) == len(coin_records) - 20000
|
|
395
|
+
|
|
396
|
+
for coin_state in response.coin_states:
|
|
397
|
+
coin_record = coin_records[coin_state.coin.name()]
|
|
398
|
+
assert coin_record.coin_state == coin_state
|
|
399
|
+
assert coin_record.confirmed_block_index > 1
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
@pytest.mark.anyio
|
|
403
|
+
async def test_request_puzzle_state(one_node: OneNode, self_hostname: str) -> None:
|
|
404
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
405
|
+
|
|
406
|
+
# Farm block to a puzzle hash we aren't looking at
|
|
407
|
+
await simulator.farm_blocks_to_puzzlehash(3, farm_to=bytes32(b"\x0a" * 32))
|
|
408
|
+
|
|
409
|
+
genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
|
|
410
|
+
|
|
411
|
+
peak_height = simulator.full_node.blockchain.get_peak_height()
|
|
412
|
+
assert peak_height is not None
|
|
413
|
+
|
|
414
|
+
peak_header_hash = simulator.full_node.blockchain.height_to_hash(peak_height)
|
|
415
|
+
assert peak_header_hash is not None
|
|
416
|
+
|
|
417
|
+
# Add coin records
|
|
418
|
+
coin_records: list[CoinRecord] = []
|
|
419
|
+
puzzle_hashes: list[bytes32] = []
|
|
420
|
+
|
|
421
|
+
for ph_i in range(10):
|
|
422
|
+
puzzle_hash = bytes32(ph_i.to_bytes(1, "big") * 32)
|
|
423
|
+
puzzle_hashes.append(puzzle_hash)
|
|
424
|
+
|
|
425
|
+
for i in range(5):
|
|
426
|
+
coin_records.append(
|
|
427
|
+
CoinRecord(
|
|
428
|
+
coin=Coin(bytes32.zeros, puzzle_hash, uint64(i)),
|
|
429
|
+
confirmed_block_index=uint32(1),
|
|
430
|
+
spent_block_index=uint32(1 if i % 2 == 0 else 0),
|
|
431
|
+
coinbase=False,
|
|
432
|
+
timestamp=uint64(0),
|
|
433
|
+
)
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
ignored_coin = CoinRecord(
|
|
437
|
+
coin=Coin(bytes32(b"\1" * 32), bytes32(b"\1" * 31 + b"\0"), uint64(1)),
|
|
438
|
+
confirmed_block_index=uint32(1),
|
|
439
|
+
spent_block_index=uint32(2),
|
|
440
|
+
coinbase=False,
|
|
441
|
+
timestamp=uint64(1),
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
await simulator.full_node.coin_store._add_coin_records([*coin_records, ignored_coin])
|
|
445
|
+
|
|
446
|
+
# We already test permutations of CoinStateFilters in the CoinStore tests
|
|
447
|
+
# So it's redundant to do so here
|
|
448
|
+
filters = wallet_protocol.CoinStateFilters(True, True, True, uint64(0))
|
|
449
|
+
|
|
450
|
+
# Request no coin states
|
|
451
|
+
resp = await simulator.request_puzzle_state(
|
|
452
|
+
wallet_protocol.RequestPuzzleState([], None, genesis, filters, False), peer
|
|
453
|
+
)
|
|
454
|
+
assert resp is not None
|
|
455
|
+
|
|
456
|
+
response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
457
|
+
|
|
458
|
+
# The peak height and header hash is returned when you are caught up to the peak
|
|
459
|
+
assert response == wallet_protocol.RespondPuzzleState([], peak_height, peak_header_hash, True, [])
|
|
460
|
+
|
|
461
|
+
# Request coin state
|
|
462
|
+
resp = await simulator.request_puzzle_state(
|
|
463
|
+
wallet_protocol.RequestPuzzleState(puzzle_hashes, None, genesis, filters, False), peer
|
|
464
|
+
)
|
|
465
|
+
assert resp is not None
|
|
466
|
+
|
|
467
|
+
response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
468
|
+
|
|
469
|
+
assert response.puzzle_hashes == puzzle_hashes
|
|
470
|
+
assert set(response.coin_states) == {cr.coin_state for cr in coin_records}
|
|
471
|
+
|
|
472
|
+
assert response.height == peak_height
|
|
473
|
+
assert response.header_hash == peak_header_hash
|
|
474
|
+
|
|
475
|
+
assert response.is_finished
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
@pytest.mark.anyio
|
|
479
|
+
async def test_request_puzzle_state_and_subscribe(one_node: OneNode, self_hostname: str) -> None:
|
|
480
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
481
|
+
|
|
482
|
+
# You have to farm a block so there is a peak.
|
|
483
|
+
# Otherwise you will get an AssertionError from `request_puzzle_state`.
|
|
484
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
485
|
+
|
|
486
|
+
genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
|
|
487
|
+
assert genesis is not None
|
|
488
|
+
|
|
489
|
+
ph1 = bytes32(b"1" * 32)
|
|
490
|
+
ph2 = bytes32(b"2" * 32)
|
|
491
|
+
ph3 = bytes32(b"3" * 32)
|
|
492
|
+
ph4 = bytes32(b"4" * 32)
|
|
493
|
+
|
|
494
|
+
# Request initial state (empty in this case) and subscribe
|
|
495
|
+
resp = await simulator.request_puzzle_state(
|
|
496
|
+
wallet_protocol.RequestPuzzleState(
|
|
497
|
+
[ph1, ph2, ph3, ph3, ph4],
|
|
498
|
+
None,
|
|
499
|
+
genesis,
|
|
500
|
+
wallet_protocol.CoinStateFilters(True, True, True, uint64(0)),
|
|
501
|
+
True,
|
|
502
|
+
),
|
|
503
|
+
peer,
|
|
504
|
+
)
|
|
505
|
+
assert resp is not None
|
|
506
|
+
|
|
507
|
+
response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
508
|
+
|
|
509
|
+
assert len(response.puzzle_hashes) == 4
|
|
510
|
+
assert len(response.coin_states) == 0
|
|
511
|
+
|
|
512
|
+
# Make sure the subscriptions were added
|
|
513
|
+
assert simulator.full_node.subscriptions.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2, ph3, ph4}
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
@pytest.mark.anyio
|
|
517
|
+
async def test_request_puzzle_state_reorg(one_node: OneNode, self_hostname: str) -> None:
|
|
518
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
519
|
+
|
|
520
|
+
# Farm block
|
|
521
|
+
await simulator.farm_blocks_to_puzzlehash(8)
|
|
522
|
+
|
|
523
|
+
header_hash = simulator.full_node.blockchain.height_to_hash(uint32(5))
|
|
524
|
+
assert header_hash is not None
|
|
525
|
+
|
|
526
|
+
# Reorg
|
|
527
|
+
await simulator.reorg_from_index_to_new_index(
|
|
528
|
+
simulator_protocol.ReorgProtocol(uint32(3), uint32(10), bytes32(b"\1" * 32), bytes32.zeros)
|
|
529
|
+
)
|
|
530
|
+
|
|
531
|
+
# Request coin state, should reject due to reorg
|
|
532
|
+
resp = await simulator.request_puzzle_state(
|
|
533
|
+
wallet_protocol.RequestPuzzleState(
|
|
534
|
+
[], uint32(5), header_hash, wallet_protocol.CoinStateFilters(True, True, True, uint64(0)), False
|
|
535
|
+
),
|
|
536
|
+
peer,
|
|
537
|
+
)
|
|
538
|
+
assert resp is not None
|
|
539
|
+
|
|
540
|
+
assert wallet_protocol.RejectPuzzleState.from_bytes(resp.data) == wallet_protocol.RejectPuzzleState(
|
|
541
|
+
uint8(wallet_protocol.RejectStateReason.REORG)
|
|
542
|
+
)
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
@pytest.mark.anyio
|
|
546
|
+
async def test_request_puzzle_state_limit(one_node: OneNode, self_hostname: str) -> None:
|
|
547
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
548
|
+
|
|
549
|
+
# Farm blocks 0-11 and make sure the last one is farmed
|
|
550
|
+
await simulator.farm_blocks_to_puzzlehash(12)
|
|
551
|
+
|
|
552
|
+
h0 = simulator.full_node.blockchain.height_to_hash(uint32(0))
|
|
553
|
+
assert h0 is not None
|
|
554
|
+
|
|
555
|
+
h1 = simulator.full_node.blockchain.height_to_hash(uint32(1))
|
|
556
|
+
assert h1 is not None
|
|
557
|
+
|
|
558
|
+
# Add more than the max response coin records
|
|
559
|
+
coin_records: OrderedDict[bytes32, CoinRecord] = OrderedDict()
|
|
560
|
+
ph = bytes32(b"\1" * 32)
|
|
561
|
+
|
|
562
|
+
for height in range(1, 12):
|
|
563
|
+
for i in range(10000):
|
|
564
|
+
coin_record = CoinRecord(
|
|
565
|
+
coin=Coin(std_hash(i.to_bytes(4, "big")), ph, uint64(height)),
|
|
566
|
+
confirmed_block_index=uint32(height),
|
|
567
|
+
spent_block_index=uint32(0),
|
|
568
|
+
coinbase=False,
|
|
569
|
+
timestamp=uint64(472618),
|
|
570
|
+
)
|
|
571
|
+
coin_records[coin_record.coin.name()] = coin_record
|
|
572
|
+
|
|
573
|
+
await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
|
|
574
|
+
|
|
575
|
+
# Fetch the coin records using the wallet protocol,
|
|
576
|
+
# only after height 10000, so that the limit of 100000 isn't exceeded
|
|
577
|
+
resp = await simulator.request_puzzle_state(
|
|
578
|
+
wallet_protocol.RequestPuzzleState(
|
|
579
|
+
[ph], uint32(1), h1, wallet_protocol.CoinStateFilters(True, True, True, uint64(0)), False
|
|
580
|
+
),
|
|
581
|
+
peer,
|
|
582
|
+
)
|
|
583
|
+
assert resp is not None
|
|
584
|
+
|
|
585
|
+
response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
586
|
+
|
|
587
|
+
assert response.puzzle_hashes == [ph]
|
|
588
|
+
assert len(response.coin_states) == len(coin_records) - 10000
|
|
589
|
+
|
|
590
|
+
for coin_state in response.coin_states:
|
|
591
|
+
coin_record = coin_records[coin_state.coin.name()]
|
|
592
|
+
assert coin_record.coin_state == coin_state
|
|
593
|
+
assert coin_record.confirmed_block_index > 1
|
|
594
|
+
|
|
595
|
+
# The expected behavior when the limit is exceeded, is to skip the rest
|
|
596
|
+
resp = await simulator.request_puzzle_state(
|
|
597
|
+
wallet_protocol.RequestPuzzleState(
|
|
598
|
+
[ph],
|
|
599
|
+
uint32(0),
|
|
600
|
+
h0,
|
|
601
|
+
wallet_protocol.CoinStateFilters(True, True, True, uint64(0)),
|
|
602
|
+
False,
|
|
603
|
+
),
|
|
604
|
+
peer,
|
|
605
|
+
)
|
|
606
|
+
assert resp is not None
|
|
607
|
+
|
|
608
|
+
response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
609
|
+
|
|
610
|
+
assert response.puzzle_hashes == [ph]
|
|
611
|
+
assert len(response.coin_states) == len(coin_records) - 10000
|
|
612
|
+
|
|
613
|
+
for coin_state in response.coin_states:
|
|
614
|
+
coin_record = coin_records[coin_state.coin.name()]
|
|
615
|
+
assert coin_record.coin_state == coin_state
|
|
616
|
+
# Unlike requesting coin state by ids, the order is enforced here so block 11 should be excluded
|
|
617
|
+
assert coin_record.confirmed_block_index <= 10
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
@dataclass(frozen=True)
|
|
621
|
+
class PuzzleStateData:
|
|
622
|
+
coin_states: list[CoinState]
|
|
623
|
+
end_of_batch: bool
|
|
624
|
+
previous_height: Optional[uint32]
|
|
625
|
+
header_hash: bytes32
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
async def sync_puzzle_hashes(
|
|
629
|
+
puzzle_hashes: list[bytes32],
|
|
630
|
+
*,
|
|
631
|
+
initial_previous_height: Optional[uint32],
|
|
632
|
+
initial_header_hash: bytes32,
|
|
633
|
+
filters: wallet_protocol.CoinStateFilters,
|
|
634
|
+
subscribe_when_finished: bool = False,
|
|
635
|
+
max_hashes_in_request: int = CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE,
|
|
636
|
+
simulator: FullNodeSimulator,
|
|
637
|
+
peer: WSChiaConnection,
|
|
638
|
+
) -> AsyncGenerator[PuzzleStateData, None]:
|
|
639
|
+
remaining = puzzle_hashes.copy()
|
|
640
|
+
|
|
641
|
+
while len(remaining) > 0:
|
|
642
|
+
previous_height = initial_previous_height
|
|
643
|
+
previous_header_hash = initial_header_hash
|
|
644
|
+
is_finished = False
|
|
645
|
+
|
|
646
|
+
while not is_finished:
|
|
647
|
+
resp = await simulator.request_puzzle_state(
|
|
648
|
+
wallet_protocol.RequestPuzzleState(
|
|
649
|
+
remaining[:max_hashes_in_request],
|
|
650
|
+
previous_height,
|
|
651
|
+
previous_header_hash,
|
|
652
|
+
filters,
|
|
653
|
+
subscribe_when_finished,
|
|
654
|
+
),
|
|
655
|
+
peer,
|
|
656
|
+
)
|
|
657
|
+
assert resp is not None
|
|
658
|
+
|
|
659
|
+
response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
|
|
660
|
+
|
|
661
|
+
consumed = len(response.puzzle_hashes)
|
|
662
|
+
assert set(response.puzzle_hashes) == set(remaining[:consumed])
|
|
663
|
+
|
|
664
|
+
if not response.is_finished:
|
|
665
|
+
previous_height = response.height
|
|
666
|
+
previous_header_hash = response.header_hash
|
|
667
|
+
yield PuzzleStateData(
|
|
668
|
+
coin_states=response.coin_states,
|
|
669
|
+
end_of_batch=False,
|
|
670
|
+
previous_height=previous_height,
|
|
671
|
+
header_hash=previous_header_hash,
|
|
672
|
+
)
|
|
673
|
+
else:
|
|
674
|
+
remaining = remaining[consumed:]
|
|
675
|
+
yield PuzzleStateData(
|
|
676
|
+
coin_states=response.coin_states,
|
|
677
|
+
end_of_batch=True,
|
|
678
|
+
previous_height=previous_height,
|
|
679
|
+
header_hash=previous_header_hash,
|
|
680
|
+
)
|
|
681
|
+
is_finished = True
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
@pytest.mark.anyio
|
|
685
|
+
@pytest.mark.parametrize("puzzle_hash_count,coins_per_block", [(0, 0), (5, 100), (3000, 3), (25000, 1)])
|
|
686
|
+
async def test_sync_puzzle_state(
|
|
687
|
+
one_node: OneNode, self_hostname: str, puzzle_hash_count: int, coins_per_block: int
|
|
688
|
+
) -> None:
|
|
689
|
+
simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
|
|
690
|
+
|
|
691
|
+
simulator.full_node.config["max_subscribe_response_items"] = 7400
|
|
692
|
+
|
|
693
|
+
# Generate coin records
|
|
694
|
+
puzzle_hashes: list[bytes32] = []
|
|
695
|
+
hints: list[tuple[bytes32, bytes]] = []
|
|
696
|
+
coin_records: dict[bytes32, CoinRecord] = dict()
|
|
697
|
+
|
|
698
|
+
rng = Random(0)
|
|
699
|
+
|
|
700
|
+
# Skip block 0 because it's skipped by `RequestPuzzleState`.
|
|
701
|
+
for i in range(1, puzzle_hash_count + 1):
|
|
702
|
+
puzzle_hash = std_hash(i.to_bytes(4, "big"))
|
|
703
|
+
puzzle_hashes.append(puzzle_hash)
|
|
704
|
+
|
|
705
|
+
base_amount = rng.randint(0, 1000000000)
|
|
706
|
+
|
|
707
|
+
for added_amount in range(coins_per_block):
|
|
708
|
+
coin_ph = puzzle_hash
|
|
709
|
+
|
|
710
|
+
# Weight toward normal puzzle hash.
|
|
711
|
+
if rng.choice([True, False, False, False, False]):
|
|
712
|
+
coin_ph = std_hash(coin_ph)
|
|
713
|
+
|
|
714
|
+
coin = Coin(bytes32.zeros, coin_ph, uint64(base_amount + added_amount))
|
|
715
|
+
|
|
716
|
+
coin_records[coin.name()] = CoinRecord(
|
|
717
|
+
coin=coin,
|
|
718
|
+
confirmed_block_index=uint32(rng.randrange(1, 10)),
|
|
719
|
+
spent_block_index=uint32(rng.randrange(11, 20) if rng.choice([True, False]) else 0),
|
|
720
|
+
coinbase=False,
|
|
721
|
+
timestamp=uint64(rng.randint(1000, 100000000)),
|
|
722
|
+
)
|
|
723
|
+
|
|
724
|
+
if coin_ph != puzzle_hash:
|
|
725
|
+
hints.append((coin.name(), puzzle_hash))
|
|
726
|
+
|
|
727
|
+
await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
|
|
728
|
+
await simulator.full_node.hint_store.add_hints(hints)
|
|
729
|
+
|
|
730
|
+
# Farm peak
|
|
731
|
+
await simulator.farm_blocks_to_puzzlehash(30)
|
|
732
|
+
|
|
733
|
+
genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
|
|
734
|
+
|
|
735
|
+
async def run_test(include_spent: bool, include_unspent: bool, include_hinted: bool, min_amount: uint64) -> None:
|
|
736
|
+
# Calculate expected coin records based on filters
|
|
737
|
+
expected_coin_records: dict[bytes32, CoinRecord] = dict()
|
|
738
|
+
|
|
739
|
+
for coin_id, coin_record in coin_records.items():
|
|
740
|
+
if not include_spent and coin_record.spent_block_index > 0:
|
|
741
|
+
continue
|
|
742
|
+
if not include_unspent and coin_record.spent_block_index == 0:
|
|
743
|
+
continue
|
|
744
|
+
if not include_hinted and coin_record.coin.puzzle_hash not in puzzle_hashes:
|
|
745
|
+
continue
|
|
746
|
+
if coin_record.coin.amount < min_amount:
|
|
747
|
+
continue
|
|
748
|
+
|
|
749
|
+
expected_coin_records[coin_id] = coin_record
|
|
750
|
+
|
|
751
|
+
# Sync all coin states
|
|
752
|
+
coin_ids: set[bytes32] = set()
|
|
753
|
+
last_height = -1
|
|
754
|
+
|
|
755
|
+
async for batch in sync_puzzle_hashes(
|
|
756
|
+
puzzle_hashes,
|
|
757
|
+
initial_previous_height=None,
|
|
758
|
+
initial_header_hash=genesis,
|
|
759
|
+
filters=wallet_protocol.CoinStateFilters(include_spent, include_unspent, include_hinted, min_amount),
|
|
760
|
+
simulator=simulator,
|
|
761
|
+
peer=peer,
|
|
762
|
+
):
|
|
763
|
+
for coin_state in batch.coin_states:
|
|
764
|
+
coin_id = coin_state.coin.name()
|
|
765
|
+
coin_ids.add(coin_id)
|
|
766
|
+
|
|
767
|
+
coin_record = expected_coin_records[coin_id]
|
|
768
|
+
assert coin_record.coin_state == coin_state
|
|
769
|
+
|
|
770
|
+
height = max(coin_state.created_height or 0, coin_state.spent_height or 0)
|
|
771
|
+
|
|
772
|
+
assert height > last_height
|
|
773
|
+
if batch.end_of_batch:
|
|
774
|
+
last_height = -1
|
|
775
|
+
|
|
776
|
+
assert len(coin_ids) == len(expected_coin_records)
|
|
777
|
+
|
|
778
|
+
for include_spent in [True, False]:
|
|
779
|
+
for include_unspent in [True, False]:
|
|
780
|
+
for include_hinted in [True, False]:
|
|
781
|
+
for min_amount in [0, 100000, 500000000]:
|
|
782
|
+
await run_test(include_spent, include_unspent, include_hinted, uint64(min_amount))
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
async def assert_mempool_added(queue: Queue[Message], transaction_ids: set[bytes32]) -> None:
|
|
786
|
+
message = await queue.get()
|
|
787
|
+
assert message.type == ProtocolMessageTypes.mempool_items_added.value
|
|
788
|
+
|
|
789
|
+
update = wallet_protocol.MempoolItemsAdded.from_bytes(message.data)
|
|
790
|
+
assert set(update.transaction_ids) == transaction_ids
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
async def assert_mempool_removed(
|
|
794
|
+
queue: Queue[Message],
|
|
795
|
+
removed_items: set[wallet_protocol.RemovedMempoolItem],
|
|
796
|
+
) -> None:
|
|
797
|
+
message = await queue.get()
|
|
798
|
+
assert message.type == ProtocolMessageTypes.mempool_items_removed.value
|
|
799
|
+
|
|
800
|
+
update = wallet_protocol.MempoolItemsRemoved.from_bytes(message.data)
|
|
801
|
+
assert set(update.removed_items) == removed_items
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
@pytest.fixture
|
|
805
|
+
async def mpu_setup(one_node: OneNode, self_hostname: str) -> Mpu:
|
|
806
|
+
return await raw_mpu_setup(one_node, self_hostname)
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
@pytest.fixture
|
|
810
|
+
async def mpu_setup_no_capability(one_node: OneNode, self_hostname: str) -> Mpu:
|
|
811
|
+
return await raw_mpu_setup(one_node, self_hostname, no_capability=True)
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
async def raw_mpu_setup(one_node: OneNode, self_hostname: str, no_capability: bool = False) -> Mpu:
|
|
815
|
+
simulator, queue, peer = await connect_to_simulator(one_node, self_hostname, mempool_updates=not no_capability)
|
|
816
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
817
|
+
await queue.get()
|
|
818
|
+
|
|
819
|
+
new_coins: list[tuple[Coin, bytes32]] = []
|
|
820
|
+
|
|
821
|
+
for i in range(10):
|
|
822
|
+
puzzle = Program.to(2)
|
|
823
|
+
ph = puzzle.get_tree_hash()
|
|
824
|
+
coin = Coin(std_hash(b"unrelated coin id" + i.to_bytes(4, "big")), ph, uint64(1))
|
|
825
|
+
hint = std_hash(b"unrelated hint" + i.to_bytes(4, "big"))
|
|
826
|
+
new_coins.append((coin, hint))
|
|
827
|
+
|
|
828
|
+
reward_1 = Coin(std_hash(b"reward 1"), std_hash(b"reward puzzle hash"), uint64(1000))
|
|
829
|
+
reward_2 = Coin(std_hash(b"reward 2"), std_hash(b"reward puzzle hash"), uint64(2000))
|
|
830
|
+
await simulator.full_node.coin_store.new_block(
|
|
831
|
+
uint32(2), uint64(10000), [reward_1, reward_2], [coin for coin, _ in new_coins], []
|
|
832
|
+
)
|
|
833
|
+
await simulator.full_node.hint_store.add_hints([(coin.name(), hint) for coin, hint in new_coins])
|
|
834
|
+
|
|
835
|
+
for coin, hint in new_coins:
|
|
836
|
+
solution = Program.to([[]])
|
|
837
|
+
bundle = SpendBundle([CoinSpend(coin, puzzle, solution)], AugSchemeMPL.aggregate([]))
|
|
838
|
+
tx_resp = await simulator.send_transaction(wallet_protocol.SendTransaction(bundle))
|
|
839
|
+
assert tx_resp is not None
|
|
840
|
+
|
|
841
|
+
ack = wallet_protocol.TransactionAck.from_bytes(tx_resp.data)
|
|
842
|
+
assert ack.error is None
|
|
843
|
+
assert ack.status == int(MempoolInclusionStatus.SUCCESS)
|
|
844
|
+
|
|
845
|
+
return simulator, queue, peer
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
async def make_coin(full_node: FullNode) -> tuple[Coin, bytes32]:
|
|
849
|
+
ph = IDENTITY_PUZZLE_HASH
|
|
850
|
+
coin = Coin(bytes32.zeros, ph, uint64(1000))
|
|
851
|
+
hint = bytes32.zeros
|
|
852
|
+
|
|
853
|
+
height = full_node.blockchain.get_peak_height()
|
|
854
|
+
assert height is not None
|
|
855
|
+
|
|
856
|
+
reward_1 = Coin(std_hash(b"reward 1"), std_hash(b"reward puzzle hash"), uint64(3000))
|
|
857
|
+
reward_2 = Coin(std_hash(b"reward 2"), std_hash(b"reward puzzle hash"), uint64(4000))
|
|
858
|
+
await full_node.coin_store.new_block(uint32(height + 1), uint64(200000), [reward_1, reward_2], [coin], [])
|
|
859
|
+
await full_node.hint_store.add_hints([(coin.name(), hint)])
|
|
860
|
+
|
|
861
|
+
return coin, hint
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
async def subscribe_coin(
|
|
865
|
+
simulator: FullNodeSimulator, coin_id: bytes32, peer: WSChiaConnection, *, existing_coin_states: int = 1
|
|
866
|
+
) -> None:
|
|
867
|
+
genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
|
|
868
|
+
assert genesis is not None
|
|
869
|
+
|
|
870
|
+
msg = await simulator.request_coin_state(wallet_protocol.RequestCoinState([coin_id], None, genesis, True), peer)
|
|
871
|
+
assert msg is not None
|
|
872
|
+
|
|
873
|
+
response = wallet_protocol.RespondCoinState.from_bytes(msg.data)
|
|
874
|
+
assert response.coin_ids == [coin_id]
|
|
875
|
+
assert len(response.coin_states) == existing_coin_states
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
async def subscribe_puzzle(
|
|
879
|
+
simulator: FullNodeSimulator, puzzle_hash: bytes32, peer: WSChiaConnection, *, existing_coin_states: int = 1
|
|
880
|
+
) -> None:
|
|
881
|
+
genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
|
|
882
|
+
assert genesis is not None
|
|
883
|
+
|
|
884
|
+
msg = await simulator.request_puzzle_state(
|
|
885
|
+
wallet_protocol.RequestPuzzleState([puzzle_hash], None, genesis, ALL_FILTER, True), peer
|
|
886
|
+
)
|
|
887
|
+
assert msg is not None
|
|
888
|
+
|
|
889
|
+
response = wallet_protocol.RespondPuzzleState.from_bytes(msg.data)
|
|
890
|
+
assert response.puzzle_hashes == [puzzle_hash]
|
|
891
|
+
assert len(response.coin_states) == existing_coin_states
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
async def spend_coin(simulator: FullNodeSimulator, coin: Coin, solution: Optional[Program] = None) -> bytes32:
|
|
895
|
+
bundle = SpendBundle(
|
|
896
|
+
[CoinSpend(coin, IDENTITY_PUZZLE, Program.to([]) if solution is None else solution)], AugSchemeMPL.aggregate([])
|
|
897
|
+
)
|
|
898
|
+
tx_resp = await simulator.send_transaction(wallet_protocol.SendTransaction(bundle))
|
|
899
|
+
assert tx_resp is not None
|
|
900
|
+
|
|
901
|
+
ack = wallet_protocol.TransactionAck.from_bytes(tx_resp.data)
|
|
902
|
+
assert ack.error is None
|
|
903
|
+
assert ack.status == int(MempoolInclusionStatus.SUCCESS)
|
|
904
|
+
|
|
905
|
+
transaction_id = bundle.name()
|
|
906
|
+
assert ack.txid == transaction_id
|
|
907
|
+
|
|
908
|
+
return transaction_id
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
@pytest.mark.anyio
|
|
912
|
+
async def test_spent_coin_id_mempool_update(mpu_setup: Mpu) -> None:
|
|
913
|
+
simulator, queue, peer = mpu_setup
|
|
914
|
+
|
|
915
|
+
# Make a coin and spend it
|
|
916
|
+
coin, _ = await make_coin(simulator.full_node)
|
|
917
|
+
await subscribe_coin(simulator, coin.name(), peer)
|
|
918
|
+
transaction_id = await spend_coin(simulator, coin)
|
|
919
|
+
|
|
920
|
+
# We should have gotten a mempool update for this transaction
|
|
921
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
922
|
+
|
|
923
|
+
# Check the mempool to make sure the transaction is there
|
|
924
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
925
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
926
|
+
|
|
927
|
+
# The mempool item should now be in the initial update
|
|
928
|
+
await subscribe_coin(simulator, coin.name(), peer)
|
|
929
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
930
|
+
|
|
931
|
+
# Farm a block and listen for the mempool removal event
|
|
932
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
933
|
+
await assert_mempool_removed(
|
|
934
|
+
queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
|
|
935
|
+
)
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
@pytest.mark.anyio
|
|
939
|
+
async def test_spent_puzzle_hash_mempool_update(mpu_setup: Mpu) -> None:
|
|
940
|
+
simulator, queue, peer = mpu_setup
|
|
941
|
+
|
|
942
|
+
# Make a coin and spend it
|
|
943
|
+
coin, _ = await make_coin(simulator.full_node)
|
|
944
|
+
await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
|
|
945
|
+
transaction_id = await spend_coin(simulator, coin)
|
|
946
|
+
|
|
947
|
+
# We should have gotten a mempool update for this transaction
|
|
948
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
949
|
+
|
|
950
|
+
# Check the mempool to make sure the transaction is there
|
|
951
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
952
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
953
|
+
|
|
954
|
+
# The mempool item should now be in the initial update
|
|
955
|
+
await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
|
|
956
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
957
|
+
|
|
958
|
+
# Farm a block and listen for the mempool removal event
|
|
959
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
960
|
+
await assert_mempool_removed(
|
|
961
|
+
queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
|
|
962
|
+
)
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
@pytest.mark.anyio
|
|
966
|
+
async def test_spent_hint_mempool_update(mpu_setup: Mpu) -> None:
|
|
967
|
+
simulator, queue, peer = mpu_setup
|
|
968
|
+
|
|
969
|
+
# Make a coin and spend it
|
|
970
|
+
coin, hint = await make_coin(simulator.full_node)
|
|
971
|
+
await subscribe_puzzle(simulator, hint, peer)
|
|
972
|
+
transaction_id = await spend_coin(simulator, coin)
|
|
973
|
+
|
|
974
|
+
# We should have gotten a mempool update for this transaction
|
|
975
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
976
|
+
|
|
977
|
+
# Check the mempool to make sure the transaction is there
|
|
978
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
979
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
980
|
+
|
|
981
|
+
# The mempool item should now be in the initial update
|
|
982
|
+
await subscribe_puzzle(simulator, hint, peer)
|
|
983
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
984
|
+
|
|
985
|
+
# Farm a block and listen for the mempool removal event
|
|
986
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
987
|
+
await assert_mempool_removed(
|
|
988
|
+
queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
|
|
989
|
+
)
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
@pytest.mark.anyio
|
|
993
|
+
async def test_created_coin_id_mempool_update(mpu_setup: Mpu) -> None:
|
|
994
|
+
simulator, queue, peer = mpu_setup
|
|
995
|
+
|
|
996
|
+
# Make a coin and spend it to create a child coin
|
|
997
|
+
coin, _ = await make_coin(simulator.full_node)
|
|
998
|
+
child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
|
|
999
|
+
await subscribe_coin(simulator, child_coin.name(), peer, existing_coin_states=0)
|
|
1000
|
+
transaction_id = await spend_coin(
|
|
1001
|
+
simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount]])
|
|
1002
|
+
)
|
|
1003
|
+
|
|
1004
|
+
# We should have gotten a mempool update for this transaction
|
|
1005
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
1006
|
+
|
|
1007
|
+
# Check the mempool to make sure the transaction is there
|
|
1008
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
1009
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
1010
|
+
|
|
1011
|
+
# The mempool item should now be in the initial update
|
|
1012
|
+
await subscribe_coin(simulator, child_coin.name(), peer, existing_coin_states=0)
|
|
1013
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
1014
|
+
|
|
1015
|
+
# Farm a block and listen for the mempool removal event
|
|
1016
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
1017
|
+
await assert_mempool_removed(
|
|
1018
|
+
queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
|
|
1019
|
+
)
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
@pytest.mark.anyio
|
|
1023
|
+
async def test_created_puzzle_hash_mempool_update(mpu_setup: Mpu) -> None:
|
|
1024
|
+
simulator, queue, peer = mpu_setup
|
|
1025
|
+
|
|
1026
|
+
# Make a coin and spend it to create a child coin
|
|
1027
|
+
coin, _ = await make_coin(simulator.full_node)
|
|
1028
|
+
child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
|
|
1029
|
+
await subscribe_puzzle(simulator, child_coin.puzzle_hash, peer, existing_coin_states=0)
|
|
1030
|
+
transaction_id = await spend_coin(
|
|
1031
|
+
simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount]])
|
|
1032
|
+
)
|
|
1033
|
+
|
|
1034
|
+
# We should have gotten a mempool update for this transaction
|
|
1035
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
1036
|
+
|
|
1037
|
+
# Check the mempool to make sure the transaction is there
|
|
1038
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
1039
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
1040
|
+
|
|
1041
|
+
# The mempool item should now be in the initial update
|
|
1042
|
+
await subscribe_puzzle(simulator, child_coin.puzzle_hash, peer, existing_coin_states=0)
|
|
1043
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
1044
|
+
|
|
1045
|
+
# Farm a block and listen for the mempool removal event
|
|
1046
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
1047
|
+
await assert_mempool_removed(
|
|
1048
|
+
queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
|
|
1049
|
+
)
|
|
1050
|
+
|
|
1051
|
+
|
|
1052
|
+
@pytest.mark.anyio
|
|
1053
|
+
async def test_created_hint_mempool_update(mpu_setup: Mpu) -> None:
|
|
1054
|
+
simulator, queue, peer = mpu_setup
|
|
1055
|
+
|
|
1056
|
+
# Make a coin and spend it to create a child coin
|
|
1057
|
+
coin, _ = await make_coin(simulator.full_node)
|
|
1058
|
+
child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
|
|
1059
|
+
hint = std_hash(b"new hint")
|
|
1060
|
+
await subscribe_puzzle(simulator, hint, peer, existing_coin_states=0)
|
|
1061
|
+
transaction_id = await spend_coin(
|
|
1062
|
+
simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount, [hint]]])
|
|
1063
|
+
)
|
|
1064
|
+
|
|
1065
|
+
# We should have gotten a mempool update for this transaction
|
|
1066
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
1067
|
+
|
|
1068
|
+
# Check the mempool to make sure the transaction is there
|
|
1069
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
1070
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
1071
|
+
|
|
1072
|
+
# The mempool item should now be in the initial update
|
|
1073
|
+
await subscribe_puzzle(simulator, hint, peer, existing_coin_states=0)
|
|
1074
|
+
await assert_mempool_added(queue, {transaction_id})
|
|
1075
|
+
|
|
1076
|
+
# Farm a block and listen for the mempool removal event
|
|
1077
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
1078
|
+
await assert_mempool_removed(
|
|
1079
|
+
queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
|
|
1080
|
+
)
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
@pytest.mark.anyio
|
|
1084
|
+
async def test_missing_capability_coin_id(mpu_setup_no_capability: Mpu) -> None:
|
|
1085
|
+
simulator, queue, peer = mpu_setup_no_capability
|
|
1086
|
+
|
|
1087
|
+
# Make a coin and spend it
|
|
1088
|
+
coin, _ = await make_coin(simulator.full_node)
|
|
1089
|
+
await subscribe_coin(simulator, coin.name(), peer)
|
|
1090
|
+
transaction_id = await spend_coin(simulator, coin)
|
|
1091
|
+
|
|
1092
|
+
# There is no mempool update for this transaction since the peer doesn't have the capability
|
|
1093
|
+
assert queue.empty()
|
|
1094
|
+
|
|
1095
|
+
# Check the mempool to make sure the transaction is there
|
|
1096
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
1097
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
1098
|
+
|
|
1099
|
+
# There is no initial mempool update since the peer doesn't have the capability
|
|
1100
|
+
await subscribe_coin(simulator, coin.name(), peer)
|
|
1101
|
+
assert queue.empty()
|
|
1102
|
+
|
|
1103
|
+
# Farm a block and there's still no mempool update
|
|
1104
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
1105
|
+
assert queue.empty()
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
@pytest.mark.anyio
|
|
1109
|
+
async def test_missing_capability_puzzle_hash(mpu_setup_no_capability: Mpu) -> None:
|
|
1110
|
+
simulator, queue, peer = mpu_setup_no_capability
|
|
1111
|
+
|
|
1112
|
+
# Make a coin and spend it
|
|
1113
|
+
coin, _ = await make_coin(simulator.full_node)
|
|
1114
|
+
await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
|
|
1115
|
+
transaction_id = await spend_coin(simulator, coin)
|
|
1116
|
+
|
|
1117
|
+
# There is no mempool update for this transaction since the peer doesn't have the capability
|
|
1118
|
+
assert queue.empty()
|
|
1119
|
+
|
|
1120
|
+
# Check the mempool to make sure the transaction is there
|
|
1121
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
1122
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
1123
|
+
|
|
1124
|
+
# There is no initial mempool update since the peer doesn't have the capability
|
|
1125
|
+
await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
|
|
1126
|
+
assert queue.empty()
|
|
1127
|
+
|
|
1128
|
+
# Farm a block and there's still no mempool update
|
|
1129
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
1130
|
+
assert queue.empty()
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
@pytest.mark.anyio
|
|
1134
|
+
async def test_missing_capability_hint(mpu_setup_no_capability: Mpu) -> None:
|
|
1135
|
+
simulator, queue, peer = mpu_setup_no_capability
|
|
1136
|
+
|
|
1137
|
+
# Make a coin and spend it
|
|
1138
|
+
coin, hint = await make_coin(simulator.full_node)
|
|
1139
|
+
await subscribe_puzzle(simulator, hint, peer)
|
|
1140
|
+
transaction_id = await spend_coin(simulator, coin)
|
|
1141
|
+
|
|
1142
|
+
# There is no mempool update for this transaction since the peer doesn't have the capability
|
|
1143
|
+
assert queue.empty()
|
|
1144
|
+
|
|
1145
|
+
# Check the mempool to make sure the transaction is there
|
|
1146
|
+
await simulator.wait_bundle_ids_in_mempool([transaction_id])
|
|
1147
|
+
assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
|
|
1148
|
+
|
|
1149
|
+
# There is no initial mempool update since the peer doesn't have the capability
|
|
1150
|
+
await subscribe_puzzle(simulator, hint, peer)
|
|
1151
|
+
assert queue.empty()
|
|
1152
|
+
|
|
1153
|
+
# Farm a block and there's still no mempool update
|
|
1154
|
+
await simulator.farm_blocks_to_puzzlehash(1)
|
|
1155
|
+
assert queue.empty()
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
@pytest.mark.anyio
|
|
1159
|
+
async def test_cost_info(one_node: OneNode, self_hostname: str) -> None:
|
|
1160
|
+
simulator, _, _ = await connect_to_simulator(one_node, self_hostname)
|
|
1161
|
+
|
|
1162
|
+
msg = await simulator.request_cost_info(wallet_protocol.RequestCostInfo())
|
|
1163
|
+
assert msg is not None
|
|
1164
|
+
|
|
1165
|
+
response = wallet_protocol.RespondCostInfo.from_bytes(msg.data)
|
|
1166
|
+
mempool_manager = simulator.full_node.mempool_manager
|
|
1167
|
+
assert response == wallet_protocol.RespondCostInfo(
|
|
1168
|
+
max_transaction_cost=mempool_manager.max_tx_clvm_cost,
|
|
1169
|
+
max_block_cost=mempool_manager.max_block_clvm_cost,
|
|
1170
|
+
max_mempool_cost=uint64(mempool_manager.mempool_max_total_cost),
|
|
1171
|
+
mempool_cost=uint64(mempool_manager.mempool._total_cost),
|
|
1172
|
+
mempool_fee=uint64(mempool_manager.mempool._total_fee),
|
|
1173
|
+
bump_fee_per_cost=uint8(mempool_manager.nonzero_fee_minimum_fpc),
|
|
1174
|
+
)
|