chia-blockchain 2.5.2rc2__py3-none-any.whl → 2.5.3__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 (640) hide show
  1. chia/__init__.py +7 -0
  2. chia/_tests/blockchain/blockchain_test_utils.py +1 -1
  3. chia/_tests/blockchain/test_augmented_chain.py +54 -5
  4. chia/_tests/blockchain/test_blockchain.py +5 -12
  5. chia/_tests/blockchain/test_blockchain_transactions.py +3 -5
  6. chia/_tests/blockchain/test_get_block_generator.py +2 -2
  7. chia/_tests/blockchain/test_lookup_fork_chain.py +2 -2
  8. chia/_tests/clvm/benchmark_costs.py +2 -1
  9. chia/_tests/clvm/coin_store.py +4 -3
  10. chia/_tests/clvm/test_chialisp_deserialization.py +2 -2
  11. chia/_tests/clvm/test_curry_and_treehash.py +1 -1
  12. chia/_tests/clvm/test_puzzle_compression.py +2 -2
  13. chia/_tests/clvm/test_puzzles.py +2 -2
  14. chia/_tests/clvm/test_singletons.py +2 -2
  15. chia/_tests/clvm/test_spend_sim.py +1 -1
  16. chia/_tests/cmds/cmd_test_utils.py +2 -2
  17. chia/_tests/cmds/test_click_types.py +2 -2
  18. chia/_tests/cmds/test_cmd_framework.py +6 -6
  19. chia/_tests/cmds/test_show.py +4 -3
  20. chia/_tests/cmds/test_tx_config_args.py +1 -1
  21. chia/_tests/cmds/testing_classes.py +2 -2
  22. chia/_tests/cmds/wallet/test_consts.py +2 -2
  23. chia/_tests/cmds/wallet/test_did.py +2 -2
  24. chia/_tests/cmds/wallet/test_nft.py +2 -2
  25. chia/_tests/cmds/wallet/test_notifications.py +3 -2
  26. chia/_tests/cmds/wallet/test_vcs.py +2 -2
  27. chia/_tests/cmds/wallet/test_wallet.py +4 -8
  28. chia/_tests/conftest.py +4 -3
  29. chia/_tests/connection_utils.py +2 -2
  30. chia/_tests/core/cmds/test_keys.py +1 -2
  31. chia/_tests/core/cmds/test_wallet.py +2 -2
  32. chia/_tests/core/consensus/test_block_creation.py +2 -2
  33. chia/_tests/core/consensus/test_pot_iterations.py +1 -1
  34. chia/_tests/core/custom_types/test_coin.py +2 -2
  35. chia/_tests/core/custom_types/test_proof_of_space.py +2 -2
  36. chia/_tests/core/custom_types/test_spend_bundle.py +2 -2
  37. chia/_tests/core/data_layer/conftest.py +1 -1
  38. chia/_tests/core/data_layer/test_data_layer.py +1 -1
  39. chia/_tests/core/data_layer/test_data_layer_util.py +1 -1
  40. chia/_tests/core/data_layer/test_data_rpc.py +2 -2
  41. chia/_tests/core/data_layer/test_data_store.py +1 -1
  42. chia/_tests/core/data_layer/test_data_store_schema.py +1 -1
  43. chia/_tests/core/data_layer/util.py +2 -1
  44. chia/_tests/core/farmer/test_farmer_api.py +1 -1
  45. chia/_tests/core/full_node/full_sync/test_full_sync.py +1 -7
  46. chia/_tests/core/full_node/ram_db.py +2 -1
  47. chia/_tests/core/full_node/stores/test_block_store.py +2 -2
  48. chia/_tests/core/full_node/stores/test_coin_store.py +2 -2
  49. chia/_tests/core/full_node/stores/test_full_node_store.py +3 -3
  50. chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
  51. chia/_tests/core/full_node/stores/test_sync_store.py +1 -1
  52. chia/_tests/core/full_node/test_address_manager.py +1 -1
  53. chia/_tests/core/full_node/test_block_height_map.py +2 -2
  54. chia/_tests/core/full_node/test_conditions.py +1 -1
  55. chia/_tests/core/full_node/test_full_node.py +346 -164
  56. chia/_tests/core/full_node/test_generator_tools.py +3 -2
  57. chia/_tests/core/full_node/test_hint_management.py +2 -2
  58. chia/_tests/core/full_node/test_performance.py +2 -15
  59. chia/_tests/core/full_node/test_subscriptions.py +1 -1
  60. chia/_tests/core/full_node/test_transactions.py +186 -185
  61. chia/_tests/core/full_node/test_tx_processing_queue.py +1 -1
  62. chia/_tests/core/make_block_generator.py +2 -2
  63. chia/_tests/core/mempool/test_mempool.py +165 -22
  64. chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
  65. chia/_tests/core/mempool/test_mempool_fee_protocol.py +1 -1
  66. chia/_tests/core/mempool/test_mempool_manager.py +476 -66
  67. chia/_tests/core/mempool/test_mempool_performance.py +2 -2
  68. chia/_tests/core/mempool/test_singleton_fast_forward.py +19 -25
  69. chia/_tests/core/node_height.py +2 -1
  70. chia/_tests/core/server/test_capabilities.py +1 -1
  71. chia/_tests/core/server/test_dos.py +36 -28
  72. chia/_tests/core/server/test_loop.py +3 -3
  73. chia/_tests/core/server/test_rate_limits.py +1 -1
  74. chia/_tests/core/server/test_server.py +2 -2
  75. chia/_tests/core/services/test_services.py +1 -1
  76. chia/_tests/core/ssl/test_ssl.py +1 -1
  77. chia/_tests/core/test_coins.py +2 -1
  78. chia/_tests/core/test_cost_calculation.py +2 -2
  79. chia/_tests/core/test_crawler.py +2 -2
  80. chia/_tests/core/test_db_conversion.py +2 -2
  81. chia/_tests/core/test_db_validation.py +26 -13
  82. chia/_tests/core/test_farmer_harvester_rpc.py +2 -2
  83. chia/_tests/core/test_full_node_rpc.py +2 -2
  84. chia/_tests/core/test_merkle_set.py +2 -2
  85. chia/_tests/core/test_program.py +2 -2
  86. chia/_tests/core/test_rpc_util.py +1 -1
  87. chia/_tests/core/test_seeder.py +1 -1
  88. chia/_tests/core/util/test_block_cache.py +3 -3
  89. chia/_tests/core/util/test_jsonify.py +3 -2
  90. chia/_tests/core/util/test_keychain.py +3 -3
  91. chia/_tests/core/util/test_streamable.py +3 -4
  92. chia/_tests/environments/wallet.py +3 -2
  93. chia/_tests/farmer_harvester/test_farmer.py +3 -4
  94. chia/_tests/farmer_harvester/test_farmer_harvester.py +2 -2
  95. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +2 -2
  96. chia/_tests/farmer_harvester/test_third_party_harvesters.py +3 -4
  97. chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -1
  98. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +2 -2
  99. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
  100. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +3 -4
  101. chia/_tests/generator/test_compression.py +20 -10
  102. chia/_tests/generator/test_rom.py +7 -9
  103. chia/_tests/plot_sync/test_delta.py +2 -2
  104. chia/_tests/plot_sync/test_plot_sync.py +2 -2
  105. chia/_tests/plot_sync/test_receiver.py +2 -2
  106. chia/_tests/plot_sync/test_sender.py +2 -2
  107. chia/_tests/plot_sync/test_sync_simulated.py +2 -2
  108. chia/_tests/plot_sync/util.py +3 -2
  109. chia/_tests/plotting/test_plot_manager.py +1 -1
  110. chia/_tests/pools/test_pool_cli_parsing.py +3 -2
  111. chia/_tests/pools/test_pool_cmdline.py +2 -2
  112. chia/_tests/pools/test_pool_puzzles_lifecycle.py +3 -3
  113. chia/_tests/pools/test_pool_rpc.py +4 -5
  114. chia/_tests/pools/test_pool_wallet.py +1 -1
  115. chia/_tests/pools/test_wallet_pool_store.py +2 -2
  116. chia/_tests/rpc/test_rpc_client.py +1 -1
  117. chia/_tests/rpc/test_rpc_server.py +1 -1
  118. chia/_tests/simulation/test_simulation.py +36 -8
  119. chia/_tests/simulation/test_simulator.py +5 -5
  120. chia/_tests/simulation/test_start_simulator.py +2 -2
  121. chia/_tests/timelord/test_new_peak.py +2 -2
  122. chia/_tests/tools/test_run_block.py +3 -2
  123. chia/_tests/util/benchmark_cost.py +2 -2
  124. chia/_tests/util/benchmarks.py +17 -6
  125. chia/_tests/util/blockchain.py +2 -1
  126. chia/_tests/util/blockchain_mock.py +9 -5
  127. chia/_tests/util/build_network_protocol_files.py +2 -1
  128. chia/_tests/util/constants.py +2 -1
  129. chia/_tests/util/full_sync.py +6 -3
  130. chia/_tests/util/gen_ssl_certs.py +2 -2
  131. chia/_tests/util/generator_tools_testing.py +4 -3
  132. chia/_tests/util/get_name_puzzle_conditions.py +2 -2
  133. chia/_tests/util/misc.py +16 -2
  134. chia/_tests/util/network_protocol_data.py +17 -7
  135. chia/_tests/util/run_block.py +6 -8
  136. chia/_tests/util/setup_nodes.py +4 -3
  137. chia/_tests/util/spend_sim.py +9 -5
  138. chia/_tests/util/test_condition_tools.py +2 -2
  139. chia/_tests/util/test_config.py +2 -1
  140. chia/_tests/util/test_errors.py +2 -1
  141. chia/_tests/util/test_full_block_utils.py +17 -7
  142. chia/_tests/util/test_misc.py +1 -1
  143. chia/_tests/util/test_network_protocol_test.py +24 -24
  144. chia/_tests/util/test_replace_str_to_bytes.py +2 -2
  145. chia/_tests/util/test_trusted_peer.py +1 -1
  146. chia/_tests/util/time_out_assert.py +20 -7
  147. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
  148. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -2
  149. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +5 -6
  150. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +17 -15
  151. chia/_tests/wallet/cat_wallet/test_trades.py +2 -2
  152. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -2
  153. chia/_tests/wallet/clawback/test_clawback_metadata.py +2 -2
  154. chia/_tests/wallet/conftest.py +3 -3
  155. chia/_tests/wallet/db_wallet/test_db_graftroot.py +3 -5
  156. chia/_tests/wallet/db_wallet/test_dl_offers.py +2 -2
  157. chia/_tests/wallet/db_wallet/test_dl_wallet.py +433 -384
  158. chia/_tests/wallet/did_wallet/test_did.py +3 -3
  159. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +2 -2
  160. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +2 -2
  161. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +3 -4
  162. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1293 -703
  163. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +28 -30
  164. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2 -2
  165. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +2 -2
  166. chia/_tests/wallet/rpc/config.py +1 -1
  167. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +2 -2
  168. chia/_tests/wallet/rpc/test_wallet_rpc.py +20 -77
  169. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +9 -7
  170. chia/_tests/wallet/sync/test_wallet_sync.py +79 -31
  171. chia/_tests/wallet/test_clvm_streamable.py +2 -2
  172. chia/_tests/wallet/test_coin_management.py +7 -7
  173. chia/_tests/wallet/test_coin_selection.py +20 -2
  174. chia/_tests/wallet/test_conditions.py +2 -2
  175. chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
  176. chia/_tests/wallet/test_new_wallet_protocol.py +2 -2
  177. chia/_tests/wallet/test_nft_store.py +2 -2
  178. chia/_tests/wallet/test_notifications.py +2 -2
  179. chia/_tests/wallet/test_puzzle_store.py +2 -2
  180. chia/_tests/wallet/test_sign_coin_spends.py +2 -2
  181. chia/_tests/wallet/test_signer_protocol.py +3 -3
  182. chia/_tests/wallet/test_singleton.py +3 -11
  183. chia/_tests/wallet/test_singleton_lifecycle_fast.py +12 -13
  184. chia/_tests/wallet/test_singleton_store.py +2 -4
  185. chia/_tests/wallet/test_transaction_store.py +2 -2
  186. chia/_tests/wallet/test_util.py +2 -2
  187. chia/_tests/wallet/test_wallet.py +53 -49
  188. chia/_tests/wallet/test_wallet_action_scope.py +24 -6
  189. chia/_tests/wallet/test_wallet_blockchain.py +1 -1
  190. chia/_tests/wallet/test_wallet_coin_store.py +2 -2
  191. chia/_tests/wallet/test_wallet_interested_store.py +2 -2
  192. chia/_tests/wallet/test_wallet_node.py +3 -3
  193. chia/_tests/wallet/test_wallet_retry.py +3 -3
  194. chia/_tests/wallet/test_wallet_state_manager.py +8 -8
  195. chia/_tests/wallet/test_wallet_test_framework.py +1 -1
  196. chia/_tests/wallet/test_wallet_trade_store.py +2 -2
  197. chia/_tests/wallet/test_wallet_utils.py +2 -2
  198. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -2
  199. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +15 -15
  200. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +5 -3
  201. chia/_tests/wallet/wallet_block_tools.py +15 -7
  202. chia/_tests/weight_proof/test_weight_proof.py +3 -3
  203. chia/cmds/chia.py +0 -2
  204. chia/cmds/cmd_classes.py +3 -3
  205. chia/cmds/cmd_helpers.py +4 -4
  206. chia/cmds/cmds_util.py +2 -2
  207. chia/cmds/coin_funcs.py +3 -2
  208. chia/cmds/coins.py +1 -1
  209. chia/cmds/data.py +2 -2
  210. chia/cmds/data_funcs.py +3 -2
  211. chia/cmds/db_upgrade_func.py +2 -2
  212. chia/cmds/db_validate_func.py +15 -8
  213. chia/cmds/farm.py +2 -4
  214. chia/cmds/keys.py +0 -2
  215. chia/cmds/keys_funcs.py +1 -1
  216. chia/cmds/netspace_funcs.py +2 -1
  217. chia/cmds/param_types.py +2 -2
  218. chia/cmds/plotnft.py +2 -2
  219. chia/cmds/plotnft_funcs.py +2 -2
  220. chia/cmds/rpc.py +1 -1
  221. chia/cmds/show.py +1 -2
  222. chia/cmds/show_funcs.py +6 -3
  223. chia/cmds/signer.py +1 -2
  224. chia/cmds/sim.py +1 -2
  225. chia/cmds/sim_funcs.py +2 -2
  226. chia/cmds/wallet.py +2 -2
  227. chia/cmds/wallet_funcs.py +4 -11
  228. chia/consensus/block_body_validation.py +3 -4
  229. chia/consensus/block_creation.py +10 -6
  230. chia/consensus/block_header_validation.py +3 -4
  231. chia/consensus/block_record.py +2 -3
  232. chia/consensus/block_rewards.py +1 -1
  233. chia/consensus/blockchain.py +20 -17
  234. chia/consensus/blockchain_interface.py +5 -4
  235. chia/consensus/coinbase.py +2 -2
  236. chia/consensus/constants.py +1 -1
  237. chia/consensus/cost_calculator.py +2 -1
  238. chia/consensus/default_constants.py +4 -3
  239. chia/consensus/deficit.py +3 -2
  240. chia/consensus/difficulty_adjustment.py +8 -9
  241. chia/consensus/find_fork_point.py +4 -3
  242. chia/consensus/full_block_to_block_record.py +4 -3
  243. chia/consensus/get_block_challenge.py +4 -3
  244. chia/consensus/get_block_generator.py +3 -2
  245. chia/consensus/make_sub_epoch_summary.py +3 -2
  246. chia/consensus/multiprocess_validation.py +9 -4
  247. chia/consensus/pos_quality.py +1 -1
  248. chia/consensus/pot_iterations.py +4 -3
  249. chia/consensus/vdf_info_computation.py +4 -3
  250. chia/daemon/client.py +1 -1
  251. chia/daemon/keychain_server.py +1 -1
  252. chia/daemon/server.py +1 -1
  253. chia/daemon/windows_signal.py +1 -1
  254. chia/data_layer/data_layer.py +4 -3
  255. chia/data_layer/data_layer_errors.py +1 -1
  256. chia/data_layer/data_layer_util.py +2 -2
  257. chia/data_layer/data_layer_wallet.py +47 -69
  258. chia/data_layer/data_store.py +1 -1
  259. chia/data_layer/dl_wallet_store.py +5 -6
  260. chia/data_layer/download_data.py +1 -1
  261. chia/data_layer/s3_plugin_service.py +4 -4
  262. chia/data_layer/singleton_record.py +23 -0
  263. chia/data_layer/util/benchmark.py +2 -1
  264. chia/farmer/farmer.py +4 -6
  265. chia/farmer/farmer_api.py +4 -6
  266. chia/full_node/bitcoin_fee_estimator.py +2 -1
  267. chia/full_node/block_height_map.py +2 -2
  268. chia/full_node/block_store.py +8 -9
  269. chia/{util → full_node}/check_fork_next_block.py +2 -1
  270. chia/full_node/coin_store.py +10 -10
  271. chia/full_node/fee_estimate.py +2 -1
  272. chia/full_node/fee_estimation.py +2 -1
  273. chia/full_node/fee_estimator.py +2 -1
  274. chia/full_node/fee_estimator_interface.py +1 -1
  275. chia/full_node/fee_history.py +2 -1
  276. chia/full_node/fee_tracker.py +2 -1
  277. chia/full_node/full_node.py +15 -13
  278. chia/full_node/full_node_api.py +12 -32
  279. chia/full_node/full_node_store.py +4 -3
  280. chia/full_node/hint_management.py +2 -1
  281. chia/full_node/hint_store.py +3 -3
  282. chia/full_node/mempool.py +80 -12
  283. chia/full_node/mempool_check_conditions.py +6 -7
  284. chia/full_node/mempool_manager.py +168 -21
  285. chia/full_node/pending_tx_cache.py +2 -2
  286. chia/full_node/subscriptions.py +2 -2
  287. chia/full_node/sync_store.py +2 -3
  288. chia/full_node/tx_processing_queue.py +2 -1
  289. chia/full_node/weight_proof.py +5 -8
  290. chia/harvester/harvester.py +5 -3
  291. chia/harvester/harvester_api.py +2 -2
  292. chia/introducer/introducer.py +30 -2
  293. chia/introducer/introducer_api.py +9 -1
  294. chia/legacy/keyring.py +1 -2
  295. chia/plot_sync/exceptions.py +2 -1
  296. chia/plot_sync/receiver.py +2 -2
  297. chia/plot_sync/sender.py +1 -1
  298. chia/plotting/cache.py +2 -2
  299. chia/plotting/check_plots.py +4 -2
  300. chia/plotting/create_plots.py +1 -1
  301. chia/plotting/manager.py +3 -3
  302. chia/plotting/util.py +2 -2
  303. chia/pools/pool_config.py +1 -1
  304. chia/pools/pool_puzzles.py +23 -17
  305. chia/pools/pool_wallet.py +22 -9
  306. chia/pools/pool_wallet_info.py +2 -2
  307. chia/protocols/farmer_protocol.py +3 -6
  308. chia/protocols/full_node_protocol.py +3 -2
  309. chia/protocols/harvester_protocol.py +3 -4
  310. chia/protocols/pool_protocol.py +2 -2
  311. chia/protocols/shared_protocol.py +2 -1
  312. chia/protocols/timelord_protocol.py +4 -4
  313. chia/protocols/wallet_protocol.py +2 -2
  314. chia/rpc/data_layer_rpc_api.py +3 -4
  315. chia/rpc/data_layer_rpc_client.py +3 -2
  316. chia/rpc/farmer_rpc_api.py +2 -2
  317. chia/rpc/farmer_rpc_client.py +2 -1
  318. chia/rpc/full_node_rpc_api.py +3 -2
  319. chia/rpc/full_node_rpc_client.py +3 -2
  320. chia/rpc/harvester_rpc_api.py +2 -1
  321. chia/rpc/rpc_client.py +2 -2
  322. chia/rpc/rpc_server.py +1 -1
  323. chia/rpc/wallet_request_types.py +2 -62
  324. chia/rpc/wallet_rpc_api.py +98 -628
  325. chia/rpc/wallet_rpc_client.py +5 -253
  326. chia/seeder/crawl_store.py +1 -1
  327. chia/seeder/crawler.py +2 -2
  328. chia/seeder/peer_record.py +2 -1
  329. chia/seeder/start_crawler.py +3 -1
  330. chia/server/address_manager.py +2 -1
  331. chia/server/address_manager_store.py +1 -1
  332. chia/server/capabilities.py +2 -1
  333. chia/server/introducer_peers.py +2 -1
  334. chia/server/node_discovery.py +1 -1
  335. chia/server/outbound_message.py +2 -1
  336. chia/server/server.py +2 -2
  337. chia/server/start_data_layer.py +2 -1
  338. chia/server/start_farmer.py +3 -1
  339. chia/server/start_full_node.py +4 -2
  340. chia/server/start_harvester.py +3 -1
  341. chia/server/start_introducer.py +12 -1
  342. chia/server/start_service.py +2 -1
  343. chia/server/start_timelord.py +3 -1
  344. chia/server/start_wallet.py +3 -1
  345. chia/server/upnp.py +1 -2
  346. chia/server/ws_connection.py +3 -4
  347. chia/simulator/add_blocks_in_batches.py +5 -3
  348. chia/simulator/block_tools.py +16 -12
  349. chia/simulator/full_node_simulator.py +9 -14
  350. chia/simulator/setup_services.py +5 -3
  351. chia/simulator/simulator_full_node_rpc_api.py +3 -2
  352. chia/simulator/simulator_full_node_rpc_client.py +3 -2
  353. chia/simulator/simulator_protocol.py +3 -2
  354. chia/simulator/simulator_test_tools.py +2 -2
  355. chia/simulator/start_simulator.py +3 -2
  356. chia/simulator/wallet_tools.py +3 -4
  357. chia/timelord/iters_from_block.py +4 -4
  358. chia/timelord/timelord.py +7 -12
  359. chia/timelord/timelord_api.py +3 -3
  360. chia/timelord/timelord_state.py +4 -3
  361. chia/types/block_protocol.py +2 -2
  362. chia/types/blockchain_format/coin.py +2 -2
  363. chia/types/blockchain_format/program.py +1 -1
  364. chia/types/blockchain_format/proof_of_space.py +3 -4
  365. chia/types/blockchain_format/tree_hash.py +1 -1
  366. chia/types/blockchain_format/vdf.py +3 -4
  367. chia/types/clvm_cost.py +1 -1
  368. chia/types/coin_record.py +4 -3
  369. chia/types/coin_spend.py +1 -1
  370. chia/types/eligible_coin_spends.py +9 -5
  371. chia/types/fee_rate.py +1 -1
  372. chia/types/generator_types.py +3 -3
  373. chia/types/internal_mempool_item.py +3 -2
  374. chia/types/mempool_item.py +10 -3
  375. chia/types/mempool_submission_status.py +2 -1
  376. chia/types/mojos.py +1 -1
  377. chia/types/peer_info.py +2 -1
  378. chia/types/transaction_queue_entry.py +2 -1
  379. chia/types/unfinished_header_block.py +4 -4
  380. chia/types/validation_state.py +2 -1
  381. chia/types/weight_proof.py +1 -9
  382. chia/util/augmented_chain.py +20 -9
  383. chia/util/block_cache.py +8 -4
  384. chia/util/condition_tools.py +2 -2
  385. chia/util/full_block_utils.py +3 -4
  386. chia/util/generator_tools.py +2 -2
  387. chia/util/initial-config.yaml +2 -11
  388. chia/util/network.py +2 -2
  389. chia/util/prev_transaction_block.py +2 -1
  390. chia/util/task_timing.py +1 -1
  391. chia/util/vdf_prover.py +3 -3
  392. chia/util/ws_message.py +1 -1
  393. chia/wallet/cat_wallet/cat_info.py +3 -2
  394. chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -2
  395. chia/wallet/cat_wallet/cat_utils.py +6 -4
  396. chia/wallet/cat_wallet/cat_wallet.py +16 -18
  397. chia/wallet/cat_wallet/lineage_store.py +2 -1
  398. chia/wallet/coin_selection.py +5 -5
  399. chia/wallet/conditions.py +22 -16
  400. chia/wallet/db_wallet/db_wallet_puzzles.py +15 -15
  401. chia/wallet/derivation_record.py +2 -2
  402. chia/wallet/derive_keys.py +2 -2
  403. chia/wallet/did_wallet/did_info.py +3 -2
  404. chia/wallet/did_wallet/did_wallet.py +41 -19
  405. chia/wallet/did_wallet/did_wallet_puzzles.py +18 -12
  406. chia/wallet/driver_protocol.py +1 -1
  407. chia/wallet/lineage_proof.py +3 -2
  408. chia/wallet/nft_wallet/metadata_outer_puzzle.py +6 -7
  409. chia/wallet/nft_wallet/nft_info.py +5 -5
  410. chia/wallet/nft_wallet/nft_puzzle_utils.py +293 -0
  411. chia/wallet/nft_wallet/nft_puzzles.py +21 -298
  412. chia/wallet/nft_wallet/nft_wallet.py +47 -62
  413. chia/wallet/nft_wallet/ownership_outer_puzzle.py +4 -8
  414. chia/wallet/nft_wallet/singleton_outer_puzzle.py +3 -2
  415. chia/wallet/nft_wallet/transfer_program_puzzle.py +6 -10
  416. chia/wallet/nft_wallet/uncurry_nft.py +6 -8
  417. chia/wallet/notification_manager.py +5 -5
  418. chia/wallet/notification_store.py +3 -2
  419. chia/wallet/outer_puzzles.py +2 -1
  420. chia/wallet/puzzles/clawback/drivers.py +21 -8
  421. chia/wallet/puzzles/clawback/metadata.py +3 -2
  422. chia/wallet/puzzles/clawback/puzzle_decorator.py +5 -4
  423. chia/wallet/puzzles/deployed_puzzle_hashes.json +0 -10
  424. chia/wallet/puzzles/p2_conditions.py +3 -2
  425. chia/wallet/puzzles/p2_delegated_conditions.py +3 -2
  426. chia/wallet/puzzles/p2_delegated_puzzle.py +3 -2
  427. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -3
  428. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +3 -2
  429. chia/wallet/puzzles/p2_puzzle_hash.py +4 -3
  430. chia/wallet/puzzles/puzzle_utils.py +3 -2
  431. chia/wallet/puzzles/singleton_top_layer.py +26 -10
  432. chia/wallet/puzzles/singleton_top_layer_v1_1.py +21 -9
  433. chia/wallet/puzzles/tails.py +21 -129
  434. chia/wallet/signer_protocol.py +3 -2
  435. chia/wallet/singleton.py +12 -6
  436. chia/wallet/singleton_record.py +3 -2
  437. chia/wallet/trade_manager.py +31 -55
  438. chia/wallet/trade_record.py +3 -2
  439. chia/wallet/trading/offer.py +14 -13
  440. chia/wallet/trading/trade_store.py +3 -4
  441. chia/wallet/transaction_record.py +2 -2
  442. chia/wallet/util/blind_signer_tl.py +3 -2
  443. chia/wallet/util/compute_hints.py +3 -2
  444. chia/wallet/util/compute_memos.py +2 -2
  445. chia/wallet/util/curry_and_treehash.py +1 -2
  446. chia/wallet/util/merkle_tree.py +1 -1
  447. chia/wallet/util/merkle_utils.py +1 -1
  448. chia/wallet/util/new_peak_queue.py +2 -1
  449. chia/wallet/util/notifications.py +5 -4
  450. chia/wallet/util/peer_request_cache.py +3 -2
  451. chia/wallet/util/puzzle_compression.py +6 -4
  452. chia/wallet/util/puzzle_decorator.py +6 -4
  453. chia/wallet/util/query_filter.py +3 -2
  454. chia/wallet/util/tx_config.py +3 -3
  455. chia/wallet/util/wallet_sync_utils.py +2 -2
  456. chia/wallet/util/wallet_types.py +2 -3
  457. chia/wallet/vc_wallet/cr_cat_drivers.py +18 -22
  458. chia/wallet/vc_wallet/cr_cat_wallet.py +14 -10
  459. chia/wallet/vc_wallet/cr_outer_puzzle.py +2 -2
  460. chia/wallet/vc_wallet/vc_drivers.py +50 -68
  461. chia/wallet/vc_wallet/vc_store.py +2 -2
  462. chia/wallet/vc_wallet/vc_wallet.py +47 -15
  463. chia/wallet/wallet.py +51 -46
  464. chia/wallet/wallet_action_scope.py +4 -0
  465. chia/wallet/wallet_blockchain.py +12 -7
  466. chia/wallet/wallet_coin_record.py +3 -2
  467. chia/wallet/wallet_coin_store.py +3 -2
  468. chia/wallet/wallet_info.py +2 -1
  469. chia/wallet/wallet_interested_store.py +3 -2
  470. chia/wallet/wallet_nft_store.py +4 -4
  471. chia/wallet/wallet_node.py +3 -4
  472. chia/wallet/wallet_pool_store.py +3 -4
  473. chia/wallet/wallet_protocol.py +19 -5
  474. chia/wallet/wallet_puzzle_store.py +2 -2
  475. chia/wallet/wallet_retry_store.py +3 -6
  476. chia/wallet/wallet_singleton_store.py +2 -2
  477. chia/wallet/wallet_state_manager.py +20 -197
  478. chia/wallet/wallet_transaction_store.py +2 -2
  479. chia/wallet/wallet_user_store.py +2 -1
  480. chia/wallet/wallet_weight_proof_handler.py +3 -2
  481. {chia_blockchain-2.5.2rc2.dist-info → chia_blockchain-2.5.3.dist-info}/METADATA +3 -2
  482. chia_blockchain-2.5.3.dist-info/RECORD +891 -0
  483. mozilla-ca/cacert.pem +64 -33
  484. chia/_tests/clvm/test_condition_codes.py +0 -13
  485. chia/_tests/cmds/wallet/test_dao.py +0 -565
  486. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  487. chia/_tests/wallet/dao_wallet/config.py +0 -3
  488. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +0 -1330
  489. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +0 -3488
  490. chia/cmds/dao.py +0 -1064
  491. chia/cmds/dao_funcs.py +0 -598
  492. chia/consensus/puzzles/__init__.py +0 -0
  493. chia/consensus/puzzles/chialisp_deserialisation.clsp +0 -69
  494. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +0 -1
  495. chia/consensus/puzzles/rom_bootstrap_generator.clsp +0 -37
  496. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +0 -1
  497. chia/full_node/puzzles/__init__.py +0 -0
  498. chia/full_node/puzzles/block_program_zero.clsp +0 -14
  499. chia/full_node/puzzles/block_program_zero.clsp.hex +0 -1
  500. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +0 -5
  501. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +0 -1
  502. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +0 -7
  503. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +0 -1
  504. chia/full_node/puzzles/decompress_puzzle.clsp +0 -6
  505. chia/full_node/puzzles/decompress_puzzle.clsp.hex +0 -1
  506. chia/pools/puzzles/__init__.py +0 -0
  507. chia/pools/puzzles/pool_member_innerpuz.clsp +0 -70
  508. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +0 -1
  509. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +0 -69
  510. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +0 -1
  511. chia/simulator/simulator_constants.py +0 -13
  512. chia/types/blockchain_format/foliage.py +0 -8
  513. chia/types/blockchain_format/pool_target.py +0 -5
  514. chia/types/blockchain_format/reward_chain_block.py +0 -6
  515. chia/types/blockchain_format/sized_bytes.py +0 -11
  516. chia/util/ints.py +0 -19
  517. chia/wallet/cat_wallet/dao_cat_info.py +0 -28
  518. chia/wallet/cat_wallet/dao_cat_wallet.py +0 -669
  519. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  520. chia/wallet/cat_wallet/puzzles/cat_truths.clib +0 -31
  521. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +0 -397
  522. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +0 -1
  523. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +0 -25
  524. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +0 -1
  525. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +0 -15
  526. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +0 -1
  527. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +0 -26
  528. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +0 -1
  529. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +0 -42
  530. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +0 -1
  531. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +0 -24
  532. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +0 -1
  533. chia/wallet/dao_wallet/__init__.py +0 -0
  534. chia/wallet/dao_wallet/dao_info.py +0 -61
  535. chia/wallet/dao_wallet/dao_utils.py +0 -811
  536. chia/wallet/dao_wallet/dao_wallet.py +0 -2119
  537. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  538. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +0 -135
  539. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +0 -1
  540. chia/wallet/payment.py +0 -33
  541. chia/wallet/puzzles/augmented_condition.clsp +0 -13
  542. chia/wallet/puzzles/augmented_condition.clsp.hex +0 -1
  543. chia/wallet/puzzles/condition_codes.clib +0 -77
  544. chia/wallet/puzzles/curry-and-treehash.clib +0 -102
  545. chia/wallet/puzzles/curry.clib +0 -135
  546. chia/wallet/puzzles/curry_by_index.clib +0 -16
  547. chia/wallet/puzzles/dao_cat_eve.clsp +0 -17
  548. chia/wallet/puzzles/dao_cat_eve.clsp.hex +0 -1
  549. chia/wallet/puzzles/dao_cat_launcher.clsp +0 -36
  550. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +0 -1
  551. chia/wallet/puzzles/dao_finished_state.clsp +0 -35
  552. chia/wallet/puzzles/dao_finished_state.clsp.hex +0 -1
  553. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +0 -1
  554. chia/wallet/puzzles/dao_lockup.clsp +0 -288
  555. chia/wallet/puzzles/dao_lockup.clsp.hex +0 -1
  556. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +0 -1
  557. chia/wallet/puzzles/dao_proposal.clsp +0 -377
  558. chia/wallet/puzzles/dao_proposal.clsp.hex +0 -1
  559. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +0 -1
  560. chia/wallet/puzzles/dao_proposal_timer.clsp +0 -78
  561. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +0 -1
  562. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +0 -1
  563. chia/wallet/puzzles/dao_proposal_validator.clsp +0 -87
  564. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +0 -1
  565. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +0 -1
  566. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +0 -240
  567. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +0 -1
  568. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +0 -1
  569. chia/wallet/puzzles/dao_treasury.clsp +0 -115
  570. chia/wallet/puzzles/dao_treasury.clsp.hex +0 -1
  571. chia/wallet/puzzles/dao_update_proposal.clsp +0 -44
  572. chia/wallet/puzzles/dao_update_proposal.clsp.hex +0 -1
  573. chia/wallet/puzzles/json.clib +0 -25
  574. chia/wallet/puzzles/merkle_utils.clib +0 -18
  575. chia/wallet/puzzles/notification.clsp +0 -7
  576. chia/wallet/puzzles/notification.clsp.hex +0 -1
  577. chia/wallet/puzzles/p2_1_of_n.clsp +0 -22
  578. chia/wallet/puzzles/p2_1_of_n.clsp.hex +0 -1
  579. chia/wallet/puzzles/p2_conditions.clsp +0 -3
  580. chia/wallet/puzzles/p2_conditions.clsp.hex +0 -1
  581. chia/wallet/puzzles/p2_delegated_conditions.clsp +0 -18
  582. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +0 -1
  583. chia/wallet/puzzles/p2_delegated_puzzle.clsp +0 -19
  584. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +0 -1
  585. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +0 -91
  586. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +0 -1
  587. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +0 -108
  588. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +0 -1
  589. chia/wallet/puzzles/p2_parent.clsp +0 -19
  590. chia/wallet/puzzles/p2_parent.clsp.hex +0 -1
  591. chia/wallet/puzzles/p2_puzzle_hash.clsp +0 -18
  592. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +0 -1
  593. chia/wallet/puzzles/p2_singleton.clsp +0 -30
  594. chia/wallet/puzzles/p2_singleton.clsp.hex +0 -1
  595. chia/wallet/puzzles/p2_singleton_aggregator.clsp +0 -81
  596. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +0 -1
  597. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +0 -50
  598. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +0 -1
  599. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +0 -47
  600. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +0 -1
  601. chia/wallet/puzzles/settlement_payments.clsp +0 -49
  602. chia/wallet/puzzles/settlement_payments.clsp.hex +0 -1
  603. chia/wallet/puzzles/sha256tree.clib +0 -11
  604. chia/wallet/puzzles/singleton_launcher.clsp +0 -16
  605. chia/wallet/puzzles/singleton_launcher.clsp.hex +0 -1
  606. chia/wallet/puzzles/singleton_top_layer.clsp +0 -177
  607. chia/wallet/puzzles/singleton_top_layer.clsp.hex +0 -1
  608. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +0 -107
  609. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +0 -1
  610. chia/wallet/puzzles/singleton_truths.clib +0 -21
  611. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  612. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +0 -3
  613. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +0 -1
  614. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +0 -304
  615. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +0 -1
  616. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +0 -45
  617. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +0 -1
  618. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  619. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +0 -30
  620. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +0 -1
  621. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +0 -75
  622. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +0 -1
  623. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +0 -32
  624. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +0 -1
  625. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +0 -80
  626. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +0 -1
  627. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +0 -163
  628. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +0 -1
  629. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +0 -16
  630. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +0 -1
  631. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +0 -74
  632. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +0 -1
  633. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +0 -23
  634. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +0 -1
  635. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +0 -64
  636. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +0 -1
  637. chia_blockchain-2.5.2rc2.dist-info/RECORD +0 -1042
  638. {chia_blockchain-2.5.2rc2.dist-info → chia_blockchain-2.5.3.dist-info}/LICENSE +0 -0
  639. {chia_blockchain-2.5.2rc2.dist-info → chia_blockchain-2.5.3.dist-info}/WHEEL +0 -0
  640. {chia_blockchain-2.5.2rc2.dist-info → chia_blockchain-2.5.3.dist-info}/entry_points.txt +0 -0
@@ -2,18 +2,26 @@ from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
4
  import logging
5
- from collections.abc import Awaitable, Collection
6
- from typing import Any, Callable, ClassVar, Optional
5
+ from collections.abc import Awaitable, Collection, Sequence
6
+ from typing import Any, Callable, ClassVar, Optional, Union
7
7
 
8
8
  import pytest
9
- from chia_rs import ELIGIBLE_FOR_DEDUP, ELIGIBLE_FOR_FF, AugSchemeMPL, G2Element, get_conditions_from_spendbundle
9
+ from chia_rs import (
10
+ ELIGIBLE_FOR_DEDUP,
11
+ ELIGIBLE_FOR_FF,
12
+ AugSchemeMPL,
13
+ ConsensusConstants,
14
+ G2Element,
15
+ get_conditions_from_spendbundle,
16
+ )
17
+ from chia_rs.sized_bytes import bytes32
18
+ from chia_rs.sized_ints import uint8, uint32, uint64
10
19
  from chiabip158 import PyBIP158
11
20
 
12
21
  from chia._tests.conftest import ConsensusMode
13
22
  from chia._tests.util.misc import invariant_check_mempool
14
23
  from chia._tests.util.setup_nodes import OldSimulatorsAndWallets, setup_simulators_and_wallets
15
24
  from chia.consensus.condition_costs import ConditionCost
16
- from chia.consensus.constants import ConsensusConstants
17
25
  from chia.consensus.default_constants import DEFAULT_CONSTANTS
18
26
  from chia.full_node.mempool import MAX_SKIPPED_ITEMS, PRIORITY_TX_THRESHOLD
19
27
  from chia.full_node.mempool_check_conditions import mempool_check_time_locks
@@ -36,7 +44,6 @@ from chia.simulator.simulator_protocol import FarmNewBlockProtocol
36
44
  from chia.types.blockchain_format.coin import Coin
37
45
  from chia.types.blockchain_format.program import INFINITE_COST, Program
38
46
  from chia.types.blockchain_format.serialized_program import SerializedProgram
39
- from chia.types.blockchain_format.sized_bytes import bytes32
40
47
  from chia.types.clvm_cost import CLVMCost
41
48
  from chia.types.coin_record import CoinRecord
42
49
  from chia.types.coin_spend import CoinSpend, make_spend
@@ -45,6 +52,7 @@ from chia.types.eligible_coin_spends import (
45
52
  DedupCoinSpend,
46
53
  EligibilityAndAdditions,
47
54
  EligibleCoinSpends,
55
+ SkipDedup,
48
56
  UnspentLineageInfo,
49
57
  run_for_cost,
50
58
  )
@@ -54,9 +62,7 @@ from chia.types.peer_info import PeerInfo
54
62
  from chia.types.spend_bundle import SpendBundle
55
63
  from chia.types.spend_bundle_conditions import SpendBundleConditions, SpendConditions
56
64
  from chia.util.errors import Err, ValidationError
57
- from chia.util.ints import uint8, uint32, uint64
58
65
  from chia.wallet.conditions import AssertCoinAnnouncement
59
- from chia.wallet.payment import Payment
60
66
  from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG
61
67
  from chia.wallet.wallet import Wallet
62
68
  from chia.wallet.wallet_coin_record import WalletCoinRecord
@@ -202,15 +208,22 @@ def make_test_conds(
202
208
  before_seconds_relative: Optional[int] = None,
203
209
  before_seconds_absolute: Optional[int] = None,
204
210
  cost: int = 0,
205
- spend_ids: list[bytes32] = [TEST_COIN_ID],
211
+ spend_ids: Sequence[tuple[Union[bytes32, Coin], int]] = [(TEST_COIN_ID, 0)],
206
212
  ) -> SpendBundleConditions:
213
+ spend_info: list[tuple[bytes32, bytes32, bytes32, uint64, int]] = []
214
+ for coin, flags in spend_ids:
215
+ if isinstance(coin, Coin):
216
+ spend_info.append((coin.name(), coin.parent_coin_info, coin.puzzle_hash, coin.amount, flags))
217
+ else:
218
+ spend_info.append((coin, IDENTITY_PUZZLE_HASH, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT, flags))
219
+
207
220
  return SpendBundleConditions(
208
221
  [
209
222
  SpendConditions(
210
- spend_id,
211
- IDENTITY_PUZZLE_HASH,
212
- IDENTITY_PUZZLE_HASH,
213
- TEST_COIN_AMOUNT,
223
+ coin_id,
224
+ parent_id,
225
+ puzzle_hash,
226
+ amount,
214
227
  None if height_relative is None else uint32(height_relative),
215
228
  None if seconds_relative is None else uint64(seconds_relative),
216
229
  None if before_height_relative is None else uint32(before_height_relative),
@@ -225,9 +238,9 @@ def make_test_conds(
225
238
  [],
226
239
  [],
227
240
  [],
228
- 0,
241
+ flags,
229
242
  )
230
- for spend_id in spend_ids
243
+ for coin_id, parent_id, puzzle_hash, amount, flags in spend_info
231
244
  ],
232
245
  0,
233
246
  uint32(height_absolute),
@@ -746,19 +759,25 @@ def mk_item(
746
759
  assert_height: Optional[int] = None,
747
760
  assert_before_height: Optional[int] = None,
748
761
  assert_before_seconds: Optional[int] = None,
762
+ flags: list[int] = [],
749
763
  ) -> MempoolItem:
750
764
  # we don't actually care about the puzzle and solutions for the purpose of
751
765
  # can_replace()
752
- spend_ids = []
766
+ spend_ids: list[tuple[bytes32, int]] = []
753
767
  coin_spends = []
754
768
  bundle_coin_spends = {}
755
- for c in coins:
769
+ if len(flags) < len(coins):
770
+ flags.extend([0] * (len(coins) - len(flags)))
771
+ for c, f in zip(coins, flags):
756
772
  coin_id = c.name()
757
- spend_ids.append(coin_id)
773
+ spend_ids.append((coin_id, f))
758
774
  spend = make_spend(c, SerializedProgram.to(None), SerializedProgram.to(None))
759
775
  coin_spends.append(spend)
760
776
  bundle_coin_spends[coin_id] = BundleCoinSpend(
761
- coin_spend=spend, eligible_for_dedup=False, eligible_for_fast_forward=False, additions=[]
777
+ coin_spend=spend,
778
+ eligible_for_dedup=bool(f & ELIGIBLE_FOR_DEDUP),
779
+ eligible_for_fast_forward=bool(f & ELIGIBLE_FOR_FF),
780
+ additions=[],
762
781
  )
763
782
  spend_bundle = SpendBundle(coin_spends, G2Element())
764
783
  conds = make_test_conds(cost=cost, spend_ids=spend_ids)
@@ -812,6 +831,46 @@ coins = make_test_coins()
812
831
  ([mk_item(coins[0:2])], mk_item(coins[0:2], fee=10000000), True),
813
832
  # or if we spend the same coins with additional coins
814
833
  ([mk_item(coins[0:2])], mk_item(coins[0:3], fee=10000000), True),
834
+ # you're not allowed to clear the fast-forward or dedup flag. It's OK to set it
835
+ # and leave it unchanged
836
+ ([mk_item(coins[0:2])], mk_item(coins[0:3], flags=[ELIGIBLE_FOR_DEDUP, 0, 0], fee=10000000), True),
837
+ ([mk_item(coins[0:2])], mk_item(coins[0:3], flags=[ELIGIBLE_FOR_FF, 0, 0], fee=10000000), True),
838
+ # flag cleared
839
+ ([mk_item(coins[0:2], flags=[ELIGIBLE_FOR_DEDUP, 0])], mk_item(coins[0:3], fee=10000000), False),
840
+ ([mk_item(coins[0:2], flags=[ELIGIBLE_FOR_FF, 0])], mk_item(coins[0:3], fee=10000000), False),
841
+ # unchanged
842
+ (
843
+ [mk_item(coins[0:2], flags=[ELIGIBLE_FOR_DEDUP, 0])],
844
+ mk_item(coins[0:3], flags=[ELIGIBLE_FOR_DEDUP, 0, 0], fee=10000000),
845
+ True,
846
+ ),
847
+ (
848
+ [mk_item(coins[0:2], flags=[ELIGIBLE_FOR_FF, 0])],
849
+ mk_item(coins[0:3], flags=[ELIGIBLE_FOR_FF, 0, 0], fee=10000000),
850
+ True,
851
+ ),
852
+ # the spends are independent
853
+ (
854
+ [mk_item(coins[0:2], flags=[ELIGIBLE_FOR_DEDUP, 0])],
855
+ mk_item(coins[0:3], flags=[0, ELIGIBLE_FOR_DEDUP, 0], fee=10000000),
856
+ False,
857
+ ),
858
+ (
859
+ [mk_item(coins[0:2], flags=[ELIGIBLE_FOR_FF, 0])],
860
+ mk_item(coins[0:3], flags=[0, ELIGIBLE_FOR_FF, 0], fee=10000000),
861
+ False,
862
+ ),
863
+ # the bits are independent
864
+ (
865
+ [mk_item(coins[0:2], flags=[ELIGIBLE_FOR_DEDUP, 0])],
866
+ mk_item(coins[0:3], flags=[ELIGIBLE_FOR_FF, 0, 0], fee=10000000),
867
+ False,
868
+ ),
869
+ (
870
+ [mk_item(coins[0:2], flags=[ELIGIBLE_FOR_DEDUP, 0])],
871
+ mk_item(coins[0:3], flags=[ELIGIBLE_FOR_FF, 0, 0], fee=10000000),
872
+ False,
873
+ ),
815
874
  # FEE- AND FEE RATE RULES
816
875
  # if we're replacing two items, each paying a fee of 100, we need to
817
876
  # spend (at least) the same coins and pay at least 10000000 higher fee
@@ -1007,9 +1066,6 @@ async def test_total_mempool_fees() -> None:
1007
1066
  @pytest.mark.parametrize("reverse_tx_order", [True, False])
1008
1067
  @pytest.mark.anyio
1009
1068
  async def test_create_bundle_from_mempool(reverse_tx_order: bool) -> None:
1010
- async def get_unspent_lineage_info_for_puzzle_hash(_: bytes32) -> Optional[UnspentLineageInfo]:
1011
- assert False # pragma: no cover
1012
-
1013
1069
  async def make_coin_spends(coins: list[Coin], *, high_fees: bool = True) -> list[CoinSpend]:
1014
1070
  spends_list = []
1015
1071
  for i in range(0, len(coins)):
@@ -1036,9 +1092,7 @@ async def test_create_bundle_from_mempool(reverse_tx_order: bool) -> None:
1036
1092
  spends = low_rate_spends + high_rate_spends if reverse_tx_order else high_rate_spends + low_rate_spends
1037
1093
  await send_spends_to_mempool(spends)
1038
1094
  assert mempool_manager.peak is not None
1039
- result = await mempool_manager.create_bundle_from_mempool(
1040
- mempool_manager.peak.header_hash, get_unspent_lineage_info_for_puzzle_hash
1041
- )
1095
+ result = await mempool_manager.create_bundle_from_mempool(mempool_manager.peak.header_hash)
1042
1096
  assert result is not None
1043
1097
  # Make sure we filled the block with only high rate spends
1044
1098
  assert len([s for s in high_rate_spends if s in result[0].coin_spends]) == len(result[0].coin_spends)
@@ -1057,9 +1111,6 @@ async def test_create_bundle_from_mempool_on_max_cost(num_skipped_items: int, ca
1057
1111
  2. After skipping MAX_SKIPPED_ITEMS, we stop processing further items.
1058
1112
  """
1059
1113
 
1060
- async def get_unspent_lineage_info_for_puzzle_hash(_: bytes32) -> Optional[UnspentLineageInfo]:
1061
- assert False # pragma: no cover
1062
-
1063
1114
  MAX_BLOCK_CLVM_COST = 550_000_000
1064
1115
 
1065
1116
  mempool_manager, coins = await setup_mempool_with_coins(
@@ -1123,7 +1174,7 @@ async def test_create_bundle_from_mempool_on_max_cost(num_skipped_items: int, ca
1123
1174
  g1 = sk.get_g1()
1124
1175
  sig = AugSchemeMPL.sign(sk, b"foobar", g1)
1125
1176
  for i in range(num_skipped_items + 1, num_skipped_items + 5):
1126
- conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, coins[i].amount - 30_000]]
1177
+ conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, coins[i].amount]]
1127
1178
  # Make the first of these without eligible coins
1128
1179
  if i == num_skipped_items + 1:
1129
1180
  conditions.append([ConditionOpcode.AGG_SIG_UNSAFE, bytes(g1), b"foobar"])
@@ -1132,22 +1183,17 @@ async def test_create_bundle_from_mempool_on_max_cost(num_skipped_items: int, ca
1132
1183
  aggsig = G2Element()
1133
1184
  sb, _, res = await generate_and_add_spendbundle(mempool_manager, conditions, coins[i], aggsig)
1134
1185
  extra_sbs.append(sb)
1135
- coin = Coin(coins[i].name(), IDENTITY_PUZZLE_HASH, uint64(coins[i].amount - 30_000))
1186
+ coin = Coin(coins[i].name(), IDENTITY_PUZZLE_HASH, uint64(coins[i].amount))
1136
1187
  extra_additions.append(coin)
1137
1188
  assert res[1] == MempoolInclusionStatus.SUCCESS
1138
1189
 
1139
1190
  assert mempool_manager.peak is not None
1140
1191
  caplog.set_level(logging.DEBUG)
1141
- result = await mempool_manager.create_bundle_from_mempool(
1142
- mempool_manager.peak.header_hash, get_unspent_lineage_info_for_puzzle_hash
1143
- )
1192
+ result = await mempool_manager.create_bundle_from_mempool(mempool_manager.peak.header_hash)
1144
1193
  assert result is not None
1145
1194
  agg, additions = result
1146
1195
  skipped_due_to_eligible_coins = sum(
1147
- 1
1148
- for line in caplog.text.split("\n")
1149
- if "Exception while checking a mempool item for deduplication: Skipping transaction with eligible coin(s)"
1150
- in line
1196
+ 1 for line in caplog.text.split("\n") if "Skipping transaction with dedup or FF spends" in line
1151
1197
  )
1152
1198
  if num_skipped_items == PRIORITY_TX_THRESHOLD:
1153
1199
  # We skipped enough big cost items to reach `PRIORITY_TX_THRESHOLD`,
@@ -1440,7 +1486,7 @@ def test_dedup_info_eligible_1st_time() -> None:
1440
1486
  # Eligible coin encountered for the first time
1441
1487
  conditions = [
1442
1488
  [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1],
1443
- [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 2],
1489
+ [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT - 1],
1444
1490
  ]
1445
1491
  sb = spend_bundle_from_conditions(conditions, TEST_COIN)
1446
1492
  mempool_item = mempool_item_from_spendbundle(sb)
@@ -1454,7 +1500,7 @@ def test_dedup_info_eligible_1st_time() -> None:
1454
1500
  assert cost_saving == 0
1455
1501
  assert set(unique_additions) == {
1456
1502
  Coin(TEST_COIN_ID, IDENTITY_PUZZLE_HASH, uint64(1)),
1457
- Coin(TEST_COIN_ID, IDENTITY_PUZZLE_HASH, uint64(2)),
1503
+ Coin(TEST_COIN_ID, IDENTITY_PUZZLE_HASH, uint64(TEST_COIN_AMOUNT - 1)),
1458
1504
  }
1459
1505
  assert eligible_coin_spends == EligibleCoinSpends({TEST_COIN_ID: DedupCoinSpend(solution=solution, cost=None)})
1460
1506
 
@@ -1463,14 +1509,14 @@ def test_dedup_info_eligible_but_different_solution() -> None:
1463
1509
  # Eligible coin but different solution from the one we encountered
1464
1510
  initial_conditions = [
1465
1511
  [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1],
1466
- [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 2],
1512
+ [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT],
1467
1513
  ]
1468
1514
  initial_solution = SerializedProgram.to(initial_conditions)
1469
1515
  eligible_coin_spends = EligibleCoinSpends({TEST_COIN_ID: DedupCoinSpend(solution=initial_solution, cost=None)})
1470
- conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 2]]
1516
+ conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT]]
1471
1517
  sb = spend_bundle_from_conditions(conditions, TEST_COIN)
1472
1518
  mempool_item = mempool_item_from_spendbundle(sb)
1473
- with pytest.raises(ValueError, match="Solution is different from what we're deduplicating on"):
1519
+ with pytest.raises(SkipDedup, match="Solution is different from what we're deduplicating on"):
1474
1520
  eligible_coin_spends.get_deduplication_info(
1475
1521
  bundle_coin_spends=mempool_item.bundle_coin_spends, max_cost=mempool_item.conds.cost
1476
1522
  )
@@ -1480,12 +1526,12 @@ def test_dedup_info_eligible_2nd_time_and_another_1st_time() -> None:
1480
1526
  # Eligible coin encountered a second time, and another for the first time
1481
1527
  initial_conditions = [
1482
1528
  [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1],
1483
- [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 2],
1529
+ [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT - 1],
1484
1530
  ]
1485
1531
  initial_solution = SerializedProgram.to(initial_conditions)
1486
1532
  eligible_coin_spends = EligibleCoinSpends({TEST_COIN_ID: DedupCoinSpend(solution=initial_solution, cost=None)})
1487
1533
  sb1 = spend_bundle_from_conditions(initial_conditions, TEST_COIN)
1488
- second_conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 3]]
1534
+ second_conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT2]]
1489
1535
  second_solution = SerializedProgram.to(second_conditions)
1490
1536
  sb2 = spend_bundle_from_conditions(second_conditions, TEST_COIN2)
1491
1537
  sb = SpendBundle.aggregate([sb1, sb2])
@@ -1498,7 +1544,7 @@ def test_dedup_info_eligible_2nd_time_and_another_1st_time() -> None:
1498
1544
  assert unique_coin_spends == sb2.coin_spends
1499
1545
  saved_cost = uint64(3600044)
1500
1546
  assert cost_saving == saved_cost
1501
- assert unique_additions == [Coin(TEST_COIN_ID2, IDENTITY_PUZZLE_HASH, uint64(3))]
1547
+ assert unique_additions == [Coin(TEST_COIN_ID2, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT2)]
1502
1548
  # The coin we encountered a second time has its cost and additions properly updated
1503
1549
  # The coin we encountered for the first time gets cost None and an empty set of additions
1504
1550
  expected_eligible_spends = EligibleCoinSpends(
@@ -1514,10 +1560,10 @@ def test_dedup_info_eligible_3rd_time_another_2nd_time_and_one_non_eligible() ->
1514
1560
  # Eligible coin encountered a third time, another for the second time and one non eligible
1515
1561
  initial_conditions = [
1516
1562
  [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1],
1517
- [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 2],
1563
+ [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT - 1],
1518
1564
  ]
1519
1565
  initial_solution = SerializedProgram.to(initial_conditions)
1520
- second_conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 3]]
1566
+ second_conditions = [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT2]]
1521
1567
  second_solution = SerializedProgram.to(second_conditions)
1522
1568
  saved_cost = uint64(3600044)
1523
1569
  eligible_coin_spends = EligibleCoinSpends(
@@ -1533,7 +1579,7 @@ def test_dedup_info_eligible_3rd_time_another_2nd_time_and_one_non_eligible() ->
1533
1579
  sig = AugSchemeMPL.sign(sk, b"foobar", g1)
1534
1580
  sb3_conditions = [
1535
1581
  [ConditionOpcode.AGG_SIG_UNSAFE, g1, b"foobar"],
1536
- [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 4],
1582
+ [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT3],
1537
1583
  ]
1538
1584
  sb3 = spend_bundle_from_conditions(sb3_conditions, TEST_COIN3, sig)
1539
1585
  sb = SpendBundle.aggregate([sb1, sb2, sb3])
@@ -1545,7 +1591,7 @@ def test_dedup_info_eligible_3rd_time_another_2nd_time_and_one_non_eligible() ->
1545
1591
  assert unique_coin_spends == sb3.coin_spends
1546
1592
  saved_cost2 = uint64(1800044)
1547
1593
  assert cost_saving == saved_cost + saved_cost2
1548
- assert unique_additions == [Coin(TEST_COIN_ID3, IDENTITY_PUZZLE_HASH, uint64(4))]
1594
+ assert unique_additions == [Coin(TEST_COIN_ID3, IDENTITY_PUZZLE_HASH, TEST_COIN_AMOUNT3)]
1549
1595
  expected_eligible_spends = EligibleCoinSpends(
1550
1596
  {
1551
1597
  TEST_COIN_ID: DedupCoinSpend(initial_solution, saved_cost),
@@ -1581,7 +1627,12 @@ async def test_coin_spending_different_ways_then_finding_it_spent_in_new_peak(ne
1581
1627
  # Create a bunch of mempool items that spend the coin in different ways
1582
1628
  for i in range(3):
1583
1629
  _, _, result = await generate_and_add_spendbundle(
1584
- mempool_manager, [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, i]], coin
1630
+ mempool_manager,
1631
+ [
1632
+ [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, coin.amount],
1633
+ [ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, uint64(i)],
1634
+ ],
1635
+ coin,
1585
1636
  )
1586
1637
  assert result[1] == MempoolInclusionStatus.SUCCESS
1587
1638
  assert len(list(mempool_manager.mempool.get_items_by_coin_id(coin_id))) == 3
@@ -1662,11 +1713,10 @@ async def test_identical_spend_aggregation_e2e(
1662
1713
  phs = [await wallet.get_new_puzzlehash() for _ in range(3)]
1663
1714
  for _ in range(2):
1664
1715
  await farm_a_block(full_node_api, wallet_node, ph)
1665
- other_recipients = [Payment(puzzle_hash=p, amount=uint64(200), memos=[]) for p in phs[1:]]
1666
1716
  async with wallet.wallet_state_manager.new_action_scope(
1667
1717
  DEFAULT_TX_CONFIG, push=False, sign=True
1668
1718
  ) as action_scope:
1669
- await wallet.generate_signed_transaction(uint64(200), phs[0], action_scope, primaries=other_recipients)
1719
+ await wallet.generate_signed_transaction([uint64(200)] * len(phs), phs, action_scope)
1670
1720
  [tx] = action_scope.side_effects.transactions
1671
1721
  assert tx.spend_bundle is not None
1672
1722
  await send_to_mempool(full_node_api, tx.spend_bundle)
@@ -1685,9 +1735,9 @@ async def test_identical_spend_aggregation_e2e(
1685
1735
  async with wallet.wallet_state_manager.new_action_scope(
1686
1736
  DEFAULT_TX_CONFIG, push=False, merge_spends=False, sign=True
1687
1737
  ) as action_scope:
1688
- await wallet.generate_signed_transaction(uint64(30), ph, action_scope, coins={coins[0].coin})
1689
- await wallet.generate_signed_transaction(uint64(30), ph, action_scope, coins={coins[1].coin})
1690
- await wallet.generate_signed_transaction(uint64(30), ph, action_scope, coins={coins[2].coin})
1738
+ await wallet.generate_signed_transaction([uint64(30)], [ph], action_scope, coins={coins[0].coin})
1739
+ await wallet.generate_signed_transaction([uint64(30)], [ph], action_scope, coins={coins[1].coin})
1740
+ await wallet.generate_signed_transaction([uint64(30)], [ph], action_scope, coins={coins[2].coin})
1691
1741
  [tx_a, tx_b, tx_c] = action_scope.side_effects.transactions
1692
1742
  assert tx_a.spend_bundle is not None
1693
1743
  assert tx_b.spend_bundle is not None
@@ -1705,7 +1755,9 @@ async def test_identical_spend_aggregation_e2e(
1705
1755
  async with wallet.wallet_state_manager.new_action_scope(
1706
1756
  DEFAULT_TX_CONFIG, push=False, merge_spends=False, sign=True
1707
1757
  ) as action_scope:
1708
- await wallet.generate_signed_transaction(uint64(200), IDENTITY_PUZZLE_HASH, action_scope, coins={coins[3].coin})
1758
+ await wallet.generate_signed_transaction(
1759
+ [uint64(200)], [IDENTITY_PUZZLE_HASH], action_scope, coins={coins[3].coin}
1760
+ )
1709
1761
  [tx] = action_scope.side_effects.transactions
1710
1762
  assert tx.spend_bundle is not None
1711
1763
  await send_to_mempool(full_node_api, tx.spend_bundle)
@@ -1714,9 +1766,8 @@ async def test_identical_spend_aggregation_e2e(
1714
1766
  coins_with_identity_ph = await full_node_api.full_node.coin_store.get_coin_records_by_puzzle_hash(
1715
1767
  False, IDENTITY_PUZZLE_HASH
1716
1768
  )
1717
- sb = spend_bundle_from_conditions(
1718
- [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 110]], coins_with_identity_ph[0].coin
1719
- )
1769
+ coin = coins_with_identity_ph[0].coin
1770
+ sb = spend_bundle_from_conditions([[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, coin.amount]], coin)
1720
1771
  await send_to_mempool(full_node_api, sb)
1721
1772
  await farm_a_block(full_node_api, wallet_node, ph)
1722
1773
  # Grab the eligible coin to spend as E in DE and EF transactions
@@ -1732,16 +1783,16 @@ async def test_identical_spend_aggregation_e2e(
1732
1783
  DEFAULT_TX_CONFIG, push=False, merge_spends=False, sign=True
1733
1784
  ) as action_scope:
1734
1785
  await wallet.generate_signed_transaction(
1735
- uint64(100),
1736
- ph,
1786
+ [uint64(100)],
1787
+ [ph],
1737
1788
  action_scope,
1738
1789
  fee=uint64(0),
1739
1790
  coins={coins[4].coin},
1740
1791
  extra_conditions=(e_announcement,),
1741
1792
  )
1742
1793
  await wallet.generate_signed_transaction(
1743
- uint64(150),
1744
- ph,
1794
+ [uint64(150)],
1795
+ [ph],
1745
1796
  action_scope,
1746
1797
  fee=uint64(0),
1747
1798
  coins={coins[5].coin},
@@ -1753,7 +1804,7 @@ async def test_identical_spend_aggregation_e2e(
1753
1804
  # Create transaction E now that spends e_coin to create another eligible
1754
1805
  # coin as well as the announcement consumed by D and F
1755
1806
  conditions: list[list[Any]] = [
1756
- [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 42],
1807
+ [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, e_coin.amount],
1757
1808
  [ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, message],
1758
1809
  ]
1759
1810
  sb_e = spend_bundle_from_conditions(conditions, e_coin)
@@ -1767,7 +1818,8 @@ async def test_identical_spend_aggregation_e2e(
1767
1818
  # Send also a transaction EG that spends E differently from DE and EF,
1768
1819
  # so that it doesn't get deduplicated on E with them
1769
1820
  conditions = [
1770
- [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, e_coin.amount - 1],
1821
+ [ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, e_coin.amount],
1822
+ [ConditionOpcode.ASSERT_MY_COIN_ID, e_coin.name()],
1771
1823
  [ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, message],
1772
1824
  ]
1773
1825
  sb_e2 = spend_bundle_from_conditions(conditions, e_coin)
@@ -1777,7 +1829,7 @@ async def test_identical_spend_aggregation_e2e(
1777
1829
  DEFAULT_TX_CONFIG, push=False, merge_spends=False, sign=True
1778
1830
  ) as action_scope:
1779
1831
  await wallet.generate_signed_transaction(
1780
- uint64(13), ph, action_scope, coins={g_coin}, extra_conditions=(e_announcement,)
1832
+ [uint64(13)], [ph], action_scope, coins={g_coin}, extra_conditions=(e_announcement,)
1781
1833
  )
1782
1834
  [tx_g] = action_scope.side_effects.transactions
1783
1835
  assert tx_g.spend_bundle is not None
@@ -1808,7 +1860,7 @@ async def test_identical_spend_aggregation_e2e(
1808
1860
  False, IDENTITY_PUZZLE_HASH
1809
1861
  )
1810
1862
  assert len(eligible_coins) == 1
1811
- assert eligible_coins[0].coin.amount == 42
1863
+ assert eligible_coins[0].coin.amount == e_coin.amount
1812
1864
 
1813
1865
 
1814
1866
  # we have two coins in this test. They have different birth heights (and
@@ -2091,3 +2143,361 @@ async def test_fill_rate_block_validation(
2091
2143
  rb_res_parsed = RespondBlock.from_bytes(rb_res.data)
2092
2144
  assert rb_res_parsed.block.transactions_info is not None
2093
2145
  assert rb_res_parsed.block.transactions_info.cost == expected_block_cost
2146
+
2147
+
2148
+ @pytest.mark.parametrize("optimized_path", [True, False])
2149
+ @pytest.mark.anyio
2150
+ async def test_height_added_to_mempool(optimized_path: bool) -> None:
2151
+ """
2152
+ This test covers scenarios when the mempool is updated or rebuilt, to make
2153
+ sure that mempool items maintain correct height added to mempool values.
2154
+ We control whether we're updating the mempool or rebuilding it, through the
2155
+ `optimized_path` param.
2156
+ """
2157
+ mempool_manager = await instantiate_mempool_manager(get_coin_records_for_test_coins)
2158
+ assert mempool_manager.peak is not None
2159
+ assert mempool_manager.peak.height == TEST_HEIGHT
2160
+ assert mempool_manager.peak.header_hash == height_hash(TEST_HEIGHT)
2161
+ # Create a mempool item and keep track of its height added to mempool
2162
+ _, sb_name, _ = await generate_and_add_spendbundle(
2163
+ mempool_manager, [[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1]]
2164
+ )
2165
+ mi = mempool_manager.get_mempool_item(sb_name)
2166
+ assert mi is not None
2167
+ original_height = mi.height_added_to_mempool
2168
+ # Let's get a new peak that doesn't include our item, and make sure the
2169
+ # height added to mempool remains correct.
2170
+ test_new_peak = TestBlockRecord(
2171
+ header_hash=height_hash(TEST_HEIGHT + 1),
2172
+ height=uint32(TEST_HEIGHT + 1),
2173
+ timestamp=uint64(TEST_TIMESTAMP + 42),
2174
+ prev_transaction_block_height=TEST_HEIGHT,
2175
+ prev_transaction_block_hash=height_hash(TEST_HEIGHT),
2176
+ )
2177
+ if optimized_path:
2178
+ # Spend an unrelated coin to get the mempool updated
2179
+ spent_coins = [TEST_COIN_ID2]
2180
+ else:
2181
+ # Trigger the slow path to get the mempool rebuilt
2182
+ spent_coins = None
2183
+ await mempool_manager.new_peak(test_new_peak, spent_coins)
2184
+ assert mempool_manager.peak.height == TEST_HEIGHT + 1
2185
+ assert mempool_manager.peak.header_hash == height_hash(TEST_HEIGHT + 1)
2186
+ # Make sure our item is still in the mempool, and that its height added to
2187
+ # mempool value is still correct.
2188
+ mempool_item = mempool_manager.get_mempool_item(sb_name)
2189
+ assert mempool_item is not None
2190
+ assert mempool_item.height_added_to_mempool == original_height
2191
+
2192
+
2193
+ # This is a test utility to provide a simple view of the coin table for the
2194
+ # mempool manager.
2195
+ class TestCoins:
2196
+ coin_records: dict[bytes32, CoinRecord]
2197
+ lineage_info: dict[bytes32, UnspentLineageInfo]
2198
+
2199
+ def __init__(self, coins: list[Coin], lineage: dict[bytes32, Coin]) -> None:
2200
+ self.coin_records = {}
2201
+ for c in coins:
2202
+ self.coin_records[c.name()] = CoinRecord(c, uint32(0), uint32(0), False, TEST_TIMESTAMP)
2203
+ self.lineage_info = {}
2204
+ for ph, c in lineage.items():
2205
+ self.lineage_info[ph] = UnspentLineageInfo(
2206
+ c.name(), c.amount, c.parent_coin_info, uint64(1337), bytes32([42] * 32)
2207
+ )
2208
+
2209
+ def spend_coin(self, coin_id: bytes32, height: uint32 = uint32(10)) -> None:
2210
+ self.coin_records[coin_id] = dataclasses.replace(self.coin_records[coin_id], spent_block_index=height)
2211
+
2212
+ def update_lineage(self, puzzle_hash: bytes32, coin: Optional[Coin]) -> None:
2213
+ if coin is None:
2214
+ self.lineage_info.pop(puzzle_hash)
2215
+ else:
2216
+ assert coin.puzzle_hash == puzzle_hash
2217
+ prev = self.lineage_info[puzzle_hash]
2218
+ self.lineage_info[puzzle_hash] = UnspentLineageInfo(
2219
+ coin.name(), coin.amount, coin.parent_coin_info, prev.coin_amount, prev.coin_id
2220
+ )
2221
+
2222
+ async def get_coin_records(self, coin_ids: Collection[bytes32]) -> list[CoinRecord]:
2223
+ ret = []
2224
+ for coin_id in coin_ids:
2225
+ rec = self.coin_records.get(coin_id)
2226
+ if rec is not None:
2227
+ ret.append(rec)
2228
+
2229
+ return ret
2230
+
2231
+ async def get_unspent_lineage_info(self, ph: bytes32) -> Optional[UnspentLineageInfo]:
2232
+ return self.lineage_info.get(ph)
2233
+
2234
+
2235
+ # creates a CoinSpend of a made up
2236
+ def make_singleton_spend(launcher_id: bytes32, parent_parent_id: bytes32 = bytes32([3] * 32)) -> CoinSpend:
2237
+ from chia_rs import supports_fast_forward
2238
+
2239
+ from chia.wallet.lineage_proof import LineageProof
2240
+ from chia.wallet.puzzles.singleton_top_layer_v1_1 import (
2241
+ puzzle_for_singleton,
2242
+ solution_for_singleton,
2243
+ )
2244
+
2245
+ singleton_puzzle = SerializedProgram.from_program(puzzle_for_singleton(launcher_id, Program.to(1)))
2246
+
2247
+ PARENT_COIN = Coin(parent_parent_id, singleton_puzzle.get_tree_hash(), uint64(1))
2248
+ COIN = Coin(PARENT_COIN.name(), singleton_puzzle.get_tree_hash(), uint64(1))
2249
+
2250
+ lineage_proof = LineageProof(parent_parent_id, IDENTITY_PUZZLE_HASH, uint64(1))
2251
+
2252
+ inner_solution = Program.to([[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, uint64(1)]])
2253
+ singleton_solution = SerializedProgram.from_program(
2254
+ solution_for_singleton(lineage_proof, uint64(1), inner_solution)
2255
+ )
2256
+
2257
+ ret = CoinSpend(COIN, singleton_puzzle, singleton_solution)
2258
+
2259
+ # we make sure the spend actually supports fast forward
2260
+ assert supports_fast_forward(ret)
2261
+ assert ret.coin.puzzle_hash == ret.puzzle_reveal.get_tree_hash()
2262
+ return ret
2263
+
2264
+
2265
+ async def setup_mempool(coins: TestCoins) -> MempoolManager:
2266
+ mempool_manager = MempoolManager(
2267
+ coins.get_coin_records,
2268
+ coins.get_unspent_lineage_info,
2269
+ DEFAULT_CONSTANTS,
2270
+ )
2271
+ test_block_record = create_test_block_record(height=uint32(10), timestamp=uint64(12345678))
2272
+ await mempool_manager.new_peak(test_block_record, None)
2273
+ return mempool_manager
2274
+
2275
+
2276
+ # adds a new peak to the memepool manager with the specified coin IDs spent
2277
+ async def advance_mempool(
2278
+ mempool: MempoolManager, spent_coins: list[bytes32], *, use_optimization: bool = True
2279
+ ) -> None:
2280
+ br = mempool.peak
2281
+ assert br is not None
2282
+
2283
+ if use_optimization:
2284
+ next_height = uint32(br.height + 1)
2285
+ else:
2286
+ next_height = uint32(br.height + 2)
2287
+
2288
+ assert br.timestamp is not None
2289
+ prev_block_hash = br.header_hash
2290
+ br = create_test_block_record(height=next_height, timestamp=uint64(br.timestamp + 10))
2291
+
2292
+ if use_optimization:
2293
+ assert prev_block_hash == br.prev_transaction_block_hash
2294
+ else:
2295
+ assert prev_block_hash != br.prev_transaction_block_hash
2296
+
2297
+ await mempool.new_peak(br, spent_coins)
2298
+ invariant_check_mempool(mempool.mempool)
2299
+
2300
+
2301
+ @pytest.mark.anyio
2302
+ @pytest.mark.parametrize("spend_singleton", [True, False])
2303
+ @pytest.mark.parametrize("spend_plain", [True, False])
2304
+ @pytest.mark.parametrize("use_optimization", [True, False])
2305
+ @pytest.mark.parametrize("reverse_spend_order", [True, False])
2306
+ async def test_new_peak_ff_eviction(
2307
+ spend_singleton: bool, spend_plain: bool, use_optimization: bool, reverse_spend_order: bool
2308
+ ) -> None:
2309
+ LAUNCHER_ID = bytes32([1] * 32)
2310
+ singleton_spend = make_singleton_spend(LAUNCHER_ID)
2311
+
2312
+ coin_spend = make_spend(
2313
+ TEST_COIN,
2314
+ IDENTITY_PUZZLE,
2315
+ Program.to([[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1336]]),
2316
+ )
2317
+ bundle = SpendBundle([singleton_spend, coin_spend], G2Element())
2318
+
2319
+ coins = TestCoins([singleton_spend.coin, TEST_COIN], {singleton_spend.coin.puzzle_hash: singleton_spend.coin})
2320
+
2321
+ mempool_manager = await setup_mempool(coins)
2322
+
2323
+ bundle_add_info = await mempool_manager.add_spend_bundle(
2324
+ bundle,
2325
+ make_test_conds(spend_ids=[(singleton_spend.coin, ELIGIBLE_FOR_FF), (TEST_COIN, 0)], cost=1000000),
2326
+ bundle.name(),
2327
+ first_added_height=uint32(1),
2328
+ )
2329
+
2330
+ assert bundle_add_info.status == MempoolInclusionStatus.SUCCESS
2331
+ item = mempool_manager.get_mempool_item(bundle.name())
2332
+ assert item is not None
2333
+ assert item.bundle_coin_spends[singleton_spend.coin.name()].eligible_for_fast_forward
2334
+ assert item.bundle_coin_spends[singleton_spend.coin.name()].latest_singleton_coin == singleton_spend.coin.name()
2335
+
2336
+ spent_coins: list[bytes32] = []
2337
+
2338
+ if spend_singleton:
2339
+ # pretend that we melted the singleton, the FF spend
2340
+ coins.update_lineage(singleton_spend.coin.puzzle_hash, None)
2341
+ coins.spend_coin(singleton_spend.coin.name(), uint32(11))
2342
+ spent_coins.append(singleton_spend.coin.name())
2343
+
2344
+ if spend_plain:
2345
+ # pretend that we spend singleton, the FF spend
2346
+ coins.spend_coin(coin_spend.coin.name(), uint32(11))
2347
+ spent_coins.append(coin_spend.coin.name())
2348
+
2349
+ assert bundle_add_info.status == MempoolInclusionStatus.SUCCESS
2350
+ invariant_check_mempool(mempool_manager.mempool)
2351
+
2352
+ if reverse_spend_order:
2353
+ spent_coins.reverse()
2354
+
2355
+ await advance_mempool(mempool_manager, spent_coins, use_optimization=use_optimization)
2356
+
2357
+ # make sure the mempool item is evicted
2358
+ if spend_singleton or spend_plain:
2359
+ assert mempool_manager.get_mempool_item(bundle.name()) is None
2360
+ else:
2361
+ item = mempool_manager.get_mempool_item(bundle.name())
2362
+ assert item is not None
2363
+ assert item.bundle_coin_spends[singleton_spend.coin.name()].eligible_for_fast_forward
2364
+ assert item.bundle_coin_spends[singleton_spend.coin.name()].latest_singleton_coin == singleton_spend.coin.name()
2365
+
2366
+
2367
+ @pytest.mark.anyio
2368
+ @pytest.mark.parametrize("use_optimization", [True, False])
2369
+ async def test_multiple_ff(use_optimization: bool) -> None:
2370
+ # create two different singleton spends of the same singleton, that support
2371
+ # fast forward. Then update the latest singleton coin and ensure both
2372
+ # entries in the mempool are updated accordingly
2373
+
2374
+ PARENT_PARENT1 = bytes32([4] * 32)
2375
+ PARENT_PARENT2 = bytes32([5] * 32)
2376
+ PARENT_PARENT3 = bytes32([6] * 32)
2377
+
2378
+ # two different spends of the same singleton. both can be fast-forwarded
2379
+ LAUNCHER_ID = bytes32([1] * 32)
2380
+ singleton_spend1 = make_singleton_spend(LAUNCHER_ID, PARENT_PARENT1)
2381
+ singleton_spend2 = make_singleton_spend(LAUNCHER_ID, PARENT_PARENT2)
2382
+
2383
+ # in the next block, this will be the latest singleton coin
2384
+ singleton_spend3 = make_singleton_spend(LAUNCHER_ID, PARENT_PARENT3)
2385
+
2386
+ coin_spend = make_spend(
2387
+ TEST_COIN,
2388
+ IDENTITY_PUZZLE,
2389
+ Program.to([[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1336]]),
2390
+ )
2391
+ bundle = SpendBundle([singleton_spend1, singleton_spend2, coin_spend], G2Element())
2392
+
2393
+ # the singleton puzzle hash resulves to the most recent singleton coin, number 2
2394
+ # pretend that coin1 is spent
2395
+ singleton_ph = singleton_spend2.coin.puzzle_hash
2396
+ coins = TestCoins([singleton_spend1.coin, singleton_spend2.coin, TEST_COIN], {singleton_ph: singleton_spend2.coin})
2397
+
2398
+ mempool_manager = await setup_mempool(coins)
2399
+
2400
+ bundle_add_info = await mempool_manager.add_spend_bundle(
2401
+ bundle,
2402
+ make_test_conds(
2403
+ spend_ids=[
2404
+ (singleton_spend1.coin, ELIGIBLE_FOR_FF),
2405
+ (singleton_spend2.coin, ELIGIBLE_FOR_FF),
2406
+ (TEST_COIN, 0),
2407
+ ],
2408
+ cost=1000000,
2409
+ ),
2410
+ bundle.name(),
2411
+ first_added_height=uint32(1),
2412
+ )
2413
+ assert bundle_add_info.status == MempoolInclusionStatus.SUCCESS
2414
+ invariant_check_mempool(mempool_manager.mempool)
2415
+
2416
+ item = mempool_manager.get_mempool_item(bundle.name())
2417
+ assert item is not None
2418
+ assert item.bundle_coin_spends[singleton_spend1.coin.name()].eligible_for_fast_forward
2419
+ assert item.bundle_coin_spends[singleton_spend2.coin.name()].eligible_for_fast_forward
2420
+ assert not item.bundle_coin_spends[coin_spend.coin.name()].eligible_for_fast_forward
2421
+
2422
+ # spend the singleton coin2 and make coin3 the latest version
2423
+ coins.update_lineage(singleton_ph, singleton_spend3.coin)
2424
+ coins.spend_coin(singleton_spend2.coin.name(), uint32(11))
2425
+
2426
+ await advance_mempool(mempool_manager, [singleton_spend2.coin.name()], use_optimization=use_optimization)
2427
+
2428
+ # we can still fast-forward the singleton spends, the bundle should still be valid
2429
+ item = mempool_manager.get_mempool_item(bundle.name())
2430
+ assert item is not None
2431
+ spend = item.bundle_coin_spends[singleton_spend1.coin.name()]
2432
+ assert spend.latest_singleton_coin == singleton_spend3.coin.name()
2433
+ spend = item.bundle_coin_spends[singleton_spend2.coin.name()]
2434
+ assert spend.latest_singleton_coin == singleton_spend3.coin.name()
2435
+
2436
+
2437
+ @pytest.mark.anyio
2438
+ @pytest.mark.parametrize("use_optimization", [True, False])
2439
+ async def test_advancing_ff(use_optimization: bool) -> None:
2440
+ # add a FF spend under coin1, advance it twice
2441
+ # the second time we have to search for it with a linear search, because
2442
+ # it's filed under the original coin
2443
+
2444
+ PARENT_PARENT1 = bytes32([4] * 32)
2445
+ PARENT_PARENT2 = bytes32([5] * 32)
2446
+ PARENT_PARENT3 = bytes32([6] * 32)
2447
+
2448
+ # two different spends of the same singleton. both can be fast-forwarded
2449
+ LAUNCHER_ID = bytes32([1] * 32)
2450
+ spend_a = make_singleton_spend(LAUNCHER_ID, PARENT_PARENT1)
2451
+ spend_b = make_singleton_spend(LAUNCHER_ID, PARENT_PARENT2)
2452
+ spend_c = make_singleton_spend(LAUNCHER_ID, PARENT_PARENT3)
2453
+
2454
+ coin_spend = make_spend(
2455
+ TEST_COIN,
2456
+ IDENTITY_PUZZLE,
2457
+ Program.to([[ConditionOpcode.CREATE_COIN, IDENTITY_PUZZLE_HASH, 1336]]),
2458
+ )
2459
+ bundle = SpendBundle([spend_a, coin_spend], G2Element())
2460
+
2461
+ # the singleton puzzle hash resulves to the most recent singleton coin, number 2
2462
+ # pretend that coin1 is spent
2463
+ singleton_ph = spend_a.coin.puzzle_hash
2464
+ coins = TestCoins([spend_a.coin, spend_b.coin, spend_c.coin, TEST_COIN], {singleton_ph: spend_a.coin})
2465
+
2466
+ mempool_manager = await setup_mempool(coins)
2467
+
2468
+ bundle_add_info = await mempool_manager.add_spend_bundle(
2469
+ bundle,
2470
+ make_test_conds(spend_ids=[(spend_a.coin, ELIGIBLE_FOR_FF), (TEST_COIN, 0)], cost=1000000),
2471
+ bundle.name(),
2472
+ first_added_height=uint32(1),
2473
+ )
2474
+ assert bundle_add_info.status == MempoolInclusionStatus.SUCCESS
2475
+ invariant_check_mempool(mempool_manager.mempool)
2476
+
2477
+ item = mempool_manager.get_mempool_item(bundle.name())
2478
+ assert item is not None
2479
+ spend = item.bundle_coin_spends[spend_a.coin.name()]
2480
+ assert spend.eligible_for_fast_forward
2481
+ assert spend.latest_singleton_coin == spend_a.coin.name()
2482
+
2483
+ coins.update_lineage(singleton_ph, spend_b.coin)
2484
+ coins.spend_coin(spend_a.coin.name(), uint32(11))
2485
+
2486
+ await advance_mempool(mempool_manager, [spend_a.coin.name()])
2487
+
2488
+ item = mempool_manager.get_mempool_item(bundle.name())
2489
+ assert item is not None
2490
+ spend = item.bundle_coin_spends[spend_a.coin.name()]
2491
+ assert spend.eligible_for_fast_forward
2492
+ assert spend.latest_singleton_coin == spend_b.coin.name()
2493
+
2494
+ coins.update_lineage(singleton_ph, spend_c.coin)
2495
+ coins.spend_coin(spend_b.coin.name(), uint32(12))
2496
+
2497
+ await advance_mempool(mempool_manager, [spend_b.coin.name()], use_optimization=use_optimization)
2498
+
2499
+ item = mempool_manager.get_mempool_item(bundle.name())
2500
+ assert item is not None
2501
+ spend = item.bundle_coin_spends[spend_a.coin.name()]
2502
+ assert spend.eligible_for_fast_forward
2503
+ assert spend.latest_singleton_coin == spend_c.coin.name()