chia-blockchain 2.5.1rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/__init__.py +10 -0
- chia/__main__.py +5 -0
- chia/_tests/README.md +53 -0
- chia/_tests/__init__.py +0 -0
- chia/_tests/blockchain/__init__.py +0 -0
- chia/_tests/blockchain/blockchain_test_utils.py +195 -0
- chia/_tests/blockchain/config.py +4 -0
- chia/_tests/blockchain/test_augmented_chain.py +145 -0
- chia/_tests/blockchain/test_blockchain.py +4202 -0
- chia/_tests/blockchain/test_blockchain_transactions.py +1031 -0
- chia/_tests/blockchain/test_build_chains.py +59 -0
- chia/_tests/blockchain/test_get_block_generator.py +72 -0
- chia/_tests/blockchain/test_lookup_fork_chain.py +194 -0
- chia/_tests/build-init-files.py +92 -0
- chia/_tests/build-job-matrix.py +204 -0
- chia/_tests/check_pytest_monitor_output.py +34 -0
- chia/_tests/check_sql_statements.py +72 -0
- chia/_tests/chia-start-sim +42 -0
- chia/_tests/clvm/__init__.py +0 -0
- chia/_tests/clvm/benchmark_costs.py +23 -0
- chia/_tests/clvm/coin_store.py +149 -0
- chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
- chia/_tests/clvm/test_clvm_step.py +37 -0
- chia/_tests/clvm/test_condition_codes.py +13 -0
- chia/_tests/clvm/test_curry_and_treehash.py +55 -0
- chia/_tests/clvm/test_message_conditions.py +184 -0
- chia/_tests/clvm/test_program.py +150 -0
- chia/_tests/clvm/test_puzzle_compression.py +143 -0
- chia/_tests/clvm/test_puzzle_drivers.py +45 -0
- chia/_tests/clvm/test_puzzles.py +242 -0
- chia/_tests/clvm/test_singletons.py +540 -0
- chia/_tests/clvm/test_spend_sim.py +181 -0
- chia/_tests/cmds/__init__.py +0 -0
- chia/_tests/cmds/cmd_test_utils.py +469 -0
- chia/_tests/cmds/config.py +3 -0
- chia/_tests/cmds/conftest.py +23 -0
- chia/_tests/cmds/test_click_types.py +200 -0
- chia/_tests/cmds/test_cmd_framework.py +620 -0
- chia/_tests/cmds/test_cmds_util.py +97 -0
- chia/_tests/cmds/test_daemon.py +92 -0
- chia/_tests/cmds/test_dev_gh.py +131 -0
- chia/_tests/cmds/test_farm_cmd.py +66 -0
- chia/_tests/cmds/test_show.py +116 -0
- chia/_tests/cmds/test_sim.py +207 -0
- chia/_tests/cmds/test_timelock_args.py +75 -0
- chia/_tests/cmds/test_tx_config_args.py +154 -0
- chia/_tests/cmds/testing_classes.py +59 -0
- chia/_tests/cmds/wallet/__init__.py +0 -0
- chia/_tests/cmds/wallet/test_consts.py +47 -0
- chia/_tests/cmds/wallet/test_dao.py +565 -0
- chia/_tests/cmds/wallet/test_did.py +403 -0
- chia/_tests/cmds/wallet/test_nft.py +471 -0
- chia/_tests/cmds/wallet/test_notifications.py +124 -0
- chia/_tests/cmds/wallet/test_offer.toffer +1 -0
- chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
- chia/_tests/cmds/wallet/test_vcs.py +400 -0
- chia/_tests/cmds/wallet/test_wallet.py +1125 -0
- chia/_tests/cmds/wallet/test_wallet_check.py +109 -0
- chia/_tests/conftest.py +1419 -0
- chia/_tests/connection_utils.py +125 -0
- chia/_tests/core/__init__.py +0 -0
- chia/_tests/core/cmds/__init__.py +0 -0
- chia/_tests/core/cmds/test_beta.py +382 -0
- chia/_tests/core/cmds/test_keys.py +1734 -0
- chia/_tests/core/cmds/test_wallet.py +126 -0
- chia/_tests/core/config.py +3 -0
- chia/_tests/core/consensus/__init__.py +0 -0
- chia/_tests/core/consensus/test_block_creation.py +54 -0
- chia/_tests/core/consensus/test_pot_iterations.py +117 -0
- chia/_tests/core/custom_types/__init__.py +0 -0
- chia/_tests/core/custom_types/test_coin.py +107 -0
- chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
- chia/_tests/core/custom_types/test_spend_bundle.py +70 -0
- chia/_tests/core/daemon/__init__.py +0 -0
- chia/_tests/core/daemon/config.py +4 -0
- chia/_tests/core/daemon/test_daemon.py +2128 -0
- chia/_tests/core/daemon/test_daemon_register.py +109 -0
- chia/_tests/core/daemon/test_keychain_proxy.py +101 -0
- chia/_tests/core/data_layer/__init__.py +0 -0
- chia/_tests/core/data_layer/config.py +5 -0
- chia/_tests/core/data_layer/conftest.py +106 -0
- chia/_tests/core/data_layer/test_data_cli.py +56 -0
- chia/_tests/core/data_layer/test_data_layer.py +83 -0
- chia/_tests/core/data_layer/test_data_layer_util.py +218 -0
- chia/_tests/core/data_layer/test_data_rpc.py +3847 -0
- chia/_tests/core/data_layer/test_data_store.py +2424 -0
- chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
- chia/_tests/core/data_layer/test_plugin.py +91 -0
- chia/_tests/core/data_layer/util.py +233 -0
- chia/_tests/core/farmer/__init__.py +0 -0
- chia/_tests/core/farmer/config.py +3 -0
- chia/_tests/core/farmer/test_farmer_api.py +103 -0
- chia/_tests/core/full_node/__init__.py +0 -0
- chia/_tests/core/full_node/config.py +4 -0
- chia/_tests/core/full_node/dos/__init__.py +0 -0
- chia/_tests/core/full_node/dos/config.py +3 -0
- chia/_tests/core/full_node/full_sync/__init__.py +0 -0
- chia/_tests/core/full_node/full_sync/config.py +4 -0
- chia/_tests/core/full_node/full_sync/test_full_sync.py +443 -0
- chia/_tests/core/full_node/ram_db.py +27 -0
- chia/_tests/core/full_node/stores/__init__.py +0 -0
- chia/_tests/core/full_node/stores/config.py +4 -0
- chia/_tests/core/full_node/stores/test_block_store.py +590 -0
- chia/_tests/core/full_node/stores/test_coin_store.py +897 -0
- chia/_tests/core/full_node/stores/test_full_node_store.py +1219 -0
- chia/_tests/core/full_node/stores/test_hint_store.py +229 -0
- chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
- chia/_tests/core/full_node/test_address_manager.py +588 -0
- chia/_tests/core/full_node/test_block_height_map.py +556 -0
- chia/_tests/core/full_node/test_conditions.py +556 -0
- chia/_tests/core/full_node/test_full_node.py +2700 -0
- chia/_tests/core/full_node/test_generator_tools.py +82 -0
- chia/_tests/core/full_node/test_hint_management.py +104 -0
- chia/_tests/core/full_node/test_node_load.py +34 -0
- chia/_tests/core/full_node/test_performance.py +179 -0
- chia/_tests/core/full_node/test_subscriptions.py +492 -0
- chia/_tests/core/full_node/test_transactions.py +203 -0
- chia/_tests/core/full_node/test_tx_processing_queue.py +155 -0
- chia/_tests/core/large_block.py +2388 -0
- chia/_tests/core/make_block_generator.py +70 -0
- chia/_tests/core/mempool/__init__.py +0 -0
- chia/_tests/core/mempool/config.py +4 -0
- chia/_tests/core/mempool/test_mempool.py +3255 -0
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
- chia/_tests/core/mempool/test_mempool_item_queries.py +190 -0
- chia/_tests/core/mempool/test_mempool_manager.py +2084 -0
- chia/_tests/core/mempool/test_mempool_performance.py +64 -0
- chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
- chia/_tests/core/node_height.py +28 -0
- chia/_tests/core/server/__init__.py +0 -0
- chia/_tests/core/server/config.py +3 -0
- chia/_tests/core/server/flood.py +84 -0
- chia/_tests/core/server/serve.py +135 -0
- chia/_tests/core/server/test_api_protocol.py +21 -0
- chia/_tests/core/server/test_capabilities.py +66 -0
- chia/_tests/core/server/test_dos.py +319 -0
- chia/_tests/core/server/test_event_loop.py +109 -0
- chia/_tests/core/server/test_loop.py +294 -0
- chia/_tests/core/server/test_node_discovery.py +73 -0
- chia/_tests/core/server/test_rate_limits.py +482 -0
- chia/_tests/core/server/test_server.py +226 -0
- chia/_tests/core/server/test_upnp.py +8 -0
- chia/_tests/core/services/__init__.py +0 -0
- chia/_tests/core/services/config.py +3 -0
- chia/_tests/core/services/test_services.py +188 -0
- chia/_tests/core/ssl/__init__.py +0 -0
- chia/_tests/core/ssl/config.py +3 -0
- chia/_tests/core/ssl/test_ssl.py +202 -0
- chia/_tests/core/test_coins.py +33 -0
- chia/_tests/core/test_cost_calculation.py +313 -0
- chia/_tests/core/test_crawler.py +175 -0
- chia/_tests/core/test_crawler_rpc.py +53 -0
- chia/_tests/core/test_daemon_rpc.py +24 -0
- chia/_tests/core/test_db_conversion.py +130 -0
- chia/_tests/core/test_db_validation.py +162 -0
- chia/_tests/core/test_farmer_harvester_rpc.py +505 -0
- chia/_tests/core/test_filter.py +35 -0
- chia/_tests/core/test_full_node_rpc.py +768 -0
- chia/_tests/core/test_merkle_set.py +343 -0
- chia/_tests/core/test_program.py +47 -0
- chia/_tests/core/test_rpc_util.py +86 -0
- chia/_tests/core/test_seeder.py +420 -0
- chia/_tests/core/test_setproctitle.py +13 -0
- chia/_tests/core/util/__init__.py +0 -0
- chia/_tests/core/util/config.py +4 -0
- chia/_tests/core/util/test_block_cache.py +44 -0
- chia/_tests/core/util/test_cached_bls.py +57 -0
- chia/_tests/core/util/test_config.py +337 -0
- chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
- chia/_tests/core/util/test_files.py +391 -0
- chia/_tests/core/util/test_jsonify.py +146 -0
- chia/_tests/core/util/test_keychain.py +522 -0
- chia/_tests/core/util/test_keyring_wrapper.py +491 -0
- chia/_tests/core/util/test_lockfile.py +380 -0
- chia/_tests/core/util/test_log_exceptions.py +187 -0
- chia/_tests/core/util/test_lru_cache.py +56 -0
- chia/_tests/core/util/test_significant_bits.py +40 -0
- chia/_tests/core/util/test_streamable.py +883 -0
- chia/_tests/db/__init__.py +0 -0
- chia/_tests/db/test_db_wrapper.py +566 -0
- chia/_tests/environments/__init__.py +0 -0
- chia/_tests/environments/common.py +35 -0
- chia/_tests/environments/full_node.py +47 -0
- chia/_tests/environments/wallet.py +429 -0
- chia/_tests/ether.py +19 -0
- chia/_tests/farmer_harvester/__init__.py +0 -0
- chia/_tests/farmer_harvester/config.py +3 -0
- chia/_tests/farmer_harvester/test_farmer.py +1264 -0
- chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +131 -0
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +528 -0
- chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
- chia/_tests/fee_estimation/__init__.py +0 -0
- chia/_tests/fee_estimation/config.py +3 -0
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +144 -0
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
- chia/_tests/generator/__init__.py +0 -0
- chia/_tests/generator/puzzles/__init__.py +0 -0
- chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
- chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
- chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
- chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
- chia/_tests/generator/test_compression.py +201 -0
- chia/_tests/generator/test_generator_types.py +44 -0
- chia/_tests/generator/test_rom.py +180 -0
- chia/_tests/plot_sync/__init__.py +0 -0
- chia/_tests/plot_sync/config.py +3 -0
- chia/_tests/plot_sync/test_delta.py +101 -0
- chia/_tests/plot_sync/test_plot_sync.py +618 -0
- chia/_tests/plot_sync/test_receiver.py +451 -0
- chia/_tests/plot_sync/test_sender.py +116 -0
- chia/_tests/plot_sync/test_sync_simulated.py +451 -0
- chia/_tests/plot_sync/util.py +68 -0
- chia/_tests/plotting/__init__.py +0 -0
- chia/_tests/plotting/config.py +3 -0
- chia/_tests/plotting/test_plot_manager.py +781 -0
- chia/_tests/plotting/util.py +12 -0
- chia/_tests/pools/__init__.py +0 -0
- chia/_tests/pools/config.py +5 -0
- chia/_tests/pools/test_pool_cli_parsing.py +128 -0
- chia/_tests/pools/test_pool_cmdline.py +1001 -0
- chia/_tests/pools/test_pool_config.py +42 -0
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +397 -0
- chia/_tests/pools/test_pool_rpc.py +1123 -0
- chia/_tests/pools/test_pool_wallet.py +205 -0
- chia/_tests/pools/test_wallet_pool_store.py +161 -0
- chia/_tests/process_junit.py +348 -0
- chia/_tests/rpc/__init__.py +0 -0
- chia/_tests/rpc/test_rpc_client.py +138 -0
- chia/_tests/rpc/test_rpc_server.py +183 -0
- chia/_tests/simulation/__init__.py +0 -0
- chia/_tests/simulation/config.py +6 -0
- chia/_tests/simulation/test_simulation.py +501 -0
- chia/_tests/simulation/test_simulator.py +232 -0
- chia/_tests/simulation/test_start_simulator.py +107 -0
- chia/_tests/testconfig.py +13 -0
- chia/_tests/timelord/__init__.py +0 -0
- chia/_tests/timelord/config.py +3 -0
- chia/_tests/timelord/test_new_peak.py +437 -0
- chia/_tests/timelord/test_timelord.py +11 -0
- chia/_tests/tools/1315537.json +170 -0
- chia/_tests/tools/1315544.json +160 -0
- chia/_tests/tools/1315630.json +150 -0
- chia/_tests/tools/300000.json +105 -0
- chia/_tests/tools/442734.json +140 -0
- chia/_tests/tools/466212.json +130 -0
- chia/_tests/tools/__init__.py +0 -0
- chia/_tests/tools/config.py +5 -0
- chia/_tests/tools/test-blockchain-db.sqlite +0 -0
- chia/_tests/tools/test_full_sync.py +30 -0
- chia/_tests/tools/test_legacy_keyring.py +82 -0
- chia/_tests/tools/test_run_block.py +128 -0
- chia/_tests/tools/test_virtual_project.py +591 -0
- chia/_tests/util/__init__.py +0 -0
- chia/_tests/util/benchmark_cost.py +170 -0
- chia/_tests/util/benchmarks.py +153 -0
- chia/_tests/util/bip39_test_vectors.json +148 -0
- chia/_tests/util/blockchain.py +134 -0
- chia/_tests/util/blockchain_mock.py +132 -0
- chia/_tests/util/build_network_protocol_files.py +302 -0
- chia/_tests/util/clvm_generator.bin +0 -0
- chia/_tests/util/config.py +3 -0
- chia/_tests/util/constants.py +20 -0
- chia/_tests/util/db_connection.py +37 -0
- chia/_tests/util/full_sync.py +253 -0
- chia/_tests/util/gen_ssl_certs.py +114 -0
- chia/_tests/util/generator_tools_testing.py +45 -0
- chia/_tests/util/get_name_puzzle_conditions.py +52 -0
- chia/_tests/util/key_tool.py +36 -0
- chia/_tests/util/misc.py +675 -0
- chia/_tests/util/network_protocol_data.py +1072 -0
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +2701 -0
- chia/_tests/util/rpc.py +26 -0
- chia/_tests/util/run_block.py +163 -0
- chia/_tests/util/setup_nodes.py +481 -0
- chia/_tests/util/spend_sim.py +492 -0
- chia/_tests/util/split_managers.py +102 -0
- chia/_tests/util/temp_file.py +14 -0
- chia/_tests/util/test_action_scope.py +144 -0
- chia/_tests/util/test_async_pool.py +366 -0
- chia/_tests/util/test_build_job_matrix.py +42 -0
- chia/_tests/util/test_build_network_protocol_files.py +7 -0
- chia/_tests/util/test_chia_version.py +50 -0
- chia/_tests/util/test_collection.py +11 -0
- chia/_tests/util/test_condition_tools.py +229 -0
- chia/_tests/util/test_config.py +426 -0
- chia/_tests/util/test_dump_keyring.py +60 -0
- chia/_tests/util/test_errors.py +10 -0
- chia/_tests/util/test_full_block_utils.py +279 -0
- chia/_tests/util/test_installed.py +20 -0
- chia/_tests/util/test_limited_semaphore.py +53 -0
- chia/_tests/util/test_logging_filter.py +42 -0
- chia/_tests/util/test_misc.py +445 -0
- chia/_tests/util/test_network.py +73 -0
- chia/_tests/util/test_network_protocol_files.py +578 -0
- chia/_tests/util/test_network_protocol_json.py +267 -0
- chia/_tests/util/test_network_protocol_test.py +256 -0
- chia/_tests/util/test_paginator.py +71 -0
- chia/_tests/util/test_pprint.py +17 -0
- chia/_tests/util/test_priority_mutex.py +488 -0
- chia/_tests/util/test_recursive_replace.py +116 -0
- chia/_tests/util/test_replace_str_to_bytes.py +137 -0
- chia/_tests/util/test_service_groups.py +15 -0
- chia/_tests/util/test_ssl_check.py +31 -0
- chia/_tests/util/test_testnet_overrides.py +19 -0
- chia/_tests/util/test_tests_misc.py +38 -0
- chia/_tests/util/test_timing.py +37 -0
- chia/_tests/util/test_trusted_peer.py +51 -0
- chia/_tests/util/time_out_assert.py +191 -0
- chia/_tests/wallet/__init__.py +0 -0
- chia/_tests/wallet/cat_wallet/__init__.py +0 -0
- chia/_tests/wallet/cat_wallet/config.py +4 -0
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1826 -0
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
- chia/_tests/wallet/cat_wallet/test_trades.py +2600 -0
- chia/_tests/wallet/clawback/__init__.py +0 -0
- chia/_tests/wallet/clawback/config.py +3 -0
- chia/_tests/wallet/clawback/test_clawback_decorator.py +78 -0
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
- chia/_tests/wallet/clawback/test_clawback_metadata.py +50 -0
- chia/_tests/wallet/config.py +4 -0
- chia/_tests/wallet/conftest.py +278 -0
- chia/_tests/wallet/dao_wallet/__init__.py +0 -0
- chia/_tests/wallet/dao_wallet/config.py +3 -0
- chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1330 -0
- chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
- chia/_tests/wallet/db_wallet/__init__.py +0 -0
- chia/_tests/wallet/db_wallet/config.py +3 -0
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +141 -0
- chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
- chia/_tests/wallet/did_wallet/__init__.py +0 -0
- chia/_tests/wallet/did_wallet/config.py +4 -0
- chia/_tests/wallet/did_wallet/test_did.py +2284 -0
- chia/_tests/wallet/nft_wallet/__init__.py +0 -0
- chia/_tests/wallet/nft_wallet/config.py +4 -0
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1493 -0
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1024 -0
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +375 -0
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2584 -0
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
- chia/_tests/wallet/rpc/__init__.py +0 -0
- chia/_tests/wallet/rpc/config.py +4 -0
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +285 -0
- chia/_tests/wallet/rpc/test_wallet_rpc.py +3153 -0
- chia/_tests/wallet/simple_sync/__init__.py +0 -0
- chia/_tests/wallet/simple_sync/config.py +3 -0
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +718 -0
- chia/_tests/wallet/sync/__init__.py +0 -0
- chia/_tests/wallet/sync/config.py +4 -0
- chia/_tests/wallet/sync/test_wallet_sync.py +1692 -0
- chia/_tests/wallet/test_address_type.py +189 -0
- chia/_tests/wallet/test_bech32m.py +45 -0
- chia/_tests/wallet/test_clvm_streamable.py +244 -0
- chia/_tests/wallet/test_coin_management.py +354 -0
- chia/_tests/wallet/test_coin_selection.py +588 -0
- chia/_tests/wallet/test_conditions.py +400 -0
- chia/_tests/wallet/test_debug_spend_bundle.py +218 -0
- chia/_tests/wallet/test_new_wallet_protocol.py +1174 -0
- chia/_tests/wallet/test_nft_store.py +192 -0
- chia/_tests/wallet/test_notifications.py +196 -0
- chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
- chia/_tests/wallet/test_puzzle_store.py +132 -0
- chia/_tests/wallet/test_sign_coin_spends.py +159 -0
- chia/_tests/wallet/test_signer_protocol.py +947 -0
- chia/_tests/wallet/test_singleton.py +122 -0
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
- chia/_tests/wallet/test_singleton_store.py +152 -0
- chia/_tests/wallet/test_taproot.py +19 -0
- chia/_tests/wallet/test_transaction_store.py +945 -0
- chia/_tests/wallet/test_util.py +185 -0
- chia/_tests/wallet/test_wallet.py +2139 -0
- chia/_tests/wallet/test_wallet_action_scope.py +85 -0
- chia/_tests/wallet/test_wallet_blockchain.py +111 -0
- chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
- chia/_tests/wallet/test_wallet_interested_store.py +43 -0
- chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
- chia/_tests/wallet/test_wallet_node.py +780 -0
- chia/_tests/wallet/test_wallet_retry.py +95 -0
- chia/_tests/wallet/test_wallet_state_manager.py +259 -0
- chia/_tests/wallet/test_wallet_test_framework.py +275 -0
- chia/_tests/wallet/test_wallet_trade_store.py +218 -0
- chia/_tests/wallet/test_wallet_user_store.py +34 -0
- chia/_tests/wallet/test_wallet_utils.py +156 -0
- chia/_tests/wallet/vc_wallet/__init__.py +0 -0
- chia/_tests/wallet/vc_wallet/config.py +3 -0
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +830 -0
- chia/_tests/wallet/wallet_block_tools.py +327 -0
- chia/_tests/weight_proof/__init__.py +0 -0
- chia/_tests/weight_proof/config.py +3 -0
- chia/_tests/weight_proof/test_weight_proof.py +528 -0
- chia/apis.py +19 -0
- chia/clvm/__init__.py +0 -0
- chia/cmds/__init__.py +0 -0
- chia/cmds/beta.py +184 -0
- chia/cmds/beta_funcs.py +137 -0
- chia/cmds/check_wallet_db.py +420 -0
- chia/cmds/chia.py +151 -0
- chia/cmds/cmd_classes.py +323 -0
- chia/cmds/cmd_helpers.py +242 -0
- chia/cmds/cmds_util.py +488 -0
- chia/cmds/coin_funcs.py +275 -0
- chia/cmds/coins.py +182 -0
- chia/cmds/completion.py +49 -0
- chia/cmds/configure.py +332 -0
- chia/cmds/dao.py +1064 -0
- chia/cmds/dao_funcs.py +598 -0
- chia/cmds/data.py +708 -0
- chia/cmds/data_funcs.py +385 -0
- chia/cmds/db.py +87 -0
- chia/cmds/db_backup_func.py +77 -0
- chia/cmds/db_upgrade_func.py +452 -0
- chia/cmds/db_validate_func.py +184 -0
- chia/cmds/dev.py +18 -0
- chia/cmds/farm.py +100 -0
- chia/cmds/farm_funcs.py +200 -0
- chia/cmds/gh.py +275 -0
- chia/cmds/init.py +63 -0
- chia/cmds/init_funcs.py +367 -0
- chia/cmds/installers.py +131 -0
- chia/cmds/keys.py +527 -0
- chia/cmds/keys_funcs.py +863 -0
- chia/cmds/netspace.py +50 -0
- chia/cmds/netspace_funcs.py +54 -0
- chia/cmds/options.py +32 -0
- chia/cmds/param_types.py +238 -0
- chia/cmds/passphrase.py +131 -0
- chia/cmds/passphrase_funcs.py +292 -0
- chia/cmds/peer.py +51 -0
- chia/cmds/peer_funcs.py +129 -0
- chia/cmds/plotnft.py +260 -0
- chia/cmds/plotnft_funcs.py +405 -0
- chia/cmds/plots.py +230 -0
- chia/cmds/plotters.py +18 -0
- chia/cmds/rpc.py +208 -0
- chia/cmds/show.py +72 -0
- chia/cmds/show_funcs.py +215 -0
- chia/cmds/signer.py +296 -0
- chia/cmds/sim.py +225 -0
- chia/cmds/sim_funcs.py +509 -0
- chia/cmds/start.py +24 -0
- chia/cmds/start_funcs.py +109 -0
- chia/cmds/stop.py +62 -0
- chia/cmds/units.py +9 -0
- chia/cmds/wallet.py +1901 -0
- chia/cmds/wallet_funcs.py +1874 -0
- chia/consensus/__init__.py +0 -0
- chia/consensus/block_body_validation.py +562 -0
- chia/consensus/block_creation.py +546 -0
- chia/consensus/block_header_validation.py +1059 -0
- chia/consensus/block_record.py +31 -0
- chia/consensus/block_rewards.py +53 -0
- chia/consensus/blockchain.py +1087 -0
- chia/consensus/blockchain_interface.py +56 -0
- chia/consensus/coinbase.py +30 -0
- chia/consensus/condition_costs.py +9 -0
- chia/consensus/constants.py +49 -0
- chia/consensus/cost_calculator.py +15 -0
- chia/consensus/default_constants.py +89 -0
- chia/consensus/deficit.py +55 -0
- chia/consensus/difficulty_adjustment.py +412 -0
- chia/consensus/find_fork_point.py +111 -0
- chia/consensus/full_block_to_block_record.py +167 -0
- chia/consensus/get_block_challenge.py +106 -0
- chia/consensus/get_block_generator.py +27 -0
- chia/consensus/make_sub_epoch_summary.py +210 -0
- chia/consensus/multiprocess_validation.py +268 -0
- chia/consensus/pos_quality.py +19 -0
- chia/consensus/pot_iterations.py +67 -0
- chia/consensus/puzzles/__init__.py +0 -0
- chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
- chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
- chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
- chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
- chia/consensus/vdf_info_computation.py +156 -0
- chia/daemon/__init__.py +0 -0
- chia/daemon/client.py +252 -0
- chia/daemon/keychain_proxy.py +502 -0
- chia/daemon/keychain_server.py +365 -0
- chia/daemon/server.py +1606 -0
- chia/daemon/windows_signal.py +56 -0
- chia/data_layer/__init__.py +0 -0
- chia/data_layer/data_layer.py +1291 -0
- chia/data_layer/data_layer_api.py +33 -0
- chia/data_layer/data_layer_errors.py +50 -0
- chia/data_layer/data_layer_server.py +170 -0
- chia/data_layer/data_layer_util.py +985 -0
- chia/data_layer/data_layer_wallet.py +1311 -0
- chia/data_layer/data_store.py +2267 -0
- chia/data_layer/dl_wallet_store.py +407 -0
- chia/data_layer/download_data.py +389 -0
- chia/data_layer/puzzles/__init__.py +0 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
- chia/data_layer/s3_plugin_config.yml +33 -0
- chia/data_layer/s3_plugin_service.py +468 -0
- chia/data_layer/util/__init__.py +0 -0
- chia/data_layer/util/benchmark.py +107 -0
- chia/data_layer/util/plugin.py +40 -0
- chia/farmer/__init__.py +0 -0
- chia/farmer/farmer.py +923 -0
- chia/farmer/farmer_api.py +820 -0
- chia/full_node/__init__.py +0 -0
- chia/full_node/bitcoin_fee_estimator.py +85 -0
- chia/full_node/block_height_map.py +271 -0
- chia/full_node/block_store.py +576 -0
- chia/full_node/bundle_tools.py +19 -0
- chia/full_node/coin_store.py +647 -0
- chia/full_node/fee_estimate.py +54 -0
- chia/full_node/fee_estimate_store.py +24 -0
- chia/full_node/fee_estimation.py +92 -0
- chia/full_node/fee_estimator.py +90 -0
- chia/full_node/fee_estimator_constants.py +38 -0
- chia/full_node/fee_estimator_interface.py +42 -0
- chia/full_node/fee_history.py +25 -0
- chia/full_node/fee_tracker.py +564 -0
- chia/full_node/full_node.py +3327 -0
- chia/full_node/full_node_api.py +2025 -0
- chia/full_node/full_node_store.py +1033 -0
- chia/full_node/hint_management.py +56 -0
- chia/full_node/hint_store.py +93 -0
- chia/full_node/mempool.py +589 -0
- chia/full_node/mempool_check_conditions.py +146 -0
- chia/full_node/mempool_manager.py +853 -0
- chia/full_node/pending_tx_cache.py +112 -0
- chia/full_node/puzzles/__init__.py +0 -0
- chia/full_node/puzzles/block_program_zero.clsp +14 -0
- chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
- chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
- chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
- chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
- chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
- chia/full_node/signage_point.py +16 -0
- chia/full_node/subscriptions.py +247 -0
- chia/full_node/sync_store.py +146 -0
- chia/full_node/tx_processing_queue.py +78 -0
- chia/full_node/util/__init__.py +0 -0
- chia/full_node/weight_proof.py +1720 -0
- chia/harvester/__init__.py +0 -0
- chia/harvester/harvester.py +272 -0
- chia/harvester/harvester_api.py +380 -0
- chia/introducer/__init__.py +0 -0
- chia/introducer/introducer.py +122 -0
- chia/introducer/introducer_api.py +70 -0
- chia/legacy/__init__.py +0 -0
- chia/legacy/keyring.py +155 -0
- chia/plot_sync/__init__.py +0 -0
- chia/plot_sync/delta.py +61 -0
- chia/plot_sync/exceptions.py +56 -0
- chia/plot_sync/receiver.py +386 -0
- chia/plot_sync/sender.py +340 -0
- chia/plot_sync/util.py +43 -0
- chia/plotters/__init__.py +0 -0
- chia/plotters/bladebit.py +388 -0
- chia/plotters/chiapos.py +63 -0
- chia/plotters/madmax.py +224 -0
- chia/plotters/plotters.py +577 -0
- chia/plotters/plotters_util.py +133 -0
- chia/plotting/__init__.py +0 -0
- chia/plotting/cache.py +213 -0
- chia/plotting/check_plots.py +283 -0
- chia/plotting/create_plots.py +278 -0
- chia/plotting/manager.py +436 -0
- chia/plotting/util.py +336 -0
- chia/pools/__init__.py +0 -0
- chia/pools/pool_config.py +110 -0
- chia/pools/pool_puzzles.py +459 -0
- chia/pools/pool_wallet.py +933 -0
- chia/pools/pool_wallet_info.py +118 -0
- chia/pools/puzzles/__init__.py +0 -0
- chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
- chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
- chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
- chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
- chia/protocols/__init__.py +0 -0
- chia/protocols/farmer_protocol.py +102 -0
- chia/protocols/full_node_protocol.py +219 -0
- chia/protocols/harvester_protocol.py +216 -0
- chia/protocols/introducer_protocol.py +25 -0
- chia/protocols/pool_protocol.py +177 -0
- chia/protocols/protocol_message_types.py +139 -0
- chia/protocols/protocol_state_machine.py +87 -0
- chia/protocols/protocol_timing.py +8 -0
- chia/protocols/shared_protocol.py +86 -0
- chia/protocols/timelord_protocol.py +93 -0
- chia/protocols/wallet_protocol.py +401 -0
- chia/py.typed +0 -0
- chia/rpc/__init__.py +0 -0
- chia/rpc/crawler_rpc_api.py +80 -0
- chia/rpc/data_layer_rpc_api.py +644 -0
- chia/rpc/data_layer_rpc_client.py +188 -0
- chia/rpc/data_layer_rpc_util.py +58 -0
- chia/rpc/farmer_rpc_api.py +365 -0
- chia/rpc/farmer_rpc_client.py +86 -0
- chia/rpc/full_node_rpc_api.py +959 -0
- chia/rpc/full_node_rpc_client.py +292 -0
- chia/rpc/harvester_rpc_api.py +141 -0
- chia/rpc/harvester_rpc_client.py +54 -0
- chia/rpc/rpc_client.py +164 -0
- chia/rpc/rpc_server.py +521 -0
- chia/rpc/timelord_rpc_api.py +32 -0
- chia/rpc/util.py +93 -0
- chia/rpc/wallet_request_types.py +904 -0
- chia/rpc/wallet_rpc_api.py +4943 -0
- chia/rpc/wallet_rpc_client.py +1814 -0
- chia/seeder/__init__.py +0 -0
- chia/seeder/crawl_store.py +425 -0
- chia/seeder/crawler.py +410 -0
- chia/seeder/crawler_api.py +135 -0
- chia/seeder/dns_server.py +593 -0
- chia/seeder/peer_record.py +146 -0
- chia/seeder/start_crawler.py +92 -0
- chia/server/__init__.py +0 -0
- chia/server/address_manager.py +658 -0
- chia/server/address_manager_store.py +237 -0
- chia/server/api_protocol.py +116 -0
- chia/server/capabilities.py +24 -0
- chia/server/chia_policy.py +346 -0
- chia/server/introducer_peers.py +76 -0
- chia/server/node_discovery.py +714 -0
- chia/server/outbound_message.py +33 -0
- chia/server/rate_limit_numbers.py +214 -0
- chia/server/rate_limits.py +153 -0
- chia/server/server.py +741 -0
- chia/server/signal_handlers.py +120 -0
- chia/server/ssl_context.py +32 -0
- chia/server/start_data_layer.py +151 -0
- chia/server/start_farmer.py +98 -0
- chia/server/start_full_node.py +112 -0
- chia/server/start_harvester.py +93 -0
- chia/server/start_introducer.py +81 -0
- chia/server/start_service.py +316 -0
- chia/server/start_timelord.py +89 -0
- chia/server/start_wallet.py +113 -0
- chia/server/upnp.py +118 -0
- chia/server/ws_connection.py +766 -0
- chia/simulator/__init__.py +0 -0
- chia/simulator/add_blocks_in_batches.py +54 -0
- chia/simulator/block_tools.py +2054 -0
- chia/simulator/full_node_simulator.py +794 -0
- chia/simulator/keyring.py +128 -0
- chia/simulator/setup_services.py +506 -0
- chia/simulator/simulator_constants.py +13 -0
- chia/simulator/simulator_full_node_rpc_api.py +99 -0
- chia/simulator/simulator_full_node_rpc_client.py +60 -0
- chia/simulator/simulator_protocol.py +29 -0
- chia/simulator/simulator_test_tools.py +164 -0
- chia/simulator/socket.py +24 -0
- chia/simulator/ssl_certs.py +114 -0
- chia/simulator/ssl_certs_1.py +697 -0
- chia/simulator/ssl_certs_10.py +697 -0
- chia/simulator/ssl_certs_2.py +697 -0
- chia/simulator/ssl_certs_3.py +697 -0
- chia/simulator/ssl_certs_4.py +697 -0
- chia/simulator/ssl_certs_5.py +697 -0
- chia/simulator/ssl_certs_6.py +697 -0
- chia/simulator/ssl_certs_7.py +697 -0
- chia/simulator/ssl_certs_8.py +697 -0
- chia/simulator/ssl_certs_9.py +697 -0
- chia/simulator/start_simulator.py +143 -0
- chia/simulator/wallet_tools.py +246 -0
- chia/ssl/__init__.py +0 -0
- chia/ssl/chia_ca.crt +19 -0
- chia/ssl/chia_ca.key +28 -0
- chia/ssl/create_ssl.py +249 -0
- chia/ssl/dst_root_ca.pem +20 -0
- chia/timelord/__init__.py +0 -0
- chia/timelord/iters_from_block.py +50 -0
- chia/timelord/timelord.py +1226 -0
- chia/timelord/timelord_api.py +138 -0
- chia/timelord/timelord_launcher.py +190 -0
- chia/timelord/timelord_state.py +244 -0
- chia/timelord/types.py +22 -0
- chia/types/__init__.py +0 -0
- chia/types/aliases.py +35 -0
- chia/types/block_protocol.py +20 -0
- chia/types/blockchain_format/__init__.py +0 -0
- chia/types/blockchain_format/classgroup.py +5 -0
- chia/types/blockchain_format/coin.py +28 -0
- chia/types/blockchain_format/foliage.py +8 -0
- chia/types/blockchain_format/pool_target.py +5 -0
- chia/types/blockchain_format/program.py +269 -0
- chia/types/blockchain_format/proof_of_space.py +135 -0
- chia/types/blockchain_format/reward_chain_block.py +6 -0
- chia/types/blockchain_format/serialized_program.py +5 -0
- chia/types/blockchain_format/sized_bytes.py +11 -0
- chia/types/blockchain_format/slots.py +9 -0
- chia/types/blockchain_format/sub_epoch_summary.py +5 -0
- chia/types/blockchain_format/tree_hash.py +72 -0
- chia/types/blockchain_format/vdf.py +86 -0
- chia/types/clvm_cost.py +13 -0
- chia/types/coin_record.py +43 -0
- chia/types/coin_spend.py +115 -0
- chia/types/condition_opcodes.py +73 -0
- chia/types/condition_with_args.py +16 -0
- chia/types/eligible_coin_spends.py +365 -0
- chia/types/end_of_slot_bundle.py +5 -0
- chia/types/fee_rate.py +38 -0
- chia/types/full_block.py +5 -0
- chia/types/generator_types.py +13 -0
- chia/types/header_block.py +5 -0
- chia/types/internal_mempool_item.py +18 -0
- chia/types/mempool_inclusion_status.py +9 -0
- chia/types/mempool_item.py +85 -0
- chia/types/mempool_submission_status.py +30 -0
- chia/types/mojos.py +7 -0
- chia/types/peer_info.py +64 -0
- chia/types/signing_mode.py +29 -0
- chia/types/spend_bundle.py +30 -0
- chia/types/spend_bundle_conditions.py +7 -0
- chia/types/transaction_queue_entry.py +55 -0
- chia/types/unfinished_block.py +5 -0
- chia/types/unfinished_header_block.py +37 -0
- chia/types/validation_state.py +14 -0
- chia/types/weight_proof.py +49 -0
- chia/util/__init__.py +0 -0
- chia/util/action_scope.py +168 -0
- chia/util/async_pool.py +226 -0
- chia/util/augmented_chain.py +134 -0
- chia/util/batches.py +42 -0
- chia/util/bech32m.py +126 -0
- chia/util/beta_metrics.py +119 -0
- chia/util/block_cache.py +56 -0
- chia/util/byte_types.py +12 -0
- chia/util/check_fork_next_block.py +33 -0
- chia/util/chia_logging.py +144 -0
- chia/util/chia_version.py +33 -0
- chia/util/collection.py +17 -0
- chia/util/condition_tools.py +201 -0
- chia/util/config.py +367 -0
- chia/util/cpu.py +22 -0
- chia/util/db_synchronous.py +23 -0
- chia/util/db_version.py +32 -0
- chia/util/db_wrapper.py +430 -0
- chia/util/default_root.py +27 -0
- chia/util/dump_keyring.py +93 -0
- chia/util/english.txt +2048 -0
- chia/util/errors.py +353 -0
- chia/util/file_keyring.py +469 -0
- chia/util/files.py +97 -0
- chia/util/full_block_utils.py +345 -0
- chia/util/generator_tools.py +72 -0
- chia/util/hash.py +31 -0
- chia/util/initial-config.yaml +694 -0
- chia/util/inline_executor.py +26 -0
- chia/util/ints.py +19 -0
- chia/util/ip_address.py +39 -0
- chia/util/json_util.py +37 -0
- chia/util/keychain.py +676 -0
- chia/util/keyring_wrapper.py +327 -0
- chia/util/limited_semaphore.py +41 -0
- chia/util/lock.py +49 -0
- chia/util/log_exceptions.py +32 -0
- chia/util/logging.py +36 -0
- chia/util/lru_cache.py +31 -0
- chia/util/math.py +20 -0
- chia/util/network.py +182 -0
- chia/util/paginator.py +48 -0
- chia/util/path.py +31 -0
- chia/util/permissions.py +20 -0
- chia/util/prev_transaction_block.py +21 -0
- chia/util/priority_mutex.py +95 -0
- chia/util/profiler.py +197 -0
- chia/util/recursive_replace.py +24 -0
- chia/util/safe_cancel_task.py +16 -0
- chia/util/service_groups.py +47 -0
- chia/util/setproctitle.py +22 -0
- chia/util/significant_bits.py +32 -0
- chia/util/ssl_check.py +213 -0
- chia/util/streamable.py +642 -0
- chia/util/task_referencer.py +59 -0
- chia/util/task_timing.py +382 -0
- chia/util/timing.py +67 -0
- chia/util/vdf_prover.py +30 -0
- chia/util/virtual_project_analysis.py +540 -0
- chia/util/ws_message.py +66 -0
- chia/wallet/__init__.py +0 -0
- chia/wallet/cat_wallet/__init__.py +0 -0
- chia/wallet/cat_wallet/cat_constants.py +75 -0
- chia/wallet/cat_wallet/cat_info.py +47 -0
- chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
- chia/wallet/cat_wallet/cat_utils.py +164 -0
- chia/wallet/cat_wallet/cat_wallet.py +855 -0
- chia/wallet/cat_wallet/dao_cat_info.py +28 -0
- chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
- chia/wallet/cat_wallet/lineage_store.py +74 -0
- chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
- chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
- chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
- chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
- chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
- chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
- chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
- chia/wallet/coin_selection.py +188 -0
- chia/wallet/conditions.py +1512 -0
- chia/wallet/dao_wallet/__init__.py +0 -0
- chia/wallet/dao_wallet/dao_info.py +61 -0
- chia/wallet/dao_wallet/dao_utils.py +811 -0
- chia/wallet/dao_wallet/dao_wallet.py +2119 -0
- chia/wallet/db_wallet/__init__.py +0 -0
- chia/wallet/db_wallet/db_wallet_puzzles.py +111 -0
- chia/wallet/derivation_record.py +30 -0
- chia/wallet/derive_keys.py +146 -0
- chia/wallet/did_wallet/__init__.py +0 -0
- chia/wallet/did_wallet/did_info.py +39 -0
- chia/wallet/did_wallet/did_wallet.py +1494 -0
- chia/wallet/did_wallet/did_wallet_puzzles.py +221 -0
- chia/wallet/did_wallet/puzzles/__init__.py +0 -0
- chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
- chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
- chia/wallet/driver_protocol.py +26 -0
- chia/wallet/key_val_store.py +55 -0
- chia/wallet/lineage_proof.py +58 -0
- chia/wallet/nft_wallet/__init__.py +0 -0
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
- chia/wallet/nft_wallet/nft_info.py +120 -0
- chia/wallet/nft_wallet/nft_puzzles.py +305 -0
- chia/wallet/nft_wallet/nft_wallet.py +1687 -0
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
- chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
- chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
- chia/wallet/nft_wallet/uncurry_nft.py +217 -0
- chia/wallet/notification_manager.py +117 -0
- chia/wallet/notification_store.py +178 -0
- chia/wallet/outer_puzzles.py +84 -0
- chia/wallet/payment.py +33 -0
- chia/wallet/puzzle_drivers.py +118 -0
- chia/wallet/puzzles/__init__.py +0 -0
- chia/wallet/puzzles/augmented_condition.clsp +13 -0
- chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
- chia/wallet/puzzles/clawback/__init__.py +0 -0
- chia/wallet/puzzles/clawback/drivers.py +188 -0
- chia/wallet/puzzles/clawback/metadata.py +38 -0
- chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
- chia/wallet/puzzles/condition_codes.clib +77 -0
- chia/wallet/puzzles/curry-and-treehash.clib +102 -0
- chia/wallet/puzzles/curry.clib +135 -0
- chia/wallet/puzzles/curry_by_index.clib +16 -0
- chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
- chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
- chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
- chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
- chia/wallet/puzzles/dao_finished_state.clsp +35 -0
- chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
- chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_lockup.clsp +288 -0
- chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
- chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal.clsp +377 -0
- chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
- chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
- chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
- chia/wallet/puzzles/dao_treasury.clsp +115 -0
- chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
- chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
- chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
- chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
- chia/wallet/puzzles/json.clib +25 -0
- chia/wallet/puzzles/load_clvm.py +161 -0
- chia/wallet/puzzles/merkle_utils.clib +18 -0
- chia/wallet/puzzles/notification.clsp +7 -0
- chia/wallet/puzzles/notification.clsp.hex +1 -0
- chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
- chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
- chia/wallet/puzzles/p2_conditions.clsp +3 -0
- chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
- chia/wallet/puzzles/p2_conditions.py +26 -0
- chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
- chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_conditions.py +21 -0
- chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
- chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_puzzle.py +34 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +160 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +21 -0
- chia/wallet/puzzles/p2_parent.clsp +19 -0
- chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
- chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
- chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
- chia/wallet/puzzles/p2_puzzle_hash.py +27 -0
- chia/wallet/puzzles/p2_singleton.clsp +30 -0
- chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
- chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
- chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
- chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
- chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/puzzles/puzzle_utils.py +34 -0
- chia/wallet/puzzles/settlement_payments.clsp +49 -0
- chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
- chia/wallet/puzzles/sha256tree.clib +11 -0
- chia/wallet/puzzles/singleton_launcher.clsp +16 -0
- chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
- chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer.py +296 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +345 -0
- chia/wallet/puzzles/singleton_truths.clib +21 -0
- chia/wallet/puzzles/tails.py +348 -0
- chia/wallet/puzzles/utility_macros.clib +48 -0
- chia/wallet/signer_protocol.py +125 -0
- chia/wallet/singleton.py +106 -0
- chia/wallet/singleton_record.py +30 -0
- chia/wallet/trade_manager.py +1102 -0
- chia/wallet/trade_record.py +67 -0
- chia/wallet/trading/__init__.py +0 -0
- chia/wallet/trading/offer.py +702 -0
- chia/wallet/trading/trade_status.py +13 -0
- chia/wallet/trading/trade_store.py +526 -0
- chia/wallet/transaction_record.py +158 -0
- chia/wallet/transaction_sorting.py +14 -0
- chia/wallet/uncurried_puzzle.py +17 -0
- chia/wallet/util/__init__.py +0 -0
- chia/wallet/util/address_type.py +55 -0
- chia/wallet/util/blind_signer_tl.py +164 -0
- chia/wallet/util/clvm_streamable.py +203 -0
- chia/wallet/util/compute_hints.py +66 -0
- chia/wallet/util/compute_memos.py +43 -0
- chia/wallet/util/curry_and_treehash.py +91 -0
- chia/wallet/util/debug_spend_bundle.py +232 -0
- chia/wallet/util/merkle_tree.py +100 -0
- chia/wallet/util/merkle_utils.py +102 -0
- chia/wallet/util/new_peak_queue.py +82 -0
- chia/wallet/util/notifications.py +12 -0
- chia/wallet/util/peer_request_cache.py +174 -0
- chia/wallet/util/pprint.py +39 -0
- chia/wallet/util/puzzle_compression.py +95 -0
- chia/wallet/util/puzzle_decorator.py +100 -0
- chia/wallet/util/puzzle_decorator_type.py +7 -0
- chia/wallet/util/query_filter.py +59 -0
- chia/wallet/util/transaction_type.py +23 -0
- chia/wallet/util/tx_config.py +158 -0
- chia/wallet/util/wallet_sync_utils.py +351 -0
- chia/wallet/util/wallet_types.py +72 -0
- chia/wallet/vc_wallet/__init__.py +0 -0
- chia/wallet/vc_wallet/cr_cat_drivers.py +664 -0
- chia/wallet/vc_wallet/cr_cat_wallet.py +877 -0
- chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
- chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
- chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
- chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
- chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
- chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
- chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
- chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_drivers.py +838 -0
- chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
- chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
- chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
- chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
- chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
- chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
- chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
- chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
- chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
- chia/wallet/vc_wallet/vc_store.py +263 -0
- chia/wallet/vc_wallet/vc_wallet.py +638 -0
- chia/wallet/wallet.py +698 -0
- chia/wallet/wallet_action_scope.py +96 -0
- chia/wallet/wallet_blockchain.py +244 -0
- chia/wallet/wallet_coin_record.py +72 -0
- chia/wallet/wallet_coin_store.py +351 -0
- chia/wallet/wallet_info.py +35 -0
- chia/wallet/wallet_interested_store.py +188 -0
- chia/wallet/wallet_nft_store.py +279 -0
- chia/wallet/wallet_node.py +1765 -0
- chia/wallet/wallet_node_api.py +207 -0
- chia/wallet/wallet_pool_store.py +119 -0
- chia/wallet/wallet_protocol.py +90 -0
- chia/wallet/wallet_puzzle_store.py +396 -0
- chia/wallet/wallet_retry_store.py +70 -0
- chia/wallet/wallet_singleton_store.py +259 -0
- chia/wallet/wallet_spend_bundle.py +25 -0
- chia/wallet/wallet_state_manager.py +2819 -0
- chia/wallet/wallet_transaction_store.py +496 -0
- chia/wallet/wallet_user_store.py +110 -0
- chia/wallet/wallet_weight_proof_handler.py +126 -0
- chia_blockchain-2.5.1rc1.dist-info/LICENSE +201 -0
- chia_blockchain-2.5.1rc1.dist-info/METADATA +156 -0
- chia_blockchain-2.5.1rc1.dist-info/RECORD +1042 -0
- chia_blockchain-2.5.1rc1.dist-info/WHEEL +4 -0
- chia_blockchain-2.5.1rc1.dist-info/entry_points.txt +17 -0
- mozilla-ca/cacert.pem +3611 -0
|
@@ -0,0 +1,2054 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import copy
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import random
|
|
8
|
+
import shutil
|
|
9
|
+
import ssl
|
|
10
|
+
import sys
|
|
11
|
+
import tempfile
|
|
12
|
+
import time
|
|
13
|
+
from collections.abc import Sequence
|
|
14
|
+
from dataclasses import dataclass, replace
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from random import Random
|
|
17
|
+
from typing import Any, Callable, Optional
|
|
18
|
+
|
|
19
|
+
import anyio
|
|
20
|
+
from chia_rs import MEMPOOL_MODE, AugSchemeMPL, G1Element, G2Element, PrivateKey, solution_generator
|
|
21
|
+
|
|
22
|
+
from chia.consensus.block_creation import create_unfinished_block, unfinished_block_to_full_block
|
|
23
|
+
from chia.consensus.block_record import BlockRecord
|
|
24
|
+
from chia.consensus.blockchain_interface import BlockRecordsProtocol
|
|
25
|
+
from chia.consensus.coinbase import create_puzzlehash_for_pk
|
|
26
|
+
from chia.consensus.condition_costs import ConditionCost
|
|
27
|
+
from chia.consensus.constants import ConsensusConstants, replace_str_to_bytes
|
|
28
|
+
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
|
29
|
+
from chia.consensus.deficit import calculate_deficit
|
|
30
|
+
from chia.consensus.full_block_to_block_record import block_to_block_record
|
|
31
|
+
from chia.consensus.make_sub_epoch_summary import next_sub_epoch_summary
|
|
32
|
+
from chia.consensus.pot_iterations import (
|
|
33
|
+
calculate_ip_iters,
|
|
34
|
+
calculate_iterations_quality,
|
|
35
|
+
calculate_sp_interval_iters,
|
|
36
|
+
calculate_sp_iters,
|
|
37
|
+
is_overflow_block,
|
|
38
|
+
)
|
|
39
|
+
from chia.consensus.vdf_info_computation import get_signage_point_vdf_info
|
|
40
|
+
from chia.daemon.keychain_proxy import KeychainProxy, connect_to_keychain_and_validate, wrap_local_keychain
|
|
41
|
+
from chia.full_node.bundle_tools import simple_solution_generator, simple_solution_generator_backrefs
|
|
42
|
+
from chia.full_node.signage_point import SignagePoint
|
|
43
|
+
from chia.plotting.create_plots import PlotKeys, create_plots
|
|
44
|
+
from chia.plotting.manager import PlotManager
|
|
45
|
+
from chia.plotting.util import (
|
|
46
|
+
Params,
|
|
47
|
+
PlotRefreshEvents,
|
|
48
|
+
PlotRefreshResult,
|
|
49
|
+
PlotsRefreshParameter,
|
|
50
|
+
add_plot_directory,
|
|
51
|
+
parse_plot_info,
|
|
52
|
+
)
|
|
53
|
+
from chia.server.server import ssl_context_for_client
|
|
54
|
+
from chia.simulator.socket import find_available_listen_port
|
|
55
|
+
from chia.simulator.ssl_certs import (
|
|
56
|
+
SSLTestCACertAndPrivateKey,
|
|
57
|
+
SSLTestCollateralWrapper,
|
|
58
|
+
SSLTestNodeCertsAndKeys,
|
|
59
|
+
get_next_nodes_certs_and_keys,
|
|
60
|
+
get_next_private_ca_cert_and_key,
|
|
61
|
+
)
|
|
62
|
+
from chia.simulator.wallet_tools import WalletTool
|
|
63
|
+
from chia.ssl.create_ssl import create_all_ssl
|
|
64
|
+
from chia.types.blockchain_format.classgroup import ClassgroupElement
|
|
65
|
+
from chia.types.blockchain_format.coin import Coin
|
|
66
|
+
from chia.types.blockchain_format.pool_target import PoolTarget
|
|
67
|
+
from chia.types.blockchain_format.program import INFINITE_COST, Program
|
|
68
|
+
from chia.types.blockchain_format.proof_of_space import (
|
|
69
|
+
ProofOfSpace,
|
|
70
|
+
calculate_pos_challenge,
|
|
71
|
+
calculate_prefix_bits,
|
|
72
|
+
generate_plot_public_key,
|
|
73
|
+
generate_taproot_sk,
|
|
74
|
+
passes_plot_filter,
|
|
75
|
+
verify_and_get_quality_string,
|
|
76
|
+
)
|
|
77
|
+
from chia.types.blockchain_format.serialized_program import SerializedProgram
|
|
78
|
+
from chia.types.blockchain_format.sized_bytes import bytes32
|
|
79
|
+
from chia.types.blockchain_format.slots import (
|
|
80
|
+
ChallengeChainSubSlot,
|
|
81
|
+
InfusedChallengeChainSubSlot,
|
|
82
|
+
RewardChainSubSlot,
|
|
83
|
+
SubSlotProofs,
|
|
84
|
+
)
|
|
85
|
+
from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
|
|
86
|
+
from chia.types.blockchain_format.vdf import VDFInfo, VDFProof
|
|
87
|
+
from chia.types.condition_opcodes import ConditionOpcode
|
|
88
|
+
from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
|
|
89
|
+
from chia.types.full_block import FullBlock
|
|
90
|
+
from chia.types.generator_types import BlockGenerator
|
|
91
|
+
from chia.types.spend_bundle import SpendBundle
|
|
92
|
+
from chia.types.unfinished_block import UnfinishedBlock
|
|
93
|
+
from chia.util.bech32m import encode_puzzle_hash
|
|
94
|
+
from chia.util.block_cache import BlockCache
|
|
95
|
+
from chia.util.config import (
|
|
96
|
+
config_path_for_filename,
|
|
97
|
+
create_default_chia_config,
|
|
98
|
+
load_config,
|
|
99
|
+
lock_config,
|
|
100
|
+
override_config,
|
|
101
|
+
save_config,
|
|
102
|
+
)
|
|
103
|
+
from chia.util.default_root import DEFAULT_ROOT_PATH
|
|
104
|
+
from chia.util.hash import std_hash
|
|
105
|
+
from chia.util.ints import uint8, uint16, uint32, uint64, uint128
|
|
106
|
+
from chia.util.keychain import Keychain, bytes_to_mnemonic
|
|
107
|
+
from chia.util.ssl_check import fix_ssl
|
|
108
|
+
from chia.util.timing import adjusted_timeout, backoff_times
|
|
109
|
+
from chia.util.vdf_prover import get_vdf_info_and_proof
|
|
110
|
+
from chia.wallet.derive_keys import (
|
|
111
|
+
master_sk_to_farmer_sk,
|
|
112
|
+
master_sk_to_local_sk,
|
|
113
|
+
master_sk_to_pool_sk,
|
|
114
|
+
master_sk_to_wallet_sk,
|
|
115
|
+
)
|
|
116
|
+
from chia.wallet.puzzles.load_clvm import load_serialized_clvm_maybe_recompile
|
|
117
|
+
|
|
118
|
+
GENERATOR_MOD: SerializedProgram = load_serialized_clvm_maybe_recompile(
|
|
119
|
+
"rom_bootstrap_generator.clsp", package_or_requirement="chia.consensus.puzzles"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
DESERIALIZE_MOD = load_serialized_clvm_maybe_recompile(
|
|
123
|
+
"chialisp_deserialisation.clsp", package_or_requirement="chia.consensus.puzzles"
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
test_constants = DEFAULT_CONSTANTS.replace(
|
|
127
|
+
MIN_PLOT_SIZE=uint8(18),
|
|
128
|
+
MIN_BLOCKS_PER_CHALLENGE_BLOCK=uint8(12),
|
|
129
|
+
DIFFICULTY_STARTING=uint64(2**10),
|
|
130
|
+
DISCRIMINANT_SIZE_BITS=uint16(16),
|
|
131
|
+
SUB_EPOCH_BLOCKS=uint32(170),
|
|
132
|
+
WEIGHT_PROOF_THRESHOLD=uint8(2),
|
|
133
|
+
WEIGHT_PROOF_RECENT_BLOCKS=uint32(380),
|
|
134
|
+
DIFFICULTY_CONSTANT_FACTOR=uint128(33554432),
|
|
135
|
+
NUM_SPS_SUB_SLOT=uint32(16), # Must be a power of 2
|
|
136
|
+
MAX_SUB_SLOT_BLOCKS=uint32(50),
|
|
137
|
+
EPOCH_BLOCKS=uint32(340),
|
|
138
|
+
# the block cache must contain at least 3 epochs in order for
|
|
139
|
+
# create_prev_sub_epoch_segments() to have access to all the blocks it needs
|
|
140
|
+
# from the cache
|
|
141
|
+
BLOCKS_CACHE_SIZE=uint32(340 * 3), # Coordinate with the above values
|
|
142
|
+
SUB_SLOT_TIME_TARGET=uint16(600), # The target number of seconds per slot, mainnet 600
|
|
143
|
+
SUB_SLOT_ITERS_STARTING=uint64(2**10), # Must be a multiple of 64
|
|
144
|
+
NUMBER_ZERO_BITS_PLOT_FILTER=uint8(1), # H(plot signature of the challenge) must start with these many zeroes
|
|
145
|
+
# Allows creating blockchains with timestamps up to 10 days in the future, for testing
|
|
146
|
+
MAX_FUTURE_TIME2=uint32(3600 * 24 * 10),
|
|
147
|
+
MEMPOOL_BLOCK_BUFFER=uint8(6),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def compute_additions_unchecked(sb: SpendBundle) -> list[Coin]:
|
|
152
|
+
ret: list[Coin] = []
|
|
153
|
+
for cs in sb.coin_spends:
|
|
154
|
+
parent_id = cs.coin.name()
|
|
155
|
+
_, r = cs.puzzle_reveal.run_with_cost(INFINITE_COST, cs.solution)
|
|
156
|
+
for cond in Program.to(r).as_iter():
|
|
157
|
+
atoms = cond.as_iter()
|
|
158
|
+
op = next(atoms).atom
|
|
159
|
+
if op != ConditionOpcode.CREATE_COIN.value:
|
|
160
|
+
continue
|
|
161
|
+
puzzle_hash = next(atoms).as_atom()
|
|
162
|
+
amount = uint64(next(atoms).as_int())
|
|
163
|
+
ret.append(Coin(parent_id, puzzle_hash, amount))
|
|
164
|
+
return ret
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def make_spend_bundle(coins: list[Coin], wallet: WalletTool, rng: Random) -> tuple[SpendBundle, list[Coin]]:
|
|
168
|
+
"""
|
|
169
|
+
makes a new spend bundle (block generator) spending some of the coins in the
|
|
170
|
+
list of coins. The list will be updated to have spent coins removed and new
|
|
171
|
+
coins appended.
|
|
172
|
+
"""
|
|
173
|
+
new_coins: list[Coin] = []
|
|
174
|
+
spend_bundles: list[SpendBundle] = []
|
|
175
|
+
to_spend = rng.sample(coins, min(5, len(coins)))
|
|
176
|
+
receiver = wallet.get_new_puzzlehash()
|
|
177
|
+
for c in to_spend:
|
|
178
|
+
bundle = wallet.generate_signed_transaction(uint64(c.amount // 2), receiver, c)
|
|
179
|
+
new_coins.extend(bundle.additions())
|
|
180
|
+
spend_bundles.append(bundle)
|
|
181
|
+
coins.remove(c)
|
|
182
|
+
|
|
183
|
+
coins.extend(new_coins)
|
|
184
|
+
|
|
185
|
+
return SpendBundle.aggregate(spend_bundles), new_coins
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class BlockTools:
|
|
189
|
+
"""
|
|
190
|
+
Tools to generate blocks for testing.
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
_block_cache_header: bytes32
|
|
194
|
+
_block_cache_height_to_hash: dict[uint32, bytes32]
|
|
195
|
+
_block_cache_difficulty: uint64
|
|
196
|
+
_block_cache: dict[bytes32, BlockRecord]
|
|
197
|
+
|
|
198
|
+
def __init__(
|
|
199
|
+
self,
|
|
200
|
+
constants: ConsensusConstants = test_constants,
|
|
201
|
+
root_path: Optional[Path] = None,
|
|
202
|
+
keychain: Optional[Keychain] = None,
|
|
203
|
+
config_overrides: Optional[dict[str, Any]] = None,
|
|
204
|
+
automated_testing: bool = True,
|
|
205
|
+
plot_dir: str = "test-plots",
|
|
206
|
+
log: logging.Logger = logging.getLogger(__name__),
|
|
207
|
+
) -> None:
|
|
208
|
+
self._block_cache_header = bytes32.zeros
|
|
209
|
+
|
|
210
|
+
self._tempdir = None
|
|
211
|
+
if root_path is None:
|
|
212
|
+
self._tempdir = tempfile.TemporaryDirectory()
|
|
213
|
+
root_path = Path(self._tempdir.name)
|
|
214
|
+
|
|
215
|
+
self.root_path = root_path
|
|
216
|
+
self.log = log
|
|
217
|
+
self.local_keychain = keychain
|
|
218
|
+
self.local_sk_cache: dict[bytes32, tuple[PrivateKey, Any]] = {}
|
|
219
|
+
self.automated_testing = automated_testing
|
|
220
|
+
self.plot_dir_name = plot_dir
|
|
221
|
+
|
|
222
|
+
if automated_testing:
|
|
223
|
+
# Hold onto the wrappers so that they can keep track of whether the certs/keys
|
|
224
|
+
# are in use by another BlockTools instance.
|
|
225
|
+
self.ssl_ca_cert_and_key_wrapper: SSLTestCollateralWrapper[SSLTestCACertAndPrivateKey] = (
|
|
226
|
+
get_next_private_ca_cert_and_key()
|
|
227
|
+
)
|
|
228
|
+
self.ssl_nodes_certs_and_keys_wrapper: SSLTestCollateralWrapper[SSLTestNodeCertsAndKeys] = (
|
|
229
|
+
get_next_nodes_certs_and_keys()
|
|
230
|
+
)
|
|
231
|
+
create_default_chia_config(root_path)
|
|
232
|
+
create_all_ssl(
|
|
233
|
+
root_path,
|
|
234
|
+
private_ca_crt_and_key=self.ssl_ca_cert_and_key_wrapper.collateral.cert_and_key,
|
|
235
|
+
node_certs_and_keys=self.ssl_nodes_certs_and_keys_wrapper.collateral.certs_and_keys,
|
|
236
|
+
)
|
|
237
|
+
fix_ssl(root_path)
|
|
238
|
+
with lock_config(root_path=root_path, filename="config.yaml"):
|
|
239
|
+
path = config_path_for_filename(root_path=root_path, filename="config.yaml")
|
|
240
|
+
path.write_text(path.read_text().replace("localhost", "127.0.0.1"))
|
|
241
|
+
self._config = load_config(self.root_path, "config.yaml")
|
|
242
|
+
if automated_testing:
|
|
243
|
+
if config_overrides is None:
|
|
244
|
+
config_overrides = {}
|
|
245
|
+
config_overrides["logging.log_stdout"] = True
|
|
246
|
+
config_overrides["selected_network"] = "testnet0"
|
|
247
|
+
for service in [
|
|
248
|
+
"harvester",
|
|
249
|
+
"farmer",
|
|
250
|
+
"full_node",
|
|
251
|
+
"wallet",
|
|
252
|
+
"introducer",
|
|
253
|
+
"timelord",
|
|
254
|
+
"pool",
|
|
255
|
+
"simulator",
|
|
256
|
+
]:
|
|
257
|
+
config_overrides[service + ".selected_network"] = "testnet0"
|
|
258
|
+
|
|
259
|
+
# some tests start the daemon, make sure it's on a free port
|
|
260
|
+
config_overrides["daemon_port"] = find_available_listen_port("BlockTools daemon")
|
|
261
|
+
|
|
262
|
+
self._config = override_config(self._config, config_overrides)
|
|
263
|
+
|
|
264
|
+
with lock_config(self.root_path, "config.yaml"):
|
|
265
|
+
save_config(self.root_path, "config.yaml", self._config)
|
|
266
|
+
overrides = self._config["network_overrides"]["constants"][self._config["selected_network"]]
|
|
267
|
+
updated_constants = replace_str_to_bytes(constants, **overrides)
|
|
268
|
+
self.constants = updated_constants
|
|
269
|
+
|
|
270
|
+
self.plot_dir: Path = get_plot_dir(self.plot_dir_name, self.automated_testing)
|
|
271
|
+
self.temp_dir: Path = get_plot_tmp_dir(self.plot_dir_name, self.automated_testing)
|
|
272
|
+
self.plot_dir.mkdir(parents=True, exist_ok=True)
|
|
273
|
+
self.temp_dir.mkdir(parents=True, exist_ok=True)
|
|
274
|
+
self.expected_plots: dict[bytes32, Path] = {}
|
|
275
|
+
self.created_plots: int = 0
|
|
276
|
+
self.total_result = PlotRefreshResult()
|
|
277
|
+
|
|
278
|
+
def test_callback(event: PlotRefreshEvents, update_result: PlotRefreshResult) -> None:
|
|
279
|
+
assert update_result.duration < 120
|
|
280
|
+
if event == PlotRefreshEvents.started:
|
|
281
|
+
self.total_result = PlotRefreshResult()
|
|
282
|
+
|
|
283
|
+
if event == PlotRefreshEvents.batch_processed:
|
|
284
|
+
self.total_result.loaded += update_result.loaded
|
|
285
|
+
self.total_result.processed += update_result.processed
|
|
286
|
+
self.total_result.duration += update_result.duration
|
|
287
|
+
assert update_result.remaining >= len(self.expected_plots) - self.total_result.processed
|
|
288
|
+
assert len(update_result.loaded) <= self.plot_manager.refresh_parameter.batch_size
|
|
289
|
+
|
|
290
|
+
if event == PlotRefreshEvents.done:
|
|
291
|
+
assert self.total_result.loaded == update_result.loaded
|
|
292
|
+
assert self.total_result.processed == update_result.processed
|
|
293
|
+
assert self.total_result.duration == update_result.duration
|
|
294
|
+
assert update_result.remaining == 0
|
|
295
|
+
assert len(self.plot_manager.plots) == len(self.expected_plots)
|
|
296
|
+
|
|
297
|
+
self.plot_manager: PlotManager = PlotManager(
|
|
298
|
+
self.root_path,
|
|
299
|
+
refresh_parameter=PlotsRefreshParameter(batch_size=uint32(2)),
|
|
300
|
+
refresh_callback=test_callback,
|
|
301
|
+
match_str=str(self.plot_dir.relative_to(DEFAULT_ROOT_PATH.parent)) if not automated_testing else None,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
async def setup_keys(self, fingerprint: Optional[int] = None, reward_ph: Optional[bytes32] = None) -> None:
|
|
305
|
+
keychain_proxy: Optional[KeychainProxy]
|
|
306
|
+
try:
|
|
307
|
+
if self.local_keychain:
|
|
308
|
+
keychain_proxy = wrap_local_keychain(self.local_keychain, log=self.log)
|
|
309
|
+
elif not self.automated_testing and fingerprint is not None:
|
|
310
|
+
keychain_proxy = await connect_to_keychain_and_validate(self.root_path, self.log)
|
|
311
|
+
else: # if we are automated testing or if we don't have a fingerprint.
|
|
312
|
+
keychain_proxy = await connect_to_keychain_and_validate(
|
|
313
|
+
self.root_path, self.log, user="testing-1.8.0", service="chia-testing-1.8.0"
|
|
314
|
+
)
|
|
315
|
+
assert keychain_proxy is not None
|
|
316
|
+
if fingerprint is None: # if we are not specifying an existing key
|
|
317
|
+
await keychain_proxy.delete_all_keys()
|
|
318
|
+
self.farmer_master_sk_entropy = std_hash(b"block_tools farmer key") # both entropies are only used here
|
|
319
|
+
self.pool_master_sk_entropy = std_hash(b"block_tools pool key")
|
|
320
|
+
self.farmer_master_sk = await keychain_proxy.add_key(bytes_to_mnemonic(self.farmer_master_sk_entropy))
|
|
321
|
+
self.pool_master_sk = await keychain_proxy.add_key(
|
|
322
|
+
bytes_to_mnemonic(self.pool_master_sk_entropy),
|
|
323
|
+
)
|
|
324
|
+
else:
|
|
325
|
+
sk = await keychain_proxy.get_key_for_fingerprint(fingerprint)
|
|
326
|
+
assert sk is not None
|
|
327
|
+
self.farmer_master_sk = sk
|
|
328
|
+
sk = await keychain_proxy.get_key_for_fingerprint(fingerprint)
|
|
329
|
+
assert sk is not None
|
|
330
|
+
self.pool_master_sk = sk
|
|
331
|
+
|
|
332
|
+
self.farmer_pk = master_sk_to_farmer_sk(self.farmer_master_sk).get_g1()
|
|
333
|
+
self.pool_pk = master_sk_to_pool_sk(self.pool_master_sk).get_g1()
|
|
334
|
+
|
|
335
|
+
if reward_ph is None:
|
|
336
|
+
self.farmer_ph: bytes32 = create_puzzlehash_for_pk(
|
|
337
|
+
master_sk_to_wallet_sk(self.farmer_master_sk, uint32(0)).get_g1()
|
|
338
|
+
)
|
|
339
|
+
self.pool_ph: bytes32 = create_puzzlehash_for_pk(
|
|
340
|
+
master_sk_to_wallet_sk(self.pool_master_sk, uint32(0)).get_g1()
|
|
341
|
+
)
|
|
342
|
+
else:
|
|
343
|
+
self.farmer_ph = reward_ph
|
|
344
|
+
self.pool_ph = reward_ph
|
|
345
|
+
if self.automated_testing:
|
|
346
|
+
self.all_sks: list[PrivateKey] = [sk for sk, _ in await keychain_proxy.get_all_private_keys()]
|
|
347
|
+
else:
|
|
348
|
+
self.all_sks = [self.farmer_master_sk] # we only want to include plots under the same fingerprint
|
|
349
|
+
self.pool_pubkeys: list[G1Element] = [master_sk_to_pool_sk(sk).get_g1() for sk in self.all_sks]
|
|
350
|
+
|
|
351
|
+
self.farmer_pubkeys: list[G1Element] = [master_sk_to_farmer_sk(sk).get_g1() for sk in self.all_sks]
|
|
352
|
+
if len(self.pool_pubkeys) == 0 or len(self.farmer_pubkeys) == 0:
|
|
353
|
+
raise RuntimeError("Keys not generated. Run `chia keys generate`")
|
|
354
|
+
|
|
355
|
+
self.plot_manager.set_public_keys(self.farmer_pubkeys, self.pool_pubkeys)
|
|
356
|
+
finally:
|
|
357
|
+
if keychain_proxy is not None:
|
|
358
|
+
await keychain_proxy.close() # close the keychain proxy
|
|
359
|
+
|
|
360
|
+
def change_config(self, new_config: dict[str, Any]) -> None:
|
|
361
|
+
self._config = new_config
|
|
362
|
+
overrides = self._config["network_overrides"]["constants"][self._config["selected_network"]]
|
|
363
|
+
updated_constants = replace_str_to_bytes(self.constants, **overrides)
|
|
364
|
+
self.constants = updated_constants
|
|
365
|
+
with lock_config(self.root_path, "config.yaml"):
|
|
366
|
+
save_config(self.root_path, "config.yaml", self._config)
|
|
367
|
+
|
|
368
|
+
def add_plot_directory(self, path: Path) -> None:
|
|
369
|
+
# don't add to config if block_tools is user run and the directory is already in the config.
|
|
370
|
+
if str(path.resolve()) not in self._config["harvester"]["plot_directories"] or self.automated_testing:
|
|
371
|
+
self._config = add_plot_directory(self.root_path, str(path))
|
|
372
|
+
|
|
373
|
+
async def setup_plots(
|
|
374
|
+
self,
|
|
375
|
+
num_og_plots: int = 15,
|
|
376
|
+
num_pool_plots: int = 5,
|
|
377
|
+
num_non_keychain_plots: int = 3,
|
|
378
|
+
plot_size: int = 20,
|
|
379
|
+
bitfield: bool = True,
|
|
380
|
+
) -> bool:
|
|
381
|
+
self.add_plot_directory(self.plot_dir)
|
|
382
|
+
assert self.created_plots == 0
|
|
383
|
+
existing_plots: bool = True
|
|
384
|
+
# OG Plots
|
|
385
|
+
for i in range(num_og_plots):
|
|
386
|
+
plot = await self.new_plot(plot_size=plot_size, bitfield=bitfield)
|
|
387
|
+
if plot.new_plot:
|
|
388
|
+
existing_plots = False
|
|
389
|
+
# Pool Plots
|
|
390
|
+
for i in range(num_pool_plots):
|
|
391
|
+
plot = await self.new_plot(self.pool_ph, plot_size=plot_size, bitfield=bitfield)
|
|
392
|
+
if plot.new_plot:
|
|
393
|
+
existing_plots = False
|
|
394
|
+
# Some plots with keys that are not in the keychain
|
|
395
|
+
for i in range(num_non_keychain_plots):
|
|
396
|
+
plot = await self.new_plot(
|
|
397
|
+
path=self.plot_dir / "not_in_keychain",
|
|
398
|
+
plot_keys=PlotKeys(G1Element(), G1Element(), None),
|
|
399
|
+
exclude_plots=True,
|
|
400
|
+
plot_size=plot_size,
|
|
401
|
+
bitfield=bitfield,
|
|
402
|
+
)
|
|
403
|
+
if plot.new_plot:
|
|
404
|
+
existing_plots = False
|
|
405
|
+
await self.refresh_plots()
|
|
406
|
+
assert len(self.plot_manager.plots) == len(self.expected_plots)
|
|
407
|
+
return existing_plots
|
|
408
|
+
|
|
409
|
+
async def new_plot(
|
|
410
|
+
self,
|
|
411
|
+
pool_contract_puzzle_hash: Optional[bytes32] = None,
|
|
412
|
+
path: Optional[Path] = None,
|
|
413
|
+
tmp_dir: Optional[Path] = None,
|
|
414
|
+
plot_keys: Optional[PlotKeys] = None,
|
|
415
|
+
exclude_plots: bool = False,
|
|
416
|
+
plot_size: int = 20,
|
|
417
|
+
bitfield: bool = True,
|
|
418
|
+
) -> BlockToolsNewPlotResult:
|
|
419
|
+
final_dir = self.plot_dir
|
|
420
|
+
if path is not None:
|
|
421
|
+
final_dir = path
|
|
422
|
+
final_dir.mkdir(parents=True, exist_ok=True)
|
|
423
|
+
if tmp_dir is None:
|
|
424
|
+
tmp_dir = self.temp_dir
|
|
425
|
+
params = Params(
|
|
426
|
+
# Can't go much lower than 20, since plots start having no solutions and more buggy
|
|
427
|
+
size=plot_size,
|
|
428
|
+
# Uses many plots for testing, in order to guarantee proofs of space at every height
|
|
429
|
+
num=1,
|
|
430
|
+
buffer=100,
|
|
431
|
+
tmp_dir=Path(tmp_dir),
|
|
432
|
+
tmp2_dir=Path(tmp_dir),
|
|
433
|
+
final_dir=Path(final_dir),
|
|
434
|
+
plotid=None,
|
|
435
|
+
memo=None,
|
|
436
|
+
buckets=0,
|
|
437
|
+
stripe_size=2000,
|
|
438
|
+
num_threads=0,
|
|
439
|
+
nobitfield=not bitfield,
|
|
440
|
+
)
|
|
441
|
+
try:
|
|
442
|
+
if plot_keys is None:
|
|
443
|
+
pool_pk: Optional[G1Element] = None
|
|
444
|
+
pool_address: Optional[str] = None
|
|
445
|
+
if pool_contract_puzzle_hash is None:
|
|
446
|
+
pool_pk = self.pool_pk
|
|
447
|
+
else:
|
|
448
|
+
pool_address = encode_puzzle_hash(pool_contract_puzzle_hash, "xch")
|
|
449
|
+
|
|
450
|
+
plot_keys = PlotKeys(self.farmer_pk, pool_pk, pool_address)
|
|
451
|
+
# No datetime in the filename, to get deterministic filenames and not re-plot
|
|
452
|
+
created, existed = await create_plots(
|
|
453
|
+
params,
|
|
454
|
+
plot_keys,
|
|
455
|
+
use_datetime=False,
|
|
456
|
+
test_private_keys=[AugSchemeMPL.key_gen(std_hash(self.created_plots.to_bytes(2, "big")))],
|
|
457
|
+
)
|
|
458
|
+
self.created_plots += 1
|
|
459
|
+
|
|
460
|
+
plot_id_new: Optional[bytes32] = None
|
|
461
|
+
path_new: Optional[Path] = None
|
|
462
|
+
new_plot: bool = True
|
|
463
|
+
|
|
464
|
+
if len(created):
|
|
465
|
+
assert len(existed) == 0
|
|
466
|
+
plot_id_new, path_new = next(iter(created.items()))
|
|
467
|
+
|
|
468
|
+
if len(existed):
|
|
469
|
+
assert len(created) == 0
|
|
470
|
+
plot_id_new, path_new = next(iter(existed.items()))
|
|
471
|
+
new_plot = False
|
|
472
|
+
assert plot_id_new is not None
|
|
473
|
+
assert path_new is not None
|
|
474
|
+
|
|
475
|
+
if not exclude_plots:
|
|
476
|
+
self.expected_plots[plot_id_new] = path_new
|
|
477
|
+
|
|
478
|
+
return BlockToolsNewPlotResult(plot_id_new, new_plot)
|
|
479
|
+
|
|
480
|
+
except KeyboardInterrupt:
|
|
481
|
+
shutil.rmtree(self.temp_dir, ignore_errors=True)
|
|
482
|
+
sys.exit(1)
|
|
483
|
+
|
|
484
|
+
async def refresh_plots(self) -> None:
|
|
485
|
+
self.plot_manager.refresh_parameter = replace(
|
|
486
|
+
self.plot_manager.refresh_parameter, batch_size=uint32(4 if len(self.expected_plots) % 3 == 0 else 3)
|
|
487
|
+
) # Make sure we have at least some batches + a remainder
|
|
488
|
+
self.plot_manager.trigger_refresh()
|
|
489
|
+
assert self.plot_manager.needs_refresh()
|
|
490
|
+
self.plot_manager.start_refreshing(sleep_interval_ms=1)
|
|
491
|
+
|
|
492
|
+
with anyio.fail_after(delay=adjusted_timeout(120)):
|
|
493
|
+
for backoff in backoff_times():
|
|
494
|
+
if not self.plot_manager.needs_refresh():
|
|
495
|
+
break
|
|
496
|
+
|
|
497
|
+
await asyncio.sleep(backoff)
|
|
498
|
+
|
|
499
|
+
self.plot_manager.stop_refreshing()
|
|
500
|
+
assert not self.plot_manager.needs_refresh()
|
|
501
|
+
|
|
502
|
+
async def delete_plot(self, plot_id: bytes32) -> None:
|
|
503
|
+
assert plot_id in self.expected_plots
|
|
504
|
+
self.expected_plots[plot_id].unlink()
|
|
505
|
+
del self.expected_plots[plot_id]
|
|
506
|
+
await self.refresh_plots()
|
|
507
|
+
|
|
508
|
+
@property
|
|
509
|
+
def config(self) -> dict[str, Any]:
|
|
510
|
+
return copy.deepcopy(self._config)
|
|
511
|
+
|
|
512
|
+
def get_daemon_ssl_context(self) -> ssl.SSLContext:
|
|
513
|
+
crt_path = self.root_path / self.config["daemon_ssl"]["private_crt"]
|
|
514
|
+
key_path = self.root_path / self.config["daemon_ssl"]["private_key"]
|
|
515
|
+
ca_cert_path = self.root_path / self.config["private_ssl_ca"]["crt"]
|
|
516
|
+
ca_key_path = self.root_path / self.config["private_ssl_ca"]["key"]
|
|
517
|
+
return ssl_context_for_client(ca_cert_path, ca_key_path, crt_path, key_path)
|
|
518
|
+
|
|
519
|
+
def get_plot_signature(self, m: bytes32, plot_pk: G1Element) -> G2Element:
|
|
520
|
+
"""
|
|
521
|
+
Returns the plot signature of the header data.
|
|
522
|
+
"""
|
|
523
|
+
farmer_sk = master_sk_to_farmer_sk(self.all_sks[0])
|
|
524
|
+
for plot_info in self.plot_manager.plots.values():
|
|
525
|
+
if plot_pk == plot_info.plot_public_key:
|
|
526
|
+
# Look up local_sk from plot to save locked memory
|
|
527
|
+
if plot_info.prover.get_id() in self.local_sk_cache:
|
|
528
|
+
local_master_sk, pool_pk_or_ph = self.local_sk_cache[plot_info.prover.get_id()]
|
|
529
|
+
else:
|
|
530
|
+
pool_pk_or_ph, _, local_master_sk = parse_plot_info(plot_info.prover.get_memo())
|
|
531
|
+
self.local_sk_cache[plot_info.prover.get_id()] = (local_master_sk, pool_pk_or_ph)
|
|
532
|
+
if isinstance(pool_pk_or_ph, G1Element):
|
|
533
|
+
include_taproot = False
|
|
534
|
+
else:
|
|
535
|
+
assert isinstance(pool_pk_or_ph, bytes32)
|
|
536
|
+
include_taproot = True
|
|
537
|
+
local_sk = master_sk_to_local_sk(local_master_sk)
|
|
538
|
+
agg_pk = generate_plot_public_key(local_sk.get_g1(), farmer_sk.get_g1(), include_taproot)
|
|
539
|
+
assert agg_pk == plot_pk
|
|
540
|
+
harv_share = AugSchemeMPL.sign(local_sk, m, agg_pk)
|
|
541
|
+
farm_share = AugSchemeMPL.sign(farmer_sk, m, agg_pk)
|
|
542
|
+
if include_taproot:
|
|
543
|
+
taproot_sk: PrivateKey = generate_taproot_sk(local_sk.get_g1(), farmer_sk.get_g1())
|
|
544
|
+
taproot_share: G2Element = AugSchemeMPL.sign(taproot_sk, m, agg_pk)
|
|
545
|
+
else:
|
|
546
|
+
taproot_share = G2Element()
|
|
547
|
+
return AugSchemeMPL.aggregate([harv_share, farm_share, taproot_share])
|
|
548
|
+
|
|
549
|
+
raise ValueError(f"Do not have key {plot_pk}")
|
|
550
|
+
|
|
551
|
+
def get_pool_key_signature(self, pool_target: PoolTarget, pool_pk: Optional[G1Element]) -> Optional[G2Element]:
|
|
552
|
+
# Returns the pool signature for the corresponding pk. If no pk is provided, returns None.
|
|
553
|
+
if pool_pk is None:
|
|
554
|
+
return None
|
|
555
|
+
|
|
556
|
+
for sk in self.all_sks:
|
|
557
|
+
sk_child = master_sk_to_pool_sk(sk)
|
|
558
|
+
if sk_child.get_g1() == pool_pk:
|
|
559
|
+
return AugSchemeMPL.sign(sk_child, bytes(pool_target))
|
|
560
|
+
raise ValueError(f"Do not have key {pool_pk}")
|
|
561
|
+
|
|
562
|
+
def get_farmer_wallet_tool(self) -> WalletTool:
|
|
563
|
+
return WalletTool(self.constants, self.farmer_master_sk)
|
|
564
|
+
|
|
565
|
+
def get_pool_wallet_tool(self) -> WalletTool:
|
|
566
|
+
return WalletTool(self.constants, self.pool_master_sk)
|
|
567
|
+
|
|
568
|
+
def get_consecutive_blocks(
|
|
569
|
+
self,
|
|
570
|
+
num_blocks: int,
|
|
571
|
+
block_list_input: Optional[list[FullBlock]] = None,
|
|
572
|
+
*,
|
|
573
|
+
farmer_reward_puzzle_hash: Optional[bytes32] = None,
|
|
574
|
+
pool_reward_puzzle_hash: Optional[bytes32] = None,
|
|
575
|
+
transaction_data: Optional[SpendBundle] = None,
|
|
576
|
+
seed: bytes = b"",
|
|
577
|
+
time_per_block: Optional[float] = None,
|
|
578
|
+
force_overflow: bool = False,
|
|
579
|
+
skip_slots: int = 0, # Force at least this number of empty slots before the first SB
|
|
580
|
+
guarantee_transaction_block: bool = False, # Force that this block must be a tx block
|
|
581
|
+
keep_going_until_tx_block: bool = False, # keep making new blocks until we find a tx block
|
|
582
|
+
normalized_to_identity_cc_eos: bool = False,
|
|
583
|
+
normalized_to_identity_icc_eos: bool = False,
|
|
584
|
+
normalized_to_identity_cc_sp: bool = False,
|
|
585
|
+
normalized_to_identity_cc_ip: bool = False,
|
|
586
|
+
current_time: bool = False,
|
|
587
|
+
block_refs: list[uint32] = [],
|
|
588
|
+
genesis_timestamp: Optional[uint64] = None,
|
|
589
|
+
force_plot_id: Optional[bytes32] = None,
|
|
590
|
+
dummy_block_references: bool = False,
|
|
591
|
+
include_transactions: bool = False,
|
|
592
|
+
skip_overflow: bool = False,
|
|
593
|
+
min_signage_point: int = -1,
|
|
594
|
+
) -> list[FullBlock]:
|
|
595
|
+
assert num_blocks > 0
|
|
596
|
+
if block_list_input is not None:
|
|
597
|
+
block_list = block_list_input.copy()
|
|
598
|
+
else:
|
|
599
|
+
block_list = []
|
|
600
|
+
|
|
601
|
+
tx_block_heights: list[uint32] = []
|
|
602
|
+
if dummy_block_references:
|
|
603
|
+
# block references can only point to transaction blocks, so we need
|
|
604
|
+
# to record which ones are
|
|
605
|
+
for b in block_list:
|
|
606
|
+
if b.transactions_generator is not None:
|
|
607
|
+
tx_block_heights.append(b.height)
|
|
608
|
+
|
|
609
|
+
constants = self.constants
|
|
610
|
+
transaction_data_included = False
|
|
611
|
+
if time_per_block is None:
|
|
612
|
+
time_per_block = float(constants.SUB_SLOT_TIME_TARGET) / float(constants.SLOT_BLOCKS_TARGET)
|
|
613
|
+
|
|
614
|
+
available_coins: list[Coin] = []
|
|
615
|
+
pending_rewards: list[Coin] = []
|
|
616
|
+
wallet: Optional[WalletTool] = None
|
|
617
|
+
rng: Optional[Random] = None
|
|
618
|
+
if include_transactions:
|
|
619
|
+
# when we generate transactions in the chain, the caller cannot also
|
|
620
|
+
# have ownership of the rewards and control the transactions
|
|
621
|
+
assert farmer_reward_puzzle_hash is None
|
|
622
|
+
assert pool_reward_puzzle_hash is None
|
|
623
|
+
assert transaction_data is None
|
|
624
|
+
|
|
625
|
+
for b in block_list:
|
|
626
|
+
for coin in b.get_included_reward_coins():
|
|
627
|
+
if coin.puzzle_hash == self.farmer_ph:
|
|
628
|
+
available_coins.append(coin)
|
|
629
|
+
print(
|
|
630
|
+
f"found {len(available_coins)} reward coins in existing chain."
|
|
631
|
+
"for simplicity, we assume the rewards are all unspent in the original chain"
|
|
632
|
+
)
|
|
633
|
+
wallet = self.get_farmer_wallet_tool()
|
|
634
|
+
rng = Random()
|
|
635
|
+
rng.seed(seed)
|
|
636
|
+
|
|
637
|
+
if farmer_reward_puzzle_hash is None:
|
|
638
|
+
farmer_reward_puzzle_hash = self.farmer_ph
|
|
639
|
+
|
|
640
|
+
if len(block_list) == 0:
|
|
641
|
+
if force_plot_id is not None:
|
|
642
|
+
raise ValueError("Cannot specify plot_id for genesis block")
|
|
643
|
+
initial_block_list_len = 0
|
|
644
|
+
genesis = self.create_genesis_block(
|
|
645
|
+
constants,
|
|
646
|
+
seed,
|
|
647
|
+
force_overflow=force_overflow,
|
|
648
|
+
skip_slots=skip_slots,
|
|
649
|
+
timestamp=(uint64(int(time.time())) if genesis_timestamp is None else genesis_timestamp),
|
|
650
|
+
)
|
|
651
|
+
self.log.info(f"Created block 0 iters: {genesis.total_iters}")
|
|
652
|
+
num_empty_slots_added = skip_slots
|
|
653
|
+
block_list = [genesis]
|
|
654
|
+
num_blocks -= 1
|
|
655
|
+
else:
|
|
656
|
+
initial_block_list_len = len(block_list)
|
|
657
|
+
num_empty_slots_added = uint32(0) # Allows forcing empty slots in the beginning, for testing purposes
|
|
658
|
+
|
|
659
|
+
if num_blocks == 0:
|
|
660
|
+
return block_list
|
|
661
|
+
|
|
662
|
+
blocks: dict[bytes32, BlockRecord]
|
|
663
|
+
if block_list[-1].header_hash == self._block_cache_header:
|
|
664
|
+
height_to_hash = self._block_cache_height_to_hash
|
|
665
|
+
difficulty = self._block_cache_difficulty
|
|
666
|
+
blocks = self._block_cache
|
|
667
|
+
else:
|
|
668
|
+
height_to_hash, difficulty, blocks = load_block_list(block_list, constants)
|
|
669
|
+
|
|
670
|
+
latest_block: BlockRecord = blocks[block_list[-1].header_hash]
|
|
671
|
+
curr = latest_block
|
|
672
|
+
while not curr.is_transaction_block:
|
|
673
|
+
curr = blocks[curr.prev_hash]
|
|
674
|
+
assert curr.timestamp is not None
|
|
675
|
+
last_timestamp = float(curr.timestamp)
|
|
676
|
+
start_height = curr.height
|
|
677
|
+
|
|
678
|
+
curr = latest_block
|
|
679
|
+
blocks_added_this_sub_slot = 1
|
|
680
|
+
|
|
681
|
+
while not curr.first_in_sub_slot:
|
|
682
|
+
curr = blocks[curr.prev_hash]
|
|
683
|
+
blocks_added_this_sub_slot += 1
|
|
684
|
+
|
|
685
|
+
finished_sub_slots_at_sp: list[EndOfSubSlotBundle] = [] # Sub-slots since last block, up to signage point
|
|
686
|
+
finished_sub_slots_at_ip: list[EndOfSubSlotBundle] = [] # Sub-slots since last block, up to infusion point
|
|
687
|
+
sub_slot_iters: uint64 = latest_block.sub_slot_iters # The number of iterations in one sub-slot
|
|
688
|
+
same_slot_as_last = True # Only applies to first slot, to prevent old blocks from being added
|
|
689
|
+
sub_slot_start_total_iters: uint128 = latest_block.ip_sub_slot_total_iters(constants)
|
|
690
|
+
sub_slots_finished = 0
|
|
691
|
+
# this variable is true whenever there is a pending sub-epoch or epoch that needs to be added in the next block.
|
|
692
|
+
pending_ses: bool = False
|
|
693
|
+
|
|
694
|
+
# Start at the last block in block list
|
|
695
|
+
# Get the challenge for that slot
|
|
696
|
+
while True:
|
|
697
|
+
slot_cc_challenge, slot_rc_challenge = get_challenges(
|
|
698
|
+
constants,
|
|
699
|
+
blocks,
|
|
700
|
+
finished_sub_slots_at_sp,
|
|
701
|
+
latest_block.header_hash,
|
|
702
|
+
)
|
|
703
|
+
prev_num_of_blocks = num_blocks
|
|
704
|
+
if num_empty_slots_added < skip_slots:
|
|
705
|
+
# If did not reach the target slots to skip, don't make any proofs for this sub-slot
|
|
706
|
+
num_empty_slots_added += 1
|
|
707
|
+
else:
|
|
708
|
+
# Loop over every signage point (Except for the last ones, which are used for overflows)
|
|
709
|
+
for signage_point_index in range(0, constants.NUM_SPS_SUB_SLOT - constants.NUM_SP_INTERVALS_EXTRA):
|
|
710
|
+
curr = latest_block
|
|
711
|
+
while curr.total_iters > sub_slot_start_total_iters + calculate_sp_iters(
|
|
712
|
+
constants, sub_slot_iters, uint8(signage_point_index)
|
|
713
|
+
):
|
|
714
|
+
if curr.height == 0:
|
|
715
|
+
break
|
|
716
|
+
curr = blocks[curr.prev_hash]
|
|
717
|
+
if curr.total_iters > sub_slot_start_total_iters:
|
|
718
|
+
finished_sub_slots_at_sp = []
|
|
719
|
+
|
|
720
|
+
if same_slot_as_last:
|
|
721
|
+
if signage_point_index < latest_block.signage_point_index:
|
|
722
|
+
# Ignore this signage_point because it's in the past
|
|
723
|
+
continue
|
|
724
|
+
|
|
725
|
+
if signage_point_index <= min_signage_point:
|
|
726
|
+
# start farming blocks after min_signage_point
|
|
727
|
+
continue
|
|
728
|
+
|
|
729
|
+
signage_point: SignagePoint = get_signage_point(
|
|
730
|
+
constants,
|
|
731
|
+
BlockCache(blocks),
|
|
732
|
+
latest_block,
|
|
733
|
+
sub_slot_start_total_iters,
|
|
734
|
+
uint8(signage_point_index),
|
|
735
|
+
finished_sub_slots_at_sp,
|
|
736
|
+
sub_slot_iters,
|
|
737
|
+
normalized_to_identity_cc_sp,
|
|
738
|
+
)
|
|
739
|
+
if signage_point_index == 0:
|
|
740
|
+
cc_sp_output_hash: bytes32 = slot_cc_challenge
|
|
741
|
+
else:
|
|
742
|
+
assert signage_point.cc_vdf is not None
|
|
743
|
+
cc_sp_output_hash = signage_point.cc_vdf.output.get_hash()
|
|
744
|
+
|
|
745
|
+
qualified_proofs: list[tuple[uint64, ProofOfSpace]] = self.get_pospaces_for_challenge(
|
|
746
|
+
constants,
|
|
747
|
+
slot_cc_challenge,
|
|
748
|
+
cc_sp_output_hash,
|
|
749
|
+
seed,
|
|
750
|
+
difficulty,
|
|
751
|
+
sub_slot_iters,
|
|
752
|
+
curr.height,
|
|
753
|
+
force_plot_id=force_plot_id,
|
|
754
|
+
)
|
|
755
|
+
|
|
756
|
+
for required_iters, proof_of_space in sorted(qualified_proofs, key=lambda t: t[0]):
|
|
757
|
+
if blocks_added_this_sub_slot == constants.MAX_SUB_SLOT_BLOCKS or force_overflow:
|
|
758
|
+
break
|
|
759
|
+
if same_slot_as_last:
|
|
760
|
+
if signage_point_index == latest_block.signage_point_index:
|
|
761
|
+
# Ignore this block because it's in the past
|
|
762
|
+
if required_iters <= latest_block.required_iters:
|
|
763
|
+
continue
|
|
764
|
+
|
|
765
|
+
assert latest_block.header_hash in blocks
|
|
766
|
+
additions = None
|
|
767
|
+
removals = None
|
|
768
|
+
if transaction_data_included:
|
|
769
|
+
transaction_data = None
|
|
770
|
+
block_refs = []
|
|
771
|
+
if transaction_data is not None:
|
|
772
|
+
additions = compute_additions_unchecked(transaction_data)
|
|
773
|
+
removals = transaction_data.removals()
|
|
774
|
+
elif include_transactions:
|
|
775
|
+
assert wallet is not None
|
|
776
|
+
assert rng is not None
|
|
777
|
+
transaction_data, additions = make_spend_bundle(available_coins, wallet, rng)
|
|
778
|
+
removals = transaction_data.removals()
|
|
779
|
+
transaction_data_included = False
|
|
780
|
+
|
|
781
|
+
assert last_timestamp is not None
|
|
782
|
+
if proof_of_space.pool_contract_puzzle_hash is not None:
|
|
783
|
+
if pool_reward_puzzle_hash is not None:
|
|
784
|
+
# The caller wants to be paid to a specific address, but this PoSpace is tied to an
|
|
785
|
+
# address, so continue until a proof of space tied to a pk is found
|
|
786
|
+
continue
|
|
787
|
+
pool_target = PoolTarget(proof_of_space.pool_contract_puzzle_hash, uint32(0))
|
|
788
|
+
else:
|
|
789
|
+
if pool_reward_puzzle_hash is not None:
|
|
790
|
+
pool_target = PoolTarget(pool_reward_puzzle_hash, uint32(0))
|
|
791
|
+
else:
|
|
792
|
+
pool_target = PoolTarget(self.pool_ph, uint32(0))
|
|
793
|
+
|
|
794
|
+
block_generator: Optional[BlockGenerator]
|
|
795
|
+
if transaction_data is not None:
|
|
796
|
+
if start_height >= constants.HARD_FORK_HEIGHT:
|
|
797
|
+
block_generator = simple_solution_generator_backrefs(transaction_data)
|
|
798
|
+
block_refs = []
|
|
799
|
+
else:
|
|
800
|
+
block_generator = simple_solution_generator(transaction_data)
|
|
801
|
+
|
|
802
|
+
aggregate_signature = transaction_data.aggregated_signature
|
|
803
|
+
else:
|
|
804
|
+
block_generator = None
|
|
805
|
+
aggregate_signature = G2Element()
|
|
806
|
+
|
|
807
|
+
if dummy_block_references:
|
|
808
|
+
if block_generator is None:
|
|
809
|
+
program = SerializedProgram.from_bytes(solution_generator([]))
|
|
810
|
+
block_generator = BlockGenerator(program, [])
|
|
811
|
+
|
|
812
|
+
if len(tx_block_heights) > 4:
|
|
813
|
+
block_refs.extend(
|
|
814
|
+
[
|
|
815
|
+
tx_block_heights[1],
|
|
816
|
+
tx_block_heights[len(tx_block_heights) // 2],
|
|
817
|
+
tx_block_heights[-2],
|
|
818
|
+
]
|
|
819
|
+
)
|
|
820
|
+
(
|
|
821
|
+
full_block,
|
|
822
|
+
block_record,
|
|
823
|
+
new_timestamp,
|
|
824
|
+
) = get_full_block_and_block_record(
|
|
825
|
+
constants,
|
|
826
|
+
blocks,
|
|
827
|
+
sub_slot_start_total_iters,
|
|
828
|
+
uint8(signage_point_index),
|
|
829
|
+
proof_of_space,
|
|
830
|
+
slot_cc_challenge,
|
|
831
|
+
slot_rc_challenge,
|
|
832
|
+
farmer_reward_puzzle_hash,
|
|
833
|
+
pool_target,
|
|
834
|
+
last_timestamp,
|
|
835
|
+
start_height,
|
|
836
|
+
time_per_block,
|
|
837
|
+
block_generator,
|
|
838
|
+
aggregate_signature,
|
|
839
|
+
additions,
|
|
840
|
+
removals,
|
|
841
|
+
height_to_hash,
|
|
842
|
+
difficulty,
|
|
843
|
+
required_iters,
|
|
844
|
+
sub_slot_iters,
|
|
845
|
+
self.get_plot_signature,
|
|
846
|
+
self.get_pool_key_signature,
|
|
847
|
+
finished_sub_slots_at_ip,
|
|
848
|
+
signage_point,
|
|
849
|
+
latest_block,
|
|
850
|
+
seed,
|
|
851
|
+
normalized_to_identity_cc_ip=normalized_to_identity_cc_ip,
|
|
852
|
+
current_time=current_time,
|
|
853
|
+
block_refs=block_refs,
|
|
854
|
+
)
|
|
855
|
+
if block_record.is_transaction_block:
|
|
856
|
+
transaction_data_included = True
|
|
857
|
+
block_refs = []
|
|
858
|
+
keep_going_until_tx_block = False
|
|
859
|
+
assert full_block.foliage_transaction_block is not None
|
|
860
|
+
elif guarantee_transaction_block:
|
|
861
|
+
continue
|
|
862
|
+
# print(f"{full_block.height:4}: difficulty {difficulty} "
|
|
863
|
+
# f"time: {new_timestamp - last_timestamp:0.2f} "
|
|
864
|
+
# f"additions: {len(additions) if block_record.is_transaction_block else 0:2} "
|
|
865
|
+
# f"removals: {len(removals) if block_record.is_transaction_block else 0:2} "
|
|
866
|
+
# f"refs: {len(full_block.transactions_generator_ref_list):3} "
|
|
867
|
+
# f"tx: {block_record.is_transaction_block}")
|
|
868
|
+
last_timestamp = new_timestamp
|
|
869
|
+
block_list.append(full_block)
|
|
870
|
+
|
|
871
|
+
if include_transactions:
|
|
872
|
+
for coin in full_block.get_included_reward_coins():
|
|
873
|
+
if coin.puzzle_hash == self.farmer_ph:
|
|
874
|
+
pending_rewards.append(coin)
|
|
875
|
+
if full_block.is_transaction_block():
|
|
876
|
+
available_coins.extend(pending_rewards)
|
|
877
|
+
pending_rewards = []
|
|
878
|
+
|
|
879
|
+
if full_block.transactions_generator is not None:
|
|
880
|
+
tx_block_heights.append(full_block.height)
|
|
881
|
+
|
|
882
|
+
blocks_added_this_sub_slot += 1
|
|
883
|
+
|
|
884
|
+
blocks[full_block.header_hash] = block_record
|
|
885
|
+
self.log.info(
|
|
886
|
+
f"Created block {block_record.height} ove=False, iters {block_record.total_iters}"
|
|
887
|
+
)
|
|
888
|
+
height_to_hash[uint32(full_block.height)] = full_block.header_hash
|
|
889
|
+
latest_block = blocks[full_block.header_hash]
|
|
890
|
+
finished_sub_slots_at_ip = []
|
|
891
|
+
num_blocks -= 1
|
|
892
|
+
if num_blocks <= 0 and not keep_going_until_tx_block:
|
|
893
|
+
self._block_cache_header = block_list[-1].header_hash
|
|
894
|
+
self._block_cache_height_to_hash = height_to_hash
|
|
895
|
+
self._block_cache_difficulty = difficulty
|
|
896
|
+
self._block_cache = blocks
|
|
897
|
+
return block_list
|
|
898
|
+
|
|
899
|
+
# Finish the end of sub-slot and try again next sub-slot
|
|
900
|
+
# End of sub-slot logic
|
|
901
|
+
if len(finished_sub_slots_at_ip) == 0:
|
|
902
|
+
# Block has been created within this sub-slot
|
|
903
|
+
eos_iters: uint64 = uint64(sub_slot_iters - (latest_block.total_iters - sub_slot_start_total_iters))
|
|
904
|
+
cc_input: ClassgroupElement = latest_block.challenge_vdf_output
|
|
905
|
+
rc_challenge: bytes32 = latest_block.reward_infusion_new_challenge
|
|
906
|
+
else:
|
|
907
|
+
# No blocks were successfully created within this sub-slot
|
|
908
|
+
eos_iters = sub_slot_iters
|
|
909
|
+
cc_input = ClassgroupElement.get_default_element()
|
|
910
|
+
rc_challenge = slot_rc_challenge
|
|
911
|
+
cc_vdf, cc_proof = get_vdf_info_and_proof(
|
|
912
|
+
constants,
|
|
913
|
+
cc_input,
|
|
914
|
+
slot_cc_challenge,
|
|
915
|
+
eos_iters,
|
|
916
|
+
)
|
|
917
|
+
rc_vdf, rc_proof = get_vdf_info_and_proof(
|
|
918
|
+
constants,
|
|
919
|
+
ClassgroupElement.get_default_element(),
|
|
920
|
+
rc_challenge,
|
|
921
|
+
eos_iters,
|
|
922
|
+
)
|
|
923
|
+
|
|
924
|
+
eos_deficit: uint8 = (
|
|
925
|
+
latest_block.deficit if latest_block.deficit > 0 else constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK
|
|
926
|
+
)
|
|
927
|
+
icc_eos_vdf, icc_ip_proof = get_icc(
|
|
928
|
+
constants,
|
|
929
|
+
uint128(sub_slot_start_total_iters + sub_slot_iters),
|
|
930
|
+
finished_sub_slots_at_ip,
|
|
931
|
+
latest_block,
|
|
932
|
+
blocks,
|
|
933
|
+
sub_slot_start_total_iters,
|
|
934
|
+
eos_deficit,
|
|
935
|
+
)
|
|
936
|
+
# End of slot vdf info for icc and cc have to be from challenge block or start of slot, respectively,
|
|
937
|
+
# in order for light clients to validate.
|
|
938
|
+
cc_vdf = VDFInfo(cc_vdf.challenge, sub_slot_iters, cc_vdf.output)
|
|
939
|
+
if normalized_to_identity_cc_eos:
|
|
940
|
+
_, cc_proof = get_vdf_info_and_proof(
|
|
941
|
+
constants,
|
|
942
|
+
ClassgroupElement.get_default_element(),
|
|
943
|
+
cc_vdf.challenge,
|
|
944
|
+
sub_slot_iters,
|
|
945
|
+
True,
|
|
946
|
+
)
|
|
947
|
+
# generate sub_epoch_summary, and if the last block was the last block of the sub-epoch or epoch
|
|
948
|
+
# include the hash in the next sub-slot
|
|
949
|
+
sub_epoch_summary: Optional[SubEpochSummary] = None
|
|
950
|
+
if not pending_ses: # if we just created a sub-epoch summary, we can at least skip another sub-slot
|
|
951
|
+
sub_epoch_summary = next_sub_epoch_summary(
|
|
952
|
+
constants,
|
|
953
|
+
BlockCache(blocks),
|
|
954
|
+
latest_block.required_iters,
|
|
955
|
+
block_list[-1],
|
|
956
|
+
False,
|
|
957
|
+
)
|
|
958
|
+
if sub_epoch_summary is not None: # the previous block is the last block of the sub-epoch or epoch
|
|
959
|
+
pending_ses = True
|
|
960
|
+
ses_hash: Optional[bytes32] = sub_epoch_summary.get_hash()
|
|
961
|
+
# if the last block is the last block of the epoch, we set the new sub-slot iters and difficulty
|
|
962
|
+
new_sub_slot_iters: Optional[uint64] = sub_epoch_summary.new_sub_slot_iters
|
|
963
|
+
new_difficulty: Optional[uint64] = sub_epoch_summary.new_difficulty
|
|
964
|
+
|
|
965
|
+
self.log.info(f"Sub epoch summary: {sub_epoch_summary} for block {latest_block.height + 1}")
|
|
966
|
+
else: # the previous block is not the last block of the sub-epoch or epoch
|
|
967
|
+
pending_ses = False
|
|
968
|
+
ses_hash = None
|
|
969
|
+
new_sub_slot_iters = None
|
|
970
|
+
new_difficulty = None
|
|
971
|
+
|
|
972
|
+
if icc_eos_vdf is not None:
|
|
973
|
+
# Icc vdf (Deficit of latest block is <= 4)
|
|
974
|
+
if len(finished_sub_slots_at_ip) == 0:
|
|
975
|
+
# This means there are blocks in this sub-slot
|
|
976
|
+
curr = latest_block
|
|
977
|
+
while not curr.is_challenge_block(constants) and not curr.first_in_sub_slot:
|
|
978
|
+
curr = blocks[curr.prev_hash]
|
|
979
|
+
if curr.is_challenge_block(constants):
|
|
980
|
+
icc_eos_iters = uint64(sub_slot_start_total_iters + sub_slot_iters - curr.total_iters)
|
|
981
|
+
else:
|
|
982
|
+
icc_eos_iters = sub_slot_iters
|
|
983
|
+
else:
|
|
984
|
+
# This means there are no blocks in this sub-slot
|
|
985
|
+
icc_eos_iters = sub_slot_iters
|
|
986
|
+
icc_eos_vdf = VDFInfo(
|
|
987
|
+
icc_eos_vdf.challenge,
|
|
988
|
+
icc_eos_iters,
|
|
989
|
+
icc_eos_vdf.output,
|
|
990
|
+
)
|
|
991
|
+
if normalized_to_identity_icc_eos:
|
|
992
|
+
_, icc_ip_proof = get_vdf_info_and_proof(
|
|
993
|
+
constants,
|
|
994
|
+
ClassgroupElement.get_default_element(),
|
|
995
|
+
icc_eos_vdf.challenge,
|
|
996
|
+
icc_eos_iters,
|
|
997
|
+
True,
|
|
998
|
+
)
|
|
999
|
+
icc_sub_slot: Optional[InfusedChallengeChainSubSlot] = InfusedChallengeChainSubSlot(icc_eos_vdf)
|
|
1000
|
+
assert icc_sub_slot is not None
|
|
1001
|
+
icc_sub_slot_hash = icc_sub_slot.get_hash() if latest_block.deficit == 0 else None
|
|
1002
|
+
cc_sub_slot = ChallengeChainSubSlot(
|
|
1003
|
+
cc_vdf,
|
|
1004
|
+
icc_sub_slot_hash,
|
|
1005
|
+
ses_hash,
|
|
1006
|
+
new_sub_slot_iters,
|
|
1007
|
+
new_difficulty,
|
|
1008
|
+
)
|
|
1009
|
+
else:
|
|
1010
|
+
# No icc
|
|
1011
|
+
icc_sub_slot = None
|
|
1012
|
+
cc_sub_slot = ChallengeChainSubSlot(cc_vdf, None, ses_hash, new_sub_slot_iters, new_difficulty)
|
|
1013
|
+
|
|
1014
|
+
finished_sub_slots_at_ip.append(
|
|
1015
|
+
EndOfSubSlotBundle(
|
|
1016
|
+
cc_sub_slot,
|
|
1017
|
+
icc_sub_slot,
|
|
1018
|
+
RewardChainSubSlot(
|
|
1019
|
+
rc_vdf,
|
|
1020
|
+
cc_sub_slot.get_hash(),
|
|
1021
|
+
icc_sub_slot.get_hash() if icc_sub_slot is not None else None,
|
|
1022
|
+
eos_deficit,
|
|
1023
|
+
),
|
|
1024
|
+
SubSlotProofs(cc_proof, icc_ip_proof, rc_proof),
|
|
1025
|
+
)
|
|
1026
|
+
)
|
|
1027
|
+
|
|
1028
|
+
finished_sub_slots_eos = finished_sub_slots_at_ip.copy()
|
|
1029
|
+
latest_block_eos = latest_block
|
|
1030
|
+
overflow_cc_challenge = finished_sub_slots_at_ip[-1].challenge_chain.get_hash()
|
|
1031
|
+
overflow_rc_challenge = finished_sub_slots_at_ip[-1].reward_chain.get_hash()
|
|
1032
|
+
additions = None
|
|
1033
|
+
removals = None
|
|
1034
|
+
if transaction_data_included:
|
|
1035
|
+
transaction_data = None
|
|
1036
|
+
if transaction_data is not None:
|
|
1037
|
+
additions = compute_additions_unchecked(transaction_data)
|
|
1038
|
+
removals = transaction_data.removals()
|
|
1039
|
+
elif include_transactions:
|
|
1040
|
+
assert wallet is not None
|
|
1041
|
+
assert rng is not None
|
|
1042
|
+
transaction_data, additions = make_spend_bundle(available_coins, wallet, rng)
|
|
1043
|
+
removals = transaction_data.removals()
|
|
1044
|
+
transaction_data_included = False
|
|
1045
|
+
sub_slots_finished += 1
|
|
1046
|
+
self.log.info(
|
|
1047
|
+
f"Sub slot finished. blocks included: {blocks_added_this_sub_slot} blocks_per_slot: "
|
|
1048
|
+
f"{(len(block_list) - initial_block_list_len) / sub_slots_finished}"
|
|
1049
|
+
f"Sub Epoch Summary Included: {sub_epoch_summary is not None} "
|
|
1050
|
+
)
|
|
1051
|
+
blocks_added_this_sub_slot = 0 # Sub slot ended, overflows are in next sub slot
|
|
1052
|
+
|
|
1053
|
+
# Handle overflows: No overflows on new epoch or sub-epoch
|
|
1054
|
+
|
|
1055
|
+
if (
|
|
1056
|
+
new_sub_slot_iters is None
|
|
1057
|
+
and num_empty_slots_added >= skip_slots
|
|
1058
|
+
and not pending_ses
|
|
1059
|
+
and not skip_overflow
|
|
1060
|
+
):
|
|
1061
|
+
for signage_point_index in range(
|
|
1062
|
+
constants.NUM_SPS_SUB_SLOT - constants.NUM_SP_INTERVALS_EXTRA,
|
|
1063
|
+
constants.NUM_SPS_SUB_SLOT,
|
|
1064
|
+
):
|
|
1065
|
+
if same_slot_as_last and signage_point_index <= min_signage_point:
|
|
1066
|
+
# start farming blocks after min_signage_point
|
|
1067
|
+
continue
|
|
1068
|
+
# note that we are passing in the finished slots which include the last slot
|
|
1069
|
+
signage_point = get_signage_point(
|
|
1070
|
+
constants,
|
|
1071
|
+
BlockCache(blocks),
|
|
1072
|
+
latest_block_eos,
|
|
1073
|
+
sub_slot_start_total_iters,
|
|
1074
|
+
uint8(signage_point_index),
|
|
1075
|
+
finished_sub_slots_eos,
|
|
1076
|
+
sub_slot_iters,
|
|
1077
|
+
normalized_to_identity_cc_sp,
|
|
1078
|
+
)
|
|
1079
|
+
if signage_point_index == 0:
|
|
1080
|
+
cc_sp_output_hash = slot_cc_challenge
|
|
1081
|
+
else:
|
|
1082
|
+
assert signage_point is not None
|
|
1083
|
+
assert signage_point.cc_vdf is not None
|
|
1084
|
+
cc_sp_output_hash = signage_point.cc_vdf.output.get_hash()
|
|
1085
|
+
|
|
1086
|
+
# If did not reach the target slots to skip, don't make any proofs for this sub-slot
|
|
1087
|
+
qualified_proofs = self.get_pospaces_for_challenge(
|
|
1088
|
+
constants,
|
|
1089
|
+
slot_cc_challenge,
|
|
1090
|
+
cc_sp_output_hash,
|
|
1091
|
+
seed,
|
|
1092
|
+
difficulty,
|
|
1093
|
+
sub_slot_iters,
|
|
1094
|
+
curr.height,
|
|
1095
|
+
force_plot_id=force_plot_id,
|
|
1096
|
+
)
|
|
1097
|
+
for required_iters, proof_of_space in sorted(qualified_proofs, key=lambda t: t[0]):
|
|
1098
|
+
if blocks_added_this_sub_slot == constants.MAX_SUB_SLOT_BLOCKS:
|
|
1099
|
+
break
|
|
1100
|
+
assert last_timestamp is not None
|
|
1101
|
+
if proof_of_space.pool_contract_puzzle_hash is not None:
|
|
1102
|
+
if pool_reward_puzzle_hash is not None:
|
|
1103
|
+
# The caller wants to be paid to a specific address, but this PoSpace is tied to an
|
|
1104
|
+
# address, so continue until a proof of space tied to a pk is found
|
|
1105
|
+
continue
|
|
1106
|
+
pool_target = PoolTarget(proof_of_space.pool_contract_puzzle_hash, uint32(0))
|
|
1107
|
+
else:
|
|
1108
|
+
if pool_reward_puzzle_hash is not None:
|
|
1109
|
+
pool_target = PoolTarget(pool_reward_puzzle_hash, uint32(0))
|
|
1110
|
+
else:
|
|
1111
|
+
pool_target = PoolTarget(self.pool_ph, uint32(0))
|
|
1112
|
+
if transaction_data is not None:
|
|
1113
|
+
if start_height >= constants.HARD_FORK_HEIGHT:
|
|
1114
|
+
block_generator = simple_solution_generator_backrefs(transaction_data)
|
|
1115
|
+
block_refs = []
|
|
1116
|
+
else:
|
|
1117
|
+
block_generator = simple_solution_generator(transaction_data)
|
|
1118
|
+
aggregate_signature = transaction_data.aggregated_signature
|
|
1119
|
+
else:
|
|
1120
|
+
block_generator = None
|
|
1121
|
+
aggregate_signature = G2Element()
|
|
1122
|
+
|
|
1123
|
+
if dummy_block_references:
|
|
1124
|
+
if block_generator is None:
|
|
1125
|
+
program = SerializedProgram.from_bytes(solution_generator([]))
|
|
1126
|
+
block_generator = BlockGenerator(program, [])
|
|
1127
|
+
|
|
1128
|
+
if len(tx_block_heights) > 4:
|
|
1129
|
+
block_refs.extend(
|
|
1130
|
+
[
|
|
1131
|
+
tx_block_heights[1],
|
|
1132
|
+
tx_block_heights[len(tx_block_heights) // 2],
|
|
1133
|
+
tx_block_heights[-2],
|
|
1134
|
+
]
|
|
1135
|
+
)
|
|
1136
|
+
|
|
1137
|
+
(
|
|
1138
|
+
full_block,
|
|
1139
|
+
block_record,
|
|
1140
|
+
new_timestamp,
|
|
1141
|
+
) = get_full_block_and_block_record(
|
|
1142
|
+
constants,
|
|
1143
|
+
blocks,
|
|
1144
|
+
sub_slot_start_total_iters,
|
|
1145
|
+
uint8(signage_point_index),
|
|
1146
|
+
proof_of_space,
|
|
1147
|
+
slot_cc_challenge,
|
|
1148
|
+
slot_rc_challenge,
|
|
1149
|
+
farmer_reward_puzzle_hash,
|
|
1150
|
+
pool_target,
|
|
1151
|
+
last_timestamp,
|
|
1152
|
+
start_height,
|
|
1153
|
+
time_per_block,
|
|
1154
|
+
block_generator,
|
|
1155
|
+
aggregate_signature,
|
|
1156
|
+
additions,
|
|
1157
|
+
removals,
|
|
1158
|
+
height_to_hash,
|
|
1159
|
+
difficulty,
|
|
1160
|
+
required_iters,
|
|
1161
|
+
sub_slot_iters,
|
|
1162
|
+
self.get_plot_signature,
|
|
1163
|
+
self.get_pool_key_signature,
|
|
1164
|
+
finished_sub_slots_at_ip,
|
|
1165
|
+
signage_point,
|
|
1166
|
+
latest_block,
|
|
1167
|
+
seed,
|
|
1168
|
+
overflow_cc_challenge=overflow_cc_challenge,
|
|
1169
|
+
overflow_rc_challenge=overflow_rc_challenge,
|
|
1170
|
+
normalized_to_identity_cc_ip=normalized_to_identity_cc_ip,
|
|
1171
|
+
current_time=current_time,
|
|
1172
|
+
block_refs=block_refs,
|
|
1173
|
+
)
|
|
1174
|
+
|
|
1175
|
+
if block_record.is_transaction_block:
|
|
1176
|
+
transaction_data_included = True
|
|
1177
|
+
block_refs = []
|
|
1178
|
+
keep_going_until_tx_block = False
|
|
1179
|
+
assert full_block.foliage_transaction_block is not None
|
|
1180
|
+
elif guarantee_transaction_block:
|
|
1181
|
+
continue
|
|
1182
|
+
# print(f"{full_block.height:4}: difficulty {difficulty} "
|
|
1183
|
+
# f"time: {new_timestamp - last_timestamp:0.2f} "
|
|
1184
|
+
# f"additions: {len(additions) if block_record.is_transaction_block else 0:2} "
|
|
1185
|
+
# f"removals: {len(removals) if block_record.is_transaction_block else 0:2} "
|
|
1186
|
+
# f"refs: {len(full_block.transactions_generator_ref_list):3} "
|
|
1187
|
+
# f"tx: {block_record.is_transaction_block}")
|
|
1188
|
+
last_timestamp = new_timestamp
|
|
1189
|
+
|
|
1190
|
+
block_list.append(full_block)
|
|
1191
|
+
|
|
1192
|
+
if include_transactions:
|
|
1193
|
+
for coin in full_block.get_included_reward_coins():
|
|
1194
|
+
if coin.puzzle_hash == self.farmer_ph:
|
|
1195
|
+
pending_rewards.append(coin)
|
|
1196
|
+
if full_block.is_transaction_block():
|
|
1197
|
+
available_coins.extend(pending_rewards)
|
|
1198
|
+
pending_rewards = []
|
|
1199
|
+
|
|
1200
|
+
if full_block.transactions_generator is not None:
|
|
1201
|
+
tx_block_heights.append(full_block.height)
|
|
1202
|
+
|
|
1203
|
+
blocks_added_this_sub_slot += 1
|
|
1204
|
+
self.log.info(f"Created block {block_record.height} ov=True, iters {block_record.total_iters}")
|
|
1205
|
+
num_blocks -= 1
|
|
1206
|
+
|
|
1207
|
+
blocks[full_block.header_hash] = block_record
|
|
1208
|
+
height_to_hash[uint32(full_block.height)] = full_block.header_hash
|
|
1209
|
+
latest_block = blocks[full_block.header_hash]
|
|
1210
|
+
finished_sub_slots_at_ip = []
|
|
1211
|
+
|
|
1212
|
+
if num_blocks <= 0 and not keep_going_until_tx_block:
|
|
1213
|
+
self._block_cache_header = block_list[-1].header_hash
|
|
1214
|
+
self._block_cache_height_to_hash = height_to_hash
|
|
1215
|
+
self._block_cache_difficulty = difficulty
|
|
1216
|
+
self._block_cache = blocks
|
|
1217
|
+
return block_list
|
|
1218
|
+
|
|
1219
|
+
finished_sub_slots_at_sp = finished_sub_slots_eos.copy()
|
|
1220
|
+
same_slot_as_last = False
|
|
1221
|
+
sub_slot_start_total_iters = uint128(sub_slot_start_total_iters + sub_slot_iters)
|
|
1222
|
+
if num_blocks < prev_num_of_blocks:
|
|
1223
|
+
num_empty_slots_added += 1
|
|
1224
|
+
|
|
1225
|
+
if new_sub_slot_iters is not None and new_difficulty is not None: # new epoch
|
|
1226
|
+
sub_slot_iters = new_sub_slot_iters
|
|
1227
|
+
difficulty = new_difficulty
|
|
1228
|
+
|
|
1229
|
+
def create_genesis_block(
|
|
1230
|
+
self,
|
|
1231
|
+
constants: ConsensusConstants,
|
|
1232
|
+
seed: bytes = b"",
|
|
1233
|
+
timestamp: Optional[uint64] = None,
|
|
1234
|
+
force_overflow: bool = False,
|
|
1235
|
+
skip_slots: int = 0,
|
|
1236
|
+
) -> FullBlock:
|
|
1237
|
+
if timestamp is None:
|
|
1238
|
+
timestamp = uint64(int(time.time()))
|
|
1239
|
+
|
|
1240
|
+
finished_sub_slots: list[EndOfSubSlotBundle] = []
|
|
1241
|
+
unfinished_block: Optional[UnfinishedBlock] = None
|
|
1242
|
+
ip_iters: uint64 = uint64(0)
|
|
1243
|
+
sub_slot_total_iters: uint128 = uint128(0)
|
|
1244
|
+
|
|
1245
|
+
# Keep trying until we get a good proof of space that also passes sp filter
|
|
1246
|
+
while True:
|
|
1247
|
+
cc_challenge, rc_challenge = get_challenges(constants, {}, finished_sub_slots, None)
|
|
1248
|
+
for signage_point_index in range(0, constants.NUM_SPS_SUB_SLOT):
|
|
1249
|
+
signage_point: SignagePoint = get_signage_point(
|
|
1250
|
+
constants,
|
|
1251
|
+
BlockCache({}),
|
|
1252
|
+
None,
|
|
1253
|
+
sub_slot_total_iters,
|
|
1254
|
+
uint8(signage_point_index),
|
|
1255
|
+
finished_sub_slots,
|
|
1256
|
+
constants.SUB_SLOT_ITERS_STARTING,
|
|
1257
|
+
)
|
|
1258
|
+
if signage_point_index == 0:
|
|
1259
|
+
cc_sp_output_hash: bytes32 = cc_challenge
|
|
1260
|
+
else:
|
|
1261
|
+
assert signage_point is not None
|
|
1262
|
+
assert signage_point.cc_vdf is not None
|
|
1263
|
+
cc_sp_output_hash = signage_point.cc_vdf.output.get_hash()
|
|
1264
|
+
# If did not reach the target slots to skip, don't make any proofs for this sub-slot
|
|
1265
|
+
# we're creating the genesis block, its height is always 0
|
|
1266
|
+
qualified_proofs: list[tuple[uint64, ProofOfSpace]] = self.get_pospaces_for_challenge(
|
|
1267
|
+
constants,
|
|
1268
|
+
cc_challenge,
|
|
1269
|
+
cc_sp_output_hash,
|
|
1270
|
+
seed,
|
|
1271
|
+
constants.DIFFICULTY_STARTING,
|
|
1272
|
+
constants.SUB_SLOT_ITERS_STARTING,
|
|
1273
|
+
uint32(0),
|
|
1274
|
+
)
|
|
1275
|
+
|
|
1276
|
+
# Try each of the proofs of space
|
|
1277
|
+
for required_iters, proof_of_space in qualified_proofs:
|
|
1278
|
+
sp_iters: uint64 = calculate_sp_iters(
|
|
1279
|
+
constants,
|
|
1280
|
+
uint64(constants.SUB_SLOT_ITERS_STARTING),
|
|
1281
|
+
uint8(signage_point_index),
|
|
1282
|
+
)
|
|
1283
|
+
ip_iters = calculate_ip_iters(
|
|
1284
|
+
constants,
|
|
1285
|
+
uint64(constants.SUB_SLOT_ITERS_STARTING),
|
|
1286
|
+
uint8(signage_point_index),
|
|
1287
|
+
required_iters,
|
|
1288
|
+
)
|
|
1289
|
+
is_overflow = is_overflow_block(constants, uint8(signage_point_index))
|
|
1290
|
+
if force_overflow and not is_overflow:
|
|
1291
|
+
continue
|
|
1292
|
+
if len(finished_sub_slots) < skip_slots:
|
|
1293
|
+
continue
|
|
1294
|
+
|
|
1295
|
+
unfinished_block = create_unfinished_block(
|
|
1296
|
+
constants,
|
|
1297
|
+
sub_slot_total_iters,
|
|
1298
|
+
constants.SUB_SLOT_ITERS_STARTING,
|
|
1299
|
+
uint8(signage_point_index),
|
|
1300
|
+
sp_iters,
|
|
1301
|
+
ip_iters,
|
|
1302
|
+
proof_of_space,
|
|
1303
|
+
cc_challenge,
|
|
1304
|
+
constants.GENESIS_PRE_FARM_FARMER_PUZZLE_HASH,
|
|
1305
|
+
PoolTarget(constants.GENESIS_PRE_FARM_POOL_PUZZLE_HASH, uint32(0)),
|
|
1306
|
+
self.get_plot_signature,
|
|
1307
|
+
self.get_pool_key_signature,
|
|
1308
|
+
signage_point,
|
|
1309
|
+
timestamp,
|
|
1310
|
+
BlockCache({}),
|
|
1311
|
+
seed=seed,
|
|
1312
|
+
finished_sub_slots_input=finished_sub_slots,
|
|
1313
|
+
compute_cost=compute_cost_test,
|
|
1314
|
+
compute_fees=compute_fee_test,
|
|
1315
|
+
)
|
|
1316
|
+
assert unfinished_block is not None
|
|
1317
|
+
if not is_overflow:
|
|
1318
|
+
cc_ip_vdf, cc_ip_proof = get_vdf_info_and_proof(
|
|
1319
|
+
constants,
|
|
1320
|
+
ClassgroupElement.get_default_element(),
|
|
1321
|
+
cc_challenge,
|
|
1322
|
+
ip_iters,
|
|
1323
|
+
)
|
|
1324
|
+
cc_ip_vdf = cc_ip_vdf.replace(number_of_iterations=ip_iters)
|
|
1325
|
+
rc_ip_vdf, rc_ip_proof = get_vdf_info_and_proof(
|
|
1326
|
+
constants,
|
|
1327
|
+
ClassgroupElement.get_default_element(),
|
|
1328
|
+
rc_challenge,
|
|
1329
|
+
ip_iters,
|
|
1330
|
+
)
|
|
1331
|
+
assert unfinished_block is not None
|
|
1332
|
+
total_iters_sp = uint128(sub_slot_total_iters + sp_iters)
|
|
1333
|
+
return unfinished_block_to_full_block(
|
|
1334
|
+
unfinished_block,
|
|
1335
|
+
cc_ip_vdf,
|
|
1336
|
+
cc_ip_proof,
|
|
1337
|
+
rc_ip_vdf,
|
|
1338
|
+
rc_ip_proof,
|
|
1339
|
+
None,
|
|
1340
|
+
None,
|
|
1341
|
+
finished_sub_slots,
|
|
1342
|
+
None,
|
|
1343
|
+
BlockCache({}),
|
|
1344
|
+
total_iters_sp,
|
|
1345
|
+
constants.DIFFICULTY_STARTING,
|
|
1346
|
+
)
|
|
1347
|
+
|
|
1348
|
+
if signage_point_index == constants.NUM_SPS_SUB_SLOT - constants.NUM_SP_INTERVALS_EXTRA - 1:
|
|
1349
|
+
# Finish the end of sub-slot and try again next sub-slot
|
|
1350
|
+
cc_vdf, cc_proof = get_vdf_info_and_proof(
|
|
1351
|
+
constants,
|
|
1352
|
+
ClassgroupElement.get_default_element(),
|
|
1353
|
+
cc_challenge,
|
|
1354
|
+
constants.SUB_SLOT_ITERS_STARTING,
|
|
1355
|
+
)
|
|
1356
|
+
rc_vdf, rc_proof = get_vdf_info_and_proof(
|
|
1357
|
+
constants,
|
|
1358
|
+
ClassgroupElement.get_default_element(),
|
|
1359
|
+
rc_challenge,
|
|
1360
|
+
constants.SUB_SLOT_ITERS_STARTING,
|
|
1361
|
+
)
|
|
1362
|
+
cc_slot = ChallengeChainSubSlot(cc_vdf, None, None, None, None)
|
|
1363
|
+
finished_sub_slots.append(
|
|
1364
|
+
EndOfSubSlotBundle(
|
|
1365
|
+
cc_slot,
|
|
1366
|
+
None,
|
|
1367
|
+
RewardChainSubSlot(
|
|
1368
|
+
rc_vdf,
|
|
1369
|
+
cc_slot.get_hash(),
|
|
1370
|
+
None,
|
|
1371
|
+
uint8(constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK),
|
|
1372
|
+
),
|
|
1373
|
+
SubSlotProofs(cc_proof, None, rc_proof),
|
|
1374
|
+
)
|
|
1375
|
+
)
|
|
1376
|
+
|
|
1377
|
+
if unfinished_block is not None:
|
|
1378
|
+
cc_ip_vdf, cc_ip_proof = get_vdf_info_and_proof(
|
|
1379
|
+
constants,
|
|
1380
|
+
ClassgroupElement.get_default_element(),
|
|
1381
|
+
finished_sub_slots[-1].challenge_chain.get_hash(),
|
|
1382
|
+
ip_iters,
|
|
1383
|
+
)
|
|
1384
|
+
rc_ip_vdf, rc_ip_proof = get_vdf_info_and_proof(
|
|
1385
|
+
constants,
|
|
1386
|
+
ClassgroupElement.get_default_element(),
|
|
1387
|
+
finished_sub_slots[-1].reward_chain.get_hash(),
|
|
1388
|
+
ip_iters,
|
|
1389
|
+
)
|
|
1390
|
+
total_iters_sp = uint128(
|
|
1391
|
+
sub_slot_total_iters
|
|
1392
|
+
+ calculate_sp_iters(
|
|
1393
|
+
self.constants,
|
|
1394
|
+
self.constants.SUB_SLOT_ITERS_STARTING,
|
|
1395
|
+
unfinished_block.reward_chain_block.signage_point_index,
|
|
1396
|
+
)
|
|
1397
|
+
)
|
|
1398
|
+
return unfinished_block_to_full_block(
|
|
1399
|
+
unfinished_block,
|
|
1400
|
+
cc_ip_vdf,
|
|
1401
|
+
cc_ip_proof,
|
|
1402
|
+
rc_ip_vdf,
|
|
1403
|
+
rc_ip_proof,
|
|
1404
|
+
None,
|
|
1405
|
+
None,
|
|
1406
|
+
finished_sub_slots,
|
|
1407
|
+
None,
|
|
1408
|
+
BlockCache({}),
|
|
1409
|
+
total_iters_sp,
|
|
1410
|
+
constants.DIFFICULTY_STARTING,
|
|
1411
|
+
)
|
|
1412
|
+
sub_slot_total_iters = uint128(sub_slot_total_iters + constants.SUB_SLOT_ITERS_STARTING)
|
|
1413
|
+
|
|
1414
|
+
def get_pospaces_for_challenge(
|
|
1415
|
+
self,
|
|
1416
|
+
constants: ConsensusConstants,
|
|
1417
|
+
challenge_hash: bytes32,
|
|
1418
|
+
signage_point: bytes32,
|
|
1419
|
+
seed: bytes,
|
|
1420
|
+
difficulty: uint64,
|
|
1421
|
+
sub_slot_iters: uint64,
|
|
1422
|
+
height: uint32,
|
|
1423
|
+
force_plot_id: Optional[bytes32] = None,
|
|
1424
|
+
) -> list[tuple[uint64, ProofOfSpace]]:
|
|
1425
|
+
found_proofs: list[tuple[uint64, ProofOfSpace]] = []
|
|
1426
|
+
rng = random.Random()
|
|
1427
|
+
rng.seed(seed)
|
|
1428
|
+
for plot_info in self.plot_manager.plots.values():
|
|
1429
|
+
plot_id: bytes32 = plot_info.prover.get_id()
|
|
1430
|
+
if force_plot_id is not None and plot_id != force_plot_id:
|
|
1431
|
+
continue
|
|
1432
|
+
prefix_bits = calculate_prefix_bits(constants, height)
|
|
1433
|
+
if passes_plot_filter(prefix_bits, plot_id, challenge_hash, signage_point):
|
|
1434
|
+
new_challenge: bytes32 = calculate_pos_challenge(plot_id, challenge_hash, signage_point)
|
|
1435
|
+
qualities = plot_info.prover.get_qualities_for_challenge(new_challenge)
|
|
1436
|
+
|
|
1437
|
+
for proof_index, quality_str in enumerate(qualities):
|
|
1438
|
+
required_iters = calculate_iterations_quality(
|
|
1439
|
+
constants.DIFFICULTY_CONSTANT_FACTOR,
|
|
1440
|
+
quality_str,
|
|
1441
|
+
plot_info.prover.get_size(),
|
|
1442
|
+
difficulty,
|
|
1443
|
+
signage_point,
|
|
1444
|
+
)
|
|
1445
|
+
if required_iters < calculate_sp_interval_iters(constants, sub_slot_iters):
|
|
1446
|
+
proof_xs: bytes = plot_info.prover.get_full_proof(new_challenge, proof_index)
|
|
1447
|
+
|
|
1448
|
+
# Look up local_sk from plot to save locked memory
|
|
1449
|
+
(
|
|
1450
|
+
pool_public_key_or_puzzle_hash,
|
|
1451
|
+
farmer_public_key,
|
|
1452
|
+
local_master_sk,
|
|
1453
|
+
) = parse_plot_info(plot_info.prover.get_memo())
|
|
1454
|
+
local_sk = master_sk_to_local_sk(local_master_sk)
|
|
1455
|
+
|
|
1456
|
+
if isinstance(pool_public_key_or_puzzle_hash, G1Element):
|
|
1457
|
+
include_taproot = False
|
|
1458
|
+
else:
|
|
1459
|
+
assert isinstance(pool_public_key_or_puzzle_hash, bytes32)
|
|
1460
|
+
include_taproot = True
|
|
1461
|
+
plot_pk = generate_plot_public_key(local_sk.get_g1(), farmer_public_key, include_taproot)
|
|
1462
|
+
proof_of_space: ProofOfSpace = ProofOfSpace(
|
|
1463
|
+
new_challenge,
|
|
1464
|
+
plot_info.pool_public_key,
|
|
1465
|
+
plot_info.pool_contract_puzzle_hash,
|
|
1466
|
+
plot_pk,
|
|
1467
|
+
plot_info.prover.get_size(),
|
|
1468
|
+
proof_xs,
|
|
1469
|
+
)
|
|
1470
|
+
found_proofs.append((required_iters, proof_of_space))
|
|
1471
|
+
random_sample = found_proofs
|
|
1472
|
+
if len(found_proofs) >= 1:
|
|
1473
|
+
if rng.random() < 0.1:
|
|
1474
|
+
# Removes some proofs of space to create "random" chains, based on the seed
|
|
1475
|
+
random_sample = rng.sample(found_proofs, len(found_proofs) - 1)
|
|
1476
|
+
return random_sample
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
def get_signage_point(
|
|
1480
|
+
constants: ConsensusConstants,
|
|
1481
|
+
blocks: BlockRecordsProtocol,
|
|
1482
|
+
latest_block: Optional[BlockRecord],
|
|
1483
|
+
sub_slot_start_total_iters: uint128,
|
|
1484
|
+
signage_point_index: uint8,
|
|
1485
|
+
finished_sub_slots: list[EndOfSubSlotBundle],
|
|
1486
|
+
sub_slot_iters: uint64,
|
|
1487
|
+
normalized_to_identity_cc_sp: bool = False,
|
|
1488
|
+
) -> SignagePoint:
|
|
1489
|
+
if signage_point_index == 0:
|
|
1490
|
+
return SignagePoint(None, None, None, None)
|
|
1491
|
+
sp_iters = calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
|
|
1492
|
+
overflow = is_overflow_block(constants, signage_point_index)
|
|
1493
|
+
sp_total_iters = uint128(
|
|
1494
|
+
sub_slot_start_total_iters + calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
|
|
1495
|
+
)
|
|
1496
|
+
|
|
1497
|
+
(
|
|
1498
|
+
cc_vdf_challenge,
|
|
1499
|
+
rc_vdf_challenge,
|
|
1500
|
+
cc_vdf_input,
|
|
1501
|
+
rc_vdf_input,
|
|
1502
|
+
cc_vdf_iters,
|
|
1503
|
+
rc_vdf_iters,
|
|
1504
|
+
) = get_signage_point_vdf_info(
|
|
1505
|
+
constants,
|
|
1506
|
+
finished_sub_slots,
|
|
1507
|
+
overflow,
|
|
1508
|
+
latest_block,
|
|
1509
|
+
blocks,
|
|
1510
|
+
sp_total_iters,
|
|
1511
|
+
sp_iters,
|
|
1512
|
+
)
|
|
1513
|
+
|
|
1514
|
+
cc_sp_vdf, cc_sp_proof = get_vdf_info_and_proof(
|
|
1515
|
+
constants,
|
|
1516
|
+
cc_vdf_input,
|
|
1517
|
+
cc_vdf_challenge,
|
|
1518
|
+
cc_vdf_iters,
|
|
1519
|
+
)
|
|
1520
|
+
rc_sp_vdf, rc_sp_proof = get_vdf_info_and_proof(
|
|
1521
|
+
constants,
|
|
1522
|
+
rc_vdf_input,
|
|
1523
|
+
rc_vdf_challenge,
|
|
1524
|
+
rc_vdf_iters,
|
|
1525
|
+
)
|
|
1526
|
+
cc_sp_vdf = cc_sp_vdf.replace(number_of_iterations=sp_iters)
|
|
1527
|
+
if normalized_to_identity_cc_sp:
|
|
1528
|
+
_, cc_sp_proof = get_vdf_info_and_proof(
|
|
1529
|
+
constants,
|
|
1530
|
+
ClassgroupElement.get_default_element(),
|
|
1531
|
+
cc_sp_vdf.challenge,
|
|
1532
|
+
sp_iters,
|
|
1533
|
+
True,
|
|
1534
|
+
)
|
|
1535
|
+
return SignagePoint(cc_sp_vdf, cc_sp_proof, rc_sp_vdf, rc_sp_proof)
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
def finish_block(
|
|
1539
|
+
constants: ConsensusConstants,
|
|
1540
|
+
blocks: dict[bytes32, BlockRecord],
|
|
1541
|
+
height_to_hash: dict[uint32, bytes32],
|
|
1542
|
+
finished_sub_slots: list[EndOfSubSlotBundle],
|
|
1543
|
+
sub_slot_start_total_iters: uint128,
|
|
1544
|
+
signage_point_index: uint8,
|
|
1545
|
+
unfinished_block: UnfinishedBlock,
|
|
1546
|
+
required_iters: uint64,
|
|
1547
|
+
ip_iters: uint64,
|
|
1548
|
+
slot_cc_challenge: bytes32,
|
|
1549
|
+
slot_rc_challenge: bytes32,
|
|
1550
|
+
latest_block: BlockRecord,
|
|
1551
|
+
sub_slot_iters: uint64,
|
|
1552
|
+
difficulty: uint64,
|
|
1553
|
+
normalized_to_identity_cc_ip: bool = False,
|
|
1554
|
+
) -> tuple[FullBlock, BlockRecord]:
|
|
1555
|
+
is_overflow = is_overflow_block(constants, signage_point_index)
|
|
1556
|
+
cc_vdf_challenge = slot_cc_challenge
|
|
1557
|
+
if len(finished_sub_slots) == 0:
|
|
1558
|
+
new_ip_iters = uint64(unfinished_block.total_iters - latest_block.total_iters)
|
|
1559
|
+
cc_vdf_input = latest_block.challenge_vdf_output
|
|
1560
|
+
rc_vdf_challenge = latest_block.reward_infusion_new_challenge
|
|
1561
|
+
else:
|
|
1562
|
+
new_ip_iters = ip_iters
|
|
1563
|
+
cc_vdf_input = ClassgroupElement.get_default_element()
|
|
1564
|
+
rc_vdf_challenge = slot_rc_challenge
|
|
1565
|
+
cc_ip_vdf, cc_ip_proof = get_vdf_info_and_proof(
|
|
1566
|
+
constants,
|
|
1567
|
+
cc_vdf_input,
|
|
1568
|
+
cc_vdf_challenge,
|
|
1569
|
+
new_ip_iters,
|
|
1570
|
+
)
|
|
1571
|
+
cc_ip_vdf = cc_ip_vdf.replace(number_of_iterations=ip_iters)
|
|
1572
|
+
if normalized_to_identity_cc_ip:
|
|
1573
|
+
_, cc_ip_proof = get_vdf_info_and_proof(
|
|
1574
|
+
constants,
|
|
1575
|
+
ClassgroupElement.get_default_element(),
|
|
1576
|
+
cc_ip_vdf.challenge,
|
|
1577
|
+
ip_iters,
|
|
1578
|
+
True,
|
|
1579
|
+
)
|
|
1580
|
+
deficit = calculate_deficit(
|
|
1581
|
+
constants,
|
|
1582
|
+
uint32(latest_block.height + 1),
|
|
1583
|
+
latest_block,
|
|
1584
|
+
is_overflow,
|
|
1585
|
+
len(finished_sub_slots),
|
|
1586
|
+
)
|
|
1587
|
+
|
|
1588
|
+
icc_ip_vdf, icc_ip_proof = get_icc(
|
|
1589
|
+
constants,
|
|
1590
|
+
unfinished_block.total_iters,
|
|
1591
|
+
finished_sub_slots,
|
|
1592
|
+
latest_block,
|
|
1593
|
+
blocks,
|
|
1594
|
+
uint128(sub_slot_start_total_iters + sub_slot_iters) if is_overflow else sub_slot_start_total_iters,
|
|
1595
|
+
deficit,
|
|
1596
|
+
)
|
|
1597
|
+
|
|
1598
|
+
rc_ip_vdf, rc_ip_proof = get_vdf_info_and_proof(
|
|
1599
|
+
constants,
|
|
1600
|
+
ClassgroupElement.get_default_element(),
|
|
1601
|
+
rc_vdf_challenge,
|
|
1602
|
+
new_ip_iters,
|
|
1603
|
+
)
|
|
1604
|
+
assert unfinished_block is not None
|
|
1605
|
+
sp_total_iters = uint128(
|
|
1606
|
+
sub_slot_start_total_iters + calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
|
|
1607
|
+
)
|
|
1608
|
+
full_block: FullBlock = unfinished_block_to_full_block(
|
|
1609
|
+
unfinished_block,
|
|
1610
|
+
cc_ip_vdf,
|
|
1611
|
+
cc_ip_proof,
|
|
1612
|
+
rc_ip_vdf,
|
|
1613
|
+
rc_ip_proof,
|
|
1614
|
+
icc_ip_vdf,
|
|
1615
|
+
icc_ip_proof,
|
|
1616
|
+
finished_sub_slots,
|
|
1617
|
+
latest_block,
|
|
1618
|
+
BlockCache(blocks),
|
|
1619
|
+
sp_total_iters,
|
|
1620
|
+
difficulty,
|
|
1621
|
+
)
|
|
1622
|
+
|
|
1623
|
+
block_record = block_to_block_record(
|
|
1624
|
+
constants, BlockCache(blocks), required_iters, full_block, sub_slot_iters=sub_slot_iters
|
|
1625
|
+
)
|
|
1626
|
+
return full_block, block_record
|
|
1627
|
+
|
|
1628
|
+
|
|
1629
|
+
def get_challenges(
|
|
1630
|
+
constants: ConsensusConstants,
|
|
1631
|
+
blocks: dict[bytes32, BlockRecord],
|
|
1632
|
+
finished_sub_slots: list[EndOfSubSlotBundle],
|
|
1633
|
+
prev_header_hash: Optional[bytes32],
|
|
1634
|
+
) -> tuple[bytes32, bytes32]:
|
|
1635
|
+
if len(finished_sub_slots) == 0:
|
|
1636
|
+
if prev_header_hash is None:
|
|
1637
|
+
return constants.GENESIS_CHALLENGE, constants.GENESIS_CHALLENGE
|
|
1638
|
+
curr: BlockRecord = blocks[prev_header_hash]
|
|
1639
|
+
while not curr.first_in_sub_slot:
|
|
1640
|
+
curr = blocks[curr.prev_hash]
|
|
1641
|
+
assert curr.finished_challenge_slot_hashes is not None
|
|
1642
|
+
assert curr.finished_reward_slot_hashes is not None
|
|
1643
|
+
cc_challenge = curr.finished_challenge_slot_hashes[-1]
|
|
1644
|
+
rc_challenge = curr.finished_reward_slot_hashes[-1]
|
|
1645
|
+
else:
|
|
1646
|
+
cc_challenge = finished_sub_slots[-1].challenge_chain.get_hash()
|
|
1647
|
+
rc_challenge = finished_sub_slots[-1].reward_chain.get_hash()
|
|
1648
|
+
return cc_challenge, rc_challenge
|
|
1649
|
+
|
|
1650
|
+
|
|
1651
|
+
def get_plot_dir(plot_dir_name: str = "test-plots", automated_testing: bool = True) -> Path:
|
|
1652
|
+
root_dir = DEFAULT_ROOT_PATH.parent
|
|
1653
|
+
if not automated_testing: # make sure we don't accidentally stack directories.
|
|
1654
|
+
root_dir = (
|
|
1655
|
+
root_dir.parent
|
|
1656
|
+
if root_dir.parts[-1] == plot_dir_name.split("/")[0] or root_dir.parts[-1] == plot_dir_name.split("\\")[0]
|
|
1657
|
+
else root_dir
|
|
1658
|
+
)
|
|
1659
|
+
cache_path = root_dir.joinpath(plot_dir_name)
|
|
1660
|
+
|
|
1661
|
+
ci = os.environ.get("CI")
|
|
1662
|
+
if ci is not None and not cache_path.exists() and automated_testing:
|
|
1663
|
+
raise Exception(f"Running in CI and expected path not found: {cache_path!r}")
|
|
1664
|
+
|
|
1665
|
+
cache_path.mkdir(parents=True, exist_ok=True)
|
|
1666
|
+
return cache_path
|
|
1667
|
+
|
|
1668
|
+
|
|
1669
|
+
def get_plot_tmp_dir(plot_dir_name: str = "test-plots", automated_testing: bool = True) -> Path:
|
|
1670
|
+
return get_plot_dir(plot_dir_name, automated_testing) / "tmp"
|
|
1671
|
+
|
|
1672
|
+
|
|
1673
|
+
def load_block_list(
|
|
1674
|
+
block_list: list[FullBlock], constants: ConsensusConstants
|
|
1675
|
+
) -> tuple[dict[uint32, bytes32], uint64, dict[bytes32, BlockRecord]]:
|
|
1676
|
+
difficulty = uint64(constants.DIFFICULTY_STARTING)
|
|
1677
|
+
sub_slot_iters = uint64(constants.SUB_SLOT_ITERS_STARTING)
|
|
1678
|
+
height_to_hash: dict[uint32, bytes32] = {}
|
|
1679
|
+
blocks: dict[bytes32, BlockRecord] = {}
|
|
1680
|
+
for full_block in block_list:
|
|
1681
|
+
if full_block.height != 0:
|
|
1682
|
+
if len(full_block.finished_sub_slots) > 0:
|
|
1683
|
+
if full_block.finished_sub_slots[0].challenge_chain.new_difficulty is not None:
|
|
1684
|
+
difficulty = full_block.finished_sub_slots[0].challenge_chain.new_difficulty
|
|
1685
|
+
if full_block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters is not None:
|
|
1686
|
+
sub_slot_iters = full_block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters
|
|
1687
|
+
if full_block.reward_chain_block.signage_point_index == 0:
|
|
1688
|
+
challenge = full_block.reward_chain_block.pos_ss_cc_challenge_hash
|
|
1689
|
+
sp_hash = challenge
|
|
1690
|
+
else:
|
|
1691
|
+
assert full_block.reward_chain_block.challenge_chain_sp_vdf is not None
|
|
1692
|
+
challenge = full_block.reward_chain_block.challenge_chain_sp_vdf.challenge
|
|
1693
|
+
sp_hash = full_block.reward_chain_block.challenge_chain_sp_vdf.output.get_hash()
|
|
1694
|
+
quality_str = verify_and_get_quality_string(
|
|
1695
|
+
full_block.reward_chain_block.proof_of_space, constants, challenge, sp_hash, height=full_block.height
|
|
1696
|
+
)
|
|
1697
|
+
assert quality_str is not None
|
|
1698
|
+
required_iters: uint64 = calculate_iterations_quality(
|
|
1699
|
+
constants.DIFFICULTY_CONSTANT_FACTOR,
|
|
1700
|
+
quality_str,
|
|
1701
|
+
full_block.reward_chain_block.proof_of_space.size,
|
|
1702
|
+
uint64(difficulty),
|
|
1703
|
+
sp_hash,
|
|
1704
|
+
)
|
|
1705
|
+
|
|
1706
|
+
blocks[full_block.header_hash] = block_to_block_record(
|
|
1707
|
+
constants,
|
|
1708
|
+
BlockCache(blocks),
|
|
1709
|
+
required_iters,
|
|
1710
|
+
full_block,
|
|
1711
|
+
sub_slot_iters,
|
|
1712
|
+
)
|
|
1713
|
+
height_to_hash[uint32(full_block.height)] = full_block.header_hash
|
|
1714
|
+
return height_to_hash, uint64(difficulty), blocks
|
|
1715
|
+
|
|
1716
|
+
|
|
1717
|
+
def get_icc(
|
|
1718
|
+
constants: ConsensusConstants,
|
|
1719
|
+
vdf_end_total_iters: uint128,
|
|
1720
|
+
finished_sub_slots: list[EndOfSubSlotBundle],
|
|
1721
|
+
latest_block: BlockRecord,
|
|
1722
|
+
blocks: dict[bytes32, BlockRecord],
|
|
1723
|
+
sub_slot_start_total_iters: uint128,
|
|
1724
|
+
deficit: uint8,
|
|
1725
|
+
) -> tuple[Optional[VDFInfo], Optional[VDFProof]]:
|
|
1726
|
+
if len(finished_sub_slots) == 0:
|
|
1727
|
+
prev_deficit = latest_block.deficit
|
|
1728
|
+
else:
|
|
1729
|
+
prev_deficit = finished_sub_slots[-1].reward_chain.deficit
|
|
1730
|
+
|
|
1731
|
+
if deficit == prev_deficit == constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
|
|
1732
|
+
# new slot / overflow sb to new slot / overflow sb
|
|
1733
|
+
return None, None
|
|
1734
|
+
|
|
1735
|
+
if deficit == (prev_deficit - 1) == (constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1):
|
|
1736
|
+
# new slot / overflow sb to challenge sb
|
|
1737
|
+
return None, None
|
|
1738
|
+
|
|
1739
|
+
if len(finished_sub_slots) != 0:
|
|
1740
|
+
last_ss = finished_sub_slots[-1]
|
|
1741
|
+
assert last_ss.infused_challenge_chain is not None
|
|
1742
|
+
assert finished_sub_slots[-1].reward_chain.deficit <= (constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1)
|
|
1743
|
+
return get_vdf_info_and_proof(
|
|
1744
|
+
constants,
|
|
1745
|
+
ClassgroupElement.get_default_element(),
|
|
1746
|
+
last_ss.infused_challenge_chain.get_hash(),
|
|
1747
|
+
uint64(vdf_end_total_iters - sub_slot_start_total_iters),
|
|
1748
|
+
)
|
|
1749
|
+
|
|
1750
|
+
curr = latest_block # curr deficit is 0, 1, 2, 3, or 4
|
|
1751
|
+
while not curr.is_challenge_block(constants) and not curr.first_in_sub_slot:
|
|
1752
|
+
curr = blocks[curr.prev_hash]
|
|
1753
|
+
icc_iters = uint64(vdf_end_total_iters - latest_block.total_iters)
|
|
1754
|
+
if latest_block.is_challenge_block(constants):
|
|
1755
|
+
icc_input: Optional[ClassgroupElement] = ClassgroupElement.get_default_element()
|
|
1756
|
+
else:
|
|
1757
|
+
icc_input = latest_block.infused_challenge_vdf_output
|
|
1758
|
+
assert icc_input is not None
|
|
1759
|
+
|
|
1760
|
+
if curr.is_challenge_block(constants): # Deficit 4
|
|
1761
|
+
icc_challenge_hash = curr.challenge_block_info_hash
|
|
1762
|
+
else:
|
|
1763
|
+
assert curr.finished_infused_challenge_slot_hashes is not None
|
|
1764
|
+
# First block in sub slot has deficit 0,1,2 or 3
|
|
1765
|
+
icc_challenge_hash = curr.finished_infused_challenge_slot_hashes[-1]
|
|
1766
|
+
return get_vdf_info_and_proof(
|
|
1767
|
+
constants,
|
|
1768
|
+
icc_input,
|
|
1769
|
+
icc_challenge_hash,
|
|
1770
|
+
icc_iters,
|
|
1771
|
+
)
|
|
1772
|
+
|
|
1773
|
+
|
|
1774
|
+
def get_full_block_and_block_record(
|
|
1775
|
+
constants: ConsensusConstants,
|
|
1776
|
+
blocks: dict[bytes32, BlockRecord],
|
|
1777
|
+
sub_slot_start_total_iters: uint128,
|
|
1778
|
+
signage_point_index: uint8,
|
|
1779
|
+
proof_of_space: ProofOfSpace,
|
|
1780
|
+
slot_cc_challenge: bytes32,
|
|
1781
|
+
slot_rc_challenge: bytes32,
|
|
1782
|
+
farmer_reward_puzzle_hash: bytes32,
|
|
1783
|
+
pool_target: PoolTarget,
|
|
1784
|
+
last_timestamp: float,
|
|
1785
|
+
start_height: uint32,
|
|
1786
|
+
time_per_block: float,
|
|
1787
|
+
block_generator: Optional[BlockGenerator],
|
|
1788
|
+
aggregate_signature: G2Element,
|
|
1789
|
+
additions: Optional[list[Coin]],
|
|
1790
|
+
removals: Optional[list[Coin]],
|
|
1791
|
+
height_to_hash: dict[uint32, bytes32],
|
|
1792
|
+
difficulty: uint64,
|
|
1793
|
+
required_iters: uint64,
|
|
1794
|
+
sub_slot_iters: uint64,
|
|
1795
|
+
get_plot_signature: Callable[[bytes32, G1Element], G2Element],
|
|
1796
|
+
get_pool_signature: Callable[[PoolTarget, Optional[G1Element]], Optional[G2Element]],
|
|
1797
|
+
finished_sub_slots: list[EndOfSubSlotBundle],
|
|
1798
|
+
signage_point: SignagePoint,
|
|
1799
|
+
prev_block: BlockRecord,
|
|
1800
|
+
seed: bytes = b"",
|
|
1801
|
+
*,
|
|
1802
|
+
block_refs: list[uint32] = [],
|
|
1803
|
+
overflow_cc_challenge: Optional[bytes32] = None,
|
|
1804
|
+
overflow_rc_challenge: Optional[bytes32] = None,
|
|
1805
|
+
normalized_to_identity_cc_ip: bool = False,
|
|
1806
|
+
current_time: bool = False,
|
|
1807
|
+
) -> tuple[FullBlock, BlockRecord, float]:
|
|
1808
|
+
# we're simulating time between blocks here. The more VDF iterations the
|
|
1809
|
+
# blocks advances, the longer it should have taken (and vice versa). This
|
|
1810
|
+
# formula is meant to converge at 1024 iters per the specified
|
|
1811
|
+
# time_per_block (which defaults to 18.75 seconds)
|
|
1812
|
+
time_per_block *= (((sub_slot_iters / 1024) - 1) * 0.2) + 1
|
|
1813
|
+
if current_time is True:
|
|
1814
|
+
timestamp = max(int(time.time()), last_timestamp + time_per_block)
|
|
1815
|
+
else:
|
|
1816
|
+
timestamp = last_timestamp + time_per_block
|
|
1817
|
+
sp_iters = calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
|
|
1818
|
+
ip_iters = calculate_ip_iters(constants, sub_slot_iters, signage_point_index, required_iters)
|
|
1819
|
+
|
|
1820
|
+
unfinished_block = create_unfinished_block(
|
|
1821
|
+
constants,
|
|
1822
|
+
sub_slot_start_total_iters,
|
|
1823
|
+
sub_slot_iters,
|
|
1824
|
+
signage_point_index,
|
|
1825
|
+
sp_iters,
|
|
1826
|
+
ip_iters,
|
|
1827
|
+
proof_of_space,
|
|
1828
|
+
slot_cc_challenge,
|
|
1829
|
+
farmer_reward_puzzle_hash,
|
|
1830
|
+
pool_target,
|
|
1831
|
+
get_plot_signature,
|
|
1832
|
+
get_pool_signature,
|
|
1833
|
+
signage_point,
|
|
1834
|
+
uint64(timestamp),
|
|
1835
|
+
BlockCache(blocks),
|
|
1836
|
+
seed,
|
|
1837
|
+
block_generator,
|
|
1838
|
+
aggregate_signature,
|
|
1839
|
+
additions,
|
|
1840
|
+
removals,
|
|
1841
|
+
prev_block,
|
|
1842
|
+
finished_sub_slots,
|
|
1843
|
+
compute_cost=compute_cost_test,
|
|
1844
|
+
compute_fees=compute_fee_test,
|
|
1845
|
+
)
|
|
1846
|
+
|
|
1847
|
+
if (overflow_cc_challenge is not None) and (overflow_rc_challenge is not None):
|
|
1848
|
+
slot_cc_challenge = overflow_cc_challenge
|
|
1849
|
+
slot_rc_challenge = overflow_rc_challenge
|
|
1850
|
+
|
|
1851
|
+
full_block, block_record = finish_block(
|
|
1852
|
+
constants,
|
|
1853
|
+
blocks,
|
|
1854
|
+
height_to_hash,
|
|
1855
|
+
finished_sub_slots,
|
|
1856
|
+
sub_slot_start_total_iters,
|
|
1857
|
+
signage_point_index,
|
|
1858
|
+
unfinished_block,
|
|
1859
|
+
required_iters,
|
|
1860
|
+
ip_iters,
|
|
1861
|
+
slot_cc_challenge,
|
|
1862
|
+
slot_rc_challenge,
|
|
1863
|
+
prev_block,
|
|
1864
|
+
sub_slot_iters,
|
|
1865
|
+
difficulty,
|
|
1866
|
+
normalized_to_identity_cc_ip,
|
|
1867
|
+
)
|
|
1868
|
+
|
|
1869
|
+
return full_block, block_record, timestamp
|
|
1870
|
+
|
|
1871
|
+
|
|
1872
|
+
# these are the costs of unknown conditions, as defined chia_rs here:
|
|
1873
|
+
# https://github.com/Chia-Network/chia_rs/pull/181
|
|
1874
|
+
def compute_cost_table() -> list[int]:
|
|
1875
|
+
A = 17
|
|
1876
|
+
B = 16
|
|
1877
|
+
s = []
|
|
1878
|
+
NUM = 100
|
|
1879
|
+
DEN = 1
|
|
1880
|
+
MAX = 1 << 59
|
|
1881
|
+
for i in range(256):
|
|
1882
|
+
v = str(NUM // DEN)
|
|
1883
|
+
v1 = v[:3] + ("0" * (len(v) - 3))
|
|
1884
|
+
s.append(int(v1))
|
|
1885
|
+
NUM *= A
|
|
1886
|
+
DEN *= B
|
|
1887
|
+
assert NUM < 1 << 64
|
|
1888
|
+
assert DEN < 1 << 64
|
|
1889
|
+
if NUM > MAX:
|
|
1890
|
+
NUM >>= 5
|
|
1891
|
+
DEN >>= 5
|
|
1892
|
+
return s
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
CONDITION_COSTS = compute_cost_table()
|
|
1896
|
+
|
|
1897
|
+
|
|
1898
|
+
def conditions_cost(conds: Program) -> uint64:
|
|
1899
|
+
condition_cost = 0
|
|
1900
|
+
for cond in conds.as_iter():
|
|
1901
|
+
condition = cond.first().as_atom()
|
|
1902
|
+
if condition == ConditionOpcode.CREATE_COIN:
|
|
1903
|
+
condition_cost += ConditionCost.CREATE_COIN.value
|
|
1904
|
+
# after the 2.0 hard fork, two byte conditions (with no leading 0)
|
|
1905
|
+
# have costs. Account for that.
|
|
1906
|
+
elif len(condition) == 2 and condition[0] != 0:
|
|
1907
|
+
condition_cost += CONDITION_COSTS[condition[1]]
|
|
1908
|
+
elif condition == ConditionOpcode.SOFTFORK.value:
|
|
1909
|
+
arg = cond.rest().first().as_int()
|
|
1910
|
+
condition_cost += arg * 10000
|
|
1911
|
+
elif condition in {
|
|
1912
|
+
ConditionOpcode.AGG_SIG_UNSAFE,
|
|
1913
|
+
ConditionOpcode.AGG_SIG_ME,
|
|
1914
|
+
ConditionOpcode.AGG_SIG_PARENT,
|
|
1915
|
+
ConditionOpcode.AGG_SIG_PUZZLE,
|
|
1916
|
+
ConditionOpcode.AGG_SIG_AMOUNT,
|
|
1917
|
+
ConditionOpcode.AGG_SIG_PUZZLE_AMOUNT,
|
|
1918
|
+
ConditionOpcode.AGG_SIG_PARENT_AMOUNT,
|
|
1919
|
+
ConditionOpcode.AGG_SIG_PARENT_PUZZLE,
|
|
1920
|
+
}:
|
|
1921
|
+
condition_cost += ConditionCost.AGG_SIG.value
|
|
1922
|
+
return uint64(condition_cost)
|
|
1923
|
+
|
|
1924
|
+
|
|
1925
|
+
def compute_fee_test(additions: Sequence[Coin], removals: Sequence[Coin]) -> uint64:
|
|
1926
|
+
removal_amount = 0
|
|
1927
|
+
addition_amount = 0
|
|
1928
|
+
for coin in removals:
|
|
1929
|
+
removal_amount += coin.amount
|
|
1930
|
+
for coin in additions:
|
|
1931
|
+
addition_amount += coin.amount
|
|
1932
|
+
|
|
1933
|
+
ret = removal_amount - addition_amount
|
|
1934
|
+
# in order to allow creating blocks that mint coins, clamp the fee
|
|
1935
|
+
# to 0, if it ends up being negative
|
|
1936
|
+
ret = max(ret, 0)
|
|
1937
|
+
return uint64(ret)
|
|
1938
|
+
|
|
1939
|
+
|
|
1940
|
+
def compute_cost_test(generator: BlockGenerator, constants: ConsensusConstants, height: uint32) -> uint64:
|
|
1941
|
+
# this function cannot *validate* the block or any of the transactions. We
|
|
1942
|
+
# deliberately create invalid blocks as parts of the tests, and we still
|
|
1943
|
+
# need to be able to compute the cost of it
|
|
1944
|
+
|
|
1945
|
+
condition_cost = 0
|
|
1946
|
+
clvm_cost = 0
|
|
1947
|
+
|
|
1948
|
+
if height >= constants.HARD_FORK_HEIGHT:
|
|
1949
|
+
blocks = generator.generator_refs
|
|
1950
|
+
cost, result = generator.program._run(INFINITE_COST, MEMPOOL_MODE, [DESERIALIZE_MOD, blocks])
|
|
1951
|
+
clvm_cost += cost
|
|
1952
|
+
|
|
1953
|
+
for spend in result.first().as_iter():
|
|
1954
|
+
# each spend is a list of:
|
|
1955
|
+
# (parent-coin-id puzzle amount solution)
|
|
1956
|
+
puzzle = spend.at("rf")
|
|
1957
|
+
solution = spend.at("rrrf")
|
|
1958
|
+
|
|
1959
|
+
cost, result = puzzle._run(INFINITE_COST, MEMPOOL_MODE, solution)
|
|
1960
|
+
clvm_cost += cost
|
|
1961
|
+
condition_cost += conditions_cost(result)
|
|
1962
|
+
|
|
1963
|
+
else:
|
|
1964
|
+
block_program_args = SerializedProgram.to([generator.generator_refs])
|
|
1965
|
+
clvm_cost, result = GENERATOR_MOD._run(INFINITE_COST, MEMPOOL_MODE, [generator.program, block_program_args])
|
|
1966
|
+
|
|
1967
|
+
for res in result.first().as_iter():
|
|
1968
|
+
# each condition item is:
|
|
1969
|
+
# (parent-coin-id puzzle-hash amount conditions)
|
|
1970
|
+
conditions = res.at("rrrf")
|
|
1971
|
+
condition_cost += conditions_cost(conditions)
|
|
1972
|
+
|
|
1973
|
+
size_cost = len(bytes(generator.program)) * constants.COST_PER_BYTE
|
|
1974
|
+
|
|
1975
|
+
return uint64(clvm_cost + size_cost + condition_cost)
|
|
1976
|
+
|
|
1977
|
+
|
|
1978
|
+
@dataclass
|
|
1979
|
+
class BlockToolsNewPlotResult:
|
|
1980
|
+
plot_id: bytes32
|
|
1981
|
+
new_plot: bool
|
|
1982
|
+
|
|
1983
|
+
|
|
1984
|
+
# Remove these counters when `create_block_tools` and `create_block_tools_async` are removed
|
|
1985
|
+
create_block_tools_async_count = 0
|
|
1986
|
+
create_block_tools_count = 0
|
|
1987
|
+
|
|
1988
|
+
# Note: tests that still use `create_block_tools` and `create_block_tools_async` should probably be
|
|
1989
|
+
# moved to the bt fixture in conftest.py. Take special care to find out if the users of these functions
|
|
1990
|
+
# need different BlockTools instances
|
|
1991
|
+
|
|
1992
|
+
# All tests need different root directories containing different config.yaml files.
|
|
1993
|
+
# The daemon's listen port is configured in the config.yaml, and the only way a test can control which
|
|
1994
|
+
# listen port it uses is to write it to the config file.
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
async def create_block_tools_async(
|
|
1998
|
+
constants: ConsensusConstants = test_constants,
|
|
1999
|
+
root_path: Optional[Path] = None,
|
|
2000
|
+
keychain: Optional[Keychain] = None,
|
|
2001
|
+
config_overrides: Optional[dict[str, Any]] = None,
|
|
2002
|
+
num_og_plots: int = 15,
|
|
2003
|
+
num_pool_plots: int = 5,
|
|
2004
|
+
num_non_keychain_plots: int = 3,
|
|
2005
|
+
) -> BlockTools:
|
|
2006
|
+
global create_block_tools_async_count
|
|
2007
|
+
create_block_tools_async_count += 1
|
|
2008
|
+
print(f" create_block_tools_async called {create_block_tools_async_count} times")
|
|
2009
|
+
bt = BlockTools(constants, root_path, keychain, config_overrides=config_overrides)
|
|
2010
|
+
await bt.setup_keys()
|
|
2011
|
+
await bt.setup_plots(
|
|
2012
|
+
num_og_plots=num_og_plots,
|
|
2013
|
+
num_pool_plots=num_pool_plots,
|
|
2014
|
+
num_non_keychain_plots=num_non_keychain_plots,
|
|
2015
|
+
)
|
|
2016
|
+
|
|
2017
|
+
return bt
|
|
2018
|
+
|
|
2019
|
+
|
|
2020
|
+
def create_block_tools(
|
|
2021
|
+
constants: ConsensusConstants = test_constants,
|
|
2022
|
+
root_path: Optional[Path] = None,
|
|
2023
|
+
keychain: Optional[Keychain] = None,
|
|
2024
|
+
config_overrides: Optional[dict[str, Any]] = None,
|
|
2025
|
+
) -> BlockTools:
|
|
2026
|
+
global create_block_tools_count
|
|
2027
|
+
create_block_tools_count += 1
|
|
2028
|
+
print(f" create_block_tools called {create_block_tools_count} times")
|
|
2029
|
+
bt = BlockTools(constants, root_path, keychain, config_overrides=config_overrides)
|
|
2030
|
+
|
|
2031
|
+
asyncio.get_event_loop().run_until_complete(bt.setup_keys())
|
|
2032
|
+
asyncio.get_event_loop().run_until_complete(bt.setup_plots())
|
|
2033
|
+
return bt
|
|
2034
|
+
|
|
2035
|
+
|
|
2036
|
+
def make_unfinished_block(
|
|
2037
|
+
block: FullBlock, constants: ConsensusConstants, *, force_overflow: bool = False
|
|
2038
|
+
) -> UnfinishedBlock:
|
|
2039
|
+
if force_overflow or is_overflow_block(constants, block.reward_chain_block.signage_point_index):
|
|
2040
|
+
finished_ss = block.finished_sub_slots[:-1]
|
|
2041
|
+
else:
|
|
2042
|
+
finished_ss = block.finished_sub_slots
|
|
2043
|
+
|
|
2044
|
+
return UnfinishedBlock(
|
|
2045
|
+
finished_ss,
|
|
2046
|
+
block.reward_chain_block.get_unfinished(),
|
|
2047
|
+
block.challenge_chain_sp_proof,
|
|
2048
|
+
block.reward_chain_sp_proof,
|
|
2049
|
+
block.foliage,
|
|
2050
|
+
block.foliage_transaction_block,
|
|
2051
|
+
block.transactions_info,
|
|
2052
|
+
block.transactions_generator,
|
|
2053
|
+
block.transactions_generator_ref_list,
|
|
2054
|
+
)
|