chia-blockchain 2.5.7rc4__py3-none-any.whl → 2.6.0rc2__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 (531) 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_blockchain_transactions.py +5 -2
  6. chia/_tests/blockchain/test_build_chains.py +2 -4
  7. chia/_tests/blockchain/test_get_block_generator.py +2 -3
  8. chia/_tests/clvm/coin_store.py +4 -7
  9. chia/_tests/clvm/test_clvm_step.py +4 -4
  10. chia/_tests/clvm/test_puzzle_compression.py +2 -1
  11. chia/_tests/clvm/test_puzzle_drivers.py +2 -2
  12. chia/_tests/clvm/test_singletons.py +2 -4
  13. chia/_tests/clvm/test_spend_sim.py +2 -2
  14. chia/_tests/cmds/cmd_test_utils.py +27 -45
  15. chia/_tests/cmds/test_cmd_framework.py +6 -6
  16. chia/_tests/cmds/test_daemon.py +3 -3
  17. chia/_tests/cmds/test_show.py +4 -4
  18. chia/_tests/cmds/test_tx_config_args.py +1 -2
  19. chia/_tests/cmds/testing_classes.py +4 -5
  20. chia/_tests/cmds/wallet/test_did.py +24 -27
  21. chia/_tests/cmds/wallet/test_nft.py +12 -10
  22. chia/_tests/cmds/wallet/test_vcs.py +11 -12
  23. chia/_tests/cmds/wallet/test_wallet.py +134 -89
  24. chia/_tests/conftest.py +66 -31
  25. chia/_tests/connection_utils.py +2 -2
  26. chia/_tests/core/cmds/test_beta.py +4 -4
  27. chia/_tests/core/cmds/test_keys.py +2 -3
  28. chia/_tests/core/cmds/test_wallet.py +15 -15
  29. chia/_tests/core/consensus/test_pot_iterations.py +19 -73
  30. chia/_tests/core/custom_types/test_proof_of_space.py +124 -98
  31. chia/_tests/core/daemon/test_daemon.py +11 -11
  32. chia/_tests/core/data_layer/conftest.py +2 -2
  33. chia/_tests/core/data_layer/test_data_rpc.py +28 -14
  34. chia/_tests/core/data_layer/test_data_store.py +10 -10
  35. chia/_tests/core/data_layer/util.py +11 -11
  36. chia/_tests/core/farmer/test_farmer_api.py +2 -4
  37. chia/_tests/core/full_node/full_sync/test_full_sync.py +8 -7
  38. chia/_tests/core/full_node/stores/test_block_store.py +5 -4
  39. chia/_tests/core/full_node/stores/test_coin_store.py +5 -11
  40. chia/_tests/core/full_node/stores/test_full_node_store.py +8 -8
  41. chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
  42. chia/_tests/core/full_node/test_block_height_map.py +3 -4
  43. chia/_tests/core/full_node/test_conditions.py +21 -23
  44. chia/_tests/core/full_node/test_full_node.py +273 -70
  45. chia/_tests/core/full_node/test_hard_fork_utils.py +92 -0
  46. chia/_tests/core/full_node/test_hint_management.py +2 -4
  47. chia/_tests/core/full_node/test_performance.py +0 -1
  48. chia/_tests/core/full_node/test_prev_tx_block.py +88 -11
  49. chia/_tests/core/full_node/test_transactions.py +1 -2
  50. chia/_tests/core/full_node/test_tx_processing_queue.py +198 -30
  51. chia/_tests/core/mempool/test_mempool.py +54 -50
  52. chia/_tests/core/mempool/test_mempool_fee_estimator.py +39 -39
  53. chia/_tests/core/mempool/test_mempool_fee_protocol.py +2 -6
  54. chia/_tests/core/mempool/test_mempool_manager.py +988 -854
  55. chia/_tests/core/mempool/test_singleton_fast_forward.py +6 -6
  56. chia/_tests/core/server/serve.py +7 -7
  57. chia/_tests/core/server/test_dos.py +1 -2
  58. chia/_tests/core/server/test_event_loop.py +12 -4
  59. chia/_tests/core/server/test_loop.py +7 -8
  60. chia/_tests/core/server/test_rate_limits.py +9 -8
  61. chia/_tests/core/server/test_server.py +61 -1
  62. chia/_tests/core/services/test_services.py +2 -2
  63. chia/_tests/core/ssl/test_ssl.py +2 -2
  64. chia/_tests/core/test_cost_calculation.py +2 -6
  65. chia/_tests/core/test_farmer_harvester_rpc.py +3 -5
  66. chia/_tests/core/test_filter.py +0 -1
  67. chia/_tests/core/test_full_node_rpc.py +2 -2
  68. chia/_tests/core/test_merkle_set.py +1 -2
  69. chia/_tests/core/test_seeder.py +4 -4
  70. chia/_tests/core/util/test_config.py +4 -4
  71. chia/_tests/core/util/test_jsonify.py +2 -2
  72. chia/_tests/core/util/test_keychain.py +3 -3
  73. chia/_tests/core/util/test_lockfile.py +2 -1
  74. chia/_tests/core/util/test_log_exceptions.py +1 -2
  75. chia/_tests/core/util/test_streamable.py +17 -17
  76. chia/_tests/db/test_db_wrapper.py +3 -2
  77. chia/_tests/environments/wallet.py +14 -14
  78. chia/_tests/ether.py +4 -3
  79. chia/_tests/farmer_harvester/test_farmer.py +41 -24
  80. chia/_tests/farmer_harvester/test_farmer_harvester.py +50 -17
  81. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +27 -27
  82. chia/_tests/farmer_harvester/test_third_party_harvesters.py +21 -22
  83. chia/_tests/fee_estimation/test_fee_estimation_integration.py +18 -18
  84. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +11 -9
  85. chia/_tests/harvester/test_harvester_api.py +11 -4
  86. chia/_tests/plot_sync/test_plot_sync.py +13 -11
  87. chia/_tests/plot_sync/test_receiver.py +11 -10
  88. chia/_tests/plot_sync/test_sync_simulated.py +2 -2
  89. chia/_tests/plot_sync/util.py +1 -2
  90. chia/_tests/plotting/test_plot_manager.py +7 -6
  91. chia/_tests/plotting/test_prover.py +30 -38
  92. chia/_tests/pools/test_pool_cmdline.py +4 -6
  93. chia/_tests/pools/test_pool_rpc.py +203 -61
  94. chia/_tests/pools/test_pool_wallet.py +3 -3
  95. chia/_tests/pools/test_wallet_pool_store.py +1 -4
  96. chia/_tests/process_junit.py +2 -2
  97. chia/_tests/rpc/test_rpc_client.py +4 -4
  98. chia/_tests/rpc/test_rpc_server.py +3 -3
  99. chia/_tests/simulation/test_simulation.py +12 -25
  100. chia/_tests/solver/test_solver_service.py +13 -4
  101. chia/_tests/testconfig.py +2 -2
  102. chia/_tests/timelord/test_new_peak.py +22 -11
  103. chia/_tests/tools/test_run_block.py +0 -2
  104. chia/_tests/tools/test_virtual_project.py +2 -1
  105. chia/_tests/util/benchmarks.py +1 -0
  106. chia/_tests/util/blockchain.py +38 -36
  107. chia/_tests/util/blockchain_mock.py +11 -11
  108. chia/_tests/util/build_network_protocol_files.py +2 -1
  109. chia/_tests/util/coin_store.py +2 -1
  110. chia/_tests/util/config.py +1 -1
  111. chia/_tests/util/db_connection.py +2 -3
  112. chia/_tests/util/full_sync.py +9 -11
  113. chia/_tests/util/gen_ssl_certs.py +4 -5
  114. chia/_tests/util/get_name_puzzle_conditions.py +2 -0
  115. chia/_tests/util/misc.py +24 -24
  116. chia/_tests/util/network_protocol_data.py +20 -3
  117. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  118. chia/_tests/util/protocol_messages_json.py +292 -3
  119. chia/_tests/util/setup_nodes.py +62 -47
  120. chia/_tests/util/spend_sim.py +57 -57
  121. chia/_tests/util/test_async_pool.py +2 -3
  122. chia/_tests/util/test_chia_version.py +1 -3
  123. chia/_tests/util/test_config.py +3 -3
  124. chia/_tests/util/test_full_block_utils.py +6 -3
  125. chia/_tests/util/test_limited_semaphore.py +1 -2
  126. chia/_tests/util/test_misc.py +2 -2
  127. chia/_tests/util/test_network.py +1 -2
  128. chia/_tests/util/test_priority_mutex.py +3 -3
  129. chia/_tests/util/test_recursive_replace.py +5 -6
  130. chia/_tests/util/test_replace_str_to_bytes.py +9 -10
  131. chia/_tests/util/test_testnet_overrides.py +3 -3
  132. chia/_tests/util/time_out_assert.py +2 -2
  133. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +4 -6
  134. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -4
  135. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +19 -13
  136. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +13 -13
  137. chia/_tests/wallet/cat_wallet/test_trades.py +40 -38
  138. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -4
  139. chia/_tests/wallet/conftest.py +6 -6
  140. chia/_tests/wallet/db_wallet/test_db_graftroot.py +1 -1
  141. chia/_tests/wallet/db_wallet/test_dl_offers.py +34 -34
  142. chia/_tests/wallet/did_wallet/test_did.py +16 -6
  143. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +21 -21
  144. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +20 -6
  145. chia/_tests/wallet/nft_wallet/test_nft_offers.py +19 -21
  146. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +1 -2
  147. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +121 -2
  148. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +6 -9
  149. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +44 -1
  150. chia/_tests/wallet/rpc/test_wallet_rpc.py +1672 -896
  151. chia/_tests/wallet/sync/test_wallet_sync.py +63 -60
  152. chia/_tests/wallet/test_clvm_streamable.py +2 -3
  153. chia/_tests/wallet/test_coin_management.py +2 -2
  154. chia/_tests/wallet/test_conditions.py +45 -51
  155. chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
  156. chia/_tests/wallet/test_new_wallet_protocol.py +17 -17
  157. chia/_tests/wallet/test_notifications.py +14 -14
  158. chia/_tests/wallet/test_signer_protocol.py +5 -5
  159. chia/_tests/wallet/test_singleton_lifecycle_fast.py +4 -3
  160. chia/_tests/wallet/test_transaction_store.py +20 -20
  161. chia/_tests/wallet/test_util.py +2 -2
  162. chia/_tests/wallet/test_wallet.py +380 -228
  163. chia/_tests/wallet/test_wallet_action_scope.py +4 -4
  164. chia/_tests/wallet/test_wallet_blockchain.py +12 -12
  165. chia/_tests/wallet/test_wallet_coin_store.py +3 -4
  166. chia/_tests/wallet/test_wallet_node.py +16 -15
  167. chia/_tests/wallet/test_wallet_test_framework.py +2 -1
  168. chia/_tests/wallet/test_wallet_utils.py +2 -3
  169. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -5
  170. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +14 -15
  171. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -24
  172. chia/_tests/wallet/wallet_block_tools.py +12 -11
  173. chia/_tests/weight_proof/config.py +1 -0
  174. chia/_tests/weight_proof/test_weight_proof.py +5 -4
  175. chia/apis/__init__.py +21 -0
  176. chia/apis/farmer_stub.py +102 -0
  177. chia/apis/full_node_stub.py +374 -0
  178. chia/apis/harvester_stub.py +57 -0
  179. chia/apis/introducer_stub.py +35 -0
  180. chia/apis/solver_stub.py +30 -0
  181. chia/apis/stub_protocol_registry.py +21 -0
  182. chia/apis/timelord_stub.py +39 -0
  183. chia/apis/wallet_stub.py +161 -0
  184. chia/cmds/beta.py +3 -4
  185. chia/cmds/beta_funcs.py +4 -3
  186. chia/cmds/check_wallet_db.py +4 -4
  187. chia/cmds/chia.py +1 -2
  188. chia/cmds/cmd_classes.py +11 -13
  189. chia/cmds/cmd_helpers.py +11 -11
  190. chia/cmds/cmds_util.py +15 -15
  191. chia/cmds/coin_funcs.py +6 -7
  192. chia/cmds/coins.py +2 -3
  193. chia/cmds/configure.py +1 -2
  194. chia/cmds/data.py +42 -42
  195. chia/cmds/data_funcs.py +81 -81
  196. chia/cmds/db.py +4 -5
  197. chia/cmds/db_backup_func.py +2 -2
  198. chia/cmds/db_upgrade_func.py +3 -3
  199. chia/cmds/db_validate_func.py +2 -2
  200. chia/cmds/dev/data.py +4 -4
  201. chia/cmds/dev/gh.py +5 -5
  202. chia/cmds/dev/installers.py +2 -3
  203. chia/cmds/dev/mempool.py +3 -4
  204. chia/cmds/dev/mempool_funcs.py +4 -4
  205. chia/cmds/dev/sim.py +8 -8
  206. chia/cmds/dump_keyring.py +3 -3
  207. chia/cmds/farm.py +6 -8
  208. chia/cmds/farm_funcs.py +25 -24
  209. chia/cmds/init_funcs.py +4 -4
  210. chia/cmds/keys.py +16 -18
  211. chia/cmds/keys_funcs.py +36 -36
  212. chia/cmds/netspace.py +1 -3
  213. chia/cmds/netspace_funcs.py +1 -2
  214. chia/cmds/options.py +3 -2
  215. chia/cmds/param_types.py +17 -16
  216. chia/cmds/passphrase.py +6 -7
  217. chia/cmds/passphrase_funcs.py +11 -13
  218. chia/cmds/peer.py +1 -3
  219. chia/cmds/peer_funcs.py +3 -3
  220. chia/cmds/plotnft.py +6 -7
  221. chia/cmds/plotnft_funcs.py +37 -26
  222. chia/cmds/rpc.py +3 -3
  223. chia/cmds/show.py +3 -5
  224. chia/cmds/show_funcs.py +9 -9
  225. chia/cmds/sim_funcs.py +25 -26
  226. chia/cmds/solver.py +1 -3
  227. chia/cmds/solver_funcs.py +1 -2
  228. chia/cmds/start_funcs.py +2 -2
  229. chia/cmds/wallet.py +76 -81
  230. chia/cmds/wallet_funcs.py +206 -177
  231. chia/consensus/augmented_chain.py +6 -6
  232. chia/consensus/block_body_validation.py +19 -15
  233. chia/consensus/block_creation.py +25 -21
  234. chia/consensus/block_header_validation.py +27 -13
  235. chia/consensus/block_height_map.py +3 -6
  236. chia/consensus/block_height_map_protocol.py +2 -2
  237. chia/consensus/block_record.py +2 -4
  238. chia/consensus/blockchain.py +58 -40
  239. chia/consensus/blockchain_interface.py +7 -7
  240. chia/consensus/coin_store_protocol.py +5 -6
  241. chia/consensus/condition_tools.py +4 -4
  242. chia/consensus/cost_calculator.py +2 -3
  243. chia/consensus/default_constants.py +19 -13
  244. chia/consensus/deficit.py +1 -3
  245. chia/consensus/difficulty_adjustment.py +3 -5
  246. chia/consensus/find_fork_point.py +2 -4
  247. chia/consensus/full_block_to_block_record.py +11 -13
  248. chia/consensus/generator_tools.py +2 -3
  249. chia/consensus/get_block_challenge.py +50 -26
  250. chia/consensus/get_block_generator.py +2 -3
  251. chia/consensus/make_sub_epoch_summary.py +8 -7
  252. chia/consensus/multiprocess_validation.py +31 -20
  253. chia/consensus/pos_quality.py +6 -23
  254. chia/consensus/pot_iterations.py +17 -44
  255. chia/consensus/signage_point.py +4 -5
  256. chia/consensus/vdf_info_computation.py +2 -4
  257. chia/daemon/client.py +8 -8
  258. chia/daemon/keychain_proxy.py +31 -37
  259. chia/daemon/server.py +32 -33
  260. chia/daemon/windows_signal.py +4 -3
  261. chia/data_layer/data_layer.py +86 -77
  262. chia/data_layer/data_layer_rpc_api.py +9 -9
  263. chia/data_layer/data_layer_rpc_client.py +13 -15
  264. chia/data_layer/data_layer_server.py +3 -3
  265. chia/data_layer/data_layer_util.py +14 -14
  266. chia/data_layer/data_layer_wallet.py +94 -101
  267. chia/data_layer/data_store.py +50 -50
  268. chia/data_layer/dl_wallet_store.py +9 -12
  269. chia/data_layer/download_data.py +8 -9
  270. chia/data_layer/s3_plugin_service.py +5 -9
  271. chia/data_layer/start_data_layer.py +5 -5
  272. chia/farmer/farmer.py +31 -31
  273. chia/farmer/farmer_api.py +45 -33
  274. chia/farmer/farmer_rpc_api.py +5 -4
  275. chia/farmer/farmer_rpc_client.py +6 -6
  276. chia/farmer/start_farmer.py +6 -6
  277. chia/full_node/block_store.py +13 -16
  278. chia/full_node/check_fork_next_block.py +1 -2
  279. chia/full_node/coin_store.py +15 -16
  280. chia/full_node/eligible_coin_spends.py +3 -3
  281. chia/full_node/fee_estimate_store.py +2 -3
  282. chia/full_node/fee_tracker.py +1 -2
  283. chia/full_node/full_block_utils.py +4 -4
  284. chia/full_node/full_node.py +239 -223
  285. chia/full_node/full_node_api.py +197 -152
  286. chia/full_node/full_node_rpc_api.py +34 -32
  287. chia/full_node/full_node_rpc_client.py +18 -19
  288. chia/full_node/full_node_store.py +45 -43
  289. chia/full_node/hard_fork_utils.py +44 -0
  290. chia/full_node/hint_management.py +2 -2
  291. chia/full_node/mempool.py +17 -19
  292. chia/full_node/mempool_manager.py +89 -42
  293. chia/full_node/pending_tx_cache.py +2 -3
  294. chia/full_node/start_full_node.py +5 -5
  295. chia/full_node/sync_store.py +3 -4
  296. chia/full_node/tx_processing_queue.py +120 -36
  297. chia/full_node/weight_proof.py +61 -48
  298. chia/harvester/harvester.py +25 -24
  299. chia/harvester/harvester_api.py +61 -38
  300. chia/harvester/harvester_rpc_api.py +10 -10
  301. chia/harvester/start_harvester.py +4 -4
  302. chia/introducer/introducer.py +3 -3
  303. chia/introducer/introducer_api.py +6 -4
  304. chia/introducer/start_introducer.py +4 -4
  305. chia/legacy/keyring.py +3 -3
  306. chia/plot_sync/delta.py +1 -2
  307. chia/plot_sync/receiver.py +20 -17
  308. chia/plot_sync/sender.py +15 -10
  309. chia/plotters/bladebit.py +7 -7
  310. chia/plotters/chiapos.py +2 -2
  311. chia/plotters/madmax.py +4 -4
  312. chia/plotters/plotters.py +4 -4
  313. chia/plotters/plotters_util.py +3 -3
  314. chia/plotting/cache.py +20 -14
  315. chia/plotting/check_plots.py +26 -35
  316. chia/plotting/create_plots.py +22 -23
  317. chia/plotting/manager.py +21 -14
  318. chia/plotting/prover.py +59 -42
  319. chia/plotting/util.py +16 -16
  320. chia/pools/pool_config.py +2 -1
  321. chia/pools/pool_puzzles.py +11 -12
  322. chia/pools/pool_wallet.py +34 -57
  323. chia/pools/pool_wallet_info.py +39 -10
  324. chia/protocols/farmer_protocol.py +8 -9
  325. chia/protocols/fee_estimate.py +3 -4
  326. chia/protocols/full_node_protocol.py +3 -4
  327. chia/protocols/harvester_protocol.py +27 -15
  328. chia/protocols/outbound_message.py +3 -3
  329. chia/protocols/pool_protocol.py +8 -9
  330. chia/protocols/shared_protocol.py +1 -2
  331. chia/protocols/solver_protocol.py +9 -2
  332. chia/protocols/timelord_protocol.py +4 -7
  333. chia/protocols/wallet_protocol.py +11 -12
  334. chia/rpc/rpc_client.py +9 -9
  335. chia/rpc/rpc_server.py +17 -17
  336. chia/rpc/util.py +2 -2
  337. chia/seeder/crawler.py +8 -8
  338. chia/seeder/crawler_api.py +21 -27
  339. chia/seeder/crawler_rpc_api.py +2 -2
  340. chia/seeder/dns_server.py +21 -21
  341. chia/seeder/start_crawler.py +4 -4
  342. chia/server/address_manager.py +15 -16
  343. chia/server/api_protocol.py +11 -11
  344. chia/server/chia_policy.py +46 -26
  345. chia/server/introducer_peers.py +2 -3
  346. chia/server/node_discovery.py +19 -19
  347. chia/server/rate_limit_numbers.py +4 -5
  348. chia/server/rate_limits.py +4 -4
  349. chia/server/resolve_peer_info.py +4 -4
  350. chia/server/server.py +49 -52
  351. chia/server/signal_handlers.py +6 -6
  352. chia/server/start_service.py +17 -17
  353. chia/server/upnp.py +4 -6
  354. chia/server/ws_connection.py +52 -37
  355. chia/simulator/add_blocks_in_batches.py +1 -3
  356. chia/simulator/block_tools.py +312 -200
  357. chia/simulator/full_node_simulator.py +56 -35
  358. chia/simulator/keyring.py +2 -3
  359. chia/simulator/setup_services.py +15 -15
  360. chia/simulator/simulator_full_node_rpc_api.py +1 -2
  361. chia/simulator/simulator_full_node_rpc_client.py +1 -2
  362. chia/simulator/simulator_protocol.py +1 -2
  363. chia/simulator/simulator_test_tools.py +3 -3
  364. chia/simulator/start_simulator.py +7 -7
  365. chia/simulator/wallet_tools.py +10 -10
  366. chia/solver/solver.py +10 -10
  367. chia/solver/solver_api.py +10 -8
  368. chia/solver/solver_rpc_api.py +2 -2
  369. chia/solver/start_solver.py +4 -4
  370. chia/ssl/cacert.pem +148 -90
  371. chia/ssl/chia_ca.crt +14 -10
  372. chia/ssl/chia_ca_old.crt +19 -0
  373. chia/ssl/create_ssl.py +4 -4
  374. chia/ssl/renewedselfsignedca.conf +4 -0
  375. chia/ssl/ssl_check.py +1 -2
  376. chia/timelord/iters_from_block.py +1 -4
  377. chia/timelord/start_timelord.py +4 -4
  378. chia/timelord/timelord.py +44 -40
  379. chia/timelord/timelord_api.py +6 -4
  380. chia/timelord/timelord_launcher.py +2 -2
  381. chia/timelord/timelord_rpc_api.py +2 -2
  382. chia/timelord/timelord_state.py +11 -12
  383. chia/types/block_protocol.py +1 -3
  384. chia/types/blockchain_format/coin.py +1 -3
  385. chia/types/blockchain_format/program.py +11 -8
  386. chia/types/blockchain_format/proof_of_space.py +123 -76
  387. chia/types/blockchain_format/tree_hash.py +3 -3
  388. chia/types/blockchain_format/vdf.py +1 -2
  389. chia/types/coin_spend.py +3 -3
  390. chia/types/mempool_item.py +5 -5
  391. chia/types/mempool_submission_status.py +2 -3
  392. chia/types/peer_info.py +1 -2
  393. chia/types/unfinished_header_block.py +3 -4
  394. chia/types/validation_state.py +1 -2
  395. chia/util/action_scope.py +8 -8
  396. chia/util/async_pool.py +5 -5
  397. chia/util/bech32m.py +1 -2
  398. chia/util/beta_metrics.py +2 -2
  399. chia/util/block_cache.py +4 -4
  400. chia/util/chia_logging.py +2 -2
  401. chia/util/chia_version.py +1 -2
  402. chia/util/config.py +15 -16
  403. chia/util/db_wrapper.py +26 -27
  404. chia/util/default_root.py +1 -2
  405. chia/util/errors.py +3 -3
  406. chia/util/file_keyring.py +14 -14
  407. chia/util/files.py +2 -3
  408. chia/util/hash.py +4 -4
  409. chia/util/initial-config.yaml +4 -5
  410. chia/util/inline_executor.py +2 -1
  411. chia/util/ip_address.py +1 -2
  412. chia/util/keychain.py +25 -27
  413. chia/util/keyring_wrapper.py +18 -19
  414. chia/util/lock.py +3 -4
  415. chia/util/log_exceptions.py +1 -2
  416. chia/util/lru_cache.py +2 -2
  417. chia/util/network.py +6 -6
  418. chia/util/path.py +2 -3
  419. chia/util/priority_mutex.py +2 -2
  420. chia/util/profiler.py +1 -2
  421. chia/util/safe_cancel_task.py +1 -2
  422. chia/util/streamable.py +24 -10
  423. chia/util/task_referencer.py +1 -1
  424. chia/util/timing.py +3 -3
  425. chia/util/virtual_project_analysis.py +6 -5
  426. chia/util/ws_message.py +2 -2
  427. chia/wallet/cat_wallet/cat_info.py +3 -4
  428. chia/wallet/cat_wallet/cat_outer_puzzle.py +12 -11
  429. chia/wallet/cat_wallet/cat_utils.py +3 -4
  430. chia/wallet/cat_wallet/cat_wallet.py +61 -83
  431. chia/wallet/cat_wallet/lineage_store.py +3 -4
  432. chia/wallet/cat_wallet/r_cat_wallet.py +19 -22
  433. chia/wallet/coin_selection.py +9 -10
  434. chia/wallet/conditions.py +142 -106
  435. chia/wallet/db_wallet/db_wallet_puzzles.py +4 -5
  436. chia/wallet/derivation_record.py +1 -2
  437. chia/wallet/derive_keys.py +2 -4
  438. chia/wallet/did_wallet/did_info.py +10 -11
  439. chia/wallet/did_wallet/did_wallet.py +36 -82
  440. chia/wallet/did_wallet/did_wallet_puzzles.py +7 -8
  441. chia/wallet/driver_protocol.py +5 -7
  442. chia/wallet/lineage_proof.py +4 -4
  443. chia/wallet/nft_wallet/metadata_outer_puzzle.py +11 -11
  444. chia/wallet/nft_wallet/nft_info.py +8 -9
  445. chia/wallet/nft_wallet/nft_puzzle_utils.py +8 -8
  446. chia/wallet/nft_wallet/nft_wallet.py +79 -116
  447. chia/wallet/nft_wallet/ownership_outer_puzzle.py +14 -14
  448. chia/wallet/nft_wallet/singleton_outer_puzzle.py +12 -11
  449. chia/wallet/nft_wallet/transfer_program_puzzle.py +11 -11
  450. chia/wallet/nft_wallet/uncurry_nft.py +10 -11
  451. chia/wallet/notification_manager.py +3 -3
  452. chia/wallet/notification_store.py +44 -61
  453. chia/wallet/outer_puzzles.py +6 -7
  454. chia/wallet/puzzle_drivers.py +34 -6
  455. chia/wallet/puzzles/clawback/drivers.py +6 -6
  456. chia/wallet/puzzles/deployed_puzzle_hashes.json +1 -54
  457. chia/wallet/puzzles/load_clvm.py +1 -1
  458. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -2
  459. chia/wallet/puzzles/singleton_top_layer.py +2 -3
  460. chia/wallet/puzzles/singleton_top_layer_v1_1.py +3 -4
  461. chia/wallet/puzzles/tails.py +3 -3
  462. chia/wallet/singleton.py +5 -7
  463. chia/wallet/singleton_record.py +3 -3
  464. chia/wallet/start_wallet.py +5 -5
  465. chia/wallet/trade_manager.py +37 -58
  466. chia/wallet/trade_record.py +4 -4
  467. chia/wallet/trading/offer.py +59 -46
  468. chia/wallet/trading/trade_store.py +8 -9
  469. chia/wallet/transaction_record.py +8 -8
  470. chia/wallet/uncurried_puzzle.py +1 -2
  471. chia/wallet/util/clvm_streamable.py +12 -12
  472. chia/wallet/util/compute_hints.py +4 -5
  473. chia/wallet/util/curry_and_treehash.py +1 -2
  474. chia/wallet/util/merkle_tree.py +2 -3
  475. chia/wallet/util/peer_request_cache.py +8 -8
  476. chia/wallet/util/signing.py +85 -0
  477. chia/wallet/util/tx_config.py +15 -6
  478. chia/wallet/util/wallet_sync_utils.py +14 -16
  479. chia/wallet/util/wallet_types.py +2 -2
  480. chia/wallet/vc_wallet/cr_cat_drivers.py +10 -11
  481. chia/wallet/vc_wallet/cr_cat_wallet.py +50 -68
  482. chia/wallet/vc_wallet/cr_outer_puzzle.py +14 -13
  483. chia/wallet/vc_wallet/vc_drivers.py +27 -27
  484. chia/wallet/vc_wallet/vc_store.py +5 -6
  485. chia/wallet/vc_wallet/vc_wallet.py +33 -61
  486. chia/wallet/wallet.py +50 -78
  487. chia/wallet/wallet_action_scope.py +11 -11
  488. chia/wallet/wallet_blockchain.py +12 -12
  489. chia/wallet/wallet_coin_record.py +12 -6
  490. chia/wallet/wallet_coin_store.py +24 -25
  491. chia/wallet/wallet_interested_store.py +3 -5
  492. chia/wallet/wallet_nft_store.py +10 -11
  493. chia/wallet/wallet_node.py +53 -61
  494. chia/wallet/wallet_node_api.py +5 -3
  495. chia/wallet/wallet_protocol.py +23 -23
  496. chia/wallet/wallet_puzzle_store.py +15 -18
  497. chia/wallet/wallet_request_types.py +778 -114
  498. chia/wallet/wallet_retry_store.py +1 -3
  499. chia/wallet/wallet_rpc_api.py +572 -909
  500. chia/wallet/wallet_rpc_client.py +87 -279
  501. chia/wallet/wallet_singleton_store.py +3 -4
  502. chia/wallet/wallet_state_manager.py +332 -106
  503. chia/wallet/wallet_transaction_store.py +11 -14
  504. chia/wallet/wallet_user_store.py +4 -6
  505. chia/wallet/wallet_weight_proof_handler.py +4 -4
  506. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/METADATA +6 -5
  507. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/RECORD +510 -517
  508. chia/apis.py +0 -21
  509. chia/consensus/check_time_locks.py +0 -57
  510. chia/data_layer/puzzles/__init__.py +0 -0
  511. chia/data_layer/puzzles/graftroot_dl_offers.clsp +0 -100
  512. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +0 -1
  513. chia/types/coin_record.py +0 -44
  514. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  515. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +0 -6
  516. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +0 -1
  517. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +0 -6
  518. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +0 -1
  519. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +0 -30
  520. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +0 -1
  521. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +0 -28
  522. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +0 -1
  523. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +0 -100
  524. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +0 -1
  525. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +0 -78
  526. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +0 -1
  527. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +0 -74
  528. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +0 -1
  529. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/WHEEL +0 -0
  530. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/entry_points.txt +0 -0
  531. {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,92 @@
1
+ from __future__ import annotations
2
+
3
+ import pytest
4
+ from chia_rs import BlockRecord, get_flags_for_height_and_constants
5
+ from chia_rs.sized_bytes import bytes32
6
+ from chia_rs.sized_ints import uint32
7
+
8
+ from chia.consensus.get_block_challenge import pre_sp_tx_block_height
9
+ from chia.full_node.hard_fork_utils import get_flags
10
+ from chia.simulator.block_tools import BlockTools, load_block_list, test_constants
11
+ from chia.util.block_cache import BlockCache
12
+
13
+
14
+ class MockBlocksProtocol(BlockCache):
15
+ """Mock implementation of BlocksProtocol for testing get_flags."""
16
+
17
+ async def get_block_record_from_db(self, header_hash: bytes32) -> BlockRecord | None:
18
+ return self.try_block_record(header_hash)
19
+
20
+ async def lookup_block_generators(self, header_hash: bytes32, generator_refs: set[uint32]) -> dict[uint32, bytes]:
21
+ return {}
22
+
23
+ def add_block_record(self, block_record: BlockRecord) -> None:
24
+ self.add_block(block_record)
25
+
26
+
27
+ @pytest.mark.anyio
28
+ async def test_get_flags_outside_transition_period(bt: BlockTools) -> None:
29
+ """Test get_flags when block is outside the transition period."""
30
+ block_list = bt.get_consecutive_blocks(
31
+ 10,
32
+ block_list_input=[],
33
+ guarantee_transaction_block=True,
34
+ )
35
+ _, _, blocks = load_block_list(block_list, bt.constants)
36
+ block = block_list[-1]
37
+ mock_blocks = MockBlocksProtocol(blocks)
38
+
39
+ # Before hard fork: block.height < HARD_FORK2_HEIGHT, expects 0
40
+ constants = test_constants.replace(HARD_FORK2_HEIGHT=uint32(1000))
41
+ assert block.height < constants.HARD_FORK2_HEIGHT
42
+ result = await get_flags(constants, mock_blocks, block)
43
+ assert result == 0
44
+
45
+ # After transition period: block.height >= HARD_FORK2_HEIGHT + SUB_EPOCH_BLOCKS
46
+ constants = test_constants.replace(
47
+ HARD_FORK2_HEIGHT=uint32(0),
48
+ SUB_EPOCH_BLOCKS=uint32(min(5, block.height)),
49
+ )
50
+ assert block.height >= constants.HARD_FORK2_HEIGHT + constants.SUB_EPOCH_BLOCKS
51
+ result = await get_flags(constants, mock_blocks, block)
52
+ assert result == get_flags_for_height_and_constants(block.height, constants)
53
+
54
+
55
+ @pytest.mark.anyio
56
+ async def test_get_flags_during_transition_period(bt: BlockTools) -> None:
57
+ """When block.height is in the transition period, get_flags should walk
58
+ the chain and return flags based on the latest tx block before signage point."""
59
+ # We need more blocks to ensure we're in the transition period
60
+ block_list = bt.get_consecutive_blocks(
61
+ 15,
62
+ block_list_input=[],
63
+ guarantee_transaction_block=True,
64
+ )
65
+ _, _, blocks = load_block_list(block_list, bt.constants)
66
+ mock_blocks = MockBlocksProtocol(blocks)
67
+
68
+ # Configure constants so that the block is in the transition period
69
+ # HARD_FORK2_HEIGHT <= block.height < HARD_FORK2_HEIGHT + SUB_EPOCH_BLOCKS
70
+ block = block_list[-1]
71
+ # Set HARD_FORK2_HEIGHT to be close to block height but leave room for transition
72
+ constants = test_constants.replace(
73
+ HARD_FORK2_HEIGHT=uint32(max(0, block.height - 5)),
74
+ SUB_EPOCH_BLOCKS=test_constants.SUB_EPOCH_BLOCKS,
75
+ )
76
+
77
+ # Ensure we're in the transition period
78
+ assert block.height >= constants.HARD_FORK2_HEIGHT
79
+ assert block.height < constants.HARD_FORK2_HEIGHT + constants.SUB_EPOCH_BLOCKS
80
+
81
+ result = await get_flags(constants, mock_blocks, block)
82
+
83
+ # The result should be based on the height of the latest tx block before the signage point
84
+ expected_height = pre_sp_tx_block_height(
85
+ constants=constants,
86
+ blocks=mock_blocks,
87
+ prev_b_hash=block.prev_header_hash,
88
+ sp_index=block.reward_chain_block.signage_point_index,
89
+ finished_sub_slots=len(block.finished_sub_slots),
90
+ )
91
+ expected = get_flags_for_height_and_constants(expected_height, constants)
92
+ assert result == expected
@@ -1,7 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Optional
4
-
5
3
  import pytest
6
4
  from chia_rs import BlockRecord
7
5
  from chia_rs.sized_bytes import bytes32
@@ -38,7 +36,7 @@ async def test_hints_to_add(bt: BlockTools, empty_blockchain: Blockchain) -> Non
38
36
  blocks = bt.get_consecutive_blocks(2)
39
37
  await _validate_and_add_block(empty_blockchain, blocks[0])
40
38
  await _validate_and_add_block(empty_blockchain, blocks[1])
41
- br: Optional[BlockRecord] = empty_blockchain.get_peak()
39
+ br: BlockRecord | None = empty_blockchain.get_peak()
42
40
  assert br is not None
43
41
 
44
42
  scs = StateChangeSummary(br, uint32(0), [], removals, additions, [])
@@ -56,7 +54,7 @@ async def test_lookup_coin_ids(bt: BlockTools, empty_blockchain: Blockchain) ->
56
54
  blocks = bt.get_consecutive_blocks(2)
57
55
  await _validate_and_add_block(empty_blockchain, blocks[0])
58
56
  await _validate_and_add_block(empty_blockchain, blocks[1])
59
- br: Optional[BlockRecord] = empty_blockchain.get_peak()
57
+ br: BlockRecord | None = empty_blockchain.get_peak()
60
58
  assert br is not None
61
59
 
62
60
  rewards: list[Coin] = [
@@ -36,7 +36,6 @@ class TestPerformance:
36
36
  block_list_input=blocks,
37
37
  guarantee_transaction_block=True,
38
38
  farmer_reward_puzzle_hash=wallet_ph,
39
- pool_reward_puzzle_hash=wallet_ph,
40
39
  )
41
40
  for block in blocks:
42
41
  await full_node_1.full_node.add_block(block)
@@ -1,16 +1,29 @@
1
1
  from __future__ import annotations
2
2
 
3
- from chia_rs.sized_ints import uint32
3
+ from chia_rs import FullBlock
4
+ from chia_rs.sized_ints import uint8, uint32
4
5
 
5
- from chia.consensus.generator_tools import get_block_header
6
- from chia.consensus.get_block_challenge import prev_tx_block
7
- from chia.simulator.block_tools import BlockTools, load_block_list
6
+ from chia.consensus.get_block_challenge import pre_sp_tx_block_height
7
+ from chia.simulator.block_tools import BlockTools, load_block_list, test_constants
8
8
  from chia.util.block_cache import BlockCache
9
9
 
10
10
 
11
11
  def test_prev_tx_block_none() -> None:
12
12
  # If prev_b is None, should return 0
13
- assert prev_tx_block(BlockCache({}), None) == uint32(0)
13
+ assert pre_sp_tx_block_height(
14
+ constants=test_constants,
15
+ blocks=BlockCache({}),
16
+ prev_b_hash=test_constants.GENESIS_CHALLENGE,
17
+ sp_index=uint8(0),
18
+ finished_sub_slots=0,
19
+ ) == uint32(0)
20
+ assert pre_sp_tx_block_height(
21
+ constants=test_constants,
22
+ blocks=BlockCache({}),
23
+ prev_b_hash=test_constants.GENESIS_CHALLENGE,
24
+ sp_index=uint8(1),
25
+ finished_sub_slots=1,
26
+ ) == uint32(0)
14
27
 
15
28
 
16
29
  def test_prev_tx_block_blockrecord_tx(bt: BlockTools) -> None:
@@ -21,9 +34,45 @@ def test_prev_tx_block_blockrecord_tx(bt: BlockTools) -> None:
21
34
  guarantee_transaction_block=True,
22
35
  )
23
36
  _, _, blocks = load_block_list(block_list, bt.constants)
24
- assert prev_tx_block(BlockCache(blocks), block_list[-1]) == uint32(9)
25
- assert prev_tx_block(BlockCache(blocks), blocks[block_list[-1].header_hash]) == uint32(9)
26
- assert prev_tx_block(BlockCache(blocks), get_block_header(block_list[-1])) == uint32(9)
37
+ block = block_list[-1]
38
+ latest_tx_before_sp = find_tx_before_sp(block_list)
39
+ assert latest_tx_before_sp is not None
40
+ assert (
41
+ pre_sp_tx_block_height(
42
+ constants=test_constants,
43
+ blocks=BlockCache(blocks),
44
+ prev_b_hash=block.prev_header_hash,
45
+ sp_index=block.reward_chain_block.signage_point_index,
46
+ finished_sub_slots=len(block.finished_sub_slots),
47
+ )
48
+ == latest_tx_before_sp.height
49
+ )
50
+ block = block_list[-2]
51
+ latest_tx_before_sp = find_tx_before_sp(block_list[:-1])
52
+ assert latest_tx_before_sp is not None
53
+ assert (
54
+ pre_sp_tx_block_height(
55
+ constants=test_constants,
56
+ blocks=BlockCache(blocks),
57
+ prev_b_hash=block.prev_header_hash,
58
+ sp_index=block.reward_chain_block.signage_point_index,
59
+ finished_sub_slots=len(block.finished_sub_slots),
60
+ )
61
+ == latest_tx_before_sp.height
62
+ )
63
+ block = block_list[-3]
64
+ latest_tx_before_sp = find_tx_before_sp(block_list[:-2])
65
+ assert latest_tx_before_sp is not None
66
+ assert (
67
+ pre_sp_tx_block_height(
68
+ constants=test_constants,
69
+ blocks=BlockCache(blocks),
70
+ prev_b_hash=block.prev_header_hash,
71
+ sp_index=block.reward_chain_block.signage_point_index,
72
+ finished_sub_slots=len(block.finished_sub_slots),
73
+ )
74
+ == latest_tx_before_sp.height
75
+ )
27
76
 
28
77
 
29
78
  def test_prev_tx_block_blockrecord_not_tx(bt: BlockTools) -> None:
@@ -38,6 +87,34 @@ def test_prev_tx_block_blockrecord_not_tx(bt: BlockTools) -> None:
38
87
  block_list_input=block_list,
39
88
  )
40
89
  _, _, blocks = load_block_list(block_list, bt.constants)
41
- assert prev_tx_block(BlockCache(blocks), block_list[-1]) == uint32(7)
42
- assert prev_tx_block(BlockCache(blocks), blocks[block_list[-1].header_hash]) == uint32(7)
43
- assert prev_tx_block(BlockCache(blocks), get_block_header(block_list[-1])) == uint32(7)
90
+ block = block_list[-1]
91
+ latest_tx_before_sp = find_tx_before_sp(block_list)
92
+ assert latest_tx_before_sp is not None
93
+ assert pre_sp_tx_block_height(
94
+ constants=test_constants,
95
+ blocks=BlockCache(blocks),
96
+ prev_b_hash=block.prev_header_hash,
97
+ sp_index=block.reward_chain_block.signage_point_index,
98
+ finished_sub_slots=len(block.finished_sub_slots),
99
+ ) == uint32(latest_tx_before_sp.height)
100
+
101
+
102
+ # get the latest infused transaction block before the signage point of the last block in the list
103
+ def find_tx_before_sp(block_list: list[FullBlock]) -> FullBlock | None:
104
+ before_slot = False
105
+ before_sp = False
106
+ if len(block_list[-1].finished_sub_slots) > 0:
107
+ before_slot = True
108
+ sp_index = block_list[-1].reward_chain_block.signage_point_index
109
+ idx = len(block_list) - 2
110
+ curr = None
111
+ while idx > 0:
112
+ curr = block_list[idx]
113
+ if curr.reward_chain_block.signage_point_index < sp_index:
114
+ before_sp = True
115
+ if curr.foliage_transaction_block is not None and (before_slot or before_sp):
116
+ break
117
+ if len(curr.finished_sub_slots) > 0:
118
+ before_slot = True
119
+ idx -= 1
120
+ return curr
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import random
5
- from typing import Optional
6
5
 
7
6
  import pytest
8
7
  from chia_rs import BlockRecord
@@ -77,7 +76,7 @@ async def test_tx_propagation(three_nodes_two_wallets, self_hostname, seeded_ran
77
76
  await time_out_assert(20, wallet_0.wallet_state_manager.main_wallet.get_confirmed_balance, funds)
78
77
 
79
78
  async def peak_height(fna: FullNodeAPI):
80
- peak: Optional[BlockRecord] = fna.full_node.blockchain.get_peak()
79
+ peak: BlockRecord | None = fna.full_node.blockchain.get_peak()
81
80
  if peak is None:
82
81
  return -1
83
82
  peak_height = peak.height
@@ -2,35 +2,46 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import logging
5
+ import math
5
6
  import random
6
- from dataclasses import dataclass
7
- from typing import Optional, cast
7
+ from dataclasses import dataclass, field
8
+ from typing import cast
8
9
 
9
10
  import pytest
11
+ from chia_rs import G2Element, SpendBundle
10
12
  from chia_rs.sized_bytes import bytes32
13
+ from chia_rs.sized_ints import uint64
11
14
 
12
- from chia.full_node.tx_processing_queue import TransactionQueue, TransactionQueueEntry, TransactionQueueFull
15
+ from chia.full_node.tx_processing_queue import PeerWithTx, TransactionQueue, TransactionQueueEntry, TransactionQueueFull
16
+ from chia.simulator.block_tools import test_constants
13
17
  from chia.util.task_referencer import create_referenced_task
14
18
 
15
19
  log = logging.getLogger(__name__)
16
20
 
21
+ TEST_MAX_TX_CLVM_COST = uint64(test_constants.MAX_BLOCK_COST_CLVM // 2)
22
+
17
23
 
18
24
  @dataclass(frozen=True)
19
25
  class FakeTransactionQueueEntry:
20
- index: int
21
- peer_id: Optional[bytes32]
26
+ index: int = field(compare=False)
27
+ peer_id: bytes32 | None = field(compare=False)
28
+ peers_with_tx: dict[bytes32, PeerWithTx] | None = field(compare=False)
22
29
 
23
30
 
24
- def get_transaction_queue_entry(peer_id: Optional[bytes32], tx_index: int) -> TransactionQueueEntry: # easy shortcut
25
- return cast(TransactionQueueEntry, FakeTransactionQueueEntry(index=tx_index, peer_id=peer_id))
31
+ def get_transaction_queue_entry(
32
+ peer_id: bytes32 | None, tx_index: int, peers_with_tx: dict[bytes32, PeerWithTx] | None = None
33
+ ) -> TransactionQueueEntry: # easy shortcut
34
+ if peers_with_tx is None:
35
+ peers_with_tx = {}
36
+ return cast(TransactionQueueEntry, FakeTransactionQueueEntry(tx_index, peer_id, peers_with_tx))
26
37
 
27
38
 
28
39
  @pytest.mark.anyio
29
40
  async def test_local_txs(seeded_random: random.Random) -> None:
30
- transaction_queue = TransactionQueue(1000, log)
41
+ transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
31
42
  # test 1 tx
32
43
  first_tx = get_transaction_queue_entry(None, 0)
33
- await transaction_queue.put(first_tx, None)
44
+ transaction_queue.put(first_tx, None)
34
45
 
35
46
  result1 = await transaction_queue.pop()
36
47
 
@@ -40,7 +51,7 @@ async def test_local_txs(seeded_random: random.Random) -> None:
40
51
  num_txs = 2000
41
52
  list_txs = [get_transaction_queue_entry(bytes32.random(seeded_random), i) for i in range(num_txs)]
42
53
  for tx in list_txs:
43
- await transaction_queue.put(tx, None)
54
+ transaction_queue.put(tx, None)
44
55
 
45
56
  resulting_txs = []
46
57
  for _ in range(num_txs):
@@ -52,18 +63,18 @@ async def test_local_txs(seeded_random: random.Random) -> None:
52
63
 
53
64
  @pytest.mark.anyio
54
65
  async def test_one_peer_and_await(seeded_random: random.Random) -> None:
55
- transaction_queue = TransactionQueue(1000, log)
66
+ transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
56
67
  num_txs = 100
57
68
  peer_id = bytes32.random(seeded_random)
58
69
 
59
70
  list_txs = [get_transaction_queue_entry(peer_id, i) for i in range(num_txs)]
60
71
  for tx in list_txs:
61
- await transaction_queue.put(tx, peer_id)
72
+ transaction_queue.put(tx, peer_id)
62
73
 
63
74
  # test transaction priority
64
75
  local_txs = [get_transaction_queue_entry(None, i) for i in range(int(num_txs / 5))] # 20 txs
65
76
  for tx in local_txs:
66
- await transaction_queue.put(tx, None)
77
+ transaction_queue.put(tx, None)
67
78
 
68
79
  resulting_txs = []
69
80
  for _ in range(num_txs + len(local_txs)):
@@ -80,13 +91,13 @@ async def test_one_peer_and_await(seeded_random: random.Random) -> None:
80
91
  with pytest.raises(asyncio.InvalidStateError): # task is not done, so we expect an error when getting result
81
92
  task.result()
82
93
  # add a tx to test task completion
83
- await transaction_queue.put(get_transaction_queue_entry(None, 0), None)
94
+ transaction_queue.put(get_transaction_queue_entry(None, 0), None)
84
95
  await asyncio.wait_for(task, 1) # we should never time out here
85
96
 
86
97
 
87
98
  @pytest.mark.anyio
88
99
  async def test_lots_of_peers(seeded_random: random.Random) -> None:
89
- transaction_queue = TransactionQueue(1000, log)
100
+ transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
90
101
  num_peers = 1000
91
102
  num_txs = 100
92
103
  total_txs = num_txs * num_peers
@@ -95,7 +106,7 @@ async def test_lots_of_peers(seeded_random: random.Random) -> None:
95
106
  # 100 txs per peer
96
107
  list_txs = [get_transaction_queue_entry(peer_id, i) for peer_id in peer_ids for i in range(num_txs)]
97
108
  for tx in list_txs:
98
- await transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
109
+ transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
99
110
 
100
111
  resulting_txs = []
101
112
  for _ in range(total_txs):
@@ -108,7 +119,7 @@ async def test_lots_of_peers(seeded_random: random.Random) -> None:
108
119
 
109
120
  @pytest.mark.anyio
110
121
  async def test_full_queue(seeded_random: random.Random) -> None:
111
- transaction_queue = TransactionQueue(1000, log)
122
+ transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
112
123
  num_peers = 100
113
124
  num_txs = 1000
114
125
  total_txs = num_txs * num_peers
@@ -117,11 +128,11 @@ async def test_full_queue(seeded_random: random.Random) -> None:
117
128
  # 999 txs per peer then 1 to fail later
118
129
  list_txs = [get_transaction_queue_entry(peer_id, i) for peer_id in peer_ids for i in range(num_txs)]
119
130
  for tx in list_txs:
120
- await transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
131
+ transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
121
132
 
122
133
  # test failure case.
123
134
  with pytest.raises(TransactionQueueFull):
124
- await transaction_queue.put(get_transaction_queue_entry(peer_ids[0], 1001), peer_ids[0])
135
+ transaction_queue.put(get_transaction_queue_entry(peer_ids[0], 1001), peer_ids[0])
125
136
 
126
137
  resulting_txs = []
127
138
  for _ in range(total_txs):
@@ -130,25 +141,182 @@ async def test_full_queue(seeded_random: random.Random) -> None:
130
141
 
131
142
  @pytest.mark.anyio
132
143
  async def test_queue_cleanup_and_fairness(seeded_random: random.Random) -> None:
133
- transaction_queue = TransactionQueue(1000, log)
144
+ transaction_queue = TransactionQueue(1000, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
134
145
  peer_a = bytes32.random(seeded_random)
135
146
  peer_b = bytes32.random(seeded_random)
136
147
  peer_c = bytes32.random(seeded_random)
137
148
 
149
+ higher_tx_cost = uint64(20)
150
+ lower_tx_cost = uint64(10)
151
+ higher_tx_fee = uint64(5)
152
+ lower_tx_fee = uint64(1)
138
153
  # 2 for a, 1 for b, 2 for c
139
- peer_tx_a = [get_transaction_queue_entry(peer_a, i) for i in range(2)]
140
- peer_tx_b = [get_transaction_queue_entry(peer_b, 0)]
141
- peer_tx_c = [get_transaction_queue_entry(peer_c, i) for i in range(2)]
154
+ peer_tx_a = [
155
+ get_transaction_queue_entry(peer_a, 0, {peer_a: PeerWithTx(str(peer_a), lower_tx_fee, higher_tx_cost)}),
156
+ get_transaction_queue_entry(peer_a, 1, {peer_a: PeerWithTx(str(peer_a), higher_tx_fee, lower_tx_cost)}),
157
+ ]
158
+ peer_tx_b = [
159
+ get_transaction_queue_entry(peer_b, 0, {peer_b: PeerWithTx(str(peer_b), higher_tx_fee, lower_tx_cost)})
160
+ ]
161
+ peer_tx_c = [
162
+ get_transaction_queue_entry(peer_c, 0, {peer_c: PeerWithTx(str(peer_c), higher_tx_fee, lower_tx_cost)}),
163
+ get_transaction_queue_entry(peer_c, 1, {peer_c: PeerWithTx(str(peer_c), lower_tx_fee, higher_tx_cost)}),
164
+ ]
142
165
 
143
166
  list_txs = peer_tx_a + peer_tx_b + peer_tx_c
144
167
  for tx in list_txs:
145
- await transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
168
+ transaction_queue.put(tx, tx.peer_id) # type: ignore[attr-defined]
146
169
 
147
- resulting_ids = []
170
+ entries = []
148
171
  for _ in range(3): # we validate we get one transaction per peer
149
- resulting_ids.append((await transaction_queue.pop()).peer_id) # type: ignore[attr-defined]
150
- assert [peer_a, peer_b, peer_c] == resulting_ids # all peers have been properly included in the queue.
151
- second_resulting_ids = []
172
+ entry = await transaction_queue.pop()
173
+ entries.append((entry.peer_id, entry.index)) # type: ignore[attr-defined]
174
+ assert [(peer_a, 1), (peer_b, 0), (peer_c, 0)] == entries # all peers have been properly included in the queue.
175
+ second_entries = []
152
176
  for _ in range(2): # we validate that we properly queue the last 2 transactions
153
- second_resulting_ids.append((await transaction_queue.pop()).peer_id) # type: ignore[attr-defined]
154
- assert [peer_a, peer_c] == second_resulting_ids
177
+ entry = await transaction_queue.pop()
178
+ second_entries.append((entry.peer_id, entry.index)) # type: ignore[attr-defined]
179
+ assert [(peer_a, 0), (peer_c, 1)] == second_entries
180
+
181
+
182
+ def test_tx_queue_entry_order_compare() -> None:
183
+ """
184
+ Tests that `TransactionQueueEntry` orders and compares using transaction
185
+ IDs regardless of other fields.
186
+ """
187
+ # Let's create two items with the same transaction ID but different data
188
+ sb = SpendBundle([], G2Element())
189
+ sb_name = sb.name()
190
+ item1 = TransactionQueueEntry(
191
+ transaction=sb, transaction_bytes=bytes(sb), spend_name=sb_name, peer=None, test=False, peers_with_tx={}
192
+ )
193
+ item2 = TransactionQueueEntry(
194
+ transaction=sb, transaction_bytes=None, spend_name=sb_name, peer=None, test=True, peers_with_tx={}
195
+ )
196
+ # They should be ordered and compared (considered equal) by `spend_name`
197
+ # regardless of other fields.
198
+ assert (item1 < item2) is False
199
+ assert item1 == item2
200
+
201
+
202
+ @pytest.mark.anyio
203
+ async def test_peer_queue_prioritization_fallback() -> None:
204
+ """
205
+ Tests prioritization fallback, when `peer_id` is not in `peers_with_tx`.
206
+ """
207
+ queue = TransactionQueue(42, log, max_tx_clvm_cost=TEST_MAX_TX_CLVM_COST)
208
+ peer1 = bytes32.random()
209
+ peer2 = bytes32.random()
210
+ # We'll be using this peer to test the fallback, so we don't include it in
211
+ # peers with transactions maps.
212
+ peer3 = bytes32.random()
213
+ peers_with_tx1 = {
214
+ # This has FPC of 5.0
215
+ peer1: PeerWithTx(str(peer1), uint64(10), uint64(2)),
216
+ # This has FPC of 2.0 but higher advertised cost
217
+ peer2: PeerWithTx(str(peer2), uint64(20), uint64(10)),
218
+ }
219
+ tx1 = get_transaction_queue_entry(peer3, 0, peers_with_tx1)
220
+ queue.put(tx1, peer3)
221
+ peers_with_tx2 = {
222
+ # This has FPC of 3.0
223
+ peer1: PeerWithTx(str(peer1), uint64(30), uint64(10)),
224
+ # This has FPC of 4.0 but lower advertised cost
225
+ peer2: PeerWithTx(str(peer2), uint64(20), uint64(5)),
226
+ # This has FPC of 1.0 but lower advertised cost
227
+ peer3: PeerWithTx(str(peer3), uint64(4), uint64(4)),
228
+ }
229
+ tx2 = get_transaction_queue_entry(peer3, 1, peers_with_tx2)
230
+ queue.put(tx2, peer3)
231
+ # tx2 gets top priority with FPC 1.0
232
+ assert math.isclose(queue._peers_transactions_queues[peer3].priority_queue.queue[0][0], -1.0)
233
+ entry = await queue.pop()
234
+ # NOTE: This whole test file uses `index` as an addition to
235
+ # `TransactionQueueEntry` for easier testing, hence this type ignore here
236
+ # and everywhere else.
237
+ assert entry.index == 1 # type: ignore[attr-defined]
238
+ # tx1 comes next due to lowest priority fallback
239
+ assert math.isinf(queue._peers_transactions_queues[peer3].priority_queue.queue[0][0])
240
+ entry = await queue.pop()
241
+ assert entry.index == 0 # type: ignore[attr-defined]
242
+
243
+
244
+ @pytest.mark.anyio
245
+ async def test_normal_queue_deficit_round_robin() -> None:
246
+ """
247
+ Covers the deficit round robin behavior of the normal transaction queue where
248
+ we cycle through peers and pick their top transactions when their deficit
249
+ counters allow them to afford it, and we ensure that their deficit counters
250
+ adapt accordingly.
251
+ This also covers the case where a peer's top transaction does not advertise
252
+ cost, so that falls back to `max_tx_clvm_cost`.
253
+ This also covers the cleanup behavior where peers with no remaining
254
+ transactions are removed periodically (each 100 pop) from the queue.
255
+ """
256
+ test_max_tx_clvm_cost = uint64(20)
257
+ queue = TransactionQueue(42, log, max_tx_clvm_cost=test_max_tx_clvm_cost)
258
+ peer1 = bytes32.random()
259
+ peer2 = bytes32.random()
260
+ peer3 = bytes32.random()
261
+ peer4 = bytes32.random()
262
+ test_fee = uint64(42)
263
+ # We give this one the highest cost
264
+ tx1 = get_transaction_queue_entry(peer1, 0, {peer1: PeerWithTx(str(peer1), test_fee, uint64(15))})
265
+ queue.put(tx1, peer1)
266
+ # And this one the lowest cost
267
+ tx2 = get_transaction_queue_entry(peer2, 1, {peer2: PeerWithTx(str(peer2), test_fee, uint64(5))})
268
+ queue.put(tx2, peer2)
269
+ # And this one a cost in between
270
+ tx3 = get_transaction_queue_entry(peer3, 2, {peer3: PeerWithTx(str(peer3), test_fee, uint64(10))})
271
+ queue.put(tx3, peer3)
272
+ # This one has no cost information so its top transaction's advertised cost
273
+ # falls back to `test_max_tx_clvm_cost`.
274
+ tx4 = get_transaction_queue_entry(peer4, 3, {})
275
+ queue.put(tx4, peer4)
276
+ # When we try to pop a transaction, none of the peers initially can
277
+ # afford to send their top transactions, so we add the lowest cost among
278
+ # transactions (5) to all the peers' deficit counters and try again. This
279
+ # makes peer2 able to send its transaction tx2.
280
+ entry = await queue.pop()
281
+ assert entry.index == 1 # type: ignore[attr-defined]
282
+ assert queue._list_cursor == 2
283
+ assert queue._peers_transactions_queues[peer1].deficit == 5
284
+ assert queue._peers_transactions_queues[peer2].deficit == 0
285
+ assert queue._peers_transactions_queues[peer3].deficit == 5
286
+ assert queue._peers_transactions_queues[peer4].deficit == 5
287
+ # Now peer3, peer4 and peer1 can't afford to send their top transactions so
288
+ # we add the lowest cost among transactions (10) to their deficit counters
289
+ # and try again. This makes peer3 able to send its transaction tx3.
290
+ entry = await queue.pop()
291
+ assert entry.index == 2 # type: ignore[attr-defined]
292
+ assert queue._list_cursor == 3
293
+ assert queue._peers_transactions_queues[peer1].deficit == 15
294
+ assert queue._peers_transactions_queues[peer2].deficit == 0
295
+ assert queue._peers_transactions_queues[peer3].deficit == 0
296
+ assert queue._peers_transactions_queues[peer4].deficit == 15
297
+ # Let's force cleanup to happen on the next pop
298
+ queue._cleanup_counter = 99
299
+ # Now peer4 can't afford to send its top transaction (20) but peer1 can
300
+ # send tx1 (15) so it does.
301
+ entry = await queue.pop()
302
+ assert entry.index == 0 # type: ignore[attr-defined]
303
+ # This pop triggers cleanup, so peer1, peer2 and peer3 are removed from
304
+ # the transaction queue (they have nothing left) and only peer4 remains.
305
+ for peer in [peer1, peer2, peer3]:
306
+ assert peer not in queue._index_to_peer_map
307
+ assert peer not in queue._peers_transactions_queues
308
+ assert len(queue._index_to_peer_map) == 1
309
+ assert peer4 in queue._index_to_peer_map
310
+ assert queue._list_cursor == 0
311
+ # At this point we didn't have to increment deficit counters because peer1
312
+ # could already afford to send its top transaction, so peer4's deficit
313
+ # counter stays the same.
314
+ assert queue._peers_transactions_queues[peer4].deficit == 15
315
+ # Finally, peer4 is tried but it can't send its top transaction, which has
316
+ # a fallback cost of `test_max_tx_clvm_cost` (20), so we add that to its
317
+ # deficit counter, making it 35, and upon retrying now it's able to send
318
+ # its transaction tx4.
319
+ entry = await queue.pop()
320
+ assert entry.index == 3 # type: ignore[attr-defined]
321
+ assert queue._peers_transactions_queues[peer4].deficit == 0
322
+ assert queue._list_cursor == 0