chia-blockchain 2.5.0rc2__py3-none-any.whl → 2.5.1rc2__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 (637) hide show
  1. chia/_tests/README.md +1 -1
  2. chia/_tests/blockchain/blockchain_test_utils.py +24 -26
  3. chia/_tests/blockchain/test_augmented_chain.py +6 -8
  4. chia/_tests/blockchain/test_blockchain.py +409 -307
  5. chia/_tests/blockchain/test_blockchain_transactions.py +56 -75
  6. chia/_tests/blockchain/test_build_chains.py +11 -13
  7. chia/_tests/blockchain/test_get_block_generator.py +8 -8
  8. chia/_tests/blockchain/test_lookup_fork_chain.py +3 -4
  9. chia/_tests/build-init-files.py +3 -4
  10. chia/_tests/build-job-matrix.py +9 -9
  11. chia/_tests/check_sql_statements.py +2 -3
  12. chia/_tests/clvm/benchmark_costs.py +1 -1
  13. chia/_tests/clvm/coin_store.py +7 -5
  14. chia/_tests/clvm/test_chialisp_deserialization.py +8 -8
  15. chia/_tests/clvm/test_condition_codes.py +2 -2
  16. chia/_tests/clvm/test_curry_and_treehash.py +2 -4
  17. chia/_tests/clvm/test_message_conditions.py +184 -0
  18. chia/_tests/clvm/test_puzzle_compression.py +1 -2
  19. chia/_tests/clvm/test_puzzle_drivers.py +3 -3
  20. chia/_tests/clvm/test_puzzles.py +13 -18
  21. chia/_tests/clvm/test_singletons.py +17 -17
  22. chia/_tests/clvm/test_spend_sim.py +7 -7
  23. chia/_tests/cmds/cmd_test_utils.py +42 -45
  24. chia/_tests/cmds/conftest.py +2 -2
  25. chia/_tests/cmds/test_click_types.py +21 -16
  26. chia/_tests/cmds/test_cmd_framework.py +255 -35
  27. chia/_tests/cmds/test_cmds_util.py +2 -2
  28. chia/_tests/cmds/test_daemon.py +3 -3
  29. chia/_tests/cmds/test_dev_gh.py +131 -0
  30. chia/_tests/cmds/test_farm_cmd.py +1 -2
  31. chia/_tests/cmds/test_show.py +6 -6
  32. chia/_tests/cmds/test_tx_config_args.py +2 -1
  33. chia/_tests/cmds/wallet/test_dao.py +23 -23
  34. chia/_tests/cmds/wallet/test_did.py +29 -29
  35. chia/_tests/cmds/wallet/test_nft.py +24 -23
  36. chia/_tests/cmds/wallet/test_notifications.py +8 -8
  37. chia/_tests/cmds/wallet/test_tx_decorators.py +3 -3
  38. chia/_tests/cmds/wallet/test_vcs.py +97 -73
  39. chia/_tests/cmds/wallet/test_wallet.py +74 -75
  40. chia/_tests/cmds/wallet/test_wallet_check.py +5 -7
  41. chia/_tests/conftest.py +153 -38
  42. chia/_tests/connection_utils.py +7 -6
  43. chia/_tests/core/cmds/test_beta.py +3 -3
  44. chia/_tests/core/cmds/test_keys.py +6 -6
  45. chia/_tests/core/cmds/test_wallet.py +3 -3
  46. chia/_tests/core/consensus/test_block_creation.py +3 -5
  47. chia/_tests/core/custom_types/test_coin.py +1 -3
  48. chia/_tests/core/custom_types/test_spend_bundle.py +3 -4
  49. chia/_tests/core/daemon/test_daemon.py +58 -58
  50. chia/_tests/core/daemon/test_keychain_proxy.py +2 -1
  51. chia/_tests/core/data_layer/conftest.py +4 -3
  52. chia/_tests/core/data_layer/test_data_cli.py +1 -2
  53. chia/_tests/core/data_layer/test_data_layer.py +5 -5
  54. chia/_tests/core/data_layer/test_data_layer_util.py +8 -9
  55. chia/_tests/core/data_layer/test_data_rpc.py +75 -93
  56. chia/_tests/core/data_layer/test_data_store.py +38 -37
  57. chia/_tests/core/data_layer/test_data_store_schema.py +11 -11
  58. chia/_tests/core/data_layer/util.py +11 -10
  59. chia/_tests/core/farmer/test_farmer_api.py +6 -4
  60. chia/_tests/core/full_node/full_sync/test_full_sync.py +5 -10
  61. chia/_tests/core/full_node/ram_db.py +2 -2
  62. chia/_tests/core/full_node/stores/test_block_store.py +113 -11
  63. chia/_tests/core/full_node/stores/test_coin_store.py +37 -28
  64. chia/_tests/core/full_node/stores/test_full_node_store.py +34 -30
  65. chia/_tests/core/full_node/stores/test_hint_store.py +3 -4
  66. chia/_tests/core/full_node/test_address_manager.py +2 -2
  67. chia/_tests/core/full_node/test_block_height_map.py +1 -1
  68. chia/_tests/core/full_node/test_conditions.py +10 -12
  69. chia/_tests/core/full_node/test_full_node.py +2077 -1822
  70. chia/_tests/core/full_node/test_generator_tools.py +4 -4
  71. chia/_tests/core/full_node/test_hint_management.py +2 -2
  72. chia/_tests/core/full_node/test_performance.py +2 -5
  73. chia/_tests/core/full_node/test_subscriptions.py +4 -4
  74. chia/_tests/core/full_node/test_tx_processing_queue.py +5 -4
  75. chia/_tests/core/make_block_generator.py +5 -7
  76. chia/_tests/core/mempool/test_mempool.py +205 -208
  77. chia/_tests/core/mempool/test_mempool_fee_protocol.py +5 -5
  78. chia/_tests/core/mempool/test_mempool_item_queries.py +2 -4
  79. chia/_tests/core/mempool/test_mempool_manager.py +109 -80
  80. chia/_tests/core/mempool/test_mempool_performance.py +3 -4
  81. chia/_tests/core/mempool/test_singleton_fast_forward.py +12 -12
  82. chia/_tests/core/server/flood.py +6 -4
  83. chia/_tests/core/server/serve.py +10 -7
  84. chia/_tests/core/server/test_api_protocol.py +21 -0
  85. chia/_tests/core/server/test_capabilities.py +3 -5
  86. chia/_tests/core/server/test_dos.py +15 -16
  87. chia/_tests/core/server/test_loop.py +14 -10
  88. chia/_tests/core/server/test_node_discovery.py +1 -2
  89. chia/_tests/core/server/test_rate_limits.py +156 -44
  90. chia/_tests/core/server/test_server.py +8 -7
  91. chia/_tests/core/services/test_services.py +59 -37
  92. chia/_tests/core/ssl/test_ssl.py +5 -3
  93. chia/_tests/core/test_cost_calculation.py +5 -6
  94. chia/_tests/core/test_crawler.py +2 -2
  95. chia/_tests/core/test_db_conversion.py +5 -4
  96. chia/_tests/core/test_db_validation.py +6 -5
  97. chia/_tests/core/test_farmer_harvester_rpc.py +8 -7
  98. chia/_tests/core/test_filter.py +3 -5
  99. chia/_tests/core/test_full_node_rpc.py +64 -90
  100. chia/_tests/core/test_merkle_set.py +10 -10
  101. chia/_tests/core/test_program.py +2 -4
  102. chia/_tests/core/test_rpc_util.py +1 -2
  103. chia/_tests/core/test_seeder.py +124 -12
  104. chia/_tests/core/util/test_block_cache.py +5 -5
  105. chia/_tests/core/util/test_cached_bls.py +3 -3
  106. chia/_tests/core/util/test_config.py +13 -13
  107. chia/_tests/core/util/test_files.py +2 -2
  108. chia/_tests/core/util/test_jsonify.py +9 -9
  109. chia/_tests/core/util/test_keychain.py +13 -5
  110. chia/_tests/core/util/test_keyring_wrapper.py +6 -5
  111. chia/_tests/core/util/test_log_exceptions.py +3 -3
  112. chia/_tests/core/util/test_streamable.py +38 -38
  113. chia/_tests/db/test_db_wrapper.py +13 -12
  114. chia/_tests/environments/common.py +2 -2
  115. chia/_tests/environments/full_node.py +2 -2
  116. chia/_tests/environments/wallet.py +109 -48
  117. chia/_tests/farmer_harvester/test_farmer.py +35 -35
  118. chia/_tests/farmer_harvester/test_farmer_harvester.py +17 -17
  119. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
  120. chia/_tests/farmer_harvester/test_third_party_harvesters.py +73 -46
  121. chia/_tests/fee_estimation/test_fee_estimation_integration.py +8 -8
  122. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +47 -47
  123. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +6 -7
  124. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +11 -11
  125. chia/_tests/generator/test_compression.py +13 -30
  126. chia/_tests/generator/test_generator_types.py +3 -3
  127. chia/_tests/generator/test_rom.py +7 -9
  128. chia/_tests/plot_sync/test_delta.py +2 -3
  129. chia/_tests/plot_sync/test_plot_sync.py +25 -24
  130. chia/_tests/plot_sync/test_receiver.py +9 -9
  131. chia/_tests/plot_sync/test_sender.py +1 -1
  132. chia/_tests/plot_sync/test_sync_simulated.py +27 -26
  133. chia/_tests/plot_sync/util.py +2 -1
  134. chia/_tests/plotting/test_plot_manager.py +54 -11
  135. chia/_tests/plotting/util.py +2 -3
  136. chia/_tests/pools/test_pool_cli_parsing.py +128 -0
  137. chia/_tests/pools/test_pool_cmdline.py +993 -15
  138. chia/_tests/pools/test_pool_config.py +3 -5
  139. chia/_tests/pools/test_pool_puzzles_lifecycle.py +10 -11
  140. chia/_tests/pools/test_pool_rpc.py +203 -90
  141. chia/_tests/pools/test_pool_wallet.py +12 -8
  142. chia/_tests/pools/test_wallet_pool_store.py +3 -3
  143. chia/_tests/process_junit.py +16 -17
  144. chia/_tests/rpc/test_rpc_client.py +59 -2
  145. chia/_tests/rpc/test_rpc_server.py +183 -0
  146. chia/_tests/simulation/test_simulation.py +5 -5
  147. chia/_tests/simulation/test_simulator.py +8 -10
  148. chia/_tests/simulation/test_start_simulator.py +5 -4
  149. chia/_tests/timelord/test_new_peak.py +19 -19
  150. chia/_tests/tools/test_run_block.py +1 -2
  151. chia/_tests/tools/test_virtual_project.py +591 -0
  152. chia/_tests/util/benchmark_cost.py +9 -9
  153. chia/_tests/util/benchmarks.py +1 -2
  154. chia/_tests/util/blockchain.py +12 -11
  155. chia/_tests/util/blockchain_mock.py +15 -15
  156. chia/_tests/util/build_network_protocol_files.py +12 -12
  157. chia/_tests/util/db_connection.py +3 -2
  158. chia/_tests/util/full_sync.py +14 -6
  159. chia/_tests/util/gen_ssl_certs.py +4 -5
  160. chia/_tests/util/generator_tools_testing.py +5 -7
  161. chia/_tests/util/get_name_puzzle_conditions.py +52 -0
  162. chia/_tests/util/key_tool.py +2 -3
  163. chia/_tests/util/misc.py +59 -106
  164. chia/_tests/util/network_protocol_data.py +7 -9
  165. chia/_tests/util/protocol_messages_json.py +112 -111
  166. chia/_tests/util/rpc.py +3 -0
  167. chia/_tests/util/run_block.py +16 -16
  168. chia/_tests/util/setup_nodes.py +25 -23
  169. chia/{clvm → _tests/util}/spend_sim.py +59 -55
  170. chia/_tests/util/split_managers.py +12 -9
  171. chia/_tests/util/temp_file.py +1 -1
  172. chia/_tests/util/test_action_scope.py +2 -1
  173. chia/_tests/util/test_async_pool.py +8 -8
  174. chia/_tests/util/test_build_job_matrix.py +2 -3
  175. chia/_tests/util/test_condition_tools.py +4 -6
  176. chia/_tests/util/test_config.py +5 -5
  177. chia/_tests/util/test_dump_keyring.py +1 -1
  178. chia/_tests/util/test_full_block_utils.py +19 -11
  179. chia/_tests/util/test_limited_semaphore.py +4 -3
  180. chia/_tests/util/test_logging_filter.py +2 -3
  181. chia/_tests/util/test_misc.py +29 -28
  182. chia/_tests/util/test_network.py +32 -31
  183. chia/_tests/util/test_network_protocol_files.py +2 -3
  184. chia/_tests/util/test_network_protocol_json.py +1 -0
  185. chia/_tests/util/test_network_protocol_test.py +18 -19
  186. chia/_tests/util/test_paginator.py +3 -4
  187. chia/_tests/util/test_pprint.py +1 -1
  188. chia/_tests/util/test_priority_mutex.py +18 -17
  189. chia/_tests/util/test_recursive_replace.py +2 -2
  190. chia/_tests/util/test_testnet_overrides.py +3 -3
  191. chia/_tests/util/test_timing.py +1 -1
  192. chia/_tests/util/test_trusted_peer.py +2 -2
  193. chia/_tests/util/time_out_assert.py +43 -6
  194. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +13 -13
  195. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -1
  196. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +117 -29
  197. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +15 -15
  198. chia/_tests/wallet/cat_wallet/test_trades.py +50 -28
  199. chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -5
  200. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +6 -6
  201. chia/_tests/wallet/clawback/test_clawback_metadata.py +1 -2
  202. chia/_tests/wallet/conftest.py +135 -74
  203. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +25 -17
  204. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +75 -75
  205. chia/_tests/wallet/db_wallet/test_db_graftroot.py +10 -12
  206. chia/_tests/wallet/db_wallet/test_dl_offers.py +6 -6
  207. chia/_tests/wallet/db_wallet/test_dl_wallet.py +18 -18
  208. chia/_tests/wallet/did_wallet/test_did.py +1277 -474
  209. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +12 -11
  210. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +115 -105
  211. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +6 -7
  212. chia/_tests/wallet/nft_wallet/test_nft_offers.py +16 -16
  213. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +3 -3
  214. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +38 -12
  215. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +1 -1
  216. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +31 -33
  217. chia/_tests/wallet/rpc/test_wallet_rpc.py +218 -171
  218. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +36 -37
  219. chia/_tests/wallet/sync/test_wallet_sync.py +241 -78
  220. chia/_tests/wallet/test_address_type.py +20 -20
  221. chia/_tests/wallet/test_clvm_streamable.py +5 -5
  222. chia/_tests/wallet/test_coin_management.py +354 -0
  223. chia/_tests/wallet/test_coin_selection.py +34 -35
  224. chia/_tests/wallet/test_conditions.py +28 -16
  225. chia/_tests/wallet/test_debug_spend_bundle.py +156 -14
  226. chia/_tests/wallet/test_new_wallet_protocol.py +29 -31
  227. chia/_tests/wallet/test_nft_store.py +1 -2
  228. chia/_tests/wallet/test_notifications.py +2 -2
  229. chia/_tests/wallet/test_offer_parsing_performance.py +1 -1
  230. chia/_tests/wallet/test_puzzle_store.py +2 -3
  231. chia/_tests/wallet/test_sign_coin_spends.py +3 -3
  232. chia/_tests/wallet/test_signer_protocol.py +33 -34
  233. chia/_tests/wallet/test_singleton_lifecycle_fast.py +29 -29
  234. chia/_tests/wallet/test_taproot.py +1 -1
  235. chia/_tests/wallet/test_transaction_store.py +23 -19
  236. chia/_tests/wallet/test_util.py +36 -32
  237. chia/_tests/wallet/test_wallet.py +37 -37
  238. chia/_tests/wallet/test_wallet_action_scope.py +8 -8
  239. chia/_tests/wallet/test_wallet_blockchain.py +4 -6
  240. chia/_tests/wallet/test_wallet_coin_store.py +34 -34
  241. chia/_tests/wallet/test_wallet_node.py +69 -72
  242. chia/_tests/wallet/test_wallet_retry.py +3 -3
  243. chia/_tests/wallet/test_wallet_state_manager.py +12 -5
  244. chia/_tests/wallet/test_wallet_trade_store.py +2 -2
  245. chia/_tests/wallet/test_wallet_utils.py +5 -4
  246. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -3
  247. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +18 -18
  248. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +69 -40
  249. chia/_tests/wallet/wallet_block_tools.py +27 -27
  250. chia/_tests/weight_proof/test_weight_proof.py +30 -30
  251. chia/apis.py +19 -0
  252. chia/cmds/beta.py +8 -7
  253. chia/cmds/beta_funcs.py +15 -11
  254. chia/cmds/check_wallet_db.py +29 -27
  255. chia/cmds/chia.py +17 -9
  256. chia/cmds/cmd_classes.py +87 -79
  257. chia/cmds/cmd_helpers.py +242 -0
  258. chia/cmds/cmds_util.py +56 -66
  259. chia/cmds/coin_funcs.py +168 -153
  260. chia/cmds/coins.py +156 -194
  261. chia/cmds/configure.py +4 -3
  262. chia/cmds/dao.py +89 -33
  263. chia/cmds/dao_funcs.py +55 -33
  264. chia/cmds/data.py +7 -6
  265. chia/cmds/data_funcs.py +26 -21
  266. chia/cmds/db.py +4 -3
  267. chia/cmds/db_backup_func.py +2 -2
  268. chia/cmds/db_upgrade_func.py +3 -3
  269. chia/cmds/db_validate_func.py +2 -2
  270. chia/cmds/dev.py +2 -0
  271. chia/cmds/farm.py +18 -5
  272. chia/cmds/farm_funcs.py +17 -24
  273. chia/cmds/gh.py +275 -0
  274. chia/cmds/init.py +4 -11
  275. chia/cmds/init_funcs.py +9 -9
  276. chia/cmds/installers.py +5 -3
  277. chia/cmds/keys.py +56 -39
  278. chia/cmds/keys_funcs.py +30 -31
  279. chia/cmds/netspace.py +6 -3
  280. chia/cmds/netspace_funcs.py +3 -2
  281. chia/cmds/param_types.py +16 -6
  282. chia/cmds/passphrase.py +8 -7
  283. chia/cmds/passphrase_funcs.py +7 -61
  284. chia/cmds/peer.py +2 -1
  285. chia/cmds/peer_funcs.py +5 -5
  286. chia/cmds/plotnft.py +207 -153
  287. chia/cmds/plotnft_funcs.py +205 -174
  288. chia/cmds/plots.py +14 -6
  289. chia/cmds/plotters.py +2 -1
  290. chia/cmds/rpc.py +48 -28
  291. chia/cmds/show.py +2 -1
  292. chia/cmds/show_funcs.py +7 -6
  293. chia/cmds/signer.py +50 -58
  294. chia/cmds/sim.py +22 -14
  295. chia/cmds/sim_funcs.py +11 -11
  296. chia/cmds/start.py +3 -3
  297. chia/cmds/start_funcs.py +9 -12
  298. chia/cmds/stop.py +4 -3
  299. chia/cmds/units.py +1 -3
  300. chia/cmds/wallet.py +252 -96
  301. chia/cmds/wallet_funcs.py +217 -143
  302. chia/consensus/block_body_validation.py +133 -86
  303. chia/consensus/block_creation.py +42 -21
  304. chia/consensus/block_header_validation.py +32 -37
  305. chia/consensus/block_record.py +1 -2
  306. chia/consensus/blockchain.py +167 -180
  307. chia/consensus/blockchain_interface.py +10 -10
  308. chia/consensus/constants.py +2 -2
  309. chia/consensus/default_constants.py +3 -4
  310. chia/consensus/difficulty_adjustment.py +5 -5
  311. chia/consensus/find_fork_point.py +5 -5
  312. chia/consensus/full_block_to_block_record.py +4 -4
  313. chia/consensus/get_block_challenge.py +2 -2
  314. chia/consensus/get_block_generator.py +4 -3
  315. chia/consensus/multiprocess_validation.py +207 -304
  316. chia/consensus/vdf_info_computation.py +3 -3
  317. chia/daemon/client.py +46 -27
  318. chia/daemon/keychain_proxy.py +10 -9
  319. chia/daemon/keychain_server.py +18 -18
  320. chia/daemon/server.py +103 -113
  321. chia/daemon/windows_signal.py +2 -2
  322. chia/data_layer/data_layer.py +64 -76
  323. chia/data_layer/data_layer_api.py +8 -0
  324. chia/data_layer/data_layer_errors.py +3 -3
  325. chia/data_layer/data_layer_server.py +2 -2
  326. chia/data_layer/data_layer_util.py +71 -71
  327. chia/data_layer/data_layer_wallet.py +63 -67
  328. chia/data_layer/data_store.py +72 -72
  329. chia/data_layer/dl_wallet_store.py +10 -10
  330. chia/data_layer/download_data.py +5 -5
  331. chia/data_layer/s3_plugin_service.py +9 -9
  332. chia/data_layer/util/benchmark.py +0 -1
  333. chia/data_layer/util/plugin.py +2 -3
  334. chia/farmer/farmer.py +46 -43
  335. chia/farmer/farmer_api.py +27 -21
  336. chia/full_node/block_height_map.py +6 -6
  337. chia/full_node/block_store.py +41 -35
  338. chia/full_node/coin_store.py +42 -41
  339. chia/full_node/fee_estimate.py +2 -2
  340. chia/full_node/fee_estimation.py +1 -2
  341. chia/full_node/fee_history.py +5 -6
  342. chia/full_node/fee_tracker.py +24 -24
  343. chia/full_node/full_node.py +574 -300
  344. chia/full_node/full_node_api.py +181 -130
  345. chia/full_node/full_node_store.py +43 -43
  346. chia/full_node/hint_management.py +4 -4
  347. chia/full_node/hint_store.py +9 -10
  348. chia/full_node/mempool.py +25 -19
  349. chia/full_node/mempool_check_conditions.py +11 -42
  350. chia/full_node/mempool_manager.py +48 -53
  351. chia/full_node/pending_tx_cache.py +9 -9
  352. chia/full_node/subscriptions.py +23 -24
  353. chia/full_node/sync_store.py +8 -7
  354. chia/full_node/tx_processing_queue.py +3 -3
  355. chia/full_node/util/__init__.py +0 -0
  356. chia/full_node/weight_proof.py +79 -78
  357. chia/harvester/harvester.py +9 -8
  358. chia/harvester/harvester_api.py +19 -13
  359. chia/introducer/introducer.py +7 -5
  360. chia/introducer/introducer_api.py +9 -3
  361. chia/legacy/keyring.py +6 -5
  362. chia/plot_sync/delta.py +8 -8
  363. chia/plot_sync/receiver.py +12 -11
  364. chia/plot_sync/sender.py +15 -12
  365. chia/plotters/bladebit.py +12 -12
  366. chia/plotters/chiapos.py +2 -2
  367. chia/plotters/madmax.py +8 -8
  368. chia/plotters/plotters.py +6 -6
  369. chia/plotters/plotters_util.py +6 -4
  370. chia/plotting/cache.py +8 -7
  371. chia/plotting/check_plots.py +8 -8
  372. chia/plotting/create_plots.py +6 -6
  373. chia/plotting/manager.py +22 -22
  374. chia/plotting/util.py +31 -19
  375. chia/pools/pool_config.py +7 -7
  376. chia/pools/pool_puzzles.py +16 -16
  377. chia/pools/pool_wallet.py +64 -57
  378. chia/pools/pool_wallet_info.py +3 -3
  379. chia/protocols/full_node_protocol.py +3 -3
  380. chia/protocols/harvester_protocol.py +12 -12
  381. chia/protocols/introducer_protocol.py +1 -2
  382. chia/protocols/protocol_message_types.py +4 -4
  383. chia/protocols/protocol_state_machine.py +2 -2
  384. chia/protocols/protocol_timing.py +1 -0
  385. chia/protocols/shared_protocol.py +3 -3
  386. chia/protocols/timelord_protocol.py +2 -2
  387. chia/protocols/wallet_protocol.py +33 -33
  388. chia/rpc/crawler_rpc_api.py +12 -7
  389. chia/rpc/data_layer_rpc_api.py +49 -44
  390. chia/rpc/data_layer_rpc_client.py +41 -41
  391. chia/rpc/data_layer_rpc_util.py +7 -11
  392. chia/rpc/farmer_rpc_api.py +32 -27
  393. chia/rpc/farmer_rpc_client.py +14 -14
  394. chia/rpc/full_node_rpc_api.py +53 -48
  395. chia/rpc/full_node_rpc_client.py +30 -30
  396. chia/rpc/harvester_rpc_api.py +16 -11
  397. chia/rpc/harvester_rpc_client.py +6 -6
  398. chia/rpc/rpc_client.py +34 -14
  399. chia/rpc/rpc_server.py +117 -43
  400. chia/rpc/timelord_rpc_api.py +9 -4
  401. chia/rpc/util.py +11 -211
  402. chia/rpc/wallet_request_types.py +276 -60
  403. chia/rpc/wallet_rpc_api.py +563 -399
  404. chia/rpc/wallet_rpc_client.py +220 -250
  405. chia/seeder/crawl_store.py +6 -8
  406. chia/seeder/crawler.py +23 -36
  407. chia/seeder/crawler_api.py +28 -22
  408. chia/seeder/dns_server.py +99 -50
  409. chia/seeder/start_crawler.py +13 -9
  410. chia/server/address_manager.py +19 -19
  411. chia/server/address_manager_store.py +17 -17
  412. chia/server/api_protocol.py +106 -1
  413. chia/server/capabilities.py +3 -3
  414. chia/server/chia_policy.py +17 -16
  415. chia/server/introducer_peers.py +3 -3
  416. chia/server/node_discovery.py +34 -38
  417. chia/server/rate_limit_numbers.py +26 -16
  418. chia/server/rate_limits.py +67 -27
  419. chia/server/server.py +52 -31
  420. chia/server/signal_handlers.py +6 -3
  421. chia/server/ssl_context.py +5 -5
  422. chia/server/start_data_layer.py +37 -23
  423. chia/server/start_farmer.py +28 -16
  424. chia/server/start_full_node.py +29 -23
  425. chia/server/start_harvester.py +28 -15
  426. chia/server/start_introducer.py +27 -15
  427. chia/server/start_service.py +17 -29
  428. chia/server/start_timelord.py +25 -18
  429. chia/server/start_wallet.py +22 -18
  430. chia/server/upnp.py +4 -3
  431. chia/server/ws_connection.py +68 -54
  432. chia/simulator/add_blocks_in_batches.py +54 -0
  433. chia/simulator/block_tools.py +65 -64
  434. chia/simulator/full_node_simulator.py +66 -74
  435. chia/simulator/setup_services.py +10 -9
  436. chia/simulator/simulator_full_node_rpc_api.py +12 -14
  437. chia/simulator/simulator_full_node_rpc_client.py +3 -5
  438. chia/simulator/simulator_test_tools.py +8 -7
  439. chia/simulator/socket.py +1 -4
  440. chia/simulator/ssl_certs.py +5 -5
  441. chia/simulator/ssl_certs_1.py +2 -4
  442. chia/simulator/ssl_certs_10.py +2 -4
  443. chia/simulator/ssl_certs_2.py +2 -4
  444. chia/simulator/ssl_certs_3.py +2 -4
  445. chia/simulator/ssl_certs_4.py +2 -4
  446. chia/simulator/ssl_certs_5.py +2 -4
  447. chia/simulator/ssl_certs_6.py +2 -4
  448. chia/simulator/ssl_certs_7.py +2 -4
  449. chia/simulator/ssl_certs_8.py +2 -4
  450. chia/simulator/ssl_certs_9.py +2 -4
  451. chia/simulator/start_simulator.py +14 -6
  452. chia/simulator/wallet_tools.py +21 -20
  453. chia/ssl/create_ssl.py +11 -11
  454. chia/timelord/iters_from_block.py +2 -2
  455. chia/timelord/timelord.py +57 -33
  456. chia/timelord/timelord_api.py +12 -6
  457. chia/timelord/timelord_launcher.py +10 -8
  458. chia/timelord/timelord_state.py +5 -5
  459. chia/types/block_protocol.py +2 -2
  460. chia/types/blockchain_format/coin.py +3 -3
  461. chia/types/blockchain_format/program.py +17 -18
  462. chia/types/blockchain_format/tree_hash.py +9 -9
  463. chia/types/coin_spend.py +8 -8
  464. chia/types/condition_with_args.py +1 -2
  465. chia/types/eligible_coin_spends.py +16 -15
  466. chia/types/generator_types.py +1 -2
  467. chia/types/internal_mempool_item.py +1 -2
  468. chia/types/mempool_item.py +7 -7
  469. chia/types/mempool_submission_status.py +2 -2
  470. chia/types/peer_info.py +1 -1
  471. chia/types/spend_bundle.py +1 -2
  472. chia/types/transaction_queue_entry.py +2 -2
  473. chia/types/unfinished_header_block.py +2 -2
  474. chia/types/validation_state.py +14 -0
  475. chia/types/weight_proof.py +5 -6
  476. chia/util/action_scope.py +8 -8
  477. chia/util/async_pool.py +6 -4
  478. chia/util/augmented_chain.py +13 -9
  479. chia/util/batches.py +5 -2
  480. chia/util/bech32m.py +14 -11
  481. chia/util/beta_metrics.py +5 -4
  482. chia/util/block_cache.py +5 -5
  483. chia/util/byte_types.py +2 -0
  484. chia/util/check_fork_next_block.py +3 -2
  485. chia/util/chia_logging.py +41 -21
  486. chia/util/collection.py +3 -3
  487. chia/util/condition_tools.py +18 -18
  488. chia/util/config.py +26 -25
  489. chia/util/cpu.py +2 -0
  490. chia/util/db_synchronous.py +2 -0
  491. chia/util/db_version.py +2 -0
  492. chia/util/db_wrapper.py +13 -10
  493. chia/util/default_root.py +17 -0
  494. chia/util/dump_keyring.py +6 -6
  495. chia/util/errors.py +5 -3
  496. chia/util/file_keyring.py +22 -33
  497. chia/util/files.py +2 -0
  498. chia/util/full_block_utils.py +31 -7
  499. chia/util/generator_tools.py +18 -8
  500. chia/util/hash.py +3 -1
  501. chia/util/initial-config.yaml +19 -0
  502. chia/util/inline_executor.py +2 -0
  503. chia/util/ip_address.py +39 -0
  504. chia/util/json_util.py +0 -4
  505. chia/util/keychain.py +27 -24
  506. chia/util/keyring_wrapper.py +65 -4
  507. chia/util/limited_semaphore.py +3 -1
  508. chia/util/lock.py +4 -2
  509. chia/util/log_exceptions.py +5 -2
  510. chia/util/logging.py +3 -1
  511. chia/util/lru_cache.py +2 -0
  512. chia/util/math.py +4 -4
  513. chia/util/network.py +15 -73
  514. chia/util/paginator.py +3 -1
  515. chia/util/path.py +2 -0
  516. chia/util/permissions.py +3 -2
  517. chia/util/prev_transaction_block.py +1 -3
  518. chia/util/priority_mutex.py +6 -3
  519. chia/util/profiler.py +7 -4
  520. chia/util/recursive_replace.py +2 -0
  521. chia/util/safe_cancel_task.py +2 -0
  522. chia/util/service_groups.py +2 -2
  523. chia/util/setproctitle.py +2 -0
  524. chia/util/significant_bits.py +2 -0
  525. chia/util/ssl_check.py +11 -11
  526. chia/util/streamable.py +44 -56
  527. chia/util/task_referencer.py +59 -0
  528. chia/util/task_timing.py +22 -18
  529. chia/util/timing.py +4 -1
  530. chia/util/vdf_prover.py +2 -3
  531. chia/util/virtual_project_analysis.py +540 -0
  532. chia/util/ws_message.py +6 -6
  533. chia/wallet/cat_wallet/cat_info.py +3 -3
  534. chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -3
  535. chia/wallet/cat_wallet/cat_utils.py +5 -4
  536. chia/wallet/cat_wallet/cat_wallet.py +56 -70
  537. chia/wallet/cat_wallet/dao_cat_info.py +3 -3
  538. chia/wallet/cat_wallet/dao_cat_wallet.py +18 -18
  539. chia/wallet/cat_wallet/lineage_store.py +2 -2
  540. chia/wallet/coin_selection.py +15 -15
  541. chia/wallet/conditions.py +257 -71
  542. chia/wallet/dao_wallet/dao_info.py +4 -4
  543. chia/wallet/dao_wallet/dao_utils.py +43 -42
  544. chia/wallet/dao_wallet/dao_wallet.py +66 -68
  545. chia/wallet/db_wallet/db_wallet_puzzles.py +12 -8
  546. chia/wallet/derive_keys.py +11 -11
  547. chia/wallet/did_wallet/did_info.py +3 -3
  548. chia/wallet/did_wallet/did_wallet.py +56 -47
  549. chia/wallet/did_wallet/did_wallet_puzzles.py +7 -6
  550. chia/wallet/lineage_proof.py +4 -4
  551. chia/wallet/nft_wallet/metadata_outer_puzzle.py +2 -2
  552. chia/wallet/nft_wallet/nft_info.py +4 -4
  553. chia/wallet/nft_wallet/nft_puzzles.py +16 -16
  554. chia/wallet/nft_wallet/nft_wallet.py +90 -89
  555. chia/wallet/nft_wallet/ownership_outer_puzzle.py +2 -2
  556. chia/wallet/nft_wallet/singleton_outer_puzzle.py +2 -2
  557. chia/wallet/nft_wallet/transfer_program_puzzle.py +2 -2
  558. chia/wallet/nft_wallet/uncurry_nft.py +2 -2
  559. chia/wallet/notification_manager.py +5 -5
  560. chia/wallet/notification_store.py +6 -6
  561. chia/wallet/outer_puzzles.py +2 -2
  562. chia/wallet/payment.py +4 -5
  563. chia/wallet/puzzle_drivers.py +4 -4
  564. chia/wallet/puzzles/clawback/drivers.py +5 -5
  565. chia/wallet/puzzles/clawback/puzzle_decorator.py +7 -7
  566. chia/wallet/puzzles/load_clvm.py +2 -3
  567. chia/wallet/puzzles/p2_conditions.py +1 -2
  568. chia/wallet/puzzles/p2_delegated_conditions.py +1 -2
  569. chia/wallet/puzzles/p2_delegated_puzzle.py +2 -3
  570. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -4
  571. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +1 -2
  572. chia/wallet/puzzles/p2_puzzle_hash.py +1 -2
  573. chia/wallet/puzzles/puzzle_utils.py +7 -7
  574. chia/wallet/puzzles/singleton_top_layer.py +6 -5
  575. chia/wallet/puzzles/singleton_top_layer_v1_1.py +6 -5
  576. chia/wallet/puzzles/tails.py +34 -30
  577. chia/wallet/signer_protocol.py +7 -8
  578. chia/wallet/singleton.py +4 -4
  579. chia/wallet/trade_manager.py +155 -141
  580. chia/wallet/trade_record.py +5 -5
  581. chia/wallet/trading/offer.py +100 -101
  582. chia/wallet/trading/trade_store.py +14 -14
  583. chia/wallet/transaction_record.py +31 -16
  584. chia/wallet/util/address_type.py +4 -4
  585. chia/wallet/util/blind_signer_tl.py +8 -12
  586. chia/wallet/util/clvm_streamable.py +15 -15
  587. chia/wallet/util/compute_hints.py +5 -5
  588. chia/wallet/util/compute_memos.py +4 -6
  589. chia/wallet/util/curry_and_treehash.py +3 -2
  590. chia/wallet/util/debug_spend_bundle.py +6 -8
  591. chia/wallet/util/merkle_tree.py +10 -10
  592. chia/wallet/util/merkle_utils.py +10 -10
  593. chia/wallet/util/new_peak_queue.py +3 -3
  594. chia/wallet/util/peer_request_cache.py +8 -8
  595. chia/{util → wallet/util}/pprint.py +2 -3
  596. chia/wallet/util/puzzle_compression.py +3 -4
  597. chia/wallet/util/puzzle_decorator.py +10 -10
  598. chia/wallet/util/query_filter.py +9 -10
  599. chia/wallet/util/tx_config.py +12 -12
  600. chia/wallet/util/wallet_sync_utils.py +24 -21
  601. chia/wallet/util/wallet_types.py +9 -2
  602. chia/wallet/vc_wallet/cr_cat_drivers.py +28 -27
  603. chia/wallet/vc_wallet/cr_cat_wallet.py +42 -40
  604. chia/wallet/vc_wallet/cr_outer_puzzle.py +4 -4
  605. chia/wallet/vc_wallet/vc_drivers.py +16 -16
  606. chia/wallet/vc_wallet/vc_store.py +9 -9
  607. chia/wallet/vc_wallet/vc_wallet.py +35 -35
  608. chia/wallet/wallet.py +54 -54
  609. chia/wallet/wallet_action_scope.py +14 -13
  610. chia/wallet/wallet_blockchain.py +10 -10
  611. chia/wallet/wallet_coin_record.py +2 -2
  612. chia/wallet/wallet_coin_store.py +10 -10
  613. chia/wallet/wallet_info.py +1 -2
  614. chia/wallet/wallet_interested_store.py +5 -5
  615. chia/wallet/wallet_nft_store.py +6 -6
  616. chia/wallet/wallet_node.py +72 -76
  617. chia/wallet/wallet_node_api.py +33 -27
  618. chia/wallet/wallet_pool_store.py +1 -2
  619. chia/wallet/wallet_protocol.py +15 -15
  620. chia/wallet/wallet_puzzle_store.py +35 -4
  621. chia/wallet/wallet_retry_store.py +2 -2
  622. chia/wallet/wallet_singleton_store.py +10 -9
  623. chia/wallet/wallet_spend_bundle.py +4 -20
  624. chia/wallet/wallet_state_manager.py +223 -224
  625. chia/wallet/wallet_transaction_store.py +44 -18
  626. chia/wallet/wallet_user_store.py +2 -2
  627. chia/wallet/wallet_weight_proof_handler.py +2 -2
  628. {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/LICENSE +1 -1
  629. {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/METADATA +67 -72
  630. chia_blockchain-2.5.1rc2.dist-info/RECORD +1042 -0
  631. {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/WHEEL +1 -1
  632. mozilla-ca/cacert.pem +32 -87
  633. chia/_tests/cmds/wallet/test_coins.py +0 -195
  634. chia/consensus/block_root_validation.py +0 -46
  635. chia/util/api_decorators.py +0 -89
  636. chia_blockchain-2.5.0rc2.dist-info/RECORD +0 -1028
  637. {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/entry_points.txt +0 -0
@@ -1,16 +1,23 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- import functools
5
4
  import logging
6
5
  import time
7
6
  import traceback
7
+ from collections.abc import Collection
8
8
  from concurrent.futures import ThreadPoolExecutor
9
9
  from datetime import datetime, timezone
10
- from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, cast
10
+ from typing import TYPE_CHECKING, ClassVar, Optional, cast
11
11
 
12
12
  import anyio
13
- from chia_rs import AugSchemeMPL, G1Element, G2Element, MerkleSet
13
+ from chia_rs import (
14
+ AugSchemeMPL,
15
+ G1Element,
16
+ G2Element,
17
+ MerkleSet,
18
+ additions_and_removals,
19
+ get_flags_for_height_and_constants,
20
+ )
14
21
  from chiabip158 import PyBIP158
15
22
 
16
23
  from chia.consensus.block_creation import create_unfinished_block
@@ -22,12 +29,13 @@ from chia.full_node.bundle_tools import simple_solution_generator, simple_soluti
22
29
  from chia.full_node.coin_store import CoinStore
23
30
  from chia.full_node.fee_estimate import FeeEstimate, FeeEstimateGroup, fee_rate_v2_to_v1
24
31
  from chia.full_node.fee_estimator_interface import FeeEstimatorInterface
25
- from chia.full_node.mempool_check_conditions import get_name_puzzle_conditions, get_puzzle_and_solution_for_coin
32
+ from chia.full_node.mempool_check_conditions import get_puzzle_and_solution_for_coin
26
33
  from chia.full_node.signage_point import SignagePoint
27
34
  from chia.full_node.tx_processing_queue import TransactionQueueFull
28
35
  from chia.protocols import farmer_protocol, full_node_protocol, introducer_protocol, timelord_protocol, wallet_protocol
29
36
  from chia.protocols.full_node_protocol import RejectBlock, RejectBlocks
30
37
  from chia.protocols.protocol_message_types import ProtocolMessageTypes
38
+ from chia.protocols.protocol_timing import RATE_LIMITER_BAN_SECONDS
31
39
  from chia.protocols.shared_protocol import Capability
32
40
  from chia.protocols.wallet_protocol import (
33
41
  CoinState,
@@ -38,6 +46,7 @@ from chia.protocols.wallet_protocol import (
38
46
  RespondFeeEstimates,
39
47
  RespondSESInfo,
40
48
  )
49
+ from chia.server.api_protocol import ApiMetadata
41
50
  from chia.server.outbound_message import Message, make_msg
42
51
  from chia.server.server import ChiaServer
43
52
  from chia.server.ws_connection import WSChiaConnection
@@ -58,14 +67,14 @@ from chia.types.peer_info import PeerInfo
58
67
  from chia.types.spend_bundle import SpendBundle
59
68
  from chia.types.transaction_queue_entry import TransactionQueueEntry
60
69
  from chia.types.unfinished_block import UnfinishedBlock
61
- from chia.util.api_decorators import api_request
62
70
  from chia.util.batches import to_batches
63
71
  from chia.util.db_wrapper import SQLITE_MAX_VARIABLE_NUMBER
64
- from chia.util.full_block_utils import header_block_from_block
65
- from chia.util.generator_tools import get_block_header, tx_removals_and_additions
72
+ from chia.util.full_block_utils import get_height_and_tx_status_from_block, header_block_from_block
73
+ from chia.util.generator_tools import get_block_header
66
74
  from chia.util.hash import std_hash
67
75
  from chia.util.ints import uint8, uint32, uint64, uint128
68
76
  from chia.util.limited_semaphore import LimitedSemaphoreFullError
77
+ from chia.util.task_referencer import create_referenced_task
69
78
 
70
79
  if TYPE_CHECKING:
71
80
  from chia.full_node.full_node import FullNode
@@ -74,9 +83,15 @@ else:
74
83
 
75
84
 
76
85
  class FullNodeAPI:
86
+ if TYPE_CHECKING:
87
+ from chia.server.api_protocol import ApiProtocol
88
+
89
+ _protocol_check: ClassVar[ApiProtocol] = cast("FullNodeAPI", None)
90
+
77
91
  log: logging.Logger
78
92
  full_node: FullNode
79
93
  executor: ThreadPoolExecutor
94
+ metadata: ClassVar[ApiMetadata] = ApiMetadata()
80
95
 
81
96
  def __init__(self, full_node: FullNode) -> None:
82
97
  self.log = logging.getLogger(__name__)
@@ -91,7 +106,7 @@ class FullNodeAPI:
91
106
  def ready(self) -> bool:
92
107
  return self.full_node.initialized
93
108
 
94
- @api_request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_peers])
109
+ @metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_peers])
95
110
  async def request_peers(
96
111
  self, _request: full_node_protocol.RequestPeers, peer: WSChiaConnection
97
112
  ) -> Optional[Message]:
@@ -103,7 +118,7 @@ class FullNodeAPI:
103
118
  return msg
104
119
  return None
105
120
 
106
- @api_request(peer_required=True)
121
+ @metadata.request(peer_required=True)
107
122
  async def respond_peers(
108
123
  self, request: full_node_protocol.RespondPeers, peer: WSChiaConnection
109
124
  ) -> Optional[Message]:
@@ -112,7 +127,7 @@ class FullNodeAPI:
112
127
  await self.full_node.full_node_peers.add_peers(request.peer_list, peer.get_peer_info(), True)
113
128
  return None
114
129
 
115
- @api_request(peer_required=True)
130
+ @metadata.request(peer_required=True)
116
131
  async def respond_peers_introducer(
117
132
  self, request: introducer_protocol.RespondPeersIntroducer, peer: WSChiaConnection
118
133
  ) -> Optional[Message]:
@@ -123,7 +138,7 @@ class FullNodeAPI:
123
138
  await peer.close()
124
139
  return None
125
140
 
126
- @api_request(peer_required=True, execute_task=True)
141
+ @metadata.request(peer_required=True, execute_task=True)
127
142
  async def new_peak(self, request: full_node_protocol.NewPeak, peer: WSChiaConnection) -> None:
128
143
  """
129
144
  A peer notifies us that they have added a new peak to their blockchain. If we don't have it,
@@ -140,7 +155,7 @@ class FullNodeAPI:
140
155
 
141
156
  return None
142
157
 
143
- @api_request(peer_required=True)
158
+ @metadata.request(peer_required=True)
144
159
  async def new_transaction(
145
160
  self, transaction: full_node_protocol.NewTransaction, peer: WSChiaConnection
146
161
  ) -> Optional[Message]:
@@ -189,7 +204,7 @@ class FullNodeAPI:
189
204
  break
190
205
  if transaction_id not in full_node.full_node_store.peers_with_tx:
191
206
  break
192
- peers_with_tx: Set[bytes32] = full_node.full_node_store.peers_with_tx[transaction_id]
207
+ peers_with_tx: set[bytes32] = full_node.full_node_store.peers_with_tx[transaction_id]
193
208
  if len(peers_with_tx) == 0:
194
209
  break
195
210
  peer_id = peers_with_tx.pop()
@@ -216,14 +231,14 @@ class FullNodeAPI:
216
231
  full_node.full_node_store.tx_fetch_tasks.pop(task_id)
217
232
 
218
233
  task_id: bytes32 = bytes32.secret()
219
- fetch_task = asyncio.create_task(
234
+ fetch_task = create_referenced_task(
220
235
  tx_request_and_timeout(self.full_node, transaction.transaction_id, task_id)
221
236
  )
222
237
  self.full_node.full_node_store.tx_fetch_tasks[task_id] = fetch_task
223
238
  return None
224
239
  return None
225
240
 
226
- @api_request(reply_types=[ProtocolMessageTypes.respond_transaction])
241
+ @metadata.request(reply_types=[ProtocolMessageTypes.respond_transaction])
227
242
  async def request_transaction(self, request: full_node_protocol.RequestTransaction) -> Optional[Message]:
228
243
  """Peer has requested a full transaction from us."""
229
244
  # Ignore if syncing
@@ -238,7 +253,7 @@ class FullNodeAPI:
238
253
  msg = make_msg(ProtocolMessageTypes.respond_transaction, transaction)
239
254
  return msg
240
255
 
241
- @api_request(peer_required=True, bytes_required=True)
256
+ @metadata.request(peer_required=True, bytes_required=True)
242
257
  async def respond_transaction(
243
258
  self,
244
259
  tx: full_node_protocol.RespondTransaction,
@@ -266,7 +281,7 @@ class FullNodeAPI:
266
281
  pass # we can't do anything here, the tx will be dropped. We might do something in the future.
267
282
  return None
268
283
 
269
- @api_request(reply_types=[ProtocolMessageTypes.respond_proof_of_weight])
284
+ @metadata.request(reply_types=[ProtocolMessageTypes.respond_proof_of_weight])
270
285
  async def request_proof_of_weight(self, request: full_node_protocol.RequestProofOfWeight) -> Optional[Message]:
271
286
  if self.full_node.weight_proof_handler is None:
272
287
  return None
@@ -306,12 +321,12 @@ class FullNodeAPI:
306
321
  self.full_node.full_node_store.serialized_wp_message = message
307
322
  return message
308
323
 
309
- @api_request()
324
+ @metadata.request()
310
325
  async def respond_proof_of_weight(self, request: full_node_protocol.RespondProofOfWeight) -> Optional[Message]:
311
326
  self.log.warning("Received proof of weight too late.")
312
327
  return None
313
328
 
314
- @api_request(reply_types=[ProtocolMessageTypes.respond_block, ProtocolMessageTypes.reject_block])
329
+ @metadata.request(reply_types=[ProtocolMessageTypes.respond_block, ProtocolMessageTypes.reject_block])
315
330
  async def request_block(self, request: full_node_protocol.RequestBlock) -> Optional[Message]:
316
331
  if not self.full_node.blockchain.contains_height(request.height):
317
332
  reject = RejectBlock(request.height)
@@ -328,7 +343,7 @@ class FullNodeAPI:
328
343
  return make_msg(ProtocolMessageTypes.respond_block, full_node_protocol.RespondBlock(block))
329
344
  return make_msg(ProtocolMessageTypes.reject_block, RejectBlock(request.height))
330
345
 
331
- @api_request(reply_types=[ProtocolMessageTypes.respond_blocks, ProtocolMessageTypes.reject_blocks])
346
+ @metadata.request(reply_types=[ProtocolMessageTypes.respond_blocks, ProtocolMessageTypes.reject_blocks])
332
347
  async def request_blocks(self, request: full_node_protocol.RequestBlocks) -> Optional[Message]:
333
348
  # note that we treat the request range as *inclusive*, but we check the
334
349
  # size before we bump end_height. So MAX_BLOCK_COUNT_PER_REQUESTS is off
@@ -347,7 +362,7 @@ class FullNodeAPI:
347
362
  return msg
348
363
 
349
364
  if not request.include_transaction_block:
350
- blocks: List[FullBlock] = []
365
+ blocks: list[FullBlock] = []
351
366
  for i in range(request.start_height, request.end_height + 1):
352
367
  header_hash_i: Optional[bytes32] = self.full_node.blockchain.height_to_hash(uint32(i))
353
368
  if header_hash_i is None:
@@ -365,7 +380,7 @@ class FullNodeAPI:
365
380
  full_node_protocol.RespondBlocks(request.start_height, request.end_height, blocks),
366
381
  )
367
382
  else:
368
- blocks_bytes: List[bytes] = []
383
+ blocks_bytes: list[bytes] = []
369
384
  for i in range(request.start_height, request.end_height + 1):
370
385
  header_hash_i = self.full_node.blockchain.height_to_hash(uint32(i))
371
386
  if header_hash_i is None:
@@ -390,33 +405,44 @@ class FullNodeAPI:
390
405
 
391
406
  return msg
392
407
 
393
- @api_request()
394
- async def reject_block(self, request: full_node_protocol.RejectBlock) -> None:
395
- self.log.debug(f"reject_block {request.height}")
408
+ @metadata.request(peer_required=True)
409
+ async def reject_block(
410
+ self,
411
+ request: full_node_protocol.RejectBlock,
412
+ peer: WSChiaConnection,
413
+ ) -> None:
414
+ self.log.warning(f"unsolicited reject_block {request.height}")
415
+ await peer.close(RATE_LIMITER_BAN_SECONDS)
396
416
 
397
- @api_request()
398
- async def reject_blocks(self, request: full_node_protocol.RejectBlocks) -> None:
399
- self.log.debug(f"reject_blocks {request.start_height} {request.end_height}")
417
+ @metadata.request(peer_required=True)
418
+ async def reject_blocks(
419
+ self,
420
+ request: full_node_protocol.RejectBlocks,
421
+ peer: WSChiaConnection,
422
+ ) -> None:
423
+ self.log.warning(f"reject_blocks {request.start_height} {request.end_height}")
424
+ await peer.close(RATE_LIMITER_BAN_SECONDS)
400
425
 
401
- @api_request()
402
- async def respond_blocks(self, request: full_node_protocol.RespondBlocks) -> None:
426
+ @metadata.request(peer_required=True)
427
+ async def respond_blocks(
428
+ self,
429
+ request: full_node_protocol.RespondBlocks,
430
+ peer: WSChiaConnection,
431
+ ) -> None:
403
432
  self.log.warning("Received unsolicited/late blocks")
404
- return None
433
+ await peer.close(RATE_LIMITER_BAN_SECONDS)
405
434
 
406
- @api_request(peer_required=True)
435
+ @metadata.request(peer_required=True)
407
436
  async def respond_block(
408
437
  self,
409
438
  respond_block: full_node_protocol.RespondBlock,
410
439
  peer: WSChiaConnection,
411
440
  ) -> Optional[Message]:
412
- """
413
- Receive a full block from a peer full node (or ourselves).
414
- """
415
-
416
441
  self.log.warning(f"Received unsolicited/late block from peer {peer.get_peer_logging()}")
442
+ await peer.close(RATE_LIMITER_BAN_SECONDS)
417
443
  return None
418
444
 
419
- @api_request()
445
+ @metadata.request()
420
446
  async def new_unfinished_block(
421
447
  self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock
422
448
  ) -> Optional[Message]:
@@ -448,11 +474,11 @@ class FullNodeAPI:
448
474
  await asyncio.sleep(5)
449
475
  self.full_node.full_node_store.remove_requesting_unfinished_block(block_hash, None)
450
476
 
451
- asyncio.create_task(eventually_clear())
477
+ create_referenced_task(eventually_clear(), known_unreferenced=True)
452
478
 
453
479
  return msg
454
480
 
455
- @api_request(reply_types=[ProtocolMessageTypes.respond_unfinished_block])
481
+ @metadata.request(reply_types=[ProtocolMessageTypes.respond_unfinished_block])
456
482
  async def request_unfinished_block(
457
483
  self, request_unfinished_block: full_node_protocol.RequestUnfinishedBlock
458
484
  ) -> Optional[Message]:
@@ -467,7 +493,7 @@ class FullNodeAPI:
467
493
  return msg
468
494
  return None
469
495
 
470
- @api_request()
496
+ @metadata.request()
471
497
  async def new_unfinished_block2(
472
498
  self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock2
473
499
  ) -> Optional[Message]:
@@ -516,11 +542,11 @@ class FullNodeAPI:
516
542
  await asyncio.sleep(5)
517
543
  self.full_node.full_node_store.remove_requesting_unfinished_block(block_hash, foliage_hash)
518
544
 
519
- asyncio.create_task(eventually_clear())
545
+ create_referenced_task(eventually_clear(), known_unreferenced=True)
520
546
 
521
547
  return msg
522
548
 
523
- @api_request(reply_types=[ProtocolMessageTypes.respond_unfinished_block])
549
+ @metadata.request(reply_types=[ProtocolMessageTypes.respond_unfinished_block])
524
550
  async def request_unfinished_block2(
525
551
  self, request_unfinished_block: full_node_protocol.RequestUnfinishedBlock2
526
552
  ) -> Optional[Message]:
@@ -537,21 +563,18 @@ class FullNodeAPI:
537
563
  return msg
538
564
  return None
539
565
 
540
- @api_request(peer_required=True, bytes_required=True)
566
+ @metadata.request(peer_required=True)
541
567
  async def respond_unfinished_block(
542
568
  self,
543
569
  respond_unfinished_block: full_node_protocol.RespondUnfinishedBlock,
544
570
  peer: WSChiaConnection,
545
- respond_unfinished_block_bytes: bytes = b"",
546
571
  ) -> Optional[Message]:
547
572
  if self.full_node.sync_store.get_sync_mode():
548
573
  return None
549
- await self.full_node.add_unfinished_block(
550
- respond_unfinished_block.unfinished_block, peer, block_bytes=respond_unfinished_block_bytes
551
- )
574
+ await self.full_node.add_unfinished_block(respond_unfinished_block.unfinished_block, peer)
552
575
  return None
553
576
 
554
- @api_request(peer_required=True)
577
+ @metadata.request(peer_required=True)
555
578
  async def new_signage_point_or_end_of_sub_slot(
556
579
  self, new_sp: full_node_protocol.NewSignagePointOrEndOfSubSlot, peer: WSChiaConnection
557
580
  ) -> Optional[Message]:
@@ -635,12 +658,14 @@ class FullNodeAPI:
635
658
 
636
659
  return make_msg(ProtocolMessageTypes.request_signage_point_or_end_of_sub_slot, full_node_request)
637
660
 
638
- @api_request(reply_types=[ProtocolMessageTypes.respond_signage_point, ProtocolMessageTypes.respond_end_of_sub_slot])
661
+ @metadata.request(
662
+ reply_types=[ProtocolMessageTypes.respond_signage_point, ProtocolMessageTypes.respond_end_of_sub_slot]
663
+ )
639
664
  async def request_signage_point_or_end_of_sub_slot(
640
665
  self, request: full_node_protocol.RequestSignagePointOrEndOfSubSlot
641
666
  ) -> Optional[Message]:
642
667
  if request.index_from_challenge == 0:
643
- sub_slot: Optional[Tuple[EndOfSubSlotBundle, int, uint128]] = self.full_node.full_node_store.get_sub_slot(
668
+ sub_slot: Optional[tuple[EndOfSubSlotBundle, int, uint128]] = self.full_node.full_node_store.get_sub_slot(
644
669
  request.challenge_hash
645
670
  )
646
671
  if sub_slot is not None:
@@ -677,7 +702,7 @@ class FullNodeAPI:
677
702
  self.log.info(f"Don't have signage point {request}")
678
703
  return None
679
704
 
680
- @api_request(peer_required=True)
705
+ @metadata.request(peer_required=True)
681
706
  async def respond_signage_point(
682
707
  self, request: full_node_protocol.RespondSignagePoint, peer: WSChiaConnection
683
708
  ) -> Optional[Message]:
@@ -732,7 +757,7 @@ class FullNodeAPI:
732
757
 
733
758
  return None
734
759
 
735
- @api_request(peer_required=True)
760
+ @metadata.request(peer_required=True)
736
761
  async def respond_end_of_sub_slot(
737
762
  self, request: full_node_protocol.RespondEndOfSubSlot, peer: WSChiaConnection
738
763
  ) -> Optional[Message]:
@@ -741,7 +766,7 @@ class FullNodeAPI:
741
766
  msg, _ = await self.full_node.add_end_of_sub_slot(request.end_of_slot_bundle, peer)
742
767
  return msg
743
768
 
744
- @api_request(peer_required=True)
769
+ @metadata.request(peer_required=True)
745
770
  async def request_mempool_transactions(
746
771
  self,
747
772
  request: full_node_protocol.RequestMempoolTransactions,
@@ -749,7 +774,7 @@ class FullNodeAPI:
749
774
  ) -> Optional[Message]:
750
775
  received_filter = PyBIP158(bytearray(request.filter))
751
776
 
752
- items: List[SpendBundle] = self.full_node.mempool_manager.get_items_not_in_filter(received_filter)
777
+ items: list[SpendBundle] = self.full_node.mempool_manager.get_items_not_in_filter(received_filter)
753
778
 
754
779
  for item in items:
755
780
  transaction = full_node_protocol.RespondTransaction(item)
@@ -758,7 +783,7 @@ class FullNodeAPI:
758
783
  return None
759
784
 
760
785
  # FARMER PROTOCOL
761
- @api_request(peer_required=True)
786
+ @metadata.request(peer_required=True)
762
787
  async def declare_proof_of_space(
763
788
  self, request: farmer_protocol.DeclareProofOfSpace, peer: WSChiaConnection
764
789
  ) -> Optional[Message]:
@@ -792,7 +817,7 @@ class FullNodeAPI:
792
817
  assert sp_vdfs.cc_vdf is not None
793
818
  cc_challenge_hash = sp_vdfs.cc_vdf.challenge
794
819
 
795
- pos_sub_slot: Optional[Tuple[EndOfSubSlotBundle, int, uint128]] = None
820
+ pos_sub_slot: Optional[tuple[EndOfSubSlotBundle, int, uint128]] = None
796
821
  if request.challenge_hash != self.full_node.constants.GENESIS_CHALLENGE:
797
822
  # Checks that the proof of space is a response to a recent challenge and valid SP
798
823
  pos_sub_slot = self.full_node.full_node_store.get_sub_slot(cc_challenge_hash)
@@ -812,8 +837,8 @@ class FullNodeAPI:
812
837
  # Grab best transactions from Mempool for given tip target
813
838
  aggregate_signature: G2Element = G2Element()
814
839
  block_generator: Optional[BlockGenerator] = None
815
- additions: Optional[List[Coin]] = []
816
- removals: Optional[List[Coin]] = []
840
+ additions: Optional[list[Coin]] = []
841
+ removals: Optional[list[Coin]] = []
817
842
  async with self.full_node.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
818
843
  peak: Optional[BlockRecord] = self.full_node.blockchain.get_peak()
819
844
 
@@ -853,10 +878,17 @@ class FullNodeAPI:
853
878
  # when the hard fork activates, block generators are
854
879
  # allowed to be serialized with the improved CLVM
855
880
  # serialization format, supporting back-references
881
+ start_time = time.monotonic()
856
882
  if peak.height >= self.full_node.constants.HARD_FORK_HEIGHT:
857
883
  block_generator = simple_solution_generator_backrefs(spend_bundle)
858
884
  else:
859
885
  block_generator = simple_solution_generator(spend_bundle)
886
+ end_time = time.monotonic()
887
+ duration = end_time - start_time
888
+ self.log.log(
889
+ logging.INFO if duration < 1 else logging.WARNING,
890
+ f"serializing block generator took {duration:0.2f} seconds",
891
+ )
860
892
 
861
893
  def get_plot_sig(to_sign: bytes32, _extra: G1Element) -> G2Element:
862
894
  if to_sign == request.challenge_chain_sp:
@@ -906,7 +938,7 @@ class FullNodeAPI:
906
938
  return None
907
939
 
908
940
  try:
909
- finished_sub_slots: Optional[List[EndOfSubSlotBundle]] = (
941
+ finished_sub_slots: Optional[list[EndOfSubSlotBundle]] = (
910
942
  self.full_node.full_node_store.get_finished_sub_slots(
911
943
  self.full_node.blockchain, prev_b, cc_challenge_hash
912
944
  )
@@ -1011,7 +1043,7 @@ class FullNodeAPI:
1011
1043
  if unfinished_block.is_transaction_block():
1012
1044
  foliage_transaction_block_hash = unfinished_block.foliage.foliage_transaction_block_hash
1013
1045
  else:
1014
- foliage_transaction_block_hash = bytes32([0] * 32)
1046
+ foliage_transaction_block_hash = bytes32.zeros
1015
1047
  assert foliage_transaction_block_hash is not None
1016
1048
 
1017
1049
  foliage_block_data: Optional[FoliageBlockData] = None
@@ -1065,7 +1097,7 @@ class FullNodeAPI:
1065
1097
  )
1066
1098
  return None
1067
1099
 
1068
- @api_request(peer_required=True)
1100
+ @metadata.request(peer_required=True)
1069
1101
  async def signed_values(
1070
1102
  self, farmer_request: farmer_protocol.SignedValues, peer: WSChiaConnection
1071
1103
  ) -> Optional[Message]:
@@ -1074,7 +1106,7 @@ class FullNodeAPI:
1074
1106
  block, which only needs a Proof of Time to be finished. If the signature is valid,
1075
1107
  we call the unfinished_block routine.
1076
1108
  """
1077
- candidate_tuple: Optional[Tuple[uint32, UnfinishedBlock]] = self.full_node.full_node_store.get_candidate_block(
1109
+ candidate_tuple: Optional[tuple[uint32, UnfinishedBlock]] = self.full_node.full_node_store.get_candidate_block(
1078
1110
  farmer_request.quality_string
1079
1111
  )
1080
1112
 
@@ -1125,7 +1157,7 @@ class FullNodeAPI:
1125
1157
  return None
1126
1158
 
1127
1159
  # TIMELORD PROTOCOL
1128
- @api_request(peer_required=True)
1160
+ @metadata.request(peer_required=True)
1129
1161
  async def new_infusion_point_vdf(
1130
1162
  self, request: timelord_protocol.NewInfusionPointVDF, peer: WSChiaConnection
1131
1163
  ) -> Optional[Message]:
@@ -1135,7 +1167,7 @@ class FullNodeAPI:
1135
1167
  async with self.full_node.timelord_lock:
1136
1168
  return await self.full_node.new_infusion_point_vdf(request, peer)
1137
1169
 
1138
- @api_request(peer_required=True)
1170
+ @metadata.request(peer_required=True)
1139
1171
  async def new_signage_point_vdf(
1140
1172
  self, request: timelord_protocol.NewSignagePointVDF, peer: WSChiaConnection
1141
1173
  ) -> None:
@@ -1151,7 +1183,7 @@ class FullNodeAPI:
1151
1183
  )
1152
1184
  await self.respond_signage_point(full_node_message, peer)
1153
1185
 
1154
- @api_request(peer_required=True)
1186
+ @metadata.request(peer_required=True)
1155
1187
  async def new_end_of_sub_slot_vdf(
1156
1188
  self, request: timelord_protocol.NewEndOfSubSlotVDF, peer: WSChiaConnection
1157
1189
  ) -> Optional[Message]:
@@ -1175,7 +1207,7 @@ class FullNodeAPI:
1175
1207
  else:
1176
1208
  return msg
1177
1209
 
1178
- @api_request()
1210
+ @metadata.request()
1179
1211
  async def request_block_header(self, request: wallet_protocol.RequestBlockHeader) -> Optional[Message]:
1180
1212
  header_hash = self.full_node.blockchain.height_to_hash(request.height)
1181
1213
  if header_hash is None:
@@ -1185,8 +1217,7 @@ class FullNodeAPI:
1185
1217
  if block is None:
1186
1218
  return None
1187
1219
 
1188
- tx_removals: List[bytes32] = []
1189
- tx_additions: List[Coin] = []
1220
+ removals_and_additions: Optional[tuple[Collection[bytes32], Collection[Coin]]] = None
1190
1221
 
1191
1222
  if block.transactions_generator is not None:
1192
1223
  block_generator: Optional[BlockGenerator] = await get_block_generator(
@@ -1198,27 +1229,30 @@ class FullNodeAPI:
1198
1229
  # transactions_generator, so the block_generator should always be set
1199
1230
  assert block_generator is not None, "failed to get block_generator for tx-block"
1200
1231
 
1201
- npc_result = await asyncio.get_running_loop().run_in_executor(
1232
+ flags = get_flags_for_height_and_constants(request.height, self.full_node.constants)
1233
+ additions, removals = await asyncio.get_running_loop().run_in_executor(
1202
1234
  self.executor,
1203
- functools.partial(
1204
- get_name_puzzle_conditions,
1205
- block_generator,
1206
- self.full_node.constants.MAX_BLOCK_COST_CLVM,
1207
- mempool_mode=False,
1208
- height=request.height,
1209
- constants=self.full_node.constants,
1210
- ),
1235
+ additions_and_removals,
1236
+ bytes(block.transactions_generator),
1237
+ block_generator.generator_refs,
1238
+ flags,
1239
+ self.full_node.constants,
1211
1240
  )
1212
-
1213
- tx_removals, tx_additions = tx_removals_and_additions(npc_result.conds)
1214
- header_block = get_block_header(block, tx_additions, tx_removals)
1241
+ # strip the hint from additions, and compute the puzzle hash for
1242
+ # removals
1243
+ removals_and_additions = ([r.name() for r in removals], [a[0] for a in additions])
1244
+ elif block.is_transaction_block():
1245
+ # This is a transaction block with just reward coins.
1246
+ removals_and_additions = ([], [])
1247
+
1248
+ header_block = get_block_header(block, removals_and_additions)
1215
1249
  msg = make_msg(
1216
1250
  ProtocolMessageTypes.respond_block_header,
1217
1251
  wallet_protocol.RespondBlockHeader(header_block),
1218
1252
  )
1219
1253
  return msg
1220
1254
 
1221
- @api_request()
1255
+ @metadata.request()
1222
1256
  async def request_additions(self, request: wallet_protocol.RequestAdditions) -> Optional[Message]:
1223
1257
  if request.header_hash is None:
1224
1258
  header_hash: Optional[bytes32] = self.full_node.blockchain.height_to_hash(request.height)
@@ -1233,15 +1267,15 @@ class FullNodeAPI:
1233
1267
  if self.full_node.blockchain.height_to_hash(request.height) != header_hash:
1234
1268
  raise ValueError(f"Block {header_hash} no longer in chain, or invalid header_hash")
1235
1269
 
1236
- puzzlehash_coins_map: Dict[bytes32, List[Coin]] = {}
1270
+ puzzlehash_coins_map: dict[bytes32, list[Coin]] = {}
1237
1271
  for coin_record in additions:
1238
1272
  if coin_record.coin.puzzle_hash in puzzlehash_coins_map:
1239
1273
  puzzlehash_coins_map[coin_record.coin.puzzle_hash].append(coin_record.coin)
1240
1274
  else:
1241
1275
  puzzlehash_coins_map[coin_record.coin.puzzle_hash] = [coin_record.coin]
1242
1276
 
1243
- coins_map: List[Tuple[bytes32, List[Coin]]] = []
1244
- proofs_map: List[Tuple[bytes32, bytes, Optional[bytes]]] = []
1277
+ coins_map: list[tuple[bytes32, list[Coin]]] = []
1278
+ proofs_map: list[tuple[bytes32, bytes, Optional[bytes]]] = []
1245
1279
 
1246
1280
  if request.puzzle_hashes is None:
1247
1281
  for puzzle_hash, coins in puzzlehash_coins_map.items():
@@ -1250,7 +1284,7 @@ class FullNodeAPI:
1250
1284
  else:
1251
1285
  # Create addition Merkle set
1252
1286
  # Addition Merkle set contains puzzlehash and hash of all coins with that puzzlehash
1253
- leafs: List[bytes32] = []
1287
+ leafs: list[bytes32] = []
1254
1288
  for puzzle, coins in puzzlehash_coins_map.items():
1255
1289
  leafs.append(puzzle)
1256
1290
  leafs.append(hash_coin_ids([c.name() for c in coins]))
@@ -1275,7 +1309,7 @@ class FullNodeAPI:
1275
1309
  response = wallet_protocol.RespondAdditions(request.height, header_hash, coins_map, proofs_map)
1276
1310
  return make_msg(ProtocolMessageTypes.respond_additions, response)
1277
1311
 
1278
- @api_request()
1312
+ @metadata.request()
1279
1313
  async def request_removals(self, request: wallet_protocol.RequestRemovals) -> Optional[Message]:
1280
1314
  block: Optional[FullBlock] = await self.full_node.block_store.get_full_block(request.header_hash)
1281
1315
 
@@ -1295,21 +1329,21 @@ class FullNodeAPI:
1295
1329
  assert block is not None and block.foliage_transaction_block is not None
1296
1330
 
1297
1331
  # Note: this might return bad data if there is a reorg in this time
1298
- all_removals: List[CoinRecord] = await self.full_node.coin_store.get_coins_removed_at_height(block.height)
1332
+ all_removals: list[CoinRecord] = await self.full_node.coin_store.get_coins_removed_at_height(block.height)
1299
1333
 
1300
1334
  if self.full_node.blockchain.height_to_hash(block.height) != request.header_hash:
1301
1335
  raise ValueError(f"Block {block.header_hash} no longer in chain")
1302
1336
 
1303
- all_removals_dict: Dict[bytes32, Coin] = {}
1337
+ all_removals_dict: dict[bytes32, Coin] = {}
1304
1338
  for coin_record in all_removals:
1305
1339
  all_removals_dict[coin_record.coin.name()] = coin_record.coin
1306
1340
 
1307
- coins_map: List[Tuple[bytes32, Optional[Coin]]] = []
1308
- proofs_map: List[Tuple[bytes32, bytes]] = []
1341
+ coins_map: list[tuple[bytes32, Optional[Coin]]] = []
1342
+ proofs_map: list[tuple[bytes32, bytes]] = []
1309
1343
 
1310
1344
  # If there are no transactions, respond with empty lists
1311
1345
  if block.transactions_generator is None:
1312
- proofs: Optional[List[Tuple[bytes32, bytes]]]
1346
+ proofs: Optional[list[tuple[bytes32, bytes]]]
1313
1347
  if request.coin_names is None:
1314
1348
  proofs = None
1315
1349
  else:
@@ -1321,7 +1355,7 @@ class FullNodeAPI:
1321
1355
  response = wallet_protocol.RespondRemovals(block.height, block.header_hash, coins_map, None)
1322
1356
  else:
1323
1357
  assert block.transactions_generator
1324
- leafs: List[bytes32] = []
1358
+ leafs: list[bytes32] = []
1325
1359
  for removed_name, removed_coin in all_removals_dict.items():
1326
1360
  leafs.append(removed_name)
1327
1361
  removal_merkle_set = MerkleSet(leafs)
@@ -1341,7 +1375,7 @@ class FullNodeAPI:
1341
1375
  msg = make_msg(ProtocolMessageTypes.respond_removals, response)
1342
1376
  return msg
1343
1377
 
1344
- @api_request()
1378
+ @metadata.request()
1345
1379
  async def send_transaction(
1346
1380
  self, request: wallet_protocol.SendTransaction, *, test: bool = False
1347
1381
  ) -> Optional[Message]:
@@ -1372,7 +1406,7 @@ class FullNodeAPI:
1372
1406
  response = wallet_protocol.TransactionAck(spend_name, uint8(status.value), error_name)
1373
1407
  return make_msg(ProtocolMessageTypes.transaction_ack, response)
1374
1408
 
1375
- @api_request()
1409
+ @metadata.request()
1376
1410
  async def request_puzzle_solution(self, request: wallet_protocol.RequestPuzzleSolution) -> Optional[Message]:
1377
1411
  coin_name = request.coin_name
1378
1412
  height = request.height
@@ -1411,7 +1445,7 @@ class FullNodeAPI:
1411
1445
  response_msg = make_msg(ProtocolMessageTypes.respond_puzzle_solution, response)
1412
1446
  return response_msg
1413
1447
 
1414
- @api_request()
1448
+ @metadata.request()
1415
1449
  async def request_block_headers(self, request: wallet_protocol.RequestBlockHeaders) -> Optional[Message]:
1416
1450
  """Returns header blocks by directly streaming bytes into Message
1417
1451
 
@@ -1431,7 +1465,7 @@ class FullNodeAPI:
1431
1465
 
1432
1466
  else:
1433
1467
  height_to_hash = self.full_node.blockchain.height_to_hash
1434
- header_hashes: List[bytes32] = []
1468
+ header_hashes: list[bytes32] = []
1435
1469
  for i in range(request.start_height, request.end_height + 1):
1436
1470
  header_hash: Optional[bytes32] = height_to_hash(uint32(i))
1437
1471
  if header_hash is None:
@@ -1442,7 +1476,24 @@ class FullNodeAPI:
1442
1476
  if len(blocks_bytes) != (request.end_height - request.start_height + 1): # +1 because interval is inclusive
1443
1477
  return make_msg(ProtocolMessageTypes.reject_block_headers, reject)
1444
1478
  return_filter = request.return_filter
1445
- header_blocks_bytes: List[bytes] = [header_block_from_block(memoryview(b), return_filter) for b in blocks_bytes]
1479
+ header_blocks_bytes: list[bytes] = []
1480
+ for b in blocks_bytes:
1481
+ b_mem_view = memoryview(b)
1482
+ height, is_tx_block = get_height_and_tx_status_from_block(b_mem_view)
1483
+ if not is_tx_block:
1484
+ tx_addition_coins = []
1485
+ removal_names = []
1486
+ else:
1487
+ added_coins_records_coroutine = self.full_node.coin_store.get_coins_added_at_height(height)
1488
+ removed_coins_records_coroutine = self.full_node.coin_store.get_coins_removed_at_height(height)
1489
+ added_coins_records, removed_coins_records = await asyncio.gather(
1490
+ added_coins_records_coroutine, removed_coins_records_coroutine
1491
+ )
1492
+ tx_addition_coins = [record.coin for record in added_coins_records if not record.coinbase]
1493
+ removal_names = [record.coin.name() for record in removed_coins_records]
1494
+ header_blocks_bytes.append(
1495
+ header_block_from_block(b_mem_view, return_filter, tx_addition_coins, removal_names)
1496
+ )
1446
1497
 
1447
1498
  # we're building the RespondHeaderBlocks manually to avoid cost of
1448
1499
  # dynamic serialization
@@ -1458,7 +1509,7 @@ class FullNodeAPI:
1458
1509
  respond_header_blocks_manually_streamed += b"".join(header_blocks_bytes)
1459
1510
  return make_msg(ProtocolMessageTypes.respond_block_headers, respond_header_blocks_manually_streamed)
1460
1511
 
1461
- @api_request()
1512
+ @metadata.request()
1462
1513
  async def request_header_blocks(self, request: wallet_protocol.RequestHeaderBlocks) -> Optional[Message]:
1463
1514
  """DEPRECATED: please use RequestBlockHeaders"""
1464
1515
  if (
@@ -1467,7 +1518,7 @@ class FullNodeAPI:
1467
1518
  ):
1468
1519
  return None
1469
1520
  height_to_hash = self.full_node.blockchain.height_to_hash
1470
- header_hashes: List[bytes32] = []
1521
+ header_hashes: list[bytes32] = []
1471
1522
  for i in range(request.start_height, request.end_height + 1):
1472
1523
  header_hash: Optional[bytes32] = height_to_hash(uint32(i))
1473
1524
  if header_hash is None:
@@ -1476,7 +1527,7 @@ class FullNodeAPI:
1476
1527
  return msg
1477
1528
  header_hashes.append(header_hash)
1478
1529
 
1479
- blocks: List[FullBlock] = await self.full_node.block_store.get_blocks_by_hash(header_hashes)
1530
+ blocks: list[FullBlock] = await self.full_node.block_store.get_blocks_by_hash(header_hashes)
1480
1531
  header_blocks = []
1481
1532
  for block in blocks:
1482
1533
  added_coins_records_coroutine = self.full_node.coin_store.get_coins_added_at_height(block.height)
@@ -1486,7 +1537,7 @@ class FullNodeAPI:
1486
1537
  )
1487
1538
  added_coins = [record.coin for record in added_coins_records if not record.coinbase]
1488
1539
  removal_names = [record.coin.name() for record in removed_coins_records]
1489
- header_block = get_block_header(block, added_coins, removal_names)
1540
+ header_block = get_block_header(block, (removal_names, added_coins))
1490
1541
  header_blocks.append(header_block)
1491
1542
 
1492
1543
  msg = make_msg(
@@ -1495,7 +1546,7 @@ class FullNodeAPI:
1495
1546
  )
1496
1547
  return msg
1497
1548
 
1498
- @api_request(bytes_required=True, execute_task=True)
1549
+ @metadata.request(bytes_required=True, execute_task=True)
1499
1550
  async def respond_compact_proof_of_time(
1500
1551
  self, request: timelord_protocol.RespondCompactProofOfTime, request_bytes: bytes = b""
1501
1552
  ) -> None:
@@ -1521,7 +1572,7 @@ class FullNodeAPI:
1521
1572
 
1522
1573
  return None
1523
1574
 
1524
- @api_request(peer_required=True, bytes_required=True, execute_task=True)
1575
+ @metadata.request(peer_required=True, bytes_required=True, execute_task=True)
1525
1576
  async def new_compact_vdf(
1526
1577
  self, request: full_node_protocol.NewCompactVDF, peer: WSChiaConnection, request_bytes: bytes = b""
1527
1578
  ) -> None:
@@ -1548,22 +1599,22 @@ class FullNodeAPI:
1548
1599
 
1549
1600
  return None
1550
1601
 
1551
- @api_request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_compact_vdf])
1602
+ @metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_compact_vdf])
1552
1603
  async def request_compact_vdf(self, request: full_node_protocol.RequestCompactVDF, peer: WSChiaConnection) -> None:
1553
1604
  if self.full_node.sync_store.get_sync_mode():
1554
1605
  return None
1555
1606
  await self.full_node.request_compact_vdf(request, peer)
1556
1607
  return None
1557
1608
 
1558
- @api_request(peer_required=True)
1609
+ @metadata.request(peer_required=True)
1559
1610
  async def respond_compact_vdf(self, request: full_node_protocol.RespondCompactVDF, peer: WSChiaConnection) -> None:
1560
1611
  if self.full_node.sync_store.get_sync_mode():
1561
1612
  return None
1562
1613
  await self.full_node.add_compact_vdf(request, peer)
1563
1614
  return None
1564
1615
 
1565
- @api_request(peer_required=True)
1566
- async def register_interest_in_puzzle_hash(
1616
+ @metadata.request(peer_required=True)
1617
+ async def register_for_ph_updates(
1567
1618
  self, request: wallet_protocol.RegisterForPhUpdates, peer: WSChiaConnection
1568
1619
  ) -> Message:
1569
1620
  trusted = self.is_trusted(peer)
@@ -1585,16 +1636,16 @@ class FullNodeAPI:
1585
1636
  # before we send the response
1586
1637
 
1587
1638
  # Send all coins with requested puzzle hash that have been created after the specified height
1588
- states: Set[CoinState] = await self.full_node.coin_store.get_coin_states_by_puzzle_hashes(
1639
+ states: set[CoinState] = await self.full_node.coin_store.get_coin_states_by_puzzle_hashes(
1589
1640
  include_spent_coins=True, puzzle_hashes=puzzle_hashes, min_height=request.min_height, max_items=max_items
1590
1641
  )
1591
1642
  max_items -= len(states)
1592
1643
 
1593
1644
  hint_coin_ids = await self.full_node.hint_store.get_coin_ids_multi(
1594
- cast(Set[bytes], puzzle_hashes), max_items=max_items
1645
+ cast(set[bytes], puzzle_hashes), max_items=max_items
1595
1646
  )
1596
1647
 
1597
- hint_states: List[CoinState] = []
1648
+ hint_states: list[CoinState] = []
1598
1649
  if len(hint_coin_ids) > 0:
1599
1650
  hint_states = await self.full_node.coin_store.get_coin_states_by_ids(
1600
1651
  include_spent_coins=True,
@@ -1622,11 +1673,11 @@ class FullNodeAPI:
1622
1673
  )
1623
1674
 
1624
1675
  response = wallet_protocol.RespondToPhUpdates(request.puzzle_hashes, request.min_height, list(states))
1625
- msg = make_msg(ProtocolMessageTypes.respond_to_ph_update, response)
1676
+ msg = make_msg(ProtocolMessageTypes.respond_to_ph_updates, response)
1626
1677
  return msg
1627
1678
 
1628
- @api_request(peer_required=True)
1629
- async def register_interest_in_coin(
1679
+ @metadata.request(peer_required=True)
1680
+ async def register_for_coin_updates(
1630
1681
  self, request: wallet_protocol.RegisterForCoinUpdates, peer: WSChiaConnection
1631
1682
  ) -> Message:
1632
1683
  max_items = self.max_subscribe_response_items(peer)
@@ -1637,17 +1688,17 @@ class FullNodeAPI:
1637
1688
  # times, so we can't optimize away such DB lookups (yet)
1638
1689
  self.full_node.subscriptions.add_coin_subscriptions(peer.peer_node_id, request.coin_ids, max_subscriptions)
1639
1690
 
1640
- states: List[CoinState] = await self.full_node.coin_store.get_coin_states_by_ids(
1691
+ states: list[CoinState] = await self.full_node.coin_store.get_coin_states_by_ids(
1641
1692
  include_spent_coins=True, coin_ids=set(request.coin_ids), min_height=request.min_height, max_items=max_items
1642
1693
  )
1643
1694
 
1644
1695
  response = wallet_protocol.RespondToCoinUpdates(request.coin_ids, request.min_height, states)
1645
- msg = make_msg(ProtocolMessageTypes.respond_to_coin_update, response)
1696
+ msg = make_msg(ProtocolMessageTypes.respond_to_coin_updates, response)
1646
1697
  return msg
1647
1698
 
1648
- @api_request()
1699
+ @metadata.request()
1649
1700
  async def request_children(self, request: wallet_protocol.RequestChildren) -> Optional[Message]:
1650
- coin_records: List[CoinRecord] = await self.full_node.coin_store.get_coin_records_by_parent_ids(
1701
+ coin_records: list[CoinRecord] = await self.full_node.coin_store.get_coin_records_by_parent_ids(
1651
1702
  True, [request.coin_name]
1652
1703
  )
1653
1704
  states = [record.coin_state for record in coin_records]
@@ -1655,7 +1706,7 @@ class FullNodeAPI:
1655
1706
  msg = make_msg(ProtocolMessageTypes.respond_children, response)
1656
1707
  return msg
1657
1708
 
1658
- @api_request()
1709
+ @metadata.request()
1659
1710
  async def request_ses_hashes(self, request: wallet_protocol.RequestSESInfo) -> Message:
1660
1711
  """Returns the start and end height of a sub-epoch for the height specified in request"""
1661
1712
 
@@ -1691,9 +1742,9 @@ class FullNodeAPI:
1691
1742
  msg = make_msg(ProtocolMessageTypes.respond_ses_hashes, response)
1692
1743
  return msg
1693
1744
 
1694
- @api_request(reply_types=[ProtocolMessageTypes.respond_fee_estimates])
1745
+ @metadata.request(reply_types=[ProtocolMessageTypes.respond_fee_estimates])
1695
1746
  async def request_fee_estimates(self, request: wallet_protocol.RequestFeeEstimates) -> Message:
1696
- def get_fee_estimates(est: FeeEstimatorInterface, req_times: List[uint64]) -> List[FeeEstimate]:
1747
+ def get_fee_estimates(est: FeeEstimatorInterface, req_times: list[uint64]) -> list[FeeEstimate]:
1697
1748
  now = datetime.now(timezone.utc)
1698
1749
  utc_time = now.replace(tzinfo=timezone.utc)
1699
1750
  utc_now = int(utc_time.timestamp())
@@ -1702,14 +1753,14 @@ class FullNodeAPI:
1702
1753
  v1_fee_rates = [fee_rate_v2_to_v1(est) for est in fee_rates]
1703
1754
  return [FeeEstimate(None, req_ts, fee_rate) for req_ts, fee_rate in zip(req_times, v1_fee_rates)]
1704
1755
 
1705
- fee_estimates: List[FeeEstimate] = get_fee_estimates(
1756
+ fee_estimates: list[FeeEstimate] = get_fee_estimates(
1706
1757
  self.full_node.mempool_manager.mempool.fee_estimator, request.time_targets
1707
1758
  )
1708
1759
  response = RespondFeeEstimates(FeeEstimateGroup(error=None, estimates=fee_estimates))
1709
1760
  msg = make_msg(ProtocolMessageTypes.respond_fee_estimates, response)
1710
1761
  return msg
1711
1762
 
1712
- @api_request(
1763
+ @metadata.request(
1713
1764
  peer_required=True,
1714
1765
  reply_types=[ProtocolMessageTypes.respond_remove_puzzle_subscriptions],
1715
1766
  )
@@ -1729,7 +1780,7 @@ class FullNodeAPI:
1729
1780
  msg = make_msg(ProtocolMessageTypes.respond_remove_puzzle_subscriptions, response)
1730
1781
  return msg
1731
1782
 
1732
- @api_request(
1783
+ @metadata.request(
1733
1784
  peer_required=True,
1734
1785
  reply_types=[ProtocolMessageTypes.respond_remove_coin_subscriptions],
1735
1786
  )
@@ -1749,7 +1800,7 @@ class FullNodeAPI:
1749
1800
  msg = make_msg(ProtocolMessageTypes.respond_remove_coin_subscriptions, response)
1750
1801
  return msg
1751
1802
 
1752
- @api_request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_puzzle_state])
1803
+ @metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_puzzle_state])
1753
1804
  async def request_puzzle_state(
1754
1805
  self, request: wallet_protocol.RequestPuzzleState, peer: WSChiaConnection
1755
1806
  ) -> Message:
@@ -1828,7 +1879,7 @@ class FullNodeAPI:
1828
1879
  msg = make_msg(ProtocolMessageTypes.respond_puzzle_state, response)
1829
1880
  return msg
1830
1881
 
1831
- @api_request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_coin_state])
1882
+ @metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_coin_state])
1832
1883
  async def request_coin_state(self, request: wallet_protocol.RequestCoinState, peer: WSChiaConnection) -> Message:
1833
1884
  max_items = self.max_subscribe_response_items(peer)
1834
1885
  max_subscriptions = self.max_subscriptions(peer)
@@ -1886,7 +1937,7 @@ class FullNodeAPI:
1886
1937
  msg = make_msg(ProtocolMessageTypes.respond_coin_state, response)
1887
1938
  return msg
1888
1939
 
1889
- @api_request(reply_types=[ProtocolMessageTypes.respond_cost_info])
1940
+ @metadata.request(reply_types=[ProtocolMessageTypes.respond_cost_info])
1890
1941
  async def request_cost_info(self, _request: wallet_protocol.RequestCostInfo) -> Optional[Message]:
1891
1942
  mempool_manager = self.full_node.mempool_manager
1892
1943
  response = wallet_protocol.RespondCostInfo(
@@ -1901,7 +1952,7 @@ class FullNodeAPI:
1901
1952
  return msg
1902
1953
 
1903
1954
  async def mempool_updates_for_puzzle_hashes(
1904
- self, peer: WSChiaConnection, puzzle_hashes: Set[bytes32], include_hints: bool
1955
+ self, peer: WSChiaConnection, puzzle_hashes: set[bytes32], include_hints: bool
1905
1956
  ) -> None:
1906
1957
  if Capability.MEMPOOL_UPDATES not in peer.peer_capabilities:
1907
1958
  return
@@ -1913,10 +1964,10 @@ class FullNodeAPI:
1913
1964
  self.full_node.mempool_manager.mempool.items_with_puzzle_hashes(puzzle_hashes, include_hints)
1914
1965
  )
1915
1966
 
1916
- hinted_coin_ids: Set[bytes32] = set()
1967
+ hinted_coin_ids: set[bytes32] = set()
1917
1968
 
1918
1969
  for batch in to_batches(puzzle_hashes, SQLITE_MAX_VARIABLE_NUMBER):
1919
- hints_db: Tuple[bytes, ...] = tuple(batch.entries)
1970
+ hints_db: tuple[bytes, ...] = tuple(batch.entries)
1920
1971
  cursor = await conn.execute(
1921
1972
  f"SELECT coin_id from hints INDEXED BY hint_index "
1922
1973
  f'WHERE hint IN ({"?," * (len(batch.entries) - 1)}?)',
@@ -1939,7 +1990,7 @@ class FullNodeAPI:
1939
1990
  f"Sending initial mempool items to peer {peer.peer_node_id} took {total_time:.4f}s",
1940
1991
  )
1941
1992
 
1942
- async def mempool_updates_for_coin_ids(self, peer: WSChiaConnection, coin_ids: Set[bytes32]) -> None:
1993
+ async def mempool_updates_for_coin_ids(self, peer: WSChiaConnection, coin_ids: set[bytes32]) -> None:
1943
1994
  if Capability.MEMPOOL_UPDATES not in peer.peer_capabilities:
1944
1995
  return
1945
1996