├── .coveragerc ├── .flake8 ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── actions │ └── install │ │ └── action.yml ├── linters │ ├── .flake8 │ ├── .isort.cfg │ ├── .markdown-lint.yml │ ├── .python-black │ └── .python-lint └── workflows │ ├── build-linux-arm64-installer.yml │ ├── build-linux-installer-deb.yml │ ├── build-linux-installer-rpm.yml │ ├── build-macos-installers.yml │ └── build-windows-installer.yml ├── .gitignore ├── .gitmodules ├── .isort.cfg ├── .markdown-lint.yml ├── .pre-commit-config.yaml ├── BUILD_TIMELORD.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── INSTALL.md ├── Install-gui.ps1 ├── Install-plotter.ps1 ├── Install.ps1 ├── LICENSE ├── README.md ├── activated.ps1 ├── activated.py ├── activated.sh ├── benchmarks ├── __init__.py ├── block_ref.py ├── block_store.py ├── clvm_generator.bin ├── coin_store.py ├── jsonify.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 │ │ ├── postinst.sh │ │ └── prerm.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_windows-1-gui.ps1 ├── build_windows-2-installer.ps1 ├── check_dependency_artifacts.py ├── clean-runner.sh ├── installer-version.py ├── 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 ├── flax ├── __init__.py ├── clvm │ ├── __init__.py │ ├── singleton.py │ └── spend_sim.py ├── cmds │ ├── __init__.py │ ├── beta.py │ ├── beta_funcs.py │ ├── cmds_util.py │ ├── configure.py │ ├── data.py │ ├── data_funcs.py │ ├── db.py │ ├── db_backup_func.py │ ├── db_upgrade_func.py │ ├── db_validate_func.py │ ├── farm.py │ ├── farm_funcs.py │ ├── flax.py │ ├── init.py │ ├── init_funcs.py │ ├── keys.py │ ├── keys_funcs.py │ ├── netspace.py │ ├── netspace_funcs.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 │ ├── start.py │ ├── start_funcs.py │ ├── stop.py │ ├── units.py │ ├── wallet.py │ └── wallet_funcs.py ├── consensus │ ├── __init__.py │ ├── block_body_validation.py │ ├── block_creation.py │ ├── block_header_validation.py │ ├── block_record.py │ ├── block_rewards.py │ ├── block_root_validation.py │ ├── blockchain.py │ ├── blockchain_interface.py │ ├── coinbase.py │ ├── condition_costs.py │ ├── constants.py │ ├── cost_calculator.py │ ├── default_constants.py │ ├── deficit.py │ ├── difficulty_adjustment.py │ ├── find_fork_point.py │ ├── full_block_to_block_record.py │ ├── get_block_challenge.py │ ├── make_sub_epoch_summary.py │ ├── multiprocess_validation.py │ ├── pos_quality.py │ ├── pot_iterations.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 │ └── util │ │ ├── __init__.py │ │ └── benchmark.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 │ ├── coin_store.py │ ├── fee_estimate.py │ ├── fee_estimate_store.py │ ├── fee_estimation.py │ ├── fee_estimator.py │ ├── fee_estimator_constants.py │ ├── fee_estimator_example.py │ ├── fee_estimator_interface.py │ ├── fee_history.py │ ├── fee_tracker.py │ ├── full_node.py │ ├── full_node_api.py │ ├── full_node_store.py │ ├── generator.py │ ├── hint_management.py │ ├── hint_store.py │ ├── lock_queue.py │ ├── mempool.py │ ├── mempool_check_conditions.py │ ├── mempool_manager.py │ ├── pending_tx_cache.py │ ├── signage_point.py │ ├── sync_store.py │ └── weight_proof.py ├── harvester │ ├── __init__.py │ ├── harvester.py │ └── harvester_api.py ├── introducer │ ├── __init__.py │ ├── introducer.py │ └── introducer_api.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 │ ├── full_node_protocol.py │ ├── harvester_protocol.py │ ├── introducer_protocol.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 ├── pyinstaller.spec ├── 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_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_sqlite_store.py │ ├── address_manager_store.py │ ├── connection_utils.py │ ├── introducer_peers.py │ ├── node_discovery.py │ ├── outbound_message.py │ ├── peer_store_resolver.py │ ├── rate_limit_numbers.py │ ├── rate_limits.py │ ├── reconnect_task.py │ ├── server.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 │ ├── block_tools.py │ ├── full_node_simulator.py │ ├── simulator_constants.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 │ ├── time_out_assert.py │ └── wallet_tools.py ├── ssl │ ├── __init__.py │ ├── create_ssl.py │ ├── dst_root_ca.pem │ ├── flax_ca.crt │ └── flax_ca.key ├── timelord │ ├── __init__.py │ ├── iters_from_block.py │ ├── timelord.py │ ├── timelord_api.py │ ├── timelord_launcher.py │ ├── timelord_state.py │ └── types.py ├── types │ ├── __init__.py │ ├── announcement.py │ ├── block_protocol.py │ ├── blockchain_format │ │ ├── __init__.py │ │ ├── classgroup.py │ │ ├── coin.py │ │ ├── foliage.py │ │ ├── pool_target.py │ │ ├── program.py │ │ ├── proof_of_space.py │ │ ├── reward_chain_block.py │ │ ├── sized_bytes.py │ │ ├── slots.py │ │ ├── sub_epoch_summary.py │ │ ├── tree_hash.py │ │ └── vdf.py │ ├── clvm_cost.py │ ├── coin_record.py │ ├── coin_solution.py │ ├── coin_spend.py │ ├── condition_opcodes.py │ ├── condition_with_args.py │ ├── end_of_slot_bundle.py │ ├── fee_rate.py │ ├── full_block.py │ ├── generator_types.py │ ├── header_block.py │ ├── mempool_inclusion_status.py │ ├── mempool_item.py │ ├── mempool_submission_status.py │ ├── mojos.py │ ├── peer_info.py │ ├── spend_bundle.py │ ├── spend_bundle_conditions.py │ ├── transaction_queue_entry.py │ ├── unfinished_block.py │ ├── unfinished_header_block.py │ └── weight_proof.py ├── util │ ├── __init__.py │ ├── api_decorators.py │ ├── bech32m.py │ ├── beta_metrics.py │ ├── block_cache.py │ ├── byte_types.py │ ├── cached_bls.py │ ├── chain_utils.py │ ├── check_fork_next_block.py │ ├── chunks.py │ ├── condition_tools.py │ ├── config.py │ ├── create_alert_file.py │ ├── db_synchronous.py │ ├── db_version.py │ ├── db_wrapper.py │ ├── default_root.py │ ├── dump_keyring.py │ ├── english.txt │ ├── errors.py │ ├── file_keyring.py │ ├── files.py │ ├── flax_logging.py │ ├── full_block_utils.py │ ├── generator_tools.py │ ├── hash.py │ ├── initial-config.yaml │ ├── inline_executor.py │ ├── ints.py │ ├── json_util.py │ ├── keychain.py │ ├── keyring_wrapper.py │ ├── lock.py │ ├── log_exceptions.py │ ├── lru_cache.py │ ├── make_test_constants.py │ ├── memory_profiler.py │ ├── merkle_set.py │ ├── misc.py │ ├── network.py │ ├── paginator.py │ ├── partial_func.py │ ├── path.py │ ├── permissions.py │ ├── pip_import.py │ ├── prev_transaction_block.py │ ├── profiler.py │ ├── recursive_replace.py │ ├── safe_cancel_task.py │ ├── service_groups.py │ ├── setproctitle.py │ ├── significant_bits.py │ ├── ssl_check.py │ ├── streamable.py │ ├── struct_stream.py │ ├── task_timing.py │ ├── validate_alert.py │ ├── vdf_prover.py │ └── ws_message.py └── wallet │ ├── __init__.py │ ├── block_record.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 │ ├── 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 │ ├── flaxlisp.py │ ├── key_val_store.py │ ├── lineage_proof.py │ ├── nft_wallet │ ├── __init__.py │ ├── metadata_outer_puzzle.py │ ├── nft_info.py │ ├── nft_puzzles.py │ ├── nft_wallet.py │ ├── ownership_outer_puzzle.py │ ├── singleton_outer_puzzle.py │ ├── transfer_program_puzzle.py │ └── uncurry_nft.py │ ├── notification_manager.py │ ├── notification_store.py │ ├── outer_puzzles.py │ ├── payment.py │ ├── puzzle_drivers.py │ ├── puzzles │ ├── __init__.py │ ├── block_program_zero.clvm │ ├── block_program_zero.clvm.hex │ ├── block_program_zero.clvm.hex.sha256tree │ ├── calculate_synthetic_public_key.clvm │ ├── calculate_synthetic_public_key.clvm.hex │ ├── calculate_synthetic_public_key.clvm.hex.sha256tree │ ├── cat_loader.py │ ├── cat_truths.clib │ ├── cat_v2.clvm │ ├── cat_v2.clvm.hex │ ├── cat_v2.clvm.hex.sha256tree │ ├── condition_codes.clvm │ ├── create-lock-puzzlehash.clvm │ ├── create_nft_launcher_from_did.clvm │ ├── create_nft_launcher_from_did.clvm.hex │ ├── create_nft_launcher_from_did.clvm.hex.sha256tree │ ├── curry-and-treehash.clinc │ ├── decompress_block_spends.clvm │ ├── decompress_block_spends.clvm.hex │ ├── decompress_block_spends.clvm.hex.sha256tree │ ├── decompress_block_spends.py │ ├── decompress_coin_spend_entry.clvm │ ├── decompress_coin_spend_entry.clvm.hex │ ├── decompress_coin_spend_entry.clvm.hex.sha256tree │ ├── decompress_coin_spend_entry_with_prefix.clvm │ ├── decompress_coin_spend_entry_with_prefix.clvm.hex │ ├── decompress_coin_spend_entry_with_prefix.clvm.hex.sha256tree │ ├── decompress_puzzle.clvm │ ├── decompress_puzzle.clvm.hex │ ├── decompress_puzzle.clvm.hex.sha256tree │ ├── delegated_tail.clvm │ ├── delegated_tail.clvm.hex │ ├── delegated_tail.clvm.hex.sha256tree │ ├── did_innerpuz.clvm │ ├── did_innerpuz.clvm.hex │ ├── did_innerpuz.clvm.hex.sha256tree │ ├── everything_with_signature.clvm │ ├── everything_with_signature.clvm.hex │ ├── everything_with_signature.clvm.hex.sha256tree │ ├── flaxlisp_deserialisation.clvm │ ├── flaxlisp_deserialisation.clvm.hex │ ├── flaxlisp_deserialisation.clvm.hex.sha256tree │ ├── genesis_by_coin_id.clvm │ ├── genesis_by_coin_id.clvm.hex │ ├── genesis_by_coin_id.clvm.hex.sha256tree │ ├── genesis_by_puzzle_hash.clvm │ ├── genesis_by_puzzle_hash.clvm.hex │ ├── genesis_by_puzzle_hash.clvm.hex.sha256tree │ ├── graftroot_dl_offers.clvm │ ├── graftroot_dl_offers.clvm.hex │ ├── graftroot_dl_offers.clvm.hex.sha256tree │ ├── json.clib │ ├── load_clvm.py │ ├── lock.inner.puzzle.clvm │ ├── lock.inner.puzzle.clvm.hex │ ├── lock.inner.puzzle.clvm.hex.sha256tree │ ├── merkle_utils.clib │ ├── nft_intermediate_launcher.clvm │ ├── nft_intermediate_launcher.clvm.hex │ ├── nft_intermediate_launcher.clvm.hex.sha256tree │ ├── nft_metadata_updater_default.clvm │ ├── nft_metadata_updater_default.clvm.hex │ ├── nft_metadata_updater_default.clvm.hex.sha256tree │ ├── nft_metadata_updater_updateable.clvm │ ├── nft_metadata_updater_updateable.clvm.hex │ ├── nft_metadata_updater_updateable.clvm.hex.sha256tree │ ├── nft_ownership_layer.clvm │ ├── nft_ownership_layer.clvm.hex │ ├── nft_ownership_layer.clvm.hex.sha256tree │ ├── nft_ownership_transfer_program_one_way_claim_with_royalties.clvm │ ├── nft_ownership_transfer_program_one_way_claim_with_royalties.clvm.hex │ ├── nft_ownership_transfer_program_one_way_claim_with_royalties.clvm.hex.sha256tree │ ├── nft_state_layer.clvm │ ├── nft_state_layer.clvm.hex │ ├── nft_state_layer.clvm.hex.sha256tree │ ├── notification.clvm │ ├── notification.clvm.hex │ ├── notification.clvm.hex.sha256tree │ ├── p2_conditions.clvm │ ├── p2_conditions.clvm.hex │ ├── p2_conditions.clvm.hex.sha256tree │ ├── p2_conditions.py │ ├── p2_delegated_conditions.clvm │ ├── p2_delegated_conditions.clvm.hex │ ├── p2_delegated_conditions.clvm.hex.sha256tree │ ├── p2_delegated_conditions.py │ ├── p2_delegated_puzzle.clvm │ ├── p2_delegated_puzzle.clvm.hex │ ├── p2_delegated_puzzle.clvm.hex.sha256tree │ ├── p2_delegated_puzzle.py │ ├── p2_delegated_puzzle_or_hidden_puzzle.clvm │ ├── p2_delegated_puzzle_or_hidden_puzzle.clvm.hex │ ├── p2_delegated_puzzle_or_hidden_puzzle.clvm.hex.sha256tree │ ├── p2_delegated_puzzle_or_hidden_puzzle.py │ ├── p2_m_of_n_delegate_direct.clvm │ ├── p2_m_of_n_delegate_direct.clvm.hex │ ├── p2_m_of_n_delegate_direct.clvm.hex.sha256tree │ ├── p2_m_of_n_delegate_direct.py │ ├── p2_parent.clvm │ ├── p2_parent.clvm.hex │ ├── p2_parent.clvm.hex.sha256tree │ ├── p2_puzzle_hash.clvm │ ├── p2_puzzle_hash.clvm.hex │ ├── p2_puzzle_hash.clvm.hex.sha256tree │ ├── p2_puzzle_hash.py │ ├── p2_singleton.clvm │ ├── p2_singleton.clvm.hex │ ├── p2_singleton.clvm.hex.sha256tree │ ├── p2_singleton_or_delayed_puzhash.clvm │ ├── p2_singleton_or_delayed_puzhash.clvm.hex │ ├── p2_singleton_or_delayed_puzhash.clvm.hex.sha256tree │ ├── pool_member_innerpuz.clvm │ ├── pool_member_innerpuz.clvm.hex │ ├── pool_member_innerpuz.clvm.hex.sha256tree │ ├── pool_waitingroom_innerpuz.clvm │ ├── pool_waitingroom_innerpuz.clvm.hex │ ├── pool_waitingroom_innerpuz.clvm.hex.sha256tree │ ├── prefarm │ │ ├── __init__.py │ │ ├── make_prefarm_ph.py │ │ └── spend_prefarm.py │ ├── puzzle_utils.py │ ├── recompile-all.sh │ ├── rom_bootstrap_generator.clvm │ ├── rom_bootstrap_generator.clvm.hex │ ├── rom_bootstrap_generator.clvm.hex.sha256tree │ ├── rom_bootstrap_generator.py │ ├── settlement_payments.clvm │ ├── settlement_payments.clvm.hex │ ├── settlement_payments.clvm.hex.sha256tree │ ├── settlement_payments_old.clvm │ ├── settlement_payments_old.clvm.hex │ ├── settlement_payments_old.clvm.hex.sha256tree │ ├── sha256tree.clib │ ├── sha256tree_module.clvm │ ├── sha256tree_module.clvm.hex │ ├── sha256tree_module.clvm.hex.sha256tree │ ├── singleton_launcher.clvm │ ├── singleton_launcher.clvm.hex │ ├── singleton_launcher.clvm.hex.sha256tree │ ├── singleton_top_layer.clvm │ ├── singleton_top_layer.clvm.hex │ ├── singleton_top_layer.clvm.hex.sha256tree │ ├── singleton_top_layer.py │ ├── singleton_top_layer_v1_1.clvm │ ├── singleton_top_layer_v1_1.clvm.hex │ ├── singleton_top_layer_v1_1.clvm.hex.sha256tree │ ├── singleton_top_layer_v1_1.py │ ├── singleton_truths.clib │ ├── tails.py │ ├── test_generator_deserialize.clvm │ ├── test_generator_deserialize.clvm.hex │ ├── test_generator_deserialize.clvm.hex.sha256tree │ ├── test_multiple_generator_input_arguments.clvm │ ├── test_multiple_generator_input_arguments.clvm.hex │ ├── test_multiple_generator_input_arguments.clvm.hex.sha256tree │ └── utility_macros.clib │ ├── secret_key_store.py │ ├── settings │ ├── __init__.py │ ├── default_settings.py │ ├── settings_objects.py │ └── user_settings.py │ ├── sign_coin_spends.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 │ ├── compute_hints.py │ ├── compute_memos.py │ ├── curry_and_treehash.py │ ├── debug_spend_bundle.py │ ├── json_clvm_utils.py │ ├── merkle_tree.py │ ├── merkle_utils.py │ ├── new_peak_queue.py │ ├── notifications.py │ ├── peer_request_cache.py │ ├── puzzle_compression.py │ ├── transaction_type.py │ ├── wallet_sync_utils.py │ └── wallet_types.py │ ├── wallet.py │ ├── wallet_action.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_state_manager.py │ ├── wallet_transaction_store.py │ ├── wallet_user_store.py │ └── wallet_weight_proof_handler.py ├── install-gui.sh ├── install-plotter.sh ├── install-timelord.sh ├── install.sh ├── installhelper.py ├── lgtm.yml ├── mypy.ini ├── pylintrc ├── pyproject.toml ├── pytest.ini ├── run-py-tests.sh ├── setup.py ├── start-gui.sh ├── tests ├── README.md ├── __init__.py ├── blockchain │ ├── __init__.py │ ├── blockchain_test_utils.py │ ├── config.py │ ├── test_blockchain.py │ └── test_blockchain_transactions.py ├── build-init-files.py ├── build-job-matrix.py ├── check_pytest_monitor_output.py ├── check_sql_statements.py ├── clvm │ ├── __init__.py │ ├── benchmark_costs.py │ ├── coin_store.py │ ├── config.py │ ├── test_clvm_step.py │ ├── test_curry_and_treehash.py │ ├── test_flaxlisp_deserialization.py │ ├── test_program.py │ ├── test_puzzle_compression.py │ ├── test_puzzle_drivers.py │ ├── test_puzzles.py │ ├── test_serialized_program.py │ ├── test_singletons.py │ └── test_spend_sim.py ├── conftest.py ├── connection_utils.py ├── core │ ├── __init__.py │ ├── cmds │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_beta.py │ │ ├── test_keys.py │ │ └── test_wallet.py │ ├── config.py │ ├── consensus │ │ ├── __init__.py │ │ ├── config.py │ │ └── test_pot_iterations.py │ ├── custom_types │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_coin.py │ │ ├── test_proof_of_space.py │ │ └── test_spend_bundle.py │ ├── daemon │ │ ├── __init__.py │ │ ├── config.py │ │ └── test_daemon.py │ ├── data_layer │ │ ├── __init__.py │ │ ├── config.py │ │ ├── conftest.py │ │ ├── test_data_cli.py │ │ ├── test_data_layer_util.py │ │ ├── test_data_rpc.py │ │ ├── test_data_store.py │ │ ├── test_data_store_schema.py │ │ └── util.py │ ├── full_node │ │ ├── __init__.py │ │ ├── config.py │ │ ├── conftest.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_mempool.py │ │ ├── test_mempool_fee_protocol.py │ │ ├── test_mempool_performance.py │ │ ├── test_node_load.py │ │ ├── test_peer_store_resolver.py │ │ ├── test_performance.py │ │ └── test_transactions.py │ ├── large_block.py │ ├── make_block_generator.py │ ├── mempool │ │ ├── __init__.py │ │ └── test_mempool_fee_estimator.py │ ├── node_height.py │ ├── server │ │ ├── __init__.py │ │ ├── config.py │ │ ├── test_dos.py │ │ ├── test_rate_limits.py │ │ └── test_upnp.py │ ├── ssl │ │ ├── __init__.py │ │ ├── config.py │ │ └── test_ssl.py │ ├── test_coins.py │ ├── test_cost_calculation.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_setproctitle.py │ └── util │ │ ├── __init__.py │ │ ├── config.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_lru_cache.py │ │ ├── test_significant_bits.py │ │ └── test_streamable.py ├── db │ ├── __init__.py │ └── test_db_wrapper.py ├── farmer_harvester │ ├── __init__.py │ ├── config.py │ └── test_farmer_harvester.py ├── fee_estimation │ ├── __init__.py │ ├── cmdline_test.py │ ├── test_fee_estimation_rpc.py │ └── test_fee_estimation_unit_tests.py ├── flax-start-sim ├── generator │ ├── __init__.py │ ├── config.py │ ├── test_compression.py │ ├── test_generator_types.py │ ├── test_list_to_batches.py │ ├── test_rom.py │ └── test_scan.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_cmdline.py │ ├── test_pool_config.py │ ├── test_pool_puzzles_lifecycle.py │ ├── test_pool_rpc.py │ ├── test_pool_wallet.py │ └── test_wallet_pool_store.py ├── setup_nodes.py ├── setup_services.py ├── simulation │ ├── __init__.py │ ├── config.py │ ├── test_simulation.py │ └── test_start_simulator.py ├── testconfig.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_run_block.py ├── util │ ├── __init__.py │ ├── alert_server.py │ ├── benchmark_cost.py │ ├── bip39_test_vectors.json │ ├── blockchain.py │ ├── build_network_protocol_files.py │ ├── config.py │ ├── db_connection.py │ ├── gen_ssl_certs.py │ ├── generator_tools_testing.py │ ├── key_tool.py │ ├── keyring.py │ ├── misc.py │ ├── network_protocol_data.py │ ├── protocol_messages_bytes-v1.0 │ ├── protocol_messages_json.py │ ├── rpc.py │ ├── temp_file.py │ ├── test_chunks.py │ ├── test_full_block_utils.py │ ├── test_lock_queue.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_struct_stream.py │ └── wallet_is_synced.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 │ ├── config.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_coin_selection.py │ ├── test_flaxlisp.py │ ├── test_nft_store.py │ ├── test_notifications.py │ ├── test_offer_parsing_performance.py │ ├── test_puzzle_store.py │ ├── test_singleton.py │ ├── test_singleton_lifecycle.py │ ├── test_singleton_lifecycle_fast.py │ ├── test_taproot.py │ ├── test_transaction_store.py │ ├── test_wallet.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_trade_store.py │ └── test_wallet_user_store.py └── weight_proof │ ├── __init__.py │ ├── config.py │ └── test_weight_proof.py └── tools ├── __init__.py ├── analyze-chain.py ├── cpu_utilization.py ├── generate_chain.py ├── manage_clvm.py ├── plot-log.gnuplot ├── run_benchmark.sh ├── run_block.py ├── test_constants.py └── test_full_sync.py /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch=True 3 | relative_files=True 4 | source= 5 | flax 6 | tests 7 | concurrency=multiprocessing 8 | parallel=True 9 | 10 | [report] 11 | precision = 1 12 | exclude_lines = 13 | pragma: no cover 14 | abc\.abstractmethod 15 | typing\.overload 16 | ^\s*\.\.\.\s*$ 17 | if typing.TYPE_CHECKING: 18 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 120 3 | exclude = ./typings/**/* 4 | ignore = E203,W503 5 | per-file-ignores = 6 | tests/util/build_network_protocol_files.py:F405 7 | tests/util/test_network_protocol_files.py:F405 8 | tests/util/test_network_protocol_json.py:F405 9 | tests/util/protocol_messages_json.py:E501 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. (If what you are experiencing is NOT a bug but instead a support issue, please open a Discussion instead!) 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Desktop (please complete the following information):** 28 | 29 | - OS: [e.g. Linux] 30 | - OS Version/Flavor: [e.g. CentOS 7.2] 31 | - CPU: [e.g. Intel Xeon 8175M] 32 | 33 | **Additional context** 34 | Add any other context about the problem here. 35 | -------------------------------------------------------------------------------- /.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/Flax-Network/flax-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/Flax-Network/flax-blockchain/discussions/new?category=ideas 10 | - about: Get support on the Flax Discord chat channels. 11 | name: Join the Discord.io support chat 12 | url: 'https://discord.gg/TgJyxsEFFc' 13 | -------------------------------------------------------------------------------- /.github/linters/.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 120 3 | exclude = ./typings/**/* 4 | ignore = E203,W503 5 | -------------------------------------------------------------------------------- /.github/linters/.isort.cfg: -------------------------------------------------------------------------------- 1 | [settings] 2 | profile= 3 | 4 | ; vertical hanging indent mode also used in black configuration 5 | multi_line_output = 3 6 | 7 | ; necessary because black expect the trailing comma 8 | include_trailing_comma = true 9 | 10 | ; black compatibility 11 | force_grid_wrap = 0 12 | 13 | ; black compatibility 14 | use_parentheses = True 15 | 16 | ; black compatibility 17 | ensure_newline_before_comments = True 18 | 19 | ; we chose 120 as line length 20 | line_length = 120 21 | -------------------------------------------------------------------------------- /.github/linters/.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 | -------------------------------------------------------------------------------- /.github/linters/.python-black: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line_length = 120 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "mozilla-ca"] 2 | path = mozilla-ca 3 | url = https://github.com/Chia-Network/mozilla-ca.git 4 | [submodule "flax-blockchain-gui"] 5 | path = flax-blockchain-gui 6 | url = https://github.com/Flax-Network/flax-blockchain-gui.git 7 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Install instructions have been moved to the [INSTALL](https://github.com/Flax-Network/flax-blockchain/wiki/INSTALL) section of the repository [Wiki](https://github.com/Flax-Network/flax-blockchain/wiki). 4 | 5 | After installing, follow the remaining instructions in the 6 | [Quick Start Guide](https://github.com/Flax-Network/flax-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 Flax 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 flax-blockchain-gui 32 | 33 | $ErrorActionPreference = "SilentlyContinue" 34 | npm install --loglevel=error 35 | npm audit fix 36 | npm run build 37 | py ..\installhelper.py 38 | 39 | Write-Output "" 40 | Write-Output "Flax blockchain Install-gui.ps1 completed." 41 | Write-Output "" 42 | Write-Output "Type 'cd flax-blockchain-gui' and then 'npm run electron' to start the GUI." 43 | } finally { 44 | Pop-Location 45 | } 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flax-blockchain 2 | 3 | **Flax** is a modern community-centric green cryptocurrency based on a proof-of-space-and-time consensus algorithm. It is a community-supported fork of the [Chia Network](https://github.com/Chia-Network/chia-blockchain) codebase. 4 | -------------------------------------------------------------------------------- /activated.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | $script_directory = Split-Path $MyInvocation.MyCommand.Path -Parent 4 | 5 | $command = $args[0] 6 | $parameters = [System.Collections.ArrayList]$args 7 | $parameters.RemoveAt(0) 8 | 9 | & $script_directory/venv/Scripts/Activate.ps1 10 | & $command @parameters 11 | 12 | exit $LASTEXITCODE 13 | -------------------------------------------------------------------------------- /activated.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from __future__ import annotations 4 | 5 | import os 6 | import pathlib 7 | import subprocess 8 | import sys 9 | 10 | here = pathlib.Path(__file__).parent 11 | 12 | 13 | def main(*args: str) -> int: 14 | if len(args) == 0: 15 | print("Parameters required") 16 | return 1 17 | 18 | if sys.platform == "win32": 19 | script = "activated.ps1" 20 | command = ["powershell", os.fspath(here.joinpath(script)), *args] 21 | else: 22 | script = "activated.sh" 23 | command = ["sh", os.fspath(here.joinpath(script)), *args] 24 | 25 | completed_process = subprocess.run(command) 26 | 27 | return completed_process.returncode 28 | 29 | 30 | sys.exit(main(*sys.argv[1:])) 31 | -------------------------------------------------------------------------------- /activated.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -o errexit 4 | 5 | SCRIPT_DIRECTORY=$(cd -- "$(dirname -- "$0")"; pwd) 6 | # shellcheck disable=SC1091 7 | . "${SCRIPT_DIRECTORY}/venv/bin/activate" 8 | 9 | "$@" 10 | -------------------------------------------------------------------------------- /benchmarks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/benchmarks/__init__.py -------------------------------------------------------------------------------- /benchmarks/clvm_generator.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/benchmarks/clvm_generator.bin -------------------------------------------------------------------------------- /benchmarks/jsonify.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import random 4 | from time import perf_counter 5 | 6 | from 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/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/build_scripts/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/build_scripts/assets/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/deb/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/build_scripts/assets/deb/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/deb/control.j2: -------------------------------------------------------------------------------- 1 | Package: flax-blockchain-cli 2 | Version: {{ FLAX_INSTALLER_VERSION }} 3 | Architecture: {{ PLATFORM }} 4 | Maintainer: Flax Network Inc 5 | Description: Flax Blockchain 6 | Flax 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 | ln -s /opt/flax/resources/app.asar.unpacked/daemon/flax /usr/bin/flax || true 7 | -------------------------------------------------------------------------------- /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/flax || true 7 | -------------------------------------------------------------------------------- /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/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/build_scripts/assets/dmg/__init__.py -------------------------------------------------------------------------------- /build_scripts/assets/dmg/background.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/build_scripts/assets/dmg/background.tiff -------------------------------------------------------------------------------- /build_scripts/assets/rpm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/build_scripts/assets/rpm/__init__.py -------------------------------------------------------------------------------- /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/flax/resources/app.asar.unpacked/daemon/flax /usr/bin/flax || true 7 | -------------------------------------------------------------------------------- /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/flax || true 7 | -------------------------------------------------------------------------------- /build_scripts/clean-runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/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 flax_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 flax-blockchain-gui/build || true 15 | rm -rf flax-blockchain-gui/daemon || true 16 | rm -rf flax-blockchain-gui/node_modules || true 17 | rm flax-blockchain-gui/temp.json || true 18 | ( cd "$PWD/flax-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/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/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/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/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": "^23.5.0", 14 | "lerna": "^5.5.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /build_scripts/npm_macos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/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 | "@chia-network/notarize-cli": "^0.2.2", 14 | "dmg-license": "^1.0.11", 15 | "electron-builder": "^23.5.1", 16 | "lerna": "^5.5.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /build_scripts/npm_windows/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/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": "^23.5.1", 14 | "lerna": "^5.5.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /flax/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pkg_resources import DistributionNotFound, get_distribution, resource_filename 4 | 5 | try: 6 | __version__ = get_distribution("flax-blockchain").version 7 | except DistributionNotFound: 8 | # package is not installed 9 | __version__ = "unknown" 10 | 11 | PYINSTALLER_SPEC_PATH = resource_filename("flax", "pyinstaller.spec") 12 | -------------------------------------------------------------------------------- /flax/clvm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/clvm/__init__.py -------------------------------------------------------------------------------- /flax/clvm/singleton.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.wallet.puzzles.load_clvm import load_clvm_maybe_recompile 4 | 5 | P2_SINGLETON_MOD = load_clvm_maybe_recompile("p2_singleton.clvm") 6 | SINGLETON_TOP_LAYER_MOD = load_clvm_maybe_recompile("singleton_top_layer.clvm") 7 | SINGLETON_LAUNCHER = load_clvm_maybe_recompile("singleton_launcher.clvm") 8 | -------------------------------------------------------------------------------- /flax/cmds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/cmds/__init__.py -------------------------------------------------------------------------------- /flax/cmds/plotters.py: -------------------------------------------------------------------------------- 1 | import click 2 | from flax.plotters.plotters import call_plotters 3 | 4 | 5 | @click.command( 6 | "plotters", 7 | short_help="Advanced plotting options", 8 | context_settings={"ignore_unknown_options": True}, 9 | add_help_option=False, 10 | ) 11 | @click.pass_context 12 | @click.argument("args", nargs=-1) 13 | def plotters_cmd(ctx: click.Context, args): 14 | call_plotters(ctx.obj["root_path"], args) 15 | -------------------------------------------------------------------------------- /flax/cmds/start.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | from flax.util.config import load_config 4 | from flax.util.service_groups import all_groups 5 | 6 | 7 | @click.command("start", short_help="Start service groups") 8 | @click.option("-r", "--restart", is_flag=True, type=bool, help="Restart running services") 9 | @click.argument("group", type=click.Choice(list(all_groups())), nargs=-1, required=True) 10 | @click.pass_context 11 | def start_cmd(ctx: click.Context, restart: bool, group: str) -> None: 12 | import asyncio 13 | from flax.cmds.beta_funcs import warn_if_beta_enabled 14 | from .start_funcs import async_start 15 | 16 | root_path = ctx.obj["root_path"] 17 | config = load_config(root_path, "config.yaml") 18 | warn_if_beta_enabled(config) 19 | asyncio.run(async_start(root_path, config, group, restart, ctx.obj["force_legacy_keyring_migration"])) 20 | -------------------------------------------------------------------------------- /flax/cmds/units.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Dict 4 | 5 | # The rest of the codebase uses mojos everywhere. 6 | # Only use these units for user facing interfaces. 7 | units: Dict[str, int] = { 8 | "flax": 10**12, # 1 flax (XFX) is 1,000,000,000,000 mojo (1 trillion) 9 | "mojo": 1, 10 | "cat": 10**3, # 1 CAT is 1000 CAT mojos 11 | } 12 | -------------------------------------------------------------------------------- /flax/consensus/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/consensus/__init__.py -------------------------------------------------------------------------------- /flax/consensus/coinbase.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from blspy import G1Element 4 | 5 | from flax.types.blockchain_format.coin import Coin 6 | from flax.types.blockchain_format.sized_bytes import bytes32 7 | from flax.util.ints import uint32, uint64 8 | from flax.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import puzzle_hash_for_pk 9 | 10 | 11 | def create_puzzlehash_for_pk(pub_key: G1Element) -> bytes32: 12 | return puzzle_hash_for_pk(pub_key) 13 | 14 | 15 | def pool_parent_id(block_height: uint32, genesis_challenge: bytes32) -> bytes32: 16 | return bytes32(genesis_challenge[:16] + block_height.to_bytes(16, "big")) 17 | 18 | 19 | def farmer_parent_id(block_height: uint32, genesis_challenge: bytes32) -> bytes32: 20 | return bytes32(genesis_challenge[16:] + block_height.to_bytes(16, "big")) 21 | 22 | 23 | def create_pool_coin(block_height: uint32, puzzle_hash: bytes32, reward: uint64, genesis_challenge: bytes32) -> Coin: 24 | parent_id = pool_parent_id(block_height, genesis_challenge) 25 | return Coin(parent_id, puzzle_hash, reward) 26 | 27 | 28 | def create_farmer_coin(block_height: uint32, puzzle_hash: bytes32, reward: uint64, genesis_challenge: bytes32) -> Coin: 29 | parent_id = farmer_parent_id(block_height, genesis_challenge) 30 | return Coin(parent_id, puzzle_hash, reward) 31 | -------------------------------------------------------------------------------- /flax/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 | -------------------------------------------------------------------------------- /flax/consensus/cost_calculator.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from flax.types.spend_bundle_conditions import SpendBundleConditions 7 | from flax.util.ints import uint16, uint64 8 | from flax.util.streamable import Streamable, streamable 9 | 10 | 11 | @streamable 12 | @dataclass(frozen=True) 13 | class NPCResult(Streamable): 14 | error: Optional[uint16] 15 | conds: Optional[SpendBundleConditions] 16 | cost: uint64 # The total cost of the block, including CLVM cost, cost of 17 | # conditions and cost of bytes 18 | -------------------------------------------------------------------------------- /flax/consensus/find_fork_point.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Union 4 | 5 | from flax.consensus.block_record import BlockRecord 6 | from flax.consensus.blockchain_interface import BlockchainInterface 7 | from flax.types.header_block import HeaderBlock 8 | 9 | 10 | def find_fork_point_in_chain( 11 | blocks: BlockchainInterface, 12 | block_1: Union[BlockRecord, HeaderBlock], 13 | block_2: Union[BlockRecord, HeaderBlock], 14 | ) -> int: 15 | """Tries to find height where new chain (block_2) diverged from block_1 (assuming prev blocks 16 | are all included in chain) 17 | Returns -1 if chains have no common ancestor 18 | * assumes the fork point is loaded in blocks 19 | """ 20 | while block_2.height > 0 or block_1.height > 0: 21 | if block_2.height > block_1.height: 22 | block_2 = blocks.block_record(block_2.prev_hash) 23 | elif block_1.height > block_2.height: 24 | block_1 = blocks.block_record(block_1.prev_hash) 25 | else: 26 | if block_2.header_hash == block_1.header_hash: 27 | return block_2.height 28 | block_2 = blocks.block_record(block_2.prev_hash) 29 | block_1 = blocks.block_record(block_1.prev_hash) 30 | if block_2 != block_1: 31 | # All blocks are different 32 | return -1 33 | 34 | # First block is the same 35 | return 0 36 | -------------------------------------------------------------------------------- /flax/consensus/pos_quality.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.util.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.762 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 | -------------------------------------------------------------------------------- /flax/daemon/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/daemon/__init__.py -------------------------------------------------------------------------------- /flax/data_layer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/data_layer/__init__.py -------------------------------------------------------------------------------- /flax/data_layer/data_layer_api.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import logging 4 | 5 | from flax.data_layer.data_layer import DataLayer 6 | from flax.server.server import FlaxServer 7 | 8 | 9 | class DataLayerAPI: 10 | data_layer: DataLayer 11 | 12 | def __init__(self, data_layer: DataLayer) -> None: 13 | self.data_layer = data_layer 14 | 15 | # def _set_state_changed_callback(self, callback: Callable): 16 | # self.full_node.state_changed_callback = callback 17 | 18 | @property 19 | def server(self) -> FlaxServer: 20 | return self.data_layer.server 21 | 22 | @property 23 | def log(self) -> logging.Logger: 24 | return self.data_layer.log 25 | 26 | @property 27 | def api_ready(self) -> bool: 28 | return self.data_layer.initialized 29 | -------------------------------------------------------------------------------- /flax/data_layer/data_layer_errors.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Iterable, List 4 | 5 | from flax.types.blockchain_format.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, tree_ids: List[bytes32]) -> None: 18 | super().__init__( 19 | build_message_with_hashes( 20 | message="Found trees with generations not properly incrementing:", 21 | bytes_objects=tree_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 | -------------------------------------------------------------------------------- /flax/data_layer/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/data_layer/util/__init__.py -------------------------------------------------------------------------------- /flax/farmer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/farmer/__init__.py -------------------------------------------------------------------------------- /flax/full_node/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/full_node/__init__.py -------------------------------------------------------------------------------- /flax/full_node/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 flax.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 | -------------------------------------------------------------------------------- /flax/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 = 100 # First bucket after zero value 6 | MAX_FEE_RATE = 40000000 # Mojo per 1000 cost unit 7 | INFINITE_FEE_RATE = 1000000000 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 | SUFFICIENT_FEE_TXS = 0.1 # Require an avg of 0.1 tx in the combined fee rate bucket per block to have stat significance 33 | 34 | FEE_ESTIMATOR_VERSION = 1 35 | 36 | OLDEST_ESTIMATE_HISTORY = 6 * 1008 37 | -------------------------------------------------------------------------------- /flax/full_node/fee_history.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import List 5 | 6 | from flax.util.ints import uint8, uint32 7 | from flax.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 | -------------------------------------------------------------------------------- /flax/full_node/pending_tx_cache.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Dict 4 | 5 | from flax.types.blockchain_format.sized_bytes import bytes32 6 | from flax.types.mempool_item import MempoolItem 7 | 8 | 9 | class PendingTxCache: 10 | _cache_max_total_cost: int 11 | _cache_cost: int 12 | _txs: Dict[bytes32, MempoolItem] 13 | 14 | def __init__(self, cost_limit: int): 15 | self._cache_max_total_cost = cost_limit 16 | self._cache_cost = 0 17 | self._txs = {} 18 | 19 | def add(self, item: MempoolItem) -> None: 20 | """ 21 | Adds SpendBundles that have failed to be added to the pool in potential tx set. 22 | This is later used to retry to add them. 23 | """ 24 | if item.spend_bundle_name in self._txs: 25 | return None 26 | 27 | self._txs[item.spend_bundle_name] = item 28 | self._cache_cost += item.cost 29 | 30 | while self._cache_cost > self._cache_max_total_cost: 31 | first_in = list(self._txs.keys())[0] 32 | self._cache_cost -= self._txs[first_in].cost 33 | self._txs.pop(first_in) 34 | 35 | def drain(self) -> Dict[bytes32, MempoolItem]: 36 | ret = self._txs 37 | self._txs = {} 38 | self._cache_cost = 0 39 | return ret 40 | 41 | def cost(self) -> int: 42 | return self._cache_cost 43 | -------------------------------------------------------------------------------- /flax/full_node/signage_point.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from flax.types.blockchain_format.vdf import VDFInfo, VDFProof 7 | from flax.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 | -------------------------------------------------------------------------------- /flax/harvester/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/harvester/__init__.py -------------------------------------------------------------------------------- /flax/introducer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/introducer/__init__.py -------------------------------------------------------------------------------- /flax/plot_sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/plot_sync/__init__.py -------------------------------------------------------------------------------- /flax/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 flax.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 | -------------------------------------------------------------------------------- /flax/plotters/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/plotters/__init__.py -------------------------------------------------------------------------------- /flax/plotting/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/plotting/__init__.py -------------------------------------------------------------------------------- /flax/pools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/pools/__init__.py -------------------------------------------------------------------------------- /flax/protocols/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/protocols/__init__.py -------------------------------------------------------------------------------- /flax/protocols/introducer_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import List 5 | 6 | from flax.types.peer_info import TimestampedPeerInfo 7 | from flax.util.streamable import Streamable, streamable 8 | 9 | """ 10 | Protocol to introducer 11 | Note: When changing this file, also change protocol_message_types.py, and the protocol version in shared_protocol.py 12 | """ 13 | 14 | 15 | @streamable 16 | @dataclass(frozen=True) 17 | class RequestPeersIntroducer(Streamable): 18 | """ 19 | Return full list of peers 20 | """ 21 | 22 | 23 | @streamable 24 | @dataclass(frozen=True) 25 | class RespondPeersIntroducer(Streamable): 26 | peer_list: List[TimestampedPeerInfo] 27 | -------------------------------------------------------------------------------- /flax/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 | -------------------------------------------------------------------------------- /flax/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/py.typed -------------------------------------------------------------------------------- /flax/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/rpc/__init__.py -------------------------------------------------------------------------------- /flax/rpc/timelord_rpc_api.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any, Dict, List, Optional 4 | 5 | from flax.rpc.rpc_server import Endpoint 6 | from flax.timelord.timelord import Timelord 7 | from flax.util.ws_message import WsRpcMessage, create_payload_dict 8 | 9 | 10 | class TimelordRpcApi: 11 | def __init__(self, timelord: Timelord): 12 | self.service = timelord 13 | self.service_name = "flax_timelord" 14 | 15 | def get_routes(self) -> Dict[str, Endpoint]: 16 | return {} 17 | 18 | async def _state_changed(self, change: str, change_data: Optional[Dict[str, Any]] = None) -> List[WsRpcMessage]: 19 | payloads = [] 20 | 21 | if change_data is None: 22 | change_data = {} 23 | 24 | if change in ("finished_pot", "new_compact_proof", "skipping_peak", "new_peak"): 25 | payloads.append(create_payload_dict(change, change_data, self.service_name, "metrics")) 26 | 27 | return payloads 28 | -------------------------------------------------------------------------------- /flax/rpc/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import logging 4 | import traceback 5 | from typing import Callable 6 | 7 | import aiohttp 8 | 9 | from flax.util.json_util import obj_to_response 10 | 11 | log = logging.getLogger(__name__) 12 | 13 | 14 | def wrap_http_handler(f) -> Callable: 15 | async def inner(request) -> aiohttp.web.Response: 16 | request_data = await request.json() 17 | try: 18 | res_object = await f(request_data) 19 | if res_object is None: 20 | res_object = {} 21 | if "success" not in res_object: 22 | res_object["success"] = True 23 | except Exception as e: 24 | tb = traceback.format_exc() 25 | log.warning(f"Error while handling message: {tb}") 26 | if len(e.args) > 0: 27 | res_object = {"success": False, "error": f"{e.args[0]}"} 28 | else: 29 | res_object = {"success": False, "error": f"{e}"} 30 | 31 | return obj_to_response(res_object) 32 | 33 | return inner 34 | -------------------------------------------------------------------------------- /flax/seeder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/seeder/__init__.py -------------------------------------------------------------------------------- /flax/server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/server/__init__.py -------------------------------------------------------------------------------- /flax/server/ssl_context.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path 4 | from typing import Dict 5 | 6 | 7 | def public_ssl_paths(path: Path, config: Dict): 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): 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): 22 | return ( 23 | path / config["private_ssl_ca"]["crt"], 24 | path / config["private_ssl_ca"]["key"], 25 | ) 26 | 27 | 28 | def flax_ssl_ca_paths(path: Path, config: Dict): 29 | return ( 30 | path / config["flax_ssl_ca"]["crt"], 31 | path / config["flax_ssl_ca"]["key"], 32 | ) 33 | -------------------------------------------------------------------------------- /flax/simulator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/simulator/__init__.py -------------------------------------------------------------------------------- /flax/simulator/simulator_constants.py: -------------------------------------------------------------------------------- 1 | if __name__ == "__main__": 2 | from flax.util.default_root import DEFAULT_ROOT_PATH 3 | from flax.simulator.block_tools import create_block_tools, test_constants 4 | from tests.util.keyring import TempKeyring 5 | 6 | with TempKeyring() as keychain: 7 | # TODO: mariano: fix this with new consensus 8 | bt = create_block_tools(root_path=DEFAULT_ROOT_PATH, keychain=keychain) 9 | new_genesis_block = bt.create_genesis_block(test_constants, b"0") 10 | 11 | print(bytes(new_genesis_block)) 12 | -------------------------------------------------------------------------------- /flax/simulator/simulator_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from flax.types.blockchain_format.sized_bytes import bytes32 7 | from flax.util.ints import uint32 8 | from flax.util.streamable import Streamable, streamable 9 | 10 | 11 | @streamable 12 | @dataclass(frozen=True) 13 | class FarmNewBlockProtocol(Streamable): 14 | puzzle_hash: bytes32 15 | 16 | 17 | @streamable 18 | @dataclass(frozen=True) 19 | class ReorgProtocol(Streamable): 20 | old_index: uint32 21 | new_index: uint32 22 | puzzle_hash: bytes32 23 | seed: Optional[bytes32] 24 | 25 | 26 | @streamable 27 | @dataclass(frozen=True) 28 | class GetAllCoinsProtocol(Streamable): 29 | include_spent_coins: bool 30 | -------------------------------------------------------------------------------- /flax/simulator/socket.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import secrets 4 | import socket 5 | from typing import Set 6 | 7 | recent_ports: Set[int] = set() 8 | 9 | 10 | def find_available_listen_port(name: str = "free") -> int: 11 | global recent_ports 12 | 13 | while True: 14 | port = secrets.randbelow(0xFFFF - 1024) + 1024 15 | if port in recent_ports: 16 | continue 17 | 18 | with socket.socket() as s: 19 | try: 20 | s.bind(("127.0.0.1", port)) 21 | except OSError: 22 | recent_ports.add(port) 23 | continue 24 | 25 | recent_ports.add(port) 26 | print(f"{name} port: {port}") 27 | return port 28 | -------------------------------------------------------------------------------- /flax/ssl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/ssl/__init__.py -------------------------------------------------------------------------------- /flax/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 | -------------------------------------------------------------------------------- /flax/ssl/flax_ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDKTCCAhGgAwIBAgIUNgtAPGy+jcZhwAivtrGUIkIQ89EwDQYJKoZIhvcNAQEL 3 | BQAwRDENMAsGA1UECgwERmxheDEQMA4GA1UEAwwHRmxheCBDQTEhMB8GA1UECwwY 4 | T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIxMDYxNTEwMDE0NloXDTMxMDYx 5 | MzEwMDE0NlowRDENMAsGA1UECgwERmxheDEQMA4GA1UEAwwHRmxheCBDQTEhMB8G 6 | A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF 7 | AAOCAQ8AMIIBCgKCAQEAmqcnpRQBo8bcIF35HuwcuuLEtOVTEM+ZW8kWy6SWyBIG 8 | jd10AuldbSPgXoN6Gez/vVWXWpJkc5pGc4KgdMtSUalaQutJglqMEKz0B+0MLpiR 9 | pBY7vE0aPuRAsIdtnjzrEzkeiw4GdfjBa2IOz+aheJReXlQgAxiR0lEhj7fHqCQY 10 | gQ7TZnCnQ+rMKH5c72RYzbSitC614rqa1pgDheHSnZAF0Z6AByZCExCcz3EC0hJI 11 | Az8ln2HVGt3xurb8JmZGRlxZtU4ei3ZIyYjKfE2ApFQkZ8NR8IMbBgODvuL+c7kH 12 | 2rDfM4mgix+1tRAYJsh/9YjXYgv/hjjXgh7WrkyA7QIDAQABoxMwETAPBgNVHRMB 13 | Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBZGE0C3YSWWZ/wxYCeZU+tgjGM 14 | pvUxrdKZmnuf8ErK048U1y+AD4a5LwcJIcwiIL/S5EKHAbL2C+kMrUzGYI3eAqNt 15 | fMcFvh/izpENUa86X0zLiW0H55zKCLK1CynI0uJ+JbpfuIDQkU+fLtSXhAMvu1Ow 16 | P+F3umj1RzVVhDAYWfq5yuainceyYAZVex2B++K/L6FGP+Sp6erEamKIwbTJ6Lvb 17 | B/GS927CXVmi/fmKDs8CvuREJB7VB70PW1ZapsBx/NKmCYEjvCr46aE3VhF2/8wp 18 | fk4F/oveThwsZwyV2kqmx7EEFLYZrZtCGG0IX4hyqYBDEZ8m0pNoqZIM2lzv 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /flax/timelord/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/timelord/__init__.py -------------------------------------------------------------------------------- /flax/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 | -------------------------------------------------------------------------------- /flax/types/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/types/__init__.py -------------------------------------------------------------------------------- /flax/types/announcement.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from flax.types.blockchain_format.sized_bytes import bytes32 7 | from flax.util.hash import std_hash 8 | 9 | 10 | @dataclass(frozen=True) 11 | class Announcement: 12 | origin_info: bytes32 13 | message: bytes 14 | morph_bytes: Optional[bytes] = None # CATs morph their announcements and other puzzles may choose to do so too 15 | 16 | def name(self) -> bytes32: 17 | if self.morph_bytes is not None: 18 | message: bytes = std_hash(self.morph_bytes + self.message) 19 | else: 20 | message = self.message 21 | return std_hash(bytes(self.origin_info + message)) 22 | 23 | def __str__(self): 24 | return self.name().decode("utf-8") 25 | -------------------------------------------------------------------------------- /flax/types/block_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import List, Optional 4 | 5 | from typing_extensions import Protocol 6 | 7 | from flax.types.blockchain_format.program import SerializedProgram 8 | from flax.types.blockchain_format.sized_bytes import bytes32 9 | from flax.util.ints import uint32 10 | 11 | 12 | class BlockInfo(Protocol): 13 | @property 14 | def prev_header_hash(self) -> bytes32: 15 | pass 16 | 17 | @property 18 | def transactions_generator(self) -> Optional[SerializedProgram]: 19 | pass 20 | 21 | @property 22 | def transactions_generator_ref_list(self) -> List[uint32]: 23 | pass 24 | -------------------------------------------------------------------------------- /flax/types/blockchain_format/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/types/blockchain_format/__init__.py -------------------------------------------------------------------------------- /flax/types/blockchain_format/classgroup.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from flax.consensus.constants import ConsensusConstants 6 | from flax.types.blockchain_format.sized_bytes import bytes100 7 | from flax.util.streamable import Streamable, streamable 8 | 9 | 10 | @streamable 11 | @dataclass(frozen=True) 12 | class ClassgroupElement(Streamable): 13 | """ 14 | Represents a classgroup element (a,b,c) where a, b, and c are 512 bit signed integers. However this is using 15 | a compressed representation. VDF outputs are a single classgroup element. VDF proofs can also be one classgroup 16 | element (or multiple). 17 | """ 18 | 19 | data: bytes100 20 | 21 | @staticmethod 22 | def from_bytes(data) -> "ClassgroupElement": 23 | if len(data) < 100: 24 | data += b"\x00" * (100 - len(data)) 25 | return ClassgroupElement(bytes100(data)) 26 | 27 | @staticmethod 28 | def get_default_element() -> "ClassgroupElement": 29 | # Bit 3 in the first byte of serialized compressed form indicates if 30 | # it's the default generator element. 31 | return ClassgroupElement.from_bytes(b"\x08") 32 | 33 | @staticmethod 34 | def get_size(constants: ConsensusConstants): 35 | return 100 36 | -------------------------------------------------------------------------------- /flax/types/blockchain_format/coin.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import List, Union 4 | 5 | from chia_rs import Coin 6 | 7 | from flax.types.blockchain_format.sized_bytes import bytes32 8 | from flax.util.hash import std_hash 9 | from flax.util.ints import uint64 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 | -------------------------------------------------------------------------------- /flax/types/blockchain_format/pool_target.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from flax.types.blockchain_format.sized_bytes import bytes32 6 | from flax.util.ints import uint32 7 | from flax.util.streamable import Streamable, streamable 8 | 9 | 10 | @streamable 11 | @dataclass(frozen=True) 12 | class PoolTarget(Streamable): 13 | puzzle_hash: bytes32 14 | max_height: uint32 # A max height of 0 means it is valid forever 15 | -------------------------------------------------------------------------------- /flax/types/blockchain_format/sized_bytes.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.util.byte_types import SizedBytes 4 | 5 | 6 | class bytes4(SizedBytes): 7 | _size = 4 8 | 9 | 10 | class bytes8(SizedBytes): 11 | _size = 8 12 | 13 | 14 | class bytes32(SizedBytes): 15 | _size = 32 16 | 17 | 18 | class bytes48(SizedBytes): 19 | _size = 48 20 | 21 | 22 | class bytes96(SizedBytes): 23 | _size = 96 24 | 25 | 26 | class bytes100(SizedBytes): 27 | _size = 100 28 | 29 | 30 | class bytes480(SizedBytes): 31 | _size = 480 32 | -------------------------------------------------------------------------------- /flax/types/blockchain_format/sub_epoch_summary.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from flax.types.blockchain_format.sized_bytes import bytes32 7 | from flax.util.ints import uint8, uint64 8 | from flax.util.streamable import Streamable, streamable 9 | 10 | 11 | @streamable 12 | @dataclass(frozen=True) 13 | class SubEpochSummary(Streamable): 14 | prev_subepoch_summary_hash: bytes32 15 | reward_chain_hash: bytes32 # hash of reward chain at end of last segment 16 | num_blocks_overflow: uint8 # How many more blocks than 384*(N-1) 17 | new_difficulty: Optional[uint64] # Only once per epoch (diff adjustment) 18 | new_sub_slot_iters: Optional[uint64] # Only once per epoch (diff adjustment) 19 | -------------------------------------------------------------------------------- /flax/types/clvm_cost.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import NewType 4 | 5 | from flax.util.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 | -------------------------------------------------------------------------------- /flax/types/coin_solution.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | from .coin_spend import CoinSpend as CoinSolution # noqa lgtm[py/unused-import] 4 | 5 | 6 | warnings.warn("`CoinSolution` is now `CoinSpend`") 7 | -------------------------------------------------------------------------------- /flax/types/coin_spend.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from typing import List 3 | from flax.types.blockchain_format.coin import Coin 4 | from flax.types.blockchain_format.program import SerializedProgram, INFINITE_COST 5 | from flax.util.chain_utils import additions_for_solution, fee_for_solution 6 | from flax.util.streamable import Streamable, streamable 7 | 8 | 9 | @streamable 10 | @dataclass(frozen=True) 11 | class CoinSpend(Streamable): 12 | """ 13 | This is a rather disparate data structure that validates coin transfers. It's generally populated 14 | with data from different sources, since burned coins are identified by name, so it is built up 15 | more often that it is streamed. 16 | """ 17 | 18 | coin: Coin 19 | puzzle_reveal: SerializedProgram 20 | solution: SerializedProgram 21 | 22 | # TODO: this function should be moved out of the full node. It cannot be 23 | # called on untrusted input 24 | def additions(self) -> List[Coin]: 25 | return additions_for_solution(self.coin.name(), self.puzzle_reveal, self.solution, INFINITE_COST) 26 | 27 | # TODO: this function should be moved out of the full node. It cannot be 28 | # called on untrusted input 29 | def reserved_fee(self) -> int: 30 | return fee_for_solution(self.puzzle_reveal, self.solution, INFINITE_COST) 31 | -------------------------------------------------------------------------------- /flax/types/condition_with_args.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import List 5 | 6 | from flax.types.condition_opcodes import ConditionOpcode 7 | from flax.util.streamable import Streamable, streamable 8 | 9 | 10 | @streamable 11 | @dataclass(frozen=True) 12 | class ConditionWithArgs(Streamable): 13 | """ 14 | This structure is used to store parsed CLVM conditions 15 | Conditions in CLVM have either format of (opcode, var1) or (opcode, var1, var2) 16 | """ 17 | 18 | opcode: ConditionOpcode 19 | vars: List[bytes] 20 | -------------------------------------------------------------------------------- /flax/types/end_of_slot_bundle.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from flax.types.blockchain_format.slots import ( 7 | ChallengeChainSubSlot, 8 | InfusedChallengeChainSubSlot, 9 | RewardChainSubSlot, 10 | SubSlotProofs, 11 | ) 12 | from flax.util.streamable import Streamable, streamable 13 | 14 | 15 | @streamable 16 | @dataclass(frozen=True) 17 | class EndOfSubSlotBundle(Streamable): 18 | challenge_chain: ChallengeChainSubSlot 19 | infused_challenge_chain: Optional[InfusedChallengeChainSubSlot] 20 | reward_chain: RewardChainSubSlot 21 | proofs: SubSlotProofs 22 | -------------------------------------------------------------------------------- /flax/types/fee_rate.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import math 4 | from dataclasses import dataclass 5 | 6 | import typing_extensions 7 | 8 | from flax.types.clvm_cost import CLVMCost 9 | from flax.types.mojos import Mojos 10 | from flax.util.ints import uint64 11 | from flax.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 XFX/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 | -------------------------------------------------------------------------------- /flax/types/generator_types.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from typing import List 3 | from flax.types.blockchain_format.program import SerializedProgram 4 | from flax.util.ints import uint32 5 | from flax.util.streamable import Streamable, streamable 6 | 7 | 8 | class GeneratorBlockCacheInterface: 9 | def get_generator_for_block_height(self, height: uint32) -> SerializedProgram: 10 | # Requested block must be a transaction block 11 | pass 12 | 13 | 14 | @dataclass(frozen=True) 15 | class CompressorArg: 16 | """`CompressorArg` is used as input to the Block Compressor""" 17 | 18 | block_height: uint32 19 | generator: SerializedProgram 20 | start: int 21 | end: int 22 | 23 | 24 | @streamable 25 | @dataclass(frozen=True) 26 | class BlockGenerator(Streamable): 27 | program: SerializedProgram 28 | generator_refs: List[SerializedProgram] 29 | 30 | # the heights are only used when creating new blocks, never when validating 31 | block_height_list: List[uint32] 32 | -------------------------------------------------------------------------------- /flax/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 | -------------------------------------------------------------------------------- /flax/types/mempool_item.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import List 5 | 6 | from flax.consensus.cost_calculator import NPCResult 7 | from flax.types.blockchain_format.coin import Coin 8 | from flax.types.blockchain_format.sized_bytes import bytes32 9 | from flax.types.spend_bundle import SpendBundle 10 | from flax.util.ints import uint32, uint64 11 | from flax.util.streamable import Streamable, streamable 12 | 13 | 14 | @streamable 15 | @dataclass(frozen=True) 16 | class MempoolItem(Streamable): 17 | spend_bundle: SpendBundle 18 | fee: uint64 19 | npc_result: NPCResult 20 | cost: uint64 21 | spend_bundle_name: bytes32 22 | additions: List[Coin] 23 | removals: List[Coin] 24 | height_added_to_mempool: uint32 25 | 26 | def __lt__(self, other: MempoolItem) -> bool: 27 | return self.fee_per_cost < other.fee_per_cost 28 | 29 | @property 30 | def fee_per_cost(self) -> float: 31 | return int(self.fee) / int(self.cost) 32 | 33 | @property 34 | def name(self) -> bytes32: 35 | return self.spend_bundle_name 36 | -------------------------------------------------------------------------------- /flax/types/mempool_submission_status.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Dict, Optional, Union 5 | 6 | from flax.types.mempool_inclusion_status import MempoolInclusionStatus 7 | from flax.util.ints import uint8 8 | from flax.util.streamable import Streamable, streamable 9 | 10 | 11 | @streamable 12 | @dataclass(frozen=True) 13 | class MempoolSubmissionStatus(Streamable): 14 | """ 15 | :sent_to: in `TradeRecord` and `TransactionRecord` are a 16 | Tuple of (peer_id: str, status: MempoolInclusionStatus, error: Optional[str]) 17 | MempoolInclusionStatus is represented as a uint8 in those structs so they can be `Streamable` 18 | """ 19 | 20 | peer_id: str 21 | inclusion_status: uint8 # MempoolInclusionStatus 22 | error_msg: Optional[str] 23 | 24 | def to_json_dict_convenience(self) -> Dict[str, Union[str, MempoolInclusionStatus, Optional[str]]]: 25 | formatted = self.to_json_dict() 26 | formatted["inclusion_status"] = MempoolInclusionStatus(self.inclusion_status).name 27 | return formatted 28 | 29 | def __str__(self) -> str: 30 | return f"{self.to_json_dict_convenience()}" 31 | -------------------------------------------------------------------------------- /flax/types/mojos.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import NewType 4 | 5 | from flax.util.ints import uint64 6 | 7 | Mojos = NewType("Mojos", uint64) 8 | -------------------------------------------------------------------------------- /flax/types/spend_bundle_conditions.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from chia_rs import Spend, SpendBundleConditions 4 | 5 | __all__ = ["Spend", "SpendBundleConditions"] 6 | -------------------------------------------------------------------------------- /flax/types/transaction_queue_entry.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import Optional 5 | 6 | from flax.server.ws_connection import WSFlaxConnection 7 | from flax.types.blockchain_format.sized_bytes import bytes32 8 | from flax.types.spend_bundle import SpendBundle 9 | 10 | 11 | @dataclass(frozen=True) 12 | class TransactionQueueEntry: 13 | """ 14 | A transaction received from peer. This is put into a queue, and not yet in the mempool. 15 | """ 16 | 17 | transaction: SpendBundle 18 | transaction_bytes: Optional[bytes] 19 | spend_name: bytes32 20 | peer: Optional[WSFlaxConnection] 21 | test: bool 22 | 23 | def __lt__(self, other): 24 | return self.spend_name < other.spend_name 25 | 26 | def __le__(self, other): 27 | return self.spend_name <= other.spend_name 28 | 29 | def __gt__(self, other): 30 | return self.spend_name > other.spend_name 31 | 32 | def __ge__(self, other): 33 | return self.spend_name >= other.spend_name 34 | -------------------------------------------------------------------------------- /flax/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/util/__init__.py -------------------------------------------------------------------------------- /flax/util/check_fork_next_block.py: -------------------------------------------------------------------------------- 1 | from typing import List, Callable 2 | 3 | from flax.consensus.blockchain_interface import BlockchainInterface 4 | from flax.util.ints import uint32 5 | 6 | 7 | async def check_fork_next_block( 8 | blockchain: BlockchainInterface, fork_point_height: uint32, peers_with_peak: List, check_block_future: Callable 9 | ): 10 | our_peak_height = blockchain.get_peak_height() 11 | ses_heigths = blockchain.get_ses_heights() 12 | if len(ses_heigths) > 2 and our_peak_height is not None: 13 | ses_heigths.sort() 14 | max_fork_ses_height = ses_heigths[-3] 15 | potential_peek = uint32(our_peak_height + 1) 16 | # This is the fork point in SES in the case where no fork was detected 17 | if blockchain.get_peak_height() is not None and fork_point_height == max_fork_ses_height: 18 | for peer in peers_with_peak.copy(): 19 | if peer.closed: 20 | peers_with_peak.remove(peer) 21 | continue 22 | # Grab a block at peak + 1 and check if fork point is actually our current height 23 | if await check_block_future(peer, potential_peek, blockchain): 24 | fork_point_height = our_peak_height 25 | break 26 | return fork_point_height 27 | -------------------------------------------------------------------------------- /flax/util/chunks.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Iterator, List, TypeVar 4 | 5 | T = TypeVar("T") 6 | 7 | 8 | def chunks(in_list: List[T], size: int) -> Iterator[List[T]]: 9 | size = max(1, size) 10 | for i in range(0, len(in_list), size): 11 | yield in_list[i : i + size] 12 | -------------------------------------------------------------------------------- /flax/util/db_synchronous.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | 4 | def db_synchronous_on(setting: str) -> str: 5 | if setting == "on": 6 | return "NORMAL" 7 | if setting == "off": 8 | return "OFF" 9 | if setting == "full": 10 | return "FULL" 11 | 12 | # for now, default to synchronous=FULL mode. This can be made more 13 | # sophisticated in the future. There are still material performance 14 | # improvements to be had in cases where the risks are low. 15 | 16 | # e.g. 17 | # type = GetDriveTypeW(db_path) 18 | # if type == DRIVE_FIXED or type == DRIVE_RAMDISK: 19 | # return "OFF" 20 | 21 | return "FULL" 22 | -------------------------------------------------------------------------------- /flax/util/db_version.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import sqlite3 4 | 5 | import aiosqlite 6 | 7 | 8 | async def lookup_db_version(db: aiosqlite.Connection) -> int: 9 | try: 10 | cursor = await db.execute("SELECT * from database_version") 11 | row = await cursor.fetchone() 12 | if row is not None and row[0] == 2: 13 | return 2 14 | else: 15 | return 1 16 | except aiosqlite.OperationalError: 17 | # expects OperationalError('no such table: database_version') 18 | return 1 19 | 20 | 21 | async def set_db_version_async(db: aiosqlite.Connection, version: int) -> None: 22 | await db.execute("CREATE TABLE database_version(version int)") 23 | await db.execute("INSERT INTO database_version VALUES (?)", (version,)) 24 | await db.commit() 25 | 26 | 27 | def set_db_version(db: sqlite3.Connection, version: int) -> None: 28 | db.execute("CREATE TABLE database_version(version int)") 29 | db.execute("INSERT INTO database_version VALUES (?)", (version,)) 30 | db.commit() 31 | -------------------------------------------------------------------------------- /flax/util/default_root.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import os 4 | from pathlib import Path 5 | 6 | DEFAULT_ROOT_PATH = Path(os.path.expanduser(os.getenv("FLAX_ROOT", "~/.flax/mainnet"))).resolve() 7 | 8 | DEFAULT_KEYS_ROOT_PATH = Path(os.path.expanduser(os.getenv("FLAX_KEYS_ROOT", "~/.flax_keys"))).resolve() 9 | -------------------------------------------------------------------------------- /flax/util/hash.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from hashlib import sha256 4 | 5 | from flax.types.blockchain_format.sized_bytes import bytes32 6 | 7 | 8 | def std_hash(b, skip_bytes_conversion: bool = False) -> bytes32: 9 | """ 10 | The standard hash used in many places. 11 | """ 12 | if skip_bytes_conversion: 13 | return bytes32(sha256(b).digest()) 14 | else: 15 | return bytes32(sha256(bytes(b)).digest()) 16 | -------------------------------------------------------------------------------- /flax/util/inline_executor.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from concurrent.futures import Executor, Future 4 | from typing import Callable, TypeVar 5 | 6 | _T = TypeVar("_T") 7 | 8 | 9 | class InlineExecutor(Executor): 10 | _closing: bool = False 11 | 12 | def submit(self, fn: Callable[..., _T], *args, **kwargs) -> Future[_T]: # type: ignore 13 | if self._closing: 14 | raise RuntimeError("executor shutting down") 15 | 16 | f: Future[_T] = Future() 17 | try: 18 | f.set_result(fn(*args, **kwargs)) 19 | except BaseException as e: # lgtm[py/catch-base-exception] 20 | f.set_exception(e) 21 | return f 22 | 23 | def close(self) -> None: 24 | self._closing = True 25 | -------------------------------------------------------------------------------- /flax/util/ints.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.util.struct_stream import StructStream, parse_metadata_from_name 4 | 5 | 6 | @parse_metadata_from_name 7 | class int8(StructStream): 8 | pass 9 | 10 | 11 | @parse_metadata_from_name 12 | class uint8(StructStream): 13 | pass 14 | 15 | 16 | @parse_metadata_from_name 17 | class int16(StructStream): 18 | pass 19 | 20 | 21 | @parse_metadata_from_name 22 | class uint16(StructStream): 23 | pass 24 | 25 | 26 | @parse_metadata_from_name 27 | class int32(StructStream): 28 | pass 29 | 30 | 31 | @parse_metadata_from_name 32 | class uint32(StructStream): 33 | pass 34 | 35 | 36 | @parse_metadata_from_name 37 | class int64(StructStream): 38 | pass 39 | 40 | 41 | @parse_metadata_from_name 42 | class uint64(StructStream): 43 | pass 44 | 45 | 46 | @parse_metadata_from_name 47 | class uint128(StructStream): 48 | pass 49 | 50 | 51 | class int512(StructStream): 52 | PACK = None 53 | 54 | # Uses 65 bytes to fit in the sign bit 55 | SIZE = 65 56 | BITS = 512 57 | SIGNED = True 58 | 59 | # note that the boundaries for int512 is not what you might expect. We 60 | # encode these with one extra byte, but only allow a range of 61 | # [-INT512_MAX, INT512_MAX] 62 | MAXIMUM_EXCLUSIVE = 2**BITS 63 | MINIMUM = -(2**BITS) + 1 64 | -------------------------------------------------------------------------------- /flax/util/json_util.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import dataclasses 4 | import json 5 | from typing import Any 6 | 7 | from aiohttp import web 8 | 9 | from flax.wallet.util.wallet_types import WalletType 10 | 11 | 12 | class EnhancedJSONEncoder(json.JSONEncoder): 13 | """ 14 | Encodes bytes as hex strings with 0x, and converts all dataclasses to json. 15 | """ 16 | 17 | def default(self, o: Any): 18 | if dataclasses.is_dataclass(o): 19 | return o.to_json_dict() 20 | elif isinstance(o, WalletType): 21 | return o.name 22 | elif hasattr(type(o), "__bytes__"): 23 | return f"0x{bytes(o).hex()}" 24 | elif isinstance(o, bytes): 25 | return f"0x{o.hex()}" 26 | return super().default(o) 27 | 28 | 29 | def dict_to_json_str(o: Any) -> str: 30 | """ 31 | Converts a python object into json. 32 | """ 33 | json_str = json.dumps(o, cls=EnhancedJSONEncoder, sort_keys=True) 34 | return json_str 35 | 36 | 37 | def obj_to_response(o: Any) -> web.Response: 38 | """ 39 | Converts a python object into json. Used for RPC server which returns JSON. 40 | """ 41 | json_str = dict_to_json_str(o) 42 | return web.Response(body=json_str, content_type="application/json") 43 | -------------------------------------------------------------------------------- /flax/util/log_exceptions.py: -------------------------------------------------------------------------------- 1 | from contextlib import contextmanager 2 | import logging 3 | import traceback 4 | 5 | 6 | @contextmanager 7 | def log_exceptions(log: logging.Logger, *, consume: bool = False): 8 | try: 9 | yield 10 | except Exception as e: 11 | log.error(f"Caught Exception: {e}. Traceback: {traceback.format_exc()}") 12 | if not consume: 13 | raise 14 | -------------------------------------------------------------------------------- /flax/util/lru_cache.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from collections import OrderedDict 4 | from typing import Generic, Optional, TypeVar 5 | 6 | K = TypeVar("K") 7 | V = TypeVar("V") 8 | 9 | 10 | class LRUCache(Generic[K, V]): 11 | def __init__(self, capacity: int): 12 | self.cache: OrderedDict[K, V] = OrderedDict() 13 | self.capacity = capacity 14 | 15 | def get(self, key: K) -> Optional[V]: 16 | if key not in self.cache: 17 | return None 18 | else: 19 | self.cache.move_to_end(key) 20 | return self.cache[key] 21 | 22 | def put(self, key: K, value: V) -> None: 23 | self.cache[key] = value 24 | self.cache.move_to_end(key) 25 | if len(self.cache) > self.capacity: 26 | self.cache.popitem(last=False) 27 | 28 | def remove(self, key: K) -> None: 29 | self.cache.pop(key) 30 | -------------------------------------------------------------------------------- /flax/util/make_test_constants.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Dict 4 | 5 | from flax.consensus.constants import ConsensusConstants 6 | from flax.consensus.default_constants import DEFAULT_CONSTANTS 7 | 8 | 9 | def make_test_constants(test_constants_overrides: Dict) -> ConsensusConstants: 10 | return DEFAULT_CONSTANTS.replace(**test_constants_overrides) 11 | -------------------------------------------------------------------------------- /flax/util/partial_func.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | 4 | def partial_async_gen(f, *args): 5 | """ 6 | Returns an async generator function which is equalivalent to the passed in function, 7 | but only takes in one parameter (the first one). 8 | """ 9 | 10 | async def inner(first_param): 11 | async for x in f(first_param, *args): 12 | yield x 13 | 14 | return inner 15 | 16 | 17 | def partial_async(f, *args): 18 | """ 19 | Returns an async function which is equalivalent to the passed in function, 20 | but only takes in one parameter (the first one). 21 | """ 22 | 23 | async def inner(first_param): 24 | return await f(first_param, *args) 25 | 26 | return inner 27 | -------------------------------------------------------------------------------- /flax/util/path.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import os 4 | from pathlib import Path 5 | from typing import Union 6 | 7 | 8 | def path_from_root(root: Path, path_str: Union[str, Path]) -> Path: 9 | """ 10 | If path is relative, prepend root 11 | If path is absolute, return it directly. 12 | """ 13 | root = Path(os.path.expanduser(str(root))) 14 | path = Path(path_str) 15 | if not path.is_absolute(): 16 | path = root / path 17 | return path.resolve() 18 | 19 | 20 | def make_path_relative(path_str: Union[str, Path], root: Path) -> Path: 21 | """ 22 | Try to make the given path relative, given the default root. 23 | """ 24 | path = Path(path_str) 25 | try: 26 | path = path.relative_to(root) 27 | except ValueError: 28 | pass 29 | return path 30 | -------------------------------------------------------------------------------- /flax/util/permissions.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import os 4 | from pathlib import Path 5 | from typing import Tuple 6 | 7 | 8 | def verify_file_permissions(path: Path, mask: int) -> Tuple[bool, int]: 9 | """ 10 | Check that the file's permissions are properly restricted, as compared to the 11 | permission mask 12 | """ 13 | mode = os.stat(path).st_mode & 0o777 14 | return (mode & mask == 0, mode) 15 | 16 | 17 | def octal_mode_string(mode: int) -> str: 18 | """Yields a permission mode string: e.g. 0644""" 19 | return f"0{oct(mode)[-3:]}" 20 | -------------------------------------------------------------------------------- /flax/util/pip_import.py: -------------------------------------------------------------------------------- 1 | "Import a package and install it with PIP if it doesn't exist." 2 | 3 | from __future__ import annotations 4 | 5 | import subprocess 6 | import sys 7 | 8 | 9 | def pip_import(module, pypi_name=None): 10 | """ 11 | Return None if we can't import or install it. 12 | """ 13 | try: 14 | return __import__(module) 15 | except ImportError: 16 | pass 17 | 18 | subprocess.call([sys.executable, "-m", "pip", "install", pypi_name or module]) 19 | return __import__(module) 20 | -------------------------------------------------------------------------------- /flax/util/prev_transaction_block.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Tuple 4 | 5 | from flax.consensus.block_record import BlockRecord 6 | from flax.consensus.blockchain_interface import BlockchainInterface 7 | from flax.util.ints import uint128 8 | 9 | 10 | def get_prev_transaction_block( 11 | curr: BlockRecord, 12 | blocks: BlockchainInterface, 13 | total_iters_sp: uint128, 14 | ) -> Tuple[bool, BlockRecord]: 15 | prev_transaction_block = curr 16 | while not curr.is_transaction_block: 17 | curr = blocks.block_record(curr.prev_hash) 18 | if total_iters_sp > curr.total_iters: 19 | prev_transaction_block = curr 20 | is_transaction_block = True 21 | else: 22 | is_transaction_block = False 23 | return is_transaction_block, prev_transaction_block 24 | -------------------------------------------------------------------------------- /flax/util/recursive_replace.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import replace 4 | from typing import Any 5 | 6 | 7 | def recursive_replace(root_obj: Any, replace_str: str, replace_with: Any) -> Any: 8 | split_str = replace_str.split(".") 9 | if len(split_str) == 1: 10 | return replace(root_obj, **{split_str[0]: replace_with}) 11 | sub_obj = recursive_replace(getattr(root_obj, split_str[0]), ".".join(split_str[1:]), replace_with) 12 | return replace(root_obj, **{split_str[0]: sub_obj}) 13 | -------------------------------------------------------------------------------- /flax/util/safe_cancel_task.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import asyncio 4 | import logging 5 | from typing import Optional 6 | 7 | 8 | def cancel_task_safe(task: Optional[asyncio.Task], log: Optional[logging.Logger] = None): 9 | if task is not None: 10 | try: 11 | task.cancel() 12 | except Exception as e: 13 | if log is not None: 14 | log.error(f"Error while canceling task.{e} {task}") 15 | -------------------------------------------------------------------------------- /flax/util/setproctitle.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | try: 4 | import setproctitle as pysetproctitle 5 | 6 | no_setproctitle = False 7 | except Exception: 8 | no_setproctitle = True 9 | 10 | 11 | def setproctitle(ps_name: str) -> None: 12 | if no_setproctitle is False: 13 | pysetproctitle.setproctitle(ps_name) 14 | 15 | 16 | def getproctitle() -> str: 17 | if no_setproctitle is False: 18 | # TODO: add type hints to setproctitle 19 | return pysetproctitle.getproctitle() # type: ignore[no-any-return] 20 | 21 | return "" 22 | -------------------------------------------------------------------------------- /flax/util/significant_bits.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | 4 | def truncate_to_significant_bits(input_x: int, num_significant_bits: int) -> int: 5 | """ 6 | Truncates the number such that only the top num_significant_bits contain 1s. 7 | and the rest of the number is 0s (in binary). Ignores decimals and leading 8 | zeroes. For example, -0b011110101 and 2, returns -0b11000000. 9 | """ 10 | x = abs(input_x) 11 | if num_significant_bits > x.bit_length(): 12 | return input_x 13 | lower = x.bit_length() - num_significant_bits 14 | mask = (1 << (x.bit_length())) - 1 - ((1 << lower) - 1) 15 | if input_x < 0: 16 | return -(x & mask) 17 | else: 18 | return x & mask 19 | 20 | 21 | def count_significant_bits(input_x: int) -> int: 22 | """ 23 | Counts the number of significant bits of an integer, ignoring negative signs 24 | and leading zeroes. For example, for -0b000110010000, returns 5. 25 | """ 26 | x = input_x 27 | for i in range(x.bit_length()): 28 | if x & (1 << i) > 0: 29 | return x.bit_length() - i 30 | return 0 31 | -------------------------------------------------------------------------------- /flax/util/vdf_prover.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Tuple 4 | 5 | from chiavdf import prove 6 | 7 | from flax.consensus.constants import ConsensusConstants 8 | from flax.types.blockchain_format.classgroup import ClassgroupElement 9 | from flax.types.blockchain_format.sized_bytes import bytes32 10 | from flax.types.blockchain_format.vdf import VDFInfo, VDFProof 11 | from flax.util.ints import uint8, uint64 12 | 13 | 14 | def get_vdf_info_and_proof( 15 | constants: ConsensusConstants, 16 | vdf_input: ClassgroupElement, 17 | challenge_hash: bytes32, 18 | number_iters: uint64, 19 | normalized_to_identity: bool = False, 20 | ) -> Tuple[VDFInfo, VDFProof]: 21 | form_size = ClassgroupElement.get_size(constants) 22 | result: bytes = prove( 23 | bytes(challenge_hash), 24 | vdf_input.data, 25 | constants.DISCRIMINANT_SIZE_BITS, 26 | number_iters, 27 | ) 28 | 29 | output = ClassgroupElement.from_bytes(result[:form_size]) 30 | proof_bytes = result[form_size : 2 * form_size] 31 | return VDFInfo(challenge_hash, number_iters, output), VDFProof(uint8(0), proof_bytes, normalized_to_identity) 32 | -------------------------------------------------------------------------------- /flax/wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/__init__.py -------------------------------------------------------------------------------- /flax/wallet/block_record.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import List 5 | 6 | from flax.types.blockchain_format.coin import Coin 7 | from flax.types.header_block import HeaderBlock 8 | from flax.util.streamable import Streamable, streamable 9 | 10 | 11 | @streamable 12 | @dataclass(frozen=True) 13 | class HeaderBlockRecord(Streamable): 14 | """ 15 | These are values that are stored in the wallet database, corresponding to information 16 | that the wallet cares about in each block 17 | """ 18 | 19 | header: HeaderBlock 20 | additions: List[Coin] # A block record without additions is not finished 21 | removals: List[Coin] # A block record without removals is not finished 22 | 23 | @property 24 | def header_hash(self): 25 | return self.header.header_hash 26 | 27 | @property 28 | def prev_header_hash(self): 29 | return self.header.prev_header_hash 30 | 31 | @property 32 | def height(self): 33 | return self.header.height 34 | 35 | @property 36 | def transactions_filter(self): 37 | return self.header.transactions_filter 38 | -------------------------------------------------------------------------------- /flax/wallet/cat_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/cat_wallet/__init__.py -------------------------------------------------------------------------------- /flax/wallet/cat_wallet/cat_constants.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | DEFAULT_CATS = { 4 | } 5 | -------------------------------------------------------------------------------- /flax/wallet/cat_wallet/cat_info.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from typing import List, Optional, Tuple 3 | 4 | from flax.types.blockchain_format.program import Program 5 | from flax.types.blockchain_format.sized_bytes import bytes32 6 | from flax.wallet.lineage_proof import LineageProof 7 | from flax.util.streamable import Streamable, streamable 8 | 9 | 10 | @streamable 11 | @dataclass(frozen=True) 12 | class CATInfo(Streamable): 13 | limitations_program_hash: bytes32 14 | my_tail: Optional[Program] # this is the program 15 | 16 | 17 | # We used to store all of the lineage proofs here but it was very slow to serialize for a lot of transactions 18 | # so we moved it to CATLineageStore. We keep this around for migration purposes. 19 | @streamable 20 | @dataclass(frozen=True) 21 | class LegacyCATInfo(Streamable): 22 | limitations_program_hash: bytes32 23 | my_tail: Optional[Program] # this is the program 24 | lineage_proofs: List[Tuple[bytes32, Optional[LineageProof]]] # {coin.name(): lineage_proof} 25 | -------------------------------------------------------------------------------- /flax/wallet/db_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/db_wallet/__init__.py -------------------------------------------------------------------------------- /flax/wallet/derivation_record.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from blspy import G1Element 6 | 7 | from flax.types.blockchain_format.sized_bytes import bytes32 8 | from flax.util.ints import uint32 9 | from flax.wallet.util.wallet_types import WalletType 10 | 11 | 12 | @dataclass(frozen=True) 13 | class DerivationRecord: 14 | """ 15 | These are records representing a puzzle hash, which is generated from a 16 | public key, derivation index, and wallet type. Stored in the puzzle_store. 17 | """ 18 | 19 | index: uint32 20 | puzzle_hash: bytes32 21 | pubkey: G1Element 22 | wallet_type: WalletType 23 | wallet_id: uint32 24 | hardened: bool 25 | -------------------------------------------------------------------------------- /flax/wallet/did_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/did_wallet/__init__.py -------------------------------------------------------------------------------- /flax/wallet/did_wallet/did_info.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from typing import List, Optional, Tuple 3 | 4 | from flax.types.blockchain_format.sized_bytes import bytes32 5 | from flax.util.ints import uint64 6 | from flax.util.streamable import streamable, Streamable 7 | from flax.wallet.lineage_proof import LineageProof 8 | from flax.types.blockchain_format.program import Program 9 | from flax.types.blockchain_format.coin import Coin 10 | 11 | 12 | @streamable 13 | @dataclass(frozen=True) 14 | class DIDInfo(Streamable): 15 | origin_coin: Optional[Coin] # Coin ID of this coin is our DID 16 | backup_ids: List[bytes32] 17 | num_of_backup_ids_needed: uint64 18 | parent_info: List[Tuple[bytes32, Optional[LineageProof]]] # {coin.name(): LineageProof} 19 | current_inner: Optional[Program] # represents a Program as bytes 20 | temp_coin: Optional[Coin] # partially recovered wallet uses these to hold info 21 | temp_puzhash: Optional[bytes32] 22 | temp_pubkey: Optional[bytes] 23 | sent_recovery_transaction: bool 24 | metadata: str # JSON of the user defined metadata 25 | -------------------------------------------------------------------------------- /flax/wallet/driver_protocol.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Optional 4 | 5 | from typing_extensions import Protocol 6 | 7 | from flax.types.blockchain_format.program import Program 8 | from flax.types.blockchain_format.sized_bytes import bytes32 9 | from flax.wallet.puzzle_drivers import PuzzleInfo, Solver 10 | from flax.wallet.uncurried_puzzle import UncurriedPuzzle 11 | 12 | 13 | class DriverProtocol(Protocol): 14 | def match(self, puzzle: UncurriedPuzzle) -> Optional[PuzzleInfo]: 15 | ... 16 | 17 | def get_inner_puzzle(self, constructor: PuzzleInfo, puzzle_reveal: UncurriedPuzzle) -> Optional[Program]: 18 | ... 19 | 20 | def get_inner_solution(self, constructor: PuzzleInfo, solution: Program) -> Optional[Program]: 21 | ... 22 | 23 | def asset_id(self, constructor: PuzzleInfo) -> Optional[bytes32]: 24 | ... 25 | 26 | def construct(self, constructor: PuzzleInfo, inner_puzzle: Program) -> Program: 27 | ... 28 | 29 | def solve(self, constructor: PuzzleInfo, solver: Solver, inner_puzzle: Program, inner_solution: Program) -> Program: 30 | ... 31 | -------------------------------------------------------------------------------- /flax/wallet/lineage_proof.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from typing import Optional, Any, List 3 | 4 | from flax.types.blockchain_format.sized_bytes import bytes32 5 | from flax.types.blockchain_format.program import Program 6 | from flax.util.ints import uint64 7 | from flax.util.streamable import Streamable, streamable 8 | 9 | 10 | @streamable 11 | @dataclass(frozen=True) 12 | class LineageProof(Streamable): 13 | parent_name: Optional[bytes32] = None 14 | inner_puzzle_hash: Optional[bytes32] = None 15 | amount: Optional[uint64] = None 16 | 17 | def to_program(self) -> Program: 18 | final_list: List[Any] = [] 19 | if self.parent_name is not None: 20 | final_list.append(self.parent_name) 21 | if self.inner_puzzle_hash is not None: 22 | final_list.append(self.inner_puzzle_hash) 23 | if self.amount is not None: 24 | final_list.append(self.amount) 25 | return Program.to(final_list) 26 | 27 | def is_none(self) -> bool: 28 | return all([self.parent_name is None, self.inner_puzzle_hash is None, self.amount is None]) 29 | -------------------------------------------------------------------------------- /flax/wallet/nft_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/nft_wallet/__init__.py -------------------------------------------------------------------------------- /flax/wallet/payment.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | from typing import List 4 | 5 | from flax.types.blockchain_format.sized_bytes import bytes32 6 | from flax.types.blockchain_format.program import Program 7 | from flax.util.ints import uint64 8 | 9 | 10 | # This class is supposed to correspond to a CREATE_COIN condition 11 | @dataclass(frozen=True) 12 | class Payment: 13 | puzzle_hash: bytes32 14 | amount: uint64 15 | memos: List[bytes] 16 | 17 | def as_condition_args(self) -> List: 18 | return [self.puzzle_hash, self.amount, self.memos] 19 | 20 | def as_condition(self) -> Program: 21 | return Program.to([51, *self.as_condition_args()]) 22 | 23 | def name(self) -> bytes32: 24 | return self.as_condition().get_tree_hash() 25 | 26 | @classmethod 27 | def from_condition(cls, condition: Program) -> "Payment": 28 | python_condition: List = condition.as_python() 29 | puzzle_hash, amount = python_condition[1:3] 30 | memos: List[bytes] = [] 31 | if len(python_condition) > 3: 32 | memos = python_condition[3] 33 | return cls(bytes32(puzzle_hash), uint64(int.from_bytes(amount, "big")), memos) 34 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/puzzles/__init__.py -------------------------------------------------------------------------------- /flax/wallet/puzzles/block_program_zero.clvm: -------------------------------------------------------------------------------- 1 | 2 | ; TODO convert generators arg to list of generators 3 | 4 | (mod (decompress_puzzle decompress_coin_spend_entry start end compressed_cses deserialize gen_list reserved_arg) 5 | 6 | (defun decompress_cses (decompress_puzzle decompress_coin_spend_entry cses deserialize puzzle_prefix) 7 | (if cses 8 | (c (a decompress_coin_spend_entry (list deserialize decompress_puzzle puzzle_prefix (f cses))) 9 | (decompress_cses decompress_puzzle decompress_coin_spend_entry (r cses) deserialize puzzle_prefix )) 10 | ()) ) 11 | 12 | (list (decompress_cses decompress_puzzle decompress_coin_spend_entry compressed_cses deserialize (substr (f gen_list) start end))) 13 | 14 | ) 15 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/block_program_zero.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff02ff02ffff04ff02ffff04ff05ffff04ff0bffff04ff5fffff04ff81bfffff04ffff0cff82027fff17ff2f80ff8080808080808080ff8080ffff04ffff01ff02ffff03ff17ffff01ff04ffff02ff0bffff04ff2fffff04ff05ffff04ff5fffff04ff27ff808080808080ffff02ff02ffff04ff02ffff04ff05ffff04ff0bffff04ff37ffff04ff2fffff04ff5fff808080808080808080ff8080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/block_program_zero.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | f0a38c8efe58895ae527c65c37f700a4238504691b83990e5dd91bd8b3c30eae 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/calculate_synthetic_public_key.clvm: -------------------------------------------------------------------------------- 1 | (mod 2 | (public_key hidden_puzzle_hash) 3 | 4 | (point_add public_key (pubkey_for_exp (sha256 public_key hidden_puzzle_hash))) 5 | ) 6 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/calculate_synthetic_public_key.clvm.hex: -------------------------------------------------------------------------------- 1 | ff1dff02ffff1effff0bff02ff05808080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/calculate_synthetic_public_key.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 624c5d5704d0decadfc0503e71bbffb6cdfe45025bce7cf3e6864d1eafe8f65e 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/cat_loader.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.wallet.puzzles.load_clvm import load_clvm_maybe_recompile 4 | 5 | CAT_MOD = load_clvm_maybe_recompile("cat_v2.clvm", package_or_requirement=__name__) 6 | LOCK_INNER_PUZZLE = load_clvm_maybe_recompile("lock.inner.puzzle.clvm", package_or_requirement=__name__) 7 | 8 | CAT_MOD_HASH = CAT_MOD.get_tree_hash() 9 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/cat_truths.clib: -------------------------------------------------------------------------------- 1 | ( 2 | (defun-inline cat_truth_data_to_truth_struct (innerpuzhash cat_struct my_id this_coin_info) 3 | (c 4 | (c 5 | innerpuzhash 6 | cat_struct 7 | ) 8 | (c 9 | my_id 10 | this_coin_info 11 | ) 12 | ) 13 | ) 14 | 15 | ; CAT Truths is: ((Inner puzzle hash . (MOD hash . (MOD hash hash . TAIL hash))) . (my_id . (my_parent_info my_puzhash my_amount))) 16 | 17 | (defun-inline my_inner_puzzle_hash_cat_truth (Truths) (f (f Truths))) 18 | (defun-inline cat_struct_truth (Truths) (r (f Truths))) 19 | (defun-inline my_id_cat_truth (Truths) (f (r Truths))) 20 | (defun-inline my_coin_info_truth (Truths) (r (r Truths))) 21 | (defun-inline my_amount_cat_truth (Truths) (f (r (r (my_coin_info_truth Truths))))) 22 | (defun-inline my_full_puzzle_hash_cat_truth (Truths) (f (r (my_coin_info_truth Truths)))) 23 | (defun-inline my_parent_cat_truth (Truths) (f (my_coin_info_truth Truths))) 24 | 25 | 26 | ; CAT mod_struct is: (MOD_HASH MOD_HASH_hash TAIL_PROGRAM TAIL_PROGRAM_hash) 27 | 28 | (defun-inline cat_mod_hash_truth (Truths) (f (cat_struct_truth Truths))) 29 | (defun-inline cat_mod_hash_hash_truth (Truths) (f (r (cat_struct_truth Truths)))) 30 | (defun-inline cat_tail_program_hash_truth (Truths) (f (r (r (cat_struct_truth Truths))))) 31 | ) 32 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/cat_v2.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 37bef360ee858133b69d595a906dc45d01af50379dad515eb9518abb7c1d2a7a 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/condition_codes.clvm: -------------------------------------------------------------------------------- 1 | ; See flax/types/condition_opcodes.py 2 | 3 | ( 4 | (defconstant AGG_SIG_UNSAFE 49) 5 | (defconstant AGG_SIG_ME 50) 6 | 7 | ; the conditions below reserve coin amounts and have to be accounted for in output totals 8 | 9 | (defconstant CREATE_COIN 51) 10 | (defconstant RESERVE_FEE 52) 11 | 12 | ; the conditions below deal with announcements, for inter-coin communication 13 | 14 | ; coin announcements 15 | (defconstant CREATE_COIN_ANNOUNCEMENT 60) 16 | (defconstant ASSERT_COIN_ANNOUNCEMENT 61) 17 | 18 | ; puzzle announcements 19 | (defconstant CREATE_PUZZLE_ANNOUNCEMENT 62) 20 | (defconstant ASSERT_PUZZLE_ANNOUNCEMENT 63) 21 | 22 | ; the conditions below let coins inquire about themselves 23 | 24 | (defconstant ASSERT_MY_COIN_ID 70) 25 | (defconstant ASSERT_MY_PARENT_ID 71) 26 | (defconstant ASSERT_MY_PUZZLEHASH 72) 27 | (defconstant ASSERT_MY_AMOUNT 73) 28 | 29 | ; the conditions below ensure that we're "far enough" in the future 30 | 31 | ; wall-clock time 32 | (defconstant ASSERT_SECONDS_RELATIVE 80) 33 | (defconstant ASSERT_SECONDS_ABSOLUTE 81) 34 | 35 | ; block index 36 | (defconstant ASSERT_HEIGHT_RELATIVE 82) 37 | (defconstant ASSERT_HEIGHT_ABSOLUTE 83) 38 | 39 | ; A condition that is always true and always ignore all arguments 40 | (defconstant REMARK 1) 41 | ) 42 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/create-lock-puzzlehash.clvm: -------------------------------------------------------------------------------- 1 | ; This puzzle evaluates to an empty list , which means no conditions need to be satisfied; 2 | ; The puzzle can never evaluate to my-id. 3 | ; my-id is there on a discarded branch of the tree as a signal to another piece of code 4 | ; that will be checking if a coin whose puzzle is of this form, was created or spent. 5 | ( 6 | (defun-inline create-lock-puzzlehash (my-id) 7 | (sha256tree (list r 8 | (list c 9 | (list q 10 | my-id) 11 | (q (q ())))))) 12 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/create_nft_launcher_from_did.clvm: -------------------------------------------------------------------------------- 1 | (mod (LAUNCHER_PH MINT_NUMBER MINT_TOTAL) 2 | (include condition_codes.clvm) 3 | (list 4 | (list CREATE_COIN LAUNCHER_PH 1) 5 | (list CREATE_COIN_ANNOUNCEMENT (sha256 MINT_NUMBER MINT_TOTAL))) 6 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/create_nft_launcher_from_did.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff01ff01808080ffff04ffff04ff06ffff04ffff0bff0bff1780ff808080ff808080ffff04ffff01ff333cff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/create_nft_launcher_from_did.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 7a32d2d9571d3436791c0ad3d7fcfdb9c43ace2b0f0ff13f98d29f0cc093f445 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_block_spends.clvm: -------------------------------------------------------------------------------- 1 | (mod (block_program (block_ref)) 2 | 3 | (defconstant local_deserialize_mod 4 | ;; this monstrosity is the assembly output of `flaxlisp_deserialisation.clvm` 5 | ;; it's pasted in here because the compiler doesn't yet support nested `mod` 6 | ;; my apologies -- RK 7 | 8 | (a (q 5 (a 62 (c 2 (c 5 ())))) 9 | (c (q ((-1 . 127) -33 . -65) ((a (i (= 11 (q . -128)) (q 4 () (c 5 ())) (q 2 (i (>s 11 24) (q 2 26 (c 2 (c (a (i (>s 11 28) (q 2 (i (>s 11 20) (q 8) (q 4 (concat (logand (q . 31) 11) (substr 5 () (q . 1))) (c (substr 5 (q . 1)) ()))) 1) (q 4 (logand (q . 63) 11) (c 5 ()))) 1) ()))) (q 4 11 (c 5 ()))) 1)) 1) 4 (substr 21 () 9) (c (substr 21 9) ())) (c (c 5 19) (c 43 ())) (a 22 (c 2 (c 9 (c (a 62 (c 2 (c 21 ()))) ())))) 2 (i (= (substr 5 () (q . 1)) 16) (q 2 46 (c 2 (c (a 62 (c 2 (c (substr 5 (q . 1)) ()))) ()))) (q 2 18 (c 2 (c (substr 5 (q . 1)) (c (substr 5 () (q . 1)) ()))))) 1) 10 | 1)) 11 | ) 12 | 13 | ; main 14 | ; select the first value, and return decompressed block spends. 15 | (f (a block_program (list local_deserialize_mod block_ref))) 16 | ) 17 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_block_spends.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff05ffff02ff05ffff04ff02ffff04ff13ff8080808080ffff04ffff01ff02ffff01ff05ffff02ff3effff04ff02ffff04ff05ff8080808080ffff04ffff01ffffff81ff7fff81df81bfffffff02ffff03ffff09ff0bffff01818080ffff01ff04ff80ffff04ff05ff808080ffff01ff02ffff03ffff0aff0bff1880ffff01ff02ff1affff04ff02ffff04ffff02ffff03ffff0aff0bff1c80ffff01ff02ffff03ffff0aff0bff1480ffff01ff0880ffff01ff04ffff0effff18ffff011fff0b80ffff0cff05ff80ffff01018080ffff04ffff0cff05ffff010180ff80808080ff0180ffff01ff04ffff18ffff013fff0b80ffff04ff05ff80808080ff0180ff80808080ffff01ff04ff0bffff04ff05ff80808080ff018080ff0180ff04ffff0cff15ff80ff0980ffff04ffff0cff15ff0980ff808080ffff04ffff04ff05ff1380ffff04ff2bff808080ffff02ff16ffff04ff02ffff04ff09ffff04ffff02ff3effff04ff02ffff04ff15ff80808080ff8080808080ff02ffff03ffff09ffff0cff05ff80ffff010180ff1080ffff01ff02ff2effff04ff02ffff04ffff02ff3effff04ff02ffff04ffff0cff05ffff010180ff80808080ff80808080ffff01ff02ff12ffff04ff02ffff04ffff0cff05ffff010180ffff04ffff0cff05ff80ffff010180ff808080808080ff0180ff018080ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_block_spends.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | f890a7866079009517ae0b652d530268d2531bbac99670aaba461d604bc0ff0c 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_block_spends.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.wallet.puzzles.load_clvm import load_serialized_clvm_maybe_recompile 4 | 5 | DECOMPRESS_BLOCK_SPENDS = load_serialized_clvm_maybe_recompile( 6 | "decompress_block_spends.clvm", package_or_requirement=__name__ 7 | ) 8 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_coin_spend_entry.clvm: -------------------------------------------------------------------------------- 1 | (mod (deserialize decompress_puzzle puzzle_prefix suffix cse) 2 | 3 | ; decompress a single compressed standard transaction 4 | (c (f cse) (c (a decompress_puzzle (list deserialize puzzle_prefix (f (f (r cse))) suffix)) (c (f (r (f cse))) (r (f (r cse)))))) 5 | ) 6 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_coin_spend_entry.clvm.hex: -------------------------------------------------------------------------------- 1 | ff04ff4fffff04ffff02ff05ffff04ff02ffff04ff0bffff04ff82012fffff04ff17ff808080808080ffff04ff82014fff8201af808080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_coin_spend_entry.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 9d98ed08770d31be4bd1bde4705dab388db5e7e9c349f5a76fc3c347aa3a0b79 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_coin_spend_entry_with_prefix.clvm: -------------------------------------------------------------------------------- 1 | (mod (deserialize decompress_puzzle puzzle_prefix cse) 2 | 3 | ; decompress a single compressed standard transaction 4 | 5 | (c (f (f cse)) (c (a decompress_puzzle (list deserialize puzzle_prefix (f (f (r cse))) (q . 0xff018080))) (c (f (r (f cse))) (r (f (r cse)))))) 6 | 7 | ) 8 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_coin_spend_entry_with_prefix.clvm.hex: -------------------------------------------------------------------------------- 1 | ff04ff47ffff04ffff02ff05ffff04ff02ffff04ff0bffff04ff8197ffff01ff84ff0180808080808080ffff04ff81a7ff81d7808080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_coin_spend_entry_with_prefix.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 92aa4bc8060a8836355a1884075141b4791ce1b67ae6092bb166b2845954bc89 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_puzzle.clvm: -------------------------------------------------------------------------------- 1 | (mod (deserialize puzzle_prefix pubkey suffix) 2 | 3 | (a deserialize (list (concat puzzle_prefix pubkey suffix))) 4 | 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_puzzle.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ff02ffff04ffff0eff05ff0bff1780ff808080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/decompress_puzzle.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | fe94c58f1117afe315e0450daca1c62460ec1a1c439cd4018d79967a5d7d1370 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/delegated_tail.clvm: -------------------------------------------------------------------------------- 1 | ; This is a "limitations_program" for use with cat.clvm. 2 | (mod ( 3 | PUBKEY 4 | Truths 5 | parent_is_cat 6 | lineage_proof 7 | delta 8 | inner_conditions 9 | ( 10 | delegated_puzzle 11 | delegated_solution 12 | ) 13 | ) 14 | 15 | (include condition_codes.clvm) 16 | 17 | (defun sha256tree1 (TREE) 18 | (if (l TREE) 19 | (sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE))) 20 | (sha256 1 TREE))) 21 | 22 | (c (list AGG_SIG_UNSAFE PUBKEY (sha256tree1 delegated_puzzle)) 23 | (a delegated_puzzle (c Truths (c parent_is_cat (c lineage_proof (c delta (c inner_conditions delegated_solution)))))) 24 | ) 25 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/delegated_tail.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff82027fff80808080ff80808080ffff02ff82027fffff04ff0bffff04ff17ffff04ff2fffff04ff5fffff04ff81bfff82057f80808080808080ffff04ffff01ff31ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/delegated_tail.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 999c3696e167f8a79d938adc11feba3a3dcb39ccff69a426d570706e7b8ec399 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/did_innerpuz.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 33143d2bef64f14036742673afd158126b94284b4530a28c354fac202b0c910e 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/everything_with_signature.clvm: -------------------------------------------------------------------------------- 1 | ; This is a "limitations_program" for use with cat.clvm. 2 | (mod ( 3 | PUBKEY 4 | Truths 5 | parent_is_cat 6 | lineage_proof 7 | delta 8 | inner_conditions 9 | _ 10 | ) 11 | 12 | (include condition_codes.clvm) 13 | 14 | (list (list AGG_SIG_ME PUBKEY delta)) ; Careful with a delta of zero, the bytecode is 80 not 00 15 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/everything_with_signature.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff02ffff04ff05ffff04ff5fff80808080ff8080ffff04ffff0132ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/everything_with_signature.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 1720d13250a7c16988eaf530331cefa9dd57a76b2c82236bec8bbbff91499b89 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/flaxlisp_deserialisation.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff05ffff02ff3effff04ff02ffff04ff05ff8080808080ffff04ffff01ffffff81ff7fff81df81bfffffff02ffff03ffff09ff0bffff01818080ffff01ff04ff80ffff04ff05ff808080ffff01ff02ffff03ffff0aff0bff1880ffff01ff02ff1affff04ff02ffff04ffff02ffff03ffff0aff0bff1c80ffff01ff02ffff03ffff0aff0bff1480ffff01ff0880ffff01ff04ffff0effff18ffff011fff0b80ffff0cff05ff80ffff01018080ffff04ffff0cff05ffff010180ff80808080ff0180ffff01ff04ffff18ffff013fff0b80ffff04ff05ff80808080ff0180ff80808080ffff01ff04ff0bffff04ff05ff80808080ff018080ff0180ff04ffff0cff15ff80ff0980ffff04ffff0cff15ff0980ff808080ffff04ffff04ff05ff1380ffff04ff2bff808080ffff02ff16ffff04ff02ffff04ff09ffff04ffff02ff3effff04ff02ffff04ff15ff80808080ff8080808080ff02ffff03ffff09ffff0cff05ff80ffff010180ff1080ffff01ff02ff2effff04ff02ffff04ffff02ff3effff04ff02ffff04ffff0cff05ffff010180ff80808080ff80808080ffff01ff02ff12ffff04ff02ffff04ffff0cff05ffff010180ffff04ffff0cff05ff80ffff010180ff808080808080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/flaxlisp_deserialisation.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 94ec19077f9a34e0b11ad2456af0170f4cc03f11230ca42e3f82e6e644ac4f5d 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/genesis_by_coin_id.clvm: -------------------------------------------------------------------------------- 1 | ; This is a TAIL for use with cat.clvm. 2 | ; 3 | ; This checker allows new CATs to be created if they have a particular coin id as parent 4 | ; 5 | ; The genesis_id is curried in, making this lineage_check program unique and giving the CAT it's uniqueness 6 | (mod ( 7 | GENESIS_ID 8 | Truths 9 | parent_is_cat 10 | lineage_proof 11 | delta 12 | inner_conditions 13 | _ 14 | ) 15 | 16 | (include cat_truths.clib) 17 | 18 | (if delta 19 | (x) 20 | (if (= (my_parent_cat_truth Truths) GENESIS_ID) 21 | () 22 | (x) 23 | ) 24 | ) 25 | 26 | ) 27 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/genesis_by_coin_id.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff03ff2fffff01ff0880ffff01ff02ffff03ffff09ff2dff0280ff80ffff01ff088080ff018080ff0180 -------------------------------------------------------------------------------- /flax/wallet/puzzles/genesis_by_coin_id.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 493afb89eed93ab86741b2aa61b8f5de495d33ff9b781dfc8919e602b2afa150 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/genesis_by_puzzle_hash.clvm: -------------------------------------------------------------------------------- 1 | ; This is a "limitations_program" for use with cat.clvm. 2 | ; 3 | ; This checker allows new CATs to be created if their parent has a particular puzzle hash 4 | (mod ( 5 | GENESIS_PUZZLE_HASH 6 | Truths 7 | parent_is_cat 8 | lineage_proof 9 | delta 10 | inner_conditions 11 | (parent_parent_id parent_amount) 12 | ) 13 | 14 | (include cat_truths.clib) 15 | 16 | ; Returns nil since we don't need to add any conditions 17 | (if delta 18 | (x) 19 | (if (= (sha256 parent_parent_id GENESIS_PUZZLE_HASH parent_amount) (my_parent_cat_truth Truths)) 20 | () 21 | (x) 22 | ) 23 | ) 24 | ) 25 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/genesis_by_puzzle_hash.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff03ff2fffff01ff0880ffff01ff02ffff03ffff09ffff0bff82013fff02ff8202bf80ff2d80ff80ffff01ff088080ff018080ff0180 -------------------------------------------------------------------------------- /flax/wallet/puzzles/genesis_by_puzzle_hash.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | de5a6e06d41518be97ff6365694f4f89475dda773dede267caa33da63b434e36 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/graftroot_dl_offers.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 0893e36a88c064fddfa6f8abdb42c044584a98cb4273b80cccc83b4867b701a1 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/json.clib: -------------------------------------------------------------------------------- 1 | ( 2 | 3 | (defun search_list_then_resume (key json_object result) 4 | (if result 5 | result 6 | (search_for_value_given_key key (r json_object)) 7 | ) 8 | ) 9 | 10 | (defun search_for_value_given_key (key json_object) 11 | (if json_object 12 | (if (l (f from_json_dict)) ; if we are hitting an unlabelled item (atom), just move on 13 | (if (= (f (f json_object)) key) ; if we have found our key 14 | (r (f json_object)) ; return the value 15 | (if (l (r (f json_object))) ; otherwise check if we have hit another dictionary 16 | (search_list_then_resume key json_object (search_for_value_given_key key (r (f json_object)))) ; check new dictionary 17 | (search_for_value_given_key key (r json_object)) 18 | ) 19 | ) 20 | (search_for_value_given_key key (r json_object)) 21 | ) 22 | () 23 | ) 24 | ) 25 | ) 26 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/lock.inner.puzzle.clvm: -------------------------------------------------------------------------------- 1 | ; a trivial puzzle used as the core of a lock puzzle 2 | (mod args (q ())) 3 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/lock.inner.puzzle.clvm.hex: -------------------------------------------------------------------------------- 1 | ff01ff8080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/lock.inner.puzzle.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | f3a579254623f8094e07af862df2e45c9db5592b4105d34a256dd6c498416288 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/merkle_utils.clib: -------------------------------------------------------------------------------- 1 | ( 2 | (defun simplify_merkle_proof_after_leaf (leaf_hash (bitpath . hashes_path)) 3 | (if hashes_path 4 | (simplify_merkle_proof_after_leaf 5 | (if (logand 1 bitpath) 6 | (sha256 0x02 (f hashes_path) leaf_hash) 7 | (sha256 0x02 leaf_hash (f hashes_path)) 8 | ) 9 | (c (lsh bitpath -1) (r hashes_path)) 10 | ) 11 | leaf_hash 12 | ) 13 | ) 14 | 15 | (defun-inline simplify_merkle_proof (leaf proof) 16 | (simplify_merkle_proof_after_leaf (sha256 0x01 leaf) proof) 17 | ) 18 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_intermediate_launcher.clvm: -------------------------------------------------------------------------------- 1 | (mod (LAUNCHER_PH MINT_NUMBER MINT_TOTAL) 2 | (include condition_codes.clvm) 3 | (list 4 | (list CREATE_COIN LAUNCHER_PH 1) 5 | (list CREATE_COIN_ANNOUNCEMENT (sha256 MINT_NUMBER MINT_TOTAL))) 6 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_intermediate_launcher.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff01ff01808080ffff04ffff04ff06ffff04ffff0bff0bff1780ff808080ff808080ffff04ffff01ff333cff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_intermediate_launcher.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 7a32d2d9571d3436791c0ad3d7fcfdb9c43ace2b0f0ff13f98d29f0cc093f445 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_metadata_updater_default.clvm: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_metadata_updater_default.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ffff02ffff03ffff22ff27ff3780ffff01ff02ffff03ffff21ffff09ff27ffff01826d7580ffff09ff27ffff01826c7580ffff09ff27ffff01758080ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ffff04ff37ff808080808080ffff010580ff0180ffff010580ff0180ffff04ff0bff808080ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09ff11ff0b80ffff01ff04ffff04ff0bffff04ff17ff198080ff0d80ffff01ff04ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bffff04ff17ff8080808080808080ff0180ff8080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_metadata_updater_default.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | fe8a4b4e27a2e29a4d3fc7ce9d527adbcaccbab6ada3903ccf3ba9a769d2d78b 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_metadata_updater_updateable.clvm: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_metadata_updater_updateable.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ffff02ffff03ff27ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ff8080808080ffff010580ff0180ffff04ffff02ffff03ffff09ffff0dff5780ffff012080ffff0157ffff010b80ff0180ff808080ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09ff11ffff017580ffff01ff04ffff04ffff0175ffff04ff0bff198080ff0d80ffff01ff04ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bff80808080808080ff0180ff8080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_metadata_updater_updateable.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 0b1ffba1601777c06b78ab38636e9624f2f8da73be9b36e0ce17c8d8ef3bad9f 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_ownership_layer.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | c5abea79afaa001b5427dfa0c8cf42ca6f38f5841b78f9b3c252733eb2de2726 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ffff03ff81bfffff01ff04ff82013fffff04ff80ffff04ffff02ffff03ffff22ff82013fffff20ffff09ff82013fff2f808080ffff01ff04ffff04ff10ffff04ffff0bffff02ff2effff04ff02ffff04ff09ffff04ff8205bfffff04ffff02ff3effff04ff02ffff04ffff04ff09ffff04ff82013fff1d8080ff80808080ff808080808080ff1580ff808080ffff02ff16ffff04ff02ffff04ff0bffff04ff17ffff04ff8202bfffff04ff15ff8080808080808080ffff01ff02ff16ffff04ff02ffff04ff0bffff04ff17ffff04ff8202bfffff04ff15ff8080808080808080ff0180ff80808080ffff01ff04ff2fffff01ff80ff80808080ff0180ffff04ffff01ffffff3f02ff04ff0101ffff822710ff02ff02ffff03ff05ffff01ff02ff3affff04ff02ffff04ff0dffff04ffff0bff2affff0bff2cff1480ffff0bff2affff0bff2affff0bff2cff3c80ff0980ffff0bff2aff0bffff0bff2cff8080808080ff8080808080ffff010b80ff0180ffff02ffff03ff17ffff01ff04ffff04ff10ffff04ffff0bff81a7ffff02ff3effff04ff02ffff04ffff04ff2fffff04ffff04ff05ffff04ffff05ffff14ffff12ff47ff0b80ff128080ffff04ffff04ff05ff8080ff80808080ff808080ff8080808080ff808080ffff02ff16ffff04ff02ffff04ff05ffff04ff0bffff04ff37ffff04ff2fff8080808080808080ff8080ff0180ffff0bff2affff0bff2cff1880ffff0bff2affff0bff2affff0bff2cff3c80ff0580ffff0bff2affff02ff3affff04ff02ffff04ff07ffff04ffff0bff2cff2c80ff8080808080ffff0bff2cff8080808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 025dee0fb1e9fa110302a7e9bfb6e381ca09618e2778b0184fa5c6b275cfce1f 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/nft_state_layer.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | a04d9f57764f54a43e4030befb4d80026e870519aaa66334aef8304f5d0393c2 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/notification.clvm: -------------------------------------------------------------------------------- 1 | (mod ( 2 | TARGET 3 | AMOUNT 4 | ) 5 | (include condition_codes.clvm) 6 | (list (list CREATE_COIN TARGET AMOUNT) (list CREATE_COIN_ANNOUNCEMENT ())) 7 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/notification.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff04ff0bff80808080ffff04ffff04ff06ffff01ff808080ff808080ffff04ffff01ff333cff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/notification.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | b8b9d8ffca6d5cba5422ead7f477ecfc8f6aaaa1c024b8c3aeb1956b24a0ab1e 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_conditions.clvm: -------------------------------------------------------------------------------- 1 | (mod (conditions) 2 | (qq (q . (unquote conditions))) 3 | ) 4 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_conditions.clvm.hex: -------------------------------------------------------------------------------- 1 | ff04ffff0101ff0280 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_conditions.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 1c77d7d5efde60a7a1d2d27db6d746bc8e568aea1ef8586ca967a0d60b83cc36 2 | -------------------------------------------------------------------------------- /flax/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 flax.types.blockchain_format.program import Program 16 | 17 | from .load_clvm import load_clvm_maybe_recompile 18 | 19 | MOD = load_clvm_maybe_recompile("p2_conditions.clvm") 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 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_delegated_conditions.clvm: -------------------------------------------------------------------------------- 1 | (mod 2 | (public_key conditions) 3 | 4 | (include condition_codes.clvm) 5 | 6 | ;; hash a tree 7 | ;; This is used to calculate a puzzle hash given a puzzle program. 8 | (defun sha256tree1 9 | (TREE) 10 | (if (l TREE) 11 | (sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE))) 12 | (sha256 1 TREE) 13 | ) 14 | ) 15 | 16 | (c (list AGG_SIG_ME public_key (sha256tree1 conditions)) conditions) 17 | 18 | ) 19 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_delegated_conditions.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ff0b80ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_delegated_conditions.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 0ff94726f1a8dea5c3f70d3121945190778d3b2b3fcda3735a1f290977e98341 2 | -------------------------------------------------------------------------------- /flax/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 | 9 | from __future__ import annotations 10 | 11 | from flax.types.blockchain_format.program import Program 12 | 13 | from .load_clvm import load_clvm_maybe_recompile 14 | 15 | MOD = load_clvm_maybe_recompile("p2_delegated_conditions.clvm") 16 | 17 | 18 | def puzzle_for_pk(public_key: Program) -> Program: 19 | return MOD.curry(public_key) 20 | 21 | 22 | def solution_for_conditions(conditions: Program) -> Program: 23 | return conditions.to([conditions]) 24 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_delegated_puzzle.clvm: -------------------------------------------------------------------------------- 1 | (mod 2 | 3 | (public_key delegated_puzzle delegated_puzzle_solution) 4 | 5 | (include condition_codes.clvm) 6 | 7 | ;; hash a tree 8 | ;; This is used to calculate a puzzle hash given a puzzle program. 9 | (defun sha256tree1 10 | (TREE) 11 | (if (l TREE) 12 | (sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE))) 13 | (sha256 1 TREE) 14 | ) 15 | ) 16 | 17 | (c (list AGG_SIG_ME public_key (sha256tree1 delegated_puzzle)) 18 | (a delegated_puzzle delegated_puzzle_solution)) 19 | ) 20 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_delegated_puzzle.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff0bff80808080ff80808080ffff02ff0bff178080ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_delegated_puzzle.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 542cde70d1102cd1b763220990873efc8ab15625ded7eae22cc11e21ef2e2f7c 2 | -------------------------------------------------------------------------------- /flax/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 flax.types.blockchain_format.program import Program 18 | 19 | from . import p2_conditions 20 | from .load_clvm import load_clvm_maybe_recompile 21 | 22 | MOD = load_clvm_maybe_recompile("p2_delegated_puzzle.clvm") 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 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ffff03ff0bffff01ff02ffff03ffff09ff05ffff1dff0bffff1effff0bff0bffff02ff06ffff04ff02ffff04ff17ff8080808080808080ffff01ff02ff17ff2f80ffff01ff088080ff0180ffff01ff04ffff04ff04ffff04ff05ffff04ffff02ff06ffff04ff02ffff04ff17ff80808080ff80808080ffff02ff17ff2f808080ff0180ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | e9aaa49f45bad5c889b86ee3341550c155cfdd10c3a6757de618d20612fffd52 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_m_of_n_delegate_direct.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ffff03ffff09ff05ffff02ff16ffff04ff02ffff04ff17ff8080808080ffff01ff02ff0cffff04ff02ffff04ffff02ff0affff04ff02ffff04ff17ffff04ff0bff8080808080ffff04ffff02ff1effff04ff02ffff04ff2fff80808080ffff04ff2fffff04ff5fff80808080808080ffff01ff088080ff0180ffff04ffff01ffff31ff02ffff03ff05ffff01ff04ffff04ff08ffff04ff09ffff04ff0bff80808080ffff02ff0cffff04ff02ffff04ff0dffff04ff0bffff04ff17ffff04ff2fff8080808080808080ffff01ff02ff17ff2f8080ff0180ffff02ffff03ff05ffff01ff02ffff03ff09ffff01ff04ff13ffff02ff0affff04ff02ffff04ff0dffff04ff1bff808080808080ffff01ff02ff0affff04ff02ffff04ff0dffff04ff1bff808080808080ff0180ff8080ff0180ffff02ffff03ff05ffff01ff10ffff02ff16ffff04ff02ffff04ff0dff80808080ffff02ffff03ff09ffff01ff0101ff8080ff018080ff8080ff0180ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff1effff04ff02ffff04ff09ff80808080ffff02ff1effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_m_of_n_delegate_direct.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 0f199d5263ac1a62b077c159404a71abd3f9691cc57520bf1d4c5cb501504457 2 | -------------------------------------------------------------------------------- /flax/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 flax.types.blockchain_format.program import Program 11 | 12 | from .load_clvm import load_clvm_maybe_recompile 13 | 14 | MOD = load_clvm_maybe_recompile("p2_m_of_n_delegate_direct.clvm") 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 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_parent.clvm: -------------------------------------------------------------------------------- 1 | (mod 2 | ( 3 | MORPHER ; For no morphing, 1 4 | parent_parent_id 5 | parent_inner_puz 6 | parent_amount 7 | parent_solution 8 | ) 9 | 10 | (include condition_codes.clvm) 11 | (include curry-and-treehash.clinc) 12 | 13 | (c 14 | (list ASSERT_MY_PARENT_ID 15 | (calculate_coin_id parent_parent_id (a MORPHER (sha256tree parent_inner_puz)) parent_amount) 16 | ) 17 | (a parent_inner_puz parent_solution) 18 | ) 19 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_parent.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff08ffff04ffff02ff0affff04ff02ffff04ff0bffff04ffff02ff05ffff02ff0effff04ff02ffff04ff17ff8080808080ffff04ff2fff808080808080ff808080ffff02ff17ff5f8080ffff04ffff01ffff4720ffff02ffff03ffff22ffff09ffff0dff0580ff0c80ffff09ffff0dff0b80ff0c80ffff15ff17ffff0181ff8080ffff01ff0bff05ff0bff1780ffff01ff088080ff0180ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff0effff04ff02ffff04ff09ff80808080ffff02ff0effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_parent.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | b10ce2d0b18dcf8c21ddfaf55d9b9f0adcbf1e0beb55b1a8b9cad9bbff4e5f22 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_puzzle_hash.clvm: -------------------------------------------------------------------------------- 1 | (mod 2 | (inner_puzzle_hash inner_puzzle inner_puzzle_solution) 3 | 4 | ;; hash a tree 5 | ;; This is used to calculate a puzzle hash given a puzzle program. 6 | (defun sha256tree1 7 | (TREE) 8 | (if (l TREE) 9 | (sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE))) 10 | (sha256 1 TREE) 11 | ) 12 | ) 13 | 14 | (if (= inner_puzzle_hash (sha256tree1 inner_puzzle)) 15 | (a inner_puzzle inner_puzzle_solution) 16 | (x) 17 | ) 18 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_puzzle_hash.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ffff03ffff09ff05ffff02ff02ffff04ff02ffff04ff0bff8080808080ffff01ff02ff0bff1780ffff01ff088080ff0180ffff04ffff01ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff02ffff04ff02ffff04ff09ff80808080ffff02ff02ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_puzzle_hash.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 13e29a62b42cd2ef72a79e4bacdc59733ca6310d65af83d349360d36ec622363 2 | -------------------------------------------------------------------------------- /flax/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 flax.types.blockchain_format.program import Program 11 | from flax.types.blockchain_format.sized_bytes import bytes32 12 | 13 | from .load_clvm import load_clvm_maybe_recompile 14 | 15 | MOD = load_clvm_maybe_recompile("p2_puzzle_hash.clvm") 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 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_singleton.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff18ffff04ffff0bffff02ff2effff04ff02ffff04ff05ffff04ff2fffff04ffff02ff3effff04ff02ffff04ffff04ff05ffff04ff0bff178080ff80808080ff808080808080ff5f80ff808080ffff04ffff04ff2cffff01ff248080ffff04ffff04ff10ffff04ff5fff808080ff80808080ffff04ffff01ffffff463fff02ff3c04ffff01ff0102ffff02ffff03ff05ffff01ff02ff16ffff04ff02ffff04ff0dffff04ffff0bff3affff0bff12ff3c80ffff0bff3affff0bff3affff0bff12ff2a80ff0980ffff0bff3aff0bffff0bff12ff8080808080ff8080808080ffff010b80ff0180ffff0bff3affff0bff12ff1480ffff0bff3affff0bff3affff0bff12ff2a80ff0580ffff0bff3affff02ff16ffff04ff02ffff04ff07ffff04ffff0bff12ff1280ff8080808080ffff0bff12ff8080808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_singleton.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 40f828d8dd55603f4ff9fbf6b73271e904e69406982f4fbefae2c8dcceaf9834 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_singleton_or_delayed_puzhash.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ffff03ff82017fffff01ff04ffff04ff38ffff04ffff0bffff02ff2effff04ff02ffff04ff05ffff04ff81bfffff04ffff02ff3effff04ff02ffff04ffff04ff05ffff04ff0bff178080ff80808080ff808080808080ff82017f80ff808080ffff04ffff04ff3cffff01ff248080ffff04ffff04ff28ffff04ff82017fff808080ff80808080ffff01ff04ffff04ff24ffff04ff2fff808080ffff04ffff04ff2cffff04ff5fffff04ff81bfff80808080ffff04ffff04ff10ffff04ff81bfff808080ff8080808080ff0180ffff04ffff01ffffff49ff463fffff5002ff333cffff04ff0101ffff02ff02ffff03ff05ffff01ff02ff36ffff04ff02ffff04ff0dffff04ffff0bff26ffff0bff2aff1280ffff0bff26ffff0bff26ffff0bff2aff3a80ff0980ffff0bff26ff0bffff0bff2aff8080808080ff8080808080ffff010b80ff0180ffff0bff26ffff0bff2aff3480ffff0bff26ffff0bff26ffff0bff2aff3a80ff0580ffff0bff26ffff02ff36ffff04ff02ffff04ff07ffff04ffff0bff2aff2a80ff8080808080ffff0bff2aff8080808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/p2_singleton_or_delayed_puzhash.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | adb656e0211e2ab4f42069a4c5efc80dc907e7062be08bf1628c8e5b6d94d25b 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/pool_member_innerpuz.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ffff03ff8202ffffff01ff02ff16ffff04ff02ffff04ff05ffff04ff8204bfffff04ff8206bfffff04ff82017fffff04ffff0bffff19ff2fffff18ffff019100ffffffffffffffffffffffffffffffffff8202ff8080ff0bff82017f80ff8080808080808080ffff01ff04ffff04ff08ffff04ff17ffff04ffff02ff1effff04ff02ffff04ff82017fff80808080ff80808080ffff04ffff04ff1cffff04ff5fffff04ff8206bfff80808080ff80808080ff0180ffff04ffff01ffff32ff3d33ff3effff04ffff04ff1cffff04ff0bffff04ff17ff80808080ffff04ffff04ff1cffff04ff05ffff04ff2fff80808080ffff04ffff04ff0affff04ff5fff808080ffff04ffff04ff14ffff04ffff0bff5fffff012480ff808080ff8080808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff1effff04ff02ffff04ff09ff80808080ffff02ff1effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/pool_member_innerpuz.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | a8490702e333ddd831a3ac9c22d0fa26d2bfeaf2d33608deb22f0e0123eb0494 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/pool_waitingroom_innerpuz.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ffff03ff82017fffff01ff04ffff04ff1cffff04ff5fff808080ffff04ffff04ff12ffff04ff8205ffffff04ff8206bfff80808080ffff04ffff04ff08ffff04ff17ffff04ffff02ff1effff04ff02ffff04ffff04ff8205ffffff04ff8202ffff808080ff80808080ff80808080ff80808080ffff01ff02ff16ffff04ff02ffff04ff05ffff04ff8204bfffff04ff8206bfffff04ff8202ffffff04ffff0bffff19ff2fffff18ffff019100ffffffffffffffffffffffffffffffffff8205ff8080ff0bff8202ff80ff808080808080808080ff0180ffff04ffff01ffff32ff3d52ffff333effff04ffff04ff12ffff04ff0bffff04ff17ff80808080ffff04ffff04ff12ffff04ff05ffff04ff2fff80808080ffff04ffff04ff1affff04ff5fff808080ffff04ffff04ff14ffff04ffff0bff5fffff012480ff808080ff8080808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff1effff04ff02ffff04ff09ff80808080ffff02ff1effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/pool_waitingroom_innerpuz.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | a317541a765bf8375e1c6e7c13503d0d2cbf56cacad5182befe947e78e2c0307 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/prefarm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/puzzles/prefarm/__init__.py -------------------------------------------------------------------------------- /flax/wallet/puzzles/recompile-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This hack is a quick way to recompile everything in this directory 4 | 5 | set -o errexit 6 | 7 | #BASE_DIR=`pwd | dirname` 8 | 9 | FILES=$(ls ./*.clvm) 10 | echo "$FILES" 11 | 12 | INCLUDE_DIR=$(pwd) 13 | 14 | for FILE in $FILES 15 | do 16 | echo "run -d -i $INCLUDE_DIR $FILE > $FILE.hex" 17 | # run -d -i $INCLUDE_DIR $FILE > $FILE.hex 18 | done 19 | 20 | for FILE in $FILES 21 | do 22 | echo "opd -H $FILE.hex | head -1 > $FILE.hex.sha256tree" 23 | done 24 | 25 | echo 26 | echo "Copy & paste the above to the shell to recompile" 27 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/rom_bootstrap_generator.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 161bade1f822dcd62ab712ebaf30f3922a301e48a639e4295c5685f8bece7bd9 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/rom_bootstrap_generator.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.types.blockchain_format.program import SerializedProgram 4 | 5 | from .load_clvm import load_serialized_clvm_maybe_recompile 6 | 7 | MOD = load_serialized_clvm_maybe_recompile("rom_bootstrap_generator.clvm") 8 | 9 | 10 | def get_generator() -> SerializedProgram: 11 | return MOD 12 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/settlement_payments.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ff0affff04ff02ffff04ff03ff80808080ffff04ffff01ffff333effff02ffff03ff05ffff01ff04ffff04ff0cffff04ffff02ff1effff04ff02ffff04ff09ff80808080ff808080ffff02ff16ffff04ff02ffff04ff19ffff04ffff02ff0affff04ff02ffff04ff0dff80808080ff808080808080ff8080ff0180ffff02ffff03ff05ffff01ff02ffff03ffff15ff29ff8080ffff01ff04ffff04ff08ff0980ffff02ff16ffff04ff02ffff04ff0dffff04ff0bff808080808080ffff01ff088080ff0180ffff010b80ff0180ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff1effff04ff02ffff04ff09ff80808080ffff02ff1effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/settlement_payments.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | cfbfdeed5c4ca2de3d0bf520b9cb4bb7743a359bd2e6a188d19ce7dffc21d3e7 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/settlement_payments_old.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ff0affff04ff02ffff04ff03ff80808080ffff04ffff01ffff333effff02ffff03ff05ffff01ff04ffff04ff0cffff04ffff02ff1effff04ff02ffff04ff09ff80808080ff808080ffff02ff16ffff04ff02ffff04ff19ffff04ffff02ff0affff04ff02ffff04ff0dff80808080ff808080808080ff8080ff0180ffff02ffff03ff05ffff01ff04ffff04ff08ff0980ffff02ff16ffff04ff02ffff04ff0dffff04ff0bff808080808080ffff010b80ff0180ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff1effff04ff02ffff04ff09ff80808080ffff02ff1effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/settlement_payments_old.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | bae24162efbd568f89bc7a340798a6118df0189eb9e3f8697bcea27af99f8f79 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/sha256tree.clib: -------------------------------------------------------------------------------- 1 | ( 2 | ;; hash a tree 3 | ;; This is used to calculate a puzzle hash given a puzzle program. 4 | (defun sha256tree 5 | (TREE) 6 | (if (l TREE) 7 | (sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE))) 8 | (sha256 1 TREE) 9 | ) 10 | ) 11 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/sha256tree_module.clvm: -------------------------------------------------------------------------------- 1 | ( 2 | mod (program) 3 | 4 | ;; hash a tree 5 | ;; This is used to calculate a puzzle hash given a puzzle program. 6 | (defun sha256tree 7 | (TREE) 8 | (if (l TREE) 9 | (sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE))) 10 | (sha256 1 TREE) 11 | ) 12 | ) 13 | 14 | (sha256tree program) 15 | ) -------------------------------------------------------------------------------- /flax/wallet/puzzles/sha256tree_module.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff02ff02ffff04ff02ffff04ff05ff80808080ffff04ffff01ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff02ffff04ff02ffff04ff09ff80808080ffff02ff02ffff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/sha256tree_module.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | eb4ead6576048c9d730b5ced00646c7fdd390649cfdf48a00de1590cdd8ee18f 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/singleton_launcher.clvm: -------------------------------------------------------------------------------- 1 | (mod (singleton_full_puzzle_hash amount key_value_list) 2 | 3 | (include condition_codes.clvm) 4 | 5 | ; takes a lisp tree and returns the hash of it 6 | (defun sha256tree1 (TREE) 7 | (if (l TREE) 8 | (sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE))) 9 | (sha256 1 TREE) 10 | ) 11 | ) 12 | 13 | ; main 14 | (list (list CREATE_COIN singleton_full_puzzle_hash amount) 15 | (list CREATE_COIN_ANNOUNCEMENT (sha256tree1 (list singleton_full_puzzle_hash amount key_value_list)))) 16 | ) 17 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/singleton_launcher.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff04ff04ffff04ff05ffff04ff0bff80808080ffff04ffff04ff0affff04ffff02ff0effff04ff02ffff04ffff04ff05ffff04ff0bffff04ff17ff80808080ff80808080ff808080ff808080ffff04ffff01ff33ff3cff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff0effff04ff02ffff04ff09ff80808080ffff02ff0effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/singleton_launcher.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | eff07522495060c066f66f32acc2a77e3a3e737aca8baea4d1a64ea4cdc13da9 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/singleton_top_layer.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 24e044101e57b3d8c908b8a38ad57848afd29d3eecc439dba45f4412df4954fd 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/singleton_top_layer_v1_1.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 7faa3253bfddd1e0decb0906b2dc6247bbc4cf608f58345d173adb63e8b47c9f 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/test_generator_deserialize.clvm: -------------------------------------------------------------------------------- 1 | (mod (deserializer generator_list reserved_arg) 2 | (a deserializer (list reserved_arg)) 3 | ) 4 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/test_generator_deserialize.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ff02ffff04ff0bff808080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/test_generator_deserialize.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 52add794fc76e89512e4a063c383418bda084c8a78c74055abe80179e4a7832c 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/test_multiple_generator_input_arguments.clvm: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/test_multiple_generator_input_arguments.clvm.hex: -------------------------------------------------------------------------------- 1 | ff02ffff01ff04ffff02ff04ffff04ff02ffff04ff05ffff04ff0bffff04ff82017fffff04ff8202ffffff04ffff02ff06ffff04ff02ffff04ff8205ffffff04ff17ffff04ff2fffff04ff5fffff04ff81bfff8080808080808080ff8080808080808080ff8080ffff04ffff01ffff02ffff03ff17ffff01ff04ffff02ff0bffff04ff2fffff04ff05ffff04ff5fffff04ff27ff808080808080ffff02ff04ffff04ff02ffff04ff05ffff04ff0bffff04ff37ffff04ff2fffff04ff5fff808080808080808080ff8080ff0180ff0effff0cff09ff0bff1780ffff0cff15ff2fff5f8080ff018080 -------------------------------------------------------------------------------- /flax/wallet/puzzles/test_multiple_generator_input_arguments.clvm.hex.sha256tree: -------------------------------------------------------------------------------- 1 | 156dafbddc3e1d3bfe1f2a84e48e5e46b287b8358bf65c3c091c93e855fbfc5b 2 | -------------------------------------------------------------------------------- /flax/wallet/puzzles/utility_macros.clib: -------------------------------------------------------------------------------- 1 | ( 2 | (defmacro assert items 3 | (if (r items) 4 | (list if (f items) (c assert (r items)) (q . (x))) 5 | (f items) 6 | ) 7 | ) 8 | 9 | (defmacro and ARGS 10 | (if ARGS 11 | (qq (if (unquote (f ARGS)) 12 | (unquote (c and (r ARGS))) 13 | () 14 | )) 15 | 1) 16 | ) 17 | ) -------------------------------------------------------------------------------- /flax/wallet/secret_key_store.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Dict, Optional 4 | 5 | from blspy import G1Element, PrivateKey 6 | 7 | GROUP_ORDER = 0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001 8 | 9 | 10 | class SecretKeyStore: 11 | _pk2sk: Dict[G1Element, PrivateKey] 12 | 13 | def __init__(self): 14 | self._pk2sk = {} 15 | 16 | def save_secret_key(self, secret_key: PrivateKey): 17 | public_key = secret_key.get_g1() 18 | self._pk2sk[bytes(public_key)] = secret_key 19 | 20 | def secret_key_for_public_key(self, public_key: G1Element) -> Optional[PrivateKey]: 21 | return self._pk2sk.get(bytes(public_key)) 22 | -------------------------------------------------------------------------------- /flax/wallet/settings/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/settings/__init__.py -------------------------------------------------------------------------------- /flax/wallet/settings/default_settings.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.wallet.settings.settings_objects import BackupInitialized 4 | 5 | default_backup_initialized = BackupInitialized(False, False, False, True) 6 | 7 | default_settings = {BackupInitialized.__name__: default_backup_initialized} 8 | -------------------------------------------------------------------------------- /flax/wallet/settings/settings_objects.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from flax.util.streamable import Streamable, streamable 6 | 7 | 8 | @streamable 9 | @dataclass(frozen=True) 10 | class BackupInitialized(Streamable): 11 | """ 12 | Stores user decision regarding import of backup info 13 | """ 14 | 15 | user_initialized: bool # Stores if user made a selection in UI. (Skip vs Import backup) 16 | user_skipped: bool # Stores if user decided to skip import of backup info 17 | backup_info_imported: bool # Stores if backup info has been imported 18 | new_wallet: bool # Stores if this wallet is newly created / not restored from backup 19 | -------------------------------------------------------------------------------- /flax/wallet/trading/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/trading/__init__.py -------------------------------------------------------------------------------- /flax/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 | -------------------------------------------------------------------------------- /flax/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 | -------------------------------------------------------------------------------- /flax/wallet/uncurried_puzzle.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from flax.types.blockchain_format.program import Program 6 | 7 | 8 | @dataclass(frozen=True) 9 | class UncurriedPuzzle: 10 | mod: Program 11 | args: Program 12 | 13 | 14 | def uncurry_puzzle(puzzle: Program) -> UncurriedPuzzle: 15 | return UncurriedPuzzle(*puzzle.uncurry()) 16 | -------------------------------------------------------------------------------- /flax/wallet/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/flax/wallet/util/__init__.py -------------------------------------------------------------------------------- /flax/wallet/util/compute_hints.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from flax.types.blockchain_format.sized_bytes import bytes32 4 | from flax.types.condition_opcodes import ConditionOpcode 5 | from flax.types.blockchain_format.program import INFINITE_COST 6 | from flax.types.coin_spend import CoinSpend 7 | 8 | 9 | def compute_coin_hints(cs: CoinSpend) -> List[bytes32]: 10 | _, result_program = cs.puzzle_reveal.run_with_cost(INFINITE_COST, cs.solution) 11 | 12 | h_list: List[bytes32] = [] 13 | for condition_data in result_program.as_python(): 14 | condition = condition_data[0] 15 | args = condition_data[1:] 16 | if condition == ConditionOpcode.CREATE_COIN and len(args) > 2: 17 | if isinstance(args[2], list): 18 | if isinstance(args[2][0], bytes): 19 | h_list.append(bytes32(args[2][0])) 20 | return h_list 21 | -------------------------------------------------------------------------------- /flax/wallet/util/json_clvm_utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any 4 | 5 | from flax.types.blockchain_format.program import Program 6 | 7 | 8 | def json_to_flaxlisp(json_data: Any) -> Any: 9 | list_for_flaxlisp = [] 10 | if isinstance(json_data, list): 11 | for value in json_data: 12 | list_for_flaxlisp.append(json_to_flaxlisp(value)) 13 | else: 14 | if isinstance(json_data, dict): 15 | for key, value in json_data: 16 | list_for_flaxlisp.append((key, json_to_flaxlisp(value))) 17 | else: 18 | list_for_flaxlisp = json_data 19 | return Program.to(list_for_flaxlisp) 20 | -------------------------------------------------------------------------------- /flax/wallet/util/notifications.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.types.blockchain_format.program import Program 4 | from flax.types.blockchain_format.sized_bytes import bytes32 5 | from flax.util.ints import uint64 6 | from flax.wallet.puzzles.load_clvm import load_clvm_maybe_recompile 7 | 8 | NOTIFICATION_MOD = load_clvm_maybe_recompile("notification.clvm") 9 | 10 | 11 | def construct_notification(target: bytes32, amount: uint64) -> Program: 12 | return NOTIFICATION_MOD.curry(target, amount) 13 | -------------------------------------------------------------------------------- /flax/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 | -------------------------------------------------------------------------------- /flax/wallet/util/wallet_types.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from enum import IntEnum 4 | from typing import List 5 | 6 | from typing_extensions import TypedDict 7 | 8 | from flax.types.blockchain_format.sized_bytes import bytes32 9 | from flax.util.ints import uint64 10 | 11 | 12 | class WalletType(IntEnum): 13 | # Wallet Types 14 | STANDARD_WALLET = 0 15 | ATOMIC_SWAP = 2 16 | AUTHORIZED_PAYEE = 3 17 | MULTI_SIG = 4 18 | CUSTODY = 5 19 | CAT = 6 20 | RECOVERABLE = 7 21 | DECENTRALIZED_ID = 8 22 | POOLING_WALLET = 9 23 | NFT = 10 24 | DATA_LAYER = 11 25 | DATA_LAYER_OFFER = 12 26 | 27 | 28 | class AmountWithPuzzlehash(TypedDict): 29 | amount: uint64 30 | puzzlehash: bytes32 31 | memos: List[bytes] 32 | -------------------------------------------------------------------------------- /flax/wallet/wallet_coin_record.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | 5 | from flax.types.blockchain_format.coin import Coin 6 | from flax.types.blockchain_format.sized_bytes import bytes32 7 | from flax.util.ints import uint32 8 | from flax.wallet.util.wallet_types import WalletType 9 | 10 | 11 | @dataclass(frozen=True) 12 | class WalletCoinRecord: 13 | """ 14 | These are values that correspond to a CoinName that are used 15 | in keeping track of the unspent database. 16 | """ 17 | 18 | coin: Coin 19 | confirmed_block_height: uint32 20 | spent_block_height: uint32 21 | spent: bool 22 | coinbase: bool 23 | wallet_type: WalletType 24 | wallet_id: int 25 | 26 | def name(self) -> bytes32: 27 | return self.coin.name() 28 | -------------------------------------------------------------------------------- /flax/wallet/wallet_info.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from dataclasses import dataclass 4 | from typing import List 5 | 6 | from flax.util.ints import uint8, uint32 7 | from flax.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 | -------------------------------------------------------------------------------- /lgtm.yml: -------------------------------------------------------------------------------- 1 | path_classifiers: 2 | test: 3 | - exclude: / 4 | benchmark: 5 | - exclude: / 6 | 7 | extraction: 8 | javascript: 9 | index: 10 | include: 11 | - flax-blockchain-gui 12 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=4.1.2"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [tool.setuptools_scm] 6 | fallback_version = "unknown-no-.git-directory" 7 | local_scheme = "no-local-version" 8 | 9 | [tool.black] 10 | line-length = 120 11 | target-version = ['py37', 'py38', 'py39'] 12 | include = ''' 13 | ^/( 14 | [^/]*.py 15 | | (benchmarks|build_scripts|flax|tests|tools)/.*\.pyi? 16 | )$ 17 | ''' 18 | exclude = '' 19 | -------------------------------------------------------------------------------- /run-py-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | 5 | python3 -m venv venv 6 | # shellcheck disable=SC1091 7 | . ./activate 8 | pip3 install ".[dev]" 9 | mypy --install-types 10 | 11 | py.test ./tests -s -v 12 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/__init__.py -------------------------------------------------------------------------------- /tests/blockchain/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/blockchain/__init__.py -------------------------------------------------------------------------------- /tests/blockchain/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | job_timeout = 60 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/clvm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/clvm/__init__.py -------------------------------------------------------------------------------- /tests/clvm/benchmark_costs.py: -------------------------------------------------------------------------------- 1 | from flax.types.blockchain_format.program import INFINITE_COST 2 | from flax.types.spend_bundle import SpendBundle 3 | from flax.types.generator_types import BlockGenerator 4 | from flax.consensus.cost_calculator import NPCResult 5 | from flax.consensus.default_constants import DEFAULT_CONSTANTS 6 | from flax.full_node.bundle_tools import simple_solution_generator 7 | from flax.full_node.mempool_check_conditions import get_name_puzzle_conditions 8 | 9 | 10 | def cost_of_spend_bundle(spend_bundle: SpendBundle) -> int: 11 | program: BlockGenerator = simple_solution_generator(spend_bundle) 12 | npc_result: NPCResult = get_name_puzzle_conditions( 13 | program, INFINITE_COST, cost_per_byte=DEFAULT_CONSTANTS.COST_PER_BYTE, mempool_mode=True 14 | ) 15 | return npc_result.cost 16 | -------------------------------------------------------------------------------- /tests/clvm/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | checkout_blocks_and_plots = False 5 | -------------------------------------------------------------------------------- /tests/clvm/test_curry_and_treehash.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.types.blockchain_format.program import Program 4 | from flax.wallet.puzzles import p2_delegated_puzzle_or_hidden_puzzle # import (puzzle_for_pk, puzzle_hash_for_pk, MOD) 5 | from flax.wallet.util.curry_and_treehash import calculate_hash_of_quoted_mod_hash, curry_and_treehash 6 | 7 | 8 | def test_curry_and_treehash() -> None: 9 | arbitrary_mod = p2_delegated_puzzle_or_hidden_puzzle.MOD 10 | arbitrary_mod_hash = arbitrary_mod.get_tree_hash() 11 | 12 | # we don't really care what `arbitrary_mod` is. We just need some code 13 | 14 | quoted_mod_hash = calculate_hash_of_quoted_mod_hash(arbitrary_mod_hash) 15 | 16 | for v in range(500): 17 | args = [v, v * v, v * v * v] 18 | # we don't really care about the arguments either 19 | puzzle = arbitrary_mod.curry(*args) 20 | puzzle_hash_via_curry = puzzle.get_tree_hash() 21 | hashed_args = [Program.to(_).get_tree_hash() for _ in args] 22 | puzzle_hash_via_f = curry_and_treehash(quoted_mod_hash, *hashed_args) 23 | assert puzzle_hash_via_curry == puzzle_hash_via_f 24 | -------------------------------------------------------------------------------- /tests/clvm/test_serialized_program.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | 3 | from flax.types.blockchain_format.program import Program, SerializedProgram, INFINITE_COST 4 | from flax.wallet.puzzles.load_clvm import load_clvm 5 | 6 | SHA256TREE_MOD = load_clvm("sha256tree_module.clvm") 7 | 8 | 9 | # TODO: test multiple args 10 | class TestSerializedProgram(TestCase): 11 | def test_tree_hash(self): 12 | p = SHA256TREE_MOD 13 | s = SerializedProgram.from_bytes(bytes(SHA256TREE_MOD)) 14 | self.assertEqual(s.get_tree_hash(), p.get_tree_hash()) 15 | 16 | def test_program_execution(self): 17 | p_result = SHA256TREE_MOD.run(SHA256TREE_MOD) 18 | sp = SerializedProgram.from_bytes(bytes(SHA256TREE_MOD)) 19 | cost, sp_result = sp.run_with_cost(INFINITE_COST, sp) 20 | self.assertEqual(p_result, sp_result) 21 | 22 | def test_serialization(self): 23 | s0 = SerializedProgram.from_bytes(b"\x00") 24 | p0 = Program.from_bytes(b"\x00") 25 | print(s0, p0) 26 | # TODO: enable when clvm updated for minimal encoding of zero 27 | # self.assertEqual(bytes(p0), bytes(s0)) 28 | -------------------------------------------------------------------------------- /tests/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/__init__.py -------------------------------------------------------------------------------- /tests/core/cmds/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/cmds/__init__.py -------------------------------------------------------------------------------- /tests/core/cmds/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | -------------------------------------------------------------------------------- /tests/core/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /tests/core/consensus/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/consensus/__init__.py -------------------------------------------------------------------------------- /tests/core/consensus/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | -------------------------------------------------------------------------------- /tests/core/custom_types/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/custom_types/__init__.py -------------------------------------------------------------------------------- /tests/core/custom_types/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | -------------------------------------------------------------------------------- /tests/core/custom_types/test_proof_of_space.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from secrets import token_bytes 4 | 5 | from flax.consensus.default_constants import DEFAULT_CONSTANTS 6 | from flax.types.blockchain_format.proof_of_space import ProofOfSpace # pylint: disable=E0401 7 | 8 | 9 | class TestProofOfSpace: 10 | def test_can_create_proof(self): 11 | """ 12 | Tests that the change of getting a correct proof is exactly 1/target_filter. 13 | """ 14 | num_trials = 100000 15 | success_count = 0 16 | target_filter = 2**DEFAULT_CONSTANTS.NUMBER_ZERO_BITS_PLOT_FILTER 17 | for _ in range(num_trials): 18 | challenge_hash = token_bytes(32) 19 | plot_id = token_bytes(32) 20 | sp_output = token_bytes(32) 21 | 22 | if ProofOfSpace.passes_plot_filter(DEFAULT_CONSTANTS, plot_id, challenge_hash, sp_output): 23 | success_count += 1 24 | 25 | assert abs((success_count * target_filter / num_trials) - 1) < 0.35 26 | -------------------------------------------------------------------------------- /tests/core/daemon/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/daemon/__init__.py -------------------------------------------------------------------------------- /tests/core/daemon/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | install_timelord = True 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /tests/core/data_layer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/data_layer/__init__.py -------------------------------------------------------------------------------- /tests/core/data_layer/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = 4 4 | job_timeout = 40 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /tests/core/full_node/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/full_node/__init__.py -------------------------------------------------------------------------------- /tests/core/full_node/config.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa: E501 2 | from __future__ import annotations 3 | 4 | parallel = True 5 | job_timeout = 50 6 | check_resource_usage = True 7 | checkout_blocks_and_plots = True 8 | os_skip = ["windows"] 9 | -------------------------------------------------------------------------------- /tests/core/full_node/conftest.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import asyncio 4 | from typing import Iterator 5 | 6 | import pytest 7 | 8 | 9 | # This is an optimization to reduce runtime by reducing setup and teardown on the 10 | # wallet nodes fixture below. 11 | # https://github.com/pytest-dev/pytest-asyncio/blob/v0.18.1/pytest_asyncio/plugin.py#L479-L484 12 | @pytest.fixture(scope="module") 13 | def event_loop(request: "pytest.FixtureRequest") -> Iterator[asyncio.AbstractEventLoop]: 14 | """Create an instance of the default event loop for each test case.""" 15 | loop = asyncio.get_event_loop_policy().new_event_loop() 16 | yield loop 17 | loop.close() 18 | -------------------------------------------------------------------------------- /tests/core/full_node/dos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/full_node/dos/__init__.py -------------------------------------------------------------------------------- /tests/core/full_node/dos/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | job_timeout = 60 5 | -------------------------------------------------------------------------------- /tests/core/full_node/full_sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/full_node/full_sync/__init__.py -------------------------------------------------------------------------------- /tests/core/full_node/full_sync/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 60 4 | parallel = True 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /tests/core/full_node/ram_db.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | from pathlib import Path 3 | 4 | import random 5 | 6 | from flax.consensus.blockchain import Blockchain 7 | from flax.consensus.constants import ConsensusConstants 8 | from flax.full_node.block_store import BlockStore 9 | from flax.full_node.coin_store import CoinStore 10 | from flax.util.db_wrapper import DBWrapper2 11 | 12 | 13 | async def create_ram_blockchain(consensus_constants: ConsensusConstants) -> Tuple[DBWrapper2, Blockchain]: 14 | uri = f"file:db_{random.randint(0, 99999999)}?mode=memory&cache=shared" 15 | db_wrapper = await DBWrapper2.create(database=uri, uri=True, reader_count=1) 16 | block_store = await BlockStore.create(db_wrapper) 17 | coin_store = await CoinStore.create(db_wrapper) 18 | blockchain = await Blockchain.create(coin_store, block_store, consensus_constants, Path("."), 2) 19 | return db_wrapper, blockchain 20 | -------------------------------------------------------------------------------- /tests/core/full_node/stores/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/full_node/stores/__init__.py -------------------------------------------------------------------------------- /tests/core/full_node/stores/config.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa: E501 2 | from __future__ import annotations 3 | 4 | parallel = True 5 | job_timeout = 40 6 | check_resource_usage = True 7 | checkout_blocks_and_plots = True 8 | -------------------------------------------------------------------------------- /tests/core/mempool/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/mempool/__init__.py -------------------------------------------------------------------------------- /tests/core/node_height.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | 4 | def node_height_at_least(node, h): 5 | if node.full_node.blockchain.get_peak() is not None: 6 | return node.full_node.blockchain.get_peak().height >= h 7 | return False 8 | 9 | 10 | def node_height_exactly(node, h): 11 | if node.full_node.blockchain.get_peak() is not None: 12 | return node.full_node.blockchain.get_peak().height == h 13 | return False 14 | 15 | 16 | def node_height_between(node, h1, h2): 17 | if node.full_node.blockchain.get_peak() is not None: 18 | height = node.full_node.blockchain.get_peak().height 19 | return h1 <= height <= h2 20 | return False 21 | -------------------------------------------------------------------------------- /tests/core/server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/server/__init__.py -------------------------------------------------------------------------------- /tests/core/server/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/core/ssl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/ssl/__init__.py -------------------------------------------------------------------------------- /tests/core/ssl/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /tests/core/test_coins.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from itertools import permutations 4 | 5 | from benchmarks.utils import rand_hash 6 | from flax.types.blockchain_format.coin import hash_coin_ids 7 | from flax.types.blockchain_format.sized_bytes import bytes32 8 | from flax.util.hash import std_hash 9 | 10 | 11 | def test_hash_coin_ids_empty() -> None: 12 | assert hash_coin_ids([]) == std_hash(b"") 13 | 14 | 15 | def test_hash_coin_ids() -> None: 16 | A = bytes32([1] + [0] * 31) 17 | B = bytes32([2] + [0] * 31) 18 | C = bytes32([3] + [0] * 31) 19 | D = bytes32([4] + [0] * 31) 20 | E = bytes32([254] + [0] * 31) 21 | F = bytes32([255] + [0] * 31) 22 | 23 | expected = std_hash(F + E + D + C + B + A) 24 | 25 | for i in permutations([A, B, C, D, E, F]): 26 | assert hash_coin_ids(list(i)) == expected 27 | 28 | 29 | def test_sorting() -> None: 30 | for _ in range(5000): 31 | h1 = rand_hash() 32 | h2 = rand_hash() 33 | assert (h1 < h2) == (h1.hex() < h2.hex()) 34 | -------------------------------------------------------------------------------- /tests/core/test_daemon_rpc.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from flax import __version__ 4 | from flax.daemon.client import connect_to_daemon 5 | 6 | 7 | class TestDaemonRpc: 8 | @pytest.mark.asyncio 9 | async def test_get_version_rpc(self, get_daemon, bt): 10 | ws_server = get_daemon 11 | config = bt.config 12 | client = await connect_to_daemon( 13 | config["self_hostname"], config["daemon_port"], 50 * 1000 * 1000, bt.get_daemon_ssl_context() 14 | ) 15 | response = await client.get_version() 16 | 17 | assert response["data"]["success"] 18 | assert response["data"]["version"] == __version__ 19 | ws_server.stop() 20 | -------------------------------------------------------------------------------- /tests/core/test_filter.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import pytest 4 | from chiabip158 import PyBIP158 5 | 6 | 7 | class TestFilter: 8 | @pytest.mark.asyncio 9 | async def test_basic_filter_test(self, wallet_and_node): 10 | full_nodes, wallets, bt = wallet_and_node 11 | wallet_node, server_2 = wallets[0] 12 | wallet = wallet_node.wallet_state_manager.main_wallet 13 | 14 | num_blocks = 2 15 | ph = await wallet.get_new_puzzlehash() 16 | blocks = bt.get_consecutive_blocks( 17 | 10, 18 | guarantee_transaction_block=True, 19 | farmer_reward_puzzle_hash=ph, 20 | pool_reward_puzzle_hash=ph, 21 | ) 22 | for i in range(1, num_blocks): 23 | byte_array_tx: List[bytes] = [] 24 | block = blocks[i] 25 | coins = list(block.get_included_reward_coins()) 26 | coin_0 = bytearray(coins[0].puzzle_hash) 27 | coin_1 = bytearray(coins[1].puzzle_hash) 28 | byte_array_tx.append(coin_0) 29 | byte_array_tx.append(coin_1) 30 | 31 | pl = PyBIP158(byte_array_tx) 32 | present = pl.Match(coin_0) 33 | fee_present = pl.Match(coin_1) 34 | 35 | assert present 36 | assert fee_present 37 | -------------------------------------------------------------------------------- /tests/core/test_setproctitle.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | 5 | from flax.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(): 13 | setproctitle("flax test title") 14 | -------------------------------------------------------------------------------- /tests/core/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/core/util/__init__.py -------------------------------------------------------------------------------- /tests/core/util/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /tests/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/db/__init__.py -------------------------------------------------------------------------------- /tests/farmer_harvester/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/farmer_harvester/__init__.py -------------------------------------------------------------------------------- /tests/farmer_harvester/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /tests/fee_estimation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/fee_estimation/__init__.py -------------------------------------------------------------------------------- /tests/fee_estimation/cmdline_test.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import subprocess 4 | import sysconfig 5 | from pathlib import Path 6 | from typing import Tuple, Union 7 | 8 | from click.testing import CliRunner 9 | 10 | from flax.cmds.flax import cli 11 | from flax.full_node.full_node_api import FullNodeAPI 12 | from flax.server.server import FlaxServer 13 | from flax.simulator.block_tools import BlockTools 14 | from flax.simulator.full_node_simulator import FullNodeSimulator 15 | 16 | 17 | def test_print_fee_info_cmd( 18 | one_node_one_block: Tuple[Union[FullNodeAPI, FullNodeSimulator], FlaxServer, BlockTools] 19 | ) -> None: 20 | _, _, _ = one_node_one_block 21 | scripts_path = Path(sysconfig.get_path("scripts")) 22 | subprocess.run([scripts_path.joinpath("flax"), "show", "-f"], check=True) 23 | 24 | 25 | def test_show_fee_info( 26 | one_node_one_block: Tuple[Union[FullNodeAPI, FullNodeSimulator], FlaxServer, BlockTools] 27 | ) -> None: 28 | _, _, _ = one_node_one_block 29 | runner = CliRunner() 30 | result = runner.invoke(cli, ["show", "-f"]) 31 | assert result.exit_code == 0 32 | -------------------------------------------------------------------------------- /tests/generator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/generator/__init__.py -------------------------------------------------------------------------------- /tests/generator/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | -------------------------------------------------------------------------------- /tests/generator/test_list_to_batches.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from flax.util.generator_tools import list_to_batches 3 | 4 | 5 | def test_empty_lists(): 6 | # An empty list should return an empty iterator and skip the loop's body. 7 | for _, _ in list_to_batches([], 1): 8 | assert False 9 | 10 | 11 | def test_valid(): 12 | for k in range(1, 10): 13 | test_list = [x for x in range(0, k)] 14 | for i in range(1, len(test_list) + 1): # Test batch_size 1 to 11 (length + 1) 15 | checked = 0 16 | for remaining, batch in list_to_batches(test_list, i): 17 | assert remaining == max(len(test_list) - checked - i, 0) 18 | assert len(batch) <= i 19 | assert batch == test_list[checked : min(checked + i, len(test_list))] 20 | checked += len(batch) 21 | assert checked == len(test_list) 22 | 23 | 24 | def test_invalid_batch_sizes(): 25 | with pytest.raises(ValueError): 26 | for _ in list_to_batches([], 0): 27 | assert False 28 | with pytest.raises(ValueError): 29 | for _ in list_to_batches([], -1): 30 | assert False 31 | -------------------------------------------------------------------------------- /tests/plot_sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/plot_sync/__init__.py -------------------------------------------------------------------------------- /tests/plot_sync/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /tests/plotting/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/plotting/__init__.py -------------------------------------------------------------------------------- /tests/plotting/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | install_timelord = False 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /tests/plotting/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path 4 | from typing import List 5 | 6 | from flax.simulator.block_tools import get_plot_dir 7 | 8 | 9 | def get_test_plots(sub_dir: str = "") -> List[Path]: 10 | path = get_plot_dir() 11 | if sub_dir != "": 12 | path = path / sub_dir 13 | return list(sorted(path.glob("*.plot"))) 14 | -------------------------------------------------------------------------------- /tests/pools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/pools/__init__.py -------------------------------------------------------------------------------- /tests/pools/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = 2 4 | job_timeout = 60 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /tests/pools/test_pool_cmdline.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa: E501 2 | 3 | import click 4 | import pytest 5 | from click.testing import CliRunner, Result 6 | 7 | from flax.cmds.plotnft import validate_fee 8 | from flax.cmds.plotnft import create_cmd, show_cmd 9 | 10 | pytestmark = pytest.mark.skip("TODO: Works locally but fails on CI, needs to be fixed!") 11 | 12 | 13 | class TestPoolNFTCommands: 14 | def test_validate_fee(self): 15 | with pytest.raises(click.exceptions.BadParameter): 16 | r = validate_fee(None, "fee", "1.0") 17 | 18 | with pytest.raises(click.exceptions.BadParameter): 19 | r = validate_fee(None, "fee", "-1") 20 | 21 | r = validate_fee(None, "fee", "0") 22 | assert r == "0" 23 | 24 | r = validate_fee(None, "fee", "0.000000000001") 25 | assert r == "0.000000000001" 26 | 27 | r = validate_fee(None, "fee", "0.5") 28 | assert r == "0.5" 29 | 30 | def test_plotnft_show(self): 31 | runner = CliRunner() 32 | result: Result = runner.invoke(show_cmd, []) 33 | assert result.exit_code == 0 34 | 35 | def test_validate_fee_cmdline(self): 36 | runner = CliRunner() 37 | result: Result = runner.invoke(create_cmd, ["create", "-s", "local", "--fee", "0.005"]) 38 | assert result.exit_code != 0 39 | -------------------------------------------------------------------------------- /tests/simulation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/simulation/__init__.py -------------------------------------------------------------------------------- /tests/simulation/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 60 4 | install_timelord = True 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /tests/testconfig.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import TYPE_CHECKING, List, Union 4 | 5 | if TYPE_CHECKING: 6 | from typing_extensions import Literal 7 | 8 | Oses = Literal["macos", "ubuntu", "windows"] 9 | 10 | # Defaults are conservative. 11 | parallel: Union[bool, int, Literal["auto"]] = False 12 | checkout_blocks_and_plots = False 13 | install_timelord = False 14 | check_resource_usage = False 15 | job_timeout = 30 16 | custom_vars: List[str] = [] 17 | os_skip: List[Oses] = [] 18 | -------------------------------------------------------------------------------- /tests/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/tools/__init__.py -------------------------------------------------------------------------------- /tests/tools/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | -------------------------------------------------------------------------------- /tests/tools/test-blockchain-db.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/tools/test-blockchain-db.sqlite -------------------------------------------------------------------------------- /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 tools.test_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): 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 | -------------------------------------------------------------------------------- /tests/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/util/__init__.py -------------------------------------------------------------------------------- /tests/util/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | job_timeout = 60 5 | -------------------------------------------------------------------------------- /tests/util/db_connection.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from flax.util.db_wrapper import DBWrapper2 3 | import tempfile 4 | 5 | 6 | class DBConnection: 7 | def __init__(self, db_version: int) -> None: 8 | self.db_version = db_version 9 | 10 | async def __aenter__(self) -> DBWrapper2: 11 | self.db_path = Path(tempfile.NamedTemporaryFile().name) 12 | if self.db_path.exists(): 13 | self.db_path.unlink() 14 | self._db_wrapper = await DBWrapper2.create(database=self.db_path, reader_count=4, db_version=self.db_version) 15 | 16 | return self._db_wrapper 17 | 18 | async def __aexit__(self, exc_t, exc_v, exc_tb) -> None: 19 | await self._db_wrapper.close() 20 | self.db_path.unlink() 21 | -------------------------------------------------------------------------------- /tests/util/protocol_messages_bytes-v1.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/util/protocol_messages_bytes-v1.0 -------------------------------------------------------------------------------- /tests/util/rpc.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.rpc.rpc_client import RpcClient 4 | from flax.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_connections", 14 | "/open_connection", 15 | "/close_connection", 16 | "/stop_node", 17 | "/get_routes", 18 | "/healthz", 19 | ] 20 | assert len(routes_api) > 0 21 | assert sorted(routes_client) == sorted(routes_api + routes_server) 22 | -------------------------------------------------------------------------------- /tests/util/temp_file.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import contextlib 4 | import tempfile 5 | from pathlib import Path 6 | from typing import Iterator 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 | -------------------------------------------------------------------------------- /tests/util/test_chunks.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.util.chunks import chunks 4 | 5 | 6 | def test_chunks() -> None: 7 | 8 | assert list(chunks([], 0)) == [] 9 | assert list(chunks(["a"], 0)) == [["a"]] 10 | assert list(chunks(["a", "b"], 0)) == [["a"], ["b"]] 11 | 12 | assert list(chunks(["a", "b", "c", "d"], -1)) == [["a"], ["b"], ["c"], ["d"]] 13 | assert list(chunks(["a", "b", "c", "d"], 0)) == [["a"], ["b"], ["c"], ["d"]] 14 | assert list(chunks(["a", "b", "c", "d"], 1)) == [["a"], ["b"], ["c"], ["d"]] 15 | assert list(chunks(["a", "b", "c", "d"], 2)) == [["a", "b"], ["c", "d"]] 16 | assert list(chunks(["a", "b", "c", "d"], 3)) == [["a", "b", "c"], ["d"]] 17 | assert list(chunks(["a", "b", "c", "d"], 4)) == [["a", "b", "c", "d"]] 18 | assert list(chunks(["a", "b", "c", "d"], 200)) == [["a", "b", "c", "d"]] 19 | -------------------------------------------------------------------------------- /tests/util/wallet_is_synced.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import List 4 | 5 | from flax.full_node.full_node_api import FullNodeAPI 6 | from flax.wallet.wallet_node import WalletNode 7 | 8 | 9 | async def wallet_is_synced(wallet_node: WalletNode, full_node_api: FullNodeAPI) -> bool: 10 | wallet_height = await wallet_node.wallet_state_manager.blockchain.get_finished_sync_up_to() 11 | full_node_height = full_node_api.full_node.blockchain.get_peak_height() 12 | has_pending_queue_items = wallet_node.new_peak_queue.has_pending_data_process_items() 13 | return wallet_height == full_node_height and not has_pending_queue_items 14 | 15 | 16 | async def wallets_are_synced(wns: List[WalletNode], full_node_api: FullNodeAPI) -> bool: 17 | return all([await wallet_is_synced(wn, full_node_api) for wn in wns]) 18 | -------------------------------------------------------------------------------- /tests/wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/wallet/__init__.py -------------------------------------------------------------------------------- /tests/wallet/cat_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/wallet/cat_wallet/__init__.py -------------------------------------------------------------------------------- /tests/wallet/cat_wallet/config.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa: E501 2 | from __future__ import annotations 3 | 4 | job_timeout = 50 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /tests/wallet/config.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa: E501 2 | from __future__ import annotations 3 | 4 | job_timeout = 40 5 | parallel = True 6 | checkout_blocks_and_plots = True 7 | -------------------------------------------------------------------------------- /tests/wallet/db_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/wallet/db_wallet/__init__.py -------------------------------------------------------------------------------- /tests/wallet/db_wallet/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /tests/wallet/did_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/wallet/did_wallet/__init__.py -------------------------------------------------------------------------------- /tests/wallet/did_wallet/config.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa: E501 2 | from __future__ import annotations 3 | 4 | job_timeout = 50 5 | checkout_blocks_and_plots = True 6 | -------------------------------------------------------------------------------- /tests/wallet/nft_wallet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/wallet/nft_wallet/__init__.py -------------------------------------------------------------------------------- /tests/wallet/nft_wallet/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 45 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /tests/wallet/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/wallet/rpc/__init__.py -------------------------------------------------------------------------------- /tests/wallet/rpc/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /tests/wallet/simple_sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/wallet/simple_sync/__init__.py -------------------------------------------------------------------------------- /tests/wallet/simple_sync/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | checkout_blocks_and_plots = True 4 | -------------------------------------------------------------------------------- /tests/wallet/sync/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/wallet/sync/__init__.py -------------------------------------------------------------------------------- /tests/wallet/sync/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | job_timeout = 60 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /tests/wallet/test_taproot.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import ( 4 | DEFAULT_HIDDEN_PUZZLE, 5 | calculate_synthetic_offset, 6 | calculate_synthetic_public_key, 7 | ) 8 | from tests.core.make_block_generator import int_to_public_key 9 | 10 | 11 | class TestTaproot: 12 | def test_1(self): 13 | for main_secret_exponent in range(500, 600): 14 | hidden_puzzle_hash = DEFAULT_HIDDEN_PUZZLE.get_tree_hash() 15 | main_pubkey = int_to_public_key(main_secret_exponent) 16 | offset = calculate_synthetic_offset(main_pubkey, hidden_puzzle_hash) 17 | offset_pubkey = int_to_public_key(offset) 18 | spk1 = main_pubkey + offset_pubkey 19 | spk2 = calculate_synthetic_public_key(main_pubkey, hidden_puzzle_hash) 20 | assert spk1 == spk2 21 | -------------------------------------------------------------------------------- /tests/wallet/test_wallet_user_store.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import pytest 4 | 5 | from flax.wallet.util.wallet_types import WalletType 6 | from flax.wallet.wallet_user_store import WalletUserStore 7 | from tests.util.db_connection import DBConnection 8 | 9 | 10 | @pytest.mark.asyncio 11 | async def test_store(): 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.id == 5 21 | 22 | for i in range(2, 6): 23 | await store.delete_wallet(i) 24 | 25 | assert (await store.get_last_wallet()).id == 1 26 | wallet = await store.create_wallet("CAT_WALLET", WalletType.CAT, "abc") 27 | # Due to autoincrement, we don't reuse IDs 28 | assert (await store.get_last_wallet()).id == 6 29 | assert wallet.id == 6 30 | 31 | assert (await store.get_wallet_by_id(7)) is None 32 | assert (await store.get_wallet_by_id(6)) == wallet 33 | assert await store.get_last_wallet() == wallet 34 | -------------------------------------------------------------------------------- /tests/weight_proof/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tests/weight_proof/__init__.py -------------------------------------------------------------------------------- /tests/weight_proof/config.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | parallel = True 4 | checkout_blocks_and_plots = True 5 | -------------------------------------------------------------------------------- /tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flax-Network/flax-blockchain/bb8715f3155bb8011a04cc8c05b3fa8133e4c64b/tools/__init__.py -------------------------------------------------------------------------------- /tools/plot-log.gnuplot: -------------------------------------------------------------------------------- 1 | set term png size 6000, 1000 2 | set output 'block-cost.png' 3 | set xlabel "block height" 4 | set ylabel "cost" 5 | set y2label "duration (s)" 6 | 7 | plot "block-chain-stats.log" using 2:3 title "cost" axes x1y1 with points, \ 8 | "block-chain-stats.log" using 2:4 title "runtime" axes x1y2 with points 9 | 10 | set output 'block-size.png' 11 | set ylabel "Bytes" 12 | unset y2label 13 | 14 | plot "block-chain-stats.log" using 2:8 with points title "block size" axes x1y1 15 | 16 | set output 'block-coins.png' 17 | set ylabel "number" 18 | unset y2label 19 | 20 | plot 'block-chain-stats.log' using 2:9 title 'removals' with points, \ 21 | 'block-chain-stats.log' using 2:10 title 'additions' with points 22 | 23 | set output 'block-fees.png' 24 | set ylabel "number" 25 | unset y2label 26 | 27 | plot 'block-chain-stats.log' using 2:7 title 'fees' with points 28 | 29 | set output 'block-refs.png' 30 | set ylabel "number" 31 | set y2label "duration (s)" 32 | 33 | plot 'block-chain-stats.log' using 2:5 title 'num block references' axes x1y1 with points, \ 34 | 'block-chain-stats.log' using 2:6 title 'block reference lookup time' axes x1y2 with points 35 | -------------------------------------------------------------------------------- /tools/run_benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | run_benchmark() { 4 | # shellcheck disable=SC2086 5 | python ./tools/test_full_sync.py run $3 --profile --test-constants "$1" & 6 | test_pid=$! 7 | python ./tools/cpu_utilization.py $test_pid 8 | mkdir -p "$2" 9 | mv test-full-sync.log cpu.png cpu-usage.log plot-cpu.gnuplot "$2" 10 | python ./tools/test_full_sync.py analyze 11 | mv slow-batch-*.profile slow-batch-*.png "$2" 12 | python ./flax/util/profiler.py profile-node >"$2/node-profile.txt" 13 | mv profile-node "$2" 14 | } 15 | 16 | cd .. 17 | 18 | run_benchmark stress-test-blockchain-1500-0-refs.sqlite "$1-sync-empty" "" 19 | run_benchmark stress-test-blockchain-1500-0-refs.sqlite "$1-keepup-empty" --keep-up 20 | 21 | run_benchmark stress-test-blockchain-500-100.sqlite "$1-sync-full" "" 22 | run_benchmark stress-test-blockchain-500-100.sqlite "$1-keepup-full" --keep-up 23 | -------------------------------------------------------------------------------- /tools/test_constants.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from flax.consensus.default_constants import DEFAULT_CONSTANTS 4 | 5 | test_constants = DEFAULT_CONSTANTS.replace( 6 | **{ 7 | "MIN_PLOT_SIZE": 18, 8 | "MIN_BLOCKS_PER_CHALLENGE_BLOCK": 12, 9 | "DIFFICULTY_STARTING": 2**9, 10 | "DISCRIMINANT_SIZE_BITS": 16, 11 | "SUB_EPOCH_BLOCKS": 170, 12 | "WEIGHT_PROOF_THRESHOLD": 2, 13 | "WEIGHT_PROOF_RECENT_BLOCKS": 380, 14 | "DIFFICULTY_CONSTANT_FACTOR": 33554432, 15 | "NUM_SPS_SUB_SLOT": 16, # Must be a power of 2 16 | "MAX_SUB_SLOT_BLOCKS": 50, 17 | "EPOCH_BLOCKS": 340, 18 | "SUB_SLOT_ITERS_STARTING": 2**10, # Must be a multiple of 64 19 | "NUMBER_ZERO_BITS_PLOT_FILTER": 1, # H(plot signature of the challenge) must start with these many zeroes 20 | } 21 | ) 22 | --------------------------------------------------------------------------------