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
chia/util/streamable.py
ADDED
|
@@ -0,0 +1,642 @@
|
|
|
1
|
+
# Package: utils
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import dataclasses
|
|
6
|
+
import io
|
|
7
|
+
import os
|
|
8
|
+
import pprint
|
|
9
|
+
import traceback
|
|
10
|
+
from collections.abc import Collection
|
|
11
|
+
from enum import Enum
|
|
12
|
+
from typing import TYPE_CHECKING, Any, BinaryIO, Callable, ClassVar, Optional, TypeVar, Union, get_type_hints
|
|
13
|
+
|
|
14
|
+
from chia_rs.sized_bytes import bytes32
|
|
15
|
+
from chia_rs.sized_ints import uint16, uint32, uint64
|
|
16
|
+
from typing_extensions import Literal, get_args, get_origin
|
|
17
|
+
|
|
18
|
+
from chia.util.byte_types import hexstr_to_bytes
|
|
19
|
+
from chia.util.hash import std_hash
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from _typeshed import DataclassInstance
|
|
23
|
+
|
|
24
|
+
pp = pprint.PrettyPrinter(indent=1, width=120, compact=True)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class StreamableError(Exception):
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class UnsupportedType(StreamableError):
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DefinitionError(StreamableError):
|
|
36
|
+
def __init__(self, message: str, cls: type[object]):
|
|
37
|
+
super().__init__(
|
|
38
|
+
f"{message} Correct usage is:\n\n"
|
|
39
|
+
f"@streamable\n@dataclass(frozen=True)\nclass {cls.__name__}(Streamable):\n ..."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ParameterMissingError(StreamableError):
|
|
44
|
+
def __init__(self, cls: type, missing: list[str]):
|
|
45
|
+
super().__init__(
|
|
46
|
+
f"{len(missing)} field{'s' if len(missing) != 1 else ''} missing for {cls.__name__}: {', '.join(missing)}"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class InvalidTypeError(StreamableError):
|
|
51
|
+
def __init__(self, expected: type, actual: type):
|
|
52
|
+
super().__init__(
|
|
53
|
+
f"Invalid type: Expected {expected.__name__}, Actual: {actual.__name__}",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class InvalidSizeError(StreamableError):
|
|
58
|
+
def __init__(self, expected: int, actual: int):
|
|
59
|
+
super().__init__(
|
|
60
|
+
f"Invalid size: Expected {expected}, Actual: {actual}",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ConversionError(StreamableError):
|
|
65
|
+
def __init__(self, value: object, to_type: type, exception: Exception):
|
|
66
|
+
super().__init__(
|
|
67
|
+
f"Failed to convert {value!r} from type {type(value).__name__} to {to_type.__name__}: "
|
|
68
|
+
+ "".join(traceback.format_exception_only(type(exception), value=exception)).strip()
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
_T_Streamable = TypeVar("_T_Streamable", bound="Streamable")
|
|
73
|
+
|
|
74
|
+
ParseFunctionType = Callable[[BinaryIO], object]
|
|
75
|
+
StreamFunctionType = Callable[[object, BinaryIO], None]
|
|
76
|
+
ConvertFunctionType = Callable[[object], object]
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@dataclasses.dataclass(frozen=True)
|
|
80
|
+
class Field:
|
|
81
|
+
name: str
|
|
82
|
+
type: type[object]
|
|
83
|
+
has_default: bool
|
|
84
|
+
stream_function: StreamFunctionType
|
|
85
|
+
parse_function: ParseFunctionType
|
|
86
|
+
convert_function: ConvertFunctionType
|
|
87
|
+
post_init_function: ConvertFunctionType
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
StreamableFields = tuple[Field, ...]
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def create_fields(cls: type[DataclassInstance]) -> StreamableFields:
|
|
94
|
+
hints = get_type_hints(cls)
|
|
95
|
+
fields = []
|
|
96
|
+
for field in dataclasses.fields(cls):
|
|
97
|
+
hint = hints[field.name]
|
|
98
|
+
fields.append(
|
|
99
|
+
Field(
|
|
100
|
+
name=field.name,
|
|
101
|
+
type=hint,
|
|
102
|
+
has_default=field.default is not dataclasses.MISSING
|
|
103
|
+
or field.default_factory is not dataclasses.MISSING,
|
|
104
|
+
stream_function=function_to_stream_one_item(hint),
|
|
105
|
+
parse_function=function_to_parse_one_item(hint),
|
|
106
|
+
convert_function=function_to_convert_one_item(hint),
|
|
107
|
+
post_init_function=function_to_post_init_process_one_item(hint),
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return tuple(fields)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def is_type_List(f_type: object) -> bool:
|
|
115
|
+
return get_origin(f_type) is list or f_type is list
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def is_type_SpecificOptional(f_type: object) -> bool:
|
|
119
|
+
"""
|
|
120
|
+
Returns true for types such as Optional[T], but not Optional, or T.
|
|
121
|
+
"""
|
|
122
|
+
return get_origin(f_type) == Union and get_args(f_type)[1]() is None
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def is_type_Tuple(f_type: object) -> bool:
|
|
126
|
+
return get_origin(f_type) is tuple or f_type is tuple
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def convert_optional(convert_func: ConvertFunctionType, item: Any) -> Any:
|
|
130
|
+
if item is None:
|
|
131
|
+
return None
|
|
132
|
+
return convert_func(item)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def convert_tuple(convert_funcs: list[ConvertFunctionType], items: Collection[Any]) -> tuple[Any, ...]:
|
|
136
|
+
if not isinstance(items, (list, tuple)):
|
|
137
|
+
raise InvalidTypeError(tuple, type(items))
|
|
138
|
+
if len(items) != len(convert_funcs):
|
|
139
|
+
raise InvalidSizeError(len(convert_funcs), len(items))
|
|
140
|
+
return tuple(convert_func(item) for convert_func, item in zip(convert_funcs, items))
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def convert_list(convert_func: ConvertFunctionType, items: list[Any]) -> list[Any]:
|
|
144
|
+
if not isinstance(items, list):
|
|
145
|
+
raise InvalidTypeError(list, type(items))
|
|
146
|
+
return [convert_func(item) for item in items]
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def convert_hex_string(item: str) -> bytes:
|
|
150
|
+
if not isinstance(item, str):
|
|
151
|
+
raise InvalidTypeError(str, type(item))
|
|
152
|
+
try:
|
|
153
|
+
return hexstr_to_bytes(item)
|
|
154
|
+
except Exception as e:
|
|
155
|
+
raise ConversionError(item, bytes, e) from e
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def convert_byte_type(f_type: type[Any], item: Any) -> Any:
|
|
159
|
+
if isinstance(item, f_type):
|
|
160
|
+
return item
|
|
161
|
+
if not isinstance(item, bytes):
|
|
162
|
+
item = convert_hex_string(item)
|
|
163
|
+
try:
|
|
164
|
+
return f_type(item)
|
|
165
|
+
except Exception as e:
|
|
166
|
+
raise ConversionError(item, f_type, e) from e
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def convert_primitive(f_type: type[Any], item: Any) -> Any:
|
|
170
|
+
if isinstance(item, f_type):
|
|
171
|
+
return item
|
|
172
|
+
try:
|
|
173
|
+
return f_type(item)
|
|
174
|
+
except Exception as e:
|
|
175
|
+
raise ConversionError(item, f_type, e) from e
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def streamable_from_dict(klass: type[_T_Streamable], item: Any) -> _T_Streamable:
|
|
179
|
+
"""
|
|
180
|
+
Converts a dictionary based on a dataclass, into an instance of that dataclass.
|
|
181
|
+
Recursively goes through lists, optionals, and dictionaries.
|
|
182
|
+
"""
|
|
183
|
+
if isinstance(item, klass):
|
|
184
|
+
return item
|
|
185
|
+
if not isinstance(item, dict):
|
|
186
|
+
raise InvalidTypeError(dict, type(item))
|
|
187
|
+
|
|
188
|
+
fields = klass.streamable_fields()
|
|
189
|
+
try:
|
|
190
|
+
return klass(**{field.name: field.convert_function(item[field.name]) for field in fields if field.name in item})
|
|
191
|
+
except TypeError as e:
|
|
192
|
+
missing_fields = [field.name for field in fields if field.name not in item and not field.has_default]
|
|
193
|
+
if len(missing_fields) > 0:
|
|
194
|
+
raise ParameterMissingError(klass, missing_fields) from e
|
|
195
|
+
raise
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def function_to_convert_one_item(
|
|
199
|
+
f_type: type[Any], json_parser: Optional[Callable[[object], Streamable]] = None
|
|
200
|
+
) -> ConvertFunctionType:
|
|
201
|
+
if is_type_SpecificOptional(f_type):
|
|
202
|
+
convert_inner_func = function_to_convert_one_item(get_args(f_type)[0], json_parser)
|
|
203
|
+
return lambda item: convert_optional(convert_inner_func, item)
|
|
204
|
+
elif is_type_Tuple(f_type):
|
|
205
|
+
args = get_args(f_type)
|
|
206
|
+
convert_inner_tuple_funcs = []
|
|
207
|
+
for arg in args:
|
|
208
|
+
convert_inner_tuple_funcs.append(function_to_convert_one_item(arg, json_parser))
|
|
209
|
+
# Ignoring for now as the proper solution isn't obvious
|
|
210
|
+
return lambda items: convert_tuple(convert_inner_tuple_funcs, items) # type: ignore[arg-type]
|
|
211
|
+
elif is_type_List(f_type):
|
|
212
|
+
inner_type = get_args(f_type)[0]
|
|
213
|
+
convert_inner_func = function_to_convert_one_item(inner_type, json_parser)
|
|
214
|
+
# Ignoring for now as the proper solution isn't obvious
|
|
215
|
+
return lambda items: convert_list(convert_inner_func, items) # type: ignore[arg-type]
|
|
216
|
+
elif hasattr(f_type, "from_json_dict"):
|
|
217
|
+
if json_parser is None:
|
|
218
|
+
json_parser = f_type.from_json_dict
|
|
219
|
+
return json_parser
|
|
220
|
+
elif issubclass(f_type, bytes):
|
|
221
|
+
# Type is bytes, data is a hex string or bytes
|
|
222
|
+
return lambda item: convert_byte_type(f_type, item)
|
|
223
|
+
else:
|
|
224
|
+
# Type is a primitive, cast with correct class
|
|
225
|
+
return lambda item: convert_primitive(f_type, item)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def post_init_process_item(f_type: type[Any], item: Any) -> object:
|
|
229
|
+
if not isinstance(item, f_type):
|
|
230
|
+
try:
|
|
231
|
+
item = f_type(item)
|
|
232
|
+
except (TypeError, AttributeError, ValueError):
|
|
233
|
+
if hasattr(f_type, "from_bytes_unchecked"):
|
|
234
|
+
from_bytes_method: Callable[[bytes], Any] = f_type.from_bytes_unchecked
|
|
235
|
+
else:
|
|
236
|
+
from_bytes_method = f_type.from_bytes
|
|
237
|
+
try:
|
|
238
|
+
item = from_bytes_method(item)
|
|
239
|
+
except Exception:
|
|
240
|
+
item = from_bytes_method(bytes(item))
|
|
241
|
+
if not isinstance(item, f_type):
|
|
242
|
+
raise InvalidTypeError(f_type, type(item))
|
|
243
|
+
return item
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def function_to_post_init_process_one_item(f_type: type[object]) -> ConvertFunctionType:
|
|
247
|
+
if is_type_SpecificOptional(f_type):
|
|
248
|
+
process_inner_func = function_to_post_init_process_one_item(get_args(f_type)[0])
|
|
249
|
+
return lambda item: convert_optional(process_inner_func, item)
|
|
250
|
+
if is_type_Tuple(f_type):
|
|
251
|
+
args = get_args(f_type)
|
|
252
|
+
process_inner_tuple_funcs = []
|
|
253
|
+
for arg in args:
|
|
254
|
+
process_inner_tuple_funcs.append(function_to_post_init_process_one_item(arg))
|
|
255
|
+
return lambda items: convert_tuple(process_inner_tuple_funcs, items) # type: ignore[arg-type]
|
|
256
|
+
if is_type_List(f_type):
|
|
257
|
+
inner_type = get_args(f_type)[0]
|
|
258
|
+
process_inner_func = function_to_post_init_process_one_item(inner_type)
|
|
259
|
+
return lambda items: convert_list(process_inner_func, items) # type: ignore[arg-type]
|
|
260
|
+
return lambda item: post_init_process_item(f_type, item)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def recurse_jsonify(
|
|
264
|
+
d: Any, next_recursion_step: Optional[Callable[[Any, Any], Any]] = None, **next_recursion_env: Any
|
|
265
|
+
) -> Any:
|
|
266
|
+
"""
|
|
267
|
+
Makes bytes objects into strings with 0x, and makes large ints into strings.
|
|
268
|
+
"""
|
|
269
|
+
if next_recursion_step is None:
|
|
270
|
+
next_recursion_step = recurse_jsonify
|
|
271
|
+
if dataclasses.is_dataclass(d):
|
|
272
|
+
new_dict = {}
|
|
273
|
+
for field in dataclasses.fields(d):
|
|
274
|
+
new_dict[field.name] = next_recursion_step(getattr(d, field.name), None, **next_recursion_env)
|
|
275
|
+
return new_dict
|
|
276
|
+
|
|
277
|
+
elif isinstance(d, (list, tuple)):
|
|
278
|
+
new_list = []
|
|
279
|
+
for item in d:
|
|
280
|
+
new_list.append(next_recursion_step(item, None, **next_recursion_env))
|
|
281
|
+
return new_list
|
|
282
|
+
|
|
283
|
+
elif isinstance(d, dict):
|
|
284
|
+
new_dict = {}
|
|
285
|
+
for name, val in d.items():
|
|
286
|
+
new_dict[name] = next_recursion_step(val, None, **next_recursion_env)
|
|
287
|
+
return new_dict
|
|
288
|
+
|
|
289
|
+
elif issubclass(type(d), bytes):
|
|
290
|
+
return f"0x{bytes(d).hex()}"
|
|
291
|
+
elif isinstance(d, Enum):
|
|
292
|
+
return d.name
|
|
293
|
+
elif isinstance(d, bool):
|
|
294
|
+
return d
|
|
295
|
+
elif isinstance(d, int):
|
|
296
|
+
return int(d)
|
|
297
|
+
elif d is None or type(d) is str:
|
|
298
|
+
return d
|
|
299
|
+
elif hasattr(d, "to_json_dict"):
|
|
300
|
+
ret: Union[list[Any], dict[str, Any], str, int, None] = d.to_json_dict()
|
|
301
|
+
return ret
|
|
302
|
+
raise UnsupportedType(f"failed to jsonify {d} (type: {type(d)})")
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def parse_bool(f: BinaryIO) -> bool:
|
|
306
|
+
bool_byte = f.read(1)
|
|
307
|
+
assert bool_byte is not None and len(bool_byte) == 1 # Checks for EOF
|
|
308
|
+
if bool_byte == bytes([0]):
|
|
309
|
+
return False
|
|
310
|
+
elif bool_byte == bytes([1]):
|
|
311
|
+
return True
|
|
312
|
+
else:
|
|
313
|
+
raise ValueError("Bool byte must be 0 or 1")
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def parse_uint32(f: BinaryIO, byteorder: Literal["little", "big"] = "big") -> uint32:
|
|
317
|
+
size_bytes = f.read(4)
|
|
318
|
+
assert size_bytes is not None and len(size_bytes) == 4 # Checks for EOF
|
|
319
|
+
return uint32(int.from_bytes(size_bytes, byteorder))
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def write_uint32(f: BinaryIO, value: uint32, byteorder: Literal["little", "big"] = "big") -> None:
|
|
323
|
+
f.write(value.to_bytes(4, byteorder))
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def parse_optional(f: BinaryIO, parse_inner_type_f: ParseFunctionType) -> Optional[object]:
|
|
327
|
+
is_present_bytes = f.read(1)
|
|
328
|
+
assert is_present_bytes is not None and len(is_present_bytes) == 1 # Checks for EOF
|
|
329
|
+
if is_present_bytes == bytes([0]):
|
|
330
|
+
return None
|
|
331
|
+
elif is_present_bytes == bytes([1]):
|
|
332
|
+
return parse_inner_type_f(f)
|
|
333
|
+
else:
|
|
334
|
+
raise ValueError("Optional must be 0 or 1")
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def parse_rust(f: BinaryIO, f_type: type[Any]) -> Any:
|
|
338
|
+
assert isinstance(f, io.BytesIO)
|
|
339
|
+
buf = f.getbuffer()
|
|
340
|
+
ret, advance = f_type.parse_rust(buf[f.tell() :])
|
|
341
|
+
f.seek(advance, os.SEEK_CUR)
|
|
342
|
+
return ret
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def parse_bytes(f: BinaryIO) -> bytes:
|
|
346
|
+
list_size = parse_uint32(f)
|
|
347
|
+
bytes_read = f.read(list_size)
|
|
348
|
+
assert bytes_read is not None and len(bytes_read) == list_size
|
|
349
|
+
return bytes_read
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def parse_list(f: BinaryIO, parse_inner_type_f: ParseFunctionType) -> list[object]:
|
|
353
|
+
full_list: list[object] = []
|
|
354
|
+
# wjb assert inner_type != get_args(List)[0]
|
|
355
|
+
list_size = parse_uint32(f)
|
|
356
|
+
for list_index in range(list_size):
|
|
357
|
+
full_list.append(parse_inner_type_f(f))
|
|
358
|
+
return full_list
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def parse_tuple(f: BinaryIO, list_parse_inner_type_f: list[ParseFunctionType]) -> tuple[object, ...]:
|
|
362
|
+
full_list: list[object] = []
|
|
363
|
+
for parse_f in list_parse_inner_type_f:
|
|
364
|
+
full_list.append(parse_f(f))
|
|
365
|
+
return tuple(full_list)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def parse_str(f: BinaryIO) -> str:
|
|
369
|
+
str_size = parse_uint32(f)
|
|
370
|
+
str_read_bytes = f.read(str_size)
|
|
371
|
+
assert str_read_bytes is not None and len(str_read_bytes) == str_size # Checks for EOF
|
|
372
|
+
return bytes.decode(str_read_bytes, "utf-8")
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def function_to_parse_one_item(f_type: type[Any]) -> ParseFunctionType:
|
|
376
|
+
"""
|
|
377
|
+
This function returns a function taking one argument `f: BinaryIO` that parses
|
|
378
|
+
and returns a value of the given type.
|
|
379
|
+
"""
|
|
380
|
+
inner_type: type[Any]
|
|
381
|
+
if f_type is bool:
|
|
382
|
+
return parse_bool
|
|
383
|
+
if is_type_SpecificOptional(f_type):
|
|
384
|
+
inner_type = get_args(f_type)[0]
|
|
385
|
+
parse_inner_type_f = function_to_parse_one_item(inner_type)
|
|
386
|
+
return lambda f: parse_optional(f, parse_inner_type_f)
|
|
387
|
+
if hasattr(f_type, "parse_rust"):
|
|
388
|
+
return lambda f: parse_rust(f, f_type)
|
|
389
|
+
if hasattr(f_type, "parse"):
|
|
390
|
+
# Ignoring for now as the proper solution isn't obvious
|
|
391
|
+
return f_type.parse # type: ignore[no-any-return]
|
|
392
|
+
if f_type is bytes:
|
|
393
|
+
return parse_bytes
|
|
394
|
+
if is_type_List(f_type):
|
|
395
|
+
inner_type = get_args(f_type)[0]
|
|
396
|
+
parse_inner_type_f = function_to_parse_one_item(inner_type)
|
|
397
|
+
return lambda f: parse_list(f, parse_inner_type_f)
|
|
398
|
+
if is_type_Tuple(f_type):
|
|
399
|
+
inner_types = get_args(f_type)
|
|
400
|
+
list_parse_inner_type_f = [function_to_parse_one_item(_) for _ in inner_types]
|
|
401
|
+
return lambda f: parse_tuple(f, list_parse_inner_type_f)
|
|
402
|
+
if f_type is str:
|
|
403
|
+
return parse_str
|
|
404
|
+
raise UnsupportedType(f"Type {f_type} does not have parse")
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def stream_optional(stream_inner_type_func: StreamFunctionType, item: Any, f: BinaryIO) -> None:
|
|
408
|
+
if item is None:
|
|
409
|
+
f.write(bytes([0]))
|
|
410
|
+
else:
|
|
411
|
+
f.write(bytes([1]))
|
|
412
|
+
stream_inner_type_func(item, f)
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def stream_bytes(item: Any, f: BinaryIO) -> None:
|
|
416
|
+
write_uint32(f, uint32(len(item)))
|
|
417
|
+
f.write(item)
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def stream_list(stream_inner_type_func: StreamFunctionType, item: Any, f: BinaryIO) -> None:
|
|
421
|
+
write_uint32(f, uint32(len(item)))
|
|
422
|
+
for element in item:
|
|
423
|
+
stream_inner_type_func(element, f)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def stream_tuple(stream_inner_type_funcs: list[StreamFunctionType], item: Any, f: BinaryIO) -> None:
|
|
427
|
+
assert len(stream_inner_type_funcs) == len(item)
|
|
428
|
+
for i in range(len(item)):
|
|
429
|
+
stream_inner_type_funcs[i](item[i], f)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
def stream_str(item: Any, f: BinaryIO) -> None:
|
|
433
|
+
str_bytes = item.encode("utf-8")
|
|
434
|
+
write_uint32(f, uint32(len(str_bytes)))
|
|
435
|
+
f.write(str_bytes)
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def stream_bool(item: Any, f: BinaryIO) -> None:
|
|
439
|
+
f.write(int(item).to_bytes(1, "big"))
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def stream_streamable(item: object, f: BinaryIO) -> None:
|
|
443
|
+
getattr(item, "stream")(f)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def stream_byte_convertible(item: object, f: BinaryIO) -> None:
|
|
447
|
+
f.write(getattr(item, "__bytes__")())
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def function_to_stream_one_item(f_type: type[Any]) -> StreamFunctionType:
|
|
451
|
+
inner_type: type[Any]
|
|
452
|
+
if is_type_SpecificOptional(f_type):
|
|
453
|
+
inner_type = get_args(f_type)[0]
|
|
454
|
+
stream_inner_type_func = function_to_stream_one_item(inner_type)
|
|
455
|
+
return lambda item, f: stream_optional(stream_inner_type_func, item, f)
|
|
456
|
+
elif f_type is bytes:
|
|
457
|
+
return stream_bytes
|
|
458
|
+
elif hasattr(f_type, "stream"):
|
|
459
|
+
return stream_streamable
|
|
460
|
+
elif hasattr(f_type, "__bytes__"):
|
|
461
|
+
return stream_byte_convertible
|
|
462
|
+
elif is_type_List(f_type):
|
|
463
|
+
inner_type = get_args(f_type)[0]
|
|
464
|
+
stream_inner_type_func = function_to_stream_one_item(inner_type)
|
|
465
|
+
return lambda item, f: stream_list(stream_inner_type_func, item, f)
|
|
466
|
+
elif is_type_Tuple(f_type):
|
|
467
|
+
inner_types = get_args(f_type)
|
|
468
|
+
stream_inner_type_funcs = []
|
|
469
|
+
for i in range(len(inner_types)):
|
|
470
|
+
stream_inner_type_funcs.append(function_to_stream_one_item(inner_types[i]))
|
|
471
|
+
return lambda item, f: stream_tuple(stream_inner_type_funcs, item, f)
|
|
472
|
+
elif f_type is str:
|
|
473
|
+
return stream_str
|
|
474
|
+
elif f_type is bool:
|
|
475
|
+
return stream_bool
|
|
476
|
+
else:
|
|
477
|
+
raise UnsupportedType(f"can't stream {f_type}")
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
def streamable(cls: type[_T_Streamable]) -> type[_T_Streamable]:
|
|
481
|
+
"""
|
|
482
|
+
This decorator forces correct streamable protocol syntax/usage and populates the caches for types hints and
|
|
483
|
+
(de)serialization methods for all members of the class. The correct usage is:
|
|
484
|
+
|
|
485
|
+
@streamable
|
|
486
|
+
@dataclass(frozen=True)
|
|
487
|
+
class Example(Streamable):
|
|
488
|
+
...
|
|
489
|
+
|
|
490
|
+
The order how the decorator are applied and the inheritance from Streamable are forced. The explicit inheritance is
|
|
491
|
+
required because mypy doesn't analyse the type returned by decorators, so we can't just inherit from inside the
|
|
492
|
+
decorator. The dataclass decorator is required to fetch type hints, let mypy validate constructor calls and restrict
|
|
493
|
+
direct modification of objects by `frozen=True`.
|
|
494
|
+
"""
|
|
495
|
+
|
|
496
|
+
if not dataclasses.is_dataclass(cls):
|
|
497
|
+
raise DefinitionError("@dataclass(frozen=True) required first.", cls)
|
|
498
|
+
|
|
499
|
+
try:
|
|
500
|
+
# Ignore mypy here because we especially want to access a not available member to test if
|
|
501
|
+
# the dataclass is frozen.
|
|
502
|
+
object.__new__(cls)._streamable_test_if_dataclass_frozen_ = None
|
|
503
|
+
except dataclasses.FrozenInstanceError:
|
|
504
|
+
pass
|
|
505
|
+
else:
|
|
506
|
+
raise DefinitionError("dataclass needs to be frozen.", cls)
|
|
507
|
+
|
|
508
|
+
if not issubclass(cls, Streamable):
|
|
509
|
+
raise DefinitionError("Streamable inheritance required.", cls)
|
|
510
|
+
|
|
511
|
+
cls._streamable_fields = create_fields(cls)
|
|
512
|
+
|
|
513
|
+
return cls
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
class Streamable:
|
|
517
|
+
"""
|
|
518
|
+
This class defines a simple serialization format, and adds methods to parse from/to bytes and json. It also
|
|
519
|
+
validates and parses all fields at construction in `__post_init__` to make sure all fields have the correct type
|
|
520
|
+
and can be streamed/parsed properly.
|
|
521
|
+
|
|
522
|
+
The available primitives are:
|
|
523
|
+
* Sized ints serialized in big endian format, e.g. uint64
|
|
524
|
+
* Sized bytes serialized in big endian format, e.g. bytes32
|
|
525
|
+
* BLS public keys serialized in bls format (48 bytes)
|
|
526
|
+
* BLS signatures serialized in bls format (96 bytes)
|
|
527
|
+
* bool serialized into 1 byte (0x01 or 0x00)
|
|
528
|
+
* bytes serialized as a 4 byte size prefix and then the bytes.
|
|
529
|
+
* str serialized as a 4 byte size prefix and then the utf-8 representation in bytes.
|
|
530
|
+
|
|
531
|
+
An item is one of:
|
|
532
|
+
* primitive
|
|
533
|
+
* tuple[item1, .. itemx]
|
|
534
|
+
* list[item1, .. itemx]
|
|
535
|
+
* Optional[item]
|
|
536
|
+
* Custom item
|
|
537
|
+
|
|
538
|
+
A streamable must be a Tuple at the root level (although a dataclass is used here instead).
|
|
539
|
+
Iters are serialized in the following way:
|
|
540
|
+
|
|
541
|
+
1. A tuple of x items is serialized by appending the serialization of each item.
|
|
542
|
+
2. A List is serialized into a 4 byte size prefix (number of items) and the serialization of each item.
|
|
543
|
+
3. An Optional is serialized into a 1 byte prefix of 0x00 or 0x01, and if it's one, it's followed by the
|
|
544
|
+
serialization of the item.
|
|
545
|
+
4. A Custom item is serialized by calling the .parse method, passing in the stream of bytes into it. An example is
|
|
546
|
+
a CLVM program.
|
|
547
|
+
|
|
548
|
+
All of the constituents must have parse/from_bytes, and stream/__bytes__ and therefore
|
|
549
|
+
be of fixed size. For example, int cannot be a constituent since it is not a fixed size,
|
|
550
|
+
whereas uint32 can be.
|
|
551
|
+
|
|
552
|
+
Furthermore, a get_hash() member is added, which performs a serialization and a sha256.
|
|
553
|
+
|
|
554
|
+
This class is used for deterministic serialization and hashing, for consensus critical
|
|
555
|
+
objects such as the block header.
|
|
556
|
+
|
|
557
|
+
Make sure to use the streamable decorator when inheriting from the Streamable class to prepare the streaming caches.
|
|
558
|
+
"""
|
|
559
|
+
|
|
560
|
+
_streamable_fields: ClassVar[StreamableFields]
|
|
561
|
+
|
|
562
|
+
@classmethod
|
|
563
|
+
def streamable_fields(cls) -> StreamableFields:
|
|
564
|
+
return cls._streamable_fields
|
|
565
|
+
|
|
566
|
+
def __post_init__(self) -> None:
|
|
567
|
+
data = self.__dict__
|
|
568
|
+
try:
|
|
569
|
+
for field in self._streamable_fields:
|
|
570
|
+
object.__setattr__(self, field.name, field.post_init_function(data[field.name]))
|
|
571
|
+
except TypeError as e:
|
|
572
|
+
missing_fields = [field.name for field in self._streamable_fields if field.name not in data]
|
|
573
|
+
if len(missing_fields) > 0:
|
|
574
|
+
raise ParameterMissingError(type(self), missing_fields) from e
|
|
575
|
+
raise
|
|
576
|
+
|
|
577
|
+
@classmethod
|
|
578
|
+
def parse(cls: type[_T_Streamable], f: BinaryIO) -> _T_Streamable:
|
|
579
|
+
# Create the object without calling __init__() to avoid unnecessary post-init checks in strictdataclass
|
|
580
|
+
obj: _T_Streamable = object.__new__(cls)
|
|
581
|
+
for field in cls._streamable_fields:
|
|
582
|
+
object.__setattr__(obj, field.name, field.parse_function(f))
|
|
583
|
+
return obj
|
|
584
|
+
|
|
585
|
+
def stream(self, f: BinaryIO) -> None:
|
|
586
|
+
for field in self._streamable_fields:
|
|
587
|
+
field.stream_function(getattr(self, field.name), f)
|
|
588
|
+
|
|
589
|
+
def get_hash(self) -> bytes32:
|
|
590
|
+
return std_hash(bytes(self), skip_bytes_conversion=True)
|
|
591
|
+
|
|
592
|
+
@classmethod
|
|
593
|
+
def from_bytes(cls: type[_T_Streamable], blob: bytes) -> _T_Streamable:
|
|
594
|
+
f = io.BytesIO(blob)
|
|
595
|
+
parsed = cls.parse(f)
|
|
596
|
+
assert f.read() == b""
|
|
597
|
+
return parsed
|
|
598
|
+
|
|
599
|
+
def stream_to_bytes(self) -> bytes:
|
|
600
|
+
f = io.BytesIO()
|
|
601
|
+
self.stream(f)
|
|
602
|
+
return bytes(f.getvalue())
|
|
603
|
+
|
|
604
|
+
def __bytes__(self: Any) -> bytes:
|
|
605
|
+
f = io.BytesIO()
|
|
606
|
+
self.stream(f)
|
|
607
|
+
return bytes(f.getvalue())
|
|
608
|
+
|
|
609
|
+
def __str__(self: Any) -> str:
|
|
610
|
+
return pp.pformat(recurse_jsonify(self))
|
|
611
|
+
|
|
612
|
+
def __repr__(self: Any) -> str:
|
|
613
|
+
return pp.pformat(recurse_jsonify(self))
|
|
614
|
+
|
|
615
|
+
def to_json_dict(self) -> dict[str, Any]:
|
|
616
|
+
ret: dict[str, Any] = recurse_jsonify(self)
|
|
617
|
+
return ret
|
|
618
|
+
|
|
619
|
+
@classmethod
|
|
620
|
+
def from_json_dict(cls: type[_T_Streamable], json_dict: dict[str, Any]) -> _T_Streamable:
|
|
621
|
+
return streamable_from_dict(cls, json_dict)
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
@streamable
|
|
625
|
+
@dataclasses.dataclass(frozen=True)
|
|
626
|
+
class VersionedBlob(Streamable):
|
|
627
|
+
version: uint16
|
|
628
|
+
blob: bytes
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
@streamable
|
|
632
|
+
@dataclasses.dataclass(frozen=True)
|
|
633
|
+
class UInt32Range(Streamable):
|
|
634
|
+
start: uint32 = uint32(0)
|
|
635
|
+
stop: uint32 = uint32.MAXIMUM
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
@streamable
|
|
639
|
+
@dataclasses.dataclass(frozen=True)
|
|
640
|
+
class UInt64Range(Streamable):
|
|
641
|
+
start: uint64 = uint64(0)
|
|
642
|
+
stop: uint64 = uint64.MAXIMUM
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# TODO: this should not exist, it is a bad task group that doesn't require
|
|
2
|
+
# any responsibility of the requestor.
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import asyncio
|
|
7
|
+
import dataclasses
|
|
8
|
+
import logging
|
|
9
|
+
import typing
|
|
10
|
+
|
|
11
|
+
T = typing.TypeVar("T")
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclasses.dataclass(frozen=True)
|
|
17
|
+
class _TaskInfo:
|
|
18
|
+
task: asyncio.Task[object]
|
|
19
|
+
# retained for potential debugging use
|
|
20
|
+
known_unreferenced: bool
|
|
21
|
+
|
|
22
|
+
def __str__(self) -> str:
|
|
23
|
+
return self.task.get_name()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclasses.dataclass
|
|
27
|
+
class _TaskReferencer:
|
|
28
|
+
"""Holds strong references to tasks until they are done. This compensates for
|
|
29
|
+
asyncio holding only weak references. This should be replaced by patterns using
|
|
30
|
+
task groups such as from anyio.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
tasks: dict[asyncio.Task[object], _TaskInfo] = dataclasses.field(default_factory=dict)
|
|
34
|
+
|
|
35
|
+
def create_task(
|
|
36
|
+
self,
|
|
37
|
+
coroutine: typing.Coroutine[object, object, T],
|
|
38
|
+
*,
|
|
39
|
+
name: typing.Optional[str] = None,
|
|
40
|
+
known_unreferenced: bool = False,
|
|
41
|
+
) -> asyncio.Task[T]:
|
|
42
|
+
task = asyncio.create_task(coro=coroutine, name=name) # noqa: TID251
|
|
43
|
+
task.add_done_callback(self._task_done)
|
|
44
|
+
|
|
45
|
+
self.tasks[task] = _TaskInfo(task=task, known_unreferenced=known_unreferenced)
|
|
46
|
+
|
|
47
|
+
return task
|
|
48
|
+
|
|
49
|
+
def _task_done(self, task: asyncio.Task[object]) -> None:
|
|
50
|
+
# TODO: consider collecting results and logging errors
|
|
51
|
+
try:
|
|
52
|
+
del self.tasks[task]
|
|
53
|
+
except KeyError:
|
|
54
|
+
logger.warning("Task not found in task referencer: %s", task)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
_global_task_referencer = _TaskReferencer()
|
|
58
|
+
|
|
59
|
+
create_referenced_task = _global_task_referencer.create_task
|