chia-blockchain 2.5.7rc3__py3-none-any.whl → 2.5.8rc1__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.
Files changed (528) hide show
  1. chia/__init__.py +8 -4
  2. chia/_tests/blockchain/blockchain_test_utils.py +6 -8
  3. chia/_tests/blockchain/test_augmented_chain.py +4 -4
  4. chia/_tests/blockchain/test_blockchain.py +165 -190
  5. chia/_tests/blockchain/test_build_chains.py +2 -4
  6. chia/_tests/blockchain/test_get_block_generator.py +2 -3
  7. chia/_tests/clvm/coin_store.py +4 -7
  8. chia/_tests/clvm/test_clvm_step.py +4 -4
  9. chia/_tests/clvm/test_puzzle_compression.py +2 -1
  10. chia/_tests/clvm/test_puzzle_drivers.py +2 -2
  11. chia/_tests/clvm/test_singletons.py +2 -4
  12. chia/_tests/clvm/test_spend_sim.py +2 -2
  13. chia/_tests/cmds/cmd_test_utils.py +27 -45
  14. chia/_tests/cmds/test_cmd_framework.py +6 -6
  15. chia/_tests/cmds/test_daemon.py +3 -3
  16. chia/_tests/cmds/test_show.py +4 -4
  17. chia/_tests/cmds/test_tx_config_args.py +1 -2
  18. chia/_tests/cmds/testing_classes.py +4 -5
  19. chia/_tests/cmds/wallet/test_did.py +24 -27
  20. chia/_tests/cmds/wallet/test_nft.py +12 -10
  21. chia/_tests/cmds/wallet/test_vcs.py +11 -12
  22. chia/_tests/cmds/wallet/test_wallet.py +134 -89
  23. chia/_tests/conftest.py +59 -30
  24. chia/_tests/connection_utils.py +2 -2
  25. chia/_tests/core/cmds/test_beta.py +4 -4
  26. chia/_tests/core/cmds/test_keys.py +2 -3
  27. chia/_tests/core/cmds/test_wallet.py +15 -15
  28. chia/_tests/core/consensus/test_pot_iterations.py +19 -73
  29. chia/_tests/core/custom_types/test_proof_of_space.py +124 -98
  30. chia/_tests/core/daemon/test_daemon.py +11 -11
  31. chia/_tests/core/data_layer/conftest.py +2 -2
  32. chia/_tests/core/data_layer/test_data_rpc.py +28 -14
  33. chia/_tests/core/data_layer/test_data_store.py +10 -10
  34. chia/_tests/core/data_layer/util.py +11 -11
  35. chia/_tests/core/farmer/test_farmer_api.py +2 -4
  36. chia/_tests/core/full_node/full_sync/test_full_sync.py +8 -7
  37. chia/_tests/core/full_node/stores/test_block_store.py +5 -4
  38. chia/_tests/core/full_node/stores/test_coin_store.py +5 -11
  39. chia/_tests/core/full_node/stores/test_full_node_store.py +8 -8
  40. chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
  41. chia/_tests/core/full_node/test_block_height_map.py +3 -4
  42. chia/_tests/core/full_node/test_conditions.py +21 -23
  43. chia/_tests/core/full_node/test_full_node.py +225 -62
  44. chia/_tests/core/full_node/test_hint_management.py +2 -4
  45. chia/_tests/core/full_node/test_performance.py +0 -1
  46. chia/_tests/core/full_node/test_prev_tx_block.py +88 -11
  47. chia/_tests/core/full_node/test_transactions.py +1 -2
  48. chia/_tests/core/full_node/test_tx_processing_queue.py +109 -25
  49. chia/_tests/core/mempool/test_mempool.py +29 -37
  50. chia/_tests/core/mempool/test_mempool_fee_estimator.py +39 -39
  51. chia/_tests/core/mempool/test_mempool_fee_protocol.py +2 -6
  52. chia/_tests/core/mempool/test_mempool_manager.py +963 -839
  53. chia/_tests/core/mempool/test_singleton_fast_forward.py +6 -6
  54. chia/_tests/core/server/serve.py +7 -7
  55. chia/_tests/core/server/test_dos.py +1 -2
  56. chia/_tests/core/server/test_event_loop.py +12 -4
  57. chia/_tests/core/server/test_loop.py +7 -8
  58. chia/_tests/core/server/test_rate_limits.py +9 -8
  59. chia/_tests/core/server/test_server.py +61 -1
  60. chia/_tests/core/services/test_services.py +2 -2
  61. chia/_tests/core/ssl/test_ssl.py +2 -2
  62. chia/_tests/core/test_cost_calculation.py +2 -6
  63. chia/_tests/core/test_farmer_harvester_rpc.py +3 -5
  64. chia/_tests/core/test_filter.py +0 -1
  65. chia/_tests/core/test_full_node_rpc.py +2 -2
  66. chia/_tests/core/test_merkle_set.py +1 -2
  67. chia/_tests/core/test_seeder.py +4 -4
  68. chia/_tests/core/util/test_config.py +4 -4
  69. chia/_tests/core/util/test_jsonify.py +2 -2
  70. chia/_tests/core/util/test_keychain.py +3 -3
  71. chia/_tests/core/util/test_lockfile.py +2 -1
  72. chia/_tests/core/util/test_log_exceptions.py +1 -2
  73. chia/_tests/core/util/test_streamable.py +17 -17
  74. chia/_tests/db/test_db_wrapper.py +3 -2
  75. chia/_tests/environments/wallet.py +14 -14
  76. chia/_tests/ether.py +4 -3
  77. chia/_tests/farmer_harvester/test_farmer.py +41 -24
  78. chia/_tests/farmer_harvester/test_farmer_harvester.py +50 -17
  79. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +27 -27
  80. chia/_tests/farmer_harvester/test_third_party_harvesters.py +21 -22
  81. chia/_tests/fee_estimation/test_fee_estimation_integration.py +18 -18
  82. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +11 -9
  83. chia/_tests/harvester/test_harvester_api.py +11 -4
  84. chia/_tests/plot_sync/test_plot_sync.py +13 -11
  85. chia/_tests/plot_sync/test_receiver.py +11 -10
  86. chia/_tests/plot_sync/test_sync_simulated.py +2 -2
  87. chia/_tests/plot_sync/util.py +1 -2
  88. chia/_tests/plotting/test_plot_manager.py +7 -6
  89. chia/_tests/plotting/test_prover.py +30 -38
  90. chia/_tests/pools/test_pool_cmdline.py +4 -6
  91. chia/_tests/pools/test_pool_rpc.py +203 -61
  92. chia/_tests/pools/test_pool_wallet.py +3 -3
  93. chia/_tests/pools/test_wallet_pool_store.py +1 -4
  94. chia/_tests/process_junit.py +2 -2
  95. chia/_tests/rpc/test_rpc_client.py +4 -4
  96. chia/_tests/rpc/test_rpc_server.py +3 -3
  97. chia/_tests/simulation/test_simulation.py +12 -25
  98. chia/_tests/solver/test_solver_service.py +13 -4
  99. chia/_tests/testconfig.py +2 -2
  100. chia/_tests/timelord/test_new_peak.py +22 -11
  101. chia/_tests/tools/test_run_block.py +0 -2
  102. chia/_tests/tools/test_virtual_project.py +2 -1
  103. chia/_tests/util/benchmarks.py +1 -0
  104. chia/_tests/util/blockchain.py +38 -36
  105. chia/_tests/util/blockchain_mock.py +11 -11
  106. chia/_tests/util/build_network_protocol_files.py +2 -1
  107. chia/_tests/util/coin_store.py +2 -1
  108. chia/_tests/util/config.py +1 -1
  109. chia/_tests/util/db_connection.py +2 -3
  110. chia/_tests/util/full_sync.py +9 -11
  111. chia/_tests/util/gen_ssl_certs.py +4 -5
  112. chia/_tests/util/get_name_puzzle_conditions.py +2 -0
  113. chia/_tests/util/misc.py +24 -24
  114. chia/_tests/util/network_protocol_data.py +20 -3
  115. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  116. chia/_tests/util/protocol_messages_json.py +292 -3
  117. chia/_tests/util/setup_nodes.py +62 -47
  118. chia/_tests/util/spend_sim.py +57 -57
  119. chia/_tests/util/test_async_pool.py +2 -3
  120. chia/_tests/util/test_chia_version.py +1 -3
  121. chia/_tests/util/test_config.py +3 -3
  122. chia/_tests/util/test_full_block_utils.py +6 -3
  123. chia/_tests/util/test_limited_semaphore.py +1 -2
  124. chia/_tests/util/test_misc.py +2 -2
  125. chia/_tests/util/test_network.py +1 -2
  126. chia/_tests/util/test_priority_mutex.py +3 -3
  127. chia/_tests/util/test_recursive_replace.py +5 -6
  128. chia/_tests/util/test_replace_str_to_bytes.py +8 -10
  129. chia/_tests/util/test_testnet_overrides.py +3 -3
  130. chia/_tests/util/time_out_assert.py +2 -2
  131. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +4 -6
  132. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -4
  133. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +19 -13
  134. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +13 -13
  135. chia/_tests/wallet/cat_wallet/test_trades.py +40 -38
  136. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -4
  137. chia/_tests/wallet/conftest.py +6 -6
  138. chia/_tests/wallet/db_wallet/test_db_graftroot.py +1 -1
  139. chia/_tests/wallet/db_wallet/test_dl_offers.py +34 -34
  140. chia/_tests/wallet/did_wallet/test_did.py +16 -6
  141. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +21 -21
  142. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +20 -6
  143. chia/_tests/wallet/nft_wallet/test_nft_offers.py +19 -21
  144. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +1 -2
  145. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +121 -2
  146. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +6 -9
  147. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +44 -1
  148. chia/_tests/wallet/rpc/test_wallet_rpc.py +1672 -896
  149. chia/_tests/wallet/sync/test_wallet_sync.py +43 -47
  150. chia/_tests/wallet/test_clvm_streamable.py +2 -3
  151. chia/_tests/wallet/test_coin_management.py +2 -2
  152. chia/_tests/wallet/test_conditions.py +45 -51
  153. chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
  154. chia/_tests/wallet/test_new_wallet_protocol.py +4 -6
  155. chia/_tests/wallet/test_notifications.py +14 -14
  156. chia/_tests/wallet/test_signer_protocol.py +5 -5
  157. chia/_tests/wallet/test_singleton_lifecycle_fast.py +4 -3
  158. chia/_tests/wallet/test_transaction_store.py +20 -20
  159. chia/_tests/wallet/test_util.py +2 -2
  160. chia/_tests/wallet/test_wallet.py +380 -228
  161. chia/_tests/wallet/test_wallet_action_scope.py +4 -4
  162. chia/_tests/wallet/test_wallet_blockchain.py +12 -12
  163. chia/_tests/wallet/test_wallet_coin_store.py +3 -4
  164. chia/_tests/wallet/test_wallet_node.py +14 -14
  165. chia/_tests/wallet/test_wallet_test_framework.py +2 -1
  166. chia/_tests/wallet/test_wallet_utils.py +2 -3
  167. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -5
  168. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +14 -15
  169. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -24
  170. chia/_tests/wallet/wallet_block_tools.py +12 -11
  171. chia/_tests/weight_proof/config.py +1 -0
  172. chia/_tests/weight_proof/test_weight_proof.py +5 -4
  173. chia/apis/__init__.py +21 -0
  174. chia/apis/farmer_stub.py +102 -0
  175. chia/apis/full_node_stub.py +372 -0
  176. chia/apis/harvester_stub.py +57 -0
  177. chia/apis/introducer_stub.py +35 -0
  178. chia/apis/solver_stub.py +30 -0
  179. chia/apis/stub_protocol_registry.py +21 -0
  180. chia/apis/timelord_stub.py +39 -0
  181. chia/apis/wallet_stub.py +161 -0
  182. chia/cmds/beta.py +3 -4
  183. chia/cmds/beta_funcs.py +4 -3
  184. chia/cmds/check_wallet_db.py +4 -4
  185. chia/cmds/chia.py +1 -2
  186. chia/cmds/cmd_classes.py +11 -13
  187. chia/cmds/cmd_helpers.py +11 -11
  188. chia/cmds/cmds_util.py +15 -15
  189. chia/cmds/coin_funcs.py +6 -7
  190. chia/cmds/coins.py +2 -3
  191. chia/cmds/configure.py +1 -2
  192. chia/cmds/data.py +42 -42
  193. chia/cmds/data_funcs.py +81 -81
  194. chia/cmds/db.py +4 -5
  195. chia/cmds/db_backup_func.py +2 -2
  196. chia/cmds/db_upgrade_func.py +3 -3
  197. chia/cmds/db_validate_func.py +2 -2
  198. chia/cmds/dev/data.py +4 -4
  199. chia/cmds/dev/gh.py +5 -5
  200. chia/cmds/dev/installers.py +2 -3
  201. chia/cmds/dev/mempool.py +3 -4
  202. chia/cmds/dev/mempool_funcs.py +4 -4
  203. chia/cmds/dev/sim.py +8 -8
  204. chia/cmds/dump_keyring.py +3 -3
  205. chia/cmds/farm.py +6 -8
  206. chia/cmds/farm_funcs.py +25 -24
  207. chia/cmds/init_funcs.py +4 -4
  208. chia/cmds/keys.py +16 -18
  209. chia/cmds/keys_funcs.py +36 -36
  210. chia/cmds/netspace.py +1 -3
  211. chia/cmds/netspace_funcs.py +1 -2
  212. chia/cmds/options.py +3 -2
  213. chia/cmds/param_types.py +17 -16
  214. chia/cmds/passphrase.py +6 -7
  215. chia/cmds/passphrase_funcs.py +11 -13
  216. chia/cmds/peer.py +1 -3
  217. chia/cmds/peer_funcs.py +3 -3
  218. chia/cmds/plotnft.py +6 -7
  219. chia/cmds/plotnft_funcs.py +37 -26
  220. chia/cmds/rpc.py +3 -3
  221. chia/cmds/show.py +3 -5
  222. chia/cmds/show_funcs.py +9 -9
  223. chia/cmds/sim_funcs.py +25 -26
  224. chia/cmds/solver.py +1 -3
  225. chia/cmds/solver_funcs.py +1 -2
  226. chia/cmds/start_funcs.py +2 -2
  227. chia/cmds/wallet.py +76 -81
  228. chia/cmds/wallet_funcs.py +206 -177
  229. chia/consensus/augmented_chain.py +6 -6
  230. chia/consensus/block_body_validation.py +19 -15
  231. chia/consensus/block_creation.py +25 -21
  232. chia/consensus/block_header_validation.py +27 -13
  233. chia/consensus/block_height_map.py +3 -6
  234. chia/consensus/block_height_map_protocol.py +2 -2
  235. chia/consensus/block_record.py +2 -4
  236. chia/consensus/blockchain.py +58 -40
  237. chia/consensus/blockchain_interface.py +7 -7
  238. chia/consensus/coin_store_protocol.py +5 -6
  239. chia/consensus/condition_tools.py +4 -4
  240. chia/consensus/cost_calculator.py +2 -3
  241. chia/consensus/default_constants.py +16 -13
  242. chia/consensus/deficit.py +1 -3
  243. chia/consensus/difficulty_adjustment.py +3 -5
  244. chia/consensus/find_fork_point.py +2 -4
  245. chia/consensus/full_block_to_block_record.py +11 -13
  246. chia/consensus/generator_tools.py +2 -3
  247. chia/consensus/get_block_challenge.py +42 -26
  248. chia/consensus/get_block_generator.py +2 -3
  249. chia/consensus/make_sub_epoch_summary.py +8 -7
  250. chia/consensus/multiprocess_validation.py +31 -20
  251. chia/consensus/pos_quality.py +6 -23
  252. chia/consensus/pot_iterations.py +17 -44
  253. chia/consensus/signage_point.py +4 -5
  254. chia/consensus/vdf_info_computation.py +2 -4
  255. chia/daemon/client.py +8 -8
  256. chia/daemon/keychain_proxy.py +31 -37
  257. chia/daemon/server.py +32 -33
  258. chia/daemon/windows_signal.py +4 -3
  259. chia/data_layer/data_layer.py +86 -77
  260. chia/data_layer/data_layer_rpc_api.py +9 -9
  261. chia/data_layer/data_layer_rpc_client.py +13 -15
  262. chia/data_layer/data_layer_server.py +3 -3
  263. chia/data_layer/data_layer_util.py +14 -14
  264. chia/data_layer/data_layer_wallet.py +94 -101
  265. chia/data_layer/data_store.py +50 -50
  266. chia/data_layer/dl_wallet_store.py +9 -12
  267. chia/data_layer/download_data.py +8 -9
  268. chia/data_layer/s3_plugin_service.py +5 -9
  269. chia/data_layer/start_data_layer.py +5 -5
  270. chia/farmer/farmer.py +31 -31
  271. chia/farmer/farmer_api.py +45 -33
  272. chia/farmer/farmer_rpc_api.py +5 -4
  273. chia/farmer/farmer_rpc_client.py +6 -6
  274. chia/farmer/start_farmer.py +12 -7
  275. chia/full_node/block_store.py +13 -16
  276. chia/full_node/check_fork_next_block.py +1 -2
  277. chia/full_node/coin_store.py +15 -16
  278. chia/full_node/eligible_coin_spends.py +3 -3
  279. chia/full_node/fee_estimate_store.py +2 -3
  280. chia/full_node/fee_tracker.py +1 -2
  281. chia/full_node/full_block_utils.py +4 -4
  282. chia/full_node/full_node.py +238 -224
  283. chia/full_node/full_node_api.py +193 -150
  284. chia/full_node/full_node_rpc_api.py +53 -31
  285. chia/full_node/full_node_rpc_client.py +18 -19
  286. chia/full_node/full_node_store.py +45 -43
  287. chia/full_node/hint_management.py +2 -2
  288. chia/full_node/mempool.py +17 -19
  289. chia/full_node/mempool_manager.py +89 -42
  290. chia/full_node/pending_tx_cache.py +2 -3
  291. chia/full_node/start_full_node.py +5 -5
  292. chia/full_node/sync_store.py +3 -4
  293. chia/full_node/tx_processing_queue.py +34 -13
  294. chia/full_node/weight_proof.py +61 -48
  295. chia/harvester/harvester.py +25 -24
  296. chia/harvester/harvester_api.py +61 -38
  297. chia/harvester/harvester_rpc_api.py +10 -10
  298. chia/harvester/start_harvester.py +4 -4
  299. chia/introducer/introducer.py +3 -3
  300. chia/introducer/introducer_api.py +6 -4
  301. chia/introducer/start_introducer.py +4 -4
  302. chia/legacy/keyring.py +3 -3
  303. chia/plot_sync/delta.py +1 -2
  304. chia/plot_sync/receiver.py +20 -17
  305. chia/plot_sync/sender.py +15 -10
  306. chia/plotters/bladebit.py +7 -7
  307. chia/plotters/chiapos.py +2 -2
  308. chia/plotters/madmax.py +4 -4
  309. chia/plotters/plotters.py +4 -4
  310. chia/plotters/plotters_util.py +3 -3
  311. chia/plotting/cache.py +20 -14
  312. chia/plotting/check_plots.py +26 -35
  313. chia/plotting/create_plots.py +22 -23
  314. chia/plotting/manager.py +21 -14
  315. chia/plotting/prover.py +59 -42
  316. chia/plotting/util.py +16 -16
  317. chia/pools/pool_config.py +2 -1
  318. chia/pools/pool_puzzles.py +11 -12
  319. chia/pools/pool_wallet.py +34 -57
  320. chia/pools/pool_wallet_info.py +39 -10
  321. chia/protocols/farmer_protocol.py +8 -9
  322. chia/protocols/fee_estimate.py +3 -4
  323. chia/protocols/full_node_protocol.py +3 -4
  324. chia/protocols/harvester_protocol.py +27 -15
  325. chia/protocols/outbound_message.py +3 -3
  326. chia/protocols/pool_protocol.py +8 -9
  327. chia/protocols/shared_protocol.py +1 -2
  328. chia/protocols/solver_protocol.py +9 -2
  329. chia/protocols/timelord_protocol.py +4 -7
  330. chia/protocols/wallet_protocol.py +11 -12
  331. chia/rpc/rpc_client.py +9 -9
  332. chia/rpc/rpc_server.py +17 -17
  333. chia/rpc/util.py +2 -2
  334. chia/seeder/crawler.py +8 -8
  335. chia/seeder/crawler_api.py +21 -27
  336. chia/seeder/crawler_rpc_api.py +2 -2
  337. chia/seeder/dns_server.py +21 -21
  338. chia/seeder/start_crawler.py +4 -4
  339. chia/server/address_manager.py +15 -16
  340. chia/server/api_protocol.py +11 -11
  341. chia/server/chia_policy.py +46 -26
  342. chia/server/introducer_peers.py +2 -3
  343. chia/server/node_discovery.py +19 -19
  344. chia/server/rate_limit_numbers.py +4 -5
  345. chia/server/rate_limits.py +4 -4
  346. chia/server/resolve_peer_info.py +4 -4
  347. chia/server/server.py +49 -52
  348. chia/server/signal_handlers.py +6 -6
  349. chia/server/start_service.py +17 -17
  350. chia/server/upnp.py +4 -6
  351. chia/server/ws_connection.py +52 -37
  352. chia/simulator/add_blocks_in_batches.py +1 -3
  353. chia/simulator/block_tools.py +312 -200
  354. chia/simulator/full_node_simulator.py +56 -35
  355. chia/simulator/keyring.py +2 -3
  356. chia/simulator/setup_services.py +16 -15
  357. chia/simulator/simulator_full_node_rpc_api.py +1 -2
  358. chia/simulator/simulator_full_node_rpc_client.py +1 -2
  359. chia/simulator/simulator_protocol.py +1 -2
  360. chia/simulator/simulator_test_tools.py +3 -3
  361. chia/simulator/start_simulator.py +7 -7
  362. chia/simulator/wallet_tools.py +10 -10
  363. chia/solver/solver.py +10 -10
  364. chia/solver/solver_api.py +10 -8
  365. chia/solver/solver_rpc_api.py +2 -2
  366. chia/solver/start_solver.py +4 -4
  367. chia/ssl/cacert.pem +148 -90
  368. chia/ssl/chia_ca.crt +14 -10
  369. chia/ssl/chia_ca_old.crt +19 -0
  370. chia/ssl/create_ssl.py +4 -4
  371. chia/ssl/renewedselfsignedca.conf +4 -0
  372. chia/ssl/ssl_check.py +1 -2
  373. chia/timelord/iters_from_block.py +1 -4
  374. chia/timelord/start_timelord.py +4 -4
  375. chia/timelord/timelord.py +44 -40
  376. chia/timelord/timelord_api.py +6 -4
  377. chia/timelord/timelord_launcher.py +2 -2
  378. chia/timelord/timelord_rpc_api.py +2 -2
  379. chia/timelord/timelord_state.py +11 -12
  380. chia/types/block_protocol.py +1 -3
  381. chia/types/blockchain_format/coin.py +1 -3
  382. chia/types/blockchain_format/program.py +11 -8
  383. chia/types/blockchain_format/proof_of_space.py +123 -76
  384. chia/types/blockchain_format/tree_hash.py +3 -3
  385. chia/types/blockchain_format/vdf.py +1 -2
  386. chia/types/coin_spend.py +3 -3
  387. chia/types/mempool_item.py +5 -5
  388. chia/types/mempool_submission_status.py +2 -3
  389. chia/types/peer_info.py +1 -2
  390. chia/types/unfinished_header_block.py +3 -4
  391. chia/types/validation_state.py +1 -2
  392. chia/util/action_scope.py +8 -8
  393. chia/util/async_pool.py +5 -5
  394. chia/util/bech32m.py +1 -2
  395. chia/util/beta_metrics.py +2 -2
  396. chia/util/block_cache.py +4 -4
  397. chia/util/chia_logging.py +2 -2
  398. chia/util/chia_version.py +1 -2
  399. chia/util/config.py +15 -16
  400. chia/util/db_wrapper.py +26 -27
  401. chia/util/default_root.py +1 -2
  402. chia/util/errors.py +3 -3
  403. chia/util/file_keyring.py +14 -14
  404. chia/util/files.py +2 -3
  405. chia/util/hash.py +4 -4
  406. chia/util/initial-config.yaml +3 -5
  407. chia/util/inline_executor.py +2 -1
  408. chia/util/ip_address.py +1 -2
  409. chia/util/keychain.py +25 -27
  410. chia/util/keyring_wrapper.py +18 -19
  411. chia/util/lock.py +3 -4
  412. chia/util/log_exceptions.py +1 -2
  413. chia/util/lru_cache.py +2 -2
  414. chia/util/network.py +6 -6
  415. chia/util/path.py +2 -3
  416. chia/util/priority_mutex.py +2 -2
  417. chia/util/profiler.py +1 -2
  418. chia/util/safe_cancel_task.py +1 -2
  419. chia/util/streamable.py +22 -8
  420. chia/util/task_referencer.py +1 -1
  421. chia/util/timing.py +3 -3
  422. chia/util/virtual_project_analysis.py +6 -5
  423. chia/util/ws_message.py +2 -2
  424. chia/wallet/cat_wallet/cat_info.py +3 -4
  425. chia/wallet/cat_wallet/cat_outer_puzzle.py +12 -11
  426. chia/wallet/cat_wallet/cat_utils.py +3 -4
  427. chia/wallet/cat_wallet/cat_wallet.py +61 -83
  428. chia/wallet/cat_wallet/lineage_store.py +3 -4
  429. chia/wallet/cat_wallet/r_cat_wallet.py +19 -22
  430. chia/wallet/coin_selection.py +9 -10
  431. chia/wallet/conditions.py +120 -105
  432. chia/wallet/db_wallet/db_wallet_puzzles.py +4 -5
  433. chia/wallet/derivation_record.py +1 -2
  434. chia/wallet/derive_keys.py +2 -4
  435. chia/wallet/did_wallet/did_info.py +10 -11
  436. chia/wallet/did_wallet/did_wallet.py +36 -82
  437. chia/wallet/did_wallet/did_wallet_puzzles.py +7 -8
  438. chia/wallet/driver_protocol.py +5 -7
  439. chia/wallet/lineage_proof.py +4 -4
  440. chia/wallet/nft_wallet/metadata_outer_puzzle.py +11 -11
  441. chia/wallet/nft_wallet/nft_info.py +8 -9
  442. chia/wallet/nft_wallet/nft_puzzle_utils.py +8 -8
  443. chia/wallet/nft_wallet/nft_wallet.py +79 -116
  444. chia/wallet/nft_wallet/ownership_outer_puzzle.py +14 -14
  445. chia/wallet/nft_wallet/singleton_outer_puzzle.py +12 -11
  446. chia/wallet/nft_wallet/transfer_program_puzzle.py +11 -11
  447. chia/wallet/nft_wallet/uncurry_nft.py +10 -11
  448. chia/wallet/notification_manager.py +3 -3
  449. chia/wallet/notification_store.py +44 -61
  450. chia/wallet/outer_puzzles.py +6 -7
  451. chia/wallet/puzzle_drivers.py +34 -6
  452. chia/wallet/puzzles/clawback/drivers.py +6 -6
  453. chia/wallet/puzzles/deployed_puzzle_hashes.json +1 -54
  454. chia/wallet/puzzles/load_clvm.py +1 -1
  455. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -2
  456. chia/wallet/puzzles/singleton_top_layer.py +2 -3
  457. chia/wallet/puzzles/singleton_top_layer_v1_1.py +3 -4
  458. chia/wallet/puzzles/tails.py +3 -3
  459. chia/wallet/singleton.py +5 -7
  460. chia/wallet/singleton_record.py +3 -3
  461. chia/wallet/start_wallet.py +5 -5
  462. chia/wallet/trade_manager.py +37 -58
  463. chia/wallet/trade_record.py +4 -4
  464. chia/wallet/trading/offer.py +59 -46
  465. chia/wallet/trading/trade_store.py +8 -9
  466. chia/wallet/transaction_record.py +8 -8
  467. chia/wallet/uncurried_puzzle.py +1 -2
  468. chia/wallet/util/clvm_streamable.py +12 -12
  469. chia/wallet/util/compute_hints.py +4 -5
  470. chia/wallet/util/curry_and_treehash.py +1 -2
  471. chia/wallet/util/merkle_tree.py +2 -3
  472. chia/wallet/util/peer_request_cache.py +8 -8
  473. chia/wallet/util/signing.py +85 -0
  474. chia/wallet/util/tx_config.py +15 -6
  475. chia/wallet/util/wallet_sync_utils.py +14 -16
  476. chia/wallet/util/wallet_types.py +2 -2
  477. chia/wallet/vc_wallet/cr_cat_drivers.py +10 -11
  478. chia/wallet/vc_wallet/cr_cat_wallet.py +50 -68
  479. chia/wallet/vc_wallet/cr_outer_puzzle.py +14 -13
  480. chia/wallet/vc_wallet/vc_drivers.py +27 -27
  481. chia/wallet/vc_wallet/vc_store.py +5 -6
  482. chia/wallet/vc_wallet/vc_wallet.py +33 -61
  483. chia/wallet/wallet.py +50 -78
  484. chia/wallet/wallet_action_scope.py +11 -11
  485. chia/wallet/wallet_blockchain.py +12 -12
  486. chia/wallet/wallet_coin_record.py +12 -6
  487. chia/wallet/wallet_coin_store.py +24 -25
  488. chia/wallet/wallet_interested_store.py +3 -5
  489. chia/wallet/wallet_nft_store.py +10 -11
  490. chia/wallet/wallet_node.py +53 -61
  491. chia/wallet/wallet_node_api.py +5 -3
  492. chia/wallet/wallet_protocol.py +23 -23
  493. chia/wallet/wallet_puzzle_store.py +15 -18
  494. chia/wallet/wallet_request_types.py +778 -114
  495. chia/wallet/wallet_retry_store.py +1 -3
  496. chia/wallet/wallet_rpc_api.py +572 -909
  497. chia/wallet/wallet_rpc_client.py +87 -279
  498. chia/wallet/wallet_singleton_store.py +3 -4
  499. chia/wallet/wallet_state_manager.py +332 -106
  500. chia/wallet/wallet_transaction_store.py +11 -14
  501. chia/wallet/wallet_user_store.py +4 -6
  502. chia/wallet/wallet_weight_proof_handler.py +4 -4
  503. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/METADATA +6 -5
  504. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/RECORD +507 -516
  505. chia/apis.py +0 -21
  506. chia/consensus/check_time_locks.py +0 -57
  507. chia/data_layer/puzzles/__init__.py +0 -0
  508. chia/data_layer/puzzles/graftroot_dl_offers.clsp +0 -100
  509. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +0 -1
  510. chia/types/coin_record.py +0 -44
  511. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  512. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +0 -6
  513. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +0 -1
  514. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +0 -6
  515. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +0 -1
  516. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +0 -30
  517. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +0 -1
  518. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +0 -28
  519. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +0 -1
  520. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +0 -100
  521. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +0 -1
  522. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +0 -78
  523. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +0 -1
  524. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +0 -74
  525. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +0 -1
  526. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/WHEEL +0 -0
  527. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/entry_points.txt +0 -0
  528. {chia_blockchain-2.5.7rc3.dist-info → chia_blockchain-2.5.8rc1.dist-info}/licenses/LICENSE +0 -0
@@ -10,11 +10,14 @@ import ssl
10
10
  import sys
11
11
  import tempfile
12
12
  import time
13
- from collections.abc import Sequence
13
+ from collections.abc import AsyncIterator, Callable, Iterator, Sequence
14
+ from contextlib import asynccontextmanager, contextmanager
14
15
  from dataclasses import dataclass, replace
16
+ from functools import lru_cache
15
17
  from pathlib import Path
16
18
  from random import Random
17
- from typing import Any, Callable, Optional, Union
19
+ from types import TracebackType
20
+ from typing import Any
18
21
 
19
22
  import anyio
20
23
  from chia_puzzles_py.programs import CHIALISP_DESERIALISATION, ROM_BOOTSTRAP_GENERATOR
@@ -37,9 +40,12 @@ from chia_rs import (
37
40
  SubSlotProofs,
38
41
  UnfinishedBlock,
39
42
  solution_generator,
43
+ solve_proof,
40
44
  )
41
45
  from chia_rs.sized_bytes import bytes32
42
46
  from chia_rs.sized_ints import uint8, uint16, uint32, uint64, uint128
47
+ from filelock import FileLock
48
+ from typing_extensions import Self
43
49
 
44
50
  from chia.consensus.block_creation import create_unfinished_block, unfinished_block_to_full_block
45
51
  from chia.consensus.block_record import BlockRecordProtocol
@@ -49,6 +55,7 @@ from chia.consensus.constants import replace_str_to_bytes
49
55
  from chia.consensus.default_constants import DEFAULT_CONSTANTS
50
56
  from chia.consensus.deficit import calculate_deficit
51
57
  from chia.consensus.full_block_to_block_record import block_to_block_record
58
+ from chia.consensus.get_block_challenge import pre_sp_tx_block_height
52
59
  from chia.consensus.make_sub_epoch_summary import next_sub_epoch_summary
53
60
  from chia.consensus.pot_iterations import (
54
61
  calculate_ip_iters,
@@ -62,9 +69,10 @@ from chia.consensus.signage_point import SignagePoint
62
69
  from chia.consensus.vdf_info_computation import get_signage_point_vdf_info
63
70
  from chia.daemon.keychain_proxy import KeychainProxy, connect_to_keychain_and_validate, wrap_local_keychain
64
71
  from chia.full_node.bundle_tools import simple_solution_generator, simple_solution_generator_backrefs
72
+ from chia.plotting.cache import cached_master_sk_to_local_sk
65
73
  from chia.plotting.create_plots import PlotKeys, create_plots
66
74
  from chia.plotting.manager import PlotManager
67
- from chia.plotting.prover import PlotVersion
75
+ from chia.plotting.prover import PlotVersion, QualityProtocol, V1Prover, V2Prover, V2Quality
68
76
  from chia.plotting.util import (
69
77
  Params,
70
78
  PlotRefreshEvents,
@@ -92,13 +100,12 @@ from chia.types.blockchain_format.program import DEFAULT_FLAGS, INFINITE_COST, P
92
100
  from chia.types.blockchain_format.proof_of_space import (
93
101
  calculate_pos_challenge,
94
102
  calculate_prefix_bits,
95
- calculate_required_plot_strength,
96
103
  generate_plot_public_key,
97
104
  generate_taproot_sk,
105
+ is_v1_phased_out,
98
106
  make_pos,
107
+ num_phase_out_epochs,
99
108
  passes_plot_filter,
100
- quality_for_partial_proof,
101
- solve_proof,
102
109
  )
103
110
  from chia.types.blockchain_format.serialized_program import SerializedProgram
104
111
  from chia.types.blockchain_format.vdf import VDFInfo, VDFProof
@@ -120,7 +127,6 @@ from chia.util.keychain import Keychain, bytes_to_mnemonic
120
127
  from chia.util.timing import adjusted_timeout, backoff_times
121
128
  from chia.wallet.derive_keys import (
122
129
  master_sk_to_farmer_sk,
123
- master_sk_to_local_sk,
124
130
  master_sk_to_pool_sk,
125
131
  master_sk_to_wallet_sk,
126
132
  )
@@ -132,14 +138,13 @@ GENERATOR_MOD: SerializedProgram = SerializedProgram.from_bytes(ROM_BOOTSTRAP_GE
132
138
 
133
139
  test_constants = DEFAULT_CONSTANTS.replace(
134
140
  MIN_PLOT_SIZE_V1=uint8(18),
135
- # TODO: todo_v2_plots decide on v2 test plot k-size
136
- MIN_PLOT_SIZE_V2=uint8(18),
141
+ PLOT_SIZE_V2=uint8(18),
137
142
  MIN_BLOCKS_PER_CHALLENGE_BLOCK=uint8(12),
138
143
  DIFFICULTY_STARTING=uint64(2**10),
139
144
  DISCRIMINANT_SIZE_BITS=uint16(16),
140
145
  SUB_EPOCH_BLOCKS=uint32(170),
141
146
  WEIGHT_PROOF_THRESHOLD=uint8(2),
142
- WEIGHT_PROOF_RECENT_BLOCKS=uint32(380),
147
+ WEIGHT_PROOF_RECENT_BLOCKS=uint32(500),
143
148
  DIFFICULTY_CONSTANT_FACTOR=uint128(33554432),
144
149
  NUM_SPS_SUB_SLOT=uint8(16), # Must be a power of 2
145
150
  MAX_SUB_SLOT_BLOCKS=uint32(50),
@@ -154,9 +159,15 @@ test_constants = DEFAULT_CONSTANTS.replace(
154
159
  # Allows creating blockchains with timestamps up to 10 days in the future, for testing
155
160
  MAX_FUTURE_TIME2=uint32(3600 * 24 * 10),
156
161
  MEMPOOL_BLOCK_BUFFER=uint8(6),
162
+ PLOT_V1_PHASE_OUT_EPOCH_BITS=uint8(3),
157
163
  )
158
164
 
159
165
 
166
+ @lru_cache
167
+ def cached_master_sk_to_farmer_sk(master: PrivateKey) -> PrivateKey:
168
+ return master_sk_to_farmer_sk(master)
169
+
170
+
160
171
  def compute_additions_unchecked(sb: SpendBundle) -> list[Coin]:
161
172
  ret: list[Coin] = []
162
173
  for cs in sb.coin_spends:
@@ -246,9 +257,9 @@ class BlockTools:
246
257
  def __init__(
247
258
  self,
248
259
  constants: ConsensusConstants = test_constants,
249
- root_path: Optional[Path] = None,
250
- keychain: Optional[Keychain] = None,
251
- config_overrides: Optional[dict[str, Any]] = None,
260
+ root_path: Path | None = None,
261
+ keychain: Keychain | None = None,
262
+ config_overrides: dict[str, Any] | None = None,
252
263
  automated_testing: bool = True,
253
264
  plot_dir: str = "test-plots",
254
265
  log: logging.Logger = logging.getLogger(__name__),
@@ -257,7 +268,7 @@ class BlockTools:
257
268
 
258
269
  self._tempdir = None
259
270
  if root_path is None:
260
- self._tempdir = tempfile.TemporaryDirectory()
271
+ self._tempdir = tempfile.TemporaryDirectory(ignore_cleanup_errors=True)
261
272
  root_path = Path(self._tempdir.name)
262
273
 
263
274
  self.root_path = root_path
@@ -340,64 +351,90 @@ class BlockTools:
340
351
  assert self.total_result.processed == update_result.processed
341
352
  assert self.total_result.duration == update_result.duration
342
353
  assert update_result.remaining == 0
354
+
355
+ expected_plots: set[str] = set()
356
+ found_plots: set[str] = set()
357
+ if len(self.plot_manager.plots) != len(self.expected_plots): # pragma: no cover
358
+ for pid, filename in self.expected_plots.items():
359
+ expected_plots.add(filename.name)
360
+ for filename, _ in self.plot_manager.plots.items():
361
+ found_plots.add(filename.name)
362
+ print(f"directory: {self.plot_dir}")
363
+ print(f"expected: {len(expected_plots)}")
364
+ for f in expected_plots:
365
+ print(f)
366
+ print(f"plot manager: {len(found_plots)}")
367
+ for f in found_plots:
368
+ print(f)
369
+ diff = found_plots.difference(expected_plots)
370
+ print(f"found unexpected: {len(diff)}")
371
+ for f in diff:
372
+ print(f)
373
+ diff = expected_plots.difference(found_plots)
374
+ print(f"not found: {len(diff)}")
375
+ for f in diff:
376
+ print(f)
343
377
  assert len(self.plot_manager.plots) == len(self.expected_plots)
344
378
 
345
379
  self.plot_manager: PlotManager = PlotManager(
346
380
  self.root_path,
347
381
  refresh_parameter=PlotsRefreshParameter(batch_size=uint32(2)),
348
382
  refresh_callback=test_callback,
383
+ constants=self.constants,
349
384
  match_str=str(self.plot_dir.relative_to(DEFAULT_ROOT_PATH.parent)) if not automated_testing else None,
350
385
  )
351
386
 
387
+ def __enter__(self) -> Self:
388
+ return self
389
+
390
+ def __exit__(
391
+ self,
392
+ exc_type: type[BaseException] | None,
393
+ exc: BaseException | None,
394
+ traceback: TracebackType | None,
395
+ ) -> None:
396
+ if self._tempdir is not None:
397
+ self._tempdir.cleanup()
398
+
352
399
  def setup_new_gen(
353
400
  self,
354
- tx_block_heights: list[uint32],
401
+ generator_block_heights: list[uint32],
355
402
  curr: BlockRecordProtocol,
356
- wallet: Optional[WalletTool],
357
- rng: Optional[random.Random],
403
+ wallet: WalletTool | None,
404
+ rng: random.Random | None,
358
405
  available_coins: list[Coin],
359
406
  *,
360
407
  prev_tx_height: uint32,
361
408
  dummy_block_references: bool,
362
409
  include_transactions: bool,
363
- transaction_data: Optional[SpendBundle],
410
+ block_generator: NewBlockGenerator | None,
364
411
  block_refs: list[uint32],
365
- ) -> Optional[NewBlockGenerator]:
412
+ ) -> NewBlockGenerator | None:
413
+ if prev_tx_height >= self.constants.HARD_FORK2_HEIGHT:
414
+ assert block_refs == [], "block references are not allowed after hard fork 2"
415
+ dummy_block_references = False
416
+
366
417
  # we don't know if the new block will be a transaction
367
418
  # block or not, so even though we prepare a block
368
419
  # generator, we can't update our state (like,
369
420
  # available_coins) until it's confirmed the block
370
421
  # generator made it into the block.
371
422
  dummy_refs: list[uint32]
372
- if dummy_block_references and len(tx_block_heights) > 4:
423
+ if dummy_block_references and len(generator_block_heights) > 4:
373
424
  dummy_refs = [
374
- tx_block_heights[1],
375
- tx_block_heights[len(tx_block_heights) // 2],
376
- tx_block_heights[-2],
425
+ generator_block_heights[1],
426
+ generator_block_heights[len(generator_block_heights) // 2],
427
+ generator_block_heights[-2],
377
428
  ]
378
429
  else:
379
430
  dummy_refs = []
380
431
 
381
- if transaction_data is not None:
382
- # this means the caller passed in transaction_data
432
+ if block_generator is not None:
433
+ # this means the caller passed in block_generator
383
434
  # to be included in the block.
384
- additions = compute_additions_unchecked(transaction_data)
385
- removals = transaction_data.removals()
386
- if curr.height >= self.constants.HARD_FORK_HEIGHT:
387
- program = simple_solution_generator_backrefs(transaction_data).program
388
- else:
389
- program = simple_solution_generator(transaction_data).program
390
- block_refs = []
391
- cost = compute_block_cost(program, self.constants, uint32(curr.height + 1), prev_tx_height)
392
- return NewBlockGenerator(
393
- program,
394
- [],
395
- block_refs,
396
- transaction_data.aggregated_signature,
397
- additions,
398
- removals,
399
- cost,
400
- )
435
+ assert block_refs == [], "block references cannot be combined with block_generator"
436
+ assert not dummy_block_references, "(dummy) block references cannot be combined with block_generator"
437
+ return block_generator
401
438
 
402
439
  if include_transactions:
403
440
  # if the caller did not pass in specific
@@ -426,8 +463,8 @@ class BlockTools:
426
463
 
427
464
  return None
428
465
 
429
- async def setup_keys(self, fingerprint: Optional[int] = None, reward_ph: Optional[bytes32] = None) -> None:
430
- keychain_proxy: Optional[KeychainProxy]
466
+ async def setup_keys(self, fingerprint: int | None = None, reward_ph: bytes32 | None = None) -> None:
467
+ keychain_proxy: KeychainProxy | None
431
468
  try:
432
469
  if self.local_keychain:
433
470
  keychain_proxy = wrap_local_keychain(self.local_keychain, log=self.log)
@@ -454,7 +491,7 @@ class BlockTools:
454
491
  assert sk is not None
455
492
  self.pool_master_sk = sk
456
493
 
457
- self.farmer_pk = master_sk_to_farmer_sk(self.farmer_master_sk).get_g1()
494
+ self.farmer_pk = cached_master_sk_to_farmer_sk(self.farmer_master_sk).get_g1()
458
495
  self.pool_pk = master_sk_to_pool_sk(self.pool_master_sk).get_g1()
459
496
 
460
497
  if reward_ph is None:
@@ -473,7 +510,7 @@ class BlockTools:
473
510
  self.all_sks = [self.farmer_master_sk] # we only want to include plots under the same fingerprint
474
511
  self.pool_pubkeys: list[G1Element] = [master_sk_to_pool_sk(sk).get_g1() for sk in self.all_sks]
475
512
 
476
- self.farmer_pubkeys: list[G1Element] = [master_sk_to_farmer_sk(sk).get_g1() for sk in self.all_sks]
513
+ self.farmer_pubkeys: list[G1Element] = [cached_master_sk_to_farmer_sk(sk).get_g1() for sk in self.all_sks]
477
514
  if len(self.pool_pubkeys) == 0 or len(self.farmer_pubkeys) == 0:
478
515
  raise RuntimeError("Keys not generated. Run `chia keys generate`")
479
516
 
@@ -502,41 +539,48 @@ class BlockTools:
502
539
  num_non_keychain_plots: int = 3,
503
540
  plot_size: int = 20,
504
541
  bitfield: bool = True,
542
+ testrun_uid: str | None = None,
505
543
  ) -> bool:
506
- self.add_plot_directory(self.plot_dir)
507
- assert self.created_plots == 0
508
- existing_plots: bool = True
509
- # OG Plots
510
- for i in range(num_og_plots):
511
- plot = await self.new_plot(plot_size=plot_size, bitfield=bitfield)
512
- if plot.new_plot:
513
- existing_plots = False
514
- # Pool Plots
515
- for i in range(num_pool_plots):
516
- plot = await self.new_plot(self.pool_ph, plot_size=plot_size, bitfield=bitfield)
517
- if plot.new_plot:
518
- existing_plots = False
519
- # Some plots with keys that are not in the keychain
520
- for i in range(num_non_keychain_plots):
521
- plot = await self.new_plot(
522
- path=self.plot_dir / "not_in_keychain",
523
- plot_keys=PlotKeys(G1Element(), G1Element(), None),
524
- exclude_plots=True,
525
- plot_size=plot_size,
526
- bitfield=bitfield,
527
- )
528
- if plot.new_plot:
529
- existing_plots = False
530
- await self.refresh_plots()
531
- assert len(self.plot_manager.plots) == len(self.expected_plots)
532
- return existing_plots
544
+ if testrun_uid is None:
545
+ lock_file_name = self.plot_dir / ".lockfile"
546
+ else:
547
+ lock_file_name = self.plot_dir / (testrun_uid + ".lockfile")
548
+
549
+ with FileLock(lock_file_name):
550
+ self.add_plot_directory(self.plot_dir)
551
+ assert self.created_plots == 0
552
+ existing_plots: bool = True
553
+ # OG Plots
554
+ for i in range(num_og_plots):
555
+ plot = await self.new_plot(plot_size=plot_size, bitfield=bitfield)
556
+ if plot.new_plot:
557
+ existing_plots = False
558
+ # Pool Plots
559
+ for i in range(num_pool_plots):
560
+ plot = await self.new_plot(self.pool_ph, plot_size=plot_size, bitfield=bitfield)
561
+ if plot.new_plot:
562
+ existing_plots = False
563
+ # Some plots with keys that are not in the keychain
564
+ for i in range(num_non_keychain_plots):
565
+ plot = await self.new_plot(
566
+ path=self.plot_dir / "not_in_keychain",
567
+ plot_keys=PlotKeys(G1Element(), G1Element(), None),
568
+ exclude_plots=True,
569
+ plot_size=plot_size,
570
+ bitfield=bitfield,
571
+ )
572
+ if plot.new_plot:
573
+ existing_plots = False
574
+ await self.refresh_plots()
575
+ assert len(self.plot_manager.plots) == len(self.expected_plots)
576
+ return existing_plots
533
577
 
534
578
  async def new_plot(
535
579
  self,
536
- pool_contract_puzzle_hash: Optional[bytes32] = None,
537
- path: Optional[Path] = None,
538
- tmp_dir: Optional[Path] = None,
539
- plot_keys: Optional[PlotKeys] = None,
580
+ pool_contract_puzzle_hash: bytes32 | None = None,
581
+ path: Path | None = None,
582
+ tmp_dir: Path | None = None,
583
+ plot_keys: PlotKeys | None = None,
540
584
  exclude_plots: bool = False,
541
585
  plot_size: int = 20,
542
586
  bitfield: bool = True,
@@ -565,8 +609,8 @@ class BlockTools:
565
609
  )
566
610
  try:
567
611
  if plot_keys is None:
568
- pool_pk: Optional[G1Element] = None
569
- pool_address: Optional[str] = None
612
+ pool_pk: G1Element | None = None
613
+ pool_address: str | None = None
570
614
  if pool_contract_puzzle_hash is None:
571
615
  pool_pk = self.pool_pk
572
616
  else:
@@ -582,8 +626,8 @@ class BlockTools:
582
626
  )
583
627
  self.created_plots += 1
584
628
 
585
- plot_id_new: Optional[bytes32] = None
586
- path_new: Optional[Path] = None
629
+ plot_id_new: bytes32 | None = None
630
+ path_new: Path | None = None
587
631
  new_plot: bool = True
588
632
 
589
633
  if len(created):
@@ -645,7 +689,7 @@ class BlockTools:
645
689
  """
646
690
  Returns the plot signature of the header data.
647
691
  """
648
- farmer_sk = master_sk_to_farmer_sk(self.all_sks[0])
692
+ farmer_sk = cached_master_sk_to_farmer_sk(self.all_sks[0])
649
693
  for plot_info in self.plot_manager.plots.values():
650
694
  if plot_pk == plot_info.plot_public_key:
651
695
  # Look up local_sk from plot to save locked memory
@@ -659,7 +703,7 @@ class BlockTools:
659
703
  else:
660
704
  assert isinstance(pool_pk_or_ph, bytes32)
661
705
  include_taproot = True
662
- local_sk = master_sk_to_local_sk(local_master_sk)
706
+ local_sk = cached_master_sk_to_local_sk(local_master_sk)
663
707
  agg_pk = generate_plot_public_key(local_sk.get_g1(), farmer_sk.get_g1(), include_taproot)
664
708
  assert agg_pk == plot_pk
665
709
  harv_share = AugSchemeMPL.sign(local_sk, m, agg_pk)
@@ -673,7 +717,7 @@ class BlockTools:
673
717
 
674
718
  raise ValueError(f"Do not have key {plot_pk}")
675
719
 
676
- def get_pool_key_signature(self, pool_target: PoolTarget, pool_pk: Optional[G1Element]) -> Optional[G2Element]:
720
+ def get_pool_key_signature(self, pool_target: PoolTarget, pool_pk: G1Element | None) -> G2Element | None:
677
721
  # Returns the pool signature for the corresponding pk. If no pk is provided, returns None.
678
722
  if pool_pk is None:
679
723
  return None
@@ -693,13 +737,13 @@ class BlockTools:
693
737
  def get_consecutive_blocks(
694
738
  self,
695
739
  num_blocks: int,
696
- block_list_input: Optional[list[FullBlock]] = None,
740
+ block_list_input: list[FullBlock] | None = None,
697
741
  *,
698
- farmer_reward_puzzle_hash: Optional[bytes32] = None,
699
- pool_reward_puzzle_hash: Optional[bytes32] = None,
700
- transaction_data: Optional[SpendBundle] = None,
742
+ farmer_reward_puzzle_hash: bytes32 | None = None,
743
+ pool_reward_puzzle_hash: bytes32 | None = None,
744
+ transaction_data: SpendBundle | None = None,
701
745
  seed: bytes = b"",
702
- time_per_block: Optional[float] = None,
746
+ time_per_block: float | None = None,
703
747
  force_overflow: bool = False,
704
748
  skip_slots: int = 0, # Force at least this number of empty slots before the first SB
705
749
  guarantee_transaction_block: bool = False, # Force that this block must be a tx block
@@ -710,8 +754,8 @@ class BlockTools:
710
754
  normalized_to_identity_cc_ip: bool = False,
711
755
  current_time: bool = False,
712
756
  block_refs: list[uint32] = [],
713
- genesis_timestamp: Optional[uint64] = None,
714
- force_plot_id: Optional[bytes32] = None,
757
+ genesis_timestamp: uint64 | None = None,
758
+ force_plot_id: bytes32 | None = None,
715
759
  dummy_block_references: bool = False,
716
760
  include_transactions: bool = False,
717
761
  skip_overflow: bool = False,
@@ -725,13 +769,17 @@ class BlockTools:
725
769
  else:
726
770
  block_list = []
727
771
 
728
- tx_block_heights: list[uint32] = []
772
+ # these are heights of blocks that have transactions generators. Note
773
+ # that there may be transactions blocks without generators. These are
774
+ # used to generate dummy block references. Block references require
775
+ # generators, not just transaction blocks.
776
+ generator_block_heights: list[uint32] = []
729
777
  if dummy_block_references:
730
778
  # block references can only point to transaction blocks, so we need
731
779
  # to record which ones are
732
780
  for b in block_list:
733
781
  if b.transactions_generator is not None:
734
- tx_block_heights.append(b.height)
782
+ generator_block_heights.append(b.height)
735
783
 
736
784
  constants = self.constants
737
785
 
@@ -743,8 +791,8 @@ class BlockTools:
743
791
  # after the one they were created by, so we "stage" them here to move
744
792
  # them into available_coins at the next transaction block
745
793
  pending_rewards: list[Coin] = []
746
- wallet: Optional[WalletTool] = None
747
- rng: Optional[Random] = None
794
+ wallet: WalletTool | None = None
795
+ rng: Random | None = None
748
796
  if include_transactions:
749
797
  # when we generate transactions in the chain, the caller cannot also
750
798
  # have ownership of the rewards and control the transactions
@@ -789,6 +837,12 @@ class BlockTools:
789
837
  if num_blocks == 0:
790
838
  return block_list
791
839
 
840
+ if block_list[-1].height >= constants.HARD_FORK2_HEIGHT and pool_reward_puzzle_hash is not None:
841
+ raise ValueError(
842
+ "block height is past hard fork 2 activation. v2 plots don't "
843
+ "support pool puzzle hashes, only contract hashes"
844
+ )
845
+
792
846
  blocks: dict[bytes32, BlockRecord]
793
847
  if block_list[-1].header_hash == self._block_cache_header:
794
848
  height_to_hash = self._block_cache_height_to_hash
@@ -803,7 +857,7 @@ class BlockTools:
803
857
  curr = blocks[curr.prev_hash]
804
858
  assert curr.timestamp is not None
805
859
  last_timestamp = float(curr.timestamp)
806
- prev_tx_height = curr.height
860
+ prev_tx_height = uint32(0)
807
861
 
808
862
  curr = latest_block
809
863
  blocks_added_this_sub_slot = 1
@@ -821,6 +875,26 @@ class BlockTools:
821
875
  # this variable is true whenever there is a pending sub-epoch or epoch that needs to be added in the next block.
822
876
  pending_ses: bool = False
823
877
 
878
+ block_generator: NewBlockGenerator | None = None
879
+ if transaction_data is not None:
880
+ additions = compute_additions_unchecked(transaction_data)
881
+ removals = transaction_data.removals()
882
+ if curr.height >= self.constants.HARD_FORK_HEIGHT:
883
+ program = simple_solution_generator_backrefs(transaction_data).program
884
+ else:
885
+ program = simple_solution_generator(transaction_data).program
886
+ block_refs = []
887
+ cost = compute_block_cost(program, self.constants, uint32(curr.height + 1), prev_tx_height)
888
+ block_generator = NewBlockGenerator(
889
+ program,
890
+ [],
891
+ block_refs,
892
+ transaction_data.aggregated_signature,
893
+ additions,
894
+ removals,
895
+ cost,
896
+ )
897
+
824
898
  # Start at the last block in block list
825
899
  # Get the challenge for that slot
826
900
  while True:
@@ -872,6 +946,14 @@ class BlockTools:
872
946
  assert signage_point.cc_vdf is not None
873
947
  cc_sp_output_hash = signage_point.cc_vdf.output.get_hash()
874
948
 
949
+ prev_tx_height = pre_sp_tx_block_height(
950
+ constants=constants,
951
+ blocks=BlockCache(blocks),
952
+ prev_b_hash=latest_block.header_hash,
953
+ sp_index=uint8(signage_point_index),
954
+ first_in_sub_slot=len(finished_sub_slots_at_ip) > 0,
955
+ )
956
+
875
957
  qualified_proofs: list[tuple[uint64, ProofOfSpace]] = self.get_pospaces_for_challenge(
876
958
  constants,
877
959
  slot_cc_challenge,
@@ -880,7 +962,7 @@ class BlockTools:
880
962
  difficulty,
881
963
  sub_slot_iters,
882
964
  curr.height,
883
- tx_block_heights[-1] if len(tx_block_heights) > 0 else uint32(0),
965
+ prev_tx_height,
884
966
  force_plot_id=force_plot_id,
885
967
  )
886
968
 
@@ -908,14 +990,14 @@ class BlockTools:
908
990
  pool_target = PoolTarget(self.pool_ph, uint32(0))
909
991
 
910
992
  new_gen = self.setup_new_gen(
911
- tx_block_heights,
993
+ generator_block_heights,
912
994
  curr,
913
995
  wallet,
914
996
  rng,
915
997
  available_coins,
916
998
  prev_tx_height=prev_tx_height,
917
999
  dummy_block_references=dummy_block_references,
918
- transaction_data=transaction_data,
1000
+ block_generator=block_generator,
919
1001
  include_transactions=include_transactions,
920
1002
  block_refs=block_refs,
921
1003
  )
@@ -953,18 +1035,24 @@ class BlockTools:
953
1035
  overflow_rc_challenge=None,
954
1036
  )
955
1037
  if block_record.is_transaction_block:
956
- transaction_data = None
1038
+ block_generator = None
957
1039
  block_refs = []
958
1040
  keep_going_until_tx_block = False
959
1041
  assert full_block.foliage_transaction_block is not None
960
1042
  elif guarantee_transaction_block:
961
1043
  continue
962
- # print(f"{full_block.height:4}: difficulty {difficulty} "
963
- # f"time: {new_timestamp - last_timestamp:0.2f} "
964
- # f"additions: {len(new_gen.additions) if block_record.is_transaction_block else 0:2} "
965
- # f"removals: {len(new_gen.removals) if block_record.is_transaction_block else 0:2} "
966
- # f"refs: {len(full_block.transactions_generator_ref_list):3} "
967
- # f"tx: {block_record.is_transaction_block}")
1044
+ self.log.info(
1045
+ f"Created Block {full_block.height:4} "
1046
+ f"prev-tx: {prev_tx_height:4} "
1047
+ f"diff: {difficulty} "
1048
+ f"time: {new_timestamp - last_timestamp:0.2f} "
1049
+ f"additions: {len(new_gen.additions) if new_gen else 0:2} "
1050
+ f"removals: {len(new_gen.removals) if new_gen else 0:2} "
1051
+ f"refs: {len(full_block.transactions_generator_ref_list):3} "
1052
+ f"iters: {block_record.total_iters} "
1053
+ f"[{'TransactionBlock ' if block_record.is_transaction_block else ''}"
1054
+ f"{'V1' if proof_of_space.param().size_v1 else 'V2'}]"
1055
+ )
968
1056
  last_timestamp = new_timestamp
969
1057
  block_list.append(full_block)
970
1058
 
@@ -981,12 +1069,10 @@ class BlockTools:
981
1069
  available_coins.extend(new_gen.additions)
982
1070
 
983
1071
  if full_block.transactions_generator is not None:
984
- tx_block_heights.append(full_block.height)
985
- prev_tx_height = full_block.height
1072
+ generator_block_heights.append(full_block.height)
986
1073
 
987
1074
  blocks_added_this_sub_slot += 1
988
1075
  blocks[full_block.header_hash] = block_record
989
- self.log.info(f"Created block {block_record.height} ov=False, iters {block_record.total_iters}")
990
1076
  num_blocks -= 1
991
1077
 
992
1078
  height_to_hash[uint32(full_block.height)] = full_block.header_hash
@@ -1050,7 +1136,7 @@ class BlockTools:
1050
1136
  )
1051
1137
  # generate sub_epoch_summary, and if the last block was the last block of the sub-epoch or epoch
1052
1138
  # include the hash in the next sub-slot
1053
- sub_epoch_summary: Optional[SubEpochSummary] = None
1139
+ sub_epoch_summary: SubEpochSummary | None = None
1054
1140
  if not pending_ses: # if we just created a sub-epoch summary, we can at least skip another sub-slot
1055
1141
  sub_epoch_summary = next_sub_epoch_summary(
1056
1142
  constants,
@@ -1061,10 +1147,10 @@ class BlockTools:
1061
1147
  )
1062
1148
  if sub_epoch_summary is not None: # the previous block is the last block of the sub-epoch or epoch
1063
1149
  pending_ses = True
1064
- ses_hash: Optional[bytes32] = sub_epoch_summary.get_hash()
1150
+ ses_hash: bytes32 | None = sub_epoch_summary.get_hash()
1065
1151
  # if the last block is the last block of the epoch, we set the new sub-slot iters and difficulty
1066
- new_sub_slot_iters: Optional[uint64] = sub_epoch_summary.new_sub_slot_iters
1067
- new_difficulty: Optional[uint64] = sub_epoch_summary.new_difficulty
1152
+ new_sub_slot_iters: uint64 | None = sub_epoch_summary.new_sub_slot_iters
1153
+ new_difficulty: uint64 | None = sub_epoch_summary.new_difficulty
1068
1154
 
1069
1155
  self.log.info(f"Sub epoch summary: {sub_epoch_summary} for block {latest_block.height + 1}")
1070
1156
  else: # the previous block is not the last block of the sub-epoch or epoch
@@ -1100,7 +1186,7 @@ class BlockTools:
1100
1186
  icc_eos_iters,
1101
1187
  True,
1102
1188
  )
1103
- icc_sub_slot: Optional[InfusedChallengeChainSubSlot] = InfusedChallengeChainSubSlot(icc_eos_vdf)
1189
+ icc_sub_slot: InfusedChallengeChainSubSlot | None = InfusedChallengeChainSubSlot(icc_eos_vdf)
1104
1190
  assert icc_sub_slot is not None
1105
1191
  icc_sub_slot_hash = icc_sub_slot.get_hash() if latest_block.deficit == 0 else None
1106
1192
  cc_sub_slot = ChallengeChainSubSlot(
@@ -1136,7 +1222,7 @@ class BlockTools:
1136
1222
  sub_slots_finished += 1
1137
1223
  self.log.info(
1138
1224
  f"Sub slot finished. blocks included: {blocks_added_this_sub_slot} blocks_per_slot: "
1139
- f"{(len(block_list) - initial_block_list_len) / sub_slots_finished}"
1225
+ f"{(len(block_list) - initial_block_list_len) / sub_slots_finished} "
1140
1226
  f"Sub Epoch Summary Included: {sub_epoch_summary is not None} "
1141
1227
  )
1142
1228
  blocks_added_this_sub_slot = 0 # Sub slot ended, overflows are in next sub slot
@@ -1175,6 +1261,14 @@ class BlockTools:
1175
1261
  cc_sp_output_hash = signage_point.cc_vdf.output.get_hash()
1176
1262
 
1177
1263
  # If did not reach the target slots to skip, don't make any proofs for this sub-slot
1264
+ prev_tx_height = pre_sp_tx_block_height(
1265
+ constants=constants,
1266
+ blocks=BlockCache(blocks),
1267
+ prev_b_hash=latest_block.header_hash,
1268
+ sp_index=uint8(signage_point_index),
1269
+ first_in_sub_slot=len(finished_sub_slots_at_ip) > 0,
1270
+ )
1271
+
1178
1272
  qualified_proofs = self.get_pospaces_for_challenge(
1179
1273
  constants,
1180
1274
  slot_cc_challenge,
@@ -1183,7 +1277,7 @@ class BlockTools:
1183
1277
  difficulty,
1184
1278
  sub_slot_iters,
1185
1279
  curr.height,
1186
- tx_block_heights[-1] if len(tx_block_heights) > 0 else uint32(0),
1280
+ prev_tx_height,
1187
1281
  force_plot_id=force_plot_id,
1188
1282
  )
1189
1283
  for required_iters, proof_of_space in sorted(qualified_proofs, key=lambda t: t[0]):
@@ -1202,14 +1296,14 @@ class BlockTools:
1202
1296
  pool_target = PoolTarget(self.pool_ph, uint32(0))
1203
1297
 
1204
1298
  new_gen = self.setup_new_gen(
1205
- tx_block_heights,
1299
+ generator_block_heights,
1206
1300
  curr,
1207
1301
  wallet,
1208
1302
  rng,
1209
1303
  available_coins,
1210
1304
  prev_tx_height=prev_tx_height,
1211
1305
  dummy_block_references=dummy_block_references,
1212
- transaction_data=transaction_data,
1306
+ block_generator=block_generator,
1213
1307
  include_transactions=include_transactions,
1214
1308
  block_refs=block_refs,
1215
1309
  )
@@ -1247,18 +1341,25 @@ class BlockTools:
1247
1341
  overflow_rc_challenge=overflow_rc_challenge,
1248
1342
  )
1249
1343
  if block_record.is_transaction_block:
1250
- transaction_data = None
1344
+ block_generator = None
1251
1345
  block_refs = []
1252
1346
  keep_going_until_tx_block = False
1253
1347
  assert full_block.foliage_transaction_block is not None
1254
1348
  elif guarantee_transaction_block:
1255
1349
  continue
1256
- # print(f"{full_block.height:4}: difficulty {difficulty} "
1257
- # f"time: {new_timestamp - last_timestamp:0.2f} "
1258
- # f"additions: {len(new_gen.additions) if block_record.is_transaction_block else 0:2} "
1259
- # f"removals: {len(new_gen.removals) if block_record.is_transaction_block else 0:2} "
1260
- # f"refs: {len(full_block.transactions_generator_ref_list):3} "
1261
- # f"tx: {block_record.is_transaction_block}")
1350
+ self.log.info(
1351
+ f"Created Block {full_block.height:4} "
1352
+ f"prev-tx: {prev_tx_height:4} "
1353
+ f"diff: {difficulty} "
1354
+ f"time: {new_timestamp - last_timestamp:0.2f} "
1355
+ f"additions: {len(new_gen.additions) if new_gen else 0:2} "
1356
+ f"removals: {len(new_gen.removals) if new_gen else 0:2} "
1357
+ f"refs: {len(full_block.transactions_generator_ref_list):3} "
1358
+ f"iters: {block_record.total_iters} "
1359
+ f"[{'TransactionBlock ' if block_record.is_transaction_block else ''}"
1360
+ f"{'V1 ' if proof_of_space.param().size_v1 else 'V2 '}"
1361
+ "Overflow]"
1362
+ )
1262
1363
  last_timestamp = new_timestamp
1263
1364
  block_list.append(full_block)
1264
1365
 
@@ -1275,12 +1376,10 @@ class BlockTools:
1275
1376
  available_coins.extend(new_gen.additions)
1276
1377
 
1277
1378
  if full_block.transactions_generator is not None:
1278
- tx_block_heights.append(full_block.height)
1279
- prev_tx_height = full_block.height
1379
+ generator_block_heights.append(full_block.height)
1280
1380
 
1281
1381
  blocks_added_this_sub_slot += 1
1282
1382
  blocks[full_block.header_hash] = block_record
1283
- self.log.info(f"Created block {block_record.height} ov=True, iters {block_record.total_iters}")
1284
1383
  num_blocks -= 1
1285
1384
 
1286
1385
  height_to_hash[uint32(full_block.height)] = full_block.header_hash
@@ -1308,7 +1407,7 @@ class BlockTools:
1308
1407
  self,
1309
1408
  constants: ConsensusConstants,
1310
1409
  seed: bytes = b"",
1311
- timestamp: Optional[uint64] = None,
1410
+ timestamp: uint64 | None = None,
1312
1411
  force_overflow: bool = False,
1313
1412
  skip_slots: int = 0,
1314
1413
  ) -> FullBlock:
@@ -1316,7 +1415,7 @@ class BlockTools:
1316
1415
  timestamp = uint64(time.time())
1317
1416
 
1318
1417
  finished_sub_slots: list[EndOfSubSlotBundle] = []
1319
- unfinished_block: Optional[UnfinishedBlock] = None
1418
+ unfinished_block: UnfinishedBlock | None = None
1320
1419
  ip_iters: uint64 = uint64(0)
1321
1420
  sub_slot_total_iters: uint128 = uint128(0)
1322
1421
 
@@ -1498,63 +1597,71 @@ class BlockTools:
1498
1597
  difficulty: uint64,
1499
1598
  sub_slot_iters: uint64,
1500
1599
  height: uint32,
1501
- prev_transaction_b_height: uint32,
1502
- force_plot_id: Optional[bytes32] = None,
1600
+ prev_tx_height: uint32,
1601
+ force_plot_id: bytes32 | None = None,
1503
1602
  ) -> list[tuple[uint64, ProofOfSpace]]:
1504
1603
  found_proofs: list[tuple[uint64, ProofOfSpace]] = []
1505
1604
  rng = random.Random()
1506
1605
  rng.seed(seed)
1507
1606
 
1508
- required_plot_strength = calculate_required_plot_strength(constants, prev_transaction_b_height)
1607
+ sp_interval_iters = calculate_sp_interval_iters(constants, sub_slot_iters)
1608
+ phase_out_epochs = num_phase_out_epochs(constants)
1509
1609
 
1510
1610
  for plot_info in self.plot_manager.plots.values():
1511
1611
  plot_id: bytes32 = plot_info.prover.get_id()
1512
1612
  if force_plot_id is not None and plot_id != force_plot_id:
1513
1613
  continue
1514
- prefix_bits = calculate_prefix_bits(constants, height, plot_info.prover.get_size())
1614
+ prefix_bits = calculate_prefix_bits(constants, height, plot_info.prover.get_param())
1515
1615
  if not passes_plot_filter(prefix_bits, plot_id, challenge_hash, signage_point):
1516
1616
  continue
1517
1617
 
1518
- # v2 plots aren't valid until after the hard fork
1519
- if (
1520
- prev_transaction_b_height < constants.HARD_FORK2_HEIGHT
1521
- and plot_info.prover.get_version() == PlotVersion.V2
1522
- ):
1618
+ if plot_info.prover.get_version() == PlotVersion.V2:
1619
+ # v2 plots aren't valid until after the hard fork
1620
+ if prev_tx_height < constants.HARD_FORK2_HEIGHT:
1621
+ continue
1622
+
1623
+ if plot_info.prover.get_strength() < constants.MIN_PLOT_STRENGTH:
1624
+ self.log.warn(
1625
+ f"Plot strength ({plot_info.prover.get_strength()}) too low, "
1626
+ f"cannot be used for farming: {plot_info.prover.get_filename()}"
1627
+ )
1628
+ continue
1629
+ if plot_info.prover.get_strength() > constants.MAX_PLOT_STRENGTH:
1630
+ self.log.warn(
1631
+ f"Plot strength ({plot_info.prover.get_strength()}) too high, "
1632
+ f"cannot be used for farming: {plot_info.prover.get_filename()}"
1633
+ )
1634
+ continue
1635
+ elif prev_tx_height >= constants.HARD_FORK2_HEIGHT + phase_out_epochs * constants.EPOCH_BLOCKS:
1523
1636
  continue
1524
1637
 
1525
1638
  new_challenge: bytes32 = calculate_pos_challenge(plot_id, challenge_hash, signage_point)
1526
1639
 
1527
- # these are either qualities (v1) or partial proofs (v2)
1528
- proofs: Sequence[Union[bytes32, bytes]]
1529
- v = plot_info.prover.get_version()
1530
- if v == PlotVersion.V1:
1531
- proofs = plot_info.prover.get_qualities_for_challenge(new_challenge)
1532
- else:
1533
- proofs = plot_info.prover.get_partial_proofs_for_challenge(new_challenge, required_plot_strength)
1534
-
1535
- for proof_index, proof in enumerate(proofs):
1536
- if v == PlotVersion.V2:
1537
- quality_str = quality_for_partial_proof(proof, new_challenge)
1538
- elif v == PlotVersion.V1:
1539
- quality_str = bytes32(proof)
1640
+ qualities: Sequence[QualityProtocol] = plot_info.prover.get_qualities_for_challenge(
1641
+ new_challenge, constants.QUALITY_PROOF_SCAN_FILTER
1642
+ )
1540
1643
 
1644
+ for idx, quality in enumerate(qualities):
1541
1645
  required_iters = calculate_iterations_quality(
1542
1646
  constants,
1543
- quality_str,
1544
- plot_info.prover.get_size(),
1647
+ quality.get_string(),
1648
+ plot_info.prover.get_param(),
1545
1649
  difficulty,
1546
1650
  signage_point,
1547
- sub_slot_iters,
1548
- prev_transaction_b_height,
1549
1651
  )
1550
- if required_iters >= calculate_sp_interval_iters(constants, sub_slot_iters):
1652
+ if required_iters >= sp_interval_iters:
1551
1653
  continue
1552
1654
 
1553
- proof_xs: bytes
1554
- if v == PlotVersion.V1:
1555
- proof_xs = plot_info.prover.get_full_proof(new_challenge, proof_index)
1556
- else:
1557
- proof_xs = solve_proof(proof)
1655
+ proof = b""
1656
+ if isinstance(plot_info.prover, V1Prover):
1657
+ proof = plot_info.prover.get_full_proof(new_challenge, idx)
1658
+ if is_v1_phased_out(proof, prev_tx_height, constants):
1659
+ continue
1660
+ elif isinstance(plot_info.prover, V2Prover):
1661
+ assert isinstance(quality, V2Quality)
1662
+ partial_proof = plot_info.prover.get_partial_proof(quality)
1663
+ strength = plot_info.prover.get_strength()
1664
+ proof = solve_proof(partial_proof, plot_id, strength, constants.PLOT_SIZE_V2)
1558
1665
 
1559
1666
  # Look up local_sk from plot to save locked memory
1560
1667
  (
@@ -1562,7 +1669,7 @@ class BlockTools:
1562
1669
  farmer_public_key,
1563
1670
  local_master_sk,
1564
1671
  ) = parse_plot_info(plot_info.prover.get_memo())
1565
- local_sk = master_sk_to_local_sk(local_master_sk)
1672
+ local_sk = cached_master_sk_to_local_sk(local_master_sk)
1566
1673
 
1567
1674
  if isinstance(pool_public_key_or_puzzle_hash, G1Element):
1568
1675
  include_taproot = False
@@ -1575,8 +1682,8 @@ class BlockTools:
1575
1682
  plot_info.pool_public_key,
1576
1683
  plot_info.pool_contract_puzzle_hash,
1577
1684
  plot_pk,
1578
- plot_info.prover.get_size(),
1579
- proof_xs,
1685
+ plot_info.prover.get_param(),
1686
+ proof,
1580
1687
  )
1581
1688
  found_proofs.append((required_iters, proof_of_space))
1582
1689
  random_sample = found_proofs
@@ -1590,7 +1697,7 @@ class BlockTools:
1590
1697
  def get_signage_point(
1591
1698
  constants: ConsensusConstants,
1592
1699
  blocks: BlockRecordsProtocol,
1593
- latest_block: Optional[BlockRecord],
1700
+ latest_block: BlockRecord | None,
1594
1701
  sub_slot_start_total_iters: uint128,
1595
1702
  signage_point_index: uint8,
1596
1703
  finished_sub_slots: list[EndOfSubSlotBundle],
@@ -1741,7 +1848,7 @@ def get_challenges(
1741
1848
  constants: ConsensusConstants,
1742
1849
  blocks: dict[bytes32, BlockRecord],
1743
1850
  finished_sub_slots: list[EndOfSubSlotBundle],
1744
- prev_header_hash: Optional[bytes32],
1851
+ prev_header_hash: bytes32 | None,
1745
1852
  ) -> tuple[bytes32, bytes32]:
1746
1853
  if len(finished_sub_slots) == 0:
1747
1854
  if prev_header_hash is None:
@@ -1789,7 +1896,6 @@ def load_block_list(
1789
1896
  sub_slot_iters = uint64(constants.SUB_SLOT_ITERS_STARTING)
1790
1897
  height_to_hash: dict[uint32, bytes32] = {}
1791
1898
  blocks: dict[bytes32, BlockRecord] = {}
1792
- prev_transaction_b_height = uint32(0)
1793
1899
  for full_block in block_list:
1794
1900
  if full_block.height != 0:
1795
1901
  if len(full_block.finished_sub_slots) > 0:
@@ -1806,7 +1912,13 @@ def load_block_list(
1806
1912
  sp_hash = full_block.reward_chain_block.challenge_chain_sp_vdf.output.get_hash()
1807
1913
 
1808
1914
  cache = BlockCache(blocks)
1809
-
1915
+ prev_transaction_b_height = pre_sp_tx_block_height(
1916
+ constants=constants,
1917
+ blocks=cache,
1918
+ prev_b_hash=full_block.prev_header_hash,
1919
+ sp_index=full_block.reward_chain_block.signage_point_index,
1920
+ first_in_sub_slot=len(full_block.finished_sub_slots) > 0,
1921
+ )
1810
1922
  required_iters = validate_pospace_and_get_required_iters(
1811
1923
  constants,
1812
1924
  full_block.reward_chain_block.proof_of_space,
@@ -1814,14 +1926,10 @@ def load_block_list(
1814
1926
  sp_hash,
1815
1927
  full_block.height,
1816
1928
  uint64(difficulty),
1817
- sub_slot_iters,
1818
1929
  prev_transaction_b_height,
1819
1930
  )
1820
1931
  assert required_iters is not None
1821
1932
 
1822
- if full_block.is_transaction_block():
1823
- prev_transaction_b_height = full_block.height
1824
-
1825
1933
  blocks[full_block.header_hash] = block_to_block_record(
1826
1934
  constants,
1827
1935
  cache,
@@ -1841,7 +1949,7 @@ def get_icc(
1841
1949
  blocks: dict[bytes32, BlockRecord],
1842
1950
  sub_slot_start_total_iters: uint128,
1843
1951
  deficit: uint8,
1844
- ) -> tuple[Optional[VDFInfo], Optional[VDFProof]]:
1952
+ ) -> tuple[VDFInfo | None, VDFProof | None]:
1845
1953
  if len(finished_sub_slots) == 0:
1846
1954
  prev_deficit = latest_block.deficit
1847
1955
  else:
@@ -1871,7 +1979,7 @@ def get_icc(
1871
1979
  curr = blocks[curr.prev_hash]
1872
1980
  icc_iters = uint64(vdf_end_total_iters - latest_block.total_iters)
1873
1981
  if latest_block.is_challenge_block(constants):
1874
- icc_input: Optional[ClassgroupElement] = ClassgroupElement.get_default_element()
1982
+ icc_input: ClassgroupElement | None = ClassgroupElement.get_default_element()
1875
1983
  else:
1876
1984
  icc_input = latest_block.infused_challenge_vdf_output
1877
1985
  assert icc_input is not None
@@ -1902,20 +2010,20 @@ def get_full_block_and_block_record(
1902
2010
  pool_target: PoolTarget,
1903
2011
  last_timestamp: float,
1904
2012
  time_per_block: float,
1905
- new_gen: Optional[NewBlockGenerator],
2013
+ new_gen: NewBlockGenerator | None,
1906
2014
  height_to_hash: dict[uint32, bytes32],
1907
2015
  difficulty: uint64,
1908
2016
  required_iters: uint64,
1909
2017
  sub_slot_iters: uint64,
1910
2018
  get_plot_signature: Callable[[bytes32, G1Element], G2Element],
1911
- get_pool_signature: Callable[[PoolTarget, Optional[G1Element]], Optional[G2Element]],
2019
+ get_pool_signature: Callable[[PoolTarget, G1Element | None], G2Element | None],
1912
2020
  finished_sub_slots: list[EndOfSubSlotBundle],
1913
2021
  signage_point: SignagePoint,
1914
2022
  prev_block: BlockRecord,
1915
2023
  seed: bytes = b"",
1916
2024
  *,
1917
- overflow_cc_challenge: Optional[bytes32] = None,
1918
- overflow_rc_challenge: Optional[bytes32] = None,
2025
+ overflow_cc_challenge: bytes32 | None = None,
2026
+ overflow_rc_challenge: bytes32 | None = None,
1919
2027
  normalized_to_identity_cc_ip: bool = False,
1920
2028
  current_time: bool = False,
1921
2029
  ) -> tuple[FullBlock, BlockRecord, float]:
@@ -2075,43 +2183,47 @@ create_block_tools_count = 0
2075
2183
  # listen port it uses is to write it to the config file.
2076
2184
 
2077
2185
 
2186
+ @asynccontextmanager
2078
2187
  async def create_block_tools_async(
2079
2188
  constants: ConsensusConstants = test_constants,
2080
- root_path: Optional[Path] = None,
2081
- keychain: Optional[Keychain] = None,
2082
- config_overrides: Optional[dict[str, Any]] = None,
2189
+ root_path: Path | None = None,
2190
+ keychain: Keychain | None = None,
2191
+ config_overrides: dict[str, Any] | None = None,
2083
2192
  num_og_plots: int = 15,
2084
2193
  num_pool_plots: int = 5,
2085
2194
  num_non_keychain_plots: int = 3,
2086
- ) -> BlockTools:
2195
+ testrun_uid: str | None = None,
2196
+ ) -> AsyncIterator[BlockTools]:
2087
2197
  global create_block_tools_async_count
2088
2198
  create_block_tools_async_count += 1
2089
2199
  print(f" create_block_tools_async called {create_block_tools_async_count} times")
2090
- bt = BlockTools(constants, root_path, keychain, config_overrides=config_overrides)
2091
- await bt.setup_keys()
2092
- await bt.setup_plots(
2093
- num_og_plots=num_og_plots,
2094
- num_pool_plots=num_pool_plots,
2095
- num_non_keychain_plots=num_non_keychain_plots,
2096
- )
2097
2200
 
2098
- return bt
2201
+ with BlockTools(constants, root_path, keychain, config_overrides=config_overrides) as bt:
2202
+ await bt.setup_keys()
2203
+ await bt.setup_plots(
2204
+ num_og_plots=num_og_plots,
2205
+ num_pool_plots=num_pool_plots,
2206
+ num_non_keychain_plots=num_non_keychain_plots,
2207
+ testrun_uid=testrun_uid,
2208
+ )
2099
2209
 
2210
+ yield bt
2100
2211
 
2212
+
2213
+ @contextmanager
2101
2214
  def create_block_tools(
2102
2215
  constants: ConsensusConstants = test_constants,
2103
- root_path: Optional[Path] = None,
2104
- keychain: Optional[Keychain] = None,
2105
- config_overrides: Optional[dict[str, Any]] = None,
2106
- ) -> BlockTools:
2216
+ root_path: Path | None = None,
2217
+ keychain: Keychain | None = None,
2218
+ config_overrides: dict[str, Any] | None = None,
2219
+ ) -> Iterator[BlockTools]:
2107
2220
  global create_block_tools_count
2108
2221
  create_block_tools_count += 1
2109
2222
  print(f" create_block_tools called {create_block_tools_count} times")
2110
- bt = BlockTools(constants, root_path, keychain, config_overrides=config_overrides)
2111
-
2112
- asyncio.get_event_loop().run_until_complete(bt.setup_keys())
2113
- asyncio.get_event_loop().run_until_complete(bt.setup_plots())
2114
- return bt
2223
+ with BlockTools(constants, root_path, keychain, config_overrides=config_overrides) as bt:
2224
+ asyncio.get_event_loop().run_until_complete(bt.setup_keys())
2225
+ asyncio.get_event_loop().run_until_complete(bt.setup_plots())
2226
+ yield bt
2115
2227
 
2116
2228
 
2117
2229
  def make_unfinished_block(