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,469 @@
|
|
|
1
|
+
# Package: utils
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import base64
|
|
6
|
+
import contextlib
|
|
7
|
+
import os
|
|
8
|
+
import shutil
|
|
9
|
+
import threading
|
|
10
|
+
from collections.abc import Iterator
|
|
11
|
+
from dataclasses import asdict, dataclass, field
|
|
12
|
+
from hashlib import pbkdf2_hmac
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from secrets import token_bytes
|
|
15
|
+
from typing import Any, Optional, Union, cast
|
|
16
|
+
|
|
17
|
+
import yaml
|
|
18
|
+
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # pyright: reportMissingModuleSource=false
|
|
19
|
+
from typing_extensions import final
|
|
20
|
+
from watchdog.events import DirModifiedEvent, FileSystemEvent, FileSystemEventHandler
|
|
21
|
+
from watchdog.observers import Observer
|
|
22
|
+
from watchdog.observers.api import BaseObserver
|
|
23
|
+
|
|
24
|
+
from chia.util.default_root import DEFAULT_KEYS_ROOT_PATH
|
|
25
|
+
from chia.util.errors import KeychainFingerprintNotFound, KeychainLabelExists, KeychainLabelInvalid
|
|
26
|
+
from chia.util.lock import Lockfile
|
|
27
|
+
from chia.util.streamable import convert_byte_type
|
|
28
|
+
|
|
29
|
+
SALT_BYTES = 16 # PBKDF2 param
|
|
30
|
+
NONCE_BYTES = 12 # ChaCha20Poly1305 nonce is 12-bytes
|
|
31
|
+
HASH_ITERS = 100000 # PBKDF2 param
|
|
32
|
+
CHECKBYTES_VALUE = b"5f365b8292ee505b" # Randomly generated
|
|
33
|
+
MAX_LABEL_LENGTH = 65
|
|
34
|
+
MAX_SUPPORTED_VERSION = 1 # Max supported file format version
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def generate_nonce() -> bytes:
|
|
38
|
+
"""
|
|
39
|
+
Creates a nonce to be used by ChaCha20Poly1305. This should be called each time
|
|
40
|
+
the payload is encrypted.
|
|
41
|
+
"""
|
|
42
|
+
return token_bytes(NONCE_BYTES)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def generate_salt() -> bytes:
|
|
46
|
+
"""
|
|
47
|
+
Creates a salt to be used in combination with the master passphrase to derive
|
|
48
|
+
a symmetric key using PBKDF2
|
|
49
|
+
"""
|
|
50
|
+
return token_bytes(SALT_BYTES)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def symmetric_key_from_passphrase(passphrase: str, salt: bytes) -> bytes:
|
|
54
|
+
return pbkdf2_hmac("sha256", passphrase.encode(), salt, HASH_ITERS)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def encrypt_data(input_data: bytes, key: bytes, nonce: bytes) -> bytes:
|
|
58
|
+
encryptor = ChaCha20Poly1305(key)
|
|
59
|
+
data = encryptor.encrypt(nonce, CHECKBYTES_VALUE + input_data, None)
|
|
60
|
+
return data
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def decrypt_data(input_data: bytes, key: bytes, nonce: bytes) -> bytes:
|
|
64
|
+
decryptor = ChaCha20Poly1305(key)
|
|
65
|
+
output = decryptor.decrypt(nonce, input_data, None)
|
|
66
|
+
if CHECKBYTES_VALUE != output[: len(CHECKBYTES_VALUE)]:
|
|
67
|
+
raise ValueError("decryption failure (checkbytes)")
|
|
68
|
+
return output[len(CHECKBYTES_VALUE) :]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def default_file_keyring_data() -> DecryptedKeyringData:
|
|
72
|
+
return DecryptedKeyringData({}, {})
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def keyring_path_from_root(keys_root_path: Path) -> Path:
|
|
76
|
+
"""
|
|
77
|
+
Returns the path to keyring.yaml
|
|
78
|
+
"""
|
|
79
|
+
path_filename = keys_root_path / "keyring.yaml"
|
|
80
|
+
return path_filename
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class FileKeyringVersionError(Exception):
|
|
84
|
+
def __init__(self, actual_version: int) -> None:
|
|
85
|
+
super().__init__(
|
|
86
|
+
f"Keyring format is unrecognized. Found version {actual_version}"
|
|
87
|
+
f", expected a value <= {MAX_SUPPORTED_VERSION}. "
|
|
88
|
+
"Please update to a newer version"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@final
|
|
93
|
+
@dataclass
|
|
94
|
+
class FileKeyringContent:
|
|
95
|
+
"""
|
|
96
|
+
FileKeyringContent represents the data structure of the keyring file. It contains an encrypted data part which is
|
|
97
|
+
encrypted with a key derived from the user-provided master passphrase.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
# The version of the whole keyring file structure
|
|
101
|
+
version: int = 1
|
|
102
|
+
# Random salt used as a PBKDF2 parameter. Updated when the master passphrase changes
|
|
103
|
+
salt: bytes = field(default_factory=generate_salt)
|
|
104
|
+
# Random nonce used as a ChaCha20Poly1305 parameter. Updated on each write to the file.
|
|
105
|
+
nonce: bytes = field(default_factory=generate_nonce)
|
|
106
|
+
# Encrypted and base64 encoded keyring data.
|
|
107
|
+
# - The data with CHECKBYTES_VALUE prepended is encrypted using ChaCha20Poly1305.
|
|
108
|
+
# - The symmetric key is derived from the master passphrase using PBKDF2.
|
|
109
|
+
data: Optional[str] = None
|
|
110
|
+
# An optional passphrase hint
|
|
111
|
+
passphrase_hint: Optional[str] = None
|
|
112
|
+
|
|
113
|
+
def __post_init__(self) -> None:
|
|
114
|
+
self.salt = convert_byte_type(bytes, self.salt)
|
|
115
|
+
self.nonce = convert_byte_type(bytes, self.nonce)
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
def create_from_path(cls, path: Path) -> FileKeyringContent:
|
|
119
|
+
loaded_dict = dict(yaml.safe_load(path.read_text()))
|
|
120
|
+
version = int(loaded_dict["version"])
|
|
121
|
+
|
|
122
|
+
if version > MAX_SUPPORTED_VERSION:
|
|
123
|
+
raise FileKeyringVersionError(version)
|
|
124
|
+
|
|
125
|
+
return cls(**loaded_dict)
|
|
126
|
+
|
|
127
|
+
def write_to_path(self, path: Path) -> None:
|
|
128
|
+
os.makedirs(os.path.dirname(path), 0o700, True)
|
|
129
|
+
temp_path: Path = path.with_suffix("." + str(os.getpid()))
|
|
130
|
+
with open(os.open(str(temp_path), os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600), "w") as f:
|
|
131
|
+
_ = yaml.safe_dump(self.to_dict(), f)
|
|
132
|
+
try:
|
|
133
|
+
os.replace(str(temp_path), path)
|
|
134
|
+
except PermissionError:
|
|
135
|
+
shutil.move(str(temp_path), str(path))
|
|
136
|
+
|
|
137
|
+
def get_decrypted_data_dict(self, passphrase: str) -> dict[str, Any]:
|
|
138
|
+
if self.empty():
|
|
139
|
+
return {}
|
|
140
|
+
key = symmetric_key_from_passphrase(passphrase, self.salt)
|
|
141
|
+
encrypted_data_yml = base64.b64decode(yaml.safe_load(self.data or ""))
|
|
142
|
+
data_yml = decrypt_data(encrypted_data_yml, key, self.nonce)
|
|
143
|
+
return dict(yaml.safe_load(data_yml))
|
|
144
|
+
|
|
145
|
+
def update_encrypted_data_dict(
|
|
146
|
+
self, passphrase: str, decrypted_dict: DecryptedKeyringData, update_salt: bool
|
|
147
|
+
) -> None:
|
|
148
|
+
self.nonce = generate_nonce()
|
|
149
|
+
if update_salt:
|
|
150
|
+
self.salt = generate_salt()
|
|
151
|
+
data_yaml = yaml.safe_dump(decrypted_dict.to_dict())
|
|
152
|
+
key = symmetric_key_from_passphrase(passphrase, self.salt)
|
|
153
|
+
self.data = base64.b64encode(encrypt_data(data_yaml.encode(), key, self.nonce)).decode("utf-8")
|
|
154
|
+
|
|
155
|
+
def empty(self) -> bool:
|
|
156
|
+
return self.data is None or len(self.data) == 0
|
|
157
|
+
|
|
158
|
+
def to_dict(self) -> dict[str, Any]:
|
|
159
|
+
result = asdict(self)
|
|
160
|
+
result["salt"] = result["salt"].hex()
|
|
161
|
+
result["nonce"] = result["nonce"].hex()
|
|
162
|
+
return result
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@dataclass(frozen=True)
|
|
166
|
+
class Key:
|
|
167
|
+
secret: bytes
|
|
168
|
+
metadata: Optional[dict[str, Any]] = None
|
|
169
|
+
|
|
170
|
+
@classmethod
|
|
171
|
+
def parse(cls, data: str, metadata: Optional[dict[str, Any]]) -> Key:
|
|
172
|
+
return cls(
|
|
173
|
+
bytes.fromhex(data),
|
|
174
|
+
metadata,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def to_data(self) -> Union[str, dict[str, Any]]:
|
|
178
|
+
return self.secret.hex()
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
Users = dict[str, Key]
|
|
182
|
+
Services = dict[str, Users]
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@dataclass
|
|
186
|
+
class DecryptedKeyringData:
|
|
187
|
+
services: Services
|
|
188
|
+
labels: dict[int, str] # {fingerprint: label}
|
|
189
|
+
|
|
190
|
+
@classmethod
|
|
191
|
+
def from_dict(cls, data_dict: dict[str, Any]) -> DecryptedKeyringData:
|
|
192
|
+
return cls(
|
|
193
|
+
{
|
|
194
|
+
service: {
|
|
195
|
+
user: Key.parse(key, data_dict.get("metadata", {}).get(service, {}).get(user))
|
|
196
|
+
for user, key in users.items()
|
|
197
|
+
}
|
|
198
|
+
for service, users in data_dict.get("keys", {}).items()
|
|
199
|
+
},
|
|
200
|
+
data_dict.get("labels", {}),
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def to_dict(self) -> dict[str, Any]:
|
|
204
|
+
return {
|
|
205
|
+
"keys": {
|
|
206
|
+
service: {user: key.to_data() for user, key in users.items()}
|
|
207
|
+
for service, users in self.services.items()
|
|
208
|
+
},
|
|
209
|
+
"labels": self.labels,
|
|
210
|
+
"metadata": {
|
|
211
|
+
service: {user: key.metadata for user, key in users.items() if key.metadata is not None}
|
|
212
|
+
for service, users in self.services.items()
|
|
213
|
+
},
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@final
|
|
218
|
+
@dataclass
|
|
219
|
+
class FileKeyring(FileSystemEventHandler):
|
|
220
|
+
"""
|
|
221
|
+
FileKeyring provides a file-based keyring store to manage a FileKeyringContent .The public interface is intended
|
|
222
|
+
to align with the API provided by the keyring module such that the KeyringWrapper class can pick an appropriate
|
|
223
|
+
keyring store backend based on the OS.
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
keyring_path: Path
|
|
227
|
+
# Cache of the whole plaintext YAML file contents (never encrypted)
|
|
228
|
+
cached_file_content: FileKeyringContent
|
|
229
|
+
keyring_observer: BaseObserver = field(default_factory=Observer)
|
|
230
|
+
load_keyring_lock: threading.RLock = field(default_factory=threading.RLock) # Guards access to needs_load_keyring
|
|
231
|
+
needs_load_keyring: bool = False
|
|
232
|
+
# Cache of the decrypted YAML contained in keyring.data
|
|
233
|
+
cached_data_dict: DecryptedKeyringData = field(default_factory=default_file_keyring_data)
|
|
234
|
+
keyring_last_mod_time: Optional[float] = None
|
|
235
|
+
# Key/value pairs to set on the outer payload on the next write
|
|
236
|
+
file_content_properties_for_next_write: dict[str, Any] = field(default_factory=dict)
|
|
237
|
+
|
|
238
|
+
@classmethod
|
|
239
|
+
def create(cls, keys_root_path: Path = DEFAULT_KEYS_ROOT_PATH) -> FileKeyring:
|
|
240
|
+
"""
|
|
241
|
+
Creates a fresh keyring.yaml file if necessary. Otherwise, loads and caches file content.
|
|
242
|
+
"""
|
|
243
|
+
keyring_path = keyring_path_from_root(keys_root_path)
|
|
244
|
+
|
|
245
|
+
try:
|
|
246
|
+
file_content = FileKeyringContent.create_from_path(keyring_path)
|
|
247
|
+
except FileNotFoundError:
|
|
248
|
+
# Write the default file content to disk
|
|
249
|
+
file_content = FileKeyringContent()
|
|
250
|
+
file_content.write_to_path(keyring_path)
|
|
251
|
+
|
|
252
|
+
obj = cls(
|
|
253
|
+
keyring_path=keyring_path,
|
|
254
|
+
cached_file_content=file_content,
|
|
255
|
+
)
|
|
256
|
+
obj.setup_keyring_file_watcher()
|
|
257
|
+
|
|
258
|
+
return obj
|
|
259
|
+
|
|
260
|
+
def __hash__(self) -> int:
|
|
261
|
+
return hash(self.keyring_path)
|
|
262
|
+
|
|
263
|
+
@contextlib.contextmanager
|
|
264
|
+
def lock_and_reload_if_required(self) -> Iterator[None]:
|
|
265
|
+
with Lockfile.create(self.keyring_path, timeout=30, poll_interval=0.2):
|
|
266
|
+
self.check_if_keyring_file_modified()
|
|
267
|
+
with self.load_keyring_lock:
|
|
268
|
+
if self.needs_load_keyring:
|
|
269
|
+
self.load_keyring()
|
|
270
|
+
yield
|
|
271
|
+
|
|
272
|
+
def setup_keyring_file_watcher(self) -> None:
|
|
273
|
+
# recursive=True necessary for macOS support
|
|
274
|
+
if not self.keyring_observer.is_alive():
|
|
275
|
+
self.keyring_observer.schedule(
|
|
276
|
+
self,
|
|
277
|
+
str(self.keyring_path.parent),
|
|
278
|
+
recursive=True,
|
|
279
|
+
)
|
|
280
|
+
self.keyring_observer.start()
|
|
281
|
+
|
|
282
|
+
def cleanup_keyring_file_watcher(self) -> None:
|
|
283
|
+
if self.keyring_observer.is_alive():
|
|
284
|
+
self.keyring_observer.stop()
|
|
285
|
+
self.keyring_observer.join()
|
|
286
|
+
|
|
287
|
+
def on_modified(self, event: Union[FileSystemEvent, DirModifiedEvent]) -> None:
|
|
288
|
+
self.check_if_keyring_file_modified()
|
|
289
|
+
|
|
290
|
+
def check_if_keyring_file_modified(self) -> None:
|
|
291
|
+
try:
|
|
292
|
+
last_modified = os.stat(self.keyring_path).st_mtime
|
|
293
|
+
if not self.keyring_last_mod_time or self.keyring_last_mod_time < last_modified:
|
|
294
|
+
self.keyring_last_mod_time = last_modified
|
|
295
|
+
with self.load_keyring_lock:
|
|
296
|
+
self.needs_load_keyring = True
|
|
297
|
+
except FileNotFoundError:
|
|
298
|
+
# If the file doesn't exist there's nothing to do...
|
|
299
|
+
pass
|
|
300
|
+
|
|
301
|
+
def has_content(self) -> bool:
|
|
302
|
+
"""
|
|
303
|
+
Quick test to determine if keyring contains anything in keyring.data.
|
|
304
|
+
"""
|
|
305
|
+
return not self.cached_file_content.empty()
|
|
306
|
+
|
|
307
|
+
def cached_keys(self) -> Services:
|
|
308
|
+
"""
|
|
309
|
+
Returns keyring.data.keys
|
|
310
|
+
"""
|
|
311
|
+
return self.cached_data_dict.services
|
|
312
|
+
|
|
313
|
+
def cached_labels(self) -> dict[int, str]:
|
|
314
|
+
"""
|
|
315
|
+
Returns keyring.data.labels
|
|
316
|
+
"""
|
|
317
|
+
return self.cached_data_dict.labels
|
|
318
|
+
|
|
319
|
+
def get_key(self, service: str, user: str) -> Optional[Key]:
|
|
320
|
+
"""
|
|
321
|
+
Returns the passphrase named by the 'user' parameter from the cached
|
|
322
|
+
keyring data (does not force a read from disk)
|
|
323
|
+
"""
|
|
324
|
+
with self.lock_and_reload_if_required():
|
|
325
|
+
return self.cached_keys().get(service, {}).get(user)
|
|
326
|
+
|
|
327
|
+
def set_key(self, service: str, user: str, key: Key) -> None:
|
|
328
|
+
"""
|
|
329
|
+
Store the passphrase to the keyring data using the name specified by the
|
|
330
|
+
'user' parameter. Will force a write to keyring.yaml on success.
|
|
331
|
+
"""
|
|
332
|
+
with self.lock_and_reload_if_required():
|
|
333
|
+
keys = self.cached_keys()
|
|
334
|
+
# Ensure a dictionary exists for the 'service'
|
|
335
|
+
if keys.get(service) is None:
|
|
336
|
+
keys[service] = {}
|
|
337
|
+
keys[service][user] = key
|
|
338
|
+
self.write_keyring()
|
|
339
|
+
|
|
340
|
+
def delete_key(self, service: str, user: str) -> None:
|
|
341
|
+
"""
|
|
342
|
+
Deletes the passphrase named by the 'user' parameter from the keyring data
|
|
343
|
+
(will force a write to keyring.yaml on success)
|
|
344
|
+
"""
|
|
345
|
+
with self.lock_and_reload_if_required():
|
|
346
|
+
keys = self.cached_keys()
|
|
347
|
+
service_dict = keys.get(service, {})
|
|
348
|
+
if service_dict.pop(user, None):
|
|
349
|
+
if len(service_dict) == 0:
|
|
350
|
+
keys.pop(service)
|
|
351
|
+
self.write_keyring()
|
|
352
|
+
|
|
353
|
+
def get_label(self, fingerprint: int) -> Optional[str]:
|
|
354
|
+
"""
|
|
355
|
+
Returns the label for the given fingerprint or None if there is no label assigned.
|
|
356
|
+
"""
|
|
357
|
+
with self.lock_and_reload_if_required():
|
|
358
|
+
return self.cached_labels().get(fingerprint)
|
|
359
|
+
|
|
360
|
+
def set_label(self, fingerprint: int, label: str) -> None:
|
|
361
|
+
"""
|
|
362
|
+
Set a label for the given fingerprint. This will force a write to keyring.yaml on success.
|
|
363
|
+
"""
|
|
364
|
+
# First validate the label
|
|
365
|
+
stripped_label = label.strip()
|
|
366
|
+
if len(stripped_label) == 0:
|
|
367
|
+
raise KeychainLabelInvalid(label, "label can't be empty or whitespace only")
|
|
368
|
+
if len(stripped_label) != len(label):
|
|
369
|
+
raise KeychainLabelInvalid(label, "label can't contain leading or trailing whitespaces")
|
|
370
|
+
if len(label) != len(label.replace("\n", "").replace("\t", "")):
|
|
371
|
+
raise KeychainLabelInvalid(label, "label can't contain newline or tab")
|
|
372
|
+
if len(label) > MAX_LABEL_LENGTH:
|
|
373
|
+
raise KeychainLabelInvalid(label, f"label exceeds max length: {len(label)}/{MAX_LABEL_LENGTH}")
|
|
374
|
+
# Then try to set it
|
|
375
|
+
with self.lock_and_reload_if_required():
|
|
376
|
+
labels = self.cached_labels()
|
|
377
|
+
for existing_fingerprint, existing_label in labels.items():
|
|
378
|
+
if label == existing_label:
|
|
379
|
+
raise KeychainLabelExists(label, existing_fingerprint)
|
|
380
|
+
labels[fingerprint] = label
|
|
381
|
+
self.write_keyring()
|
|
382
|
+
|
|
383
|
+
def delete_label(self, fingerprint: int) -> None:
|
|
384
|
+
"""
|
|
385
|
+
Removes the label for the fingerprint. This will force a write to keyring.yaml on success.
|
|
386
|
+
"""
|
|
387
|
+
with self.lock_and_reload_if_required():
|
|
388
|
+
try:
|
|
389
|
+
self.cached_labels().pop(fingerprint)
|
|
390
|
+
except KeyError as e:
|
|
391
|
+
raise KeychainFingerprintNotFound(fingerprint) from e
|
|
392
|
+
self.write_keyring()
|
|
393
|
+
|
|
394
|
+
def check_passphrase(self, passphrase: str, force_reload: bool = False) -> bool:
|
|
395
|
+
"""
|
|
396
|
+
Attempts to validate the passphrase by decrypting keyring.data
|
|
397
|
+
contents and checking the checkbytes value
|
|
398
|
+
"""
|
|
399
|
+
if force_reload:
|
|
400
|
+
self.cached_file_content = FileKeyringContent.create_from_path(self.keyring_path)
|
|
401
|
+
|
|
402
|
+
try:
|
|
403
|
+
self.cached_file_content.get_decrypted_data_dict(passphrase)
|
|
404
|
+
return True
|
|
405
|
+
except Exception:
|
|
406
|
+
return False
|
|
407
|
+
|
|
408
|
+
def load_keyring(self, passphrase: Optional[str] = None) -> None:
|
|
409
|
+
from chia.util.keyring_wrapper import obtain_current_passphrase
|
|
410
|
+
|
|
411
|
+
with self.load_keyring_lock:
|
|
412
|
+
self.needs_load_keyring = False
|
|
413
|
+
|
|
414
|
+
self.cached_file_content = FileKeyringContent.create_from_path(self.keyring_path)
|
|
415
|
+
|
|
416
|
+
if not self.has_content():
|
|
417
|
+
return
|
|
418
|
+
|
|
419
|
+
if passphrase is None:
|
|
420
|
+
# TODO, this prompts for the passphrase interactively, move this out
|
|
421
|
+
passphrase = obtain_current_passphrase(use_passphrase_cache=True)
|
|
422
|
+
|
|
423
|
+
self.cached_data_dict = DecryptedKeyringData.from_dict(
|
|
424
|
+
self.cached_file_content.get_decrypted_data_dict(passphrase)
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
def write_keyring(self, fresh_salt: bool = False) -> None:
|
|
428
|
+
from chia.util.keyring_wrapper import KeyringWrapper, obtain_current_passphrase
|
|
429
|
+
|
|
430
|
+
# Merge in other properties like "passphrase_hint"
|
|
431
|
+
if "passphrase_hint" in self.file_content_properties_for_next_write:
|
|
432
|
+
self.cached_file_content.passphrase_hint = self.file_content_properties_for_next_write["passphrase_hint"]
|
|
433
|
+
|
|
434
|
+
# When writing for the first time, we should have a cached passphrase which hasn't been
|
|
435
|
+
# validated (because it can't be validated yet...)
|
|
436
|
+
if not self.has_content() and KeyringWrapper.get_shared_instance().has_cached_master_passphrase():
|
|
437
|
+
# TODO: The above checks, at the time of writing, make sure we get a str here. A reconsideration of this
|
|
438
|
+
# interface would be good.
|
|
439
|
+
passphrase = cast(str, KeyringWrapper.get_shared_instance().get_cached_master_passphrase()[0])
|
|
440
|
+
else:
|
|
441
|
+
# TODO, this prompts for the passphrase interactively, move this out
|
|
442
|
+
passphrase = obtain_current_passphrase(use_passphrase_cache=True)
|
|
443
|
+
|
|
444
|
+
try:
|
|
445
|
+
self.cached_file_content.update_encrypted_data_dict(passphrase, self.cached_data_dict, fresh_salt)
|
|
446
|
+
self.cached_file_content.write_to_path(self.keyring_path)
|
|
447
|
+
# Cleanup the cached properties now that we wrote the new content to file
|
|
448
|
+
self.file_content_properties_for_next_write = {}
|
|
449
|
+
except Exception:
|
|
450
|
+
# Restore the correct content if we failed to write the updated cache, let it re-raise if loading also fails
|
|
451
|
+
self.cached_file_content = FileKeyringContent.create_from_path(self.keyring_path)
|
|
452
|
+
|
|
453
|
+
def get_passphrase_hint(self) -> Optional[str]:
|
|
454
|
+
"""
|
|
455
|
+
Return the passphrase hint (if set). The hint data may not yet be written to the keyring, so we
|
|
456
|
+
return the hint data either from the staging dict (file_content_properties_for_next_write), or
|
|
457
|
+
from cached_file_content (loaded from the keyring)
|
|
458
|
+
"""
|
|
459
|
+
passphrase_hint: Optional[str] = self.file_content_properties_for_next_write.get("passphrase_hint", None)
|
|
460
|
+
if passphrase_hint is None:
|
|
461
|
+
passphrase_hint = self.cached_file_content.passphrase_hint
|
|
462
|
+
return passphrase_hint
|
|
463
|
+
|
|
464
|
+
def set_passphrase_hint(self, passphrase_hint: Optional[str]) -> None:
|
|
465
|
+
"""
|
|
466
|
+
Store the new passphrase hint in the staging dict (file_content_properties_for_next_write) to
|
|
467
|
+
be written-out on the next write to the keyring.
|
|
468
|
+
"""
|
|
469
|
+
self.file_content_properties_for_next_write["passphrase_hint"] = passphrase_hint
|
chia/util/files.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Package: utils
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
import os
|
|
8
|
+
import shutil
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Union
|
|
11
|
+
|
|
12
|
+
from aiofiles import tempfile
|
|
13
|
+
from typing_extensions import Literal
|
|
14
|
+
|
|
15
|
+
log = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def move_file(src: Path, dst: Path) -> None:
|
|
19
|
+
"""
|
|
20
|
+
Attempts to move the file at src to dst, falling back to a copy if the move fails.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
dir_perms: int = 0o700
|
|
24
|
+
# Create the parent directory if necessary
|
|
25
|
+
os.makedirs(dst.parent, mode=dir_perms, exist_ok=True)
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
# Attempt an atomic move first
|
|
29
|
+
os.replace(os.fspath(src), os.fspath(dst))
|
|
30
|
+
except Exception as e:
|
|
31
|
+
log.debug(f"Failed to move {src} to {dst} using os.replace, reattempting with shutil.move: {e}")
|
|
32
|
+
try:
|
|
33
|
+
# If that fails, use the more robust shutil.move(), though it may internally initiate a copy
|
|
34
|
+
shutil.move(os.fspath(src), os.fspath(dst))
|
|
35
|
+
except Exception:
|
|
36
|
+
log.exception(f"Failed to move {src} to {dst} using shutil.move")
|
|
37
|
+
raise
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
async def move_file_async(src: Path, dst: Path, *, reattempts: int = 6, reattempt_delay: float = 0.5) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Attempts to move the file at src to dst, making multiple attempts if the move fails.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
remaining_attempts: int = reattempts
|
|
46
|
+
while True:
|
|
47
|
+
try:
|
|
48
|
+
move_file(src, dst)
|
|
49
|
+
except Exception:
|
|
50
|
+
if remaining_attempts > 0:
|
|
51
|
+
log.debug(f"Failed to move {src} to {dst}, retrying in {reattempt_delay} seconds")
|
|
52
|
+
remaining_attempts -= 1
|
|
53
|
+
await asyncio.sleep(reattempt_delay)
|
|
54
|
+
else:
|
|
55
|
+
break
|
|
56
|
+
else:
|
|
57
|
+
break
|
|
58
|
+
|
|
59
|
+
if not dst.exists():
|
|
60
|
+
raise FileNotFoundError(f"Failed to move {src} to {dst}")
|
|
61
|
+
else:
|
|
62
|
+
log.debug(f"Moved {src} to {dst}")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
async def write_file_async(
|
|
66
|
+
file_path: Path, data: Union[str, bytes], *, file_mode: int = 0o600, dir_mode: int = 0o700
|
|
67
|
+
) -> None:
|
|
68
|
+
"""
|
|
69
|
+
Writes the provided data to a temporary file and then moves it to the final destination.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
# Create the parent directory if necessary
|
|
73
|
+
os.makedirs(file_path.parent, mode=dir_mode, exist_ok=True)
|
|
74
|
+
|
|
75
|
+
mode: Literal["w+", "w+b"] = "w+" if type(data) is str else "w+b"
|
|
76
|
+
temp_file_path: Path
|
|
77
|
+
async with tempfile.NamedTemporaryFile(dir=file_path.parent, mode=mode, delete=False) as f:
|
|
78
|
+
# Ignoring type error since it is not obvious how to tie the type of the data
|
|
79
|
+
# being passed in to the type of the file object, etc.
|
|
80
|
+
temp_file_path = f.name # type: ignore[assignment]
|
|
81
|
+
await f.write(data) # type: ignore[arg-type]
|
|
82
|
+
await f.flush()
|
|
83
|
+
os.fsync(f.fileno())
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
await move_file_async(temp_file_path, file_path)
|
|
87
|
+
except Exception:
|
|
88
|
+
log.exception(f"Failed to move temp file {temp_file_path} to {file_path}")
|
|
89
|
+
else:
|
|
90
|
+
os.chmod(file_path, file_mode)
|
|
91
|
+
finally:
|
|
92
|
+
# We expect the file replace/move to have succeeded, but cleanup the temp file just in case
|
|
93
|
+
try:
|
|
94
|
+
if Path(temp_file_path).exists():
|
|
95
|
+
os.remove(temp_file_path)
|
|
96
|
+
except Exception:
|
|
97
|
+
log.exception(f"Failed to remove temp file {temp_file_path}")
|