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,593 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ import signal
6
+ import sys
7
+ import traceback
8
+ from collections.abc import AsyncIterator, Awaitable
9
+ from contextlib import asynccontextmanager
10
+ from dataclasses import dataclass, field
11
+ from ipaddress import IPv4Address, IPv6Address, ip_address
12
+ from multiprocessing import freeze_support
13
+ from pathlib import Path
14
+ from types import FrameType
15
+ from typing import Any, Callable, Optional
16
+
17
+ import aiosqlite
18
+ import dns.asyncresolver
19
+ from dnslib import AAAA, EDNS0, NS, QTYPE, RCODE, RD, RR, SOA, A, DNSError, DNSHeader, DNSQuestion, DNSRecord
20
+
21
+ from chia.seeder.crawl_store import CrawlStore
22
+ from chia.server.signal_handlers import SignalHandlers
23
+ from chia.util.chia_logging import initialize_service_logging
24
+ from chia.util.config import load_config, load_config_cli
25
+ from chia.util.default_root import resolve_root_path
26
+ from chia.util.path import path_from_root
27
+ from chia.util.task_referencer import create_referenced_task
28
+
29
+ SERVICE_NAME = "seeder"
30
+ log = logging.getLogger(__name__)
31
+ DnsCallback = Callable[[DNSRecord], Awaitable[DNSRecord]]
32
+
33
+
34
+ # DNS snippet taken from: https://gist.github.com/pklaus/b5a7876d4d2cf7271873
35
+
36
+
37
+ class DomainName(str):
38
+ def __getattr__(self, item: str) -> DomainName:
39
+ return DomainName(f"{item}.{self}") # DomainName.NS becomes DomainName("NS.DomainName")
40
+
41
+
42
+ @dataclass(frozen=True)
43
+ class PeerList:
44
+ ipv4: list[IPv4Address]
45
+ ipv6: list[IPv6Address]
46
+
47
+ @property
48
+ def no_peers(self) -> bool:
49
+ return not self.ipv4 and not self.ipv6
50
+
51
+
52
+ @dataclass
53
+ class UDPDNSServerProtocol(asyncio.DatagramProtocol):
54
+ """
55
+ This is a really simple UDP Server, that converts all requests to DNSRecord objects and passes them to the callback.
56
+ """
57
+
58
+ callback: DnsCallback
59
+ transport: Optional[asyncio.DatagramTransport] = field(init=False, default=None)
60
+ data_queue: asyncio.Queue[tuple[DNSRecord, tuple[str, int]]] = field(default_factory=asyncio.Queue)
61
+ queue_task: Optional[asyncio.Task[None]] = field(init=False, default=None)
62
+
63
+ def start(self) -> None:
64
+ self.queue_task = create_referenced_task(self.respond()) # This starts the dns respond loop.
65
+
66
+ async def stop(self) -> None:
67
+ if self.queue_task is not None:
68
+ self.queue_task.cancel()
69
+ try:
70
+ await self.queue_task
71
+ except asyncio.CancelledError: # we dont care
72
+ pass
73
+ if self.transport is not None:
74
+ self.transport.close()
75
+
76
+ def connection_made(self, transport: asyncio.BaseTransport) -> None:
77
+ # we use the #ignore because transport is a subclass of BaseTransport, but we need the real type.
78
+ self.transport = transport # type: ignore[assignment]
79
+
80
+ def datagram_received(self, data: bytes, addr: tuple[str, int]) -> None:
81
+ log.debug(f"Received UDP DNS request from {addr}.")
82
+ dns_request: Optional[DNSRecord] = parse_dns_request(data)
83
+ if dns_request is None: # Invalid Request, we can just drop it and move on.
84
+ return
85
+ create_referenced_task(self.handler(dns_request, addr), known_unreferenced=True)
86
+
87
+ async def respond(self) -> None:
88
+ log.info("UDP DNS responder started.")
89
+ # TODO: switch to event driven code
90
+ while self.transport is None: # we wait for the transport to be set. # noqa: ASYNC110
91
+ await asyncio.sleep(0.1)
92
+ while not self.transport.is_closing():
93
+ try:
94
+ edns_max_size = 0
95
+ reply, caller = await self.data_queue.get()
96
+ if len(reply.ar) > 0 and reply.ar[0].rtype == QTYPE.OPT:
97
+ edns_max_size = reply.ar[0].edns_len
98
+
99
+ reply_packed = reply.pack()
100
+
101
+ if len(reply_packed) > max(512, edns_max_size): # 512 is the default max size for DNS:
102
+ log.debug(f"DNS response to {caller} is too large, truncating.")
103
+ reply_packed = reply.truncate().pack()
104
+
105
+ self.transport.sendto(reply_packed, caller)
106
+ log.debug(f"Sent UDP DNS response to {caller}, of size {len(reply_packed)}.")
107
+ except Exception as e:
108
+ log.error(f"Exception while responding to UDP DNS request: {e}. Traceback: {traceback.format_exc()}.")
109
+ log.info("UDP DNS responder stopped.")
110
+
111
+ async def handler(self, data: DNSRecord, caller: tuple[str, int]) -> None:
112
+ r_data = await get_dns_reply(self.callback, data) # process the request, returning a DNSRecord response.
113
+ await self.data_queue.put((r_data, caller))
114
+
115
+
116
+ @dataclass
117
+ class TCPDNSServerProtocol(asyncio.BufferedProtocol):
118
+ """
119
+ This TCP server is a little more complicated, because we need to handle the length field, however it still
120
+ converts all requests to DNSRecord objects and passes them to the callback, after receiving the full message.
121
+ """
122
+
123
+ callback: DnsCallback
124
+ transport: Optional[asyncio.Transport] = field(init=False, default=None)
125
+ peer_info: str = field(init=False, default="")
126
+ expected_length: int = 0
127
+ buffer: bytearray = field(init=False, default_factory=lambda: bytearray(2))
128
+ futures: list[asyncio.Future[None]] = field(init=False, default_factory=list)
129
+
130
+ def connection_made(self, transport: asyncio.BaseTransport) -> None:
131
+ """
132
+ This is called whenever we get a new connection.
133
+ """
134
+ # we use the #ignore because transport is a subclass of BaseTransport, but we need the real type.
135
+ self.transport = transport # type: ignore[assignment]
136
+ peer_info = transport.get_extra_info("peername")
137
+ self.peer_info = f"{peer_info[0]}:{peer_info[1]}"
138
+ log.debug(f"TCP connection established with {self.peer_info}.")
139
+
140
+ def connection_lost(self, exc: Optional[Exception]) -> None:
141
+ """
142
+ This is called whenever a connection is lost, or closed.
143
+ """
144
+ if exc is not None:
145
+ log.debug(f"TCP DNS connection lost with {self.peer_info}. Exception: {exc}.")
146
+ else:
147
+ log.debug(f"TCP DNS connection closed with {self.peer_info}.")
148
+ # reset the state of the protocol.
149
+ for future in self.futures:
150
+ future.cancel()
151
+ self.futures = []
152
+ self.buffer = bytearray(2)
153
+ self.expected_length = 0
154
+
155
+ def get_buffer(self, sizehint: int) -> memoryview:
156
+ """
157
+ This is the first function called after connection_made, it returns a buffer that the tcp server will write to.
158
+ Once a buffer is written to, buffer_updated is called.
159
+ """
160
+ return memoryview(self.buffer)
161
+
162
+ def buffer_updated(self, nbytes: int) -> None:
163
+ """
164
+ This is called whenever the buffer is written to, and it loops through the buffer, grouping them into messages
165
+ and then dns records.
166
+ """
167
+ while not len(self.buffer) == 0 and self.transport is not None:
168
+ if not self.expected_length:
169
+ # Length field received (This is the first part of the message)
170
+ self.expected_length = int.from_bytes(self.buffer, byteorder="big")
171
+ self.buffer = self.buffer[2:] # Remove the length field from the buffer.
172
+
173
+ if len(self.buffer) >= self.expected_length:
174
+ # This is the rest of the message (after the length field)
175
+ message = self.buffer[: self.expected_length]
176
+ self.buffer = self.buffer[self.expected_length :] # Remove the message from the buffer
177
+ self.expected_length = 0 # Reset the expected length
178
+
179
+ dns_request: Optional[DNSRecord] = parse_dns_request(message)
180
+ if dns_request is None: # Invalid Request, so we disconnect and don't send anything back.
181
+ self.transport.close()
182
+ return
183
+ self.futures.append(create_referenced_task(self.handle_and_respond(dns_request)))
184
+
185
+ self.buffer = bytearray(2 if self.expected_length == 0 else self.expected_length) # Reset the buffer if empty.
186
+
187
+ def eof_received(self) -> Optional[bool]:
188
+ """
189
+ This is called when the client closes the connection, False or None means we close the connection.
190
+ True means we keep the connection open.
191
+ """
192
+ if len(self.futures) > 0: # Successful requests
193
+ if self.expected_length != 0: # Incomplete requests
194
+ log.warning(
195
+ f"Received incomplete TCP DNS request of length {self.expected_length} from {self.peer_info}, "
196
+ f"closing connection after dns replies are sent."
197
+ )
198
+ create_referenced_task(self.wait_for_futures(), known_unreferenced=True)
199
+ return True # Keep connection open, until the futures are done.
200
+ log.info(f"Received early EOF from {self.peer_info}, closing connection.")
201
+ return False
202
+
203
+ async def wait_for_futures(self) -> None:
204
+ """
205
+ Waits for all the futures to complete, and then closes the connection.
206
+ """
207
+ try:
208
+ await asyncio.wait_for(asyncio.gather(*self.futures), timeout=10)
209
+ except asyncio.TimeoutError:
210
+ log.warning(f"Timed out waiting for DNS replies to be sent to {self.peer_info}.")
211
+ if self.transport is not None:
212
+ self.transport.close()
213
+
214
+ async def handle_and_respond(self, data: DNSRecord) -> None:
215
+ r_data = await get_dns_reply(self.callback, data) # process the request, returning a DNSRecord response.
216
+ try:
217
+ # If the client closed the connection, we don't want to send anything.
218
+ if self.transport is not None and not self.transport.is_closing():
219
+ self.transport.write(dns_response_to_tcp(r_data)) # send data back to the client
220
+ log.debug(f"Sent DNS response for {data.q.qname}, to {self.peer_info}.")
221
+ except Exception as e:
222
+ log.error(f"Exception while responding to TCP DNS request: {e}. Traceback: {traceback.format_exc()}.")
223
+
224
+
225
+ def dns_response_to_tcp(data: DNSRecord) -> bytes:
226
+ """
227
+ Converts a DNSRecord response to a TCP DNS response, by adding a 2 byte length field to the start.
228
+ """
229
+ dns_response = data.pack()
230
+ dns_response_length = len(dns_response).to_bytes(2, byteorder="big")
231
+ return bytes(dns_response_length + dns_response)
232
+
233
+
234
+ def create_dns_reply(dns_request: DNSRecord) -> DNSRecord:
235
+ """
236
+ Creates a DNS response with the correct header and section flags set.
237
+ """
238
+ # QR means query response, AA means authoritative answer, RA means recursion available
239
+ return DNSRecord(DNSHeader(id=dns_request.header.id, qr=1, aa=1, ra=0), q=dns_request.q)
240
+
241
+
242
+ def parse_dns_request(data: bytes) -> Optional[DNSRecord]:
243
+ """
244
+ Parses the DNS request, and returns a DNSRecord object, or None if the request is invalid.
245
+ """
246
+ dns_request: Optional[DNSRecord] = None
247
+ try:
248
+ dns_request = DNSRecord.parse(data)
249
+ except DNSError as e:
250
+ log.warning(f"Received invalid DNS request: {e}. Traceback: {traceback.format_exc()}.")
251
+ return dns_request
252
+
253
+
254
+ async def get_dns_reply(callback: DnsCallback, dns_request: DNSRecord) -> DNSRecord:
255
+ """
256
+ This function calls the callback, and returns SERVFAIL if the callback raises an exception.
257
+ """
258
+ try:
259
+ dns_reply = await callback(dns_request)
260
+ except Exception as e:
261
+ log.error(f"Exception during DNS record processing: {e}. Traceback: {traceback.format_exc()}.")
262
+ # we return an empty response with an error code
263
+ dns_reply = create_dns_reply(dns_request) # This is an empty response, with only the header set.
264
+ dns_reply.header.rcode = RCODE.SERVFAIL
265
+ return dns_reply
266
+
267
+
268
+ @dataclass
269
+ class DNSServer:
270
+ config: dict[str, Any]
271
+ root_path: Path
272
+ lock: asyncio.Lock = field(default_factory=asyncio.Lock)
273
+ shutdown_event: asyncio.Event = field(default_factory=asyncio.Event)
274
+ crawl_store: Optional[CrawlStore] = field(init=False, default=None)
275
+ reliable_task: Optional[asyncio.Task[None]] = field(init=False, default=None)
276
+ shutting_down: bool = field(init=False, default=False)
277
+ udp_transport_ipv4: Optional[asyncio.DatagramTransport] = field(init=False, default=None)
278
+ udp_protocol_ipv4: Optional[UDPDNSServerProtocol] = field(init=False, default=None)
279
+ udp_transport_ipv6: Optional[asyncio.DatagramTransport] = field(init=False, default=None)
280
+ udp_protocol_ipv6: Optional[UDPDNSServerProtocol] = field(init=False, default=None)
281
+ # TODO: After 3.10 is dropped change to asyncio.Server
282
+ tcp_server: Optional[asyncio.base_events.Server] = field(init=False, default=None)
283
+ # these are all set in __post_init__
284
+ tcp_dns_port: int = field(init=False)
285
+ udp_dns_port: int = field(init=False)
286
+ db_path: Path = field(init=False)
287
+ domain: DomainName = field(init=False)
288
+ ns1: DomainName = field(init=False)
289
+ ns_records: list[RR] = field(init=False)
290
+ ttl: int = field(init=False)
291
+ soa_record: RR = field(init=False)
292
+ reliable_peers_v4: list[IPv4Address] = field(default_factory=list)
293
+ reliable_peers_v6: list[IPv6Address] = field(default_factory=list)
294
+ static_peers_v4: list[IPv4Address] = field(default_factory=list)
295
+ static_peers_v6: list[IPv6Address] = field(default_factory=list)
296
+ resolver: Optional[dns.asyncresolver.Resolver] = field(init=False)
297
+ pointer_v4: int = 0
298
+ pointer_v6: int = 0
299
+
300
+ def __post_init__(self) -> None:
301
+ """
302
+ We initialize all the variables set to field(init=False) here.
303
+ """
304
+ # From Config:
305
+ # The dns ports should only really be different if testing.
306
+ self.tcp_dns_port: int = self.config.get("dns_port", 53)
307
+ self.udp_dns_port: int = self.config.get("dns_port", 53)
308
+ # DB Path:
309
+ crawler_db_path: str = self.config.get("crawler_db_path", "crawler.db")
310
+ self.db_path: Path = path_from_root(self.root_path, crawler_db_path)
311
+ self.db_path.parent.mkdir(parents=True, exist_ok=True)
312
+ # DNS info:
313
+ self.domain: DomainName = DomainName(self.config["domain_name"])
314
+ if not self.domain.endswith("."):
315
+ self.domain = DomainName(self.domain + ".") # Make sure the domain ends with a period, as per RFC 1035.
316
+ self.ns1: DomainName = DomainName(self.config["nameserver"])
317
+ self.ns_records: list[NS] = [NS(self.ns1)]
318
+ self.ttl: int = self.config["ttl"]
319
+ self.soa_record: SOA = SOA(
320
+ mname=self.ns1, # primary name server
321
+ rname=self.config["soa"]["rname"], # email of the domain administrator
322
+ times=(
323
+ self.config["soa"]["serial_number"],
324
+ self.config["soa"]["refresh"],
325
+ self.config["soa"]["retry"],
326
+ self.config["soa"]["expire"],
327
+ self.config["soa"]["minimum"],
328
+ ),
329
+ )
330
+ try:
331
+ self.resolver: Optional[dns.asyncresolver.Resolver] = dns.asyncresolver.Resolver()
332
+ except Exception:
333
+ self.resolver = None
334
+ log.exception("Error initializing asyncresolver for dns_server")
335
+
336
+ @asynccontextmanager
337
+ async def run(self) -> AsyncIterator[None]:
338
+ log.warning("Starting DNS server.")
339
+ # Get a reference to the event loop as we plan to use low-level APIs.
340
+ loop = asyncio.get_running_loop()
341
+
342
+ # Set up the crawl store and the peer update task.
343
+ self.crawl_store = await CrawlStore.create(await aiosqlite.connect(self.db_path, timeout=120))
344
+ self.reliable_task = create_referenced_task(self.periodically_get_reliable_peers())
345
+
346
+ # One protocol instance will be created for each udp transport, so that we can accept ipv4 and ipv6
347
+ self.udp_transport_ipv6, self.udp_protocol_ipv6 = await loop.create_datagram_endpoint(
348
+ lambda: UDPDNSServerProtocol(self.dns_response), local_addr=("::0", self.udp_dns_port)
349
+ )
350
+ self.udp_protocol_ipv6.start() # start ipv6 udp transmit task
351
+
352
+ # in case the port is 0, we get the real port
353
+ self.udp_dns_port = self.udp_transport_ipv6.get_extra_info("sockname")[1] # get the port we bound to
354
+
355
+ if sys.platform.startswith("win32") or sys.platform.startswith("cygwin"):
356
+ # Windows does not support dual stack sockets, so we need to create a new socket for ipv4.
357
+ self.udp_transport_ipv4, self.udp_protocol_ipv4 = await loop.create_datagram_endpoint(
358
+ lambda: UDPDNSServerProtocol(self.dns_response), local_addr=("0.0.0.0", self.udp_dns_port)
359
+ )
360
+ self.udp_protocol_ipv4.start() # start ipv4 udp transmit task
361
+
362
+ # One tcp server will handle both ipv4 and ipv6 on both linux and windows.
363
+ self.tcp_server = await loop.create_server(
364
+ lambda: TCPDNSServerProtocol(self.dns_response), ["::0", "0.0.0.0"], self.tcp_dns_port
365
+ )
366
+
367
+ log.warning("DNS server started.")
368
+ try:
369
+ yield
370
+ finally: # catches any errors and properly shuts down the server
371
+ await self.stop()
372
+ log.warning("DNS server stopped.")
373
+
374
+ async def setup_process_global_state(self, signal_handlers: SignalHandlers) -> None:
375
+ signal_handlers.setup_async_signal_handler(handler=self._accept_signal)
376
+
377
+ async def _accept_signal(
378
+ self,
379
+ signal_: signal.Signals,
380
+ stack_frame: Optional[FrameType],
381
+ loop: asyncio.AbstractEventLoop,
382
+ ) -> None: # pragma: no cover
383
+ log.info("Received signal %s (%s), shutting down.", signal_.name, signal_.value)
384
+ await self.stop()
385
+
386
+ async def stop(self) -> None:
387
+ log.warning("Stopping DNS server...")
388
+ if self.shutting_down:
389
+ return
390
+ self.shutting_down = True
391
+ if self.reliable_task is not None:
392
+ self.reliable_task.cancel() # cancel the peer update task
393
+ if self.crawl_store is not None:
394
+ await self.crawl_store.crawl_db.close()
395
+ if self.udp_protocol_ipv6 is not None:
396
+ await self.udp_protocol_ipv6.stop() # stop responding to and accepting udp requests (ipv6) & ipv4 if linux.
397
+ if self.udp_protocol_ipv4 is not None:
398
+ await self.udp_protocol_ipv4.stop() # stop responding to and accepting udp requests (ipv4) if windows.
399
+ if self.tcp_server is not None:
400
+ self.tcp_server.close() # stop accepting new tcp requests (ipv4 and ipv6)
401
+ await self.tcp_server.wait_closed() # wait for existing TCP requests to finish (ipv4 and ipv6)
402
+ self.shutdown_event.set()
403
+
404
+ async def periodically_get_reliable_peers(self) -> None:
405
+ sleep_interval = 0
406
+ while not self.shutdown_event.is_set() and self.crawl_store is not None:
407
+ await self.refresh_reliable_peers()
408
+ sleep_interval = min(15, sleep_interval + 1)
409
+ await asyncio.sleep(sleep_interval * 60)
410
+
411
+ async def refresh_reliable_peers(self) -> None:
412
+ if self.crawl_store is None:
413
+ return
414
+ new_reliable_peers: list[str] = []
415
+ while not self.shutdown_event.is_set():
416
+ try:
417
+ new_reliable_peers = await self.crawl_store.get_good_peers()
418
+ except Exception as e:
419
+ log.error(f"Error loading reliable peers from database: {e}. Traceback: {traceback.format_exc()}.")
420
+ await asyncio.sleep(2)
421
+ continue
422
+
423
+ static_peers = self.config.get("static_peers", [])
424
+ if len(static_peers) > 0:
425
+ log.warning("have static peers, resolving ip addresses")
426
+ for static_peer in static_peers:
427
+ try:
428
+ log.warning(f"Handling static peer {static_peer}")
429
+ # Attempt to parse as an IP address
430
+ # If this doesn't throw, we can just add to the list
431
+ # Otherwise, we have to resolve the hostname
432
+ ip_address(static_peer)
433
+ new_reliable_peers.append(static_peer)
434
+ except ValueError:
435
+ # Wasn't an IP address, so resolve the hostname
436
+ log.warning(f"Not an IP address, trying to resolve {static_peer} to an IP address")
437
+ if self.resolver is not None:
438
+ for rdtype in ["A", "AAAA"]:
439
+ result = await self.resolver.resolve(qname=static_peer, rdtype=rdtype, lifetime=30)
440
+ for ip in result:
441
+ try:
442
+ ip_as_string = ip.to_text()
443
+ ip_address(ip_as_string)
444
+ new_reliable_peers.append(ip_as_string)
445
+ except ValueError:
446
+ pass
447
+
448
+ if len(new_reliable_peers) > 0:
449
+ break
450
+
451
+ log.warning("No reliable peers found in database, waiting for db to be populated.")
452
+ await asyncio.sleep(2) # sleep for 2 seconds, because the db has not been populated yet.
453
+
454
+ async with self.lock:
455
+ self.reliable_peers_v4 = []
456
+ self.reliable_peers_v6 = []
457
+ self.pointer_v4 = 0
458
+ self.pointer_v6 = 0
459
+ for peer in new_reliable_peers:
460
+ try:
461
+ validated_peer = ip_address(peer)
462
+ if validated_peer.version == 4:
463
+ self.reliable_peers_v4.append(validated_peer)
464
+ elif validated_peer.version == 6:
465
+ self.reliable_peers_v6.append(validated_peer)
466
+ except ValueError:
467
+ log.error(f"Invalid peer: {peer}")
468
+ continue
469
+ log.warning(
470
+ f"Number of reliable peers discovered in dns server:"
471
+ f" IPv4 count - {len(self.reliable_peers_v4)}"
472
+ f" IPv6 count - {len(self.reliable_peers_v6)}"
473
+ )
474
+
475
+ async def get_peers_to_respond(self, ipv4_count: int, ipv6_count: int) -> PeerList:
476
+ async with self.lock:
477
+ # Append IPv4.
478
+ ipv4_peers: list[IPv4Address] = []
479
+ size = len(self.reliable_peers_v4)
480
+ if ipv4_count > 0 and size <= ipv4_count:
481
+ ipv4_peers = self.reliable_peers_v4
482
+ elif ipv4_count > 0:
483
+ ipv4_peers = [
484
+ self.reliable_peers_v4[i % size] for i in range(self.pointer_v4, self.pointer_v4 + ipv4_count)
485
+ ]
486
+ self.pointer_v4 = (self.pointer_v4 + ipv4_count) % size # mark where we left off
487
+ # Append IPv6.
488
+ ipv6_peers: list[IPv6Address] = []
489
+ size = len(self.reliable_peers_v6)
490
+ if ipv6_count > 0 and size <= ipv6_count:
491
+ ipv6_peers = self.reliable_peers_v6
492
+ elif ipv6_count > 0:
493
+ ipv6_peers = [
494
+ self.reliable_peers_v6[i % size] for i in range(self.pointer_v6, self.pointer_v6 + ipv6_count)
495
+ ]
496
+ self.pointer_v6 = (self.pointer_v6 + ipv6_count) % size # mark where we left off
497
+ return PeerList(ipv4_peers, ipv6_peers)
498
+
499
+ async def dns_response(self, request: DNSRecord) -> DNSRecord:
500
+ """
501
+ This function is called when a DNS request is received, and it returns a DNS response.
502
+ It does not catch any errors as it is called from within a try-except block.
503
+ """
504
+ reply = create_dns_reply(request)
505
+ dns_question: DNSQuestion = request.q # this is the question / request
506
+ question_type: int = dns_question.qtype # the type of the record being requested
507
+ qname = dns_question.qname # the name being queried / requested
508
+ # ADD EDNS0 to response if supported
509
+ if len(request.ar) > 0 and request.ar[0].rtype == QTYPE.OPT: # OPT Means EDNS
510
+ udp_len = min(4096, request.ar[0].edns_len)
511
+ edns_reply = EDNS0(udp_len=udp_len)
512
+ reply.add_ar(edns_reply)
513
+ # DNS labels are mixed case with DNS resolvers that implement the use of bit 0x20 to improve
514
+ # transaction identity. See https://datatracker.ietf.org/doc/html/draft-vixie-dnsext-dns0x20-00
515
+ qname_str = str(qname).lower()
516
+ if qname_str != self.domain and not qname_str.endswith(f".{self.domain}"):
517
+ # we don't answer for other domains (we have the not recursive bit set)
518
+ log.warning(f"Invalid request for {qname_str}, returning REFUSED.")
519
+ reply.header.rcode = RCODE.REFUSED
520
+ return reply
521
+
522
+ ttl: int = self.ttl
523
+ # we add these to the list as it will allow us to respond to ns and soa requests
524
+ ips: list[RD] = [self.soa_record, *self.ns_records]
525
+ ipv4_count = 0
526
+ ipv6_count = 0
527
+ if question_type is QTYPE.A:
528
+ ipv4_count = 32
529
+ elif question_type is QTYPE.AAAA:
530
+ ipv6_count = 32
531
+ elif question_type is QTYPE.ANY:
532
+ ipv4_count = 16
533
+ ipv6_count = 16
534
+ else:
535
+ ipv4_count = 32
536
+ peers: PeerList = await self.get_peers_to_respond(ipv4_count, ipv6_count)
537
+ if peers.no_peers:
538
+ log.error("No peers found, returning SOA and NS records only.")
539
+ ttl = 60 # 1 minute as we should have some peers very soon
540
+ # we always return the SOA and NS records, so we continue even if there are no peers
541
+ ips.extend([A(str(peer)) for peer in peers.ipv4])
542
+ ips.extend([AAAA(str(peer)) for peer in peers.ipv6])
543
+
544
+ records: dict[DomainName, list[RD]] = { # this is where we can add other records we want to serve
545
+ self.domain: ips,
546
+ }
547
+
548
+ valid_domain = False
549
+ for domain_name, domain_responses in records.items():
550
+ if domain_name == qname_str: # if the dns name is the same as the requested name
551
+ valid_domain = True
552
+ for response in domain_responses:
553
+ rqt: int = getattr(QTYPE, response.__class__.__name__)
554
+ if question_type in {rqt, QTYPE.ANY}:
555
+ reply.add_answer(RR(rname=qname, rtype=rqt, rclass=1, ttl=ttl, rdata=response))
556
+ if not valid_domain and len(reply.rr) == 0: # if we didn't find any records to return
557
+ reply.header.rcode = RCODE.NXDOMAIN
558
+ # always put nameservers and the SOA records
559
+ for nameserver in self.ns_records:
560
+ reply.add_auth(RR(rname=self.domain, rtype=QTYPE.NS, rclass=1, ttl=ttl, rdata=nameserver))
561
+ reply.add_auth(RR(rname=self.domain, rtype=QTYPE.SOA, rclass=1, ttl=ttl, rdata=self.soa_record))
562
+ return reply
563
+
564
+
565
+ async def run_dns_server(dns_server: DNSServer) -> None: # pragma: no cover
566
+ async with SignalHandlers.manage() as signal_handlers:
567
+ await dns_server.setup_process_global_state(signal_handlers=signal_handlers)
568
+ async with dns_server.run():
569
+ await dns_server.shutdown_event.wait() # this is released on SIGINT or SIGTERM or any unhandled exception
570
+
571
+
572
+ def create_dns_server_service(config: dict[str, Any], root_path: Path) -> DNSServer:
573
+ service_config = config[SERVICE_NAME]
574
+
575
+ return DNSServer(service_config, root_path)
576
+
577
+
578
+ def main() -> None: # pragma: no cover
579
+ freeze_support()
580
+ root_path = resolve_root_path(override=None)
581
+
582
+ # TODO: refactor to avoid the double load
583
+ config = load_config(root_path, "config.yaml")
584
+ service_config = load_config_cli(root_path, "config.yaml", SERVICE_NAME)
585
+ config[SERVICE_NAME] = service_config
586
+ initialize_service_logging(service_name=SERVICE_NAME, config=config, root_path=root_path)
587
+
588
+ dns_server = create_dns_server_service(config, root_path)
589
+ asyncio.run(run_dns_server(dns_server))
590
+
591
+
592
+ if __name__ == "__main__":
593
+ main()