Full Code of ArweaveTeam/arweave for AI

master 138acae765c7 cached
999 files
32.1 MB
1.4M tokens
101 symbols
5 requests
Download .txt
Showing preview only (5,634K chars total). Download the full file or copy to clipboard to get everything.
Repository: ArweaveTeam/arweave
Branch: master
Commit: 138acae765c7
Files: 999
Total size: 32.1 MB

Directory structure:
gitextract_87p354ak/

├── .cursor/
│   ├── BUGBOT.md
│   └── rules/
│       ├── build.mdc
│       └── protocol.mdc
├── .gitattributes
├── .github/
│   └── workflows/
│       ├── e2e-test.yml
│       ├── gitstamp.yaml
│       ├── release.yml
│       ├── test-amd64-ubuntu-22.04.yml
│       ├── test-arm64-macos-26.yml
│       ├── x-build.yml
│       ├── x-common-test.yml
│       ├── x-release-linux.yml
│       ├── x-release-macos.yml
│       ├── x-test-canary.yml
│       ├── x-test-full.yml
│       ├── x-test-on-demand.yml
│       └── x-test-vdf.yml
├── .gitignore
├── .gitmodules
├── .jupyter/
│   └── jupyter_server_config.py
├── CANARY.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── apps/
│   ├── ar_sqlite3/
│   │   ├── c_src/
│   │   │   ├── erl_comm.o
│   │   │   ├── sqlite3.o
│   │   │   └── sqlite3_driver.o
│   │   └── priv/
│   │       └── ar_sqlite3_driver
│   ├── arweave/
│   │   ├── c_src/
│   │   │   ├── Makefile
│   │   │   ├── ar_nif.c
│   │   │   ├── ar_nif.h
│   │   │   ├── randomx/
│   │   │   │   ├── ar_randomx_impl.h
│   │   │   │   ├── crc32.h
│   │   │   │   ├── feistel_msgsize_key_cipher.cpp
│   │   │   │   ├── feistel_msgsize_key_cipher.h
│   │   │   │   ├── randomx_long_with_entropy.cpp
│   │   │   │   ├── randomx_long_with_entropy.h
│   │   │   │   ├── randomx_squared.cpp
│   │   │   │   ├── randomx_squared.h
│   │   │   │   ├── rx4096/
│   │   │   │   │   └── ar_rx4096_nif.c
│   │   │   │   ├── rx512/
│   │   │   │   │   └── ar_rx512_nif.c
│   │   │   │   └── rxsquared/
│   │   │   │       └── ar_rxsquared_nif.c
│   │   │   ├── secp256k1/
│   │   │   │   └── secp256k1_nif.c
│   │   │   └── vdf/
│   │   │       ├── ar_vdf_nif.c
│   │   │       ├── sha256-armv8.S
│   │   │       ├── vdf.cpp
│   │   │       ├── vdf.h
│   │   │       ├── vdf_fused_arm.cpp
│   │   │       ├── vdf_fused_x86.cpp
│   │   │       └── vdf_hiopt_arm.cpp
│   │   ├── include/
│   │   │   ├── ar.hrl
│   │   │   ├── ar_blacklist_middleware.hrl
│   │   │   ├── ar_block.hrl
│   │   │   ├── ar_chain_stats.hrl
│   │   │   ├── ar_chunk_storage.hrl
│   │   │   ├── ar_consensus.hrl
│   │   │   ├── ar_data_discovery.hrl
│   │   │   ├── ar_data_sync.hrl
│   │   │   ├── ar_header_sync.hrl
│   │   │   ├── ar_inflation.hrl
│   │   │   ├── ar_mining.hrl
│   │   │   ├── ar_mining_cache.hrl
│   │   │   ├── ar_peers.hrl
│   │   │   ├── ar_poa.hrl
│   │   │   ├── ar_pool.hrl
│   │   │   ├── ar_pricing.hrl
│   │   │   ├── ar_repack.hrl
│   │   │   ├── ar_sup.hrl
│   │   │   ├── ar_sync_buckets.hrl
│   │   │   ├── ar_vdf.hrl
│   │   │   ├── ar_verify_chunks.hrl
│   │   │   ├── ar_wallets.hrl
│   │   │   └── user_default.hrl
│   │   ├── src/
│   │   │   ├── ar.erl
│   │   │   ├── ar_base32.erl
│   │   │   ├── ar_bench_hash.erl
│   │   │   ├── ar_bench_packing.erl
│   │   │   ├── ar_bench_timer.erl
│   │   │   ├── ar_bench_vdf.erl
│   │   │   ├── ar_blacklist_middleware.erl
│   │   │   ├── ar_block.erl
│   │   │   ├── ar_block_cache.erl
│   │   │   ├── ar_block_index.erl
│   │   │   ├── ar_block_pre_validator.erl
│   │   │   ├── ar_block_pre_validator_sup.erl
│   │   │   ├── ar_block_propagation_worker.erl
│   │   │   ├── ar_block_time_history.erl
│   │   │   ├── ar_bridge.erl
│   │   │   ├── ar_bridge_sup.erl
│   │   │   ├── ar_chain_stats.erl
│   │   │   ├── ar_chunk_copy.erl
│   │   │   ├── ar_chunk_storage.erl
│   │   │   ├── ar_chunk_storage_sup.erl
│   │   │   ├── ar_chunk_visualization.erl
│   │   │   ├── ar_cli_parser.erl
│   │   │   ├── ar_config.erl
│   │   │   ├── ar_coordination.erl
│   │   │   ├── ar_data_discovery.erl
│   │   │   ├── ar_data_doctor.erl
│   │   │   ├── ar_data_root_sync.erl
│   │   │   ├── ar_data_root_sync_sup.erl
│   │   │   ├── ar_data_sync.erl
│   │   │   ├── ar_data_sync_coordinator.erl
│   │   │   ├── ar_data_sync_sup.erl
│   │   │   ├── ar_data_sync_worker.erl
│   │   │   ├── ar_deep_hash.erl
│   │   │   ├── ar_device_lock.erl
│   │   │   ├── ar_diff_dag.erl
│   │   │   ├── ar_difficulty.erl
│   │   │   ├── ar_disk_cache.erl
│   │   │   ├── ar_disksup.erl
│   │   │   ├── ar_doctor_bench.erl
│   │   │   ├── ar_doctor_dump.erl
│   │   │   ├── ar_doctor_inspect.erl
│   │   │   ├── ar_doctor_merge.erl
│   │   │   ├── ar_domain.erl
│   │   │   ├── ar_entropy_cache.erl
│   │   │   ├── ar_entropy_gen.erl
│   │   │   ├── ar_entropy_storage.erl
│   │   │   ├── ar_ets_intervals.erl
│   │   │   ├── ar_events.erl
│   │   │   ├── ar_events_sup.erl
│   │   │   ├── ar_footprint_record.erl
│   │   │   ├── ar_fork.erl
│   │   │   ├── ar_fraction.erl
│   │   │   ├── ar_global_sync_record.erl
│   │   │   ├── ar_header_sync.erl
│   │   │   ├── ar_header_sync_sup.erl
│   │   │   ├── ar_http.erl
│   │   │   ├── ar_http_iface_client.erl
│   │   │   ├── ar_http_iface_middleware.erl
│   │   │   ├── ar_http_iface_rate_limiter_middleware.erl
│   │   │   ├── ar_http_iface_server.erl
│   │   │   ├── ar_http_req.erl
│   │   │   ├── ar_http_sup.erl
│   │   │   ├── ar_http_util.erl
│   │   │   ├── ar_ignore_registry.erl
│   │   │   ├── ar_inflation.erl
│   │   │   ├── ar_info.erl
│   │   │   ├── ar_intervals.erl
│   │   │   ├── ar_join.erl
│   │   │   ├── ar_kv.erl
│   │   │   ├── ar_kv_sup.erl
│   │   │   ├── ar_localnet.erl
│   │   │   ├── ar_localnet_mining_server.erl
│   │   │   ├── ar_localnet_mining_sup.erl
│   │   │   ├── ar_logger.erl
│   │   │   ├── ar_mempool.erl
│   │   │   ├── ar_merkle.erl
│   │   │   ├── ar_metrics.erl
│   │   │   ├── ar_metrics_collector.erl
│   │   │   ├── ar_mine_randomx.erl
│   │   │   ├── ar_mining_cache.erl
│   │   │   ├── ar_mining_hash.erl
│   │   │   ├── ar_mining_io.erl
│   │   │   ├── ar_mining_server.erl
│   │   │   ├── ar_mining_server_behaviour.erl
│   │   │   ├── ar_mining_stats.erl
│   │   │   ├── ar_mining_sup.erl
│   │   │   ├── ar_mining_worker.erl
│   │   │   ├── ar_network_middleware.erl
│   │   │   ├── ar_node.erl
│   │   │   ├── ar_node_sup.erl
│   │   │   ├── ar_node_utils.erl
│   │   │   ├── ar_node_worker.erl
│   │   │   ├── ar_nonce_limiter.erl
│   │   │   ├── ar_nonce_limiter_client.erl
│   │   │   ├── ar_nonce_limiter_server.erl
│   │   │   ├── ar_nonce_limiter_server_worker.erl
│   │   │   ├── ar_nonce_limiter_sup.erl
│   │   │   ├── ar_packing_server.erl
│   │   │   ├── ar_packing_sup.erl
│   │   │   ├── ar_patricia_tree.erl
│   │   │   ├── ar_peer_intervals.erl
│   │   │   ├── ar_peer_worker.erl
│   │   │   ├── ar_peer_worker_sup.erl
│   │   │   ├── ar_peers.erl
│   │   │   ├── ar_poa.erl
│   │   │   ├── ar_poller.erl
│   │   │   ├── ar_poller_sup.erl
│   │   │   ├── ar_poller_worker.erl
│   │   │   ├── ar_pool.erl
│   │   │   ├── ar_pool_cm_job_poller.erl
│   │   │   ├── ar_pool_job_poller.erl
│   │   │   ├── ar_pricing.erl
│   │   │   ├── ar_pricing_transition.erl
│   │   │   ├── ar_process_sampler.erl
│   │   │   ├── ar_prometheus_cowboy_handler.erl
│   │   │   ├── ar_prometheus_cowboy_labels.erl
│   │   │   ├── ar_rate_limiter.erl
│   │   │   ├── ar_repack.erl
│   │   │   ├── ar_repack_fsm.erl
│   │   │   ├── ar_repack_io.erl
│   │   │   ├── ar_replica_2_9.erl
│   │   │   ├── ar_retarget.erl
│   │   │   ├── ar_rewards.erl
│   │   │   ├── ar_rx4096_nif.erl
│   │   │   ├── ar_rx512_nif.erl
│   │   │   ├── ar_rxsquared_nif.erl
│   │   │   ├── ar_semaphore.erl
│   │   │   ├── ar_serialize.erl
│   │   │   ├── ar_shutdown_manager.erl
│   │   │   ├── ar_storage.erl
│   │   │   ├── ar_storage_module.erl
│   │   │   ├── ar_storage_sup.erl
│   │   │   ├── ar_sup.erl
│   │   │   ├── ar_sync_buckets.erl
│   │   │   ├── ar_sync_record.erl
│   │   │   ├── ar_sync_record_sup.erl
│   │   │   ├── ar_testnet.erl
│   │   │   ├── ar_timer.erl
│   │   │   ├── ar_tx.erl
│   │   │   ├── ar_tx_blacklist.erl
│   │   │   ├── ar_tx_db.erl
│   │   │   ├── ar_tx_emitter.erl
│   │   │   ├── ar_tx_emitter_sup.erl
│   │   │   ├── ar_tx_emitter_worker.erl
│   │   │   ├── ar_tx_poller.erl
│   │   │   ├── ar_tx_replay_pool.erl
│   │   │   ├── ar_tx_validator.erl
│   │   │   ├── ar_unbalanced_merkle.erl
│   │   │   ├── ar_util.erl
│   │   │   ├── ar_vdf.erl
│   │   │   ├── ar_vdf_nif.erl
│   │   │   ├── ar_verify_chunks.erl
│   │   │   ├── ar_verify_chunks_reporter.erl
│   │   │   ├── ar_verify_chunks_sup.erl
│   │   │   ├── ar_wallet.erl
│   │   │   ├── ar_wallets.erl
│   │   │   ├── ar_watchdog.erl
│   │   │   ├── ar_weave.erl
│   │   │   ├── ar_webhook.erl
│   │   │   ├── ar_webhook_sup.erl
│   │   │   ├── arweave.app.src
│   │   │   ├── e2e/
│   │   │   │   ├── ar_e2e.erl
│   │   │   │   ├── ar_repack_in_place_mine_tests.erl
│   │   │   │   ├── ar_repack_mine_tests.erl
│   │   │   │   ├── ar_sync_pack_mine_tests.erl
│   │   │   │   └── fixtures/
│   │   │   │       └── wallets/
│   │   │   │           ├── wallet_a.json
│   │   │   │           ├── wallet_b.json
│   │   │   │           ├── wallet_c.json
│   │   │   │           └── wallet_d.json
│   │   │   ├── rsa_pss.erl
│   │   │   ├── secp256k1_nif.erl
│   │   │   └── user_default.erl
│   │   └── test/
│   │       ├── ar_base64_compatibility_tests.erl
│   │       ├── ar_canary.erl
│   │       ├── ar_config_tests.erl
│   │       ├── ar_config_tests_config_fixture.json
│   │       ├── ar_coordinated_mining_tests.erl
│   │       ├── ar_data_roots_sync_tests.erl
│   │       ├── ar_data_sync_disk_pool_rotation_test.erl
│   │       ├── ar_data_sync_enqueue_intervals_test.erl
│   │       ├── ar_data_sync_mines_off_only_last_chunks_test.erl
│   │       ├── ar_data_sync_mines_off_only_second_last_chunks_test.erl
│   │       ├── ar_data_sync_records_footprints_test.erl
│   │       ├── ar_data_sync_recovers_from_corruption_test.erl
│   │       ├── ar_data_sync_syncs_after_joining_test.erl
│   │       ├── ar_data_sync_syncs_data_test.erl
│   │       ├── ar_difficulty_tests.erl
│   │       ├── ar_ecdsa_tests.erl
│   │       ├── ar_forced_validation_tests.erl
│   │       ├── ar_fork_recovery_tests.erl
│   │       ├── ar_get_chunk_tests.erl
│   │       ├── ar_header_sync_tests.erl
│   │       ├── ar_http_iface_tests.erl
│   │       ├── ar_http_util_tests.erl
│   │       ├── ar_info_tests.erl
│   │       ├── ar_mempool_tests.erl
│   │       ├── ar_mine_randomx_tests.erl
│   │       ├── ar_mine_vdf_tests.erl
│   │       ├── ar_mining_io_tests.erl
│   │       ├── ar_mining_server_tests.erl
│   │       ├── ar_mining_worker_tests.erl
│   │       ├── ar_node_tests.erl
│   │       ├── ar_nonce_limiter_tests.erl
│   │       ├── ar_packing_tests.erl
│   │       ├── ar_peer_intervals_discovery_test.erl
│   │       ├── ar_poa_tests.erl
│   │       ├── ar_poller_tests.erl
│   │       ├── ar_post_block_tests.erl
│   │       ├── ar_pricing_tests.erl
│   │       ├── ar_reject_chunks_tests.erl
│   │       ├── ar_replica_2_9_nif_tests.erl
│   │       ├── ar_semaphore_tests.erl
│   │       ├── ar_serialize_tests.erl
│   │       ├── ar_start_from_block_tests.erl
│   │       ├── ar_sync_record_tests.erl
│   │       ├── ar_test_data_sync.erl
│   │       ├── ar_test_inet_mock.erl
│   │       ├── ar_test_node.erl
│   │       ├── ar_test_runner.erl
│   │       ├── ar_tx_blacklist_tests.erl
│   │       ├── ar_tx_replay_pool_tests.erl
│   │       ├── ar_tx_tests.erl
│   │       ├── ar_vdf_block_validation_tests.erl
│   │       ├── ar_vdf_external_update_tests.erl
│   │       ├── ar_vdf_server_tests.erl
│   │       ├── ar_vdf_tests.erl
│   │       ├── ar_wallet_tests.erl
│   │       ├── ar_wallet_tests_ES256K_fixture.json
│   │       ├── ar_wallet_tests_Ed25519_fixture.json
│   │       ├── ar_wallet_tests_PS256_65537_fixture.json
│   │       ├── ar_webhook_tests.erl
│   │       └── fixtures/
│   │           └── ar_packing_tests/
│   │               ├── spora25.100kb
│   │               ├── spora25.256kb
│   │               ├── spora26.100kb
│   │               ├── spora26.256kb
│   │               ├── unpacked.100kb
│   │               └── unpacked.256kb
│   ├── arweave_config/
│   │   ├── README.md
│   │   ├── include/
│   │   │   ├── arweave_config.hrl
│   │   │   └── arweave_config_spec.hrl
│   │   ├── priv/
│   │   │   └── .gitkeep
│   │   ├── src/
│   │   │   ├── arweave_config.app.src
│   │   │   ├── arweave_config.erl
│   │   │   ├── arweave_config_arguments.erl
│   │   │   ├── arweave_config_arguments_legacy.erl
│   │   │   ├── arweave_config_bootstrap.erl
│   │   │   ├── arweave_config_environment.erl
│   │   │   ├── arweave_config_file.erl
│   │   │   ├── arweave_config_file_path.erl
│   │   │   ├── arweave_config_format_json.erl
│   │   │   ├── arweave_config_format_legacy.erl
│   │   │   ├── arweave_config_format_toml.erl
│   │   │   ├── arweave_config_format_yaml.erl
│   │   │   ├── arweave_config_fsm.erl
│   │   │   ├── arweave_config_http_server.erl
│   │   │   ├── arweave_config_legacy.erl
│   │   │   ├── arweave_config_parameters.erl
│   │   │   ├── arweave_config_parser.erl
│   │   │   ├── arweave_config_serializer.erl
│   │   │   ├── arweave_config_signal_handler.erl
│   │   │   ├── arweave_config_spec.erl
│   │   │   ├── arweave_config_specs/
│   │   │   │   ├── arweave_config_spec_default.erl
│   │   │   │   ├── arweave_config_spec_deprecated.erl
│   │   │   │   ├── arweave_config_spec_enabled.erl
│   │   │   │   ├── arweave_config_spec_environment.erl
│   │   │   │   ├── arweave_config_spec_handle_get.erl
│   │   │   │   ├── arweave_config_spec_handle_set.erl
│   │   │   │   ├── arweave_config_spec_inherit.erl
│   │   │   │   ├── arweave_config_spec_legacy.erl
│   │   │   │   ├── arweave_config_spec_long_argument.erl
│   │   │   │   ├── arweave_config_spec_long_description.erl
│   │   │   │   ├── arweave_config_spec_nargs.erl
│   │   │   │   ├── arweave_config_spec_parameter_key.erl
│   │   │   │   ├── arweave_config_spec_runtime.erl
│   │   │   │   ├── arweave_config_spec_short_argument.erl
│   │   │   │   ├── arweave_config_spec_short_description.erl
│   │   │   │   └── arweave_config_spec_type.erl
│   │   │   ├── arweave_config_store.erl
│   │   │   ├── arweave_config_sup.erl
│   │   │   └── arweave_config_type.erl
│   │   └── test/
│   │       ├── arweave_config_SUITE.erl
│   │       ├── arweave_config_arguments_SUITE.erl
│   │       ├── arweave_config_arguments_legacy_SUITE.erl
│   │       ├── arweave_config_bootstrap_SUITE.erl
│   │       ├── arweave_config_environment_SUITE.erl
│   │       ├── arweave_config_file_SUITE.erl
│   │       ├── arweave_config_file_SUITE_data/
│   │       │   ├── config_invalid.json
│   │       │   ├── config_invalid.toml
│   │       │   ├── config_invalid.yaml
│   │       │   ├── config_unsupported.xml
│   │       │   ├── config_valid.json
│   │       │   ├── config_valid.toml
│   │       │   └── config_valid.yaml
│   │       ├── arweave_config_format_SUITE.erl
│   │       ├── arweave_config_fsm_SUITE.erl
│   │       ├── arweave_config_http_server_SUITE.erl
│   │       ├── arweave_config_legacy_SUITE.erl
│   │       ├── arweave_config_serializer_SUITE.erl
│   │       ├── arweave_config_spec_SUITE.erl
│   │       ├── arweave_config_store_SUITE.erl
│   │       └── arweave_config_type_SUITE.erl
│   ├── arweave_diagnostic/
│   │   ├── README.md
│   │   ├── include/
│   │   │   └── .gitkeep
│   │   ├── priv/
│   │   │   └── .gitkeep
│   │   └── src/
│   │       ├── arweave_diagnostic.app.src
│   │       └── arweave_diagnostic.erl
│   ├── arweave_limiter/
│   │   ├── include/
│   │   │   └── .gitkeep
│   │   ├── priv/
│   │   │   └── .gitkeep
│   │   ├── src/
│   │   │   ├── arweave_limiter.app.src
│   │   │   ├── arweave_limiter.erl
│   │   │   ├── arweave_limiter_group.erl
│   │   │   ├── arweave_limiter_metrics.erl
│   │   │   ├── arweave_limiter_metrics_collector.erl
│   │   │   ├── arweave_limiter_sup.erl
│   │   │   └── arweave_limiter_time.erl
│   │   └── test/
│   │       ├── arweave_limiter_group_tests.erl
│   │       └── arweave_limiter_metrics_collector_tests.erl
│   └── randomx_square_latency_tester/
│       ├── .gitignore
│       ├── Makefile
│       └── main.cpp
├── ar-rebar3
├── arweave-server
├── arweave_styleguide.md
├── bin/
│   ├── arweave
│   ├── benchmark-hash
│   ├── benchmark-packing
│   ├── benchmark-vdf
│   ├── console
│   ├── create-ecdsa-wallet
│   ├── create-wallet
│   ├── data-doctor
│   ├── debug-logs
│   ├── e2e
│   ├── e2e_shell
│   ├── gen-dev-certs
│   ├── localnet_shell
│   ├── logs
│   ├── shell
│   ├── start
│   ├── start-localnet
│   ├── stop
│   └── test
├── config/
│   ├── sys.config
│   ├── vm.args
│   ├── vm.args.dev
│   └── vm.args.src
├── default.nix
├── deploy/
│   ├── Dockerfile.base.ubuntu20.04
│   ├── Dockerfile.base.ubuntu22.04
│   ├── Dockerfile.rocky
│   ├── Dockerfile.ubuntu
│   ├── Makefile
│   ├── build.sh
│   └── create_storage_modules.sh
├── doc/
│   ├── ar-ipfs-howto.md
│   ├── gateway_setup_guide.md
│   ├── path-manifest-schema.md
│   └── transaction_blacklists.md
├── erlang_ls.config
├── flake.nix
├── genesis_data/
│   ├── genesis_txs/
│   │   ├── -M5_EBM4MayX8ZpuLFoANHO00c4pdrSmAQbPYv7fq4U.json
│   │   ├── -wzIQJ19Hq8Zyf1L85Ga3uGTrdWA2W-UNyr8aH4a4iE.json
│   │   ├── 00nFXThK86Aog_HfLJc9j0nnXzXSlU6VdGC8qZc5ekI.json
│   │   ├── 06dr4mrXcKlfPbK8t9vWOBCDJznyG-AsKxED-Jr0U88.json
│   │   ├── 07u3F6WH-ohqBclh6UanAQ9Tau089eLJrIYM-8qkAbw.json
│   │   ├── 0EzNUQy_5b7CwNNLVAi7CnameMgnxVh-XyahT2kn74Y.json
│   │   ├── 0FJrLrxrFkVTBwRrzCCh88Gm2tG1xPxg8s_IuRZDVzw.json
│   │   ├── 0Mxvgz6_wL0FBOxJmHcRcNwiaV8B90whDxG4Vh_GFic.json
│   │   ├── 0O-UnzBvSFYoMQrbcsKHRH_YqNNylC1n9KWXmm-rr90.json
│   │   ├── 0_GKZOdtRH-nc094U5kFBlvQSjPz_oX0tcIroqLFD3U.json
│   │   ├── 0biLy8DoOhucpeYzOj5jnopxxwe0XDRfCOMjyz_a74U.json
│   │   ├── 0mFNtCi-u34uwOj3BimQTPOT9PgLGE8uqCbtXhnwoKI.json
│   │   ├── 0ogs8DTdSrNxfE2LzrScPvnyf7CQ7jMdFaS_l0-K-GU.json
│   │   ├── 0ooE635sVsd6vdhX3Pb8Ufvuqd7XRjfUbG2eXde_CmI.json
│   │   ├── 0qob-AeHGTS5EDamY6Mtsnxf1MCyUk18l09bqHAYQjU.json
│   │   ├── 128KaPgVaZyrl8Vuzt795ZlWidERzih15pNDAJgahI0.json
│   │   ├── 1Lwuom2q3FFI2pZz5EYgOzJRymgVWE3F9ZIl4vi3-kU.json
│   │   ├── 1Q2plP5JFTLwdTC27VfIgDJ-ri5h3mVsKxZploTrRmQ.json
│   │   ├── 1QoMjs6Q3XKklJ9LfovRmGbe4bAy9xY247JfDZqN3Eo.json
│   │   ├── 1nu07yo-0eB5GLxIJzzlxZW6nFTFiZ3XCDobJUcNyP4.json
│   │   ├── 1qVeYpf2sY8Qkz0iVomVPVb15NA7QUtF3eFDoMwa8PI.json
│   │   ├── 1xh_NCIFYbprcgNM4AVvZ47jRxsQmJYvCG-L-oEK4iE.json
│   │   ├── 1yvqJKdnb9SRRKoBg1m0kWAsSh9S0R5r9T9TE0YHfRQ.json
│   │   ├── 21Kfm2Apa8QWeqdMqyQAcxg9HbiluZXfQFu4-6xe-AY.json
│   │   ├── 24VRr4yT-_fOndcFYtK2oSO-p9Pm6lNtzQv8E-U43Bc.json
│   │   ├── 2vn7V0FR0JMXrVbj3Ofvc_2nvrFYCCpRoFjc7UYpJcA.json
│   │   ├── 328-6fOVCfCid4QTxHjkAMkQLMHZgDg-hZo5PnVfp2Q.json
│   │   ├── 3BSgxVi4vtVtgMBtDE8xPMqU0PmkiKtKX6P_Iw0kMsM.json
│   │   ├── 3MMMUrHDmjbCn_-TOZJJHvjLBp8PffZKUNfm_Ziy0Vk.json
│   │   ├── 3Q5gJrbqc-PeOvD4QQ4WCNp-f5cYzTyHyg6P9b-WvwM.json
│   │   ├── 3T6mnguMWl8GeiqZWiBZrGXHHtwm12mIWciusoSACkQ.json
│   │   ├── 3khTH_o8WZHSCzP-AThkmt7zZL-d_lcqUKC8nz7c8lk.json
│   │   ├── 3ku6XelnvBsaRjoNxDWb_kT_PRlQ88U0pbWURziCj7s.json
│   │   ├── 4LwZwAVcaBXhXsP5b4mnE11tUXefuRUTtTibtvoozDQ.json
│   │   ├── 4UEhkNbsGdJUjx1lJQgX9KorwSf_RRZG8VMW6jMmf8Y.json
│   │   ├── 4bPVo0hCI3E-ry2mBjvOZsBpNwPM108NT0vnJCxCeJw.json
│   │   ├── 4ewYAvsgaT-6Oy23qPqK29O_AgfvNbhLvol13yN1PdQ.json
│   │   ├── 4gLPD5njSRtiaJwjcjmNOyI5Vw8sFBQQWOefmy4SPmQ.json
│   │   ├── 4pNPqxodBesN6jQl51nH17GA1fWYfHVm8cIEfusnPLY.json
│   │   ├── 576xa7WLVidNoEcYPhAm7OlyYgbrp7Z1RBIfqLbVFzw.json
│   │   ├── 5FL2C4l-5cTl9wg4CblgIxzko8hGsB5URVA_yTAd4Nk.json
│   │   ├── 5Hatfzkj7ivvIsUIDjdOSp-4CdkClH6B7S_SNX0B2-o.json
│   │   ├── 5OdjYWAipCjWzpqfNoNhyJ673d4pRMNva8la_SFfu_c.json
│   │   ├── 5WKzIeQrDGC86IQvl2NhRtgPNKHGRA9oyjRByV1F7p4.json
│   │   ├── 5dsjbEwH2r-EWCkfOznV4JkCOLSK9vNY-0iqPr4RZUM.json
│   │   ├── 5mt79Uz6p83vdLtYRiByyWLqLI2GZBeSTutDRmzw7tM.json
│   │   ├── 5qRekKepIlFbUhGMq_nNy89bzx_K44e4GmUKYAe9MRU.json
│   │   ├── 5ynd-L6Z1vrR7Vlyr-rkrga_Jw2ibALkIgldNmsVRcQ.json
│   │   ├── 6GNIVQ-23jPJTxQkQITbSKE7SYm6J3MF4qbSgH3-AXU.json
│   │   ├── 6J1sN2nhGpqe9iJwgdfnxxCK4af88__HoEG8MLeqtyM.json
│   │   ├── 6NaT-Mz8QAiQS8atFaOu_ezqZnfu_XaQb-Grng-hvHc.json
│   │   ├── 6YbxtptbO-sidrnYdgn0G_CiNBh-az5ZzWrSCP9DYKA.json
│   │   ├── 71M1E7A4e0PFW_6C0gly77iCg7ykX17647i00eEiA-s.json
│   │   ├── 7SfLhJLtevo0zu-1bo8q6zX98WbGgpDNuY6PXbzS_j0.json
│   │   ├── 7kT0is0QnxdjqkPi0BKamhLW6z6_SK55LMAVKQC6F0M.json
│   │   ├── 87ieWrloTFUdW7YjJqJcINd1M_PBWCzA1dIRFzF4RKM.json
│   │   ├── 8b-7D96aRFJgDm8z5Tg47vBbdjseW0rRi17TYDcaQ5Q.json
│   │   ├── 8gTAwQ3f17PKI9KCX1cjuXCs9F8Hcdz8KyhsecKuCJ0.json
│   │   ├── 8rKBfpmkPlxnnYr6t0xIpUDubdidK0Fpnois7-xQJtc.json
│   │   ├── 8y-ghHqMT2lEHQn86jRXkQ8I5cLWWtKW1CQROp8mzIs.json
│   │   ├── 96Ijx5TWSxZmZaDH1pteGHFjIYY0aHmGWNHiMYeSYIM.json
│   │   ├── 98kadyXY0OPfEZKeeZcCyQ7z5mRToZklK-D6f1a-Lxw.json
│   │   ├── 9JWfraRekKtgXiIjssn0tVSzhaCaN682jECsrKtR0_E.json
│   │   ├── AN48OPO2-1mh4PKtpyoNm7SWJK2j8dF0-TFLU7Z1C9g.json
│   │   ├── AX6ZZxDpFlNhoN5Am5Hi4DER4zOBGVnQm_bse5PfHNw.json
│   │   ├── Achd6pqJVZ-1vNMLC977Lu8f20eBmgAv4dIddXql51s.json
│   │   ├── Ah6I8y8q0jb15KXjn0PyNfe7FR3v2xobg09Lfj7n1Mo.json
│   │   ├── AoSTMf_ZxlcY12bK6_sWj02kssD00K4E-vkHx2vRxG4.json
│   │   ├── B4e9FBfqZGBszHAhZqTq-TNjb-oG7rYdlMWrQa4CPZU.json
│   │   ├── BQ2RVL6XY99AIkPKDBCfUfRmJGejkZ8YKgKZc2LewhU.json
│   │   ├── BRD5ARo8tiY64RqIoxYZ6jwbE-LQT_7jA513nHwWyRE.json
│   │   ├── BYJCPwCLpd9a5K1HFy5F6ZvnemPiPFtV4hz5wMHr1NI.json
│   │   ├── ByvrfeR4UNmWJwF2fU41mBo6ThFl49u24rEGpbeSI0Q.json
│   │   ├── C3auX8HXhc2dChmvSBUfgGyYynuAr6P3g0p7420GG78.json
│   │   ├── CEXuGv3KvVtkf5gkV0ip3g1FF-i12WIDo6IOigORIZA.json
│   │   ├── CMr-rV5FdlQcRBo4loZzj66EFqwHBmA36tWiRMKGigQ.json
│   │   ├── COXhhpbcLSEe2iP2kp4SDj5NjjBAC8CucsAgOHRF_lc.json
│   │   ├── CSkFcCmNgvnp7jp7aK0tEGsLWiZVMF-QBkEFaJrAG48.json
│   │   ├── CUu1gtu6L5tJxkOAu13tNBGDKECohV8M4qgCOOPNtas.json
│   │   ├── CZ181FVir4NaSJ7JsVb50-xCaZtd3dmKbDer7jpTSyI.json
│   │   ├── CbV_CDXgVNjV6fyoBDkYmbAcaC5VsLDYXgEIwj2Ewyo.json
│   │   ├── DC6gmByeCki7uyXHJhX_A9x3pkMgmJ8Tv6wDRnh7vGs.json
│   │   ├── DDrS8BD0XTUVJt5E8kwisVTBX4PBWp0lCnSkSD3PJto.json
│   │   ├── DJf1SRoKaPo1h3F-7oKIMu4A-r9dXXMjE57WQilPdTk.json
│   │   ├── DMtXbcR_qHwdYXvkuCGOQARs_QtN9iWPw4x6TTaWOcw.json
│   │   ├── DQ6WaBfLEMEFhKoMoutuPyO_zFg1hWTDXT13CD8n1nw.json
│   │   ├── DTGNdsYZDXoU1nE82yEjG5ZEssxwUmkFTkM3_i6oSx8.json
│   │   ├── DkBAprUInkCbFa6A_WJJNL1z_PnhEavvyZtF09lmyvw.json
│   │   ├── DpEoi9F4g952ajGuT4g1HWY-xndyE77dn0VfdNXkrC8.json
│   │   ├── Dxrsx0xuPVY7oz9yHbL6wOFxo6ws7ycVe778C2bc9J8.json
│   │   ├── EPZ0hBh1wp-7T4JED4v6DOItd-9MNWkRfbLyizDLBsE.json
│   │   ├── EQh5rYFJ5Z5yESi4DIuvl2n6iVZS899tA6V6rf2Xwhk.json
│   │   ├── EUMtkWCJU0L23RnhXKfQ1wtD3Jh2O-vpFnLcQXynoAQ.json
│   │   ├── Eeo6rANLMAXonDFLDG2nu7n99O3Ymfk01wYXJBbEixY.json
│   │   ├── EnPMt9yzTsxLPR5mD9zUvndxicdYBUNzOlcCPvQlOK8.json
│   │   ├── EvKHSfokNyuiTarFKOuQ_-SaBwtllGpQGc7IFkRfBfc.json
│   │   ├── F5R2EA-gM8AtQ9_NymKwtr_Im3_ljMR38ndzCs5c77Y.json
│   │   ├── FTYnf3Z3QqEpNzTigfAlGTkgpgCWtFA7R8i-I1ik_Vo.json
│   │   ├── FkZzg_-5eSdFlbq9XnHe3wRhYidHJPXwUQ6YLuJijS0.json
│   │   ├── FmfkuPmh0vkdv_qbjXBUX1sQ-DmwBFbjuC4punobGy0.json
│   │   ├── G1GqspPmLkJTiT35QUTWBT4def7j5ORSfHCtrYzrrng.json
│   │   ├── G5FyMvm8E0_07vFgz-XISJN3VEviSrbtih9_Wptef9w.json
│   │   ├── GlWMQUuiL80knS07G7NpoYat3w18VMuyLEuC_Pmijng.json
│   │   ├── GypgExivgblZSA-1n7KjdI0SJOyXwFJkuzzPWS4NID8.json
│   │   ├── HFUR5ZwLihdaonJWHRHBuLay6cw8ZMV0bM870xhE6Qk.json
│   │   ├── HSlgnBu2Yxros7zyehPgiu2u7h80dJfCCqrA88UnkB4.json
│   │   ├── HTt6lPYQfcIgUxKPjUt3aQrpwE5e3UA4UT2EI9RxSbw.json
│   │   ├── H_0S6x36tsFH-x1h77jV_zzGGp97V8UjmgC0RZYwbtM.json
│   │   ├── I6s8Z6gEPLQABFstkCoLVv_gdQNGb-uuMMut-R7q2hA.json
│   │   ├── IACLRsWq-T6aesGEAjfFTZJd2sy7sFvWL7O6FI9A39U.json
│   │   ├── IJsiiIbd-Qs39TAJ67hiRJFsBye_rgQdU9GBid_PnZw.json
│   │   ├── IQgiEwMLp1bb6muuB_G7Q3sRaaZ3OZHUSjgshUq5YMU.json
│   │   ├── ISiC3yaTW9KnZmgs39osghIg0HP8ISh77bzH7u2m55Q.json
│   │   ├── IpwG_74praZjsu9L91_KWYHrVTpEDwyHZrsHgum4Z8o.json
│   │   ├── IvyUOghXQ31LnYE3bYEkS82gTAvpIa1rGGQKmiJuuMk.json
│   │   ├── IwSIt1P5I_mM-gAeAvXiyxRVb73hqkQAMfxLIHbbZYk.json
│   │   ├── Juzb8MlmGd2qomIUwgfGzIFO7c7ZcY87kJPmqpSkt18.json
│   │   ├── K47jh6Jr6TmZeZ_TadmyLLy1V6ZvLNpvV5FWcICohnk.json
│   │   ├── KOm2FJzmNXa_yjYC-58DkysCdk7FRFMcRmBx3DF6S9A.json
│   │   ├── KPNGfBMOznCXZwOVvCXHRR6sVJx1akVkmXTV98lCMKY.json
│   │   ├── K_ae8Bfvql0dGhIfRH-R7W-zWoeB95kYGJNi3HjFyrs.json
│   │   ├── Kgr-XWwHYos5Y95ZJ9mAUwjYjj_rP0I-GnWctQDNlp8.json
│   │   ├── KhQeu3CG_X1zoHbyy99GUlC9gVFFexf6vVPOlLgCj9I.json
│   │   ├── Kl1zrMIDIC9yW8yLMnSKQYDoV0PY41ymzJQw91qaZvY.json
│   │   ├── L8tkBBP7fyYfK4txqP-fGk_ODOU4UfIgFV79O-qd5vY.json
│   │   ├── L9J9SkTWI_Fx5KhujeWGokIchHTSFlSIC0blr0JIz80.json
│   │   ├── LBTipZADoYfO-9UecE07Z83ijiLl0f2wAGXyRFQqKCY.json
│   │   ├── LC-_5GDhs09OvN7r8GPmjMa6A9xSeVtsAmDgYCgspvc.json
│   │   ├── LFQ5iV6E5wyBbJmJoFJdH39ZxfW-y7mZFKou2H-ONvg.json
│   │   ├── LJ2QSdjHftgyCOSgy9Ub0OkTTN25rxCY7D7mt6u8Uy8.json
│   │   ├── LUdFh6g9auj1LRtk8IUwLoY3e91jIkcSyPKuQQekPY4.json
│   │   ├── LiitFWnODMUA7esa_f49IiMEdN7cTKoKw1cgG2J_eNE.json
│   │   ├── LixFbPqM1ZZ-5JWo339FMfPCpD_6M85rVK8IVmmt8m8.json
│   │   ├── M7oOLbk7TPBanLCS0pzkJSbV1CYoJabbsSDe_pCjhEo.json
│   │   ├── MOoLwb8S881q3-gM4GK7DuCEoh5CZnF1tMIZG300X58.json
│   │   ├── MPP4fxmSkvM2BVq8rumeT5yvDNu3QAT_kqpOlAq5s2E.json
│   │   ├── M_wQsQbFGtGiEaH0uW2swBubAnFab3ZcCN8IYWZvVzo.json
│   │   ├── Mk8XJgQPSOIsx_QX_XDPxdEG5NcKgO92q9i37uLZsrs.json
│   │   ├── Ms9gCRdVwT9u8-ewYd6c-T0bet-n24n_q_Hn0-BlMow.json
│   │   ├── Mv-TFhA3639O4JbKzoO3wo8LNPcFwA_vaaOLHfWRfSo.json
│   │   ├── N3lqe8CUwPfChinYVV4OZZQNjtXc26JkOJyqgoKhq7E.json
│   │   ├── N6-1fOVDkoeDwKyoNdLxCVoyy-c0EF178A_oQeEchs8.json
│   │   ├── NBxewjnZAfekK0hKmwL_OpF1521JTeIpLk2a2TLDnTk.json
│   │   ├── NE7AIvW60iQL_6aagNTSiaMpmLfAfRwbxau5FZLA10g.json
│   │   ├── NEXnMz8Yuw-xfIPprKT2iwx5A1UjWwRHCH7XCpeXIPg.json
│   │   ├── NPLj86idALmTczSq2vrZdTs0bjI-e-KI0j3EOWWpu54.json
│   │   ├── NptjIrqZrQMSdLbXAGyQCr8audCzArV3EofsjRCqrQw.json
│   │   ├── NvGRQrdis2HV22enpSpPqsb0M8s-pN_nl7eJtalZyC4.json
│   │   ├── O6qlkPRgr7H3WLHjVov-CTm-q66Q4TuvhP6GC-c5ZjY.json
│   │   ├── OILhne7UcvACtB4peA4osAjRMthaZZSW9OWhe3NpLBw.json
│   │   ├── OIOqGvvuafD_5J9QzfxyPiNlnqzIcL96i6u4PTUeDmA.json
│   │   ├── OaumRLT8oE6J8gqrQ9DrY_grMuSfWtai95VnqrX24hs.json
│   │   ├── Osgzf9EDK9j7TMlqSJ_5Y1rzZgOA6qfR7ktiakLPk4A.json
│   │   ├── P_pvvzlCIX7Yaiuv6zt1voLcn69gb9jAHPRhHaHjLng.json
│   │   ├── PjeEg7GpKT8twlBkp8GHAsEqfMvmNd3RaAx-l0R_i2w.json
│   │   ├── PySb_0NIjROmsIgwz4kMwC9MVmeY1MwuKdil0WeUzxw.json
│   │   ├── QDBM2PowqCX0eUCKzgV-DgdzeDz5TXLKYS3HVXLyqoo.json
│   │   ├── QDbVk-efwdVbHDGL1vZO3mQ3g65ol5RR-1wOvPLUkkE.json
│   │   ├── QJlE99-614f6XzZ-7VctQjX9DYe5wnO21aHSgg1RhnA.json
│   │   ├── QR75we1zHW-qO7dsI932kXX0YrAIyuC2XIDRhfmK-fE.json
│   │   ├── R0Mhun4e-WmLLGxnJq4SDTRqyNvTDTKC-uXuol1s63A.json
│   │   ├── R2h2i6y-KFxuHukxmHIjSncPZSiS4tpuzH0tD1NAooI.json
│   │   ├── RU5mkM_3UrjRMffwgj7ovDMYxxjhfXvliozhpIqw0sA.json
│   │   ├── S5Uv2W6erubrzYjzm9QHKij51XE-j-GFdYwcV2uPIAA.json
│   │   ├── SBhaeMSTQm3rS6puYacdT-4wzlnkBlZ1agn6IW6Oyg8.json
│   │   ├── SCN8yn0cQASui1DeV4mMYeQrRn8eXKr7Cp9ll7L3UfI.json
│   │   ├── SHxtj5_gLdJMI-6CcspsDbFBuU_74df3I4-sAJkAr6w.json
│   │   ├── SJXMM0tlXown7l3ffjhsiKf311FDTRa7QkKX8tgyEZ8.json
│   │   ├── SWNkfm9ZZPCiYKFg6oIW_IgqJp5Ypbp-Fs9S7YgPm0c.json
│   │   ├── TFX7m_Kf56rV6LNuyQ31NeVoDHJ3x0YqhIv4-IBQ-3s.json
│   │   ├── TGdhJ01pPw49A0ZIaCCcYBnL-RPK_3KZH3cA6E9dVqc.json
│   │   ├── TGp-18LYjSWQQ36gs5prU-vDgteOL79aywxXoDS-w0c.json
│   │   ├── TUIdVI5yQH50laHvkxgAnTV6uuE2LXXH3pxIe6Q2S7I.json
│   │   ├── TkN4QLdC4tu-_Po50RYwF33shyHcanHSe_BKpryK0JA.json
│   │   ├── Tnf6b1F67AEV2r9Flj8ktSSHYoV8SeL9dFvHRkavlZo.json
│   │   ├── UMk64563QZfxgZr_vKOTDrcp5XJNENF82Pji4a078YY.json
│   │   ├── UYoJMT0QxMtB6ctUB-9iQlcx6fF8R3s8ahM4_iF4wiQ.json
│   │   ├── UdCfZG1jBYUKgeLc13zjRxmQHO4_13B-NigE57jmJ5A.json
│   │   ├── VUfaTp1eAzjnbxLR6xx_qQGVn_WOTna3rTolM8wY5BA.json
│   │   ├── VuXQZjhUaZ2Hyi6Pl8_VTOu2mUWjoEemYb5TKXPFOS0.json
│   │   ├── WE5eBi6hEq90HQvDjtJr-EmZATWJthgxh3HPPuQ7410.json
│   │   ├── WsYJKhqhppBF6_eGbd0OACdu3LU6-CUuMcLeG3ST2qc.json
│   │   ├── X9biR_ZA-rnpzk4gfLi0-pBSsjjT2l9Rk0VfYwf1WMo.json
│   │   ├── Xjz72yVLd_Qzl8_GfSPqZA1MAkxxhjr2Lsf2tGCj_ZQ.json
│   │   ├── XtDRu-1SyoRL21gpKcxWtxyksVwTF9kvW26hvQ_bPzE.json
│   │   ├── XxgirNr3QGaJTKxPWqK9byYLj7SdbfZudKd9rbynWyM.json
│   │   ├── Y0PLaTBQ73JXn_jHvldOKC3jdbqDbqTMkcW0x65_Jek.json
│   │   ├── YIEEyYfNIRSjzm_gzv6l5CelyL4AOzKX9M4XPXRk2Yo.json
│   │   ├── YfHEyNUGsOUiuqCgHV127cg2Z5Yap9tcQB1LH7tq9ZA.json
│   │   ├── Ykh5TAI6koBN4UTQZ3GNIDr_uHNjlpHH9HsvtEkoWLA.json
│   │   ├── YlalzFjBD8CgZxDlI6eNWE3PIIflHGzXyY9VzPPeCFo.json
│   │   ├── YukfPvGxtYmXFF6wJjDiZcvqmH5YItxwsoLbMxWCVFg.json
│   │   ├── Yzj2WZ-3q5vKkBJtrmGlVjZND7iqtzvMRafS0TnQiLE.json
│   │   ├── Z5e9G5QMZ_scJQ62qoqUs2XSuhknTuuAIhhGmfg3Ye8.json
│   │   ├── Z6IgRWClifhTSnomxJet2WLw8UUaslmqAi2nynj3Ke4.json
│   │   ├── Z7gfizrPOypT4Pagg3oli5g8wA8pbKB0ZJnrw-FVyys.json
│   │   ├── ZAk05et7CFN69E9NwET2mSRI0ISRigjMEjcy8kbO-Y8.json
│   │   ├── ZC44Bxrx6AtNJYLwhvpALuINZRBXklme3tpeJbJ2rdw.json
│   │   ├── ZEB62vqKvkPK2s_RmxgQ2IhafMxJ_TXCGswrrKLhYiQ.json
│   │   ├── Znw-6H_ayGJBReeQm9z9WKulBH1ZzrOovdMsNPcIe_Y.json
│   │   ├── _01J_SIBJ164H0EedSfQ8h0dMfqet66WKHwcOFQEsMc.json
│   │   ├── _Hf1lw_E6Lyd-0PGkCRQaN10cdEx4M-hl9y-zWiDo8k.json
│   │   ├── _QEE09XylMYgab9MYPvrrMy7v1jKWh0bGwqFvsBsO8s.json
│   │   ├── _fLFu_BOzTEPdX35rqUruuyNxi7f_La8T1_JG7pIPd0.json
│   │   ├── _u44CiJCcYiOrGffgZoQSmUrJe8CfYD7Nw0MdPX0tUw.json
│   │   ├── aGqWG70qjD5P8spXLMtyXnYxS9k7Net-u932EyIFl28.json
│   │   ├── aPxbCROotxwkdovWbQEhw18UNAzVy-AmjYwjo9lb5u4.json
│   │   ├── b96k6w6qUyLSSWZlmupyBmav6XYMsdt0xTc2yIUZtOA.json
│   │   ├── bnT7410oaZtnCdurp5jNgLKju9d_RRxhgggnxa5frMQ.json
│   │   ├── bqhG__MMablNhNpiSp8nopeKDCzXy97jLuSBlsKk_u8.json
│   │   ├── cIXdvNTNHJSmA6Rt5UgSNfMcGfvxDnYTa3a1ulS1SiY.json
│   │   ├── cgU_TlXi5gJ7hShSBYsS4UVi-sLTtfFv1y1sy2nNhos.json
│   │   ├── chdl-kIl4zG7VcJbKk0Q_5TeGwuH8Xp2YFPLRJJKTWw.json
│   │   ├── dYBZuFcCEgGVcfXgS9tmeJsue_qwaCRO3Mg2OHCZh_A.json
│   │   ├── daTnztzTMlA8Ras9XgQ05Fr9ZYwOg4-UDfjW875yQeQ.json
│   │   ├── dn3p_BqD1gIcZQqdA8r6TucwycKGave22IqNjzKSHqI.json
│   │   ├── drYsyF85HcvC7LM1hkzPPgTj3_zp3amcNVNobBmOxvc.json
│   │   ├── duSw-WaGKAabAztyg2zkj6hjgaVaRGBrJuvZ5Gd2Pzk.json
│   │   ├── dv28G4IsYul7liWrycsx4UKSYHA4sWUY6xFQzRPi4p4.json
│   │   ├── eGhF0za2qN5WuadlVZ1iak1S5LxXswHRzIa3j_P-sUM.json
│   │   ├── eJ2aSQ4nm-i8XAZW2pcRq6GoEjW9K8EBM6w7rLiuSHw.json
│   │   ├── efqI0eDfp0OcYB-Ms5ELukIUr8-qtlX7Ica-ikhVZLU.json
│   │   ├── ez-ItWkyBvBZ6J7_Mobrpqc9RTp6I2JBmkPDV_xCQVY.json
│   │   ├── f3jE7NK419FZzwkx9VjTkrcX5FEgl2Ky3KSK0vH-wj0.json
│   │   ├── f6MY8LMCwGbKZqXd4dkCROQK0qFMjS5OJAbZq-UhMGA.json
│   │   ├── fBVa04p7MEL8BsPpyD_Pwv3uqBnBMVzG9YpXsCwZLtc.json
│   │   ├── fkbFeVpiaAOtvt_-M9_U4HzbA8Elh5sa8xJXObrItYM.json
│   │   ├── fx1EmDF4yioha3ms_VbddDQjl4bt6pBLpFCESuEIT6E.json
│   │   ├── g19-Tkf4xuM9golcjx0mA1RkJUYocQJ3uYnH8MU1ePs.json
│   │   ├── g6TUtTIi_rwlAHNuO6ACsQqIChWACugTPmZxaaJltDM.json
│   │   ├── g8ZQaQTNUbg-jGeE61og18FrGqpFeZxjFDypGuhT7zI.json
│   │   ├── gE-2fjp2ncJ0ZRg12UBfqnCBb75OtAOksEX3wGZguqw.json
│   │   ├── gXd75eQL5Yzcn1ba51nORAvb6f_surSnz3xcNlLAxEQ.json
│   │   ├── gbYMogbLVx3rOmm7K-o3nfGPKauLMLkGMSXcKkXW13Q.json
│   │   ├── gyG1bGFt7qkMyUCrKiEfMzMzc3_3PooewqNeJpy-3Xk.json
│   │   ├── h0MlFXsvtNQlFwgTh6y7-gjXEj0CbGECgz77EwQsca0.json
│   │   ├── h0sgGEeQQcmSxg8uyiCOigWtI_r2ex-58nk1xso004c.json
│   │   ├── h37LQjpChpTPMquvaxpfFeKt_7oAB5ElDzsdbCQ61n0.json
│   │   ├── h7qIFbn0LoexuVwBcjKW7v5A65iQDQFYZUQjuowfIbk.json
│   │   ├── hRTkBAH0k74HlmlWXTWmetXcIFXvM_Zrz3i1JXULZSM.json
│   │   ├── hX6nohfkKZ_9ajziHJ6g5V5cIe1EX9H9rg7eScK988s.json
│   │   ├── i9xaFWy0avtyCCxQdmWfGNDgh-PaJgIHkNK1pcJzmV8.json
│   │   ├── iPb5JLzNajAzUNByVeIGSEPR0rzGOV5iIYjWpi99APQ.json
│   │   ├── iRF6OnneKHJLhLMdCXpo6LsxVyWIGyklFEpu1bN3cyE.json
│   │   ├── ijroBK9n_uKCS97V7iege_5Av2E-tm6ujquAazT_sBI.json
│   │   ├── iuTLZ3xxGpaBCggV5xfUkJ6hMdUQKHw6f_vEn6sbmPo.json
│   │   ├── j2IiBCd5Vf2Q8ciTVxeHbN6JgrXUFiv0xtoMTA_VtqQ.json
│   │   ├── j3l4tvphmVOyVyFkNdS7ulmexBqPqEvsSJrBsjAFJXc.json
│   │   ├── k6UueT0FWSSUbAAH4Uc1Oz6BivunVR0nSMTEILnB_dQ.json
│   │   ├── kXu3jTQwgYsphIUFbaVGg9rNiil96fNjw0RBa6oPRtU.json
│   │   ├── kcb41aN752OE__qEKDQAsbpzCUXMdlzI3clCBuxdVts.json
│   │   ├── lFqBd1sEhgw1e_adedkee2hXP9beiNYbF625KV0vObU.json
│   │   ├── lq4SrnweWCHnEhw_AV69gMLyBrPxYOmOdVdRIXkHwOg.json
│   │   ├── lsuH-ITPI--6KSzhIFclsEAWOSoRQu-8tlnOSxj_Er0.json
│   │   ├── luQlV_58e9qjm7EZpoO6f5Y1j349Q34UwTW1Lx9J_vE.json
│   │   ├── luyHFFFOvjKPqi6nVrxngcHaQ3RwbMDMqVTLqPagHy0.json
│   │   ├── m1Vv28IVJIuYiToBhxFVp3dA47je3L8WkzSjggAWXAo.json
│   │   ├── m5zFPHB-2VjCgTLStD9TLZwD1CHfLELPKkVXFJGIptM.json
│   │   ├── mGAMsTqBzau-MjTkMS5Z3g2_nUD-qQWeLtq6qlzkVl0.json
│   │   ├── mJUxc7XyUp1HV_VRoi_54geidr26I9PUaiNL4msSNxk.json
│   │   ├── mcFln0_6FIuLwE9GtMRzmdQts4QALV3dxQkXdgSdO2s.json
│   │   ├── mvGgGlFTDJ0ukM6Bssd8G8B5PrEppr4Sg1_NTvzzV1U.json
│   │   ├── n6TKbsqmGl2m3yH15RAe405vYZQ7DStlvYsHCHp1D0U.json
│   │   ├── nXGMduBKL3mpsnFNPctfjEa9Z9zlMpdxcRrdkK95D80.json
│   │   ├── nh2sbgjxu6MmU8yGV00w7X4q4XCJETeYE3zVtcj2ldk.json
│   │   ├── o0nw6fU4gPL7Ae45x1BEQr5GkXSzZUrWnZrdIWqgx6w.json
│   │   ├── oMP40Kgd9MxLfksmW_HAlGe8Rn1Px8tpF-NOHBfe9oo.json
│   │   ├── oRvFwVpHVeo0iysSg2jFOAZKE-hKwbm6mGeZ6VUZmxk.json
│   │   ├── oWWJcAiBCxhtWkIqwir4-vTvD3JFpHgZRNIpS-Xjzp4.json
│   │   ├── ocUISm-0ItAS-N3Ydwe1swo4JmoVpRzWzngFt-pDwfo.json
│   │   ├── opfZTSNdqaxXZUmaKROD2sd4QkyNDnZE3u1A95eSw4E.json
│   │   ├── p9PJG5GkKZAxLyPJyDYw4_1CmhodHGGGqB785duwVwM.json
│   │   ├── pVZkxPK8F9VFM5lDp0oTBThaw1RvmwG64wIHFChYJKA.json
│   │   ├── piTZgtn2oBsWKt09CV8LqH3I3JaVdRjFwjOAJmC-Xp4.json
│   │   ├── puLpw8OIIYCOatImKjpV5s0JWyKFq6bXFMz_qSf6mUA.json
│   │   ├── qU2Gu35-s9wMH1N4g_zMYKCqIStYzBZmRx0XlcIpjyk.json
│   │   ├── qX9u_AprdhyXAPGfh3C94x9AbxwWx9nJSs7g8FSwITM.json
│   │   ├── qyMWe-VUOzHXkQviMhNS0wJI_27nvCgDY9iiKANk-lI.json
│   │   ├── r8Yq7Lvx0FjFYyXBLn29UM5Evv4AtGLZ00LCtE_hC60.json
│   │   ├── rC7TOXwflo7w9Ky0ljTYlzdbR0A3g2GVRbRJbIIuBfY.json
│   │   ├── rRoy9jsUZ-Y10NIBksSD3P4HcVDfZheloItTTnc8_ZQ.json
│   │   ├── rTY6dpq4KEhZtB-5moP1mWN1CtrTKurv7QSY8wAN758.json
│   │   ├── rvbM0iB1HJ1YadedIDWjJ95J2XBHWwPAJD4VfpdQpxQ.json
│   │   ├── sB51Zz1HRjpwrWFhW6ZE2E-n5hl3joqxPQgnMCLX4ZM.json
│   │   ├── sfAY_3fQ41LahxW45rXfndEzeHD1eeWJgI9ZaM3slFU.json
│   │   ├── snWRgSI3vlTOy3RRkuNckM-ws-5lpFiPMpYlLx_zPyk.json
│   │   ├── tOIFTqEef5fQYPzhlkC2Um7rddT6MyrHPzUWXDv_mJc.json
│   │   ├── tVLYd_62zbU-VPzQPOMHUo9TJR1dvSZ_pAHrC5Ubs8Q.json
│   │   ├── ud3zGJZA5tPRoitGG1c6HWm9W7iRS4ZF3u6PbZ-blns.json
│   │   ├── un3O49lggBX9raJKb6yuql_QTgZYWakWw5ydwUgUuXY.json
│   │   ├── utAoO_xht393CbJ_7P_ektVYeEpkySWLM-066yJ5HyI.json
│   │   ├── v2UplxDprWwaIwbB6z3KNEj3GjloqM8SinvVahZ1Wpk.json
│   │   ├── vQ4zTq--De8FHdVnE7sYCemwiaqoZDS4emR_y6o6ZFA.json
│   │   ├── vWeY4yJSJF9LXogRZb3Qr6QyLtEIL_8IY4bzJ2e7O5I.json
│   │   ├── vaJOh_TzVSoEgbgDyKz6ABzd_wt2-ouBTe0gA1F3oMY.json
│   │   ├── wFjsB5Y9GV61NqjCeyPCdkfXKUJOYccq8Bl9aljvwGc.json
│   │   ├── wUhEm861foyWdxy0SI7CvXRcWuohItlX6Ydqo2NvtY8.json
│   │   ├── weff0Y0_3-H7Vy1HrbpIzUmbTM1rZ8Lw0wgDGYmlsrM.json
│   │   ├── wmZTwziFc_VlvYJz_4nyxYd3WxznBmsn5QQyRKDcWXU.json
│   │   ├── wnOghJX4aZlbm7SDDb4UUX8_6GZYpYYx3GireamHwAc.json
│   │   ├── x8KM69OVm6lzslK6ccAE-3EX5sW6CUHBZB-1hbc-J0A.json
│   │   ├── xC7ski_qpcrRwRkxxHwPZd2lOX6Q---2qdQ4Rr-wxAM.json
│   │   ├── xSkMzFablxREj8H_RwoMseAFk-TCwaLVIZMHqXh5DHY.json
│   │   ├── xYpSRRpO8ejUGeohlRutNt9qUMgvuZJGkPGCyu1kSas.json
│   │   ├── xavUY4L0L0nLNVvHiYfBqGL5iqUvdwQ-iY_nLLMB6J4.json
│   │   ├── xiQYsaUMtlIq9DvTyucB4gu0BFC-qnFRIDclLv8wUT8.json
│   │   ├── y-k4KjdSmwYmIugoObrtx5JWYczlEZBzwBHGMLqNP-0.json
│   │   ├── y0PrXtX7PonEbIG3uEdu-k-McGeLLAjzUriUTCMTGcw.json
│   │   ├── y6WPKL6MHzZp2ktvb1cETmNMBJyCEPlxdisKlroEBtc.json
│   │   ├── ydvI6weQPIRj2hcNg4RPqzDpFOhqiTc9iDqQ-fUUl4I.json
│   │   ├── z7Xvravldr4BhTI4KPOEWtG325_1ORaLQ4aUPOAe_us.json
│   │   ├── zCOtSnXKGGhXgrWld31Ak9qQA_SjpOqB6n-9sF74rhk.json
│   │   ├── zUFRBcWpPAUyMlojffeTnPgsLo6YgU6JaJgOR0mpBuM.json
│   │   └── zwl046ia6I5VWLRYPJzBI70ypBQN2VlvLH9a_ndNKxA.json
│   ├── genesis_wallets.csv
│   ├── hash_list_1_0
│   └── not_found.html
├── http_iface_docs.md
├── http_post_unsigned_tx_docs.md
├── localnet_snapshot/
│   ├── ar_tx_blacklist/
│   │   ├── ar_tx_blacklist
│   │   ├── ar_tx_blacklist_offsets
│   │   ├── ar_tx_blacklist_pending_data
│   │   ├── ar_tx_blacklist_pending_headers
│   │   └── ar_tx_blacklist_pending_restore_headers
│   ├── data_sync_state
│   ├── header_sync_state
│   ├── mempool
│   ├── peers
│   ├── rocksdb/
│   │   ├── account_tree_db/
│   │   │   ├── 000009.sst
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── ar_storage_block_db/
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── ar_storage_tx_confirmation_db/
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── ar_storage_tx_db/
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── block_index_db/
│   │   │   ├── 000009.sst
│   │   │   ├── 000011.sst
│   │   │   ├── 000013.sst
│   │   │   ├── 000015.sst
│   │   │   ├── 000017.sst
│   │   │   ├── 000019.sst
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── block_time_history_db/
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   └── reward_history_db/
│   │       ├── CURRENT
│   │       ├── IDENTITY
│   │       ├── LOCK
│   │       ├── MANIFEST-000004
│   │       └── OPTIONS-000007
│   └── seed_txs/
│       ├── -B7wF8TF5AodemKM2UjeFySwA_-Q12Ai8z9FSqgIEyA.json
│       ├── 0KMeq830vwvxUUM7RLCwE0ve4i0h_XHugbUTCkPNH-M.json
│       ├── 1QGjyW1AEFlrFAs6VtUcmwOVOEZJjxaBR_z61W9mftI.json
│       ├── 1VknqhhAXRQ6hzeZL-IMVBznTFCdiWcwlXhzpLKS8Zk.json
│       ├── 1fzKf0Ygc-z3ejpZ1ZLOiNBYDRzViGRdPLtUqRS1nKY.json
│       ├── 2dxNaIAvkAuL_N2qpTGSl7d7rU3Hu7d4l4IkYb9jgDU.json
│       ├── 35wYULjhQBiTFh9u-PJz6ki0v7Zi1whk_AhowUt99Ac.json
│       ├── 3DSCNJ5H9Hpyy7auT9qG5vom9jHBrCgjs48w_R6iSJg.json
│       ├── 4QcodvSlgZnuz5uWGmBARsGUJ5XaYORIO5jYM1dTucI.json
│       ├── 4tlIV1x4YRWtNMut11ox9SS-lWt3xIzcXnrBBbNxGYs.json
│       ├── 5iK4mPnFqGdUxpiZmGtTbj7xoSC2una7sjsbUyZkOmM.json
│       ├── 7M4KyVB4Wr-Le3Knb7JExgnsXTtG7718JIlhVBNstlE.json
│       ├── 7fat_nqzDJCTfJMqyEpOcavt1cZNM-tfSzASJd0wrHo.json
│       ├── 8CPVZq-zPdMQ2to1P91vl6XBXyL7sLH8-vNclnOCug8.json
│       ├── 8TiSScQCv06oS9b8Tt5WBnf7sUVgzPAFGJ3Lq2bt8rY.json
│       ├── 8qtH9T9jgYLHH-xi39w1OCNJykqew1O5qzrDkhAxN0U.json
│       ├── 9hX3cS3Vjr6vAqJW3WtPN665NpLJegcxyaDZO2esElM.json
│       ├── A5oMEDa7ZEm1kjPlXpwjuZd40rqP6eo3GobNGQY4HlY.json
│       ├── Ace-njSprwHMwZaW5nuD0y1lKFoaafU3T8d7PLBeEIA.json
│       ├── AoCuo7S7ewDIqhYheBX6AjShrbyTgIv6Fp1AwQgmGqg.json
│       ├── BFfNP1eCeYIkLiWWAVvHNLzk1N2pxkOChFzQbdv1IiA.json
│       ├── B_F4zIV1I5DXM-lR-Ko1tVUTTSmLCOYR7PoY8V8wFas.json
│       ├── CCH2h2MzMP7WMh0Xf3GYL7zZDbU7E4CZPJWngp1qmDc.json
│       ├── CQv9OVOCzntq2DRqNJ9j_WnWPcsniyGRXpt4i_a8Iy0.json
│       ├── Cdcx7-UZJN324I9L47rrph9dIVy8RwfJa9mY7cJp9gk.json
│       ├── D29DVKVYAe74sAj9NBQ351rI6SseWZ5MMsSedGtydS8.json
│       ├── D_3jwPKLfcTpWcrDV1Q7k3D4sMtyfw7vd45D2C9pUNA.json
│       ├── DlRct3GdPx7oYi3MSdmv16CgGWqhLJjbrKcIfU0E48I.json
│       ├── EDt8sO0AWKJyNeUxd-U6ihy0rgRKUPjpfRGarEHlOCs.json
│       ├── EayO1EsmOinnbi-NVa2V7cVraoI0TZ6xE5-sNU7fc94.json
│       ├── F3c9tsVvmCiFNxK7hVEzROraVm477QdyQ8t6afBs5E4.json
│       ├── FIrCkHY8jVkXcIkWYbMpuQSRYxavkOQ3wtUZPwMS1hM.json
│       ├── FbeSRhJR00VPygimhm47VwirSeBATnlf240hv4a2G4E.json
│       ├── G6JD1n-FXMSyTSryo0HoX7L3i7e4KEFK_ekDMEn9Bcg.json
│       ├── HOMVwtocaJIRPdCeKgzorJZJq1jw_lVGz0pQ3POj7No.json
│       ├── Hiu5cti9FefwcvT6xRCIoADUMkuDEm_6pZo92CK3fiw.json
│       ├── HoEZ6sK46bzTg4Jzrfy1kHFzkFQgI2UMm9pm0qJS3as.json
│       ├── Hs-Yj4ZE9ACfQIjzS8E-qvxSkQALsCIDHwcLEMnlz90.json
│       ├── Hv0Q5APV6ARfDXDpxI-07R1YFSJAQpxTFh1Z8_nCk3U.json
│       ├── I4ifBnOF6OQFautfisGFTVIn2NsrvqrdnQ-O7JOMouE.json
│       ├── Ie-fxxzdBweiA0N1ZbzUqXhNI310uDUmaBc3ajlV6YY.json
│       ├── IeEkQUBq3aE2CSbCF2Bk126lLaLZEYjUPJ_IO601tZg.json
│       ├── IqJf6iISeiEj3oof9491-jQX4drDZ92VoFuZqNmoixk.json
│       ├── JDG-HBsrHGDodot2clC3nNkRKV5cvuhRWZjCwVFHG_Q.json
│       ├── JDS1sGkpC0ua7UGfpLEJSF-jXUnjAs2fa5V7y6rccdY.json
│       ├── JNCYRy7XYR_20vvXEAwpT43ovKB23np9yE9cqQfsIJk.json
│       ├── JUf6alhhrfuL22XuQ0yrZ6_xBFBIQqi85wRxv2nUCMs.json
│       ├── JeP9HaxmjN-TcbCkhKDIQejkGdKTlOgp68O5cy_2GRc.json
│       ├── JfTiLBj5Gxr1v7JwoNf9-7sRAiLOrg1AZ6kqwSkEpTc.json
│       ├── Jo3rf0JPJR2kCHBqZG71xouWzuOSY-MXJufpfzFl7sE.json
│       ├── K0w8hOO1oCu4sQipWDQGyEFvn6kAXO-M93neMZmRoUc.json
│       ├── Lt7WJclVu4iYHqGHIYIBia3ABMnvmd5cW4ELIzUTfPE.json
│       ├── MCCCpl9AGNAzy3WvM5lniJ88iC3-8NPiiWIsxcLZZxQ.json
│       ├── MGDpPk3LsexVpFBF43-FIIvc0vyeEDroYcIONJ6abd0.json
│       ├── MQD8-8yIZwNC4A006TC1FVZSyCDHeIAN6YpDbTiX2RU.json
│       ├── MklsZ_cDz470C40UGZUJoVfMeVA89-r7SHxuomBeCPM.json
│       ├── NBjbIMFIdd6jFhSZ20izEke9Ju8jMuvYl8O4bqe4wC4.json
│       ├── NixeAD5Y_8sQfcrMBWkODQuoXgJouUBmQmQzwTzlaKU.json
│       ├── OGA55Jyg2c-Jhkx5zDNyiDvbFZiRXF0S_JESMhWAWcs.json
│       ├── P5KQo3QSWLzTLWkq3wgJlii11CEUSKMG_O2NMN6y_8c.json
│       ├── PgxqlgdluUGnmGCal3dgB6PYCd5S7FtBpI0zKDc8-AY.json
│       ├── QAQ-134At0mSPVrwBzTTUalyL_zqE_dMR_WggkZvF5E.json
│       ├── QyQL1TYdwmguUIBjTV-shWqrwS6AwxhZ6lf7Rx-vxH0.json
│       ├── R5utplMYRQsJwA9Y63cL3Na4mXtYzE4gWG6g6zwgEQE.json
│       ├── RJzScDd1IYIVaVOMo8zV2sXaGE4ZtKxwO2ONPFK-ou4.json
│       ├── Re-7lkSGlYP4SFddz0rrXIF0r4MVYZuagjkVpEm79bY.json
│       ├── TMjINkrJIS3kbGu8bmcVt_34TaFN8lINFQPR_YGzHss.json
│       ├── TNj-jk-KpKzz84xb1SRiKqyp8LNBnONxA9SIXs3XU7k.json
│       ├── Tg9QZvUPJoAZKRkPhPgQrgnlTY6s9UxRSQaMw6shhOU.json
│       ├── U2DZlRhnzhZrC7GsVNX0TxnXbHh03P3g-cU4fkHpiXA.json
│       ├── U4o0STLxwOEf42F4DF22ooOoA5Ykdp5j_D1io-4w1lc.json
│       ├── UH3C65dDo62rp5ciK3XzyhufE71xorL7r7MWVwdhavk.json
│       ├── U_1PPd40n2grpuhkMJcMXPVuJhtaQoUWei63iN2rS7o.json
│       ├── U_UF7e-hOd5uLIj10fYZVxQ5mXyZUxvMxhWWgAMaj0s.json
│       ├── UbW68tRQtThl9ah8tJb-X_af5M8FHYARiGZFiPGk_90.json
│       ├── VL10zUkfmLz5eRxQsZi0G5wsfo8mvyN3p82updP17D4.json
│       ├── ViCjDXb4IEZcXBtlYvTm3HCB6cf4gDbrXCCdvVVgB1g.json
│       ├── WJTACYoRG89VIpjzsIZLIy93U7HoC4OJyLy6WAlqv-0.json
│       ├── WwgngUwH7mXX15tdbfcjG_9gX2t8N8wbbfW2N34b3dA.json
│       ├── XrtNbxWFUGlP-SYqQm8aYawQJU6H7CSyHpRZM1iLdKg.json
│       ├── YMnQwrWWVRmkMs0B41lz-VdixskatlPcY7j4r0iSLbQ.json
│       ├── YcTBCg3mLRFByb1cnjrq9DzEBnnOT9jQtfYEE34QZ1M.json
│       ├── Yk_dta-f75GShvyUvXq132pohaNpiQgerfIKJA0vdCw.json
│       ├── Zu9CSLWidXEnbSAQVuXGk62eMrVAGQb4qHmrtQrOQIQ.json
│       ├── _AiF52l4uqTkKOVpQw9hr6l6FCIdWs8PCFtFxEBOopU.json
│       ├── _BN_07s59sawk5e9YcjHTX2qtYX9q7nCBYrlSWXoEsc.json
│       ├── _KI9ocPARF5JjaDPIbtpqw2hj_qRonw-AERjWOs5ZYM.json
│       ├── _gduN41u7Xxac_Gm3pBQI3icoKhOfiRV2TKhDnlyakU.json
│       ├── bcbIZq2gy8ivQiUlEch7tjNoCcUMTTLhInMlj9P2P88.json
│       ├── bhEMgsj4Yf5tdCDlwK9KpHmsgVLAsBDPOLtYeUDLw0M.json
│       ├── cTmKy32Fbmlybl-WtbyuVFNhO11Efr4e_rGbzwAkPbs.json
│       ├── clMyhm_qgwUJq68xb8Yf9EEaN3F7jgdqgKnKgjVRom8.json
│       ├── d8CQoDBSrekoGZXqTatc7Y5JkHtNviX1D3JD-fxFDmU.json
│       ├── dMTZgKHD-NkP3iM5RjFNhppiwfTlYd-Imi9aA6IK0So.json
│       ├── eGYHUFl46laNa8v_WjdadvCkIErWqmx0hoia7PCSmSw.json
│       ├── ehTWq16I6ixhFOVkpTKi7s4jgYjNzGJ5CoJW3xjHDTE.json
│       ├── fAnOUj-jmlzPMtIN90ZvowG9VUmBtD36MZ8-tRP1Ut4.json
│       ├── fr3nkF8AHXTcq9bT_b7x2X7Mun2A--Ssb7eyoKgQEwI.json
│       ├── goAmthhGPdbYUqbAymyG_MjBUWVdS9OBm78mOoiITHo.json
│       ├── hB1Hj0mfuh_x3ijhqkw1s3wdCh8qdPz_IMs0MPraVCk.json
│       ├── hMfNPSlINViUDVnor18GgPs0Ut0i9XY7dwM9MVOL-2I.json
│       ├── hPnpcoVcfRdkyUyhYSFNhsEcz7nQU0UU-fPSiRalDvw.json
│       ├── hQvPcHPcBhyxv7GPx-E3bZWiNBhnCpFIDwWa3XBcYEU.json
│       ├── hXNDNwQ6zA7aHAqvfBj_az9CovV37bJywdgPdb_ooIA.json
│       ├── hxyn3yZ7-LCgKqfkCljyM7Hq7HJnmPnEKaXoybXJjHo.json
│       ├── iWUFDucATDE8gjbsL-9KpOIW9l8Ipsh1wliv4e05xhg.json
│       ├── ivWTdg5M9XqjP-Iu4C97r3qZQhotJgfF17g__7EH7VM.json
│       ├── jOFeroI0Oz4TWcOx8mgv4iOZLv6ncbRXFRtJfqS4Pq0.json
│       ├── jStDc8gP5lyHVSFIJiT_2RrXhT26GpAhNItDEje07_Y.json
│       ├── kLP-8ILxdLSAQsrC6IwvfqQL6Loq2Q6lqOzwrnb6QoE.json
│       ├── kVNsLH0kpIkFnBBGWxoIajVLSpvzmsKHpsATPAcR86Y.json
│       ├── ks0ODNqrNY4CCDxJcrgRY324WykCeTiSH4Tmdi30I2E.json
│       ├── lF7NSIz6CNf8WsMNQl8It8HbJem3MAllokozblLdU5A.json
│       ├── ldoaD2NbG9VRhLOXddM1ypoAU3W5gR_zabUWZa4r6lM.json
│       ├── lxtOUAEj-E1jb6J8uGCRlRgJDHJyFOu0O73jQHnAhpg.json
│       ├── m1DnUoXf7wMtIGkkDZAALobw0GbGehfEMX_jNLvs3i8.json
│       ├── n1GVITzrvCF95Vz7l6hH7fdYzebDDAJav5z4-9C7lB4.json
│       ├── ntnx85KcYZ_ZhR6dL2A_p8foCmStgD-69ODoOUdipiA.json
│       ├── o9ArU5IxydvpJo2iiPI-p4EGBwlpBlyFIfbnz8Qrg6c.json
│       ├── oNZMr_dB-L40nSUj6Fc19-FGteHQu7ZaRZu9_mgM1BI.json
│       ├── oO7raEVlJC6KhfK-UbNuppzbYPGdKWbh1e6rOymd_-o.json
│       ├── oiYeEvWqOkaHzCSunznZ09U_tuHqP1UyZkRrKYHgNBw.json
│       ├── ojgJyXT8qwRXj1hOVx2gbeJDT0xEOIye0o9EbfU2LRM.json
│       ├── p0MVPvnv_lkWwfhSuSCgQ3NUj83shBffAx1NKPn4oy8.json
│       ├── p4oyXU5C3T0ZycNhEwBZ0MbpV0j3voWV4mr__3fhOek.json
│       ├── q8aw85uHTIPxuXcv2Awts4JVVHEMCl7J-61WfnvbYuQ.json
│       ├── qDEFXj8hSgOuuqWM52y6pbUX1cyp7bS4qItfctgtVx8.json
│       ├── qHvSpQXYh9RZmXIoIOexmDs0iQgjCubl6KSsgg7cDz8.json
│       ├── rAARxLc7tOdjUXEdNmSpOtsJIAw0XS229YHO1KOeUqI.json
│       ├── rTaanqa6Z5KxtBV4Kj2Fu2KKqAWlstE0JeUbZ3AuN3o.json
│       ├── rY4cJeAtYkg3bnTdqk4Vb0ojEcfS76L4B-iqyvQZ2VA.json
│       ├── rcc-B4OWqf0dbVY7Eq6q3pRDHLUjJ8tix8UeLQ4D68w.json
│       ├── sEw-yqeADuF0n_M6jTPLrOgH3coalIQHYPLrwM87nmo.json
│       ├── sMF6pWIkJFygBbR2IS10liEsjsLAMDja_E9_yUvUgeI.json
│       ├── t81tluHdoePSxjq7qG-6TMqBKmQLYr5gupmfvW25Y_o.json
│       ├── tn3FQGSVFt_TE5nyQNpuf_gnHdaWF85hZg1iE5hPQSE.json
│       ├── uNiZ8TfAQ8GWjtbqhVi90qO3U5dl9afmKE1-KbHQYM4.json
│       ├── uOqsnEjVGQCbtrKI7QbHYxbbLUdCKC-792SgZr5KUKM.json
│       ├── ujON59jsellR3M8hq9unBPISOwRgEVUogdi3FG_pVMk.json
│       ├── uoTzfoaN81h2_JyFkrvXTLFMnoSlWiuc9Yu1CmsFkH0.json
│       ├── vDtQzZ9jl6r7yzczhoKhvzekCQYx-qskwYdzQO92eWo.json
│       ├── vFP1U-4lk3GypDZFceLvRXjoadcB2FRKrcNQf9WjzpQ.json
│       ├── vYnzbcbBQbPQB7GKrXzPlz1MuT9cfnNI_NBVajaTnPg.json
│       ├── vvPtX1U0EZS9PMsQBVk3mjD9yS6EHIt0FXdKf2dOELw.json
│       ├── wntmnG9yRP9aoioRDILKkmSZqdemR-XDCIKJS-wpRYw.json
│       ├── xCUsF5aatMdiiUAkGjg29_TiQGKqXpbzoMsB0yI-Dd8.json
│       ├── xK4fFG-PbnQx6EGmmj1A0JVWQ9Bg7q-FncaU7hHk9ds.json
│       ├── xaB3eS6qbtKSrfFACMcYpgxWRtaJfT1kmOVpyaE45tI.json
│       ├── y9wJkLq6Q0hKSDD67ilFqtMMatw9qpsKM9W2uy2Rfjc.json
│       ├── ycjvsn3A9cUMjnbDaSUpf1HRQd4duP9AL1YVwSjwuAQ.json
│       ├── yo8VtPVXWBpTqLbLL-ZeOmZTW2HTqTzsf9RPzgHM-bQ.json
│       ├── zNae10gPNkFt5aRVaSL2eSgxZiRDG79B9oDIeYqyzDY.json
│       └── zavm_CqSq0KuWfc-E0JccEyrrQzjigxt7yuW1ceYjE0.json
├── nix/
│   ├── README.md
│   ├── arweave.nix
│   ├── generate-config.nix
│   ├── module.nix
│   └── options.nix
├── notebooks/
│   ├── README.md
│   ├── autoredenomination_localnet.ipynb
│   ├── pricing_transition_localnet.ipynb
│   └── test.ipynb
├── priv/
│   └── templates/
│       ├── README.md
│       ├── extended_bin
│       └── vm_args
├── rebar.config
├── rebar3
├── release_notes/
│   ├── N.2.9.5/
│   │   └── README.md
│   ├── N.2.9.5-alpha5/
│   │   └── README.md
│   ├── N.2.9.5-alpha6/
│   │   └── README.md
│   ├── N.2.9.5.1/
│   │   └── README.md
│   └── README.md
├── scripts/
│   ├── full_test_modules.txt
│   ├── github_workflow.sh
│   ├── ierl_kernel.sh
│   ├── list_test_modules.sh
│   ├── run_notebook.sh
│   ├── run_notebook_headless.sh
│   ├── setup_notebook_env.sh
│   ├── surefire_to_html.py
│   ├── system_info.sh
│   └── testnet/
│       └── benchmark
└── testnet/
    ├── assert_testnet.sh
    ├── backup_data.sh
    ├── clear_data.sh
    ├── config/
    │   ├── testnet-1.json
    │   ├── testnet-2.json
    │   ├── testnet-3.json
    │   ├── testnet-4.json
    │   ├── testnet-5.json
    │   └── testnet-6.json
    ├── rebuild_mainnet.sh
    ├── rebuild_testnet.sh
    ├── restore_data.sh
    ├── start_mainnet.sh
    └── start_testnet.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .cursor/BUGBOT.md
================================================
Always suggest one or two ways to patch the issues you are highlighting.



================================================
FILE: .cursor/rules/build.mdc
================================================
---
name: build
description: "Arweave build commands and structure"
alwaysApply: true
---

# Arweave Project Rules

To better reason about the Arweave protocol, **read `.cursor/rules/protocol.mdc`** in this directory.

## Build Commands
- To compile the project: `./ar-rebar3 prod compile`

## Project Structure
- This is an Erlang/OTP project using rebar3
- It contains multiple apps in the `apps` directory
- The main app is `arweave`
- Source files: `apps/<app>/src/`
- Test files: `apps/<app>/test/`
- Include files: `apps/<app>/include/`

## Running Tests
- To run tests for a specific module: `./bin/test <module>`
  - Example: `./bin/test ar_mining_io_tests`
- To run tests for a specific test: `./bin/test <module>:<test>`
  - Example: `./bin/test ar_mining_io_tests:read_recall_range_test_`
- Multiple modules and/or tests can be run together
  - Example: `./bin/test ar_mining_io_tests ar_data_sync_root_tests:data_roots_syncs_from_peer_test_`

## Testing Notes
- Test profile uses smaller values for constants like `?PARTITION_SIZE` and `?REPLICA_2_9_ENTROPY_COUNT` (defined in rebar.config)

================================================
FILE: .cursor/rules/protocol.mdc
================================================
# Arweave protocol technical details and caveats

Recall bytes always point to chunks, not sub-chunks. We always consider all sub-chunks of every chunk durining mining. Nonce rem SubChunkCount determines which sub-chunk goes into the proof.


================================================
FILE: .gitattributes
================================================
localnet_snapshot/** filter=lfs diff=lfs merge=lfs -text


================================================
FILE: .github/workflows/e2e-test.yml
================================================
name: "Arweave e2e  Tests Suites"
on:
  workflow_dispatch:
  schedule:
    - cron: "0 13 * * *"

jobs:
  build:
    runs-on: [self-hosted, ubuntu, amd64, build-runner]
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      # only arweave dependencies are being cached,
      # those are not updated everyday and this is
      # unecessary to fetch them everytime.
      - uses: actions/cache@v4
        id: cache
        with:
          path: |
            _build/default/lib/accept
            _build/default/lib/b64fast
            _build/default/lib/cowboy
            _build/default/lib/cowlib
            _build/default/lib/gun
            _build/default/lib/jiffy
            _build/default/lib/prometheus
            _build/default/lib/prometheus_cowboy
            _build/default/lib/prometheus_httpd
            _build/default/lib/prometheus_process_collector
            _build/default/lib/quantile_estimator
            _build/default/lib/ranch
            _build/default/lib/.rebar3
            _build/default/lib/recon
            _build/default/lib/rocksdb
            _build/default/plugins/
            _build/default/plugins/aleppo
            _build/default/plugins/geas
            _build/default/plugins/geas_rebar3
            _build/default/plugins/hex_core
            _build/default/plugins/katana_code
            _build/default/plugins/pc
            _build/default/plugins/.rebar3
            _build/default/plugins/rebar3_archive_plugin
            _build/default/plugins/rebar3_elvis_plugin
            _build/default/plugins/rebar3_hex
            _build/default/plugins/samovar
            _build/default/plugins/verl
            _build/default/plugins/zipper
          key: deps-cache-${{ hashFiles('rebar.lock') }}
          restore-keys: |
            deps-cache-${{ hashFiles('rebar.lock') }}

      - name: Get dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: ./ar-rebar3 test get-deps

      - uses: actions/cache@v4
        if: steps.cache.outputs.cache-hit != 'true'
        with:
          path: |
            _build/default/lib/accept
            _build/default/lib/b64fast
            _build/default/lib/cowboy
            _build/default/lib/cowlib
            _build/default/lib/gun
            _build/default/lib/jiffy
            _build/default/lib/prometheus
            _build/default/lib/prometheus_cowboy
            _build/default/lib/prometheus_httpd
            _build/default/lib/prometheus_process_collector
            _build/default/lib/quantile_estimator
            _build/default/lib/ranch
            _build/default/lib/.rebar3
            _build/default/lib/recon
            _build/default/lib/rocksdb
            _build/default/plugins/
            _build/default/plugins/aleppo
            _build/default/plugins/geas
            _build/default/plugins/geas_rebar3
            _build/default/plugins/hex_core
            _build/default/plugins/katana_code
            _build/default/plugins/pc
            _build/default/plugins/.rebar3
            _build/default/plugins/rebar3_archive_plugin
            _build/default/plugins/rebar3_elvis_plugin
            _build/default/plugins/rebar3_hex
            _build/default/plugins/samovar
            _build/default/plugins/verl
            _build/default/plugins/zipper
          key: deps-cache-${{ hashFiles('rebar.lock') }}

      - name: Compile arweave release
        run: ./ar-rebar3 default release
          
      - name: Build arweave test sources
        run: ./ar-rebar3 test compile

      - name: Build arweave e2e test sources
        run: ./ar-rebar3 e2e compile

      # some artifacts are compiled and only available
      # in arweave directy (libraries)
      - name: Prepare artifacts
        run: |
          chmod -R u+w ./_build
          tar czfp _build.tar.gz ./_build ./bin/arweave
          tar czfp apps.tar.gz ./apps

      # to avoid reusing artifacts from someone else
      # and generating issues, an unique artifact is
      # produced using github checksum.
      - name: upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-${{ github.sha }}
          if-no-files-found: error
          include-hidden-files: true
          retention-days: 7
          overwrite: true
          path: |
            _build.tar.gz
            apps.tar.gz

  e2e-tests:
    needs: build
    runs-on: [self-hosted, ubuntu, amd64, build-runner]
    strategy:
      max-parallel: 4
      matrix:
        core_test_mod: [
            ar_sync_pack_mine_tests,
            ar_repack_mine_tests,
            ar_repack_in_place_mine_tests
          ]
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}

      # Both artifacts (_build and apps dir) are
      # required.
      - name: Extract artifact
        run: |
          tar zxfp _build.tar.gz
          tar zxfp apps.tar.gz

      - name: ${{ matrix.core_test_mod }}.erl
        id: tests
        run: bash scripts/github_workflow.sh "e2e" "${{ matrix.core_test_mod }}"

      # this part of the job produces test artifacts from logs
      # generated by the tests. It also collect dumps and the files
      # present in .tmp (temporary arweave data store)
      - name: upload artifacts in case of failure
        uses: actions/upload-artifact@v4
        if: always() && failure()
        with:
          name: "logs-${{ matrix.core_test_mod }}-${{ github.run_attempt }}-${{ job.status }}-${{ runner.name }}-${{ github.sha }}"
          retention-days: 7
          overwrite: true
          include-hidden-files: true
          path: |
            ./logs
            *.out
            *.dump


================================================
FILE: .github/workflows/gitstamp.yaml
================================================
# See: https://github.com/weavery/gitstamp-action
---
name: Gitstamp
on: 
  push:
    branches:
      - 'master'
      - 'release/**'
      - 'releases/**'
  pull_request_target:
    types: [closed]

jobs:
  gitstamp:
    runs-on: [self-hosted, ubuntu, amd64, build-runner]
    name: Timestamp commit with Gitstamp
    steps:
      - name: Clone repository
        uses: actions/checkout@v2
      - name: Submit Gitstamp transaction
        uses: weavery/gitstamp-action@v1
        with:
          wallet-key: ${{ secrets.GITSTAMP_KEYFILE }}
          commit-link: true


================================================
FILE: .github/workflows/release.yml
================================================
######################################################################
# All releases are generated using this workflow. The goal is to
# make our life easier when releasing a new version of Arweave.
# Instead of doing the process manually, some builders will be used
# to produce the necessary tarballs, create the checksums, packs them
# together and finally create the release on github side with a
# message from the repository (in release_notes directory).
######################################################################
name: Release

on:
  push:
    tags:
      - N.**
  workflow_dispatch:
    inputs:
      tag:
        required: true
        type: string
      make_latest:
        required: false
        default: true
        type: boolean
      prerelease:
        required: false
        default: true
        type: boolean
      draft:
        required: false
        default: false
        type: boolean

jobs:
  # prepare ubuntu 22.04 release (jammy) on amd64 arch
  ubuntu-jammy-release:
    uses: ./.github/workflows/x-release-linux.yml
    secrets: inherit
    with:
      os_arch: amd64
      os_release: jammy
      os_name: ubuntu
      tag: ${{ github.ref_name || inputs.tag }}

  # prepare ubuntu 24.04 release (noble) on amd64 arch
  ubuntu-noble-release:
    uses: ./.github/workflows/x-release-linux.yml
    secrets: inherit
    with:
      os_arch: amd64
      os_release: noble
      os_name: ubuntu
      tag: ${{ github.ref_name || inputs.tag }}

  # prepare rocky 9 release on amd64 arch
  rockylinux-9-release:
    uses: ./.github/workflows/x-release-linux.yml
    secrets: inherit
    with:
      os_arch: x86_64
      os_release: 9
      os_name: rockylinux
      tag: ${{ github.ref_name || inputs.tag }}

  # prepare macos release on arm64 arch
  macos-release:
    uses: ./.github/workflows/x-release-macos.yml
    secrets: inherit
    with:
      tag: ${{ github.ref_name || inputs.tag }}

  # craft the release using the previous builds
  release:
    needs:
      - ubuntu-jammy-release
      - ubuntu-noble-release
      - rockylinux-9-release
      - macos-release

    permissions:
      contents: write
      packages: write

    runs-on:
      - self-hosted
      - release-runner
      - amd64

    steps:

      # a new checkout is required to have the release
      # message from releases_notes directory.
      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      # let fetch ubuntu jammy tarball
      - name: Download Ubuntu Jammy Release
        uses: actions/download-artifact@v5
        with:
          name: arweave-ubuntu-jammy-amd64
          path: ./arweave-ubuntu-jammy-amd64

      # let fetch ubuntu noble tarball
      - name: Download Ubuntu Noble Release
        uses: actions/download-artifact@v5
        with:
          name: arweave-ubuntu-noble-amd64
          path: ./arweave-ubuntu-noble-amd64

      # let fetch rocky 9 tarball
      - name: Download Rockylinux 9 Release
        uses: actions/download-artifact@v5
        with:
          name: arweave-rockylinux-9-x86_64
          path: ./arweave-rockylinux-9-x86_64

      # let fetch macos tarball
      - name: Download MacOS Release
        uses: actions/download-artifact@v5
        with:
          name: arweave-macos-26-arm64
          path: ./arweave-macos-26-arm64

      # now this part is a bit tricky. it will rename
      # all tarball using the tag pushed. To avoid
      # some weird behaviors, the name is sanitized
      # by removing few symbols and replacing them
      # with a dash (-).
      - name: Prepare Release Tarballs and Checksums
        run: |
          #!/bin/sh
          set -eux

          # define variables
          releasedir="$(pwd)/_releases"
          ref=${{ github.ref_name }}
          release_name=$(echo ${ref} | sed -Ee 's!(/|:|@|\[|\]|\(|\)|\~)!-!g' -e 's!^N\.!!')

          # prepare release directory
          mkdir -p "${releasedir}"

          # prepare a release using a directory and a postfix name
          _prepare_release() {
            local dir=${1}
            local name=${2}
            local checksum
            cd ${dir}

            # rename arweave tarball
            cp arweave*.tar.gz ${releasedir}/arweave-${release_name}.${name}.tar.gz

            # prepare checksum file
            checksum=$(cat arweave*.tar.gz.SHA256 | awk '{ print $1 }')
            echo "${checksum} arweave-${release_name}.${name}.tar.gz" \
              > ${releasedir}/arweave-${release_name}.${name}.tar.gz.SHA256

            cd ..
          }

          # prepare releases for each distribution
          _prepare_release arweave-ubuntu-jammy-amd64 ubuntu22.x86_64
          _prepare_release arweave-ubuntu-noble-amd64 ubuntu24.x86_64
          _prepare_release arweave-rockylinux-9-x86_64 rocky9.x86_64
          _prepare_release arweave-macos-26-arm64 macos.arm64

          # check if the checksums are correct
          cd ${releasedir}
          cat *.SHA256 > checksums.txt
          cat *.SHA256 > SHA256
          sha256sum -c checksums.txt
          sha256sum -c SHA256
          cd ..

      # Release the version based on the new tag
      - name: Release the new version on github
        uses: softprops/action-gh-release@v2
        if: startsWith(github.ref, 'refs/tags/')
        with:
          name: Release ${{ github.ref_name }}
          body_path: release_notes/${{ github.ref_name }}/README.md
          files: |
            _releases/*.tar.gz
            _releases/checksums.txt
            _releases/SHA256
            LICENSE.md
          make_latest: ${{ inputs.make_latest || true }}
          prerelease: ${{ inputs.prerelease || true }}
          draft: ${{ inputs.draft || false }}


================================================
FILE: .github/workflows/test-amd64-ubuntu-22.04.yml
================================================
######################################################################
# Test suite for Ubuntu 22.04. This is the official OS supported by
# arweave team. The complete test suite should be executed.
######################################################################
name: "Test on arch:amd64 distribution:ubuntu release:22.04"

on:
  push:
    branches: ["**"]
  workflow_dispatch:

jobs:
  build:
    uses: ./.github/workflows/x-build.yml
    secrets: inherit

  test-canary:
    needs: [build]
    uses: ./.github/workflows/x-test-canary.yml
    secrets: inherit

  common-test:
    needs: [test-canary]
    uses: ./.github/workflows/x-common-test.yml
    secrets: inherit

  test:
    needs: [test-canary]
    uses: ./.github/workflows/x-test-full.yml
    secrets: inherit


================================================
FILE: .github/workflows/test-arm64-macos-26.yml
================================================
######################################################################
# Test suite for MacOS. The support of MacOS is mainly for the VDF
# part, it should not be required to do the full test suite.
######################################################################
name: "Test on arch:arm64 distribution:macos release:26"

on:
  push:
    branches: ["**"]
  workflow_dispatch:

jobs:
  build:
    uses: ./.github/workflows/x-build.yml
    secrets: inherit
    with:
      os_arch: arm64
      os_name: macos
      os_release: 26

  test-canary:
    needs: [build]
    uses: ./.github/workflows/x-test-canary.yml
    secrets: inherit
    with:
      os_arch: arm64
      os_name: macos
      os_release: 26

  common-test:
    needs: [test-canary]
    uses: ./.github/workflows/x-common-test.yml
    secrets: inherit
    with:
      os_arch: arm64
      os_name: macos
      os_release: 26

  test:
    needs: [test-canary]
    uses: ./.github/workflows/x-test-vdf.yml
    secrets: inherit
    with:
      os_arch: arm64
      os_name: macos
      os_release: 26


================================================
FILE: .github/workflows/x-build.yml
================================================
######################################################################
# Common way to build arweave. This template should be compatible with
# any kind of systems but it expects the images/vm/servers used to
# compile already have every requirement installed.
######################################################################
name: "arweave-build-template"

on:
  workflow_call:
    inputs:
      os_arch:
        description: "operating system architecture"
        default: "amd64"
        type: "string"
      os_name:
        description: "operating system name"
        default: "ubuntu"
        type: "string"
      os_release:
        description: "operating system release"
        default: "22.04"
        type: "string"

env:
  cache_key: ${{ inputs.os_arch }}-${{ inputs.os_name }}-${{ inputs.os_release }}

jobs:
  build-template:
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}

    steps:
      # On standalone runners, it is always required to cleanup
      # first. By default executed on all runners, to start with
      # clean environment.
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      # checkout arweave repository and extract it in
      # working directory.
      - name: checkout arweave repository
        uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      # before doing anything, we would like to know what kind of
      # software and libraries are present on the system for debugging
      # purpose
      - name: get software and libraries information
        run: |
          sh ./scripts/system_info.sh > _version.yaml
          cat _version.yaml

      # only arweave dependencies are being cached,
      # those are not updated everyday and this is
      # unecessary to fetch them everytime.
      - name: extract cache
        uses: actions/cache@v4
        id: cache
        with:
          path: |
            _build/default/lib/accept
            _build/default/lib/b64fast
            _build/default/lib/cowboy
            _build/default/lib/cowlib
            _build/default/lib/gun
            _build/default/lib/jiffy
            _build/default/lib/prometheus
            _build/default/lib/prometheus_cowboy
            _build/default/lib/prometheus_httpd
            _build/default/lib/prometheus_process_collector
            _build/default/lib/quantile_estimator
            _build/default/lib/ranch
            _build/default/lib/.rebar3
            _build/default/lib/recon
            _build/default/lib/rocksdb
            _build/default/plugins/
            _build/default/plugins/aleppo
            _build/default/plugins/geas
            _build/default/plugins/geas_rebar3
            _build/default/plugins/hex_core
            _build/default/plugins/katana_code
            _build/default/plugins/pc
            _build/default/plugins/.rebar3
            _build/default/plugins/rebar3_archive_plugin
            _build/default/plugins/rebar3_elvis_plugin
            _build/default/plugins/rebar3_hex
            _build/default/plugins/samovar
            _build/default/plugins/verl
            _build/default/plugins/zipper
          key: deps-cache-${{ hashFiles('rebar.lock') }}-${{ env.cache_key }}
          restore-keys: |
            deps-cache-${{ hashFiles('rebar.lock') }}-${{ env.cache_key }}

      - name: Get dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: ./ar-rebar3 test get-deps

      - uses: actions/cache@v4
        if: steps.cache.outputs.cache-hit != 'true'
        with:
          path: |
            _build/default/lib/accept
            _build/default/lib/b64fast
            _build/default/lib/cowboy
            _build/default/lib/cowlib
            _build/default/lib/gun
            _build/default/lib/jiffy
            _build/default/lib/prometheus
            _build/default/lib/prometheus_cowboy
            _build/default/lib/prometheus_httpd
            _build/default/lib/prometheus_process_collector
            _build/default/lib/quantile_estimator
            _build/default/lib/ranch
            _build/default/lib/.rebar3
            _build/default/lib/recon
            _build/default/lib/rocksdb
            _build/default/plugins/
            _build/default/plugins/aleppo
            _build/default/plugins/geas
            _build/default/plugins/geas_rebar3
            _build/default/plugins/hex_core
            _build/default/plugins/katana_code
            _build/default/plugins/pc
            _build/default/plugins/.rebar3
            _build/default/plugins/rebar3_archive_plugin
            _build/default/plugins/rebar3_elvis_plugin
            _build/default/plugins/rebar3_hex
            _build/default/plugins/samovar
            _build/default/plugins/verl
            _build/default/plugins/zipper
          key: deps-cache-${{ hashFiles('rebar.lock') }}-${{ env.cache_key }}

      - name: Compile arweave release
        run: ./ar-rebar3 default release

      - name: Build arweave test sources
        run: ./ar-rebar3 test release

      # some artifacts are compiled and only available
      # in arweave directory (libraries).
      - name: Prepare artifacts
        run: |
          chmod -R u+w ./_build

          # rebar is using a lot of absolute symlink,
          # this can generate issue on standalone worker
          # to avoid this problem, links must be
          # deferenced with -h flag.
          tar czfhp _build.tar.gz ./_build ./bin/arweave
          tar czfhp apps.tar.gz ./apps

      # to avoid reusing artifacts from someone else
      # and generating issues, an unique artifact is
      # produced using github checksum.
      - name: upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-${{ github.sha }}-${{ env.cache_key }}
          if-no-files-found: error
          retention-days: 1
          overwrite: true
          path: |
            _version.yaml
            _build.tar.gz
            apps.tar.gz


================================================
FILE: .github/workflows/x-common-test.yml
================================================
######################################################################
# Full Arweave Test Suite. Mostly used on Linux like systems.
######################################################################
name: "arweave-common-test-suite"

on:
  workflow_call:
    inputs:
      os_arch:
        description: "operating system architecture"
        default: "amd64"
        type: "string"
      os_name:
        description: "operating system name"
        default: "ubuntu"
        type: "string"
      os_release:
        description: "operating system release"
        default: "22.04"
        type: "string"

env:
  cache_key: ${{ inputs.os_arch }}-${{ inputs.os_name }}-${{ inputs.os_release }}

####################################################################
# Test modules (note: that _tests are implicitly run by a matching
# prefix name
####################################################################
jobs:
  common-test-suite:
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}
    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}-${{ env.cache_key }}

      # Both artifacts (_build and apps dir) are
      # required.
      - name: Extract artifact
        run: |
          tar zxfp _build.tar.gz
          tar zxfp apps.tar.gz

      # This is a temporary fix to prevent test failures when
      # executing the test suite on a system like MacOS. The libraries
      # must be rebuilt due to CMake full path usage, if CMake is
      # re-used on another user (then with a different full path), it
      # will fail. Here, we force to clean all external libraries
      # objects before executing the test.
      - name: temporary external libraries fix
        run: make -C apps/arweave/lib clean

      # execute common test suite with test profile and coverage
      # enabled.
      - name: run common test suite
        id: common-tests
        run: |
          ./rebar3 as test ct \
            --cover \
            --verbose \
            --logdir _ct_logs

      # execute eunit in standalone on only a small subset of
      # application available. Because arweave main application is
      # using eunit for its test suite in a specific way, testing this
      # application will crash the test suite.
      - name: run eunit test suite
        id: eunit
        run: |
          ./rebar3 as test eunit \
            --cover \
            --application arweave_config

      # generate coverage report, it will be stored in
      # _build/test/cover directory
      - name: run cover
        id: cover
        run: |
          ./rebar3 as test cover \
            --verbose

      # generate markdown/html like report to have a quick view of
      # what happened during the tests
      - name: generate workflow summary
        run: |-
          if test -f ./_build/test/cover/index.html
          then
            echo "# Coverage Summary" >> $GITHUB_STEP_SUMMARY
            echo >> $GITHUB_STEP_SUMMARY
            cat ./_build/test/cover/index.html >> $GITHUB_STEP_SUMMARY
          fi

          if test -d ./_build/test/surefire
          then
            echo "# Eunit Report" >> $GITHUB_STEP_SUMMARY
            echo >> $GITHUB_STEP_SUMMARY
            for f in ./_build/test/surefire/*.xml
            do
              ./scripts/surefire_to_html.py "${f}" >> $GITHUB_STEP_SUMMARY
            done
          fi

      # upload test coverage report as artifact.
      - name: upload coverage report
        uses: actions/upload-artifact@v4
        with:
          name: "coverage-common_test-${{ github.run_attempt }}-${{ job.status }}-${{ runner.name }}-${{ github.sha }}"
          retention-days: 7
          overwrite: true
          include-hidden-files: true
          path: |
            ./_build/test/cover
            ./_build/test/surefire

      # this part of the job produces test artifacts from logs
      # generated by the tests. It also collect dumps and the files
      # present in .tmp (temporary arweave data store)
      - name: upload artifacts in case of failure
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: "logs-common_test-${{ github.run_attempt }}-${{ job.status }}-${{ runner.name }}-${{ github.sha }}"
          retention-days: 7
          overwrite: true
          include-hidden-files: true
          path: |
            ./_ct_logs
            ./logs




================================================
FILE: .github/workflows/x-release-linux.yml
================================================
######################################################################
# Release template for Linux based systems, including at this time
# Ubuntu and Rockylinux.
######################################################################
name: "arweave-release-linux-template"

on:
  workflow_call:
    inputs:
      tag:
        required: true
        type: string
      os_arch:
        description: "operating system architecture"
        default: "amd64"
        type: "string"
      os_name:
        description: "operating system name"
        default: "ubuntu"
        type: "string"
      os_release:
        description: "operating system release"
        default: "22.04"
        type: "string"

jobs:
  linux-release:
    runs-on:
      - self-hosted
      - release-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}
    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      - name: Create Arweave Release
        run: |
          set -eux
          ./rebar3 as prod tar
          f=$(ls _build/prod/rel/arweave/arweave-*.tar.gz)
          sha256sum ${f} > ${f}.SHA256

      - name: Prepare tarball tests
        run: |
          set -eux
          f=$(ls ${PWD}/_build/prod/rel/arweave/arweave-*.tar.gz)
          mkdir _extract
          cd _extract
          tar zxf "${f}"

      - name: Test vdf openssl
        run: |
          cd _extract
          ./bin/arweave benchmark vdf mode openssl verify true 2>&1 \
            | grep -E "^VDF step computed in .* seconds."

      - name: Test vdf fused
        run: |
          cd _extract
          ./bin/arweave benchmark vdf mode openssl verify true 2>&1 \
            | grep -E "^VDF step computed in .* seconds."

      - name: Test create rsa key
        run: |
          cd _extract
          mkdir _rsa
          set +e
          (./bin/arweave wallet create rsa _rsa 2>&1) >/dev/null
          set -e
          test 1 = $(ls _rsa/wallets/arweave_keyfile*.json | wc -l)

      - name: Test create ecdsa
        run: |
          cd _extract
          mkdir _ecdsa
          set +e
          (./bin/arweave wallet create ecdsa _ecdsa 2>&1) >/dev/null
          set -e
          test 1 = $(ls _ecdsa/wallets/arweave_keyfile*.json | wc -l)

      - name: Test arweave execution
        run: |
          cd _extract
          ./bin/arweave foreground 2>&1 \
            | grep -Ee '^Usage: arweave-server' \
                   -e '^Compatible with network: arweave.N.1'

      - name: Cleanup tests
        if: always()
        run: |
          rm -rf _extract

      - name: Upload Arweave artifacts
        uses: actions/upload-artifact@v4
        with:
          name: arweave-${{ inputs.os_name }}-${{ inputs.os_release }}-${{ inputs.os_arch }}
          if-no-files-found: error
          path: |
            _build/prod/rel/arweave/arweave-*.tar.gz
            _build/prod/rel/arweave/arweave-*.tar.gz.SHA256


================================================
FILE: .github/workflows/x-release-macos.yml
================================================
######################################################################
# release template for MacOS.
######################################################################
name: "arweave-release-macos-template"

on:
  workflow_call:
    inputs:
      tag:
        required: true
        type: string
      os_arch:
        description: "operating system architecture"
        default: "arm64"
        type: "string"
      os_name:
        description: "operating system name"
        default: "macos"
        type: "string"
      os_release:
        description: "operating system release"
        default: "26"
        type: "string"

jobs:
  macos-release:
    runs-on:
      - self-hosted
      - release-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}

    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      - name: Create Arweave Release
        run: |
          set -eux
          ./rebar3 as prod tar
          f=$(ls _build/prod/rel/arweave/arweave-*.tar.gz)
          sha256sum ${f} > ${f}.SHA256

      - name: Prepare tarball tests
        run: |
          set -eux
          f=$(ls ${PWD}/_build/prod/rel/arweave/arweave-*.tar.gz)
          mkdir _extract
          cd _extract
          tar zxf "${f}"

      - name: Test vdf openssl
        run: |
          cd _extract
          ./bin/arweave benchmark vdf mode openssl verify true 2>&1 \
            | grep -E "^VDF step computed in .* seconds."

      - name: Test vdf fused
        run: |
          cd _extract
          ./bin/arweave benchmark vdf mode openssl verify true 2>&1 \
            | grep -E "^VDF step computed in .* seconds." 2>&1 \

      - name: Test vdf hiopt_m4
        run: |
          cd _extract
          ./bin/arweave benchmark vdf mode openssl hiopt_m4 true 2>&1 \
            | grep -E "^VDF step computed in .* seconds."

      - name: Test create rsa key
        run: |
          cd _extract
          mkdir _rsa
          set +e
          (./bin/arweave wallet create rsa _rsa 2>&1) >/dev/null
          set -e
          test 1 = $(ls _rsa/wallets/arweave_keyfile*.json | wc -l)

      - name: Test create ecdsa
        run: |
          cd _extract
          mkdir _ecdsa
          set +e
          (./bin/arweave wallet create ecdsa _ecdsa 2>&1) >/dev/null
          set -e
          test 1 = $(ls _ecdsa/wallets/arweave_keyfile*.json | wc -l)

      - name: Test arweave execution
        run: |
          cd _extract
          ./bin/arweave foreground 2>&1 \
            | grep -Ee '^Usage: arweave-server' \
                   -e '^Compatible with network: arweave.N.1'

      - name: Cleanup tests
        if: always()
        run: |
          rm -rf _extract

      - name: Upload Arweave artifacts
        uses: actions/upload-artifact@v4
        with:
          name: arweave-${{ inputs.os_name }}-${{ inputs.os_release }}-${{ inputs.os_arch }}
          if-no-files-found: error
          path: |
            _build/prod/rel/arweave/arweave-*.tar.gz
            _build/prod/rel/arweave/arweave-*.tar.gz.SHA256


================================================
FILE: .github/workflows/x-test-canary.yml
================================================
######################################################################
# A canary test suite, checking if the test suite is correctly
# working.
######################################################################
name: "arweave-test-suite-canary-template"

on:
  workflow_call:
    inputs:
      os_arch:
        description: "operating system architecture"
        default: "amd64"
        type: "string"
      os_name:
        description: "operating system name"
        default: "ubuntu"
        type: "string"
      os_release:
        description: "operating system release"
        default: "22.04"
        type: "string"

env:
  cache_key: ${{ inputs.os_arch }}-${{ inputs.os_name }}-${{ inputs.os_release }}

####################################################################
# Canary testing, should fail.
####################################################################
jobs:
  canary:
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}

    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}-${{ env.cache_key }}

      # Both artifacts (_build and apps dir) are
      # required.
      - name: Extract artifact
        run: |
          tar zxfp _build.tar.gz
          tar zxfp apps.tar.gz

      - id: canary
        name: ar_canary.erl
        continue-on-error: true
        run: bash scripts/github_workflow.sh "tests" "ar_canary"

      - name: should fail
        run: |
          if test "${{ steps.canary.outcome }}" = "failure"
          then
            exit 0
          else
            exit 1
          fi


================================================
FILE: .github/workflows/x-test-full.yml
================================================
######################################################################
# Full Arweave Test Suite. Mostly used on Linux like systems.
######################################################################
name: "arweave-test-suite-full"

on:
  workflow_call:
    inputs:
      os_arch:
        description: "operating system architecture"
        default: "amd64"
        type: "string"
      os_name:
        description: "operating system name"
        default: "ubuntu"
        type: "string"
      os_release:
        description: "operating system release"
        default: "22.04"
        type: "string"

env:
  cache_key: ${{ inputs.os_arch }}-${{ inputs.os_name }}-${{ inputs.os_release }}

####################################################################
# Test modules (note: that _tests are implicitly run by a matching
# prefix name
####################################################################
jobs:
  full-test-modules:
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}
    outputs:
      core_test_mods: ${{ steps.core-test-mods.outputs.core_test_mods }}
    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      - uses: actions/checkout@v4
        with:
          submodules: "recursive"

      - name: load full test modules
        id: core-test-mods
        run: |
          echo "core_test_mods=$(bash scripts/list_test_modules.sh json)" >> "$GITHUB_OUTPUT"

  eunit-tests-suite:
    needs: full-test-modules
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}

    strategy:
      fail-fast: false
      max-parallel: 12
      matrix:
        core_test_mod: ${{ fromJson(needs.full-test-modules.outputs.core_test_mods) }}
    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}-${{ env.cache_key }}

      # Both artifacts (_build and apps dir) are
      # required.
      - name: Extract artifact
        run: |
          tar zxfp _build.tar.gz
          tar zxfp apps.tar.gz

      - name: ${{ matrix.core_test_mod }}.erl
        id: tests
        run: bash scripts/github_workflow.sh "tests" "${{ matrix.core_test_mod }}"

      # this part of the job produces test artifacts from logs
      # generated by the tests. It also collect dumps and the files
      # present in .tmp (temporary arweave data store)
      - name: upload artifacts in case of failure
        uses: actions/upload-artifact@v4
        if: always() && failure()
        with:
          name: "logs-${{ matrix.core_test_mod }}-${{ github.run_attempt }}-${{ job.status }}-${{ runner.name }}-${{ github.sha }}"
          retention-days: 7
          overwrite: true
          include-hidden-files: true
          path: |
            ./logs
            *.out
            *.dump
  notebook-pricing-localnet:
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}
    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"
      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true
      - name: Fetch Git LFS objects
        run: |
          git lfs install --local
          git lfs pull
          git lfs checkout
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}-${{ env.cache_key }}
      # Both artifacts (_build and apps dir) are
      # required.
      - name: Extract artifact
        run: |
          tar zxfp _build.tar.gz
          tar zxfp apps.tar.gz
      - name: Setup notebook env
        run: scripts/setup_notebook_env.sh
      - name: Run pricing transition notebook headless
        run: scripts/run_notebook_headless.sh pricing_transition_localnet
  notebook-autoredenomination-localnet:
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}
    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"
      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true
      - name: Fetch Git LFS objects
        run: |
          git lfs install --local
          git lfs pull
          git lfs checkout
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}-${{ env.cache_key }}
      # Both artifacts (_build and apps dir) are
      # required.
      - name: Extract artifact
        run: |
          tar zxfp _build.tar.gz
          tar zxfp apps.tar.gz
      - name: Setup notebook env
        run: scripts/setup_notebook_env.sh
      - name: Run autoredenomination notebook headless
        run: scripts/run_notebook_headless.sh autoredenomination_localnet



================================================
FILE: .github/workflows/x-test-on-demand.yml
================================================
######################################################################
# Full Arweave Test Suite. On demand.
######################################################################
name: "arweave-test-suite-full"

on:
  workflow_call:
    inputs:
      test:
        type: "string"
        required: true
      os_arch:
        description: "operating system architecture"
        default: "amd64"
        type: "string"
      os_name:
        description: "operating system name"
        default: "ubuntu"
        type: "string"
      os_release:
        description: "operating system release"
        default: "22.04"
        type: "string"

env:
  cache_key: ${{ inputs.os_arch }}-${{ inputs.os_name }}-${{ inputs.os_release }}

####################################################################
# Test modules (note: that _tests are implicitly run by a matching
# prefix name
####################################################################
jobs:
  eunit-tests-suite:
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}

    strategy:
      fail-fast: false

    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}-${{ env.cache_key }}

      # Both artifacts (_build and apps dir) are
      # required.
      - name: Extract artifact
        run: |
          tar zxfp _build.tar.gz
          tar zxfp apps.tar.gz

      - name: ${{ inputs.test }}.erl
        id: tests
        run: bash scripts/github_workflow.sh "tests" "${{ inputs.test }}"

      # this part of the job produces test artifacts from logs
      # generated by the tests. It also collect dumps and the files
      # present in .tmp (temporary arweave data store)
      - name: upload artifacts in case of failure
        uses: actions/upload-artifact@v4
        if: always() && failure()
        with:
          name: "logs-${{ inputs.test }}-${{ github.run_attempt }}-${{ job.status }}-${{ runner.name }}-${{ github.sha }}"
          retention-days: 7
          overwrite: true
          include-hidden-files: true
          path: |
            ./logs
            *.out
            *.dump


================================================
FILE: .github/workflows/x-test-vdf.yml
================================================
######################################################################
# Arweave Test Suite dedicated for VDF testing.
######################################################################
name: "arweave-test-suite-vdf"

on:
  workflow_call:
    inputs:
      os_arch:
        description: "operating system architecture"
        default: "amd64"
        type: "string"
      os_name:
        description: "operating system name"
        default: "ubuntu"
        type: "string"
      os_release:
        description: "operating system release"
        default: "22.04"
        type: "string"

env:
  cache_key: ${{ inputs.os_arch }}-${{ inputs.os_name }}-${{ inputs.os_release }}

####################################################################
# Test modules (note: that _tests are implicitly run by a matching
# prefix name
####################################################################
jobs:
  eunit-tests-suite:
    runs-on:
      - self-hosted
      - build-runner
      - ${{ inputs.os_arch }}
      - ${{ inputs.os_name }}
      - ${{ inputs.os_release }}

    strategy:
      fail-fast: false
      max-parallel: 12
      matrix:
        core_test_mod: [
            # modules
            ar,
            ar_block,
            ar_block_cache,
            ar_chain_stats,
            ar_chunk_copy,
            ar_chunk_storage,
            ar_deep_hash,
            ar_device_lock,
            ar_diff_dag,
            ar_entropy_gen,
            ar_entropy_storage,
            ar_ets_intervals,
            ar_events,
            ar_footprint_record,
            ar_inflation,
            ar_intervals,
            ar_join,
            ar_kv,
            arweave_limiter_group,
            arweave_limiter_metrics_collector,
            ar_merkle,
            ar_node,
            ar_node_utils,
            ar_nonce_limiter,
            ar_patricia_tree,
            ar_peers,
            ar_peer_intervals,
            ar_pricing,
            ar_retarget,
            ar_serialize,
            ar_tx_db,
            ar_unbalanced_merkle,
            ar_util,
            ar_wallet,
            ar_webhook,
            ar_pool,
            # standard
            ar_base64_compatibility_tests,
            ar_config_tests,
            ar_difficulty_tests,
            ar_forced_validation_tests,
            ar_header_sync_tests,
            ar_http_iface_tests,
            ar_http_util_tests,
            ar_info_tests,
            ar_mempool_tests,
            ar_mine_vdf_tests,
            ar_semaphore_tests,
            ar_start_from_block_tests,
            ar_tx_blacklist_tests,
            ar_vdf_tests,
            # long running
            ar_vdf_block_validation_tests,
            ar_vdf_server_tests,
            ar_vdf_external_update_tests,
            ar_cli_parser
          ]
    steps:
      - name: cleanup
        if: always()
        run: |
          rm -rf "${GITHUB_WORKSPACE}" && mkdir -p "${GITHUB_WORKSPACE}"

      - uses: actions/checkout@v4
        with:
          submodules: "recursive"
          lfs: true

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}-${{ env.cache_key }}

      # Both artifacts (_build and apps dir) are
      # required.
      - name: Extract artifact
        run: |
          tar zxfp _build.tar.gz
          tar zxfp apps.tar.gz

      - name: ${{ matrix.core_test_mod }}.erl
        id: tests
        run: bash scripts/github_workflow.sh "tests" "${{ matrix.core_test_mod }}"

      # this part of the job produces test artifacts from logs
      # generated by the tests. It also collect dumps and the files
      # present in .tmp (temporary arweave data store)
      - name: upload artifacts in case of failure
        uses: actions/upload-artifact@v4
        if: always() && failure()
        with:
          name: "logs-${{ matrix.core_test_mod }}-${{ github.run_attempt }}-${{ job.status }}-${{ runner.name }}-${{ github.sha }}"
          retention-days: 7
          overwrite: true
          include-hidden-files: true
          path: |
            ./logs
            *.out
            *.dump


================================================
FILE: .gitignore
================================================
*.beam
*.log
*.dat
.vscode
*.out
*.code-workspace
.arweave.plt
testlog
debug_logs
apps/arweave/priv/tls
apps/arweave/priv/*.so
_build
releases
lib
/result
.rebar3
apps/arweave/c_src/**/*.o
apps/arweave/c_src/tests/tests
data_test_*
erl_crash.dump
tags
metrics
blocks
txs
hash_lists
wallet_lists
/wallets
logs*
!bin/logs
ebin
metrics_*
release/output
.DS_Store
.tmp
node_modules
screenlog.0
_*
*.swp
*~
localnet_snapshot/wallets/arweave_keyfile_*
!**/_*.json
.jupyter/migrated
notebooks/.ipynb_checkpoints



================================================
FILE: .gitmodules
================================================
[submodule "lib/RandomX"]
	path = apps/arweave/lib/RandomX
	url = https://github.com/ArweaveTeam/RandomX.git
[submodule "apps/arweave/lib/secp256k1"]
	path = apps/arweave/lib/secp256k1
	url = https://github.com/bitcoin-core/secp256k1
[submodule "apps/arweave/lib/openssl-sha-lite"]
	path = apps/arweave/lib/openssl-sha-lite
	url = https://github.com/ArweaveTeam/openssl-sha-lite


================================================
FILE: .jupyter/jupyter_server_config.py
================================================
import os


def _strip_outputs_pre_save(model, **kwargs):
    if os.getenv("NOTEBOOK_SAVE_OUTPUTS") == "1":
        return
    if model.get("type") != "notebook":
        return

    content = model.get("content")
    if not content:
        return

    for cell in content.get("cells", []):
        if cell.get("cell_type") != "code":
            continue
        cell["outputs"] = []
        cell["execution_count"] = None
        metadata = cell.get("metadata")
        if isinstance(metadata, dict):
            metadata.pop("execution", None)


c.FileContentsManager.pre_save_hook = _strip_outputs_pre_save


================================================
FILE: CANARY.md
================================================
# Arweave Team Warrant Canary

- The Arweave Team has not been contacted by any law enforcement officials regarding the project. Last update: 22 March 2024.

- The Arweave Team has not been asked to break the encryption of the system by any party. Last update: 22 March 2024.

- The Arweave Team has not been asked to reveal the identities of any backers. Last update: 22 March 2024.

- The Arweave Team is not in any way under duress. Last update: 22 March 2024.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

This is a quick overview for what you should know when contributing to this Git repository.

 - There is a code style guide in `arweave_styleguide.md`. Please note that we're using tabs for indentation.
 - Make sure the tests pass (see [README](README.md) for how to run the tests).
 - You can discuss development and get help from the Arweave organization and community in the `#dev` channel on [our Discord server](https://discord.gg/3UTNZky).

## Workflow

 1. Fork the main Git repo `https://github.com/ArweaveTeam/arweave.git`
 2. Branch out from `master`.
 3. Add your changes.
 4. Run the tests (see above).
 5. Rebase your branch on the upstream `master` if the upstream `master` has moved since you branched out.
 6. Create a PR back to the upstream `master`.

Happy hacking! :)


================================================
FILE: LICENSE.md
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

                    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

                            NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    {description}
    Copyright (C) {year}  {fullname}

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) year name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  {signature of Ty Coon}, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.


================================================
FILE: README.md
================================================
# Arweave Server

This is the repository for the official Erlang implementation of the Arweave
protocol and a gateway implementation.

Arweave is a distributed, cryptographically verified permanent archive built
on a cryptocurrency that aims to, for the first time, provide feasible data
permanence. By leveraging our novel Blockweave datastructure, data is stored
in a decentralised, peer-to-peer manner where miners are incentivised to
store rare data.

# Contributing

For instructions on how to build and update the source, please refer to the [Development Docs](https://docs.arweave.org/developers/development/getting-started)

# Contact

If you have questions or comments about Arweave you can get in touch by
finding us on [Twitter](https://twitter.com/ArweaveTeam/), [Reddit](https://www.reddit.com/r/arweave), [Discord](https://discord.gg/DjAFMJc) or by
emailing us at team@arweave.org.


For more information about the Arweave project visit [https://www.arweave.org](https://www.arweave.org/)
or have a look at our [yellow paper](https://yellow-paper.arweave.dev).

# License

The Arweave project is released under GNU General Public License v2.0.
See [LICENSE](LICENSE.md) for full license conditions.


================================================
FILE: apps/arweave/c_src/Makefile
================================================
# Based on c_src.mk from erlang.mk by Loic Hoguin <essen@ninenines.eu>

CURDIR := $(shell pwd)
BASEDIR := $(abspath $(CURDIR)/..)

PROJECT ?= $(notdir $(BASEDIR))
PROJECT := $(strip $(PROJECT))

ifeq ($(MODE), debug)
	CFLAGS ?= -O0 -g
	CXXFLAGS ?= -O0 -g
else
	CFLAGS ?= -O3
	CXXFLAGS ?= -O3
endif

UNAME_SYS := $(shell uname -s)

# Configure SHA external libraries, we are using OPENSSL_LITE
# by default, for all systems
RANDOMX_LDFLAGS = ../lib/openssl-sha-lite/libcrypto.a

# Set default libs path for secp256k1 implementation
SECP256K1_LDLIBS = -L /usr/lib -L /usr/local/lib

ifeq ($(UNAME_SYS), Linux)
	# _mm_crc32_u32 support
	CFLAGS += -msse4.2
	CXXFLAGS += -msse4.2
endif

ERTS_INCLUDE_DIR ?= $(shell erl -noshell -eval 'io:format("~ts/erts-~ts/include/", [code:root_dir(), erlang:system_info(version)]).' -s init stop)
ERL_INTERFACE_INCLUDE_DIR ?= $(shell erl -noshell -eval 'io:format("~ts", [code:lib_dir(erl_interface, include)]).' -s init stop)
ERL_INTERFACE_LIB_DIR ?= $(shell erl -noshell -eval 'io:format("~ts", [code:lib_dir(erl_interface, lib)]).' -s init stop)

# System type and C compiler/flags.

ifeq ($(UNAME_SYS), Darwin)
	OSX_CPU_ARCH ?= x86_64
	# nix systems may not have sysctl where uname -m will return the correct arch
	SYSCTL_EXISTS := $(shell which sysctl 2>/dev/null)
	ifneq ($(shell uname -m | egrep "arm64"),)
		OSX_CPU_ARCH = arm64
	else
		ifdef SYSCTL_EXISTS
			ifneq ($(shell sysctl -n machdep.cpu.brand_string | egrep "M(1|2)"),)
				OSX_CPU_ARCH = arm64
			endif
		endif
	endif
	CC ?= cc
	CFLAGS += -std=c99 -arch $(OSX_CPU_ARCH) -finline-functions -Wall -Wmissing-prototypes
	CXXFLAGS += -arch $(OSX_CPU_ARCH) -finline-functions -Wall
	LDFLAGS ?= -arch $(OSX_CPU_ARCH)
	LDFLAGS += -undefined suppress
	# on MacOS, some libs are also present in /opt/homebrew/lib
	SECP256K1_LDLIBS += -L /opt/homebrew/lib
else ifeq ($(UNAME_SYS), FreeBSD)
	CC ?= cc
	CFLAGS += -std=c99 -finline-functions -Wall -Wmissing-prototypes
	CXXFLAGS += -finline-functions -Wall
else ifeq ($(UNAME_SYS), Linux)
	CC ?= gcc
	CFLAGS += -std=c99 -finline-functions -Wall -Wmissing-prototypes
	CXXFLAGS += -finline-functions -Wall
endif

ifneq (, $(shell which pkg-config))
	CFLAGS   += -I../lib/openssl-sha-lite/include
	CXXFLAGS += -I../lib/openssl-sha-lite/include
endif

C_SRC_DIR = $(CURDIR)

SECP256K1_CFLAGS += $(CFLAGS)
SECP256K1_LDLIBS += $(LDFLAGS)
CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) -I /usr/local/include -I ../lib/RandomX/src -I $(C_SRC_DIR)
CXXFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) -I ../lib/RandomX/src -std=c++11
LDLIBS += -L $(ERL_INTERFACE_LIB_DIR) -L /usr/local/lib -lei


RX512_OUTPUT ?= $(CURDIR)/../priv/rx512_arweave.so
RX4096_OUTPUT ?= $(CURDIR)/../priv/rx4096_arweave.so
RXSQUARED_OUTPUT ?= $(CURDIR)/../priv/rxsquared_arweave.so
VDF_OUTPUT ?= $(CURDIR)/../priv/vdf_arweave.so

COMMON_RANDOMX_SOURCES = $(wildcard $(C_SRC_DIR)/randomx/*.c $(C_SRC_DIR)/randomx/*.cpp)
RX512_SOURCES = $(COMMON_RANDOMX_SOURCES) $(wildcard $(C_SRC_DIR)/*.c $(C_SRC_DIR)/randomx/rx512/*.c)
RX4096_SOURCES = $(COMMON_RANDOMX_SOURCES) $(wildcard $(C_SRC_DIR)/*.c $(C_SRC_DIR)/randomx/rx4096/*.c)
RXSQUARED_SOURCES = $(COMMON_RANDOMX_SOURCES) $(wildcard $(C_SRC_DIR)/*.c $(C_SRC_DIR)/randomx/rxsquared/*.c)
VDF_SOURCES = $(wildcard $(C_SRC_DIR)/*.c $(C_SRC_DIR)/vdf/*.c $(C_SRC_DIR)/vdf/*.cpp)

RX512_OBJECTS = $(addsuffix .o, $(basename $(RX512_SOURCES)))
RX4096_OBJECTS = $(addsuffix .o, $(basename $(RX4096_SOURCES)))
RXSQUARED_OBJECTS = $(addsuffix .o, $(basename $(RXSQUARED_SOURCES)))
VDF_OBJECTS = $(addsuffix .o, $(basename $(VDF_SOURCES)))

# NOTE tabs here will cause build fail
ifeq ($(UNAME_SYS), Linux)
  $(C_SRC_DIR)/vdf/vdf_fused_x86.o: CXXFLAGS += -msha
endif
ifeq ($(UNAME_SYS), Darwin)
  $(C_SRC_DIR)/vdf/vdf_fused_arm.o: CXXFLAGS += -march=armv8-a+crypto
  $(C_SRC_DIR)/vdf/vdf_hiopt_arm.o: CXXFLAGS += -march=armv8-a+crypto
endif
ifeq ($(UNAME_SYS), Darwin)
	VDF_ARM_ASM_OBJ = $(C_SRC_DIR)/vdf/sha256-armv8.o
	VDF_OBJECTS += $(VDF_ARM_ASM_OBJ)
$(VDF_ARM_ASM_OBJ): $(C_SRC_DIR)/vdf/sha256-armv8.S
	@echo "Assembling ARM64 specific file: $<"
	clang -O3 -arch arm64 -c $(C_SRC_DIR)/vdf/sha256-armv8.S -o $(VDF_ARM_ASM_OBJ)
endif

# Verbosity.

c_verbose_0 = @echo " C     " $(?F);
c_verbose = $(c_verbose_$(V))

cpp_verbose_0 = @echo " CPP   " $(?F);
cpp_verbose = $(cpp_verbose_$(V))

link_verbose_0 = @echo " LD    " $(@F);
link_verbose = $(link_verbose_$(V))

COMPILE_C = $(c_verbose) $(CC) $(CFLAGS) $(CPPFLAGS) -c
COMPILE_CPP = $(cpp_verbose) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c

$(RX512_OUTPUT): $(RX512_OBJECTS)
	@mkdir -p $(BASEDIR)/priv/
	$(link_verbose) $(CXX) $(RX512_OBJECTS) $(RANDOMX_LDFLAGS) $(LDFLAGS) $(LDLIBS) ../lib/RandomX/build512/librandomx512.a -shared -o $(RX512_OUTPUT)

$(RX4096_OUTPUT): $(RX4096_OBJECTS)
	@mkdir -p $(BASEDIR)/priv/
	$(link_verbose) $(CXX) $(RX4096_OBJECTS) $(RANDOMX_LDFLAGS) $(LDFLAGS) $(LDLIBS) ../lib/RandomX/build4096/librandomx4096.a -shared -o $(RX4096_OUTPUT)

$(RXSQUARED_OUTPUT): $(RXSQUARED_OBJECTS)
	@mkdir -p $(BASEDIR)/priv/
	$(link_verbose) $(CXX) $(RXSQUARED_OBJECTS) $(RANDOMX_LDFLAGS) $(LDFLAGS) $(LDLIBS) ../lib/RandomX/buildsquared/librandomxsquared.a -shared -o $(RXSQUARED_OUTPUT)

$(VDF_OUTPUT): $(VDF_OBJECTS)
	@mkdir -p $(BASEDIR)/priv/
	$(link_verbose) $(CXX) $(VDF_OBJECTS) $(RANDOMX_LDFLAGS) $(LDFLAGS) $(LDLIBS) -shared -o $(VDF_OUTPUT)

SECP256K1_SOURCES = $(wildcard $(C_SRC_DIR)/*.c $(C_SRC_DIR)/secp256k1/*.c)
SECP256K1_OBJECTS = $(addsuffix .o, $(basename $(SECP256K1_SOURCES)))
SECP256K1_CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR) -I /usr/local/include -I $(CURDIR)/../lib/secp256k1/src -I $(CURDIR)/../lib/secp256k1/include -I $(C_SRC_DIR)
SECP256K1_LDLIBS += -L $(ERL_INTERFACE_LIB_DIR)
SECP256K1_OUTPUT ?= $(CURDIR)/../priv/secp256k1_arweave.so

$(SECP256K1_OUTPUT): $(SECP256K1_OBJECTS)
	@mkdir -p $(BASEDIR)/priv/
	$(link_verbose) $(CXX) $(SECP256K1_OBJECTS) $(SECP256K1_LDLIBS) ../lib/secp256k1/build/lib/libsecp256k1.a -shared -o $(SECP256K1_OUTPUT)

%secp256k1_nif.o: %secp256k1_nif.c
	$(c_verbose) $(CC) $(SECP256K1_CFLAGS) -c $(OUTPUT_OPTION) $<

%.o: %.c
	$(COMPILE_C) $(OUTPUT_OPTION) $<

%.o: %.cc
	$(COMPILE_CPP) $(OUTPUT_OPTION) $<

%.o: %.C
	$(COMPILE_CPP) $(OUTPUT_OPTION) $<

%.o: %.cpp
	$(COMPILE_CPP) $(OUTPUT_OPTION) $<

all: $(RX512_OUTPUT) $(RX4096_OUTPUT) $(RXSQUARED_OUTPUT) $(VDF_OUTPUT) $(SECP256K1_OUTPUT)

clean:
	@rm -f $(RX512_OUTPUT) $(RX4096_OUTPUT) $(RXSQUARED_OUTPUT) $(VDF_OUTPUT) $(RX512_OBJECTS) $(RX4096_OBJECTS) $(RXSQUARED_OBJECTS) $(VDF_OBJECTS) $(SECP256K1_OUTPUT) $(SECP256K1_OBJECTS)







================================================
FILE: apps/arweave/c_src/ar_nif.c
================================================
#include "ar_nif.h"
#include <string.h>

// Utility functions.

ERL_NIF_TERM solution_tuple(ErlNifEnv* envPtr, ERL_NIF_TERM hashTerm) {
	return enif_make_tuple2(envPtr, enif_make_atom(envPtr, "true"), hashTerm);
}

ERL_NIF_TERM ok_tuple(ErlNifEnv* envPtr, ERL_NIF_TERM term)
{
	return enif_make_tuple2(envPtr, enif_make_atom(envPtr, "ok"), term);
}

ERL_NIF_TERM ok_tuple2(ErlNifEnv* envPtr, ERL_NIF_TERM term1, ERL_NIF_TERM term2)
{
	return enif_make_tuple3(envPtr, enif_make_atom(envPtr, "ok"), term1, term2);
}

ERL_NIF_TERM error_tuple(ErlNifEnv* envPtr, const char* reason)
{
	ERL_NIF_TERM reasonTerm = enif_make_string(envPtr, reason, ERL_NIF_LATIN1);
	return enif_make_tuple2(envPtr, enif_make_atom(envPtr, "error"), reasonTerm);
}

ERL_NIF_TERM make_output_binary(ErlNifEnv* envPtr, unsigned char *dataPtr, size_t size)
{
	ERL_NIF_TERM outputTerm;
	unsigned char *outputTermDataPtr;

	outputTermDataPtr = enif_make_new_binary(envPtr, size, &outputTerm);
	memcpy(outputTermDataPtr, dataPtr, size);
	return outputTerm;
}


================================================
FILE: apps/arweave/c_src/ar_nif.h
================================================
#ifndef AR_NIF_H
#define AR_NIF_H

#include <erl_nif.h>

ERL_NIF_TERM solution_tuple(ErlNifEnv*, ERL_NIF_TERM);
ERL_NIF_TERM ok_tuple(ErlNifEnv*, ERL_NIF_TERM);
ERL_NIF_TERM ok_tuple2(ErlNifEnv*, ERL_NIF_TERM, ERL_NIF_TERM);
ERL_NIF_TERM error_tuple(ErlNifEnv*, const char*);
ERL_NIF_TERM make_output_binary(ErlNifEnv*, unsigned char*, size_t);

#endif // AR_NIF_H

================================================
FILE: apps/arweave/c_src/randomx/ar_randomx_impl.h
================================================
#ifndef AR_RANDOMX_IMPL_H
#define AR_RANDOMX_IMPL_H

// Thif file includes the full definitions of any function that is shared between the
// rx512 and rx4096 shared libraries. Although ugly this was the only way I could get
// everything to work without causing symbol conflicts or seg faults once the two .so's
// are loaded into arweave and the NIFs registered. There may be a better way!

#include <erl_nif.h>
#include <randomx.h>

// From RandomX/src/jit_compiler.hpp
// needed for the JIT compiler to work on OpenBSD, NetBSD and Apple Silicon
#if defined(__OpenBSD__) || defined(__NetBSD__) || (defined(__APPLE__) && defined(__aarch64__))
#define RANDOMX_FORCE_SECURE
#endif

typedef enum { FALSE, TRUE } boolean;

struct workerThread {
	ErlNifTid threadId;
	ErlNifThreadOpts *optsPtr;
	randomx_cache *cachePtr;
	randomx_dataset *datasetPtr;
	unsigned long datasetInitStartItem;
	unsigned long datasetInitItemCount;
};

typedef enum {
	HASHING_MODE_FAST = 0,
	HASHING_MODE_LIGHT = 1,
} hashing_mode;

struct state {
	ErlNifRWLock*     lockPtr;
	int               isRandomxReleased;
	hashing_mode      mode;
	randomx_dataset*  datasetPtr;
	randomx_cache*    cachePtr;
};

ErlNifResourceType* stateType;

static ERL_NIF_TERM init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM info_nif(const char* rxSize, ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM hash_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static int load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info);
static void state_dtor(ErlNifEnv* envPtr, void* objPtr);
static boolean init_dataset(
	randomx_dataset *datasetPtr,
	randomx_cache *cachePtr,
	unsigned int numWorkers
);
static void *init_dataset_thread(void *objPtr);
static ERL_NIF_TERM init_failed(ErlNifEnv *envPtr, struct state *statePtr, const char* reason);
static randomx_vm* create_vm(struct state* statePtr,
		int fullMemEnabled, int jitEnabled, int largePagesEnabled, int hardwareAESEnabled,
		int* isRandomxReleased);
static void destroy_vm(struct state* statePtr, randomx_vm* vmPtr);

static ERL_NIF_TERM init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	ErlNifBinary key;
	hashing_mode mode;
	struct state *statePtr;
	ERL_NIF_TERM resource;
	unsigned int numWorkers;
	int jitEnabled, largePagesEnabled;
	randomx_flags flags;

	if (!enif_inspect_binary(envPtr, argv[0], &key)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[1], &mode)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[2], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_uint(envPtr, argv[4], &numWorkers)) {
		return enif_make_badarg(envPtr);
	}

	statePtr = enif_alloc_resource(stateType, sizeof(struct state));
	statePtr->cachePtr = NULL;
	statePtr->datasetPtr = NULL;
	statePtr->isRandomxReleased = 0;
	statePtr->mode = mode;

	statePtr->lockPtr = enif_rwlock_create("state_rw_lock");
	if (statePtr->lockPtr == NULL) {
		return init_failed(envPtr, statePtr, "enif_rwlock_create failed");
	}

	flags = RANDOMX_FLAG_DEFAULT;
	if (jitEnabled) {
		flags |= RANDOMX_FLAG_JIT;
#ifdef RANDOMX_FORCE_SECURE
		flags |= RANDOMX_FLAG_SECURE;
#endif
	}
	if (largePagesEnabled) {
		flags |= RANDOMX_FLAG_LARGE_PAGES;
	}

	statePtr->cachePtr = randomx_alloc_cache(flags);
	if (statePtr->cachePtr == NULL) {
		return init_failed(envPtr, statePtr, "randomx_alloc_cache failed");
	}

	randomx_init_cache(
		statePtr->cachePtr,
		key.data,
		key.size);

	if (mode == HASHING_MODE_FAST) {
		statePtr->datasetPtr = randomx_alloc_dataset(flags);
		if (statePtr->datasetPtr == NULL) {
			return init_failed(envPtr, statePtr, "randomx_alloc_dataset failed");
		}
		if (!init_dataset(statePtr->datasetPtr, statePtr->cachePtr, numWorkers)) {
			return init_failed(envPtr, statePtr, "init_dataset failed");
		}
		randomx_release_cache(statePtr->cachePtr);
		statePtr->cachePtr = NULL;
	} else {
		statePtr->datasetPtr = NULL;
	}

	resource = enif_make_resource(envPtr, statePtr);
	enif_release_resource(statePtr);

	return ok_tuple(envPtr, resource);
}

static ERL_NIF_TERM info_nif(
    const char* rxSize, ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	struct state* statePtr;
	unsigned int datasetSize;
	unsigned int scratchpadSize;
	hashing_mode hashingMode;
	ERL_NIF_TERM hashingModeTerm;

	if (argc != 1) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}

	hashingMode = statePtr->mode;

	if (hashingMode == HASHING_MODE_FAST) {
		if (statePtr->datasetPtr == NULL) {
			return error_tuple(envPtr, "dataset is not initialized for fast hashing mode");
		}
		if (statePtr->cachePtr != NULL) {
			return error_tuple(envPtr, "cache is initialized for fast hashing mode");
		}
		hashingModeTerm = enif_make_atom(envPtr, "fast");
		datasetSize = randomx_dataset_item_count();
		scratchpadSize = randomx_get_scratchpad_size();
	} else if (hashingMode == HASHING_MODE_LIGHT) {
		if (statePtr->datasetPtr != NULL) {
			return error_tuple(envPtr, "dataset is initialized for light hashing mode");
		}
		if (statePtr->cachePtr == NULL) {
			return error_tuple(envPtr, "cache is not initialized for light hashing mode");
		}
		hashingModeTerm = enif_make_atom(envPtr, "light");
		datasetSize = 0;
		scratchpadSize = randomx_get_scratchpad_size();
	} else {
		return error_tuple(envPtr, "invalid hashing mode");
	}

	ERL_NIF_TERM infoTerm = enif_make_tuple4(envPtr,
		enif_make_atom(envPtr, rxSize),
		hashingModeTerm,
		enif_make_uint(envPtr, datasetSize),
		enif_make_uint(envPtr, scratchpadSize));
	return ok_tuple(envPtr, infoTerm);
}


static ERL_NIF_TERM hash_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	int jitEnabled, largePagesEnabled, hardwareAESEnabled;
	unsigned char hashPtr[RANDOMX_HASH_SIZE];
	struct state* statePtr;
	ErlNifBinary inputData;

	if (argc != 5) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}
	if (!enif_inspect_binary(envPtr, argv[1], &inputData)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[2], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}

	int isRandomxReleased;
	randomx_vm *vmPtr = create_vm(statePtr, (statePtr->mode == HASHING_MODE_FAST), jitEnabled, largePagesEnabled, hardwareAESEnabled, &isRandomxReleased);
	if (vmPtr == NULL) {
		if (isRandomxReleased != 0) {
			return error_tuple(envPtr, "state has been released");
		}
		return error_tuple(envPtr, "randomx_create_vm failed");
	}

	randomx_calculate_hash(vmPtr, inputData.data, inputData.size, hashPtr);

	destroy_vm(statePtr, vmPtr);

	return ok_tuple(envPtr, make_output_binary(envPtr, hashPtr, RANDOMX_HASH_SIZE));
}

static int load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info)
{
	int flags = ERL_NIF_RT_CREATE;
	stateType = enif_open_resource_type(envPtr, NULL, "state", state_dtor, flags, NULL);
	if (stateType == NULL) {
		return 1;
	}

	return 0;
}

static void state_dtor(ErlNifEnv* envPtr, void* objPtr)
{
	struct state *statePtr = (struct state*) objPtr;

    if (statePtr->datasetPtr != NULL) {
		randomx_release_dataset(statePtr->datasetPtr);
		statePtr->datasetPtr = NULL;
	}
	if (statePtr->cachePtr != NULL) {
		randomx_release_cache(statePtr->cachePtr);
		statePtr->cachePtr = NULL;
	}
	statePtr->isRandomxReleased = 1;

	if (statePtr->lockPtr != NULL) {
		enif_rwlock_destroy(statePtr->lockPtr);
		statePtr->lockPtr = NULL;
	}
}

static boolean init_dataset(
	randomx_dataset *datasetPtr,
	randomx_cache *cachePtr,
	unsigned int numWorkers
) {
	struct workerThread **workerPtrPtr;
	struct workerThread *workerPtr;
	unsigned long itemsPerThread;
	unsigned long itemsRemainder;
	unsigned long startItem;
	boolean anyThreadFailed;

	workerPtrPtr = enif_alloc(sizeof(struct workerThread *) * numWorkers);
	itemsPerThread = randomx_dataset_item_count() / numWorkers;
	itemsRemainder = randomx_dataset_item_count() % numWorkers;
	startItem = 0;
	for (int i = 0; i < numWorkers; i++) {
		workerPtrPtr[i] = enif_alloc(sizeof(struct workerThread));
		workerPtr = workerPtrPtr[i];

		workerPtr->cachePtr = cachePtr;
		workerPtr->datasetPtr = datasetPtr;

		workerPtr->datasetInitStartItem = startItem;
		if (i + 1 == numWorkers) {
			workerPtr->datasetInitItemCount = itemsPerThread + itemsRemainder;
		} else {
			workerPtr->datasetInitItemCount = itemsPerThread;
		}
		startItem += workerPtr->datasetInitItemCount;
		workerPtr->optsPtr = enif_thread_opts_create("init_fast_worker");
		if (0 != enif_thread_create(
				"init_dataset_worker",
				&(workerPtr->threadId),
				&init_dataset_thread,
				workerPtr,
				workerPtr->optsPtr))
		{
			enif_thread_opts_destroy(workerPtr->optsPtr);
			enif_free(workerPtrPtr[i]);
			workerPtrPtr[i] = NULL;
		}
	}
	anyThreadFailed = FALSE;
	for (int i = 0; i < numWorkers; i++) {
		workerPtr = workerPtrPtr[i];
		if (workerPtr == NULL) {
			anyThreadFailed = TRUE;
		} else if (0 != enif_thread_join(workerPtr->threadId, NULL)) {
			anyThreadFailed = TRUE;
		}
		if (workerPtr != NULL) {
			enif_thread_opts_destroy(workerPtr->optsPtr);
			enif_free(workerPtr);
		}
	}
	enif_free(workerPtrPtr);
	return !anyThreadFailed;
}

static void *init_dataset_thread(void *objPtr)
{
	struct workerThread *workerPtr = (struct workerThread*) objPtr;
	randomx_init_dataset(
		workerPtr->datasetPtr,
		workerPtr->cachePtr,
		workerPtr->datasetInitStartItem,
		workerPtr->datasetInitItemCount);
	return NULL;
}

static ERL_NIF_TERM init_failed(ErlNifEnv *envPtr, struct state *statePtr, const char* reason)
{
	if (statePtr->lockPtr != NULL) {
		enif_rwlock_destroy(statePtr->lockPtr);
		statePtr->lockPtr = NULL;
	}
	if (statePtr->cachePtr != NULL) {
		randomx_release_cache(statePtr->cachePtr);
		statePtr->cachePtr = NULL;
	}
	if (statePtr->datasetPtr != NULL) {
		randomx_release_dataset(statePtr->datasetPtr);
		statePtr->datasetPtr = NULL;
	}
	enif_release_resource(statePtr);
	return error_tuple(envPtr, reason);
}

static randomx_vm* create_vm(struct state* statePtr,
		int fullMemEnabled, int jitEnabled, int largePagesEnabled, int hardwareAESEnabled,
		int* isRandomxReleased) {
	enif_rwlock_rlock(statePtr->lockPtr);
	*isRandomxReleased = statePtr->isRandomxReleased;
	if (statePtr->isRandomxReleased != 0) {
		enif_rwlock_runlock(statePtr->lockPtr);
		return NULL;
	}

	randomx_flags flags = RANDOMX_FLAG_DEFAULT;
	if (fullMemEnabled) {
		flags |= RANDOMX_FLAG_FULL_MEM;
	}
	if (hardwareAESEnabled) {
		flags |= RANDOMX_FLAG_HARD_AES;
	}
	if (jitEnabled) {
		flags |= RANDOMX_FLAG_JIT;
#ifdef RANDOMX_FORCE_SECURE
		flags |= RANDOMX_FLAG_SECURE;
#endif
	}
	if (largePagesEnabled) {
		flags |= RANDOMX_FLAG_LARGE_PAGES;
	}

	randomx_vm *vmPtr = randomx_create_vm(flags, statePtr->cachePtr, statePtr->datasetPtr);
	if (vmPtr == NULL) {
		enif_rwlock_runlock(statePtr->lockPtr);
		return NULL;
	}
	return vmPtr;
}

static void destroy_vm(struct state* statePtr, randomx_vm* vmPtr) {
	randomx_destroy_vm(vmPtr);
	enif_rwlock_runlock(statePtr->lockPtr);
}

#endif

================================================
FILE: apps/arweave/c_src/randomx/crc32.h
================================================
#ifndef CRC32_H
#define CRC32_H

#if defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)
  #include <immintrin.h>
  #define crc32(a, b) _mm_crc32_u32(a, b)
#elif defined(__aarch64__) || defined(__arm__) || defined(_M_ARM64) || defined(_M_ARM)
  #include <arm_acle.h>
  #define crc32(a, b) __crc32cw(a, b)
#else
  // TODO make support for soft crc32
  #error "Unsupported architecture for CRC32 operations."
#endif

#endif // CRC32_H

================================================
FILE: apps/arweave/c_src/randomx/feistel_msgsize_key_cipher.cpp
================================================
#include <openssl/sha.h>

#include "feistel_msgsize_key_cipher.h"

// NOTE feistel_encrypt_block/feistel_decrypt_block with less than 2 blocks have no sense

void feistel_hash(const unsigned char *in_r, const unsigned char *in_k, unsigned char *out) {
	SHA256_CTX sha256;
	SHA256_Init(&sha256);
	SHA256_Update(&sha256, in_r, 32);
	SHA256_Update(&sha256, in_k, 32);
	SHA256_Final(out, &sha256);
}

// size_t key_len, 
void feistel_encrypt_block(const unsigned char *in_left, const unsigned char *in_right, const unsigned char *in_key, unsigned char *out_left, unsigned char *out_right) {
	// size_t round_count = key_len / FEISTEL_BLOCK_LENGTH;

	// unsigned char temp;
	unsigned char key_hash[FEISTEL_BLOCK_LENGTH];
	unsigned char left[FEISTEL_BLOCK_LENGTH];
	unsigned char right[FEISTEL_BLOCK_LENGTH];
	const unsigned char *key = in_key;

	feistel_hash(in_right, key, key_hash);
	key += FEISTEL_BLOCK_LENGTH;
	for(int j = 0; j < FEISTEL_BLOCK_LENGTH; j++) {
		// temp = in_left[j] ^ key_hash[j];
		right[j] = in_left[j] ^ key_hash[j];
		left[j] = in_right[j];
		// right[j] = temp;
	}

	// NOTE will be unused by arweave
	// for (size_t i = 1; i < round_count - 1; i++) {
	// 	feistel_hash(right, key, key_hash);
	// 	key += FEISTEL_BLOCK_LENGTH;
	// 	for(int j = 0; j < FEISTEL_BLOCK_LENGTH; j++) {
	// 		temp = left[j] ^ key_hash[j];
	// 		left[j] = right[j];
	// 		right[j] = temp;
	// 	}
	// }

	feistel_hash(right, key, key_hash);
	for(int j = 0; j < FEISTEL_BLOCK_LENGTH; j++) {
		// temp = left[j] ^ key_hash[j];
		out_right[j] = left[j] ^ key_hash[j];
		out_left[j] = right[j];
		// out_right[j] = temp;
	}
}

void feistel_decrypt_block(const unsigned char *in_left, const unsigned char *in_right, const unsigned char *in_key, unsigned char *out_left, unsigned char *out_right) {
	// size_t round_count = key_len / FEISTEL_BLOCK_LENGTH;

	// unsigned char temp;
	unsigned char key_hash[FEISTEL_BLOCK_LENGTH];
	unsigned char left[FEISTEL_BLOCK_LENGTH];
	unsigned char right[FEISTEL_BLOCK_LENGTH];
	// const unsigned char *key = in_key + FEISTEL_BLOCK_LENGTH + 2*FEISTEL_BLOCK_LENGTH*(round_count - 1);
	const unsigned char *key = in_key + FEISTEL_BLOCK_LENGTH;

	feistel_hash(in_left, key, key_hash);
	key -= FEISTEL_BLOCK_LENGTH;
	for(int j = 0; j < FEISTEL_BLOCK_LENGTH; j++) {
		// temp = in_right[j] ^ key_hash[j];
		left[j] = in_right[j] ^ key_hash[j];
		right[j] = in_left[j];
		// left[j] = temp;
	}

	// NOTE will be unused by arweave
	// for (size_t i = 1; i < round_count - 1; i++) {
	// 	feistel_hash(left, key, key_hash);
	// 	key -= FEISTEL_BLOCK_LENGTH;
	// 	for(int j = 0; j < FEISTEL_BLOCK_LENGTH; j++) {
	// 		temp = right[j] ^ key_hash[j];
	// 		right[j] = left[j];
	// 		left[j] = temp;
	// 	}
	// }

	feistel_hash(left, key, key_hash);
	for(int j = 0; j < FEISTEL_BLOCK_LENGTH; j++) {
		// temp = right[j] ^ key_hash[j];
		out_left[j] = right[j] ^ key_hash[j];
		out_right[j] = left[j];
		// out_left[j] = temp;
	}
}

// feistel_encrypt accepts padded message with 2*FEISTEL_BLOCK_LENGTH = 64 bytes
// in_key_length == plaintext_len
// CBC
void feistel_encrypt(const unsigned char *plaintext, const size_t plaintext_len, const unsigned char *in_key, unsigned char *ciphertext) {
	size_t block_count = plaintext_len / (2*FEISTEL_BLOCK_LENGTH);
	unsigned char feed_key[2*FEISTEL_BLOCK_LENGTH] = {0};

	const unsigned char *in = plaintext;
	unsigned char *out = ciphertext;
	const unsigned char *key = in_key;

	feistel_encrypt_block(in, in + FEISTEL_BLOCK_LENGTH, key, out, out + FEISTEL_BLOCK_LENGTH);
	in  += 2*FEISTEL_BLOCK_LENGTH;
	key += 2*FEISTEL_BLOCK_LENGTH;

	for(size_t i = 1; i < block_count; i++) {
		for(int j = 0; j < 2*FEISTEL_BLOCK_LENGTH; j++) {
			feed_key[j] = key[j] ^ out[j];
		}
		out += 2*FEISTEL_BLOCK_LENGTH;

		feistel_encrypt_block(in, in + FEISTEL_BLOCK_LENGTH, feed_key, out, out + FEISTEL_BLOCK_LENGTH);
		in  += 2*FEISTEL_BLOCK_LENGTH;
		key += 2*FEISTEL_BLOCK_LENGTH;
	}
}

void feistel_decrypt(const unsigned char *ciphertext, const size_t ciphertext_len, const unsigned char *in_key, unsigned char *plaintext) {
	size_t block_count = ciphertext_len / (2*FEISTEL_BLOCK_LENGTH);
	unsigned char feed_key[2*FEISTEL_BLOCK_LENGTH] = {0};

	const unsigned char *in = ciphertext + ciphertext_len - 2*FEISTEL_BLOCK_LENGTH;
	unsigned char *out = plaintext + ciphertext_len - 2*FEISTEL_BLOCK_LENGTH;
	const unsigned char *key = in_key + ciphertext_len - 2*FEISTEL_BLOCK_LENGTH;

	for(size_t i = 0; i < block_count-1; i++) {
		for(int j = 0; j < 2*FEISTEL_BLOCK_LENGTH; j++) {
			feed_key[j] = key[j] ^ in[j - 2*FEISTEL_BLOCK_LENGTH];
		}

		feistel_decrypt_block(in, in + FEISTEL_BLOCK_LENGTH, feed_key, out, out + FEISTEL_BLOCK_LENGTH);
		in  -= 2*FEISTEL_BLOCK_LENGTH;
		key -= 2*FEISTEL_BLOCK_LENGTH;
		out -= 2*FEISTEL_BLOCK_LENGTH;
	}

	feistel_decrypt_block(in, in + FEISTEL_BLOCK_LENGTH, key, out, out + FEISTEL_BLOCK_LENGTH);
}



================================================
FILE: apps/arweave/c_src/randomx/feistel_msgsize_key_cipher.h
================================================
#ifndef FEISTEL_MSGSIZE_KEY_CIPHER_H
#define FEISTEL_MSGSIZE_KEY_CIPHER_H


#define FEISTEL_BLOCK_LENGTH 32

#if defined(__cplusplus)
extern "C" {
#endif

void feistel_encrypt(const unsigned char *plaintext, const size_t plaintext_len, const unsigned char *key, unsigned char *ciphertext);
void feistel_decrypt(const unsigned char *ciphertext, const size_t ciphertext_len, const unsigned char *key, unsigned char *plaintext);

#if defined(__cplusplus)
}
#endif

#endif // FEISTEL_MSGSIZE_KEY_CIPHER_H


================================================
FILE: apps/arweave/c_src/randomx/randomx_long_with_entropy.cpp
================================================
#include <cassert>
#include "randomx_long_with_entropy.h"
#include "vm_interpreted.hpp"
#include "vm_interpreted_light.hpp"
#include "vm_compiled.hpp"
#include "vm_compiled_light.hpp"
#include "blake2/blake2.h"
#include "feistel_msgsize_key_cipher.h"

// NOTE. possible optimisation with outputEntropySize
// can improve performance for less memcpy (has almost no impact because randomx is too long 99+%)

extern "C" {
	const unsigned char *randomx_calculate_hash_long_with_entropy_get_entropy(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const int randomxProgramCount) {
		assert(machine != nullptr);
		assert(inputSize == 0 || input != nullptr);
		alignas(16) uint64_t tempHash[8];
		int blakeResult = randomx_blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0);
		assert(blakeResult == 0);
		machine->initScratchpad(&tempHash);
		machine->resetRoundingMode();
		for (int chain = 0; chain < randomxProgramCount - 1; ++chain) {
			machine->run(&tempHash);
			blakeResult = randomx_blake2b(tempHash, sizeof(tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0);
			assert(blakeResult == 0);
		}
		machine->run(&tempHash);
		unsigned char output[64];
		machine->getFinalResult(output, RANDOMX_HASH_SIZE);
		return (const unsigned char*)machine->getScratchpad();
	}

	// feistel_encrypt accepts padded message with 2*FEISTEL_BLOCK_LENGTH = 64 bytes
	RANDOMX_EXPORT void randomx_encrypt_chunk(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const unsigned char *inChunk, const size_t inChunkSize, unsigned char *outChunk, const int randomxProgramCount) {
		assert(inChunkSize <= RANDOMX_ENTROPY_SIZE);
		assert(inChunkSize % (2*FEISTEL_BLOCK_LENGTH) == 0);
		const unsigned char *outputEntropy = randomx_calculate_hash_long_with_entropy_get_entropy(machine, input, inputSize, randomxProgramCount);

		feistel_encrypt((const unsigned char*)inChunk, inChunkSize, outputEntropy, (unsigned char*)outChunk);
	}

	RANDOMX_EXPORT void randomx_decrypt_chunk(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const unsigned char *inChunk, const size_t inChunkSize, unsigned char *outChunk, const int randomxProgramCount) {
		assert(inChunkSize <= RANDOMX_ENTROPY_SIZE);
		assert(inChunkSize % (2*FEISTEL_BLOCK_LENGTH) == 0);

		const unsigned char *outputEntropy = randomx_calculate_hash_long_with_entropy_get_entropy(machine, input, inputSize, randomxProgramCount);

		feistel_decrypt((const unsigned char*)inChunk, inChunkSize, outputEntropy, (unsigned char*)outChunk);
	}
}


================================================
FILE: apps/arweave/c_src/randomx/randomx_long_with_entropy.h
================================================
#ifndef RANDOMX_LONG_WITH_ENTROPY_H
#define RANDOMX_LONG_WITH_ENTROPY_H

#include "randomx.h"

#define RANDOMX_ENTROPY_SIZE (256*1024)

#if defined(__cplusplus)
extern "C" {
#endif

RANDOMX_EXPORT void randomx_encrypt_chunk(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const unsigned char *inChunk, const size_t inChunkSize,  unsigned char *outChunk, const int randomxProgramCount);
RANDOMX_EXPORT void randomx_decrypt_chunk(randomx_vm *machine, const unsigned char *input, const size_t inputSize, const unsigned char *inChunk, const size_t outChunkSize, unsigned char *outChunk, const int randomxProgramCount);

#if defined(__cplusplus)
}
#endif

#endif // RANDOMX_LONG_WITH_ENTROPY_H

================================================
FILE: apps/arweave/c_src/randomx/randomx_squared.cpp
================================================
#include <cassert>
#include <openssl/sha.h>
#include "crc32.h"
#include "randomx_squared.h"
#include "feistel_msgsize_key_cipher.h"

// imports from randomx
#include "vm_compiled.hpp"
#include "blake2/blake2.h"

extern "C" {

	void _rsp_mix_entropy_near(
		const unsigned char *inEntropy,
		unsigned char *outEntropy,
		const size_t entropySize
	) {
		// NOTE we can't use _mm_crc32_u64, because it output only final 32-bit result
		// NOTE commented variant is more readable but unoptimized
		unsigned int state = ~0;
		// unsigned int state = 0;
		const unsigned int *inEntropyPtr = (const unsigned int*)inEntropy;
		unsigned int *outEntropyPtr = (unsigned int*)outEntropy;
		for(size_t i=0;i<entropySize;i+=8) {
			//state = crc32(~state, *inEntropyPtr);
			//*outEntropyPtr = *inEntropyPtr ^ ~state;

			state = ~crc32(state, *inEntropyPtr);
			*outEntropyPtr = *inEntropyPtr ^ state;
			inEntropyPtr++;
			outEntropyPtr++;
			*outEntropyPtr = *inEntropyPtr;
			inEntropyPtr++;
			outEntropyPtr++;
		}

		// keep state
		// reset output entropy from start
		outEntropyPtr = (unsigned int*)outEntropy;
		outEntropyPtr++;
		// take input from output now
		inEntropyPtr = outEntropyPtr;
		// Note it's optimizeable now with only 1 pointer, but we will reduce readability later
		for(size_t i=0;i<entropySize;i+=8) {
			//state = crc32(~state, *inEntropyPtr);
			//*outEntropyPtr = *inEntropyPtr ^ ~state;

			state = ~crc32(state, *inEntropyPtr);
			*outEntropyPtr = *inEntropyPtr ^ state;
			inEntropyPtr += 2;
			outEntropyPtr += 2;
		}
	}

	// Runs 1 RX2 round of programCount RandomX execs + 1 CRC mix on a single lane.
	// VM scratchpad is updated in place.
	void _rsp_exec_inplace(
		randomx_vm* machine,
		uint64_t* tempHash,
		int programCount,
		size_t scratchpadSize
	) {
		machine->resetRoundingMode();
		for (int chain = 0; chain < programCount-1; chain++) {
			machine->run(tempHash);
			int blakeResult = randomx_blake2b(
				tempHash, 64,
				machine->getRegisterFile(),
				sizeof(randomx::RegisterFile),
				nullptr, 0
			);
			assert(blakeResult == 0);
		}
		machine->run(tempHash);
		int blakeResult = randomx_blake2b(
			tempHash, 64,
			machine->getRegisterFile(),
			sizeof(randomx::RegisterFile),
			nullptr, 0
		);
		assert(blakeResult == 0);
		_rsp_mix_entropy_near(
			(const unsigned char*)machine->getScratchpad(),
			(unsigned char*)(void*)machine->getScratchpad(),
			scratchpadSize);
	}

	void _copy_chunk_cross_lane(
		randomx_vm** inSet,
		randomx_vm** outSet,
		size_t srcPos,
		size_t dstPos,
		size_t length,
		size_t scratchpadSize
	) {
		while (length > 0) {
			int srcLane = (int)(srcPos / scratchpadSize);
			size_t offsetInSrcLane = srcPos % scratchpadSize;

			int dstLane = (int)(dstPos / scratchpadSize);
			size_t offsetInDstLane = dstPos % scratchpadSize;

			size_t srcLaneRemain = scratchpadSize - offsetInSrcLane;
			size_t dstLaneRemain = scratchpadSize - offsetInDstLane;

			size_t chunkSize = length;
			if (chunkSize > srcLaneRemain) {
				chunkSize = srcLaneRemain;
			}
			if (chunkSize > dstLaneRemain) {
				chunkSize = dstLaneRemain;
			}

			unsigned char* srcSp = (unsigned char*)(void*) inSet[srcLane]->getScratchpad();
			unsigned char* dstSp = (unsigned char*)(void*) outSet[dstLane]->getScratchpad();
			memcpy(dstSp + offsetInDstLane, srcSp + offsetInSrcLane, chunkSize);

			srcPos += chunkSize;
			dstPos += chunkSize;
			length -= chunkSize;
		}
	}

	void _rsp_mix_entropy_far(
		randomx_vm** inSet,
		randomx_vm** outSet,
		int count,
		size_t scratchpadSize,
		size_t jumpSize,
		size_t blockSize)
	{
		size_t totalSize = (size_t)count * scratchpadSize;

		size_t entropySize = totalSize;
		size_t numJumps = entropySize / jumpSize;
		size_t numBlocksPerJump = jumpSize / blockSize;
		size_t leftover = jumpSize % blockSize;

		size_t outOffset = 0;
		for (size_t offset = 0; offset < numBlocksPerJump; ++offset) {
			for (size_t i = 0; i < numJumps; ++i) {
				size_t srcPos = i * jumpSize + offset * blockSize;
				_copy_chunk_cross_lane(inSet, outSet, srcPos, outOffset, blockSize, scratchpadSize);
				outOffset += blockSize;
			}
		}

		if (leftover > 0) {
			for (size_t i = 0; i < numJumps; ++i) {
				size_t srcPos = i * jumpSize + numBlocksPerJump * blockSize;
				_copy_chunk_cross_lane(inSet, outSet, srcPos, outOffset, leftover, scratchpadSize);
				outOffset += leftover;
			}
		}
	}

	int rsp_fused_entropy(
		randomx_vm** vmList,
		size_t scratchpadSize,
		int subChunkCount,
		int subChunkSize,
		int laneCount,
		int rxDepth,
		int randomxProgramCount,
		int blockSize,
		const unsigned char* keyData,
		size_t keySize,
		unsigned char* outEntropy
	) {
		struct vm_hash_t {
			alignas(16) uint64_t tempHash[8]; // 64 bytes
		};

		vm_hash_t* vmHashes = new (std::nothrow) vm_hash_t[laneCount];
		if (!vmHashes) {
			return 0;
		}

		// Initialize the scratchaps for each lane
		for (int i = 0; i < laneCount; i++) {
			// laneSeed = sha256(<<keyData, i>>)
			// laneSeed should be unique - i.e. now two lanes across all entropies and all
			// replicas should have the same seed. Current key (as off 2025-01-01) is
			// <<Partition, EntropyIndex, RewardAddr>> where entropy index is unique within
			// a given partition.
			unsigned char laneSeed[32];
			{
				SHA256_CTX sha256;
				SHA256_Init(&sha256);
				SHA256_Update(&sha256, keyData, keySize);
				unsigned char laneIndex = (unsigned char)i + 1;
				SHA256_Update(&sha256, &laneIndex, 1);
				SHA256_Final(laneSeed, &sha256);
			}
			int blakeResult = randomx_blake2b(
				vmHashes[i].tempHash, sizeof(vmHashes[i].tempHash),
				laneSeed, 32,
				nullptr, 0
			);
			if (blakeResult != 0) {
				delete[] vmHashes;
				return 0;
			}
			vmList[i]->initScratchpad(&vmHashes[i].tempHash);
		}

		for (int d = 0; d < rxDepth; d++) {
			for (int lane = 0; lane < laneCount; lane++) {
				_rsp_exec_inplace(
					vmList[lane],
					vmHashes[lane].tempHash,
					randomxProgramCount, scratchpadSize);
			}
			_rsp_mix_entropy_far(&vmList[0], &vmList[laneCount],
										 laneCount, scratchpadSize, scratchpadSize,
										 blockSize);

			if (d + 1 < rxDepth) {
				d++;
				for (int lane = 0; lane < laneCount; lane++) {
					_rsp_exec_inplace(
						vmList[lane+laneCount],
						vmHashes[lane].tempHash,
						randomxProgramCount, scratchpadSize);
				}
				_rsp_mix_entropy_far(&vmList[laneCount], &vmList[0],
											 laneCount, scratchpadSize, scratchpadSize,
											 blockSize);
			}
		}
		// NOTE still unoptimal. Last copy can be performed from scratchpad to output.
		// But requires +1 variation (set to buffer)

		if ((rxDepth % 2) == 0) {
			unsigned char* outEntropyPtr = outEntropy;
			for (int i = 0; i < laneCount; i++) {
				void* sp = (void*)vmList[i]->getScratchpad();
				memcpy(outEntropyPtr, sp, scratchpadSize);
				outEntropyPtr += scratchpadSize;
			}
		} else {
			unsigned char* outEntropyPtr = outEntropy;
			for (int i = laneCount; i < 2*laneCount; i++) {
				void* sp = (void*)vmList[i]->getScratchpad();
				memcpy(outEntropyPtr, sp, scratchpadSize);
				outEntropyPtr += scratchpadSize;
			}
		}

		delete[] vmHashes;

		return 1;
	}

	// TODO optimized packing_apply_to_subchunk (NIF only uses slice)
}


================================================
FILE: apps/arweave/c_src/randomx/randomx_squared.h
================================================
#ifndef RANDOMX_SQUARED_H
#define RANDOMX_SQUARED_H

#include "randomx.h"

#if defined(__cplusplus)
extern "C" {
#endif

RANDOMX_EXPORT int rsp_fused_entropy(
    randomx_vm** vmList,
    size_t scratchpadSize,
    int subChunkCount,
    int subChunkSize,
    int laneCount,
    int rxDepth,
    int randomxProgramCount,
    int blockSize,
    const unsigned char* keyData,
    size_t keySize,
    unsigned char* outEntropy  // We'll pass in a pointer for final scratchpad data
);

// TODO optimized packing_apply_to_subchunk (NIF only uses slice)

#if defined(__cplusplus)
}
#endif

#endif // RANDOMX_SQUARED_H


================================================
FILE: apps/arweave/c_src/randomx/rx4096/ar_rx4096_nif.c
================================================
#include <string.h>
#include <openssl/sha.h>
#include <ar_nif.h>
#include "../randomx_long_with_entropy.h"
#include "../feistel_msgsize_key_cipher.h"

#include "../ar_randomx_impl.h"

const int PACKING_KEY_SIZE = 32;
const int MAX_CHUNK_SIZE = 256*1024;

static int rx4096_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info);
static ERL_NIF_TERM rx4096_info_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rx4096_init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rx4096_hash_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rx4096_encrypt_composite_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
);
static ERL_NIF_TERM rx4096_decrypt_composite_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
);
static ERL_NIF_TERM rx4096_decrypt_composite_sub_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
);
static ERL_NIF_TERM rx4096_reencrypt_composite_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
);

static int rx4096_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info)
{
	return load(envPtr, priv, info);
}

static ERL_NIF_TERM rx4096_info_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	return info_nif("rx4096", envPtr, argc, argv);
}

static ERL_NIF_TERM rx4096_init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	return init_nif(envPtr, argc, argv);
}

static ERL_NIF_TERM rx4096_hash_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	return hash_nif(envPtr, argc, argv);
}

static ERL_NIF_TERM encrypt_composite_chunk(ErlNifEnv* envPtr,
		randomx_vm *vmPtr, ErlNifBinary *inputDataPtr, ErlNifBinary *inputChunkPtr,
		const int subChunkCount, const int iterations,
		const int randomxRoundCount, const int jitEnabled,
		const int largePagesEnabled, const int hardwareAESEnabled) {

	unsigned char *paddedChunk = (unsigned char*)malloc(MAX_CHUNK_SIZE);
	if (inputChunkPtr->size == MAX_CHUNK_SIZE) {
		memcpy(paddedChunk, inputChunkPtr->data, inputChunkPtr->size);
	} else {
		memset(paddedChunk, 0, MAX_CHUNK_SIZE);
		memcpy(paddedChunk, inputChunkPtr->data, inputChunkPtr->size);
	}

	ERL_NIF_TERM encryptedChunkTerm;
	unsigned char* encryptedChunk = enif_make_new_binary(envPtr, MAX_CHUNK_SIZE,
			&encryptedChunkTerm);
	// MAX_CHUNK_SIZE / subChunkCount is a multiple of 64 so all sub-chunks
	// are of the same size.
	uint32_t subChunkSize = MAX_CHUNK_SIZE / subChunkCount;
	uint32_t offset = 0;
	unsigned char key[PACKING_KEY_SIZE];
	// Encrypt each sub-chunk independently and then concatenate the encrypted sub-chunks
	// to yield encrypted composite chunk.
	for (int i = 0; i < subChunkCount; i++) {
		unsigned char* subChunk = paddedChunk + offset;
		unsigned char* encryptedSubChunk = (unsigned char*)malloc(subChunkSize);

		// 3 bytes is sufficient to represent offsets up to at most MAX_CHUNK_SIZE.
		int offsetByteSize = 3;
		unsigned char offsetBytes[offsetByteSize];
		// Byte string representation of the sub-chunk start offset: i * subChunkSize.
		for (int k = 0; k < offsetByteSize; k++) {
			offsetBytes[k] = ((offset + subChunkSize) >> (8 * (offsetByteSize - 1 - k))) & 0xFF;
		}
		// Sub-chunk encryption key is the SHA256 hash of the concatenated
		// input data and the sub-chunk start offset.
		SHA256_CTX sha256;
		SHA256_Init(&sha256);
		SHA256_Update(&sha256, inputDataPtr->data, inputDataPtr->size);
		SHA256_Update(&sha256, offsetBytes, offsetByteSize);
		SHA256_Final(key, &sha256);

		// Sequentially encrypt each sub-chunk 'iterations' times.
		for (int j = 0; j < iterations; j++) {
			randomx_encrypt_chunk(
				vmPtr, key, PACKING_KEY_SIZE, subChunk, subChunkSize,
				encryptedSubChunk, randomxRoundCount);
			if (j < iterations - 1) {
				memcpy(subChunk, encryptedSubChunk, subChunkSize);
			}
		}
		memcpy(encryptedChunk + offset, encryptedSubChunk, subChunkSize);
		free(encryptedSubChunk);
		offset += subChunkSize;
	}
	free(paddedChunk);
	return encryptedChunkTerm;
}

static ERL_NIF_TERM decrypt_composite_chunk(ErlNifEnv* envPtr,
		randomx_vm *vmPtr, ErlNifBinary *inputDataPtr, ErlNifBinary *inputChunkPtr,
		const int outChunkLen, const int subChunkCount, const int iterations,
		const int randomxRoundCount, const int jitEnabled,
		const int largePagesEnabled, const int hardwareAESEnabled) {

	unsigned char *chunk = (unsigned char*)malloc(MAX_CHUNK_SIZE);
	memcpy(chunk, inputChunkPtr->data, inputChunkPtr->size);

	ERL_NIF_TERM decryptedChunkTerm;
	unsigned char* decryptedChunk = enif_make_new_binary(envPtr, outChunkLen,
			&decryptedChunkTerm);
	unsigned char* decryptedSubChunk;
	// outChunkLen / subChunkCount is a multiple of 64 so all sub-chunks
	// are of the same size.
	uint32_t subChunkSize = outChunkLen / subChunkCount;
	uint32_t offset = 0;
	unsigned char key[PACKING_KEY_SIZE];
	// Decrypt each sub-chunk independently and then concatenate the decrypted sub-chunks
	// to yield encrypted composite chunk.
	for (int i = 0; i < subChunkCount; i++) {
		unsigned char* subChunk = chunk + offset;
		decryptedSubChunk = (unsigned char*)malloc(subChunkSize);

		// 3 bytes is sufficient to represent offsets up to at most MAX_CHUNK_SIZE.
		int offsetByteSize = 3;
		unsigned char offsetBytes[offsetByteSize];
		// Byte string representation of the sub-chunk start offset: i * subChunkSize.
		for (int k = 0; k < offsetByteSize; k++) {
			offsetBytes[k] = ((offset + subChunkSize) >> (8 * (offsetByteSize - 1 - k))) & 0xFF;
		}
		// Sub-chunk encryption key is the SHA256 hash of the concatenated
		// input data and the sub-chunk start offset.
		SHA256_CTX sha256;
		SHA256_Init(&sha256);
		SHA256_Update(&sha256, inputDataPtr->data, inputDataPtr->size);
		SHA256_Update(&sha256, offsetBytes, offsetByteSize);
		SHA256_Final(key, &sha256);

		// Sequentially decrypt each sub-chunk 'iterations' times.
		for (int j = 0; j < iterations; j++) {
			randomx_decrypt_chunk(
				vmPtr, key, PACKING_KEY_SIZE, subChunk, subChunkSize,
				decryptedSubChunk, randomxRoundCount);
			if (j < iterations - 1) {
				memcpy(subChunk, decryptedSubChunk, subChunkSize);
			}
		}
		memcpy(decryptedChunk + offset, decryptedSubChunk, subChunkSize);
		free(decryptedSubChunk);
		offset += subChunkSize;
	}
	free(chunk);
	return decryptedChunkTerm;
}

static ERL_NIF_TERM rx4096_encrypt_composite_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	// RandomX rounds per sub-chunk.
	int randomxRoundCount;
	// RandomX iterations (randomxRoundCount each) per sub-chunk.
	int iterations;
	// The number of sub-chunks in the chunk.
	int subChunkCount;
	int jitEnabled, largePagesEnabled, hardwareAESEnabled;
	struct state* statePtr;
	ErlNifBinary inputData;
	ErlNifBinary inputChunk;

	if (argc != 9) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}
	if (!enif_inspect_binary(envPtr, argv[1], &inputData)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[2], &inputChunk) ||
		inputChunk.size == 0 ||
		inputChunk.size > MAX_CHUNK_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[5], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[6], &randomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[7], &iterations) ||
		iterations < 1) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[8], &subChunkCount) ||
		subChunkCount < 1 ||
		MAX_CHUNK_SIZE % subChunkCount != 0 ||
		(MAX_CHUNK_SIZE / subChunkCount) % 64 != 0 ||
		subChunkCount > (MAX_CHUNK_SIZE / 64)) {
		return enif_make_badarg(envPtr);
	}

	int isRandomxReleased;
	randomx_vm *vmPtr = create_vm(statePtr, (statePtr->mode == HASHING_MODE_FAST),
			jitEnabled, largePagesEnabled, hardwareAESEnabled, &isRandomxReleased);
	if (vmPtr == NULL) {
		if (isRandomxReleased != 0) {
			return error_tuple(envPtr, "state has been released");
		}
		return error_tuple(envPtr, "randomx_create_vm failed");
	}

	ERL_NIF_TERM encryptedChunkTerm = encrypt_composite_chunk(envPtr, vmPtr, &inputData,
			&inputChunk, subChunkCount, iterations, randomxRoundCount,
			jitEnabled, largePagesEnabled, hardwareAESEnabled);
	destroy_vm(statePtr, vmPtr);
	return ok_tuple(envPtr, encryptedChunkTerm);
}

static ERL_NIF_TERM rx4096_decrypt_composite_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	int outChunkLen;
	// RandomX rounds per sub-chunk.
	int randomxRoundCount;
	// RandomX iterations (randomxRoundCount each) per sub-chunk.
	int iterations;
	// The number of sub-chunks in the chunk.
	int subChunkCount;
	int jitEnabled, largePagesEnabled, hardwareAESEnabled;
	struct state* statePtr;
	ErlNifBinary inputData;
	ErlNifBinary inputChunk;

	if (argc != 10) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}
	if (!enif_inspect_binary(envPtr, argv[1], &inputData)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[2], &inputChunk) ||
		inputChunk.size == 0 ||
		inputChunk.size > MAX_CHUNK_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &outChunkLen) ||
		outChunkLen > MAX_CHUNK_SIZE ||
		outChunkLen < 64 ||
		inputChunk.size != outChunkLen) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[5], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[6], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[7], &randomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[8], &iterations) ||
		iterations < 1) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[9], &subChunkCount) ||
		subChunkCount < 1 ||
		outChunkLen % subChunkCount != 0 ||
		(outChunkLen / subChunkCount) % 64 != 0 ||
		subChunkCount > (outChunkLen / 64)) {
		return enif_make_badarg(envPtr);
	}

	int isRandomxReleased;
	randomx_vm *vmPtr = create_vm(statePtr, (statePtr->mode == HASHING_MODE_FAST),
			jitEnabled, largePagesEnabled, hardwareAESEnabled, &isRandomxReleased);
	if (vmPtr == NULL) {
		if (isRandomxReleased != 0) {
			return error_tuple(envPtr, "state has been released");
		}
		return error_tuple(envPtr, "randomx_create_vm failed");
	}
	ERL_NIF_TERM decryptedChunkTerm = decrypt_composite_chunk(envPtr, vmPtr,
			&inputData, &inputChunk, outChunkLen, subChunkCount, iterations,
			randomxRoundCount, jitEnabled, largePagesEnabled, hardwareAESEnabled);

	destroy_vm(statePtr, vmPtr);

	return ok_tuple(envPtr, decryptedChunkTerm);
}

static ERL_NIF_TERM rx4096_decrypt_composite_sub_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	int outChunkLen;
	// RandomX rounds per sub-chunk.
	int randomxRoundCount;
	// RandomX iterations (randomxRoundCount each) per sub-chunk.
	int iterations;
	// The relative sub-chunk start offset. We add the chunk size to it, encode the result,
	// add it to the base packing key, and SHA256-hash it to get the packing key.
	uint32_t offset;
	int jitEnabled, largePagesEnabled, hardwareAESEnabled;
	struct state* statePtr;
	ErlNifBinary inputData;
	ErlNifBinary inputChunk;

	if (argc != 10) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}
	if (!enif_inspect_binary(envPtr, argv[1], &inputData)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[2], &inputChunk)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &outChunkLen) ||
		outChunkLen > MAX_CHUNK_SIZE ||
		outChunkLen < 64 ||
		inputChunk.size != outChunkLen ) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[5], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[6], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[7], &randomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[8], &iterations) ||
		iterations < 1) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_uint(envPtr, argv[9], &offset) ||
		offset < 0 ||
		offset > MAX_CHUNK_SIZE) {
		return enif_make_badarg(envPtr);
	}

	int isRandomxReleased;
	ERL_NIF_TERM decryptedSubChunkTerm;
	unsigned char* decryptedSubChunk = enif_make_new_binary(envPtr, outChunkLen,
			&decryptedSubChunkTerm);
	uint32_t subChunkSize = outChunkLen;
	unsigned char key[PACKING_KEY_SIZE];

	randomx_vm *vmPtr = create_vm(statePtr, (statePtr->mode == HASHING_MODE_FAST),
			jitEnabled, largePagesEnabled, hardwareAESEnabled, &isRandomxReleased);
	if (vmPtr == NULL) {
		if (isRandomxReleased != 0) {
			return error_tuple(envPtr, "state has been released");
		}
		return error_tuple(envPtr, "randomx_create_vm failed");
	}

	unsigned char* subChunk = (unsigned char*)malloc(inputChunk.size);
	memcpy(subChunk, inputChunk.data, inputChunk.size);

	// 3 bytes is sufficient to represent offsets up to at most MAX_CHUNK_SIZE.
	int offsetByteSize = 3;
	unsigned char offsetBytes[offsetByteSize];
	for (int k = 0; k < offsetByteSize; k++) {
		offsetBytes[k] = ((offset + subChunkSize) >> (8 * (offsetByteSize - 1 - k))) & 0xFF;
	}
	// Sub-chunk encryption key is the SHA256 hash of the concatenated
	// input data and the sub-chunk start offset.
	SHA256_CTX sha256;
	SHA256_Init(&sha256);
	SHA256_Update(&sha256, inputData.data, inputData.size);
	SHA256_Update(&sha256, offsetBytes, offsetByteSize);
	SHA256_Final(key, &sha256);

	// Sequentially decrypt each sub-chunk 'iterations' times.
	for (int j = 0; j < iterations; j++) {
		randomx_decrypt_chunk(vmPtr, key, PACKING_KEY_SIZE, subChunk, subChunkSize,
			decryptedSubChunk, randomxRoundCount);
		if (j < iterations - 1) {
			memcpy(subChunk, decryptedSubChunk, subChunkSize);
		}
	}
	free(subChunk);
	destroy_vm(statePtr, vmPtr);

	return ok_tuple(envPtr, decryptedSubChunkTerm);
}

static ERL_NIF_TERM rx4096_reencrypt_composite_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	int decryptRandomxRoundCount, encryptRandomxRoundCount;
	int jitEnabled, largePagesEnabled, hardwareAESEnabled;
	int decryptSubChunkCount, encryptSubChunkCount, decryptIterations, encryptIterations;
	struct state* statePtr;
	ErlNifBinary decryptKey;
	ErlNifBinary encryptKey;
	ErlNifBinary inputChunk;
	ERL_NIF_TERM inputChunkTerm;

	if (argc != 13) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}
	if (!enif_inspect_binary(envPtr, argv[1], &decryptKey)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[2], &encryptKey)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[3], &inputChunk) ||
			inputChunk.size != MAX_CHUNK_SIZE) {
		return enif_make_badarg(envPtr);
	}
	inputChunkTerm = argv[3];
	if (!enif_get_int(envPtr, argv[4], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[5], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[6], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[7], &decryptRandomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[8], &encryptRandomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[9], &decryptIterations) ||
		decryptIterations < 1) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[10], &encryptIterations) ||
		encryptIterations < 1) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[11], &decryptSubChunkCount) ||
		decryptSubChunkCount < 1 ||
		MAX_CHUNK_SIZE % decryptSubChunkCount != 0 ||
		(MAX_CHUNK_SIZE / decryptSubChunkCount) % 64 != 0 ||
		decryptSubChunkCount > (MAX_CHUNK_SIZE / 64)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[12], &encryptSubChunkCount) ||
		encryptSubChunkCount < 1 ||
		MAX_CHUNK_SIZE % encryptSubChunkCount != 0 ||
		(MAX_CHUNK_SIZE / encryptSubChunkCount) % 64 != 0 ||
		encryptSubChunkCount > (MAX_CHUNK_SIZE / 64)) {
		return enif_make_badarg(envPtr);
	}

	int isRandomxReleased;
	randomx_vm *vmPtr = create_vm(statePtr, (statePtr->mode == HASHING_MODE_FAST),
			jitEnabled, largePagesEnabled, hardwareAESEnabled, &isRandomxReleased);
	if (vmPtr == NULL) {
		if (isRandomxReleased != 0) {
			return error_tuple(envPtr, "state has been released");
		}
		return error_tuple(envPtr, "randomx_create_vm failed");
	}

	int keysMatch = 0;
	if (decryptKey.size == encryptKey.size) {
		if (memcmp(decryptKey.data, encryptKey.data, decryptKey.size) == 0) {
			keysMatch = 1;
		}
	}
	int encryptionsMatch = 0;
	if (keysMatch && (decryptSubChunkCount == encryptSubChunkCount) &&
			(decryptRandomxRoundCount == encryptRandomxRoundCount)) {
		encryptionsMatch = 1;
	}

	if (encryptionsMatch && (encryptIterations <= decryptIterations)) {
		destroy_vm(statePtr, vmPtr);
		return enif_make_badarg(envPtr);
	}

	unsigned char decryptedChunk[MAX_CHUNK_SIZE];
	ErlNifBinary *decryptedChunkBinPtr;
	ERL_NIF_TERM decryptedChunkTerm;
	if (!encryptionsMatch) {
		decryptedChunkTerm = decrypt_composite_chunk(envPtr, vmPtr,
				&decryptKey, &inputChunk, inputChunk.size, decryptSubChunkCount,
				decryptIterations, decryptRandomxRoundCount, jitEnabled,
				largePagesEnabled, hardwareAESEnabled);
		ErlNifBinary decryptedChunkBin;
		if (!enif_inspect_binary(envPtr, decryptedChunkTerm, &decryptedChunkBin)) {
			destroy_vm(statePtr, vmPtr);
			return enif_make_badarg(envPtr);
		}
		decryptedChunkBinPtr = &decryptedChunkBin;
	} else {
		decryptedChunkBinPtr = &inputChunk;
		decryptedChunkTerm = inputChunkTerm;
	}
	int iterations = encryptIterations;
	if (encryptionsMatch) {
		iterations = encryptIterations - decryptIterations;
	}

	ERL_NIF_TERM reencryptedChunkTerm = encrypt_composite_chunk(envPtr, vmPtr, &encryptKey,
			decryptedChunkBinPtr, encryptSubChunkCount, iterations, encryptRandomxRoundCount,
			jitEnabled, largePagesEnabled, hardwareAESEnabled);
	destroy_vm(statePtr, vmPtr);
	return ok_tuple2(envPtr, reencryptedChunkTerm, decryptedChunkTerm);
}

static ErlNifFunc rx4096_funcs[] = {
	{"rx4096_info_nif", 1, rx4096_info_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx4096_init_nif", 5, rx4096_init_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx4096_hash_nif", 5, rx4096_hash_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx4096_encrypt_composite_chunk_nif", 9, rx4096_encrypt_composite_chunk_nif,
		ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx4096_decrypt_composite_chunk_nif", 10, rx4096_decrypt_composite_chunk_nif,
		ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx4096_decrypt_composite_sub_chunk_nif", 10, rx4096_decrypt_composite_sub_chunk_nif,
		ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx4096_reencrypt_composite_chunk_nif", 13,
		rx4096_reencrypt_composite_chunk_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND}
};

ERL_NIF_INIT(ar_rx4096_nif, rx4096_funcs, rx4096_load, NULL, NULL, NULL);


================================================
FILE: apps/arweave/c_src/randomx/rx512/ar_rx512_nif.c
================================================
#include <string.h>
#include <openssl/sha.h>
#include <ar_nif.h>
#include "../randomx_long_with_entropy.h"
#include "../feistel_msgsize_key_cipher.h"

#include "../ar_randomx_impl.h"

const int MAX_CHUNK_SIZE = 256*1024;

static int rx512_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info);
static ERL_NIF_TERM rx512_info_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rx512_init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rx512_hash_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rx512_encrypt_chunk_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rx512_decrypt_chunk_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rx512_reencrypt_chunk_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);

static int rx512_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info)
{
	return load(envPtr, priv, info);
}

static ERL_NIF_TERM rx512_info_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	return info_nif("rx512", envPtr, argc, argv);
}

static ERL_NIF_TERM rx512_init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	return init_nif(envPtr, argc, argv);
}

static ERL_NIF_TERM rx512_hash_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	return hash_nif(envPtr, argc, argv);
}

static ERL_NIF_TERM decrypt_chunk(ErlNifEnv* envPtr,
		randomx_vm *machine, const unsigned char *input, const size_t inputSize,
		const unsigned char *inChunk, const size_t inChunkSize,
		unsigned char* outChunk, const size_t outChunkSize,
		const int randomxProgramCount) {
	randomx_decrypt_chunk(
		machine, input, inputSize, inChunk, inChunkSize, outChunk, randomxProgramCount);
	return make_output_binary(envPtr, outChunk, outChunkSize);
}

static ERL_NIF_TERM encrypt_chunk(ErlNifEnv* envPtr,
		randomx_vm *machine, const unsigned char *input, const size_t inputSize,
		const unsigned char *inChunk, const size_t inChunkSize,
		const int randomxProgramCount) {
	ERL_NIF_TERM encryptedChunkTerm;
	unsigned char* encryptedChunk = enif_make_new_binary(
										envPtr, MAX_CHUNK_SIZE, &encryptedChunkTerm);

	if (inChunkSize < MAX_CHUNK_SIZE) {
		unsigned char *paddedInChunk = (unsigned char*)malloc(MAX_CHUNK_SIZE);
		memset(paddedInChunk, 0, MAX_CHUNK_SIZE);
		memcpy(paddedInChunk, inChunk, inChunkSize);
		randomx_encrypt_chunk(
			machine, input, inputSize, paddedInChunk, MAX_CHUNK_SIZE,
			encryptedChunk, randomxProgramCount);
		free(paddedInChunk);
	} else {
		randomx_encrypt_chunk(
			machine, input, inputSize, inChunk, inChunkSize,
			encryptedChunk, randomxProgramCount);
	}

	return encryptedChunkTerm;
}

static ERL_NIF_TERM rx512_encrypt_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	int randomxRoundCount, jitEnabled, largePagesEnabled, hardwareAESEnabled;
	struct state* statePtr;
	ErlNifBinary inputData;
	ErlNifBinary inputChunk;

	if (argc != 7) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}
	if (!enif_inspect_binary(envPtr, argv[1], &inputData)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[2], &inputChunk) ||
		inputChunk.size == 0 ||
		inputChunk.size > MAX_CHUNK_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &randomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[5], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[6], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}

	int isRandomxReleased;
	randomx_vm *vmPtr = create_vm(statePtr, (statePtr->mode == HASHING_MODE_FAST),
		jitEnabled, largePagesEnabled, hardwareAESEnabled, &isRandomxReleased);
	if (vmPtr == NULL) {
		if (isRandomxReleased != 0) {
			return error_tuple(envPtr, "state has been released");
		}
		return error_tuple(envPtr, "randomx_create_vm failed");
	}

	ERL_NIF_TERM outChunkTerm = encrypt_chunk(envPtr, vmPtr,
		inputData.data, inputData.size, inputChunk.data, inputChunk.size, randomxRoundCount);

	destroy_vm(statePtr, vmPtr);
	return ok_tuple(envPtr, outChunkTerm);
}

static ERL_NIF_TERM rx512_decrypt_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	int outChunkLen, randomxRoundCount, jitEnabled, largePagesEnabled, hardwareAESEnabled;
	struct state* statePtr;
	ErlNifBinary inputData;
	ErlNifBinary inputChunk;

	if (argc != 8) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}
	if (!enif_inspect_binary(envPtr, argv[1], &inputData)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[2], &inputChunk) ||
		inputChunk.size == 0 ||
		inputChunk.size > MAX_CHUNK_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &outChunkLen)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &randomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[5], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[6], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[7], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}

	int isRandomxReleased;
	randomx_vm *vmPtr = create_vm(statePtr, (statePtr->mode == HASHING_MODE_FAST),
		jitEnabled, largePagesEnabled, hardwareAESEnabled, &isRandomxReleased);
	if (vmPtr == NULL) {
		if (isRandomxReleased != 0) {
			return error_tuple(envPtr, "state has been released");
		}
		return error_tuple(envPtr, "randomx_create_vm failed");
	}

	// NOTE. Because randomx_decrypt_chunk will unpack padding too, decrypt always uses the
	// full 256KB chunk size. We'll then truncate the output to the correct feistel-padded
	// outChunkSize.
	unsigned char outChunk[MAX_CHUNK_SIZE];
	ERL_NIF_TERM decryptedChunkTerm = decrypt_chunk(envPtr, vmPtr,
		inputData.data, inputData.size, inputChunk.data, inputChunk.size,
		outChunk, outChunkLen, randomxRoundCount);

	destroy_vm(statePtr, vmPtr);

	return ok_tuple(envPtr, decryptedChunkTerm);
}

static ERL_NIF_TERM rx512_reencrypt_chunk_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	int chunkSize, decryptRandomxRoundCount, encryptRandomxRoundCount;
	int jitEnabled, largePagesEnabled, hardwareAESEnabled;
	struct state* statePtr;
	ErlNifBinary decryptKey;
	ErlNifBinary encryptKey;
	ErlNifBinary inputChunk;

	if (argc != 10) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**) &statePtr)) {
		return error_tuple(envPtr, "failed to read state");
	}
	if (!enif_inspect_binary(envPtr, argv[1], &decryptKey)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[2], &encryptKey)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[3], &inputChunk) || inputChunk.size == 0) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &chunkSize)  ||
		chunkSize == 0 ||
		chunkSize > MAX_CHUNK_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[5], &decryptRandomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[6], &encryptRandomxRoundCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[7], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[8], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[9], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}

	int isRandomxReleased;
	randomx_vm *vmPtr = create_vm(statePtr, (statePtr->mode == HASHING_MODE_FAST),
		jitEnabled, largePagesEnabled, hardwareAESEnabled, &isRandomxReleased);
	if (vmPtr == NULL) {
		if (isRandomxReleased != 0) {
			return error_tuple(envPtr, "state has been released");
		}
		return error_tuple(envPtr, "randomx_create_vm failed");
	}

	// NOTE. Because randomx_decrypt_chunk will unpack padding too, decrypt always uses the
	// full 256KB chunk size. We'll then truncate the output to the correct feistel-padded
	// outChunkSize.
	unsigned char decryptedChunk[MAX_CHUNK_SIZE];
	ERL_NIF_TERM decryptedChunkTerm = decrypt_chunk(envPtr, vmPtr,
		decryptKey.data, decryptKey.size, inputChunk.data, inputChunk.size,
		decryptedChunk, chunkSize, decryptRandomxRoundCount);

	ERL_NIF_TERM reencryptedChunkTerm = encrypt_chunk(envPtr, vmPtr,
		encryptKey.data, encryptKey.size, decryptedChunk, chunkSize, encryptRandomxRoundCount);

	destroy_vm(statePtr, vmPtr);

	return ok_tuple2(envPtr, reencryptedChunkTerm, decryptedChunkTerm);
}

static ErlNifFunc rx512_funcs[] = {
	{"rx512_info_nif", 1, rx512_info_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx512_init_nif", 5, rx512_init_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx512_hash_nif", 5, rx512_hash_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx512_encrypt_chunk_nif", 7, rx512_encrypt_chunk_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx512_decrypt_chunk_nif", 8, rx512_decrypt_chunk_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rx512_reencrypt_chunk_nif", 10, rx512_reencrypt_chunk_nif,
		ERL_NIF_DIRTY_JOB_CPU_BOUND}
};


ERL_NIF_INIT(ar_rx512_nif, rx512_funcs, rx512_load, NULL, NULL, NULL);



================================================
FILE: apps/arweave/c_src/randomx/rxsquared/ar_rxsquared_nif.c
================================================
#include <string.h>
#include <openssl/sha.h>
#include <ar_nif.h>
#include "../randomx_long_with_entropy.h"
#include "../feistel_msgsize_key_cipher.h"
#include "../randomx_squared.h"

#include "../ar_randomx_impl.h"

const int PACKING_KEY_SIZE = 32;
const int MAX_CHUNK_SIZE = 256*1024;

static int rxsquared_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info);
static ERL_NIF_TERM rxsquared_info_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rxsquared_init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rxsquared_hash_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]);

static int rxsquared_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info) {
	return load(envPtr, priv, info);
}

static ERL_NIF_TERM rxsquared_info_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]) {
	return info_nif("rxsquared", envPtr, argc, argv);
}

static ERL_NIF_TERM rxsquared_init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]) {
	return init_nif(envPtr, argc, argv);
}

static ERL_NIF_TERM rxsquared_hash_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]) {
	return hash_nif(envPtr, argc, argv);
}


static ERL_NIF_TERM rsp_feistel_encrypt_nif(
		ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]) {
	ErlNifBinary inMsgBin;
	ErlNifBinary inKeyBin;
	ERL_NIF_TERM outMsgTerm;
	unsigned char* outMsgData;

	if (argc != 2) {
		return enif_make_badarg(envPtr);
	}

	if (!enif_inspect_binary(envPtr, argv[0], &inMsgBin)) {
		return enif_make_badarg(envPtr);
	}

	if (!enif_inspect_binary(envPtr, argv[1], &inKeyBin)) {
		return enif_make_badarg(envPtr);
	}

	size_t msgSize = inMsgBin.size;

	if (inKeyBin.size != msgSize) {
		return enif_make_badarg(envPtr);
	}

	if (msgSize % 64 != 0) {
		return enif_make_badarg(envPtr);
	}

	outMsgData = enif_make_new_binary(envPtr, msgSize, &outMsgTerm);
	if (outMsgData == NULL) {
		return enif_make_badarg(envPtr);
	}

	feistel_encrypt(inMsgBin.data, msgSize, inKeyBin.data, outMsgData);

	return ok_tuple(envPtr, outMsgTerm);
}

static ERL_NIF_TERM rsp_feistel_decrypt_nif(
		ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]) {
	ErlNifBinary inMsgBin;
	ErlNifBinary inKeyBin;
	ERL_NIF_TERM outMsgTerm;
	unsigned char* outMsgData;

	if (argc != 2) {
		return enif_make_badarg(envPtr);
	}

	if (!enif_inspect_binary(envPtr, argv[0], &inMsgBin)) {
		return enif_make_badarg(envPtr);
	}

	if (!enif_inspect_binary(envPtr, argv[1], &inKeyBin)) {
		return enif_make_badarg(envPtr);
	}

	size_t msgSize = inMsgBin.size;

	if (inKeyBin.size != msgSize) {
		return enif_make_badarg(envPtr);
	}

	if (msgSize % 64 != 0) {
		return enif_make_badarg(envPtr);
	}

	outMsgData = enif_make_new_binary(envPtr, msgSize, &outMsgTerm);
	if (outMsgData == NULL) {
		return enif_make_badarg(envPtr);
	}

	feistel_decrypt(inMsgBin.data, msgSize, inKeyBin.data, outMsgData);

	return ok_tuple(envPtr, outMsgTerm);
}

static ERL_NIF_TERM rsp_fused_entropy_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[]) {
	if (argc != 10) {
		return enif_make_badarg(envPtr);
	}

	// 1. Parse the state resource
	struct state* statePtr;
	if (!enif_get_resource(envPtr, argv[0], stateType, (void**)&statePtr)) {
		return error_tuple(envPtr, "failed_to_read_state");
	}

	// 2. Parse each integer
	int subChunkCount;
	if (!enif_get_int(envPtr, argv[1], &subChunkCount)) {
		return enif_make_badarg(envPtr);
	}

	int subChunkSize;
	if (!enif_get_int(envPtr, argv[2], &subChunkSize)) {
		return enif_make_badarg(envPtr);
	}

	int laneCount;
	if (!enif_get_int(envPtr, argv[3], &laneCount)) {
		return enif_make_badarg(envPtr);
	}

	int rxDepth;
	if (!enif_get_int(envPtr, argv[4], &rxDepth)) {
		return enif_make_badarg(envPtr);
	}

	int jitEnabled;
	if (!enif_get_int(envPtr, argv[5], &jitEnabled)) {
		return enif_make_badarg(envPtr);
	}

	int largePagesEnabled;
	if (!enif_get_int(envPtr, argv[6], &largePagesEnabled)) {
		return enif_make_badarg(envPtr);
	}

	int hardwareAESEnabled;
	if (!enif_get_int(envPtr, argv[7], &hardwareAESEnabled)) {
		return enif_make_badarg(envPtr);
	}

	int randomxProgramCount;
	if (!enif_get_int(envPtr, argv[8], &randomxProgramCount)) {
		return enif_make_badarg(envPtr);
	}

	// 3. Parse key as a binary
	ErlNifBinary keyBin;
	if (!enif_inspect_binary(envPtr, argv[9], &keyBin)) {
		return enif_make_badarg(envPtr);
	}

	// 4. Create VMs
	int totalVMs = 2 * laneCount;
	randomx_vm** vmList = (randomx_vm**)calloc(totalVMs, sizeof(randomx_vm*));
	if (!vmList) {
		return error_tuple(envPtr, "vmList_alloc_failed");
	}

	size_t scratchpadSize = randomx_get_scratchpad_size();

	// 5. Pre-allocate the final output binary to store all scratchpads
	size_t outEntropySize = scratchpadSize * laneCount;
	ERL_NIF_TERM outEntropyTerm;
	unsigned char* outEntropy =
		enif_make_new_binary(envPtr, outEntropySize, &outEntropyTerm);
	if (!outEntropy) {
		free(vmList);
		return enif_make_badarg(envPtr);
	}

	// 6. Create the randomx_vm objects
	int isRandomxReleased = 0;
	for (int i = 0; i < totalVMs; i++) {
		vmList[i] = create_vm(
			statePtr,
			(statePtr->mode == HASHING_MODE_FAST),
			jitEnabled,
			largePagesEnabled,
			hardwareAESEnabled,
			&isRandomxReleased
		);
		if (!vmList[i]) {
			// Clean up partial
			for (int j = 0; j < i; j++) {
				destroy_vm(statePtr, vmList[j]);
			}
			free(vmList);
			if (isRandomxReleased != 0) {
				return error_tuple(envPtr, "state_has_been_released");
			}
			return error_tuple(envPtr, "randomx_create_vm_failed");
		}
	}

	// 7. Call the pure C++ function that does the heavy logic and returns bool
	int success = rsp_fused_entropy(
		vmList,
		scratchpadSize,
		subChunkCount,
		subChunkSize,
		laneCount,
		rxDepth,
		randomxProgramCount,
		6,
		keyBin.data,
		keyBin.size,
		outEntropy  // final buffer for the output entropy
	);

	// 8. If the function returned false, we interpret that as an error
	if (!success) {
		// Cleanup
		for (int i = 0; i < totalVMs; i++) {
			if (vmList[i]) {
				destroy_vm(statePtr, vmList[i]);
			}
		}
		free(vmList);
		return error_tuple(envPtr, "cxx_fused_entropy_failed");
	}

	// 9. If success, destroy VMs and return {ok, outEntropyTerm}
	for (int i = 0; i < totalVMs; i++) {
		destroy_vm(statePtr, vmList[i]);
	}
	free(vmList);

	return ok_tuple(envPtr, outEntropyTerm);
}


static ErlNifFunc rxsquared_funcs[] = {
	{"rxsquared_info_nif", 1, rxsquared_info_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rxsquared_init_nif", 5, rxsquared_init_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rxsquared_hash_nif", 5, rxsquared_hash_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},

	{"rsp_fused_entropy_nif", 10,
		rsp_fused_entropy_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rsp_feistel_encrypt_nif", 2, rsp_feistel_encrypt_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"rsp_feistel_decrypt_nif", 2, rsp_feistel_decrypt_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND}
};

ERL_NIF_INIT(ar_rxsquared_nif, rxsquared_funcs, rxsquared_load, NULL, NULL, NULL);

================================================
FILE: apps/arweave/c_src/secp256k1/secp256k1_nif.c
================================================
#define _GNU_SOURCE
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/random.h>

#include <secp256k1.h>
#include <secp256k1_recovery.h>

#include <ar_nif.h>

#define SECP256K1_PUBKEY_UNCOMPRESSED_SIZE 65
#define SECP256K1_PUBKEY_COMPRESSED_SIZE 33
#define SECP256K1_SIGNATURE_COMPACT_SIZE 64
#define SECP256K1_SIGNATURE_RECOVERABLE_SIZE 65
#define SECP256K1_PRIVKEY_SIZE 32
#define SECP256K1_CONTEXT_SEED_SIZE 32
#define SECP256K1_DIGEST_SIZE 32

static int secp256k1_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info) {
	return 0;
}

static int fill_devurandom(void* buffer, size_t size) {
	int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
	if (fd == -1) {
		return 0;
	}

	size_t offset = 0;
	while (offset < size) {
		ssize_t result = read(fd, (char*)buffer + offset, size - offset);
		if (result == -1) {
			if (errno == EINTR) continue;
			goto error;
		}
		// EOF
		if (result == 0) {
			goto error;
		}
		offset += (size_t)result;
	}

	close(fd);
	return 1;

error:
	close(fd);
	return 0;
}

static int fill_random(void* buffer, size_t size) {
#if defined(__linux__) || defined(__FreeBSD__)

	size_t offset = 0;
	while (offset < size) {
		ssize_t result = getrandom((char*)buffer + offset, size - offset, 0);
		if (result == -1) {
			if (errno == EINTR) continue;
			if (errno == ENOSYS) return fill_devurandom(buffer, size);
			return 0;
		}
		offset += (size_t)result;
	}

#elif defined(__APPLE__)

	size_t offset = 0;
	while (offset < size) {
		// max allowed length is 256 bytes
		size_t chunk = (size - offset > 256) ? 256 : (size - offset);
		if (getentropy((char*)buffer + offset, chunk) == -1) {
			if (errno == ENOSYS) return fill_devurandom(buffer, size);
			return 0;
		}
		offset += chunk;
	}

#else
	// Unsupported platform
	return 0;
#endif
	return 1;
}

/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */
static void secure_erase(void *ptr, size_t len) {
#if defined(__GNUC__)
	/* We use a memory barrier that scares the compiler away from optimizing out the memset.
	 *
	 * Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
	 * in BoringSSL (ISC License):
	 *	As best as we can tell, this is sufficient to break any optimisations that
	 *	might try to eliminate "superfluous" memsets.
	 * This method used in memzero_explicit() the Linux kernel, too. Its advantage is that it is
	 * pretty efficient, because the compiler can still implement the memset() efficiently,
	 * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
	 * Yang et al. (USENIX Security 2017) for more background.
	 */
	memset(ptr, 0, len);
	__asm__ __volatile__("" : : "r"(ptr) : "memory");
#else
	void *(*volatile const volatile_memset)(void *, int, size_t) = memset;
	volatile_memset(ptr, 0, len);
#endif
}

static ERL_NIF_TERM sign_recoverable(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	if (argc != 2) {
		return enif_make_badarg(env);
	}
	ErlNifBinary Digest, PrivateBytes;
	if (!enif_inspect_binary(env, argv[0], &Digest)) {
		return enif_make_badarg(env);
	}
	if (Digest.size != SECP256K1_DIGEST_SIZE) {
		return enif_make_badarg(env);
	}

	if (!enif_inspect_binary(env, argv[1], &PrivateBytes)) {
		return enif_make_badarg(env);
	}
	if (PrivateBytes.size != SECP256K1_PRIVKEY_SIZE) {
		return enif_make_badarg(env);
	}

	char *error = NULL;
	unsigned char seed[SECP256K1_CONTEXT_SEED_SIZE];
	unsigned char digest[SECP256K1_DIGEST_SIZE];
	unsigned char privbytes[SECP256K1_PRIVKEY_SIZE];
	unsigned char signature_compact[SECP256K1_SIGNATURE_COMPACT_SIZE];
	unsigned char signature_recoverable[SECP256K1_SIGNATURE_RECOVERABLE_SIZE];
	int recid;
	secp256k1_ecdsa_recoverable_signature s;
	secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);

	memcpy(digest, Digest.data, SECP256K1_DIGEST_SIZE);
	memcpy(privbytes, PrivateBytes.data, SECP256K1_PRIVKEY_SIZE);

	if (!secp256k1_ec_seckey_verify(ctx, privbytes)) {
		error = "secp256k1 key is invalid.";
		goto cleanup;
	}

	if (!fill_random(seed, sizeof(seed))) {
		error = "Failed to generate random seed for context.";
		goto cleanup;
	}

	if (!secp256k1_context_randomize(ctx, seed)) {
		error = "Failed to randomize context.";
		goto cleanup;
	}

	if(!secp256k1_ecdsa_sign_recoverable(ctx, &s, digest, privbytes, NULL, NULL)) {
		error = "Failed to create signature.";
		goto cleanup;
	}

	if(!secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, signature_compact, &recid, &s)) {
		error = "Failed to serialize signature.";
		goto cleanup;
	}
	memcpy(signature_recoverable, signature_compact, SECP256K1_SIGNATURE_COMPACT_SIZE);
	signature_recoverable[64] = (unsigned char)(recid);

	ERL_NIF_TERM signature_term = make_output_binary(env, signature_recoverable, SECP256K1_SIGNATURE_RECOVERABLE_SIZE);

cleanup:
	secp256k1_context_destroy(ctx);
	secure_erase(seed, sizeof(seed));
	secure_erase(privbytes, sizeof(privbytes));
	memset(signature_compact, 0, SECP256K1_SIGNATURE_COMPACT_SIZE);
	memset(signature_recoverable, 0, SECP256K1_SIGNATURE_RECOVERABLE_SIZE);

	if (error) {
		return error_tuple(env, error);
	}
	return ok_tuple(env, signature_term);
}

static ERL_NIF_TERM recover_pk_and_verify(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
	if (argc != 2) {
		return enif_make_badarg(env);
	}
	ErlNifBinary Digest, Signature;
	if (!enif_inspect_binary(env, argv[0], &Digest)) {
		return enif_make_badarg(env);
	}
	if (Digest.size != SECP256K1_DIGEST_SIZE) {
		return enif_make_badarg(env);
	}

	if (!enif_inspect_binary(env, argv[1], &Signature)) {
		return enif_make_badarg(env);
	}
	if (Signature.size != SECP256K1_SIGNATURE_RECOVERABLE_SIZE) {
		return enif_make_badarg(env);
	}

	char *error = NULL;
	unsigned char digest[SECP256K1_DIGEST_SIZE];
	unsigned char signature_recoverable[SECP256K1_SIGNATURE_RECOVERABLE_SIZE];
	unsigned char signature_compact[SECP256K1_SIGNATURE_COMPACT_SIZE];
	unsigned char pubbytes[SECP256K1_PUBKEY_COMPRESSED_SIZE];
	int recid;
	secp256k1_ecdsa_recoverable_signature rs;
	secp256k1_ecdsa_signature s;
	secp256k1_pubkey pubkey;

	memcpy(digest, Digest.data, SECP256K1_DIGEST_SIZE);
	memcpy(signature_recoverable, Signature.data, SECP256K1_SIGNATURE_RECOVERABLE_SIZE);

	memcpy(signature_compact, signature_recoverable, SECP256K1_SIGNATURE_COMPACT_SIZE);
	recid = (int)signature_recoverable[64];

	if (recid < 0 || recid > 3) {
		error = "Invalid signature recid. recid >= 0 && recid <= 3.";
		goto cleanup;
	}

	if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_static, &rs, signature_compact, recid)) {
		error = "Failed to deserialize/parse recoverable signature.";
		goto cleanup;
	}

	if (!secp256k1_ecdsa_recover(secp256k1_context_static, &pubkey, &rs, digest)) {
		error = "Failed to recover public key.";
		goto cleanup;
	}
	size_t l = SECP256K1_PUBKEY_COMPRESSED_SIZE;
	if (!secp256k1_ec_pubkey_serialize(secp256k1_context_static, pubbytes, &l, &pubkey, SECP256K1_EC_COMPRESSED)) {
		error = "Failed to serialize the recovered public key.";
		goto cleanup;
	}

	if (!secp256k1_ecdsa_recoverable_signature_convert(secp256k1_context_static, &s, &rs)) {
		error = "Failed to convert recoverable signature to compact signature.";
		goto cleanup;
	}

	// NOTE. https://github.com/bitcoin-core/secp256k1/blob/f79f46c70386c693ff4e7aef0b9e7923ba284e56/src/secp256k1.c#L461
	// Verify performs check for low-s
	int is_valid = secp256k1_ecdsa_verify(secp256k1_context_static, &s, digest, &pubkey);
	ERL_NIF_TERM pubkey_term = make_output_binary(env, pubbytes, SECP256K1_PUBKEY_COMPRESSED_SIZE);

cleanup:
	memset(digest, 0, SECP256K1_DIGEST_SIZE);
	memset(pubbytes, 0, SECP256K1_PUBKEY_COMPRESSED_SIZE);
	memset(signature_compact, 0, SECP256K1_SIGNATURE_COMPACT_SIZE);
	memset(signature_recoverable, 0, SECP256K1_SIGNATURE_RECOVERABLE_SIZE);

	if (error) {
		return error_tuple(env, error);
	}
	if (is_valid) {
		return ok_tuple2(env, enif_make_atom(env, "true"), pubkey_term);
	}
	return ok_tuple2(env, enif_make_atom(env, "false"), pubkey_term);
}

static ErlNifFunc nif_funcs[] = {
	{"sign_recoverable", 2, sign_recoverable},
	{"recover_pk_and_verify", 2, recover_pk_and_verify}
};

ERL_NIF_INIT(secp256k1_nif, nif_funcs, secp256k1_load, NULL, NULL, NULL)


================================================
FILE: apps/arweave/c_src/vdf/ar_vdf_nif.c
================================================
#include <erl_nif.h>
#include <string.h>
#include <openssl/sha.h>
#include <ar_nif.h>
#include "vdf.h"

#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
#include <cpuid.h>
#endif
#if defined(__linux__)
	#include <sys/auxv.h>
#endif
#if defined(__APPLE__)
	#include <sys/types.h>
	#include <sys/sysctl.h>
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
//    SHA
////////////////////////////////////////////////////////////////////////////////////////////////////
typedef void (*vdf_sha2_fn)(
	unsigned char* saltBuffer,
	unsigned char* seed,
	unsigned char* out,
	unsigned char* outCheckpoint,
	int checkpointCount,
	int skipCheckpointCount,
	int hashingIterations
);
static vdf_sha2_fn vdf_sha2_fused_ptr = NULL;
static vdf_sha2_fn vdf_sha2_hiopt_ptr = NULL;

static int vdf_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info) {
	#if defined(__x86_64__) || defined(__i386__)
		{
			unsigned int eax, ebx, ecx, edx;
			// leaf 7, subleaf 0
			if (__get_cpuid_count(7, 0, &eax, &ebx, &ecx, &edx) && (ebx & (1u << 29))) {
				printf("VDF arch x86\n");
				vdf_sha2_fused_ptr = vdf_sha2_fused_x86;
				vdf_sha2_hiopt_ptr = vdf_sha2_fused_x86; // fallback
				return 0;
			}
		}
	#endif

	#if defined(__aarch64__) || defined(__arm__)
		#if defined(__linux__)
			if (getauxval(AT_HWCAP) & HWCAP_SHA2) {
				printf("VDF arch ARM linux\n");
				vdf_sha2_fused_ptr = vdf_sha2_fused_arm;
				vdf_sha2_hiopt_ptr = vdf_sha2_hiopt_arm;
				return 0;
			}
		#elif defined(__APPLE__)
			{
				int val = 0; size_t len = sizeof(val);
				if (sysctlbyname("hw.optional.arm.FEAT_SHA256", &val, &len, NULL, 0) == 0 && val != 0) {
					printf("VDF arch ARM macos\n");
					vdf_sha2_fused_ptr = vdf_sha2_fused_arm;
					vdf_sha2_hiopt_ptr = vdf_sha2_hiopt_arm;
					return 0;
				}
			}
		#endif
	#endif

	printf("VDF arch unknown\n");
	vdf_sha2_fused_ptr = vdf_sha2;
	vdf_sha2_hiopt_ptr = vdf_sha2;
	return 0;
}
static ERL_NIF_TERM vdf_sha2_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	ErlNifBinary Salt, Seed;
	int checkpointCount;
	int skipCheckpointCount;
	int hashingIterations;

	if (argc != 5) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[0], &Salt)) {
		return enif_make_badarg(envPtr);
	}
	if (Salt.size != SALT_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[1], &Seed)) {
		return enif_make_badarg(envPtr);
	}
	if (Seed.size != VDF_SHA_HASH_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[2], &checkpointCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &skipCheckpointCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &hashingIterations)) {
		return enif_make_badarg(envPtr);
	}

	unsigned char temp_result[VDF_SHA_HASH_SIZE];
	size_t outCheckpointSize = VDF_SHA_HASH_SIZE*checkpointCount;
	ERL_NIF_TERM outputTermCheckpoint;
	unsigned char* outCheckpoint = enif_make_new_binary(envPtr, outCheckpointSize, &outputTermCheckpoint);
	vdf_sha2(Salt.data, Seed.data, temp_result, outCheckpoint, checkpointCount, skipCheckpointCount, hashingIterations);

	return ok_tuple2(envPtr, make_output_binary(envPtr, temp_result, VDF_SHA_HASH_SIZE), outputTermCheckpoint);
}
static ERL_NIF_TERM vdf_sha2_fused_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	ErlNifBinary Salt, Seed;
	int checkpointCount;
	int skipCheckpointCount;
	int hashingIterations;

	if (argc != 5) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[0], &Salt)) {
		return enif_make_badarg(envPtr);
	}
	if (Salt.size != SALT_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[1], &Seed)) {
		return enif_make_badarg(envPtr);
	}
	if (Seed.size != VDF_SHA_HASH_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[2], &checkpointCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &skipCheckpointCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &hashingIterations)) {
		return enif_make_badarg(envPtr);
	}

	unsigned char temp_result[VDF_SHA_HASH_SIZE];
	size_t outCheckpointSize = VDF_SHA_HASH_SIZE*checkpointCount;
	ERL_NIF_TERM outputTermCheckpoint;
	unsigned char* outCheckpoint = enif_make_new_binary(envPtr, outCheckpointSize, &outputTermCheckpoint);
	vdf_sha2_fused_ptr(Salt.data, Seed.data, temp_result, outCheckpoint, checkpointCount, skipCheckpointCount, hashingIterations);

	return ok_tuple2(envPtr, make_output_binary(envPtr, temp_result, VDF_SHA_HASH_SIZE), outputTermCheckpoint);
}
static ERL_NIF_TERM vdf_sha2_hiopt_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_TERM argv[])
{
	ErlNifBinary Salt, Seed;
	int checkpointCount;
	int skipCheckpointCount;
	int hashingIterations;

	if (argc != 5) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[0], &Salt)) {
		return enif_make_badarg(envPtr);
	}
	if (Salt.size != SALT_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[1], &Seed)) {
		return enif_make_badarg(envPtr);
	}
	if (Seed.size != VDF_SHA_HASH_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[2], &checkpointCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &skipCheckpointCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &hashingIterations)) {
		return enif_make_badarg(envPtr);
	}

	unsigned char temp_result[VDF_SHA_HASH_SIZE];
	size_t outCheckpointSize = VDF_SHA_HASH_SIZE*checkpointCount;
	ERL_NIF_TERM outputTermCheckpoint;
	unsigned char* outCheckpoint = enif_make_new_binary(envPtr, outCheckpointSize, &outputTermCheckpoint);
	vdf_sha2_hiopt_ptr(Salt.data, Seed.data, temp_result, outCheckpoint, checkpointCount, skipCheckpointCount, hashingIterations);

	return ok_tuple2(envPtr, make_output_binary(envPtr, temp_result, VDF_SHA_HASH_SIZE), outputTermCheckpoint);
}

static ERL_NIF_TERM vdf_parallel_sha_verify_with_reset_nif(
	ErlNifEnv* envPtr,
	int argc,
	const ERL_NIF_TERM argv[]
) {
	ErlNifBinary Salt, Seed, InCheckpoint, InRes, ResetSalt, ResetSeed;
	int checkpointCount;
	int skipCheckpointCount;
	int hashingIterations;
	int maxThreadCount;

	if (argc != 10) {
		return enif_make_badarg(envPtr);
	}

	if (!enif_inspect_binary(envPtr, argv[0], &Salt)) {
		return enif_make_badarg(envPtr);
	}
	if (Salt.size != SALT_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[1], &Seed)) {
		return enif_make_badarg(envPtr);
	}
	if (Seed.size != VDF_SHA_HASH_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[2], &checkpointCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[3], &skipCheckpointCount)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[4], &hashingIterations)) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[5], &InCheckpoint)) {
		return enif_make_badarg(envPtr);
	}
	if (InCheckpoint.size != checkpointCount*VDF_SHA_HASH_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[6], &InRes)) {
		return enif_make_badarg(envPtr);
	}
	if (InRes.size != VDF_SHA_HASH_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[7], &ResetSalt)) {
		return enif_make_badarg(envPtr);
	}
	if (ResetSalt.size != 32) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_inspect_binary(envPtr, argv[8], &ResetSeed)) {
		return enif_make_badarg(envPtr);
	}
	if (ResetSeed.size != VDF_SHA_HASH_SIZE) {
		return enif_make_badarg(envPtr);
	}
	if (!enif_get_int(envPtr, argv[9], &maxThreadCount)) {
		return enif_make_badarg(envPtr);
	}
	if (maxThreadCount < 1) {
		return enif_make_badarg(envPtr);
	}

	// NOTE last paramemter will be array later
	size_t outCheckpointSize = VDF_SHA_HASH_SIZE*(1+checkpointCount)*(1+skipCheckpointCount);
	ERL_NIF_TERM outputTermCheckpoint;
	unsigned char* outCheckpoint = enif_make_new_binary(
		envPtr, outCheckpointSize, &outputTermCheckpoint);
	bool res = vdf_parallel_sha_verify_with_reset(
		Salt.data, Seed.data, checkpointCount, skipCheckpointCount, hashingIterations,
		InRes.data, InCheckpoint.data, outCheckpoint, ResetSalt.data, ResetSeed.data,
		maxThreadCount);
	// TODO return all checkpoints
	if (!res) {
		return error_tuple(envPtr, "verification failed");
	}

	return ok_tuple(envPtr, outputTermCheckpoint);
}

static ErlNifFunc nif_funcs[] = {
	{"vdf_sha2_nif", 5, vdf_sha2_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"vdf_sha2_fused_nif", 5, vdf_sha2_fused_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"vdf_sha2_hiopt_nif", 5, vdf_sha2_hiopt_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
	{"vdf_parallel_sha_verify_with_reset_nif", 10, vdf_parallel_sha_verify_with_reset_nif,
		ERL_NIF_DIRTY_JOB_CPU_BOUND}
};

ERL_NIF_INIT(ar_vdf_nif, nif_funcs, vdf_load, NULL, NULL, NULL);


================================================
FILE: apps/arweave/c_src/vdf/sha256-armv8.S
================================================
.text
.globl	_sha256_block_vdf_order
.align	6
_sha256_block_vdf_order:
	stp	x29,x30,[sp,#-16]!
	add	x29,sp,#0
    adr    x3,K2564

    ld1    {v4.16b,v5.16b,v6.16b,v7.16b},[x1]
	ld1	   {v0.4s,v1.4s},[x0]
    
    ld1    {v16.4s},[x3],#16
    add    v16.4s,v16.4s,v4.4s
    orr    v2.16b,v0.16b,v0.16b
.long    0x5e104020    //sha256h v0.16b,v1.16b,v16.4s
.long    0x5e105041    //sha256h2 v1.16b,v2.16b,v16.4s

    ld1    {v17.4s},[x3],#16
    add    v17.4s,v17.4s,v5.4s
    orr    v2.16b,v0.16b,v0.16b
.long    0x5e114020    //sha256h v0.16b,v1.16b,v17.4s
.long    0x5e115041    //sha256h2 v1.16b,v2.16b,v17.4s
    orr    v20.16b,v0.16b,v0.16b
    orr    v21.16b,v1.16b,v1.16b
    ld1    {v18.4s,v19.4s},[x0]

Loop_hw:
	sub	x2,x2,#1	
//	rev32	v4.16b,v4.16b
//	rev32	v5.16b,v5.16b
//	rev32	v6.16b,v6.16b
//	rev32	v7.16b,v7.16b

    ld1    {v4.16b,v5.16b},[x1]
    orr    v0.16b,v20.16b,v20.16b
    orr    v1.16b,v21.16b,v21.16b
	
.long	0x5e2828a4	//sha256su0 v4.16b,v5.16b
.long	0x5e0760c4	//sha256su1 v4.16b,v6.16b,v7.16b
	ld1	{v16.4s},[x3],#16
.long	0x5e2828c5	//sha256su0 v5.16b,v6.16b
.long	0x5e0460e5	//sha256su1 v5.16b,v7.16b,v4.16b
	ld1	{v17.4s},[x3],#16
	add	v16.4s,v16.4s,v6.4s
.long	0x5e2828e6	//sha256su0 v6.16b,v7.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s
.long	0x5e056086	//sha256su1 v6.16b,v4.16b,v5.16b
	ld1	{v16.4s},[x3],#16
	add	v17.4s,v17.4s,v7.4s
.long	0x5e282887	//sha256su0 v7.16b,v4.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e114020	//sha256h v0.16b,v1.16b,v17.4s
.long	0x5e115041	//sha256h2 v1.16b,v2.16b,v17.4s
.long	0x5e0660a7	//sha256su1 v7.16b,v5.16b,v6.16b
	ld1	{v17.4s},[x3],#16
	add	v16.4s,v16.4s,v4.4s
.long	0x5e2828a4	//sha256su0 v4.16b,v5.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s
.long	0x5e0760c4	//sha256su1 v4.16b,v6.16b,v7.16b
	ld1	{v16.4s},[x3],#16
	add	v17.4s,v17.4s,v5.4s
.long	0x5e2828c5	//sha256su0 v5.16b,v6.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e114020	//sha256h v0.16b,v1.16b,v17.4s
.long	0x5e115041	//sha256h2 v1.16b,v2.16b,v17.4s
.long	0x5e0460e5	//sha256su1 v5.16b,v7.16b,v4.16b
	ld1	{v17.4s},[x3],#16
	add	v16.4s,v16.4s,v6.4s
.long	0x5e2828e6	//sha256su0 v6.16b,v7.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s
.long	0x5e056086	//sha256su1 v6.16b,v4.16b,v5.16b
	ld1	{v16.4s},[x3],#16
	add	v17.4s,v17.4s,v7.4s
.long	0x5e282887	//sha256su0 v7.16b,v4.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e114020	//sha256h v0.16b,v1.16b,v17.4s
.long	0x5e115041	//sha256h2 v1.16b,v2.16b,v17.4s
.long	0x5e0660a7	//sha256su1 v7.16b,v5.16b,v6.16b
	ld1	{v17.4s},[x3],#16
	add	v16.4s,v16.4s,v4.4s
.long	0x5e2828a4	//sha256su0 v4.16b,v5.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s
.long	0x5e0760c4	//sha256su1 v4.16b,v6.16b,v7.16b
	ld1	{v16.4s},[x3],#16
	add	v17.4s,v17.4s,v5.4s
.long	0x5e2828c5	//sha256su0 v5.16b,v6.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e114020	//sha256h v0.16b,v1.16b,v17.4s
.long	0x5e115041	//sha256h2 v1.16b,v2.16b,v17.4s
.long	0x5e0460e5	//sha256su1 v5.16b,v7.16b,v4.16b
	ld1	{v17.4s},[x3],#16
	add	v16.4s,v16.4s,v6.4s
.long	0x5e2828e6	//sha256su0 v6.16b,v7.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s
.long	0x5e056086	//sha256su1 v6.16b,v4.16b,v5.16b
	ld1	{v16.4s},[x3],#16
	add	v17.4s,v17.4s,v7.4s
.long	0x5e282887	//sha256su0 v7.16b,v4.16b
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e114020	//sha256h v0.16b,v1.16b,v17.4s
.long	0x5e115041	//sha256h2 v1.16b,v2.16b,v17.4s
.long	0x5e0660a7	//sha256su1 v7.16b,v5.16b,v6.16b
	ld1	{v17.4s},[x3],#16
	add	v16.4s,v16.4s,v4.4s
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	add	v17.4s,v17.4s,v5.4s
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e114020	//sha256h v0.16b,v1.16b,v17.4s
.long	0x5e115041	//sha256h2 v1.16b,v2.16b,v17.4s

	ld1	{v17.4s},[x3],#16
	add	v16.4s,v16.4s,v6.4s
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s
	
	add	v17.4s,v17.4s,v7.4s
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e114020	//sha256h v0.16b,v1.16b,v17.4s
.long	0x5e115041	//sha256h2 v1.16b,v2.16b,v17.4s

	add	v6.4s,v0.4s,v18.4s
	add	v7.4s,v1.4s,v19.4s

//64B

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v6.16b,v6.16b
    orr    v0.16b,v6.16b,v6.16b
    orr    v1.16b,v7.16b,v7.16b
//.long   0x5e1040e0  //sha256h v0.16b,v7.16b,v16.4s
.long   0x5e104020  //sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3],#16
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	ld1	{v16.4s},[x3]
	sub	x3,x3,#128*4-48	// rewind
	orr	v2.16b,v0.16b,v0.16b
.long	0x5e104020	//sha256h v0.16b,v1.16b,v16.4s
.long	0x5e105041	//sha256h2 v1.16b,v2.16b,v16.4s

	add	v6.4s,v0.4s,v6.4s
	add	v7.4s,v1.4s,v7.4s
	
	cbnz	x2,Loop_hw

	st1	{v6.4s,v7.4s},[x0]

	ldr	x29,[sp],#16
	ret
	
K2564:
.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
.long	0xC28A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5		//64B
.long	0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5
.long	0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3
.long	0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF374
.long	0x649B69C1,0xF0FE4786,0x0FE1EDC6,0x240CF254
.long	0x4FE9346F,0x6CC984BE,0x61B9411E,0x16F988FA
.long	0xF2C65152,0xA88E5A6D,0xB019FC65,0xB9D99EC7
.long	0x9A1231C3,0xE70EEAA0,0xFDB1232B,0xC7353EB0
.long	0x3069BAD5,0xCB976D5F,0x5A0F118F,0xDC1EEEFD
.long	0x0A35B689,0xDE0B7A04,0x58F4CA9D,0xE15D5B16
.long	0x007F3E86,0x37088980,0xA507EA32,0x6FAB9537
.long	0x17406110,0x0D8CD6F1,0xCDAA3B6D,0xC0BBBE37
.long	0x83613BDA,0xDB48A363,0x0B02E931,0x6FD15CA7
.long	0x521AFACA,0x31338431,0x6ED41A95,0x6D437890
.long	0xC39C91F2,0x9ECCABBD,0xB5C9A0E6,0x532FB63C
.long	0xD2C741C6,0x07237EA3,0xA4954B68,0x4C191D76
.long	0	//terminator


================================================
FILE: apps/arweave/c_src/vdf/vdf.cpp
================================================
#include <thread>
#include <cstdint>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <mutex>
#include <openssl/sha.h>
#include "vdf.h"

extern "C" {

struct vdf_sha_thread_arg {
	unsigned char* saltBuffer;
	unsigned char* seed;
	unsigned char* outCheckpoint;
	int checkpointCount;
	int skipCheckpointCount;
	int hashingIterations;
	unsigned char* out;
};

struct vdf_sha_verify_thread_arg;

class vdf_verify_job {
public:
	unsigned char* startSaltBuffer;
	unsigned char* seed;
	unsigned char* inCheckpointSha;
	unsigned char* outCheckpointSha;
	unsigned char* inCheckpointRandomx;
	unsigned char* resetStepNumberBin256;
	unsigned char* resetSeed;
	int checkpointCount;
	int skipCheckpointCount;
	int hashingIterationsSha;
	int hashingIterationsRandomx;

	std::vector<vdf_sha_verify_thread_arg> _vdf_sha_verify_thread_arg_list;
	volatile bool verifyRes;
	std::mutex lock;
};

struct vdf_sha_verify_thread_arg {
	std::thread* thread;
	volatile bool in_progress;

	vdf_verify_job* job;
	int checkpointIdx;
};

////////////////////////////////////////////////////////////////////////////////////////////////////
//    SHA
////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE saltBuffer is mutable in progress
void _vdf_sha2(unsigned char* saltBuffer, unsigned char* seed, unsigned char* out, unsigned char* outCheckpoint, int checkpointCount, int skipCheckpointCount, int hashingIterations) {
	unsigned char tempOut[VDF_SHA_HASH_SIZE];
	// 2 different branches for different optimisation cases
	if (skipCheckpointCount == 0) {
		for(int checkpointIdx = 0; checkpointIdx <= checkpointCount; checkpointIdx++) {
			unsigned char* locIn  = checkpointIdx == 0               ? seed : (outCheckpoint + VDF_SHA_HASH_SIZE*(checkpointIdx-1));
			unsigned char* locOut = checkpointIdx == checkpointCount ? out  : (outCheckpoint + VDF_SHA_HASH_SIZE*checkpointIdx);

			{
				SHA256_CTX sha256;
				SHA256_Init(&sha256);
				SHA256_Update(&sha256, saltBuffer, SALT_SIZE);
				SHA256_Update(&sha256, locIn, VDF_SHA_HASH_SIZE); // -1 memcpy
				SHA256_Final(tempOut, &sha256);
			}
			for(int i = 2; i < hashingIterations; i++) {
				SHA256_CTX sha256;
				SHA256_Init(&sha256);
				SHA256_Update(&sha256, saltBuffer, SALT_SIZE);
				SHA256_Update(&sha256, tempOut, VDF_SHA_HASH_SIZE);
				SHA256_Final(tempOut, &sha256);
			}
			{
				SHA256_CTX sha256;
				SHA256_Init(&sha256);
				SHA256_Update(&sha256, saltBuffer, SALT_SIZE);
				SHA256_Update(&sha256, tempOut, VDF_SHA_HASH_SIZE);
				SHA256_Final(locOut, &sha256);
			}
			long_add(saltBuffer, 1);
		}
	} else {
		for(int checkpointIdx = 0; checkpointIdx <= checkpointCount; checkpointIdx++) {
			unsigned char* locIn  = checkpointIdx == 0               ? seed : (outCheckpoint + VDF_SHA_HASH_SIZE*(checkpointIdx-1));
			unsigned char* locOut = checkpointIdx == checkpointCount ? out  : (outCheckpoint + VDF_SHA_HASH_SIZE*checkpointIdx);

			{
				SHA256_CTX sha256;
				SHA256_Init(&sha256);
				SHA256_Update(&sha256, saltBuffer, SALT_SIZE);
				SHA256_Update(&sha256, locIn, VDF_SHA_HASH_SIZE); // -1 memcpy
				SHA256_Final(tempOut, &sha256);
			}
			// 1 skip on start
			for(int i = 1; i < hashingIterations; i++) {
				SHA256_CTX sha256;
				SHA256_Init(&sha256);
				SHA256_Update(&sha256, saltBuffer, SALT_SIZE);
				SHA256_Update(&sha256, tempOut, VDF_SHA_HASH_SIZE);
				SHA256_Final(tempOut, &sha256);
			}
			long_add(saltBuffer, 1);
			for(int j = 1; j < skipCheckpointCount; j++) {
				// no skips
				for(int i = 0; i < hashingIterations; i++) {
					SHA256_CTX sha256;
					SHA256_Init(&sha256);
					SHA256_Update(&sha256, saltBuffer, SALT_SIZE);
					SHA256_Update(&sha256, tempOut, VDF_SHA_HASH_SIZE);
					SHA256_Final(tempOut, &sha256);
				}
				long_add(saltBuffer, 1);
			}
			// 1 skip on end
			for(int i = 1; i < hashingIterations; i++) {
				SHA256_CTX sha256;
				SHA256_Init(&sha256);
				SHA256_Update(&sha256, saltBuffer, SALT_SIZE);
				SHA256_Update(&sha256, tempOut, VDF_SHA_HASH_SIZE);
				SHA256_Final(tempOut, &sha256);
			}
			{
				SHA256_CTX sha256;
				SHA256_Init(&sha256);
				SHA256_Update(&sha256, saltBuffer, SALT_SIZE);
				SHA256_Update(&sha256, tempOut, VDF_SHA_HASH_SIZE);
				SHA256_Final(locOut, &sha256);
			}
			long_add(saltBuffer, 1);
		}
	}
}

// use
//   unsigned char out[VDF_SHA_HASH_SIZE];
//   unsigned char* outCheckpoint = (unsigned char*)malloc(checkpointCount*VDF_SHA_HASH_SIZE);
//   free(outCheckpoint);
// for call
void vdf_sha2(unsigned char* saltBuffer, unsigned char* seed, unsigned char* out, unsigned char* outCheckpoint, int checkpointCount, int skipCheckpointCount, int hashingIterations) {
	unsigned char saltBufferStack[SALT_SIZE];
	// ensure 1 L1 cache page used
	// no access to heap, except of 0-iteration
	memcpy(saltBufferStack, saltBuffer, SALT_SIZE);

	_vdf_sha2(saltBufferStack, seed, out, outCheckpoint, checkpointCount, skipCheckpointCount, hashingIterations);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//    Verify SHA
////////////////////////////////////////////////////////////////////////////////////////////////////
void _vdf_sha_verify_thread(vdf_sha_verify_thread_arg* _arg) {
	vdf_sha_verify_thread_arg* arg = _arg;
	while(true) {
		if (!arg->job->verifyRes) {
			return;
		}

		unsigned char expdOut[VDF_SHA_HASH_SIZE];
		unsigned char* in = arg->checkpointIdx == 0 ? arg->job->seed : (arg->job->inCheckpointSha + (arg->checkpointIdx-1)*VDF_SHA_HASH_SIZE);
		unsigned char* out = arg->job->inCheckpointSha + arg->checkpointIdx*VDF_SHA_HASH_SIZE;
		unsigned char* outFullCheckpoint = arg->job->outCheckpointSha + arg->checkpointIdx*(1+arg->job->skipCheckpointCount)*VDF_SHA_HASH_SIZE;
		unsigned char  saltBuffer[SALT_SIZE];
		memcpy(saltBuffer, arg->job->startSaltBuffer, SALT_SIZE);
		long_add(saltBuffer, arg->checkpointIdx*(1+arg->job->skipCheckpointCount));

		// unrolled for memcpy inject
		// _vdf_sha2(saltBuffer, in, expdOut, NULL, 0, arg->job->skipCheckpointCount, arg->job->hashingIterationsSha);

		// do not rewrite in
		unsigned char inCopy[VDF_SHA_HASH_SIZE];
		memcpy(inCopy, in, VDF_SHA_HASH_SIZE);
		for(int i=0;i<=arg->job->skipCheckpointCount;i++) {
			_vdf_sha2(saltBuffer, inCopy, expdOut, NULL, 0, 0, arg->job->hashingIterationsSha);
			memcpy(outFullCheckpoint, expdOut, VDF_SHA_HASH_SIZE);
			outFullCheckpoint += VDF_SHA_HASH_SIZE;
			memcpy(inCopy, expdOut, VDF_SHA_HASH_SIZE);
			// NOTE long_add included
		}
		// 0 == equal
		if (0 != memcmp(expdOut, out, VDF_SHA_HASH_SIZE)) {
			arg->job->verifyRes = false;
			return;
		}

		{
			const std::lock_guard<std::mutex> lock(arg->job->lock);

			bool found = false;
			for(int i=arg->checkpointIdx+1;i<arg->job->checkpointCount;i++) {
				vdf_sha_verify_thread_arg* new_arg = &arg->job->_vdf_sha_verify_thread_arg_list[i];
				if (!new_arg->in_progress) {
					new_arg->in_progress = true;
					arg = new_arg;
					found = true;
					break;
				}
			}
			if (!found) break;
		}
	}

	// TODO steal job from other hash function
}

void reset_mix(unsigned char* res, unsigned char* prevOutput, unsigned char* resetSeed) {
	SHA256_CTX sha256;
	SHA256_Init(&sha256);
	SHA256_Update(&sha256, prevOutput, VDF_SHA_HASH_SIZE);
	SHA256_Update(&sha256, resetSeed, VDF_SHA_HASH_SIZE);
	SHA256_Final(res, &sha256);
}

bool fast_rev_cmp256(unsigned char* a, unsigned char* b) {
	for(int i=31; i>=0; i--) {
		if (a[i] != b[i])
			return false;
	}
	return true;
}

void _vdf_sha_verify_with_reset_thread(vdf_sha_verify_thread_arg* _arg) {
	vdf_sha_verify_thread_arg* arg = _arg;
	while(true) {
		if (!arg->job->verifyRes) {
			return;
		}

		unsigned char expdOut[VDF_SHA_HASH_SIZE];
		unsigned char* in = arg->checkpointIdx == 0 ? arg->job->seed : (arg->job->inCheckpointSha + (arg->checkpointIdx-1)*VDF_SHA_HASH_SIZE);
		unsigned char* out = arg->job->inCheckpointSha + arg->checkpointIdx*VDF_SHA_HASH_SIZE;
		unsigned char* outFullCheckpoint = arg->job->outCheckpointSha + arg->checkpointIdx*(1+arg->job->skipCheckpointCount)*VDF_SHA_HASH_SIZE;
		unsigned char  saltBuffer[SALT_SIZE];
		memcpy(saltBuffer, arg->job->startSaltBuffer, SALT_SIZE);
		long_add(saltBuffer, arg->checkpointIdx*(1+arg->job->skipCheckpointCount));

		// unrolled for memcpy inject and reset_mix
		// _vdf_sha2(saltBuffer, in, expdOut, NULL, 0, arg->job->skipCheckpointCount, arg->job->hashingIterationsSha);

		// do not rewrite in
		unsigned char inCopy[VDF_SHA_HASH_SIZE];
		memcpy(inCopy, in, VDF_SHA_HASH_SIZE);

		if (fast_rev_cmp256(saltBuffer, arg->job->resetStepNumberBin256)) {
			reset_mix(inCopy, inCopy, arg->job->resetSeed);
		}

		for(int i=0;i<=arg->job->skipCheckpointCount;i++) {
			_vdf_sha2(saltBuffer, inCopy, expdOut, NULL, 0, 0, arg->job->hashingIterationsSha);
			memcpy(outFullCheckpoint, expdOut, VDF_SHA_HASH_SIZE);
			outFullCheckpoint += VDF_SHA_HASH_SIZE;
			memcpy(inCopy, expdOut, VDF_SHA_HASH_SIZE);

			if (fast_rev_cmp256(saltBuffer, arg->job->resetStepNumberBin256)) {
				reset_mix(inCopy, inCopy, arg->job->resetSeed);
			}
			// NOTE long_add included
		}
		// 0 == equal
		if (0 != memcmp(expdOut, out, VDF_SHA_HASH_SIZE)) {
			arg->job->verifyRes = false;
			return;
		}

		{
			const std::lock_guard<std::mutex> lock(arg->job->lock);

			bool found = false;
			for(int i=arg->checkpointIdx+1;i<arg->job->checkpointCount;i++) {
				vdf_sha_verify_thread_arg* new_arg = &arg->job->_vdf_sha_verify_thread_arg_list[i];
				if (!new_arg->in_progress) {
					new_arg->in_progress = true;
					arg = new_arg;
					found = true;
					break;
				}
			}
			if (!found) break;
		}
	}

	// TODO steal job from other hash function
}

bool vdf_parallel_sha_verify_with_reset(unsigned char* startSaltBuffer, unsigned char* seed, int checkpointCount, int skipCheckpointCount, int hashingIterations, unsigned char* inRes, unsigned char* inCheckpoint, unsigned char* outCheckpoint, unsigned char* resetStepNumberBin256, unsigned char* resetSeed, int maxThreadCount) {
	int freeThreadCount = maxThreadCount;

	vdf_verify_job job;
	job.startSaltBuffer = startSaltBuffer;
	job.seed = seed;
	job.inCheckpointSha = inCheckpoint;
	job.outCheckpointSha = outCheckpoint;
	job.checkpointCount = checkpointCount;
	job.skipCheckpointCount = skipCheckpointCount;
	job.hashingIterationsSha = hashingIterations;
	job.resetStepNumberBin256 = resetStepNumberBin256;
	job.resetSeed = resetSeed;
	job.verifyRes = true;

	job._vdf_sha_verify_thread_arg_list    .resize(checkpointCount);

	for (int checkpointIdx=0;checkpointIdx<checkpointCount;checkpointIdx++) {
		struct vdf_sha_verify_thread_arg*     _vdf_sha_verify_thread_arg     = &job._vdf_sha_verify_thread_arg_list[checkpointIdx];
		_vdf_sha_verify_thread_arg    ->checkpointIdx = checkpointIdx;
		_vdf_sha_verify_thread_arg    ->thread = NULL;
		_vdf_sha_verify_thread_arg    ->in_progress = false;
		_vdf_sha_verify_thread_arg    ->job = &job;
	}

	for (int checkpointIdx=0;checkpointIdx<checkpointCount;checkpointIdx++) {
		struct vdf_sha_verify_thread_arg*     _vdf_sha_verify_thread_arg     = &job._vdf_sha_verify_thread_arg_list[checkpointIdx];
		if (freeThreadCount > 0) {
			freeThreadCount--;
			const std::lock_guard<std::mutex> lock(job.lock);
			_vdf_sha_verify_thread_arg->in_progress = true;
			_vdf_sha_verify_thread_arg->thread = new std::thread(_vdf_sha_verify_with_reset_thread, _vdf_sha_verify_thread_arg);
		}
		if (freeThreadCount == 0) break;
	}

	if (job.verifyRes) {
		unsigned char expdOut[VDF_SHA_HASH_SIZE];
		unsigned char* sha_temp_result;
		if (checkpointCount == 0) {
			sha_temp_result = seed;
		} else {
			sha_temp_result = inCheckpoint + (checkpointCount-1)*VDF_SHA_HASH_SIZE;
		}

		unsigned char finalSaltBuffer[SALT_SIZE];
		memcpy(finalSaltBuffer, startSaltBuffer, SALT_SIZE);
		long_add(finalSaltBuffer, checkpointCount*(1+skipCheckpointCount));

		unsigned char* outFullCheckpoint = outCheckpoint + checkpointCount*(1+skipCheckpointCount)*VDF_SHA_HASH_SIZE;

		// unrolled for memcpy inject
		// _vdf_sha2(finalSaltBuffer, sha_temp_result, expdOut, NULL, 0, skipCheckpointCount, hashingIterations);

		// do not rewrite in
		unsigned char inCopy[VDF_SHA_HASH_SIZE];
		memcpy(inCopy, sha_temp_result, VDF_SHA_HASH_SIZE);

		if (fast_rev_cmp256(finalSaltBuffer, resetStepNumberBin256)) {
			reset_mix(inCopy, inCopy, resetSeed);
		}

		for(int i=0;i<=skipCheckpointCount;i++) {
			_vdf_sha2(finalSaltBuffer, inCopy, expdOut, NULL, 0, 0, hashingIterations);
			memcpy(outFullCheckpoint, expdOut, VDF_SHA_HASH_SIZE);
			outFullCheckpoint += VDF_SHA_HASH_SIZE;
			memcpy(inCopy, expdOut, VDF_SHA_HASH_SIZE);

			if (fast_rev_cmp256(finalSaltBuffer, resetStepNumberBin256)) {
				reset_mix(inCopy, inCopy, resetSeed);
			}
			// NOTE long_add included
		}
		if (0 != memcmp(expdOut, inRes, VDF_SHA_HASH_SIZE)) {
			job.verifyRes = false;
		}
	}

	for (int checkpointIdx=0;checkpointIdx<checkpointCount;checkpointIdx++) {
		struct vdf_sha_verify_thread_arg*     _vdf_sha_verify_thread_arg     = &job._vdf_sha_verify_thread_arg_list[checkpointIdx];

		if (_vdf_sha_verify_thread_arg->thread) {
			_vdf_sha_verify_thread_arg->thread->join();
			free(_vdf_sha_verify_thread_arg->thread);
		}
	}

	return job.verifyRes;
}

}

================================================
FILE: apps/arweave/c_src/vdf/vdf.h
================================================
#ifndef VDF_H
#define VDF_H

#include <stdbool.h>

const int SALT_SIZE = 32;
const int VDF_SHA_HASH_SIZE = 32;

static inline void long_add(unsigned char* saltBuffer, int checkpointIdx) {
	unsigned int acc = checkpointIdx;
	// big endian from erlang
	for(int i=SALT_SIZE-1;i>=0;i--) {
		unsigned int value = saltBuffer[i];
		value += acc;
		saltBuffer[i] = value & 0xFF;
		acc = value >> 8;
		if (acc == 0) break;
	}
}

#if defined(__cplusplus)
extern "C" {
#endif

// out checkpoint should return all checkpoints including skipCheckpointCount
void vdf_sha2(unsigned char* saltBuffer, unsigned char* seed, unsigned char* out, unsigned char* outCheckpoint, int checkpointCount, int skipCheckpointCount, int hashingIterations);
void vdf_sha2_fused_x86(unsigned char* saltBuffer, unsigned char* seed, unsigned char* out, unsigned char* outCheckpoint, int checkpointCount, int skipCheckpointCount, int hashingIterations);
void vdf_sha2_fused_arm(unsigned char* saltBuffer, unsigned char* seed, unsigned char* out, unsigned char* outCheckpoint, int checkpointCount, int skipCheckpointCount, int hashingIterations);
void vdf_sha2_hiopt_arm(unsigned char* saltBuffer, unsigned char* seed, unsigned char* out, unsigned char* outCheckpoint, int checkpointCount, int skipCheckpointCount, int hashingIterations);
bool vdf_parallel_sha_verify_with_reset(unsigned char* startSaltBuffer, unsigned char* seed, int checkpointCount, int skipCheckpointCount, int hashingIterations, unsigned char* inRes, unsigned char* inCheckpoint, unsigned char* outCheckpoint, unsigned char* resetSalt, unsigned char* resetSeed, int maxThreadCount);

#if defined(__cplusplus)
}
#endif


#endif


================================================
FILE: apps/arweave/c_src/vdf/vdf_fused_arm.cpp
================================================
#include <cstdint>
#include <cstring>
#include "vdf.h"

#if defined(__aarch64__) || defined(__arm__)

#include <arm_neon.h>
#include <arm_acle.h>

static const uint32_t K[] = {
	0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
	0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
	0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
	0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
	0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
	0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
	0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
	0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
	0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
	0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
	0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
	0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
	0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
	0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
	0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
	0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
};

void sha2_p2_32_32_rev_norm (unsigned char *output,
                             const unsigned char *input1,
                             const unsigned char *input2)
{
	uint32_t state[8] = {
		0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
		0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
	};

	uint32x4_t STATE0, STATE1, ABEF_SAVE, CDGH_SAVE;
	uint32x4_t MSG0, MSG1, MSG2, MSG3;
	uint32x4_t TMP0, TMP2;

	// Load state
	STATE0 = vld1q_u32(&state[0]);
	STATE1 = vld1q_u32(&state[4]);

	// Save current state
	ABEF_SAVE = STATE0;
	CDGH_SAVE = STATE1;

	// Load input1 (32 bytes) and input2 (32 bytes) into two message blocks
	// These constitute our 64-byte block
	MSG0 = vld1q_u32((const uint32_t *)(input1 + 0));
	MSG1 = vld1q_u32((const uint32_t *)(input1 + 16));
	MSG2 = vld1q_u32((const uint32_t *)(input2 + 0));
	MSG3 = vld1q_u32((const uint32_t *)(input2 + 16));

	// Adjust endianness
	MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0)));
	MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1)));
	MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2)));
	MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3)));

	// Rounds 1-4
	TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0]));
	TMP2 = STATE0;
	MSG0 = vsha256su0q_u32(MSG0, MSG1);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

	// Rounds 5-8
	TMP0 = vaddq_u32(MSG1, vld1q_u32(&K[4]));
	TMP2 = STATE0;
	MSG1 = vsha256su0q_u32(MSG1, MSG2);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

	// Rounds 9-12
	TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[8]));
	TMP2 = STATE0;
	MSG2 = vsha256su0q_u32(MSG2, MSG3);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

	// Rounds 13-16
	TMP0 = vaddq_u32(MSG3, vld1q_u32(&K[12]));
	TMP2 = STATE0;
	MSG3 = vsha256su0q_u32(MSG3, MSG0);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

	// Rounds 17-20
	TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[16]));
	TMP2 = STATE0;
	MSG0 = vsha256su0q_u32(MSG0, MSG1);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

	// Rounds 21-24
	TMP0 = vaddq_u32(MSG1, vld1q_u32(&K[20]));
	TMP2 = STATE0;
	MSG1 = vsha256su0q_u32(MSG1, MSG2);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

	// Rounds 25-28
	TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[24]));
	TMP2 = STATE0;
	MSG2 = vsha256su0q_u32(MSG2, MSG3);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

	// Rounds 29-32
	TMP0 = vaddq_u32(MSG3, vld1q_u32(&K[28]));
	TMP2 = STATE0;
	MSG3 = vsha256su0q_u32(MSG3, MSG0);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

	// Rounds 33-36
	TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[32]));
	TMP2 = STATE0;
	MSG0 = vsha256su0q_u32(MSG0, MSG1);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

	// Rounds 37-40
	TMP0 = vaddq_u32(MSG1, vld1q_u32(&K[36]));
	TMP2 = STATE0;
	MSG1 = vsha256su0q_u32(MSG1, MSG2);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

	// Rounds 41-44
	TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[40]));
	TMP2 = STATE0;
	MSG2 = vsha256su0q_u32(MSG2, MSG3);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

	// Rounds 45-48
	TMP0 = vaddq_u32(MSG3, vld1q_u32(&K[44]));
	TMP2 = STATE0;
	MSG3 = vsha256su0q_u32(MSG3, MSG0);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

	// Rounds 49-52
	TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[48]));
	TMP2 = STATE0;
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

	// Rounds 53-56
	TMP0 = vaddq_u32(MSG1, vld1q_u32(&K[52]));
	TMP2 = STATE0;
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

	// Rounds 57-60
	TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[56]));
	TMP2 = STATE0;
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

	// Rounds 61-64
	TMP0 = vaddq_u32(MSG3, vld1q_u32(&K[60]));
	TMP2 = STATE0;
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

	// Update state
	STATE0 = vaddq_u32(STATE0, ABEF_SAVE);
	STATE1 = vaddq_u32(STATE1, CDGH_SAVE);

	// Now we need to process the padding block
	// For a 64-byte input (32+32), the padding block consists of 0x80 followed by zeros
	// and the 64-bit length (512 bits)

	// TODO merge with endian fixes
	uint8_t padding[64] = {0};
	padding[0] = 0x80;  // Padding start marker

	// Set the 64-bit length value (512 bits = 0x0200)
	padding[56] = 0x00;
	padding[57] = 0x00;
	padding[58] = 0x00;
	padding[59] = 0x00;
	padding[60] = 0x00;
	padding[61] = 0x00;
	padding[62] = 0x02;
	padding[63] = 0x00;

	// Save current state
	ABEF_SAVE = STATE0;
	CDGH_SAVE = STATE1;

	// Load padding block
	MSG0 = vld1q_u32((const uint32_t *)(padding + 0));
	MSG1 = vld1q_u32((const uint32_t *)(padding + 16));
	MSG2 = vld1q_u32((const uint32_t *)(padding + 32));
	MSG3 = vld1q_u32((const uint32_t *)(padding + 48));

	MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0)));
	MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1)));
	MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2)));
	MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3)));

	// Rounds 1-4
	TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[0]));
	TMP2 = STATE0;
	MSG0 = vsha256su0q_u32(MSG0, MSG1);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

	// Rounds 5-8
	TMP0 = vaddq_u32(MSG1, vld1q_u32(&K[4]));
	TMP2 = STATE0;
	MSG1 = vsha256su0q_u32(MSG1, MSG2);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

	// Rounds 9-12
	TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[8]));
	TMP2 = STATE0;
	MSG2 = vsha256su0q_u32(MSG2, MSG3);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

	// Rounds 13-16
	TMP0 = vaddq_u32(MSG3, vld1q_u32(&K[12]));
	TMP2 = STATE0;
	MSG3 = vsha256su0q_u32(MSG3, MSG0);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

	// Rounds 17-20
	TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[16]));
	TMP2 = STATE0;
	MSG0 = vsha256su0q_u32(MSG0, MSG1);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

	// Rounds 21-24
	TMP0 = vaddq_u32(MSG1, vld1q_u32(&K[20]));
	TMP2 = STATE0;
	MSG1 = vsha256su0q_u32(MSG1, MSG2);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

	// Rounds 25-28
	TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[24]));
	TMP2 = STATE0;
	MSG2 = vsha256su0q_u32(MSG2, MSG3);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

	// Rounds 29-32
	TMP0 = vaddq_u32(MSG3, vld1q_u32(&K[28]));
	TMP2 = STATE0;
	MSG3 = vsha256su0q_u32(MSG3, MSG0);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

	// Rounds 33-36
	TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[32]));
	TMP2 = STATE0;
	MSG0 = vsha256su0q_u32(MSG0, MSG1);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG0 = vsha256su1q_u32(MSG0, MSG2, MSG3);

	// Rounds 37-40
	TMP0 = vaddq_u32(MSG1, vld1q_u32(&K[36]));
	TMP2 = STATE0;
	MSG1 = vsha256su0q_u32(MSG1, MSG2);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG1 = vsha256su1q_u32(MSG1, MSG3, MSG0);

	// Rounds 41-44
	TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[40]));
	TMP2 = STATE0;
	MSG2 = vsha256su0q_u32(MSG2, MSG3);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG2 = vsha256su1q_u32(MSG2, MSG0, MSG1);

	// Rounds 45-48
	TMP0 = vaddq_u32(MSG3, vld1q_u32(&K[44]));
	TMP2 = STATE0;
	MSG3 = vsha256su0q_u32(MSG3, MSG0);
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);
	MSG3 = vsha256su1q_u32(MSG3, MSG1, MSG2);

	// Rounds 49-52
	TMP0 = vaddq_u32(MSG0, vld1q_u32(&K[48]));
	TMP2 = STATE0;
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

	// Rounds 53-56
	TMP0 = vaddq_u32(MSG1, vld1q_u32(&K[52]));
	TMP2 = STATE0;
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

	// Rounds 57-60
	TMP0 = vaddq_u32(MSG2, vld1q_u32(&K[56]));
	TMP2 = STATE0;
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

	// Rounds 61-64
	TMP0 = vaddq_u32(MSG3, vld1q_u32(&K[60]));
	TMP2 = STATE0;
	STATE0 = vsha256hq_u32(STATE0, STATE1, TMP0);
	STATE1 = vsha256h2q_u32(STATE1, TMP2, TMP0);

	// Update state
	STATE0 = vaddq_u32(STATE0, ABEF_SAVE);
	STATE1 = vaddq_u32(STATE1, CDGH_SAVE);

	/* write 32-bit words little-endian */
	vst1q_u32((uint32_t *)output,      STATE0);
	vst1q_u32((uint32_t *)(output+16), STATE1);
}

void sha2_p2_32_32_norm_loop(unsigned char  *tempOut,
                        const unsigned char *saltBuffer,
                        int                 iterations)
{
	uint32_t state[8] = {
		0x6a09e667, 0xbb67ae85, 0x3c6ef372,
Download .txt
gitextract_87p354ak/

├── .cursor/
│   ├── BUGBOT.md
│   └── rules/
│       ├── build.mdc
│       └── protocol.mdc
├── .gitattributes
├── .github/
│   └── workflows/
│       ├── e2e-test.yml
│       ├── gitstamp.yaml
│       ├── release.yml
│       ├── test-amd64-ubuntu-22.04.yml
│       ├── test-arm64-macos-26.yml
│       ├── x-build.yml
│       ├── x-common-test.yml
│       ├── x-release-linux.yml
│       ├── x-release-macos.yml
│       ├── x-test-canary.yml
│       ├── x-test-full.yml
│       ├── x-test-on-demand.yml
│       └── x-test-vdf.yml
├── .gitignore
├── .gitmodules
├── .jupyter/
│   └── jupyter_server_config.py
├── CANARY.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── apps/
│   ├── ar_sqlite3/
│   │   ├── c_src/
│   │   │   ├── erl_comm.o
│   │   │   ├── sqlite3.o
│   │   │   └── sqlite3_driver.o
│   │   └── priv/
│   │       └── ar_sqlite3_driver
│   ├── arweave/
│   │   ├── c_src/
│   │   │   ├── Makefile
│   │   │   ├── ar_nif.c
│   │   │   ├── ar_nif.h
│   │   │   ├── randomx/
│   │   │   │   ├── ar_randomx_impl.h
│   │   │   │   ├── crc32.h
│   │   │   │   ├── feistel_msgsize_key_cipher.cpp
│   │   │   │   ├── feistel_msgsize_key_cipher.h
│   │   │   │   ├── randomx_long_with_entropy.cpp
│   │   │   │   ├── randomx_long_with_entropy.h
│   │   │   │   ├── randomx_squared.cpp
│   │   │   │   ├── randomx_squared.h
│   │   │   │   ├── rx4096/
│   │   │   │   │   └── ar_rx4096_nif.c
│   │   │   │   ├── rx512/
│   │   │   │   │   └── ar_rx512_nif.c
│   │   │   │   └── rxsquared/
│   │   │   │       └── ar_rxsquared_nif.c
│   │   │   ├── secp256k1/
│   │   │   │   └── secp256k1_nif.c
│   │   │   └── vdf/
│   │   │       ├── ar_vdf_nif.c
│   │   │       ├── sha256-armv8.S
│   │   │       ├── vdf.cpp
│   │   │       ├── vdf.h
│   │   │       ├── vdf_fused_arm.cpp
│   │   │       ├── vdf_fused_x86.cpp
│   │   │       └── vdf_hiopt_arm.cpp
│   │   ├── include/
│   │   │   ├── ar.hrl
│   │   │   ├── ar_blacklist_middleware.hrl
│   │   │   ├── ar_block.hrl
│   │   │   ├── ar_chain_stats.hrl
│   │   │   ├── ar_chunk_storage.hrl
│   │   │   ├── ar_consensus.hrl
│   │   │   ├── ar_data_discovery.hrl
│   │   │   ├── ar_data_sync.hrl
│   │   │   ├── ar_header_sync.hrl
│   │   │   ├── ar_inflation.hrl
│   │   │   ├── ar_mining.hrl
│   │   │   ├── ar_mining_cache.hrl
│   │   │   ├── ar_peers.hrl
│   │   │   ├── ar_poa.hrl
│   │   │   ├── ar_pool.hrl
│   │   │   ├── ar_pricing.hrl
│   │   │   ├── ar_repack.hrl
│   │   │   ├── ar_sup.hrl
│   │   │   ├── ar_sync_buckets.hrl
│   │   │   ├── ar_vdf.hrl
│   │   │   ├── ar_verify_chunks.hrl
│   │   │   ├── ar_wallets.hrl
│   │   │   └── user_default.hrl
│   │   ├── src/
│   │   │   ├── ar.erl
│   │   │   ├── ar_base32.erl
│   │   │   ├── ar_bench_hash.erl
│   │   │   ├── ar_bench_packing.erl
│   │   │   ├── ar_bench_timer.erl
│   │   │   ├── ar_bench_vdf.erl
│   │   │   ├── ar_blacklist_middleware.erl
│   │   │   ├── ar_block.erl
│   │   │   ├── ar_block_cache.erl
│   │   │   ├── ar_block_index.erl
│   │   │   ├── ar_block_pre_validator.erl
│   │   │   ├── ar_block_pre_validator_sup.erl
│   │   │   ├── ar_block_propagation_worker.erl
│   │   │   ├── ar_block_time_history.erl
│   │   │   ├── ar_bridge.erl
│   │   │   ├── ar_bridge_sup.erl
│   │   │   ├── ar_chain_stats.erl
│   │   │   ├── ar_chunk_copy.erl
│   │   │   ├── ar_chunk_storage.erl
│   │   │   ├── ar_chunk_storage_sup.erl
│   │   │   ├── ar_chunk_visualization.erl
│   │   │   ├── ar_cli_parser.erl
│   │   │   ├── ar_config.erl
│   │   │   ├── ar_coordination.erl
│   │   │   ├── ar_data_discovery.erl
│   │   │   ├── ar_data_doctor.erl
│   │   │   ├── ar_data_root_sync.erl
│   │   │   ├── ar_data_root_sync_sup.erl
│   │   │   ├── ar_data_sync.erl
│   │   │   ├── ar_data_sync_coordinator.erl
│   │   │   ├── ar_data_sync_sup.erl
│   │   │   ├── ar_data_sync_worker.erl
│   │   │   ├── ar_deep_hash.erl
│   │   │   ├── ar_device_lock.erl
│   │   │   ├── ar_diff_dag.erl
│   │   │   ├── ar_difficulty.erl
│   │   │   ├── ar_disk_cache.erl
│   │   │   ├── ar_disksup.erl
│   │   │   ├── ar_doctor_bench.erl
│   │   │   ├── ar_doctor_dump.erl
│   │   │   ├── ar_doctor_inspect.erl
│   │   │   ├── ar_doctor_merge.erl
│   │   │   ├── ar_domain.erl
│   │   │   ├── ar_entropy_cache.erl
│   │   │   ├── ar_entropy_gen.erl
│   │   │   ├── ar_entropy_storage.erl
│   │   │   ├── ar_ets_intervals.erl
│   │   │   ├── ar_events.erl
│   │   │   ├── ar_events_sup.erl
│   │   │   ├── ar_footprint_record.erl
│   │   │   ├── ar_fork.erl
│   │   │   ├── ar_fraction.erl
│   │   │   ├── ar_global_sync_record.erl
│   │   │   ├── ar_header_sync.erl
│   │   │   ├── ar_header_sync_sup.erl
│   │   │   ├── ar_http.erl
│   │   │   ├── ar_http_iface_client.erl
│   │   │   ├── ar_http_iface_middleware.erl
│   │   │   ├── ar_http_iface_rate_limiter_middleware.erl
│   │   │   ├── ar_http_iface_server.erl
│   │   │   ├── ar_http_req.erl
│   │   │   ├── ar_http_sup.erl
│   │   │   ├── ar_http_util.erl
│   │   │   ├── ar_ignore_registry.erl
│   │   │   ├── ar_inflation.erl
│   │   │   ├── ar_info.erl
│   │   │   ├── ar_intervals.erl
│   │   │   ├── ar_join.erl
│   │   │   ├── ar_kv.erl
│   │   │   ├── ar_kv_sup.erl
│   │   │   ├── ar_localnet.erl
│   │   │   ├── ar_localnet_mining_server.erl
│   │   │   ├── ar_localnet_mining_sup.erl
│   │   │   ├── ar_logger.erl
│   │   │   ├── ar_mempool.erl
│   │   │   ├── ar_merkle.erl
│   │   │   ├── ar_metrics.erl
│   │   │   ├── ar_metrics_collector.erl
│   │   │   ├── ar_mine_randomx.erl
│   │   │   ├── ar_mining_cache.erl
│   │   │   ├── ar_mining_hash.erl
│   │   │   ├── ar_mining_io.erl
│   │   │   ├── ar_mining_server.erl
│   │   │   ├── ar_mining_server_behaviour.erl
│   │   │   ├── ar_mining_stats.erl
│   │   │   ├── ar_mining_sup.erl
│   │   │   ├── ar_mining_worker.erl
│   │   │   ├── ar_network_middleware.erl
│   │   │   ├── ar_node.erl
│   │   │   ├── ar_node_sup.erl
│   │   │   ├── ar_node_utils.erl
│   │   │   ├── ar_node_worker.erl
│   │   │   ├── ar_nonce_limiter.erl
│   │   │   ├── ar_nonce_limiter_client.erl
│   │   │   ├── ar_nonce_limiter_server.erl
│   │   │   ├── ar_nonce_limiter_server_worker.erl
│   │   │   ├── ar_nonce_limiter_sup.erl
│   │   │   ├── ar_packing_server.erl
│   │   │   ├── ar_packing_sup.erl
│   │   │   ├── ar_patricia_tree.erl
│   │   │   ├── ar_peer_intervals.erl
│   │   │   ├── ar_peer_worker.erl
│   │   │   ├── ar_peer_worker_sup.erl
│   │   │   ├── ar_peers.erl
│   │   │   ├── ar_poa.erl
│   │   │   ├── ar_poller.erl
│   │   │   ├── ar_poller_sup.erl
│   │   │   ├── ar_poller_worker.erl
│   │   │   ├── ar_pool.erl
│   │   │   ├── ar_pool_cm_job_poller.erl
│   │   │   ├── ar_pool_job_poller.erl
│   │   │   ├── ar_pricing.erl
│   │   │   ├── ar_pricing_transition.erl
│   │   │   ├── ar_process_sampler.erl
│   │   │   ├── ar_prometheus_cowboy_handler.erl
│   │   │   ├── ar_prometheus_cowboy_labels.erl
│   │   │   ├── ar_rate_limiter.erl
│   │   │   ├── ar_repack.erl
│   │   │   ├── ar_repack_fsm.erl
│   │   │   ├── ar_repack_io.erl
│   │   │   ├── ar_replica_2_9.erl
│   │   │   ├── ar_retarget.erl
│   │   │   ├── ar_rewards.erl
│   │   │   ├── ar_rx4096_nif.erl
│   │   │   ├── ar_rx512_nif.erl
│   │   │   ├── ar_rxsquared_nif.erl
│   │   │   ├── ar_semaphore.erl
│   │   │   ├── ar_serialize.erl
│   │   │   ├── ar_shutdown_manager.erl
│   │   │   ├── ar_storage.erl
│   │   │   ├── ar_storage_module.erl
│   │   │   ├── ar_storage_sup.erl
│   │   │   ├── ar_sup.erl
│   │   │   ├── ar_sync_buckets.erl
│   │   │   ├── ar_sync_record.erl
│   │   │   ├── ar_sync_record_sup.erl
│   │   │   ├── ar_testnet.erl
│   │   │   ├── ar_timer.erl
│   │   │   ├── ar_tx.erl
│   │   │   ├── ar_tx_blacklist.erl
│   │   │   ├── ar_tx_db.erl
│   │   │   ├── ar_tx_emitter.erl
│   │   │   ├── ar_tx_emitter_sup.erl
│   │   │   ├── ar_tx_emitter_worker.erl
│   │   │   ├── ar_tx_poller.erl
│   │   │   ├── ar_tx_replay_pool.erl
│   │   │   ├── ar_tx_validator.erl
│   │   │   ├── ar_unbalanced_merkle.erl
│   │   │   ├── ar_util.erl
│   │   │   ├── ar_vdf.erl
│   │   │   ├── ar_vdf_nif.erl
│   │   │   ├── ar_verify_chunks.erl
│   │   │   ├── ar_verify_chunks_reporter.erl
│   │   │   ├── ar_verify_chunks_sup.erl
│   │   │   ├── ar_wallet.erl
│   │   │   ├── ar_wallets.erl
│   │   │   ├── ar_watchdog.erl
│   │   │   ├── ar_weave.erl
│   │   │   ├── ar_webhook.erl
│   │   │   ├── ar_webhook_sup.erl
│   │   │   ├── arweave.app.src
│   │   │   ├── e2e/
│   │   │   │   ├── ar_e2e.erl
│   │   │   │   ├── ar_repack_in_place_mine_tests.erl
│   │   │   │   ├── ar_repack_mine_tests.erl
│   │   │   │   ├── ar_sync_pack_mine_tests.erl
│   │   │   │   └── fixtures/
│   │   │   │       └── wallets/
│   │   │   │           ├── wallet_a.json
│   │   │   │           ├── wallet_b.json
│   │   │   │           ├── wallet_c.json
│   │   │   │           └── wallet_d.json
│   │   │   ├── rsa_pss.erl
│   │   │   ├── secp256k1_nif.erl
│   │   │   └── user_default.erl
│   │   └── test/
│   │       ├── ar_base64_compatibility_tests.erl
│   │       ├── ar_canary.erl
│   │       ├── ar_config_tests.erl
│   │       ├── ar_config_tests_config_fixture.json
│   │       ├── ar_coordinated_mining_tests.erl
│   │       ├── ar_data_roots_sync_tests.erl
│   │       ├── ar_data_sync_disk_pool_rotation_test.erl
│   │       ├── ar_data_sync_enqueue_intervals_test.erl
│   │       ├── ar_data_sync_mines_off_only_last_chunks_test.erl
│   │       ├── ar_data_sync_mines_off_only_second_last_chunks_test.erl
│   │       ├── ar_data_sync_records_footprints_test.erl
│   │       ├── ar_data_sync_recovers_from_corruption_test.erl
│   │       ├── ar_data_sync_syncs_after_joining_test.erl
│   │       ├── ar_data_sync_syncs_data_test.erl
│   │       ├── ar_difficulty_tests.erl
│   │       ├── ar_ecdsa_tests.erl
│   │       ├── ar_forced_validation_tests.erl
│   │       ├── ar_fork_recovery_tests.erl
│   │       ├── ar_get_chunk_tests.erl
│   │       ├── ar_header_sync_tests.erl
│   │       ├── ar_http_iface_tests.erl
│   │       ├── ar_http_util_tests.erl
│   │       ├── ar_info_tests.erl
│   │       ├── ar_mempool_tests.erl
│   │       ├── ar_mine_randomx_tests.erl
│   │       ├── ar_mine_vdf_tests.erl
│   │       ├── ar_mining_io_tests.erl
│   │       ├── ar_mining_server_tests.erl
│   │       ├── ar_mining_worker_tests.erl
│   │       ├── ar_node_tests.erl
│   │       ├── ar_nonce_limiter_tests.erl
│   │       ├── ar_packing_tests.erl
│   │       ├── ar_peer_intervals_discovery_test.erl
│   │       ├── ar_poa_tests.erl
│   │       ├── ar_poller_tests.erl
│   │       ├── ar_post_block_tests.erl
│   │       ├── ar_pricing_tests.erl
│   │       ├── ar_reject_chunks_tests.erl
│   │       ├── ar_replica_2_9_nif_tests.erl
│   │       ├── ar_semaphore_tests.erl
│   │       ├── ar_serialize_tests.erl
│   │       ├── ar_start_from_block_tests.erl
│   │       ├── ar_sync_record_tests.erl
│   │       ├── ar_test_data_sync.erl
│   │       ├── ar_test_inet_mock.erl
│   │       ├── ar_test_node.erl
│   │       ├── ar_test_runner.erl
│   │       ├── ar_tx_blacklist_tests.erl
│   │       ├── ar_tx_replay_pool_tests.erl
│   │       ├── ar_tx_tests.erl
│   │       ├── ar_vdf_block_validation_tests.erl
│   │       ├── ar_vdf_external_update_tests.erl
│   │       ├── ar_vdf_server_tests.erl
│   │       ├── ar_vdf_tests.erl
│   │       ├── ar_wallet_tests.erl
│   │       ├── ar_wallet_tests_ES256K_fixture.json
│   │       ├── ar_wallet_tests_Ed25519_fixture.json
│   │       ├── ar_wallet_tests_PS256_65537_fixture.json
│   │       ├── ar_webhook_tests.erl
│   │       └── fixtures/
│   │           └── ar_packing_tests/
│   │               ├── spora25.100kb
│   │               ├── spora25.256kb
│   │               ├── spora26.100kb
│   │               ├── spora26.256kb
│   │               ├── unpacked.100kb
│   │               └── unpacked.256kb
│   ├── arweave_config/
│   │   ├── README.md
│   │   ├── include/
│   │   │   ├── arweave_config.hrl
│   │   │   └── arweave_config_spec.hrl
│   │   ├── priv/
│   │   │   └── .gitkeep
│   │   ├── src/
│   │   │   ├── arweave_config.app.src
│   │   │   ├── arweave_config.erl
│   │   │   ├── arweave_config_arguments.erl
│   │   │   ├── arweave_config_arguments_legacy.erl
│   │   │   ├── arweave_config_bootstrap.erl
│   │   │   ├── arweave_config_environment.erl
│   │   │   ├── arweave_config_file.erl
│   │   │   ├── arweave_config_file_path.erl
│   │   │   ├── arweave_config_format_json.erl
│   │   │   ├── arweave_config_format_legacy.erl
│   │   │   ├── arweave_config_format_toml.erl
│   │   │   ├── arweave_config_format_yaml.erl
│   │   │   ├── arweave_config_fsm.erl
│   │   │   ├── arweave_config_http_server.erl
│   │   │   ├── arweave_config_legacy.erl
│   │   │   ├── arweave_config_parameters.erl
│   │   │   ├── arweave_config_parser.erl
│   │   │   ├── arweave_config_serializer.erl
│   │   │   ├── arweave_config_signal_handler.erl
│   │   │   ├── arweave_config_spec.erl
│   │   │   ├── arweave_config_specs/
│   │   │   │   ├── arweave_config_spec_default.erl
│   │   │   │   ├── arweave_config_spec_deprecated.erl
│   │   │   │   ├── arweave_config_spec_enabled.erl
│   │   │   │   ├── arweave_config_spec_environment.erl
│   │   │   │   ├── arweave_config_spec_handle_get.erl
│   │   │   │   ├── arweave_config_spec_handle_set.erl
│   │   │   │   ├── arweave_config_spec_inherit.erl
│   │   │   │   ├── arweave_config_spec_legacy.erl
│   │   │   │   ├── arweave_config_spec_long_argument.erl
│   │   │   │   ├── arweave_config_spec_long_description.erl
│   │   │   │   ├── arweave_config_spec_nargs.erl
│   │   │   │   ├── arweave_config_spec_parameter_key.erl
│   │   │   │   ├── arweave_config_spec_runtime.erl
│   │   │   │   ├── arweave_config_spec_short_argument.erl
│   │   │   │   ├── arweave_config_spec_short_description.erl
│   │   │   │   └── arweave_config_spec_type.erl
│   │   │   ├── arweave_config_store.erl
│   │   │   ├── arweave_config_sup.erl
│   │   │   └── arweave_config_type.erl
│   │   └── test/
│   │       ├── arweave_config_SUITE.erl
│   │       ├── arweave_config_arguments_SUITE.erl
│   │       ├── arweave_config_arguments_legacy_SUITE.erl
│   │       ├── arweave_config_bootstrap_SUITE.erl
│   │       ├── arweave_config_environment_SUITE.erl
│   │       ├── arweave_config_file_SUITE.erl
│   │       ├── arweave_config_file_SUITE_data/
│   │       │   ├── config_invalid.json
│   │       │   ├── config_invalid.toml
│   │       │   ├── config_invalid.yaml
│   │       │   ├── config_unsupported.xml
│   │       │   ├── config_valid.json
│   │       │   ├── config_valid.toml
│   │       │   └── config_valid.yaml
│   │       ├── arweave_config_format_SUITE.erl
│   │       ├── arweave_config_fsm_SUITE.erl
│   │       ├── arweave_config_http_server_SUITE.erl
│   │       ├── arweave_config_legacy_SUITE.erl
│   │       ├── arweave_config_serializer_SUITE.erl
│   │       ├── arweave_config_spec_SUITE.erl
│   │       ├── arweave_config_store_SUITE.erl
│   │       └── arweave_config_type_SUITE.erl
│   ├── arweave_diagnostic/
│   │   ├── README.md
│   │   ├── include/
│   │   │   └── .gitkeep
│   │   ├── priv/
│   │   │   └── .gitkeep
│   │   └── src/
│   │       ├── arweave_diagnostic.app.src
│   │       └── arweave_diagnostic.erl
│   ├── arweave_limiter/
│   │   ├── include/
│   │   │   └── .gitkeep
│   │   ├── priv/
│   │   │   └── .gitkeep
│   │   ├── src/
│   │   │   ├── arweave_limiter.app.src
│   │   │   ├── arweave_limiter.erl
│   │   │   ├── arweave_limiter_group.erl
│   │   │   ├── arweave_limiter_metrics.erl
│   │   │   ├── arweave_limiter_metrics_collector.erl
│   │   │   ├── arweave_limiter_sup.erl
│   │   │   └── arweave_limiter_time.erl
│   │   └── test/
│   │       ├── arweave_limiter_group_tests.erl
│   │       └── arweave_limiter_metrics_collector_tests.erl
│   └── randomx_square_latency_tester/
│       ├── .gitignore
│       ├── Makefile
│       └── main.cpp
├── ar-rebar3
├── arweave-server
├── arweave_styleguide.md
├── bin/
│   ├── arweave
│   ├── benchmark-hash
│   ├── benchmark-packing
│   ├── benchmark-vdf
│   ├── console
│   ├── create-ecdsa-wallet
│   ├── create-wallet
│   ├── data-doctor
│   ├── debug-logs
│   ├── e2e
│   ├── e2e_shell
│   ├── gen-dev-certs
│   ├── localnet_shell
│   ├── logs
│   ├── shell
│   ├── start
│   ├── start-localnet
│   ├── stop
│   └── test
├── config/
│   ├── sys.config
│   ├── vm.args
│   ├── vm.args.dev
│   └── vm.args.src
├── default.nix
├── deploy/
│   ├── Dockerfile.base.ubuntu20.04
│   ├── Dockerfile.base.ubuntu22.04
│   ├── Dockerfile.rocky
│   ├── Dockerfile.ubuntu
│   ├── Makefile
│   ├── build.sh
│   └── create_storage_modules.sh
├── doc/
│   ├── ar-ipfs-howto.md
│   ├── gateway_setup_guide.md
│   ├── path-manifest-schema.md
│   └── transaction_blacklists.md
├── erlang_ls.config
├── flake.nix
├── genesis_data/
│   ├── genesis_txs/
│   │   ├── -M5_EBM4MayX8ZpuLFoANHO00c4pdrSmAQbPYv7fq4U.json
│   │   ├── -wzIQJ19Hq8Zyf1L85Ga3uGTrdWA2W-UNyr8aH4a4iE.json
│   │   ├── 00nFXThK86Aog_HfLJc9j0nnXzXSlU6VdGC8qZc5ekI.json
│   │   ├── 06dr4mrXcKlfPbK8t9vWOBCDJznyG-AsKxED-Jr0U88.json
│   │   ├── 07u3F6WH-ohqBclh6UanAQ9Tau089eLJrIYM-8qkAbw.json
│   │   ├── 0EzNUQy_5b7CwNNLVAi7CnameMgnxVh-XyahT2kn74Y.json
│   │   ├── 0FJrLrxrFkVTBwRrzCCh88Gm2tG1xPxg8s_IuRZDVzw.json
│   │   ├── 0Mxvgz6_wL0FBOxJmHcRcNwiaV8B90whDxG4Vh_GFic.json
│   │   ├── 0O-UnzBvSFYoMQrbcsKHRH_YqNNylC1n9KWXmm-rr90.json
│   │   ├── 0_GKZOdtRH-nc094U5kFBlvQSjPz_oX0tcIroqLFD3U.json
│   │   ├── 0biLy8DoOhucpeYzOj5jnopxxwe0XDRfCOMjyz_a74U.json
│   │   ├── 0mFNtCi-u34uwOj3BimQTPOT9PgLGE8uqCbtXhnwoKI.json
│   │   ├── 0ogs8DTdSrNxfE2LzrScPvnyf7CQ7jMdFaS_l0-K-GU.json
│   │   ├── 0ooE635sVsd6vdhX3Pb8Ufvuqd7XRjfUbG2eXde_CmI.json
│   │   ├── 0qob-AeHGTS5EDamY6Mtsnxf1MCyUk18l09bqHAYQjU.json
│   │   ├── 128KaPgVaZyrl8Vuzt795ZlWidERzih15pNDAJgahI0.json
│   │   ├── 1Lwuom2q3FFI2pZz5EYgOzJRymgVWE3F9ZIl4vi3-kU.json
│   │   ├── 1Q2plP5JFTLwdTC27VfIgDJ-ri5h3mVsKxZploTrRmQ.json
│   │   ├── 1QoMjs6Q3XKklJ9LfovRmGbe4bAy9xY247JfDZqN3Eo.json
│   │   ├── 1nu07yo-0eB5GLxIJzzlxZW6nFTFiZ3XCDobJUcNyP4.json
│   │   ├── 1qVeYpf2sY8Qkz0iVomVPVb15NA7QUtF3eFDoMwa8PI.json
│   │   ├── 1xh_NCIFYbprcgNM4AVvZ47jRxsQmJYvCG-L-oEK4iE.json
│   │   ├── 1yvqJKdnb9SRRKoBg1m0kWAsSh9S0R5r9T9TE0YHfRQ.json
│   │   ├── 21Kfm2Apa8QWeqdMqyQAcxg9HbiluZXfQFu4-6xe-AY.json
│   │   ├── 24VRr4yT-_fOndcFYtK2oSO-p9Pm6lNtzQv8E-U43Bc.json
│   │   ├── 2vn7V0FR0JMXrVbj3Ofvc_2nvrFYCCpRoFjc7UYpJcA.json
│   │   ├── 328-6fOVCfCid4QTxHjkAMkQLMHZgDg-hZo5PnVfp2Q.json
│   │   ├── 3BSgxVi4vtVtgMBtDE8xPMqU0PmkiKtKX6P_Iw0kMsM.json
│   │   ├── 3MMMUrHDmjbCn_-TOZJJHvjLBp8PffZKUNfm_Ziy0Vk.json
│   │   ├── 3Q5gJrbqc-PeOvD4QQ4WCNp-f5cYzTyHyg6P9b-WvwM.json
│   │   ├── 3T6mnguMWl8GeiqZWiBZrGXHHtwm12mIWciusoSACkQ.json
│   │   ├── 3khTH_o8WZHSCzP-AThkmt7zZL-d_lcqUKC8nz7c8lk.json
│   │   ├── 3ku6XelnvBsaRjoNxDWb_kT_PRlQ88U0pbWURziCj7s.json
│   │   ├── 4LwZwAVcaBXhXsP5b4mnE11tUXefuRUTtTibtvoozDQ.json
│   │   ├── 4UEhkNbsGdJUjx1lJQgX9KorwSf_RRZG8VMW6jMmf8Y.json
│   │   ├── 4bPVo0hCI3E-ry2mBjvOZsBpNwPM108NT0vnJCxCeJw.json
│   │   ├── 4ewYAvsgaT-6Oy23qPqK29O_AgfvNbhLvol13yN1PdQ.json
│   │   ├── 4gLPD5njSRtiaJwjcjmNOyI5Vw8sFBQQWOefmy4SPmQ.json
│   │   ├── 4pNPqxodBesN6jQl51nH17GA1fWYfHVm8cIEfusnPLY.json
│   │   ├── 576xa7WLVidNoEcYPhAm7OlyYgbrp7Z1RBIfqLbVFzw.json
│   │   ├── 5FL2C4l-5cTl9wg4CblgIxzko8hGsB5URVA_yTAd4Nk.json
│   │   ├── 5Hatfzkj7ivvIsUIDjdOSp-4CdkClH6B7S_SNX0B2-o.json
│   │   ├── 5OdjYWAipCjWzpqfNoNhyJ673d4pRMNva8la_SFfu_c.json
│   │   ├── 5WKzIeQrDGC86IQvl2NhRtgPNKHGRA9oyjRByV1F7p4.json
│   │   ├── 5dsjbEwH2r-EWCkfOznV4JkCOLSK9vNY-0iqPr4RZUM.json
│   │   ├── 5mt79Uz6p83vdLtYRiByyWLqLI2GZBeSTutDRmzw7tM.json
│   │   ├── 5qRekKepIlFbUhGMq_nNy89bzx_K44e4GmUKYAe9MRU.json
│   │   ├── 5ynd-L6Z1vrR7Vlyr-rkrga_Jw2ibALkIgldNmsVRcQ.json
│   │   ├── 6GNIVQ-23jPJTxQkQITbSKE7SYm6J3MF4qbSgH3-AXU.json
│   │   ├── 6J1sN2nhGpqe9iJwgdfnxxCK4af88__HoEG8MLeqtyM.json
│   │   ├── 6NaT-Mz8QAiQS8atFaOu_ezqZnfu_XaQb-Grng-hvHc.json
│   │   ├── 6YbxtptbO-sidrnYdgn0G_CiNBh-az5ZzWrSCP9DYKA.json
│   │   ├── 71M1E7A4e0PFW_6C0gly77iCg7ykX17647i00eEiA-s.json
│   │   ├── 7SfLhJLtevo0zu-1bo8q6zX98WbGgpDNuY6PXbzS_j0.json
│   │   ├── 7kT0is0QnxdjqkPi0BKamhLW6z6_SK55LMAVKQC6F0M.json
│   │   ├── 87ieWrloTFUdW7YjJqJcINd1M_PBWCzA1dIRFzF4RKM.json
│   │   ├── 8b-7D96aRFJgDm8z5Tg47vBbdjseW0rRi17TYDcaQ5Q.json
│   │   ├── 8gTAwQ3f17PKI9KCX1cjuXCs9F8Hcdz8KyhsecKuCJ0.json
│   │   ├── 8rKBfpmkPlxnnYr6t0xIpUDubdidK0Fpnois7-xQJtc.json
│   │   ├── 8y-ghHqMT2lEHQn86jRXkQ8I5cLWWtKW1CQROp8mzIs.json
│   │   ├── 96Ijx5TWSxZmZaDH1pteGHFjIYY0aHmGWNHiMYeSYIM.json
│   │   ├── 98kadyXY0OPfEZKeeZcCyQ7z5mRToZklK-D6f1a-Lxw.json
│   │   ├── 9JWfraRekKtgXiIjssn0tVSzhaCaN682jECsrKtR0_E.json
│   │   ├── AN48OPO2-1mh4PKtpyoNm7SWJK2j8dF0-TFLU7Z1C9g.json
│   │   ├── AX6ZZxDpFlNhoN5Am5Hi4DER4zOBGVnQm_bse5PfHNw.json
│   │   ├── Achd6pqJVZ-1vNMLC977Lu8f20eBmgAv4dIddXql51s.json
│   │   ├── Ah6I8y8q0jb15KXjn0PyNfe7FR3v2xobg09Lfj7n1Mo.json
│   │   ├── AoSTMf_ZxlcY12bK6_sWj02kssD00K4E-vkHx2vRxG4.json
│   │   ├── B4e9FBfqZGBszHAhZqTq-TNjb-oG7rYdlMWrQa4CPZU.json
│   │   ├── BQ2RVL6XY99AIkPKDBCfUfRmJGejkZ8YKgKZc2LewhU.json
│   │   ├── BRD5ARo8tiY64RqIoxYZ6jwbE-LQT_7jA513nHwWyRE.json
│   │   ├── BYJCPwCLpd9a5K1HFy5F6ZvnemPiPFtV4hz5wMHr1NI.json
│   │   ├── ByvrfeR4UNmWJwF2fU41mBo6ThFl49u24rEGpbeSI0Q.json
│   │   ├── C3auX8HXhc2dChmvSBUfgGyYynuAr6P3g0p7420GG78.json
│   │   ├── CEXuGv3KvVtkf5gkV0ip3g1FF-i12WIDo6IOigORIZA.json
│   │   ├── CMr-rV5FdlQcRBo4loZzj66EFqwHBmA36tWiRMKGigQ.json
│   │   ├── COXhhpbcLSEe2iP2kp4SDj5NjjBAC8CucsAgOHRF_lc.json
│   │   ├── CSkFcCmNgvnp7jp7aK0tEGsLWiZVMF-QBkEFaJrAG48.json
│   │   ├── CUu1gtu6L5tJxkOAu13tNBGDKECohV8M4qgCOOPNtas.json
│   │   ├── CZ181FVir4NaSJ7JsVb50-xCaZtd3dmKbDer7jpTSyI.json
│   │   ├── CbV_CDXgVNjV6fyoBDkYmbAcaC5VsLDYXgEIwj2Ewyo.json
│   │   ├── DC6gmByeCki7uyXHJhX_A9x3pkMgmJ8Tv6wDRnh7vGs.json
│   │   ├── DDrS8BD0XTUVJt5E8kwisVTBX4PBWp0lCnSkSD3PJto.json
│   │   ├── DJf1SRoKaPo1h3F-7oKIMu4A-r9dXXMjE57WQilPdTk.json
│   │   ├── DMtXbcR_qHwdYXvkuCGOQARs_QtN9iWPw4x6TTaWOcw.json
│   │   ├── DQ6WaBfLEMEFhKoMoutuPyO_zFg1hWTDXT13CD8n1nw.json
│   │   ├── DTGNdsYZDXoU1nE82yEjG5ZEssxwUmkFTkM3_i6oSx8.json
│   │   ├── DkBAprUInkCbFa6A_WJJNL1z_PnhEavvyZtF09lmyvw.json
│   │   ├── DpEoi9F4g952ajGuT4g1HWY-xndyE77dn0VfdNXkrC8.json
│   │   ├── Dxrsx0xuPVY7oz9yHbL6wOFxo6ws7ycVe778C2bc9J8.json
│   │   ├── EPZ0hBh1wp-7T4JED4v6DOItd-9MNWkRfbLyizDLBsE.json
│   │   ├── EQh5rYFJ5Z5yESi4DIuvl2n6iVZS899tA6V6rf2Xwhk.json
│   │   ├── EUMtkWCJU0L23RnhXKfQ1wtD3Jh2O-vpFnLcQXynoAQ.json
│   │   ├── Eeo6rANLMAXonDFLDG2nu7n99O3Ymfk01wYXJBbEixY.json
│   │   ├── EnPMt9yzTsxLPR5mD9zUvndxicdYBUNzOlcCPvQlOK8.json
│   │   ├── EvKHSfokNyuiTarFKOuQ_-SaBwtllGpQGc7IFkRfBfc.json
│   │   ├── F5R2EA-gM8AtQ9_NymKwtr_Im3_ljMR38ndzCs5c77Y.json
│   │   ├── FTYnf3Z3QqEpNzTigfAlGTkgpgCWtFA7R8i-I1ik_Vo.json
│   │   ├── FkZzg_-5eSdFlbq9XnHe3wRhYidHJPXwUQ6YLuJijS0.json
│   │   ├── FmfkuPmh0vkdv_qbjXBUX1sQ-DmwBFbjuC4punobGy0.json
│   │   ├── G1GqspPmLkJTiT35QUTWBT4def7j5ORSfHCtrYzrrng.json
│   │   ├── G5FyMvm8E0_07vFgz-XISJN3VEviSrbtih9_Wptef9w.json
│   │   ├── GlWMQUuiL80knS07G7NpoYat3w18VMuyLEuC_Pmijng.json
│   │   ├── GypgExivgblZSA-1n7KjdI0SJOyXwFJkuzzPWS4NID8.json
│   │   ├── HFUR5ZwLihdaonJWHRHBuLay6cw8ZMV0bM870xhE6Qk.json
│   │   ├── HSlgnBu2Yxros7zyehPgiu2u7h80dJfCCqrA88UnkB4.json
│   │   ├── HTt6lPYQfcIgUxKPjUt3aQrpwE5e3UA4UT2EI9RxSbw.json
│   │   ├── H_0S6x36tsFH-x1h77jV_zzGGp97V8UjmgC0RZYwbtM.json
│   │   ├── I6s8Z6gEPLQABFstkCoLVv_gdQNGb-uuMMut-R7q2hA.json
│   │   ├── IACLRsWq-T6aesGEAjfFTZJd2sy7sFvWL7O6FI9A39U.json
│   │   ├── IJsiiIbd-Qs39TAJ67hiRJFsBye_rgQdU9GBid_PnZw.json
│   │   ├── IQgiEwMLp1bb6muuB_G7Q3sRaaZ3OZHUSjgshUq5YMU.json
│   │   ├── ISiC3yaTW9KnZmgs39osghIg0HP8ISh77bzH7u2m55Q.json
│   │   ├── IpwG_74praZjsu9L91_KWYHrVTpEDwyHZrsHgum4Z8o.json
│   │   ├── IvyUOghXQ31LnYE3bYEkS82gTAvpIa1rGGQKmiJuuMk.json
│   │   ├── IwSIt1P5I_mM-gAeAvXiyxRVb73hqkQAMfxLIHbbZYk.json
│   │   ├── Juzb8MlmGd2qomIUwgfGzIFO7c7ZcY87kJPmqpSkt18.json
│   │   ├── K47jh6Jr6TmZeZ_TadmyLLy1V6ZvLNpvV5FWcICohnk.json
│   │   ├── KOm2FJzmNXa_yjYC-58DkysCdk7FRFMcRmBx3DF6S9A.json
│   │   ├── KPNGfBMOznCXZwOVvCXHRR6sVJx1akVkmXTV98lCMKY.json
│   │   ├── K_ae8Bfvql0dGhIfRH-R7W-zWoeB95kYGJNi3HjFyrs.json
│   │   ├── Kgr-XWwHYos5Y95ZJ9mAUwjYjj_rP0I-GnWctQDNlp8.json
│   │   ├── KhQeu3CG_X1zoHbyy99GUlC9gVFFexf6vVPOlLgCj9I.json
│   │   ├── Kl1zrMIDIC9yW8yLMnSKQYDoV0PY41ymzJQw91qaZvY.json
│   │   ├── L8tkBBP7fyYfK4txqP-fGk_ODOU4UfIgFV79O-qd5vY.json
│   │   ├── L9J9SkTWI_Fx5KhujeWGokIchHTSFlSIC0blr0JIz80.json
│   │   ├── LBTipZADoYfO-9UecE07Z83ijiLl0f2wAGXyRFQqKCY.json
│   │   ├── LC-_5GDhs09OvN7r8GPmjMa6A9xSeVtsAmDgYCgspvc.json
│   │   ├── LFQ5iV6E5wyBbJmJoFJdH39ZxfW-y7mZFKou2H-ONvg.json
│   │   ├── LJ2QSdjHftgyCOSgy9Ub0OkTTN25rxCY7D7mt6u8Uy8.json
│   │   ├── LUdFh6g9auj1LRtk8IUwLoY3e91jIkcSyPKuQQekPY4.json
│   │   ├── LiitFWnODMUA7esa_f49IiMEdN7cTKoKw1cgG2J_eNE.json
│   │   ├── LixFbPqM1ZZ-5JWo339FMfPCpD_6M85rVK8IVmmt8m8.json
│   │   ├── M7oOLbk7TPBanLCS0pzkJSbV1CYoJabbsSDe_pCjhEo.json
│   │   ├── MOoLwb8S881q3-gM4GK7DuCEoh5CZnF1tMIZG300X58.json
│   │   ├── MPP4fxmSkvM2BVq8rumeT5yvDNu3QAT_kqpOlAq5s2E.json
│   │   ├── M_wQsQbFGtGiEaH0uW2swBubAnFab3ZcCN8IYWZvVzo.json
│   │   ├── Mk8XJgQPSOIsx_QX_XDPxdEG5NcKgO92q9i37uLZsrs.json
│   │   ├── Ms9gCRdVwT9u8-ewYd6c-T0bet-n24n_q_Hn0-BlMow.json
│   │   ├── Mv-TFhA3639O4JbKzoO3wo8LNPcFwA_vaaOLHfWRfSo.json
│   │   ├── N3lqe8CUwPfChinYVV4OZZQNjtXc26JkOJyqgoKhq7E.json
│   │   ├── N6-1fOVDkoeDwKyoNdLxCVoyy-c0EF178A_oQeEchs8.json
│   │   ├── NBxewjnZAfekK0hKmwL_OpF1521JTeIpLk2a2TLDnTk.json
│   │   ├── NE7AIvW60iQL_6aagNTSiaMpmLfAfRwbxau5FZLA10g.json
│   │   ├── NEXnMz8Yuw-xfIPprKT2iwx5A1UjWwRHCH7XCpeXIPg.json
│   │   ├── NPLj86idALmTczSq2vrZdTs0bjI-e-KI0j3EOWWpu54.json
│   │   ├── NptjIrqZrQMSdLbXAGyQCr8audCzArV3EofsjRCqrQw.json
│   │   ├── NvGRQrdis2HV22enpSpPqsb0M8s-pN_nl7eJtalZyC4.json
│   │   ├── O6qlkPRgr7H3WLHjVov-CTm-q66Q4TuvhP6GC-c5ZjY.json
│   │   ├── OILhne7UcvACtB4peA4osAjRMthaZZSW9OWhe3NpLBw.json
│   │   ├── OIOqGvvuafD_5J9QzfxyPiNlnqzIcL96i6u4PTUeDmA.json
│   │   ├── OaumRLT8oE6J8gqrQ9DrY_grMuSfWtai95VnqrX24hs.json
│   │   ├── Osgzf9EDK9j7TMlqSJ_5Y1rzZgOA6qfR7ktiakLPk4A.json
│   │   ├── P_pvvzlCIX7Yaiuv6zt1voLcn69gb9jAHPRhHaHjLng.json
│   │   ├── PjeEg7GpKT8twlBkp8GHAsEqfMvmNd3RaAx-l0R_i2w.json
│   │   ├── PySb_0NIjROmsIgwz4kMwC9MVmeY1MwuKdil0WeUzxw.json
│   │   ├── QDBM2PowqCX0eUCKzgV-DgdzeDz5TXLKYS3HVXLyqoo.json
│   │   ├── QDbVk-efwdVbHDGL1vZO3mQ3g65ol5RR-1wOvPLUkkE.json
│   │   ├── QJlE99-614f6XzZ-7VctQjX9DYe5wnO21aHSgg1RhnA.json
│   │   ├── QR75we1zHW-qO7dsI932kXX0YrAIyuC2XIDRhfmK-fE.json
│   │   ├── R0Mhun4e-WmLLGxnJq4SDTRqyNvTDTKC-uXuol1s63A.json
│   │   ├── R2h2i6y-KFxuHukxmHIjSncPZSiS4tpuzH0tD1NAooI.json
│   │   ├── RU5mkM_3UrjRMffwgj7ovDMYxxjhfXvliozhpIqw0sA.json
│   │   ├── S5Uv2W6erubrzYjzm9QHKij51XE-j-GFdYwcV2uPIAA.json
│   │   ├── SBhaeMSTQm3rS6puYacdT-4wzlnkBlZ1agn6IW6Oyg8.json
│   │   ├── SCN8yn0cQASui1DeV4mMYeQrRn8eXKr7Cp9ll7L3UfI.json
│   │   ├── SHxtj5_gLdJMI-6CcspsDbFBuU_74df3I4-sAJkAr6w.json
│   │   ├── SJXMM0tlXown7l3ffjhsiKf311FDTRa7QkKX8tgyEZ8.json
│   │   ├── SWNkfm9ZZPCiYKFg6oIW_IgqJp5Ypbp-Fs9S7YgPm0c.json
│   │   ├── TFX7m_Kf56rV6LNuyQ31NeVoDHJ3x0YqhIv4-IBQ-3s.json
│   │   ├── TGdhJ01pPw49A0ZIaCCcYBnL-RPK_3KZH3cA6E9dVqc.json
│   │   ├── TGp-18LYjSWQQ36gs5prU-vDgteOL79aywxXoDS-w0c.json
│   │   ├── TUIdVI5yQH50laHvkxgAnTV6uuE2LXXH3pxIe6Q2S7I.json
│   │   ├── TkN4QLdC4tu-_Po50RYwF33shyHcanHSe_BKpryK0JA.json
│   │   ├── Tnf6b1F67AEV2r9Flj8ktSSHYoV8SeL9dFvHRkavlZo.json
│   │   ├── UMk64563QZfxgZr_vKOTDrcp5XJNENF82Pji4a078YY.json
│   │   ├── UYoJMT0QxMtB6ctUB-9iQlcx6fF8R3s8ahM4_iF4wiQ.json
│   │   ├── UdCfZG1jBYUKgeLc13zjRxmQHO4_13B-NigE57jmJ5A.json
│   │   ├── VUfaTp1eAzjnbxLR6xx_qQGVn_WOTna3rTolM8wY5BA.json
│   │   ├── VuXQZjhUaZ2Hyi6Pl8_VTOu2mUWjoEemYb5TKXPFOS0.json
│   │   ├── WE5eBi6hEq90HQvDjtJr-EmZATWJthgxh3HPPuQ7410.json
│   │   ├── WsYJKhqhppBF6_eGbd0OACdu3LU6-CUuMcLeG3ST2qc.json
│   │   ├── X9biR_ZA-rnpzk4gfLi0-pBSsjjT2l9Rk0VfYwf1WMo.json
│   │   ├── Xjz72yVLd_Qzl8_GfSPqZA1MAkxxhjr2Lsf2tGCj_ZQ.json
│   │   ├── XtDRu-1SyoRL21gpKcxWtxyksVwTF9kvW26hvQ_bPzE.json
│   │   ├── XxgirNr3QGaJTKxPWqK9byYLj7SdbfZudKd9rbynWyM.json
│   │   ├── Y0PLaTBQ73JXn_jHvldOKC3jdbqDbqTMkcW0x65_Jek.json
│   │   ├── YIEEyYfNIRSjzm_gzv6l5CelyL4AOzKX9M4XPXRk2Yo.json
│   │   ├── YfHEyNUGsOUiuqCgHV127cg2Z5Yap9tcQB1LH7tq9ZA.json
│   │   ├── Ykh5TAI6koBN4UTQZ3GNIDr_uHNjlpHH9HsvtEkoWLA.json
│   │   ├── YlalzFjBD8CgZxDlI6eNWE3PIIflHGzXyY9VzPPeCFo.json
│   │   ├── YukfPvGxtYmXFF6wJjDiZcvqmH5YItxwsoLbMxWCVFg.json
│   │   ├── Yzj2WZ-3q5vKkBJtrmGlVjZND7iqtzvMRafS0TnQiLE.json
│   │   ├── Z5e9G5QMZ_scJQ62qoqUs2XSuhknTuuAIhhGmfg3Ye8.json
│   │   ├── Z6IgRWClifhTSnomxJet2WLw8UUaslmqAi2nynj3Ke4.json
│   │   ├── Z7gfizrPOypT4Pagg3oli5g8wA8pbKB0ZJnrw-FVyys.json
│   │   ├── ZAk05et7CFN69E9NwET2mSRI0ISRigjMEjcy8kbO-Y8.json
│   │   ├── ZC44Bxrx6AtNJYLwhvpALuINZRBXklme3tpeJbJ2rdw.json
│   │   ├── ZEB62vqKvkPK2s_RmxgQ2IhafMxJ_TXCGswrrKLhYiQ.json
│   │   ├── Znw-6H_ayGJBReeQm9z9WKulBH1ZzrOovdMsNPcIe_Y.json
│   │   ├── _01J_SIBJ164H0EedSfQ8h0dMfqet66WKHwcOFQEsMc.json
│   │   ├── _Hf1lw_E6Lyd-0PGkCRQaN10cdEx4M-hl9y-zWiDo8k.json
│   │   ├── _QEE09XylMYgab9MYPvrrMy7v1jKWh0bGwqFvsBsO8s.json
│   │   ├── _fLFu_BOzTEPdX35rqUruuyNxi7f_La8T1_JG7pIPd0.json
│   │   ├── _u44CiJCcYiOrGffgZoQSmUrJe8CfYD7Nw0MdPX0tUw.json
│   │   ├── aGqWG70qjD5P8spXLMtyXnYxS9k7Net-u932EyIFl28.json
│   │   ├── aPxbCROotxwkdovWbQEhw18UNAzVy-AmjYwjo9lb5u4.json
│   │   ├── b96k6w6qUyLSSWZlmupyBmav6XYMsdt0xTc2yIUZtOA.json
│   │   ├── bnT7410oaZtnCdurp5jNgLKju9d_RRxhgggnxa5frMQ.json
│   │   ├── bqhG__MMablNhNpiSp8nopeKDCzXy97jLuSBlsKk_u8.json
│   │   ├── cIXdvNTNHJSmA6Rt5UgSNfMcGfvxDnYTa3a1ulS1SiY.json
│   │   ├── cgU_TlXi5gJ7hShSBYsS4UVi-sLTtfFv1y1sy2nNhos.json
│   │   ├── chdl-kIl4zG7VcJbKk0Q_5TeGwuH8Xp2YFPLRJJKTWw.json
│   │   ├── dYBZuFcCEgGVcfXgS9tmeJsue_qwaCRO3Mg2OHCZh_A.json
│   │   ├── daTnztzTMlA8Ras9XgQ05Fr9ZYwOg4-UDfjW875yQeQ.json
│   │   ├── dn3p_BqD1gIcZQqdA8r6TucwycKGave22IqNjzKSHqI.json
│   │   ├── drYsyF85HcvC7LM1hkzPPgTj3_zp3amcNVNobBmOxvc.json
│   │   ├── duSw-WaGKAabAztyg2zkj6hjgaVaRGBrJuvZ5Gd2Pzk.json
│   │   ├── dv28G4IsYul7liWrycsx4UKSYHA4sWUY6xFQzRPi4p4.json
│   │   ├── eGhF0za2qN5WuadlVZ1iak1S5LxXswHRzIa3j_P-sUM.json
│   │   ├── eJ2aSQ4nm-i8XAZW2pcRq6GoEjW9K8EBM6w7rLiuSHw.json
│   │   ├── efqI0eDfp0OcYB-Ms5ELukIUr8-qtlX7Ica-ikhVZLU.json
│   │   ├── ez-ItWkyBvBZ6J7_Mobrpqc9RTp6I2JBmkPDV_xCQVY.json
│   │   ├── f3jE7NK419FZzwkx9VjTkrcX5FEgl2Ky3KSK0vH-wj0.json
│   │   ├── f6MY8LMCwGbKZqXd4dkCROQK0qFMjS5OJAbZq-UhMGA.json
│   │   ├── fBVa04p7MEL8BsPpyD_Pwv3uqBnBMVzG9YpXsCwZLtc.json
│   │   ├── fkbFeVpiaAOtvt_-M9_U4HzbA8Elh5sa8xJXObrItYM.json
│   │   ├── fx1EmDF4yioha3ms_VbddDQjl4bt6pBLpFCESuEIT6E.json
│   │   ├── g19-Tkf4xuM9golcjx0mA1RkJUYocQJ3uYnH8MU1ePs.json
│   │   ├── g6TUtTIi_rwlAHNuO6ACsQqIChWACugTPmZxaaJltDM.json
│   │   ├── g8ZQaQTNUbg-jGeE61og18FrGqpFeZxjFDypGuhT7zI.json
│   │   ├── gE-2fjp2ncJ0ZRg12UBfqnCBb75OtAOksEX3wGZguqw.json
│   │   ├── gXd75eQL5Yzcn1ba51nORAvb6f_surSnz3xcNlLAxEQ.json
│   │   ├── gbYMogbLVx3rOmm7K-o3nfGPKauLMLkGMSXcKkXW13Q.json
│   │   ├── gyG1bGFt7qkMyUCrKiEfMzMzc3_3PooewqNeJpy-3Xk.json
│   │   ├── h0MlFXsvtNQlFwgTh6y7-gjXEj0CbGECgz77EwQsca0.json
│   │   ├── h0sgGEeQQcmSxg8uyiCOigWtI_r2ex-58nk1xso004c.json
│   │   ├── h37LQjpChpTPMquvaxpfFeKt_7oAB5ElDzsdbCQ61n0.json
│   │   ├── h7qIFbn0LoexuVwBcjKW7v5A65iQDQFYZUQjuowfIbk.json
│   │   ├── hRTkBAH0k74HlmlWXTWmetXcIFXvM_Zrz3i1JXULZSM.json
│   │   ├── hX6nohfkKZ_9ajziHJ6g5V5cIe1EX9H9rg7eScK988s.json
│   │   ├── i9xaFWy0avtyCCxQdmWfGNDgh-PaJgIHkNK1pcJzmV8.json
│   │   ├── iPb5JLzNajAzUNByVeIGSEPR0rzGOV5iIYjWpi99APQ.json
│   │   ├── iRF6OnneKHJLhLMdCXpo6LsxVyWIGyklFEpu1bN3cyE.json
│   │   ├── ijroBK9n_uKCS97V7iege_5Av2E-tm6ujquAazT_sBI.json
│   │   ├── iuTLZ3xxGpaBCggV5xfUkJ6hMdUQKHw6f_vEn6sbmPo.json
│   │   ├── j2IiBCd5Vf2Q8ciTVxeHbN6JgrXUFiv0xtoMTA_VtqQ.json
│   │   ├── j3l4tvphmVOyVyFkNdS7ulmexBqPqEvsSJrBsjAFJXc.json
│   │   ├── k6UueT0FWSSUbAAH4Uc1Oz6BivunVR0nSMTEILnB_dQ.json
│   │   ├── kXu3jTQwgYsphIUFbaVGg9rNiil96fNjw0RBa6oPRtU.json
│   │   ├── kcb41aN752OE__qEKDQAsbpzCUXMdlzI3clCBuxdVts.json
│   │   ├── lFqBd1sEhgw1e_adedkee2hXP9beiNYbF625KV0vObU.json
│   │   ├── lq4SrnweWCHnEhw_AV69gMLyBrPxYOmOdVdRIXkHwOg.json
│   │   ├── lsuH-ITPI--6KSzhIFclsEAWOSoRQu-8tlnOSxj_Er0.json
│   │   ├── luQlV_58e9qjm7EZpoO6f5Y1j349Q34UwTW1Lx9J_vE.json
│   │   ├── luyHFFFOvjKPqi6nVrxngcHaQ3RwbMDMqVTLqPagHy0.json
│   │   ├── m1Vv28IVJIuYiToBhxFVp3dA47je3L8WkzSjggAWXAo.json
│   │   ├── m5zFPHB-2VjCgTLStD9TLZwD1CHfLELPKkVXFJGIptM.json
│   │   ├── mGAMsTqBzau-MjTkMS5Z3g2_nUD-qQWeLtq6qlzkVl0.json
│   │   ├── mJUxc7XyUp1HV_VRoi_54geidr26I9PUaiNL4msSNxk.json
│   │   ├── mcFln0_6FIuLwE9GtMRzmdQts4QALV3dxQkXdgSdO2s.json
│   │   ├── mvGgGlFTDJ0ukM6Bssd8G8B5PrEppr4Sg1_NTvzzV1U.json
│   │   ├── n6TKbsqmGl2m3yH15RAe405vYZQ7DStlvYsHCHp1D0U.json
│   │   ├── nXGMduBKL3mpsnFNPctfjEa9Z9zlMpdxcRrdkK95D80.json
│   │   ├── nh2sbgjxu6MmU8yGV00w7X4q4XCJETeYE3zVtcj2ldk.json
│   │   ├── o0nw6fU4gPL7Ae45x1BEQr5GkXSzZUrWnZrdIWqgx6w.json
│   │   ├── oMP40Kgd9MxLfksmW_HAlGe8Rn1Px8tpF-NOHBfe9oo.json
│   │   ├── oRvFwVpHVeo0iysSg2jFOAZKE-hKwbm6mGeZ6VUZmxk.json
│   │   ├── oWWJcAiBCxhtWkIqwir4-vTvD3JFpHgZRNIpS-Xjzp4.json
│   │   ├── ocUISm-0ItAS-N3Ydwe1swo4JmoVpRzWzngFt-pDwfo.json
│   │   ├── opfZTSNdqaxXZUmaKROD2sd4QkyNDnZE3u1A95eSw4E.json
│   │   ├── p9PJG5GkKZAxLyPJyDYw4_1CmhodHGGGqB785duwVwM.json
│   │   ├── pVZkxPK8F9VFM5lDp0oTBThaw1RvmwG64wIHFChYJKA.json
│   │   ├── piTZgtn2oBsWKt09CV8LqH3I3JaVdRjFwjOAJmC-Xp4.json
│   │   ├── puLpw8OIIYCOatImKjpV5s0JWyKFq6bXFMz_qSf6mUA.json
│   │   ├── qU2Gu35-s9wMH1N4g_zMYKCqIStYzBZmRx0XlcIpjyk.json
│   │   ├── qX9u_AprdhyXAPGfh3C94x9AbxwWx9nJSs7g8FSwITM.json
│   │   ├── qyMWe-VUOzHXkQviMhNS0wJI_27nvCgDY9iiKANk-lI.json
│   │   ├── r8Yq7Lvx0FjFYyXBLn29UM5Evv4AtGLZ00LCtE_hC60.json
│   │   ├── rC7TOXwflo7w9Ky0ljTYlzdbR0A3g2GVRbRJbIIuBfY.json
│   │   ├── rRoy9jsUZ-Y10NIBksSD3P4HcVDfZheloItTTnc8_ZQ.json
│   │   ├── rTY6dpq4KEhZtB-5moP1mWN1CtrTKurv7QSY8wAN758.json
│   │   ├── rvbM0iB1HJ1YadedIDWjJ95J2XBHWwPAJD4VfpdQpxQ.json
│   │   ├── sB51Zz1HRjpwrWFhW6ZE2E-n5hl3joqxPQgnMCLX4ZM.json
│   │   ├── sfAY_3fQ41LahxW45rXfndEzeHD1eeWJgI9ZaM3slFU.json
│   │   ├── snWRgSI3vlTOy3RRkuNckM-ws-5lpFiPMpYlLx_zPyk.json
│   │   ├── tOIFTqEef5fQYPzhlkC2Um7rddT6MyrHPzUWXDv_mJc.json
│   │   ├── tVLYd_62zbU-VPzQPOMHUo9TJR1dvSZ_pAHrC5Ubs8Q.json
│   │   ├── ud3zGJZA5tPRoitGG1c6HWm9W7iRS4ZF3u6PbZ-blns.json
│   │   ├── un3O49lggBX9raJKb6yuql_QTgZYWakWw5ydwUgUuXY.json
│   │   ├── utAoO_xht393CbJ_7P_ektVYeEpkySWLM-066yJ5HyI.json
│   │   ├── v2UplxDprWwaIwbB6z3KNEj3GjloqM8SinvVahZ1Wpk.json
│   │   ├── vQ4zTq--De8FHdVnE7sYCemwiaqoZDS4emR_y6o6ZFA.json
│   │   ├── vWeY4yJSJF9LXogRZb3Qr6QyLtEIL_8IY4bzJ2e7O5I.json
│   │   ├── vaJOh_TzVSoEgbgDyKz6ABzd_wt2-ouBTe0gA1F3oMY.json
│   │   ├── wFjsB5Y9GV61NqjCeyPCdkfXKUJOYccq8Bl9aljvwGc.json
│   │   ├── wUhEm861foyWdxy0SI7CvXRcWuohItlX6Ydqo2NvtY8.json
│   │   ├── weff0Y0_3-H7Vy1HrbpIzUmbTM1rZ8Lw0wgDGYmlsrM.json
│   │   ├── wmZTwziFc_VlvYJz_4nyxYd3WxznBmsn5QQyRKDcWXU.json
│   │   ├── wnOghJX4aZlbm7SDDb4UUX8_6GZYpYYx3GireamHwAc.json
│   │   ├── x8KM69OVm6lzslK6ccAE-3EX5sW6CUHBZB-1hbc-J0A.json
│   │   ├── xC7ski_qpcrRwRkxxHwPZd2lOX6Q---2qdQ4Rr-wxAM.json
│   │   ├── xSkMzFablxREj8H_RwoMseAFk-TCwaLVIZMHqXh5DHY.json
│   │   ├── xYpSRRpO8ejUGeohlRutNt9qUMgvuZJGkPGCyu1kSas.json
│   │   ├── xavUY4L0L0nLNVvHiYfBqGL5iqUvdwQ-iY_nLLMB6J4.json
│   │   ├── xiQYsaUMtlIq9DvTyucB4gu0BFC-qnFRIDclLv8wUT8.json
│   │   ├── y-k4KjdSmwYmIugoObrtx5JWYczlEZBzwBHGMLqNP-0.json
│   │   ├── y0PrXtX7PonEbIG3uEdu-k-McGeLLAjzUriUTCMTGcw.json
│   │   ├── y6WPKL6MHzZp2ktvb1cETmNMBJyCEPlxdisKlroEBtc.json
│   │   ├── ydvI6weQPIRj2hcNg4RPqzDpFOhqiTc9iDqQ-fUUl4I.json
│   │   ├── z7Xvravldr4BhTI4KPOEWtG325_1ORaLQ4aUPOAe_us.json
│   │   ├── zCOtSnXKGGhXgrWld31Ak9qQA_SjpOqB6n-9sF74rhk.json
│   │   ├── zUFRBcWpPAUyMlojffeTnPgsLo6YgU6JaJgOR0mpBuM.json
│   │   └── zwl046ia6I5VWLRYPJzBI70ypBQN2VlvLH9a_ndNKxA.json
│   ├── genesis_wallets.csv
│   ├── hash_list_1_0
│   └── not_found.html
├── http_iface_docs.md
├── http_post_unsigned_tx_docs.md
├── localnet_snapshot/
│   ├── ar_tx_blacklist/
│   │   ├── ar_tx_blacklist
│   │   ├── ar_tx_blacklist_offsets
│   │   ├── ar_tx_blacklist_pending_data
│   │   ├── ar_tx_blacklist_pending_headers
│   │   └── ar_tx_blacklist_pending_restore_headers
│   ├── data_sync_state
│   ├── header_sync_state
│   ├── mempool
│   ├── peers
│   ├── rocksdb/
│   │   ├── account_tree_db/
│   │   │   ├── 000009.sst
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── ar_storage_block_db/
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── ar_storage_tx_confirmation_db/
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── ar_storage_tx_db/
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── block_index_db/
│   │   │   ├── 000009.sst
│   │   │   ├── 000011.sst
│   │   │   ├── 000013.sst
│   │   │   ├── 000015.sst
│   │   │   ├── 000017.sst
│   │   │   ├── 000019.sst
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   ├── block_time_history_db/
│   │   │   ├── CURRENT
│   │   │   ├── IDENTITY
│   │   │   ├── LOCK
│   │   │   ├── MANIFEST-000004
│   │   │   └── OPTIONS-000007
│   │   └── reward_history_db/
│   │       ├── CURRENT
│   │       ├── IDENTITY
│   │       ├── LOCK
│   │       ├── MANIFEST-000004
│   │       └── OPTIONS-000007
│   └── seed_txs/
│       ├── -B7wF8TF5AodemKM2UjeFySwA_-Q12Ai8z9FSqgIEyA.json
│       ├── 0KMeq830vwvxUUM7RLCwE0ve4i0h_XHugbUTCkPNH-M.json
│       ├── 1QGjyW1AEFlrFAs6VtUcmwOVOEZJjxaBR_z61W9mftI.json
│       ├── 1VknqhhAXRQ6hzeZL-IMVBznTFCdiWcwlXhzpLKS8Zk.json
│       ├── 1fzKf0Ygc-z3ejpZ1ZLOiNBYDRzViGRdPLtUqRS1nKY.json
│       ├── 2dxNaIAvkAuL_N2qpTGSl7d7rU3Hu7d4l4IkYb9jgDU.json
│       ├── 35wYULjhQBiTFh9u-PJz6ki0v7Zi1whk_AhowUt99Ac.json
│       ├── 3DSCNJ5H9Hpyy7auT9qG5vom9jHBrCgjs48w_R6iSJg.json
│       ├── 4QcodvSlgZnuz5uWGmBARsGUJ5XaYORIO5jYM1dTucI.json
│       ├── 4tlIV1x4YRWtNMut11ox9SS-lWt3xIzcXnrBBbNxGYs.json
│       ├── 5iK4mPnFqGdUxpiZmGtTbj7xoSC2una7sjsbUyZkOmM.json
│       ├── 7M4KyVB4Wr-Le3Knb7JExgnsXTtG7718JIlhVBNstlE.json
│       ├── 7fat_nqzDJCTfJMqyEpOcavt1cZNM-tfSzASJd0wrHo.json
│       ├── 8CPVZq-zPdMQ2to1P91vl6XBXyL7sLH8-vNclnOCug8.json
│       ├── 8TiSScQCv06oS9b8Tt5WBnf7sUVgzPAFGJ3Lq2bt8rY.json
│       ├── 8qtH9T9jgYLHH-xi39w1OCNJykqew1O5qzrDkhAxN0U.json
│       ├── 9hX3cS3Vjr6vAqJW3WtPN665NpLJegcxyaDZO2esElM.json
│       ├── A5oMEDa7ZEm1kjPlXpwjuZd40rqP6eo3GobNGQY4HlY.json
│       ├── Ace-njSprwHMwZaW5nuD0y1lKFoaafU3T8d7PLBeEIA.json
│       ├── AoCuo7S7ewDIqhYheBX6AjShrbyTgIv6Fp1AwQgmGqg.json
│       ├── BFfNP1eCeYIkLiWWAVvHNLzk1N2pxkOChFzQbdv1IiA.json
│       ├── B_F4zIV1I5DXM-lR-Ko1tVUTTSmLCOYR7PoY8V8wFas.json
│       ├── CCH2h2MzMP7WMh0Xf3GYL7zZDbU7E4CZPJWngp1qmDc.json
│       ├── CQv9OVOCzntq2DRqNJ9j_WnWPcsniyGRXpt4i_a8Iy0.json
│       ├── Cdcx7-UZJN324I9L47rrph9dIVy8RwfJa9mY7cJp9gk.json
│       ├── D29DVKVYAe74sAj9NBQ351rI6SseWZ5MMsSedGtydS8.json
│       ├── D_3jwPKLfcTpWcrDV1Q7k3D4sMtyfw7vd45D2C9pUNA.json
│       ├── DlRct3GdPx7oYi3MSdmv16CgGWqhLJjbrKcIfU0E48I.json
│       ├── EDt8sO0AWKJyNeUxd-U6ihy0rgRKUPjpfRGarEHlOCs.json
│       ├── EayO1EsmOinnbi-NVa2V7cVraoI0TZ6xE5-sNU7fc94.json
│       ├── F3c9tsVvmCiFNxK7hVEzROraVm477QdyQ8t6afBs5E4.json
│       ├── FIrCkHY8jVkXcIkWYbMpuQSRYxavkOQ3wtUZPwMS1hM.json
│       ├── FbeSRhJR00VPygimhm47VwirSeBATnlf240hv4a2G4E.json
│       ├── G6JD1n-FXMSyTSryo0HoX7L3i7e4KEFK_ekDMEn9Bcg.json
│       ├── HOMVwtocaJIRPdCeKgzorJZJq1jw_lVGz0pQ3POj7No.json
│       ├── Hiu5cti9FefwcvT6xRCIoADUMkuDEm_6pZo92CK3fiw.json
│       ├── HoEZ6sK46bzTg4Jzrfy1kHFzkFQgI2UMm9pm0qJS3as.json
│       ├── Hs-Yj4ZE9ACfQIjzS8E-qvxSkQALsCIDHwcLEMnlz90.json
│       ├── Hv0Q5APV6ARfDXDpxI-07R1YFSJAQpxTFh1Z8_nCk3U.json
│       ├── I4ifBnOF6OQFautfisGFTVIn2NsrvqrdnQ-O7JOMouE.json
│       ├── Ie-fxxzdBweiA0N1ZbzUqXhNI310uDUmaBc3ajlV6YY.json
│       ├── IeEkQUBq3aE2CSbCF2Bk126lLaLZEYjUPJ_IO601tZg.json
│       ├── IqJf6iISeiEj3oof9491-jQX4drDZ92VoFuZqNmoixk.json
│       ├── JDG-HBsrHGDodot2clC3nNkRKV5cvuhRWZjCwVFHG_Q.json
│       ├── JDS1sGkpC0ua7UGfpLEJSF-jXUnjAs2fa5V7y6rccdY.json
│       ├── JNCYRy7XYR_20vvXEAwpT43ovKB23np9yE9cqQfsIJk.json
│       ├── JUf6alhhrfuL22XuQ0yrZ6_xBFBIQqi85wRxv2nUCMs.json
│       ├── JeP9HaxmjN-TcbCkhKDIQejkGdKTlOgp68O5cy_2GRc.json
│       ├── JfTiLBj5Gxr1v7JwoNf9-7sRAiLOrg1AZ6kqwSkEpTc.json
│       ├── Jo3rf0JPJR2kCHBqZG71xouWzuOSY-MXJufpfzFl7sE.json
│       ├── K0w8hOO1oCu4sQipWDQGyEFvn6kAXO-M93neMZmRoUc.json
│       ├── Lt7WJclVu4iYHqGHIYIBia3ABMnvmd5cW4ELIzUTfPE.json
│       ├── MCCCpl9AGNAzy3WvM5lniJ88iC3-8NPiiWIsxcLZZxQ.json
│       ├── MGDpPk3LsexVpFBF43-FIIvc0vyeEDroYcIONJ6abd0.json
│       ├── MQD8-8yIZwNC4A006TC1FVZSyCDHeIAN6YpDbTiX2RU.json
│       ├── MklsZ_cDz470C40UGZUJoVfMeVA89-r7SHxuomBeCPM.json
│       ├── NBjbIMFIdd6jFhSZ20izEke9Ju8jMuvYl8O4bqe4wC4.json
│       ├── NixeAD5Y_8sQfcrMBWkODQuoXgJouUBmQmQzwTzlaKU.json
│       ├── OGA55Jyg2c-Jhkx5zDNyiDvbFZiRXF0S_JESMhWAWcs.json
│       ├── P5KQo3QSWLzTLWkq3wgJlii11CEUSKMG_O2NMN6y_8c.json
│       ├── PgxqlgdluUGnmGCal3dgB6PYCd5S7FtBpI0zKDc8-AY.json
│       ├── QAQ-134At0mSPVrwBzTTUalyL_zqE_dMR_WggkZvF5E.json
│       ├── QyQL1TYdwmguUIBjTV-shWqrwS6AwxhZ6lf7Rx-vxH0.json
│       ├── R5utplMYRQsJwA9Y63cL3Na4mXtYzE4gWG6g6zwgEQE.json
│       ├── RJzScDd1IYIVaVOMo8zV2sXaGE4ZtKxwO2ONPFK-ou4.json
│       ├── Re-7lkSGlYP4SFddz0rrXIF0r4MVYZuagjkVpEm79bY.json
│       ├── TMjINkrJIS3kbGu8bmcVt_34TaFN8lINFQPR_YGzHss.json
│       ├── TNj-jk-KpKzz84xb1SRiKqyp8LNBnONxA9SIXs3XU7k.json
│       ├── Tg9QZvUPJoAZKRkPhPgQrgnlTY6s9UxRSQaMw6shhOU.json
│       ├── U2DZlRhnzhZrC7GsVNX0TxnXbHh03P3g-cU4fkHpiXA.json
│       ├── U4o0STLxwOEf42F4DF22ooOoA5Ykdp5j_D1io-4w1lc.json
│       ├── UH3C65dDo62rp5ciK3XzyhufE71xorL7r7MWVwdhavk.json
│       ├── U_1PPd40n2grpuhkMJcMXPVuJhtaQoUWei63iN2rS7o.json
│       ├── U_UF7e-hOd5uLIj10fYZVxQ5mXyZUxvMxhWWgAMaj0s.json
│       ├── UbW68tRQtThl9ah8tJb-X_af5M8FHYARiGZFiPGk_90.json
│       ├── VL10zUkfmLz5eRxQsZi0G5wsfo8mvyN3p82updP17D4.json
│       ├── ViCjDXb4IEZcXBtlYvTm3HCB6cf4gDbrXCCdvVVgB1g.json
│       ├── WJTACYoRG89VIpjzsIZLIy93U7HoC4OJyLy6WAlqv-0.json
│       ├── WwgngUwH7mXX15tdbfcjG_9gX2t8N8wbbfW2N34b3dA.json
│       ├── XrtNbxWFUGlP-SYqQm8aYawQJU6H7CSyHpRZM1iLdKg.json
│       ├── YMnQwrWWVRmkMs0B41lz-VdixskatlPcY7j4r0iSLbQ.json
│       ├── YcTBCg3mLRFByb1cnjrq9DzEBnnOT9jQtfYEE34QZ1M.json
│       ├── Yk_dta-f75GShvyUvXq132pohaNpiQgerfIKJA0vdCw.json
│       ├── Zu9CSLWidXEnbSAQVuXGk62eMrVAGQb4qHmrtQrOQIQ.json
│       ├── _AiF52l4uqTkKOVpQw9hr6l6FCIdWs8PCFtFxEBOopU.json
│       ├── _BN_07s59sawk5e9YcjHTX2qtYX9q7nCBYrlSWXoEsc.json
│       ├── _KI9ocPARF5JjaDPIbtpqw2hj_qRonw-AERjWOs5ZYM.json
│       ├── _gduN41u7Xxac_Gm3pBQI3icoKhOfiRV2TKhDnlyakU.json
│       ├── bcbIZq2gy8ivQiUlEch7tjNoCcUMTTLhInMlj9P2P88.json
│       ├── bhEMgsj4Yf5tdCDlwK9KpHmsgVLAsBDPOLtYeUDLw0M.json
│       ├── cTmKy32Fbmlybl-WtbyuVFNhO11Efr4e_rGbzwAkPbs.json
│       ├── clMyhm_qgwUJq68xb8Yf9EEaN3F7jgdqgKnKgjVRom8.json
│       ├── d8CQoDBSrekoGZXqTatc7Y5JkHtNviX1D3JD-fxFDmU.json
│       ├── dMTZgKHD-NkP3iM5RjFNhppiwfTlYd-Imi9aA6IK0So.json
│       ├── eGYHUFl46laNa8v_WjdadvCkIErWqmx0hoia7PCSmSw.json
│       ├── ehTWq16I6ixhFOVkpTKi7s4jgYjNzGJ5CoJW3xjHDTE.json
│       ├── fAnOUj-jmlzPMtIN90ZvowG9VUmBtD36MZ8-tRP1Ut4.json
│       ├── fr3nkF8AHXTcq9bT_b7x2X7Mun2A--Ssb7eyoKgQEwI.json
│       ├── goAmthhGPdbYUqbAymyG_MjBUWVdS9OBm78mOoiITHo.json
│       ├── hB1Hj0mfuh_x3ijhqkw1s3wdCh8qdPz_IMs0MPraVCk.json
│       ├── hMfNPSlINViUDVnor18GgPs0Ut0i9XY7dwM9MVOL-2I.json
│       ├── hPnpcoVcfRdkyUyhYSFNhsEcz7nQU0UU-fPSiRalDvw.json
│       ├── hQvPcHPcBhyxv7GPx-E3bZWiNBhnCpFIDwWa3XBcYEU.json
│       ├── hXNDNwQ6zA7aHAqvfBj_az9CovV37bJywdgPdb_ooIA.json
│       ├── hxyn3yZ7-LCgKqfkCljyM7Hq7HJnmPnEKaXoybXJjHo.json
│       ├── iWUFDucATDE8gjbsL-9KpOIW9l8Ipsh1wliv4e05xhg.json
│       ├── ivWTdg5M9XqjP-Iu4C97r3qZQhotJgfF17g__7EH7VM.json
│       ├── jOFeroI0Oz4TWcOx8mgv4iOZLv6ncbRXFRtJfqS4Pq0.json
│       ├── jStDc8gP5lyHVSFIJiT_2RrXhT26GpAhNItDEje07_Y.json
│       ├── kLP-8ILxdLSAQsrC6IwvfqQL6Loq2Q6lqOzwrnb6QoE.json
│       ├── kVNsLH0kpIkFnBBGWxoIajVLSpvzmsKHpsATPAcR86Y.json
│       ├── ks0ODNqrNY4CCDxJcrgRY324WykCeTiSH4Tmdi30I2E.json
│       ├── lF7NSIz6CNf8WsMNQl8It8HbJem3MAllokozblLdU5A.json
│       ├── ldoaD2NbG9VRhLOXddM1ypoAU3W5gR_zabUWZa4r6lM.json
│       ├── lxtOUAEj-E1jb6J8uGCRlRgJDHJyFOu0O73jQHnAhpg.json
│       ├── m1DnUoXf7wMtIGkkDZAALobw0GbGehfEMX_jNLvs3i8.json
│       ├── n1GVITzrvCF95Vz7l6hH7fdYzebDDAJav5z4-9C7lB4.json
│       ├── ntnx85KcYZ_ZhR6dL2A_p8foCmStgD-69ODoOUdipiA.json
│       ├── o9ArU5IxydvpJo2iiPI-p4EGBwlpBlyFIfbnz8Qrg6c.json
│       ├── oNZMr_dB-L40nSUj6Fc19-FGteHQu7ZaRZu9_mgM1BI.json
│       ├── oO7raEVlJC6KhfK-UbNuppzbYPGdKWbh1e6rOymd_-o.json
│       ├── oiYeEvWqOkaHzCSunznZ09U_tuHqP1UyZkRrKYHgNBw.json
│       ├── ojgJyXT8qwRXj1hOVx2gbeJDT0xEOIye0o9EbfU2LRM.json
│       ├── p0MVPvnv_lkWwfhSuSCgQ3NUj83shBffAx1NKPn4oy8.json
│       ├── p4oyXU5C3T0ZycNhEwBZ0MbpV0j3voWV4mr__3fhOek.json
│       ├── q8aw85uHTIPxuXcv2Awts4JVVHEMCl7J-61WfnvbYuQ.json
│       ├── qDEFXj8hSgOuuqWM52y6pbUX1cyp7bS4qItfctgtVx8.json
│       ├── qHvSpQXYh9RZmXIoIOexmDs0iQgjCubl6KSsgg7cDz8.json
│       ├── rAARxLc7tOdjUXEdNmSpOtsJIAw0XS229YHO1KOeUqI.json
│       ├── rTaanqa6Z5KxtBV4Kj2Fu2KKqAWlstE0JeUbZ3AuN3o.json
│       ├── rY4cJeAtYkg3bnTdqk4Vb0ojEcfS76L4B-iqyvQZ2VA.json
│       ├── rcc-B4OWqf0dbVY7Eq6q3pRDHLUjJ8tix8UeLQ4D68w.json
│       ├── sEw-yqeADuF0n_M6jTPLrOgH3coalIQHYPLrwM87nmo.json
│       ├── sMF6pWIkJFygBbR2IS10liEsjsLAMDja_E9_yUvUgeI.json
│       ├── t81tluHdoePSxjq7qG-6TMqBKmQLYr5gupmfvW25Y_o.json
│       ├── tn3FQGSVFt_TE5nyQNpuf_gnHdaWF85hZg1iE5hPQSE.json
│       ├── uNiZ8TfAQ8GWjtbqhVi90qO3U5dl9afmKE1-KbHQYM4.json
│       ├── uOqsnEjVGQCbtrKI7QbHYxbbLUdCKC-792SgZr5KUKM.json
│       ├── ujON59jsellR3M8hq9unBPISOwRgEVUogdi3FG_pVMk.json
│       ├── uoTzfoaN81h2_JyFkrvXTLFMnoSlWiuc9Yu1CmsFkH0.json
│       ├── vDtQzZ9jl6r7yzczhoKhvzekCQYx-qskwYdzQO92eWo.json
│       ├── vFP1U-4lk3GypDZFceLvRXjoadcB2FRKrcNQf9WjzpQ.json
│       ├── vYnzbcbBQbPQB7GKrXzPlz1MuT9cfnNI_NBVajaTnPg.json
│       ├── vvPtX1U0EZS9PMsQBVk3mjD9yS6EHIt0FXdKf2dOELw.json
│       ├── wntmnG9yRP9aoioRDILKkmSZqdemR-XDCIKJS-wpRYw.json
│       ├── xCUsF5aatMdiiUAkGjg29_TiQGKqXpbzoMsB0yI-Dd8.json
│       ├── xK4fFG-PbnQx6EGmmj1A0JVWQ9Bg7q-FncaU7hHk9ds.json
│       ├── xaB3eS6qbtKSrfFACMcYpgxWRtaJfT1kmOVpyaE45tI.json
│       ├── y9wJkLq6Q0hKSDD67ilFqtMMatw9qpsKM9W2uy2Rfjc.json
│       ├── ycjvsn3A9cUMjnbDaSUpf1HRQd4duP9AL1YVwSjwuAQ.json
│       ├── yo8VtPVXWBpTqLbLL-ZeOmZTW2HTqTzsf9RPzgHM-bQ.json
│       ├── zNae10gPNkFt5aRVaSL2eSgxZiRDG79B9oDIeYqyzDY.json
│       └── zavm_CqSq0KuWfc-E0JccEyrrQzjigxt7yuW1ceYjE0.json
├── nix/
│   ├── README.md
│   ├── arweave.nix
│   ├── generate-config.nix
│   ├── module.nix
│   └── options.nix
├── notebooks/
│   ├── README.md
│   ├── autoredenomination_localnet.ipynb
│   ├── pricing_transition_localnet.ipynb
│   └── test.ipynb
├── priv/
│   └── templates/
│       ├── README.md
│       ├── extended_bin
│       └── vm_args
├── rebar.config
├── rebar3
├── release_notes/
│   ├── N.2.9.5/
│   │   └── README.md
│   ├── N.2.9.5-alpha5/
│   │   └── README.md
│   ├── N.2.9.5-alpha6/
│   │   └── README.md
│   ├── N.2.9.5.1/
│   │   └── README.md
│   └── README.md
├── scripts/
│   ├── full_test_modules.txt
│   ├── github_workflow.sh
│   ├── ierl_kernel.sh
│   ├── list_test_modules.sh
│   ├── run_notebook.sh
│   ├── run_notebook_headless.sh
│   ├── setup_notebook_env.sh
│   ├── surefire_to_html.py
│   ├── system_info.sh
│   └── testnet/
│       └── benchmark
└── testnet/
    ├── assert_testnet.sh
    ├── backup_data.sh
    ├── clear_data.sh
    ├── config/
    │   ├── testnet-1.json
    │   ├── testnet-2.json
    │   ├── testnet-3.json
    │   ├── testnet-4.json
    │   ├── testnet-5.json
    │   └── testnet-6.json
    ├── rebuild_mainnet.sh
    ├── rebuild_testnet.sh
    ├── restore_data.sh
    ├── start_mainnet.sh
    └── start_testnet.sh
Download .txt
SYMBOL INDEX (101 symbols across 18 files)

FILE: .jupyter/jupyter_server_config.py
  function _strip_outputs_pre_save (line 4) | def _strip_outputs_pre_save(model, **kwargs):

FILE: apps/arweave/c_src/ar_nif.c
  function ERL_NIF_TERM (line 6) | ERL_NIF_TERM solution_tuple(ErlNifEnv* envPtr, ERL_NIF_TERM hashTerm) {
  function ERL_NIF_TERM (line 10) | ERL_NIF_TERM ok_tuple(ErlNifEnv* envPtr, ERL_NIF_TERM term)
  function ERL_NIF_TERM (line 15) | ERL_NIF_TERM ok_tuple2(ErlNifEnv* envPtr, ERL_NIF_TERM term1, ERL_NIF_TE...
  function ERL_NIF_TERM (line 20) | ERL_NIF_TERM error_tuple(ErlNifEnv* envPtr, const char* reason)
  function ERL_NIF_TERM (line 26) | ERL_NIF_TERM make_output_binary(ErlNifEnv* envPtr, unsigned char *dataPt...

FILE: apps/arweave/c_src/randomx/ar_randomx_impl.h
  type boolean (line 18) | typedef enum { FALSE, TRUE } boolean;
  type workerThread (line 20) | struct workerThread {
  type hashing_mode (line 29) | typedef enum {
  type state (line 34) | struct state {
  type state (line 55) | struct state
  type state (line 56) | struct state
  type state (line 59) | struct state
  function ERL_NIF_TERM (line 61) | static ERL_NIF_TERM init_nif(ErlNifEnv* envPtr, int argc, const ERL_NIF_...
  function ERL_NIF_TERM (line 139) | static ERL_NIF_TERM info_nif(
  function ERL_NIF_TERM (line 190) | static ERL_NIF_TERM hash_nif(
  function load (line 235) | static int load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info)
  function state_dtor (line 246) | static void state_dtor(ErlNifEnv* envPtr, void* objPtr)
  function boolean (line 266) | static boolean init_dataset(
  type workerThread (line 328) | struct workerThread
  type workerThread (line 328) | struct workerThread
  function ERL_NIF_TERM (line 337) | static ERL_NIF_TERM init_failed(ErlNifEnv *envPtr, struct state *statePt...
  function randomx_vm (line 355) | static randomx_vm* create_vm(struct state* statePtr,
  function destroy_vm (line 390) | static void destroy_vm(struct state* statePtr, randomx_vm* vmPtr) {

FILE: apps/arweave/c_src/randomx/feistel_msgsize_key_cipher.cpp
  function feistel_hash (line 7) | void feistel_hash(const unsigned char *in_r, const unsigned char *in_k, ...
  function feistel_encrypt_block (line 16) | void feistel_encrypt_block(const unsigned char *in_left, const unsigned ...
  function feistel_decrypt_block (line 54) | void feistel_decrypt_block(const unsigned char *in_left, const unsigned ...
  function feistel_encrypt (line 96) | void feistel_encrypt(const unsigned char *plaintext, const size_t plaint...
  function feistel_decrypt (line 120) | void feistel_decrypt(const unsigned char *ciphertext, const size_t ciphe...

FILE: apps/arweave/c_src/randomx/randomx_long_with_entropy.cpp
  function RANDOMX_EXPORT (line 34) | RANDOMX_EXPORT void randomx_encrypt_chunk(randomx_vm *machine, const uns...
  function RANDOMX_EXPORT (line 42) | RANDOMX_EXPORT void randomx_decrypt_chunk(randomx_vm *machine, const uns...

FILE: apps/arweave/c_src/randomx/randomx_squared.cpp
  function _rsp_mix_entropy_near (line 13) | void _rsp_mix_entropy_near(
  function _rsp_exec_inplace (line 57) | void _rsp_exec_inplace(
  function _copy_chunk_cross_lane (line 88) | void _copy_chunk_cross_lane(
  function _rsp_mix_entropy_far (line 124) | void _rsp_mix_entropy_far(
  function rsp_fused_entropy (line 157) | int rsp_fused_entropy(

FILE: apps/arweave/c_src/randomx/rx4096/ar_rx4096_nif.c
  function rx4096_load (line 37) | static int rx4096_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info)
  function ERL_NIF_TERM (line 42) | static ERL_NIF_TERM rx4096_info_nif(ErlNifEnv* envPtr, int argc, const E...
  function ERL_NIF_TERM (line 47) | static ERL_NIF_TERM rx4096_init_nif(ErlNifEnv* envPtr, int argc, const E...
  function ERL_NIF_TERM (line 52) | static ERL_NIF_TERM rx4096_hash_nif(ErlNifEnv* envPtr, int argc, const E...
  function ERL_NIF_TERM (line 57) | static ERL_NIF_TERM encrypt_composite_chunk(ErlNifEnv* envPtr,
  function ERL_NIF_TERM (line 117) | static ERL_NIF_TERM decrypt_composite_chunk(ErlNifEnv* envPtr,
  function ERL_NIF_TERM (line 173) | static ERL_NIF_TERM rx4096_encrypt_composite_chunk_nif(
  function ERL_NIF_TERM (line 244) | static ERL_NIF_TERM rx4096_decrypt_composite_chunk_nif(
  function ERL_NIF_TERM (line 323) | static ERL_NIF_TERM rx4096_decrypt_composite_sub_chunk_nif(
  function ERL_NIF_TERM (line 428) | static ERL_NIF_TERM rx4096_reencrypt_composite_chunk_nif(

FILE: apps/arweave/c_src/randomx/rx512/ar_rx512_nif.c
  function rx512_load (line 19) | static int rx512_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM info)
  function ERL_NIF_TERM (line 24) | static ERL_NIF_TERM rx512_info_nif(ErlNifEnv* envPtr, int argc, const ER...
  function ERL_NIF_TERM (line 29) | static ERL_NIF_TERM rx512_init_nif(ErlNifEnv* envPtr, int argc, const ER...
  function ERL_NIF_TERM (line 34) | static ERL_NIF_TERM rx512_hash_nif(ErlNifEnv* envPtr, int argc, const ER...
  function ERL_NIF_TERM (line 39) | static ERL_NIF_TERM decrypt_chunk(ErlNifEnv* envPtr,
  function ERL_NIF_TERM (line 49) | static ERL_NIF_TERM encrypt_chunk(ErlNifEnv* envPtr,
  function ERL_NIF_TERM (line 74) | static ERL_NIF_TERM rx512_encrypt_chunk_nif(
  function ERL_NIF_TERM (line 128) | static ERL_NIF_TERM rx512_decrypt_chunk_nif(
  function ERL_NIF_TERM (line 191) | static ERL_NIF_TERM rx512_reencrypt_chunk_nif(

FILE: apps/arweave/c_src/randomx/rxsquared/ar_rxsquared_nif.c
  function rxsquared_load (line 18) | static int rxsquared_load(ErlNifEnv* envPtr, void** priv, ERL_NIF_TERM i...
  function ERL_NIF_TERM (line 22) | static ERL_NIF_TERM rxsquared_info_nif(ErlNifEnv* envPtr, int argc, cons...
  function ERL_NIF_TERM (line 26) | static ERL_NIF_TERM rxsquared_init_nif(ErlNifEnv* envPtr, int argc, cons...
  function ERL_NIF_TERM (line 30) | static ERL_NIF_TERM rxsquared_hash_nif(ErlNifEnv* envPtr, int argc, cons...
  function ERL_NIF_TERM (line 35) | static ERL_NIF_TERM rsp_feistel_encrypt_nif(
  function ERL_NIF_TERM (line 74) | static ERL_NIF_TERM rsp_feistel_decrypt_nif(
  function ERL_NIF_TERM (line 113) | static ERL_NIF_TERM rsp_fused_entropy_nif(ErlNifEnv* envPtr, int argc, c...

FILE: apps/arweave/c_src/secp256k1/secp256k1_nif.c
  function secp256k1_load (line 23) | static int secp256k1_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load...
  function fill_devurandom (line 27) | static int fill_devurandom(void* buffer, size_t size) {
  function fill_random (line 55) | static int fill_random(void* buffer, size_t size) {
  function secure_erase (line 90) | static void secure_erase(void *ptr, size_t len) {
  function ERL_NIF_TERM (line 111) | static ERL_NIF_TERM sign_recoverable(ErlNifEnv *env, int argc, const ERL...
  function ERL_NIF_TERM (line 185) | static ERL_NIF_TERM recover_pk_and_verify(ErlNifEnv *env, int argc, cons...

FILE: apps/arweave/c_src/vdf/ar_vdf_nif.c
  function vdf_load (line 33) | static int vdf_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info) {
  function ERL_NIF_TERM (line 73) | static ERL_NIF_TERM vdf_sha2_nif(ErlNifEnv* envPtr, int argc, const ERL_...
  function ERL_NIF_TERM (line 113) | static ERL_NIF_TERM vdf_sha2_fused_nif(ErlNifEnv* envPtr, int argc, cons...
  function ERL_NIF_TERM (line 153) | static ERL_NIF_TERM vdf_sha2_hiopt_nif(ErlNifEnv* envPtr, int argc, cons...
  function ERL_NIF_TERM (line 194) | static ERL_NIF_TERM vdf_parallel_sha_verify_with_reset_nif(

FILE: apps/arweave/c_src/vdf/vdf.cpp
  type vdf_sha_thread_arg (line 12) | struct vdf_sha_thread_arg {
  type vdf_sha_verify_thread_arg (line 22) | struct vdf_sha_verify_thread_arg
  class vdf_verify_job (line 24) | class vdf_verify_job {
  type vdf_sha_verify_thread_arg (line 43) | struct vdf_sha_verify_thread_arg {
  function _vdf_sha2 (line 55) | void _vdf_sha2(unsigned char* saltBuffer, unsigned char* seed, unsigned ...
  function vdf_sha2 (line 143) | void vdf_sha2(unsigned char* saltBuffer, unsigned char* seed, unsigned c...
  function _vdf_sha_verify_thread (line 155) | void _vdf_sha_verify_thread(vdf_sha_verify_thread_arg* _arg) {
  function reset_mix (line 209) | void reset_mix(unsigned char* res, unsigned char* prevOutput, unsigned c...
  function fast_rev_cmp256 (line 217) | bool fast_rev_cmp256(unsigned char* a, unsigned char* b) {
  function _vdf_sha_verify_with_reset_thread (line 225) | void _vdf_sha_verify_with_reset_thread(vdf_sha_verify_thread_arg* _arg) {
  function vdf_parallel_sha_verify_with_reset (line 288) | bool vdf_parallel_sha_verify_with_reset(unsigned char* startSaltBuffer, ...

FILE: apps/arweave/c_src/vdf/vdf.h
  function long_add (line 9) | static inline void long_add(unsigned char* saltBuffer, int checkpointIdx) {

FILE: apps/arweave/c_src/vdf/vdf_fused_arm.cpp
  function sha2_p2_32_32_rev_norm (line 29) | void sha2_p2_32_32_rev_norm (unsigned char *output,
  function sha2_p2_32_32_norm_loop (line 349) | void sha2_p2_32_32_norm_loop(unsigned char  *tempOut,
  function sha2_p2_32_32_norm_rev (line 668) | void sha2_p2_32_32_norm_rev (unsigned char *output,
  function _vdf_sha2_fused_arm (line 993) | void _vdf_sha2_fused_arm(unsigned char* saltBuffer, unsigned char* seed,...
  function vdf_sha2_fused_arm (line 1028) | void vdf_sha2_fused_arm(unsigned char* saltBuffer, unsigned char* seed, ...

FILE: apps/arweave/c_src/vdf/vdf_fused_x86.cpp
  function _vdf_sha2_fused_x86 (line 504) | void _vdf_sha2_fused_x86(unsigned char* saltBuffer, unsigned char* seed,...
  function vdf_sha2_fused_x86 (line 544) | void vdf_sha2_fused_x86(unsigned char* saltBuffer, unsigned char* seed, ...

FILE: apps/arweave/c_src/vdf/vdf_hiopt_arm.cpp
  function reverse_endianness_asm (line 9) | void reverse_endianness_asm(const uint32_t h[8], uint8_t* md) {
  function _vdf_sha2_hiopt_arm (line 41) | void _vdf_sha2_hiopt_arm(unsigned char* saltBuffer, unsigned char* seed,...
  function vdf_sha2_hiopt_arm (line 99) | void vdf_sha2_hiopt_arm(unsigned char* saltBuffer, unsigned char* seed, ...

FILE: apps/randomx_square_latency_tester/main.cpp
  function main (line 7) | int main() {

FILE: scripts/surefire_to_html.py
  function usage (line 11) | def usage():
  function main (line 14) | def main():
  function from_stdin (line 24) | def from_stdin():
  function from_file (line 29) | def from_file(file):
  function convert (line 34) | def convert(element):
Condensed preview — 999 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,890K chars).
[
  {
    "path": ".cursor/BUGBOT.md",
    "chars": 74,
    "preview": "Always suggest one or two ways to patch the issues you are highlighting.\n\n"
  },
  {
    "path": ".cursor/rules/build.mdc",
    "chars": 1102,
    "preview": "---\nname: build\ndescription: \"Arweave build commands and structure\"\nalwaysApply: true\n---\n\n# Arweave Project Rules\n\nTo b"
  },
  {
    "path": ".cursor/rules/protocol.mdc",
    "chars": 241,
    "preview": "# Arweave protocol technical details and caveats\n\nRecall bytes always point to chunks, not sub-chunks. We always conside"
  },
  {
    "path": ".gitattributes",
    "chars": 57,
    "preview": "localnet_snapshot/** filter=lfs diff=lfs merge=lfs -text\n"
  },
  {
    "path": ".github/workflows/e2e-test.yml",
    "chars": 5900,
    "preview": "name: \"Arweave e2e  Tests Suites\"\non:\n  workflow_dispatch:\n  schedule:\n    - cron: \"0 13 * * *\"\n\njobs:\n  build:\n    runs"
  },
  {
    "path": ".github/workflows/gitstamp.yaml",
    "chars": 570,
    "preview": "# See: https://github.com/weavery/gitstamp-action\n---\nname: Gitstamp\non: \n  push:\n    branches:\n      - 'master'\n      -"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 5753,
    "preview": "######################################################################\n# All releases are generated using this workflow."
  },
  {
    "path": ".github/workflows/test-amd64-ubuntu-22.04.yml",
    "chars": 780,
    "preview": "######################################################################\n# Test suite for Ubuntu 22.04. This is the offici"
  },
  {
    "path": ".github/workflows/test-arm64-macos-26.yml",
    "chars": 1067,
    "preview": "######################################################################\n# Test suite for MacOS. The support of MacOS is m"
  },
  {
    "path": ".github/workflows/x-build.yml",
    "chars": 6178,
    "preview": "######################################################################\n# Common way to build arweave. This template shou"
  },
  {
    "path": ".github/workflows/x-common-test.yml",
    "chars": 4790,
    "preview": "######################################################################\n# Full Arweave Test Suite. Mostly used on Linux l"
  },
  {
    "path": ".github/workflows/x-release-linux.yml",
    "chars": 3121,
    "preview": "######################################################################\n# Release template for Linux based systems, inclu"
  },
  {
    "path": ".github/workflows/x-release-macos.yml",
    "chars": 3230,
    "preview": "######################################################################\n# release template for MacOS.\n###################"
  },
  {
    "path": ".github/workflows/x-test-canary.yml",
    "chars": 1956,
    "preview": "######################################################################\n# A canary test suite, checking if the test suite"
  },
  {
    "path": ".github/workflows/x-test-full.yml",
    "chars": 5691,
    "preview": "######################################################################\n# Full Arweave Test Suite. Mostly used on Linux l"
  },
  {
    "path": ".github/workflows/x-test-on-demand.yml",
    "chars": 2482,
    "preview": "######################################################################\n# Full Arweave Test Suite. On demand.\n###########"
  },
  {
    "path": ".github/workflows/x-test-vdf.yml",
    "chars": 4167,
    "preview": "######################################################################\n# Arweave Test Suite dedicated for VDF testing.\n#"
  },
  {
    "path": ".gitignore",
    "chars": 506,
    "preview": "*.beam\n*.log\n*.dat\n.vscode\n*.out\n*.code-workspace\n.arweave.plt\ntestlog\ndebug_logs\napps/arweave/priv/tls\napps/arweave/pri"
  },
  {
    "path": ".gitmodules",
    "chars": 379,
    "preview": "[submodule \"lib/RandomX\"]\n\tpath = apps/arweave/lib/RandomX\n\turl = https://github.com/ArweaveTeam/RandomX.git\n[submodule "
  },
  {
    "path": ".jupyter/jupyter_server_config.py",
    "chars": 612,
    "preview": "import os\n\n\ndef _strip_outputs_pre_save(model, **kwargs):\n    if os.getenv(\"NOTEBOOK_SAVE_OUTPUTS\") == \"1\":\n        retu"
  },
  {
    "path": "CANARY.md",
    "chars": 464,
    "preview": "# Arweave Team Warrant Canary\n\n- The Arweave Team has not been contacted by any law enforcement officials regarding the "
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 804,
    "preview": "# Contributing\n\nThis is a quick overview for what you should know when contributing to this Git repository.\n\n - There is"
  },
  {
    "path": "LICENSE.md",
    "chars": 18046,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Fr"
  },
  {
    "path": "README.md",
    "chars": 1213,
    "preview": "# Arweave Server\n\nThis is the repository for the official Erlang implementation of the Arweave\nprotocol and a gateway im"
  },
  {
    "path": "apps/arweave/c_src/Makefile",
    "chars": 6634,
    "preview": "# Based on c_src.mk from erlang.mk by Loic Hoguin <essen@ninenines.eu>\n\nCURDIR := $(shell pwd)\nBASEDIR := $(abspath $(CU"
  },
  {
    "path": "apps/arweave/c_src/ar_nif.c",
    "chars": 1027,
    "preview": "#include \"ar_nif.h\"\n#include <string.h>\n\n// Utility functions.\n\nERL_NIF_TERM solution_tuple(ErlNifEnv* envPtr, ERL_NIF_T"
  },
  {
    "path": "apps/arweave/c_src/ar_nif.h",
    "chars": 364,
    "preview": "#ifndef AR_NIF_H\n#define AR_NIF_H\n\n#include <erl_nif.h>\n\nERL_NIF_TERM solution_tuple(ErlNifEnv*, ERL_NIF_TERM);\nERL_NIF_"
  },
  {
    "path": "apps/arweave/c_src/randomx/ar_randomx_impl.h",
    "chars": 11455,
    "preview": "#ifndef AR_RANDOMX_IMPL_H\n#define AR_RANDOMX_IMPL_H\n\n// Thif file includes the full definitions of any function that is "
  },
  {
    "path": "apps/arweave/c_src/randomx/crc32.h",
    "chars": 460,
    "preview": "#ifndef CRC32_H\n#define CRC32_H\n\n#if defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)\n  #"
  },
  {
    "path": "apps/arweave/c_src/randomx/feistel_msgsize_key_cipher.cpp",
    "chars": 4886,
    "preview": "#include <openssl/sha.h>\n\n#include \"feistel_msgsize_key_cipher.h\"\n\n// NOTE feistel_encrypt_block/feistel_decrypt_block w"
  },
  {
    "path": "apps/arweave/c_src/randomx/feistel_msgsize_key_cipher.h",
    "chars": 501,
    "preview": "#ifndef FEISTEL_MSGSIZE_KEY_CIPHER_H\n#define FEISTEL_MSGSIZE_KEY_CIPHER_H\n\n\n#define FEISTEL_BLOCK_LENGTH 32\n\n#if defined"
  },
  {
    "path": "apps/arweave/c_src/randomx/randomx_long_with_entropy.cpp",
    "chars": 2583,
    "preview": "#include <cassert>\n#include \"randomx_long_with_entropy.h\"\n#include \"vm_interpreted.hpp\"\n#include \"vm_interpreted_light.h"
  },
  {
    "path": "apps/arweave/c_src/randomx/randomx_long_with_entropy.h",
    "chars": 713,
    "preview": "#ifndef RANDOMX_LONG_WITH_ENTROPY_H\n#define RANDOMX_LONG_WITH_ENTROPY_H\n\n#include \"randomx.h\"\n\n#define RANDOMX_ENTROPY_S"
  },
  {
    "path": "apps/arweave/c_src/randomx/randomx_squared.cpp",
    "chars": 7190,
    "preview": "#include <cassert>\n#include <openssl/sha.h>\n#include \"crc32.h\"\n#include \"randomx_squared.h\"\n#include \"feistel_msgsize_ke"
  },
  {
    "path": "apps/arweave/c_src/randomx/randomx_squared.h",
    "chars": 612,
    "preview": "#ifndef RANDOMX_SQUARED_H\n#define RANDOMX_SQUARED_H\n\n#include \"randomx.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n"
  },
  {
    "path": "apps/arweave/c_src/randomx/rx4096/ar_rx4096_nif.c",
    "chars": 19651,
    "preview": "#include <string.h>\n#include <openssl/sha.h>\n#include <ar_nif.h>\n#include \"../randomx_long_with_entropy.h\"\n#include \"../"
  },
  {
    "path": "apps/arweave/c_src/randomx/rx512/ar_rx512_nif.c",
    "chars": 9544,
    "preview": "#include <string.h>\n#include <openssl/sha.h>\n#include <ar_nif.h>\n#include \"../randomx_long_with_entropy.h\"\n#include \"../"
  },
  {
    "path": "apps/arweave/c_src/randomx/rxsquared/ar_rxsquared_nif.c",
    "chars": 6929,
    "preview": "#include <string.h>\n#include <openssl/sha.h>\n#include <ar_nif.h>\n#include \"../randomx_long_with_entropy.h\"\n#include \"../"
  },
  {
    "path": "apps/arweave/c_src/secp256k1/secp256k1_nif.c",
    "chars": 8321,
    "preview": "#define _GNU_SOURCE\n#include <string.h>\n#include <errno.h>\n#include <stddef.h>\n#include <stdint.h>\n#include <fcntl.h>\n#i"
  },
  {
    "path": "apps/arweave/c_src/vdf/ar_vdf_nif.c",
    "chars": 8982,
    "preview": "#include <erl_nif.h>\n#include <string.h>\n#include <openssl/sha.h>\n#include <ar_nif.h>\n#include \"vdf.h\"\n\n#if defined(__x8"
  },
  {
    "path": "apps/arweave/c_src/vdf/sha256-armv8.S",
    "chars": 8751,
    "preview": ".text\n.globl\t_sha256_block_vdf_order\n.align\t6\n_sha256_block_vdf_order:\n\tstp\tx29,x30,[sp,#-16]!\n\tadd\tx29,sp,#0\n    adr   "
  },
  {
    "path": "apps/arweave/c_src/vdf/vdf.cpp",
    "chars": 13228,
    "preview": "#include <thread>\n#include <cstdint>\n#include <cstring>\n#include <cstdlib>\n#include <vector>\n#include <mutex>\n#include <"
  },
  {
    "path": "apps/arweave/c_src/vdf/vdf.h",
    "chars": 1662,
    "preview": "#ifndef VDF_H\n#define VDF_H\n\n#include <stdbool.h>\n\nconst int SALT_SIZE = 32;\nconst int VDF_SHA_HASH_SIZE = 32;\n\nstatic i"
  },
  {
    "path": "apps/arweave/c_src/vdf/vdf_fused_arm.cpp",
    "chars": 33244,
    "preview": "#include <cstdint>\n#include <cstring>\n#include \"vdf.h\"\n\n#if defined(__aarch64__) || defined(__arm__)\n\n#include <arm_neon"
  },
  {
    "path": "apps/arweave/c_src/vdf/vdf_fused_x86.cpp",
    "chars": 51908,
    "preview": "#include <cstdint>\n#include <cstring>\n#include \"vdf.h\"\n\n#if defined(__x86_64__) || defined(__i386__)\n\n#include <immintri"
  },
  {
    "path": "apps/arweave/c_src/vdf/vdf_hiopt_arm.cpp",
    "chars": 3957,
    "preview": "#include <cstdint>\n#include <cstring>\n#include \"vdf.h\"\n\n#if defined(__aarch64__) || defined(__arm__)\n\nextern \"C\" {\n\tvoid"
  },
  {
    "path": "apps/arweave/include/ar.hrl",
    "chars": 31007,
    "preview": "-ifndef(AR_HRL).\n-define(AR_HRL, true).\n\n%%% A collection of record structures used throughout the Arweave server.\n\n%% T"
  },
  {
    "path": "apps/arweave/include/ar_blacklist_middleware.hrl",
    "chars": 4713,
    "preview": "-define(THROTTLE_PERIOD, 30000).\n\n-define(BAN_CLEANUP_INTERVAL, 60000).\n\n-define(RPM_BY_PATH(Path), fun() ->\n\t?RPM_BY_PA"
  },
  {
    "path": "apps/arweave/include/ar_block.hrl",
    "chars": 107,
    "preview": "%% Size in bytes of the timestamp and last_retarget block fields.\n-define(TIMESTAMP_FIELD_SIZE_LIMIT, 12).\n"
  },
  {
    "path": "apps/arweave/include/ar_chain_stats.hrl",
    "chars": 348,
    "preview": "-ifndef(AR_CHAIN_STATS_HRL).\n-define(AR_CHAIN_STATS_HRL, true).\n\n-define(RECENT_FORKS_AGE, 60 * 60 * 24 * 30). %% last 3"
  },
  {
    "path": "apps/arweave/include/ar_chunk_storage.hrl",
    "chars": 181,
    "preview": "-define(OFFSET_SIZE, 3). % Sufficient to represent a number up to 256 * 1024 (?DATA_CHUNK_SIZE).\n-define(OFFSET_BIT_SIZE"
  },
  {
    "path": "apps/arweave/include/ar_consensus.hrl",
    "chars": 8769,
    "preview": "%% The number of RandomX hashes to compute to pack a chunk.\n-define(PACKING_DIFFICULTY, 20).\n\n%% The number of RandomX h"
  },
  {
    "path": "apps/arweave/include/ar_data_discovery.hrl",
    "chars": 2113,
    "preview": "%% The size in bytes of a bucket used to group peers' sync records. When we want to sync\n%% an interval, we process it b"
  },
  {
    "path": "apps/arweave/include/ar_data_sync.hrl",
    "chars": 10654,
    "preview": "%% The size in bits of the offset key in kv databases.\n-define(OFFSET_KEY_BITSIZE, 256).\n\n%% The size in bits of the key"
  },
  {
    "path": "apps/arweave/include/ar_header_sync.hrl",
    "chars": 1059,
    "preview": "%% The frequency of processing items in the queue.\n-ifdef(AR_TEST).\n-define(PROCESS_ITEM_INTERVAL_MS, 1000).\n-else.\n-def"
  },
  {
    "path": "apps/arweave/include/ar_inflation.hrl",
    "chars": 1601,
    "preview": "-ifndef(AR_INFLATION_HRL).\n-define(AR_INFLATION_HRL, true).\n\n-include_lib(\"arweave/include/ar.hrl\").\n\n%% An approximatio"
  },
  {
    "path": "apps/arweave/include/ar_mining.hrl",
    "chars": 1973,
    "preview": "-ifndef(AR_MINING_HRL).\n-define(AR_MINING_HRL, true).\n\n-define(GC_LOG_THRESHOLD, 1000).\n\n%% fields prefixed with cm_ are"
  },
  {
    "path": "apps/arweave/include/ar_mining_cache.hrl",
    "chars": 821,
    "preview": "-ifndef(AR_MINING_CACHE_HRL).\n-define(AR_MINING_CACHE_HRL, true).\n\n-record(ar_mining_cache_value, {\n  chunk1 :: binary()"
  },
  {
    "path": "apps/arweave/include/ar_peers.hrl",
    "chars": 435,
    "preview": "-ifndef(AR_PEERS_HRL).\n-define(AR_PEERS_HRL, true).\n\n-include_lib(\"ar.hrl\").\n\n-record(performance, {\n\tversion = 3,\n\trele"
  },
  {
    "path": "apps/arweave/include/ar_poa.hrl",
    "chars": 789,
    "preview": "-ifndef(AR_POA_HRL).\n-define(AR_POA_HRL, true).\n\n-include(\"ar.hrl\").\n\n-record(chunk_proof, {\n\tmetadata :: #chunk_metadat"
  },
  {
    "path": "apps/arweave/include/ar_pool.hrl",
    "chars": 1836,
    "preview": "%% The number of VDF steps (\"jobs\") the pool server serves at a time.\n-define(GET_JOBS_COUNT, 10).\n\n%% The time in secon"
  },
  {
    "path": "apps/arweave/include/ar_pricing.hrl",
    "chars": 10361,
    "preview": "%% @doc Pricing macros.\n\n%% For a new account, we charge the fee equal to the price of uploading\n%% this number of bytes"
  },
  {
    "path": "apps/arweave/include/ar_repack.hrl",
    "chars": 965,
    "preview": "-ifndef(AR_REPACK_HRL).\n-define(AR_REPACK_HRL, true).\n\n-record(repack_chunk, {\n\tstate = needs_chunk :: \n\t\tneeds_chunk | "
  },
  {
    "path": "apps/arweave/include/ar_sup.hrl",
    "chars": 1212,
    "preview": "%% The number of milliseconds the supervisor gives every process for shutdown.\n-ifdef(AR_TEST).\n-define(SHUTDOWN_TIMEOUT"
  },
  {
    "path": "apps/arweave/include/ar_sync_buckets.hrl",
    "chars": 610,
    "preview": "%% The size in bytes of a bucket in sync buckets. The bigger the bucket,\n%% the more compact the structure is, but also "
  },
  {
    "path": "apps/arweave/include/ar_vdf.hrl",
    "chars": 687,
    "preview": "% 25 checkpoints 40 ms each = 1000 ms\n-define(VDF_CHECKPOINT_COUNT_IN_STEP, 25).\n\n-define(VDF_BYTE_SIZE, 32).\n\n%% Typica"
  },
  {
    "path": "apps/arweave/include/ar_verify_chunks.hrl",
    "chars": 672,
    "preview": "-ifndef(AR_VERIFY_CHUNKS_HRL).\n-define(AR_VERIFY_CHUNKS_HRL, true).\n\n-record(verify_report, {\n\tstart_time :: non_neg_int"
  },
  {
    "path": "apps/arweave/include/ar_wallets.hrl",
    "chars": 559,
    "preview": "%% @doc The maximum number of wallets served via /wallet_list/<root_hash>[/<cursor>].\n-ifdef(AR_TEST).\n-define(WALLET_LI"
  },
  {
    "path": "apps/arweave/include/user_default.hrl",
    "chars": 1371,
    "preview": "%%\n%% This file is only intended to be included into user_default.erl file.\n%% The reason to incluide these headers into"
  },
  {
    "path": "apps/arweave/src/ar.erl",
    "chars": 10483,
    "preview": "%%%===================================================================\n%%% GNU General Public License, version 2 (GPL-2."
  },
  {
    "path": "apps/arweave/src/ar_base32.erl",
    "chars": 2233,
    "preview": "%% @doc This module is very strongly inspired by OTP's base64 source code.\n%% See https://github.com/erlang/otp/blob/93e"
  },
  {
    "path": "apps/arweave/src/ar_bench_hash.erl",
    "chars": 2715,
    "preview": "-module(ar_bench_hash).\n\n-export([run_benchmark_from_cli/1, run_benchmark/1]).\n\n-include_lib(\"arweave/include/ar_consens"
  },
  {
    "path": "apps/arweave/src/ar_bench_packing.erl",
    "chars": 26198,
    "preview": "-module(ar_bench_packing).\n\n-export([show_help/0, run_benchmark_from_cli/1, run_benchmark/1]).\n\n-include_lib(\"arweave/in"
  },
  {
    "path": "apps/arweave/src/ar_bench_timer.erl",
    "chars": 2299,
    "preview": "-module(ar_bench_timer).\n\n-export([initialize/0, reset/0, record/3, start/1, stop/1, get_timing_data/0, print_timing_dat"
  },
  {
    "path": "apps/arweave/src/ar_bench_vdf.erl",
    "chars": 2754,
    "preview": "-module(ar_bench_vdf).\n\n-export([run_benchmark/0, run_benchmark_from_cli/1]).\n\n-include_lib(\"arweave/include/ar_vdf.hrl\""
  },
  {
    "path": "apps/arweave/src/ar_blacklist_middleware.erl",
    "chars": 1811,
    "preview": "-module(ar_blacklist_middleware).\n\n-export([start/0, ban_peer/2, is_peer_banned/1, cleanup_ban/1]).\n-export([start_link/"
  },
  {
    "path": "apps/arweave/src/ar_block.erl",
    "chars": 45949,
    "preview": "-module(ar_block).\n\n-export([get_consensus_window_size/0, get_max_tx_anchor_depth/0,\n\t\tpartition_size/0,\n\t\tget_replica_2"
  },
  {
    "path": "apps/arweave/src/ar_block_cache.erl",
    "chars": 63845,
    "preview": "%%% @doc The module maintains a DAG of blocks that have passed the PoW validation, in ETS.\n%%% NOTE It is not safe to ca"
  },
  {
    "path": "apps/arweave/src/ar_block_index.erl",
    "chars": 7070,
    "preview": "-module(ar_block_index).\n\n-export([init/1, update/2, member/1, get_list/1, get_list_by_hash/1, get_element_by_height/1,\n"
  },
  {
    "path": "apps/arweave/src/ar_block_pre_validator.erl",
    "chars": 35669,
    "preview": "-module(ar_block_pre_validator).\n\n-behaviour(gen_server).\n\n-export([start_link/0, pre_validate/3]).\n\n-export([init/1, ha"
  },
  {
    "path": "apps/arweave/src/ar_block_pre_validator_sup.erl",
    "chars": 719,
    "preview": "-module(ar_block_pre_validator_sup).\n\n-behaviour(supervisor).\n\n-include_lib(\"arweave/include/ar_sup.hrl\").\n-include_lib("
  },
  {
    "path": "apps/arweave/src/ar_block_propagation_worker.erl",
    "chars": 3546,
    "preview": "-module(ar_block_propagation_worker).\n\n-behaviour(gen_server).\n\n-export([start_link/1]).\n\n-export([init/1, handle_call/3"
  },
  {
    "path": "apps/arweave/src/ar_block_time_history.erl",
    "chars": 3482,
    "preview": "-module(ar_block_time_history).\n\n-export([history_length/0, has_history/1, get_history/1, get_history_from_blocks/2, \n\ts"
  },
  {
    "path": "apps/arweave/src/ar_bridge.erl",
    "chars": 12153,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_bridge_sup.erl",
    "chars": 1125,
    "preview": "-module(ar_bridge_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"arweave/in"
  },
  {
    "path": "apps/arweave/src/ar_chain_stats.erl",
    "chars": 6647,
    "preview": "-module(ar_chain_stats).\n\n-behaviour(gen_server).\n\n-include(\"ar.hrl\").\n-include(\"ar_chain_stats.hrl\").\n\n-include_lib(\"ar"
  },
  {
    "path": "apps/arweave/src/ar_chunk_copy.erl",
    "chars": 9517,
    "preview": "%%% @doc The module maintains a queue of processes fetching data from the network\n%%% and from the local storage modules"
  },
  {
    "path": "apps/arweave/src/ar_chunk_storage.erl",
    "chars": 51170,
    "preview": "%% The blob storage optimized for fast reads.\n-module(ar_chunk_storage).\n\n-behaviour(gen_server).\n\n-export([start_link/2"
  },
  {
    "path": "apps/arweave/src/ar_chunk_storage_sup.erl",
    "chars": 947,
    "preview": "-module(ar_chunk_storage_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"arw"
  },
  {
    "path": "apps/arweave/src/ar_chunk_visualization.erl",
    "chars": 6591,
    "preview": "-module(ar_chunk_visualization).\n\n-export([get_chunk_packings/3, get_chunk_packings/4, generate_bitmap/1, bitmap_to_bina"
  },
  {
    "path": "apps/arweave/src/ar_cli_parser.erl",
    "chars": 50563,
    "preview": "%%%===================================================================\n%%% GNU General Public License, version 2 (GPL-2."
  },
  {
    "path": "apps/arweave/src/ar_config.erl",
    "chars": 95341,
    "preview": "%%%===================================================================\n%%% GNU General Public License, version 2 (GPL-2."
  },
  {
    "path": "apps/arweave/src/ar_coordination.erl",
    "chars": 17335,
    "preview": "-module(ar_coordination).\n\n-behaviour(gen_server).\n\n-export([\n\tstart_link/0, computed_h1/2, compute_h2_for_peer/2, compu"
  },
  {
    "path": "apps/arweave/src/ar_data_discovery.erl",
    "chars": 14089,
    "preview": "-module(ar_data_discovery).\n\n-behaviour(gen_server).\n\n-export([start_link/0, get_bucket_peers/1, get_footprint_bucket_pe"
  },
  {
    "path": "apps/arweave/src/ar_data_doctor.erl",
    "chars": 1068,
    "preview": "-module(ar_data_doctor).\n\n-export([main/0, main/1]).\n\n-include_lib(\"arweave/include/ar.hrl\").\n-include_lib(\"arweave_conf"
  },
  {
    "path": "apps/arweave/src/ar_data_root_sync.erl",
    "chars": 7654,
    "preview": "-module(ar_data_root_sync).\n\n-behaviour(gen_server).\n\n-export([start_link/1, name/1, store_data_roots/4, store_data_root"
  },
  {
    "path": "apps/arweave/src/ar_data_root_sync_sup.erl",
    "chars": 1020,
    "preview": "-module(ar_data_root_sync_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n-export([init/1]).\n\n%% internal\n-expo"
  },
  {
    "path": "apps/arweave/src/ar_data_sync.erl",
    "chars": 152807,
    "preview": "-module(ar_data_sync).\n\n-behaviour(gen_server).\n\n-export([name/1, start_link/2, register_workers/0, join/1, add_tip_bloc"
  },
  {
    "path": "apps/arweave/src/ar_data_sync_coordinator.erl",
    "chars": 28039,
    "preview": "%%% @doc Coordinates data sync tasks between worker processes and peer workers.\n%%%\n%%% This module acts as a coordinato"
  },
  {
    "path": "apps/arweave/src/ar_data_sync_sup.erl",
    "chars": 1065,
    "preview": "-module(ar_data_sync_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"ar_sup."
  },
  {
    "path": "apps/arweave/src/ar_data_sync_worker.erl",
    "chars": 11335,
    "preview": "%%% @doc A process fetching the weave data from the network and from the local\n%%% storage modules, one chunk (or a rang"
  },
  {
    "path": "apps/arweave/src/ar_deep_hash.erl",
    "chars": 2419,
    "preview": "-module(ar_deep_hash).\n-export([hash/1]).\n\n-include_lib(\"arweave/include/ar.hrl\").\n-include_lib(\"eunit/include/eunit.hrl"
  },
  {
    "path": "apps/arweave/src/ar_device_lock.erl",
    "chars": 25671,
    "preview": "-module(ar_device_lock).\n\n-behaviour(gen_server).\n\n-export([get_store_id_to_device_map/0, is_ready/0, acquire_lock/3, re"
  },
  {
    "path": "apps/arweave/src/ar_diff_dag.erl",
    "chars": 18033,
    "preview": "%%% @doc A directed acyclic graph with a single sink node. The sink node is supposed\n%%% to store some big expensive to "
  },
  {
    "path": "apps/arweave/src/ar_difficulty.erl",
    "chars": 6326,
    "preview": "-module(ar_difficulty).\n\n-export([get_hash_rate_fixed_ratio/1, next_cumulative_diff/3, multiply_diff_pre_fork_2_5/2,\n\t\t\t"
  },
  {
    "path": "apps/arweave/src/ar_disk_cache.erl",
    "chars": 10707,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_disksup.erl",
    "chars": 14417,
    "preview": "%% Erlang OTP disksup copyright note:\n%%\n%% %CopyrightBegin%\n%%\n%% Copyright Ericsson AB 1996-2018. All Rights Reserved."
  },
  {
    "path": "apps/arweave/src/ar_doctor_bench.erl",
    "chars": 14081,
    "preview": "-module(ar_doctor_bench).\n\n-export([main/1, help/0]).\n\n-include_lib(\"kernel/include/file.hrl\").\n-include_lib(\"arweave/in"
  },
  {
    "path": "apps/arweave/src/ar_doctor_dump.erl",
    "chars": 3353,
    "preview": "-module(ar_doctor_dump).\n\n-export([main/1, help/0]).\n\n-include_lib(\"kernel/include/file.hrl\").\n-include_lib(\"arweave/inc"
  },
  {
    "path": "apps/arweave/src/ar_doctor_inspect.erl",
    "chars": 9347,
    "preview": "-module(ar_doctor_inspect).\n\n-export([main/1, help/0]).\n\n-include_lib(\"arweave/include/ar.hrl\").\n-include_lib(\"arweave/i"
  },
  {
    "path": "apps/arweave/src/ar_doctor_merge.erl",
    "chars": 4761,
    "preview": "-module(ar_doctor_merge).\n\n-export([main/1, help/0]).\n\n-include_lib(\"arweave/include/ar.hrl\").\n-include_lib(\"arweave_con"
  },
  {
    "path": "apps/arweave/src/ar_domain.erl",
    "chars": 1233,
    "preview": "-module(ar_domain).\n\n-export([get_labeling/3, lookup_arweave_txt_record/1, derive_tx_label/2]).\n\n%%%===================="
  },
  {
    "path": "apps/arweave/src/ar_entropy_cache.erl",
    "chars": 5743,
    "preview": "-module(ar_entropy_cache).\n\n-export([get/1, clean_up_space/2, put/3, total_size/0]).\n\n-include(\"ar.hrl\").\n\n-include_lib("
  },
  {
    "path": "apps/arweave/src/ar_entropy_gen.erl",
    "chars": 21328,
    "preview": "-module(ar_entropy_gen).\n\n-behaviour(gen_server).\n\n-export([name/1, register_workers/1,  initialize_context/2,\n\tmap_entr"
  },
  {
    "path": "apps/arweave/src/ar_entropy_storage.erl",
    "chars": 18398,
    "preview": "-module(ar_entropy_storage).\n\n-behaviour(gen_server).\n\n-export([name/1, acquire_semaphore/1, release_semaphore/1, is_rea"
  },
  {
    "path": "apps/arweave/src/ar_ets_intervals.erl",
    "chars": 13354,
    "preview": "%%% @doc The utilities for managing sets of non-overlapping intervals stored in an ETS table.\n%%% The API is similar to "
  },
  {
    "path": "apps/arweave/src/ar_events.erl",
    "chars": 7290,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_events_sup.erl",
    "chars": 2136,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_footprint_record.erl",
    "chars": 20603,
    "preview": "-module(ar_footprint_record).\n\n-export([add/3, add_async/4, delete/2, get_offset/1, get_padded_offset_from_footprint_off"
  },
  {
    "path": "apps/arweave/src/ar_fork.erl",
    "chars": 2817,
    "preview": "%%%\n%%% @doc The module defines Arweave hard forks' heights.\n%%%\n\n-module(ar_fork).\n\n-export([height_1_6/0, height_1_7/0"
  },
  {
    "path": "apps/arweave/src/ar_fraction.erl",
    "chars": 3548,
    "preview": "%%% @doc The module with utilities for performing computations on fractions.\n-module(ar_fraction).\n\n-export([pow/2, natu"
  },
  {
    "path": "apps/arweave/src/ar_global_sync_record.erl",
    "chars": 9791,
    "preview": "-module(ar_global_sync_record).\n\n-behaviour(gen_server).\n\n-include(\"ar.hrl\").\n-include_lib(\"arweave_config/include/arwea"
  },
  {
    "path": "apps/arweave/src/ar_header_sync.erl",
    "chars": 19149,
    "preview": "-module(ar_header_sync).\n\n-behaviour(gen_server).\n\n-export([start_link/0, join/3, add_tip_block/2, add_block/1, request_"
  },
  {
    "path": "apps/arweave/src/ar_header_sync_sup.erl",
    "chars": 713,
    "preview": "-module(ar_header_sync_sup).\n-behaviour(supervisor).\n\n-export([start_link/1]).\n-export([init/1]).\n\n%%%=================="
  },
  {
    "path": "apps/arweave/src/ar_http.erl",
    "chars": 15538,
    "preview": "%%% A wrapper library for gun.\n-module(ar_http).\n\n-behaviour(gen_server).\n\n-export([start_link/0, req/1]).\n\n-ifdef(AR_TE"
  },
  {
    "path": "apps/arweave/src/ar_http_iface_client.erl",
    "chars": 49253,
    "preview": "%%%\n%%% @doc Exposes access to an internal Arweave client to external nodes on the network.\n%%%\n\n-module(ar_http_iface_c"
  },
  {
    "path": "apps/arweave/src/ar_http_iface_middleware.erl",
    "chars": 116989,
    "preview": "-module(ar_http_iface_middleware).\n\n-behaviour(cowboy_middleware).\n\n-export([execute/2, read_body_chunk/4]).\n\n-include_l"
  },
  {
    "path": "apps/arweave/src/ar_http_iface_rate_limiter_middleware.erl",
    "chars": 3939,
    "preview": "%%%\n%%% @doc Cowboy handler to manage server-side rate limiting.\n%%%\n%%% This module provides a routing layer, mapping i"
  },
  {
    "path": "apps/arweave/src/ar_http_iface_server.erl",
    "chars": 10000,
    "preview": "%%%===================================================================\n%%% @doc Handle http requests.\n%%%==============="
  },
  {
    "path": "apps/arweave/src/ar_http_req.erl",
    "chars": 3336,
    "preview": "-module(ar_http_req).\n\n-include_lib(\"arweave/include/ar.hrl\").\n-include_lib(\"arweave_config/include/arweave_config.hrl\")"
  },
  {
    "path": "apps/arweave/src/ar_http_sup.erl",
    "chars": 880,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_http_util.erl",
    "chars": 3370,
    "preview": "-module(ar_http_util).\n\n-export([get_tx_content_type/1, arweave_peer/1]).\n\n-include_lib(\"arweave/include/ar.hrl\").\n-incl"
  },
  {
    "path": "apps/arweave/src/ar_ignore_registry.erl",
    "chars": 2226,
    "preview": "%%% @doc The module offers an interface to the \"ignore registry\" -\n%%% an in-memory storage used for avoiding redundant "
  },
  {
    "path": "apps/arweave/src/ar_inflation.erl",
    "chars": 5326,
    "preview": "%%% @doc Module responsible for managing and testing the inflation schedule of \n%%% the Arweave main network.\n-module(ar"
  },
  {
    "path": "apps/arweave/src/ar_info.erl",
    "chars": 4436,
    "preview": "%%%\n%%% @doc Gathers the data for the /info and /recent endpoints.\n%%%\n\n-module(ar_info).\n\n-export([get_info/0, get_rece"
  },
  {
    "path": "apps/arweave/src/ar_intervals.erl",
    "chars": 15577,
    "preview": "%%% @doc A set of non-overlapping intervals.\n-module(ar_intervals).\n\n-export([new/0, from_list/1, add/3, delete/3, cut/2"
  },
  {
    "path": "apps/arweave/src/ar_join.erl",
    "chars": 19530,
    "preview": "-module(ar_join).\n\n-export([start/1]).\n\n-include(\"ar.hrl\").\n-include_lib(\"arweave_config/include/arweave_config.hrl\").\n-"
  },
  {
    "path": "apps/arweave/src/ar_kv.erl",
    "chars": 28721,
    "preview": "-module(ar_kv).\n\n-behaviour(gen_server).\n\n-export([\n\tstart_link/0, create_ets/0, open/1, open_readonly/1, close/1, put/3"
  },
  {
    "path": "apps/arweave/src/ar_kv_sup.erl",
    "chars": 690,
    "preview": "-module(ar_kv_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"arweave/includ"
  },
  {
    "path": "apps/arweave/src/ar_localnet.erl",
    "chars": 46531,
    "preview": "-module(ar_localnet).\n\n-export([start/0, start/1, submit_snapshot_data/0,\n\t\tmine_one_block/0, mine_until_height/1, creat"
  },
  {
    "path": "apps/arweave/src/ar_localnet_mining_server.erl",
    "chars": 10969,
    "preview": "-module(ar_localnet_mining_server).\n\n-behaviour(ar_mining_server_behaviour).\n-behaviour(gen_server).\n\n-export([start_lin"
  },
  {
    "path": "apps/arweave/src/ar_localnet_mining_sup.erl",
    "chars": 671,
    "preview": "-module(ar_localnet_mining_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"a"
  },
  {
    "path": "apps/arweave/src/ar_logger.erl",
    "chars": 13532,
    "preview": "%%%===================================================================\n%%% GNU General Public License, version 2 (GPL-2."
  },
  {
    "path": "apps/arweave/src/ar_mempool.erl",
    "chars": 21168,
    "preview": "-module(ar_mempool).\n\n-include(\"ar.hrl\").\n\n-export([reset/0, load_from_disk/0, add_tx/2, drop_txs/1, drop_txs/3,\n\t\tget_m"
  },
  {
    "path": "apps/arweave/src/ar_merkle.erl",
    "chars": 42023,
    "preview": "%%% @doc Generates annotated merkle trees, paths inside those trees, as well\n%%% as verification of those proofs.\n-modul"
  },
  {
    "path": "apps/arweave/src/ar_metrics.erl",
    "chars": 24280,
    "preview": "-module(ar_metrics).\n\n-include(\"ar.hrl\").\n\n-export([register/0, get_status_class/1, record_rate_metric/4]).\n\n%%%========"
  },
  {
    "path": "apps/arweave/src/ar_metrics_collector.erl",
    "chars": 2999,
    "preview": "-module(ar_metrics_collector).\n\n-behaviour(prometheus_collector).\n\n-export([\n\tderegister_cleanup/1,\n\tcollect_mf/2\n]).\n\n-"
  },
  {
    "path": "apps/arweave/src/ar_mine_randomx.erl",
    "chars": 16595,
    "preview": "-module(ar_mine_randomx).\n\n-export([init_fast/3, init_light/2, info/1, hash/2, hash/5,\n\t\trandomx_encrypt_chunk/4,\n\t\trand"
  },
  {
    "path": "apps/arweave/src/ar_mining_cache.erl",
    "chars": 26032,
    "preview": "-module(ar_mining_cache).\n-include_lib(\"arweave/include/ar_mining_cache.hrl\").\n-include_lib(\"arweave/include/ar.hrl\").\n\n"
  },
  {
    "path": "apps/arweave/src/ar_mining_hash.erl",
    "chars": 5542,
    "preview": "-module(ar_mining_hash).\n\n-behaviour(gen_server).\n\n-export([start_link/0, compute_h0/2, compute_h1/2, compute_h2/2,\n\t\tga"
  },
  {
    "path": "apps/arweave/src/ar_mining_io.erl",
    "chars": 17593,
    "preview": "-module(ar_mining_io).\n\n-behaviour(gen_server).\n\n-export([start_link/0, start_link/1, set_largest_seen_upper_bound/1,\n\t\t"
  },
  {
    "path": "apps/arweave/src/ar_mining_server.erl",
    "chars": 59504,
    "preview": "%%% @doc The 2.6 mining server.\n-module(ar_mining_server).\n\n-behaviour(ar_mining_server_behaviour).\n-behaviour(gen_serve"
  },
  {
    "path": "apps/arweave/src/ar_mining_server_behaviour.erl",
    "chars": 633,
    "preview": "-module(ar_mining_server_behaviour).\n\n-include(\"ar.hrl\").\n-include(\"ar_mining.hrl\").\n\n-callback start_mining({DiffPair, "
  },
  {
    "path": "apps/arweave/src/ar_mining_stats.erl",
    "chars": 63411,
    "preview": "-module(ar_mining_stats).\n-behaviour(gen_server).\n\n-export([start_link/0, start_performance_reports/0, pause_performance"
  },
  {
    "path": "apps/arweave/src/ar_mining_sup.erl",
    "chars": 1308,
    "preview": "-module(ar_mining_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"arweave/in"
  },
  {
    "path": "apps/arweave/src/ar_mining_worker.erl",
    "chars": 50692,
    "preview": "-module(ar_mining_worker).\n\n-behaviour(gen_server).\n\n-export([start_link/2, name/2, reset_mining_session/2, set_sessions"
  },
  {
    "path": "apps/arweave/src/ar_network_middleware.erl",
    "chars": 1166,
    "preview": "-module(ar_network_middleware).\n\n-behaviour(cowboy_middleware).\n\n-export([execute/2]).\n\n-include_lib(\"arweave/include/ar"
  },
  {
    "path": "apps/arweave/src/ar_node.erl",
    "chars": 14822,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_node_sup.erl",
    "chars": 3648,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_node_utils.erl",
    "chars": 36352,
    "preview": "%%% @doc Different utility functions for node and node worker.\n-module(ar_node_utils).\n\n-export([apply_tx/3, apply_txs/3"
  },
  {
    "path": "apps/arweave/src/ar_node_worker.erl",
    "chars": 85502,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_nonce_limiter.erl",
    "chars": 67099,
    "preview": "-module(ar_nonce_limiter).\n\n-behaviour(gen_server).\n\n-export([start_link/0, account_tree_initialized/1, encode_session_k"
  },
  {
    "path": "apps/arweave/src/ar_nonce_limiter_client.erl",
    "chars": 10391,
    "preview": "-module(ar_nonce_limiter_client).\n\n-behaviour(gen_server).\n\n-export([start_link/0, maybe_request_sessions/1]).\n\n-export("
  },
  {
    "path": "apps/arweave/src/ar_nonce_limiter_server.erl",
    "chars": 7414,
    "preview": "-module(ar_nonce_limiter_server).\n\n-behaviour(gen_server).\n\n-export([start_link/0, make_full_nonce_limiter_update/2, mak"
  },
  {
    "path": "apps/arweave/src/ar_nonce_limiter_server_worker.erl",
    "chars": 7712,
    "preview": "-module(ar_nonce_limiter_server_worker).\n\n-behaviour(gen_server).\n\n-export([start_link/2]).\n\n-export([init/1, handle_cas"
  },
  {
    "path": "apps/arweave/src/ar_nonce_limiter_sup.erl",
    "chars": 1350,
    "preview": "-module(ar_nonce_limiter_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"arw"
  },
  {
    "path": "apps/arweave/src/ar_packing_server.erl",
    "chars": 43314,
    "preview": "-module(ar_packing_server).\n\n-behaviour(gen_server).\n\n-export([start_link/0, packing_atom/1, get_packing_state/0, get_ra"
  },
  {
    "path": "apps/arweave/src/ar_packing_sup.erl",
    "chars": 826,
    "preview": "-module(ar_packing_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"arweave/i"
  },
  {
    "path": "apps/arweave/src/ar_patricia_tree.erl",
    "chars": 29240,
    "preview": "%%% @doc An implementation of a tree closely resembling a merkle patricia tree.\n-module(ar_patricia_tree).\n\n-export([new"
  },
  {
    "path": "apps/arweave/src/ar_peer_intervals.erl",
    "chars": 19912,
    "preview": "-module(ar_peer_intervals).\n\n-export([fetch/5]).\n\n-include_lib(\"arweave_config/include/arweave_config.hrl\").\n\n-include(\""
  },
  {
    "path": "apps/arweave/src/ar_peer_worker.erl",
    "chars": 36141,
    "preview": "%%% @doc Per-peer process managing sync task queue, dispatch state, and footprints.\n%%%\n%%% Each peer gets its own worke"
  },
  {
    "path": "apps/arweave/src/ar_peer_worker_sup.erl",
    "chars": 1039,
    "preview": "%%% @doc Supervisor for ar_peer_worker processes.\n%%% Uses simple_one_for_one to dynamically spawn peer workers on deman"
  },
  {
    "path": "apps/arweave/src/ar_peers.erl",
    "chars": 47741,
    "preview": "%%% @doc Tracks the availability and performance of the network peers.\n-module(ar_peers).\n-behaviour(gen_server).\n-inclu"
  },
  {
    "path": "apps/arweave/src/ar_poa.erl",
    "chars": 11034,
    "preview": "%%% @doc This module implements all mechanisms required to validate a proof of access\n%%% for a chunk of data received f"
  },
  {
    "path": "apps/arweave/src/ar_poller.erl",
    "chars": 6121,
    "preview": "%% This Source Code Form is subject to the terms of the GNU General\n%% Public License, v. 2.0. If a copy of the GPLv2 wa"
  },
  {
    "path": "apps/arweave/src/ar_poller_sup.erl",
    "chars": 1112,
    "preview": "-module(ar_poller_sup).\n\n-behaviour(supervisor).\n\n-export([start_link/0]).\n\n-export([init/1]).\n\n-include_lib(\"arweave/in"
  },
  {
    "path": "apps/arweave/src/ar_poller_worker.erl",
    "chars": 7460,
    "preview": "-module(ar_poller_worker).\n\n-behaviour(gen_server).\n\n-export([start_link/1]).\n\n-export([init/1, handle_call/3, handle_ca"
  },
  {
    "path": "apps/arweave/src/ar_pool.erl",
    "chars": 43465,
    "preview": "%%% @doc The module defines the core pool mining functionality.\n%%%\n%%% The key actors are a pool client, a pool proxy, "
  },
  {
    "path": "apps/arweave/src/ar_pool_cm_job_poller.erl",
    "chars": 2825,
    "preview": "-module(ar_pool_cm_job_poller).\n\n-behaviour(gen_server).\n\n-export([start_link/0]).\n\n-export([init/1, handle_cast/2, hand"
  },
  {
    "path": "apps/arweave/src/ar_pool_job_poller.erl",
    "chars": 3062,
    "preview": "-module(ar_pool_job_poller).\n\n-behaviour(gen_server).\n\n-export([start_link/0]).\n\n-export([init/1, handle_cast/2, handle_"
  },
  {
    "path": "apps/arweave/src/ar_pricing.erl",
    "chars": 36242,
    "preview": "-module(ar_pricing).\n\n%% 2.6 exports.\n-export([get_price_per_gib_minute/2, get_tx_fee/1,\n\t\tget_miner_reward_endowment_po"
  },
  {
    "path": "apps/arweave/src/ar_pricing_transition.erl",
    "chars": 10521,
    "preview": "-module(ar_pricing_transition).\n\n-export([get_transition_price/2, static_price/0, static_pricing_height/0, is_v2_pricing"
  },
  {
    "path": "apps/arweave/src/ar_process_sampler.erl",
    "chars": 9822,
    "preview": "-module(ar_process_sampler).\n-behaviour(gen_server).\n\n-include_lib(\"arweave/include/ar.hrl\").\n\n-export([start_link/0]).\n"
  },
  {
    "path": "apps/arweave/src/ar_prometheus_cowboy_handler.erl",
    "chars": 1868,
    "preview": "%% @doc\n%% Cowboy2 handler for exporting prometheus metrics.\n%% @end\n-module(ar_prometheus_cowboy_handler).\n\n%% -behavio"
  },
  {
    "path": "apps/arweave/src/ar_prometheus_cowboy_labels.erl",
    "chars": 1059,
    "preview": "-module(ar_prometheus_cowboy_labels).\n\n-export([label_value/2]).\n\n%%%==================================================="
  },
  {
    "path": "apps/arweave/src/ar_rate_limiter.erl",
    "chars": 7245,
    "preview": "-module(ar_rate_limiter).\n\n-behaviour(gen_server).\n\n-export([start_link/0, throttle/2, off/0, on/0, is_on_cooldown/2, se"
  },
  {
    "path": "apps/arweave/src/ar_repack.erl",
    "chars": 65945,
    "preview": "-module(ar_repack).\n\n-behaviour(gen_server).\n\n-export([name/1, register_workers/0, get_read_range/3, chunk_range_read/4]"
  },
  {
    "path": "apps/arweave/src/ar_repack_fsm.erl",
    "chars": 28418,
    "preview": "-module(ar_repack_fsm).\n\n-export([crank_state/1]).\n\n-include(\"ar.hrl\").\n-include(\"ar_repack.hrl\").\n-include_lib(\"eunit/i"
  },
  {
    "path": "apps/arweave/src/ar_repack_io.erl",
    "chars": 12186,
    "preview": "-module(ar_repack_io).\n\n-behaviour(gen_server).\n\n-export([name/1, read_footprint/4, write_queue/3]).\n\n-export([start_lin"
  },
  {
    "path": "apps/arweave/src/ar_replica_2_9.erl",
    "chars": 27947,
    "preview": "-module(ar_replica_2_9).\n\n-export([get_entropy_partition/1, get_entropy_partition_range/1, get_entropy_key/3,\n    get_sl"
  },
  {
    "path": "apps/arweave/src/ar_retarget.erl",
    "chars": 13617,
    "preview": "%%% @doc A helper module for deciding when and which blocks will be retarget\n%%% blocks, that is those in which change t"
  },
  {
    "path": "apps/arweave/src/ar_rewards.erl",
    "chars": 11421,
    "preview": "-module(ar_rewards).\n\n-export([reward_history_length/1, expected_hashes_length/1, buffered_reward_history_length/1, \n\t\ts"
  },
  {
    "path": "apps/arweave/src/ar_rx4096_nif.erl",
    "chars": 2033,
    "preview": "-module(ar_rx4096_nif).\n\n-include_lib(\"arweave/include/ar.hrl\").\n\n-on_load(init_nif/0).\n\n-export([rx4096_hash_nif/5, rx4"
  },
  {
    "path": "apps/arweave/src/ar_rx512_nif.erl",
    "chars": 1478,
    "preview": "-module(ar_rx512_nif).\n\n-include_lib(\"arweave/include/ar.hrl\").\n\n-on_load(init_nif/0).\n\n-export([rx512_hash_nif/5, rx512"
  },
  {
    "path": "apps/arweave/src/ar_rxsquared_nif.erl",
    "chars": 1622,
    "preview": "-module(ar_rxsquared_nif).\n\n-include_lib(\"arweave/include/ar.hrl\").\n\n-on_load(init_nif/0).\n\n-export([rxsquared_hash_nif/"
  },
  {
    "path": "apps/arweave/src/ar_semaphore.erl",
    "chars": 3197,
    "preview": "-module(ar_semaphore).\n-behaviour(gen_server).\n\n-export([start_link/2, acquire/2, stop/1]).\n-export([init/1, handle_call"
  },
  {
    "path": "apps/arweave/src/ar_serialize.erl",
    "chars": 91048,
    "preview": "%%% @doc The module contains the serialization and deserialization utilities for the\n%%% various protocol entitities - t"
  },
  {
    "path": "apps/arweave/src/ar_shutdown_manager.erl",
    "chars": 20611,
    "preview": "%%%===================================================================\n%%% This Source Code Form is subject to the terms"
  },
  {
    "path": "apps/arweave/src/ar_storage.erl",
    "chars": 56908,
    "preview": "-module(ar_storage).\n\n-behaviour(gen_server).\n\n-export([start_link/0, read_block_index/0, read_block_index/1, read_rewar"
  },
  {
    "path": "apps/arweave/src/ar_storage_module.erl",
    "chars": 17764,
    "preview": "-module(ar_storage_module).\n\n-export([get_overlap/1, id/1, label/1, address_label/2, module_address/1,\n\t\tmodule_packing_"
  }
]

// ... and 799 more files (download for full content)

About this extraction

This page contains the full source code of the ArweaveTeam/arweave GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 999 files (32.1 MB), approximately 1.4M tokens, and a symbol index with 101 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!