├── .coveragerc ├── .diffcover.toml ├── .git_archival.txt ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md ├── actionlint.yaml ├── actions │ └── install │ │ └── action.yml ├── dependabot.yml ├── release.yml └── workflows │ ├── benchmarks.yml │ ├── build-linux-installer-deb.yml │ ├── build-linux-installer-rpm.yml │ ├── build-macos-installers.yml │ ├── build-windows-installer.yml │ ├── check-commit-signing.yml │ ├── check_wheel_availability.yaml │ ├── codeql-analysis.yml │ ├── conflict-check.yml │ ├── dependency-review.yml │ ├── mozilla-ca-cert.yml │ ├── pre-commit.yml │ ├── reflow-publish-installer.yml │ ├── reflow-version.yml │ ├── require-labels.yml │ ├── stale-issue.yml │ ├── start-release.yml │ ├── start-sync-test.yml │ ├── super-linter.yml │ ├── test-install-scripts.yml │ ├── test-single.yml │ ├── test.yml │ ├── trigger-docker-dev.yml │ ├── trigger-docker-main.yml │ └── upload-pypi-source.yml ├── .gitignore ├── .gitmodules ├── .markdown-lint.yml ├── .pre-commit-config.yaml ├── .prettierrc.yml ├── .repo-content-updater.yml ├── .shellcheckrc ├── BUILD_TIMELORD.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── INSTALL.md ├── Install-gui.ps1 ├── Install-plotter.ps1 ├── Install.ps1 ├── LEGACY-SUPPORT-POLICY.md ├── LICENSE ├── PRETTY_GOOD_PRACTICES.md ├── README.md ├── SECURITY.md ├── Setup-poetry.ps1 ├── activated.ps1 ├── activated.py ├── activated.sh ├── benchmarks ├── __init__.py ├── address_manager_store.py ├── block_ref.py ├── block_store.py ├── blockchains.py ├── coin_store.py ├── jsonify.py ├── mempool-long-lived.py ├── mempool.py ├── streamable.py ├── transaction_height_delta └── utils.py ├── build_scripts ├── __init__.py ├── assets │ ├── __init__.py │ ├── deb │ │ ├── __init__.py │ │ ├── control.j2 │ │ ├── postinst.sh │ │ └── prerm.sh │ ├── dmg │ │ ├── README │ │ ├── __init__.py │ │ └── background.tiff │ ├── rpm │ │ ├── __init__.py │ │ ├── before-install.sh │ │ ├── postinst.sh │ │ └── prerm.sh │ └── systemd │ │ ├── __init__.py │ │ ├── chia-crawler@.service │ │ ├── chia-daemon@.service │ │ ├── chia-data-layer-http@.service │ │ ├── chia-data-layer@.service │ │ ├── chia-farmer@.service │ │ ├── chia-full-node@.service │ │ ├── chia-harvester@.service │ │ ├── chia-introducer@.service │ │ ├── chia-seeder@.service │ │ ├── chia-timelord@.service │ │ └── chia-wallet@.service ├── build_license_directory.sh ├── build_linux_deb-1-gui.sh ├── build_linux_deb-2-installer.sh ├── build_linux_rpm-1-gui.sh ├── build_linux_rpm-2-installer.sh ├── build_macos-1-gui.sh ├── build_macos-2-installer.sh ├── build_win_license_dir.sh ├── build_windows-1-gui.ps1 ├── build_windows-2-installer.ps1 ├── check_dependency_artifacts.py ├── clean-runner.sh ├── electron-builder.json ├── npm_global │ ├── __init__.py │ ├── package-lock.json │ └── package.json ├── npm_linux │ ├── __init__.py │ ├── package-lock.json │ └── package.json ├── npm_macos │ ├── __init__.py │ ├── package-lock.json │ └── package.json ├── npm_windows │ ├── __init__.py │ ├── package-lock.json │ └── package.json ├── pyinstaller.spec └── remove_brew_rpaths.sh ├── chia ├── __init__.py ├── __main__.py ├── _tests │ ├── README.md │ ├── __init__.py │ ├── blockchain │ │ ├── __init__.py │ │ ├── blockchain_test_utils.py │ │ ├── config.py │ │ ├── test_augmented_chain.py │ │ ├── test_blockchain.py │ │ ├── test_blockchain_transactions.py │ │ ├── test_build_chains.py │ │ ├── test_get_block_generator.py │ │ └── test_lookup_fork_chain.py │ ├── build-init-files.py │ ├── build-job-matrix.py │ ├── check_pytest_monitor_output.py │ ├── check_sql_statements.py │ ├── chia-start-sim │ ├── clvm │ │ ├── __init__.py │ │ ├── benchmark_costs.py │ │ ├── coin_store.py │ │ ├── test_chialisp_deserialization.py │ │ ├── test_clvm_step.py │ │ ├── test_curry_and_treehash.py │ │ ├── test_message_conditions.py │ │ ├── test_program.py │ │ ├── test_puzzle_compression.py │ │ ├── test_puzzle_drivers.py │ │ ├── test_puzzles.py │ │ ├── test_singletons.py │ │ └── test_spend_sim.py │ ├── cmds │ │ ├── __init__.py │ │ ├── cmd_test_utils.py │ │ ├── config.py │ │ ├── conftest.py │ │ ├── test_click_types.py │ │ ├── test_cmd_framework.py │ │ ├── test_cmds_util.py │ │ ├── test_daemon.py │ │ ├── test_dev_gh.py │ │ ├── test_farm_cmd.py │ │ ├── test_show.py │ │ ├── test_sim.py │ │ ├── test_timelock_args.py │ │ ├── test_tx_config_args.py │ │ ├── testing_classes.py │ │ └── wallet │ │ │ ├── __init__.py │ │ │ ├── test_consts.py │ │ │ ├── test_did.py │ │ │ ├── test_nft.py │ │ │ ├── test_notifications.py │ │ │ ├── test_offer.toffer │ │ │ ├── test_tx_decorators.py │ │ │ ├── test_vcs.py │ │ │ ├── test_wallet.py │ │ │ └── test_wallet_check.py │ ├── conftest.py │ ├── connection_utils.py │ ├── core │ │ ├── __init__.py │ │ ├── cmds │ │ │ ├── __init__.py │ │ │ ├── test_beta.py │ │ │ ├── test_keys.py │ │ │ └── test_wallet.py │ │ ├── config.py │ │ ├── consensus │ │ │ ├── __init__.py │ │ │ ├── test_block_creation.py │ │ │ └── test_pot_iterations.py │ │ ├── custom_types │ │ │ ├── __init__.py │ │ │ ├── test_coin.py │ │ │ ├── test_proof_of_space.py │ │ │ └── test_spend_bundle.py │ │ ├── daemon │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_daemon.py │ │ │ ├── test_daemon_register.py │ │ │ └── test_keychain_proxy.py │ │ ├── data_layer │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── conftest.py │ │ │ ├── test_data_cli.py │ │ │ ├── test_data_layer.py │ │ │ ├── test_data_layer_util.py │ │ │ ├── test_data_rpc.py │ │ │ ├── test_data_store.py │ │ │ ├── test_data_store_schema.py │ │ │ ├── test_plugin.py │ │ │ └── util.py │ │ ├── farmer │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ └── test_farmer_api.py │ │ ├── full_node │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── dos │ │ │ │ ├── __init__.py │ │ │ │ └── config.py │ │ │ ├── full_sync │ │ │ │ ├── __init__.py │ │ │ │ ├── config.py │ │ │ │ └── test_full_sync.py │ │ │ ├── ram_db.py │ │ │ ├── stores │ │ │ │ ├── __init__.py │ │ │ │ ├── config.py │ │ │ │ ├── test_block_store.py │ │ │ │ ├── test_coin_store.py │ │ │ │ ├── test_full_node_store.py │ │ │ │ ├── test_hint_store.py │ │ │ │ └── test_sync_store.py │ │ │ ├── test_address_manager.py │ │ │ ├── test_block_height_map.py │ │ │ ├── test_conditions.py │ │ │ ├── test_full_node.py │ │ │ ├── test_generator_tools.py │ │ │ ├── test_hint_management.py │ │ │ ├── test_node_load.py │ │ │ ├── test_performance.py │ │ │ ├── test_prev_tx_block.py │ │ │ ├── test_subscriptions.py │ │ │ ├── test_transactions.py │ │ │ └── test_tx_processing_queue.py │ │ ├── large_block.py │ │ ├── make_block_generator.py │ │ ├── mempool │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_mempool.py │ │ │ ├── test_mempool_fee_estimator.py │ │ │ ├── test_mempool_fee_protocol.py │ │ │ ├── test_mempool_item_queries.py │ │ │ ├── test_mempool_manager.py │ │ │ ├── test_mempool_performance.py │ │ │ └── test_singleton_fast_forward.py │ │ ├── node_height.py │ │ ├── server │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── flood.py │ │ │ ├── serve.py │ │ │ ├── test_api_protocol.py │ │ │ ├── test_capabilities.py │ │ │ ├── test_dos.py │ │ │ ├── test_event_loop.py │ │ │ ├── test_loop.py │ │ │ ├── test_node_discovery.py │ │ │ ├── test_rate_limits.py │ │ │ ├── test_server.py │ │ │ └── test_upnp.py │ │ ├── services │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ └── test_services.py │ │ ├── ssl │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ └── test_ssl.py │ │ ├── test_coins.py │ │ ├── test_cost_calculation.py │ │ ├── test_crawler.py │ │ ├── test_crawler_rpc.py │ │ ├── test_daemon_rpc.py │ │ ├── test_db_conversion.py │ │ ├── test_db_validation.py │ │ ├── test_farmer_harvester_rpc.py │ │ ├── test_filter.py │ │ ├── test_full_node_rpc.py │ │ ├── test_merkle_set.py │ │ ├── test_program.py │ │ ├── test_rpc_util.py │ │ ├── test_seeder.py │ │ ├── test_setproctitle.py │ │ └── util │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_block_cache.py │ │ │ ├── test_cached_bls.py │ │ │ ├── test_config.py │ │ │ ├── test_file_keyring_synchronization.py │ │ │ ├── test_files.py │ │ │ ├── test_jsonify.py │ │ │ ├── test_keychain.py │ │ │ ├── test_keyring_wrapper.py │ │ │ ├── test_lockfile.py │ │ │ ├── test_log_exceptions.py │ │ │ ├── test_lru_cache.py │ │ │ ├── test_significant_bits.py │ │ │ └── test_streamable.py │ ├── db │ │ ├── __init__.py │ │ └── test_db_wrapper.py │ ├── environments │ │ ├── __init__.py │ │ ├── common.py │ │ ├── full_node.py │ │ └── wallet.py │ ├── ether.py │ ├── farmer_harvester │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_farmer.py │ │ ├── test_farmer_harvester.py │ │ ├── test_filter_prefix_bits.py │ │ ├── test_third_party_harvesters.py │ │ └── test_third_party_harvesters_data.json │ ├── fee_estimation │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_fee_estimation_integration.py │ │ ├── test_fee_estimation_rpc.py │ │ └── test_fee_estimation_unit_tests.py │ ├── generator │ │ ├── __init__.py │ │ ├── puzzles │ │ │ ├── __init__.py │ │ │ ├── test_generator_deserialize.clsp │ │ │ ├── test_generator_deserialize.clsp.hex │ │ │ ├── test_multiple_generator_input_arguments.clsp │ │ │ └── test_multiple_generator_input_arguments.clsp.hex │ │ ├── test_compression.py │ │ ├── test_generator_types.py │ │ └── test_rom.py │ ├── plot_sync │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_delta.py │ │ ├── test_plot_sync.py │ │ ├── test_receiver.py │ │ ├── test_sender.py │ │ ├── test_sync_simulated.py │ │ └── util.py │ ├── plotting │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_plot_manager.py │ │ └── util.py │ ├── pools │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_pool_cli_parsing.py │ │ ├── test_pool_cmdline.py │ │ ├── test_pool_config.py │ │ ├── test_pool_puzzles_lifecycle.py │ │ ├── test_pool_rpc.py │ │ ├── test_pool_wallet.py │ │ └── test_wallet_pool_store.py │ ├── process_junit.py │ ├── rpc │ │ ├── __init__.py │ │ ├── test_rpc_client.py │ │ └── test_rpc_server.py │ ├── simulation │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_simulation.py │ │ ├── test_simulator.py │ │ └── test_start_simulator.py │ ├── testconfig.py │ ├── timelord │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_new_peak.py │ │ └── test_timelord.py │ ├── tools │ │ ├── 1315537.json │ │ ├── 1315544.json │ │ ├── 1315630.json │ │ ├── 300000.json │ │ ├── 442734.json │ │ ├── 466212.json │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test-blockchain-db.sqlite │ │ ├── test_full_sync.py │ │ ├── test_legacy_keyring.py │ │ ├── test_run_block.py │ │ └── test_virtual_project.py │ ├── util │ │ ├── __init__.py │ │ ├── benchmark_cost.py │ │ ├── benchmarks.py │ │ ├── bip39_test_vectors.json │ │ ├── blockchain.py │ │ ├── blockchain_mock.py │ │ ├── build_network_protocol_files.py │ │ ├── clvm_generator.bin │ │ ├── config.py │ │ ├── constants.py │ │ ├── db_connection.py │ │ ├── full_sync.py │ │ ├── gen_ssl_certs.py │ │ ├── generator_tools_testing.py │ │ ├── get_name_puzzle_conditions.py │ │ ├── key_tool.py │ │ ├── misc.py │ │ ├── network_protocol_data.py │ │ ├── protocol_messages_bytes-v1.0 │ │ ├── protocol_messages_json.py │ │ ├── rpc.py │ │ ├── run_block.py │ │ ├── setup_nodes.py │ │ ├── spend_sim.py │ │ ├── split_managers.py │ │ ├── temp_file.py │ │ ├── test_action_scope.py │ │ ├── test_async_pool.py │ │ ├── test_build_job_matrix.py │ │ ├── test_build_network_protocol_files.py │ │ ├── test_chia_version.py │ │ ├── test_collection.py │ │ ├── test_condition_tools.py │ │ ├── test_config.py │ │ ├── test_dump_keyring.py │ │ ├── test_errors.py │ │ ├── test_full_block_utils.py │ │ ├── test_installed.py │ │ ├── test_limited_semaphore.py │ │ ├── test_logging_filter.py │ │ ├── test_misc.py │ │ ├── test_network.py │ │ ├── test_network_protocol_files.py │ │ ├── test_network_protocol_json.py │ │ ├── test_network_protocol_test.py │ │ ├── test_paginator.py │ │ ├── test_pprint.py │ │ ├── test_priority_mutex.py │ │ ├── test_recursive_replace.py │ │ ├── test_replace_str_to_bytes.py │ │ ├── test_service_groups.py │ │ ├── test_ssl_check.py │ │ ├── test_testnet_overrides.py │ │ ├── test_tests_misc.py │ │ ├── test_timing.py │ │ ├── test_trusted_peer.py │ │ └── time_out_assert.py │ ├── wallet │ │ ├── __init__.py │ │ ├── cat_wallet │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_cat_lifecycle.py │ │ │ ├── test_cat_outer_puzzle.py │ │ │ ├── test_cat_wallet.py │ │ │ ├── test_offer_lifecycle.py │ │ │ └── test_trades.py │ │ ├── clawback │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_clawback_decorator.py │ │ │ ├── test_clawback_lifecycle.py │ │ │ └── test_clawback_metadata.py │ │ ├── config.py │ │ ├── conftest.py │ │ ├── db_wallet │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_db_graftroot.py │ │ │ ├── test_dl_offers.py │ │ │ └── test_dl_wallet.py │ │ ├── did_wallet │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ └── test_did.py │ │ ├── nft_wallet │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_nft_1_offers.py │ │ │ ├── test_nft_bulk_mint.py │ │ │ ├── test_nft_lifecycle.py │ │ │ ├── test_nft_offers.py │ │ │ ├── test_nft_puzzles.py │ │ │ ├── test_nft_wallet.py │ │ │ └── test_ownership_outer_puzzle.py │ │ ├── rpc │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_dl_wallet_rpc.py │ │ │ └── test_wallet_rpc.py │ │ ├── simple_sync │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ └── test_simple_sync_protocol.py │ │ ├── sync │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ └── test_wallet_sync.py │ │ ├── test_address_type.py │ │ ├── test_bech32m.py │ │ ├── test_clvm_streamable.py │ │ ├── test_coin_management.py │ │ ├── test_coin_selection.py │ │ ├── test_conditions.py │ │ ├── test_debug_spend_bundle.py │ │ ├── test_new_wallet_protocol.py │ │ ├── test_nft_store.py │ │ ├── test_notifications.py │ │ ├── test_offer_parsing_performance.py │ │ ├── test_puzzle_store.py │ │ ├── test_sign_coin_spends.py │ │ ├── test_signer_protocol.py │ │ ├── test_singleton.py │ │ ├── test_singleton_lifecycle_fast.py │ │ ├── test_singleton_store.py │ │ ├── test_taproot.py │ │ ├── test_transaction_store.py │ │ ├── test_util.py │ │ ├── test_wallet.py │ │ ├── test_wallet_action_scope.py │ │ ├── test_wallet_blockchain.py │ │ ├── test_wallet_coin_store.py │ │ ├── test_wallet_interested_store.py │ │ ├── test_wallet_key_val_store.py │ │ ├── test_wallet_node.py │ │ ├── test_wallet_retry.py │ │ ├── test_wallet_state_manager.py │ │ ├── test_wallet_test_framework.py │ │ ├── test_wallet_trade_store.py │ │ ├── test_wallet_user_store.py │ │ ├── test_wallet_utils.py │ │ ├── vc_wallet │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── test_cr_outer_puzzle.py │ │ │ ├── test_vc_lifecycle.py │ │ │ └── test_vc_wallet.py │ │ └── wallet_block_tools.py │ └── weight_proof │ │ ├── __init__.py │ │ ├── config.py │ │ └── test_weight_proof.py ├── apis.py ├── clvm │ └── __init__.py ├── cmds │ ├── __init__.py │ ├── beta.py │ ├── beta_funcs.py │ ├── check_wallet_db.py │ ├── chia.py │ ├── cmd_classes.py │ ├── cmd_helpers.py │ ├── cmds_util.py │ ├── coin_funcs.py │ ├── coins.py │ ├── completion.py │ ├── configure.py │ ├── data.py │ ├── data_funcs.py │ ├── db.py │ ├── db_backup_func.py │ ├── db_upgrade_func.py │ ├── db_validate_func.py │ ├── dev │ │ ├── __init__.py │ │ ├── data.py │ │ ├── gh.py │ │ ├── installers.py │ │ ├── main.py │ │ ├── mempool.py │ │ ├── mempool_funcs.py │ │ └── sim.py │ ├── dump_keyring.py │ ├── farm.py │ ├── farm_funcs.py │ ├── init.py │ ├── init_funcs.py │ ├── keys.py │ ├── keys_funcs.py │ ├── netspace.py │ ├── netspace_funcs.py │ ├── options.py │ ├── param_types.py │ ├── passphrase.py │ ├── passphrase_funcs.py │ ├── peer.py │ ├── peer_funcs.py │ ├── plotnft.py │ ├── plotnft_funcs.py │ ├── plots.py │ ├── plotters.py │ ├── rpc.py │ ├── show.py │ ├── show_funcs.py │ ├── signer.py │ ├── sim_funcs.py │ ├── start.py │ ├── start_funcs.py │ ├── stop.py │ ├── units.py │ ├── wallet.py │ └── wallet_funcs.py ├── consensus │ ├── __init__.py │ ├── augmented_chain.py │ ├── block_body_validation.py │ ├── block_creation.py │ ├── block_header_validation.py │ ├── block_record.py │ ├── block_rewards.py │ ├── blockchain.py │ ├── blockchain_interface.py │ ├── coinbase.py │ ├── condition_costs.py │ ├── condition_tools.py │ ├── constants.py │ ├── cost_calculator.py │ ├── default_constants.py │ ├── deficit.py │ ├── difficulty_adjustment.py │ ├── find_fork_point.py │ ├── full_block_to_block_record.py │ ├── generator_tools.py │ ├── get_block_challenge.py │ ├── get_block_generator.py │ ├── make_sub_epoch_summary.py │ ├── multiprocess_validation.py │ ├── pos_quality.py │ ├── pot_iterations.py │ ├── prev_transaction_block.py │ └── vdf_info_computation.py ├── daemon │ ├── __init__.py │ ├── client.py │ ├── keychain_proxy.py │ ├── keychain_server.py │ ├── server.py │ └── windows_signal.py ├── data_layer │ ├── __init__.py │ ├── data_layer.py │ ├── data_layer_api.py │ ├── data_layer_errors.py │ ├── data_layer_server.py │ ├── data_layer_util.py │ ├── data_layer_wallet.py │ ├── data_store.py │ ├── dl_wallet_store.py │ ├── download_data.py │ ├── puzzles │ │ ├── __init__.py │ │ ├── graftroot_dl_offers.clsp │ │ └── graftroot_dl_offers.clsp.hex │ ├── s3_plugin_config.yml │ ├── s3_plugin_service.py │ ├── singleton_record.py │ └── util │ │ ├── __init__.py │ │ ├── benchmark.py │ │ └── plugin.py ├── farmer │ ├── __init__.py │ ├── farmer.py │ └── farmer_api.py ├── full_node │ ├── __init__.py │ ├── bitcoin_fee_estimator.py │ ├── block_height_map.py │ ├── block_store.py │ ├── bundle_tools.py │ ├── check_fork_next_block.py │ ├── coin_store.py │ ├── eligible_coin_spends.py │ ├── fee_estimation.py │ ├── fee_estimator.py │ ├── fee_estimator_constants.py │ ├── fee_estimator_interface.py │ ├── fee_history.py │ ├── fee_tracker.py │ ├── full_block_utils.py │ ├── full_node.py │ ├── full_node_api.py │ ├── full_node_store.py │ ├── hint_management.py │ ├── hint_store.py │ ├── mempool.py │ ├── mempool_check_conditions.py │ ├── mempool_manager.py │ ├── pending_tx_cache.py │ ├── signage_point.py │ ├── subscriptions.py │ ├── sync_store.py │ ├── tx_processing_queue.py │ ├── util │ │ └── __init__.py │ └── weight_proof.py ├── harvester │ ├── __init__.py │ ├── harvester.py │ └── harvester_api.py ├── introducer │ ├── __init__.py │ ├── introducer.py │ └── introducer_api.py ├── legacy │ ├── __init__.py │ └── keyring.py ├── plot_sync │ ├── __init__.py │ ├── delta.py │ ├── exceptions.py │ ├── receiver.py │ ├── sender.py │ └── util.py ├── plotters │ ├── __init__.py │ ├── bladebit.py │ ├── chiapos.py │ ├── madmax.py │ ├── plotters.py │ └── plotters_util.py ├── plotting │ ├── __init__.py │ ├── cache.py │ ├── check_plots.py │ ├── create_plots.py │ ├── manager.py │ └── util.py ├── pools │ ├── __init__.py │ ├── pool_config.py │ ├── pool_puzzles.py │ ├── pool_wallet.py │ └── pool_wallet_info.py ├── protocols │ ├── __init__.py │ ├── farmer_protocol.py │ ├── fee_estimate.py │ ├── fee_estimate_store.py │ ├── full_node_protocol.py │ ├── harvester_protocol.py │ ├── introducer_protocol.py │ ├── outbound_message.py │ ├── pool_protocol.py │ ├── protocol_message_types.py │ ├── protocol_state_machine.py │ ├── protocol_timing.py │ ├── shared_protocol.py │ ├── timelord_protocol.py │ └── wallet_protocol.py ├── py.typed ├── rpc │ ├── __init__.py │ ├── crawler_rpc_api.py │ ├── data_layer_rpc_api.py │ ├── data_layer_rpc_client.py │ ├── data_layer_rpc_util.py │ ├── farmer_rpc_api.py │ ├── farmer_rpc_client.py │ ├── full_node_rpc_api.py │ ├── full_node_rpc_client.py │ ├── harvester_rpc_api.py │ ├── harvester_rpc_client.py │ ├── rpc_client.py │ ├── rpc_server.py │ ├── timelord_rpc_api.py │ ├── util.py │ ├── wallet_request_types.py │ ├── wallet_rpc_api.py │ └── wallet_rpc_client.py ├── seeder │ ├── __init__.py │ ├── crawl_store.py │ ├── crawler.py │ ├── crawler_api.py │ ├── dns_server.py │ ├── peer_record.py │ └── start_crawler.py ├── server │ ├── __init__.py │ ├── address_manager.py │ ├── address_manager_store.py │ ├── aliases.py │ ├── api_protocol.py │ ├── capabilities.py │ ├── chia_policy.py │ ├── introducer_peers.py │ ├── node_discovery.py │ ├── rate_limit_numbers.py │ ├── rate_limits.py │ ├── resolve_peer_info.py │ ├── server.py │ ├── signal_handlers.py │ ├── ssl_context.py │ ├── start_data_layer.py │ ├── start_farmer.py │ ├── start_full_node.py │ ├── start_harvester.py │ ├── start_introducer.py │ ├── start_service.py │ ├── start_timelord.py │ ├── start_wallet.py │ ├── upnp.py │ └── ws_connection.py ├── simulator │ ├── __init__.py │ ├── add_blocks_in_batches.py │ ├── block_tools.py │ ├── full_node_simulator.py │ ├── keyring.py │ ├── setup_services.py │ ├── simulator_full_node_rpc_api.py │ ├── simulator_full_node_rpc_client.py │ ├── simulator_protocol.py │ ├── simulator_test_tools.py │ ├── socket.py │ ├── ssl_certs.py │ ├── ssl_certs_1.py │ ├── ssl_certs_10.py │ ├── ssl_certs_2.py │ ├── ssl_certs_3.py │ ├── ssl_certs_4.py │ ├── ssl_certs_5.py │ ├── ssl_certs_6.py │ ├── ssl_certs_7.py │ ├── ssl_certs_8.py │ ├── ssl_certs_9.py │ ├── start_simulator.py │ ├── vdf_prover.py │ └── wallet_tools.py ├── ssl │ ├── __init__.py │ ├── chia_ca.crt │ ├── chia_ca.key │ ├── create_ssl.py │ ├── dst_root_ca.pem │ └── ssl_check.py ├── timelord │ ├── __init__.py │ ├── iters_from_block.py │ ├── timelord.py │ ├── timelord_api.py │ ├── timelord_launcher.py │ ├── timelord_state.py │ └── types.py ├── types │ ├── __init__.py │ ├── block_protocol.py │ ├── blockchain_format │ │ ├── __init__.py │ │ ├── classgroup.py │ │ ├── coin.py │ │ ├── program.py │ │ ├── proof_of_space.py │ │ ├── serialized_program.py │ │ ├── tree_hash.py │ │ └── vdf.py │ ├── clvm_cost.py │ ├── coin_record.py │ ├── coin_spend.py │ ├── condition_opcodes.py │ ├── condition_with_args.py │ ├── fee_rate.py │ ├── generator_types.py │ ├── internal_mempool_item.py │ ├── mempool_inclusion_status.py │ ├── mempool_item.py │ ├── mempool_submission_status.py │ ├── mojos.py │ ├── peer_info.py │ ├── signing_mode.py │ ├── unfinished_header_block.py │ ├── validation_state.py │ └── weight_proof.py ├── util │ ├── __init__.py │ ├── action_scope.py │ ├── async_pool.py │ ├── batches.py │ ├── bech32m.py │ ├── beta_metrics.py │ ├── block_cache.py │ ├── byte_types.py │ ├── chia_logging.py │ ├── chia_version.py │ ├── collection.py │ ├── config.py │ ├── cpu.py │ ├── db_synchronous.py │ ├── db_version.py │ ├── db_wrapper.py │ ├── default_root.py │ ├── english.txt │ ├── errors.py │ ├── file_keyring.py │ ├── files.py │ ├── hash.py │ ├── initial-config.yaml │ ├── inline_executor.py │ ├── ip_address.py │ ├── json_util.py │ ├── keychain.py │ ├── keyring_wrapper.py │ ├── limited_semaphore.py │ ├── lock.py │ ├── log_exceptions.py │ ├── logging.py │ ├── lru_cache.py │ ├── math.py │ ├── network.py │ ├── paginator.py │ ├── path.py │ ├── permissions.py │ ├── priority_mutex.py │ ├── profiler.py │ ├── recursive_replace.py │ ├── safe_cancel_task.py │ ├── service_groups.py │ ├── setproctitle.py │ ├── significant_bits.py │ ├── streamable.py │ ├── task_referencer.py │ ├── task_timing.py │ ├── timing.py │ ├── virtual_project_analysis.py │ └── ws_message.py └── wallet │ ├── __init__.py │ ├── cat_wallet │ ├── __init__.py │ ├── cat_constants.py │ ├── cat_info.py │ ├── cat_outer_puzzle.py │ ├── cat_utils.py │ ├── cat_wallet.py │ └── lineage_store.py │ ├── coin_selection.py │ ├── conditions.py │ ├── db_wallet │ ├── __init__.py │ └── db_wallet_puzzles.py │ ├── derivation_record.py │ ├── derive_keys.py │ ├── did_wallet │ ├── __init__.py │ ├── did_info.py │ ├── did_wallet.py │ └── did_wallet_puzzles.py │ ├── driver_protocol.py │ ├── estimate_fees.py │ ├── key_val_store.py │ ├── lineage_proof.py │ ├── nft_wallet │ ├── __init__.py │ ├── metadata_outer_puzzle.py │ ├── nft_info.py │ ├── nft_puzzle_utils.py │ ├── nft_puzzles.py │ ├── nft_wallet.py │ ├── ownership_outer_puzzle.py │ ├── puzzles │ │ ├── __init__.py │ │ ├── create_nft_launcher_from_did.clsp │ │ ├── create_nft_launcher_from_did.clsp.hex │ │ ├── nft_intermediate_launcher.clsp │ │ ├── nft_intermediate_launcher.clsp.hex │ │ ├── nft_metadata_updater_default.clsp │ │ ├── nft_metadata_updater_default.clsp.hex │ │ ├── nft_metadata_updater_updateable.clsp │ │ ├── nft_metadata_updater_updateable.clsp.hex │ │ ├── nft_ownership_layer.clsp │ │ ├── nft_ownership_layer.clsp.hex │ │ ├── nft_ownership_transfer_program_one_way_claim_with_royalties.clsp │ │ ├── nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex │ │ ├── nft_state_layer.clsp │ │ └── nft_state_layer.clsp.hex │ ├── singleton_outer_puzzle.py │ ├── transfer_program_puzzle.py │ └── uncurry_nft.py │ ├── notification_manager.py │ ├── notification_store.py │ ├── outer_puzzles.py │ ├── puzzle_drivers.py │ ├── puzzles │ ├── __init__.py │ ├── clawback │ │ ├── __init__.py │ │ ├── drivers.py │ │ ├── metadata.py │ │ └── puzzle_decorator.py │ ├── deployed_puzzle_hashes.json │ ├── load_clvm.py │ ├── p2_conditions.py │ ├── p2_delegated_conditions.py │ ├── p2_delegated_puzzle.py │ ├── p2_delegated_puzzle_or_hidden_puzzle.py │ ├── p2_m_of_n_delegate_direct.py │ ├── p2_puzzle_hash.py │ ├── puzzle_utils.py │ ├── singleton_top_layer.py │ ├── singleton_top_layer_v1_1.py │ ├── tails.py │ └── utility_macros.clib │ ├── signer_protocol.py │ ├── singleton.py │ ├── singleton_record.py │ ├── trade_manager.py │ ├── trade_record.py │ ├── trading │ ├── __init__.py │ ├── offer.py │ ├── trade_status.py │ └── trade_store.py │ ├── transaction_record.py │ ├── transaction_sorting.py │ ├── uncurried_puzzle.py │ ├── util │ ├── __init__.py │ ├── address_type.py │ ├── blind_signer_tl.py │ ├── clvm_streamable.py │ ├── compute_additions.py │ ├── compute_hints.py │ ├── compute_memos.py │ ├── curry_and_treehash.py │ ├── debug_spend_bundle.py │ ├── merkle_tree.py │ ├── merkle_utils.py │ ├── new_peak_queue.py │ ├── notifications.py │ ├── peer_request_cache.py │ ├── pprint.py │ ├── puzzle_compression.py │ ├── puzzle_decorator.py │ ├── puzzle_decorator_type.py │ ├── query_filter.py │ ├── transaction_type.py │ ├── tx_config.py │ ├── wallet_sync_utils.py │ └── wallet_types.py │ ├── vc_wallet │ ├── __init__.py │ ├── cr_cat_drivers.py │ ├── cr_cat_wallet.py │ ├── cr_outer_puzzle.py │ ├── vc_drivers.py │ ├── vc_store.py │ └── vc_wallet.py │ ├── wallet.py │ ├── wallet_action_scope.py │ ├── wallet_blockchain.py │ ├── wallet_coin_record.py │ ├── wallet_coin_store.py │ ├── wallet_info.py │ ├── wallet_interested_store.py │ ├── wallet_nft_store.py │ ├── wallet_node.py │ ├── wallet_node_api.py │ ├── wallet_pool_store.py │ ├── wallet_protocol.py │ ├── wallet_puzzle_store.py │ ├── wallet_retry_store.py │ ├── wallet_singleton_store.py │ ├── wallet_spend_bundle.py │ ├── wallet_state_manager.py │ ├── wallet_transaction_store.py │ ├── wallet_user_store.py │ ├── wallet_weight_proof_handler.py │ └── wsm_apis.py ├── install-gui.sh ├── install-plotter.sh ├── install-timelord.sh ├── install.sh ├── installhelper.py ├── manage-mypy.py ├── mypy-exclusions.txt ├── mypy.ini.template ├── poetry.lock ├── poetry.toml ├── pyproject.toml ├── pytest.ini ├── requirements-poetry.txt ├── ruff.toml ├── setup-poetry.sh ├── start-gui.sh ├── tools ├── __init__.py ├── analyze-chain.py ├── analyze_memory_profile.py ├── chialispp.py ├── cpu_utilization.py ├── generate_chain.py ├── manage_clvm.py ├── plot-log.gnuplot ├── run_benchmark.sh ├── run_block.py └── test_full_sync.py └── virtual_project.yaml /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch=True 3 | disable_warnings= 4 | module-not-measured 5 | relative_files=True 6 | source_pkgs= 7 | chia 8 | omit= 9 | chia/_tests/**/config.py 10 | concurrency=multiprocessing, thread 11 | parallel=True 12 | 13 | [paths] 14 | source = 15 | chia/ 16 | .venv/**/site-packages/chia/ 17 | 18 | [report] 19 | precision = 1 20 | exclude_also = 21 | abc\.abstractmethod 22 | typing\.overload 23 | ^\s*\.\.\.\s*$ 24 | if typing.TYPE_CHECKING: 25 | if TYPE_CHECKING: 26 | ^ *@pytest.mark.skip($|\() 27 | benchmark_runner: BenchmarkRunner 28 | -------------------------------------------------------------------------------- /.diffcover.toml: -------------------------------------------------------------------------------- 1 | [tool.diff_cover] 2 | exclude = [ 3 | "*/chia/_tests/*/config.py", 4 | ] 5 | -------------------------------------------------------------------------------- /.git_archival.txt: -------------------------------------------------------------------------------- 1 | node: 9289a05f128c431057ba238d5c2705de25684cf8 2 | node-date: 2025-06-10T11:27:17-07:00 3 | describe-name: 2.5.4-219-g9289a05f128c 4 | ref-names: HEAD -> main 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | .git_archival.txt export-subst 2 | **/*.lock linguist-generated=false 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @Chia-Network/required-reviewers 2 | /.github/**/* @Chia-Network/actions-reviewers 3 | /PRETTY_GOOD_PRACTICES.md @altendky @Chia-Network/required-reviewers 4 | /tests/ether.py @altendky @Chia-Network/required-reviewers 5 | /pyproject.toml @altendky @Chia-Network/required-reviewers 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - about: Ask a question or request support here 3 | name: Ask for Support 4 | url: >- 5 | https://github.com/Chia-Network/chia-blockchain/discussions/new?category=support 6 | - about: Request a new feature or idea here 7 | name: Make a Request 8 | url: >- 9 | https://github.com/Chia-Network/chia-blockchain/discussions/new?category=ideas 10 | - about: Get support in the Chia Discord chat channels. 11 | name: Join the Discord support chat 12 | url: "https://discord.gg/chia" 13 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | ### Purpose: 8 | 9 | 10 | 11 | ### Current Behavior: 12 | 13 | ### New Behavior: 14 | 15 | 16 | 17 | ### Testing Notes: 18 | 19 | 20 | -------------------------------------------------------------------------------- /.github/actionlint.yaml: -------------------------------------------------------------------------------- 1 | self-hosted-runner: 2 | # Labels of self-hosted runner in array of strings. 3 | labels: ["benchmark", "glue-notify"] 4 | 5 | # Configuration variables in array of strings defined in your repository or 6 | # organization. `null` means disabling configuration variables check. 7 | # Empty array means no configuration variable is allowed. 8 | config-variables: null 9 | 10 | # Configuration for file paths. The keys are glob patterns to match to file 11 | # paths relative to the repository root. The values are the configurations for 12 | # the file paths. Note that the path separator is always '/'. 13 | # The following configurations are available. 14 | # 15 | # "ignore" is an array of regular expression patterns. Matched error messages 16 | # are ignored. This is similar to the "-ignore" command line option. 17 | paths: 18 | # .github/workflows/**/*.yml: 19 | # ignore: [] 20 | ".github/workflows/*.y*ml": 21 | ignore: ["string should not be empty", ".* SC2002:.*"] 22 | ".github/workflows/test-single.yml": 23 | ignore: [ 24 | # special case here using a variable as a key in the excludes 25 | 'value .*\$\{\{ inputs.matrix_mode \}\}.* in "exclude" does not match in matrix "python" combinations. possible values are', 26 | ] 27 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | # .github/release.yml 2 | 3 | changelog: 4 | exclude: 5 | labels: 6 | - CI 7 | - Tests 8 | - Cleanup 9 | - dependencies 10 | - checkpoint_merge 11 | - Exclude_Notes 12 | - GUI-Pin 13 | authors: 14 | - octocat 15 | - dependabot 16 | - snyk-bot 17 | - github-actions 18 | categories: 19 | - title: Added 20 | labels: 21 | - Added 22 | - title: Changed 23 | labels: 24 | - Changed 25 | - title: Fixed 26 | labels: 27 | - Fixed 28 | -------------------------------------------------------------------------------- /.github/workflows/check-commit-signing.yml: -------------------------------------------------------------------------------- 1 | name: 🚨 Check commit signing 2 | 3 | on: 4 | push: 5 | branches: 6 | - long_lived/** 7 | - main 8 | - release/** 9 | pull_request: 10 | branches: 11 | - "**" 12 | 13 | concurrency: 14 | group: ${{ github.event_name == 'pull_request' && format('{0}-{1}', github.workflow_ref, github.event.pull_request.number) || github.run_id }} 15 | cancel-in-progress: true 16 | 17 | jobs: 18 | check-commit-signing: 19 | name: Check commit signing 20 | runs-on: [ubuntu-latest] 21 | timeout-minutes: 5 22 | 23 | steps: 24 | - name: Checkout Code 25 | uses: actions/checkout@v4 26 | with: 27 | fetch-depth: 0 28 | 29 | - uses: chia-network/actions/check-commit-signing@main 30 | -------------------------------------------------------------------------------- /.github/workflows/conflict-check.yml: -------------------------------------------------------------------------------- 1 | name: 🩹 Conflict Check 2 | on: 3 | # So that PRs touching the same files as the push are updated 4 | push: 5 | branches-ignore: 6 | - "tmp/**" 7 | # So that the `dirtyLabel` is removed if conflicts are resolve 8 | # We recommend `pull_request_target` so that github secrets are available. 9 | # In `pull_request` we wouldn't be able to change labels of fork PRs 10 | pull_request_target: 11 | types: [opened, synchronize, reopened] 12 | 13 | jobs: 14 | main: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: check if prs are behind main 18 | uses: Chia-Network/actions/label-conflict@main 19 | with: 20 | labelToAddOnConflict: "merge_conflict" 21 | secretToken: "${{ secrets.GITHUB_TOKEN }}" 22 | # targeting 2 minutes of retry, longest observed window thus far is ~30 seconds 23 | retryIntervalSec: 5 24 | retryMax: 24 25 | commentToAddOnConflict: "This pull request has conflicts, please resolve those before we can evaluate the pull request." 26 | commentToAddOnClean: "Conflicts have been resolved. A maintainer will review the pull request shortly." 27 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Managed by repo-content-updater 2 | # Dependency Review Action 3 | # 4 | # This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. 5 | # 6 | # Source repository: https://github.com/actions/dependency-review-action 7 | # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement 8 | name: "🚨 Dependency Review" 9 | on: [pull_request] 10 | 11 | permissions: 12 | contents: read 13 | 14 | jobs: 15 | dependency-review: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: "Checkout Repository" 19 | uses: actions/checkout@v4 20 | 21 | - name: "Dependency Review" 22 | uses: actions/dependency-review-action@v4 23 | with: 24 | allow-dependencies-licenses: pkg:pypi/pyinstaller, pkg:pypi/mypy 25 | deny-licenses: AGPL-1.0-only, AGPL-1.0-or-later, AGPL-1.0-or-later, AGPL-3.0-or-later, GPL-1.0-only, GPL-1.0-or-later, GPL-2.0-only, GPL-2.0-or-later, GPL-3.0-only, GPL-3.0-or-later 26 | -------------------------------------------------------------------------------- /.github/workflows/mozilla-ca-cert.yml: -------------------------------------------------------------------------------- 1 | name: "Update Mozilla CA sub module" 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | update_ca_module: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | with: 11 | fetch-depth: 0 12 | repository: chia-network/chia-blockchain 13 | submodules: recursive 14 | token: "${{ secrets.GITHUB_TOKEN }}" 15 | 16 | - name: Set up commit signing 17 | uses: Chia-Network/actions/commit-sign/gpg@main 18 | with: 19 | gpg_private_key: ${{ secrets.CHIA_AUTOMATION_PRIVATE_GPG_KEY }} 20 | passphrase: ${{ secrets.CHIA_AUTOMATION_PRIVATE_GPG_PASSPHRASE }} 21 | 22 | - name: "Add changes to new branch" 23 | run: | 24 | cd ./mozilla-ca 25 | git pull origin main 26 | 27 | - name: "Create Pull Request" 28 | uses: peter-evans/create-pull-request@v7 29 | with: 30 | base: main 31 | body: "Newest Mozilla CA cert" 32 | branch: mozilla-ca-updates 33 | commit-message: "adding ca updates" 34 | delete-branch: true 35 | reviewers: "wjblanke,emlowe" 36 | assignees: "wallentx" 37 | title: "CA Cert updates" 38 | token: "${{ secrets.GITHUB_TOKEN }}" 39 | committer: "ChiaAutomation " 40 | author: "ChiaAutomation " 41 | -------------------------------------------------------------------------------- /.github/workflows/require-labels.yml: -------------------------------------------------------------------------------- 1 | name: 🚨 Check PR Labels 2 | on: 3 | pull_request: 4 | types: [opened, labeled, unlabeled, synchronize] 5 | jobs: 6 | check-labels: 7 | runs-on: ubuntu-latest 8 | permissions: 9 | checks: write 10 | pull-requests: read 11 | statuses: write 12 | outputs: 13 | status: ${{ steps.check-labels.outputs.status }} 14 | steps: 15 | - id: check-labels 16 | uses: mheap/github-action-required-labels@v5 17 | with: 18 | mode: exactly 19 | count: 1 20 | labels: "Added, Changed, Fixed" 21 | exit_type: success 22 | - run: echo SUCCESS 23 | if: steps.check-labels.outputs.status == 'success' 24 | - run: echo FAILURE && exit 1 25 | if: steps.check-labels.outputs.status == 'failure' 26 | -------------------------------------------------------------------------------- /.github/workflows/start-release.yml: -------------------------------------------------------------------------------- 1 | # Starts a release for the given ref on the Glue API 2 | name: Start Release 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [published] 7 | 8 | permissions: 9 | id-token: write 10 | contents: read 11 | 12 | jobs: 13 | start_release: 14 | name: Starts release process in Glue API 15 | runs-on: [glue-notify] 16 | steps: 17 | - name: Set Env 18 | uses: Chia-Network/actions/setjobenv@main 19 | env: 20 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | 22 | - name: Start pre-release 23 | uses: Chia-Network/actions/github/glue@main 24 | if: "github.event.release.prerelease" 25 | with: 26 | json_data: '{"chia_ref": "${{ env.RELEASE_TAG }}"}' 27 | glue_url: "${{ secrets.GLUE_API_URL }}" 28 | glue_project: "${{ env.RFC_REPO }}-prerelease/${{ env.RELEASE_TAG }}" 29 | glue_path: "start" 30 | 31 | - name: Start release 32 | uses: Chia-Network/actions/github/glue@main 33 | if: "!github.event.release.prerelease" 34 | with: 35 | json_data: '{"chia_ref": "${{ env.RELEASE_TAG }}"}' 36 | glue_url: "${{ secrets.GLUE_API_URL }}" 37 | glue_project: "${{ env.RFC_REPO }}/${{ env.RELEASE_TAG }}" 38 | glue_path: "start" 39 | -------------------------------------------------------------------------------- /.github/workflows/start-sync-test.yml: -------------------------------------------------------------------------------- 1 | # Starts a sync test for every new release (pre-releases included) 2 | name: Start Sync Test 3 | 4 | on: 5 | release: 6 | types: [published] 7 | 8 | permissions: 9 | id-token: write 10 | contents: read 11 | 12 | jobs: 13 | start_release: 14 | name: Starts Sync Test 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Set Env 18 | uses: Chia-Network/actions/setjobenv@main 19 | env: 20 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | 22 | - name: Trigger sync test workflow via github-glue 23 | uses: Chia-Network/actions/github/glue@main 24 | with: 25 | json_data: '{"test_ref": "${{ env.RELEASE_TAG }}"}' 26 | glue_url: "${{ secrets.GLUE_API_URL }}" 27 | glue_project: "sync-test/${{ env.RELEASE_TAG }}" 28 | glue_path: "start" 29 | 30 | - name: Trigger sync test workflow success via github-glue 31 | uses: Chia-Network/actions/github/glue@main 32 | with: 33 | json_data: '{"test_ref": "${{ env.RELEASE_TAG }}"}' 34 | glue_url: "${{ secrets.GLUE_API_URL }}" 35 | glue_project: "sync-test/${{ env.RELEASE_TAG }}" 36 | glue_path: "success/deploy" 37 | -------------------------------------------------------------------------------- /.github/workflows/trigger-docker-main.yml: -------------------------------------------------------------------------------- 1 | name: 📦🚀 Trigger Main Docker Build 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - "**.md" 7 | branches: 8 | - main 9 | 10 | concurrency: 11 | group: ${{ github.event_name == 'pull_request' && format('{0}-{1}', github.workflow_ref, github.event.pull_request.number) || github.run_id }} 12 | cancel-in-progress: true 13 | 14 | permissions: 15 | id-token: write 16 | contents: read 17 | 18 | jobs: 19 | trigger: 20 | name: Trigger building a new `main` tag for the chia-docker image 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Trigger docker main workflow via github-glue 24 | uses: Chia-Network/actions/github/glue@main 25 | with: 26 | json_data: "{}" 27 | glue_url: "${{ secrets.GLUE_API_URL }}" 28 | glue_project: "docker-build-main/${{ github.sha }}" 29 | glue_path: "start" 30 | 31 | - name: Trigger docker main success via github-glue 32 | uses: Chia-Network/actions/github/glue@main 33 | with: 34 | json_data: "{}" 35 | glue_url: "${{ secrets.GLUE_API_URL }}" 36 | glue_project: "docker-build-main/${{ github.sha }}" 37 | glue_path: "success/build-main" 38 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "chia-blockchain-gui"] 2 | path = chia-blockchain-gui 3 | url = https://github.com/Chia-Network/chia-blockchain-gui.git 4 | branch = main 5 | [submodule "mozilla-ca"] 6 | path = mozilla-ca 7 | url = https://github.com/Chia-Network/mozilla-ca.git 8 | branch = main 9 | -------------------------------------------------------------------------------- /.markdown-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ########################### 3 | ########################### 4 | ## Markdown Linter rules ## 5 | ########################### 6 | ########################### 7 | 8 | # Linter rules doc: 9 | # - https://github.com/DavidAnson/markdownlint 10 | # 11 | # Note: 12 | # To comment out a single error: 13 | # 14 | # any violations you want 15 | # 16 | # 17 | 18 | ############### 19 | # Rules by id # 20 | ############### 21 | MD004: false # Unordered list style 22 | MD007: 23 | indent: 2 # Unordered list indentation 24 | MD013: 25 | line_length: 808 # Line length 26 | MD024: 27 | allow_different_nesting: true 28 | MD026: 29 | punctuation: ".,;:!。,;:" # List of not allowed 30 | MD029: false # Ordered list item prefix 31 | MD033: false # Allow inline HTML 32 | MD036: false # Emphasis used instead of a heading 33 | MD041: false # Allow file to start without h1 34 | 35 | ################# 36 | # Rules by tags # 37 | ################# 38 | blank_lines: false # Error on blank lines 39 | -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | overrides: 2 | - files: ["*.yaml", "*.yml", "*.toml", "*.json", "*.ini"] 3 | options: 4 | tabWidth: 2 5 | singleQuote: false 6 | experimentalTernaries: true 7 | useTabs: false 8 | - files: ["*.md"] 9 | options: 10 | singleQuote: false 11 | - files: ["*.js", "*.jsx", "*.ts", "*.tsx", "*.cjs", "*.mjs"] 12 | options: 13 | printWidth: 120 14 | singleQuote: true 15 | -------------------------------------------------------------------------------- /.repo-content-updater.yml: -------------------------------------------------------------------------------- 1 | var_overrides: 2 | DEPENDABOT_ACTIONS_REVIEWERS: '["cmmarslender", "altendky"]' 3 | DEPENDENCY_REVIEW_ALLOW_DEPENDENCIES_LICENSES: pkg:pypi/pyinstaller, pkg:pypi/mypy 4 | -------------------------------------------------------------------------------- /.shellcheckrc: -------------------------------------------------------------------------------- 1 | disable=SC2002 2 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Install instructions have been moved to the [INSTALL](https://github.com/Chia-Network/chia-blockchain/wiki/INSTALL) section of the repository [Wiki](https://github.com/Chia-Network/chia-blockchain/wiki). 4 | 5 | After installing, follow the remaining instructions in the 6 | [Quick Start Guide](https://github.com/Chia-Network/chia-blockchain/wiki/Quick-Start-Guide) 7 | to run the software. 8 | -------------------------------------------------------------------------------- /Install-gui.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | $SUBMODULE_BRANCH = $args[0] 3 | 4 | if ($null -eq (Get-ChildItem env:VIRTUAL_ENV -ErrorAction SilentlyContinue)) 5 | { 6 | Write-Output "This script requires that the Chia Python virtual environment is activated." 7 | Write-Output "Execute '.\venv\Scripts\Activate.ps1' before running." 8 | Exit 1 9 | } 10 | 11 | if ($null -eq (Get-Command node -ErrorAction SilentlyContinue)) 12 | { 13 | Write-Output "Unable to find Node.js" 14 | Exit 1 15 | } 16 | 17 | Write-Output "Running 'git submodule update --init --recursive'." 18 | Write-Output "" 19 | git submodule update --init --recursive 20 | if ( $SUBMODULE_BRANCH ) { 21 | git fetch --all 22 | git reset --hard $SUBMODULE_BRANCH 23 | Write-Output "" 24 | Write-Output "Building the GUI with branch $SUBMODULE_BRANCH" 25 | Write-Output "" 26 | } 27 | 28 | 29 | Push-Location 30 | try { 31 | Set-Location chia-blockchain-gui 32 | 33 | $ErrorActionPreference = "SilentlyContinue" 34 | npm ci --loglevel=error 35 | npm audit fix 36 | npm run build 37 | py ..\installhelper.py 38 | 39 | Write-Output "" 40 | Write-Output "Chia blockchain Install-gui.ps1 completed." 41 | Write-Output "" 42 | Write-Output "Type 'cd chia-blockchain-gui' and then 'npm run electron' to start the GUI." 43 | } finally { 44 | Pop-Location 45 | } 46 | -------------------------------------------------------------------------------- /LEGACY-SUPPORT-POLICY.md: -------------------------------------------------------------------------------- 1 | # Legacy Software and Operating System Support Policy 2 | 3 | It is the official policy of the Chia Blockchain project to end software support when the original maintainer of the software deems it End of Life (EOL) or stops providing support. The most relevant targets of this policy are Python, Node.js, and operating systems. 4 | 5 | ## Long-term Support Conflicts 6 | 7 | If a long-term support version of an operating system uses a default Python version that has lost official support, we also intend to end support for that operating system version, so as to avoid issues with installing a new Python version via Chia install, which may break crucial operating system components. 8 | 9 | ## More Information 10 | 11 | For more information, please contact hello@chia.net or reach out on the community Discord. 12 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Supported Versions 2 | 3 | Use this section to tell people about which versions of your project are 4 | currently being supported with security updates. 5 | 6 | | Version | Supported | 7 | | ------- | ------------------ | 8 | | 1.2.x | :x: | 9 | | 1.3.x | :x: | 10 | | 1.4.x | :x: | 11 | | 1.5.x | :x: | 12 | | 1.6.x | :x: | 13 | | 1.7.x | :x: | 14 | | 1.8.x | :x: | 15 | | 2.0.x | :x: | 16 | | 2.1.x | :white_check_mark: | 17 | 18 | ## Reporting a Vulnerability 19 | 20 | Please report security concerns to https://hackerone.com/chia_network. 21 | 22 | If your security issue is established to be valid, we will reach out immediately to establish 23 | communication channels and compensate the issue reporter for responsibly reporting security bugs via 24 | our bug bounty program. 25 | -------------------------------------------------------------------------------- /Setup-poetry.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory, HelpMessage="Python version")] 3 | [string] 4 | $pythonVersion 5 | ) 6 | 7 | $ErrorActionPreference = "Stop" 8 | 9 | if (-not (Get-Item -ErrorAction SilentlyContinue ".penv/Scripts/").Exists) 10 | { 11 | py -$pythonVersion -m venv .penv 12 | .penv/Scripts/python -m pip install --upgrade pip 13 | } 14 | # TODO: maybe make our own zipapp/shiv/pex of poetry and download that? 15 | .penv/Scripts/python -m pip install --upgrade --requirement requirements-poetry.txt 16 | -------------------------------------------------------------------------------- /activated.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | $script_directory = Split-Path $MyInvocation.MyCommand.Path -Parent 4 | 5 | $env_directory = $args[0] 6 | $command = $args[1] 7 | $parameters = [System.Collections.ArrayList]$args 8 | $parameters.RemoveAt(0) 9 | $parameters.RemoveAt(0) 10 | 11 | & $script_directory/$env_directory/Scripts/Activate.ps1 12 | & $command @parameters 13 | 14 | exit $LASTEXITCODE 15 | -------------------------------------------------------------------------------- /activated.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from __future__ import annotations 4 | 5 | import enum 6 | import os 7 | import pathlib 8 | import subprocess 9 | import sys 10 | 11 | here = pathlib.Path(__file__).parent.absolute() 12 | 13 | 14 | class Env(enum.Enum): 15 | chia = ".venv" 16 | poetry = ".penv" 17 | 18 | 19 | def main(*args: str) -> int: 20 | if len(args) == 0: 21 | print("Parameters required") 22 | return 1 23 | 24 | env = Env.chia 25 | if args[0].startswith("--"): 26 | env = Env[args[0][2:]] 27 | args = args[1:] 28 | 29 | if sys.platform == "win32": 30 | script = "activated.ps1" 31 | command = ["powershell", os.fspath(here.joinpath(script)), env.value, *args] 32 | else: 33 | script = "activated.sh" 34 | command = ["sh", os.fspath(here.joinpath(script)), env.value, *args] 35 | 36 | completed_process = subprocess.run(command, check=False) 37 | 38 | return completed_process.returncode 39 | 40 | 41 | sys.exit(main(*sys.argv[1:])) 42 | -------------------------------------------------------------------------------- /activated.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | 5 | SCRIPT_DIRECTORY=$( 6 | cd -- "$(dirname -- "$0")" 7 | pwd 8 | ) 9 | 10 | ENV_DIRECTORY="$1" 11 | shift 12 | 13 | # shellcheck disable=SC1090,SC1091 14 | . "${SCRIPT_DIRECTORY}/${ENV_DIRECTORY}/bin/activate" 15 | 16 | "$@" 17 | -------------------------------------------------------------------------------- /benchmarks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/benchmarks/__init__.py -------------------------------------------------------------------------------- /benchmarks/jsonify.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import random 4 | from time import perf_counter 5 | 6 | from chia._tests.util.test_full_block_utils import get_full_blocks 7 | 8 | random.seed(123456789) 9 | 10 | 11 | def main() -> None: 12 | total_time = 0.0 13 | counter = 0 14 | for block in get_full_blocks(): 15 | start = perf_counter() 16 | block.to_json_dict() 17 | end = perf_counter() 18 | total_time += end - start 19 | counter += 1 20 | 21 | print(f"total time: {total_time:0.2f}s ({counter} iterations)") 22 | 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /build_scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/assets/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/deb/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/assets/deb/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/deb/control.j2: -------------------------------------------------------------------------------- 1 | Package: chia-blockchain-cli 2 | Version: {{ CHIA_DEB_CONTROL_VERSION }} 3 | Architecture: {{ PLATFORM }} 4 | Maintainer: Chia Network Inc 5 | Description: Chia Blockchain 6 | Chia is a modern cryptocurrency built from scratch, designed to be efficient, decentralized, and secure. 7 | -------------------------------------------------------------------------------- /build_scripts/assets/deb/postinst.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Post install script for the UI .deb to place symlinks in places to allow the CLI to work similarly in both versions 3 | 4 | set -e 5 | 6 | chown -f root:root /opt/chia/chrome-sandbox || true 7 | chmod -f 4755 /opt/chia/chrome-sandbox || true 8 | ln -s /opt/chia/resources/app.asar.unpacked/daemon/chia /usr/bin/chia || true 9 | ln -s /opt/chia/chia-blockchain /usr/bin/chia-blockchain || true 10 | -------------------------------------------------------------------------------- /build_scripts/assets/deb/prerm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Pre remove script for the UI .deb to clean up the symlinks from the installer 3 | 4 | set -e 5 | 6 | unlink /usr/bin/chia || true 7 | unlink /usr/bin/chia-blockchain || true 8 | -------------------------------------------------------------------------------- /build_scripts/assets/dmg/README: -------------------------------------------------------------------------------- 1 | To update the DMG background image, create 1x and 2x versions of a background: 2 | 3 | 1x: background.png 4 | 2x: background@2x.png 5 | 6 | Create a single TIFF combining both 1x and 2x background bitmaps: 7 | Run 'tiffutil -cathidpicheck background.png background@2x.png -out background.tiff' 8 | 9 | Use background.tiff as the DMG background 10 | -------------------------------------------------------------------------------- /build_scripts/assets/dmg/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/assets/dmg/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/dmg/background.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/assets/dmg/background.tiff -------------------------------------------------------------------------------- /build_scripts/assets/rpm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/assets/rpm/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/rpm/before-install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # handling multiple cases where empty directories are left behind resulting 6 | # in issues with the python identifying the blockchain version 7 | find /opt/chia -type d -empty -delete || true 8 | -------------------------------------------------------------------------------- /build_scripts/assets/rpm/postinst.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Post install script for the UI .rpm to place symlinks in places to allow the CLI to work similarly in both versions 3 | 4 | set -e 5 | 6 | ln -s /opt/chia/resources/app.asar.unpacked/daemon/chia /usr/bin/chia || true 7 | ln -s /opt/chia/chia-blockchain /usr/bin/chia-blockchain || true 8 | -------------------------------------------------------------------------------- /build_scripts/assets/rpm/prerm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Pre remove script for the UI .rpm to clean up the symlinks from the installer 3 | 4 | set -e 5 | 6 | unlink /usr/bin/chia || true 7 | unlink /usr/bin/chia-blockchain || true 8 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/assets/systemd/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-crawler@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Crawler Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_crawler 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-daemon@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Daemon Service for %i 3 | StopWhenUnneeded=true 4 | 5 | [Service] 6 | Type=simple 7 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 8 | ExecStart=/opt/chia/daemon 9 | ExecStartPost=/bin/bash -c '(while ! /opt/chia/chia rpc daemon get_version 2>/dev/null; do echo "Waiting for the daemon to listen on port 55400..."; sleep 1; done); sleep 1' 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-data-layer-http@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Data Layer HTTP Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_data_layer_http 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | TimeoutStopSec=15 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-data-layer@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Data Layer Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_data_layer 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | TimeoutStopSec=15 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-farmer@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Farmer Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_farmer 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-full-node@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Full Node Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_full_node 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-harvester@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Harvester Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_harvester 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-introducer@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Introducer Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_introducer 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-seeder@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Seeder Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_seeder 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-timelord@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Timelord Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_timelord 10 | User=%i 11 | Group=%i 12 | LimitNOFILE=1048576 13 | LimitNPROC=1048576 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /build_scripts/assets/systemd/chia-wallet@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Chia Wallet Service for %i 3 | Requires=chia-daemon@%i.service 4 | After=chia-daemon@%i.service 5 | 6 | [Service] 7 | Type=simple 8 | Environment=CHIA_ROOT=/home/%i/.chia/mainnet 9 | ExecStart=/opt/chia/start_wallet 10 | ExecStartPost=/bin/bash -c '(while ! /opt/chia/chia rpc wallet get_version 2>/dev/null; do echo "Waiting for the wallet to listen on port 9256..."; sleep 1; done); sleep 1' 11 | User=%i 12 | Group=%i 13 | LimitNOFILE=1048576 14 | LimitNPROC=1048576 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /build_scripts/build_linux_rpm-1-gui.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit 4 | 5 | cd ../ || exit 1 6 | git submodule update --init chia-blockchain-gui 7 | 8 | cd ./chia-blockchain-gui || exit 1 9 | echo "npm build" 10 | npx lerna clean -y # Removes packages/*/node_modules 11 | npm ci 12 | # Audit fix does not currently work with Lerna. See https://github.com/lerna/lerna/issues/1663 13 | # npm audit fix 14 | npm run build 15 | LAST_EXIT_CODE=$? 16 | if [ "$LAST_EXIT_CODE" -ne 0 ]; then 17 | echo >&2 "npm run build failed!" 18 | exit $LAST_EXIT_CODE 19 | fi 20 | 21 | # Remove unused packages 22 | rm -rf node_modules 23 | 24 | # Other than `chia-blockchain-gui/package/gui`, all other packages are no longer necessary after build. 25 | # Since these unused packages make cache unnecessarily fat, here unused packages are removed. 26 | echo "Remove unused @chia-network packages to make cache slim" 27 | ls -l packages 28 | rm -rf packages/api 29 | rm -rf packages/api-react 30 | rm -rf packages/core 31 | rm -rf packages/icons 32 | rm -rf packages/wallets 33 | 34 | # Remove unused fat npm modules from the gui package 35 | cd ./packages/gui/node_modules || exit 1 36 | echo "Remove unused node_modules in the gui package to make cache slim more" 37 | rm -rf electron/dist # ~186MB 38 | rm -rf "@mui" # ~71MB 39 | rm -rf typescript # ~63MB 40 | 41 | # Remove `packages/gui/node_modules/@chia-network` because it causes an error on later `electron-packager` command 42 | rm -rf "@chia-network" 43 | -------------------------------------------------------------------------------- /build_scripts/clean-runner.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Cleans up files/directories that may be left over from previous runs for a clean slate before starting a new build 3 | 4 | set -o errexit 5 | 6 | PWD=$(pwd) 7 | 8 | rm -rf ../venv || true 9 | rm -rf venv || true 10 | rm -rf chia_blockchain.egg-info || true 11 | rm -rf build_scripts/final_installer || true 12 | rm -rf build_scripts/dist || true 13 | rm -rf build_scripts/pyinstaller || true 14 | rm -rf chia-blockchain-gui/build || true 15 | rm -rf chia-blockchain-gui/daemon || true 16 | rm -rf chia-blockchain-gui/node_modules || true 17 | rm chia-blockchain-gui/temp.json || true 18 | (cd "$PWD/chia-blockchain-gui" && git checkout HEAD -- package-lock.json) || true 19 | cd "$PWD" || true 20 | 21 | # Clean up old globally installed node_modules that might conflict with the current build 22 | rm -rf /opt/homebrew/lib/node_modules || true 23 | 24 | # Clean up any installed versions of node so we can start fresh 25 | brew list | grep "^node\@\|^node$" | xargs -L1 brew uninstall || true 26 | -------------------------------------------------------------------------------- /build_scripts/npm_global/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/npm_global/__init__.py -------------------------------------------------------------------------------- /build_scripts/npm_global/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm_global", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "n": { 8 | "version": "8.2.0", 9 | "resolved": "https://registry.npmjs.org/n/-/n-8.2.0.tgz", 10 | "integrity": "sha512-qv+jwJoXaV94C+uASaLS/Qe/iprgvQKe+5hqg6YvUH8mqe5ysgjby875pUVLLWieGFywipEO/J/bgekYbC18Jw==" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /build_scripts/npm_global/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm_global", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "n": "^8.2.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /build_scripts/npm_linux/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/npm_linux/__init__.py -------------------------------------------------------------------------------- /build_scripts/npm_linux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm_linux", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "electron-builder": "^24.13.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /build_scripts/npm_macos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/npm_macos/__init__.py -------------------------------------------------------------------------------- /build_scripts/npm_macos/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm_macos", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "dmg-license": "^1.0.11", 14 | "electron-builder": "^24.13.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /build_scripts/npm_windows/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/build_scripts/npm_windows/__init__.py -------------------------------------------------------------------------------- /build_scripts/npm_windows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm_windows", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "electron-builder": "^24.13.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /build_scripts/remove_brew_rpaths.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail 3 | 4 | # Removes rpath loader commands from _ssl.cpython-*.so which are sometimes 5 | # added on Apple M-series CPUs, prefer bundled dynamic libraries for which 6 | # there is an rpath added already as "@loader_path/.." -- however, the 7 | # homebrew rpaths appear with higher precedence, potentially causing issues. 8 | # See: #18099 9 | 10 | echo "" 11 | echo "Stripping brew rpaths..." 12 | 13 | rpath_name=/opt/homebrew/lib 14 | 15 | so_path=$(find "dist/daemon/_internal/lib-dynload" -name "_ssl.cpython-*.so") 16 | if [[ -z "${so_path}" ]]; then 17 | >&2 echo "Failed to find _ssl.cpython-*.so" 18 | fi 19 | 20 | echo "Found '_ssl.cpython-*.so' at '$so_path':" 21 | otool -l "$so_path" 22 | echo "" 23 | 24 | set +e 25 | nt_output= 26 | r=0 27 | while [[ $r -eq 0 ]]; do 28 | install_name_tool -delete_rpath $rpath_name "$so_path" 2>&1 | read -r nt_output 29 | r=$? 30 | done 31 | 32 | if [[ -n "$nt_output" ]]; then 33 | echo "$nt_output" | grep "no LC_RPATH load command with path:" >/dev/null 34 | # shellcheck disable=SC2181 35 | if [[ $? -ne 0 ]]; then 36 | >&2 echo "An unexpected error occurred when running install_name_tool:" 37 | >&2 echo "$nt_output" 38 | fi 39 | fi 40 | 41 | echo "Done." 42 | echo "" 43 | -------------------------------------------------------------------------------- /chia/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import importlib.metadata 4 | 5 | __version__: str 6 | try: 7 | __version__ = importlib.metadata.version("chia-blockchain") 8 | except importlib.metadata.PackageNotFoundError: 9 | # package is not installed 10 | __version__ = "unknown" 11 | 12 | try: 13 | assert False 14 | except AssertionError: 15 | pass 16 | else: 17 | raise Exception("asserts are not working and _must_ be enabled, do not run with an optimized build of python") 18 | -------------------------------------------------------------------------------- /chia/__main__.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia.cmds.chia import main 4 | 5 | main() 6 | -------------------------------------------------------------------------------- /chia/_tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/__init__.py -------------------------------------------------------------------------------- /chia/_tests/blockchain/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/blockchain/__init__.py -------------------------------------------------------------------------------- /chia/_tests/blockchain/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 70 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/check_pytest_monitor_output.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from __future__ import annotations 3 | 4 | import sys 5 | 6 | ret = 0 7 | 8 | # example input line 9 | # test_non_tx_aggregate_limits 0.997759588095738 1.45325589179993 554.45703125 10 | for ln in sys.stdin: 11 | line = ln.strip().split() 12 | 13 | print(f"{float(line[1]) * 100.0: 8.1f}% CPU {float(line[2]):7.1f}s {float(line[3]): 8.2f} MB RAM {line[0]}") 14 | limit = 800 15 | 16 | # until this can be optimized, use higher limits 17 | if "test_duplicate_coin_announces" in line[0]: 18 | limit = 2200 19 | elif ( 20 | "test_duplicate_large_integer_substr" in line[0] 21 | or "test_duplicate_reserve_fee" in line[0] 22 | or "test_duplicate_large_integer_negative" in line[0] 23 | or "test_duplicate_large_integer" in line[0] 24 | ): 25 | limit = 1100 26 | 27 | if float(line[3]) > limit: 28 | print(" ERROR: ^^ exceeded RAM limit ^^ \n") 29 | ret += 1 30 | 31 | if ret > 0: 32 | print("some tests used too much RAM") 33 | 34 | sys.exit(ret) 35 | -------------------------------------------------------------------------------- /chia/_tests/clvm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/clvm/__init__.py -------------------------------------------------------------------------------- /chia/_tests/clvm/benchmark_costs.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs import SpendBundle 4 | from chia_rs.sized_ints import uint64 5 | 6 | from chia._tests.util.get_name_puzzle_conditions import get_name_puzzle_conditions 7 | from chia.consensus.cost_calculator import NPCResult 8 | from chia.consensus.default_constants import DEFAULT_CONSTANTS 9 | from chia.full_node.bundle_tools import simple_solution_generator 10 | from chia.types.blockchain_format.program import INFINITE_COST 11 | from chia.types.generator_types import BlockGenerator 12 | 13 | 14 | def cost_of_spend_bundle(spend_bundle: SpendBundle) -> int: 15 | program: BlockGenerator = simple_solution_generator(spend_bundle) 16 | # always use the post soft-fork2 semantics 17 | npc_result: NPCResult = get_name_puzzle_conditions( 18 | program, 19 | INFINITE_COST, 20 | mempool_mode=True, 21 | height=DEFAULT_CONSTANTS.HARD_FORK_HEIGHT, 22 | constants=DEFAULT_CONSTANTS, 23 | ) 24 | return uint64(0 if npc_result.conds is None else npc_result.conds.cost) 25 | -------------------------------------------------------------------------------- /chia/_tests/clvm/test_clvm_step.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any, Optional 4 | 5 | from clvm_tools_rs import start_clvm_program 6 | 7 | factorial = ( 8 | "ff02ffff01ff02ff02ffff04ff02ffff04ff05ff80808080ffff04ffff01ff02" 9 | + "ffff03ffff09ff05ffff010180ffff01ff0101ffff01ff12ff05ffff02ff02ff" 10 | + "ff04ff02ffff04ffff11ff05ffff010180ff808080808080ff0180ff018080" 11 | ) 12 | 13 | factorial_function_hash = "de3687023fa0a095d65396f59415a859dd46fc84ed00504bf4c9724fca08c9de" 14 | factorial_sym = {factorial_function_hash: "factorial"} 15 | 16 | 17 | def test_simple_program_run() -> None: 18 | p = start_clvm_program(factorial, "ff0580", factorial_sym) 19 | 20 | last: Optional[Any] = None 21 | location: Optional[Any] = None 22 | 23 | while not p.is_ended(): 24 | step_result = p.step() 25 | if step_result is not None: 26 | last = step_result 27 | assert "Failure" not in last 28 | 29 | if "Operator-Location" in last: 30 | location = last["Operator-Location"] 31 | 32 | assert last is not None 33 | assert location is not None 34 | if last is not None and location is not None: 35 | assert "Final" in last 36 | assert int(last["Final"]) == 120 37 | assert location.startswith("factorial") 38 | -------------------------------------------------------------------------------- /chia/_tests/cmds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/cmds/__init__.py -------------------------------------------------------------------------------- /chia/_tests/cmds/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/cmds/conftest.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import tempfile 4 | from collections.abc import Iterator 5 | from pathlib import Path 6 | 7 | import pytest 8 | 9 | from chia._tests.cmds.cmd_test_utils import TestRpcClients, create_service_and_wallet_client_generators 10 | from chia.util.config import create_default_chia_config 11 | 12 | 13 | @pytest.fixture(scope="module") # every file has its own config generated, just to be safe 14 | def get_test_cli_clients() -> Iterator[tuple[TestRpcClients, Path]]: 15 | # we cant use the normal config fixture because it only supports function scope. 16 | with tempfile.TemporaryDirectory() as tmp_path: 17 | root_path: Path = Path(tmp_path) / "chia_root" 18 | root_path.mkdir(parents=True, exist_ok=True) 19 | create_default_chia_config(root_path) 20 | # ^ this is basically the generate config fixture. 21 | global_test_rpc_clients = TestRpcClients() 22 | create_service_and_wallet_client_generators(global_test_rpc_clients, root_path) 23 | yield global_test_rpc_clients, root_path 24 | -------------------------------------------------------------------------------- /chia/_tests/cmds/wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/cmds/wallet/__init__.py -------------------------------------------------------------------------------- /chia/_tests/cmds/wallet/test_tx_decorators.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any 4 | 5 | import click 6 | from click.testing import CliRunner 7 | 8 | from chia._tests.cmds.wallet.test_consts import STD_TX 9 | from chia.cmds.cmds_util import TransactionBundle, tx_out_cmd 10 | from chia.wallet.transaction_record import TransactionRecord 11 | 12 | 13 | def test_tx_out_cmd() -> None: 14 | @click.command() 15 | @tx_out_cmd() 16 | def test_cmd(**kwargs: Any) -> list[TransactionRecord]: 17 | with open("./temp.push", "w") as file: 18 | file.write(str(kwargs["push"])) 19 | return [STD_TX, STD_TX] 20 | 21 | runner: CliRunner = CliRunner() 22 | with runner.isolated_filesystem(): 23 | runner.invoke(test_cmd, ["--transaction-file-out", "./temp.transaction"]) 24 | with open("./temp.transaction", "rb") as file: 25 | assert TransactionBundle.from_bytes(file.read()) == TransactionBundle([STD_TX, STD_TX]) 26 | with open("./temp.push") as file2: 27 | assert file2.read() == "True" 28 | -------------------------------------------------------------------------------- /chia/_tests/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/cmds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/cmds/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/core/consensus/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/consensus/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/consensus/test_block_creation.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | from chia_rs.sized_bytes import bytes32 5 | from chia_rs.sized_ints import uint64 6 | 7 | from chia.consensus.block_creation import compute_block_fee 8 | from chia.types.blockchain_format.coin import Coin 9 | 10 | 11 | @pytest.mark.parametrize("add_amount", [[0], [1, 2, 3], []]) 12 | @pytest.mark.parametrize("rem_amount", [[0], [1, 2, 3], []]) 13 | def test_compute_block_fee(add_amount: list[int], rem_amount: list[int]) -> None: 14 | additions: list[Coin] = [Coin(bytes32.random(), bytes32.random(), uint64(amt)) for amt in add_amount] 15 | removals: list[Coin] = [Coin(bytes32.random(), bytes32.random(), uint64(amt)) for amt in rem_amount] 16 | 17 | # the fee is the left-overs from the removals (spent) coins after deducting 18 | # the newly created coins (additions) 19 | expected = sum(rem_amount) - sum(add_amount) 20 | 21 | if expected < 0: 22 | with pytest.raises(ValueError, match="does not fit into uint64"): 23 | compute_block_fee(additions, removals) 24 | else: 25 | assert compute_block_fee(additions, removals) == expected 26 | -------------------------------------------------------------------------------- /chia/_tests/core/custom_types/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/custom_types/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/daemon/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/daemon/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/daemon/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 50 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/core/data_layer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/data_layer/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/data_layer/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = 4 4 | job_timeout = 80 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /chia/_tests/core/farmer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/farmer/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/farmer/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/core/full_node/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/full_node/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/full_node/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 70 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/core/full_node/dos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/full_node/dos/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/full_node/dos/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 60 4 | -------------------------------------------------------------------------------- /chia/_tests/core/full_node/full_sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/full_node/full_sync/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/full_node/full_sync/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 60 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/core/full_node/ram_db.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import contextlib 4 | import random 5 | from collections.abc import AsyncIterator 6 | from pathlib import Path 7 | 8 | from chia_rs import ConsensusConstants 9 | 10 | from chia.consensus.blockchain import Blockchain 11 | from chia.full_node.block_store import BlockStore 12 | from chia.full_node.coin_store import CoinStore 13 | from chia.util.db_wrapper import DBWrapper2 14 | 15 | 16 | @contextlib.asynccontextmanager 17 | async def create_ram_blockchain( 18 | consensus_constants: ConsensusConstants, 19 | ) -> AsyncIterator[tuple[DBWrapper2, Blockchain]]: 20 | uri = f"file:db_{random.randint(0, 99999999)}?mode=memory&cache=shared" 21 | async with DBWrapper2.managed(database=uri, uri=True, reader_count=1, db_version=2) as db_wrapper: 22 | block_store = await BlockStore.create(db_wrapper) 23 | coin_store = await CoinStore.create(db_wrapper) 24 | blockchain = await Blockchain.create(coin_store, block_store, consensus_constants, Path("."), 2) 25 | try: 26 | yield db_wrapper, blockchain 27 | finally: 28 | blockchain.shut_down() 29 | -------------------------------------------------------------------------------- /chia/_tests/core/full_node/stores/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/full_node/stores/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/full_node/stores/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 40 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/core/mempool/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/mempool/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/mempool/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 50 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/core/node_height.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs.sized_ints import uint32 4 | 5 | from chia.full_node.full_node_api import FullNodeAPI 6 | 7 | 8 | def node_height_at_least(node: FullNodeAPI, h: uint32) -> bool: 9 | if node.full_node.blockchain.get_peak() is not None: 10 | peak = node.full_node.blockchain.get_peak() 11 | if peak is not None: 12 | return peak.height >= h 13 | return False 14 | 15 | 16 | def node_height_exactly(node: FullNodeAPI, h: uint32) -> bool: 17 | if node.full_node.blockchain.get_peak() is not None: 18 | peak = node.full_node.blockchain.get_peak() 19 | if peak is not None: 20 | return peak.height == h 21 | return False 22 | 23 | 24 | def node_height_between(node: FullNodeAPI, h1: uint32, h2: uint32) -> bool: 25 | if node.full_node.blockchain.get_peak() is not None: 26 | peak = node.full_node.blockchain.get_peak() 27 | if peak is not None: 28 | return h1 <= peak.height <= h2 29 | return False 30 | -------------------------------------------------------------------------------- /chia/_tests/core/server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/server/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/server/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/core/server/test_api_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | 5 | from chia.protocols.full_node_protocol import RequestTransaction 6 | from chia.protocols.protocol_message_types import ProtocolMessageTypes 7 | from chia.server.api_protocol import ApiMetadata 8 | 9 | 10 | def test_api_protocol_raises_for_repeat_request_registration() -> None: 11 | metadata = ApiMetadata() 12 | 13 | @metadata.request(request_type=ProtocolMessageTypes.handshake) 14 | async def f(self: object, request: RequestTransaction) -> None: ... 15 | 16 | async def g(self: object, request: RequestTransaction) -> None: ... 17 | 18 | decorator = metadata.request(request_type=ProtocolMessageTypes.handshake) 19 | 20 | with pytest.raises(Exception, match="request type already registered"): 21 | decorator(g) 22 | -------------------------------------------------------------------------------- /chia/_tests/core/server/test_upnp.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | 4 | def test_miniupnpc_imports_successfully() -> None: 5 | import miniupnpc 6 | 7 | # use it to avoid all related warnings 8 | assert miniupnpc is not None 9 | -------------------------------------------------------------------------------- /chia/_tests/core/services/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/services/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/services/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = False 4 | -------------------------------------------------------------------------------- /chia/_tests/core/ssl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/ssl/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/ssl/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/core/test_coins.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from itertools import permutations 4 | 5 | from chia_rs.sized_bytes import bytes32 6 | 7 | from chia._tests.util.benchmarks import rand_hash 8 | from chia.types.blockchain_format.coin import hash_coin_ids 9 | from chia.util.hash import std_hash 10 | 11 | 12 | def test_hash_coin_ids_empty() -> None: 13 | assert hash_coin_ids([]) == std_hash(b"") 14 | 15 | 16 | def test_hash_coin_ids() -> None: 17 | A = bytes32([1] + [0] * 31) 18 | B = bytes32([2] + [0] * 31) 19 | C = bytes32([3] + [0] * 31) 20 | D = bytes32([4] + [0] * 31) 21 | E = bytes32([254] + [0] * 31) 22 | F = bytes32([255] + [0] * 31) 23 | 24 | expected = std_hash(F + E + D + C + B + A) 25 | 26 | for i in permutations([A, B, C, D, E, F]): 27 | assert hash_coin_ids(list(i)) == expected 28 | 29 | 30 | def test_sorting() -> None: 31 | for _ in range(5000): 32 | h1 = rand_hash() 33 | h2 = rand_hash() 34 | assert (h1 < h2) == (h1.hex() < h2.hex()) 35 | -------------------------------------------------------------------------------- /chia/_tests/core/test_daemon_rpc.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | 5 | from chia import __version__ 6 | from chia.daemon.client import connect_to_daemon 7 | 8 | 9 | @pytest.mark.anyio 10 | async def test_get_version_rpc(get_daemon, bt): 11 | ws_server = get_daemon 12 | config = bt.config 13 | client = await connect_to_daemon( 14 | config["self_hostname"], 15 | config["daemon_port"], 16 | 50 * 1000 * 1000, 17 | bt.get_daemon_ssl_context(), 18 | heartbeat=config["daemon_heartbeat"], 19 | ) 20 | response = await client.get_version() 21 | 22 | assert response["data"]["success"] 23 | assert response["data"]["version"] == __version__ 24 | ws_server.stop() 25 | -------------------------------------------------------------------------------- /chia/_tests/core/test_filter.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | from chiabip158 import PyBIP158 5 | 6 | from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG 7 | 8 | 9 | @pytest.mark.anyio 10 | async def test_basic_filter_test(simulator_and_wallet): 11 | _full_nodes, wallets, bt = simulator_and_wallet 12 | wallet_node, _server_2 = wallets[0] 13 | wallet = wallet_node.wallet_state_manager.main_wallet 14 | 15 | num_blocks = 2 16 | async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope: 17 | ph = await action_scope.get_puzzle_hash(wallet.wallet_state_manager) 18 | blocks = bt.get_consecutive_blocks( 19 | 10, 20 | guarantee_transaction_block=True, 21 | farmer_reward_puzzle_hash=ph, 22 | pool_reward_puzzle_hash=ph, 23 | ) 24 | for i in range(1, num_blocks): 25 | byte_array_tx: list[bytes] = [] 26 | block = blocks[i] 27 | coins = block.get_included_reward_coins() 28 | coin_0 = bytearray(coins[0].puzzle_hash) 29 | coin_1 = bytearray(coins[1].puzzle_hash) 30 | byte_array_tx.append(coin_0) 31 | byte_array_tx.append(coin_1) 32 | 33 | pl = PyBIP158(byte_array_tx) 34 | present = pl.Match(coin_0) 35 | fee_present = pl.Match(coin_1) 36 | 37 | assert present 38 | assert fee_present 39 | -------------------------------------------------------------------------------- /chia/_tests/core/test_setproctitle.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | 5 | from chia.util.setproctitle import setproctitle 6 | 7 | pytestmark = pytest.mark.skip( 8 | reason="this test ends up hanging frequently and needs to be rewritten with a subprocess and a title check", 9 | ) 10 | 11 | 12 | def test_does_not_crash() -> None: 13 | setproctitle("chia test title") 14 | -------------------------------------------------------------------------------- /chia/_tests/core/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/core/util/__init__.py -------------------------------------------------------------------------------- /chia/_tests/core/util/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | parallel = False 5 | -------------------------------------------------------------------------------- /chia/_tests/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/db/__init__.py -------------------------------------------------------------------------------- /chia/_tests/environments/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/environments/__init__.py -------------------------------------------------------------------------------- /chia/_tests/environments/common.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import ClassVar, Protocol, TypeVar 5 | 6 | from chia.rpc.rpc_server import RpcApiProtocol, RpcServer, RpcServiceProtocol 7 | from chia.server.api_protocol import ApiProtocol 8 | from chia.server.server import ChiaServer 9 | from chia.server.start_service import Service 10 | 11 | T_Node = TypeVar("T_Node", bound=RpcServiceProtocol) 12 | T_RpcApi = TypeVar("T_RpcApi", bound=RpcApiProtocol) 13 | T_PeerApi = TypeVar("T_PeerApi", bound=ApiProtocol) 14 | 15 | 16 | @dataclass 17 | class ServiceEnvironment(Protocol[T_Node, T_RpcApi, T_PeerApi]): 18 | service: Service[T_Node, T_PeerApi, T_RpcApi] 19 | 20 | __match_args__: ClassVar[tuple[str, ...]] = () 21 | 22 | @property 23 | def node(self) -> T_Node: ... 24 | 25 | @property 26 | def rpc_api(self) -> T_RpcApi: ... 27 | 28 | @property 29 | def rpc_server(self) -> RpcServer[T_RpcApi]: ... 30 | 31 | @property 32 | def peer_api(self) -> T_PeerApi: ... 33 | 34 | @property 35 | def peer_server(self) -> ChiaServer: ... 36 | -------------------------------------------------------------------------------- /chia/_tests/ether.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import TYPE_CHECKING, Callable, Optional 4 | 5 | if TYPE_CHECKING: 6 | from chia._tests.util.misc import TestId 7 | 8 | # NOTE: Do not just put any useful thing here. This is specifically for making 9 | # fixture values globally available during tests. In _most_ cases fixtures 10 | # should be directly requested using normal mechanisms. Very little should 11 | # be put here. 12 | 13 | # NOTE: When using this module do not import the attributes directly. Rather, import 14 | # something like `from chia._tests import ether`. Importing attributes directly will 15 | # result in you likely getting the default `None` values since they are not 16 | # populated until tests are running. 17 | 18 | record_property: Optional[Callable[[str, object], None]] = None 19 | test_id: Optional[TestId] = None 20 | -------------------------------------------------------------------------------- /chia/_tests/farmer_harvester/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/farmer_harvester/__init__.py -------------------------------------------------------------------------------- /chia/_tests/farmer_harvester/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/fee_estimation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/fee_estimation/__init__.py -------------------------------------------------------------------------------- /chia/_tests/fee_estimation/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/generator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/generator/__init__.py -------------------------------------------------------------------------------- /chia/_tests/generator/puzzles/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/generator/puzzles/__init__.py -------------------------------------------------------------------------------- /chia/_tests/generator/puzzles/test_generator_deserialize.clsp: -------------------------------------------------------------------------------- 1 | (mod (deserializer generator_list reserved_arg) 2 | (a deserializer (list reserved_arg)) 3 | ) 4 | -------------------------------------------------------------------------------- /chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex: -------------------------------------------------------------------------------- 1 | ff02ff02ffff04ff0bff808080 2 | -------------------------------------------------------------------------------- /chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp: -------------------------------------------------------------------------------- 1 | 2 | (mod (decompress_puzzle decompress_coin_spend_entry start1 end1 start2 end2 compressed_cses deserialize gen_list reserved_arg) 3 | 4 | (defun decompress_cses (decompress_puzzle decompress_coin_spend_entry cses deserialize puzzle_prefix) 5 | (if cses 6 | (c (a decompress_coin_spend_entry (list deserialize decompress_puzzle puzzle_prefix (f cses))) 7 | (decompress_cses decompress_puzzle decompress_coin_spend_entry (r cses) deserialize puzzle_prefix )) 8 | ()) ) 9 | 10 | (defun join_gen_args (generators start1 end1 start2 end2) 11 | (concat 12 | (substr (f generators) start1 end1) 13 | (substr (f (r generators)) start2 end2) 14 | ) 15 | ) 16 | 17 | (list (decompress_cses decompress_puzzle decompress_coin_spend_entry compressed_cses deserialize (join_gen_args gen_list start1 end1 start2 end2))) 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff02ff04ffff04ff02ffff04ff05ffff04ff0bffff04ff82017fffff04ff8202ffffff04ffff02ff06ffff04ff02ffff04ff8205ffffff04ff17ffff04ff2fffff04ff5fffff04ff81bfff8080808080808080ff8080808080808080ff8080ffff04ffff01ffff02ffff03ff17ffff01ff04ffff02ff0bffff04ff2fffff04ff05ffff04ff5fffff04ff27ff808080808080ffff02ff04ffff04ff02ffff04ff05ffff04ff0bffff04ff37ffff04ff2fffff04ff5fff808080808080808080ff8080ff0180ff0effff0cff09ff0bff1780ffff0cff15ff2fff5f8080ff018080 2 | -------------------------------------------------------------------------------- /chia/_tests/plot_sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/plot_sync/__init__.py -------------------------------------------------------------------------------- /chia/_tests/plot_sync/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/plotting/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/plotting/__init__.py -------------------------------------------------------------------------------- /chia/_tests/plotting/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/plotting/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path 4 | 5 | from chia.simulator.block_tools import get_plot_dir 6 | 7 | 8 | def get_test_plots(sub_dir: str = "") -> list[Path]: 9 | path = get_plot_dir() 10 | if sub_dir != "": 11 | path /= sub_dir 12 | return list(sorted(path.glob("*.plot"))) 13 | -------------------------------------------------------------------------------- /chia/_tests/pools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/pools/__init__.py -------------------------------------------------------------------------------- /chia/_tests/pools/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = 2 4 | job_timeout = 60 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /chia/_tests/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/rpc/__init__.py -------------------------------------------------------------------------------- /chia/_tests/simulation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/simulation/__init__.py -------------------------------------------------------------------------------- /chia/_tests/simulation/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 60 4 | parallel = False 5 | install_timelord = True 6 | checkout_blocks_and_plots = True 7 | -------------------------------------------------------------------------------- /chia/_tests/testconfig.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Literal, Union 4 | 5 | # Defaults are conservative. 6 | parallel: Union[bool, int, Literal["auto"]] = True 7 | checkout_blocks_and_plots = False 8 | install_timelord = False 9 | # NOTE: do not use until the hangs are fixed 10 | # https://github.com/CFMTech/pytest-monitor/issues/53 11 | # https://github.com/pythonprofilers/memory_profiler/issues/342 12 | check_resource_usage = False 13 | job_timeout = 30 14 | -------------------------------------------------------------------------------- /chia/_tests/timelord/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/timelord/__init__.py -------------------------------------------------------------------------------- /chia/_tests/timelord/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/timelord/test_timelord.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | 5 | from chia.server.aliases import TimelordService 6 | 7 | 8 | @pytest.mark.anyio 9 | async def test_timelord_has_no_server(timelord_service: TimelordService) -> None: 10 | timelord_server = timelord_service._node.server 11 | assert timelord_server.webserver is None 12 | -------------------------------------------------------------------------------- /chia/_tests/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/tools/__init__.py -------------------------------------------------------------------------------- /chia/_tests/tools/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import sys 4 | 5 | legacy_keyring_required = sys.platform == "linux" 6 | -------------------------------------------------------------------------------- /chia/_tests/tools/test-blockchain-db.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/tools/test-blockchain-db.sqlite -------------------------------------------------------------------------------- /chia/_tests/tools/test_full_sync.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from __future__ import annotations 4 | 5 | import asyncio 6 | import os 7 | from pathlib import Path 8 | 9 | import pytest 10 | 11 | from chia._tests.util.full_sync import run_sync_test 12 | 13 | 14 | @pytest.mark.parametrize("keep_up", [True, False]) 15 | def test_full_sync_test(keep_up: bool) -> None: 16 | file_path = os.path.realpath(__file__) 17 | db_file = Path(file_path).parent / "test-blockchain-db.sqlite" 18 | asyncio.run( 19 | run_sync_test( 20 | db_file, 21 | db_version=2, 22 | profile=False, 23 | single_thread=False, 24 | test_constants=False, 25 | keep_up=keep_up, 26 | db_sync="off", 27 | node_profiler=False, 28 | start_at_checkpoint=None, 29 | ) 30 | ) 31 | -------------------------------------------------------------------------------- /chia/_tests/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/util/__init__.py -------------------------------------------------------------------------------- /chia/_tests/util/clvm_generator.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/util/clvm_generator.bin -------------------------------------------------------------------------------- /chia/_tests/util/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 60 4 | -------------------------------------------------------------------------------- /chia/_tests/util/constants.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs.sized_ints import uint8, uint16, uint32, uint64, uint128 4 | 5 | from chia.consensus.default_constants import DEFAULT_CONSTANTS 6 | 7 | test_constants = DEFAULT_CONSTANTS.replace( 8 | MIN_PLOT_SIZE=uint8(18), 9 | MIN_BLOCKS_PER_CHALLENGE_BLOCK=uint8(12), 10 | DIFFICULTY_STARTING=uint64(2**9), 11 | DISCRIMINANT_SIZE_BITS=uint16(16), 12 | SUB_EPOCH_BLOCKS=uint32(170), 13 | WEIGHT_PROOF_THRESHOLD=uint8(2), 14 | WEIGHT_PROOF_RECENT_BLOCKS=uint32(380), 15 | DIFFICULTY_CONSTANT_FACTOR=uint128(33554432), 16 | NUM_SPS_SUB_SLOT=uint32(16), # Must be a power of 2 17 | MAX_SUB_SLOT_BLOCKS=uint32(50), 18 | EPOCH_BLOCKS=uint32(340), 19 | SUB_SLOT_ITERS_STARTING=uint64(2**10), # Must be a multiple of 64 20 | NUMBER_ZERO_BITS_PLOT_FILTER_V1=uint8(1), # H(plot signature of the challenge) must start with these many zeroes 21 | NUMBER_ZERO_BITS_PLOT_FILTER_V2=uint8(1), # H(plot signature of the challenge) must start with these many zeroes 22 | ) 23 | -------------------------------------------------------------------------------- /chia/_tests/util/db_connection.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import tempfile 4 | from collections.abc import AsyncIterator 5 | from contextlib import asynccontextmanager 6 | from pathlib import Path 7 | from typing import Optional 8 | 9 | import aiosqlite 10 | 11 | from chia.util.db_wrapper import DBWrapper2, generate_in_memory_db_uri 12 | 13 | 14 | @asynccontextmanager 15 | async def DBConnection( 16 | db_version: int, 17 | foreign_keys: Optional[bool] = None, 18 | row_factory: Optional[type[aiosqlite.Row]] = None, 19 | ) -> AsyncIterator[DBWrapper2]: 20 | db_uri = generate_in_memory_db_uri() 21 | async with DBWrapper2.managed( 22 | database=db_uri, 23 | uri=True, 24 | reader_count=4, 25 | db_version=db_version, 26 | foreign_keys=foreign_keys, 27 | row_factory=row_factory, 28 | ) as _db_wrapper: 29 | yield _db_wrapper 30 | 31 | 32 | @asynccontextmanager 33 | async def PathDBConnection(db_version: int) -> AsyncIterator[DBWrapper2]: 34 | with tempfile.TemporaryDirectory() as directory: 35 | db_path = Path(directory).joinpath("db.sqlite") 36 | async with DBWrapper2.managed(database=db_path, reader_count=4, db_version=db_version) as _db_wrapper: 37 | yield _db_wrapper 38 | -------------------------------------------------------------------------------- /chia/_tests/util/protocol_messages_bytes-v1.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/util/protocol_messages_bytes-v1.0 -------------------------------------------------------------------------------- /chia/_tests/util/rpc.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia.rpc.rpc_client import RpcClient 4 | from chia.rpc.rpc_server import RpcApiProtocol 5 | 6 | 7 | async def validate_get_routes(client: RpcClient, api: RpcApiProtocol) -> None: 8 | routes_client = (await client.fetch("get_routes", {}))["routes"] 9 | assert len(routes_client) > 0 10 | routes_api = list(api.get_routes().keys()) 11 | # TODO: avoid duplication of RpcServer.get_routes() 12 | routes_server = [ 13 | "/get_network_info", 14 | "/get_connections", 15 | "/open_connection", 16 | "/close_connection", 17 | "/stop_node", 18 | "/get_routes", 19 | "/get_version", 20 | "/healthz", 21 | "/get_log_level", 22 | "/set_log_level", 23 | "/reset_log_level", 24 | ] 25 | assert len(routes_api) > 0 26 | assert sorted(routes_client) == sorted(routes_api + routes_server) 27 | -------------------------------------------------------------------------------- /chia/_tests/util/temp_file.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import contextlib 4 | import tempfile 5 | from collections.abc import Iterator 6 | from pathlib import Path 7 | 8 | 9 | @contextlib.contextmanager 10 | def TempFile() -> Iterator[Path]: 11 | path = Path(tempfile.NamedTemporaryFile().name) 12 | yield path 13 | if path.exists(): 14 | path.unlink() 15 | -------------------------------------------------------------------------------- /chia/_tests/util/test_build_job_matrix.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import json 4 | import pathlib 5 | import subprocess 6 | import sys 7 | 8 | import chia._tests 9 | 10 | build_job_matrix_path = pathlib.Path(chia._tests.__file__).with_name("build-job-matrix.py") 11 | 12 | 13 | def run(args: list[str]) -> str: 14 | completed_process = subprocess.run( 15 | [sys.executable, build_job_matrix_path, *args], 16 | check=True, 17 | encoding="utf-8", 18 | stdout=subprocess.PIPE, 19 | ) 20 | return completed_process.stdout 21 | 22 | 23 | def test() -> None: 24 | timeouts: dict[int, dict[str, int]] = {} 25 | 26 | multipliers = [1, 2, 3] 27 | 28 | for multiplier in multipliers: 29 | timeouts[multiplier] = {} 30 | output = run(args=["--per", "directory", "--timeout-multiplier", str(multiplier)]) 31 | matrix = json.loads(output) 32 | for entry in matrix: 33 | timeouts[multiplier][entry["name"]] = entry["job_timeout"] 34 | 35 | reference = timeouts[1] 36 | 37 | for multiplier in multipliers: 38 | if multiplier == 1: 39 | continue 40 | 41 | adjusted_reference = {key: value * multiplier for key, value in reference.items()} 42 | assert timeouts[multiplier] == adjusted_reference 43 | -------------------------------------------------------------------------------- /chia/_tests/util/test_build_network_protocol_files.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia._tests.util.build_network_protocol_files import main 4 | 5 | 6 | def test_build_network_protocol_files() -> None: 7 | main() 8 | -------------------------------------------------------------------------------- /chia/_tests/util/test_collection.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia.util.collection import find_duplicates 4 | 5 | 6 | def test_find_duplicates() -> None: 7 | assert find_duplicates([]) == set() 8 | assert find_duplicates([1, 1]) == {1} 9 | assert find_duplicates([3, 2, 1]) == set() 10 | assert find_duplicates([1, 2, 3]) == set() 11 | assert find_duplicates([1, 2, 3, 2, 1]) == {1, 2} 12 | -------------------------------------------------------------------------------- /chia/_tests/util/test_errors.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs.sized_ints import int16 4 | 5 | from chia.util.errors import Err 6 | 7 | 8 | def test_error_codes_int16() -> None: 9 | # Make sure all Err codes fit into int16 because its part of the ProtocolMessageTypes.error message structure 10 | for err in Err: 11 | assert int16(err.value) == err.value 12 | -------------------------------------------------------------------------------- /chia/_tests/util/test_installed.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import os 4 | import pathlib 5 | 6 | import pytest 7 | 8 | import chia 9 | 10 | 11 | @pytest.mark.skipif(condition=os.environ.get("CI") is None, reason="Skip outside CI") 12 | def test_chia_installed() -> None: 13 | """This checks that the in-memory chia package was loaded from an installed copy 14 | and not the not-installed source code. This is relevant because it makes our 15 | tests exercise the code and support files from our wheel which can differ from 16 | the source. We have missed some source files and also some data files in the past 17 | and testing the installed code checks for that. A next step would be to install 18 | using the actual wheel file we are going to publish. 19 | """ 20 | assert ".venv" in pathlib.Path(chia.__file__).parts 21 | -------------------------------------------------------------------------------- /chia/_tests/util/test_logging_filter.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import logging 4 | import time 5 | from time import sleep 6 | 7 | import pytest 8 | 9 | from chia.util.logging import TimedDuplicateFilter 10 | 11 | 12 | def test_logging_filter(caplog: pytest.LogCaptureFixture) -> None: 13 | log_interval_secs = 1 14 | num_logs = 11 15 | sleep_secs = 0.095 16 | 17 | log = logging.getLogger() 18 | log.addFilter(TimedDuplicateFilter("Filter this log message.*", log_interval_secs)) 19 | last_time = time.monotonic() 20 | 21 | for n in range(num_logs): 22 | with caplog.at_level(logging.WARNING): 23 | log.warning(f"Filter this log message {n}") 24 | now = time.monotonic() 25 | print(now - last_time) 26 | sleep(min(0.0, now - last_time)) 27 | last_time = now 28 | 29 | assert len(caplog.text.split("\n")) <= ((num_logs * sleep_secs) / log_interval_secs) + 1 30 | 31 | 32 | def test_dont_filter_non_matches(caplog: pytest.LogCaptureFixture) -> None: 33 | log = logging.getLogger() 34 | log.addFilter(TimedDuplicateFilter("Filter this log message.*", 10)) 35 | 36 | num_log_statements = 13 37 | 38 | for n in range(num_log_statements - 1): 39 | with caplog.at_level(logging.WARNING): 40 | log.warning(f"Don't Filter this log message {n}") 41 | 42 | assert len(caplog.text.split("\n")) == num_log_statements 43 | -------------------------------------------------------------------------------- /chia/_tests/util/test_pprint.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia.wallet.util.pprint import print_compact_ranges 4 | 5 | 6 | def test_print_compact_ranges() -> None: 7 | assert print_compact_ranges([]) == "[]" 8 | assert print_compact_ranges([1]) == "[1]" 9 | assert print_compact_ranges([1, 2]) == "[1 to 2]" 10 | assert print_compact_ranges([2, 1]) == "[1 to 2]" 11 | assert print_compact_ranges([1, 3, 4]) == "[1, 3 to 4]" 12 | assert print_compact_ranges([1, 2, 4]) == "[1 to 2, 4]" 13 | assert print_compact_ranges([1, 2, 4, 5]) == "[1 to 2, 4 to 5]" 14 | 15 | assert print_compact_ranges([-1, -2]) == "[-2 to -1]" 16 | 17 | assert print_compact_ranges([1, 1, 1, 2, 2, 4, 4, 9]) == "[1 to 2, 4, 9]" 18 | -------------------------------------------------------------------------------- /chia/_tests/util/test_service_groups.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia.util.service_groups import services_for_groups 4 | 5 | 6 | def test_services_for_groups() -> None: 7 | i = 0 8 | for service in services_for_groups(["harvester"]): 9 | assert service == "chia_harvester" 10 | i += 1 11 | assert i == 1 12 | 13 | for _ in services_for_groups(["daemon"]): 14 | # The loop should never be run 15 | assert False # pragma: no cover 16 | -------------------------------------------------------------------------------- /chia/_tests/util/test_ssl_check.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import sys 4 | from pathlib import Path 5 | 6 | import pytest 7 | 8 | from chia.ssl.create_ssl import create_all_ssl 9 | from chia.ssl.ssl_check import check_ssl 10 | 11 | 12 | def test_check_ssl_stream_with_bad_permissions( 13 | capsys: pytest.CaptureFixture[str], 14 | root_path_populated_with_config: Path, 15 | ) -> None: 16 | with capsys.disabled(): 17 | create_all_ssl(root_path=root_path_populated_with_config) 18 | root_path_populated_with_config.joinpath("config", "ssl", "daemon", "private_daemon.crt").chmod(mode=0o777) 19 | 20 | check_ssl(root_path=root_path_populated_with_config) 21 | 22 | with capsys.disabled(): 23 | captured = capsys.readouterr() 24 | print(f"stdout: {captured.out!r}") 25 | print(f"stderr: {captured.err!r}") 26 | 27 | assert captured.out == "" 28 | if sys.platform == "win32": 29 | assert captured.err == "" 30 | else: 31 | assert "WARNING: UNPROTECTED SSL FILE!" in captured.err 32 | -------------------------------------------------------------------------------- /chia/_tests/util/test_testnet_overrides.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any 4 | 5 | from chia.consensus.default_constants import update_testnet_overrides 6 | 7 | 8 | def test_testnet11() -> None: 9 | overrides: dict[str, Any] = {} 10 | update_testnet_overrides("testnet11", overrides) 11 | assert overrides == {} 12 | 13 | 14 | def test_mainnet() -> None: 15 | overrides: dict[str, Any] = {} 16 | update_testnet_overrides("mainnet", overrides) 17 | assert overrides == {} 18 | -------------------------------------------------------------------------------- /chia/_tests/util/test_tests_misc.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | import pytest 6 | 7 | from chia._tests.util.misc import Marks, datacases, named_datacases 8 | 9 | 10 | @dataclass 11 | class DataCase: 12 | id: str 13 | marks: Marks 14 | 15 | 16 | sample_cases = [ 17 | DataCase(id="id_a", marks=[pytest.mark.test_mark_a1, pytest.mark.test_mark_a2]), 18 | DataCase(id="id_b", marks=[pytest.mark.test_mark_b1, pytest.mark.test_mark_b2]), 19 | ] 20 | 21 | 22 | def sample_result(name: str) -> pytest.MarkDecorator: 23 | return pytest.mark.parametrize( 24 | argnames=name, 25 | argvalues=[pytest.param(case, id=case.id, marks=case.marks) for case in sample_cases], 26 | ) 27 | 28 | 29 | def test_datacases() -> None: 30 | result = datacases(*sample_cases) 31 | 32 | assert result == sample_result(name="case") 33 | 34 | 35 | def test_named_datacases() -> None: 36 | result = named_datacases("Sharrilanda")(*sample_cases) 37 | 38 | assert result == sample_result(name="Sharrilanda") 39 | -------------------------------------------------------------------------------- /chia/_tests/util/test_timing.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from collections.abc import Iterator 4 | 5 | from chia.util.timing import backoff_times 6 | 7 | 8 | def test_backoff_yields_initial_first() -> None: 9 | backoff = backoff_times(initial=3, final=10) 10 | assert next(backoff) == 3 11 | 12 | 13 | def test_backoff_yields_final_at_end() -> None: 14 | def clock(times: Iterator[int] = iter([0, 1])) -> float: 15 | return next(times) 16 | 17 | backoff = backoff_times(initial=2, final=7, time_to_final=1, clock=clock) 18 | next(backoff) 19 | assert next(backoff) == 7 20 | 21 | 22 | def test_backoff_yields_half_at_halfway() -> None: 23 | def clock(times: Iterator[int] = iter([0, 1])) -> float: 24 | return next(times) 25 | 26 | backoff = backoff_times(initial=4, final=6, time_to_final=2, clock=clock) 27 | next(backoff) 28 | assert next(backoff) == 5 29 | 30 | 31 | def test_backoff_saturates_at_final() -> None: 32 | def clock(times: Iterator[int] = iter([0, 2])) -> float: 33 | return next(times) 34 | 35 | backoff = backoff_times(initial=1, final=3, time_to_final=1, clock=clock) 36 | next(backoff) 37 | assert next(backoff) == 3 38 | -------------------------------------------------------------------------------- /chia/_tests/wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/cat_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/cat_wallet/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/cat_wallet/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 90 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/wallet/clawback/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/clawback/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/clawback/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/wallet/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 40 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/wallet/db_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/db_wallet/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/db_wallet/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/wallet/did_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/did_wallet/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/did_wallet/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 50 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/wallet/nft_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/nft_wallet/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/nft_wallet/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 115 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/wallet/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/rpc/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/rpc/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | job_timeout = 35 5 | -------------------------------------------------------------------------------- /chia/_tests/wallet/simple_sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/simple_sync/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/simple_sync/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/wallet/sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/sync/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/sync/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 60 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /chia/_tests/wallet/test_taproot.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia._tests.core.make_block_generator import int_to_public_key 4 | from chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import ( 5 | DEFAULT_HIDDEN_PUZZLE, 6 | calculate_synthetic_offset, 7 | calculate_synthetic_public_key, 8 | ) 9 | 10 | 11 | def test_1() -> None: 12 | for main_secret_exponent in range(500, 600): 13 | hidden_puzzle_hash = DEFAULT_HIDDEN_PUZZLE.get_tree_hash() 14 | main_pubkey = int_to_public_key(main_secret_exponent) 15 | offset = calculate_synthetic_offset(main_pubkey, hidden_puzzle_hash) 16 | offset_pubkey = int_to_public_key(offset) 17 | spk1 = main_pubkey + offset_pubkey 18 | spk2 = calculate_synthetic_public_key(main_pubkey, hidden_puzzle_hash) 19 | assert spk1 == spk2 20 | -------------------------------------------------------------------------------- /chia/_tests/wallet/test_wallet_user_store.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | 5 | from chia._tests.util.db_connection import DBConnection 6 | from chia.wallet.util.wallet_types import WalletType 7 | from chia.wallet.wallet_user_store import WalletUserStore 8 | 9 | 10 | @pytest.mark.anyio 11 | async def test_store() -> None: 12 | async with DBConnection(1) as db_wrapper: 13 | store = await WalletUserStore.create(db_wrapper) 14 | await store.init_wallet() 15 | wallet = None 16 | for i in range(1, 5): 17 | assert (await store.get_last_wallet()).id == i 18 | wallet = await store.create_wallet("CAT_WALLET", WalletType.CAT, "abc") 19 | assert wallet.id == i + 1 20 | assert wallet is not None 21 | assert wallet.id == 5 22 | 23 | for i in range(2, 6): 24 | await store.delete_wallet(i) 25 | 26 | assert (await store.get_last_wallet()).id == 1 27 | wallet = await store.create_wallet("CAT_WALLET", WalletType.CAT, "abc") 28 | # Due to autoincrement, we don't reuse IDs 29 | assert (await store.get_last_wallet()).id == 6 30 | assert wallet.id == 6 31 | 32 | assert (await store.get_wallet_by_id(7)) is None 33 | assert (await store.get_wallet_by_id(6)) == wallet 34 | assert await store.get_last_wallet() == wallet 35 | -------------------------------------------------------------------------------- /chia/_tests/wallet/vc_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/wallet/vc_wallet/__init__.py -------------------------------------------------------------------------------- /chia/_tests/wallet/vc_wallet/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/_tests/weight_proof/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/_tests/weight_proof/__init__.py -------------------------------------------------------------------------------- /chia/_tests/weight_proof/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /chia/apis.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia.farmer.farmer_api import FarmerAPI 4 | from chia.full_node.full_node_api import FullNodeAPI 5 | from chia.harvester.harvester_api import HarvesterAPI 6 | from chia.introducer.introducer_api import IntroducerAPI 7 | from chia.protocols.outbound_message import NodeType 8 | from chia.server.api_protocol import ApiProtocol 9 | from chia.timelord.timelord_api import TimelordAPI 10 | from chia.wallet.wallet_node_api import WalletNodeAPI 11 | 12 | ApiProtocolRegistry: dict[NodeType, type[ApiProtocol]] = { 13 | NodeType.FULL_NODE: FullNodeAPI, 14 | NodeType.WALLET: WalletNodeAPI, 15 | NodeType.INTRODUCER: IntroducerAPI, 16 | NodeType.TIMELORD: TimelordAPI, 17 | NodeType.FARMER: FarmerAPI, 18 | NodeType.HARVESTER: HarvesterAPI, 19 | } 20 | -------------------------------------------------------------------------------- /chia/clvm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/clvm/__init__.py -------------------------------------------------------------------------------- /chia/cmds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/cmds/__init__.py -------------------------------------------------------------------------------- /chia/cmds/dev/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/cmds/dev/__init__.py -------------------------------------------------------------------------------- /chia/cmds/dev/main.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import click 4 | 5 | from chia.cmds.dev.data import data_group 6 | from chia.cmds.dev.gh import gh_group 7 | from chia.cmds.dev.installers import installers_group 8 | from chia.cmds.dev.mempool import mempool_cmd 9 | from chia.cmds.dev.sim import sim_cmd 10 | 11 | 12 | @click.group("dev", help="Developer commands and tools") 13 | @click.pass_context 14 | def dev_cmd(ctx: click.Context) -> None: 15 | pass 16 | 17 | 18 | dev_cmd.add_command(sim_cmd) 19 | dev_cmd.add_command(installers_group) 20 | dev_cmd.add_command(gh_group) 21 | dev_cmd.add_command(mempool_cmd) 22 | dev_cmd.add_command(data_group) 23 | -------------------------------------------------------------------------------- /chia/cmds/options.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any, Callable, TypeVar, Union 4 | 5 | import click 6 | 7 | from chia.cmds.param_types import TransactionFeeParamType 8 | 9 | FC = TypeVar("FC", bound=Union[Callable[..., Any], click.Command]) 10 | 11 | 12 | def create_fingerprint(required: bool = False) -> Callable[[FC], FC]: 13 | return click.option( 14 | "-f", 15 | "--fingerprint", 16 | help="Fingerprint of the wallet to use", 17 | required=required, 18 | # TODO: should be uint32 19 | type=int, 20 | ) 21 | 22 | 23 | def create_fee(message: str = "Set the fees for the transaction, in XCH", required: bool = True) -> Callable[[FC], FC]: 24 | return click.option( 25 | "-m", 26 | "--fee", 27 | help=message, 28 | type=TransactionFeeParamType(), 29 | default="0", 30 | show_default=True, 31 | required=required, 32 | ) 33 | -------------------------------------------------------------------------------- /chia/cmds/plotters.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import click 4 | 5 | from chia.cmds.cmd_classes import ChiaCliContext 6 | from chia.plotters.plotters import call_plotters 7 | 8 | 9 | @click.command( 10 | "plotters", 11 | help="Advanced plotting options", 12 | context_settings={"ignore_unknown_options": True}, 13 | add_help_option=False, 14 | ) 15 | @click.pass_context 16 | @click.argument("args", nargs=-1) 17 | def plotters_cmd(ctx: click.Context, args: tuple[click.Argument]) -> None: 18 | call_plotters(ChiaCliContext.set_default(ctx).root_path, args) 19 | -------------------------------------------------------------------------------- /chia/cmds/start.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import click 4 | 5 | from chia.cmds.cmd_classes import ChiaCliContext 6 | from chia.util.config import load_config 7 | from chia.util.service_groups import all_groups 8 | 9 | 10 | @click.command("start", help="Start service groups") 11 | @click.option("-r", "--restart", is_flag=True, type=bool, help="Restart running services") 12 | @click.option("-s", "--skip-keyring", is_flag=True, type=bool, help="Skip to unlock keyring") 13 | @click.argument("group", type=click.Choice(list(all_groups())), nargs=-1, required=True) 14 | @click.pass_context 15 | def start_cmd(ctx: click.Context, restart: bool, skip_keyring: bool, group: tuple[str, ...]) -> None: 16 | import asyncio 17 | 18 | from chia.cmds.beta_funcs import warn_if_beta_enabled 19 | from chia.cmds.start_funcs import async_start 20 | 21 | root_path = ChiaCliContext.set_default(ctx).root_path 22 | config = load_config(root_path, "config.yaml") 23 | warn_if_beta_enabled(config) 24 | asyncio.run(async_start(root_path, config, group, restart, skip_keyring=skip_keyring)) 25 | -------------------------------------------------------------------------------- /chia/cmds/units.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | # The rest of the codebase uses mojos everywhere. 4 | # Only use these units for user facing interfaces. 5 | units: dict[str, int] = { 6 | "chia": 10**12, # 1 chia (XCH) is 1,000,000,000,000 mojo (1 trillion) 7 | "mojo": 1, 8 | "cat": 10**3, # 1 CAT is 1000 CAT mojos 9 | } 10 | -------------------------------------------------------------------------------- /chia/consensus/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/consensus/__init__.py -------------------------------------------------------------------------------- /chia/consensus/block_record.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Optional 4 | 5 | from chia_rs.sized_bytes import bytes32 6 | from chia_rs.sized_ints import uint32, uint64 7 | from typing_extensions import Protocol 8 | 9 | 10 | class BlockRecordProtocol(Protocol): 11 | @property 12 | def header_hash(self) -> bytes32: ... 13 | 14 | @property 15 | def height(self) -> uint32: ... 16 | 17 | @property 18 | def timestamp(self) -> Optional[uint64]: ... 19 | 20 | @property 21 | def prev_transaction_block_height(self) -> uint32: ... 22 | 23 | @property 24 | def prev_transaction_block_hash(self) -> Optional[bytes32]: ... 25 | 26 | @property 27 | def is_transaction_block(self) -> bool: ... 28 | -------------------------------------------------------------------------------- /chia/consensus/coinbase.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs.sized_bytes import bytes32 4 | from chia_rs.sized_ints import uint32, uint64 5 | 6 | from chia.types.blockchain_format.coin import Coin 7 | 8 | 9 | def pool_parent_id(block_height: uint32, genesis_challenge: bytes32) -> bytes32: 10 | return bytes32(genesis_challenge[:16] + block_height.to_bytes(16, "big")) 11 | 12 | 13 | def farmer_parent_id(block_height: uint32, genesis_challenge: bytes32) -> bytes32: 14 | return bytes32(genesis_challenge[16:] + block_height.to_bytes(16, "big")) 15 | 16 | 17 | def create_pool_coin(block_height: uint32, puzzle_hash: bytes32, reward: uint64, genesis_challenge: bytes32) -> Coin: 18 | parent_id = pool_parent_id(block_height, genesis_challenge) 19 | return Coin(parent_id, puzzle_hash, reward) 20 | 21 | 22 | def create_farmer_coin(block_height: uint32, puzzle_hash: bytes32, reward: uint64, genesis_challenge: bytes32) -> Coin: 23 | parent_id = farmer_parent_id(block_height, genesis_challenge) 24 | return Coin(parent_id, puzzle_hash, reward) 25 | -------------------------------------------------------------------------------- /chia/consensus/condition_costs.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from enum import Enum 4 | 5 | 6 | class ConditionCost(Enum): 7 | # Condition Costs 8 | AGG_SIG = 1200000 # the cost of one G1 subgroup check + aggregated signature validation 9 | CREATE_COIN = 1800000 10 | -------------------------------------------------------------------------------- /chia/consensus/cost_calculator.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from chia_rs import SpendBundleConditions 7 | from chia_rs.sized_ints import uint16 8 | 9 | from chia.util.streamable import Streamable, streamable 10 | 11 | 12 | @streamable 13 | @dataclass(frozen=True) 14 | class NPCResult(Streamable): 15 | error: Optional[uint16] 16 | conds: Optional[SpendBundleConditions] 17 | -------------------------------------------------------------------------------- /chia/consensus/get_block_generator.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from collections.abc import Awaitable 4 | from typing import Callable, Optional 5 | 6 | from chia_rs.sized_bytes import bytes32 7 | from chia_rs.sized_ints import uint32 8 | 9 | from chia.types.block_protocol import BlockInfo 10 | from chia.types.generator_types import BlockGenerator 11 | 12 | 13 | async def get_block_generator( 14 | lookup_block_generators: Callable[[bytes32, set[uint32]], Awaitable[dict[uint32, bytes]]], 15 | block: BlockInfo, 16 | ) -> Optional[BlockGenerator]: 17 | ref_list = block.transactions_generator_ref_list 18 | if block.transactions_generator is None: 19 | assert len(ref_list) == 0 20 | return None 21 | if len(ref_list) == 0: 22 | return BlockGenerator(block.transactions_generator, []) 23 | 24 | generator_refs = set(ref_list) 25 | generators: dict[uint32, bytes] = await lookup_block_generators(block.prev_header_hash, generator_refs) 26 | 27 | result = [generators[height] for height in block.transactions_generator_ref_list] 28 | return BlockGenerator(block.transactions_generator, result) 29 | -------------------------------------------------------------------------------- /chia/consensus/pos_quality.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs.sized_ints import uint64 4 | 5 | # The actual space in bytes of a plot, is _expected_plot_size(k) * UI_ACTUAL_SPACE_CONSTANT_FACTO 6 | # This is not used in consensus, only for display purposes 7 | UI_ACTUAL_SPACE_CONSTANT_FACTOR = 0.78 8 | 9 | 10 | def _expected_plot_size(k: int) -> uint64: 11 | """ 12 | Given the plot size parameter k (which is between 32 and 59), computes the 13 | expected size of the plot in bytes (times a constant factor). This is based on efficient encoding 14 | of the plot, and aims to be scale agnostic, so larger plots don't 15 | necessarily get more rewards per byte. The +1 is added to give half a bit more space per entry, which 16 | is necessary to store the entries in the plot. 17 | """ 18 | 19 | return uint64(((2 * k) + 1) * (2 ** (k - 1))) 20 | -------------------------------------------------------------------------------- /chia/consensus/prev_transaction_block.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs import BlockRecord 4 | from chia_rs.sized_ints import uint128 5 | 6 | from chia.consensus.blockchain_interface import BlockRecordsProtocol 7 | 8 | 9 | def get_prev_transaction_block( 10 | curr: BlockRecord, 11 | blocks: BlockRecordsProtocol, 12 | total_iters_sp: uint128, 13 | ) -> tuple[bool, BlockRecord]: 14 | prev_transaction_block = curr 15 | while not curr.is_transaction_block: 16 | curr = blocks.block_record(curr.prev_hash) 17 | if total_iters_sp > curr.total_iters: 18 | prev_transaction_block = curr 19 | is_transaction_block = True 20 | else: 21 | is_transaction_block = False 22 | return is_transaction_block, prev_transaction_block 23 | -------------------------------------------------------------------------------- /chia/daemon/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/daemon/__init__.py -------------------------------------------------------------------------------- /chia/data_layer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/data_layer/__init__.py -------------------------------------------------------------------------------- /chia/data_layer/data_layer_api.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import logging 4 | from typing import TYPE_CHECKING, ClassVar, cast 5 | 6 | from chia.data_layer.data_layer import DataLayer 7 | from chia.server.api_protocol import ApiMetadata 8 | from chia.server.server import ChiaServer 9 | 10 | 11 | class DataLayerAPI: 12 | if TYPE_CHECKING: 13 | from chia.server.api_protocol import ApiProtocol 14 | 15 | _protocol_check: ClassVar[ApiProtocol] = cast("DataLayerAPI", None) 16 | 17 | log: logging.Logger 18 | data_layer: DataLayer 19 | metadata: ClassVar[ApiMetadata] = ApiMetadata() 20 | 21 | def __init__(self, data_layer: DataLayer) -> None: 22 | self.log = logging.getLogger(__name__) 23 | self.data_layer = data_layer 24 | 25 | # def _set_state_changed_callback(self, callback: StateChangedProtocol) -> None: 26 | # self.full_node.state_changed_callback = callback 27 | 28 | @property 29 | def server(self) -> ChiaServer: 30 | return self.data_layer.server 31 | 32 | def ready(self) -> bool: 33 | return self.data_layer.initialized 34 | -------------------------------------------------------------------------------- /chia/data_layer/data_layer_errors.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from collections.abc import Iterable 4 | 5 | from chia_rs.sized_bytes import bytes32 6 | 7 | 8 | class IntegrityError(Exception): 9 | pass 10 | 11 | 12 | def build_message_with_hashes(message: str, bytes_objects: Iterable[bytes]) -> str: 13 | return "\n".join([message, *[f" {b.hex()}" for b in bytes_objects]]) 14 | 15 | 16 | class TreeGenerationIncrementingError(IntegrityError): 17 | def __init__(self, store_ids: list[bytes32]) -> None: 18 | super().__init__( 19 | build_message_with_hashes( 20 | message="Found trees with generations not properly incrementing:", 21 | bytes_objects=store_ids, 22 | ) 23 | ) 24 | 25 | 26 | class NodeHashError(IntegrityError): 27 | def __init__(self, node_hashes: list[bytes32]) -> None: 28 | super().__init__( 29 | build_message_with_hashes( 30 | message="Found nodes with incorrect hashes:", 31 | bytes_objects=node_hashes, 32 | ) 33 | ) 34 | 35 | 36 | class KeyNotFoundError(Exception): 37 | def __init__(self, key: bytes) -> None: 38 | super().__init__(f"Key not found: {key.hex()}") 39 | 40 | 41 | class OfferIntegrityError(Exception): 42 | pass 43 | 44 | 45 | class ProofIntegrityError(Exception): 46 | pass 47 | 48 | 49 | class LauncherCoinNotFoundError(Exception): 50 | pass 51 | -------------------------------------------------------------------------------- /chia/data_layer/puzzles/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/data_layer/puzzles/__init__.py -------------------------------------------------------------------------------- /chia/data_layer/s3_plugin_config.yml: -------------------------------------------------------------------------------- 1 | instance-1: 2 | log_filename: "s3_plugin.log" 3 | log_level: INFO 4 | server_files_location: "/Users/test/.chia/mainnet/data_layer/db/server_files_location_testnet10" 5 | port: 8998 6 | aws_credentials: 7 | access_key_id: "xxx" 8 | secret_access_key: "xxx" 9 | region: "xxx" 10 | 11 | stores: 12 | - store_id: "7acfcbd1ed73bfe2b698508f4ea5ed353c60ace154360272ce91f9ab0c8423c3" 13 | upload_bucket: "chia-datalayer-test-bucket-2" 14 | download_urls: ["s3://hello", "s3://goodbye"] 15 | - store_id: "a14daf55d41ced6419bcd011fbc1f74ab9567fe55340d88435aa6493d628fa47" 16 | upload_bucket: 17 | download_urls: ["s3://hello", "s3://goodbye"] 18 | 19 | instance-2: 20 | port: 8999 21 | server_files_location: "/Users/test/.chia/mainnet/data_layer/db/server_files_location_testnet10" 22 | aws_credentials: 23 | access_key_id: "xxx" 24 | secret_access_key: "xxx" 25 | region: "xxx" 26 | 27 | stores: 28 | - store_id: "7acfcbd1ed73bfe2b698508f4ea5ed353c60ace154360272ce91f9ab0c8423c3" 29 | upload_bucket: "" 30 | download_urls: [] 31 | - store_id: "a14daf55d41ced6419bcd011fbc1f74ab9567fe55340d88435aa6493d628fa47" 32 | upload_bucket: "chia-datalayer-test-bucket-1" 33 | download_urls: [] 34 | -------------------------------------------------------------------------------- /chia/data_layer/singleton_record.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import dataclasses 4 | 5 | from chia_rs.sized_bytes import bytes32 6 | from chia_rs.sized_ints import uint32, uint64 7 | 8 | from chia.util.streamable import Streamable, streamable 9 | from chia.wallet.lineage_proof import LineageProof 10 | 11 | 12 | @streamable 13 | @dataclasses.dataclass(frozen=True) 14 | class SingletonRecord(Streamable): 15 | coin_id: bytes32 16 | launcher_id: bytes32 17 | root: bytes32 18 | inner_puzzle_hash: bytes32 19 | confirmed: bool 20 | confirmed_at_height: uint32 21 | lineage_proof: LineageProof 22 | generation: uint32 23 | timestamp: uint64 24 | -------------------------------------------------------------------------------- /chia/data_layer/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/data_layer/util/__init__.py -------------------------------------------------------------------------------- /chia/farmer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/farmer/__init__.py -------------------------------------------------------------------------------- /chia/full_node/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/full_node/__init__.py -------------------------------------------------------------------------------- /chia/full_node/bundle_tools.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs import SpendBundle, solution_generator, solution_generator_backrefs 4 | 5 | from chia.types.blockchain_format.serialized_program import SerializedProgram 6 | from chia.types.generator_types import BlockGenerator 7 | 8 | 9 | def simple_solution_generator(bundle: SpendBundle) -> BlockGenerator: 10 | spends = [(cs.coin, bytes(cs.puzzle_reveal), bytes(cs.solution)) for cs in bundle.coin_spends] 11 | block_program = solution_generator(spends) 12 | return BlockGenerator(SerializedProgram.from_bytes(block_program), []) 13 | 14 | 15 | def simple_solution_generator_backrefs(bundle: SpendBundle) -> BlockGenerator: 16 | spends = [(cs.coin, bytes(cs.puzzle_reveal), bytes(cs.solution)) for cs in bundle.coin_spends] 17 | block_program = solution_generator_backrefs(spends) 18 | return BlockGenerator(SerializedProgram.from_bytes(block_program), []) 19 | -------------------------------------------------------------------------------- /chia/full_node/fee_estimator_constants.py: -------------------------------------------------------------------------------- 1 | # https://github.com/bitcoin/bitcoin/blob/5b6f0f31fa6ce85db3fb7f9823b1bbb06161ae32/src/policy/fees.h 2 | from __future__ import annotations 3 | 4 | MIN_FEE_RATE = 0 # Value of first bucket 5 | INITIAL_STEP = 5.0 # First bucket after zero value 6 | MAX_FEE_RATE = 40000000.0 # Mojo per 1000 cost unit 7 | INFINITE_FEE_RATE = 1000000000.0 8 | 9 | STEP_SIZE = 1.05 # bucket increase by 1.05 10 | 11 | # Track confirm delays up to SHORT_BLOCK_PERIOD blocks for short horizon 12 | SHORT_BLOCK_PERIOD = 12 # 3 13 | SHORT_SCALE = 1 14 | 15 | # Track confirm delays up to MED_BLOCK_PERIOD blocks for medium horizon 16 | MED_BLOCK_PERIOD = 24 # 15 17 | MED_SCALE = 2 18 | 19 | # Track confirm delays up to LONG_BLOCK_PERIOD blocks for long horizon 20 | LONG_BLOCK_PERIOD = 42 # 15 21 | LONG_SCALE = 24 # 4 22 | 23 | SECONDS_PER_BLOCK = 40 24 | 25 | SHORT_DECAY = 0.962 26 | MED_DECAY = 0.9952 27 | LONG_DECAY = 0.99931 28 | 29 | HALF_SUCCESS_PCT = 0.6 # Require 60 % success rate for target confirmations 30 | SUCCESS_PCT = 0.85 # Require 85 % success rate for target confirmations 31 | DOUBLE_SUCCESS_PCT = 0.95 # Require 95 % success rate for target confirmations 32 | 33 | # Require an avg of SUFFICIENT_FEE_TXS tx in the combined fee rate bucket per block to have stat. significance 34 | SUFFICIENT_FEE_TXS = 0.01 35 | 36 | FEE_ESTIMATOR_VERSION = 1 37 | 38 | OLDEST_ESTIMATE_HISTORY = 6 * 1008 39 | -------------------------------------------------------------------------------- /chia/full_node/fee_history.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from chia_rs.sized_ints import uint8, uint32 6 | 7 | from chia.util.streamable import Streamable, streamable 8 | 9 | 10 | @streamable 11 | @dataclass(frozen=True) 12 | class FeeStatBackup(Streamable): 13 | type: str 14 | tx_ct_avg: list[str] 15 | confirmed_average: list[list[str]] 16 | failed_average: list[list[str]] 17 | m_fee_rate_avg: list[str] 18 | 19 | 20 | @streamable 21 | @dataclass(frozen=True) 22 | class FeeTrackerBackup(Streamable): 23 | fee_estimator_version: uint8 24 | first_recorded_height: uint32 25 | latest_seen_height: uint32 26 | stats: list[FeeStatBackup] 27 | -------------------------------------------------------------------------------- /chia/full_node/signage_point.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from chia.types.blockchain_format.vdf import VDFInfo, VDFProof 7 | from chia.util.streamable import Streamable, streamable 8 | 9 | 10 | @streamable 11 | @dataclass(frozen=True) 12 | class SignagePoint(Streamable): 13 | cc_vdf: Optional[VDFInfo] 14 | cc_proof: Optional[VDFProof] 15 | rc_vdf: Optional[VDFInfo] 16 | rc_proof: Optional[VDFProof] 17 | -------------------------------------------------------------------------------- /chia/full_node/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/full_node/util/__init__.py -------------------------------------------------------------------------------- /chia/harvester/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/harvester/__init__.py -------------------------------------------------------------------------------- /chia/introducer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/introducer/__init__.py -------------------------------------------------------------------------------- /chia/legacy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/legacy/__init__.py -------------------------------------------------------------------------------- /chia/plot_sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/plot_sync/__init__.py -------------------------------------------------------------------------------- /chia/plot_sync/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from enum import IntEnum 4 | from typing import TypeVar 5 | 6 | from typing_extensions import Protocol 7 | 8 | from chia.protocols.harvester_protocol import PlotSyncIdentifier 9 | 10 | 11 | class Constants: 12 | message_timeout: int = 10 13 | 14 | 15 | class State(IntEnum): 16 | idle = 0 17 | loaded = 1 18 | removed = 2 19 | invalid = 3 20 | keys_missing = 4 21 | duplicates = 5 22 | done = 6 23 | 24 | 25 | class ErrorCodes(IntEnum): 26 | unknown = -1 27 | invalid_state = 0 28 | invalid_peer_id = 1 29 | invalid_identifier = 2 30 | invalid_last_sync_id = 3 31 | invalid_connection_type = 4 32 | plot_already_available = 5 33 | plot_not_available = 6 34 | sync_ids_match = 7 35 | 36 | 37 | class PlotSyncMessage(Protocol): 38 | @property 39 | def identifier(self) -> PlotSyncIdentifier: 40 | pass 41 | 42 | 43 | T_PlotSyncMessage = TypeVar("T_PlotSyncMessage", bound=PlotSyncMessage) 44 | -------------------------------------------------------------------------------- /chia/plotters/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/plotters/__init__.py -------------------------------------------------------------------------------- /chia/plotting/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/plotting/__init__.py -------------------------------------------------------------------------------- /chia/pools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/pools/__init__.py -------------------------------------------------------------------------------- /chia/protocols/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/protocols/__init__.py -------------------------------------------------------------------------------- /chia/protocols/fee_estimate_store.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import dataclasses 4 | from typing import Optional 5 | 6 | import typing_extensions 7 | 8 | from chia.full_node.fee_history import FeeTrackerBackup 9 | 10 | 11 | @typing_extensions.final 12 | @dataclasses.dataclass 13 | class FeeStore: 14 | """ 15 | This object stores Fee Stats 16 | """ 17 | 18 | _backup: Optional[FeeTrackerBackup] = None 19 | 20 | def get_stored_fee_data(self) -> Optional[FeeTrackerBackup]: 21 | return self._backup 22 | 23 | def store_fee_data(self, fee_backup: FeeTrackerBackup) -> None: 24 | self._backup = fee_backup 25 | -------------------------------------------------------------------------------- /chia/protocols/introducer_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from chia.types.peer_info import TimestampedPeerInfo 6 | from chia.util.streamable import Streamable, streamable 7 | 8 | """ 9 | Protocol to introducer 10 | Note: When changing this file, also change protocol_message_types.py, and the protocol version in shared_protocol.py 11 | """ 12 | 13 | 14 | @streamable 15 | @dataclass(frozen=True) 16 | class RequestPeersIntroducer(Streamable): 17 | """ 18 | Return full list of peers 19 | """ 20 | 21 | 22 | @streamable 23 | @dataclass(frozen=True) 24 | class RespondPeersIntroducer(Streamable): 25 | peer_list: list[TimestampedPeerInfo] 26 | -------------------------------------------------------------------------------- /chia/protocols/outbound_message.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from enum import IntEnum 5 | from typing import Optional, SupportsBytes, Union 6 | 7 | from chia_rs.sized_ints import uint8, uint16 8 | 9 | from chia.protocols.protocol_message_types import ProtocolMessageTypes 10 | from chia.util.streamable import Streamable, streamable 11 | 12 | 13 | class NodeType(IntEnum): 14 | FULL_NODE = 1 15 | HARVESTER = 2 16 | FARMER = 3 17 | TIMELORD = 4 18 | INTRODUCER = 5 19 | WALLET = 6 20 | DATA_LAYER = 7 21 | 22 | 23 | @streamable 24 | @dataclass(frozen=True) 25 | class Message(Streamable): 26 | type: uint8 # one of ProtocolMessageTypes 27 | # message id 28 | id: Optional[uint16] 29 | # Message data for that type 30 | data: bytes 31 | 32 | 33 | def make_msg(msg_type: ProtocolMessageTypes, data: Union[bytes, SupportsBytes]) -> Message: 34 | return Message(uint8(msg_type.value), None, bytes(data)) 35 | -------------------------------------------------------------------------------- /chia/protocols/protocol_timing.py: -------------------------------------------------------------------------------- 1 | # These settings should not be end-user configurable 2 | from __future__ import annotations 3 | 4 | INVALID_PROTOCOL_BAN_SECONDS = 10 5 | API_EXCEPTION_BAN_SECONDS = 10 6 | INTERNAL_PROTOCOL_ERROR_BAN_SECONDS = 10 # Don't flap if our client is at fault 7 | CONSENSUS_ERROR_BAN_SECONDS = 600 8 | RATE_LIMITER_BAN_SECONDS = 300 9 | -------------------------------------------------------------------------------- /chia/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/py.typed -------------------------------------------------------------------------------- /chia/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/rpc/__init__.py -------------------------------------------------------------------------------- /chia/rpc/timelord_rpc_api.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import TYPE_CHECKING, Any, ClassVar, Optional, cast 4 | 5 | from chia.rpc.rpc_server import Endpoint 6 | from chia.timelord.timelord import Timelord 7 | from chia.util.ws_message import WsRpcMessage, create_payload_dict 8 | 9 | 10 | class TimelordRpcApi: 11 | if TYPE_CHECKING: 12 | from chia.rpc.rpc_server import RpcApiProtocol 13 | 14 | _protocol_check: ClassVar[RpcApiProtocol] = cast("TimelordRpcApi", None) 15 | 16 | def __init__(self, timelord: Timelord): 17 | self.service = timelord 18 | self.service_name = "chia_timelord" 19 | 20 | def get_routes(self) -> dict[str, Endpoint]: 21 | return {} 22 | 23 | async def _state_changed(self, change: str, change_data: Optional[dict[str, Any]] = None) -> list[WsRpcMessage]: 24 | payloads = [] 25 | 26 | if change_data is None: 27 | change_data = {} 28 | 29 | if change in {"finished_pot", "new_compact_proof", "skipping_peak", "new_peak"}: 30 | payloads.append(create_payload_dict(change, change_data, self.service_name, "metrics")) 31 | 32 | return payloads 33 | -------------------------------------------------------------------------------- /chia/seeder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/seeder/__init__.py -------------------------------------------------------------------------------- /chia/server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/server/__init__.py -------------------------------------------------------------------------------- /chia/server/address_manager_store.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import logging 4 | from dataclasses import dataclass 5 | 6 | from chia_rs.sized_ints import uint64 7 | 8 | from chia.util.streamable import Streamable, streamable 9 | 10 | log = logging.getLogger(__name__) 11 | 12 | 13 | @streamable 14 | @dataclass(frozen=True) 15 | class PeerDataSerialization(Streamable): 16 | """ 17 | Serializable property bag for the peer data that was previously stored in sqlite. 18 | """ 19 | 20 | metadata: list[tuple[str, str]] 21 | nodes: list[tuple[uint64, str]] 22 | new_table: list[tuple[uint64, uint64]] 23 | -------------------------------------------------------------------------------- /chia/server/capabilities.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from collections.abc import Iterable 4 | 5 | from chia_rs.sized_ints import uint16 6 | 7 | from chia.protocols.shared_protocol import Capability 8 | 9 | 10 | def known_active_capabilities(values: Iterable[tuple[uint16, str]]) -> list[Capability]: 11 | # NOTE: order is not guaranteed 12 | # TODO: what if there's a claim for both supporting and not? 13 | # presently it considers it supported 14 | filtered: set[Capability] = set() 15 | for value, state in values: 16 | if state != "1": 17 | continue 18 | 19 | try: 20 | filtered.add(Capability(value)) 21 | except ValueError: 22 | pass 23 | 24 | # TODO: consider changing all uses to sets instead of lists 25 | return list(filtered) 26 | -------------------------------------------------------------------------------- /chia/server/ssl_context.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path 4 | from typing import Any 5 | 6 | 7 | def public_ssl_paths(path: Path, config: dict[str, Any]) -> tuple[Path, Path]: 8 | return ( 9 | path / config["ssl"]["public_crt"], 10 | path / config["ssl"]["public_key"], 11 | ) 12 | 13 | 14 | def private_ssl_paths(path: Path, config: dict[str, Any]) -> tuple[Path, Path]: 15 | return ( 16 | path / config["ssl"]["private_crt"], 17 | path / config["ssl"]["private_key"], 18 | ) 19 | 20 | 21 | def private_ssl_ca_paths(path: Path, config: dict[str, Any]) -> tuple[Path, Path]: 22 | return ( 23 | path / config["private_ssl_ca"]["crt"], 24 | path / config["private_ssl_ca"]["key"], 25 | ) 26 | 27 | 28 | def chia_ssl_ca_paths(path: Path, config: dict[str, Any]) -> tuple[Path, Path]: 29 | return ( 30 | path / config["chia_ssl_ca"]["crt"], 31 | path / config["chia_ssl_ca"]["key"], 32 | ) 33 | -------------------------------------------------------------------------------- /chia/simulator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/simulator/__init__.py -------------------------------------------------------------------------------- /chia/simulator/simulator_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from chia_rs.sized_bytes import bytes32 7 | from chia_rs.sized_ints import uint32 8 | 9 | from chia.util.streamable import Streamable, streamable 10 | 11 | 12 | @streamable 13 | @dataclass(frozen=True) 14 | class FarmNewBlockProtocol(Streamable): 15 | puzzle_hash: bytes32 16 | 17 | 18 | @streamable 19 | @dataclass(frozen=True) 20 | class ReorgProtocol(Streamable): 21 | old_index: uint32 22 | new_index: uint32 23 | puzzle_hash: bytes32 24 | seed: Optional[bytes32] 25 | 26 | 27 | @streamable 28 | @dataclass(frozen=True) 29 | class GetAllCoinsProtocol(Streamable): 30 | include_spent_coins: bool 31 | -------------------------------------------------------------------------------- /chia/simulator/socket.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import socket 4 | from contextlib import closing 5 | 6 | recent_ports: set[int] = set() 7 | 8 | 9 | def find_available_listen_port(name: str = "free") -> int: 10 | while True: 11 | with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: 12 | try: 13 | s.bind(("", 0)) 14 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 15 | port = s.getsockname()[1] 16 | except OSError: 17 | continue 18 | 19 | if port in recent_ports: 20 | continue 21 | 22 | recent_ports.add(port) 23 | print(f"{name} port: {port}") 24 | return port # type: ignore 25 | -------------------------------------------------------------------------------- /chia/simulator/vdf_prover.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs import ConsensusConstants 4 | from chia_rs.sized_bytes import bytes32 5 | from chia_rs.sized_ints import uint8, uint64 6 | from chiavdf import prove 7 | 8 | from chia.types.blockchain_format.classgroup import ClassgroupElement 9 | from chia.types.blockchain_format.vdf import VDFInfo, VDFProof 10 | 11 | 12 | def get_vdf_info_and_proof( 13 | constants: ConsensusConstants, 14 | vdf_input: ClassgroupElement, 15 | challenge_hash: bytes32, 16 | number_iters: uint64, 17 | normalized_to_identity: bool = False, 18 | ) -> tuple[VDFInfo, VDFProof]: 19 | form_size = ClassgroupElement.get_size() 20 | result: bytes = prove( 21 | bytes(challenge_hash), 22 | vdf_input.data, 23 | constants.DISCRIMINANT_SIZE_BITS, 24 | number_iters, 25 | "", 26 | ) 27 | 28 | output = ClassgroupElement.create(result[:form_size]) 29 | proof_bytes = result[form_size : 2 * form_size] 30 | return VDFInfo(challenge_hash, number_iters, output), VDFProof(uint8(0), proof_bytes, normalized_to_identity) 31 | -------------------------------------------------------------------------------- /chia/ssl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/ssl/__init__.py -------------------------------------------------------------------------------- /chia/ssl/chia_ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDKTCCAhGgAwIBAgIUXIpxI5MoZQ65/vhc7DK/d5ymoMUwDQYJKoZIhvcNAQEL 3 | BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY 4 | T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIxMDEyMzA4NTEwNloXDTMxMDEy 5 | MTA4NTEwNlowRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8G 6 | A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF 7 | AAOCAQ8AMIIBCgKCAQEAzz/L219Zjb5CIKnUkpd2julGC+j3E97KUiuOalCH9wdq 8 | gpJi9nBqLccwPCSFXFew6CNBIBM+CW2jT3UVwgzjdXJ7pgtu8gWj0NQ6NqSLiXV2 9 | WbpZovfrVh3x7Z4bjPgI3ouWjyehUfmK1GPIld4BfUSQtPlUJ53+XT32GRizUy+b 10 | 0CcJ84jp1XvyZAMajYnclFRNNJSw9WXtTlMUu+Z1M4K7c4ZPwEqgEnCgRc0TCaXj 11 | 180vo7mCHJQoDiNSCRATwfH+kWxOOK/nePkq2t4mPSFaX8xAS4yILISIOWYn7sNg 12 | dy9D6gGNFo2SZ0FR3x9hjUjYEV3cPqg3BmNE3DDynQIDAQABoxMwETAPBgNVHRMB 13 | Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAEugnFQjzHhS0eeCqUwOHmP3ww 14 | /rXPkKF+bJ6uiQgXZl+B5W3m3zaKimJeyatmuN+5ST1gUET+boMhbA/7grXAsRsk 15 | SFTHG0T9CWfPiuimVmGCzoxLGpWDMJcHZncpQZ72dcy3h7mjWS+U59uyRVHeiprE 16 | hvSyoNSYmfvh7vplRKS1wYeA119LL5fRXvOQNW6pSsts17auu38HWQGagSIAd1UP 17 | 5zEvDS1HgvaU1E09hlHzlpdSdNkAx7si0DMzxKHUg9oXeRZedt6kcfyEmryd52Mj 18 | 1r1R9mf4iMIUv1zc2sHVc1omxnCw9+7U4GMWLtL5OgyJyfNyoxk3tC+D3KNU 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /chia/ssl/dst_root_ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ 3 | MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT 4 | DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow 5 | PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD 6 | Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 7 | AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O 8 | rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq 9 | OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b 10 | xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw 11 | 7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD 12 | aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV 13 | HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG 14 | SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 15 | ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr 16 | AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz 17 | R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 18 | JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo 19 | Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /chia/timelord/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/timelord/__init__.py -------------------------------------------------------------------------------- /chia/timelord/types.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from enum import Enum 4 | 5 | 6 | class Chain(Enum): 7 | CHALLENGE_CHAIN = 1 8 | REWARD_CHAIN = 2 9 | INFUSED_CHALLENGE_CHAIN = 3 10 | BLUEBOX = 4 11 | 12 | 13 | class IterationType(Enum): 14 | SIGNAGE_POINT = 1 15 | INFUSION_POINT = 2 16 | END_OF_SUBSLOT = 3 17 | 18 | 19 | class StateType(Enum): 20 | PEAK = 1 21 | END_OF_SUB_SLOT = 2 22 | FIRST_SUB_SLOT = 3 23 | -------------------------------------------------------------------------------- /chia/types/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/types/__init__.py -------------------------------------------------------------------------------- /chia/types/block_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Optional 4 | 5 | from chia_rs.sized_bytes import bytes32 6 | from chia_rs.sized_ints import uint32 7 | from typing_extensions import Protocol 8 | 9 | from chia.types.blockchain_format.serialized_program import SerializedProgram 10 | 11 | 12 | class BlockInfo(Protocol): 13 | @property 14 | def prev_header_hash(self) -> bytes32: ... 15 | 16 | @property 17 | def transactions_generator(self) -> Optional[SerializedProgram]: ... 18 | 19 | @property 20 | def transactions_generator_ref_list(self) -> list[uint32]: ... 21 | -------------------------------------------------------------------------------- /chia/types/blockchain_format/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/types/blockchain_format/__init__.py -------------------------------------------------------------------------------- /chia/types/blockchain_format/classgroup.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs import ClassgroupElement 4 | 5 | __all__ = ["ClassgroupElement"] 6 | -------------------------------------------------------------------------------- /chia/types/blockchain_format/coin.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Union 4 | 5 | from chia_rs import Coin 6 | from chia_rs.sized_bytes import bytes32 7 | from chia_rs.sized_ints import uint64 8 | 9 | from chia.util.hash import std_hash 10 | 11 | __all__ = ["Coin", "coin_as_list", "hash_coin_ids"] 12 | 13 | 14 | def coin_as_list(c: Coin) -> list[Union[bytes32, uint64]]: 15 | return [c.parent_coin_info, c.puzzle_hash, uint64(c.amount)] 16 | 17 | 18 | def hash_coin_ids(coin_ids: list[bytes32]) -> bytes32: 19 | if len(coin_ids) == 1: 20 | return std_hash(coin_ids[0]) 21 | 22 | coin_ids.sort(reverse=True) 23 | buffer = bytearray() 24 | 25 | for name in coin_ids: 26 | buffer.extend(name) 27 | 28 | return std_hash(buffer, skip_bytes_conversion=True) 29 | -------------------------------------------------------------------------------- /chia/types/blockchain_format/serialized_program.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import chia_rs 4 | 5 | SerializedProgram = chia_rs.Program 6 | -------------------------------------------------------------------------------- /chia/types/clvm_cost.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import NewType 4 | 5 | from chia_rs.sized_ints import uint64 6 | 7 | """ 8 | CLVM Cost is the cost to run a CLVM program on the CLVM. 9 | It is similar to transaction bytes in the Bitcoin, but some operations 10 | are charged a higher rate, depending on their arguments. 11 | """ 12 | 13 | CLVMCost = NewType("CLVMCost", uint64) 14 | -------------------------------------------------------------------------------- /chia/types/coin_record.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from chia_rs import CoinState 7 | from chia_rs.sized_bytes import bytes32 8 | from chia_rs.sized_ints import uint32, uint64 9 | 10 | from chia.types.blockchain_format.coin import Coin 11 | from chia.util.streamable import Streamable, streamable 12 | 13 | 14 | @streamable 15 | @dataclass(frozen=True) 16 | class CoinRecord(Streamable): 17 | """ 18 | These are values that correspond to a CoinName that are used 19 | in keeping track of the unspent database. 20 | """ 21 | 22 | coin: Coin 23 | confirmed_block_index: uint32 24 | spent_block_index: uint32 25 | coinbase: bool 26 | timestamp: uint64 # Timestamp of the block at height confirmed_block_index 27 | 28 | @property 29 | def spent(self) -> bool: 30 | return self.spent_block_index > 0 31 | 32 | @property 33 | def name(self) -> bytes32: 34 | return self.coin.name() 35 | 36 | @property 37 | def coin_state(self) -> CoinState: 38 | spent_h = None 39 | if self.spent: 40 | spent_h = self.spent_block_index 41 | confirmed_height: Optional[uint32] = self.confirmed_block_index 42 | if self.confirmed_block_index == 0 and self.timestamp == 0: 43 | confirmed_height = None 44 | return CoinState(self.coin, spent_h, confirmed_height) 45 | -------------------------------------------------------------------------------- /chia/types/condition_with_args.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from chia.types.condition_opcodes import ConditionOpcode 6 | 7 | 8 | @dataclass(frozen=True) 9 | class ConditionWithArgs: 10 | """ 11 | This structure is used to store parsed CLVM conditions 12 | Conditions in CLVM have either format of (opcode, var1) or (opcode, var1, var2) 13 | """ 14 | 15 | opcode: ConditionOpcode 16 | vars: list[bytes] 17 | -------------------------------------------------------------------------------- /chia/types/fee_rate.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import math 4 | from dataclasses import dataclass 5 | 6 | import typing_extensions 7 | from chia_rs.sized_ints import uint64 8 | 9 | from chia.types.clvm_cost import CLVMCost 10 | from chia.types.mojos import Mojos 11 | from chia.util.streamable import Streamable, streamable 12 | 13 | 14 | @typing_extensions.final 15 | @streamable 16 | @dataclass(frozen=True) 17 | class FeeRate(Streamable): 18 | """ 19 | Represents Fee Rate in mojos divided by CLVM Cost. 20 | Performs XCH/mojo conversion. 21 | Similar to 'Fee per cost'. 22 | """ 23 | 24 | mojos_per_clvm_cost: uint64 25 | 26 | @classmethod 27 | def create(cls, mojos: Mojos, clvm_cost: CLVMCost) -> FeeRate: 28 | return cls(uint64(math.ceil(mojos / clvm_cost))) 29 | 30 | 31 | @dataclass(frozen=True) 32 | class FeeRateV2: 33 | """ 34 | Represents Fee Rate in mojos divided by CLVM Cost. 35 | Similar to 'Fee per cost'. 36 | """ 37 | 38 | mojos_per_clvm_cost: float 39 | -------------------------------------------------------------------------------- /chia/types/internal_mempool_item.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from chia_rs import SpendBundle, SpendBundleConditions 6 | from chia_rs.sized_bytes import bytes32 7 | from chia_rs.sized_ints import uint32 8 | 9 | from chia.types.mempool_item import BundleCoinSpend 10 | 11 | 12 | @dataclass(frozen=True) 13 | class InternalMempoolItem: 14 | spend_bundle: SpendBundle 15 | conds: SpendBundleConditions 16 | height_added_to_mempool: uint32 17 | # Map of coin ID to coin spend data between the bundle and its NPCResult 18 | bundle_coin_spends: dict[bytes32, BundleCoinSpend] 19 | -------------------------------------------------------------------------------- /chia/types/mempool_inclusion_status.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from enum import IntEnum 4 | 5 | 6 | class MempoolInclusionStatus(IntEnum): 7 | SUCCESS = 1 # Transaction added to mempool 8 | PENDING = 2 # Transaction not yet added to mempool 9 | FAILED = 3 # Transaction was invalid and dropped 10 | -------------------------------------------------------------------------------- /chia/types/mempool_submission_status.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional, Union 5 | 6 | from chia_rs.sized_ints import uint8 7 | 8 | from chia.types.mempool_inclusion_status import MempoolInclusionStatus 9 | from chia.util.streamable import Streamable, streamable 10 | 11 | 12 | @streamable 13 | @dataclass(frozen=True) 14 | class MempoolSubmissionStatus(Streamable): 15 | """ 16 | :sent_to: in `TradeRecord` and `TransactionRecord` are a 17 | Tuple of (peer_id: str, status: MempoolInclusionStatus, error: Optional[str]) 18 | MempoolInclusionStatus is represented as a uint8 in those structs so they can be `Streamable` 19 | """ 20 | 21 | peer_id: str 22 | inclusion_status: uint8 # MempoolInclusionStatus 23 | error_msg: Optional[str] 24 | 25 | def to_json_dict_convenience(self) -> dict[str, Union[str, MempoolInclusionStatus, Optional[str]]]: 26 | formatted = self.to_json_dict() 27 | formatted["inclusion_status"] = MempoolInclusionStatus(self.inclusion_status).name 28 | return formatted 29 | 30 | def __str__(self) -> str: 31 | return f"{self.to_json_dict_convenience()}" 32 | -------------------------------------------------------------------------------- /chia/types/mojos.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import NewType 4 | 5 | from chia_rs.sized_ints import uint64 6 | 7 | Mojos = NewType("Mojos", uint64) 8 | -------------------------------------------------------------------------------- /chia/types/validation_state.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import dataclasses 4 | from typing import Optional 5 | 6 | from chia_rs import BlockRecord 7 | from chia_rs.sized_ints import uint64 8 | 9 | 10 | @dataclasses.dataclass 11 | class ValidationState: 12 | ssi: uint64 13 | difficulty: uint64 14 | prev_ses_block: Optional[BlockRecord] = None 15 | -------------------------------------------------------------------------------- /chia/types/weight_proof.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from chia_rs import EndOfSubSlotBundle, HeaderBlock, RewardChainBlock, SubEpochChallengeSegment, SubEpochData 6 | 7 | from chia.util.streamable import Streamable, streamable 8 | 9 | # number of challenge blocks 10 | # Average iters for challenge blocks 11 | # |--A-R----R-------R--------R------R----R----------R-----R--R---| Honest difficulty 1000 12 | # 0.16 13 | 14 | # compute total reward chain blocks 15 | # |----------------------------A---------------------------------| Attackers chain 1000 16 | # 0.48 17 | # total number of challenge blocks == total number of reward chain blocks 18 | 19 | 20 | @streamable 21 | @dataclass(frozen=True) 22 | # this is used only for serialization to database 23 | class RecentChainData(Streamable): 24 | recent_chain_data: list[HeaderBlock] 25 | 26 | 27 | @streamable 28 | @dataclass(frozen=True) 29 | class ProofBlockHeader(Streamable): 30 | finished_sub_slots: list[EndOfSubSlotBundle] 31 | reward_chain_block: RewardChainBlock 32 | 33 | 34 | @streamable 35 | @dataclass(frozen=True) 36 | class WeightProof(Streamable): 37 | sub_epochs: list[SubEpochData] 38 | sub_epoch_segments: list[SubEpochChallengeSegment] # sampled sub epoch 39 | recent_chain_data: list[HeaderBlock] 40 | -------------------------------------------------------------------------------- /chia/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/util/__init__.py -------------------------------------------------------------------------------- /chia/util/batches.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | from collections.abc import Collection, Iterator 6 | from dataclasses import dataclass 7 | from typing import Generic, TypeVar 8 | 9 | T = TypeVar("T") 10 | 11 | 12 | @dataclass(frozen=True) 13 | class Batch(Generic[T]): 14 | remaining: int 15 | entries: list[T] 16 | 17 | 18 | def to_batches(to_split: Collection[T], batch_size: int) -> Iterator[Batch[T]]: 19 | if batch_size <= 0: 20 | raise ValueError("to_batches: batch_size must be greater than 0.") 21 | total_size = len(to_split) 22 | if total_size == 0: 23 | return 24 | 25 | if isinstance(to_split, list): 26 | for batch_start in range(0, total_size, batch_size): 27 | batch_end = min(batch_start + batch_size, total_size) 28 | yield Batch(total_size - batch_end, to_split[batch_start:batch_end]) 29 | elif isinstance(to_split, set): 30 | processed = 0 31 | entries = [] 32 | for entry in to_split: 33 | entries.append(entry) 34 | if len(entries) >= batch_size: 35 | processed += len(entries) 36 | yield Batch(total_size - processed, entries) 37 | entries = [] 38 | if len(entries) > 0: 39 | processed += len(entries) 40 | yield Batch(total_size - processed, entries) 41 | else: 42 | raise ValueError(f"to_batches: Unsupported type {type(to_split)}") 43 | -------------------------------------------------------------------------------- /chia/util/byte_types.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | 6 | def hexstr_to_bytes(input_str: str) -> bytes: 7 | """ 8 | Converts a hex string into bytes, removing the 0x if it's present. 9 | """ 10 | if input_str.startswith("0x") or input_str.startswith("0X"): 11 | return bytes.fromhex(input_str[2:]) 12 | return bytes.fromhex(input_str) 13 | -------------------------------------------------------------------------------- /chia/util/chia_version.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from re import search 4 | from typing import Union 5 | 6 | from packaging.version import InvalidVersion, Version 7 | 8 | from chia import __version__ 9 | 10 | 11 | def _chia_short_version_from_version(version: Version) -> str: 12 | release_version_str = f"{version.major}.{version.minor}.{version.micro}" 13 | 14 | return release_version_str if version.pre is None else release_version_str + "".join(map(str, version.pre)) 15 | 16 | 17 | def _chia_short_version_from_str(version: str) -> str: 18 | try: 19 | return chia_short_version(Version(version)) 20 | except InvalidVersion: 21 | pass 22 | match = search(r"^(\d+\.\d+\.\d+)", version) 23 | if match is not None: 24 | return match.group(1) 25 | 26 | return version 27 | 28 | 29 | def chia_short_version(version: Union[str, Version] = __version__) -> str: 30 | if isinstance(version, Version): 31 | return _chia_short_version_from_version(version) 32 | 33 | return _chia_short_version_from_str(version) 34 | -------------------------------------------------------------------------------- /chia/util/collection.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | # Utility Functions for Collections & Sequences 6 | 7 | 8 | def find_duplicates(array: list[int]) -> set[int]: 9 | seen = set() 10 | duplicates = set() 11 | 12 | for i in array: 13 | if i in seen: 14 | duplicates.add(i) 15 | seen.add(i) 16 | 17 | return duplicates 18 | -------------------------------------------------------------------------------- /chia/util/cpu.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import os 6 | import sys 7 | 8 | import psutil 9 | 10 | 11 | def available_logical_cores() -> int: 12 | if sys.platform == "darwin": 13 | count = os.cpu_count() 14 | assert count is not None 15 | return count 16 | 17 | cores = len(psutil.Process().cpu_affinity()) 18 | 19 | if sys.platform == "win32": 20 | cores = min(61, cores) # https://github.com/python/cpython/issues/89240 21 | 22 | return cores 23 | -------------------------------------------------------------------------------- /chia/util/db_synchronous.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | 6 | def db_synchronous_on(setting: str) -> str: 7 | if setting == "on": 8 | return "NORMAL" 9 | if setting == "off": 10 | return "OFF" 11 | if setting == "full": 12 | return "FULL" 13 | 14 | # for now, default to synchronous=NORMAL mode. This can be made more 15 | # sophisticated in the future. There are still material performance 16 | # improvements to be had in cases where the risks are low. 17 | 18 | # e.g. 19 | # type = GetDriveTypeW(db_path) 20 | # if type == DRIVE_FIXED or type == DRIVE_RAMDISK: 21 | # return "OFF" 22 | 23 | return "NORMAL" 24 | -------------------------------------------------------------------------------- /chia/util/db_version.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import sqlite3 6 | 7 | import aiosqlite 8 | 9 | 10 | async def lookup_db_version(db: aiosqlite.Connection) -> int: 11 | try: 12 | cursor = await db.execute("SELECT * from database_version") 13 | row = await cursor.fetchone() 14 | if row is not None and row[0] == 2: 15 | return 2 16 | else: 17 | return 1 18 | except aiosqlite.OperationalError: 19 | # expects OperationalError('no such table: database_version') 20 | return 1 21 | 22 | 23 | async def set_db_version_async(db: aiosqlite.Connection, version: int) -> None: 24 | await db.execute("CREATE TABLE database_version(version int)") 25 | await db.execute("INSERT INTO database_version VALUES (?)", (version,)) 26 | await db.commit() 27 | 28 | 29 | def set_db_version(db: sqlite3.Connection, version: int) -> None: 30 | db.execute("CREATE TABLE database_version(version int)") 31 | db.execute("INSERT INTO database_version VALUES (?)", (version,)) 32 | db.commit() 33 | -------------------------------------------------------------------------------- /chia/util/default_root.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import os 6 | from pathlib import Path 7 | from typing import Optional 8 | 9 | DEFAULT_ROOT_PATH = Path(os.path.expanduser(os.getenv("CHIA_ROOT", "~/.chia/mainnet"))).resolve() 10 | 11 | DEFAULT_KEYS_ROOT_PATH = Path(os.path.expanduser(os.getenv("CHIA_KEYS_ROOT", "~/.chia_keys"))).resolve() 12 | 13 | SIMULATOR_ROOT_PATH = Path(os.path.expanduser(os.getenv("CHIA_SIMULATOR_ROOT", "~/.chia/simulator"))).resolve() 14 | 15 | 16 | def resolve_root_path(*, override: Optional[Path]) -> Path: 17 | candidates = [ 18 | override, 19 | os.environ.get("CHIA_ROOT"), 20 | "~/.chia/mainnet", 21 | ] 22 | 23 | for candidate in candidates: 24 | if candidate is not None: 25 | return Path(candidate).expanduser().resolve() 26 | 27 | raise RuntimeError("unreachable: last candidate is hardcoded to be found") 28 | -------------------------------------------------------------------------------- /chia/util/hash.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | from hashlib import sha256 6 | from typing import Literal, SupportsBytes, Union, cast, overload 7 | 8 | from chia_rs.sized_bytes import bytes32 9 | 10 | 11 | @overload 12 | def std_hash(b: Union[bytes, SupportsBytes]) -> bytes32: ... 13 | 14 | 15 | @overload 16 | def std_hash(b: Union[bytes, SupportsBytes], skip_bytes_conversion: Literal[False]) -> bytes32: ... 17 | 18 | 19 | @overload 20 | def std_hash(b: bytes, skip_bytes_conversion: Literal[True]) -> bytes32: ... 21 | 22 | 23 | def std_hash(b: Union[bytes, SupportsBytes], skip_bytes_conversion: bool = False) -> bytes32: 24 | """ 25 | The standard hash used in many places. 26 | """ 27 | if skip_bytes_conversion: 28 | # casting for hinting based on above overloads constraining the type 29 | return bytes32(sha256(cast(bytes, b)).digest()) 30 | else: 31 | return bytes32(sha256(bytes(b)).digest()) 32 | -------------------------------------------------------------------------------- /chia/util/inline_executor.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | from concurrent.futures import Executor, Future 6 | from typing import Callable, TypeVar 7 | 8 | _T = TypeVar("_T") 9 | 10 | 11 | class InlineExecutor(Executor): 12 | _closing: bool = False 13 | 14 | def submit(self, fn: Callable[..., _T], *args, **kwargs) -> Future[_T]: # type: ignore 15 | if self._closing: 16 | raise RuntimeError("executor shutting down") 17 | 18 | f: Future[_T] = Future() 19 | try: 20 | f.set_result(fn(*args, **kwargs)) 21 | except BaseException as e: # lgtm[py/catch-base-exception] 22 | f.set_exception(e) 23 | return f 24 | 25 | def close(self) -> None: 26 | self._closing = True 27 | -------------------------------------------------------------------------------- /chia/util/ip_address.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from ipaddress import IPv4Address, IPv6Address, ip_address 5 | from typing import Union 6 | 7 | 8 | @dataclass(frozen=True) 9 | class IPAddress: 10 | _inner: Union[IPv4Address, IPv6Address] 11 | 12 | @classmethod 13 | def create(cls, ip: str) -> IPAddress: 14 | return cls(ip_address(ip)) 15 | 16 | def __int__(self) -> int: 17 | return int(self._inner) 18 | 19 | def __str__(self) -> str: 20 | return str(self._inner) 21 | 22 | def __repr__(self) -> str: 23 | return repr(self._inner) 24 | 25 | @property 26 | def packed(self) -> bytes: 27 | return self._inner.packed 28 | 29 | @property 30 | def is_private(self) -> bool: 31 | return self._inner.is_private 32 | 33 | @property 34 | def is_v4(self) -> bool: 35 | return self._inner.version == 4 36 | 37 | @property 38 | def is_v6(self) -> bool: 39 | return self._inner.version == 6 40 | -------------------------------------------------------------------------------- /chia/util/json_util.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import json 4 | from typing import Any 5 | 6 | from aiohttp import web 7 | 8 | 9 | class EnhancedJSONEncoder(json.JSONEncoder): 10 | """ 11 | Encodes bytes as hex strings with 0x, and converts all dataclasses to json. 12 | """ 13 | 14 | def default(self, o: Any) -> Any: 15 | if hasattr(type(o), "to_json_dict"): 16 | return o.to_json_dict() 17 | elif hasattr(type(o), "__bytes__"): 18 | return f"0x{bytes(o).hex()}" 19 | elif isinstance(o, bytes): 20 | return f"0x{o.hex()}" 21 | return super().default(o) 22 | 23 | 24 | def dict_to_json_str(o: Any) -> str: 25 | """ 26 | Converts a python object into json. 27 | """ 28 | json_str = json.dumps(o, cls=EnhancedJSONEncoder, sort_keys=True) 29 | return json_str 30 | 31 | 32 | def obj_to_response(o: Any) -> web.Response: 33 | """ 34 | Converts a python object into json. Used for RPC server which returns JSON. 35 | """ 36 | json_str = dict_to_json_str(o) 37 | return web.Response(body=json_str, content_type="application/json") 38 | -------------------------------------------------------------------------------- /chia/util/limited_semaphore.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import asyncio 6 | import contextlib 7 | from collections.abc import AsyncIterator 8 | from dataclasses import dataclass 9 | 10 | from typing_extensions import final 11 | 12 | 13 | class LimitedSemaphoreFullError(Exception): 14 | def __init__(self) -> None: 15 | super().__init__("no waiting slot available") 16 | 17 | 18 | @final 19 | @dataclass 20 | class LimitedSemaphore: 21 | _semaphore: asyncio.Semaphore 22 | _available_count: int 23 | 24 | @classmethod 25 | def create(cls, active_limit: int, waiting_limit: int) -> LimitedSemaphore: 26 | return cls( 27 | _semaphore=asyncio.Semaphore(active_limit), 28 | _available_count=active_limit + waiting_limit, 29 | ) 30 | 31 | @contextlib.asynccontextmanager 32 | async def acquire(self) -> AsyncIterator[int]: 33 | if self._available_count < 1: 34 | raise LimitedSemaphoreFullError() 35 | 36 | self._available_count -= 1 37 | try: 38 | async with self._semaphore: 39 | yield self._available_count 40 | finally: 41 | self._available_count += 1 42 | -------------------------------------------------------------------------------- /chia/util/log_exceptions.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import logging 6 | import traceback 7 | from collections.abc import Iterator 8 | from contextlib import contextmanager 9 | from typing import Union 10 | 11 | 12 | @contextmanager 13 | def log_exceptions( 14 | log: logging.Logger, 15 | *, 16 | consume: bool = False, 17 | message: str = "Caught exception", 18 | level: int = logging.ERROR, 19 | show_traceback: bool = True, 20 | exceptions_to_process: Union[type[BaseException], tuple[type[BaseException], ...]] = Exception, 21 | ) -> Iterator[None]: 22 | try: 23 | yield 24 | except exceptions_to_process as e: 25 | message = f"{message}: {type(e).__name__}: {e}" 26 | if show_traceback: 27 | message += f"\n{traceback.format_exc()}" 28 | 29 | log.log(level, message) 30 | 31 | if not consume: 32 | raise 33 | -------------------------------------------------------------------------------- /chia/util/logging.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import logging 6 | import re 7 | import time 8 | from re import Pattern 9 | 10 | 11 | class TimedDuplicateFilter(logging.Filter): 12 | last_log_time: float 13 | regex: Pattern[str] 14 | min_time_wait_secs: int 15 | 16 | def __init__(self, regex_str: str, min_time_wait_secs: int, name: str = ""): 17 | super().__init__(name) 18 | self.last_log_time = time.monotonic() 19 | self.regex = re.compile(regex_str) 20 | self.min_time_wait_secs = min_time_wait_secs 21 | 22 | def filter(self, record: logging.LogRecord) -> bool: 23 | _ = super().filter(record) 24 | if not _: 25 | return False 26 | 27 | msg = record.getMessage() 28 | 29 | if self.regex.match(msg): 30 | now = time.monotonic() 31 | if now - self.last_log_time > self.min_time_wait_secs: 32 | self.last_log_time = now 33 | return True 34 | return False 35 | else: 36 | return True 37 | -------------------------------------------------------------------------------- /chia/util/lru_cache.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | from collections import OrderedDict 6 | from typing import Generic, Optional, TypeVar 7 | 8 | K = TypeVar("K") 9 | V = TypeVar("V") 10 | 11 | 12 | class LRUCache(Generic[K, V]): 13 | def __init__(self, capacity: int): 14 | self.cache: OrderedDict[K, V] = OrderedDict() 15 | self.capacity = capacity 16 | 17 | def get(self, key: K) -> Optional[V]: 18 | if key not in self.cache: 19 | return None 20 | else: 21 | self.cache.move_to_end(key) 22 | return self.cache[key] 23 | 24 | def put(self, key: K, value: V) -> None: 25 | self.cache[key] = value 26 | self.cache.move_to_end(key) 27 | if len(self.cache) > self.capacity: 28 | self.cache.popitem(last=False) 29 | 30 | def remove(self, key: K) -> None: 31 | self.cache.pop(key) 32 | -------------------------------------------------------------------------------- /chia/util/math.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | 6 | def clamp(n: int, smallest: int, largest: int) -> int: 7 | return max(smallest, min(n, largest)) 8 | 9 | 10 | def make_monotonically_decreasing(seq: list[float]) -> list[float]: 11 | out: list[float] = [] 12 | if len(seq) > 0: 13 | min = seq[0] 14 | for n in seq: 15 | if n <= min: 16 | out.append(n) 17 | min = n 18 | else: 19 | out.append(min) 20 | return out 21 | -------------------------------------------------------------------------------- /chia/util/path.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import os 6 | from pathlib import Path 7 | from typing import Union 8 | 9 | 10 | def path_from_root(root: Path, path_str: Union[str, Path]) -> Path: 11 | """ 12 | If path is relative, prepend root 13 | If path is absolute, return it directly. 14 | """ 15 | root = Path(os.path.expanduser(str(root))) 16 | path = Path(path_str) 17 | if not path.is_absolute(): 18 | path = root / path 19 | return path.resolve() 20 | 21 | 22 | def make_path_relative(path_str: Union[str, Path], root: Path) -> Path: 23 | """ 24 | Try to make the given path relative, given the default root. 25 | """ 26 | path = Path(path_str) 27 | try: 28 | path = path.relative_to(root) 29 | except ValueError: 30 | pass 31 | return path 32 | -------------------------------------------------------------------------------- /chia/util/permissions.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import os 6 | from pathlib import Path 7 | 8 | 9 | def verify_file_permissions(path: Path, mask: int) -> tuple[bool, int]: 10 | """ 11 | Check that the file's permissions are properly restricted, as compared to the 12 | permission mask 13 | """ 14 | mode = os.stat(path).st_mode & 0o777 15 | return (mode & mask == 0, mode) 16 | 17 | 18 | def octal_mode_string(mode: int) -> str: 19 | """Yields a permission mode string: e.g. 0644""" 20 | return f"0{oct(mode)[-3:]}" 21 | -------------------------------------------------------------------------------- /chia/util/recursive_replace.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | from dataclasses import replace 6 | from typing import Any 7 | 8 | 9 | def recursive_replace(root_obj: Any, replace_str: str, replace_with: Any) -> Any: 10 | split_str = replace_str.split(".") 11 | if len(split_str) == 1: 12 | # This check is here to support native types (implemented in Rust 13 | # in chia_rs) that aren't dataclasses. They instead implement a 14 | # replace() method in their python bindings. 15 | if hasattr(root_obj, "replace"): 16 | return root_obj.replace(**{split_str[0]: replace_with}) 17 | else: 18 | return replace(root_obj, **{split_str[0]: replace_with}) 19 | sub_obj = recursive_replace(getattr(root_obj, split_str[0]), ".".join(split_str[1:]), replace_with) 20 | # See comment above 21 | if hasattr(root_obj, "replace"): 22 | return root_obj.replace(**{split_str[0]: sub_obj}) 23 | else: 24 | return replace(root_obj, **{split_str[0]: sub_obj}) 25 | -------------------------------------------------------------------------------- /chia/util/safe_cancel_task.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | import asyncio 6 | import logging 7 | from typing import Optional 8 | 9 | 10 | def cancel_task_safe(task: Optional[asyncio.Task[None]], log: Optional[logging.Logger] = None) -> None: 11 | if task is not None: 12 | try: 13 | task.cancel() 14 | except Exception as e: 15 | if log is not None: 16 | log.error(f"Error while canceling task.{e} {task}") 17 | -------------------------------------------------------------------------------- /chia/util/setproctitle.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | try: 6 | import setproctitle as pysetproctitle 7 | 8 | no_setproctitle = False 9 | except Exception: 10 | no_setproctitle = True 11 | 12 | 13 | def setproctitle(ps_name: str) -> None: 14 | if no_setproctitle is False: 15 | pysetproctitle.setproctitle(ps_name) 16 | 17 | 18 | def getproctitle() -> str: 19 | if no_setproctitle is False: 20 | return pysetproctitle.getproctitle() 21 | 22 | return "" 23 | -------------------------------------------------------------------------------- /chia/util/significant_bits.py: -------------------------------------------------------------------------------- 1 | # Package: utils 2 | 3 | from __future__ import annotations 4 | 5 | 6 | def truncate_to_significant_bits(input_x: int, num_significant_bits: int) -> int: 7 | """ 8 | Truncates the number such that only the top num_significant_bits contain 1s. 9 | and the rest of the number is 0s (in binary). Ignores decimals and leading 10 | zeroes. For example, -0b011110101 and 2, returns -0b11000000. 11 | """ 12 | x = abs(input_x) 13 | if num_significant_bits > x.bit_length(): 14 | return input_x 15 | lower = x.bit_length() - num_significant_bits 16 | mask = (1 << (x.bit_length())) - 1 - ((1 << lower) - 1) 17 | if input_x < 0: 18 | return -(x & mask) 19 | else: 20 | return x & mask 21 | 22 | 23 | def count_significant_bits(input_x: int) -> int: 24 | """ 25 | Counts the number of significant bits of an integer, ignoring negative signs 26 | and leading zeroes. For example, for -0b000110010000, returns 5. 27 | """ 28 | x = input_x 29 | for i in range(x.bit_length()): 30 | if x & (1 << i) > 0: 31 | return x.bit_length() - i 32 | return 0 33 | -------------------------------------------------------------------------------- /chia/wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/__init__.py -------------------------------------------------------------------------------- /chia/wallet/cat_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/cat_wallet/__init__.py -------------------------------------------------------------------------------- /chia/wallet/db_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/db_wallet/__init__.py -------------------------------------------------------------------------------- /chia/wallet/did_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/did_wallet/__init__.py -------------------------------------------------------------------------------- /chia/wallet/driver_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Optional 4 | 5 | from chia_rs.sized_bytes import bytes32 6 | from typing_extensions import Protocol 7 | 8 | from chia.types.blockchain_format.program import Program 9 | from chia.wallet.puzzle_drivers import PuzzleInfo, Solver 10 | from chia.wallet.uncurried_puzzle import UncurriedPuzzle 11 | 12 | 13 | class DriverProtocol(Protocol): 14 | def match(self, puzzle: UncurriedPuzzle) -> Optional[PuzzleInfo]: ... 15 | 16 | def get_inner_puzzle(self, constructor: PuzzleInfo, puzzle_reveal: UncurriedPuzzle) -> Optional[Program]: ... 17 | 18 | def get_inner_solution(self, constructor: PuzzleInfo, solution: Program) -> Optional[Program]: ... 19 | 20 | def asset_id(self, constructor: PuzzleInfo) -> Optional[bytes32]: ... 21 | 22 | def construct(self, constructor: PuzzleInfo, inner_puzzle: Program) -> Program: ... 23 | 24 | def solve( 25 | self, constructor: PuzzleInfo, solver: Solver, inner_puzzle: Program, inner_solution: Program 26 | ) -> Program: ... 27 | -------------------------------------------------------------------------------- /chia/wallet/estimate_fees.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs import SpendBundle 4 | 5 | from chia.consensus.default_constants import DEFAULT_CONSTANTS 6 | from chia.util.errors import Err, ValidationError 7 | from chia.wallet.util.compute_additions import compute_additions_with_cost 8 | 9 | 10 | # This function executes all the puzzles to compute the difference between 11 | # additions and removals 12 | def estimate_fees(spend_bundle: SpendBundle) -> int: 13 | """Unsafe to use for fees validation!!!""" 14 | removed_amount = 0 15 | added_amount = 0 16 | max_cost = int(DEFAULT_CONSTANTS.MAX_BLOCK_COST_CLVM) 17 | for cs in spend_bundle.coin_spends: 18 | removed_amount += cs.coin.amount 19 | coins, cost = compute_additions_with_cost(cs, max_cost=max_cost) 20 | max_cost -= cost 21 | if max_cost < 0: 22 | raise ValidationError(Err.BLOCK_COST_EXCEEDS_MAX, "estimate_fees() for SpendBundle") 23 | for c in coins: 24 | added_amount += c.amount 25 | return removed_amount - added_amount 26 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/nft_wallet/__init__.py -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/nft_puzzles.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_puzzles_py.programs import ( 4 | NFT_INTERMEDIATE_LAUNCHER, 5 | NFT_METADATA_UPDATER_DEFAULT, 6 | NFT_METADATA_UPDATER_DEFAULT_HASH, 7 | NFT_OWNERSHIP_TRANSFER_PROGRAM_ONE_WAY_CLAIM_WITH_ROYALTIES, 8 | NFT_STATE_LAYER, 9 | NFT_STATE_LAYER_HASH, 10 | ) 11 | from chia_puzzles_py.programs import ( 12 | NFT_OWNERSHIP_LAYER as NFT_OWNERSHIP_LAYER_BYTES, 13 | ) 14 | from chia_puzzles_py.programs import ( 15 | NFT_OWNERSHIP_LAYER_HASH as NFT_OWNERSHIP_LAYER_HASH_BYTES, 16 | ) 17 | from chia_rs.sized_bytes import bytes32 18 | 19 | from chia.types.blockchain_format.program import Program 20 | 21 | NFT_STATE_LAYER_MOD = Program.from_bytes(NFT_STATE_LAYER) 22 | NFT_STATE_LAYER_MOD_HASH = bytes32(NFT_STATE_LAYER_HASH) 23 | NFT_METADATA_UPDATER = Program.from_bytes(NFT_METADATA_UPDATER_DEFAULT) 24 | NFT_METADATA_UPDATER_HASH = bytes32(NFT_METADATA_UPDATER_DEFAULT_HASH) 25 | NFT_OWNERSHIP_LAYER = Program.from_bytes(NFT_OWNERSHIP_LAYER_BYTES) 26 | NFT_OWNERSHIP_LAYER_HASH = bytes32(NFT_OWNERSHIP_LAYER_HASH_BYTES) 27 | NFT_TRANSFER_PROGRAM_DEFAULT = Program.from_bytes(NFT_OWNERSHIP_TRANSFER_PROGRAM_ONE_WAY_CLAIM_WITH_ROYALTIES) 28 | INTERMEDIATE_LAUNCHER_MOD = Program.from_bytes(NFT_INTERMEDIATE_LAUNCHER) 29 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/nft_wallet/puzzles/__init__.py -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp: -------------------------------------------------------------------------------- 1 | (mod (LAUNCHER_PH MINT_NUMBER MINT_TOTAL) 2 | (include condition_codes.clib) 3 | (list 4 | (list CREATE_COIN LAUNCHER_PH 1) 5 | (list CREATE_COIN_ANNOUNCEMENT (sha256 MINT_NUMBER MINT_TOTAL))) 6 | ) 7 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff01ff01808080ffff04ffff04ff06ffff04ffff0bff0bff1780ff808080ff808080ffff04ffff01ff333cff018080 2 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp: -------------------------------------------------------------------------------- 1 | (mod (LAUNCHER_PH MINT_NUMBER MINT_TOTAL) 2 | (include condition_codes.clib) 3 | (list 4 | (list CREATE_COIN LAUNCHER_PH 1) 5 | (list CREATE_COIN_ANNOUNCEMENT (sha256 MINT_NUMBER MINT_TOTAL))) 6 | ) 7 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff01ff01808080ffff04ffff04ff06ffff04ffff0bff0bff1780ff808080ff808080ffff04ffff01ff333cff018080 2 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp: -------------------------------------------------------------------------------- 1 | (mod (CURRENT_METADATA METADATA_UPDATER_PUZZLE_HASH (key . new_url)) 2 | 3 | ; METADATA and METADATA_UPDATER_PUZZLE_HASH are passed in as truths from the layer above 4 | ; This program returns ((new_metadata new_metadata_updater_puzhash) conditions) 5 | 6 | ; Add uri to a field 7 | (defun add_url (METADATA key new_url) 8 | (if METADATA 9 | (if (= (f (f METADATA)) key) 10 | (c (c key (c new_url (r (f METADATA)))) (r METADATA)) 11 | (c (f METADATA) (add_url (r METADATA) key new_url)) 12 | ) 13 | () 14 | ) 15 | ) 16 | ; main 17 | ; returns ((new_metadata new_metadata_updater_puzhash) conditions) 18 | (list 19 | (list 20 | (if (all key new_url) 21 | (if (any (= key "mu") (= key "lu") (= key "u")) 22 | (add_url CURRENT_METADATA key new_url) 23 | CURRENT_METADATA 24 | ) 25 | CURRENT_METADATA 26 | ) 27 | METADATA_UPDATER_PUZZLE_HASH) 28 | 0 29 | ) 30 | ) 31 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ffff02ffff03ffff22ff27ff3780ffff01ff02ffff03ffff21ffff09ff27ffff01826d7580ffff09ff27ffff01826c7580ffff09ff27ffff01758080ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ffff04ff37ff808080808080ffff010580ff0180ffff010580ff0180ffff04ff0bff808080ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09ff11ff0b80ffff01ff04ffff04ff0bffff04ff17ff198080ff0d80ffff01ff04ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bffff04ff17ff8080808080808080ff0180ff8080ff0180ff018080 2 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp: -------------------------------------------------------------------------------- 1 | (mod (CURRENT_METADATA METADATA_UPDATER_PUZZLE_HASH solution) 2 | 3 | ; solution is (new_url new_metadata_updater_puzhash) 4 | 5 | ; METADATA and METADATA_UPDATER_PUZZLE_HASH are passed in as truths from the layer above 6 | ; This program returns ((new_metadata new_metadata_updater_puzhash) conditions) 7 | 8 | ; NOTE THIS PROGRAM IS FOR TESTING ONLY - USE IN DEPLOYMENT AT YOUR OWN PERIL 9 | 10 | ; once we find 'u' we don't need to continue looping 11 | (defun add_url (METADATA new_url) 12 | (if METADATA 13 | (if (= (f (f METADATA)) 'u') 14 | (c (c 'u' (c new_url (r (f METADATA)))) (r METADATA)) 15 | (c (f METADATA) (add_url (r METADATA) new_url)) 16 | ) 17 | () 18 | ) 19 | ) 20 | 21 | (defun-inline assert_bytes32 (value) 22 | (= (strlen value) 32) 23 | ) 24 | 25 | ; main 26 | ; returns ((new_metadata new_metadata_updater_puzhash) conditions) 27 | (list (list (if (f solution) (add_url CURRENT_METADATA (f solution)) CURRENT_METADATA) (if (assert_bytes32 (f (r solution))) (f (r solution)) METADATA_UPDATER_PUZZLE_HASH)) 0) 28 | ) 29 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ffff02ffff03ff27ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ff8080808080ffff010580ff0180ffff04ffff02ffff03ffff09ffff0dff5780ffff012080ffff0157ffff010b80ff0180ff808080ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09ff11ffff017580ffff01ff04ffff04ffff0175ffff04ff0bff198080ff0d80ffff01ff04ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bff80808080808080ff0180ff8080ff0180ff018080 2 | -------------------------------------------------------------------------------- /chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ffff03ff81bfffff01ff04ff82013fffff04ff80ffff04ffff02ffff03ffff22ff82013fffff20ffff09ff82013fff2f808080ffff01ff04ffff04ff10ffff04ffff0bffff02ff2effff04ff02ffff04ff09ffff04ff8205bfffff04ffff02ff3effff04ff02ffff04ffff04ff09ffff04ff82013fff1d8080ff80808080ff808080808080ff1580ff808080ffff02ff16ffff04ff02ffff04ff0bffff04ff17ffff04ff8202bfffff04ff15ff8080808080808080ffff01ff02ff16ffff04ff02ffff04ff0bffff04ff17ffff04ff8202bfffff04ff15ff8080808080808080ff0180ff80808080ffff01ff04ff2fffff01ff80ff80808080ff0180ffff04ffff01ffffff3f02ff04ff0101ffff822710ff02ff02ffff03ff05ffff01ff02ff3affff04ff02ffff04ff0dffff04ffff0bff2affff0bff2cff1480ffff0bff2affff0bff2affff0bff2cff3c80ff0980ffff0bff2aff0bffff0bff2cff8080808080ff8080808080ffff010b80ff0180ffff02ffff03ff17ffff01ff04ffff04ff10ffff04ffff0bff81a7ffff02ff3effff04ff02ffff04ffff04ff2fffff04ffff04ff05ffff04ffff05ffff14ffff12ff47ff0b80ff128080ffff04ffff04ff05ff8080ff80808080ff808080ff8080808080ff808080ffff02ff16ffff04ff02ffff04ff05ffff04ff0bffff04ff37ffff04ff2fff8080808080808080ff8080ff0180ffff0bff2affff0bff2cff1880ffff0bff2affff0bff2affff0bff2cff3c80ff0580ffff0bff2affff02ff3affff04ff02ffff04ff07ffff04ffff0bff2cff2c80ff8080808080ffff0bff2cff8080808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 2 | -------------------------------------------------------------------------------- /chia/wallet/puzzles/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/puzzles/__init__.py -------------------------------------------------------------------------------- /chia/wallet/puzzles/clawback/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/puzzles/clawback/__init__.py -------------------------------------------------------------------------------- /chia/wallet/puzzles/clawback/metadata.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from enum import IntEnum 5 | 6 | from chia_rs.sized_bytes import bytes32 7 | from chia_rs.sized_ints import uint16, uint64 8 | 9 | from chia.util.streamable import Streamable, streamable 10 | from chia.wallet.wallet_puzzle_store import WalletPuzzleStore 11 | 12 | 13 | @streamable 14 | @dataclass(frozen=True) 15 | class ClawbackMetadata(Streamable): 16 | time_lock: uint64 17 | sender_puzzle_hash: bytes32 18 | recipient_puzzle_hash: bytes32 19 | 20 | async def is_recipient(self, puzzle_store: WalletPuzzleStore) -> bool: 21 | if await puzzle_store.puzzle_hash_exists(self.sender_puzzle_hash): 22 | return False 23 | elif await puzzle_store.puzzle_hash_exists(self.recipient_puzzle_hash): 24 | return True 25 | else: 26 | raise ValueError("Both sender and recipient puzzle hashes not found in puzzle store") 27 | 28 | 29 | class ClawbackVersion(IntEnum): 30 | V1 = uint16(1) 31 | 32 | 33 | @streamable 34 | @dataclass(frozen=True) 35 | class AutoClaimSettings(Streamable): 36 | enabled: bool = False 37 | tx_fee: uint64 = uint64(0) 38 | min_amount: uint64 = uint64(0) 39 | batch_size: uint16 = uint16(50) 40 | -------------------------------------------------------------------------------- /chia/wallet/puzzles/p2_conditions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Pay to conditions 3 | 4 | In this puzzle program, the solution is ignored. The reveal of the puzzle 5 | returns a fixed list of conditions. This roughly corresponds to OP_SECURETHEBAG 6 | in bitcoin. 7 | 8 | This is a pretty useless most of the time. But some (most?) solutions 9 | require a delegated puzzle program, so in those cases, this is just what 10 | the doctor ordered. 11 | """ 12 | 13 | from __future__ import annotations 14 | 15 | from chia_puzzles_py.programs import P2_CONDITIONS 16 | 17 | from chia.types.blockchain_format.program import Program 18 | 19 | MOD = Program.from_bytes(P2_CONDITIONS) 20 | 21 | 22 | def puzzle_for_conditions(conditions) -> Program: 23 | return MOD.run([conditions]) 24 | 25 | 26 | def solution_for_conditions(conditions) -> Program: 27 | return Program.to([puzzle_for_conditions(conditions), 0]) 28 | -------------------------------------------------------------------------------- /chia/wallet/puzzles/p2_delegated_conditions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Pay to delegated conditions 3 | 4 | In this puzzle program, the solution must be a signed list of conditions, which 5 | is returned literally. 6 | """ 7 | 8 | from __future__ import annotations 9 | 10 | from chia_puzzles_py.programs import P2_DELEGATED_CONDITIONS 11 | 12 | from chia.types.blockchain_format.program import Program 13 | 14 | MOD = Program.from_bytes(P2_DELEGATED_CONDITIONS) 15 | 16 | 17 | def puzzle_for_pk(public_key: Program) -> Program: 18 | return MOD.curry(public_key) 19 | 20 | 21 | def solution_for_conditions(conditions: Program) -> Program: 22 | return conditions.to([conditions]) 23 | -------------------------------------------------------------------------------- /chia/wallet/puzzles/p2_delegated_puzzle.py: -------------------------------------------------------------------------------- 1 | """ 2 | Pay to delegated puzzle 3 | 4 | In this puzzle program, the solution must be a signed delegated puzzle, along with 5 | its (unsigned) solution. The delegated puzzle is executed, passing in the solution. 6 | This obviously could be done recursively, arbitrarily deep (as long as the maximum 7 | cost is not exceeded). 8 | 9 | If you want to specify the conditions directly (thus terminating the potential recursion), 10 | you can use p2_conditions. 11 | 12 | This roughly corresponds to bitcoin's graftroot. 13 | """ 14 | 15 | from __future__ import annotations 16 | 17 | from chia_puzzles_py.programs import P2_DELEGATED_PUZZLE 18 | 19 | from chia.types.blockchain_format.program import Program 20 | from chia.wallet.puzzles import p2_conditions 21 | 22 | MOD = Program.from_bytes(P2_DELEGATED_PUZZLE) 23 | 24 | 25 | def puzzle_for_pk(public_key: bytes) -> Program: 26 | return MOD.curry(public_key) 27 | 28 | 29 | def solution_for_conditions(conditions) -> Program: 30 | delegated_puzzle = p2_conditions.puzzle_for_conditions(conditions) 31 | return solution_for_delegated_puzzle(delegated_puzzle, Program.to(0)) 32 | 33 | 34 | def solution_for_delegated_puzzle(delegated_puzzle: Program, delegated_solution: Program) -> Program: 35 | return delegated_puzzle.to([delegated_puzzle, delegated_solution]) 36 | -------------------------------------------------------------------------------- /chia/wallet/puzzles/p2_m_of_n_delegate_direct.py: -------------------------------------------------------------------------------- 1 | """ 2 | Pay to m of n direct 3 | 4 | This puzzle program is like p2_delegated_puzzle except instead of one public key, 5 | it includes N public keys, any M of which needs to sign the delegated puzzle. 6 | """ 7 | 8 | from __future__ import annotations 9 | 10 | from chia_puzzles_py.programs import P2_M_OF_N_DELEGATE_DIRECT 11 | 12 | from chia.types.blockchain_format.program import Program 13 | 14 | MOD = Program.from_bytes(P2_M_OF_N_DELEGATE_DIRECT) 15 | 16 | 17 | def puzzle_for_m_of_public_key_list(m, public_key_list) -> Program: 18 | return MOD.curry(m, public_key_list) 19 | 20 | 21 | def solution_for_delegated_puzzle(m, selectors, puzzle, solution) -> Program: 22 | return Program.to([selectors, puzzle, solution]) 23 | -------------------------------------------------------------------------------- /chia/wallet/puzzles/p2_puzzle_hash.py: -------------------------------------------------------------------------------- 1 | """ 2 | Pay to puzzle hash 3 | 4 | In this puzzle program, the solution must be a reveal of the puzzle with the given 5 | hash along with its solution. 6 | """ 7 | 8 | from __future__ import annotations 9 | 10 | from chia_puzzles_py.programs import P2_PUZZLE_HASH 11 | from chia_rs.sized_bytes import bytes32 12 | 13 | from chia.types.blockchain_format.program import Program 14 | 15 | MOD = Program.from_bytes(P2_PUZZLE_HASH) 16 | 17 | 18 | def puzzle_for_inner_puzzle_hash(inner_puzzle_hash: bytes32) -> Program: 19 | program = MOD.curry(inner_puzzle_hash) 20 | return program 21 | 22 | 23 | def puzzle_for_inner_puzzle(inner_puzzle: Program) -> Program: 24 | return puzzle_for_inner_puzzle_hash(inner_puzzle.get_tree_hash()) 25 | 26 | 27 | def solution_for_inner_puzzle_and_inner_solution(inner_puzzle: Program, inner_puzzle_solution: Program) -> Program: 28 | return Program.to([inner_puzzle, inner_puzzle_solution]) 29 | -------------------------------------------------------------------------------- /chia/wallet/puzzles/puzzle_utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any 4 | 5 | from chia_rs.sized_bytes import bytes32 6 | from chia_rs.sized_ints import uint64 7 | 8 | from chia.types.condition_opcodes import ConditionOpcode 9 | 10 | 11 | def make_create_coin_condition(puzzle_hash: bytes32, amount: uint64, memos: list[bytes]) -> list[Any]: 12 | condition = [ConditionOpcode.CREATE_COIN, puzzle_hash, amount] 13 | if len(memos) > 0: 14 | condition.append(memos) 15 | return condition 16 | 17 | 18 | def make_reserve_fee_condition(fee: uint64) -> list[Any]: 19 | return [ConditionOpcode.RESERVE_FEE, fee] 20 | 21 | 22 | def make_assert_coin_announcement(announcement_hash: bytes32) -> list[bytes]: 23 | return [ConditionOpcode.ASSERT_COIN_ANNOUNCEMENT, announcement_hash] 24 | 25 | 26 | def make_assert_puzzle_announcement(announcement_hash: bytes32) -> list[bytes]: 27 | return [ConditionOpcode.ASSERT_PUZZLE_ANNOUNCEMENT, announcement_hash] 28 | 29 | 30 | def make_create_coin_announcement(message: bytes) -> list[bytes]: 31 | return [ConditionOpcode.CREATE_COIN_ANNOUNCEMENT, message] 32 | 33 | 34 | def make_create_puzzle_announcement(message: bytes) -> list[bytes]: 35 | return [ConditionOpcode.CREATE_PUZZLE_ANNOUNCEMENT, message] 36 | -------------------------------------------------------------------------------- /chia/wallet/puzzles/utility_macros.clib: -------------------------------------------------------------------------------- 1 | ( 2 | ; assert takes a list of parameters 3 | ; all items in the list are required to be non-nil 4 | ; except for the final item which is returned 5 | (defmacro assert items 6 | (if (r items) 7 | (list if (f items) (c assert (r items)) (q . (x))) 8 | (f items) 9 | ) 10 | ) 11 | 12 | (defmacro and ARGS 13 | (if ARGS 14 | (qq (if (unquote (f ARGS)) 15 | (unquote (c and (r ARGS))) 16 | () 17 | )) 18 | 1) 19 | ) 20 | 21 | (defmacro or ARGS 22 | (if ARGS 23 | (qq (if (unquote (f ARGS)) 24 | 1 25 | (unquote (c or (r ARGS))) 26 | )) 27 | 0) 28 | ) 29 | 30 | (defun in (atom list_a) 31 | (if list_a 32 | (i (= atom (f list_a)) 33 | 1 34 | (in atom (r list_a)) 35 | ) 36 | () 37 | ) 38 | ) 39 | 40 | (defun gte (atom_a atom_b) 41 | (not (> atom_b atom_a)) 42 | ) 43 | 44 | (defun lte (atom_a atom_b) 45 | (not (> atom_a atom_b)) 46 | ) 47 | 48 | ) 49 | -------------------------------------------------------------------------------- /chia/wallet/singleton_record.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Any, Optional 5 | 6 | from chia_rs import CoinSpend 7 | from chia_rs.sized_bytes import bytes32 8 | from chia_rs.sized_ints import uint32 9 | 10 | from chia.types.blockchain_format.coin import Coin 11 | from chia.wallet.lineage_proof import LineageProof 12 | 13 | 14 | @dataclass(frozen=True) 15 | class SingletonRecord: 16 | """ 17 | These are values that correspond to a singleton in the WalletSingletonStore 18 | """ 19 | 20 | coin: Coin 21 | singleton_id: bytes32 22 | wallet_id: uint32 23 | parent_coinspend: CoinSpend 24 | inner_puzzle_hash: Optional[bytes32] 25 | pending: bool 26 | removed_height: int 27 | lineage_proof: LineageProof 28 | custom_data: Optional[Any] 29 | 30 | def name(self) -> bytes32: # pragma: no cover 31 | return self.coin.name() 32 | -------------------------------------------------------------------------------- /chia/wallet/trading/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/trading/__init__.py -------------------------------------------------------------------------------- /chia/wallet/trading/trade_status.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from enum import Enum 4 | 5 | 6 | class TradeStatus(Enum): 7 | PENDING_ACCEPT = 0 8 | PENDING_CONFIRM = 1 9 | PENDING_CANCEL = 2 10 | CANCELLED = 3 11 | CONFIRMED = 4 12 | FAILED = 5 13 | EXPIRED = 6 14 | -------------------------------------------------------------------------------- /chia/wallet/transaction_sorting.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import enum 4 | 5 | 6 | class SortKey(enum.Enum): 7 | CONFIRMED_AT_HEIGHT = "ORDER BY confirmed_at_height {ASC}" 8 | RELEVANCE = "ORDER BY confirmed {ASC}, confirmed_at_height {DESC}, created_at_time {DESC}" 9 | 10 | def ascending(self) -> str: 11 | return self.value.format(ASC="ASC", DESC="DESC") 12 | 13 | def descending(self) -> str: 14 | return self.value.format(ASC="DESC", DESC="ASC") 15 | -------------------------------------------------------------------------------- /chia/wallet/uncurried_puzzle.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Union 5 | 6 | from chia.types.blockchain_format.program import Program, uncurry 7 | from chia.types.blockchain_format.serialized_program import SerializedProgram 8 | 9 | 10 | @dataclass(frozen=True) 11 | class UncurriedPuzzle: 12 | mod: Program 13 | args: Program 14 | 15 | 16 | def uncurry_puzzle(puzzle: Union[Program, SerializedProgram]) -> UncurriedPuzzle: 17 | return UncurriedPuzzle(*uncurry(puzzle)) 18 | -------------------------------------------------------------------------------- /chia/wallet/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/util/__init__.py -------------------------------------------------------------------------------- /chia/wallet/util/notifications.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_puzzles_py.programs import NOTIFICATION 4 | from chia_rs.sized_bytes import bytes32 5 | from chia_rs.sized_ints import uint64 6 | 7 | from chia.types.blockchain_format.program import Program 8 | 9 | NOTIFICATION_MOD = Program.from_bytes(NOTIFICATION) 10 | 11 | 12 | def construct_notification(target: bytes32, amount: uint64) -> Program: 13 | return NOTIFICATION_MOD.curry(target, amount) 14 | -------------------------------------------------------------------------------- /chia/wallet/util/pprint.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | 6 | @dataclass 7 | class Range: 8 | first: int 9 | last: int 10 | 11 | def __repr__(self) -> str: 12 | if self.first == self.last: 13 | return f"{self.first}" 14 | else: 15 | return f"{self.first} to {self.last}" 16 | 17 | 18 | def int_list_to_ranges(array: list[int]) -> list[Range]: 19 | if len(array) == 0: 20 | return [] 21 | sorted_array = sorted(array) 22 | first = sorted_array[0] 23 | last = first 24 | ranges = [] 25 | for i in sorted_array[1:]: 26 | if i == last: 27 | pass 28 | elif i == last + 1: 29 | last = i 30 | else: 31 | ranges.append(Range(first, last)) 32 | first = i 33 | last = i 34 | ranges.append(Range(first, last)) 35 | return ranges 36 | 37 | 38 | def print_compact_ranges(array: list[int]) -> str: 39 | return str(int_list_to_ranges(array)) 40 | -------------------------------------------------------------------------------- /chia/wallet/util/puzzle_decorator_type.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from enum import Enum 4 | 5 | 6 | class PuzzleDecoratorType(Enum): 7 | CLAWBACK = 1 8 | -------------------------------------------------------------------------------- /chia/wallet/util/transaction_type.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from enum import IntEnum 4 | 5 | 6 | class TransactionType(IntEnum): 7 | INCOMING_TX = 0 8 | OUTGOING_TX = 1 9 | COINBASE_REWARD = 2 10 | FEE_REWARD = 3 11 | INCOMING_TRADE = 4 12 | OUTGOING_TRADE = 5 13 | INCOMING_CLAWBACK_RECEIVE = 6 14 | INCOMING_CLAWBACK_SEND = 7 15 | OUTGOING_CLAWBACK = 8 16 | INCOMING_CRCAT_PENDING = 9 17 | 18 | 19 | CLAWBACK_INCOMING_TRANSACTION_TYPES = { 20 | TransactionType.INCOMING_CLAWBACK_SEND.value, 21 | TransactionType.INCOMING_CLAWBACK_RECEIVE.value, 22 | TransactionType.INCOMING_CRCAT_PENDING.value, 23 | } 24 | -------------------------------------------------------------------------------- /chia/wallet/vc_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chia-Network/chia-blockchain/9289a05f128c431057ba238d5c2705de25684cf8/chia/wallet/vc_wallet/__init__.py -------------------------------------------------------------------------------- /chia/wallet/wallet_info.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from chia_rs.sized_ints import uint8, uint32 6 | 7 | from chia.util.streamable import Streamable, streamable 8 | 9 | 10 | @streamable 11 | @dataclass(frozen=True) 12 | class WalletInfo(Streamable): 13 | """ 14 | This object represents the wallet data as it is stored in DB. 15 | ID: Main wallet (Standard) is stored at index 1, every wallet created after done has auto incremented id. 16 | Name: can be a user provided or default generated name. (can be modified) 17 | Type: is specified during wallet creation and should never be changed. 18 | Data: this filed is intended to be used for storing any wallet specific information required for it. 19 | (RL wallet stores origin_id, admin/user pubkey, rate limit, etc.) 20 | This data should be json encoded string. 21 | """ 22 | 23 | id: uint32 24 | name: str 25 | type: uint8 # WalletType(type) 26 | data: str 27 | 28 | 29 | @streamable 30 | @dataclass(frozen=True) 31 | class WalletInfoBackup(Streamable): 32 | """ 33 | Used for transforming list of WalletInfo objects into bytes. 34 | """ 35 | 36 | wallet_list: list[WalletInfo] 37 | -------------------------------------------------------------------------------- /chia/wallet/wallet_spend_bundle.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from collections.abc import Sequence 4 | from typing import TypeVar 5 | 6 | from chia_rs import AugSchemeMPL, CoinSpend, G2Element, SpendBundle 7 | 8 | from chia.consensus.default_constants import DEFAULT_CONSTANTS 9 | from chia.wallet.util.debug_spend_bundle import debug_spend_bundle 10 | 11 | T_SpendBundle = TypeVar("T_SpendBundle", bound="SpendBundle") 12 | 13 | 14 | class WalletSpendBundle(SpendBundle): 15 | @classmethod 16 | def aggregate(cls, spend_bundles: Sequence[T_SpendBundle]) -> WalletSpendBundle: 17 | coin_spends: list[CoinSpend] = [] 18 | sigs: list[G2Element] = [] 19 | for bundle in spend_bundles: 20 | coin_spends += bundle.coin_spends 21 | sigs.append(bundle.aggregated_signature) 22 | aggregated_signature = AugSchemeMPL.aggregate(sigs) 23 | return cls(coin_spends, aggregated_signature) 24 | 25 | def debug(self, agg_sig_additional_data: bytes = DEFAULT_CONSTANTS.AGG_SIG_ME_ADDITIONAL_DATA) -> None: 26 | debug_spend_bundle(self, agg_sig_additional_data) # pragma: no cover 27 | -------------------------------------------------------------------------------- /mypy.ini.template: -------------------------------------------------------------------------------- 1 | [mypy] 2 | files = benchmarks,build_scripts,chia,tools,*.py 3 | ignore_missing_imports = True 4 | show_error_codes = True 5 | warn_unused_ignores = True 6 | 7 | disallow_any_generics = True 8 | disallow_subclassing_any = True 9 | disallow_untyped_calls = True 10 | disallow_untyped_defs = True 11 | disallow_incomplete_defs = True 12 | check_untyped_defs = True 13 | disallow_untyped_decorators = True 14 | no_implicit_optional = True 15 | warn_return_any = True 16 | no_implicit_reexport = True 17 | strict_equality = True 18 | warn_redundant_casts = True 19 | 20 | [mypy-chia-exclusions] 21 | disable_error_code = annotation-unchecked 22 | disallow_any_generics = False 23 | disallow_subclassing_any = False 24 | disallow_untyped_calls = False 25 | disallow_untyped_defs = False 26 | disallow_incomplete_defs = False 27 | check_untyped_defs = False 28 | disallow_untyped_decorators = False 29 | no_implicit_optional = False 30 | warn_return_any = False 31 | no_implicit_reexport = False 32 | strict_equality = False 33 | -------------------------------------------------------------------------------- /poetry.toml: -------------------------------------------------------------------------------- 1 | [virtualenvs] 2 | in-project = true 3 | 4 | [keyring] 5 | # avoiding silent hangs with no indication 6 | # https://github.com/python-poetry/poetry/issues/8623 7 | enabled = false 8 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | ; logging options 3 | log_cli = False 4 | addopts = --verbose --tb=short -n auto -p no:monitor 5 | log_level = WARNING 6 | console_output_style = count 7 | log_format = %(asctime)s %(name)s: %(levelname)s %(message)s 8 | markers = 9 | build_test_chains 10 | limit_consensus_modes 11 | standard_block_tools 12 | data_layer: Mark as a data layer related test. 13 | test_mark_a1: used in testing test utilities 14 | test_mark_a2: used in testing test utilities 15 | test_mark_b1: used in testing test utilities 16 | test_mark_b2: used in testing test utilities 17 | testpaths = chia/_tests/ 18 | filterwarnings = 19 | error 20 | ignore:unclosed "$2/node-profile.txt" 15 | # mv profile-node "$2" 16 | } 17 | 18 | cd .. 19 | 20 | if [ "$1" = "" ]; then 21 | TEST_NAME="node-benchmark" 22 | else 23 | TEST_NAME=$1 24 | fi 25 | 26 | # generate the test blockchain databases by running: 27 | # python -m tools.generate_chain --fill-rate 0 --length 1500 --block-refs 1 28 | # python -m tools.generate_chain --fill-rate 100 --length 500 --block-refs 0 29 | run_benchmark stress-test-blockchain-1500-0-refs.sqlite "${TEST_NAME}-sync-empty" "" 30 | run_benchmark stress-test-blockchain-1500-0-refs.sqlite "${TEST_NAME}-keepup-empty" --keep-up 31 | 32 | run_benchmark stress-test-blockchain-500-100.sqlite "${TEST_NAME}-sync-full" "" 33 | run_benchmark stress-test-blockchain-500-100.sqlite "${TEST_NAME}-keepup-full" --keep-up 34 | -------------------------------------------------------------------------------- /virtual_project.yaml: -------------------------------------------------------------------------------- 1 | exclude_paths: 2 | ignore: 3 | packages: 4 | files: 5 | edges: 6 | --------------------------------------------------------------------------------