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,1311 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import dataclasses
|
|
4
|
+
import logging
|
|
5
|
+
import time
|
|
6
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Optional, cast
|
|
7
|
+
|
|
8
|
+
from chia_rs import G1Element, G2Element
|
|
9
|
+
from clvm.EvalError import EvalError
|
|
10
|
+
from typing_extensions import Unpack, final
|
|
11
|
+
|
|
12
|
+
from chia.consensus.block_record import BlockRecord
|
|
13
|
+
from chia.data_layer.data_layer_errors import LauncherCoinNotFoundError, OfferIntegrityError
|
|
14
|
+
from chia.data_layer.data_layer_util import OfferStore, ProofOfInclusion, ProofOfInclusionLayer, StoreProofs, leaf_hash
|
|
15
|
+
from chia.protocols.wallet_protocol import CoinState
|
|
16
|
+
from chia.server.ws_connection import WSChiaConnection
|
|
17
|
+
from chia.types.blockchain_format.coin import Coin
|
|
18
|
+
from chia.types.blockchain_format.program import Program
|
|
19
|
+
from chia.types.blockchain_format.serialized_program import SerializedProgram
|
|
20
|
+
from chia.types.blockchain_format.sized_bytes import bytes32
|
|
21
|
+
from chia.types.coin_spend import CoinSpend, compute_additions
|
|
22
|
+
from chia.types.condition_opcodes import ConditionOpcode
|
|
23
|
+
from chia.util.ints import uint8, uint32, uint64, uint128
|
|
24
|
+
from chia.util.streamable import Streamable, streamable
|
|
25
|
+
from chia.wallet.conditions import (
|
|
26
|
+
AssertAnnouncement,
|
|
27
|
+
AssertCoinAnnouncement,
|
|
28
|
+
AssertPuzzleAnnouncement,
|
|
29
|
+
Condition,
|
|
30
|
+
CreateCoinAnnouncement,
|
|
31
|
+
UnknownCondition,
|
|
32
|
+
parse_timelock_info,
|
|
33
|
+
)
|
|
34
|
+
from chia.wallet.db_wallet.db_wallet_puzzles import (
|
|
35
|
+
ACS_MU,
|
|
36
|
+
ACS_MU_PH,
|
|
37
|
+
GRAFTROOT_DL_OFFERS,
|
|
38
|
+
SINGLETON_LAUNCHER,
|
|
39
|
+
create_graftroot_offer_puz,
|
|
40
|
+
create_host_fullpuz,
|
|
41
|
+
create_host_layer_puzzle,
|
|
42
|
+
create_mirror_puzzle,
|
|
43
|
+
get_mirror_info,
|
|
44
|
+
launch_solution_to_singleton_info,
|
|
45
|
+
launcher_to_struct,
|
|
46
|
+
match_dl_singleton,
|
|
47
|
+
)
|
|
48
|
+
from chia.wallet.derivation_record import DerivationRecord
|
|
49
|
+
from chia.wallet.lineage_proof import LineageProof
|
|
50
|
+
from chia.wallet.outer_puzzles import AssetType
|
|
51
|
+
from chia.wallet.payment import Payment
|
|
52
|
+
from chia.wallet.puzzle_drivers import PuzzleInfo, Solver
|
|
53
|
+
from chia.wallet.puzzles.singleton_top_layer_v1_1 import SINGLETON_LAUNCHER_HASH
|
|
54
|
+
from chia.wallet.trading.offer import NotarizedPayment, Offer
|
|
55
|
+
from chia.wallet.transaction_record import TransactionRecord
|
|
56
|
+
from chia.wallet.util.compute_memos import compute_memos
|
|
57
|
+
from chia.wallet.util.merkle_utils import _simplify_merkle_proof
|
|
58
|
+
from chia.wallet.util.transaction_type import TransactionType
|
|
59
|
+
from chia.wallet.util.wallet_sync_utils import fetch_coin_spend, fetch_coin_spend_for_coin_state
|
|
60
|
+
from chia.wallet.util.wallet_types import WalletType
|
|
61
|
+
from chia.wallet.wallet import Wallet
|
|
62
|
+
from chia.wallet.wallet_action_scope import WalletActionScope
|
|
63
|
+
from chia.wallet.wallet_coin_record import WalletCoinRecord
|
|
64
|
+
from chia.wallet.wallet_info import WalletInfo
|
|
65
|
+
from chia.wallet.wallet_protocol import GSTOptionalArgs, WalletProtocol
|
|
66
|
+
from chia.wallet.wallet_spend_bundle import WalletSpendBundle
|
|
67
|
+
|
|
68
|
+
if TYPE_CHECKING:
|
|
69
|
+
from chia.wallet.wallet_state_manager import WalletStateManager
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@streamable
|
|
73
|
+
@dataclasses.dataclass(frozen=True)
|
|
74
|
+
class SingletonRecord(Streamable):
|
|
75
|
+
coin_id: bytes32
|
|
76
|
+
launcher_id: bytes32
|
|
77
|
+
root: bytes32
|
|
78
|
+
inner_puzzle_hash: bytes32
|
|
79
|
+
confirmed: bool
|
|
80
|
+
confirmed_at_height: uint32
|
|
81
|
+
lineage_proof: LineageProof
|
|
82
|
+
generation: uint32
|
|
83
|
+
timestamp: uint64
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclasses.dataclass(frozen=True)
|
|
87
|
+
class Mirror:
|
|
88
|
+
coin_id: bytes32
|
|
89
|
+
launcher_id: bytes32
|
|
90
|
+
amount: uint64
|
|
91
|
+
urls: list[bytes]
|
|
92
|
+
ours: bool
|
|
93
|
+
confirmed_at_height: Optional[uint32]
|
|
94
|
+
|
|
95
|
+
def to_json_dict(self) -> dict[str, Any]:
|
|
96
|
+
return {
|
|
97
|
+
"coin_id": self.coin_id.hex(),
|
|
98
|
+
"launcher_id": self.launcher_id.hex(),
|
|
99
|
+
"amount": self.amount,
|
|
100
|
+
"urls": [url.decode("utf8") for url in self.urls],
|
|
101
|
+
"ours": self.ours,
|
|
102
|
+
"confirmed_at_height": self.confirmed_at_height,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
def from_json_dict(cls, json_dict: dict[str, Any]) -> Mirror:
|
|
107
|
+
return cls(
|
|
108
|
+
bytes32.from_hexstr(json_dict["coin_id"]),
|
|
109
|
+
bytes32.from_hexstr(json_dict["launcher_id"]),
|
|
110
|
+
json_dict["amount"],
|
|
111
|
+
[bytes(url, "utf8") for url in json_dict["urls"]],
|
|
112
|
+
json_dict["ours"],
|
|
113
|
+
json_dict["confirmed_at_height"],
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@final
|
|
118
|
+
class DataLayerWallet:
|
|
119
|
+
if TYPE_CHECKING:
|
|
120
|
+
# TODO Create DataLayer coin data model if necessary
|
|
121
|
+
_protocol_check: ClassVar[WalletProtocol[object]] = cast("DataLayerWallet", None)
|
|
122
|
+
|
|
123
|
+
wallet_state_manager: WalletStateManager
|
|
124
|
+
log: logging.Logger
|
|
125
|
+
wallet_info: WalletInfo
|
|
126
|
+
wallet_id: uint8
|
|
127
|
+
standard_wallet: Wallet
|
|
128
|
+
"""
|
|
129
|
+
interface used by datalayer for interacting with the chain
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
@classmethod
|
|
133
|
+
async def create(
|
|
134
|
+
cls,
|
|
135
|
+
wallet_state_manager: WalletStateManager,
|
|
136
|
+
wallet_info: WalletInfo,
|
|
137
|
+
) -> DataLayerWallet:
|
|
138
|
+
self = cls()
|
|
139
|
+
self.wallet_state_manager = wallet_state_manager
|
|
140
|
+
self.log = logging.getLogger(__name__)
|
|
141
|
+
self.standard_wallet = wallet_state_manager.main_wallet
|
|
142
|
+
self.wallet_info = wallet_info
|
|
143
|
+
self.wallet_id = uint8(self.wallet_info.id)
|
|
144
|
+
|
|
145
|
+
return self
|
|
146
|
+
|
|
147
|
+
@classmethod
|
|
148
|
+
def type(cls) -> WalletType:
|
|
149
|
+
return WalletType.DATA_LAYER
|
|
150
|
+
|
|
151
|
+
def id(self) -> uint32:
|
|
152
|
+
return self.wallet_info.id
|
|
153
|
+
|
|
154
|
+
@classmethod
|
|
155
|
+
async def create_new_dl_wallet(cls, wallet_state_manager: WalletStateManager) -> DataLayerWallet:
|
|
156
|
+
"""
|
|
157
|
+
This must be called under the wallet state manager lock
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
self = cls()
|
|
161
|
+
self.wallet_state_manager = wallet_state_manager
|
|
162
|
+
self.log = logging.getLogger(__name__)
|
|
163
|
+
self.standard_wallet = wallet_state_manager.main_wallet
|
|
164
|
+
|
|
165
|
+
for _, w in self.wallet_state_manager.wallets.items():
|
|
166
|
+
if w.type() == WalletType.DATA_LAYER:
|
|
167
|
+
raise ValueError("DataLayer Wallet already exists for this key")
|
|
168
|
+
|
|
169
|
+
self.wallet_info = await wallet_state_manager.user_store.create_wallet(
|
|
170
|
+
"DataLayer Wallet",
|
|
171
|
+
WalletType.DATA_LAYER.value,
|
|
172
|
+
"",
|
|
173
|
+
)
|
|
174
|
+
await self.wallet_state_manager.add_new_wallet(self)
|
|
175
|
+
|
|
176
|
+
return self
|
|
177
|
+
|
|
178
|
+
#############
|
|
179
|
+
# LAUNCHING #
|
|
180
|
+
#############
|
|
181
|
+
|
|
182
|
+
@staticmethod
|
|
183
|
+
async def match_dl_launcher(launcher_spend: CoinSpend) -> tuple[bool, Optional[bytes32]]:
|
|
184
|
+
# Sanity check it's a launcher
|
|
185
|
+
if launcher_spend.puzzle_reveal.to_program() != SINGLETON_LAUNCHER:
|
|
186
|
+
return False, None
|
|
187
|
+
|
|
188
|
+
# Let's make sure the solution looks how we expect it to
|
|
189
|
+
try:
|
|
190
|
+
full_puzhash, amount, root, inner_puzhash = launch_solution_to_singleton_info(
|
|
191
|
+
launcher_spend.solution.to_program()
|
|
192
|
+
)
|
|
193
|
+
except ValueError:
|
|
194
|
+
return False, None
|
|
195
|
+
|
|
196
|
+
# Now let's check that the full puzzle is an odd data layer singleton
|
|
197
|
+
if (
|
|
198
|
+
full_puzhash
|
|
199
|
+
!= create_host_fullpuz(inner_puzhash, root, launcher_spend.coin.name()).get_tree_hash_precalc(inner_puzhash)
|
|
200
|
+
or amount % 2 == 0
|
|
201
|
+
):
|
|
202
|
+
return False, None
|
|
203
|
+
|
|
204
|
+
return True, inner_puzhash
|
|
205
|
+
|
|
206
|
+
async def get_launcher_coin_state(self, launcher_id: bytes32, peer: WSChiaConnection) -> CoinState:
|
|
207
|
+
coin_states: list[CoinState] = await self.wallet_state_manager.wallet_node.get_coin_state(
|
|
208
|
+
[launcher_id], peer=peer
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
if len(coin_states) == 0:
|
|
212
|
+
raise LauncherCoinNotFoundError(f"Launcher ID {launcher_id} is not a valid coin")
|
|
213
|
+
if coin_states[0].coin.puzzle_hash != SINGLETON_LAUNCHER.get_tree_hash():
|
|
214
|
+
raise ValueError(f"Coin with ID {launcher_id} is not a singleton launcher")
|
|
215
|
+
if coin_states[0].created_height is None:
|
|
216
|
+
raise ValueError(f"Launcher with ID {launcher_id} has not been created (maybe reorged)")
|
|
217
|
+
if coin_states[0].spent_height is None:
|
|
218
|
+
raise ValueError(f"Launcher with ID {launcher_id} has not been spent")
|
|
219
|
+
|
|
220
|
+
return coin_states[0]
|
|
221
|
+
|
|
222
|
+
# This is the entry point for non-owned singletons
|
|
223
|
+
async def track_new_launcher_id(
|
|
224
|
+
self,
|
|
225
|
+
launcher_id: bytes32,
|
|
226
|
+
peer: WSChiaConnection,
|
|
227
|
+
spend: Optional[CoinSpend] = None,
|
|
228
|
+
height: Optional[uint32] = None,
|
|
229
|
+
) -> None:
|
|
230
|
+
if await self.wallet_state_manager.dl_store.get_launcher(launcher_id) is not None:
|
|
231
|
+
self.log.info(f"Spend of launcher {launcher_id} has already been processed")
|
|
232
|
+
return None
|
|
233
|
+
if spend is None or height is None:
|
|
234
|
+
launcher_state: CoinState = await self.get_launcher_coin_state(launcher_id, peer)
|
|
235
|
+
spend = await fetch_coin_spend_for_coin_state(launcher_state, peer)
|
|
236
|
+
assert launcher_state.spent_height is not None
|
|
237
|
+
height = uint32(launcher_state.spent_height)
|
|
238
|
+
|
|
239
|
+
assert spend.coin.name() == launcher_id, "coin_id should always match the launcher_id here"
|
|
240
|
+
|
|
241
|
+
full_puzhash, amount, root, inner_puzhash = launch_solution_to_singleton_info(spend.solution.to_program())
|
|
242
|
+
new_singleton = Coin(launcher_id, full_puzhash, amount)
|
|
243
|
+
|
|
244
|
+
singleton_record: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_latest_singleton(
|
|
245
|
+
launcher_id
|
|
246
|
+
)
|
|
247
|
+
if singleton_record is not None:
|
|
248
|
+
if ( # This is an unconfirmed singleton that we know about
|
|
249
|
+
singleton_record.coin_id == new_singleton.name() and not singleton_record.confirmed
|
|
250
|
+
):
|
|
251
|
+
timestamp = await self.wallet_state_manager.wallet_node.get_timestamp_for_height(height)
|
|
252
|
+
await self.wallet_state_manager.dl_store.set_confirmed(singleton_record.coin_id, height, timestamp)
|
|
253
|
+
else:
|
|
254
|
+
self.log.info(f"Spend of launcher {launcher_id} has already been processed")
|
|
255
|
+
return None
|
|
256
|
+
else:
|
|
257
|
+
timestamp = await self.wallet_state_manager.wallet_node.get_timestamp_for_height(height)
|
|
258
|
+
await self.wallet_state_manager.dl_store.add_singleton_record(
|
|
259
|
+
SingletonRecord(
|
|
260
|
+
coin_id=new_singleton.name(),
|
|
261
|
+
launcher_id=launcher_id,
|
|
262
|
+
root=root,
|
|
263
|
+
inner_puzzle_hash=inner_puzhash,
|
|
264
|
+
confirmed=True,
|
|
265
|
+
confirmed_at_height=height,
|
|
266
|
+
timestamp=timestamp,
|
|
267
|
+
lineage_proof=LineageProof(
|
|
268
|
+
launcher_id,
|
|
269
|
+
create_host_layer_puzzle(inner_puzhash, root).get_tree_hash_precalc(inner_puzhash),
|
|
270
|
+
amount,
|
|
271
|
+
),
|
|
272
|
+
generation=uint32(0),
|
|
273
|
+
)
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
await self.wallet_state_manager.dl_store.add_launcher(spend.coin, height)
|
|
277
|
+
await self.wallet_state_manager.add_interested_puzzle_hashes([launcher_id], [self.id()])
|
|
278
|
+
await self.wallet_state_manager.add_interested_coin_ids([new_singleton.name()])
|
|
279
|
+
|
|
280
|
+
new_singleton_coin_record: Optional[
|
|
281
|
+
WalletCoinRecord
|
|
282
|
+
] = await self.wallet_state_manager.coin_store.get_coin_record(new_singleton.name())
|
|
283
|
+
while new_singleton_coin_record is not None and new_singleton_coin_record.spent_block_height > 0:
|
|
284
|
+
# We've already synced this before, so we need to sort of force a resync
|
|
285
|
+
parent_spend = await fetch_coin_spend(new_singleton_coin_record.spent_block_height, new_singleton, peer)
|
|
286
|
+
await self.singleton_removed(parent_spend, new_singleton_coin_record.spent_block_height)
|
|
287
|
+
try:
|
|
288
|
+
additions = compute_additions(parent_spend)
|
|
289
|
+
new_singleton = next(coin for coin in additions if coin.amount % 2 != 0)
|
|
290
|
+
new_singleton_coin_record = await self.wallet_state_manager.coin_store.get_coin_record(
|
|
291
|
+
new_singleton.name()
|
|
292
|
+
)
|
|
293
|
+
except StopIteration:
|
|
294
|
+
new_singleton_coin_record = None
|
|
295
|
+
|
|
296
|
+
################
|
|
297
|
+
# TRANSACTIONS #
|
|
298
|
+
################
|
|
299
|
+
|
|
300
|
+
async def generate_new_reporter(
|
|
301
|
+
self,
|
|
302
|
+
initial_root: bytes32,
|
|
303
|
+
action_scope: WalletActionScope,
|
|
304
|
+
fee: uint64 = uint64(0),
|
|
305
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
306
|
+
) -> bytes32:
|
|
307
|
+
"""
|
|
308
|
+
Creates the initial singleton, which includes spending an origin coin, the launcher, and creating a singleton
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
coins: set[Coin] = await self.standard_wallet.select_coins(uint64(fee + 1), action_scope)
|
|
312
|
+
if coins is None:
|
|
313
|
+
raise ValueError("Not enough coins to create new data layer singleton")
|
|
314
|
+
|
|
315
|
+
launcher_parent: Coin = next(iter(coins))
|
|
316
|
+
launcher_coin: Coin = Coin(launcher_parent.name(), SINGLETON_LAUNCHER.get_tree_hash(), uint64(1))
|
|
317
|
+
|
|
318
|
+
inner_puzzle: Program = await self.standard_wallet.get_puzzle(
|
|
319
|
+
new=not action_scope.config.tx_config.reuse_puzhash
|
|
320
|
+
)
|
|
321
|
+
full_puzzle: Program = create_host_fullpuz(inner_puzzle, initial_root, launcher_coin.name())
|
|
322
|
+
|
|
323
|
+
genesis_launcher_solution: Program = Program.to(
|
|
324
|
+
[full_puzzle.get_tree_hash(), 1, [initial_root, inner_puzzle.get_tree_hash()]]
|
|
325
|
+
)
|
|
326
|
+
announcement_message: bytes32 = genesis_launcher_solution.get_tree_hash()
|
|
327
|
+
announcement = AssertCoinAnnouncement(asserted_id=launcher_coin.name(), asserted_msg=announcement_message)
|
|
328
|
+
|
|
329
|
+
await self.standard_wallet.generate_signed_transaction(
|
|
330
|
+
amount=uint64(1),
|
|
331
|
+
puzzle_hash=SINGLETON_LAUNCHER.get_tree_hash(),
|
|
332
|
+
action_scope=action_scope,
|
|
333
|
+
fee=fee,
|
|
334
|
+
origin_id=launcher_parent.name(),
|
|
335
|
+
coins=coins,
|
|
336
|
+
primaries=None,
|
|
337
|
+
extra_conditions=(*extra_conditions, announcement),
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
launcher_cs: CoinSpend = CoinSpend(
|
|
341
|
+
launcher_coin,
|
|
342
|
+
SerializedProgram.from_program(SINGLETON_LAUNCHER),
|
|
343
|
+
SerializedProgram.from_program(genesis_launcher_solution),
|
|
344
|
+
)
|
|
345
|
+
launcher_sb = WalletSpendBundle([launcher_cs], G2Element())
|
|
346
|
+
|
|
347
|
+
async with action_scope.use() as interface:
|
|
348
|
+
interface.side_effects.extra_spends.append(launcher_sb)
|
|
349
|
+
|
|
350
|
+
singleton_record = SingletonRecord(
|
|
351
|
+
coin_id=Coin(launcher_coin.name(), full_puzzle.get_tree_hash(), uint64(1)).name(),
|
|
352
|
+
launcher_id=launcher_coin.name(),
|
|
353
|
+
root=initial_root,
|
|
354
|
+
inner_puzzle_hash=inner_puzzle.get_tree_hash(),
|
|
355
|
+
confirmed=False,
|
|
356
|
+
confirmed_at_height=uint32(0),
|
|
357
|
+
timestamp=uint64(0),
|
|
358
|
+
lineage_proof=LineageProof(
|
|
359
|
+
launcher_coin.name(),
|
|
360
|
+
create_host_layer_puzzle(inner_puzzle, initial_root).get_tree_hash(),
|
|
361
|
+
uint64(1),
|
|
362
|
+
),
|
|
363
|
+
generation=uint32(0),
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
await self.wallet_state_manager.dl_store.add_singleton_record(singleton_record)
|
|
367
|
+
await self.wallet_state_manager.add_interested_puzzle_hashes([singleton_record.launcher_id], [self.id()])
|
|
368
|
+
|
|
369
|
+
return launcher_coin.name()
|
|
370
|
+
|
|
371
|
+
async def create_tandem_xch_tx(
|
|
372
|
+
self,
|
|
373
|
+
fee: uint64,
|
|
374
|
+
announcement_to_assert: AssertAnnouncement,
|
|
375
|
+
action_scope: WalletActionScope,
|
|
376
|
+
) -> None:
|
|
377
|
+
await self.standard_wallet.generate_signed_transaction(
|
|
378
|
+
amount=uint64(0),
|
|
379
|
+
puzzle_hash=await self.standard_wallet.get_puzzle_hash(new=not action_scope.config.tx_config.reuse_puzhash),
|
|
380
|
+
action_scope=action_scope,
|
|
381
|
+
fee=fee,
|
|
382
|
+
negative_change_allowed=False,
|
|
383
|
+
extra_conditions=(announcement_to_assert,),
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
async def create_update_state_spend(
|
|
387
|
+
self,
|
|
388
|
+
launcher_id: bytes32,
|
|
389
|
+
root_hash: Optional[bytes32],
|
|
390
|
+
action_scope: WalletActionScope,
|
|
391
|
+
new_puz_hash: Optional[bytes32] = None,
|
|
392
|
+
new_amount: Optional[uint64] = None,
|
|
393
|
+
fee: uint64 = uint64(0),
|
|
394
|
+
add_pending_singleton: bool = True,
|
|
395
|
+
announce_new_state: bool = False,
|
|
396
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
397
|
+
) -> None:
|
|
398
|
+
singleton_record, parent_lineage = await self.get_spendable_singleton_info(launcher_id)
|
|
399
|
+
|
|
400
|
+
if root_hash is None:
|
|
401
|
+
root_hash = singleton_record.root
|
|
402
|
+
|
|
403
|
+
inner_puzzle_derivation: Optional[
|
|
404
|
+
DerivationRecord
|
|
405
|
+
] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(
|
|
406
|
+
singleton_record.inner_puzzle_hash
|
|
407
|
+
)
|
|
408
|
+
if inner_puzzle_derivation is None:
|
|
409
|
+
raise ValueError(f"DL Wallet does not have permission to update Singleton with launcher ID {launcher_id}")
|
|
410
|
+
|
|
411
|
+
# Make the child's puzzles
|
|
412
|
+
if new_puz_hash is None:
|
|
413
|
+
new_puz_hash = await self.standard_wallet.get_puzzle_hash(
|
|
414
|
+
new=not action_scope.config.tx_config.reuse_puzhash
|
|
415
|
+
)
|
|
416
|
+
assert new_puz_hash is not None
|
|
417
|
+
next_full_puz_hash: bytes32 = create_host_fullpuz(new_puz_hash, root_hash, launcher_id).get_tree_hash_precalc(
|
|
418
|
+
new_puz_hash
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
# Construct the current puzzles
|
|
422
|
+
current_inner_puzzle: Program = self.standard_wallet.puzzle_for_pk(inner_puzzle_derivation.pubkey)
|
|
423
|
+
current_full_puz = create_host_fullpuz(
|
|
424
|
+
current_inner_puzzle,
|
|
425
|
+
singleton_record.root,
|
|
426
|
+
launcher_id,
|
|
427
|
+
)
|
|
428
|
+
assert singleton_record.lineage_proof.parent_name is not None
|
|
429
|
+
assert singleton_record.lineage_proof.amount is not None
|
|
430
|
+
current_coin = Coin(
|
|
431
|
+
singleton_record.lineage_proof.parent_name,
|
|
432
|
+
current_full_puz.get_tree_hash(),
|
|
433
|
+
singleton_record.lineage_proof.amount,
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
new_singleton_record = SingletonRecord(
|
|
437
|
+
coin_id=Coin(current_coin.name(), next_full_puz_hash, singleton_record.lineage_proof.amount).name(),
|
|
438
|
+
launcher_id=launcher_id,
|
|
439
|
+
root=root_hash,
|
|
440
|
+
inner_puzzle_hash=new_puz_hash,
|
|
441
|
+
confirmed=False,
|
|
442
|
+
confirmed_at_height=uint32(0),
|
|
443
|
+
timestamp=uint64(0),
|
|
444
|
+
lineage_proof=LineageProof(
|
|
445
|
+
singleton_record.coin_id,
|
|
446
|
+
new_puz_hash,
|
|
447
|
+
singleton_record.lineage_proof.amount,
|
|
448
|
+
),
|
|
449
|
+
generation=uint32(singleton_record.generation + 1),
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
# Optionally add an ephemeral spend to announce
|
|
453
|
+
if announce_new_state:
|
|
454
|
+
announce_only: Program = Program.to(
|
|
455
|
+
(
|
|
456
|
+
1,
|
|
457
|
+
[
|
|
458
|
+
[
|
|
459
|
+
51,
|
|
460
|
+
new_puz_hash,
|
|
461
|
+
singleton_record.lineage_proof.amount,
|
|
462
|
+
[launcher_id, root_hash, new_puz_hash],
|
|
463
|
+
],
|
|
464
|
+
[62, b"$"],
|
|
465
|
+
],
|
|
466
|
+
)
|
|
467
|
+
)
|
|
468
|
+
second_full_puz: Program = create_host_fullpuz(
|
|
469
|
+
announce_only,
|
|
470
|
+
root_hash,
|
|
471
|
+
launcher_id,
|
|
472
|
+
)
|
|
473
|
+
second_coin = Coin(
|
|
474
|
+
current_coin.name(), second_full_puz.get_tree_hash(), singleton_record.lineage_proof.amount
|
|
475
|
+
)
|
|
476
|
+
second_coin_spend = CoinSpend(
|
|
477
|
+
second_coin,
|
|
478
|
+
SerializedProgram.from_program(second_full_puz),
|
|
479
|
+
SerializedProgram.to(
|
|
480
|
+
[
|
|
481
|
+
LineageProof(
|
|
482
|
+
current_coin.parent_coin_info,
|
|
483
|
+
create_host_layer_puzzle(current_inner_puzzle, singleton_record.root).get_tree_hash(),
|
|
484
|
+
singleton_record.lineage_proof.amount,
|
|
485
|
+
).to_program(),
|
|
486
|
+
singleton_record.lineage_proof.amount,
|
|
487
|
+
[[]],
|
|
488
|
+
]
|
|
489
|
+
),
|
|
490
|
+
)
|
|
491
|
+
extra_conditions += (
|
|
492
|
+
AssertPuzzleAnnouncement(asserted_ph=second_full_puz.get_tree_hash(), asserted_msg=b"$"),
|
|
493
|
+
)
|
|
494
|
+
second_singleton_record = SingletonRecord(
|
|
495
|
+
coin_id=second_coin.name(),
|
|
496
|
+
launcher_id=launcher_id,
|
|
497
|
+
root=root_hash,
|
|
498
|
+
inner_puzzle_hash=announce_only.get_tree_hash(),
|
|
499
|
+
confirmed=False,
|
|
500
|
+
confirmed_at_height=uint32(0),
|
|
501
|
+
timestamp=uint64(0),
|
|
502
|
+
lineage_proof=LineageProof(
|
|
503
|
+
second_coin.parent_coin_info,
|
|
504
|
+
announce_only.get_tree_hash(),
|
|
505
|
+
singleton_record.lineage_proof.amount,
|
|
506
|
+
),
|
|
507
|
+
generation=uint32(singleton_record.generation + 1),
|
|
508
|
+
)
|
|
509
|
+
new_singleton_record = dataclasses.replace(
|
|
510
|
+
new_singleton_record,
|
|
511
|
+
coin_id=Coin(second_coin.name(), next_full_puz_hash, singleton_record.lineage_proof.amount).name(),
|
|
512
|
+
lineage_proof=LineageProof(
|
|
513
|
+
second_coin.name(),
|
|
514
|
+
next_full_puz_hash,
|
|
515
|
+
singleton_record.lineage_proof.amount,
|
|
516
|
+
),
|
|
517
|
+
generation=uint32(second_singleton_record.generation + 1),
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
# Create the solution
|
|
521
|
+
primaries = [
|
|
522
|
+
Payment(
|
|
523
|
+
announce_only.get_tree_hash() if announce_new_state else new_puz_hash,
|
|
524
|
+
singleton_record.lineage_proof.amount if new_amount is None else new_amount,
|
|
525
|
+
[
|
|
526
|
+
launcher_id,
|
|
527
|
+
root_hash,
|
|
528
|
+
announce_only.get_tree_hash() if announce_new_state else new_puz_hash,
|
|
529
|
+
],
|
|
530
|
+
)
|
|
531
|
+
]
|
|
532
|
+
if root_hash != singleton_record.root:
|
|
533
|
+
extra_conditions = (
|
|
534
|
+
*extra_conditions,
|
|
535
|
+
UnknownCondition(
|
|
536
|
+
opcode=Program.to(-24),
|
|
537
|
+
args=[
|
|
538
|
+
ACS_MU,
|
|
539
|
+
Program.to([[(root_hash, None), ACS_MU_PH], None]),
|
|
540
|
+
],
|
|
541
|
+
),
|
|
542
|
+
)
|
|
543
|
+
inner_sol: Program = self.standard_wallet.make_solution(
|
|
544
|
+
primaries=primaries,
|
|
545
|
+
conditions=(*extra_conditions, CreateCoinAnnouncement(b"$")) if fee > 0 else extra_conditions,
|
|
546
|
+
)
|
|
547
|
+
db_layer_sol = Program.to([inner_sol])
|
|
548
|
+
full_sol = Program.to(
|
|
549
|
+
[
|
|
550
|
+
parent_lineage.to_program(),
|
|
551
|
+
singleton_record.lineage_proof.amount,
|
|
552
|
+
db_layer_sol,
|
|
553
|
+
]
|
|
554
|
+
)
|
|
555
|
+
|
|
556
|
+
# Create the spend
|
|
557
|
+
coin_spend = CoinSpend(
|
|
558
|
+
current_coin,
|
|
559
|
+
SerializedProgram.from_program(current_full_puz),
|
|
560
|
+
SerializedProgram.from_program(full_sol),
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
spend_bundle = WalletSpendBundle([coin_spend], G2Element())
|
|
564
|
+
|
|
565
|
+
if announce_new_state:
|
|
566
|
+
spend_bundle = WalletSpendBundle([coin_spend, second_coin_spend], spend_bundle.aggregated_signature)
|
|
567
|
+
|
|
568
|
+
dl_tx = TransactionRecord(
|
|
569
|
+
confirmed_at_height=uint32(0),
|
|
570
|
+
created_at_time=uint64(int(time.time())),
|
|
571
|
+
to_puzzle_hash=new_puz_hash,
|
|
572
|
+
amount=uint64(singleton_record.lineage_proof.amount),
|
|
573
|
+
fee_amount=fee,
|
|
574
|
+
confirmed=False,
|
|
575
|
+
sent=uint32(10),
|
|
576
|
+
spend_bundle=spend_bundle,
|
|
577
|
+
additions=spend_bundle.additions(),
|
|
578
|
+
removals=spend_bundle.removals(),
|
|
579
|
+
memos=list(compute_memos(spend_bundle).items()),
|
|
580
|
+
wallet_id=self.id(),
|
|
581
|
+
sent_to=[],
|
|
582
|
+
trade_id=None,
|
|
583
|
+
type=uint32(TransactionType.OUTGOING_TX.value),
|
|
584
|
+
name=singleton_record.coin_id,
|
|
585
|
+
valid_times=parse_timelock_info(extra_conditions),
|
|
586
|
+
)
|
|
587
|
+
assert dl_tx.spend_bundle is not None
|
|
588
|
+
if fee > 0:
|
|
589
|
+
await self.create_tandem_xch_tx(
|
|
590
|
+
fee,
|
|
591
|
+
AssertAnnouncement(True, asserted_origin_id=current_coin.name(), asserted_msg=b"$"),
|
|
592
|
+
action_scope,
|
|
593
|
+
)
|
|
594
|
+
|
|
595
|
+
if add_pending_singleton:
|
|
596
|
+
await self.wallet_state_manager.dl_store.add_singleton_record(
|
|
597
|
+
new_singleton_record,
|
|
598
|
+
)
|
|
599
|
+
if announce_new_state:
|
|
600
|
+
await self.wallet_state_manager.dl_store.add_singleton_record(
|
|
601
|
+
second_singleton_record,
|
|
602
|
+
)
|
|
603
|
+
|
|
604
|
+
async with action_scope.use() as interface:
|
|
605
|
+
interface.side_effects.transactions.append(dl_tx)
|
|
606
|
+
|
|
607
|
+
async def generate_signed_transaction(
|
|
608
|
+
self,
|
|
609
|
+
amounts: list[uint64],
|
|
610
|
+
puzzle_hashes: list[bytes32],
|
|
611
|
+
action_scope: WalletActionScope,
|
|
612
|
+
fee: uint64 = uint64(0),
|
|
613
|
+
coins: set[Coin] = set(),
|
|
614
|
+
memos: Optional[list[list[bytes]]] = None, # ignored
|
|
615
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
616
|
+
**kwargs: Unpack[GSTOptionalArgs],
|
|
617
|
+
) -> None:
|
|
618
|
+
launcher_id: Optional[bytes32] = kwargs.get("launcher_id", None)
|
|
619
|
+
new_root_hash: Optional[bytes32] = kwargs.get("new_root_hash", None)
|
|
620
|
+
add_pending_singleton: bool = kwargs.get("add_pending_singleton", True)
|
|
621
|
+
announce_new_state: bool = kwargs.get("announce_new_state", False)
|
|
622
|
+
# Figure out the launcher ID
|
|
623
|
+
if len(coins) == 0:
|
|
624
|
+
if launcher_id is None:
|
|
625
|
+
raise ValueError("Not enough info to know which DL coin to send")
|
|
626
|
+
else:
|
|
627
|
+
if len(coins) != 1:
|
|
628
|
+
raise ValueError("The wallet can only send one DL coin at a time")
|
|
629
|
+
else:
|
|
630
|
+
record = await self.wallet_state_manager.dl_store.get_singleton_record(next(iter(coins)).name())
|
|
631
|
+
if record is None:
|
|
632
|
+
raise ValueError("The specified coin is not a tracked DL")
|
|
633
|
+
else:
|
|
634
|
+
launcher_id = record.launcher_id
|
|
635
|
+
|
|
636
|
+
if len(amounts) != 1 or len(puzzle_hashes) != 1:
|
|
637
|
+
raise ValueError("The wallet can only send one DL coin to one place at a time")
|
|
638
|
+
|
|
639
|
+
await self.create_update_state_spend(
|
|
640
|
+
launcher_id,
|
|
641
|
+
new_root_hash,
|
|
642
|
+
action_scope,
|
|
643
|
+
puzzle_hashes[0],
|
|
644
|
+
amounts[0],
|
|
645
|
+
fee,
|
|
646
|
+
add_pending_singleton,
|
|
647
|
+
announce_new_state,
|
|
648
|
+
extra_conditions,
|
|
649
|
+
)
|
|
650
|
+
|
|
651
|
+
async def get_spendable_singleton_info(self, launcher_id: bytes32) -> tuple[SingletonRecord, LineageProof]:
|
|
652
|
+
# First, let's make sure this is a singleton that we track and that we can spend
|
|
653
|
+
singleton_record: Optional[SingletonRecord] = await self.get_latest_singleton(launcher_id)
|
|
654
|
+
if singleton_record is None:
|
|
655
|
+
raise ValueError(f"Singleton with launcher ID {launcher_id} is not tracked by DL Wallet")
|
|
656
|
+
|
|
657
|
+
# Next, the singleton should be confirmed or else we shouldn't be ready to spend it
|
|
658
|
+
if not singleton_record.confirmed:
|
|
659
|
+
raise ValueError(f"Singleton with launcher ID {launcher_id} is currently pending")
|
|
660
|
+
|
|
661
|
+
# Next, let's verify we have all of the relevant coin information
|
|
662
|
+
if singleton_record.lineage_proof.parent_name is None or singleton_record.lineage_proof.amount is None:
|
|
663
|
+
raise ValueError(f"Singleton with launcher ID {launcher_id} has insufficient information to spend")
|
|
664
|
+
|
|
665
|
+
# Finally, let's get the parent record for its lineage proof
|
|
666
|
+
parent_singleton: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_singleton_record(
|
|
667
|
+
singleton_record.lineage_proof.parent_name
|
|
668
|
+
)
|
|
669
|
+
parent_lineage: LineageProof
|
|
670
|
+
if parent_singleton is None:
|
|
671
|
+
if singleton_record.lineage_proof.parent_name != launcher_id:
|
|
672
|
+
raise ValueError(f"Have not found the parent of singleton with launcher ID {launcher_id}")
|
|
673
|
+
else:
|
|
674
|
+
launcher_coin: Optional[Coin] = await self.wallet_state_manager.dl_store.get_launcher(launcher_id)
|
|
675
|
+
if launcher_coin is None:
|
|
676
|
+
raise ValueError(f"DL Wallet does not have launcher info for id {launcher_id}")
|
|
677
|
+
else:
|
|
678
|
+
parent_lineage = LineageProof(launcher_coin.parent_coin_info, None, uint64(launcher_coin.amount))
|
|
679
|
+
else:
|
|
680
|
+
parent_lineage = parent_singleton.lineage_proof
|
|
681
|
+
|
|
682
|
+
return singleton_record, parent_lineage
|
|
683
|
+
|
|
684
|
+
async def get_owned_singletons(self) -> list[SingletonRecord]:
|
|
685
|
+
launcher_ids = await self.wallet_state_manager.dl_store.get_all_launchers()
|
|
686
|
+
|
|
687
|
+
collected = []
|
|
688
|
+
|
|
689
|
+
for launcher_id in launcher_ids:
|
|
690
|
+
singleton_record = await self.wallet_state_manager.dl_store.get_latest_singleton(launcher_id=launcher_id)
|
|
691
|
+
if singleton_record is None:
|
|
692
|
+
# this is likely due to a race between getting the list and acquiring the extra data
|
|
693
|
+
continue
|
|
694
|
+
|
|
695
|
+
inner_puzzle_derivation: Optional[
|
|
696
|
+
DerivationRecord
|
|
697
|
+
] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(
|
|
698
|
+
singleton_record.inner_puzzle_hash
|
|
699
|
+
)
|
|
700
|
+
if inner_puzzle_derivation is not None:
|
|
701
|
+
collected.append(singleton_record)
|
|
702
|
+
|
|
703
|
+
return collected
|
|
704
|
+
|
|
705
|
+
async def create_new_mirror(
|
|
706
|
+
self,
|
|
707
|
+
launcher_id: bytes32,
|
|
708
|
+
amount: uint64,
|
|
709
|
+
urls: list[bytes],
|
|
710
|
+
action_scope: WalletActionScope,
|
|
711
|
+
fee: uint64 = uint64(0),
|
|
712
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
713
|
+
) -> None:
|
|
714
|
+
await self.standard_wallet.generate_signed_transaction(
|
|
715
|
+
amount=amount,
|
|
716
|
+
puzzle_hash=create_mirror_puzzle().get_tree_hash(),
|
|
717
|
+
action_scope=action_scope,
|
|
718
|
+
fee=fee,
|
|
719
|
+
primaries=[],
|
|
720
|
+
memos=[launcher_id, *(url for url in urls)],
|
|
721
|
+
extra_conditions=extra_conditions,
|
|
722
|
+
)
|
|
723
|
+
|
|
724
|
+
async def delete_mirror(
|
|
725
|
+
self,
|
|
726
|
+
mirror_id: bytes32,
|
|
727
|
+
peer: WSChiaConnection,
|
|
728
|
+
action_scope: WalletActionScope,
|
|
729
|
+
fee: uint64 = uint64(0),
|
|
730
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
731
|
+
) -> None:
|
|
732
|
+
mirror: Mirror = await self.get_mirror(mirror_id)
|
|
733
|
+
mirror_coin: Coin = (await self.wallet_state_manager.wallet_node.get_coin_state([mirror.coin_id], peer=peer))[
|
|
734
|
+
0
|
|
735
|
+
].coin
|
|
736
|
+
parent_coin: Coin = (
|
|
737
|
+
await self.wallet_state_manager.wallet_node.get_coin_state([mirror_coin.parent_coin_info], peer=peer)
|
|
738
|
+
)[0].coin
|
|
739
|
+
inner_puzzle_derivation: Optional[
|
|
740
|
+
DerivationRecord
|
|
741
|
+
] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(parent_coin.puzzle_hash)
|
|
742
|
+
if inner_puzzle_derivation is None:
|
|
743
|
+
raise ValueError(f"DL Wallet does not have permission to delete mirror with ID {mirror_id}")
|
|
744
|
+
|
|
745
|
+
parent_inner_puzzle: Program = self.standard_wallet.puzzle_for_pk(inner_puzzle_derivation.pubkey)
|
|
746
|
+
new_puzhash: bytes32 = await self.standard_wallet.get_puzzle_hash(
|
|
747
|
+
new=not action_scope.config.tx_config.reuse_puzhash
|
|
748
|
+
)
|
|
749
|
+
excess_fee: int = fee - mirror_coin.amount
|
|
750
|
+
inner_sol: Program = self.standard_wallet.make_solution(
|
|
751
|
+
primaries=[Payment(new_puzhash, uint64(mirror_coin.amount - fee))] if excess_fee < 0 else [],
|
|
752
|
+
conditions=(*extra_conditions, CreateCoinAnnouncement(b"$")) if excess_fee > 0 else extra_conditions,
|
|
753
|
+
)
|
|
754
|
+
mirror_spend = CoinSpend(
|
|
755
|
+
mirror_coin,
|
|
756
|
+
SerializedProgram.from_program(create_mirror_puzzle()),
|
|
757
|
+
SerializedProgram.to(
|
|
758
|
+
[
|
|
759
|
+
parent_coin.parent_coin_info,
|
|
760
|
+
parent_inner_puzzle,
|
|
761
|
+
parent_coin.amount,
|
|
762
|
+
inner_sol,
|
|
763
|
+
]
|
|
764
|
+
),
|
|
765
|
+
)
|
|
766
|
+
mirror_bundle = WalletSpendBundle([mirror_spend], G2Element())
|
|
767
|
+
|
|
768
|
+
async with action_scope.use() as interface:
|
|
769
|
+
interface.side_effects.transactions.append(
|
|
770
|
+
TransactionRecord(
|
|
771
|
+
confirmed_at_height=uint32(0),
|
|
772
|
+
created_at_time=uint64(int(time.time())),
|
|
773
|
+
to_puzzle_hash=new_puzhash,
|
|
774
|
+
amount=uint64(mirror_coin.amount),
|
|
775
|
+
fee_amount=fee,
|
|
776
|
+
confirmed=False,
|
|
777
|
+
sent=uint32(10),
|
|
778
|
+
spend_bundle=mirror_bundle,
|
|
779
|
+
additions=mirror_bundle.additions(),
|
|
780
|
+
removals=mirror_bundle.removals(),
|
|
781
|
+
memos=list(compute_memos(mirror_bundle).items()),
|
|
782
|
+
wallet_id=self.id(), # This is being called before the wallet is created so we're using a ID of 0
|
|
783
|
+
sent_to=[],
|
|
784
|
+
trade_id=None,
|
|
785
|
+
type=uint32(TransactionType.OUTGOING_TX.value),
|
|
786
|
+
name=mirror_bundle.name(),
|
|
787
|
+
valid_times=parse_timelock_info(extra_conditions),
|
|
788
|
+
)
|
|
789
|
+
)
|
|
790
|
+
|
|
791
|
+
if excess_fee > 0:
|
|
792
|
+
await self.wallet_state_manager.main_wallet.generate_signed_transaction(
|
|
793
|
+
uint64(1),
|
|
794
|
+
new_puzhash,
|
|
795
|
+
action_scope,
|
|
796
|
+
fee=uint64(excess_fee),
|
|
797
|
+
extra_conditions=(AssertCoinAnnouncement(asserted_id=mirror_coin.name(), asserted_msg=b"$"),),
|
|
798
|
+
)
|
|
799
|
+
|
|
800
|
+
###########
|
|
801
|
+
# SYNCING #
|
|
802
|
+
###########
|
|
803
|
+
|
|
804
|
+
async def coin_added(self, coin: Coin, height: uint32, peer: WSChiaConnection, coin_data: Optional[object]) -> None:
|
|
805
|
+
if coin.puzzle_hash == create_mirror_puzzle().get_tree_hash():
|
|
806
|
+
parent_state: CoinState = (
|
|
807
|
+
await self.wallet_state_manager.wallet_node.get_coin_state([coin.parent_coin_info], peer=peer)
|
|
808
|
+
)[0]
|
|
809
|
+
parent_spend = await fetch_coin_spend(height, parent_state.coin, peer)
|
|
810
|
+
assert parent_spend is not None
|
|
811
|
+
launcher_id, urls = get_mirror_info(parent_spend.puzzle_reveal, parent_spend.solution)
|
|
812
|
+
# Don't track mirrors with empty url list.
|
|
813
|
+
if not urls:
|
|
814
|
+
return
|
|
815
|
+
if await self.wallet_state_manager.dl_store.is_launcher_tracked(launcher_id):
|
|
816
|
+
ours: bool = await self.wallet_state_manager.get_wallet_for_coin(coin.parent_coin_info) is not None
|
|
817
|
+
await self.wallet_state_manager.dl_store.add_mirror(
|
|
818
|
+
Mirror(
|
|
819
|
+
coin.name(),
|
|
820
|
+
launcher_id,
|
|
821
|
+
uint64(coin.amount),
|
|
822
|
+
urls,
|
|
823
|
+
ours,
|
|
824
|
+
height,
|
|
825
|
+
)
|
|
826
|
+
)
|
|
827
|
+
await self.wallet_state_manager.add_interested_coin_ids([coin.name()])
|
|
828
|
+
|
|
829
|
+
async def singleton_removed(self, parent_spend: CoinSpend, height: uint32) -> None:
|
|
830
|
+
parent_name = parent_spend.coin.name()
|
|
831
|
+
puzzle = parent_spend.puzzle_reveal
|
|
832
|
+
solution = parent_spend.solution
|
|
833
|
+
|
|
834
|
+
matched, _ = match_dl_singleton(puzzle)
|
|
835
|
+
if matched:
|
|
836
|
+
self.log.info(f"DL singleton removed: {parent_spend.coin}")
|
|
837
|
+
singleton_record: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_singleton_record(
|
|
838
|
+
parent_name
|
|
839
|
+
)
|
|
840
|
+
if singleton_record is None:
|
|
841
|
+
self.log.warning(f"DL wallet received coin it does not have parent for. Expected parent {parent_name}.")
|
|
842
|
+
return
|
|
843
|
+
|
|
844
|
+
# Information we need to create the singleton record
|
|
845
|
+
full_puzzle_hash: bytes32
|
|
846
|
+
amount: uint64
|
|
847
|
+
root: bytes32
|
|
848
|
+
inner_puzzle_hash: bytes32
|
|
849
|
+
|
|
850
|
+
conditions = puzzle.run_with_cost(self.wallet_state_manager.constants.MAX_BLOCK_COST_CLVM, solution)[
|
|
851
|
+
1
|
|
852
|
+
].as_python()
|
|
853
|
+
found_singleton: bool = False
|
|
854
|
+
for condition in conditions:
|
|
855
|
+
if condition[0] == ConditionOpcode.CREATE_COIN and int.from_bytes(condition[2], "big") % 2 == 1:
|
|
856
|
+
full_puzzle_hash = bytes32(condition[1])
|
|
857
|
+
amount = uint64(int.from_bytes(condition[2], "big"))
|
|
858
|
+
try:
|
|
859
|
+
root = bytes32(condition[3][1])
|
|
860
|
+
inner_puzzle_hash = bytes32(condition[3][2])
|
|
861
|
+
except IndexError:
|
|
862
|
+
self.log.warning(
|
|
863
|
+
f"Parent {parent_name} with launcher {singleton_record.launcher_id} "
|
|
864
|
+
"did not hint its child properly"
|
|
865
|
+
)
|
|
866
|
+
return
|
|
867
|
+
found_singleton = True
|
|
868
|
+
break
|
|
869
|
+
|
|
870
|
+
if not found_singleton:
|
|
871
|
+
self.log.warning(f"Singleton with launcher ID {singleton_record.launcher_id} was melted")
|
|
872
|
+
return
|
|
873
|
+
|
|
874
|
+
new_singleton = Coin(parent_name, full_puzzle_hash, amount)
|
|
875
|
+
timestamp = await self.wallet_state_manager.wallet_node.get_timestamp_for_height(height)
|
|
876
|
+
await self.wallet_state_manager.dl_store.add_singleton_record(
|
|
877
|
+
SingletonRecord(
|
|
878
|
+
coin_id=new_singleton.name(),
|
|
879
|
+
launcher_id=singleton_record.launcher_id,
|
|
880
|
+
root=root,
|
|
881
|
+
inner_puzzle_hash=inner_puzzle_hash,
|
|
882
|
+
confirmed=True,
|
|
883
|
+
confirmed_at_height=height,
|
|
884
|
+
timestamp=timestamp,
|
|
885
|
+
lineage_proof=LineageProof(
|
|
886
|
+
parent_name,
|
|
887
|
+
create_host_layer_puzzle(inner_puzzle_hash, root).get_tree_hash_precalc(inner_puzzle_hash),
|
|
888
|
+
amount,
|
|
889
|
+
),
|
|
890
|
+
generation=uint32(singleton_record.generation + 1),
|
|
891
|
+
)
|
|
892
|
+
)
|
|
893
|
+
await self.wallet_state_manager.add_interested_coin_ids(
|
|
894
|
+
[new_singleton.name()],
|
|
895
|
+
)
|
|
896
|
+
elif parent_spend.coin.puzzle_hash == create_mirror_puzzle().get_tree_hash():
|
|
897
|
+
await self.wallet_state_manager.dl_store.delete_mirror(parent_name)
|
|
898
|
+
|
|
899
|
+
async def stop_tracking_singleton(self, launcher_id: bytes32) -> None:
|
|
900
|
+
await self.wallet_state_manager.dl_store.delete_singleton_records_by_launcher_id(launcher_id)
|
|
901
|
+
await self.wallet_state_manager.dl_store.delete_launcher(launcher_id)
|
|
902
|
+
|
|
903
|
+
###########
|
|
904
|
+
# UTILITY #
|
|
905
|
+
###########
|
|
906
|
+
|
|
907
|
+
async def get_latest_singleton(
|
|
908
|
+
self, launcher_id: bytes32, only_confirmed: bool = False
|
|
909
|
+
) -> Optional[SingletonRecord]:
|
|
910
|
+
singleton: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_latest_singleton(
|
|
911
|
+
launcher_id, only_confirmed
|
|
912
|
+
)
|
|
913
|
+
return singleton
|
|
914
|
+
|
|
915
|
+
async def get_history(
|
|
916
|
+
self,
|
|
917
|
+
launcher_id: bytes32,
|
|
918
|
+
min_generation: Optional[uint32] = None,
|
|
919
|
+
max_generation: Optional[uint32] = None,
|
|
920
|
+
num_results: Optional[uint32] = None,
|
|
921
|
+
) -> list[SingletonRecord]:
|
|
922
|
+
history: list[SingletonRecord] = await self.wallet_state_manager.dl_store.get_all_singletons_for_launcher(
|
|
923
|
+
launcher_id,
|
|
924
|
+
min_generation,
|
|
925
|
+
max_generation,
|
|
926
|
+
num_results,
|
|
927
|
+
)
|
|
928
|
+
return history
|
|
929
|
+
|
|
930
|
+
async def get_singleton_record(self, coin_id: bytes32) -> Optional[SingletonRecord]:
|
|
931
|
+
singleton: Optional[SingletonRecord] = await self.wallet_state_manager.dl_store.get_singleton_record(coin_id)
|
|
932
|
+
return singleton
|
|
933
|
+
|
|
934
|
+
async def get_singletons_by_root(self, launcher_id: bytes32, root: bytes32) -> list[SingletonRecord]:
|
|
935
|
+
singletons: list[SingletonRecord] = await self.wallet_state_manager.dl_store.get_singletons_by_root(
|
|
936
|
+
launcher_id, root
|
|
937
|
+
)
|
|
938
|
+
return singletons
|
|
939
|
+
|
|
940
|
+
async def get_mirrors_for_launcher(self, launcher_id: bytes32) -> list[Mirror]:
|
|
941
|
+
return await self.wallet_state_manager.dl_store.get_mirrors(launcher_id)
|
|
942
|
+
|
|
943
|
+
async def get_mirror(self, coin_id: bytes32) -> Mirror:
|
|
944
|
+
return await self.wallet_state_manager.dl_store.get_mirror(coin_id)
|
|
945
|
+
|
|
946
|
+
##########
|
|
947
|
+
# WALLET #
|
|
948
|
+
##########
|
|
949
|
+
|
|
950
|
+
def require_derivation_paths(self) -> bool:
|
|
951
|
+
return True
|
|
952
|
+
|
|
953
|
+
def puzzle_hash_for_pk(self, pubkey: G1Element) -> bytes32:
|
|
954
|
+
puzzle: Program = self.puzzle_for_pk(pubkey)
|
|
955
|
+
return puzzle.get_tree_hash()
|
|
956
|
+
|
|
957
|
+
def puzzle_for_pk(self, pubkey: G1Element) -> Program:
|
|
958
|
+
return self.standard_wallet.puzzle_for_pk(pubkey)
|
|
959
|
+
|
|
960
|
+
async def get_new_puzzle(self) -> Program:
|
|
961
|
+
return self.puzzle_for_pk(
|
|
962
|
+
(await self.wallet_state_manager.get_unused_derivation_record(self.wallet_info.id)).pubkey
|
|
963
|
+
)
|
|
964
|
+
|
|
965
|
+
async def get_new_puzzlehash(self) -> bytes32:
|
|
966
|
+
return (await self.get_new_puzzle()).get_tree_hash()
|
|
967
|
+
|
|
968
|
+
async def new_peak(self, peak: BlockRecord) -> None:
|
|
969
|
+
pass
|
|
970
|
+
|
|
971
|
+
async def get_confirmed_balance(self, record_list: Optional[set[WalletCoinRecord]] = None) -> uint128:
|
|
972
|
+
return uint128(0)
|
|
973
|
+
|
|
974
|
+
async def get_unconfirmed_balance(self, record_list: Optional[set[WalletCoinRecord]] = None) -> uint128:
|
|
975
|
+
return uint128(0)
|
|
976
|
+
|
|
977
|
+
async def get_spendable_balance(self, unspent_records: Optional[set[WalletCoinRecord]] = None) -> uint128:
|
|
978
|
+
return uint128(0)
|
|
979
|
+
|
|
980
|
+
async def get_pending_change_balance(self) -> uint64:
|
|
981
|
+
return uint64(0)
|
|
982
|
+
|
|
983
|
+
async def get_max_send_amount(self, unspent_records: Optional[set[WalletCoinRecord]] = None) -> uint128:
|
|
984
|
+
return uint128(0)
|
|
985
|
+
|
|
986
|
+
def get_name(self) -> str:
|
|
987
|
+
return self.wallet_info.name
|
|
988
|
+
|
|
989
|
+
##########
|
|
990
|
+
# OFFERS #
|
|
991
|
+
##########
|
|
992
|
+
|
|
993
|
+
async def get_puzzle_info(self, launcher_id: bytes32) -> PuzzleInfo:
|
|
994
|
+
record = await self.get_latest_singleton(launcher_id)
|
|
995
|
+
if record is None:
|
|
996
|
+
raise ValueError(f"DL wallet does not know about launcher ID {launcher_id}")
|
|
997
|
+
return PuzzleInfo(
|
|
998
|
+
{
|
|
999
|
+
"type": AssetType.SINGLETON.value,
|
|
1000
|
+
"launcher_id": "0x" + launcher_id.hex(),
|
|
1001
|
+
"launcher_ph": "0x" + SINGLETON_LAUNCHER_HASH.hex(),
|
|
1002
|
+
"also": {
|
|
1003
|
+
"type": AssetType.METADATA.value,
|
|
1004
|
+
"metadata": f"(0x{record.root} . ())",
|
|
1005
|
+
"updater_hash": "0x" + ACS_MU_PH.hex(),
|
|
1006
|
+
},
|
|
1007
|
+
}
|
|
1008
|
+
)
|
|
1009
|
+
|
|
1010
|
+
async def get_coins_to_offer(self, launcher_id: bytes32, *args: Any, **kwargs: Any) -> set[Coin]:
|
|
1011
|
+
record = await self.get_latest_singleton(launcher_id)
|
|
1012
|
+
if record is None:
|
|
1013
|
+
raise ValueError(f"DL wallet does not know about launcher ID {launcher_id}")
|
|
1014
|
+
puzhash: bytes32 = create_host_fullpuz(
|
|
1015
|
+
record.inner_puzzle_hash, record.root, launcher_id
|
|
1016
|
+
).get_tree_hash_precalc(record.inner_puzzle_hash)
|
|
1017
|
+
assert record.lineage_proof.parent_name is not None
|
|
1018
|
+
assert record.lineage_proof.amount is not None
|
|
1019
|
+
return {Coin(record.lineage_proof.parent_name, puzhash, record.lineage_proof.amount)}
|
|
1020
|
+
|
|
1021
|
+
@staticmethod
|
|
1022
|
+
async def make_update_offer(
|
|
1023
|
+
wallet_state_manager: Any,
|
|
1024
|
+
offer_dict: dict[Optional[bytes32], int],
|
|
1025
|
+
driver_dict: dict[bytes32, PuzzleInfo],
|
|
1026
|
+
solver: Solver,
|
|
1027
|
+
action_scope: WalletActionScope,
|
|
1028
|
+
fee: uint64 = uint64(0),
|
|
1029
|
+
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
1030
|
+
) -> Offer:
|
|
1031
|
+
dl_wallet = None
|
|
1032
|
+
for wallet in wallet_state_manager.wallets.values():
|
|
1033
|
+
if wallet.type() == WalletType.DATA_LAYER.value:
|
|
1034
|
+
dl_wallet = wallet
|
|
1035
|
+
break
|
|
1036
|
+
if dl_wallet is None:
|
|
1037
|
+
raise ValueError("DL Wallet is not initialized")
|
|
1038
|
+
|
|
1039
|
+
offered_launchers: list[bytes32] = [k for k, v in offer_dict.items() if v < 0 and k is not None]
|
|
1040
|
+
fee_left_to_pay: uint64 = fee
|
|
1041
|
+
all_transactions: list[TransactionRecord] = []
|
|
1042
|
+
for launcher in offered_launchers:
|
|
1043
|
+
try:
|
|
1044
|
+
this_solver: Solver = solver[launcher.hex()]
|
|
1045
|
+
except KeyError:
|
|
1046
|
+
this_solver = solver["0x" + launcher.hex()]
|
|
1047
|
+
new_root: bytes32 = this_solver["new_root"]
|
|
1048
|
+
new_ph: bytes32 = await wallet_state_manager.main_wallet.get_puzzle_hash(
|
|
1049
|
+
new=not action_scope.config.tx_config.reuse_puzhash
|
|
1050
|
+
)
|
|
1051
|
+
async with wallet_state_manager.new_action_scope(
|
|
1052
|
+
action_scope.config.tx_config, push=False
|
|
1053
|
+
) as inner_action_scope:
|
|
1054
|
+
await dl_wallet.generate_signed_transaction(
|
|
1055
|
+
[uint64(1)],
|
|
1056
|
+
[new_ph],
|
|
1057
|
+
inner_action_scope,
|
|
1058
|
+
fee=fee_left_to_pay,
|
|
1059
|
+
launcher_id=launcher,
|
|
1060
|
+
new_root_hash=new_root,
|
|
1061
|
+
add_pending_singleton=False,
|
|
1062
|
+
announce_new_state=True,
|
|
1063
|
+
extra_conditions=extra_conditions,
|
|
1064
|
+
)
|
|
1065
|
+
fee_left_to_pay = uint64(0)
|
|
1066
|
+
extra_conditions = tuple()
|
|
1067
|
+
|
|
1068
|
+
async with inner_action_scope.use() as interface:
|
|
1069
|
+
dl_spend: CoinSpend = next(
|
|
1070
|
+
cs
|
|
1071
|
+
for tx in interface.side_effects.transactions
|
|
1072
|
+
for cs in tx.spend_bundle.coin_spends
|
|
1073
|
+
if tx.spend_bundle is not None and match_dl_singleton(cs.puzzle_reveal)[0]
|
|
1074
|
+
)
|
|
1075
|
+
dl_solution: Program = dl_spend.solution.to_program()
|
|
1076
|
+
old_graftroot: Program = dl_solution.at("rrffrf")
|
|
1077
|
+
new_graftroot: Program = create_graftroot_offer_puz(
|
|
1078
|
+
[bytes32(dep["launcher_id"]) for dep in this_solver["dependencies"]],
|
|
1079
|
+
[list(v for v in dep["values_to_prove"]) for dep in this_solver["dependencies"]],
|
|
1080
|
+
old_graftroot,
|
|
1081
|
+
)
|
|
1082
|
+
|
|
1083
|
+
new_solution: Program = dl_solution.replace(rrffrf=new_graftroot, rrffrrf=Program.to([None] * 5))
|
|
1084
|
+
new_spend: CoinSpend = dl_spend.replace(solution=SerializedProgram.from_program(new_solution))
|
|
1085
|
+
async with inner_action_scope.use() as interface:
|
|
1086
|
+
for i, tx in enumerate(interface.side_effects.transactions):
|
|
1087
|
+
if tx.spend_bundle is not None and dl_spend in tx.spend_bundle.coin_spends:
|
|
1088
|
+
break
|
|
1089
|
+
else:
|
|
1090
|
+
# No test coverage for this line because it should never be reached
|
|
1091
|
+
raise RuntimeError("Internal logic error while constructing update offer") # pragma: no cover
|
|
1092
|
+
new_bundle = WalletSpendBundle(
|
|
1093
|
+
[
|
|
1094
|
+
*(
|
|
1095
|
+
cs
|
|
1096
|
+
for cs in interface.side_effects.transactions[i].spend_bundle.coin_spends
|
|
1097
|
+
if cs != dl_spend
|
|
1098
|
+
),
|
|
1099
|
+
new_spend,
|
|
1100
|
+
],
|
|
1101
|
+
G2Element(),
|
|
1102
|
+
)
|
|
1103
|
+
interface.side_effects.transactions[i] = dataclasses.replace(
|
|
1104
|
+
interface.side_effects.transactions[i], spend_bundle=new_bundle, name=new_bundle.name()
|
|
1105
|
+
)
|
|
1106
|
+
|
|
1107
|
+
all_transactions.extend(inner_action_scope.side_effects.transactions)
|
|
1108
|
+
|
|
1109
|
+
# create some dummy requested payments
|
|
1110
|
+
requested_payments = {
|
|
1111
|
+
k: [NotarizedPayment(bytes32.zeros, uint64(v), [], bytes32.zeros)] for k, v in offer_dict.items() if v > 0
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
async with action_scope.use() as interface:
|
|
1115
|
+
interface.side_effects.transactions.extend(all_transactions)
|
|
1116
|
+
|
|
1117
|
+
return Offer(
|
|
1118
|
+
requested_payments,
|
|
1119
|
+
WalletSpendBundle.aggregate([tx.spend_bundle for tx in all_transactions if tx.spend_bundle is not None]),
|
|
1120
|
+
driver_dict,
|
|
1121
|
+
)
|
|
1122
|
+
|
|
1123
|
+
@staticmethod
|
|
1124
|
+
async def finish_graftroot_solutions(offer: Offer, solver: Solver) -> Offer:
|
|
1125
|
+
# Build a mapping of launcher IDs to their new innerpuz
|
|
1126
|
+
singleton_to_innerpuzhash: dict[bytes32, bytes32] = {}
|
|
1127
|
+
singleton_to_root: dict[bytes32, bytes32] = {}
|
|
1128
|
+
all_parent_ids: list[bytes32] = [cs.coin.parent_coin_info for cs in offer.coin_spends()]
|
|
1129
|
+
for spend in offer.coin_spends():
|
|
1130
|
+
matched, curried_args = match_dl_singleton(spend.puzzle_reveal)
|
|
1131
|
+
if matched and spend.coin.name() not in all_parent_ids:
|
|
1132
|
+
innerpuz, root_prg, launcher_id = curried_args
|
|
1133
|
+
singleton_struct = launcher_to_struct(bytes32(launcher_id.as_python())).get_tree_hash()
|
|
1134
|
+
singleton_to_root[singleton_struct] = bytes32(root_prg.as_python())
|
|
1135
|
+
singleton_to_innerpuzhash[singleton_struct] = innerpuz.get_tree_hash()
|
|
1136
|
+
|
|
1137
|
+
# Create all of the new solutions
|
|
1138
|
+
new_spends: list[CoinSpend] = []
|
|
1139
|
+
for spend in offer.coin_spends():
|
|
1140
|
+
solution = spend.solution.to_program()
|
|
1141
|
+
if match_dl_singleton(spend.puzzle_reveal)[0]:
|
|
1142
|
+
try:
|
|
1143
|
+
graftroot: Program = solution.at("rrffrf")
|
|
1144
|
+
except EvalError:
|
|
1145
|
+
new_spends.append(spend)
|
|
1146
|
+
continue
|
|
1147
|
+
mod, curried_args_prg = graftroot.uncurry()
|
|
1148
|
+
if mod == GRAFTROOT_DL_OFFERS:
|
|
1149
|
+
_, singleton_structs, _, values_to_prove = curried_args_prg.as_iter()
|
|
1150
|
+
all_proofs = []
|
|
1151
|
+
roots = []
|
|
1152
|
+
for singleton, values in zip(singleton_structs.as_iter(), values_to_prove.as_python()):
|
|
1153
|
+
asserted_root: Optional[str] = None
|
|
1154
|
+
proofs_of_inclusion = []
|
|
1155
|
+
for value in values:
|
|
1156
|
+
for proof_of_inclusion in solver["proofs_of_inclusion"]:
|
|
1157
|
+
root: str = proof_of_inclusion[0]
|
|
1158
|
+
proof: tuple[int, list[bytes32]] = (proof_of_inclusion[1], proof_of_inclusion[2])
|
|
1159
|
+
calculated_root: bytes32 = _simplify_merkle_proof(value, proof)
|
|
1160
|
+
if (
|
|
1161
|
+
calculated_root == bytes32.from_hexstr(root)
|
|
1162
|
+
and calculated_root == singleton_to_root[singleton.get_tree_hash()]
|
|
1163
|
+
):
|
|
1164
|
+
proofs_of_inclusion.append(proof)
|
|
1165
|
+
if asserted_root is None:
|
|
1166
|
+
asserted_root = root
|
|
1167
|
+
elif asserted_root != root:
|
|
1168
|
+
raise ValueError("Malformed DL offer")
|
|
1169
|
+
break
|
|
1170
|
+
roots.append(asserted_root)
|
|
1171
|
+
all_proofs.append(proofs_of_inclusion)
|
|
1172
|
+
if sum(len(proofs) for proofs in all_proofs) < sum(1 for _ in values_to_prove.as_iter()):
|
|
1173
|
+
raise ValueError("One or more proofs of inclusion were invalid")
|
|
1174
|
+
new_solution: Program = solution.replace(
|
|
1175
|
+
rrffrrf=Program.to(
|
|
1176
|
+
[
|
|
1177
|
+
all_proofs,
|
|
1178
|
+
[Program.to((bytes32.from_hexstr(root), None)) for root in roots if root is not None],
|
|
1179
|
+
[ACS_MU_PH] * len(all_proofs),
|
|
1180
|
+
[
|
|
1181
|
+
singleton_to_innerpuzhash[struct.get_tree_hash()]
|
|
1182
|
+
for struct in singleton_structs.as_iter()
|
|
1183
|
+
],
|
|
1184
|
+
solution.at("rrffrrfrrrrf"),
|
|
1185
|
+
]
|
|
1186
|
+
)
|
|
1187
|
+
)
|
|
1188
|
+
new_spend: CoinSpend = spend.replace(solution=SerializedProgram.from_program(new_solution))
|
|
1189
|
+
spend = new_spend
|
|
1190
|
+
new_spends.append(spend)
|
|
1191
|
+
|
|
1192
|
+
return Offer({}, WalletSpendBundle(new_spends, offer.aggregated_signature()), offer.driver_dict)
|
|
1193
|
+
|
|
1194
|
+
@staticmethod
|
|
1195
|
+
async def get_offer_summary(offer: Offer) -> dict[str, Any]:
|
|
1196
|
+
summary: dict[str, Any] = {"offered": []}
|
|
1197
|
+
for spend in offer.coin_spends():
|
|
1198
|
+
solution = spend.solution.to_program()
|
|
1199
|
+
matched, curried_args = match_dl_singleton(spend.puzzle_reveal)
|
|
1200
|
+
if matched:
|
|
1201
|
+
try:
|
|
1202
|
+
graftroot: Program = solution.at("rrffrf")
|
|
1203
|
+
except EvalError:
|
|
1204
|
+
continue
|
|
1205
|
+
mod, graftroot_curried_args = graftroot.uncurry()
|
|
1206
|
+
if mod == GRAFTROOT_DL_OFFERS:
|
|
1207
|
+
child_spend: CoinSpend = next(
|
|
1208
|
+
cs for cs in offer.coin_spends() if cs.coin.parent_coin_info == spend.coin.name()
|
|
1209
|
+
)
|
|
1210
|
+
_, child_curried_args = match_dl_singleton(child_spend.puzzle_reveal)
|
|
1211
|
+
singleton_summary = {
|
|
1212
|
+
"launcher_id": list(curried_args)[2].as_python().hex(),
|
|
1213
|
+
"new_root": list(child_curried_args)[1].as_python().hex(),
|
|
1214
|
+
"dependencies": [],
|
|
1215
|
+
}
|
|
1216
|
+
_, singleton_structs, _, values_to_prove = graftroot_curried_args.as_iter()
|
|
1217
|
+
for struct, values in zip(singleton_structs.as_iter(), values_to_prove.as_iter()):
|
|
1218
|
+
singleton_summary["dependencies"].append(
|
|
1219
|
+
{
|
|
1220
|
+
"launcher_id": struct.at("rf").as_python().hex(),
|
|
1221
|
+
"values_to_prove": [value.as_python().hex() for value in values.as_iter()],
|
|
1222
|
+
}
|
|
1223
|
+
)
|
|
1224
|
+
summary["offered"].append(singleton_summary)
|
|
1225
|
+
return summary
|
|
1226
|
+
|
|
1227
|
+
async def select_coins(
|
|
1228
|
+
self,
|
|
1229
|
+
amount: uint64,
|
|
1230
|
+
action_scope: WalletActionScope,
|
|
1231
|
+
) -> set[Coin]:
|
|
1232
|
+
raise RuntimeError("DataLayerWallet does not support select_coins()")
|
|
1233
|
+
|
|
1234
|
+
async def match_hinted_coin(self, coin: Coin, hint: bytes32) -> bool:
|
|
1235
|
+
return coin.amount % 2 == 1 and await self.wallet_state_manager.dl_store.get_launcher(hint) is not None
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
def verify_offer(
|
|
1239
|
+
maker: tuple[StoreProofs, ...],
|
|
1240
|
+
taker: tuple[OfferStore, ...],
|
|
1241
|
+
summary: dict[str, Any],
|
|
1242
|
+
) -> None:
|
|
1243
|
+
# TODO: consistency in error messages
|
|
1244
|
+
# TODO: custom exceptions
|
|
1245
|
+
# TODO: show data in errors?
|
|
1246
|
+
# TODO: collect and report all failures
|
|
1247
|
+
# TODO: review for case coverage (and test those cases)
|
|
1248
|
+
|
|
1249
|
+
if len({store_proof.store_id for store_proof in maker}) != len(maker):
|
|
1250
|
+
raise OfferIntegrityError("maker: repeated store id")
|
|
1251
|
+
|
|
1252
|
+
for store_proof in maker:
|
|
1253
|
+
proofs: list[ProofOfInclusion] = []
|
|
1254
|
+
for reference_proof in store_proof.proofs:
|
|
1255
|
+
proof = ProofOfInclusion(
|
|
1256
|
+
node_hash=reference_proof.node_hash,
|
|
1257
|
+
layers=[
|
|
1258
|
+
ProofOfInclusionLayer(
|
|
1259
|
+
other_hash_side=layer.other_hash_side,
|
|
1260
|
+
other_hash=layer.other_hash,
|
|
1261
|
+
combined_hash=layer.combined_hash,
|
|
1262
|
+
)
|
|
1263
|
+
for layer in reference_proof.layers
|
|
1264
|
+
],
|
|
1265
|
+
)
|
|
1266
|
+
|
|
1267
|
+
proofs.append(proof)
|
|
1268
|
+
|
|
1269
|
+
if leaf_hash(key=reference_proof.key, value=reference_proof.value) != proof.node_hash:
|
|
1270
|
+
raise OfferIntegrityError("maker: node hash does not match key and value")
|
|
1271
|
+
|
|
1272
|
+
if not proof.valid():
|
|
1273
|
+
raise OfferIntegrityError("maker: invalid proof of inclusion found")
|
|
1274
|
+
|
|
1275
|
+
# TODO: verify each kv hash to the proof's node hash
|
|
1276
|
+
roots = {proof.root_hash for proof in proofs}
|
|
1277
|
+
if len(roots) > 1:
|
|
1278
|
+
raise OfferIntegrityError("maker: multiple roots referenced for a single store id")
|
|
1279
|
+
if len(roots) < 1:
|
|
1280
|
+
raise OfferIntegrityError("maker: no roots referenced for store id")
|
|
1281
|
+
|
|
1282
|
+
# TODO: what about validating duplicate entries are consistent?
|
|
1283
|
+
maker_from_offer = {
|
|
1284
|
+
bytes32.from_hexstr(offered["launcher_id"]): bytes32.from_hexstr(offered["new_root"])
|
|
1285
|
+
for offered in summary["offered"]
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
maker_from_reference = {
|
|
1289
|
+
# verified above that there is at least one proof and all combined hashes match
|
|
1290
|
+
store_proof.store_id: store_proof.proofs[0].root()
|
|
1291
|
+
for store_proof in maker
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
if maker_from_offer != maker_from_reference:
|
|
1295
|
+
raise OfferIntegrityError("maker: offered stores and their roots do not match the reference data")
|
|
1296
|
+
|
|
1297
|
+
taker_from_offer = {
|
|
1298
|
+
bytes32.from_hexstr(dependency["launcher_id"]): [
|
|
1299
|
+
bytes32.from_hexstr(value) for value in dependency["values_to_prove"]
|
|
1300
|
+
]
|
|
1301
|
+
for offered in summary["offered"]
|
|
1302
|
+
for dependency in offered["dependencies"]
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
taker_from_reference = {
|
|
1306
|
+
store.store_id: [leaf_hash(key=inclusion.key, value=inclusion.value) for inclusion in store.inclusions]
|
|
1307
|
+
for store in taker
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
if taker_from_offer != taker_from_reference:
|
|
1311
|
+
raise OfferIntegrityError("taker: reference and offer inclusions do not match")
|