chia-blockchain 2.5.4rc2__py3-none-any.whl → 2.5.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/_tests/blockchain/blockchain_test_utils.py +2 -3
- chia/_tests/blockchain/test_augmented_chain.py +2 -3
- chia/_tests/blockchain/test_blockchain.py +261 -44
- chia/_tests/blockchain/test_blockchain_transactions.py +4 -3
- chia/_tests/blockchain/test_build_chains.py +197 -1
- chia/_tests/blockchain/test_get_block_generator.py +1 -1
- chia/_tests/blockchain/test_lookup_fork_chain.py +1 -1
- chia/_tests/clvm/benchmark_costs.py +1 -1
- chia/_tests/clvm/coin_store.py +3 -4
- chia/_tests/clvm/test_message_conditions.py +2 -2
- chia/_tests/clvm/test_puzzle_compression.py +2 -3
- chia/_tests/clvm/test_puzzles.py +1 -2
- chia/_tests/clvm/test_singletons.py +2 -3
- chia/_tests/clvm/test_spend_sim.py +7 -7
- chia/_tests/cmds/cmd_test_utils.py +30 -25
- chia/_tests/cmds/test_dev_gh.py +1 -1
- chia/_tests/cmds/test_farm_cmd.py +1 -1
- chia/_tests/cmds/test_show.py +1 -2
- chia/_tests/cmds/wallet/test_did.py +101 -56
- chia/_tests/cmds/wallet/test_nft.py +109 -84
- chia/_tests/cmds/wallet/test_notifications.py +1 -1
- chia/_tests/cmds/wallet/test_offer.toffer +1 -1
- chia/_tests/cmds/wallet/test_vcs.py +8 -8
- chia/_tests/cmds/wallet/test_wallet.py +100 -46
- chia/_tests/conftest.py +31 -20
- chia/_tests/connection_utils.py +1 -1
- chia/_tests/core/consensus/stores/__init__.py +0 -0
- chia/_tests/core/consensus/stores/test_coin_store_protocol.py +40 -0
- chia/_tests/core/consensus/test_block_creation.py +2 -31
- chia/_tests/core/consensus/test_pot_iterations.py +38 -3
- chia/_tests/core/custom_types/test_proof_of_space.py +154 -26
- chia/_tests/core/custom_types/test_spend_bundle.py +2 -3
- chia/_tests/core/daemon/test_daemon.py +80 -0
- chia/_tests/core/data_layer/test_data_layer.py +1 -1
- chia/_tests/core/data_layer/test_data_layer_util.py +1 -1
- chia/_tests/core/data_layer/test_data_rpc.py +14 -10
- chia/_tests/core/data_layer/test_data_store.py +5 -5
- chia/_tests/core/farmer/test_farmer_api.py +2 -2
- chia/_tests/core/full_node/full_sync/test_full_sync.py +446 -406
- chia/_tests/core/full_node/ram_db.py +3 -1
- chia/_tests/core/full_node/stores/test_block_store.py +28 -16
- chia/_tests/core/full_node/stores/test_coin_store.py +277 -185
- chia/_tests/core/full_node/stores/test_full_node_store.py +11 -4
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/test_address_manager.py +200 -27
- chia/_tests/core/full_node/test_block_height_map.py +2 -2
- chia/_tests/core/full_node/test_conditions.py +7 -6
- chia/_tests/core/full_node/test_full_node.py +456 -40
- chia/_tests/core/full_node/test_generator_tools.py +32 -2
- chia/_tests/core/full_node/test_hint_management.py +1 -1
- chia/_tests/core/full_node/test_node_load.py +20 -21
- chia/_tests/core/full_node/test_performance.py +3 -4
- chia/_tests/core/full_node/test_prev_tx_block.py +43 -0
- chia/_tests/core/full_node/test_subscriptions.py +1 -2
- chia/_tests/core/full_node/test_transactions.py +9 -5
- chia/_tests/core/full_node/test_tx_processing_queue.py +1 -2
- chia/_tests/core/large_block.py +1 -2
- chia/_tests/core/make_block_generator.py +3 -4
- chia/_tests/core/mempool/test_mempool.py +36 -86
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
- chia/_tests/core/mempool/test_mempool_item_queries.py +1 -3
- chia/_tests/core/mempool/test_mempool_manager.py +529 -69
- chia/_tests/core/mempool/test_mempool_performance.py +3 -2
- chia/_tests/core/mempool/test_singleton_fast_forward.py +61 -132
- chia/_tests/core/server/flood.py +1 -1
- chia/_tests/core/server/test_dos.py +1 -1
- chia/_tests/core/server/test_node_discovery.py +41 -27
- chia/_tests/core/server/test_rate_limits.py +1 -1
- chia/_tests/core/server/test_server.py +1 -1
- chia/_tests/core/services/test_services.py +5 -5
- chia/_tests/core/ssl/test_ssl.py +1 -1
- chia/_tests/core/test_cost_calculation.py +6 -6
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_crawler_rpc.py +1 -1
- chia/_tests/core/test_db_conversion.py +3 -1
- chia/_tests/core/test_db_validation.py +5 -3
- chia/_tests/core/test_farmer_harvester_rpc.py +15 -15
- chia/_tests/core/test_filter.py +4 -1
- chia/_tests/core/test_full_node_rpc.py +99 -82
- chia/_tests/core/test_program.py +2 -2
- chia/_tests/core/util/test_block_cache.py +1 -1
- chia/_tests/core/util/test_keychain.py +2 -2
- chia/_tests/core/util/test_lockfile.py +1 -1
- chia/_tests/core/util/test_log_exceptions.py +5 -5
- chia/_tests/core/util/test_streamable.py +81 -22
- chia/_tests/db/test_db_wrapper.py +1 -3
- chia/_tests/environments/wallet.py +5 -5
- chia/_tests/farmer_harvester/test_farmer.py +9 -7
- chia/_tests/farmer_harvester/test_farmer_harvester.py +11 -4
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +15 -9
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -2
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +7 -5
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
- chia/_tests/generator/test_compression.py +1 -2
- chia/_tests/generator/test_rom.py +8 -4
- chia/_tests/plot_sync/test_plot_sync.py +3 -3
- chia/_tests/plot_sync/test_receiver.py +3 -3
- chia/_tests/plot_sync/test_sender.py +1 -1
- chia/_tests/plot_sync/test_sync_simulated.py +3 -3
- chia/_tests/plot_sync/util.py +2 -2
- chia/_tests/pools/test_pool_cmdline.py +48 -21
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +2 -3
- chia/_tests/pools/test_pool_rpc.py +237 -105
- chia/_tests/pools/test_pool_wallet.py +11 -2
- chia/_tests/pools/test_wallet_pool_store.py +5 -4
- chia/_tests/rpc/test_rpc_client.py +1 -1
- chia/_tests/simulation/test_simulation.py +13 -8
- chia/_tests/simulation/test_simulator.py +2 -2
- chia/_tests/timelord/test_new_peak.py +191 -47
- chia/_tests/timelord/test_timelord.py +1 -1
- chia/_tests/tools/test_full_sync.py +0 -2
- chia/_tests/tools/test_run_block.py +3 -1
- chia/_tests/util/benchmark_cost.py +3 -3
- chia/_tests/util/benchmarks.py +2 -2
- chia/_tests/util/blockchain.py +11 -5
- chia/_tests/util/blockchain_mock.py +1 -4
- chia/_tests/util/coin_store.py +29 -0
- chia/_tests/util/constants.py +2 -18
- chia/_tests/util/full_sync.py +3 -3
- chia/_tests/util/generator_tools_testing.py +2 -3
- chia/_tests/util/key_tool.py +2 -3
- chia/_tests/util/misc.py +33 -31
- chia/_tests/util/network_protocol_data.py +19 -17
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +3 -1
- chia/_tests/util/run_block.py +2 -2
- chia/_tests/util/setup_nodes.py +7 -7
- chia/_tests/util/spend_sim.py +47 -55
- chia/_tests/util/test_condition_tools.py +5 -4
- chia/_tests/util/test_config.py +2 -2
- chia/_tests/util/test_dump_keyring.py +1 -1
- chia/_tests/util/test_full_block_utils.py +12 -14
- chia/_tests/util/test_misc.py +2 -2
- chia/_tests/util/test_paginator.py +4 -4
- chia/_tests/util/test_priority_mutex.py +2 -2
- chia/_tests/util/test_replace_str_to_bytes.py +15 -5
- chia/_tests/util/test_ssl_check.py +1 -1
- chia/_tests/util/test_testnet_overrides.py +13 -3
- chia/_tests/util/time_out_assert.py +4 -2
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -2
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +352 -432
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +3 -6
- chia/_tests/wallet/cat_wallet/test_trades.py +53 -77
- chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -1
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +3 -3
- chia/_tests/wallet/clawback/test_clawback_metadata.py +4 -2
- chia/_tests/wallet/conftest.py +11 -12
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +11 -4
- chia/_tests/wallet/db_wallet/test_dl_offers.py +433 -130
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +3 -3
- chia/_tests/wallet/did_wallet/test_did.py +2132 -2000
- chia/_tests/wallet/nft_wallet/config.py +1 -1
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1610 -742
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +486 -907
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +4 -4
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +517 -294
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +133 -62
- chia/_tests/wallet/rpc/test_wallet_rpc.py +495 -265
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +10 -6
- chia/_tests/wallet/sync/test_wallet_sync.py +89 -60
- chia/_tests/wallet/test_clvm_casts.py +88 -0
- chia/_tests/wallet/test_coin_management.py +1 -1
- chia/_tests/wallet/test_coin_selection.py +1 -1
- chia/_tests/wallet/test_conditions.py +1 -1
- chia/_tests/wallet/test_new_wallet_protocol.py +13 -11
- chia/_tests/wallet/test_notifications.py +5 -3
- chia/_tests/wallet/test_sign_coin_spends.py +6 -6
- chia/_tests/wallet/test_signer_protocol.py +13 -12
- chia/_tests/wallet/test_singleton.py +1 -1
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +5 -7
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +108 -29
- chia/_tests/wallet/test_wallet_action_scope.py +9 -2
- chia/_tests/wallet/test_wallet_blockchain.py +2 -3
- chia/_tests/wallet/test_wallet_key_val_store.py +1 -2
- chia/_tests/wallet/test_wallet_node.py +2 -4
- chia/_tests/wallet/test_wallet_retry.py +4 -2
- chia/_tests/wallet/test_wallet_state_manager.py +191 -5
- chia/_tests/wallet/test_wallet_test_framework.py +1 -1
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +8 -8
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -12
- chia/_tests/wallet/wallet_block_tools.py +6 -6
- chia/_tests/weight_proof/test_weight_proof.py +10 -48
- chia/apis.py +1 -1
- chia/cmds/beta.py +1 -1
- chia/cmds/chia.py +9 -9
- chia/cmds/cmd_classes.py +12 -11
- chia/cmds/cmd_helpers.py +1 -1
- chia/cmds/cmds_util.py +12 -9
- chia/cmds/coin_funcs.py +2 -2
- chia/cmds/configure.py +2 -2
- chia/cmds/data.py +0 -2
- chia/cmds/data_funcs.py +1 -1
- chia/cmds/db_validate_func.py +1 -2
- chia/cmds/dev/__init__.py +0 -0
- chia/cmds/dev/data.py +273 -0
- chia/cmds/{gh.py → dev/gh.py} +5 -5
- chia/cmds/dev/main.py +22 -0
- chia/cmds/dev/mempool.py +78 -0
- chia/cmds/dev/mempool_funcs.py +63 -0
- chia/cmds/farm_funcs.py +5 -4
- chia/cmds/init_funcs.py +11 -11
- chia/cmds/keys.py +2 -2
- chia/cmds/keys_funcs.py +4 -4
- chia/cmds/netspace_funcs.py +1 -1
- chia/cmds/peer_funcs.py +2 -2
- chia/cmds/plotnft_funcs.py +72 -26
- chia/cmds/rpc.py +1 -1
- chia/cmds/show_funcs.py +5 -5
- chia/cmds/signer.py +8 -7
- chia/cmds/sim_funcs.py +8 -9
- chia/cmds/wallet.py +2 -2
- chia/cmds/wallet_funcs.py +165 -131
- chia/{util → consensus}/augmented_chain.py +1 -2
- chia/consensus/block_body_validation.py +54 -40
- chia/consensus/block_creation.py +42 -76
- chia/consensus/block_header_validation.py +32 -26
- chia/consensus/block_record.py +0 -3
- chia/consensus/blockchain.py +23 -32
- chia/consensus/blockchain_interface.py +1 -5
- chia/consensus/check_time_locks.py +57 -0
- chia/consensus/coin_store_protocol.py +151 -0
- chia/consensus/coinbase.py +0 -6
- chia/consensus/condition_costs.py +4 -0
- chia/{util → consensus}/condition_tools.py +4 -5
- chia/consensus/cost_calculator.py +1 -1
- chia/consensus/default_constants.py +32 -9
- chia/consensus/deficit.py +1 -3
- chia/consensus/difficulty_adjustment.py +1 -2
- chia/consensus/find_fork_point.py +1 -3
- chia/consensus/full_block_to_block_record.py +1 -6
- chia/{util → consensus}/generator_tools.py +1 -3
- chia/consensus/get_block_challenge.py +30 -7
- chia/consensus/make_sub_epoch_summary.py +1 -5
- chia/consensus/multiprocess_validation.py +21 -20
- chia/consensus/pot_iterations.py +74 -13
- chia/{util → consensus}/prev_transaction_block.py +1 -1
- chia/consensus/vdf_info_computation.py +1 -3
- chia/daemon/keychain_proxy.py +5 -5
- chia/daemon/server.py +22 -5
- chia/data_layer/data_layer.py +92 -51
- chia/{rpc → data_layer}/data_layer_rpc_api.py +1 -1
- chia/{rpc → data_layer}/data_layer_rpc_util.py +3 -6
- chia/data_layer/data_layer_util.py +4 -6
- chia/data_layer/data_layer_wallet.py +42 -69
- chia/data_layer/dl_wallet_store.py +12 -6
- chia/data_layer/download_data.py +3 -3
- chia/data_layer/s3_plugin_service.py +0 -1
- chia/farmer/farmer.py +3 -4
- chia/farmer/farmer_api.py +11 -7
- chia/{rpc → farmer}/farmer_rpc_client.py +1 -1
- chia/full_node/block_height_map.py +7 -6
- chia/full_node/block_store.py +5 -7
- chia/full_node/bundle_tools.py +1 -2
- chia/full_node/coin_store.py +153 -124
- chia/{types → full_node}/eligible_coin_spends.py +39 -70
- chia/full_node/fee_estimator.py +1 -1
- chia/full_node/fee_estimator_interface.py +0 -8
- chia/full_node/fee_tracker.py +25 -25
- chia/full_node/full_node.py +70 -53
- chia/full_node/full_node_api.py +57 -40
- chia/{rpc → full_node}/full_node_rpc_api.py +87 -8
- chia/{rpc → full_node}/full_node_rpc_client.py +7 -6
- chia/full_node/full_node_store.py +23 -8
- chia/full_node/mempool.py +206 -53
- chia/full_node/mempool_check_conditions.py +20 -63
- chia/full_node/mempool_manager.py +47 -45
- chia/full_node/subscriptions.py +1 -3
- chia/full_node/tx_processing_queue.py +50 -3
- chia/full_node/weight_proof.py +46 -37
- chia/harvester/harvester.py +1 -1
- chia/harvester/harvester_api.py +22 -7
- chia/introducer/introducer.py +1 -1
- chia/introducer/introducer_api.py +1 -1
- chia/plot_sync/exceptions.py +1 -1
- chia/plot_sync/receiver.py +1 -1
- chia/plot_sync/sender.py +2 -2
- chia/pools/pool_puzzles.py +13 -18
- chia/pools/pool_wallet.py +23 -46
- chia/protocols/farmer_protocol.py +11 -3
- chia/protocols/full_node_protocol.py +1 -4
- chia/protocols/harvester_protocol.py +3 -3
- chia/protocols/pool_protocol.py +1 -2
- chia/protocols/shared_protocol.py +3 -3
- chia/protocols/timelord_protocol.py +1 -3
- chia/protocols/wallet_protocol.py +3 -3
- chia/rpc/rpc_client.py +7 -8
- chia/rpc/rpc_server.py +3 -3
- chia/rpc/util.py +3 -1
- chia/seeder/crawler.py +1 -1
- chia/seeder/crawler_api.py +1 -1
- chia/seeder/dns_server.py +2 -0
- chia/seeder/start_crawler.py +3 -3
- chia/server/address_manager.py +286 -38
- chia/server/address_manager_store.py +0 -215
- chia/{types → server}/aliases.py +7 -7
- chia/server/api_protocol.py +1 -1
- chia/server/chia_policy.py +1 -1
- chia/server/node_discovery.py +76 -113
- chia/server/rate_limits.py +1 -1
- chia/server/resolve_peer_info.py +43 -0
- chia/server/server.py +5 -5
- chia/server/start_data_layer.py +4 -4
- chia/server/start_farmer.py +5 -4
- chia/server/start_full_node.py +5 -4
- chia/server/start_harvester.py +7 -5
- chia/server/start_introducer.py +2 -2
- chia/server/start_service.py +1 -1
- chia/server/start_timelord.py +7 -5
- chia/server/start_wallet.py +7 -5
- chia/server/ws_connection.py +1 -1
- chia/simulator/add_blocks_in_batches.py +2 -2
- chia/simulator/block_tools.py +245 -201
- chia/simulator/full_node_simulator.py +38 -10
- chia/simulator/setup_services.py +12 -12
- chia/simulator/simulator_full_node_rpc_api.py +2 -2
- chia/simulator/simulator_full_node_rpc_client.py +2 -2
- chia/simulator/simulator_test_tools.py +2 -2
- chia/simulator/start_simulator.py +1 -1
- chia/simulator/wallet_tools.py +10 -18
- chia/ssl/create_ssl.py +1 -1
- chia/timelord/iters_from_block.py +14 -14
- chia/timelord/timelord.py +15 -11
- chia/timelord/timelord_api.py +14 -2
- chia/timelord/timelord_state.py +20 -14
- chia/types/blockchain_format/program.py +53 -10
- chia/types/blockchain_format/proof_of_space.py +73 -19
- chia/types/coin_spend.py +3 -56
- chia/types/generator_types.py +28 -0
- chia/types/internal_mempool_item.py +1 -2
- chia/types/mempool_item.py +12 -7
- chia/types/unfinished_header_block.py +1 -2
- chia/types/validation_state.py +1 -2
- chia/types/weight_proof.py +1 -3
- chia/util/action_scope.py +3 -3
- chia/util/block_cache.py +1 -2
- chia/util/byte_types.py +1 -1
- chia/util/casts.py +21 -0
- chia/util/config.py +0 -37
- chia/util/db_wrapper.py +8 -1
- chia/util/errors.py +3 -2
- chia/util/initial-config.yaml +21 -5
- chia/util/keychain.py +6 -7
- chia/util/keyring_wrapper.py +5 -5
- chia/util/limited_semaphore.py +1 -1
- chia/util/priority_mutex.py +1 -1
- chia/util/streamable.py +63 -5
- chia/util/task_timing.py +1 -1
- chia/util/virtual_project_analysis.py +1 -1
- chia/wallet/cat_wallet/cat_info.py +7 -3
- chia/wallet/cat_wallet/cat_outer_puzzle.py +9 -5
- chia/wallet/cat_wallet/cat_utils.py +1 -1
- chia/wallet/cat_wallet/cat_wallet.py +44 -36
- chia/wallet/cat_wallet/lineage_store.py +7 -0
- chia/wallet/cat_wallet/r_cat_wallet.py +274 -0
- chia/wallet/conditions.py +5 -10
- chia/wallet/db_wallet/db_wallet_puzzles.py +4 -4
- chia/wallet/derivation_record.py +33 -0
- chia/wallet/derive_keys.py +3 -3
- chia/wallet/did_wallet/did_info.py +12 -3
- chia/wallet/did_wallet/did_wallet.py +132 -101
- chia/wallet/did_wallet/did_wallet_puzzles.py +9 -9
- chia/wallet/driver_protocol.py +3 -1
- chia/{types/spend_bundle.py → wallet/estimate_fees.py} +2 -7
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +5 -3
- chia/wallet/nft_wallet/nft_puzzle_utils.py +1 -1
- chia/wallet/nft_wallet/nft_wallet.py +69 -112
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +5 -3
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +6 -4
- chia/wallet/nft_wallet/transfer_program_puzzle.py +4 -2
- chia/wallet/nft_wallet/uncurry_nft.py +4 -6
- chia/wallet/notification_manager.py +2 -3
- chia/wallet/outer_puzzles.py +7 -2
- chia/wallet/puzzle_drivers.py +1 -1
- chia/wallet/puzzles/clawback/drivers.py +5 -4
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -1
- chia/wallet/puzzles/singleton_top_layer.py +2 -1
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +2 -1
- chia/wallet/puzzles/tails.py +1 -3
- chia/wallet/signer_protocol.py +5 -6
- chia/wallet/singleton.py +5 -4
- chia/wallet/singleton_record.py +1 -1
- chia/wallet/trade_manager.py +18 -20
- chia/wallet/trade_record.py +3 -6
- chia/wallet/trading/offer.py +12 -13
- chia/wallet/uncurried_puzzle.py +2 -2
- chia/wallet/util/compute_additions.py +58 -0
- chia/wallet/util/compute_hints.py +3 -3
- chia/wallet/util/compute_memos.py +4 -4
- chia/wallet/util/curry_and_treehash.py +2 -1
- chia/wallet/util/debug_spend_bundle.py +1 -1
- chia/wallet/util/merkle_tree.py +1 -1
- chia/wallet/util/peer_request_cache.py +1 -2
- chia/wallet/util/tx_config.py +3 -8
- chia/wallet/util/wallet_sync_utils.py +10 -5
- chia/wallet/util/wallet_types.py +1 -0
- chia/wallet/vc_wallet/cr_cat_drivers.py +17 -18
- chia/wallet/vc_wallet/cr_cat_wallet.py +30 -28
- chia/wallet/vc_wallet/cr_outer_puzzle.py +5 -3
- chia/wallet/vc_wallet/vc_drivers.py +50 -8
- chia/wallet/vc_wallet/vc_store.py +3 -5
- chia/wallet/vc_wallet/vc_wallet.py +15 -22
- chia/wallet/wallet.py +36 -46
- chia/wallet/wallet_action_scope.py +73 -4
- chia/wallet/wallet_blockchain.py +1 -3
- chia/wallet/wallet_interested_store.py +1 -1
- chia/wallet/wallet_nft_store.py +3 -3
- chia/wallet/wallet_node.py +17 -16
- chia/wallet/wallet_node_api.py +4 -5
- chia/wallet/wallet_pool_store.py +1 -1
- chia/wallet/wallet_protocol.py +2 -0
- chia/wallet/wallet_puzzle_store.py +1 -1
- chia/{rpc → wallet}/wallet_request_types.py +670 -81
- chia/{rpc → wallet}/wallet_rpc_api.py +735 -766
- chia/{rpc → wallet}/wallet_rpc_client.py +268 -420
- chia/wallet/wallet_singleton_store.py +8 -7
- chia/wallet/wallet_spend_bundle.py +4 -3
- chia/wallet/wallet_state_manager.py +320 -191
- chia/wallet/wallet_weight_proof_handler.py +1 -2
- chia/wallet/wsm_apis.py +98 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5.dist-info}/METADATA +7 -7
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5.dist-info}/RECORD +443 -436
- mozilla-ca/cacert.pem +3 -165
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +0 -145
- chia/cmds/dev.py +0 -18
- chia/types/blockchain_format/slots.py +0 -9
- chia/types/blockchain_format/sub_epoch_summary.py +0 -5
- chia/types/end_of_slot_bundle.py +0 -5
- chia/types/full_block.py +0 -5
- chia/types/header_block.py +0 -5
- chia/types/spend_bundle_conditions.py +0 -7
- chia/types/transaction_queue_entry.py +0 -56
- chia/types/unfinished_block.py +0 -5
- /chia/cmds/{installers.py → dev/installers.py} +0 -0
- /chia/cmds/{sim.py → dev/sim.py} +0 -0
- /chia/{util → cmds}/dump_keyring.py +0 -0
- /chia/{full_node → consensus}/signage_point.py +0 -0
- /chia/{rpc → data_layer}/data_layer_rpc_client.py +0 -0
- /chia/{rpc → farmer}/farmer_rpc_api.py +0 -0
- /chia/{util → full_node}/full_block_utils.py +0 -0
- /chia/{rpc → harvester}/harvester_rpc_api.py +0 -0
- /chia/{rpc → harvester}/harvester_rpc_client.py +0 -0
- /chia/{full_node → protocols}/fee_estimate.py +0 -0
- /chia/{server → protocols}/outbound_message.py +0 -0
- /chia/{rpc → seeder}/crawler_rpc_api.py +0 -0
- /chia/{util → simulator}/vdf_prover.py +0 -0
- /chia/{util → ssl}/ssl_check.py +0 -0
- /chia/{rpc → timelord}/timelord_rpc_api.py +0 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5.dist-info}/LICENSE +0 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.4rc2.dist-info → chia_blockchain-2.5.5.dist-info}/entry_points.txt +0 -0
|
@@ -5,31 +5,31 @@ from dataclasses import dataclass
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import Optional
|
|
7
7
|
|
|
8
|
+
import aiosqlite
|
|
8
9
|
import pytest
|
|
10
|
+
from chia_rs import CoinState, FullBlock, additions_and_removals, get_flags_for_height_and_constants
|
|
9
11
|
from chia_rs.sized_bytes import bytes32
|
|
10
12
|
from chia_rs.sized_ints import uint32, uint64
|
|
11
|
-
from clvm.casts import int_to_bytes
|
|
12
13
|
|
|
13
14
|
from chia._tests.blockchain.blockchain_test_utils import _validate_and_add_block
|
|
15
|
+
from chia._tests.util.coin_store import add_coin_records_to_db
|
|
14
16
|
from chia._tests.util.db_connection import DBConnection
|
|
15
|
-
from chia._tests.util.get_name_puzzle_conditions import get_name_puzzle_conditions
|
|
16
17
|
from chia._tests.util.misc import Marks, datacases
|
|
17
18
|
from chia.consensus.block_body_validation import ForkInfo
|
|
18
19
|
from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
|
|
19
20
|
from chia.consensus.blockchain import AddBlockResult, Blockchain
|
|
20
21
|
from chia.consensus.coinbase import create_farmer_coin, create_pool_coin
|
|
22
|
+
from chia.full_node.block_height_map import BlockHeightMap
|
|
21
23
|
from chia.full_node.block_store import BlockStore
|
|
22
24
|
from chia.full_node.coin_store import CoinStore
|
|
23
25
|
from chia.full_node.hint_store import HintStore
|
|
24
|
-
from chia.protocols.wallet_protocol import CoinState
|
|
25
26
|
from chia.simulator.block_tools import BlockTools, test_constants
|
|
26
27
|
from chia.simulator.wallet_tools import WalletTool
|
|
27
28
|
from chia.types.blockchain_format.coin import Coin
|
|
28
29
|
from chia.types.coin_record import CoinRecord
|
|
29
|
-
from chia.types.
|
|
30
|
-
from chia.
|
|
31
|
-
from chia.
|
|
32
|
-
from chia.util.generator_tools import tx_removals_and_additions
|
|
30
|
+
from chia.types.mempool_item import UnspentLineageInfo
|
|
31
|
+
from chia.util.casts import int_to_bytes
|
|
32
|
+
from chia.util.db_wrapper import DBWrapper2
|
|
33
33
|
from chia.util.hash import std_hash
|
|
34
34
|
|
|
35
35
|
constants = test_constants
|
|
@@ -98,75 +98,73 @@ async def test_basic_coin_store(db_version: int, softfork_height: uint32, bt: Bl
|
|
|
98
98
|
farmer_coin, pool_coin = get_future_reward_coins(block)
|
|
99
99
|
should_be_included.add(farmer_coin)
|
|
100
100
|
should_be_included.add(pool_coin)
|
|
101
|
-
if block.is_transaction_block():
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
101
|
+
if not block.is_transaction_block():
|
|
102
|
+
continue
|
|
103
|
+
if block.transactions_generator is not None:
|
|
104
|
+
assert block.transactions_info is not None
|
|
105
|
+
flags = get_flags_for_height_and_constants(block.height, bt.constants)
|
|
106
|
+
additions, removals = additions_and_removals(
|
|
107
|
+
bytes(block.transactions_generator), [], flags, bt.constants
|
|
108
|
+
)
|
|
109
|
+
tx_removals = [name for name, _ in removals]
|
|
110
|
+
tx_additions = [(addition.name(), addition, False) for addition, _ in additions]
|
|
111
|
+
else:
|
|
112
|
+
tx_removals, tx_additions = [], []
|
|
113
|
+
|
|
114
|
+
reward_coins = block.get_included_reward_coins()
|
|
115
|
+
assert set(reward_coins) == should_be_included_prev
|
|
116
|
+
|
|
117
|
+
assert block.foliage_transaction_block is not None
|
|
118
|
+
await coin_store.new_block(
|
|
119
|
+
block.height,
|
|
120
|
+
block.foliage_transaction_block.timestamp,
|
|
121
|
+
reward_coins,
|
|
122
|
+
tx_additions,
|
|
123
|
+
tx_removals,
|
|
124
|
+
)
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
if block.height != 0:
|
|
127
|
+
with pytest.raises(Exception):
|
|
120
128
|
await coin_store.new_block(
|
|
121
129
|
block.height,
|
|
122
130
|
block.foliage_transaction_block.timestamp,
|
|
123
|
-
|
|
131
|
+
reward_coins,
|
|
124
132
|
tx_additions,
|
|
125
133
|
tx_removals,
|
|
126
134
|
)
|
|
127
135
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
assert coin == record.coin
|
|
158
|
-
all_records.add(record)
|
|
159
|
-
|
|
160
|
-
db_records = await coin_store.get_coin_records(
|
|
161
|
-
[c.name() for c in list(should_be_included_prev) + tx_additions] + tx_removals
|
|
162
|
-
)
|
|
163
|
-
assert len(db_records) == len(should_be_included_prev) + len(tx_removals) + len(tx_additions)
|
|
164
|
-
assert len(db_records) == len(all_records)
|
|
165
|
-
for record in db_records:
|
|
166
|
-
assert record in all_records
|
|
136
|
+
all_records = set()
|
|
137
|
+
for expected_coin in should_be_included_prev:
|
|
138
|
+
# Check that the coinbase rewards are added
|
|
139
|
+
record = await coin_store.get_coin_record(expected_coin.name())
|
|
140
|
+
assert record is not None
|
|
141
|
+
assert not record.spent
|
|
142
|
+
assert record.coin == expected_coin
|
|
143
|
+
all_records.add(record)
|
|
144
|
+
for coin_name in tx_removals:
|
|
145
|
+
# Check that the removed coins are set to spent
|
|
146
|
+
record = await coin_store.get_coin_record(coin_name)
|
|
147
|
+
assert record is not None
|
|
148
|
+
assert record.spent
|
|
149
|
+
all_records.add(record)
|
|
150
|
+
for coin_id, coin, _ in tx_additions:
|
|
151
|
+
# Check that the added coins are added
|
|
152
|
+
record = await coin_store.get_coin_record(coin_id)
|
|
153
|
+
assert record is not None
|
|
154
|
+
assert not record.spent
|
|
155
|
+
assert coin == record.coin
|
|
156
|
+
all_records.add(record)
|
|
157
|
+
|
|
158
|
+
db_records = await coin_store.get_coin_records(
|
|
159
|
+
[c.name() for c in should_be_included_prev] + [coin_id for coin_id, _, _ in tx_additions] + tx_removals
|
|
160
|
+
)
|
|
161
|
+
assert len(db_records) == len(should_be_included_prev) + len(tx_removals) + len(tx_additions)
|
|
162
|
+
assert len(db_records) == len(all_records)
|
|
163
|
+
for record in db_records:
|
|
164
|
+
assert record in all_records
|
|
167
165
|
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
should_be_included_prev = should_be_included.copy()
|
|
167
|
+
should_be_included = set()
|
|
170
168
|
|
|
171
169
|
|
|
172
170
|
@pytest.mark.limit_consensus_modes(reason="save time")
|
|
@@ -179,39 +177,31 @@ async def test_set_spent(db_version: int, bt: BlockTools) -> None:
|
|
|
179
177
|
|
|
180
178
|
# Save/get block
|
|
181
179
|
for block in blocks:
|
|
182
|
-
if block.is_transaction_block():
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
block.foliage_transaction_block.timestamp,
|
|
191
|
-
block.get_included_reward_coins(),
|
|
192
|
-
additions,
|
|
193
|
-
removals,
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
coins = block.get_included_reward_coins()
|
|
197
|
-
records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
|
|
180
|
+
if not block.is_transaction_block():
|
|
181
|
+
continue
|
|
182
|
+
assert block.foliage_transaction_block is not None
|
|
183
|
+
await coin_store.new_block(
|
|
184
|
+
block.height, block.foliage_transaction_block.timestamp, block.get_included_reward_coins(), [], []
|
|
185
|
+
)
|
|
186
|
+
coins = block.get_included_reward_coins()
|
|
187
|
+
records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
|
|
198
188
|
|
|
199
|
-
|
|
189
|
+
await coin_store._set_spent([r.name for r in records if r is not None], block.height)
|
|
200
190
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
191
|
+
if len(records) > 0:
|
|
192
|
+
for r in records:
|
|
193
|
+
assert r is not None
|
|
194
|
+
assert (await coin_store.get_coin_record(r.name)) is not None
|
|
205
195
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
196
|
+
# Check that we can't spend a coin twice in DB
|
|
197
|
+
with pytest.raises(ValueError, match="Invalid operation to set spent"):
|
|
198
|
+
await coin_store._set_spent([r.name for r in records if r is not None], block.height)
|
|
209
199
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
200
|
+
records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
|
|
201
|
+
for record in records:
|
|
202
|
+
assert record is not None
|
|
203
|
+
assert record.spent
|
|
204
|
+
assert record.spent_block_index == block.height
|
|
215
205
|
|
|
216
206
|
|
|
217
207
|
@pytest.mark.limit_consensus_modes(reason="save time")
|
|
@@ -228,22 +218,12 @@ async def test_num_unspent(bt: BlockTools, db_version: int) -> None:
|
|
|
228
218
|
for block in blocks:
|
|
229
219
|
if not block.is_transaction_block():
|
|
230
220
|
continue
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
block.height,
|
|
238
|
-
block.foliage_transaction_block.timestamp,
|
|
239
|
-
block.get_included_reward_coins(),
|
|
240
|
-
additions,
|
|
241
|
-
removals,
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
expect_unspent += len(block.get_included_reward_coins())
|
|
245
|
-
assert await coin_store.num_unspent() == expect_unspent
|
|
246
|
-
test_excercised = expect_unspent > 0
|
|
221
|
+
assert block.foliage_transaction_block is not None
|
|
222
|
+
reward_coins = block.get_included_reward_coins()
|
|
223
|
+
await coin_store.new_block(block.height, block.foliage_transaction_block.timestamp, reward_coins, [], [])
|
|
224
|
+
expect_unspent += len(reward_coins)
|
|
225
|
+
assert await coin_store.num_unspent() == expect_unspent
|
|
226
|
+
test_excercised = expect_unspent > 0
|
|
247
227
|
|
|
248
228
|
assert test_excercised
|
|
249
229
|
|
|
@@ -260,48 +240,41 @@ async def test_rollback(db_version: int, bt: BlockTools) -> None:
|
|
|
260
240
|
all_coins: list[Coin] = []
|
|
261
241
|
|
|
262
242
|
for block in blocks:
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
spend_selected_coin = selected_coin is not None
|
|
279
|
-
if block.height != 0 and selected_coin is None:
|
|
280
|
-
# Select the first CoinRecord which will be spent at the next transaction block.
|
|
281
|
-
selected_coin = records[0]
|
|
282
|
-
await coin_store._set_spent([r.name for r in records[1:] if r is not None], block.height)
|
|
283
|
-
else:
|
|
284
|
-
await coin_store._set_spent([r.name for r in records if r is not None], block.height)
|
|
285
|
-
|
|
286
|
-
if spend_selected_coin:
|
|
287
|
-
assert selected_coin is not None
|
|
288
|
-
await coin_store._set_spent([selected_coin.name], block.height)
|
|
243
|
+
if not block.is_transaction_block():
|
|
244
|
+
continue
|
|
245
|
+
assert block.foliage_transaction_block is not None
|
|
246
|
+
reward_coins = block.get_included_reward_coins()
|
|
247
|
+
all_coins += reward_coins
|
|
248
|
+
await coin_store.new_block(block.height, block.foliage_transaction_block.timestamp, reward_coins, [], [])
|
|
249
|
+
records = [await coin_store.get_coin_record(coin.name()) for coin in reward_coins]
|
|
250
|
+
|
|
251
|
+
spend_selected_coin = selected_coin is not None
|
|
252
|
+
if block.height != 0 and selected_coin is None:
|
|
253
|
+
# Select the first CoinRecord which will be spent at the next transaction block.
|
|
254
|
+
selected_coin = records[0]
|
|
255
|
+
await coin_store._set_spent([r.name for r in records[1:] if r is not None], block.height)
|
|
256
|
+
else:
|
|
257
|
+
await coin_store._set_spent([r.name for r in records if r is not None], block.height)
|
|
289
258
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
259
|
+
if spend_selected_coin:
|
|
260
|
+
assert selected_coin is not None
|
|
261
|
+
await coin_store._set_spent([selected_coin.name], block.height)
|
|
262
|
+
|
|
263
|
+
records = [await coin_store.get_coin_record(coin.name()) for coin in reward_coins] # update coin records
|
|
264
|
+
for record in records:
|
|
265
|
+
assert record is not None
|
|
266
|
+
if (
|
|
267
|
+
selected_coin is not None
|
|
268
|
+
and selected_coin.name == record.name
|
|
269
|
+
and not selected_coin.confirmed_block_index < block.height
|
|
270
|
+
):
|
|
271
|
+
assert not record.spent
|
|
272
|
+
else:
|
|
273
|
+
assert record.spent
|
|
274
|
+
assert record.spent_block_index == block.height
|
|
302
275
|
|
|
303
|
-
|
|
304
|
-
|
|
276
|
+
if spend_selected_coin:
|
|
277
|
+
break
|
|
305
278
|
|
|
306
279
|
assert selected_coin is not None
|
|
307
280
|
reorg_index = selected_coin.confirmed_block_index
|
|
@@ -311,28 +284,29 @@ async def test_rollback(db_version: int, bt: BlockTools) -> None:
|
|
|
311
284
|
|
|
312
285
|
# The reorg will revert the creation and spend of many coins. It will also revert the spend (but not the
|
|
313
286
|
# creation) of the selected coin.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
assert selected_coin in
|
|
287
|
+
coin_changes = await coin_store.rollback_to_block(reorg_index)
|
|
288
|
+
changed_coins = {cr.coin for cr in coin_changes.values()}
|
|
289
|
+
assert selected_coin.coin in changed_coins
|
|
317
290
|
for coin_record in all_records:
|
|
318
291
|
assert coin_record is not None
|
|
319
292
|
if coin_record.confirmed_block_index > reorg_index:
|
|
320
|
-
assert coin_record.coin in
|
|
293
|
+
assert coin_record.coin in changed_coins
|
|
321
294
|
if coin_record.spent_block_index > reorg_index:
|
|
322
|
-
assert coin_record.coin in
|
|
295
|
+
assert coin_record.coin in changed_coins
|
|
323
296
|
|
|
324
297
|
for block in blocks:
|
|
325
|
-
if block.is_transaction_block():
|
|
326
|
-
|
|
327
|
-
|
|
298
|
+
if not block.is_transaction_block():
|
|
299
|
+
continue
|
|
300
|
+
reward_coins = block.get_included_reward_coins()
|
|
301
|
+
records = [await coin_store.get_coin_record(coin.name()) for coin in reward_coins]
|
|
328
302
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
303
|
+
if block.height <= reorg_index:
|
|
304
|
+
for record in records:
|
|
305
|
+
assert record is not None
|
|
306
|
+
assert record.spent == (record.name != selected_coin.name)
|
|
307
|
+
else:
|
|
308
|
+
for record in records:
|
|
309
|
+
assert record is None
|
|
336
310
|
|
|
337
311
|
|
|
338
312
|
@pytest.mark.anyio
|
|
@@ -343,7 +317,8 @@ async def test_basic_reorg(tmp_dir: Path, db_version: int, bt: BlockTools) -> No
|
|
|
343
317
|
blocks = bt.get_consecutive_blocks(initial_block_count)
|
|
344
318
|
coin_store = await CoinStore.create(db_wrapper)
|
|
345
319
|
store = await BlockStore.create(db_wrapper)
|
|
346
|
-
|
|
320
|
+
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
|
321
|
+
b: Blockchain = await Blockchain.create(coin_store, store, height_map, bt.constants, 2)
|
|
347
322
|
try:
|
|
348
323
|
records: list[Optional[CoinRecord]] = []
|
|
349
324
|
|
|
@@ -409,7 +384,8 @@ async def test_get_puzzle_hash(tmp_dir: Path, db_version: int, bt: BlockTools) -
|
|
|
409
384
|
)
|
|
410
385
|
coin_store = await CoinStore.create(db_wrapper)
|
|
411
386
|
store = await BlockStore.create(db_wrapper)
|
|
412
|
-
|
|
387
|
+
height_map = await BlockHeightMap.create(tmp_dir, db_wrapper)
|
|
388
|
+
b: Blockchain = await Blockchain.create(coin_store, store, height_map, bt.constants, 2)
|
|
413
389
|
for block in blocks:
|
|
414
390
|
await _validate_and_add_block(b, block)
|
|
415
391
|
peak = b.get_peak()
|
|
@@ -449,7 +425,7 @@ async def test_get_coin_states(db_version: int) -> None:
|
|
|
449
425
|
for i in range(1, 301)
|
|
450
426
|
]
|
|
451
427
|
coin_store = await CoinStore.create(db_wrapper)
|
|
452
|
-
await coin_store
|
|
428
|
+
await add_coin_records_to_db(coin_store, crs)
|
|
453
429
|
|
|
454
430
|
assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(0))) == 300
|
|
455
431
|
assert len(await coin_store.get_coin_states_by_puzzle_hashes(False, {std_hash(b"2")}, uint32(0))) == 0
|
|
@@ -577,7 +553,7 @@ async def test_coin_state_batches(
|
|
|
577
553
|
coin_store = await CoinStore.create(db_wrapper)
|
|
578
554
|
hint_store = await HintStore.create(db_wrapper)
|
|
579
555
|
|
|
580
|
-
await coin_store
|
|
556
|
+
await add_coin_records_to_db(coin_store, random_coin_records.items)
|
|
581
557
|
await hint_store.add_hints(random_coin_records.hints)
|
|
582
558
|
|
|
583
559
|
# Make sure all of the coin states are found when batching.
|
|
@@ -671,7 +647,7 @@ async def test_batch_many_coin_states(db_version: int, cut_off_middle: bool) ->
|
|
|
671
647
|
coin_store = await CoinStore.create(db_wrapper)
|
|
672
648
|
await HintStore.create(db_wrapper)
|
|
673
649
|
|
|
674
|
-
await coin_store
|
|
650
|
+
await add_coin_records_to_db(coin_store, coin_records)
|
|
675
651
|
|
|
676
652
|
# Make sure all of the coin states are found.
|
|
677
653
|
(all_coin_states, next_height) = await coin_store.batch_coin_states_by_puzzle_hashes([ph])
|
|
@@ -684,7 +660,8 @@ async def test_batch_many_coin_states(db_version: int, cut_off_middle: bool) ->
|
|
|
684
660
|
assert coin_records[i].coin.name().hex() == all_coin_states[i].coin.name().hex(), i
|
|
685
661
|
|
|
686
662
|
# For the middle case, insert a coin record between the two heights 10 and 12.
|
|
687
|
-
await
|
|
663
|
+
await add_coin_records_to_db(
|
|
664
|
+
coin_store,
|
|
688
665
|
[
|
|
689
666
|
CoinRecord(
|
|
690
667
|
coin=Coin(std_hash(b"extra coin"), ph, uint64(0)),
|
|
@@ -695,7 +672,7 @@ async def test_batch_many_coin_states(db_version: int, cut_off_middle: bool) ->
|
|
|
695
672
|
coinbase=False,
|
|
696
673
|
timestamp=uint64(0),
|
|
697
674
|
)
|
|
698
|
-
]
|
|
675
|
+
],
|
|
699
676
|
)
|
|
700
677
|
|
|
701
678
|
(all_coin_states, next_height) = await coin_store.batch_coin_states_by_puzzle_hashes([ph])
|
|
@@ -732,7 +709,7 @@ async def test_duplicate_by_hint(db_version: int) -> None:
|
|
|
732
709
|
uint64(12321312),
|
|
733
710
|
)
|
|
734
711
|
|
|
735
|
-
await coin_store
|
|
712
|
+
await add_coin_records_to_db(coin_store, [cr])
|
|
736
713
|
await hint_store.add_hints([(cr.coin.name(), cr.coin.puzzle_hash)])
|
|
737
714
|
|
|
738
715
|
coin_states, height = await coin_store.batch_coin_states_by_puzzle_hashes([cr.coin.puzzle_hash])
|
|
@@ -763,7 +740,7 @@ class UnspentLineageInfoTestItem:
|
|
|
763
740
|
puzzlehash: bytes
|
|
764
741
|
amount: int
|
|
765
742
|
parent_id: bytes
|
|
766
|
-
|
|
743
|
+
spent_index: int = 0
|
|
767
744
|
|
|
768
745
|
|
|
769
746
|
@dataclass
|
|
@@ -783,7 +760,7 @@ class UnspentLineageInfoCase:
|
|
|
783
760
|
UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
|
|
784
761
|
UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
|
|
785
762
|
UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
|
|
786
|
-
UnspentLineageInfoTestItem(TEST_PARENT_ID, b"4" * 32, TEST_AMOUNT, TEST_PARENT_PARENT_ID,
|
|
763
|
+
UnspentLineageInfoTestItem(TEST_PARENT_ID, b"4" * 32, TEST_AMOUNT, TEST_PARENT_PARENT_ID, spent_index=1),
|
|
787
764
|
],
|
|
788
765
|
expected_success=False,
|
|
789
766
|
),
|
|
@@ -798,11 +775,11 @@ class UnspentLineageInfoCase:
|
|
|
798
775
|
TEST_PUZZLEHASH,
|
|
799
776
|
TEST_PARENT_DIFFERENT_AMOUNT,
|
|
800
777
|
TEST_PARENT_PARENT_ID,
|
|
801
|
-
|
|
778
|
+
spent_index=1,
|
|
802
779
|
),
|
|
803
780
|
],
|
|
804
781
|
parent_with_diff_amount=True,
|
|
805
|
-
expected_success=
|
|
782
|
+
expected_success=False,
|
|
806
783
|
),
|
|
807
784
|
UnspentLineageInfoCase(
|
|
808
785
|
id="Unspent with parent that has same puzzlehash and amount but is also unspent",
|
|
@@ -821,7 +798,7 @@ class UnspentLineageInfoCase:
|
|
|
821
798
|
UnspentLineageInfoTestItem(b"2" * 32, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
|
|
822
799
|
UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
|
|
823
800
|
UnspentLineageInfoTestItem(
|
|
824
|
-
TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID,
|
|
801
|
+
TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID, spent_index=1
|
|
825
802
|
),
|
|
826
803
|
],
|
|
827
804
|
expected_success=False,
|
|
@@ -829,11 +806,11 @@ class UnspentLineageInfoCase:
|
|
|
829
806
|
UnspentLineageInfoCase(
|
|
830
807
|
id="Unspent with parent that has same puzzlehash and amount",
|
|
831
808
|
items=[
|
|
832
|
-
UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
|
|
809
|
+
UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID, spent_index=-1),
|
|
833
810
|
UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
|
|
834
811
|
UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
|
|
835
812
|
UnspentLineageInfoTestItem(
|
|
836
|
-
TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID,
|
|
813
|
+
TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID, spent_index=1
|
|
837
814
|
),
|
|
838
815
|
],
|
|
839
816
|
expected_success=True,
|
|
@@ -858,7 +835,7 @@ async def test_get_unspent_lineage_info_for_puzzle_hash(case: UnspentLineageInfo
|
|
|
858
835
|
(
|
|
859
836
|
item.coin_id,
|
|
860
837
|
0,
|
|
861
|
-
|
|
838
|
+
item.spent_index,
|
|
862
839
|
0,
|
|
863
840
|
item.puzzlehash,
|
|
864
841
|
item.parent_id,
|
|
@@ -884,14 +861,129 @@ async def test_get_unspent_lineage_info_for_puzzle_hash(case: UnspentLineageInfo
|
|
|
884
861
|
if case.expected_success:
|
|
885
862
|
assert result == UnspentLineageInfo(
|
|
886
863
|
coin_id=bytes32(TEST_COIN_ID),
|
|
887
|
-
coin_amount=TEST_AMOUNT,
|
|
888
864
|
parent_id=(
|
|
889
865
|
bytes32(TEST_PARENT_ID_DIFFERENT_AMOUNT)
|
|
890
866
|
if case.parent_with_diff_amount
|
|
891
867
|
else bytes32(TEST_PARENT_ID)
|
|
892
868
|
),
|
|
893
|
-
parent_amount=TEST_PARENT_DIFFERENT_AMOUNT if case.parent_with_diff_amount else TEST_AMOUNT,
|
|
894
869
|
parent_parent_id=bytes32(TEST_PARENT_PARENT_ID),
|
|
895
870
|
)
|
|
896
871
|
else:
|
|
897
872
|
assert result is None
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
@pytest.mark.anyio
|
|
876
|
+
async def test_add_coin_records_to_db() -> None:
|
|
877
|
+
async with DBConnection(2) as db_wrapper:
|
|
878
|
+
coin_store = await CoinStore.create(db_wrapper)
|
|
879
|
+
test_records = [
|
|
880
|
+
CoinRecord(
|
|
881
|
+
coin=Coin(bytes32([i * 2] * 32), bytes32([i * 2 + 1] * 32), uint64(i)),
|
|
882
|
+
confirmed_block_index=uint32(i + 1),
|
|
883
|
+
spent_block_index=uint32(i),
|
|
884
|
+
coinbase=i % 2 == 0,
|
|
885
|
+
timestamp=uint64(i),
|
|
886
|
+
)
|
|
887
|
+
for i in range(5)
|
|
888
|
+
]
|
|
889
|
+
await add_coin_records_to_db(coin_store, test_records)
|
|
890
|
+
# Verify all records got inserted correctly
|
|
891
|
+
for record in test_records:
|
|
892
|
+
resulting_record = await coin_store.get_coin_record(record.coin.name())
|
|
893
|
+
assert resulting_record is not None
|
|
894
|
+
assert resulting_record == record
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
async def get_spent_index(conn: aiosqlite.Connection, coin_name: bytes32) -> int:
|
|
898
|
+
cursor = await conn.execute("SELECT spent_index FROM coin_record WHERE coin_name = ?", (coin_name,))
|
|
899
|
+
row = await cursor.fetchone()
|
|
900
|
+
assert row is not None
|
|
901
|
+
return int(row[0])
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
@pytest.mark.anyio
|
|
905
|
+
async def test_new_block_tx_additions() -> None:
|
|
906
|
+
"""
|
|
907
|
+
Covers properly adding coin records for normal unspent coins and potential
|
|
908
|
+
fast forward singleton unspent coins. That means giving them spent index 0
|
|
909
|
+
and -1 respectively.
|
|
910
|
+
"""
|
|
911
|
+
async with DBConnection(2) as db_wrapper:
|
|
912
|
+
coin_store = await CoinStore.create(db_wrapper)
|
|
913
|
+
normal_coin = Coin(bytes32([0] * 32), bytes32([0] * 32), uint64(1))
|
|
914
|
+
normal_coin_id = normal_coin.name()
|
|
915
|
+
same_as_parent_coin = Coin(bytes32([0] * 32), bytes32([0] * 32), uint64(1337))
|
|
916
|
+
same_as_parent_coin_id = same_as_parent_coin.name()
|
|
917
|
+
await coin_store.new_block(
|
|
918
|
+
height=uint32(0),
|
|
919
|
+
timestamp=uint64(1),
|
|
920
|
+
included_reward_coins=[],
|
|
921
|
+
tx_additions=[
|
|
922
|
+
(normal_coin_id, normal_coin, False),
|
|
923
|
+
(same_as_parent_coin_id, same_as_parent_coin, True),
|
|
924
|
+
],
|
|
925
|
+
tx_removals=[],
|
|
926
|
+
)
|
|
927
|
+
async with db_wrapper.reader_no_transaction() as conn:
|
|
928
|
+
# Normal coin should have spent_index 0
|
|
929
|
+
assert await get_spent_index(conn, normal_coin_id) == 0
|
|
930
|
+
# Potential ff singleton should have spent_index -1
|
|
931
|
+
assert await get_spent_index(conn, same_as_parent_coin_id) == -1
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
@pytest.mark.anyio
|
|
935
|
+
async def test_rollback_to_block_spent_index_update() -> None:
|
|
936
|
+
"""
|
|
937
|
+
Covers properly marking coins as unspent on rollback. Reward coins and
|
|
938
|
+
normal coins get `spent_index` set to `0`, potential ff singleton ones get
|
|
939
|
+
`spent_index` set to `-1`.
|
|
940
|
+
"""
|
|
941
|
+
|
|
942
|
+
async def insert_coins(db_wrapper: DBWrapper2, coins: list[tuple[Coin, int, bool]]) -> None:
|
|
943
|
+
values_to_insert = [
|
|
944
|
+
(
|
|
945
|
+
coin.name(),
|
|
946
|
+
0,
|
|
947
|
+
spent_index,
|
|
948
|
+
int(coinbase),
|
|
949
|
+
coin.puzzle_hash,
|
|
950
|
+
coin.parent_coin_info,
|
|
951
|
+
coin.amount.stream_to_bytes(),
|
|
952
|
+
0,
|
|
953
|
+
)
|
|
954
|
+
for coin, spent_index, coinbase in coins
|
|
955
|
+
]
|
|
956
|
+
async with db_wrapper.writer() as conn:
|
|
957
|
+
await conn.executemany("INSERT INTO coin_record VALUES (?, ?, ?, ?, ?, ?, ?, ?)", values_to_insert)
|
|
958
|
+
|
|
959
|
+
async with DBConnection(2) as db_wrapper:
|
|
960
|
+
coin_store = await CoinStore.create(db_wrapper)
|
|
961
|
+
# Let's set things up for roll back. All coins are confirmed at height
|
|
962
|
+
# 0, parent coin gets spent at height 2 and the other test coins get
|
|
963
|
+
# spent at height 3.
|
|
964
|
+
parent_coin = Coin(bytes32([0] * 32), bytes32([1] * 32), uint64(1337))
|
|
965
|
+
parent_coin_id = parent_coin.name()
|
|
966
|
+
normal_child = Coin(parent_coin_id, bytes32([2] * 32), uint64(42))
|
|
967
|
+
same_as_parent_child = Coin(parent_coin_id, parent_coin.puzzle_hash, parent_coin.amount)
|
|
968
|
+
reward_coin = Coin(bytes32([0] * 32), bytes32([0] * 32), uint64(1))
|
|
969
|
+
await insert_coins(
|
|
970
|
+
db_wrapper,
|
|
971
|
+
# List of (coin, spent_index, coinbase) values
|
|
972
|
+
[
|
|
973
|
+
(parent_coin, 2, False),
|
|
974
|
+
(normal_child, 3, False),
|
|
975
|
+
(same_as_parent_child, 3, False),
|
|
976
|
+
(reward_coin, 3, True),
|
|
977
|
+
],
|
|
978
|
+
)
|
|
979
|
+
# Let's roll back
|
|
980
|
+
await coin_store.rollback_to_block(2)
|
|
981
|
+
async with db_wrapper.reader_no_transaction() as conn:
|
|
982
|
+
# Parent should still be spent
|
|
983
|
+
assert await get_spent_index(conn, parent_coin_id) == 2
|
|
984
|
+
# Normal child should be unspent with spent_index 0
|
|
985
|
+
assert await get_spent_index(conn, normal_child.name()) == 0
|
|
986
|
+
# Same for the reward coin
|
|
987
|
+
assert await get_spent_index(conn, reward_coin.name()) == 0
|
|
988
|
+
# The potential ff singleton child should be marked with -1
|
|
989
|
+
assert await get_spent_index(conn, same_as_parent_child.name()) == -1
|