chia-blockchain 2.5.7rc4__py3-none-any.whl → 2.6.0rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/__init__.py +8 -4
- chia/_tests/blockchain/blockchain_test_utils.py +6 -8
- chia/_tests/blockchain/test_augmented_chain.py +4 -4
- chia/_tests/blockchain/test_blockchain.py +165 -190
- chia/_tests/blockchain/test_blockchain_transactions.py +5 -2
- chia/_tests/blockchain/test_build_chains.py +2 -4
- chia/_tests/blockchain/test_get_block_generator.py +2 -3
- chia/_tests/clvm/coin_store.py +4 -7
- chia/_tests/clvm/test_clvm_step.py +4 -4
- chia/_tests/clvm/test_puzzle_compression.py +2 -1
- chia/_tests/clvm/test_puzzle_drivers.py +2 -2
- chia/_tests/clvm/test_singletons.py +2 -4
- chia/_tests/clvm/test_spend_sim.py +2 -2
- chia/_tests/cmds/cmd_test_utils.py +27 -45
- chia/_tests/cmds/test_cmd_framework.py +6 -6
- chia/_tests/cmds/test_daemon.py +3 -3
- chia/_tests/cmds/test_show.py +4 -4
- chia/_tests/cmds/test_tx_config_args.py +1 -2
- chia/_tests/cmds/testing_classes.py +4 -5
- chia/_tests/cmds/wallet/test_did.py +24 -27
- chia/_tests/cmds/wallet/test_nft.py +12 -10
- chia/_tests/cmds/wallet/test_vcs.py +11 -12
- chia/_tests/cmds/wallet/test_wallet.py +134 -89
- chia/_tests/conftest.py +66 -31
- chia/_tests/connection_utils.py +2 -2
- chia/_tests/core/cmds/test_beta.py +4 -4
- chia/_tests/core/cmds/test_keys.py +2 -3
- chia/_tests/core/cmds/test_wallet.py +15 -15
- chia/_tests/core/consensus/test_pot_iterations.py +19 -73
- chia/_tests/core/custom_types/test_proof_of_space.py +124 -98
- chia/_tests/core/daemon/test_daemon.py +11 -11
- chia/_tests/core/data_layer/conftest.py +2 -2
- chia/_tests/core/data_layer/test_data_rpc.py +28 -14
- chia/_tests/core/data_layer/test_data_store.py +10 -10
- chia/_tests/core/data_layer/util.py +11 -11
- chia/_tests/core/farmer/test_farmer_api.py +2 -4
- chia/_tests/core/full_node/full_sync/test_full_sync.py +8 -7
- chia/_tests/core/full_node/stores/test_block_store.py +5 -4
- chia/_tests/core/full_node/stores/test_coin_store.py +5 -11
- chia/_tests/core/full_node/stores/test_full_node_store.py +8 -8
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/test_block_height_map.py +3 -4
- chia/_tests/core/full_node/test_conditions.py +21 -23
- chia/_tests/core/full_node/test_full_node.py +273 -70
- chia/_tests/core/full_node/test_hard_fork_utils.py +92 -0
- chia/_tests/core/full_node/test_hint_management.py +2 -4
- chia/_tests/core/full_node/test_performance.py +0 -1
- chia/_tests/core/full_node/test_prev_tx_block.py +88 -11
- chia/_tests/core/full_node/test_transactions.py +1 -2
- chia/_tests/core/full_node/test_tx_processing_queue.py +198 -30
- chia/_tests/core/mempool/test_mempool.py +54 -50
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +39 -39
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +2 -6
- chia/_tests/core/mempool/test_mempool_manager.py +988 -854
- chia/_tests/core/mempool/test_singleton_fast_forward.py +6 -6
- chia/_tests/core/server/serve.py +7 -7
- chia/_tests/core/server/test_dos.py +1 -2
- chia/_tests/core/server/test_event_loop.py +12 -4
- chia/_tests/core/server/test_loop.py +7 -8
- chia/_tests/core/server/test_rate_limits.py +9 -8
- chia/_tests/core/server/test_server.py +61 -1
- chia/_tests/core/services/test_services.py +2 -2
- chia/_tests/core/ssl/test_ssl.py +2 -2
- chia/_tests/core/test_cost_calculation.py +2 -6
- chia/_tests/core/test_farmer_harvester_rpc.py +3 -5
- chia/_tests/core/test_filter.py +0 -1
- chia/_tests/core/test_full_node_rpc.py +2 -2
- chia/_tests/core/test_merkle_set.py +1 -2
- chia/_tests/core/test_seeder.py +4 -4
- chia/_tests/core/util/test_config.py +4 -4
- chia/_tests/core/util/test_jsonify.py +2 -2
- chia/_tests/core/util/test_keychain.py +3 -3
- chia/_tests/core/util/test_lockfile.py +2 -1
- chia/_tests/core/util/test_log_exceptions.py +1 -2
- chia/_tests/core/util/test_streamable.py +17 -17
- chia/_tests/db/test_db_wrapper.py +3 -2
- chia/_tests/environments/wallet.py +14 -14
- chia/_tests/ether.py +4 -3
- chia/_tests/farmer_harvester/test_farmer.py +41 -24
- chia/_tests/farmer_harvester/test_farmer_harvester.py +50 -17
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +27 -27
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +21 -22
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +18 -18
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +11 -9
- chia/_tests/harvester/test_harvester_api.py +11 -4
- chia/_tests/plot_sync/test_plot_sync.py +13 -11
- chia/_tests/plot_sync/test_receiver.py +11 -10
- chia/_tests/plot_sync/test_sync_simulated.py +2 -2
- chia/_tests/plot_sync/util.py +1 -2
- chia/_tests/plotting/test_plot_manager.py +7 -6
- chia/_tests/plotting/test_prover.py +30 -38
- chia/_tests/pools/test_pool_cmdline.py +4 -6
- chia/_tests/pools/test_pool_rpc.py +203 -61
- chia/_tests/pools/test_pool_wallet.py +3 -3
- chia/_tests/pools/test_wallet_pool_store.py +1 -4
- chia/_tests/process_junit.py +2 -2
- chia/_tests/rpc/test_rpc_client.py +4 -4
- chia/_tests/rpc/test_rpc_server.py +3 -3
- chia/_tests/simulation/test_simulation.py +12 -25
- chia/_tests/solver/test_solver_service.py +13 -4
- chia/_tests/testconfig.py +2 -2
- chia/_tests/timelord/test_new_peak.py +22 -11
- chia/_tests/tools/test_run_block.py +0 -2
- chia/_tests/tools/test_virtual_project.py +2 -1
- chia/_tests/util/benchmarks.py +1 -0
- chia/_tests/util/blockchain.py +38 -36
- chia/_tests/util/blockchain_mock.py +11 -11
- chia/_tests/util/build_network_protocol_files.py +2 -1
- chia/_tests/util/coin_store.py +2 -1
- chia/_tests/util/config.py +1 -1
- chia/_tests/util/db_connection.py +2 -3
- chia/_tests/util/full_sync.py +9 -11
- chia/_tests/util/gen_ssl_certs.py +4 -5
- chia/_tests/util/get_name_puzzle_conditions.py +2 -0
- chia/_tests/util/misc.py +24 -24
- chia/_tests/util/network_protocol_data.py +20 -3
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +292 -3
- chia/_tests/util/setup_nodes.py +62 -47
- chia/_tests/util/spend_sim.py +57 -57
- chia/_tests/util/test_async_pool.py +2 -3
- chia/_tests/util/test_chia_version.py +1 -3
- chia/_tests/util/test_config.py +3 -3
- chia/_tests/util/test_full_block_utils.py +6 -3
- chia/_tests/util/test_limited_semaphore.py +1 -2
- chia/_tests/util/test_misc.py +2 -2
- chia/_tests/util/test_network.py +1 -2
- chia/_tests/util/test_priority_mutex.py +3 -3
- chia/_tests/util/test_recursive_replace.py +5 -6
- chia/_tests/util/test_replace_str_to_bytes.py +9 -10
- chia/_tests/util/test_testnet_overrides.py +3 -3
- chia/_tests/util/time_out_assert.py +2 -2
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +4 -6
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -4
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +19 -13
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +13 -13
- chia/_tests/wallet/cat_wallet/test_trades.py +40 -38
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -4
- chia/_tests/wallet/conftest.py +6 -6
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +1 -1
- chia/_tests/wallet/db_wallet/test_dl_offers.py +34 -34
- chia/_tests/wallet/did_wallet/test_did.py +16 -6
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +21 -21
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +20 -6
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +19 -21
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +1 -2
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +121 -2
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +6 -9
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +44 -1
- chia/_tests/wallet/rpc/test_wallet_rpc.py +1672 -896
- chia/_tests/wallet/sync/test_wallet_sync.py +63 -60
- chia/_tests/wallet/test_clvm_streamable.py +2 -3
- chia/_tests/wallet/test_coin_management.py +2 -2
- chia/_tests/wallet/test_conditions.py +45 -51
- chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
- chia/_tests/wallet/test_new_wallet_protocol.py +17 -17
- chia/_tests/wallet/test_notifications.py +14 -14
- chia/_tests/wallet/test_signer_protocol.py +5 -5
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +4 -3
- chia/_tests/wallet/test_transaction_store.py +20 -20
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +380 -228
- chia/_tests/wallet/test_wallet_action_scope.py +4 -4
- chia/_tests/wallet/test_wallet_blockchain.py +12 -12
- chia/_tests/wallet/test_wallet_coin_store.py +3 -4
- chia/_tests/wallet/test_wallet_node.py +16 -15
- chia/_tests/wallet/test_wallet_test_framework.py +2 -1
- chia/_tests/wallet/test_wallet_utils.py +2 -3
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -5
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +14 -15
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -24
- chia/_tests/wallet/wallet_block_tools.py +12 -11
- chia/_tests/weight_proof/config.py +1 -0
- chia/_tests/weight_proof/test_weight_proof.py +5 -4
- chia/apis/__init__.py +21 -0
- chia/apis/farmer_stub.py +102 -0
- chia/apis/full_node_stub.py +374 -0
- chia/apis/harvester_stub.py +57 -0
- chia/apis/introducer_stub.py +35 -0
- chia/apis/solver_stub.py +30 -0
- chia/apis/stub_protocol_registry.py +21 -0
- chia/apis/timelord_stub.py +39 -0
- chia/apis/wallet_stub.py +161 -0
- chia/cmds/beta.py +3 -4
- chia/cmds/beta_funcs.py +4 -3
- chia/cmds/check_wallet_db.py +4 -4
- chia/cmds/chia.py +1 -2
- chia/cmds/cmd_classes.py +11 -13
- chia/cmds/cmd_helpers.py +11 -11
- chia/cmds/cmds_util.py +15 -15
- chia/cmds/coin_funcs.py +6 -7
- chia/cmds/coins.py +2 -3
- chia/cmds/configure.py +1 -2
- chia/cmds/data.py +42 -42
- chia/cmds/data_funcs.py +81 -81
- chia/cmds/db.py +4 -5
- chia/cmds/db_backup_func.py +2 -2
- chia/cmds/db_upgrade_func.py +3 -3
- chia/cmds/db_validate_func.py +2 -2
- chia/cmds/dev/data.py +4 -4
- chia/cmds/dev/gh.py +5 -5
- chia/cmds/dev/installers.py +2 -3
- chia/cmds/dev/mempool.py +3 -4
- chia/cmds/dev/mempool_funcs.py +4 -4
- chia/cmds/dev/sim.py +8 -8
- chia/cmds/dump_keyring.py +3 -3
- chia/cmds/farm.py +6 -8
- chia/cmds/farm_funcs.py +25 -24
- chia/cmds/init_funcs.py +4 -4
- chia/cmds/keys.py +16 -18
- chia/cmds/keys_funcs.py +36 -36
- chia/cmds/netspace.py +1 -3
- chia/cmds/netspace_funcs.py +1 -2
- chia/cmds/options.py +3 -2
- chia/cmds/param_types.py +17 -16
- chia/cmds/passphrase.py +6 -7
- chia/cmds/passphrase_funcs.py +11 -13
- chia/cmds/peer.py +1 -3
- chia/cmds/peer_funcs.py +3 -3
- chia/cmds/plotnft.py +6 -7
- chia/cmds/plotnft_funcs.py +37 -26
- chia/cmds/rpc.py +3 -3
- chia/cmds/show.py +3 -5
- chia/cmds/show_funcs.py +9 -9
- chia/cmds/sim_funcs.py +25 -26
- chia/cmds/solver.py +1 -3
- chia/cmds/solver_funcs.py +1 -2
- chia/cmds/start_funcs.py +2 -2
- chia/cmds/wallet.py +76 -81
- chia/cmds/wallet_funcs.py +206 -177
- chia/consensus/augmented_chain.py +6 -6
- chia/consensus/block_body_validation.py +19 -15
- chia/consensus/block_creation.py +25 -21
- chia/consensus/block_header_validation.py +27 -13
- chia/consensus/block_height_map.py +3 -6
- chia/consensus/block_height_map_protocol.py +2 -2
- chia/consensus/block_record.py +2 -4
- chia/consensus/blockchain.py +58 -40
- chia/consensus/blockchain_interface.py +7 -7
- chia/consensus/coin_store_protocol.py +5 -6
- chia/consensus/condition_tools.py +4 -4
- chia/consensus/cost_calculator.py +2 -3
- chia/consensus/default_constants.py +19 -13
- chia/consensus/deficit.py +1 -3
- chia/consensus/difficulty_adjustment.py +3 -5
- chia/consensus/find_fork_point.py +2 -4
- chia/consensus/full_block_to_block_record.py +11 -13
- chia/consensus/generator_tools.py +2 -3
- chia/consensus/get_block_challenge.py +50 -26
- chia/consensus/get_block_generator.py +2 -3
- chia/consensus/make_sub_epoch_summary.py +8 -7
- chia/consensus/multiprocess_validation.py +31 -20
- chia/consensus/pos_quality.py +6 -23
- chia/consensus/pot_iterations.py +17 -44
- chia/consensus/signage_point.py +4 -5
- chia/consensus/vdf_info_computation.py +2 -4
- chia/daemon/client.py +8 -8
- chia/daemon/keychain_proxy.py +31 -37
- chia/daemon/server.py +32 -33
- chia/daemon/windows_signal.py +4 -3
- chia/data_layer/data_layer.py +86 -77
- chia/data_layer/data_layer_rpc_api.py +9 -9
- chia/data_layer/data_layer_rpc_client.py +13 -15
- chia/data_layer/data_layer_server.py +3 -3
- chia/data_layer/data_layer_util.py +14 -14
- chia/data_layer/data_layer_wallet.py +94 -101
- chia/data_layer/data_store.py +50 -50
- chia/data_layer/dl_wallet_store.py +9 -12
- chia/data_layer/download_data.py +8 -9
- chia/data_layer/s3_plugin_service.py +5 -9
- chia/data_layer/start_data_layer.py +5 -5
- chia/farmer/farmer.py +31 -31
- chia/farmer/farmer_api.py +45 -33
- chia/farmer/farmer_rpc_api.py +5 -4
- chia/farmer/farmer_rpc_client.py +6 -6
- chia/farmer/start_farmer.py +6 -6
- chia/full_node/block_store.py +13 -16
- chia/full_node/check_fork_next_block.py +1 -2
- chia/full_node/coin_store.py +15 -16
- chia/full_node/eligible_coin_spends.py +3 -3
- chia/full_node/fee_estimate_store.py +2 -3
- chia/full_node/fee_tracker.py +1 -2
- chia/full_node/full_block_utils.py +4 -4
- chia/full_node/full_node.py +239 -223
- chia/full_node/full_node_api.py +197 -152
- chia/full_node/full_node_rpc_api.py +34 -32
- chia/full_node/full_node_rpc_client.py +18 -19
- chia/full_node/full_node_store.py +45 -43
- chia/full_node/hard_fork_utils.py +44 -0
- chia/full_node/hint_management.py +2 -2
- chia/full_node/mempool.py +17 -19
- chia/full_node/mempool_manager.py +89 -42
- chia/full_node/pending_tx_cache.py +2 -3
- chia/full_node/start_full_node.py +5 -5
- chia/full_node/sync_store.py +3 -4
- chia/full_node/tx_processing_queue.py +120 -36
- chia/full_node/weight_proof.py +61 -48
- chia/harvester/harvester.py +25 -24
- chia/harvester/harvester_api.py +61 -38
- chia/harvester/harvester_rpc_api.py +10 -10
- chia/harvester/start_harvester.py +4 -4
- chia/introducer/introducer.py +3 -3
- chia/introducer/introducer_api.py +6 -4
- chia/introducer/start_introducer.py +4 -4
- chia/legacy/keyring.py +3 -3
- chia/plot_sync/delta.py +1 -2
- chia/plot_sync/receiver.py +20 -17
- chia/plot_sync/sender.py +15 -10
- chia/plotters/bladebit.py +7 -7
- chia/plotters/chiapos.py +2 -2
- chia/plotters/madmax.py +4 -4
- chia/plotters/plotters.py +4 -4
- chia/plotters/plotters_util.py +3 -3
- chia/plotting/cache.py +20 -14
- chia/plotting/check_plots.py +26 -35
- chia/plotting/create_plots.py +22 -23
- chia/plotting/manager.py +21 -14
- chia/plotting/prover.py +59 -42
- chia/plotting/util.py +16 -16
- chia/pools/pool_config.py +2 -1
- chia/pools/pool_puzzles.py +11 -12
- chia/pools/pool_wallet.py +34 -57
- chia/pools/pool_wallet_info.py +39 -10
- chia/protocols/farmer_protocol.py +8 -9
- chia/protocols/fee_estimate.py +3 -4
- chia/protocols/full_node_protocol.py +3 -4
- chia/protocols/harvester_protocol.py +27 -15
- chia/protocols/outbound_message.py +3 -3
- chia/protocols/pool_protocol.py +8 -9
- chia/protocols/shared_protocol.py +1 -2
- chia/protocols/solver_protocol.py +9 -2
- chia/protocols/timelord_protocol.py +4 -7
- chia/protocols/wallet_protocol.py +11 -12
- chia/rpc/rpc_client.py +9 -9
- chia/rpc/rpc_server.py +17 -17
- chia/rpc/util.py +2 -2
- chia/seeder/crawler.py +8 -8
- chia/seeder/crawler_api.py +21 -27
- chia/seeder/crawler_rpc_api.py +2 -2
- chia/seeder/dns_server.py +21 -21
- chia/seeder/start_crawler.py +4 -4
- chia/server/address_manager.py +15 -16
- chia/server/api_protocol.py +11 -11
- chia/server/chia_policy.py +46 -26
- chia/server/introducer_peers.py +2 -3
- chia/server/node_discovery.py +19 -19
- chia/server/rate_limit_numbers.py +4 -5
- chia/server/rate_limits.py +4 -4
- chia/server/resolve_peer_info.py +4 -4
- chia/server/server.py +49 -52
- chia/server/signal_handlers.py +6 -6
- chia/server/start_service.py +17 -17
- chia/server/upnp.py +4 -6
- chia/server/ws_connection.py +52 -37
- chia/simulator/add_blocks_in_batches.py +1 -3
- chia/simulator/block_tools.py +312 -200
- chia/simulator/full_node_simulator.py +56 -35
- chia/simulator/keyring.py +2 -3
- chia/simulator/setup_services.py +15 -15
- chia/simulator/simulator_full_node_rpc_api.py +1 -2
- chia/simulator/simulator_full_node_rpc_client.py +1 -2
- chia/simulator/simulator_protocol.py +1 -2
- chia/simulator/simulator_test_tools.py +3 -3
- chia/simulator/start_simulator.py +7 -7
- chia/simulator/wallet_tools.py +10 -10
- chia/solver/solver.py +10 -10
- chia/solver/solver_api.py +10 -8
- chia/solver/solver_rpc_api.py +2 -2
- chia/solver/start_solver.py +4 -4
- chia/ssl/cacert.pem +148 -90
- chia/ssl/chia_ca.crt +14 -10
- chia/ssl/chia_ca_old.crt +19 -0
- chia/ssl/create_ssl.py +4 -4
- chia/ssl/renewedselfsignedca.conf +4 -0
- chia/ssl/ssl_check.py +1 -2
- chia/timelord/iters_from_block.py +1 -4
- chia/timelord/start_timelord.py +4 -4
- chia/timelord/timelord.py +44 -40
- chia/timelord/timelord_api.py +6 -4
- chia/timelord/timelord_launcher.py +2 -2
- chia/timelord/timelord_rpc_api.py +2 -2
- chia/timelord/timelord_state.py +11 -12
- chia/types/block_protocol.py +1 -3
- chia/types/blockchain_format/coin.py +1 -3
- chia/types/blockchain_format/program.py +11 -8
- chia/types/blockchain_format/proof_of_space.py +123 -76
- chia/types/blockchain_format/tree_hash.py +3 -3
- chia/types/blockchain_format/vdf.py +1 -2
- chia/types/coin_spend.py +3 -3
- chia/types/mempool_item.py +5 -5
- chia/types/mempool_submission_status.py +2 -3
- chia/types/peer_info.py +1 -2
- chia/types/unfinished_header_block.py +3 -4
- chia/types/validation_state.py +1 -2
- chia/util/action_scope.py +8 -8
- chia/util/async_pool.py +5 -5
- chia/util/bech32m.py +1 -2
- chia/util/beta_metrics.py +2 -2
- chia/util/block_cache.py +4 -4
- chia/util/chia_logging.py +2 -2
- chia/util/chia_version.py +1 -2
- chia/util/config.py +15 -16
- chia/util/db_wrapper.py +26 -27
- chia/util/default_root.py +1 -2
- chia/util/errors.py +3 -3
- chia/util/file_keyring.py +14 -14
- chia/util/files.py +2 -3
- chia/util/hash.py +4 -4
- chia/util/initial-config.yaml +4 -5
- chia/util/inline_executor.py +2 -1
- chia/util/ip_address.py +1 -2
- chia/util/keychain.py +25 -27
- chia/util/keyring_wrapper.py +18 -19
- chia/util/lock.py +3 -4
- chia/util/log_exceptions.py +1 -2
- chia/util/lru_cache.py +2 -2
- chia/util/network.py +6 -6
- chia/util/path.py +2 -3
- chia/util/priority_mutex.py +2 -2
- chia/util/profiler.py +1 -2
- chia/util/safe_cancel_task.py +1 -2
- chia/util/streamable.py +24 -10
- chia/util/task_referencer.py +1 -1
- chia/util/timing.py +3 -3
- chia/util/virtual_project_analysis.py +6 -5
- chia/util/ws_message.py +2 -2
- chia/wallet/cat_wallet/cat_info.py +3 -4
- chia/wallet/cat_wallet/cat_outer_puzzle.py +12 -11
- chia/wallet/cat_wallet/cat_utils.py +3 -4
- chia/wallet/cat_wallet/cat_wallet.py +61 -83
- chia/wallet/cat_wallet/lineage_store.py +3 -4
- chia/wallet/cat_wallet/r_cat_wallet.py +19 -22
- chia/wallet/coin_selection.py +9 -10
- chia/wallet/conditions.py +142 -106
- chia/wallet/db_wallet/db_wallet_puzzles.py +4 -5
- chia/wallet/derivation_record.py +1 -2
- chia/wallet/derive_keys.py +2 -4
- chia/wallet/did_wallet/did_info.py +10 -11
- chia/wallet/did_wallet/did_wallet.py +36 -82
- chia/wallet/did_wallet/did_wallet_puzzles.py +7 -8
- chia/wallet/driver_protocol.py +5 -7
- chia/wallet/lineage_proof.py +4 -4
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +11 -11
- chia/wallet/nft_wallet/nft_info.py +8 -9
- chia/wallet/nft_wallet/nft_puzzle_utils.py +8 -8
- chia/wallet/nft_wallet/nft_wallet.py +79 -116
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +14 -14
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +12 -11
- chia/wallet/nft_wallet/transfer_program_puzzle.py +11 -11
- chia/wallet/nft_wallet/uncurry_nft.py +10 -11
- chia/wallet/notification_manager.py +3 -3
- chia/wallet/notification_store.py +44 -61
- chia/wallet/outer_puzzles.py +6 -7
- chia/wallet/puzzle_drivers.py +34 -6
- chia/wallet/puzzles/clawback/drivers.py +6 -6
- chia/wallet/puzzles/deployed_puzzle_hashes.json +1 -54
- chia/wallet/puzzles/load_clvm.py +1 -1
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -2
- chia/wallet/puzzles/singleton_top_layer.py +2 -3
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +3 -4
- chia/wallet/puzzles/tails.py +3 -3
- chia/wallet/singleton.py +5 -7
- chia/wallet/singleton_record.py +3 -3
- chia/wallet/start_wallet.py +5 -5
- chia/wallet/trade_manager.py +37 -58
- chia/wallet/trade_record.py +4 -4
- chia/wallet/trading/offer.py +59 -46
- chia/wallet/trading/trade_store.py +8 -9
- chia/wallet/transaction_record.py +8 -8
- chia/wallet/uncurried_puzzle.py +1 -2
- chia/wallet/util/clvm_streamable.py +12 -12
- chia/wallet/util/compute_hints.py +4 -5
- chia/wallet/util/curry_and_treehash.py +1 -2
- chia/wallet/util/merkle_tree.py +2 -3
- chia/wallet/util/peer_request_cache.py +8 -8
- chia/wallet/util/signing.py +85 -0
- chia/wallet/util/tx_config.py +15 -6
- chia/wallet/util/wallet_sync_utils.py +14 -16
- chia/wallet/util/wallet_types.py +2 -2
- chia/wallet/vc_wallet/cr_cat_drivers.py +10 -11
- chia/wallet/vc_wallet/cr_cat_wallet.py +50 -68
- chia/wallet/vc_wallet/cr_outer_puzzle.py +14 -13
- chia/wallet/vc_wallet/vc_drivers.py +27 -27
- chia/wallet/vc_wallet/vc_store.py +5 -6
- chia/wallet/vc_wallet/vc_wallet.py +33 -61
- chia/wallet/wallet.py +50 -78
- chia/wallet/wallet_action_scope.py +11 -11
- chia/wallet/wallet_blockchain.py +12 -12
- chia/wallet/wallet_coin_record.py +12 -6
- chia/wallet/wallet_coin_store.py +24 -25
- chia/wallet/wallet_interested_store.py +3 -5
- chia/wallet/wallet_nft_store.py +10 -11
- chia/wallet/wallet_node.py +53 -61
- chia/wallet/wallet_node_api.py +5 -3
- chia/wallet/wallet_protocol.py +23 -23
- chia/wallet/wallet_puzzle_store.py +15 -18
- chia/wallet/wallet_request_types.py +778 -114
- chia/wallet/wallet_retry_store.py +1 -3
- chia/wallet/wallet_rpc_api.py +572 -909
- chia/wallet/wallet_rpc_client.py +87 -279
- chia/wallet/wallet_singleton_store.py +3 -4
- chia/wallet/wallet_state_manager.py +332 -106
- chia/wallet/wallet_transaction_store.py +11 -14
- chia/wallet/wallet_user_store.py +4 -6
- chia/wallet/wallet_weight_proof_handler.py +4 -4
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/METADATA +6 -5
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/RECORD +510 -517
- chia/apis.py +0 -21
- chia/consensus/check_time_locks.py +0 -57
- chia/data_layer/puzzles/__init__.py +0 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp +0 -100
- chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +0 -1
- chia/types/coin_record.py +0 -44
- chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +0 -6
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +0 -6
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +0 -30
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +0 -28
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +0 -100
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +0 -78
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +0 -74
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +0 -1
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/entry_points.txt +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from chia_rs import AugSchemeMPL, G1Element, G2Element, PrivateKey
|
|
6
|
+
from chia_rs.sized_bytes import bytes32
|
|
7
|
+
|
|
8
|
+
from chia.types.blockchain_format.program import Program
|
|
9
|
+
from chia.types.signing_mode import CHIP_0002_SIGN_MESSAGE_PREFIX, SigningMode
|
|
10
|
+
from chia.util.bech32m import decode_puzzle_hash
|
|
11
|
+
from chia.util.byte_types import hexstr_to_bytes
|
|
12
|
+
from chia.wallet.puzzles import p2_delegated_conditions
|
|
13
|
+
from chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import puzzle_hash_for_synthetic_public_key
|
|
14
|
+
from chia.wallet.wallet_request_types import VerifySignatureResponse
|
|
15
|
+
|
|
16
|
+
# CHIP-0002 message signing as documented at:
|
|
17
|
+
# https://github.com/Chia-Network/chips/blob/80e4611fe52b174bf1a0382b9dff73805b18b8c6/CHIPs/chip-0002.md
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def verify_signature(
|
|
21
|
+
*, signing_mode: SigningMode, public_key: G1Element, message: str, signature: G2Element, address: str | None
|
|
22
|
+
) -> VerifySignatureResponse:
|
|
23
|
+
"""
|
|
24
|
+
Given a public key, message and signature, verify if it is valid.
|
|
25
|
+
:param request:
|
|
26
|
+
:return:
|
|
27
|
+
"""
|
|
28
|
+
if signing_mode in {SigningMode.CHIP_0002, SigningMode.CHIP_0002_P2_DELEGATED_CONDITIONS}:
|
|
29
|
+
# CHIP-0002 message signatures are made over the tree hash of:
|
|
30
|
+
# ("Chia Signed Message", message)
|
|
31
|
+
message_to_verify: bytes = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, message)).get_tree_hash()
|
|
32
|
+
elif signing_mode == SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT:
|
|
33
|
+
# Message is expected to be a hex string
|
|
34
|
+
message_to_verify = hexstr_to_bytes(message)
|
|
35
|
+
elif signing_mode == SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT:
|
|
36
|
+
# Message is expected to be a UTF-8 string
|
|
37
|
+
message_to_verify = bytes(message, "utf-8")
|
|
38
|
+
else:
|
|
39
|
+
raise ValueError(f"Unsupported signing mode: {signing_mode!r}")
|
|
40
|
+
|
|
41
|
+
# Verify using the BLS message augmentation scheme
|
|
42
|
+
is_valid = AugSchemeMPL.verify(
|
|
43
|
+
public_key,
|
|
44
|
+
message_to_verify,
|
|
45
|
+
signature,
|
|
46
|
+
)
|
|
47
|
+
if address is not None:
|
|
48
|
+
# For signatures made by the sign_message_by_address/sign_message_by_id
|
|
49
|
+
# endpoints, the "address" field should contain the p2_address of the NFT/DID
|
|
50
|
+
# that was used to sign the message.
|
|
51
|
+
puzzle_hash: bytes32 = decode_puzzle_hash(address)
|
|
52
|
+
expected_puzzle_hash: bytes32 | None = None
|
|
53
|
+
if signing_mode == SigningMode.CHIP_0002_P2_DELEGATED_CONDITIONS:
|
|
54
|
+
puzzle = p2_delegated_conditions.puzzle_for_pk(Program.to(public_key))
|
|
55
|
+
expected_puzzle_hash = bytes32(puzzle.get_tree_hash())
|
|
56
|
+
else:
|
|
57
|
+
expected_puzzle_hash = puzzle_hash_for_synthetic_public_key(public_key)
|
|
58
|
+
if puzzle_hash != expected_puzzle_hash:
|
|
59
|
+
return VerifySignatureResponse(isValid=False, error="Public key doesn't match the address")
|
|
60
|
+
if is_valid:
|
|
61
|
+
return VerifySignatureResponse(isValid=is_valid)
|
|
62
|
+
else:
|
|
63
|
+
return VerifySignatureResponse(isValid=False, error="Signature is invalid.")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass(kw_only=True, frozen=True)
|
|
67
|
+
class SignMessageResponse:
|
|
68
|
+
pubkey: G1Element
|
|
69
|
+
signature: G2Element
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def sign_message(secret_key: PrivateKey, message: str, mode: SigningMode) -> SignMessageResponse:
|
|
73
|
+
public_key = secret_key.get_g1()
|
|
74
|
+
if mode == SigningMode.CHIP_0002_HEX_INPUT:
|
|
75
|
+
hex_message: bytes = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, bytes.fromhex(message))).get_tree_hash()
|
|
76
|
+
elif mode == SigningMode.BLS_MESSAGE_AUGMENTATION_UTF8_INPUT:
|
|
77
|
+
hex_message = bytes(message, "utf-8")
|
|
78
|
+
elif mode == SigningMode.BLS_MESSAGE_AUGMENTATION_HEX_INPUT:
|
|
79
|
+
hex_message = bytes.fromhex(message)
|
|
80
|
+
else:
|
|
81
|
+
hex_message = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, message)).get_tree_hash()
|
|
82
|
+
return SignMessageResponse(
|
|
83
|
+
pubkey=public_key,
|
|
84
|
+
signature=AugSchemeMPL.sign(secret_key, hex_message),
|
|
85
|
+
)
|
chia/wallet/util/tx_config.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import dataclasses
|
|
4
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
5
5
|
|
|
6
6
|
from chia_rs import ConsensusConstants
|
|
7
7
|
from chia_rs.sized_bytes import bytes32
|
|
@@ -32,6 +32,15 @@ class CoinSelectionConfig:
|
|
|
32
32
|
def override(self, **kwargs: Any) -> CoinSelectionConfig:
|
|
33
33
|
return dataclasses.replace(self, **kwargs)
|
|
34
34
|
|
|
35
|
+
def filter_coins(self, coins: set[Coin]) -> set[Coin]:
|
|
36
|
+
return {
|
|
37
|
+
coin
|
|
38
|
+
for coin in coins
|
|
39
|
+
if self.min_coin_amount <= coin.amount <= self.max_coin_amount
|
|
40
|
+
and coin.amount not in self.excluded_coin_amounts
|
|
41
|
+
and coin.name() not in self.excluded_coin_ids
|
|
42
|
+
}
|
|
43
|
+
|
|
35
44
|
|
|
36
45
|
@dataclasses.dataclass(frozen=True)
|
|
37
46
|
class TXConfig(CoinSelectionConfig):
|
|
@@ -69,10 +78,10 @@ class AutofillArgs(TypedDict):
|
|
|
69
78
|
@streamable
|
|
70
79
|
@dataclasses.dataclass(frozen=True)
|
|
71
80
|
class CoinSelectionConfigLoader(Streamable):
|
|
72
|
-
min_coin_amount:
|
|
73
|
-
max_coin_amount:
|
|
74
|
-
excluded_coin_amounts:
|
|
75
|
-
excluded_coin_ids:
|
|
81
|
+
min_coin_amount: uint64 | None = None
|
|
82
|
+
max_coin_amount: uint64 | None = None
|
|
83
|
+
excluded_coin_amounts: list[uint64] | None = None
|
|
84
|
+
excluded_coin_ids: list[bytes32] | None = None
|
|
76
85
|
|
|
77
86
|
def autofill(
|
|
78
87
|
self,
|
|
@@ -106,7 +115,7 @@ class CoinSelectionConfigLoader(Streamable):
|
|
|
106
115
|
@streamable
|
|
107
116
|
@dataclasses.dataclass(frozen=True)
|
|
108
117
|
class TXConfigLoader(CoinSelectionConfigLoader):
|
|
109
|
-
reuse_puzhash:
|
|
118
|
+
reuse_puzhash: bool | None = None
|
|
110
119
|
|
|
111
120
|
def autofill(
|
|
112
121
|
self,
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
5
|
import random
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
7
|
|
|
8
8
|
from chia_rs import (
|
|
9
9
|
CoinSpend,
|
|
@@ -60,7 +60,7 @@ async def subscribe_to_phs(
|
|
|
60
60
|
Tells full nodes that we are interested in puzzle hashes, and returns the response.
|
|
61
61
|
"""
|
|
62
62
|
msg = RegisterForPhUpdates(puzzle_hashes, uint32(max(min_height, uint32(0))))
|
|
63
|
-
all_coins_state:
|
|
63
|
+
all_coins_state: RespondToPhUpdates | None = await peer.call_api(
|
|
64
64
|
FullNodeAPI.register_for_ph_updates, msg, timeout=300
|
|
65
65
|
)
|
|
66
66
|
if all_coins_state is None:
|
|
@@ -77,7 +77,7 @@ async def subscribe_to_coin_updates(
|
|
|
77
77
|
Tells full nodes that we are interested in coin ids, and returns the response.
|
|
78
78
|
"""
|
|
79
79
|
msg = RegisterForCoinUpdates(coin_names, uint32(max(0, min_height)))
|
|
80
|
-
all_coins_state:
|
|
80
|
+
all_coins_state: RespondToCoinUpdates | None = await peer.call_api(
|
|
81
81
|
FullNodeAPI.register_for_coin_updates, msg, timeout=300
|
|
82
82
|
)
|
|
83
83
|
|
|
@@ -88,7 +88,7 @@ async def subscribe_to_coin_updates(
|
|
|
88
88
|
|
|
89
89
|
def validate_additions(
|
|
90
90
|
coins: list[tuple[bytes32, list[Coin]]],
|
|
91
|
-
proofs:
|
|
91
|
+
proofs: list[tuple[bytes32, bytes, bytes | None]] | None,
|
|
92
92
|
root: bytes32,
|
|
93
93
|
) -> bool:
|
|
94
94
|
if proofs is None:
|
|
@@ -107,8 +107,8 @@ def validate_additions(
|
|
|
107
107
|
for i in range(len(coins)):
|
|
108
108
|
assert coins[i][0] == proofs[i][0]
|
|
109
109
|
coin_list_1: list[Coin] = coins[i][1]
|
|
110
|
-
puzzle_hash_proof:
|
|
111
|
-
coin_list_proof:
|
|
110
|
+
puzzle_hash_proof: bytes | None = proofs[i][1]
|
|
111
|
+
coin_list_proof: bytes | None = proofs[i][2]
|
|
112
112
|
if len(coin_list_1) == 0:
|
|
113
113
|
# Verify exclusion proof for puzzle hash
|
|
114
114
|
assert puzzle_hash_proof is not None
|
|
@@ -149,7 +149,7 @@ def validate_additions(
|
|
|
149
149
|
|
|
150
150
|
|
|
151
151
|
def validate_removals(
|
|
152
|
-
coins: list[tuple[bytes32,
|
|
152
|
+
coins: list[tuple[bytes32, Coin | None]], proofs: list[tuple[bytes32, bytes]] | None, root: bytes32
|
|
153
153
|
) -> bool:
|
|
154
154
|
if proofs is None:
|
|
155
155
|
# If there are no proofs, it means all removals were returned in the response.
|
|
@@ -198,7 +198,7 @@ async def request_and_validate_removals(
|
|
|
198
198
|
) -> bool:
|
|
199
199
|
removals_request = RequestRemovals(height, header_hash, [coin_name])
|
|
200
200
|
|
|
201
|
-
removals_res:
|
|
201
|
+
removals_res: RespondRemovals | RejectRemovalsRequest | None = await peer.call_api(
|
|
202
202
|
FullNodeAPI.request_removals, removals_request
|
|
203
203
|
)
|
|
204
204
|
if removals_res is None or isinstance(removals_res, RejectRemovalsRequest):
|
|
@@ -217,7 +217,7 @@ async def request_and_validate_additions(
|
|
|
217
217
|
if peer_request_cache.in_additions_in_block(header_hash, puzzle_hash):
|
|
218
218
|
return True
|
|
219
219
|
additions_request = RequestAdditions(height, header_hash, [puzzle_hash])
|
|
220
|
-
additions_res:
|
|
220
|
+
additions_res: RespondAdditions | RejectAdditionsRequest | None = await peer.call_api(
|
|
221
221
|
FullNodeAPI.request_additions, additions_request
|
|
222
222
|
)
|
|
223
223
|
if additions_res is None or isinstance(additions_res, RejectAdditionsRequest):
|
|
@@ -254,7 +254,7 @@ def sort_coin_states(coin_states: set[CoinState]) -> list[CoinState]:
|
|
|
254
254
|
|
|
255
255
|
async def request_header_blocks(
|
|
256
256
|
peer: WSChiaConnection, start_height: uint32, end_height: uint32
|
|
257
|
-
) ->
|
|
257
|
+
) -> list[HeaderBlock] | None:
|
|
258
258
|
if Capability.BLOCK_HEADERS in peer.peer_capabilities:
|
|
259
259
|
response = await peer.call_api(
|
|
260
260
|
FullNodeAPI.request_block_headers, RequestBlockHeaders(start_height, end_height, False)
|
|
@@ -271,7 +271,7 @@ async def _fetch_header_blocks_inner(
|
|
|
271
271
|
all_peers: list[tuple[WSChiaConnection, bool]],
|
|
272
272
|
request_start: uint32,
|
|
273
273
|
request_end: uint32,
|
|
274
|
-
) ->
|
|
274
|
+
) -> RespondHeaderBlocks | RespondBlockHeaders | None:
|
|
275
275
|
# We will modify this list, don't modify passed parameters.
|
|
276
276
|
bytes_api_peers = [peer for peer in all_peers if Capability.BLOCK_HEADERS in peer[0].peer_capabilities]
|
|
277
277
|
other_peers = [peer for peer in all_peers if Capability.BLOCK_HEADERS not in peer[0].peer_capabilities]
|
|
@@ -305,19 +305,17 @@ async def fetch_header_blocks_in_range(
|
|
|
305
305
|
end: uint32,
|
|
306
306
|
peer_request_cache: PeerRequestCache,
|
|
307
307
|
all_peers: list[tuple[WSChiaConnection, bool]],
|
|
308
|
-
) ->
|
|
308
|
+
) -> list[HeaderBlock] | None:
|
|
309
309
|
blocks: list[HeaderBlock] = []
|
|
310
310
|
for i in range(start - (start % 32), end + 1, 32):
|
|
311
311
|
request_start = min(uint32(i), end)
|
|
312
312
|
request_end = min(uint32(i + 31), end)
|
|
313
|
-
res_h_blocks_task:
|
|
314
|
-
request_start, request_end
|
|
315
|
-
)
|
|
313
|
+
res_h_blocks_task: asyncio.Task[Any] | None = peer_request_cache.get_block_request(request_start, request_end)
|
|
316
314
|
|
|
317
315
|
if res_h_blocks_task is not None:
|
|
318
316
|
log.debug(f"Using cache for: {start}-{end}")
|
|
319
317
|
if res_h_blocks_task.done():
|
|
320
|
-
res_h_blocks:
|
|
318
|
+
res_h_blocks: RespondBlockHeaders | RespondHeaderBlocks | None = res_h_blocks_task.result()
|
|
321
319
|
else:
|
|
322
320
|
res_h_blocks = await res_h_blocks_task
|
|
323
321
|
else:
|
chia/wallet/util/wallet_types.py
CHANGED
|
@@ -33,8 +33,8 @@ class WalletType(IntEnum):
|
|
|
33
33
|
def to_json_dict(self) -> str:
|
|
34
34
|
# yes, this isn't a `dict`, but it is json and
|
|
35
35
|
# unfortunately the magic method name is misleading
|
|
36
|
-
|
|
37
|
-
#
|
|
36
|
+
|
|
37
|
+
# This gets called with EnhancedJSONEncoder in the RPC
|
|
38
38
|
return self.name
|
|
39
39
|
|
|
40
40
|
|
|
@@ -4,7 +4,6 @@ import functools
|
|
|
4
4
|
from collections.abc import Iterable
|
|
5
5
|
from dataclasses import dataclass, replace
|
|
6
6
|
from enum import IntEnum
|
|
7
|
-
from typing import Optional
|
|
8
7
|
|
|
9
8
|
from chia_puzzles_py.programs import (
|
|
10
9
|
CONDITIONS_W_FEE_ANNOUNCE,
|
|
@@ -65,7 +64,7 @@ CREDENTIAL_STRUCT: Program = Program.to(
|
|
|
65
64
|
curry_and_treehash(
|
|
66
65
|
Program.to((1, EXTIGENT_METADATA_LAYER_HASH)).get_tree_hash_precalc(EXTIGENT_METADATA_LAYER_HASH),
|
|
67
66
|
Program.to(EXTIGENT_METADATA_LAYER_HASH).get_tree_hash(),
|
|
68
|
-
Program.
|
|
67
|
+
Program.NIL.get_tree_hash(),
|
|
69
68
|
GUARANTEED_NIL_TP_HASH,
|
|
70
69
|
Program.to(GUARANTEED_NIL_TP_HASH).get_tree_hash(),
|
|
71
70
|
P2_ANNOUNCED_DELEGATED_PUZZLE_HASH,
|
|
@@ -127,7 +126,7 @@ def construct_cr_layer_hash(
|
|
|
127
126
|
|
|
128
127
|
def match_cr_layer(
|
|
129
128
|
uncurried_puzzle: UncurriedPuzzle,
|
|
130
|
-
) ->
|
|
129
|
+
) -> tuple[list[bytes32], Program, Program] | None:
|
|
131
130
|
extra_uncurried_puzzle = uncurry_puzzle(uncurried_puzzle.mod)
|
|
132
131
|
if extra_uncurried_puzzle.mod == CREDENTIAL_RESTRICTION:
|
|
133
132
|
return (
|
|
@@ -188,7 +187,7 @@ class CRCAT:
|
|
|
188
187
|
authorized_providers: list[bytes32],
|
|
189
188
|
proofs_checker: Program,
|
|
190
189
|
# Probably never need this but some tail might
|
|
191
|
-
optional_lineage_proof:
|
|
190
|
+
optional_lineage_proof: LineageProof | None = None,
|
|
192
191
|
) -> tuple[Program, CoinSpend, CRCAT]:
|
|
193
192
|
"""
|
|
194
193
|
Launch a new CR-CAT from XCH.
|
|
@@ -327,7 +326,7 @@ class CRCAT:
|
|
|
327
326
|
def get_next_from_coin_spend(
|
|
328
327
|
cls,
|
|
329
328
|
parent_spend: CoinSpend,
|
|
330
|
-
conditions:
|
|
329
|
+
conditions: Program | None = None, # For optimization purposes, the conditions may already have been run
|
|
331
330
|
) -> list[CRCAT]:
|
|
332
331
|
"""
|
|
333
332
|
Given a coin spend, this will return the next CR-CATs that were created as an output of that spend.
|
|
@@ -342,7 +341,7 @@ class CRCAT:
|
|
|
342
341
|
|
|
343
342
|
# Get info by uncurrying
|
|
344
343
|
_, tail_hash_as_prog, potential_cr_layer = puzzle.uncurry()[1].as_iter()
|
|
345
|
-
new_inner_puzzle_hash:
|
|
344
|
+
new_inner_puzzle_hash: bytes32 | None = None
|
|
346
345
|
if potential_cr_layer.uncurry()[0].uncurry()[0] != CREDENTIAL_RESTRICTION:
|
|
347
346
|
# If the previous spend is not a CR-CAT:
|
|
348
347
|
# we look for a remark condition that tells us the authorized_providers and proofs_checker
|
|
@@ -428,12 +427,12 @@ class CRCAT:
|
|
|
428
427
|
proof_checker_solution: Program,
|
|
429
428
|
provider_id: bytes32,
|
|
430
429
|
vc_launcher_id: bytes32,
|
|
431
|
-
vc_inner_puzhash:
|
|
430
|
+
vc_inner_puzhash: bytes32 | None, # Optional for incomplete spends
|
|
432
431
|
# Inner puzzle and solution
|
|
433
432
|
inner_puzzle: Program,
|
|
434
433
|
inner_solution: Program,
|
|
435
434
|
# For optimization purposes the conditions may already have been run
|
|
436
|
-
conditions:
|
|
435
|
+
conditions: Iterable[Program] | None = None,
|
|
437
436
|
) -> tuple[list[AssertCoinAnnouncement], CoinSpend, list[CRCAT]]:
|
|
438
437
|
"""
|
|
439
438
|
Spend a CR-CAT.
|
|
@@ -521,7 +520,7 @@ class CRCAT:
|
|
|
521
520
|
proof_checker_solution: Program,
|
|
522
521
|
provider_id: bytes32,
|
|
523
522
|
vc_launcher_id: bytes32,
|
|
524
|
-
vc_inner_puzhash:
|
|
523
|
+
vc_inner_puzhash: bytes32 | None, # Optional for incomplete spends
|
|
525
524
|
) -> tuple[list[AssertCoinAnnouncement], list[CoinSpend], list[CRCAT]]:
|
|
526
525
|
"""
|
|
527
526
|
Spend a multiple CR-CATs.
|
|
@@ -615,7 +614,7 @@ class CRCATSpend:
|
|
|
615
614
|
inner_puzzle,
|
|
616
615
|
inner_solution,
|
|
617
616
|
CRCAT.get_next_from_coin_spend(spend, conditions=inner_conditions),
|
|
618
|
-
Program.from_serialized(spend.solution).at("f").at("rrrrf") == Program.
|
|
617
|
+
Program.from_serialized(spend.solution).at("f").at("rrrrf") == Program.NIL,
|
|
619
618
|
list(inner_conditions.as_iter()),
|
|
620
619
|
Program.from_serialized(spend.solution).at("f").at("f"),
|
|
621
620
|
)
|
|
@@ -628,7 +627,7 @@ class ProofsChecker(Streamable):
|
|
|
628
627
|
|
|
629
628
|
def as_program(self) -> Program:
|
|
630
629
|
def byte_sort_flags(f1: str, f2: str) -> int:
|
|
631
|
-
return 1 if Program.to([10, (1, f1), (1, f2)]).run([]) == Program.
|
|
630
|
+
return 1 if Program.to([10, (1, f1), (1, f2)]).run([]) == Program.NIL else -1
|
|
632
631
|
|
|
633
632
|
return PROOF_FLAGS_CHECKER.curry(
|
|
634
633
|
[
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import logging
|
|
4
4
|
import time
|
|
5
5
|
import traceback
|
|
6
|
-
from typing import TYPE_CHECKING, Any, ClassVar
|
|
6
|
+
from typing import TYPE_CHECKING, Any, ClassVar
|
|
7
7
|
|
|
8
8
|
from chia_rs import CoinSpend, G1Element, G2Element
|
|
9
9
|
from chia_rs.sized_bytes import bytes32
|
|
@@ -72,8 +72,8 @@ class CRCATWallet(CATWallet):
|
|
|
72
72
|
wallet_info_type: ClassVar[type[CRCATInfo]] = CRCATInfo
|
|
73
73
|
|
|
74
74
|
@staticmethod
|
|
75
|
-
def default_wallet_name_for_unknown_cat(
|
|
76
|
-
return f"CAT {
|
|
75
|
+
def default_wallet_name_for_unknown_cat(limitations_program_hash: bytes32) -> str:
|
|
76
|
+
return f"CAT {limitations_program_hash.hex()[:16]}..."
|
|
77
77
|
|
|
78
78
|
@property
|
|
79
79
|
def cost_of_single_tx(self) -> int:
|
|
@@ -87,7 +87,7 @@ class CRCATWallet(CATWallet):
|
|
|
87
87
|
amount: uint64,
|
|
88
88
|
action_scope: WalletActionScope,
|
|
89
89
|
fee: uint64 = uint64(0),
|
|
90
|
-
name:
|
|
90
|
+
name: str | None = None,
|
|
91
91
|
push: bool = False,
|
|
92
92
|
) -> CATWallet: # pragma: no cover
|
|
93
93
|
raise NotImplementedError("create_new_cat_wallet is a legacy method and is not available on CR-CAT wallets")
|
|
@@ -97,31 +97,29 @@ class CRCATWallet(CATWallet):
|
|
|
97
97
|
cls,
|
|
98
98
|
wallet_state_manager: WalletStateManager,
|
|
99
99
|
wallet: Wallet,
|
|
100
|
-
|
|
101
|
-
name:
|
|
102
|
-
authorized_providers:
|
|
103
|
-
proofs_checker:
|
|
100
|
+
limitations_program_hash: bytes32,
|
|
101
|
+
name: str | None = None,
|
|
102
|
+
authorized_providers: list[bytes32] | None = None,
|
|
103
|
+
proofs_checker: ProofsChecker | None = None,
|
|
104
104
|
) -> Self:
|
|
105
105
|
if authorized_providers is None or proofs_checker is None: # pragma: no cover
|
|
106
106
|
raise ValueError("get_or_create_wallet_for_cat was call on CRCATWallet without proper arguments")
|
|
107
107
|
self = cls()
|
|
108
108
|
self.standard_wallet = wallet
|
|
109
109
|
if name is None:
|
|
110
|
-
name = self.default_wallet_name_for_unknown_cat(
|
|
110
|
+
name = self.default_wallet_name_for_unknown_cat(limitations_program_hash)
|
|
111
111
|
self.log = logging.getLogger(name)
|
|
112
112
|
|
|
113
|
-
tail_hash = bytes32.from_hexstr(limitations_program_hash_hex)
|
|
114
|
-
|
|
115
113
|
for id, w in wallet_state_manager.wallets.items():
|
|
116
114
|
if w.type() == cls.type():
|
|
117
115
|
assert isinstance(w, cls)
|
|
118
|
-
if w.get_asset_id() ==
|
|
116
|
+
if w.get_asset_id() == limitations_program_hash:
|
|
119
117
|
self.log.warning("Not creating wallet for already existing CR-CAT wallet")
|
|
120
118
|
return w
|
|
121
119
|
|
|
122
120
|
self.wallet_state_manager = wallet_state_manager
|
|
123
121
|
|
|
124
|
-
self.info = cls.wallet_info_type(
|
|
122
|
+
self.info = cls.wallet_info_type(limitations_program_hash, None, authorized_providers, proofs_checker)
|
|
125
123
|
info_as_string = bytes(self.info).hex()
|
|
126
124
|
self.wallet_info = await wallet_state_manager.user_store.create_wallet(name, WalletType.CRCAT, info_as_string)
|
|
127
125
|
|
|
@@ -134,20 +132,20 @@ class CRCATWallet(CATWallet):
|
|
|
134
132
|
wallet_state_manager: WalletStateManager,
|
|
135
133
|
wallet: Wallet,
|
|
136
134
|
puzzle_driver: PuzzleInfo,
|
|
137
|
-
name:
|
|
135
|
+
name: str | None = None,
|
|
138
136
|
# We're hinting this as Any for mypy by should explore adding this to the wallet protocol and hinting properly
|
|
139
|
-
potential_subclasses:
|
|
137
|
+
potential_subclasses: dict[AssetType, Any] | None = None,
|
|
140
138
|
) -> Any:
|
|
141
139
|
if potential_subclasses is None:
|
|
142
140
|
potential_subclasses = {}
|
|
143
141
|
|
|
144
|
-
cr_layer:
|
|
142
|
+
cr_layer: PuzzleInfo | None = puzzle_driver.also()
|
|
145
143
|
if cr_layer is None: # pragma: no cover
|
|
146
144
|
raise ValueError("create_from_puzzle_info called on CRCATWallet with a non CR-CAT puzzle driver")
|
|
147
145
|
return await cls.get_or_create_wallet_for_cat(
|
|
148
146
|
wallet_state_manager,
|
|
149
147
|
wallet,
|
|
150
|
-
puzzle_driver["tail"]
|
|
148
|
+
puzzle_driver["tail"],
|
|
151
149
|
name,
|
|
152
150
|
[bytes32(provider) for provider in cr_layer["authorized_providers"]],
|
|
153
151
|
ProofsChecker.from_program(uncurry_puzzle(cr_layer["proofs_checker"])),
|
|
@@ -201,14 +199,14 @@ class CRCATWallet(CATWallet):
|
|
|
201
199
|
def id(self) -> uint32:
|
|
202
200
|
return self.wallet_info.id
|
|
203
201
|
|
|
204
|
-
def get_asset_id(self) ->
|
|
205
|
-
return
|
|
202
|
+
def get_asset_id(self) -> bytes32:
|
|
203
|
+
return self.info.limitations_program_hash
|
|
206
204
|
|
|
207
205
|
async def set_tail_program(self, tail_program: str) -> None: # pragma: no cover
|
|
208
206
|
raise NotImplementedError("set_tail_program is a legacy method and is not available on CR-CAT wallets")
|
|
209
207
|
|
|
210
208
|
async def coin_added(
|
|
211
|
-
self, coin: Coin, height: uint32, peer: WSChiaConnection, coin_data:
|
|
209
|
+
self, coin: Coin, height: uint32, peer: WSChiaConnection, coin_data: CATCoinData | None
|
|
212
210
|
) -> None:
|
|
213
211
|
"""Notification from wallet state manager that wallet has been received."""
|
|
214
212
|
self.log.info(f"CR-CAT wallet has been notified that {coin.name().hex()} was added")
|
|
@@ -322,21 +320,13 @@ class CRCATWallet(CATWallet):
|
|
|
322
320
|
"inner_puzzle_for_cat_puzhash is a legacy method and is not available on CR-CAT wallets"
|
|
323
321
|
)
|
|
324
322
|
|
|
325
|
-
async def
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
)
|
|
331
|
-
|
|
332
|
-
for record in record_list:
|
|
333
|
-
crcat: CRCAT = self.coin_record_to_crcat(record)
|
|
334
|
-
if crcat.lineage_proof is not None and not crcat.lineage_proof.is_none():
|
|
335
|
-
result.append(record)
|
|
336
|
-
|
|
337
|
-
return result
|
|
323
|
+
async def is_coin_spendable(self, record: WalletCoinRecord) -> bool:
|
|
324
|
+
crcat: CRCAT = self.coin_record_to_crcat(record)
|
|
325
|
+
if crcat.lineage_proof is not None and not crcat.lineage_proof.is_none():
|
|
326
|
+
return True
|
|
327
|
+
return False
|
|
338
328
|
|
|
339
|
-
async def get_confirmed_balance(self, record_list:
|
|
329
|
+
async def get_confirmed_balance(self, record_list: set[WalletCoinRecord] | None = None) -> uint128:
|
|
340
330
|
if record_list is None:
|
|
341
331
|
record_list = await self.wallet_state_manager.coin_store.get_unspent_coins_for_wallet(
|
|
342
332
|
self.id(), CoinType.CRCAT
|
|
@@ -350,7 +340,7 @@ class CRCATWallet(CATWallet):
|
|
|
350
340
|
self.log.info(f"Confirmed balance for cat wallet {self.id()} is {amount}")
|
|
351
341
|
return uint128(amount)
|
|
352
342
|
|
|
353
|
-
async def get_pending_approval_balance(self, record_list:
|
|
343
|
+
async def get_pending_approval_balance(self, record_list: set[WalletCoinRecord] | None = None) -> uint128:
|
|
354
344
|
if record_list is None:
|
|
355
345
|
record_list = await self.wallet_state_manager.coin_store.get_unspent_coins_for_wallet(
|
|
356
346
|
self.id(), CoinType.CRCAT_PENDING
|
|
@@ -398,7 +388,7 @@ class CRCATWallet(CATWallet):
|
|
|
398
388
|
except Exception as e: # pragma: no cover
|
|
399
389
|
raise ValueError(f"Error parsing CRCAT metadata: {e}")
|
|
400
390
|
|
|
401
|
-
async def get_lineage_proof_for_coin(self, coin: Coin) ->
|
|
391
|
+
async def get_lineage_proof_for_coin(self, coin: Coin) -> LineageProof | None: # pragma: no cover
|
|
402
392
|
raise RuntimeError("get_lineage_proof_for_coin is a legacy method and is not available on CR-CAT wallets")
|
|
403
393
|
|
|
404
394
|
async def _generate_unsigned_spendbundle(
|
|
@@ -406,8 +396,8 @@ class CRCATWallet(CATWallet):
|
|
|
406
396
|
payments: list[CreateCoin],
|
|
407
397
|
action_scope: WalletActionScope,
|
|
408
398
|
fee: uint64 = uint64(0),
|
|
409
|
-
cat_discrepancy:
|
|
410
|
-
coins:
|
|
399
|
+
cat_discrepancy: tuple[int, Program, Program] | None = None, # (extra_delta, tail_reveal, tail_solution)
|
|
400
|
+
coins: set[Coin] | None = None,
|
|
411
401
|
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
412
402
|
add_authorizations_to_cr_cats: bool = True,
|
|
413
403
|
) -> WalletSpendBundle:
|
|
@@ -480,7 +470,7 @@ class CRCATWallet(CATWallet):
|
|
|
480
470
|
raise RuntimeError("CR-CATs cannot be spent without an appropriate VC") # pragma: no cover
|
|
481
471
|
|
|
482
472
|
# Loop through the coins we've selected and gather the information we need to spend them
|
|
483
|
-
vc:
|
|
473
|
+
vc: VerifiedCredential | None = None
|
|
484
474
|
vc_announcements_to_make: list[bytes] = []
|
|
485
475
|
inner_spends: list[tuple[CRCAT, int, Program, Program]] = []
|
|
486
476
|
first = True
|
|
@@ -502,7 +492,7 @@ class CRCATWallet(CATWallet):
|
|
|
502
492
|
cat_condition = UnknownCondition(
|
|
503
493
|
opcode=Program.to(51),
|
|
504
494
|
args=[
|
|
505
|
-
Program.
|
|
495
|
+
Program.NIL,
|
|
506
496
|
Program.to(-113),
|
|
507
497
|
tail_reveal,
|
|
508
498
|
tail_solution,
|
|
@@ -583,7 +573,7 @@ class CRCATWallet(CATWallet):
|
|
|
583
573
|
expected_announcements, coin_spends, _ = CRCAT.spend_many(
|
|
584
574
|
inner_spends,
|
|
585
575
|
proof_of_inclusions,
|
|
586
|
-
Program.
|
|
576
|
+
Program.NIL, # TODO: With more proofs checkers, this may need to be flexible. For now, it's hardcoded.
|
|
587
577
|
vc.proof_provider,
|
|
588
578
|
vc.launcher_id,
|
|
589
579
|
vc.wrap_inner_with_backdoor().get_tree_hash() if add_authorizations_to_cr_cats else None,
|
|
@@ -609,13 +599,13 @@ class CRCATWallet(CATWallet):
|
|
|
609
599
|
puzzle_hashes: list[bytes32],
|
|
610
600
|
action_scope: WalletActionScope,
|
|
611
601
|
fee: uint64 = uint64(0),
|
|
612
|
-
coins:
|
|
613
|
-
memos:
|
|
602
|
+
coins: set[Coin] | None = None,
|
|
603
|
+
memos: list[list[bytes]] | None = None,
|
|
614
604
|
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
615
605
|
**kwargs: Unpack[GSTOptionalArgs],
|
|
616
606
|
) -> None:
|
|
617
607
|
# (extra_delta, tail_reveal, tail_solution)
|
|
618
|
-
cat_discrepancy:
|
|
608
|
+
cat_discrepancy: tuple[int, Program, Program] | None = kwargs.get("cat_discrepancy", None)
|
|
619
609
|
add_authorizations_to_cr_cats: bool = kwargs.get("add_authorizations_to_cr_cats", True)
|
|
620
610
|
if memos is None:
|
|
621
611
|
memos = [[] for _ in range(len(puzzle_hashes))]
|
|
@@ -659,25 +649,17 @@ class CRCATWallet(CATWallet):
|
|
|
659
649
|
addition for tx in interface.side_effects.transactions for addition in tx.additions
|
|
660
650
|
}
|
|
661
651
|
tx_list = [
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
confirmed=False,
|
|
670
|
-
sent=uint32(0),
|
|
671
|
-
spend_bundle=spend_bundle if i == 0 else None,
|
|
652
|
+
self.wallet_state_manager.new_outgoing_transaction(
|
|
653
|
+
wallet_id=self.id(),
|
|
654
|
+
puzzle_hash=payment.puzzle_hash,
|
|
655
|
+
amount=uint64(payment.amount),
|
|
656
|
+
fee=fee,
|
|
657
|
+
# semantics guarantee not None here
|
|
658
|
+
spend_bundle=spend_bundle if i == 0 else None, # type: ignore[arg-type]
|
|
672
659
|
additions=list(set(spend_bundle.additions()) - other_tx_additions) if i == 0 else [],
|
|
673
660
|
removals=list(set(spend_bundle.removals()) - other_tx_removals) if i == 0 else [],
|
|
674
|
-
wallet_id=self.id(),
|
|
675
|
-
sent_to=[],
|
|
676
|
-
trade_id=None,
|
|
677
|
-
type=uint32(TransactionType.OUTGOING_TX.value),
|
|
678
661
|
name=spend_bundle.name() if i == 0 else payment.to_program().get_tree_hash(),
|
|
679
|
-
|
|
680
|
-
valid_times=parse_timelock_info(extra_conditions),
|
|
662
|
+
extra_conditions=extra_conditions,
|
|
681
663
|
)
|
|
682
664
|
for i, payment in enumerate(payments)
|
|
683
665
|
]
|
|
@@ -689,11 +671,11 @@ class CRCATWallet(CATWallet):
|
|
|
689
671
|
min_amount_to_claim: uint64,
|
|
690
672
|
action_scope: WalletActionScope,
|
|
691
673
|
fee: uint64 = uint64(0),
|
|
692
|
-
coins:
|
|
693
|
-
min_coin_amount:
|
|
694
|
-
max_coin_amount:
|
|
695
|
-
excluded_coin_amounts:
|
|
696
|
-
reuse_puzhash:
|
|
674
|
+
coins: set[Coin] | None = None,
|
|
675
|
+
min_coin_amount: uint64 | None = None,
|
|
676
|
+
max_coin_amount: uint64 | None = None,
|
|
677
|
+
excluded_coin_amounts: list[uint64] | None = None,
|
|
678
|
+
reuse_puzhash: bool | None = None,
|
|
697
679
|
extra_conditions: tuple[Condition, ...] = tuple(),
|
|
698
680
|
) -> None:
|
|
699
681
|
# Select the relevant CR-CAT coins
|
|
@@ -723,7 +705,7 @@ class CRCATWallet(CATWallet):
|
|
|
723
705
|
|
|
724
706
|
# Select the relevant VC coin
|
|
725
707
|
vc_wallet: VCWallet = await self.wallet_state_manager.get_or_create_vc_wallet()
|
|
726
|
-
vc:
|
|
708
|
+
vc: VerifiedCredential | None = await vc_wallet.get_vc_with_provider_in_and_proofs(
|
|
727
709
|
self.info.authorized_providers, self.info.proofs_checker.flags
|
|
728
710
|
)
|
|
729
711
|
if vc is None: # pragma: no cover
|
|
@@ -756,7 +738,7 @@ class CRCATWallet(CATWallet):
|
|
|
756
738
|
for crcat, inner_puzhash in crcats_and_puzhashes
|
|
757
739
|
],
|
|
758
740
|
proof_of_inclusions,
|
|
759
|
-
Program.
|
|
741
|
+
Program.NIL, # TODO: With more proofs checkers, this may need to be flexible. For now, it's hardcoded.
|
|
760
742
|
vc.proof_provider,
|
|
761
743
|
vc.launcher_id,
|
|
762
744
|
vc.wrap_inner_with_backdoor().get_tree_hash(),
|
|
@@ -818,7 +800,7 @@ class CRCATWallet(CATWallet):
|
|
|
818
800
|
AssetType(puzzle_driver.type()) == AssetType.CAT
|
|
819
801
|
and puzzle_driver["tail"] == self.info.limitations_program_hash
|
|
820
802
|
):
|
|
821
|
-
inner_puzzle_driver:
|
|
803
|
+
inner_puzzle_driver: PuzzleInfo | None = puzzle_driver.also()
|
|
822
804
|
if inner_puzzle_driver is None:
|
|
823
805
|
raise ValueError("Malformed puzzle driver passed to CRCATWallet.match_puzzle_info") # pragma: no cover
|
|
824
806
|
return (
|