chia-blockchain 2.5.1rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1042) hide show
  1. chia/__init__.py +10 -0
  2. chia/__main__.py +5 -0
  3. chia/_tests/README.md +53 -0
  4. chia/_tests/__init__.py +0 -0
  5. chia/_tests/blockchain/__init__.py +0 -0
  6. chia/_tests/blockchain/blockchain_test_utils.py +195 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +145 -0
  9. chia/_tests/blockchain/test_blockchain.py +4202 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1031 -0
  11. chia/_tests/blockchain/test_build_chains.py +59 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +194 -0
  14. chia/_tests/build-init-files.py +92 -0
  15. chia/_tests/build-job-matrix.py +204 -0
  16. chia/_tests/check_pytest_monitor_output.py +34 -0
  17. chia/_tests/check_sql_statements.py +72 -0
  18. chia/_tests/chia-start-sim +42 -0
  19. chia/_tests/clvm/__init__.py +0 -0
  20. chia/_tests/clvm/benchmark_costs.py +23 -0
  21. chia/_tests/clvm/coin_store.py +149 -0
  22. chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
  23. chia/_tests/clvm/test_clvm_step.py +37 -0
  24. chia/_tests/clvm/test_condition_codes.py +13 -0
  25. chia/_tests/clvm/test_curry_and_treehash.py +55 -0
  26. chia/_tests/clvm/test_message_conditions.py +184 -0
  27. chia/_tests/clvm/test_program.py +150 -0
  28. chia/_tests/clvm/test_puzzle_compression.py +143 -0
  29. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  30. chia/_tests/clvm/test_puzzles.py +242 -0
  31. chia/_tests/clvm/test_singletons.py +540 -0
  32. chia/_tests/clvm/test_spend_sim.py +181 -0
  33. chia/_tests/cmds/__init__.py +0 -0
  34. chia/_tests/cmds/cmd_test_utils.py +469 -0
  35. chia/_tests/cmds/config.py +3 -0
  36. chia/_tests/cmds/conftest.py +23 -0
  37. chia/_tests/cmds/test_click_types.py +200 -0
  38. chia/_tests/cmds/test_cmd_framework.py +620 -0
  39. chia/_tests/cmds/test_cmds_util.py +97 -0
  40. chia/_tests/cmds/test_daemon.py +92 -0
  41. chia/_tests/cmds/test_dev_gh.py +131 -0
  42. chia/_tests/cmds/test_farm_cmd.py +66 -0
  43. chia/_tests/cmds/test_show.py +116 -0
  44. chia/_tests/cmds/test_sim.py +207 -0
  45. chia/_tests/cmds/test_timelock_args.py +75 -0
  46. chia/_tests/cmds/test_tx_config_args.py +154 -0
  47. chia/_tests/cmds/testing_classes.py +59 -0
  48. chia/_tests/cmds/wallet/__init__.py +0 -0
  49. chia/_tests/cmds/wallet/test_consts.py +47 -0
  50. chia/_tests/cmds/wallet/test_dao.py +565 -0
  51. chia/_tests/cmds/wallet/test_did.py +403 -0
  52. chia/_tests/cmds/wallet/test_nft.py +471 -0
  53. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  54. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  55. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  56. chia/_tests/cmds/wallet/test_vcs.py +400 -0
  57. chia/_tests/cmds/wallet/test_wallet.py +1125 -0
  58. chia/_tests/cmds/wallet/test_wallet_check.py +109 -0
  59. chia/_tests/conftest.py +1419 -0
  60. chia/_tests/connection_utils.py +125 -0
  61. chia/_tests/core/__init__.py +0 -0
  62. chia/_tests/core/cmds/__init__.py +0 -0
  63. chia/_tests/core/cmds/test_beta.py +382 -0
  64. chia/_tests/core/cmds/test_keys.py +1734 -0
  65. chia/_tests/core/cmds/test_wallet.py +126 -0
  66. chia/_tests/core/config.py +3 -0
  67. chia/_tests/core/consensus/__init__.py +0 -0
  68. chia/_tests/core/consensus/test_block_creation.py +54 -0
  69. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  70. chia/_tests/core/custom_types/__init__.py +0 -0
  71. chia/_tests/core/custom_types/test_coin.py +107 -0
  72. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  73. chia/_tests/core/custom_types/test_spend_bundle.py +70 -0
  74. chia/_tests/core/daemon/__init__.py +0 -0
  75. chia/_tests/core/daemon/config.py +4 -0
  76. chia/_tests/core/daemon/test_daemon.py +2128 -0
  77. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  78. chia/_tests/core/daemon/test_keychain_proxy.py +101 -0
  79. chia/_tests/core/data_layer/__init__.py +0 -0
  80. chia/_tests/core/data_layer/config.py +5 -0
  81. chia/_tests/core/data_layer/conftest.py +106 -0
  82. chia/_tests/core/data_layer/test_data_cli.py +56 -0
  83. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  84. chia/_tests/core/data_layer/test_data_layer_util.py +218 -0
  85. chia/_tests/core/data_layer/test_data_rpc.py +3847 -0
  86. chia/_tests/core/data_layer/test_data_store.py +2424 -0
  87. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  88. chia/_tests/core/data_layer/test_plugin.py +91 -0
  89. chia/_tests/core/data_layer/util.py +233 -0
  90. chia/_tests/core/farmer/__init__.py +0 -0
  91. chia/_tests/core/farmer/config.py +3 -0
  92. chia/_tests/core/farmer/test_farmer_api.py +103 -0
  93. chia/_tests/core/full_node/__init__.py +0 -0
  94. chia/_tests/core/full_node/config.py +4 -0
  95. chia/_tests/core/full_node/dos/__init__.py +0 -0
  96. chia/_tests/core/full_node/dos/config.py +3 -0
  97. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  98. chia/_tests/core/full_node/full_sync/config.py +4 -0
  99. chia/_tests/core/full_node/full_sync/test_full_sync.py +443 -0
  100. chia/_tests/core/full_node/ram_db.py +27 -0
  101. chia/_tests/core/full_node/stores/__init__.py +0 -0
  102. chia/_tests/core/full_node/stores/config.py +4 -0
  103. chia/_tests/core/full_node/stores/test_block_store.py +590 -0
  104. chia/_tests/core/full_node/stores/test_coin_store.py +897 -0
  105. chia/_tests/core/full_node/stores/test_full_node_store.py +1219 -0
  106. chia/_tests/core/full_node/stores/test_hint_store.py +229 -0
  107. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  108. chia/_tests/core/full_node/test_address_manager.py +588 -0
  109. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  110. chia/_tests/core/full_node/test_conditions.py +556 -0
  111. chia/_tests/core/full_node/test_full_node.py +2700 -0
  112. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  113. chia/_tests/core/full_node/test_hint_management.py +104 -0
  114. chia/_tests/core/full_node/test_node_load.py +34 -0
  115. chia/_tests/core/full_node/test_performance.py +179 -0
  116. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  117. chia/_tests/core/full_node/test_transactions.py +203 -0
  118. chia/_tests/core/full_node/test_tx_processing_queue.py +155 -0
  119. chia/_tests/core/large_block.py +2388 -0
  120. chia/_tests/core/make_block_generator.py +70 -0
  121. chia/_tests/core/mempool/__init__.py +0 -0
  122. chia/_tests/core/mempool/config.py +4 -0
  123. chia/_tests/core/mempool/test_mempool.py +3255 -0
  124. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  125. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  126. chia/_tests/core/mempool/test_mempool_item_queries.py +190 -0
  127. chia/_tests/core/mempool/test_mempool_manager.py +2084 -0
  128. chia/_tests/core/mempool/test_mempool_performance.py +64 -0
  129. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  130. chia/_tests/core/node_height.py +28 -0
  131. chia/_tests/core/server/__init__.py +0 -0
  132. chia/_tests/core/server/config.py +3 -0
  133. chia/_tests/core/server/flood.py +84 -0
  134. chia/_tests/core/server/serve.py +135 -0
  135. chia/_tests/core/server/test_api_protocol.py +21 -0
  136. chia/_tests/core/server/test_capabilities.py +66 -0
  137. chia/_tests/core/server/test_dos.py +319 -0
  138. chia/_tests/core/server/test_event_loop.py +109 -0
  139. chia/_tests/core/server/test_loop.py +294 -0
  140. chia/_tests/core/server/test_node_discovery.py +73 -0
  141. chia/_tests/core/server/test_rate_limits.py +482 -0
  142. chia/_tests/core/server/test_server.py +226 -0
  143. chia/_tests/core/server/test_upnp.py +8 -0
  144. chia/_tests/core/services/__init__.py +0 -0
  145. chia/_tests/core/services/config.py +3 -0
  146. chia/_tests/core/services/test_services.py +188 -0
  147. chia/_tests/core/ssl/__init__.py +0 -0
  148. chia/_tests/core/ssl/config.py +3 -0
  149. chia/_tests/core/ssl/test_ssl.py +202 -0
  150. chia/_tests/core/test_coins.py +33 -0
  151. chia/_tests/core/test_cost_calculation.py +313 -0
  152. chia/_tests/core/test_crawler.py +175 -0
  153. chia/_tests/core/test_crawler_rpc.py +53 -0
  154. chia/_tests/core/test_daemon_rpc.py +24 -0
  155. chia/_tests/core/test_db_conversion.py +130 -0
  156. chia/_tests/core/test_db_validation.py +162 -0
  157. chia/_tests/core/test_farmer_harvester_rpc.py +505 -0
  158. chia/_tests/core/test_filter.py +35 -0
  159. chia/_tests/core/test_full_node_rpc.py +768 -0
  160. chia/_tests/core/test_merkle_set.py +343 -0
  161. chia/_tests/core/test_program.py +47 -0
  162. chia/_tests/core/test_rpc_util.py +86 -0
  163. chia/_tests/core/test_seeder.py +420 -0
  164. chia/_tests/core/test_setproctitle.py +13 -0
  165. chia/_tests/core/util/__init__.py +0 -0
  166. chia/_tests/core/util/config.py +4 -0
  167. chia/_tests/core/util/test_block_cache.py +44 -0
  168. chia/_tests/core/util/test_cached_bls.py +57 -0
  169. chia/_tests/core/util/test_config.py +337 -0
  170. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  171. chia/_tests/core/util/test_files.py +391 -0
  172. chia/_tests/core/util/test_jsonify.py +146 -0
  173. chia/_tests/core/util/test_keychain.py +522 -0
  174. chia/_tests/core/util/test_keyring_wrapper.py +491 -0
  175. chia/_tests/core/util/test_lockfile.py +380 -0
  176. chia/_tests/core/util/test_log_exceptions.py +187 -0
  177. chia/_tests/core/util/test_lru_cache.py +56 -0
  178. chia/_tests/core/util/test_significant_bits.py +40 -0
  179. chia/_tests/core/util/test_streamable.py +883 -0
  180. chia/_tests/db/__init__.py +0 -0
  181. chia/_tests/db/test_db_wrapper.py +566 -0
  182. chia/_tests/environments/__init__.py +0 -0
  183. chia/_tests/environments/common.py +35 -0
  184. chia/_tests/environments/full_node.py +47 -0
  185. chia/_tests/environments/wallet.py +429 -0
  186. chia/_tests/ether.py +19 -0
  187. chia/_tests/farmer_harvester/__init__.py +0 -0
  188. chia/_tests/farmer_harvester/config.py +3 -0
  189. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  190. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  191. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +131 -0
  192. chia/_tests/farmer_harvester/test_third_party_harvesters.py +528 -0
  193. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  194. chia/_tests/fee_estimation/__init__.py +0 -0
  195. chia/_tests/fee_estimation/config.py +3 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  197. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  198. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +144 -0
  199. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  200. chia/_tests/generator/__init__.py +0 -0
  201. chia/_tests/generator/puzzles/__init__.py +0 -0
  202. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  203. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  204. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  205. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  206. chia/_tests/generator/test_compression.py +201 -0
  207. chia/_tests/generator/test_generator_types.py +44 -0
  208. chia/_tests/generator/test_rom.py +180 -0
  209. chia/_tests/plot_sync/__init__.py +0 -0
  210. chia/_tests/plot_sync/config.py +3 -0
  211. chia/_tests/plot_sync/test_delta.py +101 -0
  212. chia/_tests/plot_sync/test_plot_sync.py +618 -0
  213. chia/_tests/plot_sync/test_receiver.py +451 -0
  214. chia/_tests/plot_sync/test_sender.py +116 -0
  215. chia/_tests/plot_sync/test_sync_simulated.py +451 -0
  216. chia/_tests/plot_sync/util.py +68 -0
  217. chia/_tests/plotting/__init__.py +0 -0
  218. chia/_tests/plotting/config.py +3 -0
  219. chia/_tests/plotting/test_plot_manager.py +781 -0
  220. chia/_tests/plotting/util.py +12 -0
  221. chia/_tests/pools/__init__.py +0 -0
  222. chia/_tests/pools/config.py +5 -0
  223. chia/_tests/pools/test_pool_cli_parsing.py +128 -0
  224. chia/_tests/pools/test_pool_cmdline.py +1001 -0
  225. chia/_tests/pools/test_pool_config.py +42 -0
  226. chia/_tests/pools/test_pool_puzzles_lifecycle.py +397 -0
  227. chia/_tests/pools/test_pool_rpc.py +1123 -0
  228. chia/_tests/pools/test_pool_wallet.py +205 -0
  229. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  230. chia/_tests/process_junit.py +348 -0
  231. chia/_tests/rpc/__init__.py +0 -0
  232. chia/_tests/rpc/test_rpc_client.py +138 -0
  233. chia/_tests/rpc/test_rpc_server.py +183 -0
  234. chia/_tests/simulation/__init__.py +0 -0
  235. chia/_tests/simulation/config.py +6 -0
  236. chia/_tests/simulation/test_simulation.py +501 -0
  237. chia/_tests/simulation/test_simulator.py +232 -0
  238. chia/_tests/simulation/test_start_simulator.py +107 -0
  239. chia/_tests/testconfig.py +13 -0
  240. chia/_tests/timelord/__init__.py +0 -0
  241. chia/_tests/timelord/config.py +3 -0
  242. chia/_tests/timelord/test_new_peak.py +437 -0
  243. chia/_tests/timelord/test_timelord.py +11 -0
  244. chia/_tests/tools/1315537.json +170 -0
  245. chia/_tests/tools/1315544.json +160 -0
  246. chia/_tests/tools/1315630.json +150 -0
  247. chia/_tests/tools/300000.json +105 -0
  248. chia/_tests/tools/442734.json +140 -0
  249. chia/_tests/tools/466212.json +130 -0
  250. chia/_tests/tools/__init__.py +0 -0
  251. chia/_tests/tools/config.py +5 -0
  252. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  253. chia/_tests/tools/test_full_sync.py +30 -0
  254. chia/_tests/tools/test_legacy_keyring.py +82 -0
  255. chia/_tests/tools/test_run_block.py +128 -0
  256. chia/_tests/tools/test_virtual_project.py +591 -0
  257. chia/_tests/util/__init__.py +0 -0
  258. chia/_tests/util/benchmark_cost.py +170 -0
  259. chia/_tests/util/benchmarks.py +153 -0
  260. chia/_tests/util/bip39_test_vectors.json +148 -0
  261. chia/_tests/util/blockchain.py +134 -0
  262. chia/_tests/util/blockchain_mock.py +132 -0
  263. chia/_tests/util/build_network_protocol_files.py +302 -0
  264. chia/_tests/util/clvm_generator.bin +0 -0
  265. chia/_tests/util/config.py +3 -0
  266. chia/_tests/util/constants.py +20 -0
  267. chia/_tests/util/db_connection.py +37 -0
  268. chia/_tests/util/full_sync.py +253 -0
  269. chia/_tests/util/gen_ssl_certs.py +114 -0
  270. chia/_tests/util/generator_tools_testing.py +45 -0
  271. chia/_tests/util/get_name_puzzle_conditions.py +52 -0
  272. chia/_tests/util/key_tool.py +36 -0
  273. chia/_tests/util/misc.py +675 -0
  274. chia/_tests/util/network_protocol_data.py +1072 -0
  275. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  276. chia/_tests/util/protocol_messages_json.py +2701 -0
  277. chia/_tests/util/rpc.py +26 -0
  278. chia/_tests/util/run_block.py +163 -0
  279. chia/_tests/util/setup_nodes.py +481 -0
  280. chia/_tests/util/spend_sim.py +492 -0
  281. chia/_tests/util/split_managers.py +102 -0
  282. chia/_tests/util/temp_file.py +14 -0
  283. chia/_tests/util/test_action_scope.py +144 -0
  284. chia/_tests/util/test_async_pool.py +366 -0
  285. chia/_tests/util/test_build_job_matrix.py +42 -0
  286. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  287. chia/_tests/util/test_chia_version.py +50 -0
  288. chia/_tests/util/test_collection.py +11 -0
  289. chia/_tests/util/test_condition_tools.py +229 -0
  290. chia/_tests/util/test_config.py +426 -0
  291. chia/_tests/util/test_dump_keyring.py +60 -0
  292. chia/_tests/util/test_errors.py +10 -0
  293. chia/_tests/util/test_full_block_utils.py +279 -0
  294. chia/_tests/util/test_installed.py +20 -0
  295. chia/_tests/util/test_limited_semaphore.py +53 -0
  296. chia/_tests/util/test_logging_filter.py +42 -0
  297. chia/_tests/util/test_misc.py +445 -0
  298. chia/_tests/util/test_network.py +73 -0
  299. chia/_tests/util/test_network_protocol_files.py +578 -0
  300. chia/_tests/util/test_network_protocol_json.py +267 -0
  301. chia/_tests/util/test_network_protocol_test.py +256 -0
  302. chia/_tests/util/test_paginator.py +71 -0
  303. chia/_tests/util/test_pprint.py +17 -0
  304. chia/_tests/util/test_priority_mutex.py +488 -0
  305. chia/_tests/util/test_recursive_replace.py +116 -0
  306. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  307. chia/_tests/util/test_service_groups.py +15 -0
  308. chia/_tests/util/test_ssl_check.py +31 -0
  309. chia/_tests/util/test_testnet_overrides.py +19 -0
  310. chia/_tests/util/test_tests_misc.py +38 -0
  311. chia/_tests/util/test_timing.py +37 -0
  312. chia/_tests/util/test_trusted_peer.py +51 -0
  313. chia/_tests/util/time_out_assert.py +191 -0
  314. chia/_tests/wallet/__init__.py +0 -0
  315. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  316. chia/_tests/wallet/cat_wallet/config.py +4 -0
  317. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  318. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  319. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1826 -0
  320. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  321. chia/_tests/wallet/cat_wallet/test_trades.py +2600 -0
  322. chia/_tests/wallet/clawback/__init__.py +0 -0
  323. chia/_tests/wallet/clawback/config.py +3 -0
  324. chia/_tests/wallet/clawback/test_clawback_decorator.py +78 -0
  325. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  326. chia/_tests/wallet/clawback/test_clawback_metadata.py +50 -0
  327. chia/_tests/wallet/config.py +4 -0
  328. chia/_tests/wallet/conftest.py +278 -0
  329. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  330. chia/_tests/wallet/dao_wallet/config.py +3 -0
  331. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1330 -0
  332. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  333. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  334. chia/_tests/wallet/db_wallet/config.py +3 -0
  335. chia/_tests/wallet/db_wallet/test_db_graftroot.py +141 -0
  336. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  337. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  338. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  339. chia/_tests/wallet/did_wallet/config.py +4 -0
  340. chia/_tests/wallet/did_wallet/test_did.py +2284 -0
  341. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  342. chia/_tests/wallet/nft_wallet/config.py +4 -0
  343. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1493 -0
  344. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1024 -0
  345. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +375 -0
  346. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  347. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  348. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2584 -0
  349. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  350. chia/_tests/wallet/rpc/__init__.py +0 -0
  351. chia/_tests/wallet/rpc/config.py +4 -0
  352. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +285 -0
  353. chia/_tests/wallet/rpc/test_wallet_rpc.py +3153 -0
  354. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  355. chia/_tests/wallet/simple_sync/config.py +3 -0
  356. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +718 -0
  357. chia/_tests/wallet/sync/__init__.py +0 -0
  358. chia/_tests/wallet/sync/config.py +4 -0
  359. chia/_tests/wallet/sync/test_wallet_sync.py +1692 -0
  360. chia/_tests/wallet/test_address_type.py +189 -0
  361. chia/_tests/wallet/test_bech32m.py +45 -0
  362. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  363. chia/_tests/wallet/test_coin_management.py +354 -0
  364. chia/_tests/wallet/test_coin_selection.py +588 -0
  365. chia/_tests/wallet/test_conditions.py +400 -0
  366. chia/_tests/wallet/test_debug_spend_bundle.py +218 -0
  367. chia/_tests/wallet/test_new_wallet_protocol.py +1174 -0
  368. chia/_tests/wallet/test_nft_store.py +192 -0
  369. chia/_tests/wallet/test_notifications.py +196 -0
  370. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  371. chia/_tests/wallet/test_puzzle_store.py +132 -0
  372. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  373. chia/_tests/wallet/test_signer_protocol.py +947 -0
  374. chia/_tests/wallet/test_singleton.py +122 -0
  375. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  376. chia/_tests/wallet/test_singleton_store.py +152 -0
  377. chia/_tests/wallet/test_taproot.py +19 -0
  378. chia/_tests/wallet/test_transaction_store.py +945 -0
  379. chia/_tests/wallet/test_util.py +185 -0
  380. chia/_tests/wallet/test_wallet.py +2139 -0
  381. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  382. chia/_tests/wallet/test_wallet_blockchain.py +111 -0
  383. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  384. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  385. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  386. chia/_tests/wallet/test_wallet_node.py +780 -0
  387. chia/_tests/wallet/test_wallet_retry.py +95 -0
  388. chia/_tests/wallet/test_wallet_state_manager.py +259 -0
  389. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  390. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  391. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  392. chia/_tests/wallet/test_wallet_utils.py +156 -0
  393. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  394. chia/_tests/wallet/vc_wallet/config.py +3 -0
  395. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  396. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  397. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +830 -0
  398. chia/_tests/wallet/wallet_block_tools.py +327 -0
  399. chia/_tests/weight_proof/__init__.py +0 -0
  400. chia/_tests/weight_proof/config.py +3 -0
  401. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  402. chia/apis.py +19 -0
  403. chia/clvm/__init__.py +0 -0
  404. chia/cmds/__init__.py +0 -0
  405. chia/cmds/beta.py +184 -0
  406. chia/cmds/beta_funcs.py +137 -0
  407. chia/cmds/check_wallet_db.py +420 -0
  408. chia/cmds/chia.py +151 -0
  409. chia/cmds/cmd_classes.py +323 -0
  410. chia/cmds/cmd_helpers.py +242 -0
  411. chia/cmds/cmds_util.py +488 -0
  412. chia/cmds/coin_funcs.py +275 -0
  413. chia/cmds/coins.py +182 -0
  414. chia/cmds/completion.py +49 -0
  415. chia/cmds/configure.py +332 -0
  416. chia/cmds/dao.py +1064 -0
  417. chia/cmds/dao_funcs.py +598 -0
  418. chia/cmds/data.py +708 -0
  419. chia/cmds/data_funcs.py +385 -0
  420. chia/cmds/db.py +87 -0
  421. chia/cmds/db_backup_func.py +77 -0
  422. chia/cmds/db_upgrade_func.py +452 -0
  423. chia/cmds/db_validate_func.py +184 -0
  424. chia/cmds/dev.py +18 -0
  425. chia/cmds/farm.py +100 -0
  426. chia/cmds/farm_funcs.py +200 -0
  427. chia/cmds/gh.py +275 -0
  428. chia/cmds/init.py +63 -0
  429. chia/cmds/init_funcs.py +367 -0
  430. chia/cmds/installers.py +131 -0
  431. chia/cmds/keys.py +527 -0
  432. chia/cmds/keys_funcs.py +863 -0
  433. chia/cmds/netspace.py +50 -0
  434. chia/cmds/netspace_funcs.py +54 -0
  435. chia/cmds/options.py +32 -0
  436. chia/cmds/param_types.py +238 -0
  437. chia/cmds/passphrase.py +131 -0
  438. chia/cmds/passphrase_funcs.py +292 -0
  439. chia/cmds/peer.py +51 -0
  440. chia/cmds/peer_funcs.py +129 -0
  441. chia/cmds/plotnft.py +260 -0
  442. chia/cmds/plotnft_funcs.py +405 -0
  443. chia/cmds/plots.py +230 -0
  444. chia/cmds/plotters.py +18 -0
  445. chia/cmds/rpc.py +208 -0
  446. chia/cmds/show.py +72 -0
  447. chia/cmds/show_funcs.py +215 -0
  448. chia/cmds/signer.py +296 -0
  449. chia/cmds/sim.py +225 -0
  450. chia/cmds/sim_funcs.py +509 -0
  451. chia/cmds/start.py +24 -0
  452. chia/cmds/start_funcs.py +109 -0
  453. chia/cmds/stop.py +62 -0
  454. chia/cmds/units.py +9 -0
  455. chia/cmds/wallet.py +1901 -0
  456. chia/cmds/wallet_funcs.py +1874 -0
  457. chia/consensus/__init__.py +0 -0
  458. chia/consensus/block_body_validation.py +562 -0
  459. chia/consensus/block_creation.py +546 -0
  460. chia/consensus/block_header_validation.py +1059 -0
  461. chia/consensus/block_record.py +31 -0
  462. chia/consensus/block_rewards.py +53 -0
  463. chia/consensus/blockchain.py +1087 -0
  464. chia/consensus/blockchain_interface.py +56 -0
  465. chia/consensus/coinbase.py +30 -0
  466. chia/consensus/condition_costs.py +9 -0
  467. chia/consensus/constants.py +49 -0
  468. chia/consensus/cost_calculator.py +15 -0
  469. chia/consensus/default_constants.py +89 -0
  470. chia/consensus/deficit.py +55 -0
  471. chia/consensus/difficulty_adjustment.py +412 -0
  472. chia/consensus/find_fork_point.py +111 -0
  473. chia/consensus/full_block_to_block_record.py +167 -0
  474. chia/consensus/get_block_challenge.py +106 -0
  475. chia/consensus/get_block_generator.py +27 -0
  476. chia/consensus/make_sub_epoch_summary.py +210 -0
  477. chia/consensus/multiprocess_validation.py +268 -0
  478. chia/consensus/pos_quality.py +19 -0
  479. chia/consensus/pot_iterations.py +67 -0
  480. chia/consensus/puzzles/__init__.py +0 -0
  481. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  482. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  483. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  484. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  485. chia/consensus/vdf_info_computation.py +156 -0
  486. chia/daemon/__init__.py +0 -0
  487. chia/daemon/client.py +252 -0
  488. chia/daemon/keychain_proxy.py +502 -0
  489. chia/daemon/keychain_server.py +365 -0
  490. chia/daemon/server.py +1606 -0
  491. chia/daemon/windows_signal.py +56 -0
  492. chia/data_layer/__init__.py +0 -0
  493. chia/data_layer/data_layer.py +1291 -0
  494. chia/data_layer/data_layer_api.py +33 -0
  495. chia/data_layer/data_layer_errors.py +50 -0
  496. chia/data_layer/data_layer_server.py +170 -0
  497. chia/data_layer/data_layer_util.py +985 -0
  498. chia/data_layer/data_layer_wallet.py +1311 -0
  499. chia/data_layer/data_store.py +2267 -0
  500. chia/data_layer/dl_wallet_store.py +407 -0
  501. chia/data_layer/download_data.py +389 -0
  502. chia/data_layer/puzzles/__init__.py +0 -0
  503. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  504. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  505. chia/data_layer/s3_plugin_config.yml +33 -0
  506. chia/data_layer/s3_plugin_service.py +468 -0
  507. chia/data_layer/util/__init__.py +0 -0
  508. chia/data_layer/util/benchmark.py +107 -0
  509. chia/data_layer/util/plugin.py +40 -0
  510. chia/farmer/__init__.py +0 -0
  511. chia/farmer/farmer.py +923 -0
  512. chia/farmer/farmer_api.py +820 -0
  513. chia/full_node/__init__.py +0 -0
  514. chia/full_node/bitcoin_fee_estimator.py +85 -0
  515. chia/full_node/block_height_map.py +271 -0
  516. chia/full_node/block_store.py +576 -0
  517. chia/full_node/bundle_tools.py +19 -0
  518. chia/full_node/coin_store.py +647 -0
  519. chia/full_node/fee_estimate.py +54 -0
  520. chia/full_node/fee_estimate_store.py +24 -0
  521. chia/full_node/fee_estimation.py +92 -0
  522. chia/full_node/fee_estimator.py +90 -0
  523. chia/full_node/fee_estimator_constants.py +38 -0
  524. chia/full_node/fee_estimator_interface.py +42 -0
  525. chia/full_node/fee_history.py +25 -0
  526. chia/full_node/fee_tracker.py +564 -0
  527. chia/full_node/full_node.py +3327 -0
  528. chia/full_node/full_node_api.py +2025 -0
  529. chia/full_node/full_node_store.py +1033 -0
  530. chia/full_node/hint_management.py +56 -0
  531. chia/full_node/hint_store.py +93 -0
  532. chia/full_node/mempool.py +589 -0
  533. chia/full_node/mempool_check_conditions.py +146 -0
  534. chia/full_node/mempool_manager.py +853 -0
  535. chia/full_node/pending_tx_cache.py +112 -0
  536. chia/full_node/puzzles/__init__.py +0 -0
  537. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  538. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  539. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  540. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  541. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  542. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  543. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  544. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  545. chia/full_node/signage_point.py +16 -0
  546. chia/full_node/subscriptions.py +247 -0
  547. chia/full_node/sync_store.py +146 -0
  548. chia/full_node/tx_processing_queue.py +78 -0
  549. chia/full_node/util/__init__.py +0 -0
  550. chia/full_node/weight_proof.py +1720 -0
  551. chia/harvester/__init__.py +0 -0
  552. chia/harvester/harvester.py +272 -0
  553. chia/harvester/harvester_api.py +380 -0
  554. chia/introducer/__init__.py +0 -0
  555. chia/introducer/introducer.py +122 -0
  556. chia/introducer/introducer_api.py +70 -0
  557. chia/legacy/__init__.py +0 -0
  558. chia/legacy/keyring.py +155 -0
  559. chia/plot_sync/__init__.py +0 -0
  560. chia/plot_sync/delta.py +61 -0
  561. chia/plot_sync/exceptions.py +56 -0
  562. chia/plot_sync/receiver.py +386 -0
  563. chia/plot_sync/sender.py +340 -0
  564. chia/plot_sync/util.py +43 -0
  565. chia/plotters/__init__.py +0 -0
  566. chia/plotters/bladebit.py +388 -0
  567. chia/plotters/chiapos.py +63 -0
  568. chia/plotters/madmax.py +224 -0
  569. chia/plotters/plotters.py +577 -0
  570. chia/plotters/plotters_util.py +133 -0
  571. chia/plotting/__init__.py +0 -0
  572. chia/plotting/cache.py +213 -0
  573. chia/plotting/check_plots.py +283 -0
  574. chia/plotting/create_plots.py +278 -0
  575. chia/plotting/manager.py +436 -0
  576. chia/plotting/util.py +336 -0
  577. chia/pools/__init__.py +0 -0
  578. chia/pools/pool_config.py +110 -0
  579. chia/pools/pool_puzzles.py +459 -0
  580. chia/pools/pool_wallet.py +933 -0
  581. chia/pools/pool_wallet_info.py +118 -0
  582. chia/pools/puzzles/__init__.py +0 -0
  583. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  584. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  585. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  586. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  587. chia/protocols/__init__.py +0 -0
  588. chia/protocols/farmer_protocol.py +102 -0
  589. chia/protocols/full_node_protocol.py +219 -0
  590. chia/protocols/harvester_protocol.py +216 -0
  591. chia/protocols/introducer_protocol.py +25 -0
  592. chia/protocols/pool_protocol.py +177 -0
  593. chia/protocols/protocol_message_types.py +139 -0
  594. chia/protocols/protocol_state_machine.py +87 -0
  595. chia/protocols/protocol_timing.py +8 -0
  596. chia/protocols/shared_protocol.py +86 -0
  597. chia/protocols/timelord_protocol.py +93 -0
  598. chia/protocols/wallet_protocol.py +401 -0
  599. chia/py.typed +0 -0
  600. chia/rpc/__init__.py +0 -0
  601. chia/rpc/crawler_rpc_api.py +80 -0
  602. chia/rpc/data_layer_rpc_api.py +644 -0
  603. chia/rpc/data_layer_rpc_client.py +188 -0
  604. chia/rpc/data_layer_rpc_util.py +58 -0
  605. chia/rpc/farmer_rpc_api.py +365 -0
  606. chia/rpc/farmer_rpc_client.py +86 -0
  607. chia/rpc/full_node_rpc_api.py +959 -0
  608. chia/rpc/full_node_rpc_client.py +292 -0
  609. chia/rpc/harvester_rpc_api.py +141 -0
  610. chia/rpc/harvester_rpc_client.py +54 -0
  611. chia/rpc/rpc_client.py +164 -0
  612. chia/rpc/rpc_server.py +521 -0
  613. chia/rpc/timelord_rpc_api.py +32 -0
  614. chia/rpc/util.py +93 -0
  615. chia/rpc/wallet_request_types.py +904 -0
  616. chia/rpc/wallet_rpc_api.py +4943 -0
  617. chia/rpc/wallet_rpc_client.py +1814 -0
  618. chia/seeder/__init__.py +0 -0
  619. chia/seeder/crawl_store.py +425 -0
  620. chia/seeder/crawler.py +410 -0
  621. chia/seeder/crawler_api.py +135 -0
  622. chia/seeder/dns_server.py +593 -0
  623. chia/seeder/peer_record.py +146 -0
  624. chia/seeder/start_crawler.py +92 -0
  625. chia/server/__init__.py +0 -0
  626. chia/server/address_manager.py +658 -0
  627. chia/server/address_manager_store.py +237 -0
  628. chia/server/api_protocol.py +116 -0
  629. chia/server/capabilities.py +24 -0
  630. chia/server/chia_policy.py +346 -0
  631. chia/server/introducer_peers.py +76 -0
  632. chia/server/node_discovery.py +714 -0
  633. chia/server/outbound_message.py +33 -0
  634. chia/server/rate_limit_numbers.py +214 -0
  635. chia/server/rate_limits.py +153 -0
  636. chia/server/server.py +741 -0
  637. chia/server/signal_handlers.py +120 -0
  638. chia/server/ssl_context.py +32 -0
  639. chia/server/start_data_layer.py +151 -0
  640. chia/server/start_farmer.py +98 -0
  641. chia/server/start_full_node.py +112 -0
  642. chia/server/start_harvester.py +93 -0
  643. chia/server/start_introducer.py +81 -0
  644. chia/server/start_service.py +316 -0
  645. chia/server/start_timelord.py +89 -0
  646. chia/server/start_wallet.py +113 -0
  647. chia/server/upnp.py +118 -0
  648. chia/server/ws_connection.py +766 -0
  649. chia/simulator/__init__.py +0 -0
  650. chia/simulator/add_blocks_in_batches.py +54 -0
  651. chia/simulator/block_tools.py +2054 -0
  652. chia/simulator/full_node_simulator.py +794 -0
  653. chia/simulator/keyring.py +128 -0
  654. chia/simulator/setup_services.py +506 -0
  655. chia/simulator/simulator_constants.py +13 -0
  656. chia/simulator/simulator_full_node_rpc_api.py +99 -0
  657. chia/simulator/simulator_full_node_rpc_client.py +60 -0
  658. chia/simulator/simulator_protocol.py +29 -0
  659. chia/simulator/simulator_test_tools.py +164 -0
  660. chia/simulator/socket.py +24 -0
  661. chia/simulator/ssl_certs.py +114 -0
  662. chia/simulator/ssl_certs_1.py +697 -0
  663. chia/simulator/ssl_certs_10.py +697 -0
  664. chia/simulator/ssl_certs_2.py +697 -0
  665. chia/simulator/ssl_certs_3.py +697 -0
  666. chia/simulator/ssl_certs_4.py +697 -0
  667. chia/simulator/ssl_certs_5.py +697 -0
  668. chia/simulator/ssl_certs_6.py +697 -0
  669. chia/simulator/ssl_certs_7.py +697 -0
  670. chia/simulator/ssl_certs_8.py +697 -0
  671. chia/simulator/ssl_certs_9.py +697 -0
  672. chia/simulator/start_simulator.py +143 -0
  673. chia/simulator/wallet_tools.py +246 -0
  674. chia/ssl/__init__.py +0 -0
  675. chia/ssl/chia_ca.crt +19 -0
  676. chia/ssl/chia_ca.key +28 -0
  677. chia/ssl/create_ssl.py +249 -0
  678. chia/ssl/dst_root_ca.pem +20 -0
  679. chia/timelord/__init__.py +0 -0
  680. chia/timelord/iters_from_block.py +50 -0
  681. chia/timelord/timelord.py +1226 -0
  682. chia/timelord/timelord_api.py +138 -0
  683. chia/timelord/timelord_launcher.py +190 -0
  684. chia/timelord/timelord_state.py +244 -0
  685. chia/timelord/types.py +22 -0
  686. chia/types/__init__.py +0 -0
  687. chia/types/aliases.py +35 -0
  688. chia/types/block_protocol.py +20 -0
  689. chia/types/blockchain_format/__init__.py +0 -0
  690. chia/types/blockchain_format/classgroup.py +5 -0
  691. chia/types/blockchain_format/coin.py +28 -0
  692. chia/types/blockchain_format/foliage.py +8 -0
  693. chia/types/blockchain_format/pool_target.py +5 -0
  694. chia/types/blockchain_format/program.py +269 -0
  695. chia/types/blockchain_format/proof_of_space.py +135 -0
  696. chia/types/blockchain_format/reward_chain_block.py +6 -0
  697. chia/types/blockchain_format/serialized_program.py +5 -0
  698. chia/types/blockchain_format/sized_bytes.py +11 -0
  699. chia/types/blockchain_format/slots.py +9 -0
  700. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  701. chia/types/blockchain_format/tree_hash.py +72 -0
  702. chia/types/blockchain_format/vdf.py +86 -0
  703. chia/types/clvm_cost.py +13 -0
  704. chia/types/coin_record.py +43 -0
  705. chia/types/coin_spend.py +115 -0
  706. chia/types/condition_opcodes.py +73 -0
  707. chia/types/condition_with_args.py +16 -0
  708. chia/types/eligible_coin_spends.py +365 -0
  709. chia/types/end_of_slot_bundle.py +5 -0
  710. chia/types/fee_rate.py +38 -0
  711. chia/types/full_block.py +5 -0
  712. chia/types/generator_types.py +13 -0
  713. chia/types/header_block.py +5 -0
  714. chia/types/internal_mempool_item.py +18 -0
  715. chia/types/mempool_inclusion_status.py +9 -0
  716. chia/types/mempool_item.py +85 -0
  717. chia/types/mempool_submission_status.py +30 -0
  718. chia/types/mojos.py +7 -0
  719. chia/types/peer_info.py +64 -0
  720. chia/types/signing_mode.py +29 -0
  721. chia/types/spend_bundle.py +30 -0
  722. chia/types/spend_bundle_conditions.py +7 -0
  723. chia/types/transaction_queue_entry.py +55 -0
  724. chia/types/unfinished_block.py +5 -0
  725. chia/types/unfinished_header_block.py +37 -0
  726. chia/types/validation_state.py +14 -0
  727. chia/types/weight_proof.py +49 -0
  728. chia/util/__init__.py +0 -0
  729. chia/util/action_scope.py +168 -0
  730. chia/util/async_pool.py +226 -0
  731. chia/util/augmented_chain.py +134 -0
  732. chia/util/batches.py +42 -0
  733. chia/util/bech32m.py +126 -0
  734. chia/util/beta_metrics.py +119 -0
  735. chia/util/block_cache.py +56 -0
  736. chia/util/byte_types.py +12 -0
  737. chia/util/check_fork_next_block.py +33 -0
  738. chia/util/chia_logging.py +144 -0
  739. chia/util/chia_version.py +33 -0
  740. chia/util/collection.py +17 -0
  741. chia/util/condition_tools.py +201 -0
  742. chia/util/config.py +367 -0
  743. chia/util/cpu.py +22 -0
  744. chia/util/db_synchronous.py +23 -0
  745. chia/util/db_version.py +32 -0
  746. chia/util/db_wrapper.py +430 -0
  747. chia/util/default_root.py +27 -0
  748. chia/util/dump_keyring.py +93 -0
  749. chia/util/english.txt +2048 -0
  750. chia/util/errors.py +353 -0
  751. chia/util/file_keyring.py +469 -0
  752. chia/util/files.py +97 -0
  753. chia/util/full_block_utils.py +345 -0
  754. chia/util/generator_tools.py +72 -0
  755. chia/util/hash.py +31 -0
  756. chia/util/initial-config.yaml +694 -0
  757. chia/util/inline_executor.py +26 -0
  758. chia/util/ints.py +19 -0
  759. chia/util/ip_address.py +39 -0
  760. chia/util/json_util.py +37 -0
  761. chia/util/keychain.py +676 -0
  762. chia/util/keyring_wrapper.py +327 -0
  763. chia/util/limited_semaphore.py +41 -0
  764. chia/util/lock.py +49 -0
  765. chia/util/log_exceptions.py +32 -0
  766. chia/util/logging.py +36 -0
  767. chia/util/lru_cache.py +31 -0
  768. chia/util/math.py +20 -0
  769. chia/util/network.py +182 -0
  770. chia/util/paginator.py +48 -0
  771. chia/util/path.py +31 -0
  772. chia/util/permissions.py +20 -0
  773. chia/util/prev_transaction_block.py +21 -0
  774. chia/util/priority_mutex.py +95 -0
  775. chia/util/profiler.py +197 -0
  776. chia/util/recursive_replace.py +24 -0
  777. chia/util/safe_cancel_task.py +16 -0
  778. chia/util/service_groups.py +47 -0
  779. chia/util/setproctitle.py +22 -0
  780. chia/util/significant_bits.py +32 -0
  781. chia/util/ssl_check.py +213 -0
  782. chia/util/streamable.py +642 -0
  783. chia/util/task_referencer.py +59 -0
  784. chia/util/task_timing.py +382 -0
  785. chia/util/timing.py +67 -0
  786. chia/util/vdf_prover.py +30 -0
  787. chia/util/virtual_project_analysis.py +540 -0
  788. chia/util/ws_message.py +66 -0
  789. chia/wallet/__init__.py +0 -0
  790. chia/wallet/cat_wallet/__init__.py +0 -0
  791. chia/wallet/cat_wallet/cat_constants.py +75 -0
  792. chia/wallet/cat_wallet/cat_info.py +47 -0
  793. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  794. chia/wallet/cat_wallet/cat_utils.py +164 -0
  795. chia/wallet/cat_wallet/cat_wallet.py +855 -0
  796. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  797. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  798. chia/wallet/cat_wallet/lineage_store.py +74 -0
  799. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  800. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  801. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  802. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  803. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  804. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  805. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  806. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  807. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  808. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  809. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  810. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  811. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  812. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  813. chia/wallet/coin_selection.py +188 -0
  814. chia/wallet/conditions.py +1512 -0
  815. chia/wallet/dao_wallet/__init__.py +0 -0
  816. chia/wallet/dao_wallet/dao_info.py +61 -0
  817. chia/wallet/dao_wallet/dao_utils.py +811 -0
  818. chia/wallet/dao_wallet/dao_wallet.py +2119 -0
  819. chia/wallet/db_wallet/__init__.py +0 -0
  820. chia/wallet/db_wallet/db_wallet_puzzles.py +111 -0
  821. chia/wallet/derivation_record.py +30 -0
  822. chia/wallet/derive_keys.py +146 -0
  823. chia/wallet/did_wallet/__init__.py +0 -0
  824. chia/wallet/did_wallet/did_info.py +39 -0
  825. chia/wallet/did_wallet/did_wallet.py +1494 -0
  826. chia/wallet/did_wallet/did_wallet_puzzles.py +221 -0
  827. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  828. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  829. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  830. chia/wallet/driver_protocol.py +26 -0
  831. chia/wallet/key_val_store.py +55 -0
  832. chia/wallet/lineage_proof.py +58 -0
  833. chia/wallet/nft_wallet/__init__.py +0 -0
  834. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  835. chia/wallet/nft_wallet/nft_info.py +120 -0
  836. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  837. chia/wallet/nft_wallet/nft_wallet.py +1687 -0
  838. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  839. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  840. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  841. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  842. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  843. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  844. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  845. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  846. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  847. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  848. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  849. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  850. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  851. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  852. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  853. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  854. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  855. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  856. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  857. chia/wallet/notification_manager.py +117 -0
  858. chia/wallet/notification_store.py +178 -0
  859. chia/wallet/outer_puzzles.py +84 -0
  860. chia/wallet/payment.py +33 -0
  861. chia/wallet/puzzle_drivers.py +118 -0
  862. chia/wallet/puzzles/__init__.py +0 -0
  863. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  864. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  865. chia/wallet/puzzles/clawback/__init__.py +0 -0
  866. chia/wallet/puzzles/clawback/drivers.py +188 -0
  867. chia/wallet/puzzles/clawback/metadata.py +38 -0
  868. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  869. chia/wallet/puzzles/condition_codes.clib +77 -0
  870. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  871. chia/wallet/puzzles/curry.clib +135 -0
  872. chia/wallet/puzzles/curry_by_index.clib +16 -0
  873. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  874. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  876. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  877. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  878. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  879. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  880. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  881. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  882. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  883. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  884. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  885. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  886. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  887. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  888. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  889. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  890. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  891. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  892. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  893. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  894. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  895. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  896. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  897. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  898. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  899. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  900. chia/wallet/puzzles/json.clib +25 -0
  901. chia/wallet/puzzles/load_clvm.py +161 -0
  902. chia/wallet/puzzles/merkle_utils.clib +18 -0
  903. chia/wallet/puzzles/notification.clsp +7 -0
  904. chia/wallet/puzzles/notification.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  906. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  907. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  908. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  909. chia/wallet/puzzles/p2_conditions.py +26 -0
  910. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  911. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  912. chia/wallet/puzzles/p2_delegated_conditions.py +21 -0
  913. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  914. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  915. chia/wallet/puzzles/p2_delegated_puzzle.py +34 -0
  916. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  917. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +160 -0
  919. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  920. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  921. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +21 -0
  922. chia/wallet/puzzles/p2_parent.clsp +19 -0
  923. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  924. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  925. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  926. chia/wallet/puzzles/p2_puzzle_hash.py +27 -0
  927. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  928. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  929. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  930. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  931. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  932. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  933. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  934. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  935. chia/wallet/puzzles/puzzle_utils.py +34 -0
  936. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  937. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  938. chia/wallet/puzzles/sha256tree.clib +11 -0
  939. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  940. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  941. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  942. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  943. chia/wallet/puzzles/singleton_top_layer.py +296 -0
  944. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  945. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  946. chia/wallet/puzzles/singleton_top_layer_v1_1.py +345 -0
  947. chia/wallet/puzzles/singleton_truths.clib +21 -0
  948. chia/wallet/puzzles/tails.py +348 -0
  949. chia/wallet/puzzles/utility_macros.clib +48 -0
  950. chia/wallet/signer_protocol.py +125 -0
  951. chia/wallet/singleton.py +106 -0
  952. chia/wallet/singleton_record.py +30 -0
  953. chia/wallet/trade_manager.py +1102 -0
  954. chia/wallet/trade_record.py +67 -0
  955. chia/wallet/trading/__init__.py +0 -0
  956. chia/wallet/trading/offer.py +702 -0
  957. chia/wallet/trading/trade_status.py +13 -0
  958. chia/wallet/trading/trade_store.py +526 -0
  959. chia/wallet/transaction_record.py +158 -0
  960. chia/wallet/transaction_sorting.py +14 -0
  961. chia/wallet/uncurried_puzzle.py +17 -0
  962. chia/wallet/util/__init__.py +0 -0
  963. chia/wallet/util/address_type.py +55 -0
  964. chia/wallet/util/blind_signer_tl.py +164 -0
  965. chia/wallet/util/clvm_streamable.py +203 -0
  966. chia/wallet/util/compute_hints.py +66 -0
  967. chia/wallet/util/compute_memos.py +43 -0
  968. chia/wallet/util/curry_and_treehash.py +91 -0
  969. chia/wallet/util/debug_spend_bundle.py +232 -0
  970. chia/wallet/util/merkle_tree.py +100 -0
  971. chia/wallet/util/merkle_utils.py +102 -0
  972. chia/wallet/util/new_peak_queue.py +82 -0
  973. chia/wallet/util/notifications.py +12 -0
  974. chia/wallet/util/peer_request_cache.py +174 -0
  975. chia/wallet/util/pprint.py +39 -0
  976. chia/wallet/util/puzzle_compression.py +95 -0
  977. chia/wallet/util/puzzle_decorator.py +100 -0
  978. chia/wallet/util/puzzle_decorator_type.py +7 -0
  979. chia/wallet/util/query_filter.py +59 -0
  980. chia/wallet/util/transaction_type.py +23 -0
  981. chia/wallet/util/tx_config.py +158 -0
  982. chia/wallet/util/wallet_sync_utils.py +351 -0
  983. chia/wallet/util/wallet_types.py +72 -0
  984. chia/wallet/vc_wallet/__init__.py +0 -0
  985. chia/wallet/vc_wallet/cr_cat_drivers.py +664 -0
  986. chia/wallet/vc_wallet/cr_cat_wallet.py +877 -0
  987. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  988. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  989. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  990. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  992. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  994. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  996. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  997. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  998. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  1002. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  1003. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  1004. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  1005. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  1006. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  1007. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  1008. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  1009. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  1010. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  1011. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  1012. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  1013. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1014. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1015. chia/wallet/vc_wallet/vc_store.py +263 -0
  1016. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1017. chia/wallet/wallet.py +698 -0
  1018. chia/wallet/wallet_action_scope.py +96 -0
  1019. chia/wallet/wallet_blockchain.py +244 -0
  1020. chia/wallet/wallet_coin_record.py +72 -0
  1021. chia/wallet/wallet_coin_store.py +351 -0
  1022. chia/wallet/wallet_info.py +35 -0
  1023. chia/wallet/wallet_interested_store.py +188 -0
  1024. chia/wallet/wallet_nft_store.py +279 -0
  1025. chia/wallet/wallet_node.py +1765 -0
  1026. chia/wallet/wallet_node_api.py +207 -0
  1027. chia/wallet/wallet_pool_store.py +119 -0
  1028. chia/wallet/wallet_protocol.py +90 -0
  1029. chia/wallet/wallet_puzzle_store.py +396 -0
  1030. chia/wallet/wallet_retry_store.py +70 -0
  1031. chia/wallet/wallet_singleton_store.py +259 -0
  1032. chia/wallet/wallet_spend_bundle.py +25 -0
  1033. chia/wallet/wallet_state_manager.py +2819 -0
  1034. chia/wallet/wallet_transaction_store.py +496 -0
  1035. chia/wallet/wallet_user_store.py +110 -0
  1036. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1037. chia_blockchain-2.5.1rc1.dist-info/LICENSE +201 -0
  1038. chia_blockchain-2.5.1rc1.dist-info/METADATA +156 -0
  1039. chia_blockchain-2.5.1rc1.dist-info/RECORD +1042 -0
  1040. chia_blockchain-2.5.1rc1.dist-info/WHEEL +4 -0
  1041. chia_blockchain-2.5.1rc1.dist-info/entry_points.txt +17 -0
  1042. mozilla-ca/cacert.pem +3611 -0
@@ -0,0 +1,1512 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+ from collections.abc import Iterable
5
+ from dataclasses import dataclass, fields, replace
6
+ from typing import Any, ClassVar, Optional, TypeVar, Union, final, get_type_hints
7
+
8
+ from chia_rs import Coin, G1Element
9
+ from clvm.casts import int_from_bytes, int_to_bytes
10
+
11
+ from chia.types.blockchain_format.program import Program
12
+ from chia.types.blockchain_format.sized_bytes import bytes32
13
+ from chia.types.condition_opcodes import ConditionOpcode
14
+ from chia.util.hash import std_hash
15
+ from chia.util.ints import uint8, uint32, uint64
16
+ from chia.util.streamable import Streamable, streamable
17
+
18
+ _T_Condition = TypeVar("_T_Condition", bound="Condition")
19
+
20
+
21
+ class Condition(Streamable, ABC):
22
+ @abstractmethod
23
+ def to_program(self) -> Program: ...
24
+
25
+ @classmethod
26
+ @abstractmethod
27
+ def from_program(cls: type[_T_Condition], program: Program) -> _T_Condition: ...
28
+
29
+
30
+ @final
31
+ @streamable
32
+ @dataclass(frozen=True)
33
+ class AggSigParent(Condition):
34
+ pubkey: G1Element
35
+ msg: bytes
36
+ parent_id: Optional[bytes32] = None
37
+
38
+ def to_program(self) -> Program:
39
+ condition: Program = Program.to([ConditionOpcode.AGG_SIG_PARENT, self.pubkey.to_bytes(), self.msg])
40
+ return condition
41
+
42
+ @classmethod
43
+ def from_program(cls, program: Program, parent_id: Optional[bytes32] = None) -> AggSigParent:
44
+ return cls(
45
+ G1Element.from_bytes(program.at("rf").as_atom()),
46
+ program.at("rrf").as_atom(),
47
+ parent_id,
48
+ )
49
+
50
+
51
+ @final
52
+ @streamable
53
+ @dataclass(frozen=True)
54
+ class AggSigPuzzle(Condition):
55
+ pubkey: G1Element
56
+ msg: bytes
57
+ puzzle_hash: Optional[bytes32] = None
58
+
59
+ def to_program(self) -> Program:
60
+ condition: Program = Program.to([ConditionOpcode.AGG_SIG_PUZZLE, self.pubkey.to_bytes(), self.msg])
61
+ return condition
62
+
63
+ @classmethod
64
+ def from_program(cls, program: Program, puzzle_hash: Optional[bytes32] = None) -> AggSigPuzzle:
65
+ return cls(
66
+ G1Element.from_bytes(program.at("rf").as_atom()),
67
+ program.at("rrf").as_atom(),
68
+ puzzle_hash,
69
+ )
70
+
71
+
72
+ @final
73
+ @streamable
74
+ @dataclass(frozen=True)
75
+ class AggSigAmount(Condition):
76
+ pubkey: G1Element
77
+ msg: bytes
78
+ amount: Optional[uint64] = None
79
+
80
+ def to_program(self) -> Program:
81
+ condition: Program = Program.to([ConditionOpcode.AGG_SIG_AMOUNT, self.pubkey.to_bytes(), self.msg])
82
+ return condition
83
+
84
+ @classmethod
85
+ def from_program(cls, program: Program, amount: Optional[uint64] = None) -> AggSigAmount:
86
+ return cls(
87
+ G1Element.from_bytes(program.at("rf").as_atom()),
88
+ program.at("rrf").as_atom(),
89
+ amount,
90
+ )
91
+
92
+
93
+ @final
94
+ @streamable
95
+ @dataclass(frozen=True)
96
+ class AggSigPuzzleAmount(Condition):
97
+ pubkey: G1Element
98
+ msg: bytes
99
+ puzzle_hash: Optional[bytes32] = None
100
+ amount: Optional[uint64] = None
101
+
102
+ def to_program(self) -> Program:
103
+ condition: Program = Program.to([ConditionOpcode.AGG_SIG_PUZZLE_AMOUNT, self.pubkey.to_bytes(), self.msg])
104
+ return condition
105
+
106
+ @classmethod
107
+ def from_program(
108
+ cls,
109
+ program: Program,
110
+ puzzle_hash: Optional[bytes32] = None,
111
+ amount: Optional[uint64] = None,
112
+ ) -> AggSigPuzzleAmount:
113
+ return cls(
114
+ G1Element.from_bytes(program.at("rf").as_atom()),
115
+ program.at("rrf").as_atom(),
116
+ puzzle_hash,
117
+ amount,
118
+ )
119
+
120
+
121
+ @final
122
+ @streamable
123
+ @dataclass(frozen=True)
124
+ class AggSigParentAmount(Condition):
125
+ pubkey: G1Element
126
+ msg: bytes
127
+ parent_id: Optional[bytes32] = None
128
+ amount: Optional[uint64] = None
129
+
130
+ def to_program(self) -> Program:
131
+ condition: Program = Program.to([ConditionOpcode.AGG_SIG_PARENT_AMOUNT, self.pubkey.to_bytes(), self.msg])
132
+ return condition
133
+
134
+ @classmethod
135
+ def from_program(
136
+ cls,
137
+ program: Program,
138
+ parent_id: Optional[bytes32] = None,
139
+ amount: Optional[uint64] = None,
140
+ ) -> AggSigParentAmount:
141
+ return cls(
142
+ G1Element.from_bytes(program.at("rf").as_atom()),
143
+ program.at("rrf").as_atom(),
144
+ parent_id,
145
+ amount,
146
+ )
147
+
148
+
149
+ @final
150
+ @streamable
151
+ @dataclass(frozen=True)
152
+ class AggSigParentPuzzle(Condition):
153
+ pubkey: G1Element
154
+ msg: bytes
155
+ parent_id: Optional[bytes32] = None
156
+ puzzle_hash: Optional[bytes32] = None
157
+
158
+ def to_program(self) -> Program:
159
+ condition: Program = Program.to([ConditionOpcode.AGG_SIG_PARENT_PUZZLE, self.pubkey.to_bytes(), self.msg])
160
+ return condition
161
+
162
+ @classmethod
163
+ def from_program(
164
+ cls,
165
+ program: Program,
166
+ parent_id: Optional[bytes32] = None,
167
+ puzzle_hash: Optional[bytes32] = None,
168
+ ) -> AggSigParentPuzzle:
169
+ return cls(
170
+ G1Element.from_bytes(program.at("rf").as_atom()),
171
+ program.at("rrf").as_atom(),
172
+ parent_id,
173
+ puzzle_hash,
174
+ )
175
+
176
+
177
+ @final
178
+ @streamable
179
+ @dataclass(frozen=True)
180
+ class AggSigUnsafe(Condition):
181
+ pubkey: G1Element
182
+ msg: bytes
183
+
184
+ def to_program(self) -> Program:
185
+ condition: Program = Program.to([ConditionOpcode.AGG_SIG_UNSAFE, self.pubkey.to_bytes(), self.msg])
186
+ return condition
187
+
188
+ @classmethod
189
+ def from_program(cls, program: Program) -> AggSigUnsafe:
190
+ return cls(
191
+ G1Element.from_bytes(program.at("rf").as_atom()),
192
+ program.at("rrf").as_atom(),
193
+ )
194
+
195
+
196
+ @final
197
+ @streamable
198
+ @dataclass(frozen=True)
199
+ class AggSigMe(Condition):
200
+ pubkey: G1Element
201
+ msg: bytes
202
+ coin_id: Optional[bytes32] = None
203
+ additional_data: Optional[bytes32] = None
204
+
205
+ def to_program(self) -> Program:
206
+ condition: Program = Program.to([ConditionOpcode.AGG_SIG_ME, self.pubkey.to_bytes(), self.msg])
207
+ return condition
208
+
209
+ @classmethod
210
+ def from_program(
211
+ cls,
212
+ program: Program,
213
+ coin_id: Optional[bytes32] = None,
214
+ additional_data: Optional[bytes32] = None,
215
+ ) -> AggSigMe:
216
+ return cls(
217
+ G1Element.from_bytes(program.at("rf").as_atom()),
218
+ program.at("rrf").as_atom(),
219
+ coin_id,
220
+ additional_data,
221
+ )
222
+
223
+
224
+ @final
225
+ @streamable
226
+ @dataclass(frozen=True)
227
+ class CreateCoin(Condition):
228
+ puzzle_hash: bytes32
229
+ amount: uint64
230
+ memos: Optional[list[bytes]] = None
231
+
232
+ def to_program(self) -> Program:
233
+ condition_args = [ConditionOpcode.CREATE_COIN, self.puzzle_hash, self.amount]
234
+ if self.memos is not None:
235
+ condition_args.append(self.memos)
236
+ condition: Program = Program.to(condition_args)
237
+ return condition
238
+
239
+ @classmethod
240
+ def from_program(cls, program: Program) -> CreateCoin:
241
+ potential_memos: Program = program.at("rrr")
242
+ return cls(
243
+ bytes32(program.at("rf").as_atom()),
244
+ uint64(program.at("rrf").as_int()),
245
+ (
246
+ None
247
+ if potential_memos == Program.to(None)
248
+ else [memo.as_atom() for memo in potential_memos.at("f").as_iter()]
249
+ ),
250
+ )
251
+
252
+
253
+ @final
254
+ @streamable
255
+ @dataclass(frozen=True)
256
+ class ReserveFee(Condition):
257
+ amount: uint64
258
+
259
+ def to_program(self) -> Program:
260
+ condition: Program = Program.to([ConditionOpcode.RESERVE_FEE, self.amount])
261
+ return condition
262
+
263
+ @classmethod
264
+ def from_program(cls, program: Program) -> ReserveFee:
265
+ return cls(
266
+ uint64(program.at("rf").as_int()),
267
+ )
268
+
269
+
270
+ @final
271
+ @streamable
272
+ @dataclass(frozen=True)
273
+ class AssertCoinAnnouncement(Condition):
274
+ msg: Optional[bytes32] = None
275
+ asserted_id: Optional[bytes32] = None
276
+ asserted_msg: Optional[bytes] = None
277
+
278
+ def __post_init__(self) -> None:
279
+ if self.msg is None and (self.asserted_id is None or self.asserted_msg is None):
280
+ raise ValueError("Must specify either the complete announcement message or both of its components")
281
+
282
+ @property
283
+ def msg_calc(self) -> bytes32:
284
+ if self.msg is None:
285
+ # Our __post_init__ assures us these are not None
286
+ return std_hash(self.asserted_id + self.asserted_msg) # type: ignore[operator]
287
+ else:
288
+ return self.msg
289
+
290
+ def corresponding_creation(self) -> CreateCoinAnnouncement:
291
+ if self.asserted_msg is None:
292
+ raise ValueError("Cannot create coin announcement creation without asserted_msg")
293
+ else:
294
+ return CreateCoinAnnouncement(self.asserted_msg, self.asserted_id)
295
+
296
+ def to_program(self) -> Program:
297
+ condition: Program = Program.to([ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, self.msg_calc])
298
+ return condition
299
+
300
+ @classmethod
301
+ def from_program(
302
+ cls,
303
+ program: Program,
304
+ asserted_id: Optional[bytes32] = None,
305
+ asserted_msg: Optional[bytes] = None,
306
+ ) -> AssertCoinAnnouncement:
307
+ return cls(
308
+ bytes32(program.at("rf").as_atom()),
309
+ asserted_id,
310
+ asserted_msg,
311
+ )
312
+
313
+
314
+ @final
315
+ @streamable
316
+ @dataclass(frozen=True)
317
+ class CreateCoinAnnouncement(Condition):
318
+ msg: bytes
319
+ coin_id: Optional[bytes32] = None
320
+
321
+ def corresponding_assertion(self) -> AssertCoinAnnouncement:
322
+ if self.coin_id is None:
323
+ raise ValueError("Cannot create coin announcement assertion without coin_id")
324
+ else:
325
+ return AssertCoinAnnouncement(asserted_id=self.coin_id, asserted_msg=self.msg)
326
+
327
+ def to_program(self) -> Program:
328
+ condition: Program = Program.to([ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, self.msg])
329
+ return condition
330
+
331
+ @classmethod
332
+ def from_program(cls, program: Program, coin_id: Optional[bytes32] = None) -> CreateCoinAnnouncement:
333
+ return cls(
334
+ program.at("rf").as_atom(),
335
+ coin_id,
336
+ )
337
+
338
+
339
+ @final
340
+ @streamable
341
+ @dataclass(frozen=True)
342
+ class AssertPuzzleAnnouncement(Condition):
343
+ msg: Optional[bytes32] = None
344
+ asserted_ph: Optional[bytes32] = None
345
+ asserted_msg: Optional[bytes] = None
346
+
347
+ def __post_init__(self) -> None:
348
+ if self.msg is None and (self.asserted_ph is None or self.asserted_msg is None):
349
+ raise ValueError("Must specify either the complete announcement message or both of its components")
350
+
351
+ @property
352
+ def msg_calc(self) -> bytes32:
353
+ if self.msg is None:
354
+ # Our __post_init__ assures us these are not None
355
+ return std_hash(self.asserted_ph + self.asserted_msg) # type: ignore[operator]
356
+ else:
357
+ return self.msg
358
+
359
+ def corresponding_creation(self) -> CreatePuzzleAnnouncement:
360
+ if self.asserted_msg is None:
361
+ raise ValueError("Cannot create puzzle announcement creation without asserted_msg")
362
+ else:
363
+ return CreatePuzzleAnnouncement(self.asserted_msg, self.asserted_ph)
364
+
365
+ def to_program(self) -> Program:
366
+ condition: Program = Program.to([ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT, self.msg_calc])
367
+ return condition
368
+
369
+ @classmethod
370
+ def from_program(
371
+ cls,
372
+ program: Program,
373
+ asserted_ph: Optional[bytes32] = None,
374
+ asserted_msg: Optional[bytes] = None,
375
+ ) -> AssertPuzzleAnnouncement:
376
+ return cls(
377
+ bytes32(program.at("rf").as_atom()),
378
+ asserted_ph,
379
+ asserted_msg,
380
+ )
381
+
382
+
383
+ @final
384
+ @streamable
385
+ @dataclass(frozen=True)
386
+ class CreatePuzzleAnnouncement(Condition):
387
+ msg: bytes
388
+ puzzle_hash: Optional[bytes32] = None
389
+
390
+ def corresponding_assertion(self) -> AssertPuzzleAnnouncement:
391
+ if self.puzzle_hash is None:
392
+ raise ValueError("Cannot create puzzle announcement assertion without puzzle_hash")
393
+ else:
394
+ return AssertPuzzleAnnouncement(asserted_ph=self.puzzle_hash, asserted_msg=self.msg)
395
+
396
+ def to_program(self) -> Program:
397
+ condition: Program = Program.to([ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT, self.msg])
398
+ return condition
399
+
400
+ @classmethod
401
+ def from_program(cls, program: Program, puzzle_hash: Optional[bytes32] = None) -> CreatePuzzleAnnouncement:
402
+ return cls(
403
+ program.at("rf").as_atom(),
404
+ puzzle_hash,
405
+ )
406
+
407
+
408
+ @final
409
+ @streamable
410
+ @dataclass(frozen=True)
411
+ class MessageParticipant(Streamable):
412
+ mode_integer: Optional[uint8] = None
413
+ parent_id_committed: Optional[bytes32] = None
414
+ puzzle_hash_committed: Optional[bytes32] = None
415
+ amount_committed: Optional[uint64] = None
416
+ coin_id_committed: Optional[bytes32] = None
417
+
418
+ def __post_init__(self) -> None:
419
+ if (
420
+ self.parent_id_committed is None
421
+ and self.puzzle_hash_committed is None
422
+ and self.amount_committed is None
423
+ and self.coin_id_committed is None
424
+ and self.mode_integer is None
425
+ ):
426
+ raise ValueError("Must specify at least one committment. Anyone-can-send/recieve is not allowed.")
427
+ if self.coin_id_committed is not None:
428
+ if self.parent_id_committed is None or self.puzzle_hash_committed is None or self.amount_committed is None:
429
+ if not (
430
+ self.parent_id_committed is None
431
+ and self.puzzle_hash_committed is None
432
+ and self.amount_committed is None
433
+ ):
434
+ raise ValueError(
435
+ "Cannot commit to coin_id and only specify some of the other arguments. "
436
+ "You must specify all or none of them."
437
+ )
438
+ else:
439
+ assert (
440
+ Coin(
441
+ parent_coin_info=self.parent_id_committed,
442
+ puzzle_hash=self.puzzle_hash_committed,
443
+ amount=self.amount_committed,
444
+ ).name()
445
+ == self.coin_id_committed
446
+ ), "The value for coin_id_committed must be equal to the implied ID of the other three arguments"
447
+ if self.mode_integer is not None:
448
+ assert (
449
+ self.mode == self.mode_integer
450
+ ), "If mode_integer is manually specified, you must specify committments that match with the mode"
451
+
452
+ @property
453
+ def _nothing_committed(self) -> bool:
454
+ return (
455
+ self.coin_id_committed is None
456
+ and self.parent_id_committed is None
457
+ and self.puzzle_hash_committed is None
458
+ and self.amount_committed is None
459
+ )
460
+
461
+ @property
462
+ def mode(self) -> uint8:
463
+ if self._nothing_committed:
464
+ # The non-None-ness of this is asserted by __post_init__
465
+ return self.mode_integer # type: ignore[return-value]
466
+ if self.coin_id_committed is not None:
467
+ return uint8(0b111)
468
+
469
+ def convert_noneness_to_bit(maybe_none: Optional[Any]) -> int:
470
+ return 1 if maybe_none is not None else 0
471
+
472
+ return uint8(
473
+ (convert_noneness_to_bit(self.parent_id_committed) << 2)
474
+ | (convert_noneness_to_bit(self.puzzle_hash_committed) << 1)
475
+ | convert_noneness_to_bit(self.amount_committed)
476
+ )
477
+
478
+ @property
479
+ def necessary_args(self) -> list[Program]:
480
+ if self._nothing_committed:
481
+ raise ValueError("Cannot generate necessary_args for a participant without committment information")
482
+
483
+ if self.coin_id_committed:
484
+ return [Program.to(self.coin_id_committed)]
485
+
486
+ condition_args = []
487
+ if self.parent_id_committed is not None:
488
+ condition_args.append(Program.to(self.parent_id_committed))
489
+ if self.puzzle_hash_committed is not None:
490
+ condition_args.append(Program.to(self.puzzle_hash_committed))
491
+ if self.amount_committed is not None:
492
+ condition_args.append(Program.to(self.amount_committed))
493
+ return condition_args
494
+
495
+ @classmethod
496
+ def from_mode_and_maybe_args(
497
+ cls, sender: bool, full_mode: uint8, args: Optional[Iterable[Program]] = None
498
+ ) -> MessageParticipant:
499
+ if sender:
500
+ mode = full_mode >> 3
501
+ else:
502
+ mode = full_mode & 0b000111
503
+
504
+ if args is None:
505
+ return cls(mode_integer=uint8(mode))
506
+
507
+ if mode == 0b111:
508
+ return cls(mode_integer=uint8(mode), coin_id_committed=next(bytes32(arg.as_atom()) for arg in args))
509
+
510
+ parent_id_committed: Optional[bytes32] = None
511
+ puzzle_hash_committed: Optional[bytes32] = None
512
+ amount_committed: Optional[uint64] = None
513
+ # This loop probably looks a little strange
514
+ # It's trying to account for the fact that the arguments may be any 1 or 2 of these arguments in this order
515
+ # Not sure of a more elgant way to do it
516
+ original_mode = mode
517
+ for arg in args:
518
+ if mode & 0b100:
519
+ parent_id_committed = bytes32(arg.as_atom())
520
+ mode &= 0b011
521
+ continue
522
+ if mode & 0b010:
523
+ puzzle_hash_committed = bytes32(arg.as_atom())
524
+ mode &= 0b101
525
+ continue
526
+ if mode & 0b001:
527
+ amount_committed = uint64(arg.as_int())
528
+ break
529
+
530
+ return cls(
531
+ mode_integer=uint8(original_mode),
532
+ parent_id_committed=parent_id_committed,
533
+ puzzle_hash_committed=puzzle_hash_committed,
534
+ amount_committed=amount_committed,
535
+ )
536
+
537
+
538
+ _T_MessageCondition = TypeVar("_T_MessageCondition", bound="SendMessage")
539
+
540
+
541
+ @streamable
542
+ @dataclass(frozen=True)
543
+ class SendMessage(Condition):
544
+ msg: bytes
545
+ var_args: Optional[list[Program]] = None
546
+ mode_integer: Optional[uint8] = None
547
+ sender: Optional[MessageParticipant] = None
548
+ receiver: Optional[MessageParticipant] = None
549
+ _other_party_is_receiver: ClassVar[bool] = True
550
+
551
+ @property
552
+ def _other_party(self) -> Optional[MessageParticipant]:
553
+ return self.receiver
554
+
555
+ @property
556
+ def _opcode(self) -> ConditionOpcode:
557
+ return ConditionOpcode.SEND_MESSAGE
558
+
559
+ def __post_init__(self) -> None:
560
+ if self.mode_integer is None and (self.sender is None or self.receiver is None):
561
+ raise ValueError("Must specify either mode_integer or both sender and reciever")
562
+
563
+ if self.mode_integer is not None and self.sender is not None:
564
+ assert (
565
+ self.mode_integer >> 3 == self.sender.mode
566
+ ), "The first 3 bits of mode_integer don't match the sender's mode"
567
+
568
+ if self.mode_integer is not None and self.receiver is not None:
569
+ assert (
570
+ self.mode_integer & 0b000111 == self.receiver.mode
571
+ ), "The last 3 bits of mode_integer don't match the receiver's mode"
572
+
573
+ if self.var_args is None and self._other_party is None:
574
+ raise ValueError(
575
+ f"Must specify either var_args or {'receiver' if self._other_party_is_receiver else 'sender'}"
576
+ )
577
+
578
+ if self.var_args is not None and self._other_party is not None and not self._other_party._nothing_committed:
579
+ assert (
580
+ self.var_args == self._other_party.necessary_args
581
+ ), f"The implied arguments for {self._other_party} do not match the specified arguments {self.var_args}"
582
+
583
+ @property
584
+ def args(self) -> list[Program]:
585
+ if self.var_args is not None:
586
+ return self.var_args
587
+
588
+ # The non-None-ness of this is asserted in __post_init__
589
+ return self._other_party.necessary_args # type: ignore[union-attr]
590
+
591
+ @property
592
+ def mode(self) -> uint8:
593
+ if self.mode_integer is not None:
594
+ return self.mode_integer
595
+
596
+ # The non-None-ness of these are asserted in __post_init__
597
+ return uint8((self.sender.mode << 3) | self.receiver.mode) # type: ignore[union-attr]
598
+
599
+ def to_program(self) -> Program:
600
+ condition: Program = Program.to([self._opcode, self.mode, self.msg, *self.args])
601
+ return condition
602
+
603
+ @classmethod
604
+ def from_program(cls: type[_T_MessageCondition], program: Program) -> _T_MessageCondition:
605
+ full_mode = uint8(program.at("rf").as_int())
606
+ var_args = list(program.at("rrr").as_iter())
607
+ return cls(
608
+ program.at("rrf").as_atom(),
609
+ var_args,
610
+ full_mode,
611
+ MessageParticipant.from_mode_and_maybe_args(
612
+ True, full_mode, var_args if not cls._other_party_is_receiver else None
613
+ ),
614
+ MessageParticipant.from_mode_and_maybe_args(
615
+ False, full_mode, var_args if cls._other_party_is_receiver else None
616
+ ),
617
+ )
618
+
619
+
620
+ @final
621
+ @streamable
622
+ @dataclass(frozen=True)
623
+ class ReceiveMessage(SendMessage):
624
+ _other_party_is_receiver: ClassVar[bool] = False
625
+
626
+ @property
627
+ def _other_party(self) -> Optional[MessageParticipant]:
628
+ return self.sender
629
+
630
+ @property
631
+ def _opcode(self) -> ConditionOpcode:
632
+ return ConditionOpcode.RECEIVE_MESSAGE
633
+
634
+
635
+ @final
636
+ @streamable
637
+ @dataclass(frozen=True)
638
+ class AssertConcurrentSpend(Condition):
639
+ coin_id: bytes32
640
+
641
+ def to_program(self) -> Program:
642
+ condition: Program = Program.to([ConditionOpcode.ASSERT_CONCURRENT_SPEND, self.coin_id])
643
+ return condition
644
+
645
+ @classmethod
646
+ def from_program(cls, program: Program) -> AssertConcurrentSpend:
647
+ return cls(
648
+ bytes32(program.at("rf").as_atom()),
649
+ )
650
+
651
+
652
+ @final
653
+ @streamable
654
+ @dataclass(frozen=True)
655
+ class AssertConcurrentPuzzle(Condition):
656
+ puzzle_hash: bytes32
657
+
658
+ def to_program(self) -> Program:
659
+ condition: Program = Program.to([ConditionOpcode.ASSERT_CONCURRENT_PUZZLE, self.puzzle_hash])
660
+ return condition
661
+
662
+ @classmethod
663
+ def from_program(cls, program: Program) -> AssertConcurrentPuzzle:
664
+ return cls(
665
+ bytes32(program.at("rf").as_atom()),
666
+ )
667
+
668
+
669
+ @final
670
+ @streamable
671
+ @dataclass(frozen=True)
672
+ class AssertMyCoinID(Condition):
673
+ coin_id: bytes32
674
+
675
+ def to_program(self) -> Program:
676
+ condition: Program = Program.to([ConditionOpcode.ASSERT_MY_COIN_ID, self.coin_id])
677
+ return condition
678
+
679
+ @classmethod
680
+ def from_program(cls, program: Program) -> AssertMyCoinID:
681
+ return cls(
682
+ bytes32(program.at("rf").as_atom()),
683
+ )
684
+
685
+
686
+ @final
687
+ @streamable
688
+ @dataclass(frozen=True)
689
+ class AssertMyParentID(Condition):
690
+ coin_id: bytes32
691
+
692
+ def to_program(self) -> Program:
693
+ condition: Program = Program.to([ConditionOpcode.ASSERT_MY_PARENT_ID, self.coin_id])
694
+ return condition
695
+
696
+ @classmethod
697
+ def from_program(cls, program: Program) -> AssertMyParentID:
698
+ return cls(
699
+ bytes32(program.at("rf").as_atom()),
700
+ )
701
+
702
+
703
+ @final
704
+ @streamable
705
+ @dataclass(frozen=True)
706
+ class AssertMyPuzzleHash(Condition):
707
+ puzzle_hash: bytes32
708
+
709
+ def to_program(self) -> Program:
710
+ condition: Program = Program.to([ConditionOpcode.ASSERT_MY_PUZZLEHASH, self.puzzle_hash])
711
+ return condition
712
+
713
+ @classmethod
714
+ def from_program(cls, program: Program) -> AssertMyPuzzleHash:
715
+ return cls(
716
+ bytes32(program.at("rf").as_atom()),
717
+ )
718
+
719
+
720
+ @final
721
+ @streamable
722
+ @dataclass(frozen=True)
723
+ class AssertMyAmount(Condition):
724
+ amount: uint64
725
+
726
+ def to_program(self) -> Program:
727
+ condition: Program = Program.to([ConditionOpcode.ASSERT_MY_AMOUNT, self.amount])
728
+ return condition
729
+
730
+ @classmethod
731
+ def from_program(cls, program: Program) -> AssertMyAmount:
732
+ return cls(
733
+ uint64(program.at("rf").as_int()),
734
+ )
735
+
736
+
737
+ @final
738
+ @streamable
739
+ @dataclass(frozen=True)
740
+ class AssertMyBirthSeconds(Condition):
741
+ seconds: uint64
742
+
743
+ def to_program(self) -> Program:
744
+ condition: Program = Program.to([ConditionOpcode.ASSERT_MY_BIRTH_SECONDS, self.seconds])
745
+ return condition
746
+
747
+ @classmethod
748
+ def from_program(cls, program: Program) -> AssertMyBirthSeconds:
749
+ return cls(
750
+ uint64(program.at("rf").as_int()),
751
+ )
752
+
753
+
754
+ @final
755
+ @streamable
756
+ @dataclass(frozen=True)
757
+ class AssertMyBirthHeight(Condition):
758
+ height: uint32
759
+
760
+ def to_program(self) -> Program:
761
+ condition: Program = Program.to([ConditionOpcode.ASSERT_MY_BIRTH_HEIGHT, self.height])
762
+ return condition
763
+
764
+ @classmethod
765
+ def from_program(cls, program: Program) -> AssertMyBirthHeight:
766
+ return cls(
767
+ uint32(program.at("rf").as_int()),
768
+ )
769
+
770
+
771
+ @final
772
+ @streamable
773
+ @dataclass(frozen=True)
774
+ class AssertEphemeral(Condition):
775
+ def to_program(self) -> Program:
776
+ condition: Program = Program.to([ConditionOpcode.ASSERT_EPHEMERAL])
777
+ return condition
778
+
779
+ @classmethod
780
+ def from_program(cls, program: Program) -> AssertEphemeral:
781
+ return cls()
782
+
783
+
784
+ @final
785
+ @streamable
786
+ @dataclass(frozen=True)
787
+ class AssertSecondsRelative(Condition):
788
+ seconds: uint64
789
+
790
+ def to_program(self) -> Program:
791
+ condition: Program = Program.to([ConditionOpcode.ASSERT_SECONDS_RELATIVE, self.seconds])
792
+ return condition
793
+
794
+ @classmethod
795
+ def from_program(cls, program: Program) -> AssertSecondsRelative:
796
+ return cls(
797
+ uint64(program.at("rf").as_int()),
798
+ )
799
+
800
+
801
+ @final
802
+ @streamable
803
+ @dataclass(frozen=True)
804
+ class AssertSecondsAbsolute(Condition):
805
+ seconds: uint64
806
+
807
+ def to_program(self) -> Program:
808
+ condition: Program = Program.to([ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, self.seconds])
809
+ return condition
810
+
811
+ @classmethod
812
+ def from_program(cls, program: Program) -> AssertSecondsAbsolute:
813
+ return cls(
814
+ uint64(program.at("rf").as_int()),
815
+ )
816
+
817
+
818
+ @final
819
+ @streamable
820
+ @dataclass(frozen=True)
821
+ class AssertHeightRelative(Condition):
822
+ height: uint32
823
+
824
+ def to_program(self) -> Program:
825
+ condition: Program = Program.to([ConditionOpcode.ASSERT_HEIGHT_RELATIVE, self.height])
826
+ return condition
827
+
828
+ @classmethod
829
+ def from_program(cls, program: Program) -> AssertHeightRelative:
830
+ return cls(
831
+ uint32(program.at("rf").as_int()),
832
+ )
833
+
834
+
835
+ @final
836
+ @streamable
837
+ @dataclass(frozen=True)
838
+ class AssertHeightAbsolute(Condition):
839
+ height: uint32
840
+
841
+ def to_program(self) -> Program:
842
+ condition: Program = Program.to([ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, self.height])
843
+ return condition
844
+
845
+ @classmethod
846
+ def from_program(cls, program: Program) -> AssertHeightAbsolute:
847
+ return cls(
848
+ uint32(program.at("rf").as_int()),
849
+ )
850
+
851
+
852
+ @final
853
+ @streamable
854
+ @dataclass(frozen=True)
855
+ class AssertBeforeSecondsRelative(Condition):
856
+ seconds: uint64
857
+
858
+ def to_program(self) -> Program:
859
+ condition: Program = Program.to([ConditionOpcode.ASSERT_BEFORE_SECONDS_RELATIVE, self.seconds])
860
+ return condition
861
+
862
+ @classmethod
863
+ def from_program(cls, program: Program) -> AssertBeforeSecondsRelative:
864
+ return cls(
865
+ uint64(program.at("rf").as_int()),
866
+ )
867
+
868
+
869
+ @final
870
+ @streamable
871
+ @dataclass(frozen=True)
872
+ class AssertBeforeSecondsAbsolute(Condition):
873
+ seconds: uint64
874
+
875
+ def to_program(self) -> Program:
876
+ condition: Program = Program.to([ConditionOpcode.ASSERT_BEFORE_SECONDS_ABSOLUTE, self.seconds])
877
+ return condition
878
+
879
+ @classmethod
880
+ def from_program(cls, program: Program) -> AssertBeforeSecondsAbsolute:
881
+ return cls(
882
+ uint64(program.at("rf").as_int()),
883
+ )
884
+
885
+
886
+ @final
887
+ @streamable
888
+ @dataclass(frozen=True)
889
+ class AssertBeforeHeightRelative(Condition):
890
+ height: uint32
891
+
892
+ def to_program(self) -> Program:
893
+ condition: Program = Program.to([ConditionOpcode.ASSERT_BEFORE_HEIGHT_RELATIVE, self.height])
894
+ return condition
895
+
896
+ @classmethod
897
+ def from_program(cls, program: Program) -> AssertBeforeHeightRelative:
898
+ return cls(
899
+ uint32(program.at("rf").as_int()),
900
+ )
901
+
902
+
903
+ @final
904
+ @streamable
905
+ @dataclass(frozen=True)
906
+ class AssertBeforeHeightAbsolute(Condition):
907
+ height: uint32
908
+
909
+ def to_program(self) -> Program:
910
+ condition: Program = Program.to([ConditionOpcode.ASSERT_BEFORE_HEIGHT_ABSOLUTE, self.height])
911
+ return condition
912
+
913
+ @classmethod
914
+ def from_program(cls, program: Program) -> AssertBeforeHeightAbsolute:
915
+ return cls(
916
+ uint32(program.at("rf").as_int()),
917
+ )
918
+
919
+
920
+ @final
921
+ @streamable
922
+ @dataclass(frozen=True)
923
+ class Softfork(Condition):
924
+ cost: uint64
925
+ conditions: list[Program]
926
+
927
+ def to_program(self) -> Program:
928
+ condition: Program = Program.to([ConditionOpcode.SOFTFORK, self.cost, self.conditions])
929
+ return condition
930
+
931
+ @classmethod
932
+ def from_program(cls, program: Program) -> Softfork:
933
+ return cls(
934
+ uint64(program.at("rf").as_int()),
935
+ list(program.at("rrf").as_iter()),
936
+ )
937
+
938
+
939
+ @final
940
+ @streamable
941
+ @dataclass(frozen=True)
942
+ class Remark(Condition):
943
+ rest: Program
944
+
945
+ def to_program(self) -> Program:
946
+ condition: Program = Program.to((ConditionOpcode.REMARK, self.rest))
947
+ return condition
948
+
949
+ @classmethod
950
+ def from_program(cls, program: Program) -> Remark:
951
+ return cls(
952
+ program.at("r"),
953
+ )
954
+
955
+
956
+ @final
957
+ @streamable
958
+ @dataclass(frozen=True)
959
+ class UnknownCondition(Condition):
960
+ opcode: Program
961
+ args: list[Program]
962
+
963
+ def to_program(self) -> Program:
964
+ return self.opcode.cons(Program.to(self.args))
965
+
966
+ @classmethod
967
+ def from_program(cls, program: Program) -> UnknownCondition:
968
+ return cls(
969
+ program.at("f"), [] if program.at("r") == Program.to(None) else [p for p in program.at("r").as_iter()]
970
+ )
971
+
972
+
973
+ # Abstractions
974
+ @final
975
+ @streamable
976
+ @dataclass(frozen=True)
977
+ class AggSig(Condition):
978
+ pubkey: G1Element
979
+ msg: bytes
980
+ opcode: bytes = ConditionOpcode.AGG_SIG_ME.value
981
+ coin_id: Optional[bytes32] = None
982
+ parent_id: Optional[bytes32] = None
983
+ puzzle_hash: Optional[bytes32] = None
984
+ amount: Optional[uint64] = None
985
+ additional_data: Optional[bytes32] = None
986
+
987
+ def to_program(self) -> Program:
988
+ # We know we are an agg sig or we want to error
989
+ return CONDITION_DRIVERS[self.opcode](self.pubkey.to_bytes(), self.msg).to_program() # type: ignore[call-arg]
990
+
991
+ @classmethod
992
+ def from_program(cls, program: Program, **kwargs: Optional[Union[uint64, bytes32]]) -> AggSig:
993
+ opcode: bytes = program.at("f").as_atom()
994
+ condition_driver: Condition = CONDITION_DRIVERS[opcode].from_program(program, **kwargs)
995
+ return cls(
996
+ # We are either parsing an agg sig condition, all of which have these, or we want to error
997
+ condition_driver.pubkey, # type: ignore[attr-defined]
998
+ condition_driver.msg, # type: ignore[attr-defined]
999
+ opcode,
1000
+ **{key: value for key, value in condition_driver.__dict__.items() if key not in {"pubkey", "msg"}},
1001
+ )
1002
+
1003
+
1004
+ @final
1005
+ @streamable
1006
+ @dataclass(frozen=True)
1007
+ class CreateAnnouncement(Condition):
1008
+ msg: bytes
1009
+ coin_not_puzzle: bool
1010
+ origin_id: Optional[bytes32] = None
1011
+
1012
+ def corresponding_assertion(self) -> AssertAnnouncement:
1013
+ if self.origin_id is None:
1014
+ raise ValueError("Cannot create coin announcement assertion without origin_id")
1015
+ else:
1016
+ return AssertAnnouncement(self.coin_not_puzzle, asserted_origin_id=self.origin_id, asserted_msg=self.msg)
1017
+
1018
+ def to_program(self) -> Program:
1019
+ if self.coin_not_puzzle:
1020
+ return CreateCoinAnnouncement(self.msg, self.origin_id).to_program()
1021
+ else:
1022
+ return CreatePuzzleAnnouncement(self.msg, self.origin_id).to_program()
1023
+
1024
+ @classmethod
1025
+ def from_program(cls, program: Program, **kwargs: Optional[bytes32]) -> CreateAnnouncement:
1026
+ if program.at("f").as_atom() == ConditionOpcode.CREATE_COIN_ANNOUNCEMENT:
1027
+ coin_not_puzzle: bool = True
1028
+ condition: Union[CreateCoinAnnouncement, CreatePuzzleAnnouncement] = CreateCoinAnnouncement.from_program(
1029
+ program, **kwargs
1030
+ )
1031
+ assert isinstance(condition, CreateCoinAnnouncement)
1032
+ origin_id: Optional[bytes32] = condition.coin_id
1033
+ else:
1034
+ coin_not_puzzle = False
1035
+ condition = CreatePuzzleAnnouncement.from_program(program, **kwargs)
1036
+ assert isinstance(condition, CreatePuzzleAnnouncement)
1037
+ origin_id = condition.puzzle_hash
1038
+ return cls(
1039
+ condition.msg,
1040
+ coin_not_puzzle,
1041
+ origin_id,
1042
+ )
1043
+
1044
+
1045
+ @final
1046
+ @streamable
1047
+ @dataclass(frozen=True)
1048
+ class AssertAnnouncement(Condition):
1049
+ coin_not_puzzle: bool
1050
+ msg: Optional[bytes32] = None
1051
+ asserted_origin_id: Optional[bytes32] = None
1052
+ asserted_msg: Optional[bytes] = None
1053
+
1054
+ def __post_init__(self) -> None:
1055
+ if self.msg is None and (self.asserted_origin_id is None or self.asserted_msg is None):
1056
+ raise ValueError("Must specify either the complete announcement message or both of its components")
1057
+
1058
+ @property
1059
+ def msg_calc(self) -> bytes32:
1060
+ if self.msg is None:
1061
+ # Our __post_init__ assures us these are not None
1062
+ return std_hash(self.asserted_origin_id + self.asserted_msg) # type: ignore[operator]
1063
+ else:
1064
+ return self.msg
1065
+
1066
+ def to_program(self) -> Program:
1067
+ if self.coin_not_puzzle:
1068
+ return AssertCoinAnnouncement(self.msg_calc, self.asserted_origin_id, self.asserted_msg).to_program()
1069
+ else:
1070
+ return AssertPuzzleAnnouncement(self.msg_calc, self.asserted_origin_id, self.asserted_msg).to_program()
1071
+
1072
+ def corresponding_creation(self) -> CreateAnnouncement:
1073
+ if self.asserted_msg is None:
1074
+ raise ValueError("Cannot create coin announcement creation without asserted_msg")
1075
+ else:
1076
+ return CreateAnnouncement(self.asserted_msg, self.coin_not_puzzle, self.asserted_origin_id)
1077
+
1078
+ @classmethod
1079
+ def from_program(cls, program: Program, **kwargs: Optional[bytes32]) -> AssertAnnouncement:
1080
+ if program.at("f").as_atom() == ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT:
1081
+ coin_not_puzzle: bool = True
1082
+ condition: Union[AssertCoinAnnouncement, AssertPuzzleAnnouncement] = AssertCoinAnnouncement.from_program(
1083
+ program, **kwargs
1084
+ )
1085
+ assert isinstance(condition, AssertCoinAnnouncement)
1086
+ asserted_origin_id: Optional[bytes32] = condition.asserted_id
1087
+ else:
1088
+ coin_not_puzzle = False
1089
+ condition = AssertPuzzleAnnouncement.from_program(program, **kwargs)
1090
+ assert isinstance(condition, AssertPuzzleAnnouncement)
1091
+ asserted_origin_id = condition.asserted_ph
1092
+ return cls(
1093
+ coin_not_puzzle,
1094
+ condition.msg_calc,
1095
+ asserted_origin_id,
1096
+ condition.asserted_msg,
1097
+ )
1098
+
1099
+
1100
+ TIMELOCK_TYPES = Union[
1101
+ AssertSecondsRelative,
1102
+ AssertHeightRelative,
1103
+ AssertSecondsAbsolute,
1104
+ AssertHeightAbsolute,
1105
+ AssertBeforeSecondsRelative,
1106
+ AssertBeforeHeightRelative,
1107
+ AssertBeforeSecondsAbsolute,
1108
+ AssertBeforeHeightAbsolute,
1109
+ ]
1110
+
1111
+
1112
+ TIMELOCK_DRIVERS: tuple[
1113
+ type[TIMELOCK_TYPES],
1114
+ type[TIMELOCK_TYPES],
1115
+ type[TIMELOCK_TYPES],
1116
+ type[TIMELOCK_TYPES],
1117
+ type[TIMELOCK_TYPES],
1118
+ type[TIMELOCK_TYPES],
1119
+ type[TIMELOCK_TYPES],
1120
+ type[TIMELOCK_TYPES],
1121
+ ] = (
1122
+ AssertSecondsRelative,
1123
+ AssertHeightRelative,
1124
+ AssertSecondsAbsolute,
1125
+ AssertHeightAbsolute,
1126
+ AssertBeforeSecondsRelative,
1127
+ AssertBeforeHeightRelative,
1128
+ AssertBeforeSecondsAbsolute,
1129
+ AssertBeforeHeightAbsolute,
1130
+ )
1131
+ SECONDS_TIMELOCK_DRIVERS: set[type[TIMELOCK_TYPES]] = {
1132
+ AssertSecondsRelative,
1133
+ AssertSecondsAbsolute,
1134
+ AssertBeforeSecondsRelative,
1135
+ AssertBeforeSecondsAbsolute,
1136
+ }
1137
+ HEIGHT_TIMELOCK_DRIVERS: set[type[TIMELOCK_TYPES]] = {
1138
+ AssertHeightRelative,
1139
+ AssertHeightAbsolute,
1140
+ AssertBeforeHeightRelative,
1141
+ AssertBeforeHeightAbsolute,
1142
+ }
1143
+ AFTER_TIMELOCK_DRIVERS: set[type[TIMELOCK_TYPES]] = {
1144
+ AssertSecondsRelative,
1145
+ AssertHeightRelative,
1146
+ AssertSecondsAbsolute,
1147
+ AssertHeightAbsolute,
1148
+ }
1149
+ BEFORE_TIMELOCK_DRIVERS: set[type[TIMELOCK_TYPES]] = {
1150
+ AssertBeforeSecondsRelative,
1151
+ AssertBeforeHeightRelative,
1152
+ AssertBeforeSecondsAbsolute,
1153
+ AssertBeforeHeightAbsolute,
1154
+ }
1155
+ RELATIVE_TIMELOCK_DRIVERS: set[type[TIMELOCK_TYPES]] = {
1156
+ AssertSecondsRelative,
1157
+ AssertHeightRelative,
1158
+ AssertBeforeSecondsRelative,
1159
+ AssertBeforeHeightRelative,
1160
+ }
1161
+ ABSOLUTE_TIMELOCK_DRIVERS: set[type[TIMELOCK_TYPES]] = {
1162
+ AssertSecondsAbsolute,
1163
+ AssertHeightAbsolute,
1164
+ AssertBeforeSecondsAbsolute,
1165
+ AssertBeforeHeightAbsolute,
1166
+ }
1167
+ TIMELOCK_DRIVERS_SET: set[type[TIMELOCK_TYPES]] = set(TIMELOCK_DRIVERS)
1168
+
1169
+
1170
+ TIMELOCK_OPCODES: set[bytes] = {
1171
+ ConditionOpcode.ASSERT_SECONDS_RELATIVE.value,
1172
+ ConditionOpcode.ASSERT_HEIGHT_RELATIVE.value,
1173
+ ConditionOpcode.ASSERT_SECONDS_ABSOLUTE.value,
1174
+ ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE.value,
1175
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_RELATIVE.value,
1176
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_RELATIVE.value,
1177
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_ABSOLUTE.value,
1178
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_ABSOLUTE.value,
1179
+ }
1180
+ SECONDS_TIMELOCK_OPCODES: set[bytes] = {
1181
+ ConditionOpcode.ASSERT_SECONDS_RELATIVE.value,
1182
+ ConditionOpcode.ASSERT_SECONDS_ABSOLUTE.value,
1183
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_RELATIVE.value,
1184
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_ABSOLUTE.value,
1185
+ }
1186
+ HEIGHT_TIMELOCK_OPCODES: set[bytes] = {
1187
+ ConditionOpcode.ASSERT_HEIGHT_RELATIVE.value,
1188
+ ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE.value,
1189
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_RELATIVE.value,
1190
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_ABSOLUTE.value,
1191
+ }
1192
+ AFTER_TIMELOCK_OPCODES: set[bytes] = {
1193
+ ConditionOpcode.ASSERT_SECONDS_RELATIVE.value,
1194
+ ConditionOpcode.ASSERT_HEIGHT_RELATIVE.value,
1195
+ ConditionOpcode.ASSERT_SECONDS_ABSOLUTE.value,
1196
+ ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE.value,
1197
+ }
1198
+ BEFORE_TIMELOCK_OPCODES: set[bytes] = {
1199
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_RELATIVE.value,
1200
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_RELATIVE.value,
1201
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_ABSOLUTE.value,
1202
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_ABSOLUTE.value,
1203
+ }
1204
+ RELATIVE_TIMELOCK_OPCODES: set[bytes] = {
1205
+ ConditionOpcode.ASSERT_SECONDS_RELATIVE.value,
1206
+ ConditionOpcode.ASSERT_HEIGHT_RELATIVE.value,
1207
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_RELATIVE.value,
1208
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_RELATIVE.value,
1209
+ }
1210
+ ABSOLUTE_TIMELOCK_OPCODES: set[bytes] = {
1211
+ ConditionOpcode.ASSERT_SECONDS_ABSOLUTE.value,
1212
+ ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE.value,
1213
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_ABSOLUTE.value,
1214
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_ABSOLUTE.value,
1215
+ }
1216
+
1217
+
1218
+ @final
1219
+ @streamable
1220
+ @dataclass(frozen=True)
1221
+ class Timelock(Condition):
1222
+ after_not_before: bool
1223
+ relative_not_absolute: bool
1224
+ seconds_not_height: bool
1225
+ timestamp: uint64
1226
+
1227
+ def to_program(self) -> Program:
1228
+ if self.after_not_before:
1229
+ potential_drivers = TIMELOCK_DRIVERS_SET - BEFORE_TIMELOCK_DRIVERS
1230
+ else:
1231
+ potential_drivers = TIMELOCK_DRIVERS_SET - AFTER_TIMELOCK_DRIVERS
1232
+
1233
+ if self.relative_not_absolute:
1234
+ potential_drivers -= ABSOLUTE_TIMELOCK_DRIVERS
1235
+ else:
1236
+ potential_drivers -= RELATIVE_TIMELOCK_DRIVERS
1237
+
1238
+ if self.seconds_not_height:
1239
+ potential_drivers -= HEIGHT_TIMELOCK_DRIVERS
1240
+ else:
1241
+ potential_drivers -= SECONDS_TIMELOCK_DRIVERS
1242
+
1243
+ driver: type[TIMELOCK_TYPES] = next(iter(potential_drivers))
1244
+
1245
+ if self.seconds_not_height:
1246
+ # Semantics here mean that we're assuredly passing a uint64 to a class that expects it
1247
+ return driver(self.timestamp).to_program() # type: ignore[arg-type]
1248
+ else:
1249
+ # Semantics here mean that we're assuredly passing a uint32 to a class that expects it
1250
+ return driver(uint32(self.timestamp)).to_program() # type: ignore[arg-type]
1251
+
1252
+ @classmethod
1253
+ def from_program(cls, program: Program) -> Timelock:
1254
+ opcode: bytes = program.at("f").as_atom()
1255
+ if opcode in AFTER_TIMELOCK_OPCODES:
1256
+ after_not_before = True
1257
+ else:
1258
+ after_not_before = False
1259
+
1260
+ if opcode in RELATIVE_TIMELOCK_OPCODES:
1261
+ relative_not_absolute = True
1262
+ else:
1263
+ relative_not_absolute = False
1264
+
1265
+ if opcode in SECONDS_TIMELOCK_OPCODES:
1266
+ seconds_not_height = True
1267
+ else:
1268
+ seconds_not_height = False
1269
+
1270
+ return cls(
1271
+ after_not_before,
1272
+ relative_not_absolute,
1273
+ seconds_not_height,
1274
+ uint64(program.at("rf").as_int()),
1275
+ )
1276
+
1277
+
1278
+ CONDITION_DRIVERS: dict[bytes, type[Condition]] = {
1279
+ ConditionOpcode.AGG_SIG_PARENT.value: AggSigParent,
1280
+ ConditionOpcode.AGG_SIG_PUZZLE.value: AggSigPuzzle,
1281
+ ConditionOpcode.AGG_SIG_AMOUNT.value: AggSigAmount,
1282
+ ConditionOpcode.AGG_SIG_PUZZLE_AMOUNT.value: AggSigPuzzleAmount,
1283
+ ConditionOpcode.AGG_SIG_PARENT_AMOUNT.value: AggSigParentAmount,
1284
+ ConditionOpcode.AGG_SIG_PARENT_PUZZLE.value: AggSigParentPuzzle,
1285
+ ConditionOpcode.AGG_SIG_UNSAFE.value: AggSigUnsafe,
1286
+ ConditionOpcode.AGG_SIG_ME.value: AggSigMe,
1287
+ ConditionOpcode.CREATE_COIN.value: CreateCoin,
1288
+ ConditionOpcode.RESERVE_FEE.value: ReserveFee,
1289
+ ConditionOpcode.CREATE_COIN_ANNOUNCEMENT.value: CreateCoinAnnouncement,
1290
+ ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT.value: AssertCoinAnnouncement,
1291
+ ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT.value: CreatePuzzleAnnouncement,
1292
+ ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT.value: AssertPuzzleAnnouncement,
1293
+ ConditionOpcode.SEND_MESSAGE.value: SendMessage,
1294
+ ConditionOpcode.RECEIVE_MESSAGE.value: ReceiveMessage,
1295
+ ConditionOpcode.ASSERT_CONCURRENT_SPEND.value: AssertConcurrentSpend,
1296
+ ConditionOpcode.ASSERT_CONCURRENT_PUZZLE.value: AssertConcurrentPuzzle,
1297
+ ConditionOpcode.ASSERT_MY_COIN_ID.value: AssertMyCoinID,
1298
+ ConditionOpcode.ASSERT_MY_PARENT_ID.value: AssertMyParentID,
1299
+ ConditionOpcode.ASSERT_MY_PUZZLEHASH.value: AssertMyPuzzleHash,
1300
+ ConditionOpcode.ASSERT_MY_AMOUNT.value: AssertMyAmount,
1301
+ ConditionOpcode.ASSERT_MY_BIRTH_SECONDS.value: AssertMyBirthSeconds,
1302
+ ConditionOpcode.ASSERT_MY_BIRTH_HEIGHT.value: AssertMyBirthHeight,
1303
+ ConditionOpcode.ASSERT_EPHEMERAL.value: AssertEphemeral,
1304
+ ConditionOpcode.ASSERT_SECONDS_RELATIVE.value: AssertSecondsRelative,
1305
+ ConditionOpcode.ASSERT_SECONDS_ABSOLUTE.value: AssertSecondsAbsolute,
1306
+ ConditionOpcode.ASSERT_HEIGHT_RELATIVE.value: AssertHeightRelative,
1307
+ ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE.value: AssertHeightAbsolute,
1308
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_RELATIVE.value: AssertBeforeSecondsRelative,
1309
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_ABSOLUTE.value: AssertBeforeSecondsAbsolute,
1310
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_RELATIVE.value: AssertBeforeHeightRelative,
1311
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_ABSOLUTE.value: AssertBeforeHeightAbsolute,
1312
+ ConditionOpcode.SOFTFORK.value: Softfork,
1313
+ ConditionOpcode.REMARK.value: Remark,
1314
+ }
1315
+ DRIVERS_TO_OPCODES: dict[type[Condition], bytes] = {v: k for k, v in CONDITION_DRIVERS.items()}
1316
+
1317
+
1318
+ CONDITION_DRIVERS_W_ABSTRACTIONS: dict[bytes, type[Condition]] = {
1319
+ ConditionOpcode.AGG_SIG_PARENT.value: AggSig,
1320
+ ConditionOpcode.AGG_SIG_PUZZLE.value: AggSig,
1321
+ ConditionOpcode.AGG_SIG_AMOUNT.value: AggSig,
1322
+ ConditionOpcode.AGG_SIG_PUZZLE_AMOUNT.value: AggSig,
1323
+ ConditionOpcode.AGG_SIG_PARENT_AMOUNT.value: AggSig,
1324
+ ConditionOpcode.AGG_SIG_PARENT_PUZZLE.value: AggSig,
1325
+ ConditionOpcode.AGG_SIG_UNSAFE.value: AggSig,
1326
+ ConditionOpcode.AGG_SIG_ME.value: AggSig,
1327
+ ConditionOpcode.CREATE_COIN.value: CreateCoin,
1328
+ ConditionOpcode.RESERVE_FEE.value: ReserveFee,
1329
+ ConditionOpcode.CREATE_COIN_ANNOUNCEMENT.value: CreateAnnouncement,
1330
+ ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT.value: AssertAnnouncement,
1331
+ ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT.value: CreateAnnouncement,
1332
+ ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT.value: AssertAnnouncement,
1333
+ ConditionOpcode.SEND_MESSAGE.value: SendMessage,
1334
+ ConditionOpcode.RECEIVE_MESSAGE.value: ReceiveMessage,
1335
+ ConditionOpcode.ASSERT_CONCURRENT_SPEND.value: AssertConcurrentSpend,
1336
+ ConditionOpcode.ASSERT_CONCURRENT_PUZZLE.value: AssertConcurrentPuzzle,
1337
+ ConditionOpcode.ASSERT_MY_COIN_ID.value: AssertMyCoinID,
1338
+ ConditionOpcode.ASSERT_MY_PARENT_ID.value: AssertMyParentID,
1339
+ ConditionOpcode.ASSERT_MY_PUZZLEHASH.value: AssertMyPuzzleHash,
1340
+ ConditionOpcode.ASSERT_MY_AMOUNT.value: AssertMyAmount,
1341
+ ConditionOpcode.ASSERT_MY_BIRTH_SECONDS.value: AssertMyBirthSeconds,
1342
+ ConditionOpcode.ASSERT_MY_BIRTH_HEIGHT.value: AssertMyBirthHeight,
1343
+ ConditionOpcode.ASSERT_EPHEMERAL.value: AssertEphemeral,
1344
+ ConditionOpcode.ASSERT_SECONDS_RELATIVE.value: Timelock,
1345
+ ConditionOpcode.ASSERT_SECONDS_ABSOLUTE.value: Timelock,
1346
+ ConditionOpcode.ASSERT_HEIGHT_RELATIVE.value: Timelock,
1347
+ ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE.value: Timelock,
1348
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_RELATIVE.value: Timelock,
1349
+ ConditionOpcode.ASSERT_BEFORE_SECONDS_ABSOLUTE.value: Timelock,
1350
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_RELATIVE.value: Timelock,
1351
+ ConditionOpcode.ASSERT_BEFORE_HEIGHT_ABSOLUTE.value: Timelock,
1352
+ ConditionOpcode.SOFTFORK.value: Softfork,
1353
+ ConditionOpcode.REMARK.value: Remark,
1354
+ }
1355
+
1356
+
1357
+ def parse_conditions_non_consensus(
1358
+ conditions: Iterable[Program],
1359
+ abstractions: bool = True, # Use abstractions like *Announcement or Timelock instead of specific condition class
1360
+ ) -> list[Condition]:
1361
+ driver_dictionary: dict[bytes, type[Condition]] = (
1362
+ CONDITION_DRIVERS_W_ABSTRACTIONS if abstractions else CONDITION_DRIVERS
1363
+ )
1364
+ final_condition_list: list[Condition] = []
1365
+ for condition in conditions:
1366
+ try:
1367
+ final_condition_list.append(driver_dictionary[condition.at("f").as_atom()].from_program(condition))
1368
+ except Exception:
1369
+ final_condition_list.append(UnknownCondition.from_program(condition))
1370
+
1371
+ return final_condition_list
1372
+
1373
+
1374
+ def conditions_from_json_dicts(conditions: Iterable[dict[str, Any]]) -> list[Condition]:
1375
+ final_condition_list: list[Condition] = []
1376
+ for condition in conditions:
1377
+ opcode_specified: Union[str, int] = condition["opcode"]
1378
+ if isinstance(opcode_specified, str):
1379
+ try:
1380
+ opcode: bytes = ConditionOpcode[opcode_specified]
1381
+ except KeyError:
1382
+ final_condition_list.append(UnknownCondition.from_json_dict(condition))
1383
+ continue
1384
+ elif isinstance(opcode_specified, int):
1385
+ opcode = int_to_bytes(opcode_specified)
1386
+ else:
1387
+ raise ValueError(f"Invalid condition opcode {opcode_specified}")
1388
+
1389
+ try:
1390
+ final_condition_list.append(CONDITION_DRIVERS[opcode].from_json_dict(condition["args"]))
1391
+ except Exception:
1392
+ condition["opcode"] = Program.to(opcode)
1393
+ final_condition_list.append(UnknownCondition.from_json_dict(condition))
1394
+
1395
+ return final_condition_list
1396
+
1397
+
1398
+ def conditions_to_json_dicts(conditions: Iterable[Condition]) -> list[dict[str, Any]]:
1399
+ return [
1400
+ {
1401
+ "opcode": int_from_bytes(DRIVERS_TO_OPCODES[condition.__class__]),
1402
+ "args": condition.to_json_dict(),
1403
+ }
1404
+ for condition in conditions
1405
+ ]
1406
+
1407
+
1408
+ @streamable
1409
+ @dataclass(frozen=True)
1410
+ class ConditionValidTimes(Streamable):
1411
+ min_secs_since_created: Optional[uint64] = None # ASSERT_SECONDS_RELATIVE
1412
+ min_time: Optional[uint64] = None # ASSERT_SECONDS_ABSOLUTE
1413
+ min_blocks_since_created: Optional[uint32] = None # ASSERT_HEIGHT_RELATIVE
1414
+ min_height: Optional[uint32] = None # ASSERT_HEIGHT_ABSOLUTE
1415
+ max_secs_after_created: Optional[uint64] = None # ASSERT_BEFORE_SECONDS_RELATIVE
1416
+ max_time: Optional[uint64] = None # ASSERT_BEFORE_SECONDS_ABSOLUTE
1417
+ max_blocks_after_created: Optional[uint32] = None # ASSERT_BEFORE_HEIGHT_RELATIVE
1418
+ max_height: Optional[uint32] = None # ASSERT_BEFORE_HEIGHT_ABSOLUTE
1419
+
1420
+ def to_conditions(self) -> list[Condition]:
1421
+ final_condition_list: list[Condition] = []
1422
+ if self.min_secs_since_created is not None:
1423
+ final_condition_list.append(AssertSecondsRelative(self.min_secs_since_created))
1424
+ if self.min_time is not None:
1425
+ final_condition_list.append(AssertSecondsAbsolute(self.min_time))
1426
+ if self.min_blocks_since_created is not None:
1427
+ final_condition_list.append(AssertHeightRelative(self.min_blocks_since_created))
1428
+ if self.min_height is not None:
1429
+ final_condition_list.append(AssertHeightAbsolute(self.min_height))
1430
+ if self.max_secs_after_created is not None:
1431
+ final_condition_list.append(AssertBeforeSecondsRelative(self.max_secs_after_created))
1432
+ if self.max_time is not None:
1433
+ final_condition_list.append(AssertBeforeSecondsAbsolute(self.max_time))
1434
+ if self.max_blocks_after_created is not None:
1435
+ final_condition_list.append(AssertBeforeHeightRelative(self.max_blocks_after_created))
1436
+ if self.max_height is not None:
1437
+ final_condition_list.append(AssertBeforeHeightAbsolute(self.max_height))
1438
+
1439
+ return final_condition_list
1440
+
1441
+
1442
+ condition_valid_times_hints = get_type_hints(ConditionValidTimes)
1443
+ condition_valid_times_types: dict[str, type[int]] = {}
1444
+ for field in fields(ConditionValidTimes):
1445
+ hint = condition_valid_times_hints[field.name]
1446
+ [type_] = [type_ for type_ in hint.__args__ if type_ is not type(None)]
1447
+ condition_valid_times_types[field.name] = type_
1448
+
1449
+
1450
+ # Properties of the dataclass above, grouped by their property
1451
+ SECONDS_PROPERTIES: set[str] = {"min_secs_since_created", "min_time", "max_secs_after_created", "max_time"}
1452
+ HEIGHT_PROPERTIES: set[str] = {"min_blocks_since_created", "min_height", "max_blocks_after_created", "max_height"}
1453
+ AFTER_PROPERTIES: set[str] = {"min_blocks_since_created", "min_height", "min_secs_since_created", "min_time"}
1454
+ BEFORE_PROPERTIES: set[str] = {"max_blocks_after_created", "max_height", "max_secs_after_created", "max_time"}
1455
+ RELATIVE_PROPERTIES: set[str] = {
1456
+ "min_blocks_since_created",
1457
+ "min_secs_since_created",
1458
+ "max_secs_after_created",
1459
+ "max_blocks_after_created",
1460
+ }
1461
+ ABSOLUTE_PROPERTIES: set[str] = {"min_time", "max_time", "min_height", "max_height"}
1462
+ ALL_PROPERTIES: set[str] = SECONDS_PROPERTIES | HEIGHT_PROPERTIES
1463
+
1464
+
1465
+ def parse_timelock_info(conditions: Iterable[Condition]) -> ConditionValidTimes:
1466
+ valid_times: ConditionValidTimes = ConditionValidTimes()
1467
+ properties: set[str] = ALL_PROPERTIES.copy()
1468
+ for condition in conditions:
1469
+ if isinstance(condition, TIMELOCK_DRIVERS):
1470
+ timelock: Timelock = Timelock.from_program(condition.to_program())
1471
+ elif isinstance(condition, Timelock):
1472
+ timelock = condition
1473
+ else:
1474
+ # Something about python 3.9 makes this be not covered but on 3.10+ it is covered
1475
+ # https://github.com/nedbat/coveragepy/issues/1530
1476
+ continue # pragma: no cover
1477
+
1478
+ properties_left = properties.copy()
1479
+ min_not_max: bool = True
1480
+ if timelock.after_not_before:
1481
+ min_not_max = False
1482
+ properties_left -= BEFORE_PROPERTIES
1483
+ else:
1484
+ properties_left -= AFTER_PROPERTIES
1485
+
1486
+ if timelock.seconds_not_height:
1487
+ properties_left -= HEIGHT_PROPERTIES
1488
+ else:
1489
+ properties_left -= SECONDS_PROPERTIES
1490
+
1491
+ if timelock.relative_not_absolute:
1492
+ properties_left -= ABSOLUTE_PROPERTIES
1493
+ else:
1494
+ properties_left -= RELATIVE_PROPERTIES
1495
+
1496
+ assert len(properties_left) == 1
1497
+ final_property: str = next(iter(properties_left))
1498
+ current_value: Optional[int] = getattr(valid_times, final_property)
1499
+ if current_value is not None:
1500
+ if min_not_max:
1501
+ new_value: int = min(current_value, timelock.timestamp)
1502
+ else:
1503
+ new_value = max(current_value, timelock.timestamp)
1504
+ else:
1505
+ new_value = timelock.timestamp
1506
+
1507
+ final_type = condition_valid_times_types[final_property]
1508
+ replacement: dict[str, int] = {final_property: final_type(new_value)}
1509
+ # the type is enforced above
1510
+ valid_times = replace(valid_times, **replacement) # type: ignore[arg-type]
1511
+
1512
+ return valid_times