chia-blockchain 2.5.4rc1__py3-none-any.whl → 2.5.5__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/_tests/blockchain/blockchain_test_utils.py +2 -3
- chia/_tests/blockchain/test_augmented_chain.py +2 -3
- chia/_tests/blockchain/test_blockchain.py +261 -44
- chia/_tests/blockchain/test_blockchain_transactions.py +4 -3
- chia/_tests/blockchain/test_build_chains.py +197 -1
- chia/_tests/blockchain/test_get_block_generator.py +1 -1
- chia/_tests/blockchain/test_lookup_fork_chain.py +1 -1
- chia/_tests/clvm/benchmark_costs.py +1 -1
- chia/_tests/clvm/coin_store.py +3 -4
- chia/_tests/clvm/test_message_conditions.py +2 -2
- chia/_tests/clvm/test_puzzle_compression.py +2 -3
- chia/_tests/clvm/test_puzzles.py +1 -2
- chia/_tests/clvm/test_singletons.py +2 -3
- chia/_tests/clvm/test_spend_sim.py +7 -7
- chia/_tests/cmds/cmd_test_utils.py +30 -25
- chia/_tests/cmds/test_dev_gh.py +1 -1
- chia/_tests/cmds/test_farm_cmd.py +1 -1
- chia/_tests/cmds/test_show.py +1 -2
- chia/_tests/cmds/wallet/test_did.py +101 -56
- chia/_tests/cmds/wallet/test_nft.py +109 -84
- chia/_tests/cmds/wallet/test_notifications.py +1 -1
- chia/_tests/cmds/wallet/test_offer.toffer +1 -1
- chia/_tests/cmds/wallet/test_vcs.py +8 -8
- chia/_tests/cmds/wallet/test_wallet.py +100 -46
- chia/_tests/conftest.py +31 -20
- chia/_tests/connection_utils.py +1 -1
- chia/_tests/core/consensus/stores/__init__.py +0 -0
- chia/_tests/core/consensus/stores/test_coin_store_protocol.py +40 -0
- chia/_tests/core/consensus/test_block_creation.py +2 -31
- chia/_tests/core/consensus/test_pot_iterations.py +38 -3
- chia/_tests/core/custom_types/test_proof_of_space.py +154 -26
- chia/_tests/core/custom_types/test_spend_bundle.py +2 -3
- chia/_tests/core/daemon/test_daemon.py +80 -0
- chia/_tests/core/data_layer/test_data_layer.py +1 -1
- chia/_tests/core/data_layer/test_data_layer_util.py +1 -1
- chia/_tests/core/data_layer/test_data_rpc.py +14 -10
- chia/_tests/core/data_layer/test_data_store.py +5 -5
- chia/_tests/core/farmer/test_farmer_api.py +2 -2
- chia/_tests/core/full_node/full_sync/test_full_sync.py +446 -406
- chia/_tests/core/full_node/ram_db.py +3 -1
- chia/_tests/core/full_node/stores/test_block_store.py +28 -16
- chia/_tests/core/full_node/stores/test_coin_store.py +277 -185
- chia/_tests/core/full_node/stores/test_full_node_store.py +11 -4
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/test_address_manager.py +200 -27
- chia/_tests/core/full_node/test_block_height_map.py +2 -2
- chia/_tests/core/full_node/test_conditions.py +7 -6
- chia/_tests/core/full_node/test_full_node.py +456 -40
- chia/_tests/core/full_node/test_generator_tools.py +32 -2
- chia/_tests/core/full_node/test_hint_management.py +1 -1
- chia/_tests/core/full_node/test_node_load.py +20 -21
- chia/_tests/core/full_node/test_performance.py +3 -4
- chia/_tests/core/full_node/test_prev_tx_block.py +43 -0
- chia/_tests/core/full_node/test_subscriptions.py +1 -2
- chia/_tests/core/full_node/test_transactions.py +9 -5
- chia/_tests/core/full_node/test_tx_processing_queue.py +1 -2
- chia/_tests/core/large_block.py +1 -2
- chia/_tests/core/make_block_generator.py +3 -4
- chia/_tests/core/mempool/test_mempool.py +36 -86
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
- chia/_tests/core/mempool/test_mempool_item_queries.py +1 -3
- chia/_tests/core/mempool/test_mempool_manager.py +529 -69
- chia/_tests/core/mempool/test_mempool_performance.py +3 -2
- chia/_tests/core/mempool/test_singleton_fast_forward.py +61 -132
- chia/_tests/core/server/flood.py +1 -1
- chia/_tests/core/server/test_dos.py +1 -1
- chia/_tests/core/server/test_node_discovery.py +41 -27
- chia/_tests/core/server/test_rate_limits.py +1 -1
- chia/_tests/core/server/test_server.py +1 -1
- chia/_tests/core/services/test_services.py +5 -5
- chia/_tests/core/ssl/test_ssl.py +1 -1
- chia/_tests/core/test_cost_calculation.py +6 -6
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_crawler_rpc.py +1 -1
- chia/_tests/core/test_db_conversion.py +3 -1
- chia/_tests/core/test_db_validation.py +5 -3
- chia/_tests/core/test_farmer_harvester_rpc.py +15 -15
- chia/_tests/core/test_filter.py +4 -1
- chia/_tests/core/test_full_node_rpc.py +99 -82
- chia/_tests/core/test_program.py +2 -2
- chia/_tests/core/util/test_block_cache.py +1 -1
- chia/_tests/core/util/test_keychain.py +2 -2
- chia/_tests/core/util/test_lockfile.py +1 -1
- chia/_tests/core/util/test_log_exceptions.py +5 -5
- chia/_tests/core/util/test_streamable.py +81 -22
- chia/_tests/db/test_db_wrapper.py +1 -3
- chia/_tests/environments/wallet.py +5 -5
- chia/_tests/farmer_harvester/test_farmer.py +9 -7
- chia/_tests/farmer_harvester/test_farmer_harvester.py +11 -4
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +15 -9
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -2
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +7 -5
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
- chia/_tests/generator/test_compression.py +1 -2
- chia/_tests/generator/test_rom.py +8 -4
- chia/_tests/plot_sync/test_plot_sync.py +3 -3
- chia/_tests/plot_sync/test_receiver.py +3 -3
- chia/_tests/plot_sync/test_sender.py +1 -1
- chia/_tests/plot_sync/test_sync_simulated.py +3 -3
- chia/_tests/plot_sync/util.py +2 -2
- chia/_tests/pools/test_pool_cmdline.py +48 -21
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +2 -3
- chia/_tests/pools/test_pool_rpc.py +237 -105
- chia/_tests/pools/test_pool_wallet.py +11 -2
- chia/_tests/pools/test_wallet_pool_store.py +5 -4
- chia/_tests/rpc/test_rpc_client.py +1 -1
- chia/_tests/simulation/test_simulation.py +13 -8
- chia/_tests/simulation/test_simulator.py +2 -2
- chia/_tests/timelord/test_new_peak.py +191 -47
- chia/_tests/timelord/test_timelord.py +1 -1
- chia/_tests/tools/test_full_sync.py +0 -2
- chia/_tests/tools/test_run_block.py +3 -1
- chia/_tests/util/benchmark_cost.py +3 -3
- chia/_tests/util/benchmarks.py +2 -2
- chia/_tests/util/blockchain.py +11 -5
- chia/_tests/util/blockchain_mock.py +1 -4
- chia/_tests/util/coin_store.py +29 -0
- chia/_tests/util/constants.py +2 -18
- chia/_tests/util/full_sync.py +3 -3
- chia/_tests/util/generator_tools_testing.py +2 -3
- chia/_tests/util/key_tool.py +2 -3
- chia/_tests/util/misc.py +33 -31
- chia/_tests/util/network_protocol_data.py +19 -17
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +3 -1
- chia/_tests/util/run_block.py +2 -2
- chia/_tests/util/setup_nodes.py +7 -7
- chia/_tests/util/spend_sim.py +47 -55
- chia/_tests/util/test_condition_tools.py +5 -4
- chia/_tests/util/test_config.py +2 -2
- chia/_tests/util/test_dump_keyring.py +1 -1
- chia/_tests/util/test_full_block_utils.py +12 -14
- chia/_tests/util/test_misc.py +2 -2
- chia/_tests/util/test_paginator.py +4 -4
- chia/_tests/util/test_priority_mutex.py +2 -2
- chia/_tests/util/test_replace_str_to_bytes.py +15 -5
- chia/_tests/util/test_ssl_check.py +1 -1
- chia/_tests/util/test_testnet_overrides.py +13 -3
- chia/_tests/util/time_out_assert.py +4 -2
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -2
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +352 -432
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +3 -6
- chia/_tests/wallet/cat_wallet/test_trades.py +53 -77
- chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -1
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +3 -3
- chia/_tests/wallet/clawback/test_clawback_metadata.py +4 -2
- chia/_tests/wallet/conftest.py +11 -12
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +11 -4
- chia/_tests/wallet/db_wallet/test_dl_offers.py +433 -130
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +3 -3
- chia/_tests/wallet/did_wallet/test_did.py +2132 -2000
- chia/_tests/wallet/nft_wallet/config.py +1 -1
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1610 -742
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +486 -907
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +4 -4
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +517 -294
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +133 -62
- chia/_tests/wallet/rpc/test_wallet_rpc.py +495 -265
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +10 -6
- chia/_tests/wallet/sync/test_wallet_sync.py +89 -60
- chia/_tests/wallet/test_clvm_casts.py +88 -0
- chia/_tests/wallet/test_coin_management.py +1 -1
- chia/_tests/wallet/test_coin_selection.py +1 -1
- chia/_tests/wallet/test_conditions.py +1 -1
- chia/_tests/wallet/test_new_wallet_protocol.py +13 -11
- chia/_tests/wallet/test_notifications.py +5 -3
- chia/_tests/wallet/test_sign_coin_spends.py +6 -6
- chia/_tests/wallet/test_signer_protocol.py +13 -12
- chia/_tests/wallet/test_singleton.py +1 -1
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +5 -7
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +108 -29
- chia/_tests/wallet/test_wallet_action_scope.py +9 -2
- chia/_tests/wallet/test_wallet_blockchain.py +2 -3
- chia/_tests/wallet/test_wallet_key_val_store.py +1 -2
- chia/_tests/wallet/test_wallet_node.py +2 -4
- chia/_tests/wallet/test_wallet_retry.py +4 -2
- chia/_tests/wallet/test_wallet_state_manager.py +191 -5
- chia/_tests/wallet/test_wallet_test_framework.py +1 -1
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +8 -8
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -12
- chia/_tests/wallet/wallet_block_tools.py +6 -6
- chia/_tests/weight_proof/test_weight_proof.py +10 -48
- chia/apis.py +1 -1
- chia/cmds/beta.py +1 -1
- chia/cmds/chia.py +9 -9
- chia/cmds/cmd_classes.py +12 -11
- chia/cmds/cmd_helpers.py +1 -1
- chia/cmds/cmds_util.py +12 -9
- chia/cmds/coin_funcs.py +2 -2
- chia/cmds/configure.py +2 -2
- chia/cmds/data.py +0 -2
- chia/cmds/data_funcs.py +1 -1
- chia/cmds/db_validate_func.py +1 -2
- chia/cmds/dev/__init__.py +0 -0
- chia/cmds/dev/data.py +273 -0
- chia/cmds/{gh.py → dev/gh.py} +5 -5
- chia/cmds/dev/main.py +22 -0
- chia/cmds/dev/mempool.py +78 -0
- chia/cmds/dev/mempool_funcs.py +63 -0
- chia/cmds/farm_funcs.py +5 -4
- chia/cmds/init_funcs.py +11 -11
- chia/cmds/keys.py +2 -2
- chia/cmds/keys_funcs.py +4 -4
- chia/cmds/netspace_funcs.py +1 -1
- chia/cmds/peer_funcs.py +2 -2
- chia/cmds/plotnft_funcs.py +72 -26
- chia/cmds/rpc.py +1 -1
- chia/cmds/show_funcs.py +5 -5
- chia/cmds/signer.py +8 -7
- chia/cmds/sim_funcs.py +8 -9
- chia/cmds/wallet.py +2 -2
- chia/cmds/wallet_funcs.py +165 -131
- chia/{util → consensus}/augmented_chain.py +1 -2
- chia/consensus/block_body_validation.py +54 -40
- chia/consensus/block_creation.py +42 -76
- chia/consensus/block_header_validation.py +32 -26
- chia/consensus/block_record.py +0 -3
- chia/consensus/blockchain.py +23 -32
- chia/consensus/blockchain_interface.py +1 -5
- chia/consensus/check_time_locks.py +57 -0
- chia/consensus/coin_store_protocol.py +151 -0
- chia/consensus/coinbase.py +0 -6
- chia/consensus/condition_costs.py +4 -0
- chia/{util → consensus}/condition_tools.py +4 -5
- chia/consensus/cost_calculator.py +1 -1
- chia/consensus/default_constants.py +32 -9
- chia/consensus/deficit.py +1 -3
- chia/consensus/difficulty_adjustment.py +1 -2
- chia/consensus/find_fork_point.py +1 -3
- chia/consensus/full_block_to_block_record.py +1 -6
- chia/{util → consensus}/generator_tools.py +1 -3
- chia/consensus/get_block_challenge.py +30 -7
- chia/consensus/make_sub_epoch_summary.py +1 -5
- chia/consensus/multiprocess_validation.py +21 -20
- chia/consensus/pot_iterations.py +74 -13
- chia/{util → consensus}/prev_transaction_block.py +1 -1
- chia/consensus/vdf_info_computation.py +1 -3
- chia/daemon/keychain_proxy.py +5 -5
- chia/daemon/server.py +22 -5
- chia/data_layer/data_layer.py +92 -51
- chia/{rpc → data_layer}/data_layer_rpc_api.py +1 -1
- chia/{rpc → data_layer}/data_layer_rpc_util.py +3 -6
- chia/data_layer/data_layer_util.py +4 -6
- chia/data_layer/data_layer_wallet.py +42 -69
- chia/data_layer/dl_wallet_store.py +12 -6
- chia/data_layer/download_data.py +3 -3
- chia/data_layer/s3_plugin_service.py +0 -1
- chia/farmer/farmer.py +3 -4
- chia/farmer/farmer_api.py +11 -7
- chia/{rpc → farmer}/farmer_rpc_client.py +1 -1
- chia/full_node/block_height_map.py +7 -6
- chia/full_node/block_store.py +5 -7
- chia/full_node/bundle_tools.py +1 -2
- chia/full_node/coin_store.py +153 -124
- chia/{types → full_node}/eligible_coin_spends.py +39 -70
- chia/full_node/fee_estimator.py +1 -1
- chia/full_node/fee_estimator_interface.py +0 -8
- chia/full_node/fee_tracker.py +25 -25
- chia/full_node/full_node.py +70 -53
- chia/full_node/full_node_api.py +57 -40
- chia/{rpc → full_node}/full_node_rpc_api.py +87 -8
- chia/{rpc → full_node}/full_node_rpc_client.py +7 -6
- chia/full_node/full_node_store.py +23 -8
- chia/full_node/mempool.py +206 -53
- chia/full_node/mempool_check_conditions.py +20 -63
- chia/full_node/mempool_manager.py +53 -47
- chia/full_node/subscriptions.py +1 -3
- chia/full_node/tx_processing_queue.py +50 -3
- chia/full_node/weight_proof.py +46 -37
- chia/harvester/harvester.py +1 -1
- chia/harvester/harvester_api.py +22 -7
- chia/introducer/introducer.py +1 -1
- chia/introducer/introducer_api.py +1 -1
- chia/plot_sync/exceptions.py +1 -1
- chia/plot_sync/receiver.py +1 -1
- chia/plot_sync/sender.py +2 -2
- chia/pools/pool_puzzles.py +13 -18
- chia/pools/pool_wallet.py +23 -46
- chia/protocols/farmer_protocol.py +11 -3
- chia/protocols/full_node_protocol.py +1 -4
- chia/protocols/harvester_protocol.py +3 -3
- chia/protocols/pool_protocol.py +1 -2
- chia/protocols/shared_protocol.py +3 -3
- chia/protocols/timelord_protocol.py +1 -3
- chia/protocols/wallet_protocol.py +3 -3
- chia/rpc/rpc_client.py +7 -8
- chia/rpc/rpc_server.py +3 -3
- chia/rpc/util.py +3 -1
- chia/seeder/crawler.py +1 -1
- chia/seeder/crawler_api.py +1 -1
- chia/seeder/dns_server.py +2 -0
- chia/seeder/start_crawler.py +3 -3
- chia/server/address_manager.py +286 -38
- chia/server/address_manager_store.py +0 -215
- chia/{types → server}/aliases.py +7 -7
- chia/server/api_protocol.py +1 -1
- chia/server/chia_policy.py +1 -1
- chia/server/node_discovery.py +76 -113
- chia/server/rate_limits.py +1 -1
- chia/server/resolve_peer_info.py +43 -0
- chia/server/server.py +5 -5
- chia/server/start_data_layer.py +4 -4
- chia/server/start_farmer.py +5 -4
- chia/server/start_full_node.py +5 -4
- chia/server/start_harvester.py +7 -5
- chia/server/start_introducer.py +2 -2
- chia/server/start_service.py +1 -1
- chia/server/start_timelord.py +7 -5
- chia/server/start_wallet.py +7 -5
- chia/server/ws_connection.py +1 -1
- chia/simulator/add_blocks_in_batches.py +2 -2
- chia/simulator/block_tools.py +245 -201
- chia/simulator/full_node_simulator.py +38 -10
- chia/simulator/setup_services.py +12 -12
- chia/simulator/simulator_full_node_rpc_api.py +2 -2
- chia/simulator/simulator_full_node_rpc_client.py +2 -2
- chia/simulator/simulator_test_tools.py +2 -2
- chia/simulator/start_simulator.py +1 -1
- chia/simulator/wallet_tools.py +10 -18
- chia/ssl/create_ssl.py +1 -1
- chia/timelord/iters_from_block.py +14 -14
- chia/timelord/timelord.py +15 -11
- chia/timelord/timelord_api.py +14 -2
- chia/timelord/timelord_state.py +20 -14
- chia/types/blockchain_format/program.py +53 -10
- chia/types/blockchain_format/proof_of_space.py +73 -19
- chia/types/coin_spend.py +3 -56
- chia/types/generator_types.py +28 -0
- chia/types/internal_mempool_item.py +1 -2
- chia/types/mempool_item.py +12 -7
- chia/types/unfinished_header_block.py +1 -2
- chia/types/validation_state.py +1 -2
- chia/types/weight_proof.py +1 -3
- chia/util/action_scope.py +3 -3
- chia/util/block_cache.py +1 -2
- chia/util/byte_types.py +1 -1
- chia/util/casts.py +21 -0
- chia/util/config.py +0 -37
- chia/util/db_wrapper.py +8 -1
- chia/util/errors.py +3 -2
- chia/util/initial-config.yaml +21 -5
- chia/util/keychain.py +6 -7
- chia/util/keyring_wrapper.py +5 -5
- chia/util/limited_semaphore.py +1 -1
- chia/util/priority_mutex.py +1 -1
- chia/util/streamable.py +63 -5
- chia/util/task_timing.py +1 -1
- chia/util/virtual_project_analysis.py +1 -1
- chia/wallet/cat_wallet/cat_info.py +7 -3
- chia/wallet/cat_wallet/cat_outer_puzzle.py +9 -5
- chia/wallet/cat_wallet/cat_utils.py +1 -1
- chia/wallet/cat_wallet/cat_wallet.py +44 -36
- chia/wallet/cat_wallet/lineage_store.py +7 -0
- chia/wallet/cat_wallet/r_cat_wallet.py +274 -0
- chia/wallet/conditions.py +5 -10
- chia/wallet/db_wallet/db_wallet_puzzles.py +4 -4
- chia/wallet/derivation_record.py +33 -0
- chia/wallet/derive_keys.py +3 -3
- chia/wallet/did_wallet/did_info.py +12 -3
- chia/wallet/did_wallet/did_wallet.py +132 -101
- chia/wallet/did_wallet/did_wallet_puzzles.py +9 -9
- chia/wallet/driver_protocol.py +3 -1
- chia/{types/spend_bundle.py → wallet/estimate_fees.py} +2 -7
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +5 -3
- chia/wallet/nft_wallet/nft_puzzle_utils.py +1 -1
- chia/wallet/nft_wallet/nft_wallet.py +69 -112
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +5 -3
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +6 -4
- chia/wallet/nft_wallet/transfer_program_puzzle.py +4 -2
- chia/wallet/nft_wallet/uncurry_nft.py +4 -6
- chia/wallet/notification_manager.py +2 -3
- chia/wallet/outer_puzzles.py +7 -2
- chia/wallet/puzzle_drivers.py +1 -1
- chia/wallet/puzzles/clawback/drivers.py +5 -4
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -1
- chia/wallet/puzzles/singleton_top_layer.py +2 -1
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +2 -1
- chia/wallet/puzzles/tails.py +1 -3
- chia/wallet/signer_protocol.py +5 -6
- chia/wallet/singleton.py +5 -4
- chia/wallet/singleton_record.py +1 -1
- chia/wallet/trade_manager.py +18 -20
- chia/wallet/trade_record.py +3 -6
- chia/wallet/trading/offer.py +12 -13
- chia/wallet/uncurried_puzzle.py +2 -2
- chia/wallet/util/compute_additions.py +58 -0
- chia/wallet/util/compute_hints.py +3 -3
- chia/wallet/util/compute_memos.py +4 -4
- chia/wallet/util/curry_and_treehash.py +2 -1
- chia/wallet/util/debug_spend_bundle.py +1 -1
- chia/wallet/util/merkle_tree.py +1 -1
- chia/wallet/util/peer_request_cache.py +1 -2
- chia/wallet/util/tx_config.py +3 -8
- chia/wallet/util/wallet_sync_utils.py +10 -5
- chia/wallet/util/wallet_types.py +1 -0
- chia/wallet/vc_wallet/cr_cat_drivers.py +17 -18
- chia/wallet/vc_wallet/cr_cat_wallet.py +30 -28
- chia/wallet/vc_wallet/cr_outer_puzzle.py +5 -3
- chia/wallet/vc_wallet/vc_drivers.py +50 -8
- chia/wallet/vc_wallet/vc_store.py +3 -5
- chia/wallet/vc_wallet/vc_wallet.py +15 -22
- chia/wallet/wallet.py +36 -46
- chia/wallet/wallet_action_scope.py +73 -4
- chia/wallet/wallet_blockchain.py +1 -3
- chia/wallet/wallet_interested_store.py +1 -1
- chia/wallet/wallet_nft_store.py +3 -3
- chia/wallet/wallet_node.py +17 -16
- chia/wallet/wallet_node_api.py +4 -5
- chia/wallet/wallet_pool_store.py +1 -1
- chia/wallet/wallet_protocol.py +2 -0
- chia/wallet/wallet_puzzle_store.py +1 -1
- chia/{rpc → wallet}/wallet_request_types.py +670 -81
- chia/{rpc → wallet}/wallet_rpc_api.py +735 -766
- chia/{rpc → wallet}/wallet_rpc_client.py +268 -420
- chia/wallet/wallet_singleton_store.py +8 -7
- chia/wallet/wallet_spend_bundle.py +4 -3
- chia/wallet/wallet_state_manager.py +320 -191
- chia/wallet/wallet_weight_proof_handler.py +1 -2
- chia/wallet/wsm_apis.py +98 -0
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/METADATA +7 -7
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/RECORD +443 -436
- mozilla-ca/cacert.pem +3 -165
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +0 -145
- chia/cmds/dev.py +0 -18
- chia/types/blockchain_format/slots.py +0 -9
- chia/types/blockchain_format/sub_epoch_summary.py +0 -5
- chia/types/end_of_slot_bundle.py +0 -5
- chia/types/full_block.py +0 -5
- chia/types/header_block.py +0 -5
- chia/types/spend_bundle_conditions.py +0 -7
- chia/types/transaction_queue_entry.py +0 -56
- chia/types/unfinished_block.py +0 -5
- /chia/cmds/{installers.py → dev/installers.py} +0 -0
- /chia/cmds/{sim.py → dev/sim.py} +0 -0
- /chia/{util → cmds}/dump_keyring.py +0 -0
- /chia/{full_node → consensus}/signage_point.py +0 -0
- /chia/{rpc → data_layer}/data_layer_rpc_client.py +0 -0
- /chia/{rpc → farmer}/farmer_rpc_api.py +0 -0
- /chia/{util → full_node}/full_block_utils.py +0 -0
- /chia/{rpc → harvester}/harvester_rpc_api.py +0 -0
- /chia/{rpc → harvester}/harvester_rpc_client.py +0 -0
- /chia/{full_node → protocols}/fee_estimate.py +0 -0
- /chia/{server → protocols}/outbound_message.py +0 -0
- /chia/{rpc → seeder}/crawler_rpc_api.py +0 -0
- /chia/{util → simulator}/vdf_prover.py +0 -0
- /chia/{util → ssl}/ssl_check.py +0 -0
- /chia/{rpc → timelord}/timelord_rpc_api.py +0 -0
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/LICENSE +0 -0
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/entry_points.txt +0 -0
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import dataclasses
|
|
4
4
|
import json
|
|
5
|
+
from typing import Any, Optional, Union
|
|
5
6
|
|
|
6
7
|
import pytest
|
|
7
8
|
from chia_rs import AugSchemeMPL, G1Element, G2Element
|
|
@@ -12,8 +13,7 @@ from chia._tests.conftest import ConsensusMode
|
|
|
12
13
|
from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework
|
|
13
14
|
from chia._tests.util.setup_nodes import OldSimulatorsAndWallets
|
|
14
15
|
from chia._tests.util.time_out_assert import time_out_assert
|
|
15
|
-
from chia.
|
|
16
|
-
from chia.rpc.wallet_rpc_api import WalletRpcApi
|
|
16
|
+
from chia.consensus.condition_tools import conditions_dict_for_solution
|
|
17
17
|
from chia.server.server import ChiaServer
|
|
18
18
|
from chia.simulator.block_tools import BlockTools
|
|
19
19
|
from chia.simulator.full_node_simulator import FullNodeSimulator
|
|
@@ -23,13 +23,23 @@ from chia.types.condition_opcodes import ConditionOpcode
|
|
|
23
23
|
from chia.types.peer_info import PeerInfo
|
|
24
24
|
from chia.types.signing_mode import CHIP_0002_SIGN_MESSAGE_PREFIX
|
|
25
25
|
from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
|
|
26
|
-
from chia.util.condition_tools import conditions_dict_for_solution
|
|
27
26
|
from chia.wallet.did_wallet.did_wallet import DIDWallet
|
|
28
|
-
from chia.wallet.
|
|
27
|
+
from chia.wallet.did_wallet.did_wallet_puzzles import (
|
|
28
|
+
DID_INNERPUZ_MOD,
|
|
29
|
+
)
|
|
30
|
+
from chia.wallet.singleton import (
|
|
31
|
+
SINGLETON_LAUNCHER_PUZZLE_HASH,
|
|
32
|
+
SINGLETON_TOP_LAYER_MOD_HASH,
|
|
33
|
+
create_singleton_puzzle,
|
|
34
|
+
)
|
|
29
35
|
from chia.wallet.util.address_type import AddressType
|
|
30
36
|
from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG
|
|
31
37
|
from chia.wallet.util.wallet_types import WalletType
|
|
38
|
+
from chia.wallet.wallet import Wallet
|
|
39
|
+
from chia.wallet.wallet_action_scope import WalletActionScope
|
|
32
40
|
from chia.wallet.wallet_node import WalletNode
|
|
41
|
+
from chia.wallet.wallet_request_types import DIDFindLostDID, DIDGetCurrentCoinInfo, DIDGetInfo, DIDGetRecoveryInfo
|
|
42
|
+
from chia.wallet.wallet_rpc_api import WalletRpcApi
|
|
33
43
|
from chia.wallet.wallet_spend_bundle import WalletSpendBundle
|
|
34
44
|
|
|
35
45
|
|
|
@@ -41,2185 +51,2297 @@ def get_parent_num(did_wallet: DIDWallet):
|
|
|
41
51
|
return len(did_wallet.did_info.parent_info)
|
|
42
52
|
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
78
|
-
}
|
|
79
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
80
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
81
|
-
}
|
|
54
|
+
async def make_did_wallet(
|
|
55
|
+
wallet_state_manager: Any,
|
|
56
|
+
wallet: Wallet,
|
|
57
|
+
amount: uint64,
|
|
58
|
+
action_scope: WalletActionScope,
|
|
59
|
+
recovery_list: list[bytes32] = [],
|
|
60
|
+
metadata: dict[str, str] = {},
|
|
61
|
+
fee: uint64 = uint64(0),
|
|
62
|
+
use_alternate_recovery: bool = False,
|
|
63
|
+
) -> DIDWallet:
|
|
64
|
+
def alt_create_innerpuz(
|
|
65
|
+
p2_puzzle_or_hash: Union[Program, bytes32],
|
|
66
|
+
recovery_list: list[bytes32],
|
|
67
|
+
num_of_backup_ids_needed: uint64,
|
|
68
|
+
launcher_id: bytes32,
|
|
69
|
+
metadata: Program = Program.to([]),
|
|
70
|
+
recovery_list_hash: Optional[Program] = None,
|
|
71
|
+
) -> Program:
|
|
72
|
+
# override the default of NIL_TREEHASH with NIL to match other wallet implementations
|
|
73
|
+
nil_recovery = Program.to(None)
|
|
74
|
+
singleton_struct = Program.to((SINGLETON_TOP_LAYER_MOD_HASH, (launcher_id, SINGLETON_LAUNCHER_PUZZLE_HASH)))
|
|
75
|
+
return DID_INNERPUZ_MOD.curry(p2_puzzle_or_hash, nil_recovery, 0, singleton_struct, metadata)
|
|
76
|
+
|
|
77
|
+
if use_alternate_recovery:
|
|
78
|
+
with pytest.MonkeyPatch.context() as m:
|
|
79
|
+
m.setattr("chia.wallet.did_wallet.did_wallet_puzzles.create_innerpuz", alt_create_innerpuz)
|
|
80
|
+
did_wallet = await DIDWallet.create_new_did_wallet(
|
|
81
|
+
wallet_state_manager, wallet, uint64(101), action_scope, metadata=metadata, fee=fee
|
|
82
|
+
)
|
|
83
|
+
else:
|
|
84
|
+
did_wallet = await DIDWallet.create_new_did_wallet(
|
|
85
|
+
wallet_state_manager, wallet, amount, action_scope, backups_ids=recovery_list, metadata=metadata, fee=fee
|
|
86
|
+
)
|
|
82
87
|
|
|
83
|
-
|
|
84
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
85
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
86
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
87
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
88
|
+
return did_wallet
|
|
88
89
|
|
|
89
|
-
await full_node_api.farm_blocks_to_wallet(1, wallet_0)
|
|
90
|
-
await full_node_api.farm_blocks_to_wallet(1, wallet_1)
|
|
91
90
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
# TODO: See Issue CHIA-1544
|
|
92
|
+
# This test should be ported to WalletTestFramework once we can replace keys in the wallet node
|
|
93
|
+
@pytest.mark.parametrize(
|
|
94
|
+
"trusted",
|
|
95
|
+
[True, False],
|
|
96
|
+
)
|
|
97
|
+
@pytest.mark.parametrize(
|
|
98
|
+
"use_alternate_recovery",
|
|
99
|
+
[True, False],
|
|
100
|
+
)
|
|
101
|
+
@pytest.mark.anyio
|
|
102
|
+
async def test_creation_from_coin_spend(
|
|
103
|
+
self_hostname: str,
|
|
104
|
+
two_nodes_two_wallets_with_same_keys: OldSimulatorsAndWallets,
|
|
105
|
+
trusted: bool,
|
|
106
|
+
use_alternate_recovery: bool,
|
|
107
|
+
) -> None:
|
|
108
|
+
"""
|
|
109
|
+
Verify that DIDWallet.create_new_did_wallet_from_coin_spend() is called after Singleton creation on
|
|
110
|
+
the blockchain, and that the wallet is created in the second wallet node.
|
|
111
|
+
"""
|
|
112
|
+
full_nodes, wallets, _ = two_nodes_two_wallets_with_same_keys
|
|
113
|
+
full_node_api = full_nodes[0]
|
|
114
|
+
full_node_server = full_node_api.server
|
|
115
|
+
wallet_node_0, server_0 = wallets[0]
|
|
116
|
+
wallet_node_1, server_1 = wallets[1]
|
|
117
|
+
|
|
118
|
+
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
119
|
+
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
120
|
+
|
|
121
|
+
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
122
|
+
ph0 = await action_scope.get_puzzle_hash(wallet_0.wallet_state_manager)
|
|
123
|
+
async with wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
124
|
+
ph1 = await action_scope.get_puzzle_hash(wallet_1.wallet_state_manager)
|
|
125
|
+
|
|
126
|
+
sk0 = await wallet_node_0.wallet_state_manager.get_private_key(ph0)
|
|
127
|
+
sk1 = await wallet_node_1.wallet_state_manager.get_private_key(ph1)
|
|
128
|
+
assert sk0 == sk1
|
|
129
|
+
|
|
130
|
+
if trusted:
|
|
131
|
+
wallet_node_0.config["trusted_peers"] = {
|
|
132
|
+
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
133
|
+
}
|
|
134
|
+
wallet_node_1.config["trusted_peers"] = {
|
|
135
|
+
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
136
|
+
}
|
|
97
137
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
138
|
+
else:
|
|
139
|
+
wallet_node_0.config["trusted_peers"] = {}
|
|
140
|
+
wallet_node_1.config["trusted_peers"] = {}
|
|
141
|
+
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
142
|
+
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
143
|
+
|
|
144
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet_0)
|
|
145
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet_1)
|
|
146
|
+
|
|
147
|
+
# Wallet1 sets up DIDWallet1 without any backup set
|
|
148
|
+
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
149
|
+
did_wallet_0: DIDWallet = await make_did_wallet(
|
|
150
|
+
wallet_node_0.wallet_state_manager,
|
|
151
|
+
wallet_0,
|
|
152
|
+
uint64(101),
|
|
153
|
+
action_scope,
|
|
154
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
155
|
+
)
|
|
101
156
|
|
|
102
|
-
|
|
103
|
-
await
|
|
157
|
+
with pytest.raises(RuntimeError):
|
|
158
|
+
assert await did_wallet_0.get_coin() == set()
|
|
159
|
+
assert await did_wallet_0.get_info_for_recovery() is None
|
|
104
160
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
await time_out_assert(15, did_wallet_0.get_pending_change_balance, 0)
|
|
161
|
+
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
162
|
+
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1])
|
|
108
163
|
|
|
109
|
-
|
|
164
|
+
await time_out_assert(15, did_wallet_0.get_confirmed_balance, 101)
|
|
165
|
+
await time_out_assert(15, did_wallet_0.get_unconfirmed_balance, 101)
|
|
166
|
+
await time_out_assert(15, did_wallet_0.get_pending_change_balance, 0)
|
|
110
167
|
|
|
111
|
-
|
|
112
|
-
all_node_0_wallets = await wallet_node_0.wallet_state_manager.user_store.get_all_wallet_info_entries()
|
|
113
|
-
all_node_1_wallets = await wallet_node_1.wallet_state_manager.user_store.get_all_wallet_info_entries()
|
|
114
|
-
assert (
|
|
115
|
-
json.loads(all_node_0_wallets[1].data)["current_inner"]
|
|
116
|
-
== json.loads(all_node_1_wallets[1].data)["current_inner"]
|
|
117
|
-
)
|
|
168
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet_0)
|
|
118
169
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
"blocks_needed": [1, 1, 1],
|
|
126
|
-
}
|
|
127
|
-
],
|
|
128
|
-
indirect=True,
|
|
170
|
+
#######################
|
|
171
|
+
all_node_0_wallets = await wallet_node_0.wallet_state_manager.user_store.get_all_wallet_info_entries()
|
|
172
|
+
all_node_1_wallets = await wallet_node_1.wallet_state_manager.user_store.get_all_wallet_info_entries()
|
|
173
|
+
assert (
|
|
174
|
+
json.loads(all_node_0_wallets[1].data)["current_inner"]
|
|
175
|
+
== json.loads(all_node_1_wallets[1].data)["current_inner"]
|
|
129
176
|
)
|
|
130
|
-
@pytest.mark.anyio
|
|
131
|
-
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
132
|
-
async def test_creation_from_backup_file(self, wallet_environments: WalletTestFramework) -> None:
|
|
133
|
-
env_0 = wallet_environments.environments[0]
|
|
134
|
-
env_1 = wallet_environments.environments[1]
|
|
135
|
-
env_2 = wallet_environments.environments[2]
|
|
136
|
-
|
|
137
|
-
env_0.wallet_aliases = {
|
|
138
|
-
"xch": 1,
|
|
139
|
-
"did": 2,
|
|
140
|
-
}
|
|
141
|
-
env_1.wallet_aliases = {
|
|
142
|
-
"xch": 1,
|
|
143
|
-
"did": 2,
|
|
144
|
-
}
|
|
145
|
-
env_2.wallet_aliases = {
|
|
146
|
-
"xch": 1,
|
|
147
|
-
"did": 2,
|
|
148
|
-
}
|
|
149
177
|
|
|
150
|
-
# Wallet1 sets up DIDWallet1 without any backup set
|
|
151
|
-
async with env_0.wallet_state_manager.new_action_scope(
|
|
152
|
-
wallet_environments.tx_config, push=True
|
|
153
|
-
) as action_scope:
|
|
154
|
-
did_wallet_0: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
155
|
-
env_0.wallet_state_manager, env_0.xch_wallet, uint64(101), action_scope
|
|
156
|
-
)
|
|
157
178
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
179
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
180
|
+
@pytest.mark.parametrize(
|
|
181
|
+
"wallet_environments",
|
|
182
|
+
[
|
|
183
|
+
{
|
|
184
|
+
"num_environments": 3,
|
|
185
|
+
"blocks_needed": [1, 1, 1],
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
indirect=True,
|
|
189
|
+
)
|
|
190
|
+
@pytest.mark.parametrize(
|
|
191
|
+
"use_alternate_recovery",
|
|
192
|
+
[True, False],
|
|
193
|
+
)
|
|
194
|
+
@pytest.mark.anyio
|
|
195
|
+
@pytest.mark.limit_consensus_modes(reason="irrelevant")
|
|
196
|
+
async def test_creation_from_backup_file(
|
|
197
|
+
wallet_environments: WalletTestFramework, use_alternate_recovery: bool
|
|
198
|
+
) -> None:
|
|
199
|
+
env_0 = wallet_environments.environments[0]
|
|
200
|
+
env_1 = wallet_environments.environments[1]
|
|
201
|
+
env_2 = wallet_environments.environments[2]
|
|
202
|
+
|
|
203
|
+
env_0.wallet_aliases = {
|
|
204
|
+
"xch": 1,
|
|
205
|
+
"did": 2,
|
|
206
|
+
}
|
|
207
|
+
env_1.wallet_aliases = {
|
|
208
|
+
"xch": 1,
|
|
209
|
+
"did": 2,
|
|
210
|
+
}
|
|
211
|
+
env_2.wallet_aliases = {
|
|
212
|
+
"xch": 1,
|
|
213
|
+
"did": 2,
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
# Wallet1 sets up DIDWallet1 without any backup set
|
|
217
|
+
async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
218
|
+
did_wallet_0: DIDWallet = await make_did_wallet(
|
|
219
|
+
env_0.wallet_state_manager,
|
|
220
|
+
env_0.xch_wallet,
|
|
221
|
+
uint64(101),
|
|
222
|
+
action_scope,
|
|
223
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
203
224
|
)
|
|
204
225
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
WalletStateTransition(
|
|
222
|
-
pre_block_balance_updates={
|
|
223
|
-
"xch": {
|
|
224
|
-
"unconfirmed_wallet_balance": -201,
|
|
225
|
-
"<=#spendable_balance": -201,
|
|
226
|
-
"<=#max_send_amount": -201,
|
|
227
|
-
">=#pending_change": 1,
|
|
228
|
-
"pending_coin_removal_count": 1,
|
|
229
|
-
},
|
|
230
|
-
"did": {
|
|
231
|
-
"init": True,
|
|
232
|
-
"unconfirmed_wallet_balance": 201,
|
|
233
|
-
"pending_change": 201,
|
|
234
|
-
"pending_coin_removal_count": 1,
|
|
235
|
-
},
|
|
226
|
+
await wallet_environments.process_pending_states(
|
|
227
|
+
[
|
|
228
|
+
WalletStateTransition(
|
|
229
|
+
pre_block_balance_updates={
|
|
230
|
+
"xch": {
|
|
231
|
+
"unconfirmed_wallet_balance": -101,
|
|
232
|
+
"<=#spendable_balance": -101,
|
|
233
|
+
"<=#max_send_amount": -101,
|
|
234
|
+
">=#pending_change": 1,
|
|
235
|
+
"pending_coin_removal_count": 1,
|
|
236
|
+
},
|
|
237
|
+
"did": {
|
|
238
|
+
"init": True,
|
|
239
|
+
"unconfirmed_wallet_balance": 101,
|
|
240
|
+
"pending_change": 101,
|
|
241
|
+
"pending_coin_removal_count": 1,
|
|
236
242
|
},
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
243
|
+
},
|
|
244
|
+
post_block_balance_updates={
|
|
245
|
+
"xch": {
|
|
246
|
+
"confirmed_wallet_balance": -101,
|
|
247
|
+
">=#spendable_balance": 1,
|
|
248
|
+
">=#max_send_amount": 1,
|
|
249
|
+
"<=#pending_change": -1,
|
|
250
|
+
"pending_coin_removal_count": -1,
|
|
251
|
+
},
|
|
252
|
+
"did": {
|
|
253
|
+
"confirmed_wallet_balance": 101,
|
|
254
|
+
"spendable_balance": 101,
|
|
255
|
+
"max_send_amount": 101,
|
|
256
|
+
"unspent_coin_count": 1,
|
|
257
|
+
"pending_change": -101,
|
|
258
|
+
"pending_coin_removal_count": -1,
|
|
253
259
|
},
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
260
|
+
},
|
|
261
|
+
),
|
|
262
|
+
WalletStateTransition(
|
|
263
|
+
pre_block_balance_updates={},
|
|
264
|
+
post_block_balance_updates={},
|
|
265
|
+
),
|
|
266
|
+
WalletStateTransition(
|
|
267
|
+
pre_block_balance_updates={},
|
|
268
|
+
post_block_balance_updates={},
|
|
269
|
+
),
|
|
270
|
+
]
|
|
271
|
+
)
|
|
261
272
|
|
|
262
|
-
|
|
273
|
+
# Wallet1 sets up DIDWallet_1 with DIDWallet_0 as backup
|
|
274
|
+
backup_ids = [bytes32.from_hexstr(did_wallet_0.get_my_DID())]
|
|
263
275
|
|
|
264
|
-
|
|
265
|
-
await
|
|
266
|
-
uint64(
|
|
267
|
-
DEFAULT_TX_CONFIG,
|
|
268
|
-
type="recovery",
|
|
269
|
-
backup_data=backup_data,
|
|
276
|
+
async with env_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
277
|
+
did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
278
|
+
env_1.wallet_state_manager, env_1.xch_wallet, uint64(201), action_scope, backup_ids
|
|
270
279
|
)
|
|
271
|
-
did_wallet_2 = env_2.wallet_state_manager.get_wallet(id=uint32(2), required_type=DIDWallet)
|
|
272
|
-
recovery_info = await env_2.rpc_client.did_get_recovery_info(
|
|
273
|
-
DIDGetRecoveryInfo(uint32(env_2.wallet_aliases["did"]))
|
|
274
|
-
)
|
|
275
|
-
assert recovery_info.wallet_id == env_2.wallet_aliases["did"]
|
|
276
|
-
assert recovery_info.backup_dids == backup_ids
|
|
277
|
-
current_coin_info_response = await env_0.rpc_client.did_get_current_coin_info(
|
|
278
|
-
DIDGetCurrentCoinInfo(uint32(env_0.wallet_aliases["did"]))
|
|
279
|
-
)
|
|
280
|
-
# TODO: this check is kind of weak, we should research when this endpoint might actually be useful
|
|
281
|
-
assert current_coin_info_response.wallet_id == env_0.wallet_aliases["did"]
|
|
282
|
-
async with env_0.wallet_state_manager.new_action_scope(
|
|
283
|
-
wallet_environments.tx_config, push=True
|
|
284
|
-
) as action_scope:
|
|
285
|
-
message_spend_bundle, attest_data = await did_wallet_0.create_attestment(
|
|
286
|
-
recovery_info.coin_name, recovery_info.newpuzhash, recovery_info.pubkey, action_scope
|
|
287
|
-
)
|
|
288
280
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
"
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
281
|
+
await wallet_environments.process_pending_states(
|
|
282
|
+
[
|
|
283
|
+
WalletStateTransition(
|
|
284
|
+
pre_block_balance_updates={},
|
|
285
|
+
post_block_balance_updates={},
|
|
286
|
+
),
|
|
287
|
+
WalletStateTransition(
|
|
288
|
+
pre_block_balance_updates={
|
|
289
|
+
"xch": {
|
|
290
|
+
"unconfirmed_wallet_balance": -201,
|
|
291
|
+
"<=#spendable_balance": -201,
|
|
292
|
+
"<=#max_send_amount": -201,
|
|
293
|
+
">=#pending_change": 1,
|
|
294
|
+
"pending_coin_removal_count": 1,
|
|
295
|
+
},
|
|
296
|
+
"did": {
|
|
297
|
+
"init": True,
|
|
298
|
+
"unconfirmed_wallet_balance": 201,
|
|
299
|
+
"pending_change": 201,
|
|
300
|
+
"pending_coin_removal_count": 1,
|
|
307
301
|
},
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
"
|
|
316
|
-
|
|
317
|
-
|
|
302
|
+
},
|
|
303
|
+
post_block_balance_updates={
|
|
304
|
+
"xch": {
|
|
305
|
+
"confirmed_wallet_balance": -201,
|
|
306
|
+
">=#spendable_balance": 1,
|
|
307
|
+
">=#max_send_amount": 1,
|
|
308
|
+
"<=#pending_change": -1,
|
|
309
|
+
"pending_coin_removal_count": -1,
|
|
310
|
+
},
|
|
311
|
+
"did": {
|
|
312
|
+
"confirmed_wallet_balance": 201,
|
|
313
|
+
"spendable_balance": 201,
|
|
314
|
+
"max_send_amount": 201,
|
|
315
|
+
"unspent_coin_count": 1,
|
|
316
|
+
"pending_change": -201,
|
|
317
|
+
"pending_coin_removal_count": -1,
|
|
318
318
|
},
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
319
|
+
},
|
|
320
|
+
),
|
|
321
|
+
WalletStateTransition(
|
|
322
|
+
pre_block_balance_updates={},
|
|
323
|
+
post_block_balance_updates={},
|
|
324
|
+
),
|
|
325
|
+
]
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
backup_data = did_wallet_1.create_backup()
|
|
329
|
+
|
|
330
|
+
# Wallet2 recovers DIDWallet2 to a new set of keys
|
|
331
|
+
await env_2.rpc_client.create_new_did_wallet(
|
|
332
|
+
uint64(1),
|
|
333
|
+
DEFAULT_TX_CONFIG,
|
|
334
|
+
type="recovery",
|
|
335
|
+
backup_data=backup_data,
|
|
336
|
+
)
|
|
337
|
+
did_wallet_2 = env_2.wallet_state_manager.get_wallet(id=uint32(2), required_type=DIDWallet)
|
|
338
|
+
recovery_info = await env_2.rpc_client.did_get_recovery_info(
|
|
339
|
+
DIDGetRecoveryInfo(uint32(env_2.wallet_aliases["did"]))
|
|
340
|
+
)
|
|
341
|
+
assert recovery_info.wallet_id == env_2.wallet_aliases["did"]
|
|
342
|
+
assert recovery_info.backup_dids == backup_ids
|
|
343
|
+
current_coin_info_response = await env_0.rpc_client.did_get_current_coin_info(
|
|
344
|
+
DIDGetCurrentCoinInfo(uint32(env_0.wallet_aliases["did"]))
|
|
345
|
+
)
|
|
346
|
+
# TODO: this check is kind of weak, we should research when this endpoint might actually be useful
|
|
347
|
+
assert current_coin_info_response.wallet_id == env_0.wallet_aliases["did"]
|
|
348
|
+
async with env_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
349
|
+
assert recovery_info.pubkey is not None
|
|
350
|
+
assert recovery_info.newpuzhash is not None
|
|
351
|
+
message_spend_bundle, attest_data = await did_wallet_0.create_attestment(
|
|
352
|
+
recovery_info.coin_name, recovery_info.newpuzhash, recovery_info.pubkey, action_scope
|
|
322
353
|
)
|
|
323
354
|
|
|
324
|
-
|
|
355
|
+
await wallet_environments.process_pending_states(
|
|
356
|
+
[
|
|
357
|
+
WalletStateTransition(
|
|
358
|
+
pre_block_balance_updates={
|
|
359
|
+
"did": {
|
|
360
|
+
"spendable_balance": -101,
|
|
361
|
+
"pending_change": 101,
|
|
362
|
+
"pending_coin_removal_count": 1,
|
|
363
|
+
"max_send_amount": -101,
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
post_block_balance_updates={
|
|
367
|
+
"did": {
|
|
368
|
+
"spendable_balance": 101,
|
|
369
|
+
"pending_change": -101,
|
|
370
|
+
"pending_coin_removal_count": -1,
|
|
371
|
+
"max_send_amount": 101,
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
),
|
|
375
|
+
WalletStateTransition(
|
|
376
|
+
pre_block_balance_updates={},
|
|
377
|
+
post_block_balance_updates={},
|
|
378
|
+
),
|
|
379
|
+
WalletStateTransition(
|
|
380
|
+
pre_block_balance_updates={
|
|
381
|
+
"did": {
|
|
382
|
+
"init": True,
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
post_block_balance_updates={},
|
|
386
|
+
),
|
|
387
|
+
]
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
(
|
|
391
|
+
test_info_list,
|
|
392
|
+
test_message_spend_bundle,
|
|
393
|
+
) = await did_wallet_2.load_attest_files_for_recovery_spend([attest_data])
|
|
394
|
+
assert message_spend_bundle == test_message_spend_bundle
|
|
395
|
+
|
|
396
|
+
async with env_2.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
397
|
+
assert did_wallet_2.did_info.temp_coin is not None
|
|
398
|
+
await did_wallet_2.recovery_spend(
|
|
399
|
+
did_wallet_2.did_info.temp_coin,
|
|
400
|
+
recovery_info.newpuzhash,
|
|
325
401
|
test_info_list,
|
|
402
|
+
recovery_info.pubkey,
|
|
326
403
|
test_message_spend_bundle,
|
|
327
|
-
|
|
328
|
-
|
|
404
|
+
action_scope,
|
|
405
|
+
)
|
|
329
406
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
407
|
+
await wallet_environments.process_pending_states(
|
|
408
|
+
[
|
|
409
|
+
WalletStateTransition(
|
|
410
|
+
pre_block_balance_updates={},
|
|
411
|
+
post_block_balance_updates={},
|
|
412
|
+
),
|
|
413
|
+
WalletStateTransition(
|
|
414
|
+
pre_block_balance_updates={},
|
|
415
|
+
post_block_balance_updates={
|
|
416
|
+
"did": {
|
|
417
|
+
"confirmed_wallet_balance": -201,
|
|
418
|
+
"unconfirmed_wallet_balance": -201,
|
|
419
|
+
"spendable_balance": -201,
|
|
420
|
+
"max_send_amount": -201,
|
|
421
|
+
"unspent_coin_count": -1,
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
),
|
|
425
|
+
WalletStateTransition(
|
|
426
|
+
pre_block_balance_updates={
|
|
427
|
+
"did": {
|
|
428
|
+
"unconfirmed_wallet_balance": 201,
|
|
429
|
+
"pending_coin_removal_count": 2,
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
post_block_balance_updates={
|
|
433
|
+
"did": {
|
|
434
|
+
"confirmed_wallet_balance": 201,
|
|
435
|
+
"spendable_balance": 201,
|
|
436
|
+
"max_send_amount": 201,
|
|
437
|
+
"unspent_coin_count": 1,
|
|
438
|
+
"pending_coin_removal_count": -2,
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
),
|
|
442
|
+
]
|
|
443
|
+
)
|
|
342
444
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
WalletStateTransition(
|
|
346
|
-
pre_block_balance_updates={},
|
|
347
|
-
post_block_balance_updates={},
|
|
348
|
-
),
|
|
349
|
-
WalletStateTransition(
|
|
350
|
-
pre_block_balance_updates={},
|
|
351
|
-
post_block_balance_updates={
|
|
352
|
-
"did": {
|
|
353
|
-
"confirmed_wallet_balance": -201,
|
|
354
|
-
"unconfirmed_wallet_balance": -201,
|
|
355
|
-
"spendable_balance": -201,
|
|
356
|
-
"max_send_amount": -201,
|
|
357
|
-
"unspent_coin_count": -1,
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
),
|
|
361
|
-
WalletStateTransition(
|
|
362
|
-
pre_block_balance_updates={
|
|
363
|
-
"did": {
|
|
364
|
-
"unconfirmed_wallet_balance": 201,
|
|
365
|
-
"pending_coin_removal_count": 2,
|
|
366
|
-
}
|
|
367
|
-
},
|
|
368
|
-
post_block_balance_updates={
|
|
369
|
-
"did": {
|
|
370
|
-
"confirmed_wallet_balance": 201,
|
|
371
|
-
"spendable_balance": 201,
|
|
372
|
-
"max_send_amount": 201,
|
|
373
|
-
"unspent_coin_count": 1,
|
|
374
|
-
"pending_coin_removal_count": -2,
|
|
375
|
-
}
|
|
376
|
-
},
|
|
377
|
-
),
|
|
378
|
-
]
|
|
379
|
-
)
|
|
445
|
+
for wallet in [did_wallet_0, did_wallet_1, did_wallet_2]:
|
|
446
|
+
assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
|
|
380
447
|
|
|
381
|
-
|
|
382
|
-
|
|
448
|
+
some_ph = bytes32(32 * b"\2")
|
|
449
|
+
async with env_2.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
450
|
+
await did_wallet_2.create_exit_spend(some_ph, action_scope)
|
|
383
451
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
452
|
+
await wallet_environments.process_pending_states(
|
|
453
|
+
[
|
|
454
|
+
WalletStateTransition(
|
|
455
|
+
pre_block_balance_updates={},
|
|
456
|
+
post_block_balance_updates={},
|
|
457
|
+
),
|
|
458
|
+
WalletStateTransition(
|
|
459
|
+
pre_block_balance_updates={},
|
|
460
|
+
post_block_balance_updates={},
|
|
461
|
+
),
|
|
462
|
+
WalletStateTransition(
|
|
463
|
+
pre_block_balance_updates={
|
|
464
|
+
"did": {
|
|
465
|
+
"unconfirmed_wallet_balance": -201,
|
|
466
|
+
"spendable_balance": -201,
|
|
467
|
+
"max_send_amount": -201,
|
|
468
|
+
"pending_coin_removal_count": 1,
|
|
469
|
+
}
|
|
470
|
+
},
|
|
471
|
+
post_block_balance_updates={
|
|
472
|
+
"did": {
|
|
473
|
+
"confirmed_wallet_balance": -201,
|
|
474
|
+
"unspent_coin_count": -1,
|
|
475
|
+
"pending_coin_removal_count": -1,
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
),
|
|
479
|
+
]
|
|
480
|
+
)
|
|
389
481
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
pre_block_balance_updates={},
|
|
394
|
-
post_block_balance_updates={},
|
|
395
|
-
),
|
|
396
|
-
WalletStateTransition(
|
|
397
|
-
pre_block_balance_updates={},
|
|
398
|
-
post_block_balance_updates={},
|
|
399
|
-
),
|
|
400
|
-
WalletStateTransition(
|
|
401
|
-
pre_block_balance_updates={
|
|
402
|
-
"did": {
|
|
403
|
-
"unconfirmed_wallet_balance": -201,
|
|
404
|
-
"spendable_balance": -201,
|
|
405
|
-
"max_send_amount": -201,
|
|
406
|
-
"pending_coin_removal_count": 1,
|
|
407
|
-
}
|
|
408
|
-
},
|
|
409
|
-
post_block_balance_updates={
|
|
410
|
-
"did": {
|
|
411
|
-
"confirmed_wallet_balance": -201,
|
|
412
|
-
"unspent_coin_count": -1,
|
|
413
|
-
"pending_coin_removal_count": -1,
|
|
414
|
-
}
|
|
415
|
-
},
|
|
416
|
-
),
|
|
417
|
-
]
|
|
418
|
-
)
|
|
482
|
+
async def get_coins_with_ph() -> bool:
|
|
483
|
+
coins = await wallet_environments.full_node.full_node.coin_store.get_coin_records_by_puzzle_hash(True, some_ph)
|
|
484
|
+
return len(coins) == 1
|
|
419
485
|
|
|
420
|
-
|
|
421
|
-
coins = await wallet_environments.full_node.full_node.coin_store.get_coin_records_by_puzzle_hash(
|
|
422
|
-
True, some_ph
|
|
423
|
-
)
|
|
424
|
-
return len(coins) == 1
|
|
425
|
-
|
|
426
|
-
await time_out_assert(15, get_coins_with_ph, True)
|
|
427
|
-
|
|
428
|
-
for wallet in [did_wallet_0, did_wallet_1]:
|
|
429
|
-
assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
|
|
430
|
-
|
|
431
|
-
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
432
|
-
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
433
|
-
@pytest.mark.anyio
|
|
434
|
-
async def test_did_recovery_with_multiple_backup_dids(self, wallet_environments: WalletTestFramework):
|
|
435
|
-
env_0 = wallet_environments.environments[0]
|
|
436
|
-
env_1 = wallet_environments.environments[1]
|
|
437
|
-
wallet_node_0 = env_0.node
|
|
438
|
-
wallet_node_1 = env_1.node
|
|
439
|
-
wallet_0 = env_0.xch_wallet
|
|
440
|
-
wallet_1 = env_1.xch_wallet
|
|
441
|
-
|
|
442
|
-
env_0.wallet_aliases = {
|
|
443
|
-
"xch": 1,
|
|
444
|
-
"did": 2,
|
|
445
|
-
}
|
|
446
|
-
env_1.wallet_aliases = {
|
|
447
|
-
"xch": 1,
|
|
448
|
-
"did": 2,
|
|
449
|
-
}
|
|
486
|
+
await time_out_assert(15, get_coins_with_ph, True)
|
|
450
487
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
) as action_scope:
|
|
454
|
-
did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
455
|
-
wallet_node_0.wallet_state_manager, wallet_0, uint64(101), action_scope
|
|
456
|
-
)
|
|
457
|
-
assert did_wallet.get_name() == "Profile 1"
|
|
458
|
-
recovery_list = [bytes32.from_hexstr(did_wallet.get_my_DID())]
|
|
488
|
+
for wallet in [did_wallet_0, did_wallet_1]:
|
|
489
|
+
assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
|
|
459
490
|
|
|
460
|
-
async with wallet_1.wallet_state_manager.new_action_scope(
|
|
461
|
-
wallet_environments.tx_config, push=True
|
|
462
|
-
) as action_scope:
|
|
463
|
-
did_wallet_2: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
464
|
-
wallet_node_1.wallet_state_manager, wallet_1, uint64(101), action_scope, recovery_list
|
|
465
|
-
)
|
|
466
491
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
492
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
493
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
494
|
+
@pytest.mark.parametrize(
|
|
495
|
+
"use_alternate_recovery",
|
|
496
|
+
[True, False],
|
|
497
|
+
)
|
|
498
|
+
@pytest.mark.anyio
|
|
499
|
+
async def test_did_recovery_with_multiple_backup_dids(
|
|
500
|
+
wallet_environments: WalletTestFramework, use_alternate_recovery: bool
|
|
501
|
+
) -> None:
|
|
502
|
+
env_0 = wallet_environments.environments[0]
|
|
503
|
+
env_1 = wallet_environments.environments[1]
|
|
504
|
+
wallet_node_0 = env_0.node
|
|
505
|
+
wallet_node_1 = env_1.node
|
|
506
|
+
wallet_0 = env_0.xch_wallet
|
|
507
|
+
wallet_1 = env_1.xch_wallet
|
|
508
|
+
|
|
509
|
+
env_0.wallet_aliases = {
|
|
510
|
+
"xch": 1,
|
|
511
|
+
"did": 2,
|
|
512
|
+
}
|
|
513
|
+
env_1.wallet_aliases = {
|
|
514
|
+
"xch": 1,
|
|
515
|
+
"did": 2,
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
519
|
+
did_wallet: DIDWallet = await make_did_wallet(
|
|
520
|
+
wallet_node_0.wallet_state_manager,
|
|
521
|
+
wallet_0,
|
|
522
|
+
uint64(101),
|
|
523
|
+
action_scope,
|
|
524
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
525
|
+
)
|
|
526
|
+
assert did_wallet.get_name() == "Profile 1"
|
|
527
|
+
recovery_list = [bytes32.from_hexstr(did_wallet.get_my_DID())]
|
|
528
|
+
|
|
529
|
+
async with wallet_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
530
|
+
did_wallet_2: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
531
|
+
wallet_node_1.wallet_state_manager, wallet_1, uint64(101), action_scope, recovery_list
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
await wallet_environments.process_pending_states(
|
|
535
|
+
[
|
|
536
|
+
WalletStateTransition(
|
|
537
|
+
pre_block_balance_updates={
|
|
538
|
+
"xch": {
|
|
539
|
+
"set_remainder": True,
|
|
480
540
|
},
|
|
481
|
-
|
|
482
|
-
"
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
"
|
|
486
|
-
"confirmed_wallet_balance": 101,
|
|
487
|
-
"spendable_balance": 101,
|
|
488
|
-
"max_send_amount": 101,
|
|
489
|
-
"unspent_coin_count": 1,
|
|
490
|
-
"pending_change": -101,
|
|
491
|
-
"pending_coin_removal_count": -1,
|
|
492
|
-
},
|
|
541
|
+
"did": {
|
|
542
|
+
"init": True,
|
|
543
|
+
"unconfirmed_wallet_balance": 101,
|
|
544
|
+
"pending_change": 101,
|
|
545
|
+
"pending_coin_removal_count": 1,
|
|
493
546
|
},
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
"
|
|
498
|
-
"set_remainder": True,
|
|
499
|
-
},
|
|
500
|
-
"did": {
|
|
501
|
-
"init": True,
|
|
502
|
-
"unconfirmed_wallet_balance": 101,
|
|
503
|
-
"pending_change": 101,
|
|
504
|
-
"pending_coin_removal_count": 1,
|
|
505
|
-
},
|
|
547
|
+
},
|
|
548
|
+
post_block_balance_updates={
|
|
549
|
+
"xch": {
|
|
550
|
+
"set_remainder": True,
|
|
506
551
|
},
|
|
507
|
-
|
|
508
|
-
"
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
"
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
"max_send_amount": 101,
|
|
515
|
-
"unspent_coin_count": 1,
|
|
516
|
-
"pending_change": -101,
|
|
517
|
-
"pending_coin_removal_count": -1,
|
|
518
|
-
},
|
|
552
|
+
"did": {
|
|
553
|
+
"confirmed_wallet_balance": 101,
|
|
554
|
+
"spendable_balance": 101,
|
|
555
|
+
"max_send_amount": 101,
|
|
556
|
+
"unspent_coin_count": 1,
|
|
557
|
+
"pending_change": -101,
|
|
558
|
+
"pending_coin_removal_count": -1,
|
|
519
559
|
},
|
|
520
|
-
|
|
521
|
-
|
|
560
|
+
},
|
|
561
|
+
),
|
|
562
|
+
WalletStateTransition(
|
|
563
|
+
pre_block_balance_updates={
|
|
564
|
+
"xch": {
|
|
565
|
+
"set_remainder": True,
|
|
566
|
+
},
|
|
567
|
+
"did": {
|
|
568
|
+
"init": True,
|
|
569
|
+
"unconfirmed_wallet_balance": 101,
|
|
570
|
+
"pending_change": 101,
|
|
571
|
+
"pending_coin_removal_count": 1,
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
post_block_balance_updates={
|
|
575
|
+
"xch": {
|
|
576
|
+
"set_remainder": True,
|
|
577
|
+
},
|
|
578
|
+
"did": {
|
|
579
|
+
"confirmed_wallet_balance": 101,
|
|
580
|
+
"spendable_balance": 101,
|
|
581
|
+
"max_send_amount": 101,
|
|
582
|
+
"unspent_coin_count": 1,
|
|
583
|
+
"pending_change": -101,
|
|
584
|
+
"pending_coin_removal_count": -1,
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
),
|
|
588
|
+
]
|
|
589
|
+
)
|
|
590
|
+
assert did_wallet_2.did_info.backup_ids == recovery_list
|
|
591
|
+
|
|
592
|
+
recovery_list.append(bytes32.from_hexstr(did_wallet_2.get_my_DID()))
|
|
593
|
+
|
|
594
|
+
async with wallet_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
595
|
+
did_wallet_3: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
596
|
+
wallet_node_1.wallet_state_manager, wallet_1, uint64(201), action_scope, recovery_list
|
|
522
597
|
)
|
|
523
|
-
assert did_wallet_2.did_info.backup_ids == recovery_list
|
|
524
598
|
|
|
525
|
-
|
|
599
|
+
env_1.wallet_aliases["did_2"] = 3
|
|
526
600
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
)
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
[
|
|
538
|
-
WalletStateTransition(
|
|
539
|
-
pre_block_balance_updates={},
|
|
540
|
-
post_block_balance_updates={},
|
|
541
|
-
),
|
|
542
|
-
WalletStateTransition(
|
|
543
|
-
pre_block_balance_updates={
|
|
544
|
-
"xch": {
|
|
545
|
-
"set_remainder": True,
|
|
546
|
-
},
|
|
547
|
-
"did": {
|
|
548
|
-
"set_remainder": True,
|
|
549
|
-
},
|
|
550
|
-
"did_2": {
|
|
551
|
-
"init": True,
|
|
552
|
-
"unconfirmed_wallet_balance": 201,
|
|
553
|
-
"pending_change": 201,
|
|
554
|
-
"pending_coin_removal_count": 1,
|
|
555
|
-
},
|
|
601
|
+
await wallet_environments.process_pending_states(
|
|
602
|
+
[
|
|
603
|
+
WalletStateTransition(
|
|
604
|
+
pre_block_balance_updates={},
|
|
605
|
+
post_block_balance_updates={},
|
|
606
|
+
),
|
|
607
|
+
WalletStateTransition(
|
|
608
|
+
pre_block_balance_updates={
|
|
609
|
+
"xch": {
|
|
610
|
+
"set_remainder": True,
|
|
556
611
|
},
|
|
557
|
-
|
|
558
|
-
"
|
|
559
|
-
"set_remainder": True,
|
|
560
|
-
},
|
|
561
|
-
"did": {
|
|
562
|
-
"set_remainder": True,
|
|
563
|
-
},
|
|
564
|
-
"did_2": {
|
|
565
|
-
"confirmed_wallet_balance": 201,
|
|
566
|
-
"spendable_balance": 201,
|
|
567
|
-
"max_send_amount": 201,
|
|
568
|
-
"unspent_coin_count": 1,
|
|
569
|
-
"pending_change": -201,
|
|
570
|
-
"pending_coin_removal_count": -1,
|
|
571
|
-
},
|
|
612
|
+
"did": {
|
|
613
|
+
"set_remainder": True,
|
|
572
614
|
},
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
615
|
+
"did_2": {
|
|
616
|
+
"init": True,
|
|
617
|
+
"unconfirmed_wallet_balance": 201,
|
|
618
|
+
"pending_change": 201,
|
|
619
|
+
"pending_coin_removal_count": 1,
|
|
620
|
+
},
|
|
621
|
+
},
|
|
622
|
+
post_block_balance_updates={
|
|
623
|
+
"xch": {
|
|
624
|
+
"set_remainder": True,
|
|
625
|
+
},
|
|
626
|
+
"did": {
|
|
627
|
+
"set_remainder": True,
|
|
628
|
+
},
|
|
629
|
+
"did_2": {
|
|
630
|
+
"confirmed_wallet_balance": 201,
|
|
631
|
+
"spendable_balance": 201,
|
|
632
|
+
"max_send_amount": 201,
|
|
633
|
+
"unspent_coin_count": 1,
|
|
634
|
+
"pending_change": -201,
|
|
635
|
+
"pending_coin_removal_count": -1,
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
),
|
|
639
|
+
]
|
|
640
|
+
)
|
|
641
|
+
coin = await did_wallet_3.get_coin()
|
|
579
642
|
|
|
580
|
-
|
|
581
|
-
did_wallet_4 = await DIDWallet.create_new_did_wallet_from_recovery(
|
|
582
|
-
wallet_node_0.wallet_state_manager,
|
|
583
|
-
wallet_0,
|
|
584
|
-
backup_data,
|
|
585
|
-
)
|
|
586
|
-
assert did_wallet_4.get_name() == "Profile 2"
|
|
587
|
-
env_0.wallet_aliases["did_2"] = 3
|
|
643
|
+
backup_data = did_wallet_3.create_backup()
|
|
588
644
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
645
|
+
async with wallet_node_0.wallet_state_manager.lock:
|
|
646
|
+
did_wallet_4 = await DIDWallet.create_new_did_wallet_from_recovery(
|
|
647
|
+
wallet_node_0.wallet_state_manager,
|
|
648
|
+
wallet_0,
|
|
649
|
+
backup_data,
|
|
650
|
+
)
|
|
651
|
+
assert did_wallet_4.get_name() == "Profile 2"
|
|
652
|
+
env_0.wallet_aliases["did_2"] = 3
|
|
653
|
+
|
|
654
|
+
pubkey = (await did_wallet_4.wallet_state_manager.get_unused_derivation_record(did_wallet_2.wallet_info.id)).pubkey
|
|
655
|
+
new_ph = did_wallet_4.did_info.temp_puzhash
|
|
656
|
+
async with did_wallet.wallet_state_manager.new_action_scope(
|
|
657
|
+
wallet_environments.tx_config, push=True
|
|
658
|
+
) as action_scope:
|
|
659
|
+
message_spend_bundle, attest1 = await did_wallet.create_attestment(coin.name(), new_ph, pubkey, action_scope)
|
|
660
|
+
|
|
661
|
+
async with did_wallet_2.wallet_state_manager.new_action_scope(
|
|
662
|
+
wallet_environments.tx_config, push=True
|
|
663
|
+
) as action_scope_2:
|
|
664
|
+
message_spend_bundle2, attest2 = await did_wallet_2.create_attestment(
|
|
665
|
+
coin.name(), new_ph, pubkey, action_scope_2
|
|
666
|
+
)
|
|
599
667
|
|
|
600
|
-
|
|
601
|
-
wallet_environments.tx_config, push=True
|
|
602
|
-
) as action_scope_2:
|
|
603
|
-
message_spend_bundle2, attest2 = await did_wallet_2.create_attestment(
|
|
604
|
-
coin.name(), new_ph, pubkey, action_scope_2
|
|
605
|
-
)
|
|
668
|
+
message_spend_bundle = message_spend_bundle.aggregate([message_spend_bundle, message_spend_bundle2])
|
|
606
669
|
|
|
607
|
-
|
|
670
|
+
(
|
|
671
|
+
test_info_list,
|
|
672
|
+
test_message_spend_bundle,
|
|
673
|
+
) = await did_wallet_4.load_attest_files_for_recovery_spend([attest1, attest2])
|
|
674
|
+
assert message_spend_bundle == test_message_spend_bundle
|
|
608
675
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
},
|
|
626
|
-
"did_2": {
|
|
627
|
-
"init": True,
|
|
628
|
-
"unconfirmed_wallet_balance": 0,
|
|
629
|
-
"pending_change": 0,
|
|
630
|
-
"pending_coin_removal_count": 0,
|
|
631
|
-
},
|
|
676
|
+
await wallet_environments.process_pending_states(
|
|
677
|
+
[
|
|
678
|
+
WalletStateTransition(
|
|
679
|
+
pre_block_balance_updates={
|
|
680
|
+
"did": {
|
|
681
|
+
"spendable_balance": -101,
|
|
682
|
+
"pending_change": 101,
|
|
683
|
+
"max_send_amount": -101,
|
|
684
|
+
"pending_coin_removal_count": 1,
|
|
685
|
+
"set_remainder": True,
|
|
686
|
+
},
|
|
687
|
+
"did_2": {
|
|
688
|
+
"init": True,
|
|
689
|
+
"unconfirmed_wallet_balance": 0,
|
|
690
|
+
"pending_change": 0,
|
|
691
|
+
"pending_coin_removal_count": 0,
|
|
632
692
|
},
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
693
|
+
},
|
|
694
|
+
post_block_balance_updates={
|
|
695
|
+
"did": {
|
|
696
|
+
"spendable_balance": 101,
|
|
697
|
+
"pending_change": -101,
|
|
698
|
+
"max_send_amount": 101,
|
|
699
|
+
"pending_coin_removal_count": -1,
|
|
700
|
+
},
|
|
701
|
+
"did_2": {
|
|
702
|
+
"confirmed_wallet_balance": 0,
|
|
703
|
+
"spendable_balance": 0,
|
|
704
|
+
"max_send_amount": 0,
|
|
705
|
+
"unspent_coin_count": 0,
|
|
706
|
+
"pending_change": 0,
|
|
707
|
+
"pending_coin_removal_count": 0,
|
|
648
708
|
},
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
709
|
+
},
|
|
710
|
+
),
|
|
711
|
+
WalletStateTransition(
|
|
712
|
+
pre_block_balance_updates={
|
|
713
|
+
"did": {
|
|
714
|
+
"spendable_balance": -101,
|
|
715
|
+
"pending_change": 101,
|
|
716
|
+
"max_send_amount": -101,
|
|
717
|
+
"pending_coin_removal_count": 1,
|
|
718
|
+
"set_remainder": True,
|
|
659
719
|
},
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
720
|
+
},
|
|
721
|
+
post_block_balance_updates={
|
|
722
|
+
"did": {
|
|
723
|
+
"spendable_balance": 101,
|
|
724
|
+
"pending_change": -101,
|
|
725
|
+
"max_send_amount": 101,
|
|
726
|
+
"pending_coin_removal_count": -1,
|
|
667
727
|
},
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
728
|
+
},
|
|
729
|
+
),
|
|
730
|
+
]
|
|
731
|
+
)
|
|
671
732
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
733
|
+
async with did_wallet_4.wallet_state_manager.new_action_scope(
|
|
734
|
+
wallet_environments.tx_config, push=True
|
|
735
|
+
) as action_scope:
|
|
736
|
+
await did_wallet_4.recovery_spend(coin, new_ph, test_info_list, pubkey, message_spend_bundle, action_scope)
|
|
676
737
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
},
|
|
738
|
+
await wallet_environments.process_pending_states(
|
|
739
|
+
[
|
|
740
|
+
WalletStateTransition(
|
|
741
|
+
pre_block_balance_updates={
|
|
742
|
+
"did_2": {
|
|
743
|
+
"unconfirmed_wallet_balance": 201,
|
|
744
|
+
"pending_change": 0,
|
|
745
|
+
"pending_coin_removal_count": 3,
|
|
686
746
|
},
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
747
|
+
},
|
|
748
|
+
post_block_balance_updates={
|
|
749
|
+
"did_2": {
|
|
750
|
+
"confirmed_wallet_balance": 201,
|
|
751
|
+
"spendable_balance": 201,
|
|
752
|
+
"max_send_amount": 201,
|
|
753
|
+
"unspent_coin_count": 1,
|
|
754
|
+
"pending_change": 0,
|
|
755
|
+
"pending_coin_removal_count": -3,
|
|
696
756
|
},
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
757
|
+
},
|
|
758
|
+
),
|
|
759
|
+
WalletStateTransition(
|
|
760
|
+
pre_block_balance_updates={
|
|
761
|
+
"did_2": {
|
|
762
|
+
"unconfirmed_wallet_balance": 0, # TODO: fix pre-block balances for recovery
|
|
763
|
+
"spendable_balance": 0,
|
|
764
|
+
"pending_change": 0,
|
|
765
|
+
"max_send_amount": 0,
|
|
766
|
+
"pending_coin_removal_count": 0,
|
|
767
|
+
"set_remainder": True,
|
|
708
768
|
},
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
769
|
+
},
|
|
770
|
+
post_block_balance_updates={
|
|
771
|
+
"did_2": {
|
|
772
|
+
"confirmed_wallet_balance": -201,
|
|
773
|
+
"spendable_balance": -201,
|
|
774
|
+
"max_send_amount": -201,
|
|
775
|
+
"unspent_coin_count": -1,
|
|
776
|
+
"set_remainder": True,
|
|
717
777
|
},
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
for wallet in [did_wallet, did_wallet_2, did_wallet_3, did_wallet_4]:
|
|
723
|
-
assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
|
|
724
|
-
|
|
725
|
-
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
726
|
-
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
727
|
-
@pytest.mark.anyio
|
|
728
|
-
async def test_did_recovery_with_empty_set(self, wallet_environments: WalletTestFramework):
|
|
729
|
-
env_0 = wallet_environments.environments[0]
|
|
730
|
-
wallet_node_0 = env_0.node
|
|
731
|
-
wallet_0 = env_0.xch_wallet
|
|
778
|
+
},
|
|
779
|
+
),
|
|
780
|
+
]
|
|
781
|
+
)
|
|
732
782
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
"did": 2,
|
|
736
|
-
}
|
|
783
|
+
for wallet in [did_wallet, did_wallet_2, did_wallet_3, did_wallet_4]:
|
|
784
|
+
assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
|
|
737
785
|
|
|
738
|
-
ph = await wallet_0.get_new_puzzlehash()
|
|
739
786
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
787
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
788
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
789
|
+
@pytest.mark.parametrize(
|
|
790
|
+
"use_alternate_recovery",
|
|
791
|
+
[True, False],
|
|
792
|
+
)
|
|
793
|
+
@pytest.mark.anyio
|
|
794
|
+
async def test_did_recovery_with_empty_set(wallet_environments: WalletTestFramework, use_alternate_recovery: bool):
|
|
795
|
+
env_0 = wallet_environments.environments[0]
|
|
796
|
+
wallet_node_0 = env_0.node
|
|
797
|
+
wallet_0 = env_0.xch_wallet
|
|
798
|
+
|
|
799
|
+
env_0.wallet_aliases = {
|
|
800
|
+
"xch": 1,
|
|
801
|
+
"did": 2,
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
805
|
+
ph = await action_scope.get_puzzle_hash(wallet_0.wallet_state_manager)
|
|
806
|
+
|
|
807
|
+
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
808
|
+
did_wallet: DIDWallet = await make_did_wallet(
|
|
809
|
+
wallet_node_0.wallet_state_manager,
|
|
810
|
+
wallet_0,
|
|
811
|
+
uint64(101),
|
|
812
|
+
action_scope,
|
|
813
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
814
|
+
)
|
|
744
815
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
},
|
|
752
|
-
"did": {
|
|
753
|
-
"init": True,
|
|
754
|
-
"unconfirmed_wallet_balance": 101,
|
|
755
|
-
"pending_change": 101,
|
|
756
|
-
"pending_coin_removal_count": 1,
|
|
757
|
-
},
|
|
816
|
+
await wallet_environments.process_pending_states(
|
|
817
|
+
[
|
|
818
|
+
WalletStateTransition(
|
|
819
|
+
pre_block_balance_updates={
|
|
820
|
+
"xch": {
|
|
821
|
+
"set_remainder": True,
|
|
758
822
|
},
|
|
759
|
-
|
|
760
|
-
"
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
"
|
|
764
|
-
"confirmed_wallet_balance": 101,
|
|
765
|
-
"spendable_balance": 101,
|
|
766
|
-
"max_send_amount": 101,
|
|
767
|
-
"unspent_coin_count": 1,
|
|
768
|
-
"pending_change": -101,
|
|
769
|
-
"pending_coin_removal_count": -1,
|
|
770
|
-
},
|
|
823
|
+
"did": {
|
|
824
|
+
"init": True,
|
|
825
|
+
"unconfirmed_wallet_balance": 101,
|
|
826
|
+
"pending_change": 101,
|
|
827
|
+
"pending_coin_removal_count": 1,
|
|
771
828
|
},
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
env_0 = wallet_environments.environments[0]
|
|
796
|
-
wallet_node_0 = env_0.node
|
|
797
|
-
wallet_0 = env_0.xch_wallet
|
|
798
|
-
api_0 = env_0.rpc_api
|
|
799
|
-
|
|
800
|
-
env_0.wallet_aliases = {
|
|
801
|
-
"xch": 1,
|
|
802
|
-
"did": 2,
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
async with wallet_0.wallet_state_manager.new_action_scope(
|
|
806
|
-
wallet_environments.tx_config, push=True
|
|
829
|
+
},
|
|
830
|
+
post_block_balance_updates={
|
|
831
|
+
"xch": {
|
|
832
|
+
"set_remainder": True,
|
|
833
|
+
},
|
|
834
|
+
"did": {
|
|
835
|
+
"confirmed_wallet_balance": 101,
|
|
836
|
+
"spendable_balance": 101,
|
|
837
|
+
"max_send_amount": 101,
|
|
838
|
+
"unspent_coin_count": 1,
|
|
839
|
+
"pending_change": -101,
|
|
840
|
+
"pending_coin_removal_count": -1,
|
|
841
|
+
},
|
|
842
|
+
},
|
|
843
|
+
),
|
|
844
|
+
]
|
|
845
|
+
)
|
|
846
|
+
coin = await did_wallet.get_coin()
|
|
847
|
+
info: list[tuple[bytes, bytes, int]] = []
|
|
848
|
+
pubkey = (await did_wallet.wallet_state_manager.get_unused_derivation_record(did_wallet.wallet_info.id)).pubkey
|
|
849
|
+
with pytest.raises(Exception): # We expect a CLVM 80 error for this test
|
|
850
|
+
async with did_wallet.wallet_state_manager.new_action_scope(
|
|
851
|
+
wallet_environments.tx_config, push=False
|
|
807
852
|
) as action_scope:
|
|
808
|
-
|
|
809
|
-
|
|
853
|
+
await did_wallet.recovery_spend(
|
|
854
|
+
coin,
|
|
855
|
+
ph,
|
|
856
|
+
info,
|
|
857
|
+
pubkey,
|
|
858
|
+
WalletSpendBundle([], AugSchemeMPL.aggregate([])),
|
|
859
|
+
action_scope,
|
|
810
860
|
)
|
|
811
861
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
862
|
+
|
|
863
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
864
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
865
|
+
@pytest.mark.parametrize(
|
|
866
|
+
"use_alternate_recovery",
|
|
867
|
+
[True, False],
|
|
868
|
+
)
|
|
869
|
+
@pytest.mark.anyio
|
|
870
|
+
async def test_did_find_lost_did(wallet_environments: WalletTestFramework, use_alternate_recovery: bool):
|
|
871
|
+
env_0 = wallet_environments.environments[0]
|
|
872
|
+
wallet_node_0 = env_0.node
|
|
873
|
+
wallet_0 = env_0.xch_wallet
|
|
874
|
+
|
|
875
|
+
env_0.wallet_aliases = {
|
|
876
|
+
"xch": 1,
|
|
877
|
+
"did": 2,
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
881
|
+
did_wallet_0 = await make_did_wallet(
|
|
882
|
+
wallet_node_0.wallet_state_manager,
|
|
883
|
+
wallet_0,
|
|
884
|
+
uint64(101),
|
|
885
|
+
action_scope,
|
|
886
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
887
|
+
)
|
|
888
|
+
|
|
889
|
+
await wallet_environments.process_pending_states(
|
|
890
|
+
[
|
|
891
|
+
WalletStateTransition(
|
|
892
|
+
pre_block_balance_updates={
|
|
893
|
+
"xch": {
|
|
894
|
+
"set_remainder": True,
|
|
825
895
|
},
|
|
826
|
-
|
|
827
|
-
"
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
"
|
|
831
|
-
"confirmed_wallet_balance": 101,
|
|
832
|
-
"spendable_balance": 101,
|
|
833
|
-
"max_send_amount": 101,
|
|
834
|
-
"unspent_coin_count": 1,
|
|
835
|
-
"pending_change": -101,
|
|
836
|
-
"pending_coin_removal_count": -1,
|
|
837
|
-
},
|
|
896
|
+
"did": {
|
|
897
|
+
"init": True,
|
|
898
|
+
"unconfirmed_wallet_balance": 101,
|
|
899
|
+
"pending_change": 101,
|
|
900
|
+
"pending_coin_removal_count": 1,
|
|
838
901
|
},
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
902
|
+
},
|
|
903
|
+
post_block_balance_updates={
|
|
904
|
+
"xch": {
|
|
905
|
+
"set_remainder": True,
|
|
906
|
+
},
|
|
907
|
+
"did": {
|
|
908
|
+
"confirmed_wallet_balance": 101,
|
|
909
|
+
"spendable_balance": 101,
|
|
910
|
+
"max_send_amount": 101,
|
|
911
|
+
"unspent_coin_count": 1,
|
|
912
|
+
"pending_change": -101,
|
|
913
|
+
"pending_coin_removal_count": -1,
|
|
914
|
+
},
|
|
915
|
+
},
|
|
916
|
+
),
|
|
917
|
+
]
|
|
918
|
+
)
|
|
842
919
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
await wallet_node_0.wallet_state_manager.get_all_wallet_info_entries(),
|
|
857
|
-
)
|
|
920
|
+
# Delete the coin and wallet
|
|
921
|
+
coin = await did_wallet_0.get_coin()
|
|
922
|
+
await wallet_node_0.wallet_state_manager.coin_store.delete_coin_record(coin.name())
|
|
923
|
+
await wallet_node_0.wallet_state_manager.delete_wallet(did_wallet_0.wallet_info.id)
|
|
924
|
+
wallet_node_0.wallet_state_manager.wallets.pop(did_wallet_0.wallet_info.id)
|
|
925
|
+
assert len(wallet_node_0.wallet_state_manager.wallets) == 1
|
|
926
|
+
# Find lost DID
|
|
927
|
+
assert did_wallet_0.did_info.origin_coin is not None # mypy
|
|
928
|
+
await env_0.rpc_client.find_lost_did(DIDFindLostDID(did_wallet_0.did_info.origin_coin.name().hex()))
|
|
929
|
+
did_wallets = list(
|
|
930
|
+
filter(
|
|
931
|
+
lambda w: (w.type == WalletType.DECENTRALIZED_ID),
|
|
932
|
+
await wallet_node_0.wallet_state_manager.get_all_wallet_info_entries(),
|
|
858
933
|
)
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
934
|
+
)
|
|
935
|
+
did_wallet = wallet_node_0.wallet_state_manager.wallets[did_wallets[0].id]
|
|
936
|
+
assert isinstance(did_wallet, DIDWallet)
|
|
937
|
+
env_0.wallet_aliases["did_found"] = did_wallets[0].id
|
|
938
|
+
await env_0.change_balances(
|
|
939
|
+
{
|
|
940
|
+
"did_found": {
|
|
941
|
+
"init": True,
|
|
942
|
+
"confirmed_wallet_balance": 101,
|
|
943
|
+
"unconfirmed_wallet_balance": 101,
|
|
944
|
+
"spendable_balance": 101,
|
|
945
|
+
"max_send_amount": 101,
|
|
946
|
+
"unspent_coin_count": 1,
|
|
871
947
|
}
|
|
872
|
-
|
|
873
|
-
|
|
948
|
+
}
|
|
949
|
+
)
|
|
950
|
+
await env_0.check_balances()
|
|
874
951
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
952
|
+
# Spend DID
|
|
953
|
+
recovery_list = [bytes32.fromhex(did_wallet.get_my_DID())]
|
|
954
|
+
await did_wallet.update_recovery_list(recovery_list, uint64(1))
|
|
955
|
+
assert did_wallet.did_info.backup_ids == recovery_list
|
|
956
|
+
async with did_wallet.wallet_state_manager.new_action_scope(
|
|
957
|
+
wallet_environments.tx_config, push=True
|
|
958
|
+
) as action_scope:
|
|
959
|
+
await did_wallet.create_update_spend(action_scope)
|
|
883
960
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
},
|
|
961
|
+
await wallet_environments.process_pending_states(
|
|
962
|
+
[
|
|
963
|
+
WalletStateTransition(
|
|
964
|
+
pre_block_balance_updates={
|
|
965
|
+
"did_found": {
|
|
966
|
+
"spendable_balance": -101,
|
|
967
|
+
"max_send_amount": -101,
|
|
968
|
+
"pending_change": 101,
|
|
969
|
+
"pending_coin_removal_count": 1,
|
|
894
970
|
},
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
971
|
+
},
|
|
972
|
+
post_block_balance_updates={
|
|
973
|
+
"did_found": {
|
|
974
|
+
"spendable_balance": 101,
|
|
975
|
+
"max_send_amount": 101,
|
|
976
|
+
"pending_change": -101,
|
|
977
|
+
"pending_coin_removal_count": -1,
|
|
902
978
|
},
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
# Delete the coin and change inner puzzle
|
|
908
|
-
coin = await did_wallet.get_coin()
|
|
909
|
-
await wallet_node_0.wallet_state_manager.coin_store.delete_coin_record(coin.name())
|
|
910
|
-
new_inner_puzzle = await did_wallet.get_did_innerpuz(new=True)
|
|
911
|
-
did_wallet.did_info = dataclasses.replace(did_wallet.did_info, current_inner=new_inner_puzzle)
|
|
912
|
-
# Recovery the coin
|
|
913
|
-
assert did_wallet.did_info.origin_coin is not None # mypy
|
|
914
|
-
resp = await api_0.did_find_lost_did({"coin_id": did_wallet.did_info.origin_coin.name().hex()})
|
|
915
|
-
assert resp["success"]
|
|
916
|
-
found_coin = await did_wallet.get_coin()
|
|
917
|
-
assert found_coin == coin
|
|
918
|
-
assert did_wallet.did_info.current_inner != new_inner_puzzle
|
|
919
|
-
|
|
920
|
-
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
921
|
-
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
922
|
-
@pytest.mark.anyio
|
|
923
|
-
async def test_did_attest_after_recovery(self, wallet_environments: WalletTestFramework):
|
|
924
|
-
env_0 = wallet_environments.environments[0]
|
|
925
|
-
env_1 = wallet_environments.environments[1]
|
|
926
|
-
wallet_node_0 = env_0.node
|
|
927
|
-
wallet_node_1 = env_1.node
|
|
928
|
-
wallet_0 = env_0.xch_wallet
|
|
929
|
-
wallet_1 = env_1.xch_wallet
|
|
930
|
-
|
|
931
|
-
env_0.wallet_aliases = {
|
|
932
|
-
"xch": 1,
|
|
933
|
-
"did": 2,
|
|
934
|
-
}
|
|
935
|
-
env_1.wallet_aliases = {
|
|
936
|
-
"xch": 1,
|
|
937
|
-
"did": 2,
|
|
938
|
-
}
|
|
979
|
+
},
|
|
980
|
+
),
|
|
981
|
+
]
|
|
982
|
+
)
|
|
939
983
|
|
|
940
|
-
|
|
984
|
+
# Delete the coin and change inner puzzle
|
|
985
|
+
coin = await did_wallet.get_coin()
|
|
986
|
+
await wallet_node_0.wallet_state_manager.coin_store.delete_coin_record(coin.name())
|
|
987
|
+
with wallet_environments.new_puzzle_hashes_allowed():
|
|
988
|
+
async with did_wallet.wallet_state_manager.new_action_scope(
|
|
941
989
|
wallet_environments.tx_config, push=True
|
|
942
990
|
) as action_scope:
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
991
|
+
new_inner_puzzle = await did_wallet.get_did_innerpuz(action_scope, override_reuse_puzhash_with=False)
|
|
992
|
+
did_wallet.did_info = dataclasses.replace(did_wallet.did_info, current_inner=new_inner_puzzle)
|
|
993
|
+
# Recovery the coin
|
|
994
|
+
assert did_wallet.did_info.origin_coin is not None # mypy
|
|
995
|
+
await env_0.rpc_client.find_lost_did(DIDFindLostDID(did_wallet.did_info.origin_coin.name().hex()))
|
|
996
|
+
found_coin = await did_wallet.get_coin()
|
|
997
|
+
assert found_coin == coin
|
|
998
|
+
assert did_wallet.did_info.current_inner != new_inner_puzzle
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1002
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
1003
|
+
@pytest.mark.parametrize(
|
|
1004
|
+
"use_alternate_recovery",
|
|
1005
|
+
[True, False],
|
|
1006
|
+
)
|
|
1007
|
+
@pytest.mark.anyio
|
|
1008
|
+
async def test_did_attest_after_recovery(wallet_environments: WalletTestFramework, use_alternate_recovery: bool):
|
|
1009
|
+
env_0 = wallet_environments.environments[0]
|
|
1010
|
+
env_1 = wallet_environments.environments[1]
|
|
1011
|
+
wallet_node_0 = env_0.node
|
|
1012
|
+
wallet_node_1 = env_1.node
|
|
1013
|
+
wallet_0 = env_0.xch_wallet
|
|
1014
|
+
wallet_1 = env_1.xch_wallet
|
|
1015
|
+
|
|
1016
|
+
env_0.wallet_aliases = {
|
|
1017
|
+
"xch": 1,
|
|
1018
|
+
"did": 2,
|
|
1019
|
+
}
|
|
1020
|
+
env_1.wallet_aliases = {
|
|
1021
|
+
"xch": 1,
|
|
1022
|
+
"did": 2,
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1026
|
+
did_wallet: DIDWallet = await make_did_wallet(
|
|
1027
|
+
wallet_node_0.wallet_state_manager,
|
|
1028
|
+
wallet_0,
|
|
1029
|
+
uint64(101),
|
|
1030
|
+
action_scope,
|
|
1031
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
1032
|
+
)
|
|
1033
|
+
await wallet_environments.process_pending_states(
|
|
1034
|
+
[
|
|
1035
|
+
WalletStateTransition(
|
|
1036
|
+
pre_block_balance_updates={
|
|
1037
|
+
"xch": {
|
|
1038
|
+
"set_remainder": True,
|
|
959
1039
|
},
|
|
960
|
-
|
|
961
|
-
"
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
"
|
|
965
|
-
"confirmed_wallet_balance": 101,
|
|
966
|
-
"spendable_balance": 101,
|
|
967
|
-
"max_send_amount": 101,
|
|
968
|
-
"unspent_coin_count": 1,
|
|
969
|
-
"pending_change": -101,
|
|
970
|
-
"pending_coin_removal_count": -1,
|
|
971
|
-
},
|
|
1040
|
+
"did": {
|
|
1041
|
+
"init": True,
|
|
1042
|
+
"unconfirmed_wallet_balance": 101,
|
|
1043
|
+
"pending_change": 101,
|
|
1044
|
+
"pending_coin_removal_count": 1,
|
|
972
1045
|
},
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1046
|
+
},
|
|
1047
|
+
post_block_balance_updates={
|
|
1048
|
+
"xch": {
|
|
1049
|
+
"set_remainder": True,
|
|
1050
|
+
},
|
|
1051
|
+
"did": {
|
|
1052
|
+
"confirmed_wallet_balance": 101,
|
|
1053
|
+
"spendable_balance": 101,
|
|
1054
|
+
"max_send_amount": 101,
|
|
1055
|
+
"unspent_coin_count": 1,
|
|
1056
|
+
"pending_change": -101,
|
|
1057
|
+
"pending_coin_removal_count": -1,
|
|
1058
|
+
},
|
|
1059
|
+
},
|
|
1060
|
+
),
|
|
1061
|
+
WalletStateTransition(),
|
|
1062
|
+
]
|
|
1063
|
+
)
|
|
977
1064
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1065
|
+
await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
|
|
1066
|
+
await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
|
|
1067
|
+
recovery_list = [bytes32.from_hexstr(did_wallet.get_my_DID())]
|
|
981
1068
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
"xch": {
|
|
994
|
-
"set_remainder": True,
|
|
995
|
-
},
|
|
996
|
-
"did": {
|
|
997
|
-
"init": True,
|
|
998
|
-
"unconfirmed_wallet_balance": 101,
|
|
999
|
-
"pending_change": 101,
|
|
1000
|
-
"pending_coin_removal_count": 1,
|
|
1001
|
-
},
|
|
1069
|
+
async with wallet_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1070
|
+
did_wallet_2: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
1071
|
+
wallet_node_1.wallet_state_manager, wallet_1, uint64(101), action_scope, recovery_list
|
|
1072
|
+
)
|
|
1073
|
+
await wallet_environments.process_pending_states(
|
|
1074
|
+
[
|
|
1075
|
+
WalletStateTransition(),
|
|
1076
|
+
WalletStateTransition(
|
|
1077
|
+
pre_block_balance_updates={
|
|
1078
|
+
"xch": {
|
|
1079
|
+
"set_remainder": True,
|
|
1002
1080
|
},
|
|
1003
|
-
|
|
1004
|
-
"
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
"
|
|
1008
|
-
"confirmed_wallet_balance": 101,
|
|
1009
|
-
"spendable_balance": 101,
|
|
1010
|
-
"max_send_amount": 101,
|
|
1011
|
-
"unspent_coin_count": 1,
|
|
1012
|
-
"pending_change": -101,
|
|
1013
|
-
"pending_coin_removal_count": -1,
|
|
1014
|
-
},
|
|
1081
|
+
"did": {
|
|
1082
|
+
"init": True,
|
|
1083
|
+
"unconfirmed_wallet_balance": 101,
|
|
1084
|
+
"pending_change": 101,
|
|
1085
|
+
"pending_coin_removal_count": 1,
|
|
1015
1086
|
},
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1087
|
+
},
|
|
1088
|
+
post_block_balance_updates={
|
|
1089
|
+
"xch": {
|
|
1090
|
+
"set_remainder": True,
|
|
1091
|
+
},
|
|
1092
|
+
"did": {
|
|
1093
|
+
"confirmed_wallet_balance": 101,
|
|
1094
|
+
"spendable_balance": 101,
|
|
1095
|
+
"max_send_amount": 101,
|
|
1096
|
+
"unspent_coin_count": 1,
|
|
1097
|
+
"pending_change": -101,
|
|
1098
|
+
"pending_coin_removal_count": -1,
|
|
1099
|
+
},
|
|
1100
|
+
},
|
|
1101
|
+
),
|
|
1102
|
+
]
|
|
1103
|
+
)
|
|
1019
1104
|
|
|
1020
|
-
|
|
1105
|
+
assert did_wallet_2.did_info.backup_ids == recovery_list
|
|
1021
1106
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1107
|
+
# Update coin with new ID info
|
|
1108
|
+
recovery_list = [bytes32.from_hexstr(did_wallet_2.get_my_DID())]
|
|
1109
|
+
await did_wallet.update_recovery_list(recovery_list, uint64(1))
|
|
1110
|
+
assert did_wallet.did_info.backup_ids == recovery_list
|
|
1111
|
+
async with did_wallet.wallet_state_manager.new_action_scope(
|
|
1112
|
+
wallet_environments.tx_config, push=True
|
|
1113
|
+
) as action_scope:
|
|
1114
|
+
await did_wallet.create_update_spend(action_scope)
|
|
1115
|
+
|
|
1116
|
+
await wallet_environments.process_pending_states(
|
|
1117
|
+
[
|
|
1118
|
+
WalletStateTransition(
|
|
1119
|
+
pre_block_balance_updates={
|
|
1120
|
+
"did": {
|
|
1121
|
+
"set_remainder": True,
|
|
1122
|
+
}
|
|
1123
|
+
},
|
|
1124
|
+
post_block_balance_updates={
|
|
1125
|
+
"did": {
|
|
1126
|
+
"set_remainder": True,
|
|
1127
|
+
}
|
|
1128
|
+
},
|
|
1129
|
+
),
|
|
1130
|
+
WalletStateTransition(),
|
|
1131
|
+
]
|
|
1132
|
+
)
|
|
1133
|
+
|
|
1134
|
+
# DID Wallet 2 recovers into DID Wallet 3 with new innerpuz
|
|
1135
|
+
backup_data = did_wallet_2.create_backup()
|
|
1136
|
+
|
|
1137
|
+
async with wallet_node_0.wallet_state_manager.lock:
|
|
1138
|
+
did_wallet_3 = await DIDWallet.create_new_did_wallet_from_recovery(
|
|
1139
|
+
wallet_node_0.wallet_state_manager,
|
|
1140
|
+
wallet_0,
|
|
1141
|
+
backup_data,
|
|
1142
|
+
)
|
|
1143
|
+
env_0.wallet_aliases["did_2"] = 3
|
|
1144
|
+
with wallet_environments.new_puzzle_hashes_allowed():
|
|
1145
|
+
async with did_wallet_3.wallet_state_manager.new_action_scope(
|
|
1027
1146
|
wallet_environments.tx_config, push=True
|
|
1028
1147
|
) as action_scope:
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1148
|
+
new_ph = (
|
|
1149
|
+
await did_wallet_3.get_did_innerpuz(action_scope, override_reuse_puzhash_with=False)
|
|
1150
|
+
).get_tree_hash()
|
|
1151
|
+
coin = await did_wallet_2.get_coin()
|
|
1152
|
+
pubkey = (await did_wallet_3.wallet_state_manager.get_unused_derivation_record(did_wallet_3.wallet_info.id)).pubkey
|
|
1153
|
+
|
|
1154
|
+
async with did_wallet.wallet_state_manager.new_action_scope(
|
|
1155
|
+
wallet_environments.tx_config, push=True
|
|
1156
|
+
) as action_scope:
|
|
1157
|
+
message_spend_bundle, attest_data = await did_wallet.create_attestment(
|
|
1158
|
+
coin.name(), new_ph, pubkey, action_scope
|
|
1159
|
+
)
|
|
1160
|
+
await wallet_environments.process_pending_states(
|
|
1161
|
+
[
|
|
1162
|
+
WalletStateTransition(
|
|
1163
|
+
pre_block_balance_updates={
|
|
1164
|
+
"did": {
|
|
1165
|
+
"set_remainder": True,
|
|
1038
1166
|
},
|
|
1039
|
-
|
|
1040
|
-
"
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1167
|
+
"did_2": {
|
|
1168
|
+
"init": True,
|
|
1169
|
+
"set_remainder": True,
|
|
1043
1170
|
},
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1171
|
+
},
|
|
1172
|
+
post_block_balance_updates={
|
|
1173
|
+
"did": {
|
|
1174
|
+
"set_remainder": True,
|
|
1175
|
+
},
|
|
1176
|
+
"did_2": {
|
|
1177
|
+
"set_remainder": True,
|
|
1178
|
+
},
|
|
1179
|
+
},
|
|
1180
|
+
),
|
|
1181
|
+
WalletStateTransition(),
|
|
1182
|
+
]
|
|
1183
|
+
)
|
|
1048
1184
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1185
|
+
(
|
|
1186
|
+
info,
|
|
1187
|
+
message_spend_bundle,
|
|
1188
|
+
) = await did_wallet_3.load_attest_files_for_recovery_spend([attest_data])
|
|
1189
|
+
async with did_wallet_3.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1190
|
+
await did_wallet_3.recovery_spend(coin, new_ph, info, pubkey, message_spend_bundle, action_scope)
|
|
1191
|
+
await wallet_environments.process_pending_states(
|
|
1192
|
+
[
|
|
1193
|
+
WalletStateTransition(
|
|
1194
|
+
pre_block_balance_updates={
|
|
1195
|
+
"did_2": {
|
|
1196
|
+
"unconfirmed_wallet_balance": 101,
|
|
1197
|
+
"set_remainder": True,
|
|
1198
|
+
},
|
|
1199
|
+
},
|
|
1200
|
+
post_block_balance_updates={
|
|
1201
|
+
"did_2": {
|
|
1202
|
+
"confirmed_wallet_balance": 101,
|
|
1203
|
+
"set_remainder": True,
|
|
1204
|
+
},
|
|
1205
|
+
},
|
|
1206
|
+
),
|
|
1207
|
+
WalletStateTransition(
|
|
1208
|
+
pre_block_balance_updates={
|
|
1209
|
+
"did": {
|
|
1210
|
+
"unconfirmed_wallet_balance": 0, # TODO: fix pre-block balances for recovery
|
|
1211
|
+
"set_remainder": True,
|
|
1212
|
+
},
|
|
1213
|
+
},
|
|
1214
|
+
post_block_balance_updates={
|
|
1215
|
+
"did": {
|
|
1216
|
+
"confirmed_wallet_balance": -101,
|
|
1217
|
+
"set_remainder": True,
|
|
1218
|
+
},
|
|
1219
|
+
},
|
|
1220
|
+
),
|
|
1221
|
+
]
|
|
1222
|
+
)
|
|
1051
1223
|
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
wallet_node_0.wallet_state_manager,
|
|
1055
|
-
wallet_0,
|
|
1056
|
-
backup_data,
|
|
1057
|
-
)
|
|
1058
|
-
env_0.wallet_aliases["did_2"] = 3
|
|
1059
|
-
new_ph = await did_wallet_3.get_did_inner_hash(new=True)
|
|
1060
|
-
coin = await did_wallet_2.get_coin()
|
|
1061
|
-
pubkey = (
|
|
1062
|
-
await did_wallet_3.wallet_state_manager.get_unused_derivation_record(did_wallet_3.wallet_info.id)
|
|
1063
|
-
).pubkey
|
|
1224
|
+
# DID Wallet 1 recovery spends into DID Wallet 4
|
|
1225
|
+
backup_data = did_wallet.create_backup()
|
|
1064
1226
|
|
|
1065
|
-
|
|
1227
|
+
async with wallet_node_1.wallet_state_manager.lock:
|
|
1228
|
+
did_wallet_4 = await DIDWallet.create_new_did_wallet_from_recovery(
|
|
1229
|
+
wallet_node_1.wallet_state_manager,
|
|
1230
|
+
wallet_1,
|
|
1231
|
+
backup_data,
|
|
1232
|
+
)
|
|
1233
|
+
env_1.wallet_aliases["did_2"] = 3
|
|
1234
|
+
coin = await did_wallet.get_coin()
|
|
1235
|
+
with wallet_environments.new_puzzle_hashes_allowed():
|
|
1236
|
+
async with did_wallet_4.wallet_state_manager.new_action_scope(
|
|
1066
1237
|
wallet_environments.tx_config, push=True
|
|
1067
1238
|
) as action_scope:
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
)
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1239
|
+
new_ph = (
|
|
1240
|
+
await did_wallet_4.get_did_innerpuz(action_scope, override_reuse_puzhash_with=False)
|
|
1241
|
+
).get_tree_hash()
|
|
1242
|
+
pubkey = (await did_wallet_4.wallet_state_manager.get_unused_derivation_record(did_wallet_4.wallet_info.id)).pubkey
|
|
1243
|
+
async with did_wallet_3.wallet_state_manager.new_action_scope(
|
|
1244
|
+
wallet_environments.tx_config, push=True
|
|
1245
|
+
) as action_scope:
|
|
1246
|
+
message_spend_bundle, attest1 = await did_wallet_3.create_attestment(coin.name(), new_ph, pubkey, action_scope)
|
|
1247
|
+
|
|
1248
|
+
await wallet_environments.process_pending_states(
|
|
1249
|
+
[
|
|
1250
|
+
WalletStateTransition(
|
|
1251
|
+
pre_block_balance_updates={
|
|
1252
|
+
"did_2": {
|
|
1253
|
+
"unconfirmed_wallet_balance": 0,
|
|
1254
|
+
"set_remainder": True,
|
|
1255
|
+
},
|
|
1256
|
+
},
|
|
1257
|
+
post_block_balance_updates={
|
|
1258
|
+
"did_2": {
|
|
1259
|
+
"confirmed_wallet_balance": 0,
|
|
1260
|
+
"set_remainder": True,
|
|
1082
1261
|
},
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1262
|
+
},
|
|
1263
|
+
),
|
|
1264
|
+
WalletStateTransition(
|
|
1265
|
+
pre_block_balance_updates={
|
|
1266
|
+
"did_2": {
|
|
1267
|
+
"init": True,
|
|
1268
|
+
"set_remainder": True,
|
|
1090
1269
|
},
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1270
|
+
},
|
|
1271
|
+
post_block_balance_updates={
|
|
1272
|
+
"did_2": {
|
|
1273
|
+
"confirmed_wallet_balance": 0,
|
|
1274
|
+
"set_remainder": True,
|
|
1275
|
+
},
|
|
1276
|
+
},
|
|
1277
|
+
),
|
|
1278
|
+
]
|
|
1279
|
+
)
|
|
1095
1280
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
},
|
|
1281
|
+
(
|
|
1282
|
+
test_info_list,
|
|
1283
|
+
test_message_spend_bundle,
|
|
1284
|
+
) = await did_wallet_4.load_attest_files_for_recovery_spend([attest1])
|
|
1285
|
+
async with did_wallet_4.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1286
|
+
await did_wallet_4.recovery_spend(coin, new_ph, test_info_list, pubkey, test_message_spend_bundle, action_scope)
|
|
1287
|
+
|
|
1288
|
+
await wallet_environments.process_pending_states(
|
|
1289
|
+
[
|
|
1290
|
+
WalletStateTransition(
|
|
1291
|
+
pre_block_balance_updates={
|
|
1292
|
+
"did": {
|
|
1293
|
+
"set_remainder": True,
|
|
1110
1294
|
},
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1295
|
+
},
|
|
1296
|
+
post_block_balance_updates={
|
|
1297
|
+
"did": {
|
|
1298
|
+
"confirmed_wallet_balance": -101,
|
|
1299
|
+
"set_remainder": True,
|
|
1116
1300
|
},
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
},
|
|
1301
|
+
},
|
|
1302
|
+
),
|
|
1303
|
+
WalletStateTransition(
|
|
1304
|
+
pre_block_balance_updates={
|
|
1305
|
+
"did_2": {
|
|
1306
|
+
"set_remainder": True,
|
|
1124
1307
|
},
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1308
|
+
},
|
|
1309
|
+
post_block_balance_updates={
|
|
1310
|
+
"did_2": {
|
|
1311
|
+
"confirmed_wallet_balance": 101,
|
|
1312
|
+
"set_remainder": True,
|
|
1130
1313
|
},
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1314
|
+
},
|
|
1315
|
+
),
|
|
1316
|
+
]
|
|
1317
|
+
)
|
|
1134
1318
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1319
|
+
for wallet in [did_wallet, did_wallet_3, did_wallet_4]:
|
|
1320
|
+
assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
|
|
1137
1321
|
|
|
1138
|
-
async with wallet_node_1.wallet_state_manager.lock:
|
|
1139
|
-
did_wallet_4 = await DIDWallet.create_new_did_wallet_from_recovery(
|
|
1140
|
-
wallet_node_1.wallet_state_manager,
|
|
1141
|
-
wallet_1,
|
|
1142
|
-
backup_data,
|
|
1143
|
-
)
|
|
1144
|
-
env_1.wallet_aliases["did_2"] = 3
|
|
1145
|
-
coin = await did_wallet.get_coin()
|
|
1146
|
-
new_ph = await did_wallet_4.get_did_inner_hash(new=True)
|
|
1147
|
-
pubkey = (
|
|
1148
|
-
await did_wallet_4.wallet_state_manager.get_unused_derivation_record(did_wallet_4.wallet_info.id)
|
|
1149
|
-
).pubkey
|
|
1150
|
-
async with did_wallet_3.wallet_state_manager.new_action_scope(
|
|
1151
|
-
wallet_environments.tx_config, push=True
|
|
1152
|
-
) as action_scope:
|
|
1153
|
-
message_spend_bundle, attest1 = await did_wallet_3.create_attestment(
|
|
1154
|
-
coin.name(), new_ph, pubkey, action_scope
|
|
1155
|
-
)
|
|
1156
1322
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1323
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1324
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
1325
|
+
@pytest.mark.parametrize(
|
|
1326
|
+
"with_recovery",
|
|
1327
|
+
[True, False],
|
|
1328
|
+
)
|
|
1329
|
+
@pytest.mark.anyio
|
|
1330
|
+
async def test_did_transfer(wallet_environments: WalletTestFramework, with_recovery: bool):
|
|
1331
|
+
env_0 = wallet_environments.environments[0]
|
|
1332
|
+
env_1 = wallet_environments.environments[1]
|
|
1333
|
+
wallet_node_0 = env_0.node
|
|
1334
|
+
wallet_node_1 = env_1.node
|
|
1335
|
+
wallet_0 = env_0.xch_wallet
|
|
1336
|
+
wallet_1 = env_1.xch_wallet
|
|
1337
|
+
|
|
1338
|
+
env_0.wallet_aliases = {
|
|
1339
|
+
"xch": 1,
|
|
1340
|
+
"did": 2,
|
|
1341
|
+
}
|
|
1342
|
+
env_1.wallet_aliases = {
|
|
1343
|
+
"xch": 1,
|
|
1344
|
+
"did": 2,
|
|
1345
|
+
}
|
|
1346
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1347
|
+
ph = await action_scope.get_puzzle_hash(wallet_0.wallet_state_manager)
|
|
1348
|
+
fee = uint64(1000)
|
|
1349
|
+
|
|
1350
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1351
|
+
did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
1352
|
+
wallet_node_0.wallet_state_manager,
|
|
1353
|
+
wallet_0,
|
|
1354
|
+
uint64(101),
|
|
1355
|
+
action_scope,
|
|
1356
|
+
[ph],
|
|
1357
|
+
uint64(1),
|
|
1358
|
+
{"Twitter": "Test", "GitHub": "测试"},
|
|
1359
|
+
fee=fee,
|
|
1360
|
+
)
|
|
1361
|
+
assert did_wallet_1.get_name() == "Profile 1"
|
|
1362
|
+
|
|
1363
|
+
await wallet_environments.process_pending_states(
|
|
1364
|
+
[
|
|
1365
|
+
WalletStateTransition(
|
|
1366
|
+
pre_block_balance_updates={
|
|
1367
|
+
"xch": {
|
|
1368
|
+
"set_remainder": True,
|
|
1165
1369
|
},
|
|
1166
|
-
|
|
1167
|
-
"
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1370
|
+
"did": {
|
|
1371
|
+
"init": True,
|
|
1372
|
+
"unconfirmed_wallet_balance": 101,
|
|
1373
|
+
"pending_change": 101,
|
|
1374
|
+
"pending_coin_removal_count": 1,
|
|
1171
1375
|
},
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
"
|
|
1176
|
-
"init": True,
|
|
1177
|
-
"set_remainder": True,
|
|
1178
|
-
},
|
|
1376
|
+
},
|
|
1377
|
+
post_block_balance_updates={
|
|
1378
|
+
"xch": {
|
|
1379
|
+
"set_remainder": True,
|
|
1179
1380
|
},
|
|
1180
|
-
|
|
1181
|
-
"
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1381
|
+
"did": {
|
|
1382
|
+
"confirmed_wallet_balance": 101,
|
|
1383
|
+
"spendable_balance": 101,
|
|
1384
|
+
"max_send_amount": 101,
|
|
1385
|
+
"unspent_coin_count": 1,
|
|
1386
|
+
"pending_change": -101,
|
|
1387
|
+
"pending_coin_removal_count": -1,
|
|
1185
1388
|
},
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1389
|
+
},
|
|
1390
|
+
),
|
|
1391
|
+
WalletStateTransition(),
|
|
1392
|
+
]
|
|
1393
|
+
)
|
|
1189
1394
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
)
|
|
1395
|
+
# Transfer DID
|
|
1396
|
+
async with wallet_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1397
|
+
new_puzhash = await action_scope.get_puzzle_hash(wallet_1.wallet_state_manager)
|
|
1398
|
+
async with did_wallet_1.wallet_state_manager.new_action_scope(
|
|
1399
|
+
wallet_environments.tx_config, push=True
|
|
1400
|
+
) as action_scope:
|
|
1401
|
+
await did_wallet_1.transfer_did(new_puzhash, fee, with_recovery, action_scope)
|
|
1198
1402
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
},
|
|
1403
|
+
await wallet_environments.process_pending_states(
|
|
1404
|
+
[
|
|
1405
|
+
WalletStateTransition(
|
|
1406
|
+
pre_block_balance_updates={
|
|
1407
|
+
"xch": {
|
|
1408
|
+
"set_remainder": True,
|
|
1206
1409
|
},
|
|
1207
|
-
|
|
1208
|
-
"
|
|
1209
|
-
|
|
1210
|
-
"set_remainder": True,
|
|
1211
|
-
},
|
|
1410
|
+
"did": {
|
|
1411
|
+
"unconfirmed_wallet_balance": -101,
|
|
1412
|
+
"set_remainder": True,
|
|
1212
1413
|
},
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
"
|
|
1217
|
-
"set_remainder": True,
|
|
1218
|
-
},
|
|
1414
|
+
},
|
|
1415
|
+
post_block_balance_updates={
|
|
1416
|
+
"xch": {
|
|
1417
|
+
"set_remainder": True,
|
|
1219
1418
|
},
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1419
|
+
},
|
|
1420
|
+
),
|
|
1421
|
+
WalletStateTransition(
|
|
1422
|
+
pre_block_balance_updates={},
|
|
1423
|
+
post_block_balance_updates={
|
|
1424
|
+
"did": {
|
|
1425
|
+
"init": True,
|
|
1426
|
+
"confirmed_wallet_balance": 101,
|
|
1427
|
+
"set_remainder": True,
|
|
1225
1428
|
},
|
|
1226
|
-
|
|
1227
|
-
|
|
1429
|
+
},
|
|
1430
|
+
),
|
|
1431
|
+
]
|
|
1432
|
+
)
|
|
1433
|
+
|
|
1434
|
+
# Get the new DID wallet
|
|
1435
|
+
did_wallets = list(
|
|
1436
|
+
filter(
|
|
1437
|
+
lambda w: (w.type == WalletType.DECENTRALIZED_ID),
|
|
1438
|
+
await wallet_node_1.wallet_state_manager.get_all_wallet_info_entries(),
|
|
1228
1439
|
)
|
|
1440
|
+
)
|
|
1441
|
+
did_wallet_2 = wallet_node_1.wallet_state_manager.wallets[did_wallets[0].id]
|
|
1442
|
+
assert isinstance(did_wallet_2, DIDWallet) # mypy
|
|
1443
|
+
assert len(wallet_node_0.wallet_state_manager.wallets) == 1
|
|
1444
|
+
assert did_wallet_1.did_info.origin_coin == did_wallet_2.did_info.origin_coin
|
|
1445
|
+
if with_recovery:
|
|
1446
|
+
assert did_wallet_1.did_info.backup_ids[0] == did_wallet_2.did_info.backup_ids[0]
|
|
1447
|
+
assert did_wallet_1.did_info.num_of_backup_ids_needed == did_wallet_2.did_info.num_of_backup_ids_needed
|
|
1448
|
+
metadata = json.loads(did_wallet_2.did_info.metadata)
|
|
1449
|
+
assert metadata["Twitter"] == "Test"
|
|
1450
|
+
assert metadata["GitHub"] == "测试"
|
|
1451
|
+
|
|
1452
|
+
# Test match_hinted_coin
|
|
1453
|
+
assert await did_wallet_2.match_hinted_coin(
|
|
1454
|
+
await did_wallet_2.get_coin(),
|
|
1455
|
+
new_puzhash,
|
|
1456
|
+
)
|
|
1229
1457
|
|
|
1230
|
-
for wallet in [did_wallet, did_wallet_3, did_wallet_4]:
|
|
1231
|
-
assert wallet.wallet_state_manager.wallets[wallet.id()] == wallet
|
|
1232
1458
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1459
|
+
@pytest.mark.parametrize(
|
|
1460
|
+
"trusted",
|
|
1461
|
+
[True, False],
|
|
1462
|
+
)
|
|
1463
|
+
@pytest.mark.anyio
|
|
1464
|
+
async def test_did_auto_transfer_limit(
|
|
1465
|
+
self_hostname: str,
|
|
1466
|
+
two_wallet_nodes: tuple[list[FullNodeSimulator], list[tuple[WalletNode, ChiaServer]], BlockTools],
|
|
1467
|
+
trusted: bool,
|
|
1468
|
+
) -> None:
|
|
1469
|
+
fee = uint64(1000)
|
|
1470
|
+
full_nodes, wallets, _ = two_wallet_nodes
|
|
1471
|
+
full_node_api = full_nodes[0]
|
|
1472
|
+
server_1 = full_node_api.server
|
|
1473
|
+
wallet_node, server_2 = wallets[0]
|
|
1474
|
+
wallet_node_2, server_3 = wallets[1]
|
|
1475
|
+
wallet = wallet_node.wallet_state_manager.main_wallet
|
|
1476
|
+
wallet2 = wallet_node_2.wallet_state_manager.main_wallet
|
|
1477
|
+
api_1 = WalletRpcApi(wallet_node_2)
|
|
1478
|
+
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1479
|
+
ph = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
|
|
1480
|
+
|
|
1481
|
+
if trusted:
|
|
1482
|
+
wallet_node.config["trusted_peers"] = {
|
|
1483
|
+
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
1251
1484
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
"did": 2,
|
|
1485
|
+
wallet_node_2.config["trusted_peers"] = {
|
|
1486
|
+
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
1255
1487
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1488
|
+
else:
|
|
1489
|
+
wallet_node.config["trusted_peers"] = {}
|
|
1490
|
+
wallet_node_2.config["trusted_peers"] = {}
|
|
1258
1491
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1492
|
+
await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
|
|
1493
|
+
await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
|
|
1494
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet)
|
|
1495
|
+
|
|
1496
|
+
# Check that we cap out at 10 DID Wallets automatically created upon transfer received
|
|
1497
|
+
for i in range(14):
|
|
1498
|
+
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1262
1499
|
did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
1263
|
-
|
|
1264
|
-
|
|
1500
|
+
wallet_node.wallet_state_manager,
|
|
1501
|
+
wallet,
|
|
1265
1502
|
uint64(101),
|
|
1266
1503
|
action_scope,
|
|
1267
|
-
[ph],
|
|
1504
|
+
[bytes32(bytes(ph))],
|
|
1268
1505
|
uint64(1),
|
|
1269
1506
|
{"Twitter": "Test", "GitHub": "测试"},
|
|
1270
1507
|
fee=fee,
|
|
1271
1508
|
)
|
|
1272
1509
|
assert did_wallet_1.get_name() == "Profile 1"
|
|
1273
|
-
|
|
1274
|
-
await
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
pre_block_balance_updates={
|
|
1278
|
-
"xch": {
|
|
1279
|
-
"set_remainder": True,
|
|
1280
|
-
},
|
|
1281
|
-
"did": {
|
|
1282
|
-
"init": True,
|
|
1283
|
-
"unconfirmed_wallet_balance": 101,
|
|
1284
|
-
"pending_change": 101,
|
|
1285
|
-
"pending_coin_removal_count": 1,
|
|
1286
|
-
},
|
|
1287
|
-
},
|
|
1288
|
-
post_block_balance_updates={
|
|
1289
|
-
"xch": {
|
|
1290
|
-
"set_remainder": True,
|
|
1291
|
-
},
|
|
1292
|
-
"did": {
|
|
1293
|
-
"confirmed_wallet_balance": 101,
|
|
1294
|
-
"spendable_balance": 101,
|
|
1295
|
-
"max_send_amount": 101,
|
|
1296
|
-
"unspent_coin_count": 1,
|
|
1297
|
-
"pending_change": -101,
|
|
1298
|
-
"pending_coin_removal_count": -1,
|
|
1299
|
-
},
|
|
1300
|
-
},
|
|
1301
|
-
),
|
|
1302
|
-
WalletStateTransition(),
|
|
1303
|
-
]
|
|
1304
|
-
)
|
|
1305
|
-
|
|
1510
|
+
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1511
|
+
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
|
|
1512
|
+
await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
|
|
1513
|
+
await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
|
|
1306
1514
|
# Transfer DID
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1515
|
+
assert did_wallet_1.did_info.origin_coin is not None
|
|
1516
|
+
origin_coin = did_wallet_1.did_info.origin_coin
|
|
1517
|
+
async with wallet2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1518
|
+
new_puzhash = await action_scope.get_puzzle_hash(wallet2.wallet_state_manager)
|
|
1519
|
+
async with did_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1520
|
+
await did_wallet_1.transfer_did(new_puzhash, fee, False, action_scope)
|
|
1521
|
+
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1522
|
+
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
|
|
1523
|
+
# Check if the DID wallet is created in the wallet2
|
|
1312
1524
|
|
|
1313
|
-
await
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
"set_remainder": True,
|
|
1323
|
-
},
|
|
1324
|
-
},
|
|
1325
|
-
post_block_balance_updates={
|
|
1326
|
-
"xch": {
|
|
1327
|
-
"set_remainder": True,
|
|
1328
|
-
},
|
|
1329
|
-
},
|
|
1330
|
-
),
|
|
1331
|
-
WalletStateTransition(
|
|
1332
|
-
pre_block_balance_updates={},
|
|
1333
|
-
post_block_balance_updates={
|
|
1334
|
-
"did": {
|
|
1335
|
-
"init": True,
|
|
1336
|
-
"confirmed_wallet_balance": 101,
|
|
1337
|
-
"set_remainder": True,
|
|
1338
|
-
},
|
|
1339
|
-
},
|
|
1340
|
-
),
|
|
1341
|
-
]
|
|
1525
|
+
await time_out_assert(
|
|
1526
|
+
30, get_wallet_num, min(2 + i, 11), wallet_node_2.wallet_state_manager
|
|
1527
|
+
) # check we haven't made more than 10 DID wallets
|
|
1528
|
+
await time_out_assert(30, get_wallet_num, 1, wallet_node.wallet_state_manager)
|
|
1529
|
+
# Get the new DID wallets
|
|
1530
|
+
did_wallets = list(
|
|
1531
|
+
filter(
|
|
1532
|
+
lambda w: (w.type == WalletType.DECENTRALIZED_ID),
|
|
1533
|
+
await wallet_node_2.wallet_state_manager.get_all_wallet_info_entries(),
|
|
1342
1534
|
)
|
|
1535
|
+
)
|
|
1343
1536
|
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1537
|
+
assert len(did_wallets) == 10
|
|
1538
|
+
# Test we can use the DID
|
|
1539
|
+
did_wallet_10 = wallet_node_2.wallet_state_manager.get_wallet(id=uint32(did_wallets[9].id), required_type=DIDWallet)
|
|
1540
|
+
# Delete the coin and change inner puzzle
|
|
1541
|
+
coin = await did_wallet_10.get_coin()
|
|
1542
|
+
# origin_coin = did_wallet_10.did_info.origin_coin
|
|
1543
|
+
backup_data = did_wallet_10.create_backup()
|
|
1544
|
+
await wallet_node_2.wallet_state_manager.coin_store.delete_coin_record(coin.name())
|
|
1545
|
+
await time_out_assert(15, did_wallet_10.get_confirmed_balance, 0)
|
|
1546
|
+
await wallet_node_2.wallet_state_manager.user_store.delete_wallet(did_wallet_10.wallet_info.id)
|
|
1547
|
+
wallet_node_2.wallet_state_manager.wallets.pop(did_wallet_10.wallet_info.id)
|
|
1548
|
+
# Recover the coin
|
|
1549
|
+
async with wallet_node_2.wallet_state_manager.lock:
|
|
1550
|
+
did_wallet_10 = await DIDWallet.create_new_did_wallet_from_recovery(
|
|
1551
|
+
wallet_node_2.wallet_state_manager,
|
|
1552
|
+
wallet2,
|
|
1553
|
+
backup_data,
|
|
1350
1554
|
)
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1555
|
+
assert did_wallet_10.did_info.origin_coin is not None
|
|
1556
|
+
await api_1.did_find_lost_did({"coin_id": did_wallet_10.did_info.origin_coin.name().hex()})
|
|
1557
|
+
await time_out_assert(15, did_wallet_10.get_confirmed_balance, 101)
|
|
1558
|
+
await time_out_assert(15, did_wallet_10.get_unconfirmed_balance, 101)
|
|
1559
|
+
|
|
1560
|
+
# Check we can recover an auto-discarded DID
|
|
1561
|
+
did_wallet_9 = wallet_node_2.wallet_state_manager.get_wallet(id=uint32(did_wallets[8].id), required_type=DIDWallet)
|
|
1562
|
+
# Delete the coin and wallet to make space for a auto-discarded DID
|
|
1563
|
+
coin = await did_wallet_9.get_coin()
|
|
1564
|
+
await wallet_node_2.wallet_state_manager.coin_store.delete_coin_record(coin.name())
|
|
1565
|
+
await time_out_assert(15, did_wallet_9.get_confirmed_balance, 0)
|
|
1566
|
+
await wallet_node_2.wallet_state_manager.user_store.delete_wallet(did_wallet_9.wallet_info.id)
|
|
1567
|
+
wallet_node_2.wallet_state_manager.wallets.pop(did_wallet_9.wallet_info.id)
|
|
1568
|
+
|
|
1569
|
+
did_wallets = list(
|
|
1570
|
+
filter(
|
|
1571
|
+
lambda w: (w.type == WalletType.DECENTRALIZED_ID),
|
|
1572
|
+
await wallet_node_2.wallet_state_manager.get_all_wallet_info_entries(),
|
|
1366
1573
|
)
|
|
1367
|
-
|
|
1368
|
-
@pytest.mark.parametrize(
|
|
1369
|
-
"trusted",
|
|
1370
|
-
[True, False],
|
|
1371
1574
|
)
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
1381
|
-
full_node_api = full_nodes[0]
|
|
1382
|
-
server_1 = full_node_api.server
|
|
1383
|
-
wallet_node, server_2 = wallets[0]
|
|
1384
|
-
wallet_node_2, server_3 = wallets[1]
|
|
1385
|
-
wallet = wallet_node.wallet_state_manager.main_wallet
|
|
1386
|
-
wallet2 = wallet_node_2.wallet_state_manager.main_wallet
|
|
1387
|
-
api_1 = WalletRpcApi(wallet_node_2)
|
|
1388
|
-
ph = await wallet.get_new_puzzlehash()
|
|
1389
|
-
|
|
1390
|
-
if trusted:
|
|
1391
|
-
wallet_node.config["trusted_peers"] = {
|
|
1392
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
1393
|
-
}
|
|
1394
|
-
wallet_node_2.config["trusted_peers"] = {
|
|
1395
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
1396
|
-
}
|
|
1397
|
-
else:
|
|
1398
|
-
wallet_node.config["trusted_peers"] = {}
|
|
1399
|
-
wallet_node_2.config["trusted_peers"] = {}
|
|
1400
|
-
|
|
1401
|
-
await server_2.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
|
|
1402
|
-
await server_3.start_client(PeerInfo(self_hostname, server_1.get_port()), None)
|
|
1403
|
-
await full_node_api.farm_blocks_to_wallet(1, wallet)
|
|
1404
|
-
|
|
1405
|
-
# Check that we cap out at 10 DID Wallets automatically created upon transfer received
|
|
1406
|
-
for i in range(0, 14):
|
|
1407
|
-
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1408
|
-
did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
1409
|
-
wallet_node.wallet_state_manager,
|
|
1410
|
-
wallet,
|
|
1411
|
-
uint64(101),
|
|
1412
|
-
action_scope,
|
|
1413
|
-
[bytes32(bytes(ph))],
|
|
1414
|
-
uint64(1),
|
|
1415
|
-
{"Twitter": "Test", "GitHub": "测试"},
|
|
1416
|
-
fee=fee,
|
|
1417
|
-
)
|
|
1418
|
-
assert did_wallet_1.get_name() == "Profile 1"
|
|
1419
|
-
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1420
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
|
|
1421
|
-
await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
|
|
1422
|
-
await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
|
|
1423
|
-
# Transfer DID
|
|
1424
|
-
assert did_wallet_1.did_info.origin_coin is not None
|
|
1425
|
-
origin_coin = did_wallet_1.did_info.origin_coin
|
|
1426
|
-
new_puzhash = await wallet2.get_new_puzzlehash()
|
|
1427
|
-
async with did_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1428
|
-
await did_wallet_1.transfer_did(new_puzhash, fee, False, action_scope)
|
|
1429
|
-
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1430
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
|
|
1431
|
-
# Check if the DID wallet is created in the wallet2
|
|
1432
|
-
|
|
1433
|
-
await time_out_assert(
|
|
1434
|
-
30, get_wallet_num, min(2 + i, 11), wallet_node_2.wallet_state_manager
|
|
1435
|
-
) # check we haven't made more than 10 DID wallets
|
|
1436
|
-
await time_out_assert(30, get_wallet_num, 1, wallet_node.wallet_state_manager)
|
|
1437
|
-
# Get the new DID wallets
|
|
1438
|
-
did_wallets = list(
|
|
1439
|
-
filter(
|
|
1440
|
-
lambda w: (w.type == WalletType.DECENTRALIZED_ID),
|
|
1441
|
-
await wallet_node_2.wallet_state_manager.get_all_wallet_info_entries(),
|
|
1442
|
-
)
|
|
1575
|
+
assert len(did_wallets) == 9
|
|
1576
|
+
|
|
1577
|
+
# Try and find lost coin
|
|
1578
|
+
await api_1.did_find_lost_did({"coin_id": origin_coin.name().hex()})
|
|
1579
|
+
did_wallets = list(
|
|
1580
|
+
filter(
|
|
1581
|
+
lambda w: (w.type == WalletType.DECENTRALIZED_ID),
|
|
1582
|
+
await wallet_node_2.wallet_state_manager.get_all_wallet_info_entries(),
|
|
1443
1583
|
)
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
did_wallet_10 = await DIDWallet.create_new_did_wallet_from_recovery(
|
|
1461
|
-
wallet_node_2.wallet_state_manager,
|
|
1462
|
-
wallet2,
|
|
1463
|
-
backup_data,
|
|
1464
|
-
)
|
|
1465
|
-
assert did_wallet_10.did_info.origin_coin is not None
|
|
1466
|
-
resp = await api_1.did_find_lost_did({"coin_id": did_wallet_10.did_info.origin_coin.name().hex()})
|
|
1467
|
-
assert resp["success"]
|
|
1468
|
-
await time_out_assert(15, did_wallet_10.get_confirmed_balance, 101)
|
|
1469
|
-
await time_out_assert(15, did_wallet_10.get_unconfirmed_balance, 101)
|
|
1470
|
-
|
|
1471
|
-
# Check we can recover an auto-discarded DID
|
|
1472
|
-
did_wallet_9 = wallet_node_2.wallet_state_manager.get_wallet(
|
|
1473
|
-
id=uint32(did_wallets[8].id), required_type=DIDWallet
|
|
1584
|
+
)
|
|
1585
|
+
assert len(did_wallets) == 10
|
|
1586
|
+
|
|
1587
|
+
# Check we can still manually add new DIDs while at cap
|
|
1588
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet2)
|
|
1589
|
+
async with wallet2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1590
|
+
ph = await action_scope.get_puzzle_hash(wallet2.wallet_state_manager)
|
|
1591
|
+
did_wallet_11: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
1592
|
+
wallet_node_2.wallet_state_manager,
|
|
1593
|
+
wallet2,
|
|
1594
|
+
uint64(101),
|
|
1595
|
+
action_scope,
|
|
1596
|
+
[bytes32(bytes(ph))],
|
|
1597
|
+
uint64(1),
|
|
1598
|
+
{"Twitter": "Test", "GitHub": "测试"},
|
|
1599
|
+
fee=fee,
|
|
1474
1600
|
)
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
lambda w: (w.type == WalletType.DECENTRALIZED_ID),
|
|
1485
|
-
await wallet_node_2.wallet_state_manager.get_all_wallet_info_entries(),
|
|
1486
|
-
)
|
|
1601
|
+
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1602
|
+
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node, wallet_node_2])
|
|
1603
|
+
await time_out_assert(15, did_wallet_11.get_confirmed_balance, 101)
|
|
1604
|
+
await time_out_assert(15, did_wallet_11.get_unconfirmed_balance, 101)
|
|
1605
|
+
|
|
1606
|
+
did_wallets = list(
|
|
1607
|
+
filter(
|
|
1608
|
+
lambda w: (w.type == WalletType.DECENTRALIZED_ID),
|
|
1609
|
+
await wallet_node_2.wallet_state_manager.get_all_wallet_info_entries(),
|
|
1487
1610
|
)
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1611
|
+
)
|
|
1612
|
+
assert len(did_wallets) == 11
|
|
1613
|
+
|
|
1614
|
+
|
|
1615
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1616
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
1617
|
+
@pytest.mark.parametrize(
|
|
1618
|
+
"use_alternate_recovery",
|
|
1619
|
+
[True, False],
|
|
1620
|
+
)
|
|
1621
|
+
@pytest.mark.anyio
|
|
1622
|
+
async def test_update_recovery_list(wallet_environments: WalletTestFramework, use_alternate_recovery: bool):
|
|
1623
|
+
env = wallet_environments.environments[0]
|
|
1624
|
+
wallet_node = env.node
|
|
1625
|
+
wallet = env.xch_wallet
|
|
1626
|
+
|
|
1627
|
+
env.wallet_aliases = {
|
|
1628
|
+
"xch": 1,
|
|
1629
|
+
"did": 2,
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1633
|
+
ph = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
|
|
1634
|
+
did_wallet_1: DIDWallet = await make_did_wallet(
|
|
1635
|
+
wallet_node.wallet_state_manager,
|
|
1636
|
+
wallet,
|
|
1637
|
+
uint64(101),
|
|
1638
|
+
action_scope,
|
|
1639
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
1497
1640
|
)
|
|
1498
|
-
assert len(did_wallets) == 10
|
|
1499
1641
|
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1642
|
+
await wallet_environments.process_pending_states(
|
|
1643
|
+
[
|
|
1644
|
+
WalletStateTransition(
|
|
1645
|
+
pre_block_balance_updates={
|
|
1646
|
+
"xch": {
|
|
1647
|
+
"set_remainder": True,
|
|
1648
|
+
},
|
|
1649
|
+
"did": {
|
|
1650
|
+
"init": True,
|
|
1651
|
+
"unconfirmed_wallet_balance": 101,
|
|
1652
|
+
"pending_change": 101,
|
|
1653
|
+
"pending_coin_removal_count": 1,
|
|
1654
|
+
},
|
|
1655
|
+
},
|
|
1656
|
+
post_block_balance_updates={
|
|
1657
|
+
"xch": {
|
|
1658
|
+
"set_remainder": True,
|
|
1659
|
+
},
|
|
1660
|
+
"did": {
|
|
1661
|
+
"confirmed_wallet_balance": 101,
|
|
1662
|
+
"spendable_balance": 101,
|
|
1663
|
+
"max_send_amount": 101,
|
|
1664
|
+
"unspent_coin_count": 1,
|
|
1665
|
+
"pending_change": -101,
|
|
1666
|
+
"pending_coin_removal_count": -1,
|
|
1667
|
+
},
|
|
1668
|
+
},
|
|
1669
|
+
),
|
|
1670
|
+
]
|
|
1671
|
+
)
|
|
1672
|
+
await did_wallet_1.update_recovery_list([ph], uint64(1))
|
|
1673
|
+
async with did_wallet_1.wallet_state_manager.new_action_scope(
|
|
1674
|
+
wallet_environments.tx_config, push=True
|
|
1675
|
+
) as action_scope:
|
|
1676
|
+
await did_wallet_1.create_update_spend(action_scope)
|
|
1518
1677
|
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1678
|
+
await wallet_environments.process_pending_states(
|
|
1679
|
+
[
|
|
1680
|
+
WalletStateTransition(
|
|
1681
|
+
pre_block_balance_updates={
|
|
1682
|
+
"did": {
|
|
1683
|
+
"set_remainder": True,
|
|
1684
|
+
},
|
|
1685
|
+
},
|
|
1686
|
+
post_block_balance_updates={
|
|
1687
|
+
"did": {
|
|
1688
|
+
"set_remainder": True,
|
|
1689
|
+
},
|
|
1690
|
+
},
|
|
1691
|
+
),
|
|
1692
|
+
]
|
|
1693
|
+
)
|
|
1694
|
+
assert did_wallet_1.did_info.backup_ids[0] == bytes(ph)
|
|
1695
|
+
assert did_wallet_1.did_info.num_of_backup_ids_needed == 1
|
|
1696
|
+
|
|
1697
|
+
|
|
1698
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1699
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
|
|
1700
|
+
@pytest.mark.parametrize(
|
|
1701
|
+
"use_alternate_recovery",
|
|
1702
|
+
[True, False],
|
|
1703
|
+
)
|
|
1704
|
+
@pytest.mark.anyio
|
|
1705
|
+
async def test_get_info(wallet_environments: WalletTestFramework, use_alternate_recovery: bool):
|
|
1706
|
+
env_0 = wallet_environments.environments[0]
|
|
1707
|
+
env_1 = wallet_environments.environments[1]
|
|
1708
|
+
wallet_node_0 = env_0.node
|
|
1709
|
+
wallet_0 = env_0.xch_wallet
|
|
1710
|
+
wallet_1 = env_1.xch_wallet
|
|
1711
|
+
api_0 = env_0.rpc_client
|
|
1712
|
+
|
|
1713
|
+
env_0.wallet_aliases = {
|
|
1714
|
+
"xch": 1,
|
|
1715
|
+
"did": 2,
|
|
1716
|
+
}
|
|
1717
|
+
env_1.wallet_aliases = {
|
|
1718
|
+
"xch": 1,
|
|
1719
|
+
"did": 2,
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
fee = uint64(1000)
|
|
1723
|
+
did_amount = uint64(101)
|
|
1724
|
+
async with wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1725
|
+
ph_1 = await action_scope.get_puzzle_hash(wallet_1.wallet_state_manager)
|
|
1726
|
+
|
|
1727
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1728
|
+
did_wallet_1: DIDWallet = await make_did_wallet(
|
|
1729
|
+
wallet_node_0.wallet_state_manager,
|
|
1730
|
+
wallet_0,
|
|
1731
|
+
did_amount,
|
|
1732
|
+
action_scope,
|
|
1733
|
+
[],
|
|
1734
|
+
metadata={"twitter": "twitter"},
|
|
1735
|
+
fee=fee,
|
|
1736
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
1524
1737
|
)
|
|
1525
|
-
assert len(did_wallets) == 11
|
|
1526
|
-
|
|
1527
|
-
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1528
|
-
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
1529
|
-
@pytest.mark.anyio
|
|
1530
|
-
async def test_update_recovery_list(self, wallet_environments: WalletTestFramework):
|
|
1531
|
-
env = wallet_environments.environments[0]
|
|
1532
|
-
wallet_node = env.node
|
|
1533
|
-
wallet = env.xch_wallet
|
|
1534
|
-
|
|
1535
|
-
env.wallet_aliases = {
|
|
1536
|
-
"xch": 1,
|
|
1537
|
-
"did": 2,
|
|
1538
|
-
}
|
|
1539
1738
|
|
|
1540
|
-
|
|
1739
|
+
await wallet_environments.process_pending_states(
|
|
1740
|
+
[
|
|
1741
|
+
WalletStateTransition(
|
|
1742
|
+
pre_block_balance_updates={
|
|
1743
|
+
"xch": {
|
|
1744
|
+
"set_remainder": True,
|
|
1745
|
+
},
|
|
1746
|
+
"did": {
|
|
1747
|
+
"init": True,
|
|
1748
|
+
"unconfirmed_wallet_balance": did_amount,
|
|
1749
|
+
"pending_change": did_amount,
|
|
1750
|
+
"pending_coin_removal_count": 1,
|
|
1751
|
+
},
|
|
1752
|
+
},
|
|
1753
|
+
post_block_balance_updates={
|
|
1754
|
+
"xch": {
|
|
1755
|
+
"set_remainder": True,
|
|
1756
|
+
},
|
|
1757
|
+
"did": {
|
|
1758
|
+
"confirmed_wallet_balance": did_amount,
|
|
1759
|
+
"spendable_balance": did_amount,
|
|
1760
|
+
"max_send_amount": did_amount,
|
|
1761
|
+
"unspent_coin_count": 1,
|
|
1762
|
+
"pending_change": -did_amount,
|
|
1763
|
+
"pending_coin_removal_count": -1,
|
|
1764
|
+
},
|
|
1765
|
+
},
|
|
1766
|
+
),
|
|
1767
|
+
WalletStateTransition(),
|
|
1768
|
+
]
|
|
1769
|
+
)
|
|
1770
|
+
assert did_wallet_1.did_info.origin_coin is not None # mypy
|
|
1771
|
+
coin_id_as_bech32 = encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value)
|
|
1772
|
+
response = await api_0.get_did_info(DIDGetInfo(did_wallet_1.did_info.origin_coin.name().hex()))
|
|
1773
|
+
response_with_bech32 = await api_0.get_did_info(DIDGetInfo(coin_id_as_bech32))
|
|
1774
|
+
assert response == response_with_bech32
|
|
1775
|
+
assert response.did_id == coin_id_as_bech32
|
|
1776
|
+
assert response.launcher_id == did_wallet_1.did_info.origin_coin.name()
|
|
1777
|
+
assert did_wallet_1.did_info.current_inner is not None # mypy
|
|
1778
|
+
assert response.full_puzzle == create_singleton_puzzle(
|
|
1779
|
+
did_wallet_1.did_info.current_inner, did_wallet_1.did_info.origin_coin.name()
|
|
1780
|
+
)
|
|
1781
|
+
assert response.metadata["twitter"] == "twitter"
|
|
1782
|
+
assert response.latest_coin == (await did_wallet_1.get_coin()).name()
|
|
1783
|
+
assert response.num_verification == 0
|
|
1784
|
+
if use_alternate_recovery:
|
|
1785
|
+
assert response.recovery_list_hash is None
|
|
1786
|
+
else:
|
|
1787
|
+
assert response.recovery_list_hash == Program(Program.to([])).get_tree_hash()
|
|
1788
|
+
assert decode_puzzle_hash(response.p2_address) == response.hints[0]
|
|
1789
|
+
|
|
1790
|
+
# Test non-singleton coin
|
|
1791
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1792
|
+
coin = (await wallet_0.select_coins(uint64(1), action_scope)).pop()
|
|
1793
|
+
assert coin.amount % 2 == 1
|
|
1794
|
+
coin_id = coin.name()
|
|
1795
|
+
with pytest.raises(ValueError, match="The coin is not a DID."):
|
|
1796
|
+
await api_0.get_did_info(DIDGetInfo(coin_id.hex()))
|
|
1797
|
+
|
|
1798
|
+
# Test multiple odd coins
|
|
1799
|
+
odd_amount = uint64(1)
|
|
1800
|
+
async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1801
|
+
async with action_scope.use() as interface:
|
|
1802
|
+
interface.side_effects.selected_coins.append(coin)
|
|
1803
|
+
coin_1 = (await wallet_0.select_coins(odd_amount, action_scope)).pop()
|
|
1804
|
+
assert coin_1.amount % 2 == 0
|
|
1805
|
+
async with wallet_0.wallet_state_manager.new_action_scope(
|
|
1806
|
+
wallet_environments.tx_config.override(excluded_coin_ids=[coin_id]), push=True
|
|
1807
|
+
) as action_scope:
|
|
1808
|
+
await wallet_0.generate_signed_transaction([odd_amount], [ph_1], action_scope, fee)
|
|
1809
|
+
|
|
1810
|
+
await wallet_environments.process_pending_states(
|
|
1811
|
+
[
|
|
1812
|
+
WalletStateTransition(
|
|
1813
|
+
pre_block_balance_updates={
|
|
1814
|
+
"xch": {
|
|
1815
|
+
"unconfirmed_wallet_balance": -odd_amount - fee,
|
|
1816
|
+
"set_remainder": True,
|
|
1817
|
+
},
|
|
1818
|
+
"did": {
|
|
1819
|
+
"set_remainder": True,
|
|
1820
|
+
},
|
|
1821
|
+
},
|
|
1822
|
+
post_block_balance_updates={
|
|
1823
|
+
"xch": {
|
|
1824
|
+
"confirmed_wallet_balance": -odd_amount - fee,
|
|
1825
|
+
"set_remainder": True,
|
|
1826
|
+
},
|
|
1827
|
+
"did": {
|
|
1828
|
+
"set_remainder": True,
|
|
1829
|
+
},
|
|
1830
|
+
},
|
|
1831
|
+
),
|
|
1832
|
+
WalletStateTransition(
|
|
1833
|
+
pre_block_balance_updates={
|
|
1834
|
+
"xch": {
|
|
1835
|
+
"unconfirmed_wallet_balance": 0,
|
|
1836
|
+
"set_remainder": True,
|
|
1837
|
+
}
|
|
1838
|
+
},
|
|
1839
|
+
post_block_balance_updates={
|
|
1840
|
+
"xch": {
|
|
1841
|
+
"confirmed_wallet_balance": odd_amount,
|
|
1842
|
+
"set_remainder": True,
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1845
|
+
),
|
|
1846
|
+
]
|
|
1847
|
+
)
|
|
1848
|
+
|
|
1849
|
+
with pytest.raises(ValueError, match="This is not a singleton, multiple children coins found."):
|
|
1850
|
+
await api_0.get_did_info(DIDGetInfo(coin_1.name().hex()))
|
|
1541
1851
|
|
|
1542
|
-
async with wallet.wallet_state_manager.new_action_scope(
|
|
1543
|
-
wallet_environments.tx_config, push=True
|
|
1544
|
-
) as action_scope:
|
|
1545
|
-
did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
1546
|
-
wallet_node.wallet_state_manager, wallet, uint64(101), action_scope, []
|
|
1547
|
-
)
|
|
1548
1852
|
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1853
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1854
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
1855
|
+
@pytest.mark.parametrize(
|
|
1856
|
+
"use_alternate_recovery",
|
|
1857
|
+
[True, False],
|
|
1858
|
+
)
|
|
1859
|
+
@pytest.mark.anyio
|
|
1860
|
+
async def test_message_spend(wallet_environments: WalletTestFramework, use_alternate_recovery: bool):
|
|
1861
|
+
env = wallet_environments.environments[0]
|
|
1862
|
+
wallet_node = env.node
|
|
1863
|
+
wallet = env.xch_wallet
|
|
1864
|
+
api_0 = env.rpc_api
|
|
1865
|
+
|
|
1866
|
+
env.wallet_aliases = {
|
|
1867
|
+
"xch": 1,
|
|
1868
|
+
"did": 2,
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
fee = uint64(1000)
|
|
1872
|
+
|
|
1873
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1874
|
+
did_wallet_1: DIDWallet = await make_did_wallet(
|
|
1875
|
+
wallet_node.wallet_state_manager,
|
|
1876
|
+
wallet,
|
|
1877
|
+
uint64(101),
|
|
1878
|
+
action_scope,
|
|
1879
|
+
[],
|
|
1880
|
+
fee=fee,
|
|
1881
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
1882
|
+
)
|
|
1883
|
+
await wallet_environments.process_pending_states(
|
|
1884
|
+
[
|
|
1885
|
+
WalletStateTransition(
|
|
1886
|
+
pre_block_balance_updates={
|
|
1887
|
+
"xch": {
|
|
1888
|
+
"set_remainder": True,
|
|
1562
1889
|
},
|
|
1563
|
-
|
|
1564
|
-
"
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
"
|
|
1568
|
-
"confirmed_wallet_balance": 101,
|
|
1569
|
-
"spendable_balance": 101,
|
|
1570
|
-
"max_send_amount": 101,
|
|
1571
|
-
"unspent_coin_count": 1,
|
|
1572
|
-
"pending_change": -101,
|
|
1573
|
-
"pending_coin_removal_count": -1,
|
|
1574
|
-
},
|
|
1890
|
+
"did": {
|
|
1891
|
+
"init": True,
|
|
1892
|
+
"unconfirmed_wallet_balance": 101,
|
|
1893
|
+
"pending_change": 101,
|
|
1894
|
+
"pending_coin_removal_count": 1,
|
|
1575
1895
|
},
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
async with did_wallet_1.wallet_state_manager.new_action_scope(
|
|
1581
|
-
wallet_environments.tx_config, push=True
|
|
1582
|
-
) as action_scope:
|
|
1583
|
-
await did_wallet_1.create_update_spend(action_scope)
|
|
1584
|
-
|
|
1585
|
-
await wallet_environments.process_pending_states(
|
|
1586
|
-
[
|
|
1587
|
-
WalletStateTransition(
|
|
1588
|
-
pre_block_balance_updates={
|
|
1589
|
-
"did": {
|
|
1590
|
-
"set_remainder": True,
|
|
1591
|
-
},
|
|
1896
|
+
},
|
|
1897
|
+
post_block_balance_updates={
|
|
1898
|
+
"xch": {
|
|
1899
|
+
"set_remainder": True,
|
|
1592
1900
|
},
|
|
1593
|
-
|
|
1594
|
-
"
|
|
1595
|
-
|
|
1596
|
-
|
|
1901
|
+
"did": {
|
|
1902
|
+
"confirmed_wallet_balance": 101,
|
|
1903
|
+
"spendable_balance": 101,
|
|
1904
|
+
"max_send_amount": 101,
|
|
1905
|
+
"unspent_coin_count": 1,
|
|
1906
|
+
"pending_change": -101,
|
|
1907
|
+
"pending_coin_removal_count": -1,
|
|
1597
1908
|
},
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
env_1 = wallet_environments.environments[1]
|
|
1610
|
-
wallet_node_0 = env_0.node
|
|
1611
|
-
wallet_0 = env_0.xch_wallet
|
|
1612
|
-
wallet_1 = env_1.xch_wallet
|
|
1613
|
-
api_0 = env_0.rpc_api
|
|
1614
|
-
|
|
1615
|
-
env_0.wallet_aliases = {
|
|
1616
|
-
"xch": 1,
|
|
1617
|
-
"did": 2,
|
|
1618
|
-
}
|
|
1619
|
-
env_1.wallet_aliases = {
|
|
1620
|
-
"xch": 1,
|
|
1621
|
-
"did": 2,
|
|
1622
|
-
}
|
|
1909
|
+
},
|
|
1910
|
+
),
|
|
1911
|
+
]
|
|
1912
|
+
)
|
|
1913
|
+
response = await api_0.did_message_spend(
|
|
1914
|
+
{"wallet_id": did_wallet_1.wallet_id, "coin_announcements": ["0abc"], "puzzle_announcements": ["0def"]}
|
|
1915
|
+
)
|
|
1916
|
+
spend = response["spend_bundle"].coin_spends[0]
|
|
1917
|
+
conditions = conditions_dict_for_solution(
|
|
1918
|
+
spend.puzzle_reveal, spend.solution, wallet.wallet_state_manager.constants.MAX_BLOCK_COST_CLVM
|
|
1919
|
+
)
|
|
1623
1920
|
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1921
|
+
assert len(conditions[ConditionOpcode.CREATE_COIN_ANNOUNCEMENT]) == 1
|
|
1922
|
+
assert conditions[ConditionOpcode.CREATE_COIN_ANNOUNCEMENT][0].vars[0].hex() == "0abc"
|
|
1923
|
+
assert len(conditions[ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT]) == 1
|
|
1924
|
+
assert conditions[ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT][0].vars[0].hex() == "0def"
|
|
1627
1925
|
|
|
1628
|
-
async with wallet_0.wallet_state_manager.new_action_scope(
|
|
1629
|
-
wallet_environments.tx_config, push=True
|
|
1630
|
-
) as action_scope:
|
|
1631
|
-
did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
1632
|
-
wallet_node_0.wallet_state_manager,
|
|
1633
|
-
wallet_0,
|
|
1634
|
-
did_amount,
|
|
1635
|
-
action_scope,
|
|
1636
|
-
[],
|
|
1637
|
-
metadata={"twitter": "twitter"},
|
|
1638
|
-
fee=fee,
|
|
1639
|
-
)
|
|
1640
1926
|
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
]
|
|
1671
|
-
)
|
|
1672
|
-
assert did_wallet_1.did_info.origin_coin is not None # mypy
|
|
1673
|
-
response = await api_0.did_get_info({"coin_id": did_wallet_1.did_info.origin_coin.name().hex()})
|
|
1674
|
-
assert response["did_id"] == encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value)
|
|
1675
|
-
assert response["launcher_id"] == did_wallet_1.did_info.origin_coin.name().hex()
|
|
1676
|
-
assert did_wallet_1.did_info.current_inner is not None # mypy
|
|
1677
|
-
assert response["full_puzzle"].to_program() == create_singleton_puzzle(
|
|
1678
|
-
did_wallet_1.did_info.current_inner, did_wallet_1.did_info.origin_coin.name()
|
|
1927
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1928
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
1929
|
+
@pytest.mark.parametrize(
|
|
1930
|
+
"use_alternate_recovery",
|
|
1931
|
+
[True, False],
|
|
1932
|
+
)
|
|
1933
|
+
@pytest.mark.anyio
|
|
1934
|
+
async def test_update_metadata(wallet_environments: WalletTestFramework, use_alternate_recovery: bool):
|
|
1935
|
+
env = wallet_environments.environments[0]
|
|
1936
|
+
wallet_node = env.node
|
|
1937
|
+
wallet = env.xch_wallet
|
|
1938
|
+
|
|
1939
|
+
env.wallet_aliases = {
|
|
1940
|
+
"xch": 1,
|
|
1941
|
+
"did": 2,
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
fee = uint64(1000)
|
|
1945
|
+
did_amount = uint64(101)
|
|
1946
|
+
|
|
1947
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
1948
|
+
did_wallet_1: DIDWallet = await make_did_wallet(
|
|
1949
|
+
wallet_node.wallet_state_manager,
|
|
1950
|
+
wallet,
|
|
1951
|
+
did_amount,
|
|
1952
|
+
action_scope,
|
|
1953
|
+
[],
|
|
1954
|
+
fee=fee,
|
|
1955
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
1679
1956
|
)
|
|
1680
|
-
assert response["metadata"]["twitter"] == "twitter"
|
|
1681
|
-
assert response["latest_coin"] == (await did_wallet_1.get_coin()).name().hex()
|
|
1682
|
-
assert response["num_verification"] == 0
|
|
1683
|
-
assert response["recovery_list_hash"] == Program(Program.to([])).get_tree_hash().hex()
|
|
1684
|
-
assert decode_puzzle_hash(response["p2_address"]).hex() == response["hints"][0]
|
|
1685
|
-
|
|
1686
|
-
# Test non-singleton coin
|
|
1687
|
-
async with wallet_0.wallet_state_manager.new_action_scope(
|
|
1688
|
-
wallet_environments.tx_config, push=True
|
|
1689
|
-
) as action_scope:
|
|
1690
|
-
coin = (await wallet_0.select_coins(uint64(1), action_scope)).pop()
|
|
1691
|
-
assert coin.amount % 2 == 1
|
|
1692
|
-
coin_id = coin.name()
|
|
1693
|
-
response = await api_0.did_get_info({"coin_id": coin_id.hex()})
|
|
1694
|
-
assert not response["success"]
|
|
1695
|
-
|
|
1696
|
-
# Test multiple odd coins
|
|
1697
|
-
odd_amount = uint64(1)
|
|
1698
|
-
async with wallet_0.wallet_state_manager.new_action_scope(
|
|
1699
|
-
wallet_environments.tx_config, push=True
|
|
1700
|
-
) as action_scope:
|
|
1701
|
-
async with action_scope.use() as interface:
|
|
1702
|
-
interface.side_effects.selected_coins.append(coin)
|
|
1703
|
-
coin_1 = (await wallet_0.select_coins(odd_amount, action_scope)).pop()
|
|
1704
|
-
assert coin_1.amount % 2 == 0
|
|
1705
|
-
async with wallet_0.wallet_state_manager.new_action_scope(
|
|
1706
|
-
wallet_environments.tx_config.override(excluded_coin_ids=[coin_id]), push=True
|
|
1707
|
-
) as action_scope:
|
|
1708
|
-
await wallet_0.generate_signed_transaction([odd_amount], [ph_1], action_scope, fee)
|
|
1709
1957
|
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
"set_remainder": True,
|
|
1717
|
-
},
|
|
1718
|
-
"did": {
|
|
1719
|
-
"set_remainder": True,
|
|
1720
|
-
},
|
|
1958
|
+
await wallet_environments.process_pending_states(
|
|
1959
|
+
[
|
|
1960
|
+
WalletStateTransition(
|
|
1961
|
+
pre_block_balance_updates={
|
|
1962
|
+
"xch": {
|
|
1963
|
+
"set_remainder": True,
|
|
1721
1964
|
},
|
|
1722
|
-
|
|
1723
|
-
"
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
"did": {
|
|
1728
|
-
"set_remainder": True,
|
|
1729
|
-
},
|
|
1965
|
+
"did": {
|
|
1966
|
+
"init": True,
|
|
1967
|
+
"unconfirmed_wallet_balance": 101,
|
|
1968
|
+
"pending_change": 101,
|
|
1969
|
+
"pending_coin_removal_count": 1,
|
|
1730
1970
|
},
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
"
|
|
1735
|
-
"unconfirmed_wallet_balance": 0,
|
|
1736
|
-
"set_remainder": True,
|
|
1737
|
-
}
|
|
1971
|
+
},
|
|
1972
|
+
post_block_balance_updates={
|
|
1973
|
+
"xch": {
|
|
1974
|
+
"set_remainder": True,
|
|
1738
1975
|
},
|
|
1739
|
-
|
|
1740
|
-
"
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1976
|
+
"did": {
|
|
1977
|
+
"confirmed_wallet_balance": 101,
|
|
1978
|
+
"spendable_balance": 101,
|
|
1979
|
+
"max_send_amount": 101,
|
|
1980
|
+
"unspent_coin_count": 1,
|
|
1981
|
+
"pending_change": -101,
|
|
1982
|
+
"pending_coin_removal_count": -1,
|
|
1744
1983
|
},
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1984
|
+
},
|
|
1985
|
+
),
|
|
1986
|
+
]
|
|
1987
|
+
)
|
|
1748
1988
|
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1753
|
-
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
1754
|
-
@pytest.mark.anyio
|
|
1755
|
-
async def test_message_spend(self, wallet_environments: WalletTestFramework):
|
|
1756
|
-
env = wallet_environments.environments[0]
|
|
1757
|
-
wallet_node = env.node
|
|
1758
|
-
wallet = env.xch_wallet
|
|
1759
|
-
api_0 = env.rpc_api
|
|
1760
|
-
|
|
1761
|
-
env.wallet_aliases = {
|
|
1762
|
-
"xch": 1,
|
|
1763
|
-
"did": 2,
|
|
1764
|
-
}
|
|
1989
|
+
assert did_wallet_1.did_info.current_inner is not None # mypy
|
|
1990
|
+
puzhash = did_wallet_1.did_info.current_inner.get_tree_hash()
|
|
1991
|
+
parent_num = get_parent_num(did_wallet_1)
|
|
1765
1992
|
|
|
1766
|
-
|
|
1993
|
+
bad_metadata = {"Twitter": {"url": "http://www.twitter.com"}}
|
|
1994
|
+
with pytest.raises(ValueError) as e:
|
|
1995
|
+
await did_wallet_1.update_metadata(bad_metadata) # type: ignore
|
|
1996
|
+
assert e.match("Metadata key value pairs must be strings.")
|
|
1767
1997
|
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
await
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
"
|
|
1782
|
-
|
|
1783
|
-
"unconfirmed_wallet_balance": 101,
|
|
1784
|
-
"pending_change": 101,
|
|
1785
|
-
"pending_coin_removal_count": 1,
|
|
1786
|
-
},
|
|
1998
|
+
metadata = {}
|
|
1999
|
+
metadata["Twitter"] = "http://www.twitter.com"
|
|
2000
|
+
await did_wallet_1.update_metadata(metadata)
|
|
2001
|
+
async with did_wallet_1.wallet_state_manager.new_action_scope(
|
|
2002
|
+
wallet_environments.tx_config, push=True
|
|
2003
|
+
) as action_scope:
|
|
2004
|
+
await did_wallet_1.create_update_spend(action_scope, fee)
|
|
2005
|
+
|
|
2006
|
+
await wallet_environments.process_pending_states(
|
|
2007
|
+
[
|
|
2008
|
+
WalletStateTransition(
|
|
2009
|
+
pre_block_balance_updates={
|
|
2010
|
+
"xch": {
|
|
2011
|
+
"unconfirmed_wallet_balance": -fee,
|
|
2012
|
+
"set_remainder": True,
|
|
1787
2013
|
},
|
|
1788
|
-
|
|
1789
|
-
"
|
|
1790
|
-
|
|
1791
|
-
},
|
|
1792
|
-
"did": {
|
|
1793
|
-
"confirmed_wallet_balance": 101,
|
|
1794
|
-
"spendable_balance": 101,
|
|
1795
|
-
"max_send_amount": 101,
|
|
1796
|
-
"unspent_coin_count": 1,
|
|
1797
|
-
"pending_change": -101,
|
|
1798
|
-
"pending_coin_removal_count": -1,
|
|
1799
|
-
},
|
|
2014
|
+
"did": {
|
|
2015
|
+
"unconfirmed_wallet_balance": 0,
|
|
2016
|
+
"set_remainder": True,
|
|
1800
2017
|
},
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
2018
|
+
},
|
|
2019
|
+
post_block_balance_updates={
|
|
2020
|
+
"xch": {
|
|
2021
|
+
"confirmed_wallet_balance": -fee,
|
|
2022
|
+
"set_remainder": True,
|
|
2023
|
+
},
|
|
2024
|
+
"did": {
|
|
2025
|
+
"confirmed_wallet_balance": 0,
|
|
2026
|
+
"set_remainder": True,
|
|
2027
|
+
},
|
|
2028
|
+
},
|
|
2029
|
+
),
|
|
2030
|
+
]
|
|
2031
|
+
)
|
|
1811
2032
|
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1818
|
-
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
1819
|
-
@pytest.mark.anyio
|
|
1820
|
-
async def test_update_metadata(self, wallet_environments: WalletTestFramework):
|
|
1821
|
-
env = wallet_environments.environments[0]
|
|
1822
|
-
wallet_node = env.node
|
|
1823
|
-
wallet = env.xch_wallet
|
|
1824
|
-
|
|
1825
|
-
env.wallet_aliases = {
|
|
1826
|
-
"xch": 1,
|
|
1827
|
-
"did": 2,
|
|
1828
|
-
}
|
|
2033
|
+
assert get_parent_num(did_wallet_1) == parent_num + 2
|
|
2034
|
+
assert did_wallet_1.did_info.current_inner is not None # mypy
|
|
2035
|
+
assert puzhash != did_wallet_1.did_info.current_inner.get_tree_hash()
|
|
2036
|
+
assert did_wallet_1.did_info.metadata.find("Twitter") > 0
|
|
1829
2037
|
|
|
1830
|
-
fee = uint64(1000)
|
|
1831
|
-
did_amount = uint64(101)
|
|
1832
2038
|
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
2039
|
+
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
2040
|
+
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
2041
|
+
@pytest.mark.anyio
|
|
2042
|
+
async def test_did_sign_message(wallet_environments: WalletTestFramework):
|
|
2043
|
+
env = wallet_environments.environments[0]
|
|
2044
|
+
wallet_node = env.node
|
|
2045
|
+
wallet = env.xch_wallet
|
|
2046
|
+
api_0 = env.rpc_api
|
|
2047
|
+
|
|
2048
|
+
env.wallet_aliases = {
|
|
2049
|
+
"xch": 1,
|
|
2050
|
+
"did": 2,
|
|
2051
|
+
}
|
|
2052
|
+
fee = uint64(1000)
|
|
2053
|
+
|
|
2054
|
+
async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
|
|
2055
|
+
ph = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
|
|
2056
|
+
did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
2057
|
+
wallet_node.wallet_state_manager,
|
|
2058
|
+
wallet,
|
|
2059
|
+
uint64(101),
|
|
2060
|
+
action_scope,
|
|
2061
|
+
[ph],
|
|
2062
|
+
uint64(1),
|
|
2063
|
+
{"Twitter": "Test", "GitHub": "测试"},
|
|
2064
|
+
fee=fee,
|
|
2065
|
+
)
|
|
2066
|
+
assert did_wallet_1.get_name() == "Profile 1"
|
|
1839
2067
|
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
},
|
|
1847
|
-
"did": {
|
|
1848
|
-
"init": True,
|
|
1849
|
-
"unconfirmed_wallet_balance": 101,
|
|
1850
|
-
"pending_change": 101,
|
|
1851
|
-
"pending_coin_removal_count": 1,
|
|
1852
|
-
},
|
|
2068
|
+
await wallet_environments.process_pending_states(
|
|
2069
|
+
[
|
|
2070
|
+
WalletStateTransition(
|
|
2071
|
+
pre_block_balance_updates={
|
|
2072
|
+
"xch": {
|
|
2073
|
+
"set_remainder": True,
|
|
1853
2074
|
},
|
|
1854
|
-
|
|
1855
|
-
"
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
"
|
|
1859
|
-
"confirmed_wallet_balance": 101,
|
|
1860
|
-
"spendable_balance": 101,
|
|
1861
|
-
"max_send_amount": 101,
|
|
1862
|
-
"unspent_coin_count": 1,
|
|
1863
|
-
"pending_change": -101,
|
|
1864
|
-
"pending_coin_removal_count": -1,
|
|
1865
|
-
},
|
|
2075
|
+
"did": {
|
|
2076
|
+
"init": True,
|
|
2077
|
+
"unconfirmed_wallet_balance": 101,
|
|
2078
|
+
"pending_change": 101,
|
|
2079
|
+
"pending_coin_removal_count": 1,
|
|
1866
2080
|
},
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
2081
|
+
},
|
|
2082
|
+
post_block_balance_updates={
|
|
2083
|
+
"xch": {
|
|
2084
|
+
"set_remainder": True,
|
|
2085
|
+
},
|
|
2086
|
+
"did": {
|
|
2087
|
+
"confirmed_wallet_balance": 101,
|
|
2088
|
+
"spendable_balance": 101,
|
|
2089
|
+
"max_send_amount": 101,
|
|
2090
|
+
"unspent_coin_count": 1,
|
|
2091
|
+
"pending_change": -101,
|
|
2092
|
+
"pending_coin_removal_count": -1,
|
|
2093
|
+
},
|
|
2094
|
+
},
|
|
2095
|
+
),
|
|
2096
|
+
]
|
|
2097
|
+
)
|
|
2098
|
+
# Test general string
|
|
2099
|
+
assert did_wallet_1.did_info.origin_coin is not None # mypy
|
|
2100
|
+
message = "Hello World"
|
|
2101
|
+
assert did_wallet_1.did_info.origin_coin is not None
|
|
2102
|
+
response = await api_0.sign_message_by_id(
|
|
2103
|
+
{
|
|
2104
|
+
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
|
|
2105
|
+
"message": message,
|
|
2106
|
+
}
|
|
2107
|
+
)
|
|
2108
|
+
puzzle: Program = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, message))
|
|
2109
|
+
assert AugSchemeMPL.verify(
|
|
2110
|
+
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
|
|
2111
|
+
puzzle.get_tree_hash(),
|
|
2112
|
+
G2Element.from_bytes(bytes.fromhex(response["signature"])),
|
|
2113
|
+
)
|
|
2114
|
+
# Test hex string
|
|
2115
|
+
message = "0123456789ABCDEF"
|
|
2116
|
+
response = await api_0.sign_message_by_id(
|
|
2117
|
+
{
|
|
2118
|
+
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
|
|
2119
|
+
"message": message,
|
|
2120
|
+
"is_hex": True,
|
|
2121
|
+
}
|
|
2122
|
+
)
|
|
2123
|
+
puzzle = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, bytes.fromhex(message)))
|
|
1870
2124
|
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
2125
|
+
assert AugSchemeMPL.verify(
|
|
2126
|
+
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
|
|
2127
|
+
puzzle.get_tree_hash(),
|
|
2128
|
+
G2Element.from_bytes(bytes.fromhex(response["signature"])),
|
|
2129
|
+
)
|
|
1874
2130
|
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
2131
|
+
# Test BLS sign string
|
|
2132
|
+
message = "Hello World"
|
|
2133
|
+
assert did_wallet_1.did_info.origin_coin is not None
|
|
2134
|
+
response = await api_0.sign_message_by_id(
|
|
2135
|
+
{
|
|
2136
|
+
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
|
|
2137
|
+
"message": message,
|
|
2138
|
+
"is_hex": "False",
|
|
2139
|
+
"safe_mode": "False",
|
|
2140
|
+
}
|
|
2141
|
+
)
|
|
1879
2142
|
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
2143
|
+
assert AugSchemeMPL.verify(
|
|
2144
|
+
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
|
|
2145
|
+
bytes(message, "utf-8"),
|
|
2146
|
+
G2Element.from_bytes(bytes.fromhex(response["signature"])),
|
|
2147
|
+
)
|
|
2148
|
+
# Test BLS sign hex
|
|
2149
|
+
message = "0123456789ABCDEF"
|
|
2150
|
+
assert did_wallet_1.did_info.origin_coin is not None
|
|
2151
|
+
response = await api_0.sign_message_by_id(
|
|
2152
|
+
{
|
|
2153
|
+
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
|
|
2154
|
+
"message": message,
|
|
2155
|
+
"is_hex": True,
|
|
2156
|
+
"safe_mode": False,
|
|
2157
|
+
}
|
|
2158
|
+
)
|
|
1887
2159
|
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
"unconfirmed_wallet_balance": -fee,
|
|
1894
|
-
"set_remainder": True,
|
|
1895
|
-
},
|
|
1896
|
-
"did": {
|
|
1897
|
-
"unconfirmed_wallet_balance": 0,
|
|
1898
|
-
"set_remainder": True,
|
|
1899
|
-
},
|
|
1900
|
-
},
|
|
1901
|
-
post_block_balance_updates={
|
|
1902
|
-
"xch": {
|
|
1903
|
-
"confirmed_wallet_balance": -fee,
|
|
1904
|
-
"set_remainder": True,
|
|
1905
|
-
},
|
|
1906
|
-
"did": {
|
|
1907
|
-
"confirmed_wallet_balance": 0,
|
|
1908
|
-
"set_remainder": True,
|
|
1909
|
-
},
|
|
1910
|
-
},
|
|
1911
|
-
),
|
|
1912
|
-
]
|
|
1913
|
-
)
|
|
2160
|
+
assert AugSchemeMPL.verify(
|
|
2161
|
+
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
|
|
2162
|
+
bytes.fromhex(message),
|
|
2163
|
+
G2Element.from_bytes(bytes.fromhex(response["signature"])),
|
|
2164
|
+
)
|
|
1914
2165
|
|
|
1915
|
-
assert get_parent_num(did_wallet_1) == parent_num + 2
|
|
1916
|
-
assert did_wallet_1.did_info.current_inner is not None # mypy
|
|
1917
|
-
assert puzhash != did_wallet_1.did_info.current_inner.get_tree_hash()
|
|
1918
|
-
assert did_wallet_1.did_info.metadata.find("Twitter") > 0
|
|
1919
|
-
|
|
1920
|
-
@pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="irrelevant")
|
|
1921
|
-
@pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
|
|
1922
|
-
@pytest.mark.anyio
|
|
1923
|
-
async def test_did_sign_message(self, wallet_environments: WalletTestFramework):
|
|
1924
|
-
env = wallet_environments.environments[0]
|
|
1925
|
-
wallet_node = env.node
|
|
1926
|
-
wallet = env.xch_wallet
|
|
1927
|
-
api_0 = env.rpc_api
|
|
1928
|
-
|
|
1929
|
-
env.wallet_aliases = {
|
|
1930
|
-
"xch": 1,
|
|
1931
|
-
"did": 2,
|
|
1932
|
-
}
|
|
1933
|
-
fee = uint64(1000)
|
|
1934
|
-
ph = await wallet.get_new_puzzlehash()
|
|
1935
2166
|
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
2167
|
+
@pytest.mark.parametrize(
|
|
2168
|
+
"trusted",
|
|
2169
|
+
[True, False],
|
|
2170
|
+
)
|
|
2171
|
+
@pytest.mark.anyio
|
|
2172
|
+
async def test_create_did_with_recovery_list(
|
|
2173
|
+
self_hostname: str, two_nodes_two_wallets_with_same_keys: OldSimulatorsAndWallets, trusted: bool
|
|
2174
|
+
) -> None:
|
|
2175
|
+
"""
|
|
2176
|
+
A DID is created on-chain in client0, causing a DID Wallet to be created in client1, which shares the same key.
|
|
2177
|
+
This can happen if someone uses the same key on multiple computers, or is syncing a wallet from scratch.
|
|
2178
|
+
|
|
2179
|
+
For this test, we assign a recovery list hash at DID creation time, but the recovery list is not yet available
|
|
2180
|
+
to the wallet_node that the DID Wallet is being created in (client1).
|
|
2181
|
+
|
|
2182
|
+
"""
|
|
2183
|
+
full_nodes, wallets, _ = two_nodes_two_wallets_with_same_keys
|
|
2184
|
+
full_node_api = full_nodes[0]
|
|
2185
|
+
full_node_server = full_node_api.server
|
|
2186
|
+
wallet_node_0, server_0 = wallets[0]
|
|
2187
|
+
wallet_node_1, server_1 = wallets[1]
|
|
2188
|
+
|
|
2189
|
+
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
2190
|
+
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
2191
|
+
|
|
2192
|
+
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2193
|
+
ph0 = await action_scope.get_puzzle_hash(wallet_0.wallet_state_manager)
|
|
2194
|
+
async with wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2195
|
+
ph1 = await action_scope.get_puzzle_hash(wallet_1.wallet_state_manager)
|
|
2196
|
+
|
|
2197
|
+
sk0 = await wallet_node_0.wallet_state_manager.get_private_key(ph0)
|
|
2198
|
+
sk1 = await wallet_node_1.wallet_state_manager.get_private_key(ph1)
|
|
2199
|
+
assert sk0 == sk1
|
|
2200
|
+
|
|
2201
|
+
if trusted:
|
|
2202
|
+
wallet_node_0.config["trusted_peers"] = {
|
|
2203
|
+
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2204
|
+
}
|
|
2205
|
+
wallet_node_1.config["trusted_peers"] = {
|
|
2206
|
+
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2207
|
+
}
|
|
1950
2208
|
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
"spendable_balance": 101,
|
|
1972
|
-
"max_send_amount": 101,
|
|
1973
|
-
"unspent_coin_count": 1,
|
|
1974
|
-
"pending_change": -101,
|
|
1975
|
-
"pending_coin_removal_count": -1,
|
|
1976
|
-
},
|
|
1977
|
-
},
|
|
1978
|
-
),
|
|
1979
|
-
]
|
|
1980
|
-
)
|
|
1981
|
-
# Test general string
|
|
1982
|
-
assert did_wallet_1.did_info.origin_coin is not None # mypy
|
|
1983
|
-
message = "Hello World"
|
|
1984
|
-
assert did_wallet_1.did_info.origin_coin is not None
|
|
1985
|
-
response = await api_0.sign_message_by_id(
|
|
1986
|
-
{
|
|
1987
|
-
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
|
|
1988
|
-
"message": message,
|
|
1989
|
-
}
|
|
2209
|
+
else:
|
|
2210
|
+
wallet_node_0.config["trusted_peers"] = {}
|
|
2211
|
+
wallet_node_1.config["trusted_peers"] = {}
|
|
2212
|
+
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2213
|
+
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2214
|
+
|
|
2215
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet_0)
|
|
2216
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet_1)
|
|
2217
|
+
|
|
2218
|
+
# Node 0 sets up a DID Wallet with a backup set, but num_of_backup_ids_needed=0
|
|
2219
|
+
# (a malformed solution, but legal for the clvm puzzle)
|
|
2220
|
+
recovery_list = [bytes32(bytes.fromhex("00" * 32))]
|
|
2221
|
+
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2222
|
+
did_wallet_0: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
2223
|
+
wallet_node_0.wallet_state_manager,
|
|
2224
|
+
wallet_0,
|
|
2225
|
+
uint64(101),
|
|
2226
|
+
action_scope,
|
|
2227
|
+
backups_ids=recovery_list,
|
|
2228
|
+
num_of_backup_ids_needed=uint64(0),
|
|
1990
2229
|
)
|
|
1991
|
-
puzzle: Program = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, message))
|
|
1992
|
-
assert AugSchemeMPL.verify(
|
|
1993
|
-
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
|
|
1994
|
-
puzzle.get_tree_hash(),
|
|
1995
|
-
G2Element.from_bytes(bytes.fromhex(response["signature"])),
|
|
1996
|
-
)
|
|
1997
|
-
# Test hex string
|
|
1998
|
-
message = "0123456789ABCDEF"
|
|
1999
|
-
response = await api_0.sign_message_by_id(
|
|
2000
|
-
{
|
|
2001
|
-
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
|
|
2002
|
-
"message": message,
|
|
2003
|
-
"is_hex": True,
|
|
2004
|
-
}
|
|
2005
|
-
)
|
|
2006
|
-
puzzle = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, bytes.fromhex(message)))
|
|
2007
2230
|
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
puzzle.get_tree_hash(),
|
|
2011
|
-
G2Element.from_bytes(bytes.fromhex(response["signature"])),
|
|
2012
|
-
)
|
|
2231
|
+
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
2232
|
+
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0])
|
|
2013
2233
|
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
response = await api_0.sign_message_by_id(
|
|
2018
|
-
{
|
|
2019
|
-
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
|
|
2020
|
-
"message": message,
|
|
2021
|
-
"is_hex": "False",
|
|
2022
|
-
"safe_mode": "False",
|
|
2023
|
-
}
|
|
2024
|
-
)
|
|
2234
|
+
await time_out_assert(15, did_wallet_0.get_confirmed_balance, 101)
|
|
2235
|
+
await time_out_assert(15, did_wallet_0.get_unconfirmed_balance, 101)
|
|
2236
|
+
await time_out_assert(15, did_wallet_0.get_pending_change_balance, 0)
|
|
2025
2237
|
|
|
2026
|
-
|
|
2027
|
-
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
|
|
2028
|
-
bytes(message, "utf-8"),
|
|
2029
|
-
G2Element.from_bytes(bytes.fromhex(response["signature"])),
|
|
2030
|
-
)
|
|
2031
|
-
# Test BLS sign hex
|
|
2032
|
-
message = "0123456789ABCDEF"
|
|
2033
|
-
assert did_wallet_1.did_info.origin_coin is not None
|
|
2034
|
-
response = await api_0.sign_message_by_id(
|
|
2035
|
-
{
|
|
2036
|
-
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
|
|
2037
|
-
"message": message,
|
|
2038
|
-
"is_hex": True,
|
|
2039
|
-
"safe_mode": False,
|
|
2040
|
-
}
|
|
2041
|
-
)
|
|
2238
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet_0)
|
|
2042
2239
|
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
)
|
|
2240
|
+
#######################
|
|
2241
|
+
all_node_0_wallets = await wallet_node_0.wallet_state_manager.user_store.get_all_wallet_info_entries()
|
|
2242
|
+
all_node_1_wallets = await wallet_node_1.wallet_state_manager.user_store.get_all_wallet_info_entries()
|
|
2243
|
+
assert len(all_node_0_wallets) == len(all_node_1_wallets)
|
|
2048
2244
|
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
) -> None:
|
|
2057
|
-
"""
|
|
2058
|
-
A DID is created on-chain in client0, causing a DID Wallet to be created in client1, which shares the same key.
|
|
2059
|
-
This can happen if someone uses the same key on multiple computers, or is syncing a wallet from scratch.
|
|
2060
|
-
|
|
2061
|
-
For this test, we assign a recovery list hash at DID creation time, but the recovery list is not yet available
|
|
2062
|
-
to the wallet_node that the DID Wallet is being created in (client1).
|
|
2063
|
-
|
|
2064
|
-
"""
|
|
2065
|
-
full_nodes, wallets, _ = two_nodes_two_wallets_with_same_keys
|
|
2066
|
-
full_node_api = full_nodes[0]
|
|
2067
|
-
full_node_server = full_node_api.server
|
|
2068
|
-
wallet_node_0, server_0 = wallets[0]
|
|
2069
|
-
wallet_node_1, server_1 = wallets[1]
|
|
2070
|
-
|
|
2071
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
2072
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
2073
|
-
|
|
2074
|
-
ph0 = await wallet_0.get_new_puzzlehash()
|
|
2075
|
-
ph1 = await wallet_1.get_new_puzzlehash()
|
|
2076
|
-
|
|
2077
|
-
sk0 = await wallet_node_0.wallet_state_manager.get_private_key(ph0)
|
|
2078
|
-
sk1 = await wallet_node_1.wallet_state_manager.get_private_key(ph1)
|
|
2079
|
-
assert sk0 == sk1
|
|
2080
|
-
|
|
2081
|
-
if trusted:
|
|
2082
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
2083
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2084
|
-
}
|
|
2085
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
2086
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2087
|
-
}
|
|
2245
|
+
# Note that the inner program we expect is different than the on-chain inner.
|
|
2246
|
+
# This means that we have more work to do in the checks for the two different spend cases of
|
|
2247
|
+
# the DID wallet Singleton
|
|
2248
|
+
# assert (
|
|
2249
|
+
# json.loads(all_node_0_wallets[1].data)["current_inner"]
|
|
2250
|
+
# == json.loads(all_node_1_wallets[1].data)["current_inner"]
|
|
2251
|
+
# )
|
|
2088
2252
|
|
|
2089
|
-
else:
|
|
2090
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
2091
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
2092
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2093
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2094
|
-
|
|
2095
|
-
await full_node_api.farm_blocks_to_wallet(1, wallet_0)
|
|
2096
|
-
await full_node_api.farm_blocks_to_wallet(1, wallet_1)
|
|
2097
|
-
|
|
2098
|
-
# Node 0 sets up a DID Wallet with a backup set, but num_of_backup_ids_needed=0
|
|
2099
|
-
# (a malformed solution, but legal for the clvm puzzle)
|
|
2100
|
-
recovery_list = [bytes32(bytes.fromhex("00" * 32))]
|
|
2101
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2102
|
-
did_wallet_0: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
2103
|
-
wallet_node_0.wallet_state_manager,
|
|
2104
|
-
wallet_0,
|
|
2105
|
-
uint64(101),
|
|
2106
|
-
action_scope,
|
|
2107
|
-
backups_ids=recovery_list,
|
|
2108
|
-
num_of_backup_ids_needed=uint64(0),
|
|
2109
|
-
)
|
|
2110
2253
|
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
"
|
|
2137
|
-
[
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
) -> None:
|
|
2146
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
2147
|
-
full_node_api = full_nodes[0]
|
|
2148
|
-
full_node_server = full_node_api.full_node.server
|
|
2149
|
-
wallet_node_1, wallet_server_1 = wallets[0]
|
|
2150
|
-
wallet_node_2, wallet_server_2 = wallets[1]
|
|
2151
|
-
wallet = wallet_node_1.wallet_state_manager.main_wallet
|
|
2152
|
-
wallet2 = wallet_node_2.wallet_state_manager.main_wallet
|
|
2153
|
-
fee = uint64(0)
|
|
2154
|
-
wallet_api_1 = WalletRpcApi(wallet_node_1)
|
|
2155
|
-
wallet_api_2 = WalletRpcApi(wallet_node_2)
|
|
2156
|
-
ph = await wallet.get_new_puzzlehash()
|
|
2157
|
-
if trusted:
|
|
2158
|
-
wallet_node_1.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
2159
|
-
wallet_node_2.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
2160
|
-
else:
|
|
2161
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
2162
|
-
wallet_node_2.config["trusted_peers"] = {}
|
|
2163
|
-
assert full_node_server._port is not None
|
|
2164
|
-
await wallet_server_1.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
|
|
2165
|
-
await wallet_server_2.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
|
|
2166
|
-
await full_node_api.farm_blocks_to_wallet(1, wallet)
|
|
2254
|
+
# TODO: See Issue CHIA-1544
|
|
2255
|
+
# This test should be ported to WalletTestFramework once we can replace keys in the wallet node
|
|
2256
|
+
@pytest.mark.parametrize(
|
|
2257
|
+
"trusted",
|
|
2258
|
+
[True, False],
|
|
2259
|
+
)
|
|
2260
|
+
@pytest.mark.anyio
|
|
2261
|
+
async def test_did_resync(
|
|
2262
|
+
self_hostname: str,
|
|
2263
|
+
two_wallet_nodes: tuple[list[FullNodeSimulator], list[tuple[WalletNode, ChiaServer]], BlockTools],
|
|
2264
|
+
trusted: bool,
|
|
2265
|
+
) -> None:
|
|
2266
|
+
full_nodes, wallets, _ = two_wallet_nodes
|
|
2267
|
+
full_node_api = full_nodes[0]
|
|
2268
|
+
full_node_server = full_node_api.full_node.server
|
|
2269
|
+
wallet_node_1, wallet_server_1 = wallets[0]
|
|
2270
|
+
wallet_node_2, wallet_server_2 = wallets[1]
|
|
2271
|
+
wallet = wallet_node_1.wallet_state_manager.main_wallet
|
|
2272
|
+
wallet2 = wallet_node_2.wallet_state_manager.main_wallet
|
|
2273
|
+
fee = uint64(0)
|
|
2274
|
+
wallet_api_1 = WalletRpcApi(wallet_node_1)
|
|
2275
|
+
wallet_api_2 = WalletRpcApi(wallet_node_2)
|
|
2276
|
+
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2277
|
+
ph = await action_scope.get_puzzle_hash(wallet.wallet_state_manager)
|
|
2278
|
+
if trusted:
|
|
2279
|
+
wallet_node_1.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
2280
|
+
wallet_node_2.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
2281
|
+
else:
|
|
2282
|
+
wallet_node_1.config["trusted_peers"] = {}
|
|
2283
|
+
wallet_node_2.config["trusted_peers"] = {}
|
|
2284
|
+
assert full_node_server._port is not None
|
|
2285
|
+
await wallet_server_1.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
|
|
2286
|
+
await wallet_server_2.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
|
|
2287
|
+
await full_node_api.farm_blocks_to_wallet(1, wallet)
|
|
2167
2288
|
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
await
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2289
|
+
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2290
|
+
did_wallet_1: DIDWallet = await DIDWallet.create_new_did_wallet(
|
|
2291
|
+
wallet_node_1.wallet_state_manager,
|
|
2292
|
+
wallet,
|
|
2293
|
+
uint64(101),
|
|
2294
|
+
action_scope,
|
|
2295
|
+
[bytes32(ph)],
|
|
2296
|
+
uint64(1),
|
|
2297
|
+
{"Twitter": "Test", "GitHub": "测试"},
|
|
2298
|
+
fee=fee,
|
|
2299
|
+
)
|
|
2300
|
+
assert did_wallet_1.get_name() == "Profile 1"
|
|
2301
|
+
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
2302
|
+
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_1, wallet_node_2])
|
|
2303
|
+
await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
|
|
2304
|
+
await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
|
|
2305
|
+
# Transfer DID
|
|
2306
|
+
async with wallet2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2307
|
+
new_puzhash = await action_scope.get_puzzle_hash(wallet2.wallet_state_manager)
|
|
2308
|
+
async with did_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2309
|
+
await did_wallet_1.transfer_did(new_puzhash, fee, True, action_scope=action_scope)
|
|
2310
|
+
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
2311
|
+
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_1, wallet_node_2])
|
|
2312
|
+
# Check if the DID wallet is created in the wallet2
|
|
2313
|
+
await time_out_assert(30, get_wallet_num, 2, wallet_node_2.wallet_state_manager)
|
|
2314
|
+
await time_out_assert(30, get_wallet_num, 1, wallet_node_1.wallet_state_manager)
|
|
2315
|
+
did_wallet_2 = wallet_node_2.wallet_state_manager.get_wallet(uint32(2), DIDWallet)
|
|
2316
|
+
did_info = did_wallet_2.did_info
|
|
2317
|
+
# set flag to reset wallet sync data on start
|
|
2318
|
+
await wallet_api_1.set_wallet_resync_on_startup({"enable": True})
|
|
2319
|
+
fingerprint_1 = wallet_node_1.logged_in_fingerprint
|
|
2320
|
+
await wallet_api_2.set_wallet_resync_on_startup({"enable": True})
|
|
2321
|
+
fingerprint_2 = wallet_node_2.logged_in_fingerprint
|
|
2322
|
+
# 2 reward coins
|
|
2323
|
+
assert len(await wallet_node_1.wallet_state_manager.coin_store.get_all_unspent_coins()) == 2
|
|
2324
|
+
# Delete tx records
|
|
2325
|
+
await wallet_node_1.wallet_state_manager.tx_store.rollback_to_block(0)
|
|
2326
|
+
wallet_node_1._close()
|
|
2327
|
+
await wallet_node_1._await_closed()
|
|
2328
|
+
wallet_node_2._close()
|
|
2329
|
+
await wallet_node_2._await_closed()
|
|
2330
|
+
wallet_node_1.config["database_path"] = "wallet/db/blockchain_wallet_v2_test_1_CHALLENGE_KEY.sqlite"
|
|
2331
|
+
wallet_node_2.config["database_path"] = "wallet/db/blockchain_wallet_v2_test_2_CHALLENGE_KEY.sqlite"
|
|
2332
|
+
# Start resync
|
|
2333
|
+
await wallet_node_1._start_with_fingerprint(fingerprint_1)
|
|
2334
|
+
await wallet_node_2._start_with_fingerprint(fingerprint_2)
|
|
2335
|
+
assert full_node_server._port is not None
|
|
2336
|
+
await wallet_server_1.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
|
|
2337
|
+
await wallet_server_2.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
|
|
2338
|
+
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(bytes32(b"\00" * 32)))
|
|
2339
|
+
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_1, timeout=20)
|
|
2340
|
+
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_2, timeout=20)
|
|
2341
|
+
await time_out_assert(30, get_wallet_num, 1, wallet_node_1.wallet_state_manager)
|
|
2342
|
+
await time_out_assert(30, get_wallet_num, 2, wallet_node_2.wallet_state_manager)
|
|
2343
|
+
did_wallet_2 = wallet_node_2.wallet_state_manager.get_wallet(uint32(2), DIDWallet)
|
|
2344
|
+
assert did_info == did_wallet_2.did_info
|
|
2223
2345
|
|
|
2224
2346
|
|
|
2225
2347
|
@pytest.mark.parametrize(
|
|
@@ -2232,16 +2354,24 @@ class TestDIDWallet:
|
|
|
2232
2354
|
],
|
|
2233
2355
|
indirect=True,
|
|
2234
2356
|
)
|
|
2357
|
+
@pytest.mark.parametrize(
|
|
2358
|
+
"use_alternate_recovery",
|
|
2359
|
+
[True, False],
|
|
2360
|
+
)
|
|
2235
2361
|
@pytest.mark.anyio
|
|
2236
|
-
async def test_did_coin_records(wallet_environments: WalletTestFramework,
|
|
2362
|
+
async def test_did_coin_records(wallet_environments: WalletTestFramework, use_alternate_recovery: bool) -> None:
|
|
2237
2363
|
# Setup
|
|
2238
2364
|
wallet_node = wallet_environments.environments[0].node
|
|
2239
2365
|
wallet = wallet_environments.environments[0].xch_wallet
|
|
2240
2366
|
|
|
2241
2367
|
# Generate DID wallet
|
|
2242
2368
|
async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2243
|
-
did_wallet: DIDWallet = await
|
|
2244
|
-
wallet_node.wallet_state_manager,
|
|
2369
|
+
did_wallet: DIDWallet = await make_did_wallet(
|
|
2370
|
+
wallet_node.wallet_state_manager,
|
|
2371
|
+
wallet,
|
|
2372
|
+
uint64(1),
|
|
2373
|
+
action_scope,
|
|
2374
|
+
use_alternate_recovery=use_alternate_recovery,
|
|
2245
2375
|
)
|
|
2246
2376
|
|
|
2247
2377
|
await wallet_environments.process_pending_states(
|
|
@@ -2260,11 +2390,13 @@ async def test_did_coin_records(wallet_environments: WalletTestFramework, monkey
|
|
|
2260
2390
|
]
|
|
2261
2391
|
)
|
|
2262
2392
|
|
|
2263
|
-
for _ in range(
|
|
2393
|
+
for _ in range(2):
|
|
2264
2394
|
async with did_wallet.wallet_state_manager.new_action_scope(
|
|
2265
2395
|
wallet_environments.tx_config, push=True
|
|
2266
2396
|
) as action_scope:
|
|
2267
|
-
await did_wallet.transfer_did(
|
|
2397
|
+
await did_wallet.transfer_did(
|
|
2398
|
+
await action_scope.get_puzzle_hash(did_wallet.wallet_state_manager), uint64(0), True, action_scope
|
|
2399
|
+
)
|
|
2268
2400
|
await wallet_environments.process_pending_states(
|
|
2269
2401
|
[
|
|
2270
2402
|
WalletStateTransition(
|