chia-blockchain 2.5.2rc2__py3-none-any.whl → 2.5.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/__init__.py +7 -0
- chia/_tests/blockchain/blockchain_test_utils.py +1 -1
- chia/_tests/blockchain/test_augmented_chain.py +54 -5
- chia/_tests/blockchain/test_blockchain.py +5 -12
- chia/_tests/blockchain/test_blockchain_transactions.py +3 -5
- chia/_tests/blockchain/test_get_block_generator.py +2 -2
- chia/_tests/blockchain/test_lookup_fork_chain.py +2 -2
- chia/_tests/clvm/benchmark_costs.py +2 -1
- chia/_tests/clvm/coin_store.py +4 -3
- chia/_tests/clvm/test_chialisp_deserialization.py +2 -2
- chia/_tests/clvm/test_curry_and_treehash.py +1 -1
- chia/_tests/clvm/test_puzzle_compression.py +2 -2
- chia/_tests/clvm/test_puzzles.py +2 -2
- chia/_tests/clvm/test_singletons.py +2 -2
- chia/_tests/clvm/test_spend_sim.py +1 -1
- chia/_tests/cmds/cmd_test_utils.py +2 -2
- chia/_tests/cmds/test_click_types.py +2 -2
- chia/_tests/cmds/test_cmd_framework.py +6 -6
- chia/_tests/cmds/test_show.py +4 -3
- chia/_tests/cmds/test_tx_config_args.py +1 -1
- chia/_tests/cmds/testing_classes.py +2 -2
- chia/_tests/cmds/wallet/test_consts.py +2 -2
- chia/_tests/cmds/wallet/test_did.py +2 -2
- chia/_tests/cmds/wallet/test_nft.py +2 -2
- chia/_tests/cmds/wallet/test_notifications.py +3 -2
- chia/_tests/cmds/wallet/test_vcs.py +2 -2
- chia/_tests/cmds/wallet/test_wallet.py +4 -8
- chia/_tests/conftest.py +4 -3
- chia/_tests/connection_utils.py +2 -2
- chia/_tests/core/cmds/test_keys.py +1 -2
- chia/_tests/core/cmds/test_wallet.py +2 -2
- chia/_tests/core/consensus/test_block_creation.py +2 -2
- chia/_tests/core/consensus/test_pot_iterations.py +1 -1
- chia/_tests/core/custom_types/test_coin.py +2 -2
- chia/_tests/core/custom_types/test_proof_of_space.py +2 -2
- chia/_tests/core/custom_types/test_spend_bundle.py +2 -2
- chia/_tests/core/data_layer/conftest.py +1 -1
- 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 +2 -2
- chia/_tests/core/data_layer/test_data_store.py +1 -1
- chia/_tests/core/data_layer/test_data_store_schema.py +1 -1
- chia/_tests/core/data_layer/util.py +2 -1
- chia/_tests/core/farmer/test_farmer_api.py +1 -1
- chia/_tests/core/full_node/full_sync/test_full_sync.py +1 -7
- chia/_tests/core/full_node/ram_db.py +2 -1
- chia/_tests/core/full_node/stores/test_block_store.py +2 -2
- chia/_tests/core/full_node/stores/test_coin_store.py +2 -2
- chia/_tests/core/full_node/stores/test_full_node_store.py +3 -3
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/stores/test_sync_store.py +1 -1
- chia/_tests/core/full_node/test_address_manager.py +1 -1
- chia/_tests/core/full_node/test_block_height_map.py +2 -2
- chia/_tests/core/full_node/test_conditions.py +1 -1
- chia/_tests/core/full_node/test_full_node.py +346 -164
- chia/_tests/core/full_node/test_generator_tools.py +3 -2
- chia/_tests/core/full_node/test_hint_management.py +2 -2
- chia/_tests/core/full_node/test_performance.py +2 -15
- chia/_tests/core/full_node/test_subscriptions.py +1 -1
- chia/_tests/core/full_node/test_transactions.py +186 -185
- chia/_tests/core/full_node/test_tx_processing_queue.py +1 -1
- chia/_tests/core/make_block_generator.py +2 -2
- chia/_tests/core/mempool/test_mempool.py +165 -22
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +1 -1
- chia/_tests/core/mempool/test_mempool_manager.py +476 -66
- chia/_tests/core/mempool/test_mempool_performance.py +2 -2
- chia/_tests/core/mempool/test_singleton_fast_forward.py +19 -25
- chia/_tests/core/node_height.py +2 -1
- chia/_tests/core/server/test_capabilities.py +1 -1
- chia/_tests/core/server/test_dos.py +36 -28
- chia/_tests/core/server/test_loop.py +3 -3
- chia/_tests/core/server/test_rate_limits.py +1 -1
- chia/_tests/core/server/test_server.py +2 -2
- chia/_tests/core/services/test_services.py +1 -1
- chia/_tests/core/ssl/test_ssl.py +1 -1
- chia/_tests/core/test_coins.py +2 -1
- chia/_tests/core/test_cost_calculation.py +2 -2
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_db_conversion.py +2 -2
- chia/_tests/core/test_db_validation.py +26 -13
- chia/_tests/core/test_farmer_harvester_rpc.py +2 -2
- chia/_tests/core/test_full_node_rpc.py +2 -2
- chia/_tests/core/test_merkle_set.py +2 -2
- chia/_tests/core/test_program.py +2 -2
- chia/_tests/core/test_rpc_util.py +1 -1
- chia/_tests/core/test_seeder.py +1 -1
- chia/_tests/core/util/test_block_cache.py +3 -3
- chia/_tests/core/util/test_jsonify.py +3 -2
- chia/_tests/core/util/test_keychain.py +3 -3
- chia/_tests/core/util/test_streamable.py +3 -4
- chia/_tests/environments/wallet.py +3 -2
- chia/_tests/farmer_harvester/test_farmer.py +3 -4
- chia/_tests/farmer_harvester/test_farmer_harvester.py +2 -2
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +2 -2
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +3 -4
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -1
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +2 -2
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +3 -4
- chia/_tests/generator/test_compression.py +20 -10
- chia/_tests/generator/test_rom.py +7 -9
- chia/_tests/plot_sync/test_delta.py +2 -2
- chia/_tests/plot_sync/test_plot_sync.py +2 -2
- chia/_tests/plot_sync/test_receiver.py +2 -2
- chia/_tests/plot_sync/test_sender.py +2 -2
- chia/_tests/plot_sync/test_sync_simulated.py +2 -2
- chia/_tests/plot_sync/util.py +3 -2
- chia/_tests/plotting/test_plot_manager.py +1 -1
- chia/_tests/pools/test_pool_cli_parsing.py +3 -2
- chia/_tests/pools/test_pool_cmdline.py +2 -2
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +3 -3
- chia/_tests/pools/test_pool_rpc.py +4 -5
- chia/_tests/pools/test_pool_wallet.py +1 -1
- chia/_tests/pools/test_wallet_pool_store.py +2 -2
- chia/_tests/rpc/test_rpc_client.py +1 -1
- chia/_tests/rpc/test_rpc_server.py +1 -1
- chia/_tests/simulation/test_simulation.py +36 -8
- chia/_tests/simulation/test_simulator.py +5 -5
- chia/_tests/simulation/test_start_simulator.py +2 -2
- chia/_tests/timelord/test_new_peak.py +2 -2
- chia/_tests/tools/test_run_block.py +3 -2
- chia/_tests/util/benchmark_cost.py +2 -2
- chia/_tests/util/benchmarks.py +17 -6
- chia/_tests/util/blockchain.py +2 -1
- chia/_tests/util/blockchain_mock.py +9 -5
- chia/_tests/util/build_network_protocol_files.py +2 -1
- chia/_tests/util/constants.py +2 -1
- chia/_tests/util/full_sync.py +6 -3
- chia/_tests/util/gen_ssl_certs.py +2 -2
- chia/_tests/util/generator_tools_testing.py +4 -3
- chia/_tests/util/get_name_puzzle_conditions.py +2 -2
- chia/_tests/util/misc.py +16 -2
- chia/_tests/util/network_protocol_data.py +17 -7
- chia/_tests/util/run_block.py +6 -8
- chia/_tests/util/setup_nodes.py +4 -3
- chia/_tests/util/spend_sim.py +9 -5
- chia/_tests/util/test_condition_tools.py +2 -2
- chia/_tests/util/test_config.py +2 -1
- chia/_tests/util/test_errors.py +2 -1
- chia/_tests/util/test_full_block_utils.py +17 -7
- chia/_tests/util/test_misc.py +1 -1
- chia/_tests/util/test_network_protocol_test.py +24 -24
- chia/_tests/util/test_replace_str_to_bytes.py +2 -2
- chia/_tests/util/test_trusted_peer.py +1 -1
- chia/_tests/util/time_out_assert.py +20 -7
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -2
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +5 -6
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +17 -15
- chia/_tests/wallet/cat_wallet/test_trades.py +2 -2
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -2
- chia/_tests/wallet/clawback/test_clawback_metadata.py +2 -2
- chia/_tests/wallet/conftest.py +3 -3
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +3 -5
- chia/_tests/wallet/db_wallet/test_dl_offers.py +2 -2
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +433 -384
- chia/_tests/wallet/did_wallet/test_did.py +3 -3
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +2 -2
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +2 -2
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +3 -4
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +1293 -703
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +28 -30
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2 -2
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +2 -2
- chia/_tests/wallet/rpc/config.py +1 -1
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +2 -2
- chia/_tests/wallet/rpc/test_wallet_rpc.py +20 -77
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +9 -7
- chia/_tests/wallet/sync/test_wallet_sync.py +79 -31
- chia/_tests/wallet/test_clvm_streamable.py +2 -2
- chia/_tests/wallet/test_coin_management.py +7 -7
- chia/_tests/wallet/test_coin_selection.py +20 -2
- chia/_tests/wallet/test_conditions.py +2 -2
- chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
- chia/_tests/wallet/test_new_wallet_protocol.py +2 -2
- chia/_tests/wallet/test_nft_store.py +2 -2
- chia/_tests/wallet/test_notifications.py +2 -2
- chia/_tests/wallet/test_puzzle_store.py +2 -2
- chia/_tests/wallet/test_sign_coin_spends.py +2 -2
- chia/_tests/wallet/test_signer_protocol.py +3 -3
- chia/_tests/wallet/test_singleton.py +3 -11
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +12 -13
- chia/_tests/wallet/test_singleton_store.py +2 -4
- chia/_tests/wallet/test_transaction_store.py +2 -2
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +53 -49
- chia/_tests/wallet/test_wallet_action_scope.py +24 -6
- chia/_tests/wallet/test_wallet_blockchain.py +1 -1
- chia/_tests/wallet/test_wallet_coin_store.py +2 -2
- chia/_tests/wallet/test_wallet_interested_store.py +2 -2
- chia/_tests/wallet/test_wallet_node.py +3 -3
- chia/_tests/wallet/test_wallet_retry.py +3 -3
- chia/_tests/wallet/test_wallet_state_manager.py +8 -8
- chia/_tests/wallet/test_wallet_test_framework.py +1 -1
- chia/_tests/wallet/test_wallet_trade_store.py +2 -2
- chia/_tests/wallet/test_wallet_utils.py +2 -2
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -2
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +15 -15
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +5 -3
- chia/_tests/wallet/wallet_block_tools.py +15 -7
- chia/_tests/weight_proof/test_weight_proof.py +3 -3
- chia/cmds/chia.py +0 -2
- chia/cmds/cmd_classes.py +3 -3
- chia/cmds/cmd_helpers.py +4 -4
- chia/cmds/cmds_util.py +2 -2
- chia/cmds/coin_funcs.py +3 -2
- chia/cmds/coins.py +1 -1
- chia/cmds/data.py +2 -2
- chia/cmds/data_funcs.py +3 -2
- chia/cmds/db_upgrade_func.py +2 -2
- chia/cmds/db_validate_func.py +15 -8
- chia/cmds/farm.py +2 -4
- chia/cmds/keys.py +0 -2
- chia/cmds/keys_funcs.py +1 -1
- chia/cmds/netspace_funcs.py +2 -1
- chia/cmds/param_types.py +2 -2
- chia/cmds/plotnft.py +2 -2
- chia/cmds/plotnft_funcs.py +2 -2
- chia/cmds/rpc.py +1 -1
- chia/cmds/show.py +1 -2
- chia/cmds/show_funcs.py +6 -3
- chia/cmds/signer.py +1 -2
- chia/cmds/sim.py +1 -2
- chia/cmds/sim_funcs.py +2 -2
- chia/cmds/wallet.py +2 -2
- chia/cmds/wallet_funcs.py +4 -11
- chia/consensus/block_body_validation.py +3 -4
- chia/consensus/block_creation.py +10 -6
- chia/consensus/block_header_validation.py +3 -4
- chia/consensus/block_record.py +2 -3
- chia/consensus/block_rewards.py +1 -1
- chia/consensus/blockchain.py +20 -17
- chia/consensus/blockchain_interface.py +5 -4
- chia/consensus/coinbase.py +2 -2
- chia/consensus/constants.py +1 -1
- chia/consensus/cost_calculator.py +2 -1
- chia/consensus/default_constants.py +4 -3
- chia/consensus/deficit.py +3 -2
- chia/consensus/difficulty_adjustment.py +8 -9
- chia/consensus/find_fork_point.py +4 -3
- chia/consensus/full_block_to_block_record.py +4 -3
- chia/consensus/get_block_challenge.py +4 -3
- chia/consensus/get_block_generator.py +3 -2
- chia/consensus/make_sub_epoch_summary.py +3 -2
- chia/consensus/multiprocess_validation.py +9 -4
- chia/consensus/pos_quality.py +1 -1
- chia/consensus/pot_iterations.py +4 -3
- chia/consensus/vdf_info_computation.py +4 -3
- chia/daemon/client.py +1 -1
- chia/daemon/keychain_server.py +1 -1
- chia/daemon/server.py +1 -1
- chia/daemon/windows_signal.py +1 -1
- chia/data_layer/data_layer.py +4 -3
- chia/data_layer/data_layer_errors.py +1 -1
- chia/data_layer/data_layer_util.py +2 -2
- chia/data_layer/data_layer_wallet.py +47 -69
- chia/data_layer/data_store.py +1 -1
- chia/data_layer/dl_wallet_store.py +5 -6
- chia/data_layer/download_data.py +1 -1
- chia/data_layer/s3_plugin_service.py +4 -4
- chia/data_layer/singleton_record.py +23 -0
- chia/data_layer/util/benchmark.py +2 -1
- chia/farmer/farmer.py +4 -6
- chia/farmer/farmer_api.py +4 -6
- chia/full_node/bitcoin_fee_estimator.py +2 -1
- chia/full_node/block_height_map.py +2 -2
- chia/full_node/block_store.py +8 -9
- chia/{util → full_node}/check_fork_next_block.py +2 -1
- chia/full_node/coin_store.py +10 -10
- chia/full_node/fee_estimate.py +2 -1
- chia/full_node/fee_estimation.py +2 -1
- chia/full_node/fee_estimator.py +2 -1
- chia/full_node/fee_estimator_interface.py +1 -1
- chia/full_node/fee_history.py +2 -1
- chia/full_node/fee_tracker.py +2 -1
- chia/full_node/full_node.py +15 -13
- chia/full_node/full_node_api.py +12 -32
- chia/full_node/full_node_store.py +4 -3
- chia/full_node/hint_management.py +2 -1
- chia/full_node/hint_store.py +3 -3
- chia/full_node/mempool.py +80 -12
- chia/full_node/mempool_check_conditions.py +6 -7
- chia/full_node/mempool_manager.py +168 -21
- chia/full_node/pending_tx_cache.py +2 -2
- chia/full_node/subscriptions.py +2 -2
- chia/full_node/sync_store.py +2 -3
- chia/full_node/tx_processing_queue.py +2 -1
- chia/full_node/weight_proof.py +5 -8
- chia/harvester/harvester.py +5 -3
- chia/harvester/harvester_api.py +2 -2
- chia/introducer/introducer.py +30 -2
- chia/introducer/introducer_api.py +9 -1
- chia/legacy/keyring.py +1 -2
- chia/plot_sync/exceptions.py +2 -1
- chia/plot_sync/receiver.py +2 -2
- chia/plot_sync/sender.py +1 -1
- chia/plotting/cache.py +2 -2
- chia/plotting/check_plots.py +4 -2
- chia/plotting/create_plots.py +1 -1
- chia/plotting/manager.py +3 -3
- chia/plotting/util.py +2 -2
- chia/pools/pool_config.py +1 -1
- chia/pools/pool_puzzles.py +23 -17
- chia/pools/pool_wallet.py +22 -9
- chia/pools/pool_wallet_info.py +2 -2
- chia/protocols/farmer_protocol.py +3 -6
- chia/protocols/full_node_protocol.py +3 -2
- chia/protocols/harvester_protocol.py +3 -4
- chia/protocols/pool_protocol.py +2 -2
- chia/protocols/shared_protocol.py +2 -1
- chia/protocols/timelord_protocol.py +4 -4
- chia/protocols/wallet_protocol.py +2 -2
- chia/rpc/data_layer_rpc_api.py +3 -4
- chia/rpc/data_layer_rpc_client.py +3 -2
- chia/rpc/farmer_rpc_api.py +2 -2
- chia/rpc/farmer_rpc_client.py +2 -1
- chia/rpc/full_node_rpc_api.py +3 -2
- chia/rpc/full_node_rpc_client.py +3 -2
- chia/rpc/harvester_rpc_api.py +2 -1
- chia/rpc/rpc_client.py +2 -2
- chia/rpc/rpc_server.py +1 -1
- chia/rpc/wallet_request_types.py +2 -62
- chia/rpc/wallet_rpc_api.py +98 -628
- chia/rpc/wallet_rpc_client.py +5 -253
- chia/seeder/crawl_store.py +1 -1
- chia/seeder/crawler.py +2 -2
- chia/seeder/peer_record.py +2 -1
- chia/seeder/start_crawler.py +3 -1
- chia/server/address_manager.py +2 -1
- chia/server/address_manager_store.py +1 -1
- chia/server/capabilities.py +2 -1
- chia/server/introducer_peers.py +2 -1
- chia/server/node_discovery.py +1 -1
- chia/server/outbound_message.py +2 -1
- chia/server/server.py +2 -2
- chia/server/start_data_layer.py +2 -1
- chia/server/start_farmer.py +3 -1
- chia/server/start_full_node.py +4 -2
- chia/server/start_harvester.py +3 -1
- chia/server/start_introducer.py +12 -1
- chia/server/start_service.py +2 -1
- chia/server/start_timelord.py +3 -1
- chia/server/start_wallet.py +3 -1
- chia/server/upnp.py +1 -2
- chia/server/ws_connection.py +3 -4
- chia/simulator/add_blocks_in_batches.py +5 -3
- chia/simulator/block_tools.py +16 -12
- chia/simulator/full_node_simulator.py +9 -14
- chia/simulator/setup_services.py +5 -3
- chia/simulator/simulator_full_node_rpc_api.py +3 -2
- chia/simulator/simulator_full_node_rpc_client.py +3 -2
- chia/simulator/simulator_protocol.py +3 -2
- chia/simulator/simulator_test_tools.py +2 -2
- chia/simulator/start_simulator.py +3 -2
- chia/simulator/wallet_tools.py +3 -4
- chia/timelord/iters_from_block.py +4 -4
- chia/timelord/timelord.py +7 -12
- chia/timelord/timelord_api.py +3 -3
- chia/timelord/timelord_state.py +4 -3
- chia/types/block_protocol.py +2 -2
- chia/types/blockchain_format/coin.py +2 -2
- chia/types/blockchain_format/program.py +1 -1
- chia/types/blockchain_format/proof_of_space.py +3 -4
- chia/types/blockchain_format/tree_hash.py +1 -1
- chia/types/blockchain_format/vdf.py +3 -4
- chia/types/clvm_cost.py +1 -1
- chia/types/coin_record.py +4 -3
- chia/types/coin_spend.py +1 -1
- chia/types/eligible_coin_spends.py +9 -5
- chia/types/fee_rate.py +1 -1
- chia/types/generator_types.py +3 -3
- chia/types/internal_mempool_item.py +3 -2
- chia/types/mempool_item.py +10 -3
- chia/types/mempool_submission_status.py +2 -1
- chia/types/mojos.py +1 -1
- chia/types/peer_info.py +2 -1
- chia/types/transaction_queue_entry.py +2 -1
- chia/types/unfinished_header_block.py +4 -4
- chia/types/validation_state.py +2 -1
- chia/types/weight_proof.py +1 -9
- chia/util/augmented_chain.py +20 -9
- chia/util/block_cache.py +8 -4
- chia/util/condition_tools.py +2 -2
- chia/util/full_block_utils.py +3 -4
- chia/util/generator_tools.py +2 -2
- chia/util/initial-config.yaml +2 -11
- chia/util/network.py +2 -2
- chia/util/prev_transaction_block.py +2 -1
- chia/util/task_timing.py +1 -1
- chia/util/vdf_prover.py +3 -3
- chia/util/ws_message.py +1 -1
- chia/wallet/cat_wallet/cat_info.py +3 -2
- chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -2
- chia/wallet/cat_wallet/cat_utils.py +6 -4
- chia/wallet/cat_wallet/cat_wallet.py +16 -18
- chia/wallet/cat_wallet/lineage_store.py +2 -1
- chia/wallet/coin_selection.py +5 -5
- chia/wallet/conditions.py +22 -16
- chia/wallet/db_wallet/db_wallet_puzzles.py +15 -15
- chia/wallet/derivation_record.py +2 -2
- chia/wallet/derive_keys.py +2 -2
- chia/wallet/did_wallet/did_info.py +3 -2
- chia/wallet/did_wallet/did_wallet.py +41 -19
- chia/wallet/did_wallet/did_wallet_puzzles.py +18 -12
- chia/wallet/driver_protocol.py +1 -1
- chia/wallet/lineage_proof.py +3 -2
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +6 -7
- chia/wallet/nft_wallet/nft_info.py +5 -5
- chia/wallet/nft_wallet/nft_puzzle_utils.py +293 -0
- chia/wallet/nft_wallet/nft_puzzles.py +21 -298
- chia/wallet/nft_wallet/nft_wallet.py +47 -62
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +4 -8
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +3 -2
- chia/wallet/nft_wallet/transfer_program_puzzle.py +6 -10
- chia/wallet/nft_wallet/uncurry_nft.py +6 -8
- chia/wallet/notification_manager.py +5 -5
- chia/wallet/notification_store.py +3 -2
- chia/wallet/outer_puzzles.py +2 -1
- chia/wallet/puzzles/clawback/drivers.py +21 -8
- chia/wallet/puzzles/clawback/metadata.py +3 -2
- chia/wallet/puzzles/clawback/puzzle_decorator.py +5 -4
- chia/wallet/puzzles/deployed_puzzle_hashes.json +0 -10
- chia/wallet/puzzles/p2_conditions.py +3 -2
- chia/wallet/puzzles/p2_delegated_conditions.py +3 -2
- chia/wallet/puzzles/p2_delegated_puzzle.py +3 -2
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -3
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +3 -2
- chia/wallet/puzzles/p2_puzzle_hash.py +4 -3
- chia/wallet/puzzles/puzzle_utils.py +3 -2
- chia/wallet/puzzles/singleton_top_layer.py +26 -10
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +21 -9
- chia/wallet/puzzles/tails.py +21 -129
- chia/wallet/signer_protocol.py +3 -2
- chia/wallet/singleton.py +12 -6
- chia/wallet/singleton_record.py +3 -2
- chia/wallet/trade_manager.py +31 -55
- chia/wallet/trade_record.py +3 -2
- chia/wallet/trading/offer.py +14 -13
- chia/wallet/trading/trade_store.py +3 -4
- chia/wallet/transaction_record.py +2 -2
- chia/wallet/util/blind_signer_tl.py +3 -2
- chia/wallet/util/compute_hints.py +3 -2
- chia/wallet/util/compute_memos.py +2 -2
- chia/wallet/util/curry_and_treehash.py +1 -2
- chia/wallet/util/merkle_tree.py +1 -1
- chia/wallet/util/merkle_utils.py +1 -1
- chia/wallet/util/new_peak_queue.py +2 -1
- chia/wallet/util/notifications.py +5 -4
- chia/wallet/util/peer_request_cache.py +3 -2
- chia/wallet/util/puzzle_compression.py +6 -4
- chia/wallet/util/puzzle_decorator.py +6 -4
- chia/wallet/util/query_filter.py +3 -2
- chia/wallet/util/tx_config.py +3 -3
- chia/wallet/util/wallet_sync_utils.py +2 -2
- chia/wallet/util/wallet_types.py +2 -3
- chia/wallet/vc_wallet/cr_cat_drivers.py +18 -22
- chia/wallet/vc_wallet/cr_cat_wallet.py +14 -10
- chia/wallet/vc_wallet/cr_outer_puzzle.py +2 -2
- chia/wallet/vc_wallet/vc_drivers.py +50 -68
- chia/wallet/vc_wallet/vc_store.py +2 -2
- chia/wallet/vc_wallet/vc_wallet.py +47 -15
- chia/wallet/wallet.py +51 -46
- chia/wallet/wallet_action_scope.py +4 -0
- chia/wallet/wallet_blockchain.py +12 -7
- chia/wallet/wallet_coin_record.py +3 -2
- chia/wallet/wallet_coin_store.py +3 -2
- chia/wallet/wallet_info.py +2 -1
- chia/wallet/wallet_interested_store.py +3 -2
- chia/wallet/wallet_nft_store.py +4 -4
- chia/wallet/wallet_node.py +3 -4
- chia/wallet/wallet_pool_store.py +3 -4
- chia/wallet/wallet_protocol.py +19 -5
- chia/wallet/wallet_puzzle_store.py +2 -2
- chia/wallet/wallet_retry_store.py +3 -6
- chia/wallet/wallet_singleton_store.py +2 -2
- chia/wallet/wallet_state_manager.py +20 -197
- chia/wallet/wallet_transaction_store.py +2 -2
- chia/wallet/wallet_user_store.py +2 -1
- chia/wallet/wallet_weight_proof_handler.py +3 -2
- {chia_blockchain-2.5.2rc2.dist-info → chia_blockchain-2.5.3.dist-info}/METADATA +3 -2
- chia_blockchain-2.5.3.dist-info/RECORD +891 -0
- mozilla-ca/cacert.pem +64 -33
- chia/_tests/clvm/test_condition_codes.py +0 -13
- chia/_tests/cmds/wallet/test_dao.py +0 -565
- chia/_tests/wallet/dao_wallet/__init__.py +0 -0
- chia/_tests/wallet/dao_wallet/config.py +0 -3
- chia/_tests/wallet/dao_wallet/test_dao_clvm.py +0 -1330
- chia/_tests/wallet/dao_wallet/test_dao_wallets.py +0 -3488
- chia/cmds/dao.py +0 -1064
- chia/cmds/dao_funcs.py +0 -598
- chia/consensus/puzzles/__init__.py +0 -0
- chia/consensus/puzzles/chialisp_deserialisation.clsp +0 -69
- chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +0 -1
- chia/consensus/puzzles/rom_bootstrap_generator.clsp +0 -37
- chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +0 -1
- chia/full_node/puzzles/__init__.py +0 -0
- chia/full_node/puzzles/block_program_zero.clsp +0 -14
- chia/full_node/puzzles/block_program_zero.clsp.hex +0 -1
- chia/full_node/puzzles/decompress_coin_spend_entry.clsp +0 -5
- chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +0 -1
- chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +0 -7
- chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +0 -1
- chia/full_node/puzzles/decompress_puzzle.clsp +0 -6
- chia/full_node/puzzles/decompress_puzzle.clsp.hex +0 -1
- chia/pools/puzzles/__init__.py +0 -0
- chia/pools/puzzles/pool_member_innerpuz.clsp +0 -70
- chia/pools/puzzles/pool_member_innerpuz.clsp.hex +0 -1
- chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +0 -69
- chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +0 -1
- chia/simulator/simulator_constants.py +0 -13
- chia/types/blockchain_format/foliage.py +0 -8
- chia/types/blockchain_format/pool_target.py +0 -5
- chia/types/blockchain_format/reward_chain_block.py +0 -6
- chia/types/blockchain_format/sized_bytes.py +0 -11
- chia/util/ints.py +0 -19
- chia/wallet/cat_wallet/dao_cat_info.py +0 -28
- chia/wallet/cat_wallet/dao_cat_wallet.py +0 -669
- chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
- chia/wallet/cat_wallet/puzzles/cat_truths.clib +0 -31
- chia/wallet/cat_wallet/puzzles/cat_v2.clsp +0 -397
- chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +0 -1
- chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +0 -25
- chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +0 -1
- chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +0 -15
- chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +0 -1
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +0 -26
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +0 -1
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +0 -42
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +0 -1
- chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +0 -24
- chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +0 -1
- chia/wallet/dao_wallet/__init__.py +0 -0
- chia/wallet/dao_wallet/dao_info.py +0 -61
- chia/wallet/dao_wallet/dao_utils.py +0 -811
- chia/wallet/dao_wallet/dao_wallet.py +0 -2119
- chia/wallet/did_wallet/puzzles/__init__.py +0 -0
- chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +0 -135
- chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +0 -1
- chia/wallet/payment.py +0 -33
- chia/wallet/puzzles/augmented_condition.clsp +0 -13
- chia/wallet/puzzles/augmented_condition.clsp.hex +0 -1
- chia/wallet/puzzles/condition_codes.clib +0 -77
- chia/wallet/puzzles/curry-and-treehash.clib +0 -102
- chia/wallet/puzzles/curry.clib +0 -135
- chia/wallet/puzzles/curry_by_index.clib +0 -16
- chia/wallet/puzzles/dao_cat_eve.clsp +0 -17
- chia/wallet/puzzles/dao_cat_eve.clsp.hex +0 -1
- chia/wallet/puzzles/dao_cat_launcher.clsp +0 -36
- chia/wallet/puzzles/dao_cat_launcher.clsp.hex +0 -1
- chia/wallet/puzzles/dao_finished_state.clsp +0 -35
- chia/wallet/puzzles/dao_finished_state.clsp.hex +0 -1
- chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +0 -1
- chia/wallet/puzzles/dao_lockup.clsp +0 -288
- chia/wallet/puzzles/dao_lockup.clsp.hex +0 -1
- chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +0 -1
- chia/wallet/puzzles/dao_proposal.clsp +0 -377
- chia/wallet/puzzles/dao_proposal.clsp.hex +0 -1
- chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +0 -1
- chia/wallet/puzzles/dao_proposal_timer.clsp +0 -78
- chia/wallet/puzzles/dao_proposal_timer.clsp.hex +0 -1
- chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +0 -1
- chia/wallet/puzzles/dao_proposal_validator.clsp +0 -87
- chia/wallet/puzzles/dao_proposal_validator.clsp.hex +0 -1
- chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +0 -1
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +0 -240
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +0 -1
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +0 -1
- chia/wallet/puzzles/dao_treasury.clsp +0 -115
- chia/wallet/puzzles/dao_treasury.clsp.hex +0 -1
- chia/wallet/puzzles/dao_update_proposal.clsp +0 -44
- chia/wallet/puzzles/dao_update_proposal.clsp.hex +0 -1
- chia/wallet/puzzles/json.clib +0 -25
- chia/wallet/puzzles/merkle_utils.clib +0 -18
- chia/wallet/puzzles/notification.clsp +0 -7
- chia/wallet/puzzles/notification.clsp.hex +0 -1
- chia/wallet/puzzles/p2_1_of_n.clsp +0 -22
- chia/wallet/puzzles/p2_1_of_n.clsp.hex +0 -1
- chia/wallet/puzzles/p2_conditions.clsp +0 -3
- chia/wallet/puzzles/p2_conditions.clsp.hex +0 -1
- chia/wallet/puzzles/p2_delegated_conditions.clsp +0 -18
- chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +0 -1
- chia/wallet/puzzles/p2_delegated_puzzle.clsp +0 -19
- chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +0 -1
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +0 -91
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +0 -1
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +0 -108
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +0 -1
- chia/wallet/puzzles/p2_parent.clsp +0 -19
- chia/wallet/puzzles/p2_parent.clsp.hex +0 -1
- chia/wallet/puzzles/p2_puzzle_hash.clsp +0 -18
- chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +0 -1
- chia/wallet/puzzles/p2_singleton.clsp +0 -30
- chia/wallet/puzzles/p2_singleton.clsp.hex +0 -1
- chia/wallet/puzzles/p2_singleton_aggregator.clsp +0 -81
- chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +0 -1
- chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +0 -50
- chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +0 -1
- chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +0 -47
- chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +0 -1
- chia/wallet/puzzles/settlement_payments.clsp +0 -49
- chia/wallet/puzzles/settlement_payments.clsp.hex +0 -1
- chia/wallet/puzzles/sha256tree.clib +0 -11
- chia/wallet/puzzles/singleton_launcher.clsp +0 -16
- chia/wallet/puzzles/singleton_launcher.clsp.hex +0 -1
- chia/wallet/puzzles/singleton_top_layer.clsp +0 -177
- chia/wallet/puzzles/singleton_top_layer.clsp.hex +0 -1
- chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +0 -107
- chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +0 -1
- chia/wallet/puzzles/singleton_truths.clib +0 -21
- chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
- chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +0 -3
- chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +0 -1
- chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +0 -304
- chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +0 -1
- chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +0 -45
- chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
- chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +0 -30
- chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +0 -75
- chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +0 -32
- chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +0 -80
- chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +0 -163
- chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +0 -16
- chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +0 -74
- chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +0 -23
- chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +0 -1
- chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +0 -64
- chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +0 -1
- chia_blockchain-2.5.2rc2.dist-info/RECORD +0 -1042
- {chia_blockchain-2.5.2rc2.dist-info → chia_blockchain-2.5.3.dist-info}/LICENSE +0 -0
- {chia_blockchain-2.5.2rc2.dist-info → chia_blockchain-2.5.3.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.2rc2.dist-info → chia_blockchain-2.5.3.dist-info}/entry_points.txt +0 -0
|
@@ -1,3488 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import contextlib
|
|
5
|
-
import time
|
|
6
|
-
from typing import Any, Callable, Optional, Union
|
|
7
|
-
|
|
8
|
-
import pytest
|
|
9
|
-
|
|
10
|
-
from chia._tests.util.rpc import validate_get_routes
|
|
11
|
-
from chia._tests.util.setup_nodes import OldSimulatorsAndWallets, SimulatorsAndWalletsServices
|
|
12
|
-
from chia._tests.util.time_out_assert import time_out_assert, time_out_assert_not_none
|
|
13
|
-
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
|
|
14
|
-
from chia.rpc.wallet_rpc_api import WalletRpcApi
|
|
15
|
-
from chia.rpc.wallet_rpc_client import WalletRpcClient
|
|
16
|
-
from chia.simulator.simulator_protocol import FarmNewBlockProtocol, ReorgProtocol
|
|
17
|
-
from chia.types.blockchain_format.program import Program
|
|
18
|
-
from chia.types.blockchain_format.sized_bytes import bytes32
|
|
19
|
-
from chia.types.peer_info import PeerInfo
|
|
20
|
-
from chia.util.bech32m import encode_puzzle_hash
|
|
21
|
-
from chia.util.ints import uint32, uint64, uint128
|
|
22
|
-
from chia.util.timing import adjusted_timeout
|
|
23
|
-
from chia.wallet.cat_wallet.cat_wallet import CATWallet
|
|
24
|
-
from chia.wallet.cat_wallet.dao_cat_wallet import DAOCATWallet
|
|
25
|
-
from chia.wallet.dao_wallet.dao_info import DAORules
|
|
26
|
-
from chia.wallet.dao_wallet.dao_utils import (
|
|
27
|
-
generate_mint_proposal_innerpuz,
|
|
28
|
-
generate_simple_proposal_innerpuz,
|
|
29
|
-
generate_update_proposal_innerpuz,
|
|
30
|
-
)
|
|
31
|
-
from chia.wallet.dao_wallet.dao_wallet import DAOWallet
|
|
32
|
-
from chia.wallet.transaction_record import TransactionRecord
|
|
33
|
-
from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
async def get_proposal_state(wallet: DAOWallet, index: int) -> tuple[Optional[bool], Optional[bool]]:
|
|
37
|
-
return wallet.dao_info.proposals_list[index].passed, wallet.dao_info.proposals_list[index].closed
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
async def rpc_state(
|
|
41
|
-
timeout: float,
|
|
42
|
-
async_function: Callable[[Any], Any],
|
|
43
|
-
params: list[Union[int, dict[str, Any]]],
|
|
44
|
-
condition_func: Callable[[dict[str, Any]], Any],
|
|
45
|
-
result: Optional[Any] = None,
|
|
46
|
-
) -> Union[bool, dict[str, Any]]: # pragma: no cover
|
|
47
|
-
__tracebackhide__ = True
|
|
48
|
-
|
|
49
|
-
timeout = adjusted_timeout(timeout=timeout)
|
|
50
|
-
|
|
51
|
-
start = time.monotonic()
|
|
52
|
-
|
|
53
|
-
while True:
|
|
54
|
-
resp = await async_function(*params)
|
|
55
|
-
assert isinstance(resp, dict)
|
|
56
|
-
try:
|
|
57
|
-
if result:
|
|
58
|
-
if condition_func(resp) == result:
|
|
59
|
-
return True
|
|
60
|
-
else:
|
|
61
|
-
if condition_func(resp):
|
|
62
|
-
return resp
|
|
63
|
-
except IndexError:
|
|
64
|
-
continue
|
|
65
|
-
|
|
66
|
-
now = time.monotonic()
|
|
67
|
-
elapsed = now - start
|
|
68
|
-
if elapsed >= timeout:
|
|
69
|
-
raise asyncio.TimeoutError(
|
|
70
|
-
f"timed out while waiting for {async_function.__name__}(): {elapsed} >= {timeout}",
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
await asyncio.sleep(0.3)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
puzzle_hash_0 = bytes32(32 * b"0")
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
80
|
-
@pytest.mark.parametrize(
|
|
81
|
-
"trusted",
|
|
82
|
-
[True, False],
|
|
83
|
-
)
|
|
84
|
-
@pytest.mark.anyio
|
|
85
|
-
async def test_dao_creation(self_hostname: str, two_wallet_nodes: OldSimulatorsAndWallets, trusted: bool) -> None:
|
|
86
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
87
|
-
full_node_api = full_nodes[0]
|
|
88
|
-
full_node_server = full_node_api.server
|
|
89
|
-
wallet_node_0, server_0 = wallets[0]
|
|
90
|
-
wallet_node_1, server_1 = wallets[1]
|
|
91
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
92
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
93
|
-
ph = await wallet_0.get_new_puzzlehash()
|
|
94
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
95
|
-
|
|
96
|
-
if trusted:
|
|
97
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
98
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
99
|
-
}
|
|
100
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
101
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
102
|
-
}
|
|
103
|
-
else:
|
|
104
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
105
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
106
|
-
|
|
107
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
108
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
109
|
-
|
|
110
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
|
|
111
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
112
|
-
|
|
113
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
114
|
-
|
|
115
|
-
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
|
116
|
-
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
|
117
|
-
|
|
118
|
-
cat_amt = 2000
|
|
119
|
-
dao_rules = DAORules(
|
|
120
|
-
proposal_timelock=uint64(10),
|
|
121
|
-
soft_close_length=uint64(5),
|
|
122
|
-
attendance_required=uint64(1000), # 10%
|
|
123
|
-
pass_percentage=uint64(5100), # 51%
|
|
124
|
-
self_destruct_length=uint64(20),
|
|
125
|
-
oracle_spend_delay=uint64(10),
|
|
126
|
-
proposal_minimum_amount=uint64(1),
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
fee = uint64(10)
|
|
130
|
-
fee_for_cat = uint64(20)
|
|
131
|
-
|
|
132
|
-
# Try to create a DAO with more CATs than xch balance
|
|
133
|
-
with pytest.raises(ValueError) as e_info:
|
|
134
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
|
|
135
|
-
await DAOWallet.create_new_dao_and_wallet(
|
|
136
|
-
wallet_node_0.wallet_state_manager,
|
|
137
|
-
wallet_0,
|
|
138
|
-
uint64(funds + 1),
|
|
139
|
-
dao_rules,
|
|
140
|
-
action_scope,
|
|
141
|
-
fee=fee,
|
|
142
|
-
fee_for_cat=fee_for_cat,
|
|
143
|
-
)
|
|
144
|
-
assert e_info.value.args[0] == f"Your balance of {funds} mojos is not enough to create {funds + 1} CATs"
|
|
145
|
-
|
|
146
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
147
|
-
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
|
148
|
-
wallet_node_0.wallet_state_manager,
|
|
149
|
-
wallet_0,
|
|
150
|
-
uint64(cat_amt * 2),
|
|
151
|
-
dao_rules,
|
|
152
|
-
action_scope,
|
|
153
|
-
fee=fee,
|
|
154
|
-
fee_for_cat=fee_for_cat,
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
158
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
159
|
-
)
|
|
160
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
161
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
162
|
-
|
|
163
|
-
# Check the spend was successful
|
|
164
|
-
treasury_id = dao_wallet_0.dao_info.treasury_id
|
|
165
|
-
|
|
166
|
-
# check the dao wallet balances
|
|
167
|
-
await time_out_assert(20, dao_wallet_0.get_confirmed_balance, uint128(1))
|
|
168
|
-
await time_out_assert(20, dao_wallet_0.get_unconfirmed_balance, uint128(1))
|
|
169
|
-
await time_out_assert(20, dao_wallet_0.get_pending_change_balance, uint64(0))
|
|
170
|
-
|
|
171
|
-
# check select coins
|
|
172
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
|
|
173
|
-
no_coins = await dao_wallet_0.select_coins(uint64(2), action_scope)
|
|
174
|
-
assert no_coins == set()
|
|
175
|
-
selected_coins = await dao_wallet_0.select_coins(uint64(1), action_scope)
|
|
176
|
-
assert len(selected_coins) == 1
|
|
177
|
-
|
|
178
|
-
# get the cat wallets
|
|
179
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
180
|
-
dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
|
181
|
-
# Some dao_cat_wallet checks for coverage
|
|
182
|
-
assert dao_cat_wallet_0.get_name() == f"CAT {cat_wallet_0.cat_info.limitations_program_hash.hex()[:16]}..."
|
|
183
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
|
|
184
|
-
assert (await dao_cat_wallet_0.select_coins(uint64(1), action_scope)) == set()
|
|
185
|
-
dao_cat_puzhash = await dao_cat_wallet_0.get_new_puzzlehash()
|
|
186
|
-
assert dao_cat_puzhash == bytes32.from_hexstr("09f905ba3e9db3644ac4537495565bf268c6f030266aa412863c5efced6b1800")
|
|
187
|
-
await dao_cat_wallet_0.get_new_inner_puzzle(DEFAULT_TX_CONFIG)
|
|
188
|
-
dao_cat_inner_hash = await dao_cat_wallet_0.get_new_inner_hash(DEFAULT_TX_CONFIG)
|
|
189
|
-
assert dao_cat_inner_hash == bytes32.from_hexstr("8a66292fde9ef08198d996eae0ea21677eb478afeabed8030b1bf42c728f7dcc")
|
|
190
|
-
|
|
191
|
-
cat_wallet_0_bal = await cat_wallet_0.get_confirmed_balance()
|
|
192
|
-
assert cat_wallet_0_bal == cat_amt * 2
|
|
193
|
-
|
|
194
|
-
# Create the other user's wallet from the treasury id
|
|
195
|
-
dao_wallet_1 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
196
|
-
wallet_node_1.wallet_state_manager, wallet_1, treasury_id
|
|
197
|
-
)
|
|
198
|
-
assert dao_wallet_0.dao_info.treasury_id == dao_wallet_1.dao_info.treasury_id
|
|
199
|
-
|
|
200
|
-
# Get the cat wallets for wallet_1
|
|
201
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
202
|
-
assert cat_wallet_1
|
|
203
|
-
|
|
204
|
-
# Send some cats to the dao_cat lockup
|
|
205
|
-
dao_cat_amt = uint64(100)
|
|
206
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
207
|
-
await dao_wallet_0.enter_dao_cat_voting_mode(dao_cat_amt, action_scope)
|
|
208
|
-
|
|
209
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
210
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
211
|
-
)
|
|
212
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
213
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
214
|
-
|
|
215
|
-
# Test that we can get spendable coins from both cat and dao_cat wallet
|
|
216
|
-
fake_proposal_id = Program.to("proposal_id").get_tree_hash()
|
|
217
|
-
spendable_coins = await dao_cat_wallet_0.wallet_state_manager.get_spendable_coins_for_wallet(
|
|
218
|
-
dao_cat_wallet_0.id(), None
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
assert len(spendable_coins) > 0
|
|
222
|
-
coins = await dao_cat_wallet_0.advanced_select_coins(1, fake_proposal_id)
|
|
223
|
-
assert len(coins) > 0
|
|
224
|
-
# check that we have selected the coin from dao_cat_wallet
|
|
225
|
-
assert coins[0].coin.amount == dao_cat_amt
|
|
226
|
-
|
|
227
|
-
# send some cats from wallet_0 to wallet_1 so we can test voting
|
|
228
|
-
async with cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
229
|
-
await cat_wallet_0.generate_signed_transaction([cat_amt], [ph_1], action_scope)
|
|
230
|
-
|
|
231
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
232
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
233
|
-
)
|
|
234
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
235
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
236
|
-
|
|
237
|
-
await time_out_assert(10, cat_wallet_1.get_confirmed_balance, cat_amt)
|
|
238
|
-
|
|
239
|
-
# Smaller tests of dao_wallet funcs for coverage
|
|
240
|
-
await dao_wallet_0.adjust_filter_level(uint64(10))
|
|
241
|
-
assert dao_wallet_0.dao_info.filter_below_vote_amount == uint64(10)
|
|
242
|
-
|
|
243
|
-
await dao_wallet_0.set_name("Renamed Wallet")
|
|
244
|
-
assert dao_wallet_0.get_name() == "Renamed Wallet"
|
|
245
|
-
|
|
246
|
-
new_inner_puzhash = await dao_wallet_0.get_new_p2_inner_hash()
|
|
247
|
-
assert isinstance(new_inner_puzhash, bytes32)
|
|
248
|
-
|
|
249
|
-
# run DAOCATwallet.create for coverage
|
|
250
|
-
create_dao_cat_from_info = await DAOCATWallet.create(
|
|
251
|
-
wallet_0.wallet_state_manager, wallet_0, dao_cat_wallet_0.wallet_info
|
|
252
|
-
)
|
|
253
|
-
assert create_dao_cat_from_info
|
|
254
|
-
create_dao_wallet_from_info = await DAOWallet.create(
|
|
255
|
-
wallet_0.wallet_state_manager, wallet_0, dao_wallet_0.wallet_info
|
|
256
|
-
)
|
|
257
|
-
assert create_dao_wallet_from_info
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
261
|
-
@pytest.mark.parametrize(
|
|
262
|
-
"trusted",
|
|
263
|
-
[True, False],
|
|
264
|
-
)
|
|
265
|
-
@pytest.mark.anyio
|
|
266
|
-
async def test_dao_funding(self_hostname: str, three_wallet_nodes: OldSimulatorsAndWallets, trusted: bool) -> None:
|
|
267
|
-
full_nodes, wallets, _ = three_wallet_nodes
|
|
268
|
-
full_node_api = full_nodes[0]
|
|
269
|
-
full_node_server = full_node_api.server
|
|
270
|
-
wallet_node_0, server_0 = wallets[0]
|
|
271
|
-
wallet_node_1, server_1 = wallets[1]
|
|
272
|
-
wallet_node_2, server_2 = wallets[2]
|
|
273
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
274
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
275
|
-
wallet_2 = wallet_node_1.wallet_state_manager.main_wallet
|
|
276
|
-
ph = await wallet_0.get_new_puzzlehash()
|
|
277
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
278
|
-
ph_2 = await wallet_2.get_new_puzzlehash()
|
|
279
|
-
|
|
280
|
-
if trusted:
|
|
281
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
282
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
283
|
-
}
|
|
284
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
285
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
286
|
-
}
|
|
287
|
-
wallet_node_2.config["trusted_peers"] = {
|
|
288
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
289
|
-
}
|
|
290
|
-
else:
|
|
291
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
292
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
293
|
-
wallet_node_2.config["trusted_peers"] = {}
|
|
294
|
-
|
|
295
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
296
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
297
|
-
await server_2.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
298
|
-
|
|
299
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
|
|
300
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
301
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_2))
|
|
302
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
303
|
-
|
|
304
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
305
|
-
|
|
306
|
-
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
|
307
|
-
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
|
308
|
-
|
|
309
|
-
cat_amt = 300000
|
|
310
|
-
dao_rules = DAORules(
|
|
311
|
-
proposal_timelock=uint64(5),
|
|
312
|
-
soft_close_length=uint64(5),
|
|
313
|
-
attendance_required=uint64(1000), # 10%
|
|
314
|
-
pass_percentage=uint64(5100), # 51%
|
|
315
|
-
self_destruct_length=uint64(20),
|
|
316
|
-
oracle_spend_delay=uint64(10),
|
|
317
|
-
proposal_minimum_amount=uint64(1),
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
321
|
-
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
|
322
|
-
wallet_node_0.wallet_state_manager, wallet_0, uint64(cat_amt), dao_rules, action_scope
|
|
323
|
-
)
|
|
324
|
-
|
|
325
|
-
treasury_id = dao_wallet_0.dao_info.treasury_id
|
|
326
|
-
|
|
327
|
-
# Get the full node sim to process the wallet creation spend
|
|
328
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
329
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
330
|
-
)
|
|
331
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
332
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
333
|
-
|
|
334
|
-
# get the cat wallets
|
|
335
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
336
|
-
await time_out_assert(20, cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
337
|
-
|
|
338
|
-
# Create funding spends for xch and cat
|
|
339
|
-
xch_funds = uint64(500000)
|
|
340
|
-
cat_funds = uint64(100000)
|
|
341
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
342
|
-
await dao_wallet_0.create_add_funds_to_treasury_spend(xch_funds, action_scope)
|
|
343
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
344
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
345
|
-
)
|
|
346
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
347
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
348
|
-
|
|
349
|
-
# Check that the funding spend is found
|
|
350
|
-
await time_out_assert(20, dao_wallet_0.get_balance_by_asset_type, xch_funds)
|
|
351
|
-
|
|
352
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
353
|
-
await dao_wallet_0.create_add_funds_to_treasury_spend(
|
|
354
|
-
cat_funds, action_scope, funding_wallet_id=cat_wallet_0.id()
|
|
355
|
-
)
|
|
356
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
357
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
358
|
-
)
|
|
359
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
360
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
361
|
-
|
|
362
|
-
await time_out_assert(20, cat_wallet_0.get_confirmed_balance, cat_amt - cat_funds)
|
|
363
|
-
|
|
364
|
-
# Check that the funding spend is found
|
|
365
|
-
cat_id = bytes32.from_hexstr(cat_wallet_0.get_asset_id())
|
|
366
|
-
await time_out_assert(20, dao_wallet_0.get_balance_by_asset_type, cat_funds, cat_id)
|
|
367
|
-
|
|
368
|
-
# Create and close a proposal
|
|
369
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
370
|
-
dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
|
371
|
-
dao_cat_0_bal = await dao_cat_wallet_0.get_votable_balance()
|
|
372
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
373
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dao_cat_0_bal, action_scope)
|
|
374
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
375
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
376
|
-
)
|
|
377
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
378
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
379
|
-
|
|
380
|
-
recipient_puzzle_hash = await wallet_2.get_new_puzzlehash()
|
|
381
|
-
proposal_amount_1 = uint64(10000)
|
|
382
|
-
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
|
383
|
-
treasury_id,
|
|
384
|
-
[recipient_puzzle_hash],
|
|
385
|
-
[proposal_amount_1],
|
|
386
|
-
[None],
|
|
387
|
-
)
|
|
388
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
389
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, dao_cat_0_bal)
|
|
390
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
391
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
392
|
-
)
|
|
393
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
394
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
395
|
-
|
|
396
|
-
# farm blocks to pass proposal
|
|
397
|
-
for _ in range(5):
|
|
398
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
399
|
-
|
|
400
|
-
prop_0 = dao_wallet_0.dao_info.proposals_list[0]
|
|
401
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
402
|
-
await dao_wallet_0.create_proposal_close_spend(prop_0.proposal_id, action_scope)
|
|
403
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
404
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
405
|
-
)
|
|
406
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
407
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
408
|
-
|
|
409
|
-
# Create the other user's wallet from the treasury id
|
|
410
|
-
dao_wallet_1 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
411
|
-
wallet_node_1.wallet_state_manager, wallet_1, treasury_id
|
|
412
|
-
)
|
|
413
|
-
assert dao_wallet_1.dao_info.treasury_id == dao_wallet_1.dao_info.treasury_id
|
|
414
|
-
|
|
415
|
-
# Get the cat wallets for wallet_1
|
|
416
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
417
|
-
assert cat_wallet_1
|
|
418
|
-
assert cat_wallet_1.cat_info.limitations_program_hash == cat_id
|
|
419
|
-
|
|
420
|
-
await time_out_assert(30, dao_wallet_0.get_balance_by_asset_type, xch_funds - 10000)
|
|
421
|
-
await time_out_assert(30, dao_wallet_0.get_balance_by_asset_type, cat_funds, cat_id)
|
|
422
|
-
await time_out_assert(30, dao_wallet_1.get_balance_by_asset_type, xch_funds - 10000)
|
|
423
|
-
await time_out_assert(30, dao_wallet_1.get_balance_by_asset_type, cat_funds, cat_id)
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
427
|
-
@pytest.mark.parametrize(
|
|
428
|
-
"trusted",
|
|
429
|
-
[True, False],
|
|
430
|
-
)
|
|
431
|
-
@pytest.mark.anyio
|
|
432
|
-
async def test_dao_proposals(self_hostname: str, three_wallet_nodes: OldSimulatorsAndWallets, trusted: bool) -> None:
|
|
433
|
-
"""
|
|
434
|
-
Test a set of proposals covering:
|
|
435
|
-
- the spend, update, and mint types.
|
|
436
|
-
- passing and failing
|
|
437
|
-
- force closing broken proposals
|
|
438
|
-
|
|
439
|
-
total cats issued: 300k
|
|
440
|
-
each wallet holds: 100k
|
|
441
|
-
|
|
442
|
-
The proposal types and amounts voted are:
|
|
443
|
-
P0 Spend => Pass
|
|
444
|
-
P1 Mint => Pass
|
|
445
|
-
P2 Update => Pass
|
|
446
|
-
P3 Spend => Fail
|
|
447
|
-
P4 Bad Spend => Force Close
|
|
448
|
-
|
|
449
|
-
"""
|
|
450
|
-
full_nodes, wallets, _ = three_wallet_nodes
|
|
451
|
-
full_node_api = full_nodes[0]
|
|
452
|
-
full_node_server = full_node_api.server
|
|
453
|
-
wallet_node_0, server_0 = wallets[0]
|
|
454
|
-
wallet_node_1, server_1 = wallets[1]
|
|
455
|
-
wallet_node_2, server_2 = wallets[2]
|
|
456
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
457
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
458
|
-
wallet_2 = wallet_node_2.wallet_state_manager.main_wallet
|
|
459
|
-
ph_0 = await wallet_0.get_new_puzzlehash()
|
|
460
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
461
|
-
ph_2 = await wallet_2.get_new_puzzlehash()
|
|
462
|
-
|
|
463
|
-
if trusted:
|
|
464
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
465
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
466
|
-
}
|
|
467
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
468
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
469
|
-
}
|
|
470
|
-
wallet_node_2.config["trusted_peers"] = {
|
|
471
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
472
|
-
}
|
|
473
|
-
else:
|
|
474
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
475
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
476
|
-
wallet_node_2.config["trusted_peers"] = {}
|
|
477
|
-
|
|
478
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
479
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
480
|
-
await server_2.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
481
|
-
|
|
482
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_0))
|
|
483
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
484
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_2))
|
|
485
|
-
|
|
486
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
487
|
-
|
|
488
|
-
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
|
489
|
-
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
|
490
|
-
|
|
491
|
-
# set a standard fee amount to use in all txns
|
|
492
|
-
base_fee = uint64(100)
|
|
493
|
-
|
|
494
|
-
# set the cat issuance and DAO rules
|
|
495
|
-
cat_issuance = 300000
|
|
496
|
-
proposal_min_amt = uint64(101)
|
|
497
|
-
dao_rules = DAORules(
|
|
498
|
-
proposal_timelock=uint64(10),
|
|
499
|
-
soft_close_length=uint64(5),
|
|
500
|
-
attendance_required=uint64(190000),
|
|
501
|
-
pass_percentage=uint64(5100), # 51%
|
|
502
|
-
self_destruct_length=uint64(20),
|
|
503
|
-
oracle_spend_delay=uint64(10),
|
|
504
|
-
proposal_minimum_amount=proposal_min_amt,
|
|
505
|
-
)
|
|
506
|
-
|
|
507
|
-
# Create the DAO.
|
|
508
|
-
# This takes two steps: create the treasury singleton, wait for oracle_spend_delay and
|
|
509
|
-
# then complete the eve spend
|
|
510
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
511
|
-
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
|
512
|
-
wallet_node_0.wallet_state_manager,
|
|
513
|
-
wallet_0,
|
|
514
|
-
uint64(cat_issuance),
|
|
515
|
-
dao_rules,
|
|
516
|
-
action_scope,
|
|
517
|
-
)
|
|
518
|
-
|
|
519
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
520
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
521
|
-
)
|
|
522
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
523
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
524
|
-
|
|
525
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
526
|
-
dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
|
527
|
-
await time_out_assert(10, cat_wallet_0.get_confirmed_balance, cat_issuance)
|
|
528
|
-
assert dao_cat_wallet_0
|
|
529
|
-
|
|
530
|
-
treasury_id = dao_wallet_0.dao_info.treasury_id
|
|
531
|
-
|
|
532
|
-
# Create dao_wallet_1 from the treasury id
|
|
533
|
-
dao_wallet_1 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
534
|
-
wallet_node_1.wallet_state_manager, wallet_1, treasury_id
|
|
535
|
-
)
|
|
536
|
-
assert dao_wallet_1.dao_info.treasury_id == treasury_id
|
|
537
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
538
|
-
dao_cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.dao_cat_wallet_id]
|
|
539
|
-
assert cat_wallet_1
|
|
540
|
-
assert dao_cat_wallet_1
|
|
541
|
-
|
|
542
|
-
# Create dao_wallet_2 from the treasury id
|
|
543
|
-
dao_wallet_2 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
544
|
-
wallet_node_2.wallet_state_manager, wallet_2, treasury_id
|
|
545
|
-
)
|
|
546
|
-
assert dao_wallet_2.dao_info.treasury_id == treasury_id
|
|
547
|
-
cat_wallet_2 = dao_wallet_2.wallet_state_manager.wallets[dao_wallet_2.dao_info.cat_wallet_id]
|
|
548
|
-
dao_cat_wallet_2 = dao_wallet_2.wallet_state_manager.wallets[dao_wallet_2.dao_info.dao_cat_wallet_id]
|
|
549
|
-
assert cat_wallet_2
|
|
550
|
-
assert dao_cat_wallet_2
|
|
551
|
-
|
|
552
|
-
# Send 100k cats to wallet_1 and wallet_2
|
|
553
|
-
cat_amt = uint64(100000)
|
|
554
|
-
async with cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
555
|
-
await cat_wallet_0.generate_signed_transaction([cat_amt, cat_amt], [ph_1, ph_2], action_scope, fee=base_fee)
|
|
556
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
557
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
558
|
-
)
|
|
559
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
560
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
561
|
-
|
|
562
|
-
# Lockup voting cats for all wallets
|
|
563
|
-
dao_cat_0_bal = await dao_cat_wallet_0.get_votable_balance()
|
|
564
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
565
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dao_cat_0_bal, action_scope, fee=base_fee)
|
|
566
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
567
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
568
|
-
)
|
|
569
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
570
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
571
|
-
|
|
572
|
-
dao_cat_1_bal = await dao_cat_wallet_1.get_votable_balance()
|
|
573
|
-
async with dao_cat_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
574
|
-
await dao_cat_wallet_1.enter_dao_cat_voting_mode(dao_cat_1_bal, action_scope)
|
|
575
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
576
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
577
|
-
)
|
|
578
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
579
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
580
|
-
|
|
581
|
-
dao_cat_2_bal = await dao_cat_wallet_2.get_votable_balance()
|
|
582
|
-
async with dao_cat_wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
583
|
-
await dao_cat_wallet_2.enter_dao_cat_voting_mode(dao_cat_2_bal, action_scope)
|
|
584
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
585
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
586
|
-
)
|
|
587
|
-
await full_node_api.process_all_wallet_transactions(wallet_2, timeout=60)
|
|
588
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
589
|
-
|
|
590
|
-
await time_out_assert(10, dao_cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
591
|
-
await time_out_assert(10, dao_cat_wallet_1.get_confirmed_balance, cat_amt)
|
|
592
|
-
await time_out_assert(10, dao_cat_wallet_2.get_confirmed_balance, cat_amt)
|
|
593
|
-
|
|
594
|
-
# Create funding spend so the treasury holds some XCH
|
|
595
|
-
xch_funds = uint64(500000)
|
|
596
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
597
|
-
await dao_wallet_0.create_add_funds_to_treasury_spend(xch_funds, action_scope)
|
|
598
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
599
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
600
|
-
)
|
|
601
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
602
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
603
|
-
|
|
604
|
-
# Check that the funding spend is recognized by all wallets
|
|
605
|
-
await time_out_assert(10, dao_wallet_0.get_balance_by_asset_type, xch_funds)
|
|
606
|
-
await time_out_assert(10, dao_wallet_1.get_balance_by_asset_type, xch_funds)
|
|
607
|
-
await time_out_assert(10, dao_wallet_2.get_balance_by_asset_type, xch_funds)
|
|
608
|
-
|
|
609
|
-
# Create Proposals
|
|
610
|
-
|
|
611
|
-
# Proposal 0: Spend xch to wallet_2.
|
|
612
|
-
recipient_puzzle_hash = await wallet_2.get_new_puzzlehash()
|
|
613
|
-
proposal_amount_1 = uint64(9998)
|
|
614
|
-
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
|
615
|
-
treasury_id,
|
|
616
|
-
[recipient_puzzle_hash],
|
|
617
|
-
[proposal_amount_1],
|
|
618
|
-
[None],
|
|
619
|
-
)
|
|
620
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
621
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, dao_cat_0_bal, fee=base_fee)
|
|
622
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
623
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
624
|
-
)
|
|
625
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
626
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
627
|
-
|
|
628
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 1
|
|
629
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == dao_cat_0_bal
|
|
630
|
-
assert dao_wallet_0.dao_info.proposals_list[0].timer_coin is not None
|
|
631
|
-
prop_0 = dao_wallet_0.dao_info.proposals_list[0]
|
|
632
|
-
|
|
633
|
-
# Proposal 1: Mint new CATs
|
|
634
|
-
new_mint_amount = uint64(1000)
|
|
635
|
-
mint_proposal_inner = await generate_mint_proposal_innerpuz(
|
|
636
|
-
treasury_id,
|
|
637
|
-
cat_wallet_0.cat_info.limitations_program_hash,
|
|
638
|
-
new_mint_amount,
|
|
639
|
-
recipient_puzzle_hash,
|
|
640
|
-
)
|
|
641
|
-
|
|
642
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
643
|
-
await dao_wallet_0.generate_new_proposal(
|
|
644
|
-
mint_proposal_inner, action_scope, vote_amount=dao_cat_0_bal, fee=base_fee
|
|
645
|
-
)
|
|
646
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
647
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
648
|
-
)
|
|
649
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
650
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
651
|
-
|
|
652
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 2
|
|
653
|
-
prop_1 = dao_wallet_0.dao_info.proposals_list[1]
|
|
654
|
-
|
|
655
|
-
# Proposal 2: Update DAO Rules.
|
|
656
|
-
new_dao_rules = DAORules(
|
|
657
|
-
proposal_timelock=uint64(8),
|
|
658
|
-
soft_close_length=uint64(4),
|
|
659
|
-
attendance_required=uint64(150000),
|
|
660
|
-
pass_percentage=uint64(7500),
|
|
661
|
-
self_destruct_length=uint64(12),
|
|
662
|
-
oracle_spend_delay=uint64(5),
|
|
663
|
-
proposal_minimum_amount=uint64(1),
|
|
664
|
-
)
|
|
665
|
-
current_innerpuz = dao_wallet_0.dao_info.current_treasury_innerpuz
|
|
666
|
-
assert current_innerpuz is not None
|
|
667
|
-
update_inner = await generate_update_proposal_innerpuz(current_innerpuz, new_dao_rules)
|
|
668
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
669
|
-
await dao_wallet_0.generate_new_proposal(update_inner, action_scope, dao_cat_0_bal, fee=base_fee)
|
|
670
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
671
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
672
|
-
)
|
|
673
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
674
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
675
|
-
|
|
676
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 3
|
|
677
|
-
prop_2 = dao_wallet_0.dao_info.proposals_list[2]
|
|
678
|
-
|
|
679
|
-
# Proposal 3: Spend xch to wallet_2 (this prop will close as failed)
|
|
680
|
-
proposal_amount_2 = uint64(500)
|
|
681
|
-
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
|
682
|
-
treasury_id, [recipient_puzzle_hash], [proposal_amount_2], [None]
|
|
683
|
-
)
|
|
684
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
685
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, dao_cat_0_bal, fee=base_fee)
|
|
686
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
687
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
688
|
-
)
|
|
689
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
690
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
691
|
-
|
|
692
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 4
|
|
693
|
-
prop_3 = dao_wallet_0.dao_info.proposals_list[3]
|
|
694
|
-
|
|
695
|
-
# Proposal 4: Create a 'bad' proposal (can't be executed, must be force-closed)
|
|
696
|
-
xch_proposal_inner = Program.to(["x"])
|
|
697
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
698
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, dao_cat_0_bal, fee=base_fee)
|
|
699
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
700
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
701
|
-
)
|
|
702
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
703
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
704
|
-
|
|
705
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 5
|
|
706
|
-
assert len(dao_wallet_1.dao_info.proposals_list) == 5
|
|
707
|
-
assert len(dao_wallet_1.dao_info.proposals_list) == 5
|
|
708
|
-
prop_4 = dao_wallet_0.dao_info.proposals_list[4]
|
|
709
|
-
|
|
710
|
-
# Proposal 0 Voting: wallet 1 votes yes, wallet 2 votes no. Proposal Passes
|
|
711
|
-
async with dao_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
712
|
-
await dao_wallet_1.generate_proposal_vote_spend(prop_0.proposal_id, dao_cat_1_bal, True, action_scope)
|
|
713
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
714
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
715
|
-
)
|
|
716
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
717
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
718
|
-
|
|
719
|
-
async with dao_wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
720
|
-
await dao_wallet_2.generate_proposal_vote_spend(prop_0.proposal_id, dao_cat_2_bal, False, action_scope)
|
|
721
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
722
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
723
|
-
)
|
|
724
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
725
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
726
|
-
|
|
727
|
-
total_votes = dao_cat_0_bal + dao_cat_1_bal + dao_cat_2_bal
|
|
728
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == total_votes
|
|
729
|
-
assert dao_wallet_0.dao_info.proposals_list[0].yes_votes == total_votes - dao_cat_2_bal
|
|
730
|
-
assert dao_wallet_1.dao_info.proposals_list[0].amount_voted == total_votes
|
|
731
|
-
assert dao_wallet_1.dao_info.proposals_list[0].yes_votes == total_votes - dao_cat_2_bal
|
|
732
|
-
assert dao_wallet_2.dao_info.proposals_list[0].amount_voted == total_votes
|
|
733
|
-
assert dao_wallet_2.dao_info.proposals_list[0].yes_votes == total_votes - dao_cat_2_bal
|
|
734
|
-
|
|
735
|
-
prop_0_state = await dao_wallet_0.get_proposal_state(prop_0.proposal_id)
|
|
736
|
-
assert prop_0_state["passed"]
|
|
737
|
-
assert prop_0_state["closable"]
|
|
738
|
-
|
|
739
|
-
# Proposal 0 is closable, but soft_close_length has not passed.
|
|
740
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
741
|
-
await dao_wallet_0.create_proposal_close_spend(prop_0.proposal_id, action_scope)
|
|
742
|
-
with pytest.raises(AssertionError, match="Timed assertion timed out"):
|
|
743
|
-
assert action_scope.side_effects.transactions[0].spend_bundle is not None
|
|
744
|
-
await time_out_assert_not_none(
|
|
745
|
-
5,
|
|
746
|
-
full_node_api.full_node.mempool_manager.get_spendbundle,
|
|
747
|
-
action_scope.side_effects.transactions[0].spend_bundle.name(),
|
|
748
|
-
)
|
|
749
|
-
|
|
750
|
-
for _ in range(5):
|
|
751
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
752
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
753
|
-
|
|
754
|
-
# Proposal 0: Close
|
|
755
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
756
|
-
await dao_wallet_0.create_proposal_close_spend(prop_0.proposal_id, action_scope)
|
|
757
|
-
close_sb_0 = action_scope.side_effects.transactions[0].spend_bundle
|
|
758
|
-
assert close_sb_0 is not None
|
|
759
|
-
await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, close_sb_0.name())
|
|
760
|
-
await full_node_api.process_spend_bundles(bundles=[close_sb_0])
|
|
761
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
762
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
763
|
-
await time_out_assert(20, wallet_2.get_confirmed_balance, funds + proposal_amount_1)
|
|
764
|
-
await time_out_assert(
|
|
765
|
-
20, dao_wallet_0.get_balance_by_asset_type, xch_funds - proposal_amount_1 + proposal_min_amt - 1
|
|
766
|
-
)
|
|
767
|
-
|
|
768
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_0, 0])
|
|
769
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_1, 0])
|
|
770
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_2, 0])
|
|
771
|
-
|
|
772
|
-
# Proposal 1 vote and close
|
|
773
|
-
async with dao_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
774
|
-
await dao_wallet_1.generate_proposal_vote_spend(prop_1.proposal_id, dao_cat_1_bal, True, action_scope)
|
|
775
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
776
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
777
|
-
)
|
|
778
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
779
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
780
|
-
|
|
781
|
-
for _ in range(10):
|
|
782
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
783
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
784
|
-
|
|
785
|
-
prop_1_state = await dao_wallet_0.get_proposal_state(prop_1.proposal_id)
|
|
786
|
-
assert prop_1_state["passed"]
|
|
787
|
-
assert prop_1_state["closable"]
|
|
788
|
-
|
|
789
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
790
|
-
await dao_wallet_0.create_proposal_close_spend(prop_1.proposal_id, action_scope)
|
|
791
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
792
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
793
|
-
)
|
|
794
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
795
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
796
|
-
|
|
797
|
-
await time_out_assert(20, cat_wallet_2.get_confirmed_balance, new_mint_amount)
|
|
798
|
-
|
|
799
|
-
# Proposal 2 vote and close
|
|
800
|
-
async with dao_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
801
|
-
await dao_wallet_1.generate_proposal_vote_spend(prop_2.proposal_id, dao_cat_1_bal, True, action_scope)
|
|
802
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
803
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
804
|
-
)
|
|
805
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
806
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
807
|
-
|
|
808
|
-
for _ in range(10):
|
|
809
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
810
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
811
|
-
|
|
812
|
-
prop_2_state = await dao_wallet_0.get_proposal_state(prop_2.proposal_id)
|
|
813
|
-
assert prop_2_state["passed"]
|
|
814
|
-
assert prop_2_state["closable"]
|
|
815
|
-
|
|
816
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
817
|
-
await dao_wallet_0.create_proposal_close_spend(prop_2.proposal_id, action_scope)
|
|
818
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
819
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
820
|
-
)
|
|
821
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
822
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
823
|
-
|
|
824
|
-
assert dao_wallet_0.dao_rules == new_dao_rules
|
|
825
|
-
assert dao_wallet_1.dao_rules == new_dao_rules
|
|
826
|
-
assert dao_wallet_2.dao_rules == new_dao_rules
|
|
827
|
-
|
|
828
|
-
# Proposal 3 - Close as FAILED
|
|
829
|
-
async with dao_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
830
|
-
await dao_wallet_1.generate_proposal_vote_spend(prop_3.proposal_id, dao_cat_1_bal, False, action_scope)
|
|
831
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
832
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
833
|
-
)
|
|
834
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
835
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
836
|
-
|
|
837
|
-
for _ in range(10):
|
|
838
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
839
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
840
|
-
|
|
841
|
-
prop_3_state = await dao_wallet_1.get_proposal_state(prop_3.proposal_id)
|
|
842
|
-
assert not prop_3_state["passed"]
|
|
843
|
-
assert prop_3_state["closable"]
|
|
844
|
-
|
|
845
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
846
|
-
await dao_wallet_0.create_proposal_close_spend(prop_3.proposal_id, action_scope)
|
|
847
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
848
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
849
|
-
)
|
|
850
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
851
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
852
|
-
|
|
853
|
-
await time_out_assert(20, wallet_2.get_confirmed_balance, funds + proposal_amount_1)
|
|
854
|
-
expected_balance = xch_funds - proposal_amount_1 + (3 * proposal_min_amt) - 3 - new_mint_amount
|
|
855
|
-
await time_out_assert(20, dao_wallet_0.get_balance_by_asset_type, expected_balance)
|
|
856
|
-
|
|
857
|
-
await time_out_assert(20, get_proposal_state, (False, True), *[dao_wallet_0, 3])
|
|
858
|
-
await time_out_assert(20, get_proposal_state, (False, True), *[dao_wallet_1, 3])
|
|
859
|
-
await time_out_assert(20, get_proposal_state, (False, True), *[dao_wallet_2, 3])
|
|
860
|
-
|
|
861
|
-
# Proposal 4 - Self Destruct a broken proposal
|
|
862
|
-
async with dao_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
863
|
-
await dao_wallet_1.generate_proposal_vote_spend(prop_4.proposal_id, dao_cat_1_bal, True, action_scope)
|
|
864
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
865
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
866
|
-
)
|
|
867
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
868
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
869
|
-
|
|
870
|
-
for _ in range(10):
|
|
871
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
872
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
873
|
-
|
|
874
|
-
prop_4_state = await dao_wallet_1.get_proposal_state(prop_4.proposal_id)
|
|
875
|
-
assert prop_4_state["passed"]
|
|
876
|
-
assert prop_4_state["closable"]
|
|
877
|
-
|
|
878
|
-
with pytest.raises(Exception, match="Unrecognised proposal type"):
|
|
879
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
880
|
-
await dao_wallet_0.create_proposal_close_spend(prop_4.proposal_id, action_scope)
|
|
881
|
-
|
|
882
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
883
|
-
await dao_wallet_0.create_proposal_close_spend(prop_4.proposal_id, action_scope, self_destruct=True)
|
|
884
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
885
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
886
|
-
)
|
|
887
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
888
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
889
|
-
|
|
890
|
-
# expected balance is unchanged because broken props can't release their amount
|
|
891
|
-
await time_out_assert(20, dao_wallet_0.get_balance_by_asset_type, expected_balance)
|
|
892
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_0, 4])
|
|
893
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_1, 4])
|
|
894
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_2, 4])
|
|
895
|
-
|
|
896
|
-
# Remove Proposals from Memory and Free up locked coins
|
|
897
|
-
await time_out_assert(20, len, 5, dao_wallet_0.dao_info.proposals_list)
|
|
898
|
-
await dao_wallet_0.clear_finished_proposals_from_memory()
|
|
899
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
900
|
-
await dao_wallet_0.free_coins_from_finished_proposals(action_scope, fee=uint64(100))
|
|
901
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
902
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
903
|
-
)
|
|
904
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
905
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
906
|
-
|
|
907
|
-
await dao_wallet_0.clear_finished_proposals_from_memory()
|
|
908
|
-
await time_out_assert(20, len, 0, dao_wallet_0.dao_info.proposals_list)
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
912
|
-
@pytest.mark.parametrize(
|
|
913
|
-
"trusted",
|
|
914
|
-
[True, False],
|
|
915
|
-
)
|
|
916
|
-
@pytest.mark.anyio
|
|
917
|
-
async def test_dao_proposal_partial_vote(
|
|
918
|
-
self_hostname: str, two_wallet_nodes: OldSimulatorsAndWallets, trusted: bool
|
|
919
|
-
) -> None:
|
|
920
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
921
|
-
full_node_api = full_nodes[0]
|
|
922
|
-
full_node_server = full_node_api.server
|
|
923
|
-
wallet_node_0, server_0 = wallets[0]
|
|
924
|
-
wallet_node_1, server_1 = wallets[1]
|
|
925
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
926
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
927
|
-
ph = await wallet_0.get_new_puzzlehash()
|
|
928
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
929
|
-
|
|
930
|
-
if trusted:
|
|
931
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
932
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
933
|
-
}
|
|
934
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
935
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
936
|
-
}
|
|
937
|
-
else:
|
|
938
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
939
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
940
|
-
|
|
941
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
942
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
943
|
-
|
|
944
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
|
|
945
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
946
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
947
|
-
|
|
948
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
949
|
-
|
|
950
|
-
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
|
951
|
-
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
|
952
|
-
|
|
953
|
-
cat_amt = 300000
|
|
954
|
-
dao_rules = DAORules(
|
|
955
|
-
proposal_timelock=uint64(10),
|
|
956
|
-
soft_close_length=uint64(5),
|
|
957
|
-
attendance_required=uint64(1000), # 10%
|
|
958
|
-
pass_percentage=uint64(5100), # 51%
|
|
959
|
-
self_destruct_length=uint64(20),
|
|
960
|
-
oracle_spend_delay=uint64(10),
|
|
961
|
-
proposal_minimum_amount=uint64(1),
|
|
962
|
-
)
|
|
963
|
-
|
|
964
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
965
|
-
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
|
966
|
-
wallet_node_0.wallet_state_manager, wallet_0, uint64(cat_amt), dao_rules, action_scope
|
|
967
|
-
)
|
|
968
|
-
|
|
969
|
-
# Get the full node sim to process the wallet creation spend
|
|
970
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
971
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
972
|
-
)
|
|
973
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
974
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
975
|
-
|
|
976
|
-
# get the cat wallets
|
|
977
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
978
|
-
await time_out_assert(10, cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
979
|
-
|
|
980
|
-
# get the dao_cat wallet
|
|
981
|
-
dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
|
982
|
-
|
|
983
|
-
treasury_id = dao_wallet_0.dao_info.treasury_id
|
|
984
|
-
|
|
985
|
-
# make sure the next wallet node can find the treasury
|
|
986
|
-
assert dao_wallet_0.dao_info.current_treasury_coin is not None
|
|
987
|
-
treasury_parent = dao_wallet_0.dao_info.current_treasury_coin.parent_coin_info
|
|
988
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
989
|
-
await time_out_assert_not_none(
|
|
990
|
-
60, wallet_node_1.fetch_children, treasury_parent, wallet_node_1.get_full_node_peer()
|
|
991
|
-
)
|
|
992
|
-
# Create the other user's wallet from the treasury id
|
|
993
|
-
dao_wallet_1 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
994
|
-
wallet_node_1.wallet_state_manager, wallet_1, treasury_id
|
|
995
|
-
)
|
|
996
|
-
assert dao_wallet_1.dao_info.treasury_id == treasury_id
|
|
997
|
-
|
|
998
|
-
# Create funding spends for xch
|
|
999
|
-
xch_funds = uint64(500000)
|
|
1000
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1001
|
-
await dao_wallet_0.create_add_funds_to_treasury_spend(
|
|
1002
|
-
xch_funds,
|
|
1003
|
-
action_scope,
|
|
1004
|
-
)
|
|
1005
|
-
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1006
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1007
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
1008
|
-
|
|
1009
|
-
# Check that the funding spend is recognized by both dao wallets
|
|
1010
|
-
await time_out_assert(10, dao_wallet_0.get_balance_by_asset_type, xch_funds)
|
|
1011
|
-
|
|
1012
|
-
# Send some dao_cats to wallet_1
|
|
1013
|
-
# Get the cat wallets for wallet_1
|
|
1014
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
1015
|
-
dao_cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.dao_cat_wallet_id]
|
|
1016
|
-
assert cat_wallet_1
|
|
1017
|
-
assert dao_cat_wallet_1
|
|
1018
|
-
|
|
1019
|
-
async with cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1020
|
-
await cat_wallet_0.generate_signed_transaction([100000], [ph_1], action_scope)
|
|
1021
|
-
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1022
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1023
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
1024
|
-
await time_out_assert(10, cat_wallet_1.get_spendable_balance, 100000)
|
|
1025
|
-
|
|
1026
|
-
# Create dao cats for voting
|
|
1027
|
-
dao_cat_0_bal = await dao_cat_wallet_0.get_votable_balance()
|
|
1028
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1029
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dao_cat_0_bal, action_scope)
|
|
1030
|
-
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1031
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1032
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1033
|
-
|
|
1034
|
-
# Create a mint proposal
|
|
1035
|
-
recipient_puzzle_hash = await cat_wallet_1.standard_wallet.get_puzzle_hash(new=False)
|
|
1036
|
-
new_mint_amount = uint64(500)
|
|
1037
|
-
mint_proposal_inner = await generate_mint_proposal_innerpuz(
|
|
1038
|
-
treasury_id,
|
|
1039
|
-
cat_wallet_0.cat_info.limitations_program_hash,
|
|
1040
|
-
new_mint_amount,
|
|
1041
|
-
recipient_puzzle_hash,
|
|
1042
|
-
)
|
|
1043
|
-
|
|
1044
|
-
vote_amount = dao_cat_0_bal - 10
|
|
1045
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1046
|
-
await dao_wallet_0.generate_new_proposal(
|
|
1047
|
-
mint_proposal_inner, action_scope, vote_amount=vote_amount, fee=uint64(1000)
|
|
1048
|
-
)
|
|
1049
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=action_scope.side_effects.transactions)
|
|
1050
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1051
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1052
|
-
|
|
1053
|
-
# Check the proposal is saved
|
|
1054
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 1
|
|
1055
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == vote_amount
|
|
1056
|
-
assert dao_wallet_0.dao_info.proposals_list[0].timer_coin is not None
|
|
1057
|
-
|
|
1058
|
-
# Check that wallet_1 also finds and saved the proposal
|
|
1059
|
-
assert len(dao_wallet_1.dao_info.proposals_list) == 1
|
|
1060
|
-
prop = dao_wallet_1.dao_info.proposals_list[0]
|
|
1061
|
-
|
|
1062
|
-
# Create votable dao cats and add a new vote
|
|
1063
|
-
dao_cat_1_bal = await dao_cat_wallet_1.get_votable_balance()
|
|
1064
|
-
async with dao_cat_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1065
|
-
await dao_cat_wallet_1.enter_dao_cat_voting_mode(dao_cat_1_bal, action_scope)
|
|
1066
|
-
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1067
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1068
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1069
|
-
|
|
1070
|
-
async with dao_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1071
|
-
await dao_wallet_1.generate_proposal_vote_spend(prop.proposal_id, dao_cat_1_bal // 2, True, action_scope)
|
|
1072
|
-
[vote_tx] = action_scope.side_effects.transactions
|
|
1073
|
-
vote_sb = vote_tx.spend_bundle
|
|
1074
|
-
assert vote_sb is not None
|
|
1075
|
-
await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, vote_sb.name())
|
|
1076
|
-
await full_node_api.process_spend_bundles(bundles=[vote_sb])
|
|
1077
|
-
|
|
1078
|
-
for i in range(1, dao_rules.proposal_timelock + 1):
|
|
1079
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1080
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1081
|
-
|
|
1082
|
-
total_votes = vote_amount + dao_cat_1_bal // 2
|
|
1083
|
-
|
|
1084
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == total_votes
|
|
1085
|
-
assert dao_wallet_0.dao_info.proposals_list[0].yes_votes == total_votes
|
|
1086
|
-
assert dao_wallet_1.dao_info.proposals_list[0].amount_voted == total_votes
|
|
1087
|
-
assert dao_wallet_1.dao_info.proposals_list[0].yes_votes == total_votes
|
|
1088
|
-
|
|
1089
|
-
try:
|
|
1090
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1091
|
-
await dao_wallet_0.create_proposal_close_spend(prop.proposal_id, action_scope, fee=uint64(100))
|
|
1092
|
-
except Exception as e: # pragma: no cover
|
|
1093
|
-
print(e)
|
|
1094
|
-
|
|
1095
|
-
await full_node_api.process_transaction_records(action_scope.side_effects.transactions)
|
|
1096
|
-
balance = await cat_wallet_1.get_spendable_balance()
|
|
1097
|
-
|
|
1098
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1099
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1100
|
-
|
|
1101
|
-
await time_out_assert(20, get_proposal_state, (True, True), dao_wallet_0, 0)
|
|
1102
|
-
await time_out_assert(20, get_proposal_state, (True, True), dao_wallet_1, 0)
|
|
1103
|
-
|
|
1104
|
-
await time_out_assert(20, cat_wallet_1.get_spendable_balance, balance + new_mint_amount)
|
|
1105
|
-
# Can we spend the newly minted CATs?
|
|
1106
|
-
old_balance = await cat_wallet_0.get_spendable_balance()
|
|
1107
|
-
ph_0 = await cat_wallet_0.standard_wallet.get_puzzle_hash(new=False)
|
|
1108
|
-
async with cat_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1109
|
-
await cat_wallet_1.generate_signed_transaction([balance + new_mint_amount], [ph_0], action_scope)
|
|
1110
|
-
await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
|
|
1111
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1112
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1113
|
-
|
|
1114
|
-
await time_out_assert(20, cat_wallet_1.get_spendable_balance, 0)
|
|
1115
|
-
await time_out_assert(20, cat_wallet_0.get_spendable_balance, old_balance + balance + new_mint_amount)
|
|
1116
|
-
# release coins
|
|
1117
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
1118
|
-
await dao_wallet_0.free_coins_from_finished_proposals(action_scope)
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
1122
|
-
@pytest.mark.parametrize(
|
|
1123
|
-
"trusted",
|
|
1124
|
-
[True, False],
|
|
1125
|
-
)
|
|
1126
|
-
@pytest.mark.anyio
|
|
1127
|
-
async def test_dao_rpc_api(self_hostname: str, two_wallet_nodes: Any, trusted: Any) -> None:
|
|
1128
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
1129
|
-
full_node_api = full_nodes[0]
|
|
1130
|
-
full_node_server = full_node_api.server
|
|
1131
|
-
wallet_node_0, server_0 = wallets[0]
|
|
1132
|
-
wallet_node_1, server_1 = wallets[1]
|
|
1133
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
1134
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
1135
|
-
|
|
1136
|
-
ph_0 = await wallet_0.get_new_puzzlehash()
|
|
1137
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
1138
|
-
|
|
1139
|
-
if trusted:
|
|
1140
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
1141
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
1142
|
-
}
|
|
1143
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
1144
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
1145
|
-
}
|
|
1146
|
-
else:
|
|
1147
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
1148
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
1149
|
-
|
|
1150
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
1151
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
1152
|
-
|
|
1153
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_0))
|
|
1154
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1155
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
1156
|
-
|
|
1157
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
1158
|
-
|
|
1159
|
-
await time_out_assert(30, wallet_0.get_unconfirmed_balance, funds)
|
|
1160
|
-
await time_out_assert(30, wallet_0.get_confirmed_balance, funds)
|
|
1161
|
-
|
|
1162
|
-
api_0 = WalletRpcApi(wallet_node_0)
|
|
1163
|
-
api_1 = WalletRpcApi(wallet_node_1)
|
|
1164
|
-
|
|
1165
|
-
cat_amt = 300000
|
|
1166
|
-
fee = 10000
|
|
1167
|
-
dao_rules = DAORules(
|
|
1168
|
-
proposal_timelock=uint64(10),
|
|
1169
|
-
soft_close_length=uint64(5),
|
|
1170
|
-
attendance_required=uint64(1000), # 10%
|
|
1171
|
-
pass_percentage=uint64(5100), # 51%
|
|
1172
|
-
self_destruct_length=uint64(20),
|
|
1173
|
-
oracle_spend_delay=uint64(10),
|
|
1174
|
-
proposal_minimum_amount=uint64(1),
|
|
1175
|
-
)
|
|
1176
|
-
|
|
1177
|
-
# Try to create a DAO without rules
|
|
1178
|
-
with pytest.raises(ValueError) as e_info:
|
|
1179
|
-
dao_wallet_0 = await api_0.create_new_wallet(
|
|
1180
|
-
dict(
|
|
1181
|
-
wallet_type="dao_wallet",
|
|
1182
|
-
name="DAO WALLET 1",
|
|
1183
|
-
mode="new",
|
|
1184
|
-
amount_of_cats=cat_amt,
|
|
1185
|
-
filter_amount=1,
|
|
1186
|
-
fee=fee,
|
|
1187
|
-
)
|
|
1188
|
-
)
|
|
1189
|
-
assert e_info.value.args[0] == "DAO rules must be specified for wallet creation"
|
|
1190
|
-
|
|
1191
|
-
dao_wallet_0 = await api_0.create_new_wallet(
|
|
1192
|
-
dict(
|
|
1193
|
-
wallet_type="dao_wallet",
|
|
1194
|
-
name="DAO WALLET 1",
|
|
1195
|
-
mode="new",
|
|
1196
|
-
dao_rules=dao_rules,
|
|
1197
|
-
amount_of_cats=cat_amt,
|
|
1198
|
-
filter_amount=1,
|
|
1199
|
-
fee=fee,
|
|
1200
|
-
)
|
|
1201
|
-
)
|
|
1202
|
-
assert isinstance(dao_wallet_0, dict)
|
|
1203
|
-
assert dao_wallet_0.get("success")
|
|
1204
|
-
dao_wallet_0_id = dao_wallet_0["wallet_id"]
|
|
1205
|
-
dao_cat_wallet_0_id = dao_wallet_0["cat_wallet_id"]
|
|
1206
|
-
treasury_id = bytes32(dao_wallet_0["treasury_id"])
|
|
1207
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1208
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1209
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1210
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
1211
|
-
|
|
1212
|
-
await time_out_assert(30, wallet_0.get_pending_change_balance, 0)
|
|
1213
|
-
expected_xch = funds - 1 - cat_amt - fee
|
|
1214
|
-
await time_out_assert(30, wallet_0.get_confirmed_balance, expected_xch)
|
|
1215
|
-
|
|
1216
|
-
dao_wallet_1 = await api_1.create_new_wallet(
|
|
1217
|
-
dict(
|
|
1218
|
-
wallet_type="dao_wallet",
|
|
1219
|
-
name="DAO WALLET 2",
|
|
1220
|
-
mode="existing",
|
|
1221
|
-
treasury_id=treasury_id.hex(),
|
|
1222
|
-
filter_amount=1,
|
|
1223
|
-
)
|
|
1224
|
-
)
|
|
1225
|
-
assert isinstance(dao_wallet_1, dict)
|
|
1226
|
-
assert dao_wallet_1.get("success")
|
|
1227
|
-
dao_wallet_1_id = dao_wallet_1["wallet_id"]
|
|
1228
|
-
# Create a cat wallet and add funds to treasury
|
|
1229
|
-
new_cat_amt = 1000000000000
|
|
1230
|
-
cat_wallet_0 = await api_0.create_new_wallet(
|
|
1231
|
-
dict(
|
|
1232
|
-
wallet_type="cat_wallet",
|
|
1233
|
-
name="CAT WALLET 1",
|
|
1234
|
-
test=True,
|
|
1235
|
-
mode="new",
|
|
1236
|
-
amount=new_cat_amt,
|
|
1237
|
-
)
|
|
1238
|
-
)
|
|
1239
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1240
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1241
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1242
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
1243
|
-
|
|
1244
|
-
cat_wallet_0_id = cat_wallet_0["wallet_id"]
|
|
1245
|
-
cat_id = bytes32.from_hexstr(cat_wallet_0["asset_id"])
|
|
1246
|
-
|
|
1247
|
-
await rpc_state(
|
|
1248
|
-
20,
|
|
1249
|
-
api_0.get_wallet_balance,
|
|
1250
|
-
[{"wallet_id": cat_wallet_0_id}],
|
|
1251
|
-
lambda x: x["wallet_balance"]["confirmed_wallet_balance"],
|
|
1252
|
-
new_cat_amt,
|
|
1253
|
-
)
|
|
1254
|
-
|
|
1255
|
-
cat_funding_amt = 500000
|
|
1256
|
-
cat_tx = await api_0.dao_add_funds_to_treasury(
|
|
1257
|
-
dict(
|
|
1258
|
-
wallet_id=dao_wallet_0_id,
|
|
1259
|
-
amount=cat_funding_amt,
|
|
1260
|
-
funding_wallet_id=cat_wallet_0_id,
|
|
1261
|
-
)
|
|
1262
|
-
)
|
|
1263
|
-
|
|
1264
|
-
xch_funding_amt = 200000
|
|
1265
|
-
xch_tx = await api_0.dao_add_funds_to_treasury(
|
|
1266
|
-
dict(
|
|
1267
|
-
wallet_id=dao_wallet_0_id,
|
|
1268
|
-
amount=xch_funding_amt,
|
|
1269
|
-
funding_wallet_id=1,
|
|
1270
|
-
)
|
|
1271
|
-
)
|
|
1272
|
-
txs = [TransactionRecord.from_json_dict(cat_tx["tx"]), TransactionRecord.from_json_dict(xch_tx["tx"])]
|
|
1273
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1274
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1275
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
1276
|
-
|
|
1277
|
-
expected_xch -= xch_funding_amt + new_cat_amt
|
|
1278
|
-
await time_out_assert(30, wallet_0.get_confirmed_balance, expected_xch)
|
|
1279
|
-
|
|
1280
|
-
await rpc_state(
|
|
1281
|
-
20,
|
|
1282
|
-
api_0.get_wallet_balance,
|
|
1283
|
-
[{"wallet_id": cat_wallet_0_id}],
|
|
1284
|
-
lambda x: x["wallet_balance"]["confirmed_wallet_balance"],
|
|
1285
|
-
new_cat_amt - cat_funding_amt,
|
|
1286
|
-
)
|
|
1287
|
-
|
|
1288
|
-
await rpc_state(
|
|
1289
|
-
20, api_0.dao_get_treasury_balance, [{"wallet_id": dao_wallet_0_id}], lambda x: x["balances"]["xch"]
|
|
1290
|
-
)
|
|
1291
|
-
balances = await api_0.dao_get_treasury_balance({"wallet_id": dao_wallet_0_id})
|
|
1292
|
-
assert balances["balances"]["xch"] == xch_funding_amt
|
|
1293
|
-
assert balances["balances"][cat_id.hex()] == cat_funding_amt
|
|
1294
|
-
|
|
1295
|
-
# Send some cats to wallet_1
|
|
1296
|
-
await api_0.cat_spend(
|
|
1297
|
-
{
|
|
1298
|
-
"wallet_id": dao_cat_wallet_0_id,
|
|
1299
|
-
"amount": cat_amt // 2,
|
|
1300
|
-
"inner_address": encode_puzzle_hash(ph_1, "xch"),
|
|
1301
|
-
"fee": fee,
|
|
1302
|
-
}
|
|
1303
|
-
)
|
|
1304
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1305
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1306
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1307
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
1308
|
-
|
|
1309
|
-
await rpc_state(
|
|
1310
|
-
20,
|
|
1311
|
-
api_0.get_wallet_balance,
|
|
1312
|
-
[{"wallet_id": dao_cat_wallet_0_id}],
|
|
1313
|
-
lambda x: x["wallet_balance"]["confirmed_wallet_balance"],
|
|
1314
|
-
cat_amt // 2,
|
|
1315
|
-
)
|
|
1316
|
-
|
|
1317
|
-
# send cats to lockup
|
|
1318
|
-
await api_0.dao_send_to_lockup({"wallet_id": dao_wallet_0_id, "amount": cat_amt // 2})
|
|
1319
|
-
tx_queue = await wallet_node_0.wallet_state_manager.tx_store.get_not_sent()
|
|
1320
|
-
await full_node_api.process_transaction_records(records=[tx for tx in tx_queue])
|
|
1321
|
-
await api_1.dao_send_to_lockup({"wallet_id": dao_wallet_1_id, "amount": cat_amt // 2})
|
|
1322
|
-
tx_queue = await wallet_node_1.wallet_state_manager.tx_store.get_not_sent()
|
|
1323
|
-
await full_node_api.process_transaction_records(records=[tx for tx in tx_queue])
|
|
1324
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
1325
|
-
|
|
1326
|
-
# create a spend proposal
|
|
1327
|
-
additions = [
|
|
1328
|
-
{"puzzle_hash": ph_1.hex(), "amount": 1000},
|
|
1329
|
-
]
|
|
1330
|
-
create_proposal = await api_0.dao_create_proposal(
|
|
1331
|
-
{
|
|
1332
|
-
"wallet_id": dao_wallet_0_id,
|
|
1333
|
-
"proposal_type": "spend",
|
|
1334
|
-
"additions": additions,
|
|
1335
|
-
"vote_amount": cat_amt // 2,
|
|
1336
|
-
"fee": fee,
|
|
1337
|
-
}
|
|
1338
|
-
)
|
|
1339
|
-
txs = [TransactionRecord.from_json_dict(create_proposal["tx"])]
|
|
1340
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1341
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1342
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1343
|
-
|
|
1344
|
-
await rpc_state(20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: len(x["proposals"]), 1)
|
|
1345
|
-
|
|
1346
|
-
await rpc_state(20, api_1.dao_get_proposals, [{"wallet_id": dao_wallet_1_id}], lambda x: len(x["proposals"]), 1)
|
|
1347
|
-
|
|
1348
|
-
props_0 = await api_0.dao_get_proposals({"wallet_id": dao_wallet_0_id})
|
|
1349
|
-
prop = props_0["proposals"][0]
|
|
1350
|
-
assert prop.amount_voted == cat_amt // 2
|
|
1351
|
-
assert prop.yes_votes == cat_amt // 2
|
|
1352
|
-
|
|
1353
|
-
# Add votes
|
|
1354
|
-
vote_tx = await api_1.dao_vote_on_proposal(
|
|
1355
|
-
{
|
|
1356
|
-
"wallet_id": dao_wallet_1_id,
|
|
1357
|
-
"vote_amount": cat_amt // 2,
|
|
1358
|
-
"proposal_id": prop.proposal_id.hex(),
|
|
1359
|
-
"is_yes_vote": True,
|
|
1360
|
-
}
|
|
1361
|
-
)
|
|
1362
|
-
txs = [TransactionRecord.from_json_dict(vote_tx["tx"])]
|
|
1363
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1364
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
1365
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1366
|
-
|
|
1367
|
-
await rpc_state(
|
|
1368
|
-
20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: x["proposals"][0].amount_voted, cat_amt
|
|
1369
|
-
)
|
|
1370
|
-
|
|
1371
|
-
# farm blocks until we can close proposal
|
|
1372
|
-
state = await api_0.dao_get_proposal_state({"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()})
|
|
1373
|
-
for _ in range(state["state"]["blocks_needed"] + 1):
|
|
1374
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1375
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1376
|
-
|
|
1377
|
-
await rpc_state(
|
|
1378
|
-
20,
|
|
1379
|
-
api_0.dao_get_proposal_state,
|
|
1380
|
-
[{"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1381
|
-
lambda x: x["state"]["closable"],
|
|
1382
|
-
True,
|
|
1383
|
-
)
|
|
1384
|
-
|
|
1385
|
-
proposal_tx = await api_0.dao_close_proposal({"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()})
|
|
1386
|
-
txs = [TransactionRecord.from_json_dict(proposal_tx["tx"])]
|
|
1387
|
-
try:
|
|
1388
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1389
|
-
except TimeoutError: # pragma: no cover
|
|
1390
|
-
# try again
|
|
1391
|
-
await api_0.push_tx({"spend_bundle": txs[0].spend_bundle.stream_to_bytes().hex()})
|
|
1392
|
-
await full_node_api.wait_transaction_records_marked_as_in_mempool([txs[0].name], wallet_node_0, 60)
|
|
1393
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1394
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1395
|
-
|
|
1396
|
-
await rpc_state(
|
|
1397
|
-
20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: x["proposals"][0].closed, True
|
|
1398
|
-
)
|
|
1399
|
-
|
|
1400
|
-
# check that the proposal state has changed for everyone
|
|
1401
|
-
await rpc_state(
|
|
1402
|
-
20,
|
|
1403
|
-
api_0.dao_get_proposal_state,
|
|
1404
|
-
[{"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1405
|
-
lambda x: x["state"]["closed"],
|
|
1406
|
-
True,
|
|
1407
|
-
)
|
|
1408
|
-
|
|
1409
|
-
await rpc_state(
|
|
1410
|
-
20,
|
|
1411
|
-
api_1.dao_get_proposal_state,
|
|
1412
|
-
[{"wallet_id": dao_wallet_1_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1413
|
-
lambda x: x["state"]["closed"],
|
|
1414
|
-
True,
|
|
1415
|
-
)
|
|
1416
|
-
|
|
1417
|
-
# create a mint proposal
|
|
1418
|
-
mint_proposal = await api_0.dao_create_proposal(
|
|
1419
|
-
{
|
|
1420
|
-
"wallet_id": dao_wallet_0_id,
|
|
1421
|
-
"proposal_type": "mint",
|
|
1422
|
-
"amount": uint64(10000),
|
|
1423
|
-
"cat_target_address": encode_puzzle_hash(ph_0, "xch"),
|
|
1424
|
-
"vote_amount": cat_amt // 2,
|
|
1425
|
-
"fee": fee,
|
|
1426
|
-
}
|
|
1427
|
-
)
|
|
1428
|
-
txs = [TransactionRecord.from_json_dict(mint_proposal["tx"])]
|
|
1429
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1430
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1431
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1432
|
-
|
|
1433
|
-
await rpc_state(20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: len(x["proposals"]), 2)
|
|
1434
|
-
|
|
1435
|
-
await rpc_state(20, api_1.dao_get_proposals, [{"wallet_id": dao_wallet_1_id}], lambda x: len(x["proposals"]), 2)
|
|
1436
|
-
|
|
1437
|
-
props = await api_0.dao_get_proposals({"wallet_id": dao_wallet_0_id})
|
|
1438
|
-
prop = props["proposals"][1]
|
|
1439
|
-
assert prop.amount_voted == cat_amt // 2
|
|
1440
|
-
assert prop.yes_votes == cat_amt // 2
|
|
1441
|
-
|
|
1442
|
-
# Add votes
|
|
1443
|
-
vote_tx = await api_1.dao_vote_on_proposal(
|
|
1444
|
-
{
|
|
1445
|
-
"wallet_id": dao_wallet_1_id,
|
|
1446
|
-
"vote_amount": cat_amt // 2,
|
|
1447
|
-
"proposal_id": prop.proposal_id.hex(),
|
|
1448
|
-
"is_yes_vote": True,
|
|
1449
|
-
}
|
|
1450
|
-
)
|
|
1451
|
-
txs = [TransactionRecord.from_json_dict(vote_tx["tx"])]
|
|
1452
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1453
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
1454
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1455
|
-
|
|
1456
|
-
await rpc_state(
|
|
1457
|
-
20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: x["proposals"][1].amount_voted, cat_amt
|
|
1458
|
-
)
|
|
1459
|
-
|
|
1460
|
-
# farm blocks until we can close proposal
|
|
1461
|
-
state = await api_0.dao_get_proposal_state({"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()})
|
|
1462
|
-
for _ in range(state["state"]["blocks_needed"] + 1):
|
|
1463
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1464
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1465
|
-
|
|
1466
|
-
await rpc_state(
|
|
1467
|
-
20,
|
|
1468
|
-
api_0.dao_get_proposal_state,
|
|
1469
|
-
[{"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1470
|
-
lambda x: x["state"]["closable"],
|
|
1471
|
-
True,
|
|
1472
|
-
)
|
|
1473
|
-
|
|
1474
|
-
proposal_tx = await api_0.dao_close_proposal({"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()})
|
|
1475
|
-
txs = [TransactionRecord.from_json_dict(proposal_tx["tx"])]
|
|
1476
|
-
try:
|
|
1477
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1478
|
-
except TimeoutError: # pragma: no cover
|
|
1479
|
-
# try again
|
|
1480
|
-
await api_0.push_tx({"spend_bundle": txs[0].spend_bundle.stream_to_bytes().hex()})
|
|
1481
|
-
await full_node_api.wait_transaction_records_marked_as_in_mempool([txs[0].name], wallet_node_0, 60)
|
|
1482
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1483
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1484
|
-
|
|
1485
|
-
await rpc_state(
|
|
1486
|
-
20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: x["proposals"][1].closed, True
|
|
1487
|
-
)
|
|
1488
|
-
|
|
1489
|
-
# check that the proposal state has changed for everyone
|
|
1490
|
-
await rpc_state(
|
|
1491
|
-
20,
|
|
1492
|
-
api_0.dao_get_proposal_state,
|
|
1493
|
-
[{"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1494
|
-
lambda x: x["state"]["closed"],
|
|
1495
|
-
True,
|
|
1496
|
-
)
|
|
1497
|
-
|
|
1498
|
-
await rpc_state(
|
|
1499
|
-
20,
|
|
1500
|
-
api_1.dao_get_proposal_state,
|
|
1501
|
-
[{"wallet_id": dao_wallet_1_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1502
|
-
lambda x: x["state"]["closed"],
|
|
1503
|
-
True,
|
|
1504
|
-
)
|
|
1505
|
-
|
|
1506
|
-
# Check the minted cats are received
|
|
1507
|
-
await rpc_state(
|
|
1508
|
-
20,
|
|
1509
|
-
api_0.get_wallet_balance,
|
|
1510
|
-
[{"wallet_id": dao_cat_wallet_0_id}],
|
|
1511
|
-
lambda x: x["wallet_balance"]["confirmed_wallet_balance"],
|
|
1512
|
-
10000,
|
|
1513
|
-
)
|
|
1514
|
-
|
|
1515
|
-
# create an update proposal
|
|
1516
|
-
new_dao_rules = {"pass_percentage": 10000}
|
|
1517
|
-
update_proposal = await api_0.dao_create_proposal(
|
|
1518
|
-
{
|
|
1519
|
-
"wallet_id": dao_wallet_0_id,
|
|
1520
|
-
"proposal_type": "update",
|
|
1521
|
-
"new_dao_rules": new_dao_rules,
|
|
1522
|
-
"vote_amount": cat_amt // 2,
|
|
1523
|
-
"fee": fee,
|
|
1524
|
-
}
|
|
1525
|
-
)
|
|
1526
|
-
txs = [TransactionRecord.from_json_dict(update_proposal["tx"])]
|
|
1527
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1528
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1529
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1530
|
-
|
|
1531
|
-
await rpc_state(20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: len(x["proposals"]), 3)
|
|
1532
|
-
|
|
1533
|
-
await rpc_state(20, api_1.dao_get_proposals, [{"wallet_id": dao_wallet_1_id}], lambda x: len(x["proposals"]), 3)
|
|
1534
|
-
|
|
1535
|
-
props = await api_0.dao_get_proposals({"wallet_id": dao_wallet_0_id})
|
|
1536
|
-
prop = props["proposals"][2]
|
|
1537
|
-
assert prop.amount_voted == cat_amt // 2
|
|
1538
|
-
assert prop.yes_votes == cat_amt // 2
|
|
1539
|
-
|
|
1540
|
-
# Add votes
|
|
1541
|
-
vote_tx = await api_1.dao_vote_on_proposal(
|
|
1542
|
-
{
|
|
1543
|
-
"wallet_id": dao_wallet_1_id,
|
|
1544
|
-
"vote_amount": cat_amt // 2,
|
|
1545
|
-
"proposal_id": prop.proposal_id.hex(),
|
|
1546
|
-
"is_yes_vote": True,
|
|
1547
|
-
}
|
|
1548
|
-
)
|
|
1549
|
-
txs = [TransactionRecord.from_json_dict(vote_tx["tx"])]
|
|
1550
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1551
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
1552
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1553
|
-
|
|
1554
|
-
await rpc_state(
|
|
1555
|
-
20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: x["proposals"][2].amount_voted, cat_amt
|
|
1556
|
-
)
|
|
1557
|
-
|
|
1558
|
-
# farm blocks until we can close proposal
|
|
1559
|
-
state = await api_0.dao_get_proposal_state({"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()})
|
|
1560
|
-
for _ in range(state["state"]["blocks_needed"] + 1):
|
|
1561
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1562
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1563
|
-
|
|
1564
|
-
await rpc_state(
|
|
1565
|
-
20,
|
|
1566
|
-
api_0.dao_get_proposal_state,
|
|
1567
|
-
[{"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1568
|
-
lambda x: x["state"]["closable"],
|
|
1569
|
-
True,
|
|
1570
|
-
)
|
|
1571
|
-
|
|
1572
|
-
open_props = await api_0.dao_get_proposals({"wallet_id": dao_wallet_0_id, "include_closed": False})
|
|
1573
|
-
assert len(open_props["proposals"]) == 1
|
|
1574
|
-
|
|
1575
|
-
close_tx = await api_0.dao_close_proposal({"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()})
|
|
1576
|
-
txs = [TransactionRecord.from_json_dict(close_tx["tx"])]
|
|
1577
|
-
try:
|
|
1578
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1579
|
-
except TimeoutError: # pragma: no cover
|
|
1580
|
-
# try again
|
|
1581
|
-
await api_0.push_tx({"spend_bundle": txs[0].spend_bundle.stream_to_bytes().hex()})
|
|
1582
|
-
await full_node_api.wait_transaction_records_marked_as_in_mempool([txs[0].name], wallet_node_0, 60)
|
|
1583
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1584
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1585
|
-
|
|
1586
|
-
await rpc_state(
|
|
1587
|
-
20, api_0.dao_get_proposals, [{"wallet_id": dao_wallet_0_id}], lambda x: x["proposals"][1].closed, True
|
|
1588
|
-
)
|
|
1589
|
-
|
|
1590
|
-
# check that the proposal state has changed for everyone
|
|
1591
|
-
await rpc_state(
|
|
1592
|
-
20,
|
|
1593
|
-
api_0.dao_get_proposal_state,
|
|
1594
|
-
[{"wallet_id": dao_wallet_0_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1595
|
-
lambda x: x["state"]["closed"],
|
|
1596
|
-
True,
|
|
1597
|
-
)
|
|
1598
|
-
|
|
1599
|
-
await rpc_state(
|
|
1600
|
-
20,
|
|
1601
|
-
api_1.dao_get_proposal_state,
|
|
1602
|
-
[{"wallet_id": dao_wallet_1_id, "proposal_id": prop.proposal_id.hex()}],
|
|
1603
|
-
lambda x: x["state"]["closed"],
|
|
1604
|
-
True,
|
|
1605
|
-
)
|
|
1606
|
-
|
|
1607
|
-
# Check the rules have updated
|
|
1608
|
-
dao_wallet = wallet_node_0.wallet_state_manager.wallets[dao_wallet_0_id]
|
|
1609
|
-
assert dao_wallet.dao_rules.pass_percentage == 10000
|
|
1610
|
-
|
|
1611
|
-
# Test adjust filter level
|
|
1612
|
-
resp = await api_0.dao_adjust_filter_level({"wallet_id": dao_wallet_1_id, "filter_level": 101})
|
|
1613
|
-
assert resp["success"]
|
|
1614
|
-
assert resp["dao_info"].filter_below_vote_amount == 101
|
|
1615
|
-
|
|
1616
|
-
# Test get_treasury_id
|
|
1617
|
-
resp = await api_0.dao_get_treasury_id({"wallet_id": dao_wallet_0_id})
|
|
1618
|
-
assert resp["treasury_id"] == treasury_id
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
1622
|
-
@pytest.mark.parametrize(
|
|
1623
|
-
"trusted",
|
|
1624
|
-
[True, False],
|
|
1625
|
-
)
|
|
1626
|
-
@pytest.mark.anyio
|
|
1627
|
-
async def test_dao_rpc_client(
|
|
1628
|
-
two_wallet_nodes_services: SimulatorsAndWalletsServices, trusted: bool, self_hostname: str
|
|
1629
|
-
) -> None:
|
|
1630
|
-
[full_node_service], wallet_services, _bt = two_wallet_nodes_services
|
|
1631
|
-
full_node_api = full_node_service._api
|
|
1632
|
-
full_node_server = full_node_api.full_node.server
|
|
1633
|
-
wallet_node_0 = wallet_services[0]._node
|
|
1634
|
-
server_0 = wallet_node_0.server
|
|
1635
|
-
wallet_node_1 = wallet_services[1]._node
|
|
1636
|
-
server_1 = wallet_node_1.server
|
|
1637
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
1638
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
1639
|
-
ph_0 = await wallet_0.get_new_puzzlehash()
|
|
1640
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
1641
|
-
|
|
1642
|
-
if trusted:
|
|
1643
|
-
wallet_node_0.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
1644
|
-
wallet_node_1.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
1645
|
-
else:
|
|
1646
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
1647
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
1648
|
-
|
|
1649
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
1650
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
1651
|
-
|
|
1652
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_0))
|
|
1653
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
1654
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1655
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1656
|
-
|
|
1657
|
-
initial_funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
1658
|
-
|
|
1659
|
-
await time_out_assert(15, wallet_0.get_confirmed_balance, initial_funds)
|
|
1660
|
-
await time_out_assert(15, wallet_0.get_unconfirmed_balance, initial_funds)
|
|
1661
|
-
|
|
1662
|
-
assert wallet_services[0].rpc_server is not None
|
|
1663
|
-
assert wallet_services[1].rpc_server is not None
|
|
1664
|
-
|
|
1665
|
-
async with contextlib.AsyncExitStack() as exit_stack:
|
|
1666
|
-
client_0 = await exit_stack.enter_async_context(
|
|
1667
|
-
WalletRpcClient.create_as_context(
|
|
1668
|
-
self_hostname,
|
|
1669
|
-
wallet_services[0].rpc_server.listen_port,
|
|
1670
|
-
wallet_services[0].root_path,
|
|
1671
|
-
wallet_services[0].config,
|
|
1672
|
-
)
|
|
1673
|
-
)
|
|
1674
|
-
await validate_get_routes(client_0, wallet_services[0].rpc_server.rpc_api)
|
|
1675
|
-
client_1 = await exit_stack.enter_async_context(
|
|
1676
|
-
WalletRpcClient.create_as_context(
|
|
1677
|
-
self_hostname,
|
|
1678
|
-
wallet_services[1].rpc_server.listen_port,
|
|
1679
|
-
wallet_services[1].root_path,
|
|
1680
|
-
wallet_services[1].config,
|
|
1681
|
-
)
|
|
1682
|
-
)
|
|
1683
|
-
await validate_get_routes(client_1, wallet_services[1].rpc_server.rpc_api)
|
|
1684
|
-
|
|
1685
|
-
cat_amt = uint64(150000)
|
|
1686
|
-
amount_of_cats = uint64(cat_amt * 2)
|
|
1687
|
-
dao_rules = DAORules(
|
|
1688
|
-
proposal_timelock=uint64(8),
|
|
1689
|
-
soft_close_length=uint64(4),
|
|
1690
|
-
attendance_required=uint64(1000), # 10%
|
|
1691
|
-
pass_percentage=uint64(4900), # 49%
|
|
1692
|
-
self_destruct_length=uint64(20),
|
|
1693
|
-
oracle_spend_delay=uint64(10),
|
|
1694
|
-
proposal_minimum_amount=uint64(1),
|
|
1695
|
-
)
|
|
1696
|
-
filter_amount = uint64(1)
|
|
1697
|
-
fee = uint64(10000)
|
|
1698
|
-
|
|
1699
|
-
# create new dao
|
|
1700
|
-
dao_wallet_res_0 = await client_0.create_new_dao_wallet(
|
|
1701
|
-
mode="new",
|
|
1702
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
1703
|
-
dao_rules=dao_rules.to_json_dict(),
|
|
1704
|
-
amount_of_cats=amount_of_cats,
|
|
1705
|
-
filter_amount=filter_amount,
|
|
1706
|
-
name="DAO WALLET 0",
|
|
1707
|
-
)
|
|
1708
|
-
dao_id_0 = dao_wallet_res_0.wallet_id
|
|
1709
|
-
cat_wallet_0 = wallet_node_0.wallet_state_manager.wallets[dao_wallet_res_0.cat_wallet_id]
|
|
1710
|
-
|
|
1711
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1712
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1713
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1714
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1715
|
-
|
|
1716
|
-
await time_out_assert(20, cat_wallet_0.get_confirmed_balance, amount_of_cats)
|
|
1717
|
-
|
|
1718
|
-
# Create a new standard cat for treasury funds
|
|
1719
|
-
new_cat_amt = uint64(100000)
|
|
1720
|
-
new_cat_res = await client_0.create_new_cat_and_wallet(new_cat_amt, test=True)
|
|
1721
|
-
new_cat_wallet_id = new_cat_res["wallet_id"]
|
|
1722
|
-
new_cat_wallet = wallet_node_0.wallet_state_manager.wallets[new_cat_wallet_id]
|
|
1723
|
-
|
|
1724
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1725
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1726
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1727
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1728
|
-
|
|
1729
|
-
# join dao
|
|
1730
|
-
dao_wallet_res_1 = await client_1.create_new_dao_wallet(
|
|
1731
|
-
mode="existing",
|
|
1732
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
1733
|
-
treasury_id=dao_wallet_res_0.treasury_id,
|
|
1734
|
-
filter_amount=filter_amount,
|
|
1735
|
-
name="DAO WALLET 1",
|
|
1736
|
-
)
|
|
1737
|
-
dao_id_1 = dao_wallet_res_1.wallet_id
|
|
1738
|
-
cat_wallet_1 = wallet_node_1.wallet_state_manager.wallets[dao_wallet_res_1.cat_wallet_id]
|
|
1739
|
-
|
|
1740
|
-
# fund treasury
|
|
1741
|
-
xch_funds = uint64(10000000000)
|
|
1742
|
-
await client_0.dao_add_funds_to_treasury(dao_id_0, 1, xch_funds, DEFAULT_TX_CONFIG)
|
|
1743
|
-
await client_0.dao_add_funds_to_treasury(dao_id_0, new_cat_wallet_id, new_cat_amt, DEFAULT_TX_CONFIG)
|
|
1744
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1745
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1746
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1747
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1748
|
-
|
|
1749
|
-
await rpc_state(20, client_0.dao_get_treasury_balance, [dao_id_0], lambda x: x["balances"]["xch"], xch_funds)
|
|
1750
|
-
assert isinstance(new_cat_wallet, CATWallet)
|
|
1751
|
-
new_cat_asset_id = new_cat_wallet.cat_info.limitations_program_hash
|
|
1752
|
-
await rpc_state(
|
|
1753
|
-
20,
|
|
1754
|
-
client_0.dao_get_treasury_balance,
|
|
1755
|
-
[dao_id_0],
|
|
1756
|
-
lambda x: x["balances"][new_cat_asset_id.hex()],
|
|
1757
|
-
new_cat_amt,
|
|
1758
|
-
)
|
|
1759
|
-
await rpc_state(
|
|
1760
|
-
20,
|
|
1761
|
-
client_0.dao_get_treasury_balance,
|
|
1762
|
-
[dao_id_0],
|
|
1763
|
-
lambda x: x["balances"]["xch"],
|
|
1764
|
-
xch_funds,
|
|
1765
|
-
)
|
|
1766
|
-
|
|
1767
|
-
# send cats to wallet 1
|
|
1768
|
-
await client_0.cat_spend(
|
|
1769
|
-
wallet_id=dao_wallet_res_0.cat_wallet_id,
|
|
1770
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
1771
|
-
amount=cat_amt,
|
|
1772
|
-
inner_address=encode_puzzle_hash(ph_1, "xch"),
|
|
1773
|
-
fee=fee,
|
|
1774
|
-
)
|
|
1775
|
-
|
|
1776
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1777
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1778
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1779
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1780
|
-
|
|
1781
|
-
await time_out_assert(20, cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
1782
|
-
await time_out_assert(20, cat_wallet_1.get_confirmed_balance, cat_amt)
|
|
1783
|
-
|
|
1784
|
-
# send cats to lockup
|
|
1785
|
-
await client_0.dao_send_to_lockup(dao_id_0, cat_amt, DEFAULT_TX_CONFIG)
|
|
1786
|
-
await client_1.dao_send_to_lockup(dao_id_1, cat_amt, DEFAULT_TX_CONFIG)
|
|
1787
|
-
|
|
1788
|
-
txs_0 = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1789
|
-
txs_1 = await wallet_1.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1790
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs_0 + txs_1, timeout=60)
|
|
1791
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1792
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
1793
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1794
|
-
|
|
1795
|
-
# create a spend proposal
|
|
1796
|
-
additions = [
|
|
1797
|
-
{"puzzle_hash": ph_0.hex(), "amount": 1000},
|
|
1798
|
-
{"puzzle_hash": ph_0.hex(), "amount": 10000, "asset_id": new_cat_asset_id.hex()},
|
|
1799
|
-
]
|
|
1800
|
-
await client_0.dao_create_proposal(
|
|
1801
|
-
wallet_id=dao_id_0,
|
|
1802
|
-
proposal_type="spend",
|
|
1803
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
1804
|
-
additions=additions,
|
|
1805
|
-
vote_amount=cat_amt,
|
|
1806
|
-
fee=fee,
|
|
1807
|
-
)
|
|
1808
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1809
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1810
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1811
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1812
|
-
|
|
1813
|
-
# check proposal is found by wallet 1
|
|
1814
|
-
await rpc_state(20, client_1.dao_get_proposals, [dao_id_1], lambda x: x["proposals"][0]["yes_votes"], cat_amt)
|
|
1815
|
-
props = await client_1.dao_get_proposals(dao_id_1)
|
|
1816
|
-
proposal_id_hex = props["proposals"][0]["proposal_id"]
|
|
1817
|
-
|
|
1818
|
-
# create an update proposal
|
|
1819
|
-
await client_1.dao_create_proposal(
|
|
1820
|
-
wallet_id=dao_id_1,
|
|
1821
|
-
proposal_type="update",
|
|
1822
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
1823
|
-
vote_amount=cat_amt,
|
|
1824
|
-
new_dao_rules={"proposal_timelock": uint64(10)},
|
|
1825
|
-
fee=fee,
|
|
1826
|
-
)
|
|
1827
|
-
txs = await wallet_1.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1828
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1829
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
1830
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1831
|
-
|
|
1832
|
-
# create a mint proposal
|
|
1833
|
-
mint_addr = await client_1.get_next_address(wallet_id=wallet_1.id(), new_address=False)
|
|
1834
|
-
await client_1.dao_create_proposal(
|
|
1835
|
-
wallet_id=dao_id_1,
|
|
1836
|
-
proposal_type="mint",
|
|
1837
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
1838
|
-
vote_amount=cat_amt,
|
|
1839
|
-
amount=uint64(100),
|
|
1840
|
-
cat_target_address=mint_addr,
|
|
1841
|
-
fee=fee,
|
|
1842
|
-
)
|
|
1843
|
-
txs = await wallet_1.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1844
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1845
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
1846
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1847
|
-
|
|
1848
|
-
# vote spend
|
|
1849
|
-
await client_1.dao_vote_on_proposal(
|
|
1850
|
-
wallet_id=dao_id_1,
|
|
1851
|
-
proposal_id=proposal_id_hex,
|
|
1852
|
-
vote_amount=cat_amt,
|
|
1853
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
1854
|
-
is_yes_vote=True,
|
|
1855
|
-
fee=fee,
|
|
1856
|
-
)
|
|
1857
|
-
txs = await wallet_1.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
1858
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
1859
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
1860
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1861
|
-
|
|
1862
|
-
# check updated proposal is found by wallet 0
|
|
1863
|
-
await rpc_state(
|
|
1864
|
-
20, client_0.dao_get_proposals, [dao_id_0], lambda x: x["proposals"][0]["yes_votes"], cat_amt * 2
|
|
1865
|
-
)
|
|
1866
|
-
|
|
1867
|
-
# check proposal state and farm enough blocks to pass
|
|
1868
|
-
state = await client_0.dao_get_proposal_state(wallet_id=dao_id_0, proposal_id=proposal_id_hex)
|
|
1869
|
-
assert state["success"]
|
|
1870
|
-
assert state["state"]["passed"]
|
|
1871
|
-
|
|
1872
|
-
for _ in range(0, state["state"]["blocks_needed"]):
|
|
1873
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1874
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1875
|
-
|
|
1876
|
-
state = await client_0.dao_get_proposal_state(wallet_id=dao_id_0, proposal_id=proposal_id_hex)
|
|
1877
|
-
assert state["success"]
|
|
1878
|
-
assert state["state"]["closable"]
|
|
1879
|
-
|
|
1880
|
-
# check proposal parsing
|
|
1881
|
-
props = await client_0.dao_get_proposals(dao_id_0)
|
|
1882
|
-
proposal_2_hex = props["proposals"][1]["proposal_id"]
|
|
1883
|
-
proposal_3_hex = props["proposals"][2]["proposal_id"]
|
|
1884
|
-
parsed_1 = await client_0.dao_parse_proposal(wallet_id=dao_id_0, proposal_id=proposal_id_hex)
|
|
1885
|
-
assert parsed_1["success"]
|
|
1886
|
-
parsed_2 = await client_0.dao_parse_proposal(wallet_id=dao_id_0, proposal_id=proposal_2_hex)
|
|
1887
|
-
assert parsed_2["success"]
|
|
1888
|
-
parsed_3 = await client_0.dao_parse_proposal(wallet_id=dao_id_0, proposal_id=proposal_3_hex)
|
|
1889
|
-
assert parsed_3["success"]
|
|
1890
|
-
|
|
1891
|
-
# farm blocks so proposal can close
|
|
1892
|
-
for i in range(1, 10):
|
|
1893
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
1894
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1895
|
-
|
|
1896
|
-
# close the proposal
|
|
1897
|
-
close = await client_0.dao_close_proposal(
|
|
1898
|
-
wallet_id=dao_id_0, proposal_id=proposal_id_hex, tx_config=DEFAULT_TX_CONFIG, self_destruct=False, fee=fee
|
|
1899
|
-
)
|
|
1900
|
-
tx = close.tx
|
|
1901
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[tx], timeout=60)
|
|
1902
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1903
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1904
|
-
|
|
1905
|
-
# check proposal is closed
|
|
1906
|
-
await rpc_state(20, client_0.dao_get_proposals, [dao_id_0], lambda x: x["proposals"][0]["closed"], True)
|
|
1907
|
-
await rpc_state(20, client_1.dao_get_proposals, [dao_id_1], lambda x: x["proposals"][0]["closed"], True)
|
|
1908
|
-
# check treasury balances
|
|
1909
|
-
await rpc_state(
|
|
1910
|
-
20,
|
|
1911
|
-
client_0.dao_get_treasury_balance,
|
|
1912
|
-
[dao_id_0],
|
|
1913
|
-
lambda x: x["balances"][new_cat_asset_id.hex()],
|
|
1914
|
-
new_cat_amt - 10000,
|
|
1915
|
-
)
|
|
1916
|
-
await rpc_state(
|
|
1917
|
-
20, client_0.dao_get_treasury_balance, [dao_id_0], lambda x: x["balances"]["xch"], xch_funds - 1000
|
|
1918
|
-
)
|
|
1919
|
-
|
|
1920
|
-
# check wallet balances
|
|
1921
|
-
await rpc_state(
|
|
1922
|
-
20, client_0.get_wallet_balance, [new_cat_wallet_id], lambda x: x["confirmed_wallet_balance"], 10000
|
|
1923
|
-
)
|
|
1924
|
-
expected_xch = initial_funds - amount_of_cats - new_cat_amt - xch_funds - (2 * fee) - 2 - 9000
|
|
1925
|
-
await rpc_state(
|
|
1926
|
-
20, client_0.get_wallet_balance, [wallet_0.id()], lambda x: x["confirmed_wallet_balance"], expected_xch
|
|
1927
|
-
)
|
|
1928
|
-
|
|
1929
|
-
# close the mint proposal
|
|
1930
|
-
props = await client_0.dao_get_proposals(dao_id_0)
|
|
1931
|
-
proposal_id_hex = props["proposals"][2]["proposal_id"]
|
|
1932
|
-
close = await client_0.dao_close_proposal(
|
|
1933
|
-
wallet_id=dao_id_0, proposal_id=proposal_id_hex, tx_config=DEFAULT_TX_CONFIG, self_destruct=False, fee=fee
|
|
1934
|
-
)
|
|
1935
|
-
tx = close.tx
|
|
1936
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[tx], timeout=60)
|
|
1937
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1938
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1939
|
-
|
|
1940
|
-
# check proposal is closed
|
|
1941
|
-
await rpc_state(20, client_0.dao_get_proposals, [dao_id_0], lambda x: x["proposals"][2]["closed"], True)
|
|
1942
|
-
await rpc_state(20, client_1.dao_get_proposals, [dao_id_1], lambda x: x["proposals"][2]["closed"], True)
|
|
1943
|
-
|
|
1944
|
-
# check minted cats are received
|
|
1945
|
-
await rpc_state(
|
|
1946
|
-
20,
|
|
1947
|
-
client_1.get_wallet_balance,
|
|
1948
|
-
[dao_wallet_res_1.cat_wallet_id],
|
|
1949
|
-
lambda x: x["confirmed_wallet_balance"],
|
|
1950
|
-
100,
|
|
1951
|
-
)
|
|
1952
|
-
|
|
1953
|
-
open_props = await client_0.dao_get_proposals(dao_id_0, False)
|
|
1954
|
-
assert len(open_props["proposals"]) == 1
|
|
1955
|
-
|
|
1956
|
-
# close the update proposal
|
|
1957
|
-
proposal_id_hex = props["proposals"][1]["proposal_id"]
|
|
1958
|
-
close = await client_0.dao_close_proposal(
|
|
1959
|
-
wallet_id=dao_id_0, proposal_id=proposal_id_hex, tx_config=DEFAULT_TX_CONFIG, self_destruct=False, fee=fee
|
|
1960
|
-
)
|
|
1961
|
-
tx = close.tx
|
|
1962
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[tx], timeout=60)
|
|
1963
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1964
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1965
|
-
|
|
1966
|
-
# check proposal is closed
|
|
1967
|
-
await rpc_state(20, client_0.dao_get_proposals, [dao_id_0], lambda x: x["proposals"][1]["closed"], True)
|
|
1968
|
-
await rpc_state(20, client_1.dao_get_proposals, [dao_id_1], lambda x: x["proposals"][1]["closed"], True)
|
|
1969
|
-
|
|
1970
|
-
# check dao rules are updated
|
|
1971
|
-
new_rules = await client_0.dao_get_rules(dao_id_0)
|
|
1972
|
-
assert new_rules["rules"]["proposal_timelock"] == 10
|
|
1973
|
-
new_rules_1 = await client_0.dao_get_rules(dao_id_1)
|
|
1974
|
-
assert new_rules_1["rules"]["proposal_timelock"] == 10
|
|
1975
|
-
|
|
1976
|
-
# free locked cats from finished proposal
|
|
1977
|
-
free_coins_res = await client_0.dao_free_coins_from_finished_proposals(
|
|
1978
|
-
wallet_id=dao_id_0, tx_config=DEFAULT_TX_CONFIG
|
|
1979
|
-
)
|
|
1980
|
-
free_coins_tx = free_coins_res.tx
|
|
1981
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[free_coins_tx], timeout=60)
|
|
1982
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1983
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1984
|
-
|
|
1985
|
-
bal = await client_0.get_wallet_balance(dao_wallet_res_0.dao_cat_wallet_id)
|
|
1986
|
-
assert bal["confirmed_wallet_balance"] == cat_amt
|
|
1987
|
-
|
|
1988
|
-
exit = await client_0.dao_exit_lockup(dao_id_0, tx_config=DEFAULT_TX_CONFIG)
|
|
1989
|
-
exit_tx = exit.tx
|
|
1990
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[exit_tx], timeout=60)
|
|
1991
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
1992
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
1993
|
-
|
|
1994
|
-
await rpc_state(
|
|
1995
|
-
20,
|
|
1996
|
-
client_0.get_wallet_balance,
|
|
1997
|
-
[dao_wallet_res_0.cat_wallet_id],
|
|
1998
|
-
lambda x: x["confirmed_wallet_balance"],
|
|
1999
|
-
cat_amt,
|
|
2000
|
-
)
|
|
2001
|
-
|
|
2002
|
-
# coverage tests for filter amount and get treasury id
|
|
2003
|
-
treasury_id_resp = await client_0.dao_get_treasury_id(wallet_id=dao_id_0)
|
|
2004
|
-
assert treasury_id_resp["treasury_id"] == "0x" + dao_wallet_res_0.treasury_id.hex()
|
|
2005
|
-
filter_amount_resp = await client_0.dao_adjust_filter_level(wallet_id=dao_id_0, filter_level=30)
|
|
2006
|
-
assert filter_amount_resp["dao_info"]["filter_below_vote_amount"] == 30
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
2010
|
-
@pytest.mark.parametrize(
|
|
2011
|
-
"trusted",
|
|
2012
|
-
[True, False],
|
|
2013
|
-
)
|
|
2014
|
-
@pytest.mark.anyio
|
|
2015
|
-
async def test_dao_complex_spends(
|
|
2016
|
-
two_wallet_nodes_services: SimulatorsAndWalletsServices, trusted: bool, self_hostname: str
|
|
2017
|
-
) -> None:
|
|
2018
|
-
[full_node_service], wallet_services, _bt = two_wallet_nodes_services
|
|
2019
|
-
full_node_api = full_node_service._api
|
|
2020
|
-
full_node_server = full_node_api.full_node.server
|
|
2021
|
-
wallet_node_0 = wallet_services[0]._node
|
|
2022
|
-
server_0 = wallet_node_0.server
|
|
2023
|
-
wallet_node_1 = wallet_services[1]._node
|
|
2024
|
-
server_1 = wallet_node_1.server
|
|
2025
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
2026
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
2027
|
-
ph_0 = await wallet_0.get_new_puzzlehash()
|
|
2028
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
2029
|
-
|
|
2030
|
-
if trusted:
|
|
2031
|
-
wallet_node_0.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
2032
|
-
wallet_node_1.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
2033
|
-
else:
|
|
2034
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
2035
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
2036
|
-
|
|
2037
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2038
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2039
|
-
|
|
2040
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_0))
|
|
2041
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
2042
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
2043
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2044
|
-
|
|
2045
|
-
initial_funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
2046
|
-
|
|
2047
|
-
await time_out_assert(15, wallet_0.get_confirmed_balance, initial_funds)
|
|
2048
|
-
await time_out_assert(15, wallet_0.get_unconfirmed_balance, initial_funds)
|
|
2049
|
-
|
|
2050
|
-
assert wallet_services[0].rpc_server is not None
|
|
2051
|
-
assert wallet_services[1].rpc_server is not None
|
|
2052
|
-
|
|
2053
|
-
async with contextlib.AsyncExitStack() as exit_stack:
|
|
2054
|
-
client_0 = await exit_stack.enter_async_context(
|
|
2055
|
-
WalletRpcClient.create_as_context(
|
|
2056
|
-
self_hostname,
|
|
2057
|
-
wallet_services[0].rpc_server.listen_port,
|
|
2058
|
-
wallet_services[0].root_path,
|
|
2059
|
-
wallet_services[0].config,
|
|
2060
|
-
)
|
|
2061
|
-
)
|
|
2062
|
-
await validate_get_routes(client_0, wallet_services[0].rpc_server.rpc_api)
|
|
2063
|
-
client_1 = await exit_stack.enter_async_context(
|
|
2064
|
-
WalletRpcClient.create_as_context(
|
|
2065
|
-
self_hostname,
|
|
2066
|
-
wallet_services[1].rpc_server.listen_port,
|
|
2067
|
-
wallet_services[1].root_path,
|
|
2068
|
-
wallet_services[1].config,
|
|
2069
|
-
)
|
|
2070
|
-
)
|
|
2071
|
-
await validate_get_routes(client_1, wallet_services[1].rpc_server.rpc_api)
|
|
2072
|
-
|
|
2073
|
-
cat_amt = uint64(300000)
|
|
2074
|
-
dao_rules = DAORules(
|
|
2075
|
-
proposal_timelock=uint64(2),
|
|
2076
|
-
soft_close_length=uint64(2),
|
|
2077
|
-
attendance_required=uint64(1000), # 10%
|
|
2078
|
-
pass_percentage=uint64(5100), # 51%
|
|
2079
|
-
self_destruct_length=uint64(5),
|
|
2080
|
-
oracle_spend_delay=uint64(2),
|
|
2081
|
-
proposal_minimum_amount=uint64(1),
|
|
2082
|
-
)
|
|
2083
|
-
filter_amount = uint64(1)
|
|
2084
|
-
|
|
2085
|
-
# create new dao
|
|
2086
|
-
dao_wallet_res_0 = await client_0.create_new_dao_wallet(
|
|
2087
|
-
mode="new",
|
|
2088
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
2089
|
-
dao_rules=dao_rules.to_json_dict(),
|
|
2090
|
-
amount_of_cats=cat_amt,
|
|
2091
|
-
filter_amount=filter_amount,
|
|
2092
|
-
name="DAO WALLET 0",
|
|
2093
|
-
)
|
|
2094
|
-
dao_id_0 = dao_wallet_res_0.wallet_id
|
|
2095
|
-
treasury_id = dao_wallet_res_0.treasury_id
|
|
2096
|
-
cat_wallet_0 = wallet_node_0.wallet_state_manager.wallets[dao_wallet_res_0.cat_wallet_id]
|
|
2097
|
-
|
|
2098
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2099
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2100
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2101
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2102
|
-
|
|
2103
|
-
await time_out_assert(20, cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
2104
|
-
|
|
2105
|
-
# Create a new standard cat for treasury funds
|
|
2106
|
-
new_cat_amt = uint64(1000000)
|
|
2107
|
-
new_cat_wallet_dict = await client_0.create_new_cat_and_wallet(new_cat_amt, test=True)
|
|
2108
|
-
new_cat_wallet_id = new_cat_wallet_dict["wallet_id"]
|
|
2109
|
-
new_cat_wallet = wallet_node_0.wallet_state_manager.wallets[new_cat_wallet_id]
|
|
2110
|
-
|
|
2111
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2112
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2113
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2114
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2115
|
-
|
|
2116
|
-
# Create a new standard cat for treasury funds
|
|
2117
|
-
new_cat_wallet_dict_2 = await client_0.create_new_cat_and_wallet(new_cat_amt, test=True)
|
|
2118
|
-
new_cat_wallet_id_2 = new_cat_wallet_dict_2["wallet_id"]
|
|
2119
|
-
new_cat_wallet_2 = wallet_node_0.wallet_state_manager.wallets[new_cat_wallet_id_2]
|
|
2120
|
-
|
|
2121
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2122
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2123
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2124
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2125
|
-
|
|
2126
|
-
# join dao
|
|
2127
|
-
dao_wallet_res_1 = await client_1.create_new_dao_wallet(
|
|
2128
|
-
mode="existing",
|
|
2129
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
2130
|
-
treasury_id=treasury_id,
|
|
2131
|
-
filter_amount=filter_amount,
|
|
2132
|
-
name="DAO WALLET 1",
|
|
2133
|
-
)
|
|
2134
|
-
dao_id_1 = dao_wallet_res_1.wallet_id
|
|
2135
|
-
|
|
2136
|
-
# fund treasury so there are multiple coins for each asset
|
|
2137
|
-
xch_funds = uint64(10000000000)
|
|
2138
|
-
for _ in range(4):
|
|
2139
|
-
await client_0.dao_add_funds_to_treasury(dao_id_0, 1, uint64(xch_funds / 4), DEFAULT_TX_CONFIG)
|
|
2140
|
-
await client_0.dao_add_funds_to_treasury(
|
|
2141
|
-
dao_id_0, new_cat_wallet_id, uint64(new_cat_amt / 4), DEFAULT_TX_CONFIG
|
|
2142
|
-
)
|
|
2143
|
-
await client_0.dao_add_funds_to_treasury(
|
|
2144
|
-
dao_id_0, new_cat_wallet_id_2, uint64(new_cat_amt / 4), DEFAULT_TX_CONFIG
|
|
2145
|
-
)
|
|
2146
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2147
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2148
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2149
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2150
|
-
|
|
2151
|
-
await rpc_state(20, client_0.dao_get_treasury_balance, [dao_id_0], lambda x: x["balances"]["xch"], xch_funds)
|
|
2152
|
-
assert isinstance(new_cat_wallet, CATWallet)
|
|
2153
|
-
new_cat_asset_id = new_cat_wallet.cat_info.limitations_program_hash
|
|
2154
|
-
assert isinstance(new_cat_wallet_2, CATWallet)
|
|
2155
|
-
new_cat_asset_id_2 = new_cat_wallet_2.cat_info.limitations_program_hash
|
|
2156
|
-
await rpc_state(
|
|
2157
|
-
20,
|
|
2158
|
-
client_0.dao_get_treasury_balance,
|
|
2159
|
-
[dao_id_0],
|
|
2160
|
-
lambda x: x["balances"][new_cat_asset_id.hex()],
|
|
2161
|
-
new_cat_amt,
|
|
2162
|
-
)
|
|
2163
|
-
await rpc_state(
|
|
2164
|
-
20,
|
|
2165
|
-
client_0.dao_get_treasury_balance,
|
|
2166
|
-
[dao_id_0],
|
|
2167
|
-
lambda x: x["balances"][new_cat_asset_id_2.hex()],
|
|
2168
|
-
new_cat_amt,
|
|
2169
|
-
)
|
|
2170
|
-
|
|
2171
|
-
# add the new cat wallets to wallet_1
|
|
2172
|
-
await client_1.create_wallet_for_existing_cat(new_cat_asset_id)
|
|
2173
|
-
await client_1.create_wallet_for_existing_cat(new_cat_asset_id_2)
|
|
2174
|
-
|
|
2175
|
-
# send cats to lockup
|
|
2176
|
-
await client_0.dao_send_to_lockup(dao_id_0, cat_amt, DEFAULT_TX_CONFIG)
|
|
2177
|
-
|
|
2178
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2179
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2180
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2181
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2182
|
-
|
|
2183
|
-
# Test spend proposal types
|
|
2184
|
-
|
|
2185
|
-
# Test proposal with multiple conditions and xch coins
|
|
2186
|
-
additions = [
|
|
2187
|
-
{"puzzle_hash": ph_0.hex(), "amount": xch_funds / 4},
|
|
2188
|
-
{"puzzle_hash": ph_1.hex(), "amount": xch_funds / 4},
|
|
2189
|
-
]
|
|
2190
|
-
await client_0.dao_create_proposal(
|
|
2191
|
-
wallet_id=dao_id_0,
|
|
2192
|
-
proposal_type="spend",
|
|
2193
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
2194
|
-
additions=additions,
|
|
2195
|
-
vote_amount=cat_amt,
|
|
2196
|
-
)
|
|
2197
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2198
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2199
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2200
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2201
|
-
|
|
2202
|
-
props = await client_1.dao_get_proposals(dao_id_1)
|
|
2203
|
-
proposal_id_hex = props["proposals"][-1]["proposal_id"]
|
|
2204
|
-
|
|
2205
|
-
await client_0.dao_close_proposal(
|
|
2206
|
-
wallet_id=dao_id_0, proposal_id=proposal_id_hex, tx_config=DEFAULT_TX_CONFIG, self_destruct=False
|
|
2207
|
-
)
|
|
2208
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2209
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2210
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2211
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2212
|
-
|
|
2213
|
-
# check proposal is closed
|
|
2214
|
-
await rpc_state(20, client_0.dao_get_proposals, [dao_id_0], lambda x: x["proposals"][-1]["closed"], True)
|
|
2215
|
-
await rpc_state(20, client_1.dao_get_proposals, [dao_id_1], lambda x: x["proposals"][-1]["closed"], True)
|
|
2216
|
-
# check the xch is received and removed from treasury
|
|
2217
|
-
await rpc_state(
|
|
2218
|
-
20,
|
|
2219
|
-
client_1.get_wallet_balance,
|
|
2220
|
-
[wallet_1.id()],
|
|
2221
|
-
lambda x: x["confirmed_wallet_balance"],
|
|
2222
|
-
initial_funds + (xch_funds / 4),
|
|
2223
|
-
)
|
|
2224
|
-
await rpc_state(
|
|
2225
|
-
20,
|
|
2226
|
-
client_0.dao_get_treasury_balance,
|
|
2227
|
-
[dao_id_0],
|
|
2228
|
-
lambda x: x["balances"]["xch"],
|
|
2229
|
-
xch_funds / 2,
|
|
2230
|
-
)
|
|
2231
|
-
|
|
2232
|
-
# Test proposal with multiple cats and multiple coins
|
|
2233
|
-
cat_spend_amt = 510000
|
|
2234
|
-
additions = [
|
|
2235
|
-
{"puzzle_hash": ph_0.hex(), "amount": cat_spend_amt, "asset_id": new_cat_asset_id.hex()},
|
|
2236
|
-
{"puzzle_hash": ph_0.hex(), "amount": cat_spend_amt, "asset_id": new_cat_asset_id_2.hex()},
|
|
2237
|
-
]
|
|
2238
|
-
await client_0.dao_create_proposal(
|
|
2239
|
-
wallet_id=dao_id_0,
|
|
2240
|
-
proposal_type="spend",
|
|
2241
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
2242
|
-
additions=additions,
|
|
2243
|
-
vote_amount=cat_amt,
|
|
2244
|
-
)
|
|
2245
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2246
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2247
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2248
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2249
|
-
|
|
2250
|
-
props = await client_1.dao_get_proposals(dao_id_1)
|
|
2251
|
-
proposal_id_hex = props["proposals"][-1]["proposal_id"]
|
|
2252
|
-
|
|
2253
|
-
await client_0.dao_close_proposal(
|
|
2254
|
-
wallet_id=dao_id_0, proposal_id=proposal_id_hex, tx_config=DEFAULT_TX_CONFIG, self_destruct=False
|
|
2255
|
-
)
|
|
2256
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2257
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2258
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2259
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2260
|
-
|
|
2261
|
-
# check proposal is closed
|
|
2262
|
-
await rpc_state(20, client_0.dao_get_proposals, [dao_id_0], lambda x: x["proposals"][-1]["closed"], True)
|
|
2263
|
-
await rpc_state(20, client_1.dao_get_proposals, [dao_id_1], lambda x: x["proposals"][-1]["closed"], True)
|
|
2264
|
-
|
|
2265
|
-
# check cat balances
|
|
2266
|
-
await rpc_state(
|
|
2267
|
-
20,
|
|
2268
|
-
client_0.dao_get_treasury_balance,
|
|
2269
|
-
[dao_id_0],
|
|
2270
|
-
lambda x: x["balances"][new_cat_asset_id.hex()],
|
|
2271
|
-
new_cat_amt - cat_spend_amt,
|
|
2272
|
-
)
|
|
2273
|
-
await rpc_state(
|
|
2274
|
-
20,
|
|
2275
|
-
client_0.dao_get_treasury_balance,
|
|
2276
|
-
[dao_id_0],
|
|
2277
|
-
lambda x: x["balances"][new_cat_asset_id_2.hex()],
|
|
2278
|
-
new_cat_amt - cat_spend_amt,
|
|
2279
|
-
)
|
|
2280
|
-
|
|
2281
|
-
await rpc_state(
|
|
2282
|
-
20, client_0.get_wallet_balance, [new_cat_wallet_id], lambda x: x["confirmed_wallet_balance"], cat_spend_amt
|
|
2283
|
-
)
|
|
2284
|
-
await rpc_state(
|
|
2285
|
-
20,
|
|
2286
|
-
client_0.get_wallet_balance,
|
|
2287
|
-
[new_cat_wallet_id_2],
|
|
2288
|
-
lambda x: x["confirmed_wallet_balance"],
|
|
2289
|
-
cat_spend_amt,
|
|
2290
|
-
)
|
|
2291
|
-
|
|
2292
|
-
# Spend remaining balances with multiple outputs
|
|
2293
|
-
|
|
2294
|
-
additions = [
|
|
2295
|
-
{"puzzle_hash": ph_0.hex(), "amount": 400000, "asset_id": new_cat_asset_id.hex()},
|
|
2296
|
-
{"puzzle_hash": ph_1.hex(), "amount": 90000, "asset_id": new_cat_asset_id.hex()},
|
|
2297
|
-
{"puzzle_hash": ph_0.hex(), "amount": 400000, "asset_id": new_cat_asset_id_2.hex()},
|
|
2298
|
-
{"puzzle_hash": ph_1.hex(), "amount": 90000, "asset_id": new_cat_asset_id_2.hex()},
|
|
2299
|
-
{"puzzle_hash": ph_0.hex(), "amount": xch_funds / 4},
|
|
2300
|
-
{"puzzle_hash": ph_1.hex(), "amount": xch_funds / 4},
|
|
2301
|
-
]
|
|
2302
|
-
await client_0.dao_create_proposal(
|
|
2303
|
-
wallet_id=dao_id_0,
|
|
2304
|
-
proposal_type="spend",
|
|
2305
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
2306
|
-
additions=additions,
|
|
2307
|
-
vote_amount=cat_amt,
|
|
2308
|
-
)
|
|
2309
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2310
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2311
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2312
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2313
|
-
|
|
2314
|
-
props = await client_0.dao_get_proposals(dao_id_0)
|
|
2315
|
-
proposal_id_hex = props["proposals"][-1]["proposal_id"]
|
|
2316
|
-
|
|
2317
|
-
await client_0.dao_close_proposal(
|
|
2318
|
-
wallet_id=dao_id_0,
|
|
2319
|
-
proposal_id=proposal_id_hex,
|
|
2320
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
2321
|
-
self_destruct=False,
|
|
2322
|
-
)
|
|
2323
|
-
txs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2324
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2325
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2326
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2327
|
-
|
|
2328
|
-
# check proposal is closed
|
|
2329
|
-
await rpc_state(20, client_0.dao_get_proposals, [dao_id_0], lambda x: x["proposals"][-1]["closed"], True)
|
|
2330
|
-
await rpc_state(20, client_1.dao_get_proposals, [dao_id_1], lambda x: x["proposals"][-1]["closed"], True)
|
|
2331
|
-
|
|
2332
|
-
# check cat balances
|
|
2333
|
-
await rpc_state(
|
|
2334
|
-
20,
|
|
2335
|
-
client_0.get_wallet_balance,
|
|
2336
|
-
[new_cat_wallet_id],
|
|
2337
|
-
lambda x: x["confirmed_wallet_balance"],
|
|
2338
|
-
cat_spend_amt + 400000,
|
|
2339
|
-
)
|
|
2340
|
-
await rpc_state(
|
|
2341
|
-
20,
|
|
2342
|
-
client_0.get_wallet_balance,
|
|
2343
|
-
[new_cat_wallet_id_2],
|
|
2344
|
-
lambda x: x["confirmed_wallet_balance"],
|
|
2345
|
-
cat_spend_amt + 400000,
|
|
2346
|
-
)
|
|
2347
|
-
await rpc_state(
|
|
2348
|
-
20, client_1.get_wallet_balance, [new_cat_wallet_id], lambda x: x["confirmed_wallet_balance"], 90000
|
|
2349
|
-
)
|
|
2350
|
-
await rpc_state(
|
|
2351
|
-
20, client_1.get_wallet_balance, [new_cat_wallet_id_2], lambda x: x["confirmed_wallet_balance"], 90000
|
|
2352
|
-
)
|
|
2353
|
-
|
|
2354
|
-
# check xch
|
|
2355
|
-
await rpc_state(
|
|
2356
|
-
20,
|
|
2357
|
-
client_1.get_wallet_balance,
|
|
2358
|
-
[wallet_1.id()],
|
|
2359
|
-
lambda x: x["confirmed_wallet_balance"],
|
|
2360
|
-
initial_funds + (xch_funds / 2),
|
|
2361
|
-
)
|
|
2362
|
-
|
|
2363
|
-
# check treasury balances are 0
|
|
2364
|
-
await rpc_state(
|
|
2365
|
-
20,
|
|
2366
|
-
client_1.dao_get_treasury_balance,
|
|
2367
|
-
[dao_id_0],
|
|
2368
|
-
lambda x: x["balances"]["xch"] + 1, # add 1 so result isn't 0
|
|
2369
|
-
1,
|
|
2370
|
-
)
|
|
2371
|
-
await rpc_state(
|
|
2372
|
-
20,
|
|
2373
|
-
client_1.dao_get_treasury_balance,
|
|
2374
|
-
[dao_id_0],
|
|
2375
|
-
lambda x: x["balances"][new_cat_asset_id.hex()] + 1, # add 1 so result isn't 0
|
|
2376
|
-
1,
|
|
2377
|
-
)
|
|
2378
|
-
await rpc_state(
|
|
2379
|
-
20,
|
|
2380
|
-
client_0.dao_get_treasury_balance,
|
|
2381
|
-
[dao_id_0],
|
|
2382
|
-
lambda x: x["balances"][new_cat_asset_id_2.hex()] + 1, # add 1 so result isn't 0
|
|
2383
|
-
1,
|
|
2384
|
-
)
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
2388
|
-
@pytest.mark.parametrize(
|
|
2389
|
-
"trusted",
|
|
2390
|
-
[True, False],
|
|
2391
|
-
)
|
|
2392
|
-
@pytest.mark.anyio
|
|
2393
|
-
async def test_dao_concurrency(self_hostname: str, three_wallet_nodes: OldSimulatorsAndWallets, trusted: bool) -> None:
|
|
2394
|
-
full_nodes, wallets, _ = three_wallet_nodes
|
|
2395
|
-
full_node_api = full_nodes[0]
|
|
2396
|
-
full_node_server = full_node_api.server
|
|
2397
|
-
wallet_node_0, server_0 = wallets[0]
|
|
2398
|
-
wallet_node_1, server_1 = wallets[1]
|
|
2399
|
-
wallet_node_2, server_2 = wallets[2]
|
|
2400
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
2401
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
2402
|
-
wallet_2 = wallet_node_2.wallet_state_manager.main_wallet
|
|
2403
|
-
ph = await wallet_0.get_new_puzzlehash()
|
|
2404
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
2405
|
-
ph_2 = await wallet_2.get_new_puzzlehash()
|
|
2406
|
-
|
|
2407
|
-
if trusted:
|
|
2408
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
2409
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2410
|
-
}
|
|
2411
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
2412
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2413
|
-
}
|
|
2414
|
-
wallet_node_2.config["trusted_peers"] = {
|
|
2415
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2416
|
-
}
|
|
2417
|
-
else:
|
|
2418
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
2419
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
2420
|
-
wallet_node_2.config["trusted_peers"] = {}
|
|
2421
|
-
|
|
2422
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2423
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2424
|
-
await server_2.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2425
|
-
|
|
2426
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
|
|
2427
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
2428
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_2))
|
|
2429
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
2430
|
-
|
|
2431
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
2432
|
-
|
|
2433
|
-
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
|
2434
|
-
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
|
2435
|
-
|
|
2436
|
-
cat_amt = 300000
|
|
2437
|
-
dao_rules = DAORules(
|
|
2438
|
-
proposal_timelock=uint64(10),
|
|
2439
|
-
soft_close_length=uint64(5),
|
|
2440
|
-
attendance_required=uint64(1000), # 10%
|
|
2441
|
-
pass_percentage=uint64(5100), # 51%
|
|
2442
|
-
self_destruct_length=uint64(20),
|
|
2443
|
-
oracle_spend_delay=uint64(10),
|
|
2444
|
-
proposal_minimum_amount=uint64(101),
|
|
2445
|
-
)
|
|
2446
|
-
|
|
2447
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2448
|
-
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
|
2449
|
-
wallet_node_0.wallet_state_manager, wallet_0, uint64(cat_amt), dao_rules, action_scope
|
|
2450
|
-
)
|
|
2451
|
-
|
|
2452
|
-
# Get the full node sim to process the wallet creation spend
|
|
2453
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2454
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2455
|
-
)
|
|
2456
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2457
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2458
|
-
|
|
2459
|
-
# get the cat wallets
|
|
2460
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
2461
|
-
await time_out_assert(10, cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
2462
|
-
|
|
2463
|
-
# get the dao_cat wallet
|
|
2464
|
-
dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
|
2465
|
-
|
|
2466
|
-
treasury_id = dao_wallet_0.dao_info.treasury_id
|
|
2467
|
-
|
|
2468
|
-
# Create the other user's wallet from the treasury id
|
|
2469
|
-
dao_wallet_1 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
2470
|
-
wallet_node_1.wallet_state_manager, wallet_1, treasury_id
|
|
2471
|
-
)
|
|
2472
|
-
assert dao_wallet_1.dao_info.treasury_id == treasury_id
|
|
2473
|
-
|
|
2474
|
-
# Create funding spends for xch
|
|
2475
|
-
xch_funds = uint64(500000)
|
|
2476
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2477
|
-
await dao_wallet_0.create_add_funds_to_treasury_spend(xch_funds, action_scope)
|
|
2478
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2479
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2480
|
-
)
|
|
2481
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2482
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2483
|
-
|
|
2484
|
-
# Check that the funding spend is recognized by both dao wallets
|
|
2485
|
-
await time_out_assert(10, dao_wallet_0.get_balance_by_asset_type, xch_funds)
|
|
2486
|
-
|
|
2487
|
-
# Send some dao_cats to wallet_1
|
|
2488
|
-
# Get the cat wallets for wallet_1
|
|
2489
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
2490
|
-
dao_cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.dao_cat_wallet_id]
|
|
2491
|
-
assert cat_wallet_1
|
|
2492
|
-
assert dao_cat_wallet_1
|
|
2493
|
-
|
|
2494
|
-
# Add a third wallet and check they can find proposal with accurate vote counts
|
|
2495
|
-
dao_wallet_2 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
2496
|
-
wallet_node_2.wallet_state_manager, wallet_2, treasury_id
|
|
2497
|
-
)
|
|
2498
|
-
assert dao_wallet_2.dao_info.treasury_id == treasury_id
|
|
2499
|
-
|
|
2500
|
-
dao_cat_wallet_2 = dao_wallet_2.wallet_state_manager.wallets[dao_wallet_2.dao_info.dao_cat_wallet_id]
|
|
2501
|
-
assert dao_cat_wallet_2
|
|
2502
|
-
|
|
2503
|
-
async with cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2504
|
-
await cat_wallet_0.generate_signed_transaction([100000, 100000], [ph_1, ph_2], action_scope)
|
|
2505
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2506
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2507
|
-
)
|
|
2508
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2509
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2510
|
-
|
|
2511
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
2512
|
-
await time_out_assert(10, cat_wallet_1.get_confirmed_balance, 100000)
|
|
2513
|
-
cat_wallet_2 = dao_wallet_2.wallet_state_manager.wallets[dao_wallet_2.dao_info.cat_wallet_id]
|
|
2514
|
-
await time_out_assert(10, cat_wallet_2.get_confirmed_balance, 100000)
|
|
2515
|
-
await time_out_assert(10, cat_wallet_0.get_confirmed_balance, 100000)
|
|
2516
|
-
|
|
2517
|
-
# Create dao cats for voting
|
|
2518
|
-
dao_cat_0_bal = await dao_cat_wallet_0.get_votable_balance()
|
|
2519
|
-
assert dao_cat_0_bal == 100000
|
|
2520
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2521
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dao_cat_0_bal, action_scope)
|
|
2522
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2523
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2524
|
-
)
|
|
2525
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2526
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2527
|
-
|
|
2528
|
-
# Create a proposal for xch spend
|
|
2529
|
-
recipient_puzzle_hash = await wallet_2.get_new_puzzlehash()
|
|
2530
|
-
proposal_amount = uint64(10000)
|
|
2531
|
-
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
|
2532
|
-
treasury_id,
|
|
2533
|
-
[recipient_puzzle_hash],
|
|
2534
|
-
[proposal_amount],
|
|
2535
|
-
[None],
|
|
2536
|
-
)
|
|
2537
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2538
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, dao_cat_0_bal, uint64(1000))
|
|
2539
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2540
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2541
|
-
)
|
|
2542
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2543
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2544
|
-
|
|
2545
|
-
# Check the proposal is saved
|
|
2546
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 1
|
|
2547
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == dao_cat_0_bal
|
|
2548
|
-
assert dao_wallet_0.dao_info.proposals_list[0].timer_coin is not None
|
|
2549
|
-
|
|
2550
|
-
# Check that wallet_1 also finds and saved the proposal
|
|
2551
|
-
assert len(dao_wallet_1.dao_info.proposals_list) == 1
|
|
2552
|
-
prop = dao_wallet_1.dao_info.proposals_list[0]
|
|
2553
|
-
|
|
2554
|
-
total_votes = dao_cat_0_bal
|
|
2555
|
-
|
|
2556
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == total_votes
|
|
2557
|
-
assert dao_wallet_0.dao_info.proposals_list[0].yes_votes == total_votes
|
|
2558
|
-
assert dao_wallet_1.dao_info.proposals_list[0].amount_voted == total_votes
|
|
2559
|
-
assert dao_wallet_1.dao_info.proposals_list[0].yes_votes == total_votes
|
|
2560
|
-
|
|
2561
|
-
# Create votable dao cats and add a new vote
|
|
2562
|
-
dao_cat_1_bal = await dao_cat_wallet_1.get_votable_balance()
|
|
2563
|
-
async with dao_cat_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2564
|
-
await dao_cat_wallet_1.enter_dao_cat_voting_mode(dao_cat_1_bal, action_scope)
|
|
2565
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2566
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2567
|
-
)
|
|
2568
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
2569
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
2570
|
-
|
|
2571
|
-
async with dao_cat_wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2572
|
-
await dao_cat_wallet_2.enter_dao_cat_voting_mode(dao_cat_1_bal, action_scope)
|
|
2573
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2574
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2575
|
-
)
|
|
2576
|
-
await full_node_api.process_all_wallet_transactions(wallet_2, timeout=60)
|
|
2577
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
2578
|
-
|
|
2579
|
-
async with dao_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2580
|
-
await dao_wallet_1.generate_proposal_vote_spend(prop.proposal_id, dao_cat_1_bal, True, action_scope)
|
|
2581
|
-
[vote_tx] = action_scope.side_effects.transactions
|
|
2582
|
-
vote_sb = vote_tx.spend_bundle
|
|
2583
|
-
assert vote_sb is not None
|
|
2584
|
-
async with dao_wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2585
|
-
await dao_wallet_2.generate_proposal_vote_spend(prop.proposal_id, dao_cat_1_bal, True, action_scope)
|
|
2586
|
-
[vote_tx_2] = action_scope.side_effects.transactions
|
|
2587
|
-
vote_2 = vote_tx_2.spend_bundle
|
|
2588
|
-
assert vote_2 is not None
|
|
2589
|
-
await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, vote_sb.name())
|
|
2590
|
-
await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, vote_2.name())
|
|
2591
|
-
|
|
2592
|
-
await time_out_assert(20, len, 1, dao_wallet_2.dao_info.proposals_list)
|
|
2593
|
-
await time_out_assert(20, int, total_votes, dao_wallet_1.dao_info.proposals_list[0].amount_voted)
|
|
2594
|
-
await time_out_assert(20, int, total_votes, dao_wallet_2.dao_info.proposals_list[0].amount_voted)
|
|
2595
|
-
|
|
2596
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
2597
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1, wallet_node_2], timeout=30)
|
|
2598
|
-
|
|
2599
|
-
await time_out_assert(20, int, total_votes * 2, dao_wallet_1.dao_info.proposals_list[0].amount_voted)
|
|
2600
|
-
await time_out_assert(20, int, total_votes * 2, dao_wallet_2.dao_info.proposals_list[0].amount_voted)
|
|
2601
|
-
dao_cat_1_bal = await dao_cat_wallet_1.get_votable_balance(prop.proposal_id)
|
|
2602
|
-
dao_cat_2_bal = await dao_cat_wallet_2.get_votable_balance(prop.proposal_id)
|
|
2603
|
-
|
|
2604
|
-
assert (dao_cat_1_bal == 100000 and dao_cat_2_bal == 0) or (dao_cat_1_bal == 0 and dao_cat_2_bal == 100000)
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
2608
|
-
@pytest.mark.parametrize(
|
|
2609
|
-
"trusted",
|
|
2610
|
-
[True, False],
|
|
2611
|
-
)
|
|
2612
|
-
@pytest.mark.anyio
|
|
2613
|
-
@pytest.mark.standard_block_tools
|
|
2614
|
-
async def test_dao_cat_exits(
|
|
2615
|
-
two_wallet_nodes_services: SimulatorsAndWalletsServices, trusted: bool, self_hostname: str
|
|
2616
|
-
) -> None:
|
|
2617
|
-
[full_node_service], wallet_services, _bt = two_wallet_nodes_services
|
|
2618
|
-
full_node_api = full_node_service._api
|
|
2619
|
-
full_node_server = full_node_api.full_node.server
|
|
2620
|
-
wallet_node_0 = wallet_services[0]._node
|
|
2621
|
-
server_0 = wallet_node_0.server
|
|
2622
|
-
wallet_node_1 = wallet_services[1]._node
|
|
2623
|
-
server_1 = wallet_node_1.server
|
|
2624
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
2625
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
2626
|
-
ph_0 = await wallet_0.get_new_puzzlehash()
|
|
2627
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
2628
|
-
|
|
2629
|
-
if trusted:
|
|
2630
|
-
wallet_node_0.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
2631
|
-
wallet_node_1.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()}
|
|
2632
|
-
else:
|
|
2633
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
2634
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
2635
|
-
|
|
2636
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2637
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2638
|
-
|
|
2639
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_0))
|
|
2640
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
2641
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
2642
|
-
|
|
2643
|
-
initial_funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
2644
|
-
|
|
2645
|
-
await time_out_assert(15, wallet_0.get_confirmed_balance, initial_funds)
|
|
2646
|
-
await time_out_assert(15, wallet_0.get_unconfirmed_balance, initial_funds)
|
|
2647
|
-
|
|
2648
|
-
assert wallet_services[0].rpc_server is not None
|
|
2649
|
-
assert wallet_services[1].rpc_server is not None
|
|
2650
|
-
|
|
2651
|
-
async with contextlib.AsyncExitStack() as exit_stack:
|
|
2652
|
-
client_0 = await exit_stack.enter_async_context(
|
|
2653
|
-
WalletRpcClient.create_as_context(
|
|
2654
|
-
self_hostname,
|
|
2655
|
-
wallet_services[0].rpc_server.listen_port,
|
|
2656
|
-
wallet_services[0].root_path,
|
|
2657
|
-
wallet_services[0].config,
|
|
2658
|
-
)
|
|
2659
|
-
)
|
|
2660
|
-
await validate_get_routes(client_0, wallet_services[0].rpc_server.rpc_api)
|
|
2661
|
-
client_1 = await exit_stack.enter_async_context(
|
|
2662
|
-
WalletRpcClient.create_as_context(
|
|
2663
|
-
self_hostname,
|
|
2664
|
-
wallet_services[1].rpc_server.listen_port,
|
|
2665
|
-
wallet_services[1].root_path,
|
|
2666
|
-
wallet_services[1].config,
|
|
2667
|
-
)
|
|
2668
|
-
)
|
|
2669
|
-
await validate_get_routes(client_1, wallet_services[1].rpc_server.rpc_api)
|
|
2670
|
-
|
|
2671
|
-
cat_amt = uint64(150000)
|
|
2672
|
-
dao_rules = DAORules(
|
|
2673
|
-
proposal_timelock=uint64(8),
|
|
2674
|
-
soft_close_length=uint64(4),
|
|
2675
|
-
attendance_required=uint64(1000), # 10%
|
|
2676
|
-
pass_percentage=uint64(5100), # 51%
|
|
2677
|
-
self_destruct_length=uint64(20),
|
|
2678
|
-
oracle_spend_delay=uint64(10),
|
|
2679
|
-
proposal_minimum_amount=uint64(1),
|
|
2680
|
-
)
|
|
2681
|
-
filter_amount = uint64(1)
|
|
2682
|
-
fee = uint64(10000)
|
|
2683
|
-
|
|
2684
|
-
# create new dao
|
|
2685
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2686
|
-
dao_wallet_res_0 = await client_0.create_new_dao_wallet(
|
|
2687
|
-
mode="new",
|
|
2688
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
2689
|
-
dao_rules=dao_rules.to_json_dict(),
|
|
2690
|
-
amount_of_cats=cat_amt,
|
|
2691
|
-
filter_amount=filter_amount,
|
|
2692
|
-
name="DAO WALLET 0",
|
|
2693
|
-
)
|
|
2694
|
-
dao_id_0 = dao_wallet_res_0.wallet_id
|
|
2695
|
-
cat_wallet_0 = wallet_node_0.wallet_state_manager.wallets[dao_wallet_res_0.cat_wallet_id]
|
|
2696
|
-
dao_cat_wallet_0 = wallet_node_0.wallet_state_manager.wallets[dao_wallet_res_0.dao_cat_wallet_id]
|
|
2697
|
-
ltxs = await wallet_0.wallet_state_manager.tx_store.get_all_unconfirmed()
|
|
2698
|
-
txs: list[TransactionRecord] = []
|
|
2699
|
-
for ltx in ltxs:
|
|
2700
|
-
tx = await wallet_0.wallet_state_manager.tx_store.get_transaction_record(ltx.name)
|
|
2701
|
-
assert tx is not None
|
|
2702
|
-
txs.append(tx)
|
|
2703
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2704
|
-
await full_node_api.process_transaction_records(records=txs, timeout=60)
|
|
2705
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, 60)
|
|
2706
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2707
|
-
await full_node_api.check_transactions_confirmed(wallet_node_0.wallet_state_manager, txs, 60)
|
|
2708
|
-
await time_out_assert(60, cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
2709
|
-
|
|
2710
|
-
# fund treasury
|
|
2711
|
-
xch_funds = uint64(10000000000)
|
|
2712
|
-
funding_tx = await client_0.dao_add_funds_to_treasury(dao_id_0, 1, xch_funds, DEFAULT_TX_CONFIG)
|
|
2713
|
-
tx = funding_tx.tx
|
|
2714
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[tx], timeout=60)
|
|
2715
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2716
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2717
|
-
|
|
2718
|
-
await rpc_state(20, client_0.dao_get_treasury_balance, [dao_id_0], lambda x: x["balances"]["xch"], xch_funds)
|
|
2719
|
-
|
|
2720
|
-
# send cats to lockup
|
|
2721
|
-
lockup_0 = await client_0.dao_send_to_lockup(dao_id_0, cat_amt, DEFAULT_TX_CONFIG)
|
|
2722
|
-
txs = lockup_0.txs
|
|
2723
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=txs, timeout=60)
|
|
2724
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2725
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2726
|
-
|
|
2727
|
-
assert isinstance(dao_cat_wallet_0, DAOCATWallet)
|
|
2728
|
-
await time_out_assert(60, dao_cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
2729
|
-
|
|
2730
|
-
# create a spend proposal
|
|
2731
|
-
additions = [
|
|
2732
|
-
{"puzzle_hash": ph_1.hex(), "amount": 1000},
|
|
2733
|
-
]
|
|
2734
|
-
proposal = await client_0.dao_create_proposal(
|
|
2735
|
-
wallet_id=dao_id_0,
|
|
2736
|
-
proposal_type="spend",
|
|
2737
|
-
tx_config=DEFAULT_TX_CONFIG,
|
|
2738
|
-
additions=additions,
|
|
2739
|
-
vote_amount=cat_amt,
|
|
2740
|
-
fee=fee,
|
|
2741
|
-
)
|
|
2742
|
-
tx = proposal.tx
|
|
2743
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[tx], timeout=60)
|
|
2744
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2745
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2746
|
-
|
|
2747
|
-
await time_out_assert_not_none(20, client_0.dao_get_proposals, dao_id_0)
|
|
2748
|
-
props = await client_0.dao_get_proposals(dao_id_0)
|
|
2749
|
-
proposal_id_hex = props["proposals"][0]["proposal_id"]
|
|
2750
|
-
|
|
2751
|
-
# check proposal state and farm enough blocks to pass
|
|
2752
|
-
state = await client_0.dao_get_proposal_state(wallet_id=dao_id_0, proposal_id=proposal_id_hex)
|
|
2753
|
-
assert state["success"]
|
|
2754
|
-
assert state["state"]["passed"]
|
|
2755
|
-
|
|
2756
|
-
for _ in range(state["state"]["blocks_needed"] + 1):
|
|
2757
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
2758
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2759
|
-
|
|
2760
|
-
state = await client_0.dao_get_proposal_state(wallet_id=dao_id_0, proposal_id=proposal_id_hex)
|
|
2761
|
-
assert state["success"]
|
|
2762
|
-
assert state["state"]["closable"]
|
|
2763
|
-
|
|
2764
|
-
# close the proposal
|
|
2765
|
-
close = await client_0.dao_close_proposal(
|
|
2766
|
-
wallet_id=dao_id_0, proposal_id=proposal_id_hex, tx_config=DEFAULT_TX_CONFIG, self_destruct=False, fee=fee
|
|
2767
|
-
)
|
|
2768
|
-
tx = close.tx
|
|
2769
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[tx], timeout=60)
|
|
2770
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2771
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2772
|
-
|
|
2773
|
-
# check proposal is closed
|
|
2774
|
-
await rpc_state(20, client_0.dao_get_proposals, [dao_id_0], lambda x: x["proposals"][0]["closed"], True)
|
|
2775
|
-
|
|
2776
|
-
# free locked cats from finished proposal
|
|
2777
|
-
res = await client_0.dao_free_coins_from_finished_proposals(wallet_id=dao_id_0, tx_config=DEFAULT_TX_CONFIG)
|
|
2778
|
-
tx = res.tx
|
|
2779
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[tx], timeout=60)
|
|
2780
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2781
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2782
|
-
|
|
2783
|
-
assert isinstance(dao_cat_wallet_0, DAOCATWallet)
|
|
2784
|
-
assert dao_cat_wallet_0.dao_cat_info.locked_coins[0].active_votes == []
|
|
2785
|
-
|
|
2786
|
-
exit = await client_0.dao_exit_lockup(dao_id_0, DEFAULT_TX_CONFIG)
|
|
2787
|
-
exit_tx = exit.tx
|
|
2788
|
-
await full_node_api.wait_transaction_records_entered_mempool(records=[exit_tx], timeout=60)
|
|
2789
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2790
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2791
|
-
|
|
2792
|
-
await time_out_assert(20, dao_cat_wallet_0.get_confirmed_balance, 0)
|
|
2793
|
-
await time_out_assert(20, cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
2797
|
-
@pytest.mark.parametrize(
|
|
2798
|
-
"trusted",
|
|
2799
|
-
[True, False],
|
|
2800
|
-
)
|
|
2801
|
-
@pytest.mark.anyio
|
|
2802
|
-
async def test_dao_reorgs(self_hostname: str, two_wallet_nodes: OldSimulatorsAndWallets, trusted: bool) -> None:
|
|
2803
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
2804
|
-
full_node_api = full_nodes[0]
|
|
2805
|
-
full_node_server = full_node_api.server
|
|
2806
|
-
wallet_node_0, server_0 = wallets[0]
|
|
2807
|
-
wallet_node_1, server_1 = wallets[1]
|
|
2808
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
2809
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
2810
|
-
ph = await wallet_0.get_new_puzzlehash()
|
|
2811
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
2812
|
-
|
|
2813
|
-
if trusted:
|
|
2814
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
2815
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2816
|
-
}
|
|
2817
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
2818
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
2819
|
-
}
|
|
2820
|
-
else:
|
|
2821
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
2822
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
2823
|
-
|
|
2824
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2825
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
2826
|
-
|
|
2827
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
|
|
2828
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
2829
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
2830
|
-
|
|
2831
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
2832
|
-
|
|
2833
|
-
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
|
2834
|
-
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
|
2835
|
-
|
|
2836
|
-
cat_amt = 300000
|
|
2837
|
-
dao_rules = DAORules(
|
|
2838
|
-
proposal_timelock=uint64(5),
|
|
2839
|
-
soft_close_length=uint64(2),
|
|
2840
|
-
attendance_required=uint64(1000), # 10%
|
|
2841
|
-
pass_percentage=uint64(5100), # 51%
|
|
2842
|
-
self_destruct_length=uint64(5),
|
|
2843
|
-
oracle_spend_delay=uint64(2),
|
|
2844
|
-
proposal_minimum_amount=uint64(101),
|
|
2845
|
-
)
|
|
2846
|
-
|
|
2847
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2848
|
-
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
|
2849
|
-
wallet_node_0.wallet_state_manager, wallet_0, uint64(cat_amt), dao_rules, action_scope
|
|
2850
|
-
)
|
|
2851
|
-
|
|
2852
|
-
# Get the full node sim to process the wallet creation spend
|
|
2853
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2854
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2855
|
-
)
|
|
2856
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2857
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2858
|
-
|
|
2859
|
-
await time_out_assert(60, dao_wallet_0.get_confirmed_balance, uint128(1))
|
|
2860
|
-
|
|
2861
|
-
# Test Reorg on creation
|
|
2862
|
-
height = full_node_api.full_node.blockchain.get_peak_height()
|
|
2863
|
-
assert height is not None
|
|
2864
|
-
await full_node_api.reorg_from_index_to_new_index(
|
|
2865
|
-
ReorgProtocol(uint32(height - 2), uint32(height + 1), puzzle_hash_0, None)
|
|
2866
|
-
)
|
|
2867
|
-
|
|
2868
|
-
assert dao_wallet_0.dao_info.current_treasury_coin
|
|
2869
|
-
await time_out_assert(60, dao_wallet_0.get_confirmed_balance, uint128(1))
|
|
2870
|
-
|
|
2871
|
-
# get the cat wallets
|
|
2872
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
2873
|
-
await time_out_assert(10, cat_wallet_0.get_confirmed_balance, cat_amt)
|
|
2874
|
-
|
|
2875
|
-
# get the dao_cat wallet
|
|
2876
|
-
dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
|
2877
|
-
|
|
2878
|
-
treasury_id = dao_wallet_0.dao_info.treasury_id
|
|
2879
|
-
|
|
2880
|
-
# Create the other user's wallet from the treasury id
|
|
2881
|
-
dao_wallet_1 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
2882
|
-
wallet_node_1.wallet_state_manager, wallet_1, treasury_id
|
|
2883
|
-
)
|
|
2884
|
-
assert dao_wallet_1.dao_info.treasury_id == treasury_id
|
|
2885
|
-
|
|
2886
|
-
# Create funding spends for xch
|
|
2887
|
-
xch_funds = uint64(500000)
|
|
2888
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2889
|
-
await dao_wallet_0.create_add_funds_to_treasury_spend(
|
|
2890
|
-
xch_funds,
|
|
2891
|
-
action_scope,
|
|
2892
|
-
)
|
|
2893
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2894
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2895
|
-
)
|
|
2896
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2897
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2898
|
-
|
|
2899
|
-
# Check that the funding spend is recognized by both dao wallets
|
|
2900
|
-
await time_out_assert(20, dao_wallet_0.get_balance_by_asset_type, xch_funds)
|
|
2901
|
-
await time_out_assert(20, dao_wallet_1.get_balance_by_asset_type, xch_funds)
|
|
2902
|
-
|
|
2903
|
-
# Reorg funding spend
|
|
2904
|
-
height = full_node_api.full_node.blockchain.get_peak_height()
|
|
2905
|
-
assert height is not None
|
|
2906
|
-
await full_node_api.reorg_from_index_to_new_index(
|
|
2907
|
-
ReorgProtocol(uint32(height - 1), uint32(height + 1), puzzle_hash_0, None)
|
|
2908
|
-
)
|
|
2909
|
-
await time_out_assert(20, dao_wallet_0.get_balance_by_asset_type, xch_funds)
|
|
2910
|
-
await time_out_assert(20, dao_wallet_1.get_balance_by_asset_type, xch_funds)
|
|
2911
|
-
|
|
2912
|
-
# Send some dao_cats to wallet_1
|
|
2913
|
-
# Get the cat wallets for wallet_1
|
|
2914
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
2915
|
-
dao_cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.dao_cat_wallet_id]
|
|
2916
|
-
assert cat_wallet_1
|
|
2917
|
-
assert dao_cat_wallet_1
|
|
2918
|
-
|
|
2919
|
-
async with cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2920
|
-
await cat_wallet_0.generate_signed_transaction(
|
|
2921
|
-
[100000],
|
|
2922
|
-
[ph_1],
|
|
2923
|
-
action_scope,
|
|
2924
|
-
)
|
|
2925
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2926
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2927
|
-
)
|
|
2928
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2929
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2930
|
-
|
|
2931
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
2932
|
-
await time_out_assert(20, cat_wallet_1.get_confirmed_balance, 100000)
|
|
2933
|
-
|
|
2934
|
-
# Create dao cats for voting
|
|
2935
|
-
dao_cat_0_bal = await dao_cat_wallet_0.get_votable_balance()
|
|
2936
|
-
assert dao_cat_0_bal == 200000
|
|
2937
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2938
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dao_cat_0_bal, action_scope)
|
|
2939
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2940
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2941
|
-
)
|
|
2942
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2943
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2944
|
-
|
|
2945
|
-
# Create a proposal for xch spend
|
|
2946
|
-
recipient_puzzle_hash = await wallet_0.get_new_puzzlehash()
|
|
2947
|
-
proposal_amount = uint64(10000)
|
|
2948
|
-
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
|
2949
|
-
treasury_id,
|
|
2950
|
-
[recipient_puzzle_hash],
|
|
2951
|
-
[proposal_amount],
|
|
2952
|
-
[None],
|
|
2953
|
-
)
|
|
2954
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2955
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, dao_cat_0_bal, uint64(1000))
|
|
2956
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2957
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2958
|
-
)
|
|
2959
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
2960
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2961
|
-
|
|
2962
|
-
# Check the proposal is saved
|
|
2963
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 1
|
|
2964
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == dao_cat_0_bal
|
|
2965
|
-
assert dao_wallet_0.dao_info.proposals_list[0].timer_coin is not None
|
|
2966
|
-
|
|
2967
|
-
# Reorg proposal creation
|
|
2968
|
-
height = full_node_api.full_node.blockchain.get_peak_height()
|
|
2969
|
-
assert height is not None
|
|
2970
|
-
await full_node_api.reorg_from_index_to_new_index(
|
|
2971
|
-
ReorgProtocol(uint32(height - 1), uint32(height + 1), puzzle_hash_0, None)
|
|
2972
|
-
)
|
|
2973
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 1
|
|
2974
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == dao_cat_0_bal
|
|
2975
|
-
assert dao_wallet_0.dao_info.proposals_list[0].timer_coin is not None
|
|
2976
|
-
|
|
2977
|
-
# Check that wallet_1 also finds and saved the proposal
|
|
2978
|
-
assert len(dao_wallet_1.dao_info.proposals_list) == 1
|
|
2979
|
-
prop = dao_wallet_1.dao_info.proposals_list[0]
|
|
2980
|
-
|
|
2981
|
-
total_votes = dao_cat_0_bal
|
|
2982
|
-
|
|
2983
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == total_votes
|
|
2984
|
-
assert dao_wallet_0.dao_info.proposals_list[0].yes_votes == total_votes
|
|
2985
|
-
assert dao_wallet_1.dao_info.proposals_list[0].amount_voted == total_votes
|
|
2986
|
-
assert dao_wallet_1.dao_info.proposals_list[0].yes_votes == total_votes
|
|
2987
|
-
|
|
2988
|
-
# Create votable dao cats and add a new vote
|
|
2989
|
-
dao_cat_1_bal = await dao_cat_wallet_1.get_votable_balance()
|
|
2990
|
-
async with dao_cat_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2991
|
-
await dao_cat_wallet_1.enter_dao_cat_voting_mode(dao_cat_1_bal, action_scope)
|
|
2992
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
2993
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
2994
|
-
)
|
|
2995
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
2996
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
2997
|
-
|
|
2998
|
-
async with dao_cat_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
2999
|
-
await dao_wallet_1.generate_proposal_vote_spend(prop.proposal_id, dao_cat_1_bal, True, action_scope)
|
|
3000
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3001
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3002
|
-
)
|
|
3003
|
-
await full_node_api.process_all_wallet_transactions(wallet_1, timeout=60)
|
|
3004
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
3005
|
-
|
|
3006
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == dao_cat_0_bal + dao_cat_1_bal
|
|
3007
|
-
assert dao_wallet_0.dao_info.proposals_list[0].yes_votes == dao_cat_0_bal + dao_cat_1_bal
|
|
3008
|
-
assert dao_wallet_1.dao_info.proposals_list[0].amount_voted == dao_cat_0_bal + dao_cat_1_bal
|
|
3009
|
-
assert dao_wallet_1.dao_info.proposals_list[0].yes_votes == dao_cat_0_bal + dao_cat_1_bal
|
|
3010
|
-
|
|
3011
|
-
# Reorg on vote spend
|
|
3012
|
-
height = full_node_api.full_node.blockchain.get_peak_height()
|
|
3013
|
-
assert height is not None
|
|
3014
|
-
await full_node_api.reorg_from_index_to_new_index(
|
|
3015
|
-
ReorgProtocol(uint32(height - 1), uint32(height + 1), puzzle_hash_0, None)
|
|
3016
|
-
)
|
|
3017
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == dao_cat_0_bal + dao_cat_1_bal
|
|
3018
|
-
assert dao_wallet_0.dao_info.proposals_list[0].yes_votes == dao_cat_0_bal + dao_cat_1_bal
|
|
3019
|
-
assert dao_wallet_1.dao_info.proposals_list[0].amount_voted == dao_cat_0_bal + dao_cat_1_bal
|
|
3020
|
-
assert dao_wallet_1.dao_info.proposals_list[0].yes_votes == dao_cat_0_bal + dao_cat_1_bal
|
|
3021
|
-
|
|
3022
|
-
# Close proposal
|
|
3023
|
-
for i in range(5):
|
|
3024
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
3025
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
3026
|
-
|
|
3027
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3028
|
-
await dao_wallet_0.create_proposal_close_spend(prop.proposal_id, action_scope, fee=uint64(100))
|
|
3029
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3030
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3031
|
-
)
|
|
3032
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3033
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
3034
|
-
|
|
3035
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_0, 0])
|
|
3036
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_1, 0])
|
|
3037
|
-
|
|
3038
|
-
# Reorg closed proposal
|
|
3039
|
-
height = full_node_api.full_node.blockchain.get_peak_height()
|
|
3040
|
-
assert height is not None
|
|
3041
|
-
await full_node_api.reorg_from_index_to_new_index(
|
|
3042
|
-
ReorgProtocol(uint32(height - 1), uint32(height + 1), puzzle_hash_0, None)
|
|
3043
|
-
)
|
|
3044
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
3045
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_0, 0])
|
|
3046
|
-
await time_out_assert(20, get_proposal_state, (True, True), *[dao_wallet_1, 0])
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
3050
|
-
@pytest.mark.parametrize(
|
|
3051
|
-
"trusted",
|
|
3052
|
-
[True, False],
|
|
3053
|
-
)
|
|
3054
|
-
@pytest.mark.anyio
|
|
3055
|
-
async def test_dao_votes(self_hostname: str, three_wallet_nodes: OldSimulatorsAndWallets, trusted: bool) -> None:
|
|
3056
|
-
full_nodes, wallets, _ = three_wallet_nodes
|
|
3057
|
-
full_node_api = full_nodes[0]
|
|
3058
|
-
full_node_server = full_node_api.server
|
|
3059
|
-
wallet_node_0, server_0 = wallets[0]
|
|
3060
|
-
wallet_node_1, server_1 = wallets[1]
|
|
3061
|
-
wallet_node_2, server_2 = wallets[2]
|
|
3062
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
3063
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
3064
|
-
wallet_2 = wallet_node_2.wallet_state_manager.main_wallet
|
|
3065
|
-
ph_0 = await wallet_0.get_new_puzzlehash()
|
|
3066
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
3067
|
-
ph_2 = await wallet_2.get_new_puzzlehash()
|
|
3068
|
-
|
|
3069
|
-
if trusted:
|
|
3070
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
3071
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
3072
|
-
}
|
|
3073
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
3074
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
3075
|
-
}
|
|
3076
|
-
wallet_node_2.config["trusted_peers"] = {
|
|
3077
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
3078
|
-
}
|
|
3079
|
-
else:
|
|
3080
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
3081
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
3082
|
-
wallet_node_2.config["trusted_peers"] = {}
|
|
3083
|
-
|
|
3084
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
3085
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
3086
|
-
await server_2.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
3087
|
-
|
|
3088
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_0))
|
|
3089
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
3090
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_2))
|
|
3091
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
3092
|
-
|
|
3093
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
3094
|
-
|
|
3095
|
-
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
|
3096
|
-
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
|
3097
|
-
|
|
3098
|
-
# set a standard fee amount to use in all txns
|
|
3099
|
-
base_fee = uint64(100)
|
|
3100
|
-
|
|
3101
|
-
# set the cat issuance and DAO rules
|
|
3102
|
-
cat_issuance = 300000
|
|
3103
|
-
proposal_min_amt = uint64(101)
|
|
3104
|
-
dao_rules = DAORules(
|
|
3105
|
-
proposal_timelock=uint64(10),
|
|
3106
|
-
soft_close_length=uint64(5),
|
|
3107
|
-
attendance_required=uint64(190000),
|
|
3108
|
-
pass_percentage=uint64(5100), # 51%
|
|
3109
|
-
self_destruct_length=uint64(20),
|
|
3110
|
-
oracle_spend_delay=uint64(10),
|
|
3111
|
-
proposal_minimum_amount=proposal_min_amt,
|
|
3112
|
-
)
|
|
3113
|
-
|
|
3114
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3115
|
-
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
|
3116
|
-
wallet_node_0.wallet_state_manager,
|
|
3117
|
-
wallet_0,
|
|
3118
|
-
uint64(cat_issuance),
|
|
3119
|
-
dao_rules,
|
|
3120
|
-
action_scope,
|
|
3121
|
-
)
|
|
3122
|
-
|
|
3123
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3124
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3125
|
-
)
|
|
3126
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3127
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
3128
|
-
|
|
3129
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
3130
|
-
dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
|
3131
|
-
await time_out_assert(10, cat_wallet_0.get_confirmed_balance, cat_issuance)
|
|
3132
|
-
assert dao_cat_wallet_0
|
|
3133
|
-
|
|
3134
|
-
treasury_id = dao_wallet_0.dao_info.treasury_id
|
|
3135
|
-
|
|
3136
|
-
dc_1 = uint64(100000)
|
|
3137
|
-
dc_2 = uint64(50000)
|
|
3138
|
-
dc_3 = uint64(30000)
|
|
3139
|
-
dc_4 = uint64(20000)
|
|
3140
|
-
dc_5 = uint64(10000)
|
|
3141
|
-
|
|
3142
|
-
# Lockup voting cats for all wallets
|
|
3143
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3144
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dc_1, action_scope, fee=base_fee)
|
|
3145
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3146
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3147
|
-
)
|
|
3148
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3149
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3150
|
-
|
|
3151
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3152
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dc_2, action_scope, fee=base_fee)
|
|
3153
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3154
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3155
|
-
)
|
|
3156
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3157
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3158
|
-
|
|
3159
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3160
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dc_3, action_scope, fee=base_fee)
|
|
3161
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3162
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3163
|
-
)
|
|
3164
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3165
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3166
|
-
|
|
3167
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3168
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dc_4, action_scope, fee=base_fee)
|
|
3169
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3170
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3171
|
-
)
|
|
3172
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3173
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3174
|
-
|
|
3175
|
-
async with dao_cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3176
|
-
await dao_cat_wallet_0.enter_dao_cat_voting_mode(dc_5, action_scope, fee=base_fee)
|
|
3177
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3178
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3179
|
-
)
|
|
3180
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3181
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3182
|
-
|
|
3183
|
-
await time_out_assert(10, dao_cat_wallet_0.get_confirmed_balance, dc_1 + dc_2 + dc_3 + dc_4 + dc_5)
|
|
3184
|
-
|
|
3185
|
-
# Create funding spend so the treasury holds some XCH
|
|
3186
|
-
xch_funds = uint64(500000)
|
|
3187
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3188
|
-
await dao_wallet_0.create_add_funds_to_treasury_spend(xch_funds, action_scope)
|
|
3189
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3190
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3191
|
-
)
|
|
3192
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3193
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3194
|
-
|
|
3195
|
-
# Check that the funding spend is recognized by all wallets
|
|
3196
|
-
await time_out_assert(10, dao_wallet_0.get_balance_by_asset_type, xch_funds)
|
|
3197
|
-
|
|
3198
|
-
# Create Proposals
|
|
3199
|
-
recipient_puzzle_hash = await wallet_2.get_new_puzzlehash()
|
|
3200
|
-
proposal_amount_1 = uint64(9998)
|
|
3201
|
-
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
|
3202
|
-
treasury_id,
|
|
3203
|
-
[recipient_puzzle_hash],
|
|
3204
|
-
[proposal_amount_1],
|
|
3205
|
-
[None],
|
|
3206
|
-
)
|
|
3207
|
-
|
|
3208
|
-
vote_1 = uint64(120000)
|
|
3209
|
-
vote_2 = uint64(150000)
|
|
3210
|
-
|
|
3211
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3212
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, vote_1, fee=base_fee)
|
|
3213
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3214
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3215
|
-
)
|
|
3216
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3217
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3218
|
-
|
|
3219
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 1
|
|
3220
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == vote_1
|
|
3221
|
-
assert dao_wallet_0.dao_info.proposals_list[0].timer_coin is not None
|
|
3222
|
-
prop_0 = dao_wallet_0.dao_info.proposals_list[0]
|
|
3223
|
-
|
|
3224
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3225
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, vote_2, fee=base_fee)
|
|
3226
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3227
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3228
|
-
)
|
|
3229
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3230
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3231
|
-
|
|
3232
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 2
|
|
3233
|
-
assert dao_wallet_0.dao_info.proposals_list[1].amount_voted == vote_2
|
|
3234
|
-
|
|
3235
|
-
vote_3 = uint64(30000)
|
|
3236
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3237
|
-
await dao_wallet_0.generate_proposal_vote_spend(prop_0.proposal_id, vote_3, True, action_scope)
|
|
3238
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3239
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3240
|
-
)
|
|
3241
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3242
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3243
|
-
|
|
3244
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == vote_1 + vote_3
|
|
3245
|
-
|
|
3246
|
-
vote_4 = uint64(60000)
|
|
3247
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3248
|
-
await dao_wallet_0.generate_proposal_vote_spend(prop_0.proposal_id, vote_4, True, action_scope)
|
|
3249
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3250
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3251
|
-
)
|
|
3252
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3253
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3254
|
-
|
|
3255
|
-
assert dao_wallet_0.dao_info.proposals_list[0].amount_voted == vote_1 + vote_3 + vote_4
|
|
3256
|
-
|
|
3257
|
-
vote_5 = uint64(1)
|
|
3258
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3259
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, vote_5, fee=base_fee)
|
|
3260
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3261
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3262
|
-
)
|
|
3263
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3264
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3265
|
-
|
|
3266
|
-
assert len(dao_wallet_0.dao_info.proposals_list) == 3
|
|
3267
|
-
assert dao_wallet_0.dao_info.proposals_list[2].amount_voted == vote_5
|
|
3268
|
-
prop_2 = dao_wallet_0.dao_info.proposals_list[2]
|
|
3269
|
-
|
|
3270
|
-
vote_6 = uint64(20000)
|
|
3271
|
-
for i in range(10):
|
|
3272
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3273
|
-
await dao_wallet_0.generate_proposal_vote_spend(prop_2.proposal_id, vote_6, True, action_scope)
|
|
3274
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3275
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3276
|
-
)
|
|
3277
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3278
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3279
|
-
|
|
3280
|
-
assert dao_wallet_0.dao_info.proposals_list[2].amount_voted == 200001
|
|
3281
|
-
|
|
3282
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3283
|
-
await dao_wallet_0.create_proposal_close_spend(prop_0.proposal_id, action_scope)
|
|
3284
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3285
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3286
|
-
)
|
|
3287
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3288
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3289
|
-
|
|
3290
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3291
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, fee=base_fee)
|
|
3292
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3293
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3294
|
-
)
|
|
3295
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3296
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3297
|
-
|
|
3298
|
-
assert dao_wallet_0.dao_info.proposals_list[3].amount_voted == 210000
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
@pytest.mark.limit_consensus_modes(reason="does not depend on consensus rules")
|
|
3302
|
-
@pytest.mark.parametrize(
|
|
3303
|
-
"trusted",
|
|
3304
|
-
[True, False],
|
|
3305
|
-
)
|
|
3306
|
-
@pytest.mark.anyio
|
|
3307
|
-
async def test_dao_resync(self_hostname: str, two_wallet_nodes: OldSimulatorsAndWallets, trusted: bool) -> None:
|
|
3308
|
-
full_nodes, wallets, _ = two_wallet_nodes
|
|
3309
|
-
full_node_api = full_nodes[0]
|
|
3310
|
-
full_node_server = full_node_api.server
|
|
3311
|
-
wallet_node_0, server_0 = wallets[0]
|
|
3312
|
-
wallet_node_1, server_1 = wallets[1]
|
|
3313
|
-
wallet_api_0 = WalletRpcApi(wallet_node_0)
|
|
3314
|
-
wallet_api_1 = WalletRpcApi(wallet_node_1)
|
|
3315
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
3316
|
-
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
|
|
3317
|
-
ph = await wallet_0.get_new_puzzlehash()
|
|
3318
|
-
ph_1 = await wallet_1.get_new_puzzlehash()
|
|
3319
|
-
|
|
3320
|
-
if trusted:
|
|
3321
|
-
wallet_node_0.config["trusted_peers"] = {
|
|
3322
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
3323
|
-
}
|
|
3324
|
-
wallet_node_1.config["trusted_peers"] = {
|
|
3325
|
-
full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
|
|
3326
|
-
}
|
|
3327
|
-
else:
|
|
3328
|
-
wallet_node_0.config["trusted_peers"] = {}
|
|
3329
|
-
wallet_node_1.config["trusted_peers"] = {}
|
|
3330
|
-
|
|
3331
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
3332
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
3333
|
-
|
|
3334
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
|
|
3335
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph_1))
|
|
3336
|
-
|
|
3337
|
-
funds = calculate_pool_reward(uint32(1)) + calculate_base_farmer_reward(uint32(1))
|
|
3338
|
-
|
|
3339
|
-
await time_out_assert(20, wallet_0.get_confirmed_balance, funds)
|
|
3340
|
-
await time_out_assert(20, full_node_api.wallet_is_synced, True, wallet_node_0)
|
|
3341
|
-
|
|
3342
|
-
cat_amt = 2000
|
|
3343
|
-
dao_rules = DAORules(
|
|
3344
|
-
proposal_timelock=uint64(10),
|
|
3345
|
-
soft_close_length=uint64(5),
|
|
3346
|
-
attendance_required=uint64(1000), # 10%
|
|
3347
|
-
pass_percentage=uint64(5100), # 51%
|
|
3348
|
-
self_destruct_length=uint64(20),
|
|
3349
|
-
oracle_spend_delay=uint64(10),
|
|
3350
|
-
proposal_minimum_amount=uint64(1),
|
|
3351
|
-
)
|
|
3352
|
-
|
|
3353
|
-
fee = uint64(10)
|
|
3354
|
-
fee_for_cat = uint64(20)
|
|
3355
|
-
async with wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3356
|
-
dao_wallet_0 = await DAOWallet.create_new_dao_and_wallet(
|
|
3357
|
-
wallet_node_0.wallet_state_manager,
|
|
3358
|
-
wallet_0,
|
|
3359
|
-
uint64(cat_amt * 2),
|
|
3360
|
-
dao_rules,
|
|
3361
|
-
action_scope=action_scope,
|
|
3362
|
-
fee=fee,
|
|
3363
|
-
fee_for_cat=fee_for_cat,
|
|
3364
|
-
)
|
|
3365
|
-
|
|
3366
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3367
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3368
|
-
)
|
|
3369
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3370
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
3371
|
-
|
|
3372
|
-
treasury_id = dao_wallet_0.dao_info.treasury_id
|
|
3373
|
-
|
|
3374
|
-
# get the cat wallets
|
|
3375
|
-
cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.cat_wallet_id]
|
|
3376
|
-
# dao_cat_wallet_0 = dao_wallet_0.wallet_state_manager.wallets[dao_wallet_0.dao_info.dao_cat_wallet_id]
|
|
3377
|
-
|
|
3378
|
-
# Create the other user's wallet from the treasury id
|
|
3379
|
-
dao_wallet_1 = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
3380
|
-
wallet_node_1.wallet_state_manager, wallet_1, treasury_id
|
|
3381
|
-
)
|
|
3382
|
-
assert dao_wallet_0.dao_info.treasury_id == dao_wallet_1.dao_info.treasury_id
|
|
3383
|
-
|
|
3384
|
-
# Get the cat wallets for wallet_1
|
|
3385
|
-
cat_wallet_1 = dao_wallet_1.wallet_state_manager.wallets[dao_wallet_1.dao_info.cat_wallet_id]
|
|
3386
|
-
|
|
3387
|
-
# Send some cats to the dao_cat lockup
|
|
3388
|
-
dao_cat_amt = uint64(100)
|
|
3389
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3390
|
-
await dao_wallet_0.enter_dao_cat_voting_mode(dao_cat_amt, action_scope)
|
|
3391
|
-
|
|
3392
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3393
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3394
|
-
)
|
|
3395
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3396
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3397
|
-
|
|
3398
|
-
# send some cats from wallet_0 to wallet_1 so we can test voting
|
|
3399
|
-
async with cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3400
|
-
await cat_wallet_0.generate_signed_transaction([cat_amt], [ph_1], action_scope)
|
|
3401
|
-
|
|
3402
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3403
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3404
|
-
)
|
|
3405
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3406
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=30)
|
|
3407
|
-
|
|
3408
|
-
await time_out_assert(10, cat_wallet_1.get_confirmed_balance, cat_amt)
|
|
3409
|
-
|
|
3410
|
-
recipient_puzzle_hash = await wallet_1.get_new_puzzlehash()
|
|
3411
|
-
proposal_amount_1 = uint64(9998)
|
|
3412
|
-
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
|
3413
|
-
treasury_id,
|
|
3414
|
-
[recipient_puzzle_hash],
|
|
3415
|
-
[proposal_amount_1],
|
|
3416
|
-
[None],
|
|
3417
|
-
)
|
|
3418
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3419
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope, uint64(10))
|
|
3420
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3421
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3422
|
-
)
|
|
3423
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3424
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
3425
|
-
|
|
3426
|
-
# make another proposal spending all the dao_cats
|
|
3427
|
-
xch_proposal_inner = generate_simple_proposal_innerpuz(
|
|
3428
|
-
treasury_id,
|
|
3429
|
-
[recipient_puzzle_hash],
|
|
3430
|
-
[proposal_amount_1],
|
|
3431
|
-
[None],
|
|
3432
|
-
)
|
|
3433
|
-
async with dao_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
|
|
3434
|
-
await dao_wallet_0.generate_new_proposal(xch_proposal_inner, action_scope)
|
|
3435
|
-
await full_node_api.wait_transaction_records_entered_mempool(
|
|
3436
|
-
records=action_scope.side_effects.transactions, timeout=60
|
|
3437
|
-
)
|
|
3438
|
-
await full_node_api.process_all_wallet_transactions(wallet_0, timeout=60)
|
|
3439
|
-
await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=30)
|
|
3440
|
-
|
|
3441
|
-
# set flag to reset wallet sync data on start
|
|
3442
|
-
await wallet_api_0.set_wallet_resync_on_startup({"enable": True})
|
|
3443
|
-
fingerprint_0 = wallet_node_0.logged_in_fingerprint
|
|
3444
|
-
await wallet_api_1.set_wallet_resync_on_startup({"enable": True})
|
|
3445
|
-
fingerprint_1 = wallet_node_1.logged_in_fingerprint
|
|
3446
|
-
# Delete tx records
|
|
3447
|
-
await wallet_node_0.wallet_state_manager.tx_store.rollback_to_block(0)
|
|
3448
|
-
wallet_node_0._close()
|
|
3449
|
-
await wallet_node_0._await_closed()
|
|
3450
|
-
wallet_node_1._close()
|
|
3451
|
-
await wallet_node_1._await_closed()
|
|
3452
|
-
wallet_node_0.config["database_path"] = "wallet/db/blockchain_wallet_v2_test_1_CHALLENGE_KEY.sqlite"
|
|
3453
|
-
wallet_node_1.config["database_path"] = "wallet/db/blockchain_wallet_v2_test_2_CHALLENGE_KEY.sqlite"
|
|
3454
|
-
# Start resync
|
|
3455
|
-
await wallet_node_0._start_with_fingerprint(fingerprint_0)
|
|
3456
|
-
await wallet_node_1._start_with_fingerprint(fingerprint_1)
|
|
3457
|
-
await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
3458
|
-
await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
|
|
3459
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
3460
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=20)
|
|
3461
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_1, timeout=20)
|
|
3462
|
-
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
|
|
3463
|
-
|
|
3464
|
-
assert len(await wallet_node_0.wallet_state_manager.get_all_wallet_info_entries()) == 1
|
|
3465
|
-
|
|
3466
|
-
new_dao_wallet = await DAOWallet.create_new_dao_wallet_for_existing_dao(
|
|
3467
|
-
wallet_node_0.wallet_state_manager,
|
|
3468
|
-
wallet_0,
|
|
3469
|
-
treasury_id,
|
|
3470
|
-
)
|
|
3471
|
-
|
|
3472
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
3473
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=20)
|
|
3474
|
-
assert len(await wallet_node_0.wallet_state_manager.get_all_wallet_info_entries()) == 4
|
|
3475
|
-
new_cat_wallet = new_dao_wallet.wallet_state_manager.wallets[new_dao_wallet.dao_info.cat_wallet_id]
|
|
3476
|
-
new_dao_cat_wallet = new_dao_wallet.wallet_state_manager.wallets[new_dao_wallet.dao_info.dao_cat_wallet_id]
|
|
3477
|
-
|
|
3478
|
-
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(puzzle_hash_0))
|
|
3479
|
-
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node_0, timeout=20)
|
|
3480
|
-
|
|
3481
|
-
# Check the new wallets have the right balances
|
|
3482
|
-
await time_out_assert(20, new_cat_wallet.get_confirmed_balance, cat_amt - dao_cat_amt)
|
|
3483
|
-
await time_out_assert(20, new_dao_cat_wallet.get_confirmed_balance, dao_cat_amt)
|
|
3484
|
-
|
|
3485
|
-
# Check the proposals are found and accurate
|
|
3486
|
-
assert len(new_dao_wallet.dao_info.proposals_list) == 2
|
|
3487
|
-
assert new_dao_wallet.dao_info.proposals_list[0].yes_votes == 10
|
|
3488
|
-
assert new_dao_wallet.dao_info.proposals_list[1].yes_votes == 100
|