diff --git a/.cirrus.yml b/.cirrus.yml index ebb302d4942d..1474a3f984ab 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -4,7 +4,6 @@ env: # Global defaults MAKEJOBS: "-j10" TEST_RUNNER_PORT_MIN: "14000" # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache CI_FAILFAST_TEST_LEAVE_DANGLING: "1" # Cirrus CI does not care about dangling processes and setting this variable avoids killing the CI script itself on error - RUN_FUNCTIONAL_TESTS: false # Template Provider doesn't have its own functional tests # A self-hosted machine(s) can be used via Cirrus CI. It can be configured with # multiple users to run tasks in parallel. No sudo permission is required. @@ -126,7 +125,7 @@ task: FILE_ENV: "./ci/test/00_setup_env_arm.sh" task: - name: 'CentOS, depends, gui' + name: 'CentOS, depends' << : *GLOBAL_TASK_TEMPLATE persistent_worker: labels: @@ -135,7 +134,7 @@ task: FILE_ENV: "./ci/test/00_setup_env_native_centos.sh" task: - name: 'previous releases, depends DEBUG' + name: 'depends DEBUG' << : *GLOBAL_TASK_TEMPLATE persistent_worker: labels: @@ -144,7 +143,7 @@ task: FILE_ENV: "./ci/test/00_setup_env_native_previous_releases.sh" task: - name: 'TSan, depends, no gui' + name: 'TSan, depends' << : *GLOBAL_TASK_TEMPLATE persistent_worker: labels: @@ -173,25 +172,16 @@ task: FILE_ENV: "./ci/test/00_setup_env_native_fuzz.sh" task: - name: 'no IPC, i686, DEBUG' + name: 'i686, DEBUG' << : *GLOBAL_TASK_TEMPLATE persistent_worker: labels: type: medium env: - FILE_ENV: "./ci/test/00_setup_env_i686_no_ipc.sh" + FILE_ENV: "./ci/test/00_setup_env_i686.sh" task: - name: 'no wallet, libbitcoinkernel' - << : *GLOBAL_TASK_TEMPLATE - persistent_worker: - labels: - type: small - env: - FILE_ENV: "./ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh" - -task: - name: 'macOS-cross, gui, no tests' + name: 'macOS-cross, no tests' << : *GLOBAL_TASK_TEMPLATE persistent_worker: labels: diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml deleted file mode 100644 index 83922b54cbf4..000000000000 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Bug report -description: Submit a new bug report. -labels: [bug] -body: - - type: markdown - attributes: - value: | - ## This issue tracker is only for technical issues related to Bitcoin Core. - - * General bitcoin questions and/or support requests should use Bitcoin StackExchange at https://bitcoin.stackexchange.com. - * For reporting security issues, please read instructions at https://bitcoincore.org/en/contact/. - * If the node is "stuck" during sync or giving "block checksum mismatch" errors, please ensure your hardware is stable by running `memtest` and observe CPU temperature with a load-test tool such as `linpack` before creating an issue. - - ---- - - type: checkboxes - attributes: - label: Is there an existing issue for this? - description: Please search to see if an issue already exists for the bug you encountered. - options: - - label: I have searched the existing issues - required: true - - type: textarea - id: current-behaviour - attributes: - label: Current behaviour - description: Tell us what went wrong - validations: - required: true - - type: textarea - id: expected-behaviour - attributes: - label: Expected behaviour - description: Tell us what you expected to happen - validations: - required: true - - type: textarea - id: reproduction-steps - attributes: - label: Steps to reproduce - description: | - Tell us how to reproduce your bug. Please attach related screenshots if necessary. - * Run-time or compile-time configuration options - * Actions taken - validations: - required: true - - type: textarea - id: logs - attributes: - label: Relevant log output - description: | - Please copy and paste any relevant log output or attach a debug log file. - - You can find the debug.log in your [data dir.](https://github.com/bitcoin/bitcoin/blob/master/doc/files.md#data-directory-location) - - Please be aware that the debug log might contain personally identifying information. - validations: - required: false - - type: dropdown - attributes: - label: How did you obtain Bitcoin Core - multiple: false - options: - - Compiled from source - - Pre-built binaries - - Package manager - - Other - validations: - required: true - - type: input - id: core-version - attributes: - label: What version of Bitcoin Core are you using? - description: Run `bitcoind --version` or in Bitcoin-QT use `Help > About Bitcoin Core` - placeholder: e.g. v24.0.1 or master@e1bf547 - validations: - required: true - - type: input - id: os - attributes: - label: Operating system and version - placeholder: e.g. "MacOS Ventura 13.2" or "Ubuntu 22.04 LTS" - validations: - required: true - - type: textarea - id: machine-specs - attributes: - label: Machine specifications - description: | - What are the specifications of the host machine? - e.g. OS/CPU and disk type, network connectivity - validations: - required: false - diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 40370284a6d8..000000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -blank_issues_enabled: true -contact_links: - - name: Bitcoin Core Security Policy - url: https://github.com/bitcoin/bitcoin/blob/master/SECURITY.md - about: View security policy - - name: Bitcoin Core Developers - url: https://bitcoincore.org - about: Bitcoin Core homepage diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml deleted file mode 100644 index 4622fd981919..000000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Feature Request -description: Suggest an idea for this project. -labels: [Feature] -body: - - type: textarea - id: feature - attributes: - label: Please describe the feature you'd like to see added. - description: Attach screenshots or logs if applicable. - validations: - required: true - - type: textarea - id: related-problem - attributes: - label: Is your feature related to a problem, if so please describe it. - description: Attach screenshots or logs if applicable. - validations: - required: false - - type: textarea - id: solution - attributes: - label: Describe the solution you'd like - validations: - required: false - - type: textarea - id: alternatives - attributes: - label: Describe any alternatives you've considered - validations: - required: false - - type: textarea - id: additional-context - attributes: - label: Please leave any additional context - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/good_first_issue.yml b/.github/ISSUE_TEMPLATE/good_first_issue.yml deleted file mode 100644 index 2a486b3f2b43..000000000000 --- a/.github/ISSUE_TEMPLATE/good_first_issue.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Good First Issue -description: (Regular devs only) Suggest a new good first issue -labels: [good first issue] -body: - - type: markdown - attributes: - value: | - Please add the label "good first issue" manually before or after opening - - A good first issue is an uncontroversial issue, that has a relatively unique and obvious solution - - Motivate the issue and explain the solution briefly - - type: textarea - id: motivation - attributes: - label: Motivation - description: Motivate the issue - validations: - required: true - - type: textarea - id: solution - attributes: - label: Possible solution - description: Describe a possible solution - validations: - required: false - - type: textarea - id: useful-skills - attributes: - label: Useful Skills - description: For example, “`std::thread`”, “Qt6 GUI and async GUI design” or “basic understanding of Bitcoin mining and the Bitcoin Core RPC interface”. - value: | - * Compiling Bitcoin Core from source - * Running the C++ unit tests and the Python functional tests - * ... - - type: textarea - attributes: - label: Guidance for new contributors - description: Please leave this to automatically add the footer for new contributors - value: | - Want to work on this issue? - - For guidance on contributing, please read [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md) before opening your pull request. - diff --git a/.github/ISSUE_TEMPLATE/gui_issue.yml b/.github/ISSUE_TEMPLATE/gui_issue.yml deleted file mode 100644 index 4fe578e9b5b9..000000000000 --- a/.github/ISSUE_TEMPLATE/gui_issue.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Issue or feature request related to the GUI -description: Any report, issue or feature request related to the GUI -labels: [GUI] -body: -- type: checkboxes - id: acknowledgement - attributes: - label: Issues, reports or feature requests related to the GUI should be opened directly on the GUI repo - description: https://github.com/bitcoin-core/gui/issues/ - options: - - label: I still think this issue should be opened here - required: true -- type: textarea - id: gui-request - attributes: - label: Report - validations: - required: true diff --git a/.github/ci-test-each-commit-exec.py b/.github/ci-test-each-commit-exec.py index 72ec332b281c..6b439412a501 100755 --- a/.github/ci-test-each-commit-exec.py +++ b/.github/ci-test-each-commit-exec.py @@ -37,7 +37,6 @@ def main(): "-DAPPEND_CFLAGS='-O3 -g2'", "-DCMAKE_BUILD_TYPE=Debug", "-DWERROR=ON", - "-DBUILD_BENCH=ON", "-DBUILD_FUZZ_BINARY=ON", "-DCMAKE_CXX_FLAGS=-Wno-error=unused-member-function", ]) @@ -51,14 +50,6 @@ def main(): "-j", str(num_procs), ]) - run([ - sys.executable, - "./build/test/functional/test_runner.py", - "-j", - str(num_procs * 2), - "--combinedlogslen=99999999", - ]) - if __name__ == "__main__": main() diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0865c601b792..2e4f20f44267 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,7 +77,7 @@ jobs: git config user.name "CI" - run: | sudo apt-get update - sudo apt-get install clang mold ccache build-essential cmake ninja-build pkgconf python3-zmq libevent-dev libboost-dev libsqlite3-dev systemtap-sdt-dev libzmq3-dev qt6-base-dev qt6-tools-dev qt6-l10n-tools libqrencode-dev capnproto libcapnp-dev -y + sudo apt-get install clang mold ccache build-essential cmake ninja-build pkgconf libboost-dev systemtap-sdt-dev capnproto libcapnp-dev -y - name: Compile and run tests run: | # Run tests on commits after the last merge commit and before the PR head commit @@ -105,7 +105,7 @@ jobs: include: - job-type: standard file-env: './ci/test/00_setup_env_mac_native.sh' - job-name: 'macOS 14 native, arm64, no depends, sqlite only, gui' + job-name: 'macOS 14 native, arm64, no depends' - job-type: fuzz file-env: './ci/test/00_setup_env_mac_native_fuzz.sh' job-name: 'macOS 14 native, arm64, fuzz' @@ -133,7 +133,7 @@ jobs: run: | # A workaround for "The `brew link` step did not complete successfully" error. brew install --quiet python@3 || brew link --overwrite python@3 - brew install --quiet coreutils ninja pkgconf gnu-getopt ccache boost libevent zeromq qt@6 qrencode capnp + brew install --quiet coreutils ninja pkgconf gnu-getopt ccache boost capnp - name: Set Ccache directory run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV" @@ -159,253 +159,222 @@ jobs: # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache key: ${{ github.job }}-${{ matrix.job-type }}-ccache-${{ github.run_id }} - windows-native-dll: - name: ${{ matrix.job-name }} - runs-on: windows-2022 - - if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} - - env: - PYTHONUTF8: 1 - TEST_RUNNER_TIMEOUT_FACTOR: 40 - - strategy: - fail-fast: false - matrix: - job-type: [standard, fuzz] - include: - - job-type: standard - generate-options: '-DBUILD_GUI=ON -DWITH_ZMQ=ON -DBUILD_BENCH=ON -DWERROR=ON' - job-name: 'Windows native, VS 2022' - - job-type: fuzz - generate-options: '-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON -DVCPKG_MANIFEST_FEATURES="wallet" -DBUILD_GUI=OFF -DBUILD_FOR_FUZZING=ON -DWERROR=ON' - job-name: 'Windows native, fuzz, VS 2022' - - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Configure Developer Command Prompt for Microsoft Visual C++ - # Using microsoft/setup-msbuild is not enough. - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: x64 - - - name: Get tool information - shell: pwsh - run: | - cmake -version | Tee-Object -FilePath "cmake_version" - Write-Output "---" - msbuild -version | Tee-Object -FilePath "msbuild_version" - $env:VCToolsVersion | Tee-Object -FilePath "toolset_version" - py -3 --version - Write-Host "PowerShell version $($PSVersionTable.PSVersion.ToString())" - bash --version - - - name: Using vcpkg with MSBuild - run: | - echo "set(VCPKG_BUILD_TYPE release)" >> "${VCPKG_INSTALLATION_ROOT}/triplets/x64-windows.cmake" - # Workaround for libevent, which requires CMake 3.1 but is incompatible with CMake >= 4.0. - sed -i '1s/^/set(ENV{CMAKE_POLICY_VERSION_MINIMUM} 3.5)\n/' "${VCPKG_INSTALLATION_ROOT}/scripts/ports.cmake" - - - name: vcpkg tools cache - uses: actions/cache@v4 - with: - path: C:/vcpkg/downloads/tools - key: ${{ github.job }}-vcpkg-tools - - - name: Restore vcpkg binary cache - uses: actions/cache/restore@v4 - id: vcpkg-binary-cache - with: - path: ~/AppData/Local/vcpkg/archives - key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} - - - name: Generate build system - run: | - cmake -B build -Werror=dev --preset vs2022 -DCMAKE_TOOLCHAIN_FILE="${VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" ${{ matrix.generate-options }} - - - name: Save vcpkg binary cache - uses: actions/cache/save@v4 - if: github.event_name != 'pull_request' && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' && matrix.job-type == 'standard' - with: - path: ~/AppData/Local/vcpkg/archives - key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} - - - name: Build - working-directory: build - run: | - cmake --build . -j $NUMBER_OF_PROCESSORS --config Release - - - name: Get bitcoind manifest - if: matrix.job-type == 'standard' - working-directory: build - run: | - mt.exe -nologo -inputresource:bin/Release/bitcoind.exe -out:bitcoind.manifest - cat bitcoind.manifest - echo - mt.exe -nologo -inputresource:bin/Release/bitcoind.exe -validate_manifest - - - name: Run test suite - if: matrix.job-type == 'standard' - working-directory: build - env: - QT_PLUGIN_PATH: '${{ github.workspace }}\build\vcpkg_installed\x64-windows\Qt6\plugins' - run: | - ctest --output-on-failure --stop-on-failure -j $NUMBER_OF_PROCESSORS -C Release - - - name: Run functional tests - if: matrix.job-type == 'standard' - working-directory: build - env: - BITCOIN_BIN: '${{ github.workspace }}\build\bin\Release\bitcoin.exe' - BITCOIND: '${{ github.workspace }}\build\bin\Release\bitcoind.exe' - BITCOINCLI: '${{ github.workspace }}\build\bin\Release\bitcoin-cli.exe' - BITCOINTX: '${{ github.workspace }}\build\bin\Release\bitcoin-tx.exe' - BITCOINUTIL: '${{ github.workspace }}\build\bin\Release\bitcoin-util.exe' - BITCOINWALLET: '${{ github.workspace }}\build\bin\Release\bitcoin-wallet.exe' - TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }} - run: py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --ci --quiet --tmpdirprefix="${RUNNER_TEMP}" --combinedlogslen=99999999 --timeout-factor=${TEST_RUNNER_TIMEOUT_FACTOR} ${TEST_RUNNER_EXTRA} - - - name: Clone corpora - if: matrix.job-type == 'fuzz' - run: | - git clone --depth=1 https://github.com/bitcoin-core/qa-assets "${RUNNER_TEMP}/qa-assets" - cd "${RUNNER_TEMP}/qa-assets" - echo "Using qa-assets repo from commit ..." - git log -1 - - - name: Run fuzz tests - if: matrix.job-type == 'fuzz' - working-directory: build - env: - BITCOINFUZZ: '${{ github.workspace }}\build\bin\Release\fuzz.exe' - run: | - py -3 test/fuzz/test_runner.py --par $NUMBER_OF_PROCESSORS --loglevel DEBUG "${RUNNER_TEMP}/qa-assets/fuzz_corpora" - - windows-cross: - name: 'Linux->Windows cross, no tests' - runs-on: ubuntu-latest - if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} - - env: - FILE_ENV: './ci/test/00_setup_env_win64.sh' - DANGER_CI_ON_HOST_FOLDERS: 1 - - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Set CI directories - run: | - echo "CCACHE_DIR=${{ runner.temp }}/ccache_dir" >> "$GITHUB_ENV" - echo "BASE_ROOT_DIR=${{ runner.temp }}" >> "$GITHUB_ENV" - echo "DEPENDS_DIR=${{ runner.temp }}/depends" >> "$GITHUB_ENV" - echo "BASE_BUILD_DIR=${{ runner.temp }}/build" >> "$GITHUB_ENV" - - - name: Depends cache - uses: actions/cache@v4 - with: - path: ${{ env.DEPENDS_DIR }}/built - key: ${{ github.job }}-depends-${{ hashFiles('depends/**', 'ci/test/00_setup_env_win64.sh') }} - - - name: Restore Ccache cache - id: ccache-cache - uses: actions/cache/restore@v4 - with: - path: ${{ env.CCACHE_DIR }} - key: ${{ github.job }}-ccache-${{ github.run_id }} - restore-keys: ${{ github.job }}-ccache- - - - name: CI script - run: ./ci/test_run_all.sh - - - name: Save Ccache cache - uses: actions/cache/save@v4 - if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' - with: - path: ${{ env.CCACHE_DIR }} - key: ${{ github.job }}-ccache-${{ github.run_id }} - - - name: Upload built executables - uses: actions/upload-artifact@v4 - with: - name: x86_64-w64-mingw32-executables-${{ github.run_id }} - path: | - ${{ env.BASE_BUILD_DIR }}/bin/*.exe - ${{ env.BASE_BUILD_DIR }}/src/secp256k1/bin/*.exe - ${{ env.BASE_BUILD_DIR }}/src/univalue/*.exe - ${{ env.BASE_BUILD_DIR }}/test/config.ini - - windows-native-test: - name: 'Windows, test cross-built' - runs-on: windows-2022 - needs: windows-cross - - env: - PYTHONUTF8: 1 - TEST_RUNNER_TIMEOUT_FACTOR: 40 - - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Download built executables - uses: actions/download-artifact@v4 - with: - name: x86_64-w64-mingw32-executables-${{ github.run_id }} - - - name: Run bitcoind.exe - run: ./bin/bitcoind.exe -version - - - name: Find mt.exe tool - shell: pwsh - run: | - $sdk_dir = (Get-ItemProperty 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots' -Name KitsRoot10).KitsRoot10 - $sdk_latest = (Get-ChildItem "$sdk_dir\bin" -Directory | Where-Object { $_.Name -match '^\d+\.\d+\.\d+\.\d+$' } | Sort-Object Name -Descending | Select-Object -First 1).Name - "MT_EXE=${sdk_dir}bin\${sdk_latest}\x64\mt.exe" >> $env:GITHUB_ENV - - - name: Get bitcoind manifest - shell: pwsh - run: | - & $env:MT_EXE -nologo -inputresource:bin\bitcoind.exe -out:bitcoind.manifest - Get-Content bitcoind.manifest - & $env:MT_EXE -nologo -inputresource:bin\bitcoind.exe -validate_manifest - - - name: Run unit tests - # Can't use ctest here like other jobs as we don't have a CMake build tree. - run: | - ./bin/test_bitcoin.exe -l test_suite - ./src/secp256k1/bin/exhaustive_tests.exe - ./src/secp256k1/bin/noverify_tests.exe - ./src/secp256k1/bin/tests.exe - ./src/univalue/object.exe - ./src/univalue/unitester.exe - - - name: Run benchmarks - run: ./bin/bench_bitcoin.exe -sanity-check - - - name: Adjust paths in test/config.ini - shell: pwsh - run: | - (Get-Content "test/config.ini") -replace '(?<=^SRCDIR=).*', '${{ github.workspace }}' -replace '(?<=^BUILDDIR=).*', '${{ github.workspace }}' -replace '(?<=^RPCAUTH=).*', '${{ github.workspace }}/share/rpcauth/rpcauth.py' | Set-Content "test/config.ini" - Get-Content "test/config.ini" - - - name: Set previous release directory - run: | - echo "PREVIOUS_RELEASES_DIR=${{ runner.temp }}/previous_releases" >> "$GITHUB_ENV" - - - name: Get previous releases - working-directory: test - run: ./get_previous_releases.py --target-dir $PREVIOUS_RELEASES_DIR - - - name: Run functional tests - env: - # TODO: Fix the excluded test and re-enable it. - # feature_unsupported_utxo_db.py fails on windows because of emojis in the test data directory - EXCLUDE: '--exclude wallet_multiwallet.py,feature_unsupported_utxo_db.py' - TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }} - run: py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --ci --quiet --tmpdirprefix="$RUNNER_TEMP" --combinedlogslen=99999999 --timeout-factor=$TEST_RUNNER_TIMEOUT_FACTOR $EXCLUDE $TEST_RUNNER_EXTRA + # windows-native-dll: + # name: ${{ matrix.job-name }} + # runs-on: windows-2022 + + # if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} + + # env: + # PYTHONUTF8: 1 + # TEST_RUNNER_TIMEOUT_FACTOR: 40 + + # strategy: + # fail-fast: false + # matrix: + # job-type: [standard, fuzz] + # include: + # - job-type: standard + # generate-options: '-DWERROR=ON' + # job-name: 'Windows native, VS 2022' + # - job-type: fuzz + # generate-options: '-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON -DVCPKG_MANIFEST_FEATURES="wallet" -DBUILD_FOR_FUZZING=ON -DWERROR=ON' + # job-name: 'Windows native, fuzz, VS 2022' + + # steps: + # - name: Checkout + # uses: actions/checkout@v5 + + # - name: Configure Developer Command Prompt for Microsoft Visual C++ + # # Using microsoft/setup-msbuild is not enough. + # uses: ilammy/msvc-dev-cmd@v1 + # with: + # arch: x64 + + # - name: Get tool information + # shell: pwsh + # run: | + # cmake -version | Tee-Object -FilePath "cmake_version" + # Write-Output "---" + # msbuild -version | Tee-Object -FilePath "msbuild_version" + # $env:VCToolsVersion | Tee-Object -FilePath "toolset_version" + # py -3 --version + # Write-Host "PowerShell version $($PSVersionTable.PSVersion.ToString())" + # bash --version + + # - name: Using vcpkg with MSBuild + # run: | + # echo "set(VCPKG_BUILD_TYPE release)" >> "${VCPKG_INSTALLATION_ROOT}/triplets/x64-windows.cmake" + + # - name: vcpkg tools cache + # uses: actions/cache@v4 + # with: + # path: C:/vcpkg/downloads/tools + # key: ${{ github.job }}-vcpkg-tools + + # - name: Restore vcpkg binary cache + # uses: actions/cache/restore@v4 + # id: vcpkg-binary-cache + # with: + # path: ~/AppData/Local/vcpkg/archives + # key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} + + # - name: Generate build system + # run: | + # cmake -B build -Werror=dev --preset vs2022 -DCMAKE_TOOLCHAIN_FILE="${VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" ${{ matrix.generate-options }} + + # - name: Save vcpkg binary cache + # uses: actions/cache/save@v4 + # if: github.event_name != 'pull_request' && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' && matrix.job-type == 'standard' + # with: + # path: ~/AppData/Local/vcpkg/archives + # key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} + + # - name: Build + # working-directory: build + # run: | + # cmake --build . -j $NUMBER_OF_PROCESSORS --config Release + + # - name: Get bitcoind manifest + # if: matrix.job-type == 'standard' + # working-directory: build + # run: | + # mt.exe -nologo -inputresource:bin/Release/bitcoind.exe -out:bitcoind.manifest + # cat bitcoind.manifest + # echo + # mt.exe -nologo -inputresource:bin/Release/bitcoind.exe -validate_manifest + + # - name: Run test suite + # if: matrix.job-type == 'standard' + # working-directory: build + # run: | + # ctest --output-on-failure --stop-on-failure -j $NUMBER_OF_PROCESSORS -C Release + + # - name: Clone corpora + # if: matrix.job-type == 'fuzz' + # run: | + # git clone --depth=1 https://github.com/bitcoin-core/qa-assets "${RUNNER_TEMP}/qa-assets" + # cd "${RUNNER_TEMP}/qa-assets" + # echo "Using qa-assets repo from commit ..." + # git log -1 + + # - name: Run fuzz tests + # if: matrix.job-type == 'fuzz' + # working-directory: build + # env: + # BITCOINFUZZ: '${{ github.workspace }}\build\bin\Release\fuzz.exe' + # run: | + # py -3 test/fuzz/test_runner.py --par $NUMBER_OF_PROCESSORS --loglevel DEBUG "${RUNNER_TEMP}/qa-assets/fuzz_corpora" + + # Disabled pending Windows support + # windows-cross: + # name: 'Linux->Windows cross, no tests' + # runs-on: ubuntu-latest + # if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} + + # env: + # FILE_ENV: './ci/test/00_setup_env_win64.sh' + # DANGER_CI_ON_HOST_FOLDERS: 1 + + # steps: + # - name: Checkout + # uses: actions/checkout@v5 + + # - name: Set CI directories + # run: | + # echo "CCACHE_DIR=${{ runner.temp }}/ccache_dir" >> "$GITHUB_ENV" + # echo "BASE_ROOT_DIR=${{ runner.temp }}" >> "$GITHUB_ENV" + # echo "DEPENDS_DIR=${{ runner.temp }}/depends" >> "$GITHUB_ENV" + # echo "BASE_BUILD_DIR=${{ runner.temp }}/build" >> "$GITHUB_ENV" + + # - name: Depends cache + # uses: actions/cache@v4 + # with: + # path: ${{ env.DEPENDS_DIR }}/built + # key: ${{ github.job }}-depends-${{ hashFiles('depends/**', 'ci/test/00_setup_env_win64.sh') }} + + # - name: Restore Ccache cache + # id: ccache-cache + # uses: actions/cache/restore@v4 + # with: + # path: ${{ env.CCACHE_DIR }} + # key: ${{ github.job }}-ccache-${{ github.run_id }} + # restore-keys: ${{ github.job }}-ccache- + + # - name: CI script + # run: ./ci/test_run_all.sh + + # - name: Save Ccache cache + # uses: actions/cache/save@v4 + # if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true' + # with: + # path: ${{ env.CCACHE_DIR }} + # key: ${{ github.job }}-ccache-${{ github.run_id }} + + # - name: Upload built executables + # uses: actions/upload-artifact@v4 + # with: + # name: x86_64-w64-mingw32-executables-${{ github.run_id }} + # path: | + # ${{ env.BASE_BUILD_DIR }}/bin/*.exe + # ${{ env.BASE_BUILD_DIR }}/src/secp256k1/bin/*.exe + # ${{ env.BASE_BUILD_DIR }}/src/univalue/*.exe + # ${{ env.BASE_BUILD_DIR }}/test/config.ini + + # windows-native-test: + # name: 'Windows, test cross-built' + # runs-on: windows-2022 + # needs: windows-cross + + # env: + # PYTHONUTF8: 1 + # TEST_RUNNER_TIMEOUT_FACTOR: 40 + + # steps: + # - name: Checkout + # uses: actions/checkout@v5 + + # - name: Download built executables + # uses: actions/download-artifact@v4 + # with: + # name: x86_64-w64-mingw32-executables-${{ github.run_id }} + + # - name: Run bitcoind.exe + # run: ./bin/bitcoind.exe -version + + # - name: Find mt.exe tool + # shell: pwsh + # run: | + # $sdk_dir = (Get-ItemProperty 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots' -Name KitsRoot10).KitsRoot10 + # $sdk_latest = (Get-ChildItem "$sdk_dir\bin" -Directory | Where-Object { $_.Name -match '^\d+\.\d+\.\d+\.\d+$' } | Sort-Object Name -Descending | Select-Object -First 1).Name + # "MT_EXE=${sdk_dir}bin\${sdk_latest}\x64\mt.exe" >> $env:GITHUB_ENV + + # - name: Get bitcoind manifest + # shell: pwsh + # run: | + # & $env:MT_EXE -nologo -inputresource:bin\bitcoind.exe -out:bitcoind.manifest + # Get-Content bitcoind.manifest + # & $env:MT_EXE -nologo -inputresource:bin\bitcoind.exe -validate_manifest + + # - name: Run unit tests + # # Can't use ctest here like other jobs as we don't have a CMake build tree. + # run: | + # ./bin/test_sv2.exe -l test_suite + # ./src/secp256k1/bin/exhaustive_tests.exe + # ./src/secp256k1/bin/noverify_tests.exe + # ./src/secp256k1/bin/tests.exe + # ./src/univalue/object.exe + # ./src/univalue/unitester.exe + + # - name: Adjust paths in test/config.ini + # shell: pwsh + # run: | + # (Get-Content "test/config.ini") -replace '(?<=^SRCDIR=).*', '${{ github.workspace }}' -replace '(?<=^BUILDDIR=).*', '${{ github.workspace }}' -replace '(?<=^RPCAUTH=).*', '${{ github.workspace }}/share/rpcauth/rpcauth.py' | Set-Content "test/config.ini" + # Get-Content "test/config.ini" + + # - name: Set previous release directory + # run: | + # echo "PREVIOUS_RELEASES_DIR=${{ runner.temp }}/previous_releases" >> "$GITHUB_ENV" asan-lsan-ubsan-integer-no-depends-usdt: name: 'ASan + LSan + UBSan + integer, no depends, USDT' diff --git a/.tx/config b/.tx/config deleted file mode 100644 index a7550d0884dc..000000000000 --- a/.tx/config +++ /dev/null @@ -1,7 +0,0 @@ -[main] -host = https://www.transifex.com - -[o:bitcoin:p:bitcoin:r:qt-translation-030x] -file_filter = src/qt/locale/bitcoin_.xlf -source_file = src/qt/locale/bitcoin_en.xlf -source_lang = en diff --git a/CMakeLists.txt b/CMakeLists.txt index ccc3ba37ac1e..b7ee3519797a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,9 +26,9 @@ get_directory_property(precious_variables CACHE_VARIABLES) #============================= # Project / Package metadata #============================= -set(CLIENT_NAME "Bitcoin Core") -set(CLIENT_VERSION_MAJOR 29) -set(CLIENT_VERSION_MINOR 99) +set(CLIENT_NAME "Sv2 Template Provider") +set(CLIENT_VERSION_MAJOR 0) +set(CLIENT_VERSION_MINOR 2) set(CLIENT_VERSION_BUILD 0) set(CLIENT_VERSION_RC 0) set(CLIENT_VERSION_IS_RELEASE "false") @@ -52,8 +52,8 @@ set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES project(BitcoinCore VERSION ${CLIENT_VERSION_MAJOR}.${CLIENT_VERSION_MINOR}.${CLIENT_VERSION_BUILD} - DESCRIPTION "Bitcoin client software" - HOMEPAGE_URL "https://bitcoincore.org/" + DESCRIPTION "Sv2 Template Provider" + HOMEPAGE_URL "https://github.com/sjors/sv2-tp" LANGUAGES NONE ) @@ -64,7 +64,7 @@ endif() set(COPYRIGHT_HOLDERS "The %s developers") set(COPYRIGHT_HOLDERS_FINAL "The ${CLIENT_NAME} developers") -set(CLIENT_BUGREPORT "https://github.com/bitcoin/bitcoin/issues") +set(CLIENT_BUGREPORT "https://github.com/sjors/sv2-tp/issues") #============================= # Language setup @@ -94,86 +94,28 @@ endif() #============================= include(CMakeDependentOption) # When adding a new option, end the with a full stop for consistency. -option(BUILD_BITCOIN_BIN "Build bitcoin executable." ON) -option(BUILD_DAEMON "Build bitcoind executable." ON) -option(BUILD_GUI "Build bitcoin-qt executable." OFF) -option(BUILD_CLI "Build bitcoin-cli executable." ON) - -option(BUILD_TESTS "Build test_bitcoin and other unit test executables." ON) -option(BUILD_TX "Build bitcoin-tx executable." ${BUILD_TESTS}) -option(BUILD_UTIL "Build bitcoin-util executable." ${BUILD_TESTS}) - -option(BUILD_UTIL_CHAINSTATE "Build experimental bitcoin-chainstate executable." OFF) -option(BUILD_KERNEL_LIB "Build experimental bitcoinkernel library." ${BUILD_UTIL_CHAINSTATE}) - -option(ENABLE_WALLET "Enable wallet." ON) -if(ENABLE_WALLET) - if(VCPKG_TARGET_TRIPLET) - # Use of the `unofficial::` namespace is a vcpkg package manager convention. - find_package(unofficial-sqlite3 CONFIG REQUIRED) - else() - find_package(SQLite3 3.7.17 REQUIRED) - endif() -endif() -cmake_dependent_option(BUILD_WALLET_TOOL "Build bitcoin-wallet tool." ${BUILD_TESTS} "ENABLE_WALLET" OFF) + +option(BUILD_TESTS "Build test_sv2 and other unit test executables." ON) option(REDUCE_EXPORTS "Attempt to reduce exported symbols in the resulting executables." OFF) option(WERROR "Treat compiler warnings as errors." OFF) option(WITH_CCACHE "Attempt to use ccache for compiling." ON) -option(WITH_ZMQ "Enable ZMQ notifications." OFF) -if(WITH_ZMQ) - find_package(ZeroMQ 4.0.0 MODULE REQUIRED) -endif() - option(WITH_USDT "Enable tracepoints for Userspace, Statically Defined Tracing." OFF) if(WITH_USDT) find_package(USDT MODULE REQUIRED) endif() -option(ENABLE_EXTERNAL_SIGNER "Enable external signer support." ON) - -cmake_dependent_option(WITH_QRENCODE "Enable QR code support." ON "BUILD_GUI" OFF) -if(WITH_QRENCODE) - find_package(QRencode MODULE REQUIRED) - set(USE_QRCODE TRUE) -endif() - -cmake_dependent_option(WITH_DBUS "Enable DBus support." ON "NOT CMAKE_SYSTEM_NAME MATCHES \"(Windows|Darwin)\" AND BUILD_GUI" OFF) - -cmake_dependent_option(ENABLE_IPC "Build multiprocess bitcoin-node and bitcoin-gui executables in addition to monolithic bitcoind and bitcoin-qt executables." ON "NOT WIN32" OFF) -cmake_dependent_option(WITH_EXTERNAL_LIBMULTIPROCESS "Build with external libmultiprocess library instead of with local git subtree when ENABLE_IPC is enabled. This is not normally recommended, but can be useful for developing libmultiprocess itself." OFF "ENABLE_IPC" OFF) -if(ENABLE_IPC AND WITH_EXTERNAL_LIBMULTIPROCESS) +option(WITH_EXTERNAL_LIBMULTIPROCESS "Build with external libmultiprocess library instead of with local git subtree. This is not normally recommended, but can be useful for developing libmultiprocess itself." OFF) +if(WITH_EXTERNAL_LIBMULTIPROCESS) find_package(Libmultiprocess REQUIRED COMPONENTS Lib) find_package(LibmultiprocessNative REQUIRED COMPONENTS Bin NAMES Libmultiprocess ) endif() -cmake_dependent_option(WITH_SV2 "Enable Stratum v2 functionality." ON "NOT WIN32" OFF) +option(BUILD_MINE "Build sv2-tp executable." ON) -cmake_dependent_option(BUILD_MINE "Build experimental bitcoin-mine executable." ON "ENABLE_IPC;WITH_SV2" OFF) - -cmake_dependent_option(BUILD_GUI_TESTS "Build test_bitcoin-qt executable." ON "BUILD_GUI;BUILD_TESTS" OFF) -if(BUILD_GUI) - set(qt_components Core Gui Widgets LinguistTools) - if(ENABLE_WALLET) - list(APPEND qt_components Network) - endif() - if(WITH_DBUS) - list(APPEND qt_components DBus) - set(USE_DBUS TRUE) - endif() - if(BUILD_GUI_TESTS) - list(APPEND qt_components Test) - endif() - find_package(Qt 6.2 MODULE REQUIRED - COMPONENTS ${qt_components} - ) - unset(qt_components) -endif() - -option(BUILD_BENCH "Build bench_bitcoin executable." OFF) option(BUILD_FUZZ_BINARY "Build fuzz binary." OFF) option(BUILD_FOR_FUZZING "Build for fuzzing. Enabling this will disable all other targets and override BUILD_FUZZ_BINARY." OFF) @@ -207,21 +149,8 @@ target_link_libraries(core_interface INTERFACE if(BUILD_FOR_FUZZING) message(WARNING "BUILD_FOR_FUZZING=ON will disable all other targets and force BUILD_FUZZ_BINARY=ON.") - set(BUILD_BITCOIN_BIN OFF) - set(BUILD_DAEMON OFF) - set(BUILD_CLI OFF) - set(BUILD_TX OFF) - set(BUILD_UTIL OFF) - set(BUILD_UTIL_CHAINSTATE OFF) set(BUILD_MINE OFF) - set(BUILD_KERNEL_LIB OFF) - set(BUILD_WALLET_TOOL OFF) - set(BUILD_GUI OFF) - set(ENABLE_EXTERNAL_SIGNER OFF) - set(WITH_ZMQ OFF) set(BUILD_TESTS OFF) - set(BUILD_GUI_TESTS OFF) - set(BUILD_BENCH OFF) set(BUILD_FUZZ_BINARY ON) target_compile_definitions(core_interface INTERFACE @@ -237,7 +166,6 @@ target_compile_definitions(core_interface_debug INTERFACE DEBUG DEBUG_LOCKORDER DEBUG_LOCKCONTENTION - RPC_DOC_CHECK ABORT_ON_FAILED_ASSUME ) @@ -417,10 +345,6 @@ endif() include(AddBoostIfNeeded) add_boost_if_needed() -if(BUILD_DAEMON OR BUILD_GUI OR BUILD_CLI OR BUILD_TESTS OR BUILD_BENCH OR BUILD_FUZZ_BINARY) - find_package(Libevent 2.1.8 MODULE REQUIRED) -endif() - include(cmake/introspection.cmake) include(cmake/ccache.cmake) @@ -645,62 +569,23 @@ include(Maintenance) setup_split_debug_script() add_maintenance_targets() add_windows_deploy_target() -add_macos_deploy_target() message("\n") message("Configure summary") message("=================") message("Executables:") -message(" bitcoin ............................. ${BUILD_BITCOIN_BIN}") -message(" bitcoind ............................ ${BUILD_DAEMON}") -if(BUILD_DAEMON AND ENABLE_IPC) - set(bitcoin_daemon_status ON) -else() - set(bitcoin_daemon_status OFF) -endif() -message(" bitcoin-node (multiprocess) ......... ${bitcoin_daemon_status}") -message(" bitcoin-qt (GUI) .................... ${BUILD_GUI}") -if(BUILD_GUI AND ENABLE_IPC) - set(bitcoin_gui_status ON) -else() - set(bitcoin_gui_status OFF) -endif() -message(" bitcoin-gui (GUI, multiprocess) ..... ${bitcoin_gui_status}") -message(" bitcoin-cli ......................... ${BUILD_CLI}") -message(" bitcoin-tx .......................... ${BUILD_TX}") -message(" bitcoin-util ........................ ${BUILD_UTIL}") -message(" bitcoin-wallet ...................... ${BUILD_WALLET_TOOL}") -message(" bitcoin-chainstate (experimental) ... ${BUILD_UTIL_CHAINSTATE}") -message(" libbitcoinkernel (experimental) ..... ${BUILD_KERNEL_LIB}") -if(WITH_SV2 AND ENABLE_IPC) - set(bitcoin_mine_status ON) +message(" sv2-tp .............................. ${BUILD_MINE}") +message("Libraries:") +if (WITH_EXTERNAL_LIBMULTIPROCESS) + set(ipc_status "ON (with external libmultiprocess)") else() - set(bitcoin_mine_status OFF) -endif() -message(" bitcoin-mine (experimental) ......... ${bitcoin_mine_status}") -message("Optional features:") -message(" wallet support ...................... ${ENABLE_WALLET}") -message(" external signer ..................... ${ENABLE_EXTERNAL_SIGNER}") -message(" ZeroMQ .............................. ${WITH_ZMQ}") -if(ENABLE_IPC) - if (WITH_EXTERNAL_LIBMULTIPROCESS) - set(ipc_status "ON (with external libmultiprocess)") - else() - set(ipc_status ON) - endif() -else() - set(ipc_status OFF) + set(ipc_status ON) endif() message(" IPC ................................. ${ipc_status}") +message("Optional features:") message(" USDT tracing ........................ ${WITH_USDT}") -message(" QR code (GUI) ....................... ${WITH_QRENCODE}") -message(" DBus (GUI) .......................... ${WITH_DBUS}") -message(" Stratum v2 .......................... ${WITH_SV2}") -message(" bitcoin-mine (multiprocess) ......... ${BUILD_MINE}") message("Tests:") -message(" test_bitcoin ........................ ${BUILD_TESTS}") -message(" test_bitcoin-qt ..................... ${BUILD_GUI_TESTS}") -message(" bench_bitcoin ....................... ${BUILD_BENCH}") +message(" test_sv2 ............................ ${BUILD_TESTS}") message(" fuzz binary ......................... ${BUILD_FUZZ_BINARY}") message("") if(CMAKE_CROSSCOMPILING) diff --git a/CMakePresets.json b/CMakePresets.json index d478af3e70b1..48fdb7a433d1 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -13,8 +13,7 @@ "architecture": "x64", "toolchainFile": "$env{VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake", "cacheVariables": { - "VCPKG_TARGET_TRIPLET": "x64-windows", - "BUILD_GUI": "ON" + "VCPKG_TARGET_TRIPLET": "x64-windows" } }, { @@ -29,8 +28,7 @@ "architecture": "x64", "toolchainFile": "$env{VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake", "cacheVariables": { - "VCPKG_TARGET_TRIPLET": "x64-windows-static", - "BUILD_GUI": "ON" + "VCPKG_TARGET_TRIPLET": "x64-windows-static" } }, { @@ -63,25 +61,10 @@ "binaryDir": "${sourceDir}/build_dev_mode", "errors": {"dev": true}, "cacheVariables": { - "BUILD_BENCH": "ON", - "BUILD_CLI": "ON", - "BUILD_DAEMON": "ON", "BUILD_FUZZ_BINARY": "ON", - "BUILD_GUI": "ON", - "BUILD_GUI_TESTS": "ON", - "BUILD_KERNEL_LIB": "ON", "BUILD_SHARED_LIBS": "ON", "BUILD_TESTS": "ON", - "BUILD_TX": "ON", - "BUILD_UTIL": "ON", - "BUILD_UTIL_CHAINSTATE": "ON", - "BUILD_WALLET_TOOL": "ON", - "ENABLE_EXTERNAL_SIGNER": "ON", - "ENABLE_WALLET": "ON", - "ENABLE_IPC": "ON", - "WITH_QRENCODE": "ON", - "WITH_USDT": "ON", - "WITH_ZMQ": "ON" + "WITH_USDT": "ON" } } ] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 7f42f0be3aa6..000000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,444 +0,0 @@ -Contributing to Bitcoin Core -============================ - -The Bitcoin Core project operates an open contributor model where anyone is -welcome to contribute towards development in the form of peer review, testing -and patches. This document explains the practical process and guidelines for -contributing. - -First, in terms of structure, there is no particular concept of "Bitcoin Core -developers" in the sense of privileged people. Open source often naturally -revolves around a meritocracy where contributors earn trust from the developer -community over time. Nevertheless, some hierarchy is necessary for practical -purposes. As such, there are repository maintainers who are responsible for -merging pull requests, the [release cycle](/doc/release-process.md), and -moderation. - -Getting Started ---------------- - -New contributors are very welcome and needed. - -Reviewing and testing is highly valued and the most effective way you can contribute -as a new contributor. It also will teach you much more about the code and -process than opening pull requests. Please refer to the [peer review](#peer-review) -section below. - -Before you start contributing, familiarize yourself with the Bitcoin Core build -system and tests. Refer to the documentation in the repository on how to build -Bitcoin Core and how to run the unit tests, functional tests, and fuzz tests. - -There are many open issues of varying difficulty waiting to be fixed. -If you're looking for somewhere to start contributing, check out the -[good first issue](https://github.com/bitcoin/bitcoin/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) -list or changes that are -[up for grabs](https://github.com/bitcoin/bitcoin/issues?utf8=%E2%9C%93&q=label%3A%22Up+for+grabs%22). -Some of them might no longer be applicable. So if you are interested, but -unsure, you might want to leave a comment on the issue first. - -You may also participate in the [Bitcoin Core PR Review Club](https://bitcoincore.reviews/). - -### Good First Issue Label - -The purpose of the `good first issue` label is to highlight which issues are -suitable for a new contributor without a deep understanding of the codebase. - -However, good first issues can be solved by anyone. If they remain unsolved -for a longer time, a frequent contributor might address them. - -You do not need to request permission to start working on an issue. However, -you are encouraged to leave a comment if you are planning to work on it. This -will help other contributors monitor which issues are actively being addressed -and is also an effective way to request assistance if and when you need it. - -Communication Channels ----------------------- - -Most communication about Bitcoin Core development happens on IRC, in the -`#bitcoin-core-dev` channel on Libera Chat. The easiest way to participate on IRC is -with the web client, [web.libera.chat](https://web.libera.chat/#bitcoin-core-dev). Chat -history logs can be found -on [https://www.erisian.com.au/bitcoin-core-dev/](https://www.erisian.com.au/bitcoin-core-dev/) -and [https://gnusha.org/bitcoin-core-dev/](https://gnusha.org/bitcoin-core-dev/). - -Discussion about codebase improvements happens in GitHub issues and pull -requests. - -The developer -[mailing list](https://groups.google.com/g/bitcoindev) -should be used to discuss complicated or controversial consensus or P2P protocol changes before working on -a patch set. -Archives can be found on [https://gnusha.org/pi/bitcoindev/](https://gnusha.org/pi/bitcoindev/). - - -Contributor Workflow --------------------- - -The codebase is maintained using the "contributor workflow" where everyone -without exception contributes patch proposals using "pull requests" (PRs). This -facilitates social contribution, easy testing and peer review. - -To contribute a patch, the workflow is as follows: - - 1. Fork repository ([only for the first time](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo)) - 1. Create topic branch - 1. Commit patches - -For GUI-related issues or pull requests, the https://github.com/bitcoin-core/gui repository should be used. -For all other issues and pull requests, the https://github.com/bitcoin/bitcoin node repository should be used. - -The master branch for all monotree repositories is identical. - -As a rule of thumb, everything that only modifies `src/qt` is a GUI-only pull -request. However: - -* For global refactoring or other transversal changes the node repository - should be used. -* For GUI-related build system changes, the node repository should be used - because the change needs review by the build systems reviewers. -* Changes in `src/interfaces` need to go to the node repository because they - might affect other components like the wallet. - -For large GUI changes that include build system and interface changes, it is -recommended to first open a pull request against the GUI repository. When there -is agreement to proceed with the changes, a pull request with the build system -and interfaces changes can be submitted to the node repository. - -The project coding conventions in the [developer notes](doc/developer-notes.md) -must be followed. - -### Committing Patches - -In general, [commits should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) -and diffs should be easy to read. For this reason, do not mix any formatting -fixes or code moves with actual code changes. - -Make sure each individual commit is hygienic: that it builds successfully on its -own without warnings, errors, regressions, or test failures. -This means tests must be updated in the same commit that changes the behavior. - -Commit messages should be verbose by default consisting of a short subject line -(50 chars max), a blank line and detailed explanatory text as separate -paragraph(s), unless the title alone is self-explanatory (like "Correct typo -in init.cpp") in which case a single title line is sufficient. Commit messages should be -helpful to people reading your code in the future, so explain the reasoning for -your decisions. Further explanation [here](https://cbea.ms/git-commit/). - -If a particular commit references another issue, please add the reference. For -example: `refs #1234` or `fixes #4321`. Using the `fixes` or `closes` keywords -will cause the corresponding issue to be closed when the pull request is merged. - -Commit messages should never contain any `@` mentions (usernames prefixed with "@"). - -Please refer to the [Git manual](https://git-scm.com/doc) for more information -about Git. - - - Push changes to your fork - - Create pull request - -### Creating the Pull Request - -The title of the pull request should be prefixed by the component or area that -the pull request affects. Valid areas as: - - - `consensus` for changes to consensus critical code - - `doc` for changes to the documentation - - `qt` or `gui` for changes to bitcoin-qt - - `log` for changes to log messages - - `mining` for changes to the mining code - - `net` or `p2p` for changes to the peer-to-peer network code - - `refactor` for structural changes that do not change behavior - - `rpc`, `rest` or `zmq` for changes to the RPC, REST or ZMQ APIs - - `contrib` or `cli` for changes to the scripts and tools - - `test`, `qa` or `ci` for changes to the unit tests, QA tests or CI code - - `util` or `lib` for changes to the utils or libraries - - `wallet` for changes to the wallet code - - `build` for changes to CMake - - `guix` for changes to the GUIX reproducible builds - -Examples: - - consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG - net: Automatically create onion service, listen on Tor - qt: Add feed bump button - log: Fix typo in log message - -The body of the pull request should contain sufficient description of *what* the -patch does, and even more importantly, *why*, with justification and reasoning. -You should include references to any discussions (for example, other issues or -mailing list discussions). - -The description for a new pull request should not contain any `@` mentions. The -PR description will be included in the commit message when the PR is merged and -any users mentioned in the description will be annoyingly notified each time a -fork of Bitcoin Core copies the merge. Instead, make any username mentions in a -subsequent comment to the PR. - -### Translation changes - -Note that translations should not be submitted as pull requests. Please see -[Translation Process](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md) -for more information on helping with translations. - -### Work in Progress Changes and Requests for Comments - -If a pull request is not to be considered for merging (yet), please -prefix the title with [WIP] or use [Tasks Lists](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#task-lists) -in the body of the pull request to indicate tasks are pending. - -### Address Feedback - -At this stage, one should expect comments and review from other contributors. You -can add more commits to your pull request by committing them locally and pushing -to your fork. - -You are expected to reply to any review comments before your pull request is -merged. You may update the code or reject the feedback if you do not agree with -it, but you should express so in a reply. If there is outstanding feedback and -you are not actively working on it, your pull request may be closed. - -Please refer to the [peer review](#peer-review) section below for more details. - -### Squashing Commits - -If your pull request contains fixup commits (commits that change the same line of code repeatedly) or too fine-grained -commits, you may be asked to [squash](https://git-scm.com/docs/git-rebase#_interactive_mode) your commits -before it will be reviewed. The basic squashing workflow is shown below. - - git checkout your_branch_name - git rebase -i HEAD~n - # n is normally the number of commits in the pull request. - # Set commits (except the one in the first line) from 'pick' to 'squash', save and quit. - # On the next screen, edit/refine commit messages. - # Save and quit. - git push -f # (force push to GitHub) - -Please update the resulting commit message, if needed. It should read as a -coherent message. In most cases, this means not just listing the interim -commits. - -If your change contains a merge commit, the above workflow may not work and you -will need to remove the merge commit first. See the next section for details on -how to rebase. - -Please refrain from creating several pull requests for the same change. -Use the pull request that is already open (or was created earlier) to amend -changes. This preserves the discussion and review that happened earlier for -the respective change set. - -The length of time required for peer review is unpredictable and will vary from -pull request to pull request. - -### Rebasing Changes - -When a pull request conflicts with the target branch, you may be asked to rebase it on top of the current target branch. - - git fetch https://github.com/bitcoin/bitcoin # Fetch the latest upstream commit - git rebase FETCH_HEAD # Rebuild commits on top of the new base - -This project aims to have a clean git history, where code changes are only made in non-merge commits. This simplifies -auditability because merge commits can be assumed to not contain arbitrary code changes. Merge commits should be signed, -and the resulting git tree hash must be deterministic and reproducible. The script in -[/contrib/verify-commits](/contrib/verify-commits) checks that. - -After a rebase, reviewers are encouraged to sign off on the force push. This should be relatively straightforward with -the `git range-diff` tool explained in the [productivity -notes](/doc/productivity.md#diff-the-diffs-with-git-range-diff). To avoid needless review churn, maintainers will -generally merge pull requests that received the most review attention first. - -Pull Request Philosophy ------------------------ - -Patchsets should always be focused. For example, a pull request could add a -feature, fix a bug, or refactor code; but not a mixture. Please also avoid super -pull requests which attempt to do too much, are overly large, or overly complex -as this makes review difficult. - - -### Features - -When adding a new feature, thought must be given to the long term technical debt -and maintenance that feature may require after inclusion. Before proposing a new -feature that will require maintenance, please consider if you are willing to -maintain it (including bug fixing). If features get orphaned with no maintainer -in the future, they may be removed by the Repository Maintainer. - - -### Refactoring - -Refactoring is a necessary part of any software project's evolution. The -following guidelines cover refactoring pull requests for the project. - -There are three categories of refactoring: code-only moves, code style fixes, and -code refactoring. In general, refactoring pull requests should not mix these -three kinds of activities in order to make refactoring pull requests easy to -review and uncontroversial. In all cases, refactoring PRs must not change the -behaviour of code within the pull request (bugs must be preserved as is). - -Project maintainers aim for a quick turnaround on refactoring pull requests, so -where possible keep them short, uncomplex and easy to verify. - -Pull requests that refactor the code should not be made by new contributors. It -requires a certain level of experience to know where the code belongs to and to -understand the full ramification (including rebase effort of open pull requests). - -Trivial pull requests or pull requests that refactor the code with no clear -benefits may be immediately closed by the maintainers to reduce unnecessary -workload on reviewing. - - -"Decision Making" Process -------------------------- - -The following applies to code changes to the Bitcoin Core project (and related -projects such as libsecp256k1), and is not to be confused with overall Bitcoin -Network Protocol consensus changes. - -Whether a pull request is merged into Bitcoin Core rests with the project merge -maintainers. - -Maintainers will take into consideration if a patch is in line with the general -principles of the project; meets the minimum standards for inclusion; and will -judge the general consensus of contributors. - -In general, all pull requests must: - - - Have a clear use case, fix a demonstrable bug or serve the greater good of - the project (for example refactoring for modularisation); - - Be well peer-reviewed; - - Have unit tests, functional tests, and fuzz tests, where appropriate; - - Follow code style guidelines ([C++](doc/developer-notes.md), [functional tests](test/functional/README.md)); - - Not break the existing test suite; - - Where bugs are fixed, where possible, there should be unit tests - demonstrating the bug and also proving the fix. This helps prevent regression. - - Change relevant comments and documentation when behaviour of code changes. - -Patches that change Bitcoin consensus rules are considerably more involved than -normal because they affect the entire ecosystem and so must be preceded by -extensive mailing list discussions and have a numbered BIP. While each case will -be different, one should be prepared to expend more time and effort than for -other kinds of patches because of increased peer review and consensus building -requirements. - - -### Peer Review - -Anyone may participate in peer review which is expressed by comments in the pull -request. Typically reviewers will review the code for obvious errors, as well as -test out the patch set and opine on the technical merits of the patch. Project -maintainers take into account the peer review when determining if there is -consensus to merge a pull request (remember that discussions may have been -spread out over GitHub, mailing list and IRC discussions). - -Code review is a burdensome but important part of the development process, and -as such, certain types of pull requests are rejected. In general, if the -**improvements** do not warrant the **review effort** required, the PR has a -high chance of being rejected. It is up to the PR author to convince the -reviewers that the changes warrant the review effort, and if reviewers are -"Concept NACK'ing" the PR, the author may need to present arguments and/or do -research backing their suggested changes. - -#### Conceptual Review - -A review can be a conceptual review, where the reviewer leaves a comment - * `Concept (N)ACK`, meaning "I do (not) agree with the general goal of this pull - request", - * `Approach (N)ACK`, meaning `Concept ACK`, but "I do (not) agree with the - approach of this change". - -A `NACK` needs to include a rationale why the change is not worthwhile. -NACKs without accompanying reasoning may be disregarded. - -#### Code Review - -After conceptual agreement on the change, code review can be provided. A review -begins with `ACK BRANCH_COMMIT`, where `BRANCH_COMMIT` is the top of the PR -branch, followed by a description of how the reviewer did the review. The -following language is used within pull request comments: - - - "I have tested the code", involving change-specific manual testing in - addition to running the unit, functional, or fuzz tests, and in case it is - not obvious how the manual testing was done, it should be described; - - "I have not tested the code, but I have reviewed it and it looks - OK, I agree it can be merged"; - - A "nit" refers to a trivial, often non-blocking issue. - -Project maintainers reserve the right to weigh the opinions of peer reviewers -using common sense judgement and may also weigh based on merit. Reviewers that -have demonstrated a deeper commitment and understanding of the project over time -or who have clear domain expertise may naturally have more weight, as one would -expect in all walks of life. - -Where a patch set affects consensus-critical code, the bar will be much -higher in terms of discussion and peer review requirements, keeping in mind that -mistakes could be very costly to the wider community. This includes refactoring -of consensus-critical code. - -Where a patch set proposes to change the Bitcoin consensus, it must have been -discussed extensively on the mailing list and IRC, be accompanied by a widely -discussed BIP and have a generally widely perceived technical consensus of being -a worthwhile change based on the judgement of the maintainers. - -### Finding Reviewers - -As most reviewers are themselves developers with their own projects, the review -process can be quite lengthy, and some amount of patience is required. If you find -that you've been waiting for a pull request to be given attention for several -months, there may be a number of reasons for this, some of which you can do something -about: - - - It may be because of a feature freeze due to an upcoming release. During this time, - only bug fixes are taken into consideration. If your pull request is a new feature, - it will not be prioritized until after the release. Wait for the release. - - It may be because the changes you are suggesting do not appeal to people. Rather than - nits and critique, which require effort and means they care enough to spend time on your - contribution, thundering silence is a good sign of widespread (mild) dislike of a given change - (because people don't assume *others* won't actually like the proposal). Don't take - that personally, though! Instead, take another critical look at what you are suggesting - and see if it: changes too much, is too broad, doesn't adhere to the - [developer notes](doc/developer-notes.md), is dangerous or insecure, is messily written, etc. - Identify and address any of the issues you find. Then ask e.g. on IRC if someone could give - their opinion on the concept itself. - - It may be because your code is too complex for all but a few people, and those people - may not have realized your pull request even exists. A great way to find people who - are qualified and care about the code you are touching is the - [Git Blame feature](https://docs.github.com/en/repositories/working-with-files/using-files/viewing-and-understanding-files). Simply - look up who last modified the code you are changing and see if you can find - them and give them a nudge. Don't be incessant about the nudging, though. - - Finally, if all else fails, ask on IRC or elsewhere for someone to give your pull request - a look. If you think you've been waiting for an unreasonably long time (say, - more than a month) for no particular reason (a few lines changed, etc.), - this is totally fine. Try to return the favor when someone else is asking - for feedback on their code, and the universe balances out. - - Remember that the best thing you can do while waiting is give review to others! - - -Backporting ------------ - -Security and bug fixes can be backported from `master` to release -branches. -Maintainers will do backports in batches and -use the proper `Needs backport (...)` labels -when needed (the original author does not need to worry about it). - -A backport should contain the following metadata in the commit body: - -``` -Github-Pull: # -Rebased-From: -``` - -Have a look at [an example backport PR]( -https://github.com/bitcoin/bitcoin/pull/16189). - -Also see the [backport.py script]( -https://github.com/bitcoin-core/bitcoin-maintainer-tools#backport). - -Copyright ---------- - -By contributing to this repository, you agree to license your work under the -MIT license unless specified otherwise in `contrib/debian/copyright` or at -the top of the file itself. Any work contributed where you are not the original -author must contain its license header with the original author(s) and source. diff --git a/README.md b/README.md index cfabb7f6723b..1956ad4a864a 100644 --- a/README.md +++ b/README.md @@ -1,79 +1,64 @@ -Bitcoin Core integration/staging tree +Stratum v2 Template Provider (c++) ===================================== -https://bitcoincore.org +For an immediately usable, binary version of this software, see +releases. -For an immediately usable, binary version of the Bitcoin Core software, see -https://bitcoincore.org/en/download/. +Windows support is coming soon(tm). See https://github.com/bitcoin/bitcoin/pull/32387 -What is Bitcoin Core? ---------------------- +Compile +------------------------ -Bitcoin Core connects to the Bitcoin peer-to-peer network to download and fully -validate blocks and transactions. It also includes a wallet and graphical user -interface, which can be optionally built. +```sh +cmake -B build +cmake --build build +ctest --test-dir build +``` -Further information about Bitcoin Core is available in the [doc folder](/doc). +See `doc/build*` for detailed instructions per platform, including +dependencies. -License -------- +Usage +------------------------ +Download or compile Bitcoin Core v30.0 or later. Start it with: -Bitcoin Core is released under the terms of the MIT license. See [COPYING](COPYING) for more -information or see https://opensource.org/license/MIT. + ```sh + bitcoin -m node -ipcbind=unix + ``` -Development Process -------------------- +Then start the Template Provider, thorough logging is recommended: -The `master` branch is regularly built (see `doc/build-*.md` for instructions) and tested, but it is not guaranteed to be -completely stable. [Tags](https://github.com/bitcoin/bitcoin/tags) are created -regularly from release branches to indicate new official, stable release versions of Bitcoin Core. +```sh +build/bin/sv2-tp -debug=sv2 -loglevel=sv2:trace +``` -The https://github.com/bitcoin-core/gui repository is used exclusively for the -development of the GUI. Its master branch is identical in all monotree -repositories. Release branches and tags do not exist, so please do not fork -that repository unless it is for development reasons. +(for the installed version you don't need `build/bin/`) -The contribution workflow is described in [CONTRIBUTING.md](CONTRIBUTING.md) -and useful hints for developers can be found in [doc/developer-notes.md](doc/developer-notes.md). -Testing -------- +Relation to Bitcoin Core +------------------------ -Testing and code review is the bottleneck for development; we get more pull -requests than we can review and test on short notice. Please be patient and help out by testing -other people's pull requests, and remember this is a security-critical project where any mistake might cost people -lots of money. +The code for this project is originally based on Bitcoin Core, for historical +reasons described [here](https://github.com/bitcoin/bitcoin/pull/31802). The +code is expected to diverge over time, with unused code being removed. -### Automated Testing +There is no test coverage for code that is identical to the upstream project +and bugs there should be fixed upstream, with a pull request here if they're +important. -Developers are strongly encouraged to write [unit tests](src/test/README.md) for new code, and to -submit new unit tests for old code. Unit tests can be compiled and run -(assuming they weren't disabled during the generation of the build system) with: `ctest`. Further details on running -and extending unit tests can be found in [/src/test/README.md](/src/test/README.md). +There's still many places where text will simply refer to "Bitcoin Core". Only +replace this text if the rest of the file differs from upstream. -There are also [regression and integration tests](/test), written -in Python. -These tests can be run (if the [test dependencies](/test) are installed) with: `build/test/functional/test_runner.py` -(assuming `build` is your build directory). +Where's the main code? +---------------------- -The CI (Continuous Integration) systems make sure that every pull request is tested on Windows, Linux, and macOS. -The CI must pass on all commits before merge to avoid unrelated CI failures on new pull requests. +- `src/sv2`: Stratum v2 noise protocol, transport, network and template provider +- `test/sv2*`: test coverage -### Manual Quality Assurance (QA) Testing +The rest is original Bitcoin Core code, albeit stripped down. E.g. the functional +testwork has been removed, as has the wallet, GUI, RPC, ZMQ and most p2p code. -Changes should be tested by somebody other than the developer who wrote the -code. This is especially important for large or high-risk changes. It is useful -to add a test plan to the pull request description if testing the changes is -not straightforward. - -Translations ------------- - -Changes to translations as well as new translations can be submitted to -[Bitcoin Core's Transifex page](https://explore.transifex.com/bitcoin/bitcoin/). - -Translations are periodically pulled from Transifex and merged into the git repository. See the -[translation process](doc/translation_process.md) for details on how this works. - -**Important**: We do not accept translation changes as GitHub pull requests because the next -pull from Transifex would automatically overwrite them again. +Pull requests to strip out additional unused code are welcome. The main barrier +to that is that `sv2_template_provider_tests` requires real node functionality. +This should be replaced with a mock, after which the `libbitcoin_node` target +can be dropped and many other things. diff --git a/SECURITY.md b/SECURITY.md index fd4c61d176dc..25cafe55b698 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,20 +1,11 @@ # Security Policy -## Supported Versions +The code for this project is originally from Bitcoin Core. The application also requires connecting to a running Bitcoin Core node. Issues related to the original code, such as bugs in IPC, as best reported upstream: https://github.com/bitcoin/bitcoin/blob/master/SECURITY.md -See our website for versions of Bitcoin Core that are currently supported with -security updates: https://bitcoincore.org/en/lifecycle/#schedule +The Template Provider is still considered experimental and should not be exposed to the internet. Most security issues can therefore safely be reported by simply opening an Github issue on this repository. -## Reporting a Vulnerability - -To report security issues send an email to security@bitcoincore.org (not for support). - -The following keys may be used to communicate sensitive information to developers: +When in doubt you can also send an email to (address in the commit messages): | Name | Fingerprint | |------|-------------| -| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 | -| Michael Ford | E777 299F C265 DD04 7930 70EB 944D 35F9 AC3D B76A | -| Ava Chow | 1528 1230 0785 C964 44D3 334D 1756 5732 E08E 5E41 | - -You can import a key by running the following command with that individual’s fingerprint: `gpg --keyserver hkps://keys.openpgp.org --recv-keys ""` Ensure that you put quotes around fingerprints containing spaces. +| Sjors Provoost | ED9B DF7A D6A5 5E23 2E84  5242 57FF 9BDB CC30 1009 | diff --git a/ci/lint/01_install.sh b/ci/lint/01_install.sh index 75f891105c05..ec47c63f9a53 100755 --- a/ci/lint/01_install.sh +++ b/ci/lint/01_install.sh @@ -29,7 +29,7 @@ if [ ! -d "${PYTHON_PATH}/bin" ]; then ) # For dependencies see https://github.com/pyenv/pyenv/wiki#suggested-build-environment ${CI_RETRY_EXE} apt-get install -y build-essential libssl-dev zlib1g-dev \ - libbz2-dev libreadline-dev libsqlite3-dev curl llvm \ + libbz2-dev libreadline-dev curl llvm \ libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev \ clang env CC=clang python-build "$(cat "/.python-version")" "${PYTHON_PATH}" @@ -42,7 +42,6 @@ ${CI_RETRY_EXE} pip3 install \ codespell==2.4.1 \ lief==0.16.6 \ mypy==1.4.1 \ - pyzmq==25.1.0 \ ruff==0.5.5 \ vulture==2.6 diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh index cf8fbb006f5f..4f8930efd625 100755 --- a/ci/test/00_setup_env.sh +++ b/ci/test/00_setup_env.sh @@ -40,7 +40,6 @@ export MAKEJOBS=${MAKEJOBS:--j4} export USE_BUSY_BOX=${USE_BUSY_BOX:-false} export RUN_UNIT_TESTS=${RUN_UNIT_TESTS:-true} -export RUN_FUNCTIONAL_TESTS=${RUN_FUNCTIONAL_TESTS:-true} export RUN_TIDY=${RUN_TIDY:-false} # By how much to scale the test_runner timeouts (option --timeout-factor). # This is needed because some ci machines have slow CPU or disk, so sanitizers diff --git a/ci/test/00_setup_env_arm.sh b/ci/test/00_setup_env_arm.sh index ce019784f908..f52c860a6853 100755 --- a/ci/test/00_setup_env_arm.sh +++ b/ci/test/00_setup_env_arm.sh @@ -8,13 +8,12 @@ export LC_ALL=C.UTF-8 export HOST=arm-linux-gnueabihf export DPKG_ADD_ARCH="armhf" -export PACKAGES="python3-zmq g++-arm-linux-gnueabihf busybox libc6:armhf libstdc++6:armhf libfontconfig1:armhf libxcb1:armhf" +export PACKAGES="g++-arm-linux-gnueabihf busybox libc6:armhf libstdc++6:armhf libfontconfig1:armhf libxcb1:armhf" export CONTAINER_NAME=ci_arm_linux export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" # Check that https://packages.ubuntu.com/noble/g++-arm-linux-gnueabihf (version 13.x, similar to guix) can cross-compile export CI_IMAGE_PLATFORM="linux/arm64" export USE_BUSY_BOX=true export RUN_UNIT_TESTS=true -export RUN_FUNCTIONAL_TESTS=false export GOAL="install" export CI_LIMIT_STACK_SIZE=1 # -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1" diff --git a/ci/test/00_setup_env_i686_no_ipc.sh b/ci/test/00_setup_env_i686.sh similarity index 95% rename from ci/test/00_setup_env_i686_no_ipc.sh rename to ci/test/00_setup_env_i686.sh index 5ab414372251..66402c4a164c 100755 --- a/ci/test/00_setup_env_i686_no_ipc.sh +++ b/ci/test/00_setup_env_i686.sh @@ -11,7 +11,7 @@ export CONTAINER_NAME=ci_i686_no_multiprocess export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export CI_IMAGE_PLATFORM="linux/amd64" export PACKAGES="llvm clang g++-multilib" -export DEP_OPTS="DEBUG=1 NO_IPC=1" +export DEP_OPTS="DEBUG=1" export GOAL="install" export TEST_RUNNER_EXTRA="--v2transport --usecli" export BITCOIN_CONFIG="\ diff --git a/ci/test/00_setup_env_mac_cross.sh b/ci/test/00_setup_env_mac_cross.sh index b5e0fbcc5565..653936a6034e 100755 --- a/ci/test/00_setup_env_mac_cross.sh +++ b/ci/test/00_setup_env_mac_cross.sh @@ -15,6 +15,5 @@ export PACKAGES="clang lld llvm zip" export XCODE_VERSION=15.0 export XCODE_BUILD_ID=15A240d export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false -export GOAL="deploy" +export GOAL="install" export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON" diff --git a/ci/test/00_setup_env_mac_native.sh b/ci/test/00_setup_env_mac_native.sh index b7e24c7a338c..d7b5d4121060 100755 --- a/ci/test/00_setup_env_mac_native.sh +++ b/ci/test/00_setup_env_mac_native.sh @@ -8,7 +8,6 @@ export LC_ALL=C.UTF-8 # Homebrew's python@3.12 is marked as externally managed (PEP 668). # Therefore, `--break-system-packages` is needed. -export PIP_PACKAGES="--break-system-packages zmq" export GOAL="install" export CMAKE_GENERATOR="Ninja" export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON -DCMAKE_EXE_LINKER_FLAGS='-Wl,-stack_size -Wl,0x80000'" diff --git a/ci/test/00_setup_env_mac_native_fuzz.sh b/ci/test/00_setup_env_mac_native_fuzz.sh index d8a61fbac73a..c2e859dad9e3 100755 --- a/ci/test/00_setup_env_mac_native_fuzz.sh +++ b/ci/test/00_setup_env_mac_native_fuzz.sh @@ -12,6 +12,5 @@ export CI_OS_NAME="macos" export NO_DEPENDS=1 export OSX_SDK="" export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false export RUN_FUZZ_TESTS=true export GOAL="all" diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh index aa005bd87845..105110fd3474 100755 --- a/ci/test/00_setup_env_native_asan.sh +++ b/ci/test/00_setup_env_native_asan.sh @@ -20,7 +20,7 @@ fi export CONTAINER_NAME=ci_native_asan export APT_LLVM_V="20" -export PACKAGES="systemtap-sdt-dev clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev python3-zmq qt6-base-dev qt6-tools-dev qt6-l10n-tools libevent-dev libboost-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE} libcapnp-dev capnproto" +export PACKAGES="systemtap-sdt-dev clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libboost-dev ${BPFCC_PACKAGE} libcapnp-dev capnproto" export NO_DEPENDS=1 export GOAL="install" export CI_LIMIT_STACK_SIZE=1 diff --git a/ci/test/00_setup_env_native_centos.sh b/ci/test/00_setup_env_native_centos.sh index 98e731e6e238..2cdf0734b4ce 100755 --- a/ci/test/00_setup_env_native_centos.sh +++ b/ci/test/00_setup_env_native_centos.sh @@ -9,13 +9,9 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_centos export CI_IMAGE_NAME_TAG="quay.io/centos/centos:stream10" export CI_BASE_PACKAGES="gcc-c++ glibc-devel libstdc++-devel ccache make ninja-build git python3 python3-pip which patch xz procps-ng ksh rsync coreutils bison e2fsprogs cmake" -export PIP_PACKAGES="pyzmq" export DEP_OPTS="DEBUG=1" export GOAL="install" export BITCOIN_CONFIG="\ - -DWITH_ZMQ=ON \ - -DBUILD_GUI=ON \ -DREDUCE_EXPORTS=ON \ -DCMAKE_BUILD_TYPE=Debug \ " -export BITCOIN_CMD="bitcoin -m" # Used in functional tests diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh index fc0c6b785add..2c57de9c68c1 100755 --- a/ci/test/00_setup_env_native_fuzz.sh +++ b/ci/test/00_setup_env_native_fuzz.sh @@ -9,10 +9,9 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_fuzz export APT_LLVM_V="20" -export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libevent-dev libboost-dev libsqlite3-dev libcapnp-dev capnproto" +export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libboost-dev libcapnp-dev capnproto" export NO_DEPENDS=1 export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false export RUN_FUZZ_TESTS=true export GOAL="all" export CI_CONTAINER_CAP="--cap-add SYS_PTRACE" # If run with (ASan + LSan), the container needs access to ptrace (https://github.com/google/sanitizers/issues/764) diff --git a/ci/test/00_setup_env_native_fuzz_with_msan.sh b/ci/test/00_setup_env_native_fuzz_with_msan.sh index c71772b8e2cb..b4a85d3b93c2 100755 --- a/ci/test/00_setup_env_native_fuzz_with_msan.sh +++ b/ci/test/00_setup_env_native_fuzz_with_msan.sh @@ -13,7 +13,7 @@ LIBCXX_FLAGS="-nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${L export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" export CONTAINER_NAME="ci_native_fuzz_msan" -export DEP_OPTS="DEBUG=1 NO_QT=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" +export DEP_OPTS="DEBUG=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" export GOAL="all" # Setting CMAKE_{C,CXX}_FLAGS_DEBUG flags to an empty string ensures that the flags set in MSAN_FLAGS remain unaltered. # _FORTIFY_SOURCE is not compatible with MSAN. @@ -27,5 +27,4 @@ export BITCOIN_CONFIG="\ " export USE_INSTRUMENTED_LIBCPP="MemoryWithOrigins" export RUN_UNIT_TESTS="false" -export RUN_FUNCTIONAL_TESTS="false" export RUN_FUZZ_TESTS=true diff --git a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh index f1d99f818194..845897d8df6f 100755 --- a/ci/test/00_setup_env_native_fuzz_with_valgrind.sh +++ b/ci/test/00_setup_env_native_fuzz_with_valgrind.sh @@ -8,10 +8,9 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_fuzz_valgrind -export PACKAGES="libevent-dev libboost-dev libsqlite3-dev valgrind libcapnp-dev capnproto" +export PACKAGES="libboost-dev valgrind libcapnp-dev capnproto" export NO_DEPENDS=1 export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false export RUN_FUZZ_TESTS=true export FUZZ_TESTS_CONFIG="--valgrind" export GOAL="all" diff --git a/ci/test/00_setup_env_native_msan.sh b/ci/test/00_setup_env_native_msan.sh index 4d5e0f4f5bd9..c9c903e7e66b 100755 --- a/ci/test/00_setup_env_native_msan.sh +++ b/ci/test/00_setup_env_native_msan.sh @@ -15,13 +15,12 @@ export MSAN_AND_LIBCXX_FLAGS="${MSAN_FLAGS} ${LIBCXX_FLAGS}" export CONTAINER_NAME="ci_native_msan" export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} llvm-${APT_LLVM_V}-dev libclang-${APT_LLVM_V}-dev libclang-rt-${APT_LLVM_V}-dev" -export DEP_OPTS="DEBUG=1 NO_QT=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" +export DEP_OPTS="DEBUG=1 CC=clang CXX=clang++ CFLAGS='${MSAN_FLAGS}' CXXFLAGS='${MSAN_AND_LIBCXX_FLAGS}'" export GOAL="install" export CI_LIMIT_STACK_SIZE=1 # Setting CMAKE_{C,CXX}_FLAGS_DEBUG flags to an empty string ensures that the flags set in MSAN_FLAGS remain unaltered. # _FORTIFY_SOURCE is not compatible with MSAN. export BITCOIN_CONFIG="\ - -DENABLE_WALLET=OFF \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_C_FLAGS_DEBUG='' \ -DCMAKE_CXX_FLAGS_DEBUG='' \ diff --git a/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh b/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh deleted file mode 100755 index 74bc891aafcd..000000000000 --- a/ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2019-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -export LC_ALL=C.UTF-8 - -export CONTAINER_NAME=ci_native_nowallet_libbitcoinkernel -export CI_IMAGE_NAME_TAG="mirror.gcr.io/debian:bookworm" -# Use minimum supported python3.10 (or best-effort 3.11) and clang-16, see doc/dependencies.md -export PACKAGES="python3-zmq clang-16 llvm-16 libc++abi-16-dev libc++-16-dev" -export DEP_OPTS="NO_WALLET=1 CC=clang-16 CXX='clang++-16 -stdlib=libc++'" -export GOAL="install" -export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON -DBUILD_UTIL_CHAINSTATE=ON -DBUILD_KERNEL_LIB=ON -DBUILD_SHARED_LIBS=ON" diff --git a/ci/test/00_setup_env_native_previous_releases.sh b/ci/test/00_setup_env_native_previous_releases.sh index a95ae6ff6fbd..d9e97f88fcb8 100755 --- a/ci/test/00_setup_env_native_previous_releases.sh +++ b/ci/test/00_setup_env_native_previous_releases.sh @@ -9,7 +9,7 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_previous_releases export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:22.04" # Use minimum supported python3.10 and gcc-11, see doc/dependencies.md -export PACKAGES="gcc-11 g++-11 python3-zmq" +export PACKAGES="gcc-11 g++-11" export DEP_OPTS="CC=gcc-11 CXX=g++-11" export TEST_RUNNER_EXTRA="--previous-releases --coverage --extended --exclude feature_dbcrash" # Run extended tests so that coverage does not fail, but exclude the very slow dbcrash export RUN_UNIT_TESTS_SEQUENTIAL="true" @@ -18,7 +18,7 @@ export GOAL="install" export CI_LIMIT_STACK_SIZE=1 export DOWNLOAD_PREVIOUS_RELEASES="true" export BITCOIN_CONFIG="\ - -DWITH_ZMQ=OFF -DBUILD_GUI=OFF -DREDUCE_EXPORTS=ON \ + -DREDUCE_EXPORTS=ON \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_C_FLAGS='-funsigned-char' \ -DCMAKE_C_FLAGS_DEBUG='-g2 -O2' \ diff --git a/ci/test/00_setup_env_native_tidy.sh b/ci/test/00_setup_env_native_tidy.sh index c9b3f29bbd60..93ec18e91890 100755 --- a/ci/test/00_setup_env_native_tidy.sh +++ b/ci/test/00_setup_env_native_tidy.sh @@ -10,17 +10,15 @@ export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_tidy export TIDY_LLVM_V="20" export APT_LLVM_V="${TIDY_LLVM_V}" -export PACKAGES="clang-${TIDY_LLVM_V} libclang-${TIDY_LLVM_V}-dev llvm-${TIDY_LLVM_V}-dev libomp-${TIDY_LLVM_V}-dev clang-tidy-${TIDY_LLVM_V} jq libevent-dev libboost-dev libzmq3-dev systemtap-sdt-dev qt6-base-dev qt6-tools-dev qt6-l10n-tools libqrencode-dev libsqlite3-dev libcapnp-dev capnproto" +export PACKAGES="clang-${TIDY_LLVM_V} libclang-${TIDY_LLVM_V}-dev llvm-${TIDY_LLVM_V}-dev libomp-${TIDY_LLVM_V}-dev clang-tidy-${TIDY_LLVM_V} jq libboost-dev systemtap-sdt-dev libcapnp-dev capnproto" export NO_DEPENDS=1 export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false export RUN_FUZZ_TESTS=false export RUN_CHECK_DEPS=true export RUN_TIDY=true export GOAL="install" # Wallet support is kept, because check-deps assumes it export BITCOIN_CONFIG="\ - -DBUILD_BENCH=ON \ -DWITH_USDT=ON \ -DCMAKE_C_COMPILER=clang-${TIDY_LLVM_V} \ -DCMAKE_CXX_COMPILER=clang++-${TIDY_LLVM_V} \ diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index 49caf779c0e7..1e2daa50280d 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -11,8 +11,8 @@ export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export APT_LLVM_V="20" LIBCXX_DIR="/cxx_build/" LIBCXX_FLAGS="-fsanitize=thread -nostdinc++ -nostdlib++ -isystem ${LIBCXX_DIR}include/c++/v1 -L${LIBCXX_DIR}lib -Wl,-rpath,${LIBCXX_DIR}lib -lc++ -lc++abi -lpthread -Wno-unused-command-line-argument" -export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} llvm-${APT_LLVM_V}-dev libclang-${APT_LLVM_V}-dev libclang-rt-${APT_LLVM_V}-dev python3-zmq" -export DEP_OPTS="CC=clang CXX=clang++ CXXFLAGS='${LIBCXX_FLAGS}' NO_QT=1" +export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} llvm-${APT_LLVM_V}-dev libclang-${APT_LLVM_V}-dev libclang-rt-${APT_LLVM_V}-dev" +export DEP_OPTS="CC=clang CXX=clang++ CXXFLAGS='${LIBCXX_FLAGS}'" export GOAL="install" export CI_LIMIT_STACK_SIZE=1 export BITCOIN_CONFIG="-DSANITIZERS=thread \ diff --git a/ci/test/00_setup_env_native_valgrind.sh b/ci/test/00_setup_env_native_valgrind.sh index 3cec5e56ea45..8a61b5258117 100755 --- a/ci/test/00_setup_env_native_valgrind.sh +++ b/ci/test/00_setup_env_native_valgrind.sh @@ -8,12 +8,9 @@ export LC_ALL=C.UTF-8 export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export CONTAINER_NAME=ci_native_valgrind -export PACKAGES="valgrind python3-zmq libevent-dev libboost-dev libzmq3-dev libsqlite3-dev libcapnp-dev capnproto" +export PACKAGES="valgrind libboost-dev libcapnp-dev capnproto" export USE_VALGRIND=1 export NO_DEPENDS=1 # bind tests excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 -export TEST_RUNNER_EXTRA="--exclude rpc_bind,feature_bind_extra" +export TEST_RUNNER_EXTRA="--exclude feature_bind_extra" export GOAL="install" -export BITCOIN_CONFIG="\ - -DBUILD_GUI=OFF \ -" diff --git a/ci/test/00_setup_env_s390x.sh b/ci/test/00_setup_env_s390x.sh index b84d99076ea9..4b94edebdd67 100755 --- a/ci/test/00_setup_env_s390x.sh +++ b/ci/test/00_setup_env_s390x.sh @@ -7,11 +7,9 @@ export LC_ALL=C.UTF-8 export HOST=s390x-linux-gnu -export PACKAGES="python3-zmq" export CONTAINER_NAME=ci_s390x export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04" export CI_IMAGE_PLATFORM="linux/s390x" -export TEST_RUNNER_EXTRA="--exclude rpc_bind,feature_bind_extra" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 -export RUN_FUNCTIONAL_TESTS=true +export TEST_RUNNER_EXTRA="--exclude feature_bind_extra" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547 export GOAL="install" export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON" diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh index 13e794bd6d1d..80044e993053 100755 --- a/ci/test/00_setup_env_win64.sh +++ b/ci/test/00_setup_env_win64.sh @@ -12,7 +12,6 @@ export CI_IMAGE_PLATFORM="linux/amd64" export HOST=x86_64-w64-mingw32 export PACKAGES="g++-mingw-w64-x86-64-posix nsis" export RUN_UNIT_TESTS=false -export RUN_FUNCTIONAL_TESTS=false export GOAL="deploy" -export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON -DBUILD_GUI_TESTS=OFF \ +export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON \ -DCMAKE_CXX_FLAGS='-Wno-error=maybe-uninitialized'" diff --git a/ci/test/03_test_script.sh b/ci/test/03_test_script.sh index 83b67da2aad1..c6631d0c8e05 100755 --- a/ci/test/03_test_script.sh +++ b/ci/test/03_test_script.sh @@ -98,11 +98,8 @@ if [ -z "$NO_DEPENDS" ]; then fi bash -c "$SHELL_OPTS make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS LOG=1" fi -if [ "$DOWNLOAD_PREVIOUS_RELEASES" = "true" ]; then - test/get_previous_releases.py --target-dir "$PREVIOUS_RELEASES_DIR" -fi -BITCOIN_CONFIG_ALL="-DBUILD_BENCH=ON -DBUILD_FUZZ_BINARY=ON" +BITCOIN_CONFIG_ALL="-DBUILD_FUZZ_BINARY=ON" if [ -z "$NO_DEPENDS" ]; then BITCOIN_CONFIG_ALL="${BITCOIN_CONFIG_ALL} -DCMAKE_TOOLCHAIN_FILE=$DEPENDS_DIR/$HOST/toolchain.cmake" fi @@ -163,22 +160,7 @@ if [ "$RUN_UNIT_TESTS" = "true" ]; then fi if [ "$RUN_UNIT_TESTS_SEQUENTIAL" = "true" ]; then - DIR_UNIT_TEST_DATA="${DIR_UNIT_TEST_DATA}" LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" "${BASE_BUILD_DIR}"/bin/test_bitcoin --catch_system_errors=no -l test_suite -fi - -if [ "$RUN_FUNCTIONAL_TESTS" = "true" ]; then - # parses TEST_RUNNER_EXTRA as an array which allows for multiple arguments such as TEST_RUNNER_EXTRA='--exclude "rpc_bind.py --ipv6"' - eval "TEST_RUNNER_EXTRA=($TEST_RUNNER_EXTRA)" - LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" \ - "${BASE_BUILD_DIR}/test/functional/test_runner.py" \ - --ci "${MAKEJOBS}" \ - --tmpdirprefix "${BASE_SCRATCH_DIR}/test_runner/" \ - --ansi \ - --combinedlogslen=99999999 \ - --timeout-factor="${TEST_RUNNER_TIMEOUT_FACTOR}" \ - "${TEST_RUNNER_EXTRA[@]}" \ - --quiet \ - --failfast + DIR_UNIT_TEST_DATA="${DIR_UNIT_TEST_DATA}" LD_LIBRARY_PATH="${DEPENDS_DIR}/${HOST}/lib" "${BASE_BUILD_DIR}"/bin/test_sv2 --catch_system_errors=no -l test_suite fi if [ "${RUN_TIDY}" = "true" ]; then @@ -187,9 +169,7 @@ if [ "${RUN_TIDY}" = "true" ]; then cmake --build /tidy-build --target bitcoin-tidy-tests "$MAKEJOBS" set -eo pipefail - # Filter out: - # * qt qrc and moc generated files - jq 'map(select(.file | test("src/qt/.*_autogen/.*\\.cpp$") | not))' "${BASE_BUILD_DIR}/compile_commands.json" > tmp.json + jq 'map(select(.file))' "${BASE_BUILD_DIR}/compile_commands.json" > tmp.json mv tmp.json "${BASE_BUILD_DIR}/compile_commands.json" cd "${BASE_BUILD_DIR}/src/" diff --git a/cmake/bitcoin-build-config.h.in b/cmake/bitcoin-build-config.h.in index bf3ddcd7ff62..0a64df9c1e15 100644 --- a/cmake/bitcoin-build-config.h.in +++ b/cmake/bitcoin-build-config.h.in @@ -29,16 +29,10 @@ /* Copyright year */ #define COPYRIGHT_YEAR @COPYRIGHT_YEAR@ -/* Define if external signer support is enabled */ -#cmakedefine ENABLE_EXTERNAL_SIGNER 1 - /* Define to 1 to enable tracepoints for Userspace, Statically Defined Tracing */ #cmakedefine ENABLE_TRACING 1 -/* Define to 1 to enable wallet functions. */ -#cmakedefine ENABLE_WALLET 1 - /* Define to 1 if you have the declaration of `fork', and to 0 if you don't. */ #cmakedefine01 HAVE_DECL_FORK diff --git a/cmake/libmultiprocess.cmake b/cmake/libmultiprocess.cmake index 5db8f4e9e54e..e25c9fe5d702 100644 --- a/cmake/libmultiprocess.cmake +++ b/cmake/libmultiprocess.cmake @@ -3,10 +3,10 @@ # file COPYING or https://opensource.org/license/mit/. function(add_libmultiprocess subdir) - # Set BUILD_TESTING to match BUILD_TESTS. BUILD_TESTING is a standard cmake + # BUILD_TESTING is a standard cmake # option that controls whether enable_testing() is called, but in the bitcoin # build a BUILD_TESTS option is used instead. - set(BUILD_TESTING "${BUILD_TESTS}") + set(BUILD_TESTING OFF) add_subdirectory(${subdir} EXCLUDE_FROM_ALL) # Apply core_interface compile options to libmultiprocess runtime library. target_link_libraries(multiprocess PUBLIC $) @@ -25,10 +25,6 @@ function(add_libmultiprocess subdir) mark_as_advanced(CapnProto_kj_IMPORTED_LOCATION) mark_as_advanced(CapnProto_kj-test_IMPORTED_LOCATION) mark_as_advanced(CapnProto_kj-tls_IMPORTED_LOCATION) - if(BUILD_TESTS) - # Add tests to "all" target so ctest can run them - set_target_properties(mptests PROPERTIES EXCLUDE_FROM_ALL OFF) - endif() # Exclude examples from compilation database, because the examples are not # built by default, and they contain generated c++ code. Without this # exclusion, tools like clang-tidy and IWYU that make use of compilation diff --git a/cmake/minisketch.cmake b/cmake/minisketch.cmake deleted file mode 100644 index 5f57d25e6c03..000000000000 --- a/cmake/minisketch.cmake +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 2023-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -include(CheckSourceCompilesWithFlags) - -# Check for clmul instructions support. -if(MSVC) - set(CLMUL_CXXFLAGS "") -else() - set(CLMUL_CXXFLAGS -mpclmul) -endif() -check_cxx_source_compiles_with_flags(" - #include - #include - - int main() - { - __m128i a = _mm_cvtsi64_si128((uint64_t)7); - __m128i b = _mm_clmulepi64_si128(a, a, 37); - __m128i c = _mm_srli_epi64(b, 41); - __m128i d = _mm_xor_si128(b, c); - uint64_t e = _mm_cvtsi128_si64(d); - return e == 0; - } - " HAVE_CLMUL - CXXFLAGS ${CLMUL_CXXFLAGS} -) - -add_library(minisketch_common INTERFACE) -if(MSVC) - target_compile_options(minisketch_common INTERFACE - /wd4060 - /wd4065 - /wd4146 - /wd4244 - /wd4267 - ) -endif() - -add_library(minisketch STATIC EXCLUDE_FROM_ALL - ${PROJECT_SOURCE_DIR}/src/minisketch/src/minisketch.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_1byte.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_2bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_3bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_4bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_5bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_6bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_7bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/generic_8bytes.cpp -) - -target_compile_definitions(minisketch - PRIVATE - DISABLE_DEFAULT_FIELDS - ENABLE_FIELD_32 -) - -target_include_directories(minisketch - PUBLIC - $ -) - -target_link_libraries(minisketch - PRIVATE - core_interface - minisketch_common -) - -set_target_properties(minisketch PROPERTIES - EXPORT_COMPILE_COMMANDS OFF -) - -if(HAVE_CLMUL) - set(_minisketch_clmul_src - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_1byte.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_2bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_3bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_4bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_5bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_6bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_7bytes.cpp - ${PROJECT_SOURCE_DIR}/src/minisketch/src/fields/clmul_8bytes.cpp - ) - target_sources(minisketch PRIVATE ${_minisketch_clmul_src}) - set_property(SOURCE ${_minisketch_clmul_src} PROPERTY COMPILE_OPTIONS ${CLMUL_CXXFLAGS}) - target_compile_definitions(minisketch PRIVATE HAVE_CLMUL) - unset(_minisketch_clmul_src) -endif() diff --git a/cmake/module/FindLibevent.cmake b/cmake/module/FindLibevent.cmake deleted file mode 100644 index c006b43d6040..000000000000 --- a/cmake/module/FindLibevent.cmake +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright (c) 2024-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -#[=======================================================================[ -FindLibevent ------------- - -Finds the Libevent headers and libraries. - -This is a wrapper around find_package()/pkg_check_modules() commands that: - - facilitates searching in various build environments - - prints a standard log message - -#]=======================================================================] - -# Check whether evhttp_connection_get_peer expects const char**. -# See https://github.com/libevent/libevent/commit/a18301a2bb160ff7c3ffaf5b7653c39ffe27b385 -function(check_evhttp_connection_get_peer target) - include(CMakePushCheckState) - cmake_push_check_state(RESET) - set(CMAKE_REQUIRED_LIBRARIES ${target}) - include(CheckCXXSourceCompiles) - check_cxx_source_compiles(" - #include - #include - - int main() - { - evhttp_connection* conn = (evhttp_connection*)1; - const char* host; - uint16_t port; - evhttp_connection_get_peer(conn, &host, &port); - } - " HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR - ) - cmake_pop_check_state() - target_compile_definitions(${target} INTERFACE - $<$:HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR> - ) -endfunction() - -set(_libevent_components core extra) -if(NOT WIN32) - list(APPEND _libevent_components pthreads) -endif() - -find_package(Libevent ${Libevent_FIND_VERSION} QUIET - NO_MODULE -) - -include(FindPackageHandleStandardArgs) -if(Libevent_FOUND) - find_package(Libevent ${Libevent_FIND_VERSION} QUIET - REQUIRED COMPONENTS ${_libevent_components} - NO_MODULE - ) - find_package_handle_standard_args(Libevent - REQUIRED_VARS Libevent_DIR - VERSION_VAR Libevent_VERSION - ) - check_evhttp_connection_get_peer(libevent::extra) -else() - find_package(PkgConfig REQUIRED) - foreach(component IN LISTS _libevent_components) - pkg_check_modules(libevent_${component} - REQUIRED QUIET - IMPORTED_TARGET GLOBAL - libevent_${component}>=${Libevent_FIND_VERSION} - ) - if(TARGET PkgConfig::libevent_${component} AND NOT TARGET libevent::${component}) - add_library(libevent::${component} ALIAS PkgConfig::libevent_${component}) - endif() - endforeach() - find_package_handle_standard_args(Libevent - REQUIRED_VARS libevent_core_LIBRARY_DIRS - VERSION_VAR libevent_core_VERSION - ) - check_evhttp_connection_get_peer(PkgConfig::libevent_extra) -endif() - -unset(_libevent_components) - -mark_as_advanced(Libevent_DIR) -mark_as_advanced(_event_h) -mark_as_advanced(_event_lib) diff --git a/cmake/module/FindQRencode.cmake b/cmake/module/FindQRencode.cmake deleted file mode 100644 index 575bfecc8b1a..000000000000 --- a/cmake/module/FindQRencode.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2024-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -#[=======================================================================[ -FindQRencode ------------- - -Finds the QRencode header and library. - -This is a wrapper around find_package()/pkg_check_modules() commands that: - - facilitates searching in various build environments - - prints a standard log message - -#]=======================================================================] - -find_package(PkgConfig QUIET) -if(PKG_CONFIG_FOUND) - pkg_check_modules(PC_QRencode QUIET libqrencode) -endif() - -find_path(QRencode_INCLUDE_DIR - NAMES qrencode.h - HINTS ${PC_QRencode_INCLUDE_DIRS} -) - -find_library(QRencode_LIBRARY_RELEASE - NAMES qrencode - HINTS ${PC_QRencode_LIBRARY_DIRS} -) -find_library(QRencode_LIBRARY_DEBUG - NAMES qrencoded qrencode - HINTS ${PC_QRencode_LIBRARY_DIRS} -) -include(SelectLibraryConfigurations) -select_library_configurations(QRencode) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(QRencode - REQUIRED_VARS QRencode_LIBRARY QRencode_INCLUDE_DIR - VERSION_VAR PC_QRencode_VERSION -) - -if(QRencode_FOUND) - if(NOT TARGET QRencode::QRencode) - add_library(QRencode::QRencode UNKNOWN IMPORTED) - endif() - if(QRencode_LIBRARY_RELEASE) - set_property(TARGET QRencode::QRencode APPEND PROPERTY - IMPORTED_CONFIGURATIONS RELEASE - ) - set_target_properties(QRencode::QRencode PROPERTIES - IMPORTED_LOCATION_RELEASE "${QRencode_LIBRARY_RELEASE}" - ) - endif() - if(QRencode_LIBRARY_DEBUG) - set_property(TARGET QRencode::QRencode APPEND PROPERTY - IMPORTED_CONFIGURATIONS DEBUG - ) - set_target_properties(QRencode::QRencode PROPERTIES - IMPORTED_LOCATION_DEBUG "${QRencode_LIBRARY_DEBUG}" - ) - endif() - set_target_properties(QRencode::QRencode PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${QRencode_INCLUDE_DIR}" - ) -endif() - -mark_as_advanced( - QRencode_INCLUDE_DIR -) diff --git a/cmake/module/FindQt.cmake b/cmake/module/FindQt.cmake deleted file mode 100644 index d98af5bb56b1..000000000000 --- a/cmake/module/FindQt.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (c) 2024-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -#[=======================================================================[ -FindQt ------- - -Finds the Qt headers and libraries. - -This is a wrapper around find_package() command that: - - facilitates searching in various build environments - - prints a standard log message - -#]=======================================================================] - -set(_qt_homebrew_prefix) -if(CMAKE_HOST_APPLE) - find_program(HOMEBREW_EXECUTABLE brew) - if(HOMEBREW_EXECUTABLE) - execute_process( - COMMAND ${HOMEBREW_EXECUTABLE} --prefix qt@${Qt_FIND_VERSION_MAJOR} - OUTPUT_VARIABLE _qt_homebrew_prefix - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - endif() -endif() - -find_package(Qt${Qt_FIND_VERSION_MAJOR} ${Qt_FIND_VERSION} - COMPONENTS ${Qt_FIND_COMPONENTS} - HINTS ${_qt_homebrew_prefix} - PATH_SUFFIXES Qt${Qt_FIND_VERSION_MAJOR} # Required on OpenBSD systems. -) -unset(_qt_homebrew_prefix) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Qt - REQUIRED_VARS Qt${Qt_FIND_VERSION_MAJOR}_DIR - VERSION_VAR Qt${Qt_FIND_VERSION_MAJOR}_VERSION -) - -foreach(component IN LISTS Qt_FIND_COMPONENTS ITEMS "") - mark_as_advanced(Qt${Qt_FIND_VERSION_MAJOR}${component}_DIR) -endforeach() diff --git a/cmake/module/FindZeroMQ.cmake b/cmake/module/FindZeroMQ.cmake deleted file mode 100644 index eecd9b245362..000000000000 --- a/cmake/module/FindZeroMQ.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2024-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit/. - -#[=======================================================================[ -FindZeroMQ ----------- - -Finds the ZeroMQ headers and library. - -This is a wrapper around find_package()/pkg_check_modules() commands that: - - facilitates searching in various build environments - - prints a standard log message - -#]=======================================================================] - -include(FindPackageHandleStandardArgs) -find_package(ZeroMQ ${ZeroMQ_FIND_VERSION} NO_MODULE QUIET) -if(ZeroMQ_FOUND) - find_package_handle_standard_args(ZeroMQ - REQUIRED_VARS ZeroMQ_DIR - VERSION_VAR ZeroMQ_VERSION - ) - if(TARGET libzmq) - add_library(zeromq ALIAS libzmq) - elseif(TARGET libzmq-static) - add_library(zeromq ALIAS libzmq-static) - endif() - mark_as_advanced(ZeroMQ_DIR) -else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(libzmq QUIET - IMPORTED_TARGET - libzmq>=${ZeroMQ_FIND_VERSION} - ) - find_package_handle_standard_args(ZeroMQ - REQUIRED_VARS libzmq_LIBRARY_DIRS - VERSION_VAR libzmq_VERSION - ) - add_library(zeromq ALIAS PkgConfig::libzmq) -endif() diff --git a/cmake/module/GenerateSetupNsi.cmake b/cmake/module/GenerateSetupNsi.cmake index 50191b6d0e2f..7c089de687b8 100644 --- a/cmake/module/GenerateSetupNsi.cmake +++ b/cmake/module/GenerateSetupNsi.cmake @@ -8,7 +8,7 @@ function(generate_setup_nsi) set(CLIENT_URL ${PROJECT_HOMEPAGE_URL}) set(CLIENT_TARNAME "bitcoin") set(BITCOIN_WRAPPER_NAME "bitcoin") - # TODO: add bitcoin-node and bitcoin-miner + # TODO: add sv2-tp set(EXEEXT ${CMAKE_EXECUTABLE_SUFFIX}) configure_file(${PROJECT_SOURCE_DIR}/share/setup.nsi.in ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.nsi USE_SOURCE_PERMISSIONS @ONLY) endfunction() diff --git a/cmake/module/Maintenance.cmake b/cmake/module/Maintenance.cmake index 957f2a2eeac6..9c3d2d34bb65 100644 --- a/cmake/module/Maintenance.cmake +++ b/cmake/module/Maintenance.cmake @@ -23,7 +23,7 @@ function(add_maintenance_targets) return() endif() - foreach(target IN ITEMS bitcoin bitcoind bitcoin-node bitcoin-qt bitcoin-gui bitcoin-cli bitcoin-tx bitcoin-util bitcoin-wallet test_bitcoin bench_bitcoin bitcoin-mine) + foreach(target IN ITEMS test_sv2 sv2-tp) if(TARGET ${target}) list(APPEND executables $) endif() @@ -43,8 +43,7 @@ function(add_maintenance_targets) endfunction() function(add_windows_deploy_target) - # TODO: add TARGET bitcoin-node TARGET bitcoin-mine - if(MINGW AND TARGET bitcoin) + if(MINGW AND TARGET sv2-tp) find_program(MAKENSIS_EXECUTABLE makensis) if(NOT MAKENSIS_EXECUTABLE) add_custom_target(deploy @@ -67,72 +66,3 @@ function(add_windows_deploy_target) add_custom_target(deploy DEPENDS ${PROJECT_BINARY_DIR}/bitcoin-win64-setup.exe) endif() endfunction() - -function(add_macos_deploy_target) - if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND TARGET bitcoin-qt) - set(macos_app "Bitcoin-Qt.app") - # Populate Contents subdirectory. - configure_file(${PROJECT_SOURCE_DIR}/share/qt/Info.plist.in ${macos_app}/Contents/Info.plist NO_SOURCE_PERMISSIONS) - file(CONFIGURE OUTPUT ${macos_app}/Contents/PkgInfo CONTENT "APPL????") - # Populate Contents/Resources subdirectory. - file(CONFIGURE OUTPUT ${macos_app}/Contents/Resources/empty.lproj CONTENT "") - configure_file(${PROJECT_SOURCE_DIR}/src/qt/res/icons/bitcoin.icns ${macos_app}/Contents/Resources/bitcoin.icns NO_SOURCE_PERMISSIONS COPYONLY) - file(CONFIGURE OUTPUT ${macos_app}/Contents/Resources/Base.lproj/InfoPlist.strings - CONTENT "{ CFBundleDisplayName = \"@CLIENT_NAME@\"; CFBundleName = \"@CLIENT_NAME@\"; }" - ) - - add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/${macos_app}/Contents/MacOS/Bitcoin-Qt - COMMAND ${CMAKE_COMMAND} --install ${PROJECT_BINARY_DIR} --config $ --component bitcoin-qt --prefix ${macos_app}/Contents/MacOS --strip - COMMAND ${CMAKE_COMMAND} -E rename ${macos_app}/Contents/MacOS/bin/$ ${macos_app}/Contents/MacOS/Bitcoin-Qt - COMMAND ${CMAKE_COMMAND} -E rm -rf ${macos_app}/Contents/MacOS/bin - COMMAND ${CMAKE_COMMAND} -E rm -rf ${macos_app}/Contents/MacOS/share - VERBATIM - ) - - string(REPLACE " " "-" osx_volname ${CLIENT_NAME}) - if(CMAKE_HOST_APPLE) - add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/${osx_volname}.zip - COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/contrib/macdeploy/macdeployqtplus ${macos_app} ${osx_volname} -translations-dir=${QT_TRANSLATIONS_DIR} -zip - DEPENDS ${PROJECT_BINARY_DIR}/${macos_app}/Contents/MacOS/Bitcoin-Qt - VERBATIM - ) - add_custom_target(deploydir - DEPENDS ${PROJECT_BINARY_DIR}/${osx_volname}.zip - ) - add_custom_target(deploy - DEPENDS ${PROJECT_BINARY_DIR}/${osx_volname}.zip - ) - else() - add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/dist/${macos_app}/Contents/MacOS/Bitcoin-Qt - COMMAND ${CMAKE_COMMAND} -E env OBJDUMP=${CMAKE_OBJDUMP} $ ${PROJECT_SOURCE_DIR}/contrib/macdeploy/macdeployqtplus ${macos_app} ${osx_volname} -translations-dir=${QT_TRANSLATIONS_DIR} - DEPENDS ${PROJECT_BINARY_DIR}/${macos_app}/Contents/MacOS/Bitcoin-Qt - VERBATIM - ) - add_custom_target(deploydir - DEPENDS ${PROJECT_BINARY_DIR}/dist/${macos_app}/Contents/MacOS/Bitcoin-Qt - ) - - find_program(ZIP_EXECUTABLE zip) - if(NOT ZIP_EXECUTABLE) - add_custom_target(deploy - COMMAND ${CMAKE_COMMAND} -E echo "Error: ZIP not found" - ) - else() - add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/dist/${osx_volname}.zip - WORKING_DIRECTORY dist - COMMAND ${PROJECT_SOURCE_DIR}/cmake/script/macos_zip.sh ${ZIP_EXECUTABLE} ${osx_volname}.zip - VERBATIM - ) - add_custom_target(deploy - DEPENDS ${PROJECT_BINARY_DIR}/dist/${osx_volname}.zip - ) - endif() - endif() - add_dependencies(deploydir bitcoin-qt) - add_dependencies(deploy deploydir) - endif() -endfunction() diff --git a/cmake/script/Coverage.cmake b/cmake/script/Coverage.cmake index 72587a5eb6a4..00596b4e9ed1 100644 --- a/cmake/script/Coverage.cmake +++ b/cmake/script/Coverage.cmake @@ -4,13 +4,8 @@ include(${CMAKE_CURRENT_LIST_DIR}/CoverageInclude.cmake) -set(functional_test_runner test/functional/test_runner.py) -if(EXTENDED_FUNCTIONAL_TESTS) - list(APPEND functional_test_runner --extended) -endif() if(DEFINED JOBS) list(APPEND CMAKE_CTEST_COMMAND -j ${JOBS}) - list(APPEND functional_test_runner -j ${JOBS}) endif() execute_process( @@ -19,7 +14,7 @@ execute_process( COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_COMMAND} --capture --directory src --test-name test_bitcoin --output-file test_bitcoin.info + COMMAND ${LCOV_COMMAND} --capture --directory src --test-name test_sv2 --output-file test_sv2.info WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) @@ -29,33 +24,22 @@ execute_process( COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_FILTER_COMMAND} test_bitcoin.info test_bitcoin_filtered.info - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - COMMAND_ERROR_IS_FATAL ANY -) -execute_process( - COMMAND ${LCOV_COMMAND} --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_filtered.info - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - COMMAND_ERROR_IS_FATAL ANY -) -execute_process( - COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --output-file test_bitcoin_coverage.info + COMMAND ${LCOV_FILTER_COMMAND} test_sv2.info test_sv2_filtered.info WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${GENHTML_COMMAND} test_bitcoin_coverage.info --output-directory test_bitcoin.coverage + COMMAND ${LCOV_COMMAND} --add-tracefile test_sv2_filtered.info --output-file test_sv2_filtered.info WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) - execute_process( - COMMAND ${functional_test_runner} + COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_sv2_filtered.info --output-file test_sv2_coverage.info WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_COMMAND} --capture --directory src --test-name functional-tests --output-file functional_test.info + COMMAND ${GENHTML_COMMAND} test_sv2_coverage.info --output-directory test_sv2.coverage WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} COMMAND_ERROR_IS_FATAL ANY ) @@ -65,17 +49,7 @@ execute_process( COMMAND_ERROR_IS_FATAL ANY ) execute_process( - COMMAND ${LCOV_FILTER_COMMAND} functional_test.info functional_test_filtered.info - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - COMMAND_ERROR_IS_FATAL ANY -) -execute_process( - COMMAND ${LCOV_COMMAND} --add-tracefile functional_test_filtered.info --output-file functional_test_filtered.info - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - COMMAND_ERROR_IS_FATAL ANY -) -execute_process( - COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_bitcoin_filtered.info --add-tracefile functional_test_filtered.info --output-file total_coverage.info + COMMAND ${LCOV_COMMAND} --add-tracefile baseline_filtered.info --add-tracefile test_sv2_filtered.info --output-file total_coverage.info COMMAND ${GREP_EXECUTABLE} "%" COMMAND ${AWK_EXECUTABLE} "{ print substr($3,2,50) \"/\" $5 }" OUTPUT_FILE coverage_percent.txt diff --git a/cmake/script/CoverageInclude.cmake.in b/cmake/script/CoverageInclude.cmake.in index 8fe11b48037f..b76687b4a538 100644 --- a/cmake/script/CoverageInclude.cmake.in +++ b/cmake/script/CoverageInclude.cmake.in @@ -36,9 +36,7 @@ list(APPEND LCOV_FILTER_COMMAND -p "/usr/lib/") list(APPEND LCOV_FILTER_COMMAND -p "/usr/lib64/") list(APPEND LCOV_FILTER_COMMAND -p "src/leveldb/") list(APPEND LCOV_FILTER_COMMAND -p "src/crc32c/") -list(APPEND LCOV_FILTER_COMMAND -p "src/bench/") list(APPEND LCOV_FILTER_COMMAND -p "src/crypto/ctaes") -list(APPEND LCOV_FILTER_COMMAND -p "src/minisketch") list(APPEND LCOV_FILTER_COMMAND -p "src/secp256k1") list(APPEND LCOV_FILTER_COMMAND -p "depends") diff --git a/cmake/secp256k1.cmake b/cmake/secp256k1.cmake index 15f1aacb66d1..2f9a470dbd57 100644 --- a/cmake/secp256k1.cmake +++ b/cmake/secp256k1.cmake @@ -11,12 +11,12 @@ function(add_secp256k1 subdir) set(SECP256K1_ENABLE_MODULE_RECOVERY ON CACHE BOOL "" FORCE) set(SECP256K1_ENABLE_MODULE_MUSIG ON CACHE BOOL "" FORCE) set(SECP256K1_BUILD_BENCHMARK OFF CACHE BOOL "" FORCE) - set(SECP256K1_BUILD_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) - set(SECP256K1_BUILD_EXHAUSTIVE_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) + set(SECP256K1_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(SECP256K1_BUILD_EXHAUSTIVE_TESTS OFF CACHE BOOL "" FORCE) if(NOT BUILD_TESTS) # Always skip the ctime tests, if we are building no other tests. # Otherwise, they are built if Valgrind is available. See SECP256K1_VALGRIND. - set(SECP256K1_BUILD_CTIME_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) + set(SECP256K1_BUILD_CTIME_TESTS OFF CACHE BOOL "" FORCE) endif() set(SECP256K1_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) include(GetTargetInterface) diff --git a/contrib/README.md b/contrib/README.md index f23d7ac557bb..d3d9989531d7 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -8,16 +8,6 @@ Additional tools, including the `github-merge.py` script, are available in the [ ### [Verify-Commits](/contrib/verify-commits) ### Tool to verify that every merge commit was signed by a developer using the `github-merge.py` script. -### [Linearize](/contrib/linearize) ### -Construct a linear, no-fork, best version of the blockchain. - -### [Qos](/contrib/qos) ### - -A Linux bash script that will set up traffic control (tc) to limit the outgoing bandwidth for connections to the Bitcoin network. This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it. - -### [Seeds](/contrib/seeds) ### -Utility to generate the pnSeed[] array that is compiled into the client. - Build Tools and Keys --------------------- @@ -38,16 +28,4 @@ Utilities to generate test vectors for the data-driven Bitcoin tests. ### [Verify-Binaries](/contrib/verify-binaries) ### This script attempts to download and verify the signature file SHA256SUMS.asc from bitcoin.org. -Command Line Tools ---------------------- - -### [Completions](/contrib/completions) ### -Shell completions for bash and fish. - -UTXO Set Tools --------------- -### [UTXO-to-SQLite](/contrib/utxo-tools/utxo_to_sqlite.py) ### -This script converts a compact-serialized UTXO set (as generated by Bitcoin Core with `dumptxoutset`) -to a SQLite3 database. For more details like e.g. the created table name and schema, refer to the -module docstring on top of the script, which is also contained in the command's `--help` output. diff --git a/contrib/asmap/README.md b/contrib/asmap/README.md deleted file mode 100644 index 849281c5da82..000000000000 --- a/contrib/asmap/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# ASMap Tool - -Tool for performing various operations on textual and binary asmap files, -particularly encoding/compressing the raw data to the binary format that can -be used in Bitcoin Core with the `-asmap` option. - -Example usage: -``` -python3 asmap-tool.py encode /path/to/input.file /path/to/output.file -python3 asmap-tool.py decode /path/to/input.file /path/to/output.file -python3 asmap-tool.py diff /path/to/first.file /path/to/second.file -python3 asmap-tool.py diff_addrs /path/to/first.file /path/to/second.file addrs.file -``` -These commands may take a few minutes to run with `python3`, -depending on the amount of data involved and your machine specs. -Consider using `pypy3` for a faster run time. - -### Encoding and Decoding - -ASmap files are somewhat large in text form, and need to be encoded -to binary before being used with Bitcoin Core. - -The `encode` command takes an ASmap and an output file. - -The `--fill`/`-f` flag further reduces the size of the output file -by assuming an AS assignment for an unmapped network if an adjacent network is assigned. -This procedure is lossy, in the sense that it loses information -about which ranges were unassigned. -However, if the input ASmap is incomplete, -this procedure will also reassign ranges that should have an AS assignment, -resulting in an ASmap that may diverge from reality significantly. -Finally, another consequence is that the resulting encoded file -will no longer be meaningful for diffs. -Therefore only use `--fill` if -you want to optimise space, you have a reasonably complete ASmap, -and do not intend to diff the file at a later time. - -The `decode` command takes an encoded ASmap and an output file. -As with `encode`, the `--fill`/`-f` flag reduces the output file size -by reassigning subnets. Conversely, the `--non-overlapping`/`-n` flag -increases output size by outputting strictly non-overlapping network ranges. - -### Comparing ASmaps - -AS control of IP networks changes frequently, therefore it can be useful to get -the changes between two ASmaps via the `diff` and `diff_addrs` commands. - -`diff` takes two ASmap files, and returns a file detailing the changes -in the state of a network's AS assignment between the first and the second file. -This command may take a few minutes to run, depending on your machine. - -The example below shows the three possible output states: -- reassigned to a new AS (`AS26496 # was AS20738`), -- present in the first but not the second (`# 220.157.65.0/24 was AS9723`), -- or present in the second but not the first (`# was unassigned`). - -``` -217.199.160.0/19 AS26496 # was AS20738 -# 220.157.65.0/24 was AS9723 -216.151.172.0/23 AS400080 # was unassigned -2001:470:49::/48 AS20205 # was AS6939 -# 2001:678:bd0::/48 was AS207631 -2001:67c:308::/48 AS26496 # was unassigned -``` -`diff` accepts a `--ignore-unassigned`/`-i` flag -which ignores networks present in the second but not the first. - -`diff_addrs` is intended to provide changes between two ASmaps and -a node's known peers. -The command takes two ASmap files, and a file of IP addresses as output by -the `bitcoin-cli getnodeaddresses` command. -It returns the changes between the two ASmaps for the peer IPs provided in -the `getnodeaddresses` output. -The resulting file is in the same format as the `diff` command shown above. - -You can output address data to a file: -``` -bitcoin-cli getnodeaddresses 0 > addrs.json -``` -and pass in the address file as the third argument: -``` -python3 asmap-tool.py diff_addrs path/to/first.file path/to/second.file addrs.json -``` diff --git a/contrib/asmap/asmap-tool.py b/contrib/asmap/asmap-tool.py deleted file mode 100755 index 33a380a2e7df..000000000000 --- a/contrib/asmap/asmap-tool.py +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2022 Pieter Wuille -# Distributed under the MIT software license, see the accompanying -# file LICENSE or http://www.opensource.org/licenses/mit-license.php. - -import argparse -import sys -import ipaddress -import json -import math -from collections import defaultdict - -import asmap - -def load_file(input_file): - try: - contents = input_file.read() - except OSError as err: - sys.exit(f"Input file '{input_file.name}' cannot be read: {err.strerror}.") - try: - bin_asmap = asmap.ASMap.from_binary(contents) - except ValueError: - bin_asmap = None - txt_error = None - entries = None - try: - txt_contents = str(contents, encoding="utf-8") - except UnicodeError: - txt_error = "invalid UTF-8" - txt_contents = None - if txt_contents is not None: - entries = [] - for line in txt_contents.split("\n"): - idx = line.find('#') - if idx >= 0: - line = line[:idx] - line = line.lstrip(' ').rstrip(' \t\r\n') - if len(line) == 0: - continue - fields = line.split(' ') - if len(fields) != 2: - txt_error = f"unparseable line '{line}'" - entries = None - break - prefix, asn = fields - if len(asn) <= 2 or asn[:2] != "AS" or any(c < '0' or c > '9' for c in asn[2:]): - txt_error = f"invalid ASN '{asn}'" - entries = None - break - try: - net = ipaddress.ip_network(prefix) - except ValueError: - txt_error = f"invalid network '{prefix}'" - entries = None - break - entries.append((asmap.net_to_prefix(net), int(asn[2:]))) - if entries is not None and bin_asmap is not None and len(contents) > 0: - sys.exit(f"Input file '{input_file.name}' is ambiguous.") - if entries is not None: - state = asmap.ASMap() - state.update_multi(entries) - return state - if bin_asmap is not None: - return bin_asmap - sys.exit(f"Input file '{input_file.name}' is neither a valid binary asmap file nor valid text input ({txt_error}).") - - -def save_binary(output_file, state, fill): - contents = state.to_binary(fill=fill) - try: - output_file.write(contents) - output_file.close() - except OSError as err: - sys.exit(f"Output file '{output_file.name}' cannot be written to: {err.strerror}.") - -def save_text(output_file, state, fill, overlapping): - for prefix, asn in state.to_entries(fill=fill, overlapping=overlapping): - net = asmap.prefix_to_net(prefix) - try: - print(f"{net} AS{asn}", file=output_file) - except OSError as err: - sys.exit(f"Output file '{output_file.name}' cannot be written to: {err.strerror}.") - try: - output_file.close() - except OSError as err: - sys.exit(f"Output file '{output_file.name}' cannot be written to: {err.strerror}.") - -def main(): - parser = argparse.ArgumentParser(description="Tool for performing various operations on textual and binary asmap files.") - subparsers = parser.add_subparsers(title="valid subcommands", dest="subcommand") - - parser_encode = subparsers.add_parser("encode", help="convert asmap data to binary format") - parser_encode.add_argument('-f', '--fill', dest="fill", default=False, action="store_true", - help="permit reassigning undefined network ranges arbitrarily to reduce size") - parser_encode.add_argument('infile', nargs='?', type=argparse.FileType('rb'), default=sys.stdin.buffer, - help="input asmap file (text or binary); default is stdin") - parser_encode.add_argument('outfile', nargs='?', type=argparse.FileType('wb'), default=sys.stdout.buffer, - help="output binary asmap file; default is stdout") - - parser_decode = subparsers.add_parser("decode", help="convert asmap data to text format") - parser_decode.add_argument('-f', '--fill', dest="fill", default=False, action="store_true", - help="permit reassigning undefined network ranges arbitrarily to reduce length") - parser_decode.add_argument('-n', '--nonoverlapping', dest="overlapping", default=True, action="store_false", - help="output strictly non-overall ping network ranges (increases output size)") - parser_decode.add_argument('infile', nargs='?', type=argparse.FileType('rb'), default=sys.stdin.buffer, - help="input asmap file (text or binary); default is stdin") - parser_decode.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout, - help="output text file; default is stdout") - - parser_diff = subparsers.add_parser("diff", help="compute the difference between two asmap files") - parser_diff.add_argument('-i', '--ignore-unassigned', dest="ignore_unassigned", default=False, action="store_true", - help="ignore unassigned ranges in the first input (useful when second input is filled)") - parser_diff.add_argument('infile1', type=argparse.FileType('rb'), - help="first file to compare (text or binary)") - parser_diff.add_argument('infile2', type=argparse.FileType('rb'), - help="second file to compare (text or binary)") - - parser_diff_addrs = subparsers.add_parser("diff_addrs", - help="compute difference between two asmap files for a set of addresses") - parser_diff_addrs.add_argument('-s', '--show-addresses', dest="show_addresses", default=False, action="store_true", - help="include reassigned addresses in the output") - parser_diff_addrs.add_argument("infile1", type=argparse.FileType("rb"), - help="first file to compare (text or binary)") - parser_diff_addrs.add_argument("infile2", type=argparse.FileType("rb"), - help="second file to compare (text or binary)") - parser_diff_addrs.add_argument("addrs_file", type=argparse.FileType("r"), - help="address file containing getnodeaddresses output to use in the comparison " - "(make sure to set the count parameter to zero to get all node addresses, " - "e.g. 'bitcoin-cli getnodeaddresses 0 > addrs.json')") - args = parser.parse_args() - if args.subcommand is None: - parser.print_help() - elif args.subcommand == "encode": - state = load_file(args.infile) - save_binary(args.outfile, state, fill=args.fill) - elif args.subcommand == "decode": - state = load_file(args.infile) - save_text(args.outfile, state, fill=args.fill, overlapping=args.overlapping) - elif args.subcommand == "diff": - state1 = load_file(args.infile1) - state2 = load_file(args.infile2) - ipv4_changed = 0 - ipv6_changed = 0 - for prefix, old_asn, new_asn in state1.diff(state2): - if args.ignore_unassigned and old_asn == 0: - continue - net = asmap.prefix_to_net(prefix) - if isinstance(net, ipaddress.IPv4Network): - ipv4_changed += 1 << (32 - net.prefixlen) - elif isinstance(net, ipaddress.IPv6Network): - ipv6_changed += 1 << (128 - net.prefixlen) - if new_asn == 0: - print(f"# {net} was AS{old_asn}") - elif old_asn == 0: - print(f"{net} AS{new_asn} # was unassigned") - else: - print(f"{net} AS{new_asn} # was AS{old_asn}") - ipv4_change_str = "" if ipv4_changed == 0 else f" (2^{math.log2(ipv4_changed):.2f})" - ipv6_change_str = "" if ipv6_changed == 0 else f" (2^{math.log2(ipv6_changed):.2f})" - - print( - f"# {ipv4_changed}{ipv4_change_str} IPv4 addresses changed; " - f"{ipv6_changed}{ipv6_change_str} IPv6 addresses changed" - ) - elif args.subcommand == "diff_addrs": - state1 = load_file(args.infile1) - state2 = load_file(args.infile2) - address_info = json.load(args.addrs_file) - addrs = {a["address"] for a in address_info if a["network"] in ["ipv4", "ipv6"]} - reassignments = defaultdict(list) - for addr in addrs: - net = ipaddress.ip_network(addr) - prefix = asmap.net_to_prefix(net) - old_asn = state1.lookup(prefix) - new_asn = state2.lookup(prefix) - if new_asn != old_asn: - reassignments[(old_asn, new_asn)].append(addr) - reassignments = sorted(reassignments.items(), key=lambda item: len(item[1]), reverse=True) - num_reassignment_type = defaultdict(int) - for (old_asn, new_asn), reassigned_addrs in reassignments: - num_reassigned = len(reassigned_addrs) - num_reassignment_type[(bool(old_asn), bool(new_asn))] += num_reassigned - old_asn_str = f"AS{old_asn}" if old_asn else "unassigned" - new_asn_str = f"AS{new_asn}" if new_asn else "unassigned" - opt = ": " + ", ".join(reassigned_addrs) if args.show_addresses else "" - print(f"{num_reassigned} address(es) reassigned from {old_asn_str} to {new_asn_str}{opt}") - num_reassignments = sum(len(addrs) for _, addrs in reassignments) - share = num_reassignments / len(addrs) if len(addrs) > 0 else 0 - print(f"Summary: {num_reassignments:,} ({share:.2%}) of {len(addrs):,} addresses were reassigned " - f"(migrations={num_reassignment_type[True, True]}, assignments={num_reassignment_type[False, True]}, " - f"unassignments={num_reassignment_type[True, False]})") - else: - parser.print_help() - sys.exit("No command provided.") - -if __name__ == '__main__': - main() diff --git a/contrib/asmap/asmap.py b/contrib/asmap/asmap.py deleted file mode 100644 index 2ae84a3f3119..000000000000 --- a/contrib/asmap/asmap.py +++ /dev/null @@ -1,818 +0,0 @@ -# Copyright (c) 2022 Pieter Wuille -# Distributed under the MIT software license, see the accompanying -# file LICENSE or http://www.opensource.org/licenses/mit-license.php. - -""" -This module provides the ASNEntry and ASMap classes. -""" - -import copy -import ipaddress -import random -import unittest -from collections.abc import Callable, Iterable -from enum import Enum -from functools import total_ordering -from typing import Optional, Union, overload - -def net_to_prefix(net: Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> list[bool]: - """ - Convert an IPv4 or IPv6 network to a prefix represented as a list of bits. - - IPv4 ranges are remapped to their IPv4-mapped IPv6 range (::ffff:0:0/96). - """ - num_bits = net.prefixlen - netrange = int.from_bytes(net.network_address.packed, 'big') - - # Map an IPv4 prefix into IPv6 space. - if isinstance(net, ipaddress.IPv4Network): - num_bits += 96 - netrange += 0xffff00000000 - - # Strip unused bottom bits. - assert (netrange & ((1 << (128 - num_bits)) - 1)) == 0 - return [((netrange >> (127 - i)) & 1) != 0 for i in range(num_bits)] - -def prefix_to_net(prefix: list[bool]) -> Union[ipaddress.IPv4Network,ipaddress.IPv6Network]: - """The reverse operation of net_to_prefix.""" - # Convert to number - netrange = sum(b << (127 - i) for i, b in enumerate(prefix)) - num_bits = len(prefix) - assert num_bits <= 128 - - # Return IPv4 range if in ::ffff:0:0/96 - if num_bits >= 96 and (netrange >> 32) == 0xffff: - return ipaddress.IPv4Network((netrange & 0xffffffff, num_bits - 96), True) - - # Return IPv6 range otherwise. - return ipaddress.IPv6Network((netrange, num_bits), True) - -# Shortcut for (prefix, ASN) entries. -ASNEntry = tuple[list[bool], int] - -# Shortcut for (prefix, old ASN, new ASN) entries. -ASNDiff = tuple[list[bool], int, int] - -class _VarLenCoder: - """ - A class representing a custom variable-length binary encoder/decoder for - integers. Each object represents a different coder, with different parameters - minval and clsbits. - - The encoding is easiest to describe using an example. Let's say minval=100 and - clsbits=[4,2,2,3]. In that case: - - x in [100..115]: encoded as [0] + [4-bit BE encoding of (x-100)]. - - x in [116..119]: encoded as [1,0] + [2-bit BE encoding of (x-116)]. - - x in [120..123]: encoded as [1,1,0] + [2-bit BE encoding of (x-120)]. - - x in [124..131]: encoded as [1,1,1] + [3-bit BE encoding of (x-124)]. - - In general, every number is encoded as: - - First, k "1"-bits, where k is the class the number falls in (there is one class - per element of clsbits). - - Then, a "0"-bit, unless k is the highest class, in which case there is nothing. - - Lastly, clsbits[k] bits encoding in big endian the position in its class that - number falls into. - - Every class k consists of 2^clsbits[k] consecutive integers. k=0 starts at minval, - other classes start one past the last element of the class before it. - """ - - def __init__(self, minval: int, clsbits: list[int]): - """Construct a new _VarLenCoder.""" - self._minval = minval - self._clsbits = clsbits - self._maxval = minval + sum(1 << b for b in clsbits) - 1 - - def can_encode(self, val: int) -> bool: - """Check whether value val is in the range this coder supports.""" - return self._minval <= val <= self._maxval - - def encode(self, val: int, ret: list[int]) -> None: - """Append encoding of val onto integer list ret.""" - - assert self._minval <= val <= self._maxval - val -= self._minval - bits = 0 - for k, bits in enumerate(self._clsbits): - if val >> bits: - # If the value will not fit in class k, subtract its range from v, - # emit a "1" bit and continue with the next class. - val -= 1 << bits - ret.append(1) - else: - if k + 1 < len(self._clsbits): - # Unless we're in the last class, emit a "0" bit. - ret.append(0) - break - # And then encode v (now the position within the class) in big endian. - ret.extend((val >> (bits - 1 - b)) & 1 for b in range(bits)) - - def encode_size(self, val: int) -> int: - """Compute how many bits are needed to encode val.""" - assert self._minval <= val <= self._maxval - val -= self._minval - ret = 0 - bits = 0 - for k, bits in enumerate(self._clsbits): - if val >> bits: - val -= 1 << bits - ret += 1 - else: - ret += k + 1 < len(self._clsbits) - break - return ret + bits - - def decode(self, stream, bitpos) -> tuple[int,int]: - """Decode a number starting at bitpos in stream, returning value and new bitpos.""" - val = self._minval - bits = 0 - for k, bits in enumerate(self._clsbits): - bit = 0 - if k + 1 < len(self._clsbits): - bit = stream[bitpos] - bitpos += 1 - if not bit: - break - val += 1 << bits - for i in range(bits): - bit = stream[bitpos] - bitpos += 1 - val += bit << (bits - 1 - i) - return val, bitpos - -# Variable-length encoders used in the binary asmap format. -_CODER_INS = _VarLenCoder(0, [0, 0, 1]) -_CODER_ASN = _VarLenCoder(1, list(range(15, 25))) -_CODER_MATCH = _VarLenCoder(2, list(range(1, 9))) -_CODER_JUMP = _VarLenCoder(17, list(range(5, 31))) - -class _Instruction(Enum): - """One instruction in the binary asmap format.""" - # A return instruction, encoded as [0], returns a constant ASN. It is followed by - # an integer using the ASN encoding. - RETURN = 0 - # A jump instruction, encoded as [1,0] inspects the next unused bit in the input - # and either continues execution (if 0), or skips a specified number of bits (if 1). - # It is followed by an integer, and then two subprograms. The integer uses jump encoding - # and corresponds to the length of the first subprogram (so it can be skipped). - JUMP = 1 - # A match instruction, encoded as [1,1,0] inspects 1 or more of the next unused bits - # in the input with its argument. If they all match, execution continues. If they do - # not, failure is returned. If a default instruction has been executed before, instead - # of failure the default instruction's argument is returned. It is followed by an - # integer in match encoding, and a subprogram. That value is at least 2 bits and at - # most 9 bits. An n-bit value signifies matching (n-1) bits in the input with the lower - # (n-1) bits in the match value. - MATCH = 2 - # A default instruction, encoded as [1,1,1] sets the default variable to its argument, - # and continues execution. It is followed by an integer in ASN encoding, and a subprogram. - DEFAULT = 3 - # Not an actual instruction, but a way to encode the empty program that fails. In the - # encoder, it is used more generally to represent the failure case inside MATCH instructions, - # which may (if used inside the context of a DEFAULT instruction) actually correspond to - # a successful return. In this usage, they're always converted to an actual MATCH or RETURN - # before the top level is reached (see make_default below). - END = 4 - -class _BinNode: - """A class representing a (node of) the parsed binary asmap format.""" - - @overload - def __init__(self, ins: _Instruction): ... - @overload - def __init__(self, ins: _Instruction, arg1: int): ... - @overload - def __init__(self, ins: _Instruction, arg1: "_BinNode", arg2: "_BinNode"): ... - @overload - def __init__(self, ins: _Instruction, arg1: int, arg2: "_BinNode"): ... - - def __init__(self, ins: _Instruction, arg1=None, arg2=None): - """ - Construct a new asmap node. Possibilities are: - - _BinNode(_Instruction.RETURN, asn) - - _BinNode(_Instruction.JUMP, node_0, node_1) - - _BinNode(_Instruction.MATCH, val, node) - - _BinNode(_Instruction.DEFAULT, asn, node) - - _BinNode(_Instruction.END) - """ - self.ins = ins - self.arg1 = arg1 - self.arg2 = arg2 - if ins == _Instruction.RETURN: - assert isinstance(arg1, int) - assert arg2 is None - self.size = _CODER_INS.encode_size(ins.value) + _CODER_ASN.encode_size(arg1) - elif ins == _Instruction.JUMP: - assert isinstance(arg1, _BinNode) - assert isinstance(arg2, _BinNode) - self.size = (_CODER_INS.encode_size(ins.value) + _CODER_JUMP.encode_size(arg1.size) + - arg1.size + arg2.size) - elif ins == _Instruction.DEFAULT: - assert isinstance(arg1, int) - assert isinstance(arg2, _BinNode) - self.size = _CODER_INS.encode_size(ins.value) + _CODER_ASN.encode_size(arg1) + arg2.size - elif ins == _Instruction.MATCH: - assert isinstance(arg1, int) - assert isinstance(arg2, _BinNode) - self.size = (_CODER_INS.encode_size(ins.value) + _CODER_MATCH.encode_size(arg1) - + arg2.size) - elif ins == _Instruction.END: - assert arg1 is None - assert arg2 is None - self.size = 0 - else: - assert False - - @staticmethod - def make_end() -> "_BinNode": - """Constructor for a _BinNode with just an END instruction.""" - return _BinNode(_Instruction.END) - - @staticmethod - def make_leaf(val: int) -> "_BinNode": - """Constructor for a _BinNode of just a RETURN instruction.""" - assert val is not None and val > 0 - return _BinNode(_Instruction.RETURN, val) - - @staticmethod - def make_branch(node0: "_BinNode", node1: "_BinNode") -> "_BinNode": - """ - Construct a _BinNode corresponding to running either the node0 or node1 subprogram, - based on the next input bit. It exploits shortcuts that are possible in the encoding, - and uses either a JUMP, MATCH, or END instruction. - """ - if node0.ins == _Instruction.END and node1.ins == _Instruction.END: - return node0 - if node0.ins == _Instruction.END: - if node1.ins == _Instruction.MATCH and node1.arg1 <= 0xFF: - return _BinNode(node1.ins, node1.arg1 + (1 << node1.arg1.bit_length()), node1.arg2) - return _BinNode(_Instruction.MATCH, 3, node1) - if node1.ins == _Instruction.END: - if node0.ins == _Instruction.MATCH and node0.arg1 <= 0xFF: - return _BinNode(node0.ins, node0.arg1 + (1 << (node0.arg1.bit_length() - 1)), - node0.arg2) - return _BinNode(_Instruction.MATCH, 2, node0) - return _BinNode(_Instruction.JUMP, node0, node1) - - @staticmethod - def make_default(val: int, sub: "_BinNode") -> "_BinNode": - """ - Construct a _BinNode that corresponds to the specified subprogram, with the specified - default value. It exploits shortcuts that are possible in the encoding, and will use - either a DEFAULT or a RETURN instruction.""" - assert val is not None and val > 0 - if sub.ins == _Instruction.END: - return _BinNode(_Instruction.RETURN, val) - if sub.ins in (_Instruction.RETURN, _Instruction.DEFAULT): - return sub - return _BinNode(_Instruction.DEFAULT, val, sub) - -@total_ordering -class ASMap: - """ - A class whose objects represent a mapping from subnets to ASNs. - - Internally the mapping is stored as a binary trie, but can be converted - from/to a list of ASNEntry objects, and from/to the binary asmap file format. - - In the trie representation, nodes are represented as bare lists for efficiency - and ease of manipulation: - - [0] means an unassigned subnet (no ASN mapping for it is present) - - [int] means a subnet mapped entirely to the specified ASN. - - [node,node] means a subnet whose lower half and upper half have different - - mappings, represented by new trie nodes. - """ - - def update(self, prefix: list[bool], asn: int) -> None: - """Update this ASMap object to map prefix to the specified asn.""" - assert asn == 0 or _CODER_ASN.can_encode(asn) - - def recurse(node: list, offset: int) -> None: - if offset == len(prefix): - # Reached the end of prefix; overwrite this node. - node.clear() - node.append(asn) - return - if len(node) == 1: - # Need to descend into a leaf node; split it up. - oldasn = node[0] - node.clear() - node.append([oldasn]) - node.append([oldasn]) - # Descend into the node. - recurse(node[prefix[offset]], offset + 1) - # If the result is two identical leaf children, merge them. - if len(node[0]) == 1 and len(node[1]) == 1 and node[0] == node[1]: - oldasn = node[0][0] - node.clear() - node.append(oldasn) - recurse(self._trie, 0) - - def update_multi(self, entries: list[tuple[list[bool], int]]) -> None: - """Apply multiple update operations, where longer prefixes take precedence.""" - entries.sort(key=lambda entry: len(entry[0])) - for prefix, asn in entries: - self.update(prefix, asn) - - def _set_trie(self, trie) -> None: - """Set trie directly. Internal use only.""" - def recurse(node: list) -> None: - if len(node) < 2: - return - recurse(node[0]) - recurse(node[1]) - if len(node[0]) == 2: - return - if node[0] == node[1]: - if len(node[0]) == 0: - node.clear() - else: - asn = node[0][0] - node.clear() - node.append(asn) - recurse(trie) - self._trie = trie - - def __init__(self, entries: Optional[Iterable[ASNEntry]] = None) -> None: - """Construct an ASMap object from an optional list of entries.""" - self._trie = [0] - if entries is not None: - def entry_key(entry): - """Sort function that places shorter prefixes first.""" - prefix, asn = entry - return len(prefix), prefix, asn - for prefix, asn in sorted(entries, key=entry_key): - self.update(prefix, asn) - - def lookup(self, prefix: list[bool]) -> Optional[int]: - """Look up a prefix. Returns ASN, or 0 if unassigned, or None if indeterminate.""" - node = self._trie - for bit in prefix: - if len(node) == 1: - break - node = node[bit] - if len(node) == 1: - return node[0] - return None - - def _to_entries_flat(self, fill: bool = False) -> list[ASNEntry]: - """Convert an ASMap object to a list of non-overlapping (prefix, asn) objects.""" - prefix : list[bool] = [] - - def recurse(node: list) -> list[ASNEntry]: - ret = [] - if len(node) == 1: - if node[0] > 0: - ret = [(list(prefix), node[0])] - elif len(node) == 2: - prefix.append(False) - ret = recurse(node[0]) - prefix[-1] = True - ret += recurse(node[1]) - prefix.pop() - if fill and len(ret) > 1: - asns = set(x[1] for x in ret) - if len(asns) == 1: - ret = [(list(prefix), list(asns)[0])] - return ret - return recurse(self._trie) - - def _to_entries_minimal(self, fill: bool = False) -> list[ASNEntry]: - """Convert a trie to a minimal list of ASNEntry objects, exploiting overlap.""" - prefix : list[bool] = [] - - def recurse(node: list) -> (tuple[dict[Optional[int], list[ASNEntry]], bool]): - if len(node) == 1 and node[0] == 0: - return {None if fill else 0: []}, True - if len(node) == 1: - return {node[0]: [], None: [(list(prefix), node[0])]}, False - ret: dict[Optional[int], list[ASNEntry]] = {} - prefix.append(False) - left, lhole = recurse(node[0]) - prefix[-1] = True - right, rhole = recurse(node[1]) - prefix.pop() - hole = not fill and (lhole or rhole) - def candidate(ctx: Optional[int], res0: Optional[list[ASNEntry]], - res1: Optional[list[ASNEntry]]): - if res0 is not None and res1 is not None: - if ctx not in ret or len(res0) + len(res1) < len(ret[ctx]): - ret[ctx] = res0 + res1 - for ctx in set(left) | set(right): - candidate(ctx, left.get(ctx), right.get(ctx)) - candidate(ctx, left.get(None), right.get(ctx)) - candidate(ctx, left.get(ctx), right.get(None)) - if not hole: - for ctx in list(ret): - if ctx is not None: - candidate(None, [(list(prefix), ctx)], ret[ctx]) - if None in ret: - ret = {ctx:entries for ctx, entries in ret.items() - if ctx is None or len(entries) < len(ret[None])} - if hole: - ret = {ctx:entries for ctx, entries in ret.items() if ctx is None or ctx == 0} - return ret, hole - res, _ = recurse(self._trie) - return res[0] if 0 in res else res[None] - - def __str__(self) -> str: - """Convert this ASMap object to a string containing Python code constructing it.""" - return f"ASMap({self._trie})" - - def to_entries(self, overlapping: bool = True, fill: bool = False) -> list[ASNEntry]: - """ - Convert the mappings in this ASMap object to a list of ASNEntry objects. - - Arguments: - overlapping: Permit the subnets in the resulting ASNEntry to overlap. - Setting this can result in a shorter list. - fill: Permit the resulting ASNEntry objects to cover subnets that - are unassigned in this ASMap object. Setting this can - result in a shorter list. - """ - if overlapping: - return self._to_entries_minimal(fill) - return self._to_entries_flat(fill) - - @staticmethod - def from_random(num_leaves: int = 10, max_asn: int = 6, - unassigned_prob: float = 0.5) -> "ASMap": - """ - Construct a random ASMap object, with specified: - - Number of leaves in its trie (at least 1) - - Maximum ASN value (at least 1) - - Probability for leaf nodes to be unassigned - - The number of leaves in the resulting object may be less than what is - requested. This method is mostly intended for testing. - """ - assert num_leaves >= 1 - assert max_asn >= 1 or unassigned_prob == 1 - assert _CODER_ASN.can_encode(max_asn) - assert 0.0 <= unassigned_prob <= 1.0 - trie: list = [] - leaves = [trie] - ret = ASMap() - for i in range(1, num_leaves): - idx = random.randrange(i) - leaf = leaves[idx] - lastleaf = leaves.pop() - if idx + 1 < i: - leaves[idx] = lastleaf - leaf.append([]) - leaf.append([]) - leaves.append(leaf[0]) - leaves.append(leaf[1]) - for leaf in leaves: - if random.random() >= unassigned_prob: - leaf.append(random.randrange(1, max_asn + 1)) - else: - leaf.append(0) - #pylint: disable=protected-access - ret._set_trie(trie) - return ret - - def _to_binnode(self, fill: bool = False) -> _BinNode: - """Convert a trie to a _BinNode object.""" - def recurse(node: list) -> tuple[dict[Optional[int], _BinNode], bool]: - if len(node) == 1 and node[0] == 0: - return {(None if fill else 0): _BinNode.make_end()}, True - if len(node) == 1: - return {None: _BinNode.make_leaf(node[0]), node[0]: _BinNode.make_end()}, False - ret: dict[Optional[int], _BinNode] = {} - left, lhole = recurse(node[0]) - right, rhole = recurse(node[1]) - hole = (lhole or rhole) and not fill - - def candidate(ctx: Optional[int], arg1, arg2, func: Callable): - if arg1 is not None and arg2 is not None: - cand = func(arg1, arg2) - if ctx not in ret or cand.size < ret[ctx].size: - ret[ctx] = cand - - union = set(left) | set(right) - sorted_union = sorted(union, key=lambda x: (x is None, x)) - for ctx in sorted_union: - candidate(ctx, left.get(ctx), right.get(ctx), _BinNode.make_branch) - candidate(ctx, left.get(None), right.get(ctx), _BinNode.make_branch) - candidate(ctx, left.get(ctx), right.get(None), _BinNode.make_branch) - if not hole: - for ctx in sorted(set(ret) - set([None])): - candidate(None, ctx, ret[ctx], _BinNode.make_default) - if None in ret: - ret = {ctx:enc for ctx, enc in ret.items() - if ctx is None or enc.size < ret[None].size} - if hole: - ret = {ctx:enc for ctx, enc in ret.items() if ctx is None or ctx == 0} - return ret, hole - res, _ = recurse(self._trie) - return res[0] if 0 in res else res[None] - - @staticmethod - def _from_binnode(binnode: _BinNode) -> "ASMap": - """Construct an ASMap object from a _BinNode. Internal use only.""" - def recurse(node: _BinNode, default: int) -> list: - if node.ins == _Instruction.RETURN: - return [node.arg1] - if node.ins == _Instruction.JUMP: - return [recurse(node.arg1, default), recurse(node.arg2, default)] - if node.ins == _Instruction.MATCH: - val = node.arg1 - sub = recurse(node.arg2, default) - while val >= 2: - bit = val & 1 - val >>= 1 - if bit: - sub = [[default], sub] - else: - sub = [sub, [default]] - return sub - assert node.ins == _Instruction.DEFAULT - return recurse(node.arg2, node.arg1) - ret = ASMap() - if binnode.ins != _Instruction.END: - #pylint: disable=protected-access - ret._set_trie(recurse(binnode, 0)) - return ret - - def to_binary(self, fill: bool = False) -> bytes: - """ - Convert this ASMap object to binary. - - Argument: - fill: permit the resulting binary encoder to contain mappers for - unassigned subnets in this ASMap object. Doing so may - reduce the size of the encoding. - Returns: - A bytes object with the encoding of this ASMap object. - """ - bits: list[int] = [] - - def recurse(node: _BinNode) -> None: - _CODER_INS.encode(node.ins.value, bits) - if node.ins == _Instruction.RETURN: - _CODER_ASN.encode(node.arg1, bits) - elif node.ins == _Instruction.JUMP: - _CODER_JUMP.encode(node.arg1.size, bits) - recurse(node.arg1) - recurse(node.arg2) - elif node.ins == _Instruction.DEFAULT: - _CODER_ASN.encode(node.arg1, bits) - recurse(node.arg2) - else: - assert node.ins == _Instruction.MATCH - _CODER_MATCH.encode(node.arg1, bits) - recurse(node.arg2) - - binnode = self._to_binnode(fill) - if binnode.ins != _Instruction.END: - recurse(binnode) - - val = 0 - nbits = 0 - ret = [] - for bit in bits: - val += (bit << nbits) - nbits += 1 - if nbits == 8: - ret.append(val) - val = 0 - nbits = 0 - if nbits: - ret.append(val) - return bytes(ret) - - @staticmethod - def from_binary(bindata: bytes) -> Optional["ASMap"]: - """Decode an ASMap object from the provided binary encoding.""" - - bits: list[int] = [] - for byte in bindata: - bits.extend((byte >> i) & 1 for i in range(8)) - - def recurse(bitpos: int) -> tuple[_BinNode, int]: - insval, bitpos = _CODER_INS.decode(bits, bitpos) - ins = _Instruction(insval) - if ins == _Instruction.RETURN: - asn, bitpos = _CODER_ASN.decode(bits, bitpos) - return _BinNode(ins, asn), bitpos - if ins == _Instruction.JUMP: - jump, bitpos = _CODER_JUMP.decode(bits, bitpos) - left, bitpos1 = recurse(bitpos) - if bitpos1 != bitpos + jump: - raise ValueError("Inconsistent jump") - right, bitpos = recurse(bitpos1) - return _BinNode(ins, left, right), bitpos - if ins == _Instruction.MATCH: - match, bitpos = _CODER_MATCH.decode(bits, bitpos) - sub, bitpos = recurse(bitpos) - return _BinNode(ins, match, sub), bitpos - assert ins == _Instruction.DEFAULT - asn, bitpos = _CODER_ASN.decode(bits, bitpos) - sub, bitpos = recurse(bitpos) - return _BinNode(ins, asn, sub), bitpos - - if len(bits) == 0: - binnode = _BinNode(_Instruction.END) - else: - try: - binnode, bitpos = recurse(0) - except (ValueError, IndexError): - return None - if bitpos < len(bits) - 7: - return None - if not all(bit == 0 for bit in bits[bitpos:]): - return None - - return ASMap._from_binnode(binnode) - - def __lt__(self, other: "ASMap") -> bool: - return self._trie < other._trie - - def __eq__(self, other: object) -> bool: - if isinstance(other, ASMap): - return self._trie == other._trie - return False - - def extends(self, req: "ASMap") -> bool: - """Determine whether this matches req for all subranges where req is assigned.""" - def recurse(actual: list, require: list) -> bool: - if len(require) == 1 and require[0] == 0: - return True - if len(require) == 1: - if len(actual) == 1: - return bool(require[0] == actual[0]) - return recurse(actual[0], require) and recurse(actual[1], require) - if len(actual) == 2: - return recurse(actual[0], require[0]) and recurse(actual[1], require[1]) - return recurse(actual, require[0]) and recurse(actual, require[1]) - assert isinstance(req, ASMap) - #pylint: disable=protected-access - return recurse(self._trie, req._trie) - - def diff(self, other: "ASMap") -> list[ASNDiff]: - """Compute the diff from self to other.""" - prefix: list[bool] = [] - ret: list[ASNDiff] = [] - - def recurse(old_node: list, new_node: list): - if len(old_node) == 1 and len(new_node) == 1: - if old_node[0] != new_node[0]: - ret.append((list(prefix), old_node[0], new_node[0])) - else: - old_left: list = old_node if len(old_node) == 1 else old_node[0] - old_right: list = old_node if len(old_node) == 1 else old_node[1] - new_left: list = new_node if len(new_node) == 1 else new_node[0] - new_right: list = new_node if len(new_node) == 1 else new_node[1] - prefix.append(False) - recurse(old_left, new_left) - prefix[-1] = True - recurse(old_right, new_right) - prefix.pop() - assert isinstance(other, ASMap) - #pylint: disable=protected-access - recurse(self._trie, other._trie) - return ret - - def __copy__(self) -> "ASMap": - """Construct a copy of this ASMap object. Its state will not be shared.""" - ret = ASMap() - #pylint: disable=protected-access - ret._set_trie(copy.deepcopy(self._trie)) - return ret - - def __deepcopy__(self, _) -> "ASMap": - # ASMap objects do not allow sharing of the _trie member, so we don't need the memoization. - return self.__copy__() - - -class TestASMap(unittest.TestCase): - """Unit tests for this module.""" - - def test_ipv6_prefix_roundtrips(self) -> None: - """Test that random IPv6 network ranges roundtrip through prefix encoding.""" - for _ in range(20): - net_bits = random.getrandbits(128) - for prefix_len in range(0, 129): - masked_bits = (net_bits >> (128 - prefix_len)) << (128 - prefix_len) - net = ipaddress.IPv6Network((masked_bits.to_bytes(16, 'big'), prefix_len)) - prefix = net_to_prefix(net) - self.assertTrue(len(prefix) <= 128) - net2 = prefix_to_net(prefix) - self.assertEqual(net, net2) - - def test_ipv4_prefix_roundtrips(self) -> None: - """Test that random IPv4 network ranges roundtrip through prefix encoding.""" - for _ in range(100): - net_bits = random.getrandbits(32) - for prefix_len in range(0, 33): - masked_bits = (net_bits >> (32 - prefix_len)) << (32 - prefix_len) - net = ipaddress.IPv4Network((masked_bits.to_bytes(4, 'big'), prefix_len)) - prefix = net_to_prefix(net) - self.assertTrue(32 <= len(prefix) <= 128) - net2 = prefix_to_net(prefix) - self.assertEqual(net, net2) - - def test_asmap_roundtrips(self) -> None: - """Test case that verifies random ASMap objects roundtrip to/from entries/binary.""" - # Iterate over the number of leaves the random test ASMap objects have. - for leaves in range(1, 20): - # Iterate over the number of bits in the AS numbers used. - for asnbits in range(0, 24): - # Iterate over the probability that leaves are unassigned. - for pct in range(101): - # Construct a random ASMap object according to the above parameters. - asmap = ASMap.from_random(num_leaves=leaves, max_asn=1 + (1 << asnbits), - unassigned_prob=0.01 * pct) - # Run tests for to_entries and construction from those entries, both - # for overlapping and non-overlapping ones. - for overlapping in [False, True]: - entries = asmap.to_entries(overlapping=overlapping, fill=False) - random.shuffle(entries) - asmap2 = ASMap(entries) - assert asmap2 is not None - self.assertEqual(asmap2, asmap) - entries = asmap.to_entries(overlapping=overlapping, fill=True) - random.shuffle(entries) - asmap2 = ASMap(entries) - assert asmap2 is not None - self.assertTrue(asmap2.extends(asmap)) - - # Run tests for to_binary and construction from binary. - enc = asmap.to_binary(fill=False) - asmap3 = ASMap.from_binary(enc) - assert asmap3 is not None - self.assertEqual(asmap3, asmap) - enc = asmap.to_binary(fill=True) - asmap3 = ASMap.from_binary(enc) - assert asmap3 is not None - self.assertTrue(asmap3.extends(asmap)) - - def test_patching(self) -> None: - """Test behavior of update, lookup, extends, and diff.""" - #pylint: disable=too-many-locals,too-many-nested-blocks - # Iterate over the number of leaves the random test ASMap objects have. - for leaves in range(1, 20): - # Iterate over the number of bits in the AS numbers used. - for asnbits in range(0, 10): - # Iterate over the probability that leaves are unassigned. - for pct in range(0, 101): - # Construct a random ASMap object according to the above parameters. - asmap = ASMap.from_random(num_leaves=leaves, max_asn=1 + (1 << asnbits), - unassigned_prob=0.01 * pct) - # Make a copy of that asmap object to which patches will be applied. - # It starts off being equal to asmap. - patched = copy.copy(asmap) - # Keep a list of patches performed. - patches: list[ASNEntry] = [] - # Initially there cannot be any difference. - self.assertEqual(asmap.diff(patched), []) - # Make 5 patches, each building on top of the previous ones. - for _ in range(0, 5): - # Construct a random path and new ASN to assign it to, apply it to patched, - # and remember it in patches. - pathlen = random.randrange(5) - path = [random.getrandbits(1) != 0 for _ in range(pathlen)] - newasn = random.randrange(1 + (1 << asnbits)) - patched.update(path, newasn) - patches = [(path, newasn)] + patches - - # Compute the diff, and whether asmap extends patched, and the other way - # around. - diff = asmap.diff(patched) - self.assertEqual(asmap == patched, len(diff) == 0) - extends = asmap.extends(patched) - back_extends = patched.extends(asmap) - # Determine whether those extends results are consistent with the diff - # result. - self.assertEqual(extends, all(d[2] == 0 for d in diff)) - self.assertEqual(back_extends, all(d[1] == 0 for d in diff)) - # For every diff found: - for path, old_asn, new_asn in diff: - # Verify asmap and patched actually differ there. - self.assertTrue(old_asn != new_asn) - self.assertEqual(asmap.lookup(path), old_asn) - self.assertEqual(patched.lookup(path), new_asn) - for _ in range(2): - # Extend the path far enough that it's smaller than any mapped - # range, and check the lookup holds there too. - spec_path = list(path) - while len(spec_path) < 32: - spec_path.append(random.getrandbits(1) != 0) - self.assertEqual(asmap.lookup(spec_path), old_asn) - self.assertEqual(patched.lookup(spec_path), new_asn) - # Search through the list of performed patches to find the last one - # applying to the extended path (note that patches is in reverse - # order, so the first match should work). - found = False - for patch_path, patch_asn in patches: - if spec_path[:len(patch_path)] == patch_path: - # When found, it must match whatever the result was patched - # to. - self.assertEqual(new_asn, patch_asn) - found = True - break - # And such a patch must exist. - self.assertTrue(found) - -if __name__ == '__main__': - unittest.main() diff --git a/contrib/completions/bash/bitcoin-cli.bash b/contrib/completions/bash/bitcoin-cli.bash deleted file mode 100644 index 3018d076c614..000000000000 --- a/contrib/completions/bash/bitcoin-cli.bash +++ /dev/null @@ -1,138 +0,0 @@ -# bash programmable completion for bitcoin-cli(1) -# Copyright (c) 2012-2022 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# call $bitcoin-cli for RPC -_bitcoin_rpc() { - # determine already specified args necessary for RPC - local rpcargs=() - for i in ${COMP_LINE}; do - case "$i" in - -conf=*|-datadir=*|-regtest|-rpc*|-testnet|-testnet4) - rpcargs=( "${rpcargs[@]}" "$i" ) - ;; - esac - done - $bitcoin_cli "${rpcargs[@]}" "$@" -} - -_bitcoin_cli() { - local cur prev words=() cword - local bitcoin_cli - - # save and use original argument to invoke bitcoin-cli for -help, help and RPC - # as bitcoin-cli might not be in $PATH - bitcoin_cli="$1" - - COMPREPLY=() - _get_comp_words_by_ref -n = cur prev words cword - - if ((cword > 5)); then - case ${words[cword-5]} in - sendtoaddress) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 4)); then - case ${words[cword-4]} in - listtransactions|setban) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - signrawtransactionwithkey|signrawtransactionwithwallet) - COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 3)); then - case ${words[cword-3]} in - getbalance|gettxout|listreceivedbyaddress|listsinceblock) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - esac - fi - - if ((cword > 2)); then - case ${words[cword-2]} in - addnode) - COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) - return 0 - ;; - setban) - COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) - return 0 - ;; - fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listreceivedbyaddress|sendrawtransaction) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - esac - fi - - case "$prev" in - backupwallet) - _filedir - return 0 - ;; - getaddednodeinfo|getrawmempool|lockunspent) - COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) - return 0 - ;; - getbalance|getnewaddress|listtransactions|sendmany) - return 0 - ;; - esac - - case "$cur" in - -conf=*) - cur="${cur#*=}" - _filedir - return 0 - ;; - -datadir=*) - cur="${cur#*=}" - _filedir -d - return 0 - ;; - -*=*) # prevent nonsense completions - return 0 - ;; - *) - local helpopts commands - - # only parse -help if senseful - if [[ -z "$cur" || "$cur" =~ ^- ]]; then - helpopts=$($bitcoin_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) - fi - - # only parse help if senseful - if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then - commands=$(_bitcoin_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') - fi - - COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) - - # Prevent space if an argument is desired - if [[ $COMPREPLY == *= ]]; then - compopt -o nospace - fi - return 0 - ;; - esac -} && -complete -F _bitcoin_cli bitcoin-cli - -# Local variables: -# mode: shell-script -# sh-basic-offset: 4 -# sh-indent-comment: t -# indent-tabs-mode: nil -# End: -# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/completions/bash/bitcoin-tx.bash b/contrib/completions/bash/bitcoin-tx.bash deleted file mode 100644 index 51a9fe31cb71..000000000000 --- a/contrib/completions/bash/bitcoin-tx.bash +++ /dev/null @@ -1,57 +0,0 @@ -# bash programmable completion for bitcoin-tx(1) -# Copyright (c) 2016-2022 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -_bitcoin_tx() { - local cur prev words=() cword - local bitcoin_tx - - # save and use original argument to invoke bitcoin-tx for -help - # it might not be in $PATH - bitcoin_tx="$1" - - COMPREPLY=() - _get_comp_words_by_ref -n =: cur prev words cword - - case "$cur" in - load=*:*) - cur="${cur#load=*:}" - _filedir - return 0 - ;; - *=*) # prevent attempts to complete other arguments - return 0 - ;; - esac - - if [[ "$cword" == 1 || ( "$prev" != "-create" && "$prev" == -* ) ]]; then - # only options (or an uncompletable hex-string) allowed - # parse bitcoin-tx -help for options - local helpopts - helpopts=$($bitcoin_tx -help | sed -e '/^ -/ p' -e d ) - COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) - else - # only commands are allowed - # parse -help for commands - local helpcmds - helpcmds=$($bitcoin_tx -help | sed -e '1,/Commands:/d' -e 's/=.*/=/' -e '/^ [a-z]/ p' -e d ) - COMPREPLY=( $( compgen -W "$helpcmds" -- "$cur" ) ) - fi - - # Prevent space if an argument is desired - if [[ $COMPREPLY == *= ]]; then - compopt -o nospace - fi - - return 0 -} && -complete -F _bitcoin_tx bitcoin-tx - -# Local variables: -# mode: shell-script -# sh-basic-offset: 4 -# sh-indent-comment: t -# indent-tabs-mode: nil -# End: -# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/completions/bash/bitcoind.bash b/contrib/completions/bash/bitcoind.bash deleted file mode 100644 index c11d99ef3169..000000000000 --- a/contrib/completions/bash/bitcoind.bash +++ /dev/null @@ -1,56 +0,0 @@ -# bash programmable completion for bitcoind(1) and bitcoin-qt(1) -# Copyright (c) 2012-2022 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -_bitcoind() { - local cur prev words=() cword - local bitcoind - - # save and use original argument to invoke bitcoind for -help - # it might not be in $PATH - bitcoind="$1" - - COMPREPLY=() - _get_comp_words_by_ref -n = cur prev words cword - - case "$cur" in - -conf=*|-pid=*|-loadblock=*|-rpccookiefile=*|-wallet=*) - cur="${cur#*=}" - _filedir - return 0 - ;; - -datadir=*) - cur="${cur#*=}" - _filedir -d - return 0 - ;; - -*=*) # prevent nonsense completions - return 0 - ;; - *) - - # only parse -help if sensible - if [[ -z "$cur" || "$cur" =~ ^- ]]; then - local helpopts - helpopts=$($bitcoind -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) - COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) - fi - - # Prevent space if an argument is desired - if [[ $COMPREPLY == *= ]]; then - compopt -o nospace - fi - return 0 - ;; - esac -} && -complete -F _bitcoind bitcoind bitcoin-qt - -# Local variables: -# mode: shell-script -# sh-basic-offset: 4 -# sh-indent-comment: t -# indent-tabs-mode: nil -# End: -# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/completions/fish/bitcoin-cli.fish b/contrib/completions/fish/bitcoin-cli.fish deleted file mode 100644 index 2f034c475c1d..000000000000 --- a/contrib/completions/fish/bitcoin-cli.fish +++ /dev/null @@ -1,99 +0,0 @@ -# Disable files from being included in completions by default -complete --command bitcoin-cli --no-files - -function __fish_bitcoin_cli_get_commands_helper - set --local cmd (commandline -oc) - - # Don't return commands if '-help or -?' in commandline - if string match --quiet --regex -- '^-help$|^-\?$' $cmd - return - end - - # Strip help cmd from token to avoid duplication errors - set --local cmd (string match --invert --regex -- '^help$' $cmd) - # Strip -stdin* options to avoid waiting for input while we fetch completions - # TODO: this appears to be broken when run as tab completion (requires ctrl+c to exit) - set --local cmd (string match --invert --regex -- '^-stdin.*$' $cmd) - - # Match, format and return commands - for command in ($cmd help 2>&1 | string match --invert -r '^\=\=.*' | string match --invert -r '^\\s*$') - echo $command - end -end - -function __fish_bitcoin_cli_get_commands - argparse 'nohelp' 'commandsonly' -- $argv - set --local commands - - # Exclude description, exclude help - if set -q _flag_nohelp; and set -q _flag_commandsonly - set --append commands (__fish_bitcoin_cli_get_commands_helper | string replace -r ' .*$' '' | string match --invert -r 'help') - # Include description, exclude help - else if set -q _flag_nohelp - set --append commands (__fish_bitcoin_cli_get_commands_helper | string replace ' ' \t | string match --invert -r 'help') - # Exclude description, include help - else if set -q _flag_commandsonly - set --append commands (__fish_bitcoin_cli_get_commands_helper | string replace -r ' .*$' '') - # Include description, include help - else - set --append commands (__fish_bitcoin_cli_get_commands_helper | string replace ' ' \t) - end - - if string match -q -r '^.*error.*$' $commands[1] - # RPC offline or RPC wallet not loaded - return - else - for command in $commands - echo $command - end - end -end - - -function __fish_bitcoin_cli_get_options - argparse 'nofiles' -- $argv - set --local cmd (commandline -oc) - # Don't return options if '-help or -?' in commandline - if string match --quiet --regex -- '^-help$|-\?$' $cmd - return - end - set --local options - - if set -q _flag_nofiles - set --append options ($cmd -help 2>&1 | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=' | string match --invert -r '^.*=$') - else - set --append options ($cmd -help 2>&1 | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=' | string match -r '^.*=$') - end - - for option in $options - echo $option - end -end - -# Add options with file completion -# Don't offer after a command is given -complete \ - --command bitcoin-cli \ - --no-files \ - --condition "not __fish_seen_subcommand_from (__fish_bitcoin_cli_get_commands --commandsonly)" \ - --arguments "(__fish_bitcoin_cli_get_options)" -# Enable file completions only if the commandline now contains a `*.=` style option -complete --command bitcoin-cli \ - --condition 'string match --regex -- ".*=" (commandline -pt)' \ - --force-files - -# Add options without file completion -# Don't offer after a command is given -complete \ - --command bitcoin-cli \ - --no-files \ - --condition "not __fish_seen_subcommand_from (__fish_bitcoin_cli_get_commands --commandsonly)" \ - --arguments "(__fish_bitcoin_cli_get_options --nofiles)" - -# Add commands -# Permit command completions after `bitcoin-cli help` but not after other commands -complete \ - --command bitcoin-cli \ - --no-files \ - --condition "not __fish_seen_subcommand_from (__fish_bitcoin_cli_get_commands --commandsonly --nohelp)" \ - --arguments "(__fish_bitcoin_cli_get_commands)" diff --git a/contrib/completions/fish/bitcoin-qt.fish b/contrib/completions/fish/bitcoin-qt.fish deleted file mode 100644 index 15a355ae88f5..000000000000 --- a/contrib/completions/fish/bitcoin-qt.fish +++ /dev/null @@ -1,35 +0,0 @@ -# Disable files from being included in completions by default -complete --command bitcoin-qt --no-files - -# Extract options -function __fish_bitcoinqt_get_options - argparse 'nofiles' -- $argv - set --local cmd (commandline -opc)[1] - set --local options - - if set -q _flag_nofiles - set --append options ($cmd -help-debug | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=' | string match --invert -r '^.*=$') - else - set --append options ($cmd -help-debug | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=' | string match -r '^.*=$') - end - - for option in $options - echo $option - end -end - - -# Add options with file completion -complete \ - --command bitcoin-qt \ - --arguments "(__fish_bitcoinqt_get_options)" -# Enable file completions only if the commandline now contains a `*.=` style option -complete -c bitcoin-qt \ - --condition 'string match --regex -- ".*=" (commandline -pt)' \ - --force-files - -# Add options without file completion -complete \ - --command bitcoin-qt \ - --arguments "(__fish_bitcoinqt_get_options --nofiles)" - diff --git a/contrib/completions/fish/bitcoin-tx.fish b/contrib/completions/fish/bitcoin-tx.fish deleted file mode 100644 index 0ff262b948e4..000000000000 --- a/contrib/completions/fish/bitcoin-tx.fish +++ /dev/null @@ -1,65 +0,0 @@ -# Disable files from being included in completions by default -complete --command bitcoin-tx --no-files - -# Modified version of __fish_seen_subcommand_from -# Uses regex to detect cmd= syntax -function __fish_bitcoin_seen_cmd - set -l cmd (commandline -oc) - set -e cmd[1] - for i in $cmd - for j in $argv - if string match --quiet --regex -- "^$j.*" $i - return 0 - end - end - end - return 1 -end - -# Extract options -function __fish_bitcoin_tx_get_options - set --local cmd (commandline -oc)[1] - if string match --quiet --regex -- '^-help$|-\?$' $cmd - return - end - - for option in ($cmd -help 2>&1 | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=') - echo $option - end -end - -# Extract commands -function __fish_bitcoin_tx_get_commands - argparse 'commandsonly' -- $argv - set --local cmd (commandline -oc)[1] - set --local commands - - if set -q _flag_commandsonly - set --append commands ($cmd -help | sed -e '1,/Commands:/d' -e 's/=/=\t/' -e 's/(=/=/' -e '/^ [a-z]/ p' -e d | string replace -r '\ \ ' '' | string replace -r '=.*' '') - else - set --append commands ($cmd -help | sed -e '1,/Commands:/d' -e 's/=/=\t/' -e 's/(=/=/' -e '/^ [a-z]/ p' -e d | string replace -r '\ \ ' '') - end - - for command in $commands - echo $command - end -end - -# Add options -complete \ - --command bitcoin-tx \ - --condition "not __fish_bitcoin_seen_cmd (__fish_bitcoin_tx_get_commands --commandsonly)" \ - --arguments "(__fish_bitcoin_tx_get_options)" \ - --no-files - -# Add commands -complete \ - --command bitcoin-tx \ - --arguments "(__fish_bitcoin_tx_get_commands)" \ - --no-files - -# Add file completions for load and set commands -complete \ - --command bitcoin-tx \ - --condition 'string match --regex -- "(load|set)=" (commandline -pt)' \ - --force-files diff --git a/contrib/completions/fish/bitcoin-util.fish b/contrib/completions/fish/bitcoin-util.fish deleted file mode 100644 index 0650bf2cb6d3..000000000000 --- a/contrib/completions/fish/bitcoin-util.fish +++ /dev/null @@ -1,38 +0,0 @@ -# Disable files from being included in completions by default -complete --command bitcoin-util --no-files - -# Extract options -function __fish_bitcoin_util_get_options - set --local cmd (commandline -opc)[1] - set --local options - - set --append options ($cmd -help 2>&1 | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=') - - for option in $options - echo $option - end -end - -# Extract commands -function __fish_bitcoin_util_get_commands - set --local cmd (commandline -opc)[1] - set --local commands - - set --append commands ($cmd -help | sed -e '1,/Commands:/d' -e 's/=/=\t/' -e 's/(=/=/' -e '/^ [a-z]/ p' -e d | string replace -r '\ \ ' '') - for command in $commands - echo $command - end -end - -# Add options -complete \ - --command bitcoin-util \ - --condition "not __fish_seen_subcommand_from (__fish_bitcoin_util_get_commands)" \ - --arguments "(__fish_bitcoin_util_get_options)" - -# Add commands -complete \ - --command bitcoin-util \ - --condition "not __fish_seen_subcommand_from (__fish_bitcoin_util_get_commands)" \ - --arguments "(__fish_bitcoin_util_get_commands)" - diff --git a/contrib/completions/fish/bitcoin-wallet.fish b/contrib/completions/fish/bitcoin-wallet.fish deleted file mode 100644 index 82d8277c9b4f..000000000000 --- a/contrib/completions/fish/bitcoin-wallet.fish +++ /dev/null @@ -1,35 +0,0 @@ -# Disable files from being included in completions by default -complete --command bitcoin-wallet --no-files - -# Extract options -function __fish_bitcoin_wallet_get_options - set --local cmd (commandline -opc)[1] - for option in ($cmd -help 2>&1 | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=') - echo $option - end -end - -# Extract commands -function __fish_bitcoin_wallet_get_commands - set --local cmd (commandline -opc)[1] - for command in ($cmd -help | sed -e '1,/Commands:/d' -e 's/=/=\t/' -e 's/(=/=/' -e '/^ [a-z]/ p' -e d | string replace -r '\ \ ' '') - echo $command - end -end - -# Add options -complete \ - --command bitcoin-wallet \ - --condition "not __fish_seen_subcommand_from (__fish_bitcoin_wallet_get_commands)" \ - --arguments "(__fish_bitcoin_wallet_get_options)" - -# Add commands -complete \ - --command bitcoin-wallet \ - --condition "not __fish_seen_subcommand_from (__fish_bitcoin_wallet_get_commands)" \ - --arguments "(__fish_bitcoin_wallet_get_commands)" - -# Add file completions for load and set commands -complete --command bitcoin-wallet \ - --condition "string match -r -- '(dumpfile|datadir)*=' (commandline -pt)" \ - --force-files diff --git a/contrib/completions/fish/bitcoind.fish b/contrib/completions/fish/bitcoind.fish deleted file mode 100644 index fa245ae17f47..000000000000 --- a/contrib/completions/fish/bitcoind.fish +++ /dev/null @@ -1,35 +0,0 @@ -# Disable files from being included in completions by default -complete --command bitcoind --no-files - -# Extract options -function __fish_bitcoind_get_options - argparse 'nofiles' -- $argv - set --local cmd (commandline -opc)[1] - set --local options - - if set -q _flag_nofiles - set --append options ($cmd -help-debug | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=' | string match --invert -r '^.*=$') - else - set --append options ($cmd -help-debug | string match -r '^ -.*' | string replace -r ' -' '-' | string replace -r '=.*' '=' | string match -r '^.*=$') - end - - for option in $options - echo $option - end -end - - -# Add options with file completion -complete \ - --command bitcoind \ - --arguments "(__fish_bitcoind_get_options)" -# Enable file completions only if the commandline now contains a `*.=` style option -complete --command bitcoind \ - --condition 'string match --regex -- ".*=" (commandline -pt)' \ - --force-files - -# Add options without file completion -complete \ - --command bitcoind \ - --arguments "(__fish_bitcoind_get_options --nofiles)" - diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 4e4deef9a1f8..296348ad38a7 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -4,106 +4,11 @@ Upstream-Contact: Satoshi Nakamoto irc://#bitcoin-core-dev@libera.chat Source: https://github.com/bitcoin/bitcoin -Files: * -Copyright: 2009-2025, Bitcoin Core Developers -License: Expat -Comment: The Bitcoin Core Developers encompasses all contributors to the - project, listed in the release notes or the git log. - Files: debian/* Copyright: 2010-2011, Jonas Smedegaard 2011, Matt Corallo License: GPL-2+ -Files: src/qt/res/icons/add.png - src/qt/res/icons/address-book.png - src/qt/res/icons/chevron.png - src/qt/res/icons/edit.png - src/qt/res/icons/editcopy.png - src/qt/res/icons/editpaste.png - src/qt/res/icons/export.png - src/qt/res/icons/eye.png - src/qt/res/icons/history.png - src/qt/res/icons/lock_*.png - src/qt/res/icons/overview.png - src/qt/res/icons/receive.png - src/qt/res/icons/remove.png - src/qt/res/icons/send.png - src/qt/res/icons/synced.png - src/qt/res/icons/transaction*.png - src/qt/res/icons/tx_output.png - src/qt/res/icons/warning.png -Copyright: Stephen Hutchings (and more) - http://typicons.com -License: Expat -Comment: Site: https://github.com/stephenhutchings/typicons.font - -Files: src/qt/res/icons/connect*.png - src/qt/res/src/connect-*.svg - src/qt/res/icons/network_disabled.png - src/qt/res/src/network_disabled.svg -Copyright: Marco Falke - Luke Dashjr -License: Expat -Comment: Inspired by Stephen Hutchings' Typicons - -Files: src/qt/res/icons/tx_mined.png - src/qt/res/src/mine.svg - src/qt/res/icons/fontbigger.png - src/qt/res/icons/fontsmaller.png - src/qt/res/icons/hd_disabled.png - src/qt/res/src/hd_disabled.svg - src/qt/res/icons/hd_enabled.png - src/qt/res/src/hd_enabled.svg -Copyright: Jonas Schnelli -License: Expat - -Files: src/qt/res/icons/clock*.png - src/qt/res/icons/eye_*.png - src/qt/res/icons/tx_in*.png - src/qt/res/src/clock_*.svg - src/qt/res/src/tx_*.svg -Copyright: Stephen Hutchings, Jonas Schnelli -License: Expat -Comment: Modifications of Stephen Hutchings' Typicons - -Files: src/qt/res/icons/bitcoin.* - share/pixmaps/bitcoin* - src/qt/res/src/bitcoin.svg -Copyright: Bitboy, Jonas Schnelli -License: public-domain -Comment: Site: https://bitcointalk.org/?topic=1756.0 - -Files: src/qt/res/icons/proxy.png - src/qt/res/src/proxy.svg -Copyright: Cristian Mircea Messel -License: public-domain - -Files: src/qt/res/fonts/RobotoMono-Bold.ttf -License: Apache-2.0 -Comment: Site: https://fonts.google.com/specimen/Roboto+Mono - - -License: Expat - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - . - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - License: GPL-2+ 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 diff --git a/contrib/devtools/check-deps.sh b/contrib/devtools/check-deps.sh index 5bde4398dda3..d149e9b92f56 100755 --- a/contrib/devtools/check-deps.sh +++ b/contrib/devtools/check-deps.sh @@ -5,32 +5,17 @@ set -Eeuo pipefail # Declare paths to libraries declare -A LIBS -LIBS[cli]="libbitcoin_cli.a" LIBS[common]="libbitcoin_common.a" LIBS[consensus]="libbitcoin_consensus.a" LIBS[crypto]="libbitcoin_crypto.a" -LIBS[node]="libbitcoin_node.a" -LIBS[util]="libbitcoin_util.a" -LIBS[wallet]="libbitcoin_wallet.a" # Declare allowed dependencies "X Y" where X is allowed to depend on Y. This # list is taken from doc/design/libraries.md. ALLOWED_DEPENDENCIES=( - "cli common" - "cli util" "common consensus" "common crypto" "common util" "consensus crypto" - "node common" - "node consensus" - "node crypto" - "node kernel" - "node util" - "util crypto" - "wallet common" - "wallet crypto" - "wallet util" ) # Add minor dependencies omitted from doc/design/libraries.md to keep the diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py index 12d7276455c5..ed5d51c22f11 100755 --- a/contrib/devtools/copyright_header.py +++ b/contrib/devtools/copyright_header.py @@ -16,12 +16,10 @@ EXCLUDE = [ # auto generated: - 'src/qt/bitcoinstrings.cpp', 'src/chainparamsseeds.h', # other external copyrights: 'src/test/fuzz/FuzzedDataProvider.h', 'src/tinyformat.h', - 'src/bench/nanobench.h', # python init: '*__init__.py', ] @@ -31,7 +29,6 @@ # git subtrees "src/crypto/ctaes/", "src/leveldb/", - "src/minisketch", "src/secp256k1/", "src/crc32c/", ] diff --git a/contrib/devtools/deterministic-unittest-coverage/src/main.rs b/contrib/devtools/deterministic-unittest-coverage/src/main.rs index 047c8d24eddc..88abc16c5494 100644 --- a/contrib/devtools/deterministic-unittest-coverage/src/main.rs +++ b/contrib/devtools/deterministic-unittest-coverage/src/main.rs @@ -61,7 +61,7 @@ fn app() -> AppResult { } let build_dir = Path::new(build_dir); - let test_exe = build_dir.join("bin/test_bitcoin"); + let test_exe = build_dir.join("bin/test_sv2"); sanity_check(&test_exe)?; diff --git a/contrib/devtools/gen-manpages.py b/contrib/devtools/gen-manpages.py index 0197a22f5e80..109af9c570a9 100755 --- a/contrib/devtools/gen-manpages.py +++ b/contrib/devtools/gen-manpages.py @@ -11,11 +11,8 @@ BINARIES = [ 'bin/bitcoind', 'bin/bitcoin-cli', -'bin/bitcoin-mine', -'bin/bitcoin-tx', -'bin/bitcoin-wallet', +'bin/sv2-tp', 'bin/bitcoin-util', -'bin/bitcoin-qt', ] parser = argparse.ArgumentParser( diff --git a/contrib/guix/README.md b/contrib/guix/README.md index 7f6b8232bba5..69a1a47c2fe0 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -76,8 +76,8 @@ crucial differences: 1. Since only Windows and macOS build outputs require codesigning, the `HOSTS` environment variable will have a sane default value of `x86_64-w64-mingw32 x86_64-apple-darwin arm64-apple-darwin` instead of all the platforms. -2. The `guix-codesign` command ***requires*** a `DETACHED_SIGS_REPO` flag. - * _**DETACHED_SIGS_REPO**_ +2. The `guix-codesign` command ***requires*** a `DETACHED_SIGS_REPO_SV2_TP` flag. + * _**DETACHED_SIGS_REPO_SV2_TP**_ Set the directory where detached codesignatures can be found for the current Bitcoin Core version being built. @@ -87,7 +87,7 @@ crucial differences: An invocation with all default options would look like: ``` -env DETACHED_SIGS_REPO= ./contrib/guix/guix-codesign +env DETACHED_SIGS_REPO_SV2_TP= ./contrib/guix/guix-codesign ``` ## Cleaning intermediate work directories @@ -106,15 +106,14 @@ worktree to save disk space: ## Attesting to build outputs -Much like how Gitian build outputs are attested to in a `gitian.sigs` -repository, Guix build outputs are attested to in the [`guix.sigs` -repository](https://github.com/bitcoin-core/guix.sigs). +Guix build outputs are attested to in the [`sv2-tp-guix.sigs` +repository](https://github.com/sjors/sv2-tp-guix.sigs). -After you've cloned the `guix.sigs` repository, to attest to the current +After you've cloned the `sv2-tp-guix.sigs` repository, to attest to the current worktree's commit/tag: ``` -env GUIX_SIGS_REPO= SIGNER= ./contrib/guix/guix-attest +env GUIX_SIGS_REPO_SV2_TP= SIGNER= ./contrib/guix/guix-attest ``` See `./contrib/guix/guix-attest --help` for more information on the various ways @@ -127,7 +126,7 @@ repository: ``` git -C pull -env GUIX_SIGS_REPO= ./contrib/guix/guix-verify +env GUIX_SIGS_REPO_SV2_TP= ./contrib/guix/guix-verify ``` diff --git a/contrib/guix/guix-attest b/contrib/guix/guix-attest index b0ef28dc3f92..7a395cbbeb67 100755 --- a/contrib/guix/guix-attest +++ b/contrib/guix/guix-attest @@ -39,26 +39,26 @@ cmd_usage() { cat < \\ + env GUIX_SIGS_REPO_SV2_TP= \\ SIGNER=GPG_KEY_NAME[=SIGNER_NAME] \\ [ NO_SIGN=1 ] ./contrib/guix/guix-attest Example w/o overriding signing name: - env GUIX_SIGS_REPO=/home/achow101/guix.sigs \\ + env GUIX_SIGS_REPO_SV2_TP=/home/achow101/guix.sigs \\ SIGNER=achow101 \\ ./contrib/guix/guix-attest Example overriding signing name: - env GUIX_SIGS_REPO=/home/dongcarl/guix.sigs \\ + env GUIX_SIGS_REPO_SV2_TP=/home/dongcarl/guix.sigs \\ SIGNER=0x96AB007F1A7ED999=dongcarl \\ ./contrib/guix/guix-attest Example w/o signing, just creating SHA256SUMS: - env GUIX_SIGS_REPO=/home/achow101/guix.sigs \\ + env GUIX_SIGS_REPO_SV2_TP=/home/achow101/guix.sigs \\ SIGNER=achow101 \\ NO_SIGN=1 \\ ./contrib/guix/guix-attest @@ -66,23 +66,23 @@ Example w/o signing, just creating SHA256SUMS: EOF } -if [ -z "$GUIX_SIGS_REPO" ] || [ -z "$SIGNER" ]; then +if [ -z "$GUIX_SIGS_REPO_SV2_TP" ] || [ -z "$SIGNER" ]; then cmd_usage exit 1 fi ################ -# GUIX_SIGS_REPO should exist as a directory +# GUIX_SIGS_REPO_SV2_TP should exist as a directory ################ -if [ ! -d "$GUIX_SIGS_REPO" ]; then +if [ ! -d "$GUIX_SIGS_REPO_SV2_TP" ]; then cat << EOF -ERR: The specified GUIX_SIGS_REPO is not an existent directory: +ERR: The specified GUIX_SIGS_REPO_SV2_TP is not an existent directory: - '$GUIX_SIGS_REPO' + '$GUIX_SIGS_REPO_SV2_TP' Hint: Please clone the guix.sigs repository and point to it with the - GUIX_SIGS_REPO environment variable. + GUIX_SIGS_REPO_SV2_TP environment variable. EOF cmd_usage @@ -182,7 +182,7 @@ basenameify_SHA256SUMS() { sed -E 's@(^[[:xdigit:]]{64}[[:space:]]+).+/([^/]+$)@\1\2@' } -outsigdir="$GUIX_SIGS_REPO/$VERSION/$signer_name" +outsigdir="$GUIX_SIGS_REPO_SV2_TP/$VERSION/$signer_name" mkdir -p "$outsigdir" ( cd "$outsigdir" diff --git a/contrib/guix/guix-codesign b/contrib/guix/guix-codesign index ac7aae3a1802..d75959e0ff32 100755 --- a/contrib/guix/guix-codesign +++ b/contrib/guix/guix-codesign @@ -28,13 +28,13 @@ cmd_usage() { cat < \\ + env DETACHED_SIGS_REPO_SV2_TP= \\ ./contrib/guix/guix-codesign EOF } -if [ -z "$DETACHED_SIGS_REPO" ]; then +if [ -z "$DETACHED_SIGS_REPO_SV2_TP" ]; then cmd_usage exit 1 fi @@ -77,7 +77,7 @@ check_source_date_epoch # The codesignature git worktree should not be dirty ################ -if ! git -C "$DETACHED_SIGS_REPO" diff-index --quiet HEAD -- && [ -z "$FORCE_DIRTY_WORKTREE" ]; then +if ! git -C "$DETACHED_SIGS_REPO_SV2_TP" diff-index --quiet HEAD -- && [ -z "$FORCE_DIRTY_WORKTREE" ]; then cat << EOF ERR: The DETACHED CODESIGNATURE git worktree is dirty, which may lead to broken builds. @@ -284,7 +284,7 @@ INFO: Codesigning ${VERSION:?not set} for platform triple ${HOST:?not set}: ...bind-mounted in container to: '$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$HOST")' ...outputting in: '$(outdir_for_host "$HOST" codesigned)' ...bind-mounted in container to: '$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST" codesigned)' - ...using detached signatures in: '${DETACHED_SIGS_REPO:?not set}' + ...using detached signatures in: '${DETACHED_SIGS_REPO_SV2_TP:?not set}' ...bind-mounted in container to: '/detached-sigs' EOF @@ -356,9 +356,9 @@ EOF --share="$PWD"=/bitcoin \ --share="$DISTSRC_BASE"=/distsrc-base \ --share="$OUTDIR_BASE"=/outdir-base \ - --share="$DETACHED_SIGS_REPO"=/detached-sigs \ + --share="$DETACHED_SIGS_REPO_SV2_TP"=/detached-sigs \ --expose="$(git rev-parse --git-common-dir)" \ - --expose="$(git -C "$DETACHED_SIGS_REPO" rev-parse --git-common-dir)" \ + --expose="$(git -C "$DETACHED_SIGS_REPO_SV2_TP" rev-parse --git-common-dir)" \ ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ --cores="$JOBS" \ --keep-failed \ @@ -376,7 +376,7 @@ EOF DISTSRC="$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$HOST")" \ OUTDIR="$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST" codesigned)" \ DIST_ARCHIVE_BASE=/outdir-base/dist-archive \ - DETACHED_SIGS_REPO=/detached-sigs \ + DETACHED_SIGS_REPO_SV2_TP=/detached-sigs \ CODESIGNING_TARBALL="$(OUTDIR_BASE=/outdir-base && codesigning_tarball_for_host "$HOST")" \ bash -c "cd /bitcoin && bash contrib/guix/libexec/codesign.sh" ) diff --git a/contrib/guix/guix-verify b/contrib/guix/guix-verify index 02ae022741ba..0e71a105ed34 100755 --- a/contrib/guix/guix-verify +++ b/contrib/guix/guix-verify @@ -28,32 +28,32 @@ cmd_usage() { cat < [ SIGNER= ] ./contrib/guix/guix-verify + env GUIX_SIGS_REPO_SV2_TP= [ SIGNER= ] ./contrib/guix/guix-verify Example overriding signer's manifest to use as base - env GUIX_SIGS_REPO=/home/dongcarl/guix.sigs SIGNER=achow101 ./contrib/guix/guix-verify + env GUIX_SIGS_REPO_SV2_TP=/home/dongcarl/guix.sigs SIGNER=achow101 ./contrib/guix/guix-verify EOF } -if [ -z "$GUIX_SIGS_REPO" ]; then +if [ -z "$GUIX_SIGS_REPO_SV2_TP" ]; then cmd_usage exit 1 fi ################ -# GUIX_SIGS_REPO should exist as a directory +# GUIX_SIGS_REPO_SV2_TP should exist as a directory ################ -if [ ! -d "$GUIX_SIGS_REPO" ]; then +if [ ! -d "$GUIX_SIGS_REPO_SV2_TP" ]; then cat << EOF -ERR: The specified GUIX_SIGS_REPO is not an existent directory: +ERR: The specified GUIX_SIGS_REPO_SV2_TP is not an existent directory: - '$GUIX_SIGS_REPO' + '$GUIX_SIGS_REPO_SV2_TP' Hint: Please clone the guix.sigs repository and point to it with the - GUIX_SIGS_REPO environment variable. + GUIX_SIGS_REPO_SV2_TP environment variable. EOF cmd_usage @@ -64,7 +64,7 @@ fi ## Verify ## ############## -OUTSIGDIR_BASE="${GUIX_SIGS_REPO}/${VERSION}" +OUTSIGDIR_BASE="${GUIX_SIGS_REPO_SV2_TP}/${VERSION}" echo "Looking for signature directories in '${OUTSIGDIR_BASE}'" echo "" diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 6b050a887b1a..9e4c8734291e 100755 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -74,7 +74,6 @@ build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include" build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include" case "$HOST" in - *darwin*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; # Required for qt/qmake *mingw*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; *) NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)" @@ -178,17 +177,8 @@ make -C depends --jobs="$JOBS" HOST="$HOST" \ x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \ x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \ x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \ - x86_64_linux_STRIP=x86_64-linux-gnu-strip \ - NO_QT=1 \ - NO_WALLET=1 \ - NO_ZMQ=1 + x86_64_linux_STRIP=x86_64-linux-gnu-strip -case "$HOST" in - *darwin*) - # Unset now that Qt is built - unset LIBRARY_PATH - ;; -esac ########################### # Source Tarball Building # @@ -208,10 +198,7 @@ mkdir -p "$OUTDIR" # Binary Tarball Building # ########################### -# TODO: once bitcoin-node with Mining interface is in a release: -# -DBUILD_CLI=OFF -# -DBUILD_DAEMON=OFF -CONFIGFLAGS="-DBUILD_UTIL=OFF -DBUILD_TX=OFF -DENABLE_WALLET=OFF -DENABLE_EXTERNAL_SIGNER=OFF -DWITH_USDT=OFF -DWITH_ZMQ=OFF -DREDUCE_EXPORTS=ON -DBUILD_BENCH=OFF -DBUILD_GUI_TESTS=OFF -DBUILD_FUZZ_BINARY=OFF" +CONFIGFLAGS="-DWITH_USDT=OFF -DREDUCE_EXPORTS=ON -DBUILD_FUZZ_BINARY=OFF" # CFLAGS HOST_CFLAGS="-O2 -g" @@ -264,7 +251,7 @@ mkdir -p "$DISTSRC" case "$HOST" in *mingw*) cmake --build build -j "$JOBS" -t deploy ${V:+--verbose} - mv build/bitcoin-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" + mv build/sv2-tp-win64-setup.exe "${OUTDIR}/${DISTNAME}-win64-setup-unsigned.exe" ;; esac @@ -309,12 +296,6 @@ mkdir -p "$DISTSRC" ;; esac - # copy over the example bitcoin.conf file. if contrib/devtools/gen-bitcoin-conf.sh - # has not been run before buildling, this file will be a stub - cp "${DISTSRC}/share/examples/bitcoin.conf" "${DISTNAME}/" - - cp -r "${DISTSRC}/share/rpcauth" "${DISTNAME}/share/" - # Deterministically produce {non-,}debug binary tarballs ready # for release case "$HOST" in diff --git a/contrib/guix/libexec/codesign.sh b/contrib/guix/libexec/codesign.sh index fe86065350e9..ca3363e9b94d 100755 --- a/contrib/guix/libexec/codesign.sh +++ b/contrib/guix/libexec/codesign.sh @@ -31,7 +31,7 @@ fi cat << EOF Required environment variables as seen inside the container: CODESIGNING_TARBALL: ${CODESIGNING_TARBALL:?not set} - DETACHED_SIGS_REPO: ${DETACHED_SIGS_REPO:?not set} + DETACHED_SIGS_REPO_SV2_TP: ${DETACHED_SIGS_REPO_SV2_TP:?not set} DIST_ARCHIVE_BASE: ${DIST_ARCHIVE_BASE:?not set} DISTNAME: ${DISTNAME:?not set} HOST: ${HOST:?not set} @@ -52,12 +52,12 @@ git_head_version() { fi } -CODESIGNATURE_GIT_ARCHIVE="${DIST_ARCHIVE_BASE}/${DISTNAME}-codesignatures-$(git_head_version "$DETACHED_SIGS_REPO").tar.gz" +CODESIGNATURE_GIT_ARCHIVE="${DIST_ARCHIVE_BASE}/${DISTNAME}-codesignatures-$(git_head_version "$DETACHED_SIGS_REPO_SV2_TP").tar.gz" # Create the codesignature tarball if not already there if [ ! -e "$CODESIGNATURE_GIT_ARCHIVE" ]; then mkdir -p "$(dirname "$CODESIGNATURE_GIT_ARCHIVE")" - git -C "$DETACHED_SIGS_REPO" archive --output="$CODESIGNATURE_GIT_ARCHIVE" HEAD + git -C "$DETACHED_SIGS_REPO_SV2_TP" archive --output="$CODESIGNATURE_GIT_ARCHIVE" HEAD fi mkdir -p "$OUTDIR" @@ -109,7 +109,6 @@ mkdir -p "$DISTSRC" esac # Apply detached codesignatures (in-place) - signapple apply dist/Bitcoin-Qt.app codesignatures/osx/"${HOST}"/dist/Bitcoin-Qt.app find "${DISTNAME}" \( -wholename "*/bin/*" -o -wholename "*/libexec/*" \) -type f | while read -r bin do signapple apply "${bin}" "codesignatures/osx/${HOST}/${bin}.${ARCH}sign" diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index d25c371a10c6..e8225f0ba763 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -86,7 +86,7 @@ time-machine() { ################ VERSION="${FORCE_VERSION:-$(git_head_version)}" -DISTNAME="${DISTNAME:-bitcoin-${VERSION}}" +DISTNAME="${DISTNAME:-sv2-tp-${VERSION}}" version_base_prefix="${PWD}/guix-build-" VERSION_BASE="${version_base_prefix}${VERSION}" # TOP diff --git a/contrib/guix/security-check.py b/contrib/guix/security-check.py index be2e0cfbe2af..28be49092229 100755 --- a/contrib/guix/security-check.py +++ b/contrib/guix/security-check.py @@ -81,7 +81,6 @@ def check_ELF_SEPARATE_CODE(binary): '.rodata': R, '.eh_frame_hdr': R, '.eh_frame': R, - '.qtmetadata': R, '.gcc_except_table': R, '.stapsdt.base': R, # Writable data diff --git a/contrib/guix/symbol-check.py b/contrib/guix/symbol-check.py index d808ef6becf1..89bceca61a36 100755 --- a/contrib/guix/symbol-check.py +++ b/contrib/guix/symbol-check.py @@ -41,7 +41,6 @@ lief.ELF.ARCH.RISCV: (2,31), }, 'LIBATOMIC': (1,0), -'V': (0,5,0), # xkb (bitcoin-qt only) } # Ignore symbols that are exported as part of every executable @@ -92,7 +91,7 @@ # Allowed NEEDED libraries ELF_ALLOWED_LIBRARIES = { -# bitcoind and bitcoin-qt +# bitcoind 'libgcc_s.so.1', # GCC base support 'libc.so.6', # C library 'libpthread.so.0', # threading @@ -105,50 +104,12 @@ 'ld64.so.1', # POWER64 ABIv1 dynamic linker 'ld64.so.2', # POWER64 ABIv2 dynamic linker 'ld-linux-riscv64-lp64d.so.1', # 64-bit RISC-V dynamic linker -# bitcoin-qt only -'libxcb.so.1', # part of X11 -'libxkbcommon.so.0', # keyboard keymapping -'libxkbcommon-x11.so.0', # keyboard keymapping -'libfontconfig.so.1', # font support -'libfreetype.so.6', # font parsing -'libdl.so.2', # programming interface to dynamic linker -'libxcb-cursor.so.0', -'libxcb-icccm.so.4', -'libxcb-image.so.0', -'libxcb-shm.so.0', -'libxcb-keysyms.so.1', -'libxcb-randr.so.0', -'libxcb-render-util.so.0', -'libxcb-render.so.0', -'libxcb-shape.so.0', -'libxcb-sync.so.1', -'libxcb-xfixes.so.0', -'libxcb-xkb.so.1', } MACHO_ALLOWED_LIBRARIES = { -# bitcoind and bitcoin-qt +# bitcoind 'libc++.1.dylib', # C++ Standard Library 'libSystem.B.dylib', # libc, libm, libpthread, libinfo -# bitcoin-qt only -'AppKit', # user interface -'ApplicationServices', # common application tasks. -'Carbon', # deprecated c back-compat API -'ColorSync', -'CoreFoundation', # low level func, data types -'CoreGraphics', # 2D rendering -'CoreServices', # operating system services -'CoreText', # interface for laying out text and handling fonts. -'CoreVideo', # video processing -'Foundation', # base layer functionality for apps/frameworks -'ImageIO', # read and write image file formats. -'IOKit', # user-space access to hardware devices and drivers. -'IOSurface', # cross process image/drawing buffers -'libobjc.A.dylib', # Objective-C runtime library -'Metal', # 3D graphics -'QuartzCore', # animation -'Security', # access control and authentication -'UniformTypeIdentifiers', # collection of types that map to MIME and file types } PE_ALLOWED_LIBRARIES = { @@ -159,32 +120,6 @@ 'msvcrt.dll', # C standard library for MSVC 'SHELL32.dll', # shell API 'WS2_32.dll', # sockets -# bitcoin-qt only -'api-ms-win-core-synch-l1-2-0.dll', # Synchronization Primitives API -'api-ms-win-core-winrt-l1-1-0.dll', # Windows Runtime API -'api-ms-win-core-winrt-string-l1-1-0.dll', # WinRT String API -'AUTHZ.dll', # Windows Authorization Framework -'comdlg32.dll', # Common Dialog Box Library -'d3d11.dll', # Direct3D 11 API -'d3d12.dll', # Direct3D 12 API -'d3d9.dll', # Direct3D 9 API -'dwmapi.dll', # desktop window manager -'DWrite.dll', # DirectX Typography Services -'dxgi.dll', # DirectX Graphics Infrastructure -'GDI32.dll', # graphics device interface -'IMM32.dll', # input method editor -'NETAPI32.dll', # network management -'ole32.dll', # component object model -'OLEAUT32.dll', # OLE Automation API -'SHLWAPI.dll', # light weight shell API -'USER32.dll', # user interface -'USERENV.dll', # user management -'UxTheme.dll', # visual style -'VERSION.dll', # version checking -'WINMM.dll', # WinMM audio API -'WTSAPI32.dll', # Remote Desktop -'SETUPAPI.dll', # Windows Setup API -'SHCORE.dll', # Stream Handler Core } def check_version(max_versions, version, arch) -> bool: diff --git a/contrib/linearize/README.md b/contrib/linearize/README.md deleted file mode 100644 index 25a1c7351a29..000000000000 --- a/contrib/linearize/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Linearize -Construct a linear, no-fork, best version of the Bitcoin blockchain. - -## Step 1: Download hash list - - $ ./linearize-hashes.py linearize.cfg > hashlist.txt - -Required configuration file settings for linearize-hashes: -* RPC: `datadir` (Required if `rpcuser` and `rpcpassword` are not specified) -* RPC: `rpcuser`, `rpcpassword` (Required if `datadir` is not specified) - -Optional config file setting for linearize-hashes: -* RPC: `host` (Default: `127.0.0.1`) -* RPC: `port` (Default: `8332`) -* Blockchain: `min_height`, `max_height` -* `rev_hash_bytes`: If true, the written block hash list will be -byte-reversed. (In other words, the hash returned by getblockhash will have its -bytes reversed.) False by default. Intended for generation of -standalone hash lists but safe to use with linearize-data.py, which will output -the same data no matter which byte format is chosen. - -The `linearize-hashes` script requires a connection, local or remote, to a -JSON-RPC server. Running `bitcoind` or `bitcoin-qt -server` will be sufficient. - -## Step 2: Copy local block data - - $ ./linearize-data.py linearize.cfg - -Required configuration file settings: -* `output_file`: The file that will contain the final blockchain. - or -* `output`: Output directory for linearized `blocks/blkNNNNN.dat` output. - -Optional config file setting for linearize-data: -* `debug_output`: Some printouts may not always be desired. If true, such output -will be printed. -* `file_timestamp`: Set each file's last-accessed and last-modified times, -respectively, to the current time and to the timestamp of the most recent block -written to the script's blockchain. -* `genesis`: The hash of the genesis block in the blockchain. -* `input`: bitcoind blocks/ directory containing blkNNNNN.dat -* `hashlist`: text file containing list of block hashes created by -linearize-hashes.py. -* `max_out_sz`: Maximum size for files created by the `output_file` option. -(Default: `1000*1000*1000 bytes`) -* `netmagic`: Network magic number. -* `out_of_order_cache_sz`: If out-of-order blocks are being read, the block can -be written to a cache so that the blockchain doesn't have to be sought again. -This option specifies the cache size. (Default: `100*1000*1000 bytes`) -* `rev_hash_bytes`: If true, the block hash list written by linearize-hashes.py -will be byte-reversed when read by linearize-data.py. See the linearize-hashes -entry for more information. -* `split_timestamp`: Split blockchain files when a new month is first seen, in -addition to reaching a maximum file size (`max_out_sz`). diff --git a/contrib/linearize/example-linearize.cfg b/contrib/linearize/example-linearize.cfg deleted file mode 100644 index 5f566261ca67..000000000000 --- a/contrib/linearize/example-linearize.cfg +++ /dev/null @@ -1,63 +0,0 @@ -# bitcoind RPC settings (linearize-hashes) -rpcuser=someuser -rpcpassword=somepassword -#datadir=~/.bitcoin -host=127.0.0.1 - -#mainnet default -port=8332 - -#testnet default -#port=18332 - -#regtest default -#port=18443 - -#signet default -#port=38332 - -# bootstrap.dat hashlist settings (linearize-hashes) -max_height=313000 - -# bootstrap.dat input/output settings (linearize-data) - -# mainnet -netmagic=f9beb4d9 -genesis=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f -input=/home/example/.bitcoin/blocks - -# testnet -#netmagic=0b110907 -#genesis=000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 -#input=/home/example/.bitcoin/testnet3/blocks - -# regtest -#netmagic=fabfb5da -#genesis=0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206 -#input=/home/example/.bitcoin/regtest/blocks - -# signet -#netmagic=0a03cf40 -#genesis=00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6 -#input=/home/example/.bitcoin/signet/blocks - -# "output" option causes blockchain files to be written to the given location, -# with "output_file" ignored. If not used, "output_file" is used instead. -# output=/home/example/blockchain_directory -output_file=/home/example/Downloads/bootstrap.dat -hashlist=hashlist.txt - -# Maximum size in bytes of out-of-order blocks cache in memory -out_of_order_cache_sz = 100000000 - -# Do we want the reverse the hash bytes coming from getblockhash? -rev_hash_bytes = False - -# On a new month, do we want to set the access and modify times of the new -# blockchain file? -file_timestamp = 0 -# Do we want to split the blockchain files given a new month or specific height? -split_timestamp = 0 - -# Do we want debug printouts? -debug_output = False diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py deleted file mode 100755 index 74d98307056e..000000000000 --- a/contrib/linearize/linearize-data.py +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/env python3 -# -# linearize-data.py: Construct a linear, no-fork version of the chain. -# -# Copyright (c) 2013-2022 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -# - -import struct -import re -import os -import os.path -import sys -import hashlib -import datetime -import time -import glob -from collections import namedtuple - -settings = {} - -def calc_hash_str(blk_hdr): - blk_hdr_hash = hashlib.sha256(hashlib.sha256(blk_hdr).digest()).digest() - return blk_hdr_hash[::-1].hex() - -def get_blk_dt(blk_hdr): - members = struct.unpack(" self.maxOutSz): - self.outF.close() - if self.setFileTime: - os.utime(self.outFname, (int(time.time()), self.highTS)) - self.outF = None - self.outFname = None - self.outFn = self.outFn + 1 - self.outsz = 0 - - (blkDate, blkTS) = get_blk_dt(blk_hdr) - if self.timestampSplit and (blkDate > self.lastDate): - print("New month " + blkDate.strftime("%Y-%m") + " @ " + self.hash_str) - self.lastDate = blkDate - if self.outF: - self.outF.close() - if self.setFileTime: - os.utime(self.outFname, (int(time.time()), self.highTS)) - self.outF = None - self.outFname = None - self.outFn = self.outFn + 1 - self.outsz = 0 - - if not self.outF: - if self.fileOutput: - self.outFname = self.settings['output_file'] - else: - self.outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn) - print("Output file " + self.outFname) - self.outF = open(self.outFname, "wb") - - self.outF.write(inhdr) - self.outF.write(blk_hdr) - self.outF.write(rawblock) - self.outsz = self.outsz + len(inhdr) + len(blk_hdr) + len(rawblock) - - self.blkCountOut = self.blkCountOut + 1 - if blkTS > self.highTS: - self.highTS = blkTS - - if (self.blkCountOut % 1000) == 0: - print('%i blocks scanned, %i blocks written (of %i, %.1f%% complete)' % - (self.blkCountIn, self.blkCountOut, len(self.blkindex), 100.0 * self.blkCountOut / len(self.blkindex))) - - def inFileName(self, fn): - return os.path.join(self.settings['input'], "blk%05d.dat" % fn) - - def fetchBlock(self, extent): - '''Fetch block contents from disk given extents''' - with open(self.inFileName(extent.fn), "rb") as f: - f.seek(extent.offset) - return self.read_xored(f, extent.size) - - def copyOneBlock(self): - '''Find the next block to be written in the input, and copy it to the output.''' - extent = self.blockExtents.pop(self.blkCountOut) - if self.blkCountOut in self.outOfOrderData: - # If the data is cached, use it from memory and remove from the cache - rawblock = self.outOfOrderData.pop(self.blkCountOut) - self.outOfOrderSize -= len(rawblock) - else: # Otherwise look up data on disk - rawblock = self.fetchBlock(extent) - - self.writeBlock(extent.inhdr, extent.blkhdr, rawblock) - - def run(self): - while self.blkCountOut < len(self.blkindex): - if not self.inF: - fname = self.inFileName(self.inFn) - print("Input file " + fname) - try: - self.inF = open(fname, "rb") - except IOError: - print("Premature end of block data") - return - - inhdr = self.read_xored(self.inF, 8) - if (not inhdr or (inhdr[0] == "\0")): - self.inF.close() - self.inF = None - self.inFn = self.inFn + 1 - continue - - inMagic = inhdr[:4] - if (inMagic != self.settings['netmagic']): - # Seek backwards 7 bytes (skipping the first byte in the previous search) - # and continue searching from the new position if the magic bytes are not - # found. - self.inF.seek(-7, os.SEEK_CUR) - continue - inLenLE = inhdr[4:] - su = struct.unpack(" -# -# 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 3 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, see . -# - -import sys, re, os, platform, shutil, stat, subprocess, os.path -from argparse import ArgumentParser -from pathlib import Path -from subprocess import PIPE, run -from typing import Optional - -# This is ported from the original macdeployqt with modifications - -class FrameworkInfo(object): - def __init__(self): - self.frameworkDirectory = "" - self.frameworkName = "" - self.frameworkPath = "" - self.binaryDirectory = "" - self.binaryName = "" - self.binaryPath = "" - self.version = "" - self.installName = "" - self.deployedInstallName = "" - self.sourceFilePath = "" - self.destinationDirectory = "" - self.sourceResourcesDirectory = "" - self.sourceVersionContentsDirectory = "" - self.sourceContentsDirectory = "" - self.destinationResourcesDirectory = "" - self.destinationVersionContentsDirectory = "" - - def __eq__(self, other): - if self.__class__ == other.__class__: - return self.__dict__ == other.__dict__ - else: - return False - - def __str__(self): - return f""" Framework name: {self.frameworkName} - Framework directory: {self.frameworkDirectory} - Framework path: {self.frameworkPath} - Binary name: {self.binaryName} - Binary directory: {self.binaryDirectory} - Binary path: {self.binaryPath} - Version: {self.version} - Install name: {self.installName} - Deployed install name: {self.deployedInstallName} - Source file Path: {self.sourceFilePath} - Deployed Directory (relative to bundle): {self.destinationDirectory} -""" - - def isDylib(self): - return self.frameworkName.endswith(".dylib") - - def isQtFramework(self): - if self.isDylib(): - return self.frameworkName.startswith("libQt") - else: - return self.frameworkName.startswith("Qt") - - reOLine = re.compile(r'^(.+) \(compatibility version [0-9.]+, current version [0-9.]+\)$') - bundleFrameworkDirectory = "Contents/Frameworks" - bundleBinaryDirectory = "Contents/MacOS" - - @classmethod - def fromLibraryLine(cls, line: str) -> Optional['FrameworkInfo']: - # Note: line must be trimmed - if line == "": - return None - - # Don't deploy system libraries - if line.startswith("/System/Library/") or line.startswith("@executable_path") or line.startswith("/usr/lib/"): - return None - - m = cls.reOLine.match(line) - if m is None: - raise RuntimeError(f"Line could not be parsed: {line}") - - path = m.group(1) - - info = cls() - info.sourceFilePath = path - info.installName = path - - if path.endswith(".dylib"): - dirname, filename = os.path.split(path) - info.frameworkName = filename - info.frameworkDirectory = dirname - info.frameworkPath = path - - info.binaryDirectory = dirname - info.binaryName = filename - info.binaryPath = path - info.version = "-" - - info.installName = path - info.deployedInstallName = f"@executable_path/../Frameworks/{info.binaryName}" - info.sourceFilePath = path - info.destinationDirectory = cls.bundleFrameworkDirectory - else: - parts = path.split("/") - i = 0 - # Search for the .framework directory - for part in parts: - if part.endswith(".framework"): - break - i += 1 - if i == len(parts): - raise RuntimeError(f"Could not find .framework or .dylib in line: {line}") - - info.frameworkName = parts[i] - info.frameworkDirectory = "/".join(parts[:i]) - info.frameworkPath = os.path.join(info.frameworkDirectory, info.frameworkName) - - info.binaryName = parts[i+3] - info.binaryDirectory = "/".join(parts[i+1:i+3]) - info.binaryPath = os.path.join(info.binaryDirectory, info.binaryName) - info.version = parts[i+2] - - info.deployedInstallName = f"@executable_path/../Frameworks/{os.path.join(info.frameworkName, info.binaryPath)}" - info.destinationDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, info.binaryDirectory) - - info.sourceResourcesDirectory = os.path.join(info.frameworkPath, "Resources") - info.sourceContentsDirectory = os.path.join(info.frameworkPath, "Contents") - info.sourceVersionContentsDirectory = os.path.join(info.frameworkPath, "Versions", info.version, "Contents") - info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources") - info.destinationVersionContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Versions", info.version, "Contents") - - return info - -class ApplicationBundleInfo(object): - def __init__(self, path: str): - self.path = path - # for backwards compatibility reasons, this must remain as Bitcoin-Qt - self.binaryPath = os.path.join(path, "Contents", "MacOS", "Bitcoin-Qt") - if not os.path.exists(self.binaryPath): - raise RuntimeError(f"Could not find bundle binary for {path}") - self.resourcesPath = os.path.join(path, "Contents", "Resources") - self.pluginPath = os.path.join(path, "Contents", "PlugIns") - -class DeploymentInfo(object): - def __init__(self): - self.qtPath = None - self.pluginPath = None - self.deployedFrameworks = [] - - def detectQtPath(self, frameworkDirectory: str): - parentDir = os.path.dirname(frameworkDirectory) - if os.path.exists(os.path.join(parentDir, "share", "qt", "translations")): - self.qtPath = parentDir - else: - self.qtPath = os.getenv("QTDIR", None) - - if self.qtPath is not None: - pluginPath = os.path.join(self.qtPath, "share", "qt", "plugins") - if os.path.exists(pluginPath): - self.pluginPath = pluginPath - - def usesFramework(self, name: str) -> bool: - for framework in self.deployedFrameworks: - if framework.endswith(".framework"): - if framework.startswith(f"{name}."): - return True - elif framework.endswith(".dylib"): - if framework.startswith(f"lib{name}."): - return True - return False - -def getFrameworks(binaryPath: str, verbose: int, rpath: str = '') -> list[FrameworkInfo]: - objdump = os.getenv("OBJDUMP", "objdump") - if verbose: - print(f"Inspecting with {objdump}: {binaryPath}") - output = run([objdump, "--macho", "--dylibs-used", binaryPath], stdout=PIPE, stderr=PIPE, text=True) - if output.returncode != 0: - sys.stderr.write(output.stderr) - sys.stderr.flush() - raise RuntimeError(f"{objdump} failed with return code {output.returncode}") - - lines = output.stdout.split("\n") - lines.pop(0) # First line is the inspected binary - if ".framework" in binaryPath or binaryPath.endswith(".dylib"): - lines.pop(0) # Frameworks and dylibs list themselves as a dependency. - - libraries = [] - for line in lines: - line = line.replace("@loader_path", os.path.dirname(binaryPath)) - if rpath: - line = line.replace("@rpath", rpath) - info = FrameworkInfo.fromLibraryLine(line.strip()) - if info is not None: - if verbose: - print("Found framework:") - print(info) - libraries.append(info) - - return libraries - -def runInstallNameTool(action: str, *args): - installnametoolbin=os.getenv("INSTALL_NAME_TOOL", "install_name_tool") - run([installnametoolbin, "-"+action] + list(args), check=True) - -def changeInstallName(oldName: str, newName: str, binaryPath: str, verbose: int): - if verbose: - print("Using install_name_tool:") - print(" in", binaryPath) - print(" change reference", oldName) - print(" to", newName) - runInstallNameTool("change", oldName, newName, binaryPath) - -def changeIdentification(id: str, binaryPath: str, verbose: int): - if verbose: - print("Using install_name_tool:") - print(" change identification in", binaryPath) - print(" to", id) - runInstallNameTool("id", id, binaryPath) - -def runStrip(binaryPath: str, verbose: int): - stripbin=os.getenv("STRIP", "strip") - if verbose: - print("Using strip:") - print(" stripped", binaryPath) - run([stripbin, "-x", binaryPath], check=True) - -def copyFramework(framework: FrameworkInfo, path: str, verbose: int) -> Optional[str]: - if framework.sourceFilePath.startswith("Qt"): - #standard place for Nokia Qt installer's frameworks - fromPath = f"/Library/Frameworks/{framework.sourceFilePath}" - else: - fromPath = framework.sourceFilePath - toDir = os.path.join(path, framework.destinationDirectory) - toPath = os.path.join(toDir, framework.binaryName) - - if framework.isDylib(): - if not os.path.exists(fromPath): - raise RuntimeError(f"No file at {fromPath}") - - if os.path.exists(toPath): - return None # Already there - - if not os.path.exists(toDir): - os.makedirs(toDir) - - shutil.copy2(fromPath, toPath) - if verbose: - print("Copied:", fromPath) - print(" to:", toPath) - else: - to_dir = os.path.join(path, "Contents", "Frameworks", framework.frameworkName) - if os.path.exists(to_dir): - return None # Already there - - from_dir = framework.frameworkPath - if not os.path.exists(from_dir): - raise RuntimeError(f"No directory at {from_dir}") - - shutil.copytree(from_dir, to_dir, symlinks=True) - if verbose: - print("Copied:", from_dir) - print(" to:", to_dir) - - headers_link = os.path.join(to_dir, "Headers") - if os.path.exists(headers_link): - os.unlink(headers_link) - - headers_dir = os.path.join(to_dir, framework.binaryDirectory, "Headers") - if os.path.exists(headers_dir): - shutil.rmtree(headers_dir) - - permissions = os.stat(toPath) - if not permissions.st_mode & stat.S_IWRITE: - os.chmod(toPath, permissions.st_mode | stat.S_IWRITE) - - return toPath - -def deployFrameworks(frameworks: list[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo: - if deploymentInfo is None: - deploymentInfo = DeploymentInfo() - - while len(frameworks) > 0: - framework = frameworks.pop(0) - deploymentInfo.deployedFrameworks.append(framework.frameworkName) - - print("Processing", framework.frameworkName, "...") - - # Get the Qt path from one of the Qt frameworks - if deploymentInfo.qtPath is None and framework.isQtFramework(): - deploymentInfo.detectQtPath(framework.frameworkDirectory) - - if framework.installName.startswith("@executable_path") or framework.installName.startswith(bundlePath): - print(framework.frameworkName, "already deployed, skipping.") - continue - - # install_name_tool the new id into the binary - changeInstallName(framework.installName, framework.deployedInstallName, binaryPath, verbose) - - # Copy framework to app bundle. - deployedBinaryPath = copyFramework(framework, bundlePath, verbose) - # Skip the rest if already was deployed. - if deployedBinaryPath is None: - continue - - if strip: - runStrip(deployedBinaryPath, verbose) - - # install_name_tool it a new id. - changeIdentification(framework.deployedInstallName, deployedBinaryPath, verbose) - # Check for framework dependencies - dependencies = getFrameworks(deployedBinaryPath, verbose, rpath=framework.frameworkDirectory) - - for dependency in dependencies: - changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath, verbose) - - # Deploy framework if necessary. - if dependency.frameworkName not in deploymentInfo.deployedFrameworks and dependency not in frameworks: - frameworks.append(dependency) - - return deploymentInfo - -def deployFrameworksForAppBundle(applicationBundle: ApplicationBundleInfo, strip: bool, verbose: int) -> DeploymentInfo: - frameworks = getFrameworks(applicationBundle.binaryPath, verbose) - if len(frameworks) == 0: - print(f"Warning: Could not find any external frameworks to deploy in {applicationBundle.path}.") - return DeploymentInfo() - else: - return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) - -def deployPlugins(appBundleInfo: ApplicationBundleInfo, deploymentInfo: DeploymentInfo, strip: bool, verbose: int): - plugins = [] - if deploymentInfo.pluginPath is None: - return - for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath): - pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath) - - if pluginDirectory not in ['styles', 'platforms']: - continue - - for pluginName in filenames: - pluginPath = os.path.join(pluginDirectory, pluginName) - - if pluginName.split('.')[0] not in ['libqminimal', 'libqcocoa', 'libqmacstyle']: - continue - - plugins.append((pluginDirectory, pluginName)) - - for pluginDirectory, pluginName in plugins: - print("Processing plugin", os.path.join(pluginDirectory, pluginName), "...") - - sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName) - destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory) - if not os.path.exists(destinationDirectory): - os.makedirs(destinationDirectory) - - destinationPath = os.path.join(destinationDirectory, pluginName) - shutil.copy2(sourcePath, destinationPath) - if verbose: - print("Copied:", sourcePath) - print(" to:", destinationPath) - - if strip: - runStrip(destinationPath, verbose) - - dependencies = getFrameworks(destinationPath, verbose) - - for dependency in dependencies: - changeInstallName(dependency.installName, dependency.deployedInstallName, destinationPath, verbose) - - # Deploy framework if necessary. - if dependency.frameworkName not in deploymentInfo.deployedFrameworks: - deployFrameworks([dependency], appBundleInfo.path, destinationPath, strip, verbose, deploymentInfo) - -ap = ArgumentParser(description="""Improved version of macdeployqt. - -Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .zip file. -Note, that the "dist" folder will be deleted before deploying on each run. - -Optionally, Qt translation files (.qm) can be added to the bundle.""") - -ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed") -ap.add_argument("appname", nargs=1, metavar="appname", help="name of the app being deployed") -ap.add_argument("-verbose", nargs="?", const=True, help="Output additional debugging information") -ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment") -ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries") -ap.add_argument("-translations-dir", nargs=1, metavar="path", default=None, help="Path to Qt's translations. Base translations will automatically be added to the bundle's resources.") -ap.add_argument("-zip", nargs="?", const="", metavar="zip", help="create a .zip containing the app bundle") - -config = ap.parse_args() - -verbose = config.verbose - -# ------------------------------------------------ - -app_bundle = config.app_bundle[0] -appname = config.appname[0] - -if not os.path.exists(app_bundle): - sys.stderr.write(f"Error: Could not find app bundle \"{app_bundle}\"\n") - sys.exit(1) - -# ------------------------------------------------ - -if os.path.exists("dist"): - print("+ Removing existing dist folder +") - shutil.rmtree("dist") - -if os.path.exists(appname + ".zip"): - print("+ Removing existing .zip +") - os.unlink(appname + ".zip") - -# ------------------------------------------------ - -target = os.path.join("dist", "Bitcoin-Qt.app") - -print("+ Copying source bundle +") -if verbose: - print(app_bundle, "->", target) - -os.mkdir("dist") -shutil.copytree(app_bundle, target, symlinks=True) - -applicationBundle = ApplicationBundleInfo(target) - -# ------------------------------------------------ - -print("+ Deploying frameworks +") - -try: - deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose) - if deploymentInfo.qtPath is None: - deploymentInfo.qtPath = os.getenv("QTDIR", None) - if deploymentInfo.qtPath is None: - sys.stderr.write("Warning: Could not detect Qt's path, skipping plugin deployment!\n") - config.plugins = False -except RuntimeError as e: - sys.stderr.write(f"Error: {str(e)}\n") - sys.exit(1) - -# ------------------------------------------------ - -if config.plugins: - print("+ Deploying plugins +") - - try: - deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose) - except RuntimeError as e: - sys.stderr.write(f"Error: {str(e)}\n") - sys.exit(1) - -# ------------------------------------------------ - -if config.translations_dir: - if not Path(config.translations_dir[0]).exists(): - sys.stderr.write(f"Error: Could not find translation dir \"{config.translations_dir[0]}\"\n") - sys.exit(1) - -print("+ Adding Qt translations +") - -translations = Path(config.translations_dir[0]) - -regex = re.compile('qt_[a-z]*(.qm|_[A-Z]*.qm)') - -lang_files = [x for x in translations.iterdir() if regex.match(x.name)] - -for file in lang_files: - if verbose: - print(file.as_posix(), "->", os.path.join(applicationBundle.resourcesPath, file.name)) - shutil.copy2(file.as_posix(), os.path.join(applicationBundle.resourcesPath, file.name)) - -# ------------------------------------------------ - -print("+ Installing qt.conf +") - -qt_conf="""[Paths] -Translations=Resources -Plugins=PlugIns -""" - -with open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") as f: - f.write(qt_conf.encode()) - -# ------------------------------------------------ - -if platform.system() == "Darwin": - subprocess.check_call(f"codesign --deep --force --sign - {target}", shell=True) - -# ------------------------------------------------ - -if config.zip is not None: - shutil.make_archive('{}'.format(appname), format='zip', root_dir='dist', base_dir='Bitcoin-Qt.app') - -# ------------------------------------------------ - -print("+ Done +") - -sys.exit(0) diff --git a/contrib/message-capture/message-capture-docs.md b/contrib/message-capture/message-capture-docs.md deleted file mode 100644 index 730196846134..000000000000 --- a/contrib/message-capture/message-capture-docs.md +++ /dev/null @@ -1,25 +0,0 @@ -# Per-Peer Message Capture - -## Purpose - -This feature allows for message capture on a per-peer basis. It answers the simple question: "Can I see what messages my node is sending and receiving?" - -## Usage and Functionality - -* Run `bitcoind` with the `-capturemessages` option. -* Look in the `message_capture` folder in your datadir. - * Typically this will be `~/.bitcoin/message_capture`. - * See that there are many folders inside, one for each peer names with its IP address and port. - * Inside each peer's folder there are two `.dat` files: one is for received messages (`msgs_recv.dat`) and the other is for sent messages (`msgs_sent.dat`). -* Run `contrib/message-capture/message-capture-parser.py` with the proper arguments. - * See the `-h` option for help. - * To see all messages, both sent and received, for all peers use: - ``` - ./contrib/message-capture/message-capture-parser.py -o out.json \ - ~/.bitcoin/message_capture/**/*.dat - ``` - * Note: The messages in the given `.dat` files will be interleaved in chronological order. So, giving both received and sent `.dat` files (as above with `*.dat`) will result in all messages being interleaved in chronological order. - * If an output file is not provided (i.e. the `-o` option is not used), then the output prints to `stdout`. -* View the resulting output. - * The output file is `JSON` formatted. - * Suggestion: use `jq` to view the output, with `jq . out.json` diff --git a/contrib/message-capture/message-capture-parser.py b/contrib/message-capture/message-capture-parser.py deleted file mode 100755 index 0f409717d4c8..000000000000 --- a/contrib/message-capture/message-capture-parser.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2020-2022 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Parse message capture binary files. To be used in conjunction with -capturemessages.""" - -import argparse -import os -import shutil -import sys -from io import BytesIO -import json -from pathlib import Path -from typing import Any, Optional - -sys.path.append(os.path.join(os.path.dirname(__file__), '../../test/functional')) - -from test_framework.messages import ser_uint256 # noqa: E402 -from test_framework.p2p import MESSAGEMAP # noqa: E402 - -TIME_SIZE = 8 -LENGTH_SIZE = 4 -MSGTYPE_SIZE = 12 - -# The test framework classes stores hashes as large ints in many cases. -# These are variables of type uint256 in core. -# There isn't a way to distinguish between a large int and a large int that is actually a blob of bytes. -# As such, they are itemized here. -# Any variables with these names that are of type int are actually uint256 variables. -# (These can be easily found by looking for calls to deser_uint256, deser_uint256_vector, and uint256_from_str in messages.py) -HASH_INTS = [ - "blockhash", - "block_hash", - "hash", - "hashMerkleRoot", - "hashPrevBlock", - "hashstop", - "prev_header", - "sha256", - "stop_hash", -] - -HASH_INT_VECTORS = [ - "hashes", - "headers", - "vHave", - "vHash", -] - - -class ProgressBar: - def __init__(self, total: float): - self.total = total - self.running = 0 - - def set_progress(self, progress: float): - cols = shutil.get_terminal_size()[0] - if cols <= 12: - return - max_blocks = cols - 9 - num_blocks = int(max_blocks * progress) - print('\r[ {}{} ] {:3.0f}%' - .format('#' * num_blocks, - ' ' * (max_blocks - num_blocks), - progress * 100), - end ='') - - def update(self, more: float): - self.running += more - self.set_progress(self.running / self.total) - - -def to_jsonable(obj: Any) -> Any: - if hasattr(obj, "__dict__"): - return obj.__dict__ - elif hasattr(obj, "__slots__"): - ret = {} # type: Any - for slot in obj.__slots__: - val = getattr(obj, slot, None) - if slot in HASH_INTS and isinstance(val, int): - ret[slot] = ser_uint256(val).hex() - elif slot in HASH_INT_VECTORS and all(isinstance(a, int) for a in val): - ret[slot] = [ser_uint256(a).hex() for a in val] - else: - ret[slot] = to_jsonable(val) - return ret - elif isinstance(obj, list): - return [to_jsonable(a) for a in obj] - elif isinstance(obj, bytes): - return obj.hex() - else: - return obj - - -def process_file(path: str, messages: list[Any], recv: bool, progress_bar: Optional[ProgressBar]) -> None: - with open(path, 'rb') as f_in: - if progress_bar: - bytes_read = 0 - - while True: - if progress_bar: - # Update progress bar - diff = f_in.tell() - bytes_read - 1 - progress_bar.update(diff) - bytes_read = f_in.tell() - 1 - - # Read the Header - tmp_header_raw = f_in.read(TIME_SIZE + LENGTH_SIZE + MSGTYPE_SIZE) - if not tmp_header_raw: - break - tmp_header = BytesIO(tmp_header_raw) - time = int.from_bytes(tmp_header.read(TIME_SIZE), "little") # type: int - msgtype = tmp_header.read(MSGTYPE_SIZE).split(b'\x00', 1)[0] # type: bytes - length = int.from_bytes(tmp_header.read(LENGTH_SIZE), "little") # type: int - - # Start converting the message to a dictionary - msg_dict = {} - msg_dict["direction"] = "recv" if recv else "sent" - msg_dict["time"] = time - msg_dict["size"] = length # "size" is less readable here, but more readable in the output - - msg_ser = BytesIO(f_in.read(length)) - - # Determine message type - if msgtype not in MESSAGEMAP: - # Unrecognized message type - try: - msgtype_tmp = msgtype.decode() - if not msgtype_tmp.isprintable(): - raise UnicodeDecodeError - msg_dict["msgtype"] = msgtype_tmp - except UnicodeDecodeError: - msg_dict["msgtype"] = "UNREADABLE" - msg_dict["body"] = msg_ser.read().hex() - msg_dict["error"] = "Unrecognized message type." - messages.append(msg_dict) - print(f"WARNING - Unrecognized message type {msgtype} in {path}", file=sys.stderr) - continue - - # Deserialize the message - msg = MESSAGEMAP[msgtype]() - msg_dict["msgtype"] = msgtype.decode() - - try: - msg.deserialize(msg_ser) - except KeyboardInterrupt: - raise - except Exception: - # Unable to deserialize message body - msg_ser.seek(0, os.SEEK_SET) - msg_dict["body"] = msg_ser.read().hex() - msg_dict["error"] = "Unable to deserialize message." - messages.append(msg_dict) - print(f"WARNING - Unable to deserialize message in {path}", file=sys.stderr) - continue - - # Convert body of message into a jsonable object - if length: - msg_dict["body"] = to_jsonable(msg) - messages.append(msg_dict) - - if progress_bar: - # Update the progress bar to the end of the current file - # in case we exited the loop early - f_in.seek(0, os.SEEK_END) # Go to end of file - diff = f_in.tell() - bytes_read - 1 - progress_bar.update(diff) - - -def main(): - parser = argparse.ArgumentParser( - description=__doc__, - epilog="EXAMPLE \n\t{0} -o out.json /message_capture/**/*.dat".format(sys.argv[0]), - formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument( - "capturepaths", - nargs='+', - help="binary message capture files to parse.") - parser.add_argument( - "-o", "--output", - help="output file. If unset print to stdout") - parser.add_argument( - "-n", "--no-progress-bar", - action='store_true', - help="disable the progress bar. Automatically set if the output is not a terminal") - args = parser.parse_args() - capturepaths = [Path.cwd() / Path(capturepath) for capturepath in args.capturepaths] - output = Path.cwd() / Path(args.output) if args.output else False - use_progress_bar = (not args.no_progress_bar) and sys.stdout.isatty() - - messages = [] # type: list[Any] - if use_progress_bar: - total_size = sum(capture.stat().st_size for capture in capturepaths) - progress_bar = ProgressBar(total_size) - else: - progress_bar = None - - for capture in capturepaths: - process_file(str(capture), messages, "recv" in capture.stem, progress_bar) - - messages.sort(key=lambda msg: msg['time']) - - if use_progress_bar: - progress_bar.set_progress(1) - - jsonrep = json.dumps(messages) - if output: - with open(str(output), 'w+', encoding="utf8") as f_out: - f_out.write(jsonrep) - else: - print(jsonrep) - -if __name__ == "__main__": - main() diff --git a/contrib/qos/README.md b/contrib/qos/README.md deleted file mode 100644 index 0ded87c58f4e..000000000000 --- a/contrib/qos/README.md +++ /dev/null @@ -1,5 +0,0 @@ -### QoS (Quality of service) ### - -This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitcoin network. It limits outbound TCP traffic with a source or destination port of 8333, but not if the destination IP is within a LAN. - -This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it. diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh deleted file mode 100755 index 7ebcbf225175..000000000000 --- a/contrib/qos/tc.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2017-2021 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -export LC_ALL=C -#network interface on which to limit traffic -IF="eth0" -#limit of the network interface in question -LINKCEIL="1gbit" -#limit outbound Bitcoin protocol traffic to this rate -LIMIT="160kbit" -#defines the IPv4 address space for which you wish to disable rate limiting -LOCALNET_V4="192.168.0.0/16" -#defines the IPv6 address space for which you wish to disable rate limiting -LOCALNET_V6="fe80::/10" - -#delete existing rules ('Error: Cannot delete qdisc with handle of zero.' means there weren't any.) -tc qdisc del dev ${IF} root - -#add root class -tc qdisc add dev ${IF} root handle 1: htb default 10 - -#add parent class -tc class add dev ${IF} parent 1: classid 1:1 htb rate ${LINKCEIL} ceil ${LINKCEIL} - -#add our two classes. one unlimited, another limited -tc class add dev ${IF} parent 1:1 classid 1:10 htb rate ${LINKCEIL} ceil ${LINKCEIL} prio 0 -tc class add dev ${IF} parent 1:1 classid 1:11 htb rate ${LIMIT} ceil ${LIMIT} prio 1 - -#add handles to our classes so packets marked with go into the class with "... handle fw ..." -tc filter add dev ${IF} parent 1: protocol ip prio 1 handle 1 fw classid 1:10 -tc filter add dev ${IF} parent 1: protocol ip prio 2 handle 2 fw classid 1:11 - -if [ -n "${LOCALNET_V6}" ] ; then - # v6 cannot have the same priority value as v4 - tc filter add dev ${IF} parent 1: protocol ipv6 prio 3 handle 1 fw classid 1:10 - tc filter add dev ${IF} parent 1: protocol ipv6 prio 4 handle 2 fw classid 1:11 -fi - -#delete any existing rules -#disable for now -#ret=0 -#while [ $ret -eq 0 ]; do -# iptables -t mangle -D OUTPUT 1 -# ret=$? -#done - -#limit outgoing traffic to and from port 8333. but not when dealing with a host on the local network -# (defined by $LOCALNET_V4 and $LOCALNET_V6) -# --set-mark marks packages matching these criteria with the number "2" (v4) -# --set-mark marks packages matching these criteria with the number "4" (v6) -# these packets are filtered by the tc filter with "handle 2" -# this filter sends the packages into the 1:11 class, and this class is limited to ${LIMIT} -iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET_V4} -j MARK --set-mark 0x2 -iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET_V4} -j MARK --set-mark 0x2 - -if [ -n "${LOCALNET_V6}" ] ; then - ip6tables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET_V6} -j MARK --set-mark 0x4 - ip6tables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET_V6} -j MARK --set-mark 0x4 -fi diff --git a/contrib/seeds/.gitignore b/contrib/seeds/.gitignore deleted file mode 100644 index e62dd99de64c..000000000000 --- a/contrib/seeds/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -seeds_main.txt -seeds_signet.txt -seeds_test.txt -seeds_testnet4.txt -asmap-filled.dat diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md deleted file mode 100644 index a1a2e34b5de3..000000000000 --- a/contrib/seeds/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# Seeds - -Utility to generate the seeds.txt list that is compiled into the client -(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and other utilities in [contrib/seeds](/contrib/seeds)). - -Be sure to update `PATTERN_AGENT` in `makeseeds.py` to include the current version, -and remove old versions as necessary (at a minimum when SeedsServiceFlags() -changes its default return value, as those are the services which seeds are added -to addrman with). - -Update `MIN_BLOCKS` in `makeseeds.py` and the `-m`/`--minblocks` arguments below, as needed. - -The seeds compiled into the release are created from sipa's, achow101's and luke-jr's -DNS seed, virtu's crawler, and asmap community AS map data. Run the following commands -from the `/contrib/seeds` directory: - -``` -curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt -curl https://21.ninja/seeds.txt.gz | gzip -dc >> seeds_main.txt -curl https://luke.dashjr.org/programs/bitcoin/files/charts/seeds.txt >> seeds_main.txt -curl https://mainnet.achownodes.xyz/seeds.txt.gz | gzip -dc >> seeds_main.txt -curl https://signet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_signet.txt -curl https://testnet.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_test.txt -curl https://testnet4.achownodes.xyz/seeds.txt.gz | gzip -dc > seeds_testnet4.txt -curl https://raw.githubusercontent.com/asmap/asmap-data/main/latest_asmap.dat > asmap-filled.dat -python3 makeseeds.py -a asmap-filled.dat -s seeds_main.txt > nodes_main.txt -python3 makeseeds.py -a asmap-filled.dat -s seeds_signet.txt -m 237800 > nodes_signet.txt -python3 makeseeds.py -a asmap-filled.dat -s seeds_test.txt > nodes_test.txt -python3 makeseeds.py -a asmap-filled.dat -s seeds_testnet4.txt -m 72600 > nodes_testnet4.txt -python3 generate-seeds.py . > ../../src/chainparamsseeds.h -``` diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py deleted file mode 100755 index a3ce01225190..000000000000 --- a/contrib/seeds/generate-seeds.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2014-2021 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -''' -Script to generate list of seed nodes for kernel/chainparams.cpp. - -This script expects three text files in the directory that is passed as an -argument: - - nodes_main.txt - nodes_signet.txt - nodes_test.txt - nodes_testnet4.txt - -These files must consist of lines in the format - - : - []: - .onion: - .b32.i2p: - -The output will be several data structures with the peers in binary format: - - static const uint8_t chainparams_seed_{main,signet,test,testnet4}[]={ - ... - } - -These should be pasted into `src/chainparamsseeds.h`. -''' - -from base64 import b32decode -from enum import Enum -import sys -import os -import re - -class BIP155Network(Enum): - IPV4 = 1 - IPV6 = 2 - TORV2 = 3 # no longer supported - TORV3 = 4 - I2P = 5 - CJDNS = 6 - -def name_to_bip155(addr): - '''Convert address string to BIP155 (networkID, addr) tuple.''' - if addr.endswith('.onion'): - vchAddr = b32decode(addr[0:-6], True) - if len(vchAddr) == 35: - assert vchAddr[34] == 3 - return (BIP155Network.TORV3, vchAddr[:32]) - elif len(vchAddr) == 10: - return (BIP155Network.TORV2, vchAddr) - else: - raise ValueError('Invalid onion %s' % vchAddr) - elif addr.endswith('.b32.i2p'): - vchAddr = b32decode(addr[0:-8] + '====', True) - if len(vchAddr) == 32: - return (BIP155Network.I2P, vchAddr) - else: - raise ValueError(f'Invalid I2P {vchAddr}') - elif '.' in addr: # IPv4 - return (BIP155Network.IPV4, bytes((int(x) for x in addr.split('.')))) - elif ':' in addr: # IPv6 or CJDNS - sub = [[], []] # prefix, suffix - x = 0 - addr = addr.split(':') - for i,comp in enumerate(addr): - if comp == '': - if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end - continue - x += 1 # :: skips to suffix - assert x < 2 - else: # two bytes per component - val = int(comp, 16) - sub[x].append(val >> 8) - sub[x].append(val & 0xff) - nullbytes = 16 - len(sub[0]) - len(sub[1]) - assert (x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0) - addr_bytes = bytes(sub[0] + ([0] * nullbytes) + sub[1]) - if addr_bytes[0] == 0xfc: - # Assume that seeds with fc00::/8 addresses belong to CJDNS, - # not to the publicly unroutable "Unique Local Unicast" network, see - # RFC4193: https://datatracker.ietf.org/doc/html/rfc4193#section-8 - return (BIP155Network.CJDNS, addr_bytes) - else: - return (BIP155Network.IPV6, addr_bytes) - else: - raise ValueError('Could not parse address %s' % addr) - -def parse_spec(s): - '''Convert endpoint string to BIP155 (networkID, addr, port) tuple.''' - match = re.match(r'\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s) - if match: # ipv6 - host = match.group(1) - port = match.group(2) - elif s.count(':') > 1: # ipv6, no port - host = s - port = '' - else: - (host,_,port) = s.partition(':') - - if not port: - port = 0 - else: - port = int(port) - - host = name_to_bip155(host) - - if host[0] == BIP155Network.TORV2: - return None # TORV2 is no longer supported, so we ignore it - else: - return host + (port, ) - -def ser_compact_size(l): - r = b"" - if l < 253: - r = l.to_bytes(1, "little") - elif l < 0x10000: - r = (253).to_bytes(1, "little") + l.to_bytes(2, "little") - elif l < 0x100000000: - r = (254).to_bytes(1, "little") + l.to_bytes(4, "little") - else: - r = (255).to_bytes(1, "little") + l.to_bytes(8, "little") - return r - -def bip155_serialize(spec): - ''' - Serialize (networkID, addr, port) tuple to BIP155 binary format. - ''' - r = b"" - r += spec[0].value.to_bytes(1, "little") - r += ser_compact_size(len(spec[1])) - r += spec[1] - r += spec[2].to_bytes(2, "big") - return r - -def process_nodes(g, f, structname): - g.write('static const uint8_t %s[] = {\n' % structname) - for line in f: - comment = line.find('#') - if comment != -1: - line = line[0:comment] - line = line.strip() - if not line: - continue - - spec = parse_spec(line) - if spec is None: # ignore this entry (e.g. no longer supported addresses like TORV2) - continue - blob = bip155_serialize(spec) - hoststr = ','.join(('0x%02x' % b) for b in blob) - g.write(f' {hoststr},\n') - g.write('};\n') - -def main(): - if len(sys.argv)<2: - print(('Usage: %s ' % sys.argv[0]), file=sys.stderr) - sys.exit(1) - g = sys.stdout - indir = sys.argv[1] - g.write('#ifndef BITCOIN_CHAINPARAMSSEEDS_H\n') - g.write('#define BITCOIN_CHAINPARAMSSEEDS_H\n') - g.write('/**\n') - g.write(' * List of fixed seed nodes for the bitcoin network\n') - g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n') - g.write(' *\n') - g.write(' * Each line contains a BIP155 serialized (networkID, addr, port) tuple.\n') - g.write(' */\n') - with open(os.path.join(indir,'nodes_main.txt'), 'r', encoding="utf8") as f: - process_nodes(g, f, 'chainparams_seed_main') - g.write('\n') - with open(os.path.join(indir,'nodes_signet.txt'), 'r', encoding="utf8") as f: - process_nodes(g, f, 'chainparams_seed_signet') - g.write('\n') - with open(os.path.join(indir,'nodes_test.txt'), 'r', encoding="utf8") as f: - process_nodes(g, f, 'chainparams_seed_test') - g.write('\n') - with open(os.path.join(indir,'nodes_testnet4.txt'), 'r', encoding="utf8") as f: - process_nodes(g, f, 'chainparams_seed_testnet4') - g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n') - -if __name__ == '__main__': - main() diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py deleted file mode 100755 index da6efe70873c..000000000000 --- a/contrib/seeds/makeseeds.py +++ /dev/null @@ -1,266 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2013-2022 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -# -# Generate seeds.txt from Pieter's DNS seeder -# - -import argparse -import collections -import ipaddress -from pathlib import Path -import random -import re -import sys -from typing import Union - -asmap_dir = Path(__file__).parent.parent / "asmap" -sys.path.append(str(asmap_dir)) -from asmap import ASMap, net_to_prefix # noqa: E402 - -NSEEDS=512 - -MAX_SEEDS_PER_ASN = { - 'ipv4': 2, - 'ipv6': 10, -} - -MIN_BLOCKS = 868000 - -PATTERN_IPV4 = re.compile(r"^(([0-2]?\d{1,2})\.([0-2]?\d{1,2})\.([0-2]?\d{1,2})\.([0-2]?\d{1,2})):(\d{1,5})$") -PATTERN_IPV6 = re.compile(r"^\[([\da-f:]+)]:(\d{1,5})$", re.IGNORECASE) -PATTERN_ONION = re.compile(r"^([a-z2-7]{56}\.onion):(\d+)$") -PATTERN_I2P = re.compile(r"^([a-z2-7]{52}\.b32\.i2p):(\d{1,5})$") -PATTERN_AGENT = re.compile( - r"^/Satoshi:(" - r"0\.14\.(0|1|2|3|99)" - r"|0\.15\.(0|1|2|99)" - r"|0\.16\.(0|1|2|3|99)" - r"|0\.17\.(0|0\.1|1|2|99)" - r"|0\.18\.(0|1|99)" - r"|0\.19\.(0|1|2|99)" - r"|0\.20\.(0|1|2|99)" - r"|0\.21\.(0|1|2|99)" - r"|22\.(0|1|99)\.0" - r"|23\.(0|1|2|99)\.0" - r"|24\.(0|1|2|99)\.(0|1)" - r"|25\.(0|1|2|99)\.0" - r"|26\.(0|1|2|99)\.0" - r"|27\.(0|1|2|99)\.0" - r"|28\.(0|1|99)\.0" - r")") - -def parseline(line: str) -> Union[dict, None]: - """ Parses a line from `seeds_main.txt` into a dictionary of details for that line. - or `None`, if the line could not be parsed. - """ - if line.startswith('#'): - # Ignore line that starts with comment - return None - sline = line.split() - if len(sline) < 11: - # line too short to be valid, skip it. - return None - # Skip bad results. - if int(sline[1]) == 0: - return None - m = PATTERN_IPV4.match(sline[0]) - sortkey = None - ip = None - if m is None: - m = PATTERN_IPV6.match(sline[0]) - if m is None: - m = PATTERN_ONION.match(sline[0]) - if m is None: - m = PATTERN_I2P.match(sline[0]) - if m is None: - return None - else: - net = 'i2p' - ipstr = sortkey = m.group(1) - port = int(m.group(2)) - else: - net = 'onion' - ipstr = sortkey = m.group(1) - port = int(m.group(2)) - else: - net = 'ipv6' - if m.group(1) in ['::']: # Not interested in localhost - return None - ipstr = m.group(1) - if ipstr.startswith("fc"): # cjdns looks like ipv6 but always begins with fc - net = "cjdns" - sortkey = ipstr # XXX parse IPv6 into number, could use name_to_ipv6 from generate-seeds - port = int(m.group(2)) - else: - # Do IPv4 sanity check - ip = 0 - for i in range(0,4): - if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255: - return None - ip = ip + (int(m.group(i+2)) << (8*(3-i))) - if ip == 0: - return None - net = 'ipv4' - sortkey = ip - ipstr = m.group(1) - port = int(m.group(6)) - # Extract uptime %. - uptime30 = float(sline[7][:-1]) - # Extract Unix timestamp of last success. - lastsuccess = int(sline[2]) - # Extract protocol version. - version = int(sline[10]) - # Extract user agent. - agent = sline[11][1:-1] - # Extract service flags. - service = int(sline[9], 16) - # Extract blocks. - blocks = int(sline[8]) - # Construct result. - return { - 'net': net, - 'ip': ipstr, - 'port': port, - 'ipnum': ip, - 'uptime': uptime30, - 'lastsuccess': lastsuccess, - 'version': version, - 'agent': agent, - 'service': service, - 'blocks': blocks, - 'sortkey': sortkey, - } - -def dedup(ips: list[dict]) -> list[dict]: - """ Remove duplicates from `ips` where multiple ips share address and port. """ - d = {} - for ip in ips: - d[ip['ip'],ip['port']] = ip - return list(d.values()) - -def filtermultiport(ips: list[dict]) -> list[dict]: - """ Filter out hosts with more nodes per IP""" - hist = collections.defaultdict(list) - for ip in ips: - hist[ip['sortkey']].append(ip) - return [value[0] for (key,value) in list(hist.items()) if len(value)==1] - -# Based on Greg Maxwell's seed_filter.py -def filterbyasn(asmap: ASMap, ips: list[dict], max_per_asn: dict, max_per_net: int) -> list[dict]: - """ Prunes `ips` by - (a) trimming ips to have at most `max_per_net` ips from each net (e.g. ipv4, ipv6); and - (b) trimming ips to have at most `max_per_asn` ips from each asn in each net. - """ - # Sift out ips by type - ips_ipv46 = [ip for ip in ips if ip['net'] in ['ipv4', 'ipv6']] - ips_onion = [ip for ip in ips if ip['net'] == 'onion'] - ips_i2p = [ip for ip in ips if ip['net'] == 'i2p'] - ips_cjdns = [ip for ip in ips if ip["net"] == "cjdns"] - - # Filter IPv46 by ASN, and limit to max_per_net per network - result = [] - net_count: dict[str, int] = collections.defaultdict(int) - asn_count: dict[int, int] = collections.defaultdict(int) - - for i, ip in enumerate(ips_ipv46): - if net_count[ip['net']] == max_per_net: - # do not add this ip as we already too many - # ips from this network - continue - asn = asmap.lookup(net_to_prefix(ipaddress.ip_network(ip['ip']))) - if not asn or asn_count[ip['net'], asn] == max_per_asn[ip['net']]: - # do not add this ip as we already have too many - # ips from this ASN on this network - continue - asn_count[ip['net'], asn] += 1 - net_count[ip['net']] += 1 - ip['asn'] = asn - result.append(ip) - - # Add back Onions (up to max_per_net) - result.extend(ips_onion[0:max_per_net]) - result.extend(ips_i2p[0:max_per_net]) - result.extend(ips_cjdns[0:max_per_net]) - return result - -def ip_stats(ips: list[dict]) -> str: - """ Format and return pretty string from `ips`. """ - hist: dict[str, int] = collections.defaultdict(int) - for ip in ips: - if ip is not None: - hist[ip['net']] += 1 - - return f"{hist['ipv4']:6d} {hist['ipv6']:6d} {hist['onion']:6d} {hist['i2p']:6d} {hist['cjdns']:6d}" - -def parse_args(): - argparser = argparse.ArgumentParser(description='Generate a list of bitcoin node seed ip addresses.') - argparser.add_argument("-a","--asmap", help='the location of the asmap asn database file (required)', required=True) - argparser.add_argument("-s","--seeds", help='the location of the DNS seeds file (required)', required=True) - argparser.add_argument("-m", "--minblocks", help="The minimum number of blocks each node must have", default=MIN_BLOCKS, type=int) - return argparser.parse_args() - -def main(): - args = parse_args() - - print(f'Loading asmap database "{args.asmap}"…', end='', file=sys.stderr, flush=True) - with open(args.asmap, 'rb') as f: - asmap = ASMap.from_binary(f.read()) - print('Done.', file=sys.stderr) - - print('Loading and parsing DNS seeds…', end='', file=sys.stderr, flush=True) - with open(args.seeds, 'r', encoding='utf8') as f: - lines = f.readlines() - ips = [parseline(line) for line in lines] - random.shuffle(ips) - print('Done.', file=sys.stderr) - - print('\x1b[7m IPv4 IPv6 Onion I2P CJDNS Pass \x1b[0m', file=sys.stderr) - print(f'{ip_stats(ips):s} Initial', file=sys.stderr) - # Skip entries with invalid address. - ips = [ip for ip in ips if ip is not None] - print(f'{ip_stats(ips):s} Skip entries with invalid address', file=sys.stderr) - # Skip duplicates (in case multiple seeds files were concatenated) - ips = dedup(ips) - print(f'{ip_stats(ips):s} After removing duplicates', file=sys.stderr) - # Enforce minimal number of blocks. - ips = [ip for ip in ips if ip['blocks'] >= args.minblocks] - print(f'{ip_stats(ips):s} Enforce minimal number of blocks', file=sys.stderr) - # Require service bit 1. - ips = [ip for ip in ips if (ip['service'] & 1) == 1] - print(f'{ip_stats(ips):s} Require service bit 1', file=sys.stderr) - # Require at least 50% 30-day uptime for clearnet, onion and i2p; 10% for cjdns - req_uptime = { - 'ipv4': 50, - 'ipv6': 50, - 'onion': 50, - 'i2p': 50, - 'cjdns': 10, - } - ips = [ip for ip in ips if ip['uptime'] > req_uptime[ip['net']]] - print(f'{ip_stats(ips):s} Require minimum uptime', file=sys.stderr) - # Require a known and recent user agent. - ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])] - print(f'{ip_stats(ips):s} Require a known and recent user agent', file=sys.stderr) - # Sort by availability (and use last success as tie breaker) - ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True) - # Filter out hosts with multiple bitcoin ports, these are likely abusive - ips = filtermultiport(ips) - print(f'{ip_stats(ips):s} Filter out hosts with multiple bitcoin ports', file=sys.stderr) - # Look up ASNs and limit results, both per ASN and globally. - ips = filterbyasn(asmap, ips, MAX_SEEDS_PER_ASN, NSEEDS) - print(f'{ip_stats(ips):s} Look up ASNs and limit results per ASN and per net', file=sys.stderr) - # Sort the results by IP address (for deterministic output). - ips.sort(key=lambda x: (x['net'], x['sortkey'])) - for ip in ips: - if ip['net'] == 'ipv6' or ip["net"] == "cjdns": - print(f"[{ip['ip']}]:{ip['port']}", end="") - else: - print(f"{ip['ip']}:{ip['port']}", end="") - if 'asn' in ip: - print(f" # AS{ip['asn']}", end="") - print() - -if __name__ == '__main__': - main() diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt deleted file mode 100644 index d839d3807de6..000000000000 --- a/contrib/seeds/nodes_main.txt +++ /dev/null @@ -1,2031 +0,0 @@ -[fc10:efa7:ca6:1548:f8c:6bb9:1cc4:63ae]:8333 -[fc1f:22c3:95dc:a3af:4a93:8251:beb9:1858]:8333 -[fc32:2c16:d0d0:f1fb:3b27:c187:8cb5:9201]:8333 -[fc70:de9d:7fe2:b32:5828:1a3c:d0f:83ec]:8333 -[fc77:89c1:cb33:b770:f92c:1eff:a60a:b1cb]:8333 -[fc95:6edb:af65:9ea3:cd27:21ef:f5e2:29c6]:8333 -[fca0:151:79ac:8992:b51e:bdc4:6ed9:41be]:8333 -[fcc7:be49:ccd1:dc91:3125:f0da:457d:8ce]:8333 -[fccb:248:11a6:1042:bca:1218:f7ce:7d3d]:8333 -[fcf1:22ff:3070:582f:a873:61bc:4bc1:81bf]:8333 -25rm76uae7qbj7dyrwxe5koi3eyp4pytzngnymgk2tm6m6ojzhma.b32.i2p:0 -2a4f3ac3rtweo5u5juqjdx63o4pytnpdr2ecnywjrdsd27pvvfwq.b32.i2p:0 -2cng4offkkneiw7xtfhvcgyu5rohy6ta4epowlrvnkbnuxfef3pq.b32.i2p:0 -2f6uzzetcurnwoioo65bgjjrhab3x5mgeacfojllwp77psjgwu7a.b32.i2p:0 -2hh75bmlo7nbwympmqjhtzoes7lxaxeph736i3vgrsq6uf3xkd3q.b32.i2p:0 -2ipe4z2l354zluvnxesjthdayd2n36qe4fuawqh64cetbufvagkq.b32.i2p:0 -2jgfxxzts6rfr5m2iwklltya2kmuejnkufpt4bavwjhi2j7fmyma.b32.i2p:0 -2k3lztzfal3k6dl7yrh2jykfa3xpmou2c7cm2ewo4qctkkvbhfvq.b32.i2p:0 -2lyuiflrruwnrvmlnsoxctsoez5bxsd7e7g766eamf4cw723wsxq.b32.i2p:0 -2muk57255tdm4g273fy7aitrmqnturut6krqojxz76jssrqm2rsa.b32.i2p:0 -2n23repkqxcbemx6vwl6wwkpel4xoezt6x6bissipxrz6dzijiaa.b32.i2p:0 -2ny6ifcupp7xx75a2anecwhih5kibumg2o3uqdk5j2ejn26jkv4q.b32.i2p:0 -2u6vnbkm3ofxqqzkxi5kynd55inreotaidt3dfca62fpgtxabdhq.b32.i2p:0 -2ucgg5wlvoxcas2o5lscp354ghcdwwpx5hadi3kcpr2p2pysk5ba.b32.i2p:0 -2v5nr3u3scbyxd3nkqxinw2pvqqe66y4hc3u6gotil2sgbyivruq.b32.i2p:0 -2wvq5am4tsc3ejeeunhhofp6tni244zkbqz7lbqjycjwcw7v6tva.b32.i2p:0 -2xygt6zbuiqvl2jdn2dlavjjzumqpwkgjawfosmhkaozwodcgl6a.b32.i2p:0 -3bghwmgjmsmpjevkvou3eldck2vvvvidykxvomn5kxfogmjwbxrq.b32.i2p:0 -3covklglzlod2sxmjtyq3rlzqd57kcfjricj27yyexg3rc2hroqa.b32.i2p:0 -3gfnwe3y6n55facql4jztmrg7slxif2vmbl3ygg44p2rno57yrwa.b32.i2p:0 -3lmii22nacqrs76rd2ixpgyudrchmyrkqqkigns2nk2gcffuv3da.b32.i2p:0 -3nbv3o7j6h3okg4orvk5zfhcjdjnwxuu3cdusqh2lqeeogv7uzsq.b32.i2p:0 -3q6nv6vg5aas7i5a457ckf46nfw4lyvipdagxlhujwczqzuvu77q.b32.i2p:0 -3rgwk2zwdo343z5gjxzddvig2ivr2htncvmqxmvkvlta27ceroca.b32.i2p:0 -3ru63xjzrqphkve5xw6ev3iharlzqs3rbp475yxnr5ma7bys6q7a.b32.i2p:0 -3slxqwc7rmmpnhv6dsk2spesbt77v2j25yoktwqztpnpnt2got4q.b32.i2p:0 -3t23wkj2tslzm7ytzoxzbdekf36yzno4wjllgil45j7qqlzv2dda.b32.i2p:0 -3y4oiw7cglzzshasapfmlte7ixbgpl4js7w2afsd4znemu4ddefa.b32.i2p:0 -44qgfpibsi7w7ulbg76yt5hyi33t6unleq7yifhbhdqdy5ihljyq.b32.i2p:0 -45eh6rxbfli4ju26cqaf63vfs5xx6zgt7hn3uzzz3nem45d4ps6q.b32.i2p:0 -46t7icqffks2db3utvtm7mbycopbcewpb2dihwfapdi2ukeke5pq.b32.i2p:0 -46xory66pc6qxd6glapmcrxujp6wc5swghhbnhybvewxffo37gaq.b32.i2p:0 -4ccr4ejpia2pn72d6xok5tubyb2gii7pjdqb4mwyl4c5wiwoysoq.b32.i2p:0 -4dde4fh6gybebhqtoiraoqjab2w3qn2ym4u36l6fdwmeb63ljm2q.b32.i2p:0 -4gdidscp3badfijfuesami5opqpz5ntjw2ephfdhb3i5bgrzzh2q.b32.i2p:0 -4imp5e6332cdcaoeqtuif7xymlwpmstgchotaoa5kuzgvc2wpqvq.b32.i2p:0 -4jh4w7ifveva6rh7l2nemqor4abako6qo7rdjq26lr6anfo6gbsa.b32.i2p:0 -4n2z2vlqzupmc46hh4eizoo2nhmcucmrggpiivdb3prswlnf3krq.b32.i2p:0 -4nxdyltgdwpfkautpralacdlolzlpwr43cj4ig4gozn5y43gk6nq.b32.i2p:0 -4ocs2dc2jkd2j3kedyjn6kmfvx7lkdrheu2n2wio5zv75sedzk6q.b32.i2p:0 -4ripix2seo5ac3bjb4a5louhtbycghyf3leysidy22wnbak7tzjq.b32.i2p:0 -4supe3vqjcq2pp55vdploz455wpwgmnjqgadlvtlteaxy6t437fq.b32.i2p:0 -4trblupsxprghxtsglv25zhy4ofxm3fwa4y7mmesso3x2fl2khwq.b32.i2p:0 -4unxgzwe2zlrfgivsl72b4z5he6jawedzuceu3usvlp7bcoj3c7q.b32.i2p:0 -4xpl5q7i5uu3yktqqaw7jaanmamwsgtxsdl23ds7nugh22lxsxjq.b32.i2p:0 -4z7l5ldbrcav7lv3u2a4hso7uaclug5yfcbeztqmmv5hyw6crdda.b32.i2p:0 -4zc3ku23mmbnkjvy6mcfgvgkxdoxzvioqnfvle3q6pmiuaixotfa.b32.i2p:0 -53utzmap3lyrl6m7ws5oo73rpc3y2dawcu43g7q7hkru5qx4djua.b32.i2p:0 -54h4pb62qkqott3do63jc3jflpt355n6gi5coad6fkkdvfir7jga.b32.i2p:0 -56xx7arua67o6gzmz7fisqsco3s5yx3mhz4g7dwp73nvjxx44idq.b32.i2p:0 -5dfgzcf3ccte7riwfodvefwhet3f4z6nubeln73q3qpyadbtekxa.b32.i2p:0 -5dx4sfe4huncxaflmwo5kzwgrbtvvptttu65fgjzquwl2vwizhtq.b32.i2p:0 -5kog73uwths255tdrwee7dc2pshq6xlukbxtpgn3bbwunm52jwdq.b32.i2p:0 -5on4kc5ev6pbv4ib53xcwhwve2d4agh5drzwuoqwvmrqv2czrjba.b32.i2p:0 -5pjaaexikmlyhl5dihzvqbykuec6uzkyujvvs5bjoi6htlb3oxzq.b32.i2p:0 -5puvvkyv6qr2kaqb2avbqxzhdyiquhk2767omhoa2s52gcnfcx4q.b32.i2p:0 -5pvqmsnbnldzogflte4nwyxpr6jn4x4rxmrbjcwjknwwz4255rkq.b32.i2p:0 -5qf5uwixbva3xzmrgl26k2bswq27ome6uurvhcea3i57rhz4lqgq.b32.i2p:0 -5qn7zzaxno6jogdskmjqlssi5k34ibkokcghts7vrfctb4vmc6uq.b32.i2p:0 -5xhyftag6e6hjwdosgffvkxk3fo5muk5vqbcxbithtjr6zg6vuwa.b32.i2p:0 -5yme5e7jmq73zsm4ap4agnkiwrupjagrybusvlyzemeek7lreswq.b32.i2p:0 -62cmrc6aio5blhc2rx5qgwai2urelcq2mtkl4jpprlyt6kihlbsa.b32.i2p:0 -62srw23f4rrxzs3253g7mb2lbop3pfpsu56g5iiptrao3qoasd4a.b32.i2p:0 -6cb5bbpnsnr4uxlkwtekxbg5qrwpvdqfpgncl46xndg3np4yfita.b32.i2p:0 -6dkvhlhwoiwpdjpebuemxq66soh6os6xa2sq42dwhfbp3d4sdzga.b32.i2p:0 -6mroga77egf2fzs7y46huhxwesppxx6k72jc7h2cznq2fmcaelsq.b32.i2p:0 -6rsbnc2njzfyppwcjlmpt4dxzndxe7scyc2vjzjvixlt6qebslwa.b32.i2p:0 -6ujb3xak7iformdm7xjpbzuyqzuu3tmdcngvhioqnzo4emcoxz3a.b32.i2p:0 -6v6jax64xiqf6dekptdqjwstuf63v2s5i6px3kn7camlji75ilzq.b32.i2p:0 -6vrjslktb4gtjx7uifoje5o4r5lsfasdcfbrnna6r56ruiaiowqa.b32.i2p:0 -6zsislqyaufihc6atpm3hnlo2uwewhnitnlzqzh7rsfgim3vt6gq.b32.i2p:0 -764xiwqk2izz4tylrba5urvqjo73q72yflkiubmruzpd2bib4pda.b32.i2p:0 -7djd7fbu66r6xwmisj6r2sfgcten7ovticj2zp4gvenhpbrokyiq.b32.i2p:0 -7fddpunmty7eruhumq2iqa2yw5ckcn6xpsw26pj6csnhnty3jcqa.b32.i2p:0 -7jwvx7eged34ctrgyrt5y6x5p7xzkfpidvwrxjplqywqa5dqlg3a.b32.i2p:0 -7lx7lr2taxmtbdx5sdqo2apwka3br7iig5mejzkxpw4ksvk524hq.b32.i2p:0 -7o3sndesp2d7mrkw3qlpfipknxddu4tz2l34hpymy3vexfyg27pq.b32.i2p:0 -7pmzb44ybjrq26wq24pdjz6tkktgwkyvvrpatmsbsx2xs3f6x43a.b32.i2p:0 -7rmw4miaffahgwpy42fnd324fhiq4dygn5denzxtik6gk3slhqra.b32.i2p:0 -7utc6ztzqaljtirabf3l5ynvf3akmzofayid4caia6nd6z6a2ebq.b32.i2p:0 -7vupqprsgbad6v2trw75e7kpk7vhmoyxqqlaxrkfwofg6qkfm3oa.b32.i2p:0 -7wgrywhskd24kqqjvodx6bxnjnv374xlnrwssy7zqd4wza5drqmq.b32.i2p:0 -7woh7qguyjfcmqu43k4hge6uehvfh5gdwel6ps2mjpdttml7iybq.b32.i2p:0 -7ykkgcm6pta4sywgl4klcvl4b6k4ucrxh3vw3s2umdpb7zejarjq.b32.i2p:0 -7zxl3ohprpqmnmsz72el5o2wqzs5ybc5ixie5i64ayvzhjbhe2bq.b32.i2p:0 -a2zioocy4z3jijn6qzl2grifqd7hvuk6kagjv5maoqrnxwoucdoq.b32.i2p:0 -a4ot6mtsfgtkciklj34r2zvkmxtbpg5ycint6zehehf7xtz2djka.b32.i2p:0 -a5gtxv444a52shcmjq5v4zkbmxfwn4o5ofqlyirhmr5goonrimvq.b32.i2p:0 -ab5xl3uj5rmagrwfwraocuinjthvb5f6wtstktlrjrlajnarteia.b32.i2p:0 -agd3ebr4tmkj5pnrukswh7luxk7bftdlngwvvntznc2rr5awkaqq.b32.i2p:0 -alwzfqb2uol3fu2tbmwy72kqxr243pwabg2g4mtaomvjetscckmq.b32.i2p:0 -ame7bnmodeayhxcsb4hh23ocakzaox4bm5mz6yfkpemhb26wpnuq.b32.i2p:0 -apiu52rucnbhji3q6qfxfbqdw35woslfpfm2kaca6mjobvrn4kpa.b32.i2p:0 -aqwcmdtqbg7g4b7kqpzpbkzoqhyy6epydjx276vgv2vg5kw2rywq.b32.i2p:0 -atyfkxoezxfmpmnbj4lmzhxtzaatiidv2exc7gzzm33brhapwwwa.b32.i2p:0 -awvhek2uj5fenn4scqhhdp5vuzg5vrrl7f3qasod7cy222iwb4iq.b32.i2p:0 -ayn7r3jdijhcl6t6gexmq45dw2tap2l67rn7xgoisaenkel74wha.b32.i2p:0 -azavco4tqpr375qqgan567lcmotlib6h7jjh3rboutrxax7u6haa.b32.i2p:0 -b36faeb2flnkg2tigqi7rxlnekwiljt25drgow2d4jvsruktqnaa.b32.i2p:0 -b3au442ynpqirynybrf22qowknc6leljlbq4xix5xjk2ehlkr2ha.b32.i2p:0 -bf2j2wma2oq2222heshaivpon6xud5fum3pzuuffgu3ddg7ss3ma.b32.i2p:0 -bipk7yyoxznzzs7tjyh2y7nieuph2gccf4x55vrci6w4aefbxlxa.b32.i2p:0 -bkmpto4dtnblvlqvyknp2fa2cfugse5u5oonoipd3qooizqdvbua.b32.i2p:0 -bnwgr4t47loftduanvx2rgcse7gls75b7zq5ydtlluesa6p3gxqq.b32.i2p:0 -bq56m3mk4w3q4fmh5vcrcxcusssmd7ygi4iyrazrhpbmjh4bnsja.b32.i2p:0 -bsiz6td65kdvoyx3d36w7ctinc6dkieasg6575dkotlpaxbplxzq.b32.i2p:0 -bsn5rlu4h3a4xpklhhymxorogxpdgudstloclzshghb4deiui3rq.b32.i2p:0 -bvqrib7iaoymm5oh3nkrfp2u6zfp3v3xgwp77jmvruj6hlulxi3a.b32.i2p:0 -bwq6y5u7jcx77ok4iqpjtiz5re4qagvhhlr3skhe3s4nphnrfhaa.b32.i2p:0 -bwsuwvghcfdegz2vg4vrrh4gqbs2yez6w6mzmct2gt6hyregfnga.b32.i2p:0 -byoucerid5rb2dducaqwepaytvkw4b4l2wmbfkbfgicflfcd4dta.b32.i2p:0 -c3xl7bimshx3o6oxwhq2jfmhmmmike2jbx5icugysmefwgs26n3a.b32.i2p:0 -c4rbwijavo6m4gj3sjo6jjwjdvmlmzml2mcagrbw6tqn3rixmdiq.b32.i2p:0 -c5az3bzjm47vsp7sps4yaltcifv2nvcolftvmnyiwrctrkwjjhma.b32.i2p:0 -c5ytdepbzhdrwn6ymkrk5a2ll3zkwpgk2la6ec7hs7ysvcxhf32a.b32.i2p:0 -c6sdbzckovbl7hd5bq5pfkkwc2xtdkx7b357bk3v4vdspzmy34cq.b32.i2p:0 -caqiocmm72yn5ymatzbeo3se25j7mhp33bd32xju463vr7ef2voa.b32.i2p:0 -carg765pk5ef25vhvpu7phus75yp2xmwf4juphulsksqrho5krsa.b32.i2p:0 -cazzdhgkd6ejtqu3hdh74cfnhq536ktrcnww7yq6lyjwd7ocs4iq.b32.i2p:0 -cgeb2ffbyjb56vhuder63aeswvhy6isvrhivwbxfaqcu4th5pj6a.b32.i2p:0 -chhqibkwshxl5afottq3f4qhtaw3esesunfc4xljqcjeqcht7d6q.b32.i2p:0 -cilepisotgs43xi6s7lwlahpxnp55qjti4dck7i2y3kicq7tmw7q.b32.i2p:0 -ciwvimts7zzoyrknhlowmzh35mzx4cluq7uycw3ffcckuov4tjjq.b32.i2p:0 -cjjktdv4wtr232f5jtw6rge6k2bmxbunelq236vqt2yte6jnqfkq.b32.i2p:0 -cjvo2dibbl2hapfbqnpqbcgfpzzwkpkojfac3zo4t7iiwuffjj4a.b32.i2p:0 -clqwslg6ijsxtydfzahhxymkx7oboofarzbzrzrla5mhtmpyvdvq.b32.i2p:0 -cmfgxulstg5trnmmssjvdrq5e7taqfta6jpuiqzakqujddhljs4a.b32.i2p:0 -cmnpbzyfif37aq2bncdtp2wankepsaxpvpexjpydwm6etufqseha.b32.i2p:0 -csq5rwmdv43eii7ohtywl4ou6kuewf5wb4nswifkfx2iri7fzdlq.b32.i2p:0 -cuktr7luziv3z44rh6ef75hl3atlfqcszodgjwqahgxsstaevvsa.b32.i2p:0 -cv4zl42obux6uk7ghxuujbwzl4kuaneruiq2gqmaksxqfcbnxjkq.b32.i2p:0 -cws3w5267jj34c4icoz2342dgbm66dr2gljqkeih7kh6e65r2z5a.b32.i2p:0 -cysjtseqmtwng3ty25dapg6gyzozmbzv43zqhg7abu3isjhmac4q.b32.i2p:0 -d3gmwp7tebwuagm6orga3hwhhuchp6kwsfcsdttittcssjhkshnq.b32.i2p:0 -d3udzfukxm3cm2ucd7oen3glvgtymah3r7wdndli7tl5e3xttswq.b32.i2p:0 -dclij7rdlmxclsasycgjtwczkksmjykzcqf5z4yvyhofichqyh5a.b32.i2p:0 -ddtuamdoynsa4r543psethu4ygfuwvcc7ftlb24ak2n35gnmekha.b32.i2p:0 -dfhkpobqzc4soif3kocu62sodohxekxmye5hybt7lr3agqu2k34a.b32.i2p:0 -dhci2k575bhvvi2pf45or4x3ts5csnm3yqzaff3t2tsx4mh2d76a.b32.i2p:0 -dioihjkfyyb4xgypkmfpdepzmrwoju5tc4v7bwmhcdrllnpg4hmq.b32.i2p:0 -diqahlv3xidi733dkqymddufa3ftlbxoxcgqmtvnrjs4kc5qzg7q.b32.i2p:0 -dllxsougtvwyyrhthsud4onw4q4jtpirzghofsuahpunr2pkfvya.b32.i2p:0 -dlz27nejbzcswguuwzgpv6efms3uaunximpnarc7djgjtqjlthlq.b32.i2p:0 -dmed6el2h56j5kno7xocalj6k7ehosyr2fbwcrk5yf62c3edcodq.b32.i2p:0 -do6y4lsrp2qzfenbmplla2shhysigcrdjuvb7b5rg2yuedjs2wra.b32.i2p:0 -dqr3ge73yw7ctie2vvfmowhwiywplwavkiozfttwop4sthhg6fcq.b32.i2p:0 -dqyiv5vbbxpvvzhg4z4s5d4ztjq3jeeafy7q53vuvv4gshfponoa.b32.i2p:0 -duawsbyorcgdipwpuvt3f3tmnyqs32xr7h2kzyjhct44vx5i67eq.b32.i2p:0 -dupayeh2uwvnmz2c3ti33x76zgnv2uf2rkp75kgdg3zjlyuv4xgq.b32.i2p:0 -dw7oovp44knhrikivfmt3hs2lz2trlpb7xout6dlinfnzxeac3sa.b32.i2p:0 -e6qoyaetj3zf5jmavn44avsjdynx6oc6lxdgxfsq2bq3zue4nyeq.b32.i2p:0 -ea57r6dh5gjumzc466khizfymzl4j6mxuq62t7kb7lnbp64lxpcq.b32.i2p:0 -ee75buofrqnhkjmvabyhfalbkz3sjg3p3wchl3wlaa4cz3ua4wka.b32.i2p:0 -eedgqvf6vrxdvporvfh3ihjizegyplk3buupvu6v3cbrmiplv6za.b32.i2p:0 -efopxval2cwm7fe2jxd2srg5bm23cf4q37bnydecszxdhflvcwpa.b32.i2p:0 -egweubjkn3bvp5ukk2qdtkvfuss6hmtc2pmtblmtyteu2ax4es2a.b32.i2p:0 -ejq34wotitjk7o5xmxdlx6zakrxchwwtk4vggpfpxx2abyacrh2q.b32.i2p:0 -emckeftl5wkd4mylivr3hrxphs775rpcq5s4jm4kxdaamc7luxlq.b32.i2p:0 -epzzk4ta5pn6ralqol4fp35j4gzjfvcjnmm2oefwazk2dki2246q.b32.i2p:0 -et5ndch6nw756ds2myh2ctvszhqek66j2y46xtnh3qz4m7nbmqea.b32.i2p:0 -etouz5h35ofnip445vwtffvtbl3qbvx4dfopf7ypscxhboeuy2yq.b32.i2p:0 -eubmbzk6rtpu3utz4crdwvm2jy564cywwwrw6dz7l2kfzvaiyuha.b32.i2p:0 -ev2ijxlza3gp26vxubheds4oxsimlvttrv2ezgnger44qpnpyoxa.b32.i2p:0 -f23v3vovpxxntn7xsm52uf6hzfngbmyhwbcdbtg2pqaoebag57tq.b32.i2p:0 -fae3tesbnlbnl4flz4hk7eud6axewuisklvw634nplv7ieeg457a.b32.i2p:0 -fbmglhmeasq3it5ziaow7pczmzlrbwavo726j7secd4wugakepmq.b32.i2p:0 -fd7npzmrpdkfsrsdytagsjpnzww6y5vgomxulnfpwbdiqup37yqa.b32.i2p:0 -fdraytuzmed622myazwpw2sg66xfq2pjhpplt2smi64dqv6qb3eq.b32.i2p:0 -fghecqp7tm3doc74vozr2qiddpo7j3kfzy2tu2nfckpoqss7qora.b32.i2p:0 -fh3yb7elyvnzmhxv2hap6ddqcym6lpfxafavkuhrrxk5sb3wshva.b32.i2p:0 -fnhesnhbix6ua26b5jpbieas7s5lglvusmruk3tciov3wyry4g2q.b32.i2p:0 -foc3ole3bfsxzz6sxufnwzhx72cijco6oefwggh6a7mx7kytbk3a.b32.i2p:0 -foyb2sneia3ygbbjozz4wszcaznztjbgkae4d52iskyxxzku2xra.b32.i2p:0 -fsdn2phijfbwo35ezvgtkzv4p7wp4ym3yfd72ucfcahnw524d22a.b32.i2p:0 -fwex73tw3ebsysv3sziu4pl3pmgkbdm32mc73uyiswlcx7btcf2q.b32.i2p:0 -fwiu4gd7i6da6gbslctxpetgkb7kz6bznemcsl7oy7f6aywmndvq.b32.i2p:0 -fzuoiirfzhnml7egyor6b3bzthptsioe6zuwe64mn4pktmi7c4la.b32.i2p:0 -g2ins5xhxtdd5m57rkopn2rm6mtr677ktmo26ymcrc2bz5v2igla.b32.i2p:0 -g2mv4wdsdd423imdpfq5dd4fsifa6evmvdmj2pccb2nqtfas7dza.b32.i2p:0 -g5ayhhbanipee5wyehvfsf5cuqn2djl6xvrcmuv2r7us6mrcl7da.b32.i2p:0 -g5eujubxvzwiovihiedokkb7uwheiqb674rfa2xijsyyr3sexiwq.b32.i2p:0 -g5yzfhaelbngq3zqfpufdrpntpqr5urnoteaxmnzqkcsfuqs5svq.b32.i2p:0 -g6cxz6yy54bbkkjrklbq65ujlwom6i65sh2wbhe6zebnrciwhzsq.b32.i2p:0 -g7oomoe6adb3qtwit5aztjx2lpnvkvopqgtb5xtdozara754miaq.b32.i2p:0 -g7samwpj5lyi5hkrrwizzmzez5a5r33dq2uwa7ufi6pdv236qyda.b32.i2p:0 -ga25oahtxga27pmece3snv2vlpcim4gitvzjl42mc3oxkhclxgja.b32.i2p:0 -gco2hwi2rcbbapcxkzy2m5kaaui7csxqst337pycftz6kwyeraqa.b32.i2p:0 -gd5r6jobykemsb3beip7kaham3tyfr23w7lrkjvo3zagrgbrgnjq.b32.i2p:0 -gd6pjdoj6nniith2nkvd6pdhoq5rugxbm5emz5exlhieyc3hnbna.b32.i2p:0 -ge7ppvshhfd2bf7eywnc3xepbeh5nzcqyqf5tdchoimt7nxhz2ca.b32.i2p:0 -gfartwr6pkbz4a356heez436fw5im4thimitetn6sdsq55prb74q.b32.i2p:0 -gh6mgvrqvx47hmgl2uhdn5623cdsrdbe3fwtgp2y72svvoi7gyua.b32.i2p:0 -ghrzttcyxr2ujobdxvl5pljjfywy3hfyq4i4mqiha3t3uuiqn2da.b32.i2p:0 -ghuf53y3dxdnxgjjxast56jcsjohoxffc45mbx5wvx23mt6q6nkq.b32.i2p:0 -ghvmoyhep4sayhgen7c2pcg575aiihrwlcngm7lxxqtbymbgmiha.b32.i2p:0 -gk3sjjgjcff2gxmxy3wejlxbgqbohxsnfxdmd2p5ybm5o3pgqj4a.b32.i2p:0 -gmdyky27756xd4dcky734kuqiojgwdbhavz6ou73dpkg2xhwjrsq.b32.i2p:0 -goe4yckghgepu2hsctbizoszs27r32hexxsovbbkqqi6t7n2k2wq.b32.i2p:0 -gqerl5bp6brqik4pxagwldb6d2sy5enbxav7y2a4ttgeczlk6dzq.b32.i2p:0 -gvlhwl5joqjjd7n76ve4tcbqn3rhzfy3ipmdwiql4cjfayyfiwyq.b32.i2p:0 -gxj4yw7xhezc2oodjmmsfxmiopfzxjmbhmfkipcal5fivqfc2gfq.b32.i2p:0 -gyccxcchiq47yfzcerb23dr57mqvqptip6pvnemasbd2vpbgs57q.b32.i2p:0 -h2hcwns4deljblz6xbkba6e7eltqb75lh2gjpelgkxvg4ey5hp2q.b32.i2p:0 -h3urnunwn6chzvbjvs5x7dvfauzwnozcxtj5vjjdyglnfmlzigzq.b32.i2p:0 -h4k3d34tuim4gi4tfie5ulslg6jg3yqhafujajno4pmhy62yecna.b32.i2p:0 -h7foalesr2keimfe7qv3fwygefwukvoojtr6mlgw5urw7jojjn6q.b32.i2p:0 -hcv5zizlrdemafcezwzchu7klydbrquutmdvr5vwaawdcpcwouyq.b32.i2p:0 -hfu5l2szzt7faqsbef2reqku7pdhxhfbi462pahejq4ykaeqgizq.b32.i2p:0 -hglrt74vwbajhbaykjwkbjrdtptjxgnpg3w2crfphv2jss6of5ia.b32.i2p:0 -hiewpc5jb63t2xlr37tbvzba4jywo74iei6hl4meadbj2jibow3a.b32.i2p:0 -hnmrabzioiwxj64ih237rxf2zbdttfndiepp7vikt2jko7ovvrkq.b32.i2p:0 -hnxxsx7stxzesijof4fgr4xxysunipnivnxc3lqj2lefs7k7dqfa.b32.i2p:0 -hoclepz72rcrwjxzsgl4o7uvxih5uzyqkin77iovccxwyek45eyq.b32.i2p:0 -hoislrpk3v4grtevg5mowggoi2zbltk3hfbgp23qht3zl4sn4eaa.b32.i2p:0 -hpaio6vghijyxd6fxboef4f7ogxhusqcyetjbp3ymmmbv6tzmg2q.b32.i2p:0 -hwd3yvybu435k2svvcowd4hgbk3yiemw34d5xauf3e6hr5t5wd3a.b32.i2p:0 -hxuyh2weoko3iof7hhvffcira3yt3ggmxb5prio6tywor4vut6ia.b32.i2p:0 -i2k32sb3fmkhemu2gzm7h4m24ubcgqdohhgq44qya7zbkrgw6mua.b32.i2p:0 -i2zleprgvnwstip4ehhny44y4cf6mp7gqbl7y62x3yndjx3s7nia.b32.i2p:0 -i6p5plk5yucb6klnedouoiubr47jpw5u6odvn3gwbtxqhmzwvvqq.b32.i2p:0 -ic4ybawsjcxr4gfnwvp5go2wsugw6govevz2lmmef25z2mfva7iq.b32.i2p:0 -iccnhyf2ma6m7vcbu23dp4erpz6vzf3emlrx22w5e2pie5hh2v3a.b32.i2p:0 -iddzvtvx5l4mpfv3lkutmf3nptl5qxtzv3qyxlhwbkptz2mphyva.b32.i2p:0 -idzlsjx4m6n3g4knql7h53bnnh2v62o2qt6monicpz7q56u2jwlq.b32.i2p:0 -ifajz75zdk6w63v5zq6tadlq2cycyd3tkstultnqot2fnglgxpia.b32.i2p:0 -ii7ra5loq7nw43kxjtr6tdhf6clvtnfqqatnaz2mtr6pf5hyelbq.b32.i2p:0 -iiai66vnuffmhnjiu6wllnx474hwkpw5eqowj5k7i26z2ea7dd2q.b32.i2p:0 -ij4nbzypgqlk6ztlevbjuly4m3uqantz36eyed57tciqhmlgxfqa.b32.i2p:0 -ik3asfioedfgrzjszelqicxlnban7qfnvlnng2prol5iut7ltc2a.b32.i2p:0 -iorno6nomjiens5qvzvdeav2mmizcxpp5wsbicdazpg3gvthqtaq.b32.i2p:0 -isefwae7twhnzwgrhcfrvk5oxymgxpzuokuc5cywmo55is5nb4cq.b32.i2p:0 -itrjkgswudaoyrrfmgpi4vtbowcwkpzs523lh44vbzwbmcz44rka.b32.i2p:0 -ixhgawpp5anrlwxxgfun4zl3m5xhlxassszncph4i4e6aymb5fqq.b32.i2p:0 -ixvv4njukuae6msnpatik45oucfaabpeisbauqxddhwnubu25ioa.b32.i2p:0 -izrk5tzrxm4lq23qbdiaoxbzzhygipuucoyapz6ib4dprxmfrvhq.b32.i2p:0 -j26gpaan5ablb56k4rtbeamv3ihd4vdzdv74dw4kkevxruapwarq.b32.i2p:0 -j3lqwybu6vptuo27tpnkckliz2weani3pnzzbziwfsj6nqcb43la.b32.i2p:0 -j4tjrfxnwcmbhkixmqlnotginhfxgfdvjahr6yn7j7rkbdqngh4a.b32.i2p:0 -j63slhfjsmvtoetikb364pztywrlrv3rpk452mf3dyjizm4fbdra.b32.i2p:0 -jbtdslz743oawsvgghp2traf2e67de67ec3dbigvyb6g5jotapoq.b32.i2p:0 -jd43pc2l73ek6hk2tp6hiyada7ed7vshqo2fvxbga2daylcghfyq.b32.i2p:0 -ji3bxuak6mmsvcppqrt2g27haiugobvqbyngt2n5cgtf4xmhyx6a.b32.i2p:0 -jibaw7ynbnxueqsy7k7jyvoj6ldzbuckppfx5wozt7mftihy5vcq.b32.i2p:0 -jiins2brur6m6dt35rr2rj7giaggvwcffz6lsvxcrcc5nfv2a56a.b32.i2p:0 -jpl5utzbcmszv6xjynf4buz6hn3kra27xvfowplvjalpogrsxjhq.b32.i2p:0 -jrvg22xvbmjyrkqg7mr622zhnda3ijtua65cqngwrven7sf5zd7q.b32.i2p:0 -js2nuhxqxp7ocg6wh7n7dflcjiexkyfauski5hc2w2hke42mygca.b32.i2p:0 -jspsip6bfqu55yxd45lf5kpbhn6bvtt6hgycixbzoyuwoabcenka.b32.i2p:0 -jtgpesmlbpsvhv2jxzrokydnmad7aqbsx5f6ptyqol4ypwkn3zyq.b32.i2p:0 -jxqyize2ct6mm3jvvzavm2zbccsoe5qd4ekqo7zgt75rzz3mni3q.b32.i2p:0 -jyugnnxqhe6alidik6xclgxb33mx7jqzqosznijr4i6zaqavogma.b32.i2p:0 -jzymnirkvpexwtbykienuhpcp6hf2r5hko7wjlvorhsfaojihf2q.b32.i2p:0 -k2m4cxmgn7wnv37tupfq66ycjcwcd3xubhzhgjkxluxn4hzym65a.b32.i2p:0 -k5oyn7higpqwarsh3ukdgmx3z6tvqcwju4xawrge6aaswrdnoo3a.b32.i2p:0 -k67qwu4dtuehpxm6d2nl6ik23fvdtn52rmmznoh5qitd7wylmm3q.b32.i2p:0 -kbq3zwwo46vvvhubrscfpwapbck2dx5lvyu3cs62s7ntjdyruh4q.b32.i2p:0 -kcj5ifya5tnsgeyqlgxjigdnwy3q7gdodqikmfotsz6vbbtkfbqq.b32.i2p:0 -kcqkothplemakipfpeajxmu4xsszpaxpprgtuv5tgfdaqejg2sqq.b32.i2p:0 -kdc2f7exxzig43scf7r5clipy3ywkwxhdevguymkadcmhxalyxzq.b32.i2p:0 -kehosmgk76fxnjywqjj6nqs4ohg4hsutljdzjo4sswhxlj5l5tca.b32.i2p:0 -keoewoantu2e4yah736fplwr5omvzqdryadofqogk3hbwaskn6jq.b32.i2p:0 -kh5svu6npgstymw2kuxamwnzalpu5jcmgx6gsliibsua23jds6rq.b32.i2p:0 -kizk5v5e3khywdh35vwvztsub274pruigqnmumorv36otvncbpea.b32.i2p:0 -kjdqyu7j6ojdhftlh6dd4do3ns6nhj544uzjt53p4cwhppg47mhq.b32.i2p:0 -klfp44ljmaxoxhpymmnuj33d744ai2wcbj7o5i2cv5mkjbmjc3fa.b32.i2p:0 -klsaj4g2jh7w7gxwctniktg3hqwspm7zlkwtsaxw4nu35jssjasq.b32.i2p:0 -kouxxivmwywiwv77bvpe5lgamnhlcypan6urupymt3s56lvrnftq.b32.i2p:0 -ks2nfolgkpdfg7pizwv6kueyqeqaixjru6ui5qktcycsyulppg7q.b32.i2p:0 -ktjqkbyl3soy4kscrs23n2bidiismoq2jvsx7d7p42sxizgf46rq.b32.i2p:0 -ktua3j43ijxhhhfeljsp32kdiuic5nlnfnkx3ealy7ojva4vwkoq.b32.i2p:0 -kuzu73gzvlnog4cdtdk7edbusxr4pigknvwg2bjo6l46ugsgmrtq.b32.i2p:0 -l6kwirv4m4vzzmg6lp4mpbu6k5jv2yjmdgsxxr67x6blm57i4dsq.b32.i2p:0 -l7j3gpfyicterbchswmaasozruckfohtrnqssqttsxggjomlccwq.b32.i2p:0 -l7lvurgolje5wjlbzjov5lwntoumxrlx6depd55memi6fy24bhba.b32.i2p:0 -lckuhkvnnkh5gs3s4v4tdpesmdjiruqhfifgkszyfsgy6vx2h4ga.b32.i2p:0 -ldl3a2gjjlj4sqmvbomn3gmj6xig344krwxy3gulhlcihyvqdsya.b32.i2p:0 -lfm6pz6nqqm4ofhlkja4y63myjjumgrvh7qul2ejiimrl4izdgwa.b32.i2p:0 -lfomaqlecc4ieyaldsm26o6affnlx6nsqup25wasmd3f26qeghpq.b32.i2p:0 -lfuvzzzceuik5u5pnd2i67amegel5ua2rrnncxkyyc7bhteq73aa.b32.i2p:0 -lg5h76b5n4r3ne7bwpf7be5byyncrapo7thhkuzaktblk63qvjsa.b32.i2p:0 -lhl55njfnmt2fzbklcnunvscq22jx4nxd5p4pureu74442mrjgwa.b32.i2p:0 -lprgmkc45te7skx7rffpz72ca5c3zdg3tabiksdboao5w4wceu5a.b32.i2p:0 -lrah7acdsgopybg43shadwwiv6igezaw64i6jb5muqdg7dmhj3la.b32.i2p:0 -m3rq24awypjmmimszz5cqsdwo7okpkjpilny4ss2vuxwq22fqdfq.b32.i2p:0 -m45c54fio6dij4ywvnjosbokblhqsynyds4ywagrrrkzhznoryfq.b32.i2p:0 -maqk6lnttwykae67lhms6car4py5p6w74ntyv7izskl7o5lr4x3q.b32.i2p:0 -mbz4wyfeqtllccary2crak2qfovnaq2366vdddro76ihxcaavfpq.b32.i2p:0 -mektdpdufe6p74i7ijumj5nw5ckjtphj3ic42fbpstgdlwpvqjaq.b32.i2p:0 -mf6tmlegp7uga66cdael5376uaz4qd3wacuh44yvepa3kbu4fk3a.b32.i2p:0 -mhgxec57s6h7eixgemsghlcuhmgh7m7p7phqd5kzmm4wovrp2pqq.b32.i2p:0 -mjpulaafdyuanouslfpjcsvumi4edtckfu3ffn3ipabkxj4sn35q.b32.i2p:0 -mrzn5dwt5suy7ywbc5rb3oqunxu4whkrarfdabh27rdzqu2lycoa.b32.i2p:0 -muz6dlwaldiabrmv4goironrkejtjiaivtp5s4wy4xiktwu3firq.b32.i2p:0 -mv7b44duaxqpzbdztnrdvnj6ypsp7yhs4z3dc2q64jov6pritmja.b32.i2p:0 -mwevh5r5dkzddlo2ol6bojpdds3kno4xqoy6p6ulid3paamgrtla.b32.i2p:0 -mwyjzdrgtypbwjyulw4ifetejz6xusqstvzylztsphpg2r2zf7ua.b32.i2p:0 -nbxnyibgbf3awxxneu75a6xhvs5foxrrkfzwjywk7vs2pp7dfupq.b32.i2p:0 -nghwktleeqp7j4zmii3u55hgxip3kd2xj2hm2hb7qrf5x3ym7cwq.b32.i2p:0 -nkj2zabj5b4vhold33nz3kgp2x3i3es2l3iz64rxx7em7rkgubaq.b32.i2p:0 -nluwsgpbk3cplcb2fpnfpjrhot2w7a6mtjggkqikudspysqlsceq.b32.i2p:0 -nt72dtparurtk3ccvasllacdzg2ubtvc7jp2kzx3hs4dzvrtayqa.b32.i2p:0 -ntxiyrlhss4r54zz762ugascfnpyucuzhvt2vdbjwysoyohlk7wq.b32.i2p:0 -nuj7cpelk27czgrj7vcyv47qazkdlqfhaz53huzxohv32fn4raya.b32.i2p:0 -nw5dd5rrmlmrkrf6ncqtivajhq2idmr5zluw5hv35tngsmngnprq.b32.i2p:0 -nwfdwlblhudom3oqe32yzzuuj2sb37tjvlmimiru4coazi5freeq.b32.i2p:0 -o2dfd5fx3mwyw6fig2qiesnl3foynovu2ifhixrni23uiw7gnaoa.b32.i2p:0 -o4mhr3ptokcgwopb36okxwhreo27pqq7m3wnuczm5rbku7yatuoq.b32.i2p:0 -o6vbupdnpd5bwvcx7ivaecgyo7x5vdu5em4va6cmx5iwcf5tyaca.b32.i2p:0 -odbgdisp7y4fj5xqycwzibau7cwzen5wpjph6betdvgsicxx6q5q.b32.i2p:0 -oefjimgz2vzsjixg7h56gukedb6n3gfw6m3e7mrxypzg7givl3cq.b32.i2p:0 -oig6mlccmguof4iar5y4kqotjllryhtse6j25ch4rgcerqinms2q.b32.i2p:0 -ojrr3gjhfhlshhnvrbvyqxw2wuonng4a2oq5ooph6bmdl3evhxtq.b32.i2p:0 -ok5i76xbjhfukzcsffxtjn4anq5lwgct2ktov2lnttht2ic2v3fa.b32.i2p:0 -ol4zsxh2mml3wmdl6ix3rtu4fontev4w437kp4rns47keidcz5dq.b32.i2p:0 -olctygj4urjaes36stgzuxnfvjsnub67g3qtasaxo5krmiqwwm4q.b32.i2p:0 -oqbvnqidy6wtal7amigktvq7iggyv3ghirvi5h3hxvwneb225u5q.b32.i2p:0 -orvshryqq24l24e4dvockx2ekj4hu42otqxsvyvy7tm7hhdjsz7a.b32.i2p:0 -osrwb56pz75vgfs5q3dtsgxoib2ijz7dzcjcktzbbklceg32ggea.b32.i2p:0 -ouk4enblrjm46yoycsybi4usgtysncd2eyli4pstqh3yunhrcpxa.b32.i2p:0 -ovb6oh2sliwf3q5ncjcpiyhatfb4zjsf3bg3npmlf54ry23mr55a.b32.i2p:0 -ovkjylbsfe2756cpphzx2zvhhmtbetr5ci6swmydqc5itajqxm7a.b32.i2p:0 -p37ckc2woa4tvpt7opht7btmks7ni7cdrj3a7tb5aqw5euthacwa.b32.i2p:0 -p3qxhtoxajkmt7tgc6stv55msievc5323rtrsiwstvtf37iwi4dq.b32.i2p:0 -pcdlqw2awppohbiued4rffgs6n3lv3thhon3r67jmx2652qx2khq.b32.i2p:0 -peh2c5jbvzupm3stkgkmrlkhzzlnn4lqlejlehe3xjartzm4t6dq.b32.i2p:0 -phixf45de5tbuqt3yla4cldxx4cckybafsbiu6mbuoru4b5wttwq.b32.i2p:0 -pivckwqf5htiicsoevadbi2qtkapd3fr52jbsijhlwr7ksc6i4eq.b32.i2p:0 -pl4dsxve665bl6y5dtldtnldp3mrzkuw7hs45juitlay2zj7xvva.b32.i2p:0 -pnhspu3rloczdbzsysa2iftsgoiy3zgcd22jodmk7zdjanhiemla.b32.i2p:0 -pnsmjjbigqktlxpuxwvuc7jb3bm7f3rtd5xfulrwbjxdqhzjjsaa.b32.i2p:0 -pomodyf3nnav7yeu2usrshzq7dvdqawrhoau3uxlimivhy46lmaq.b32.i2p:0 -ppe2jfsb2xrmgwugbq7agy44ucb6yq4qbufaf2sh76b4kwpa4jcq.b32.i2p:0 -ppez53yrs6lanyvyxuxblqxiuvhnqvvtafmwaid2kgp2dx2v5iaq.b32.i2p:0 -ppyl3c4tanrlkpwzi2zpctkmevfceo5a6mkemsyvgg7gpwl44k4a.b32.i2p:0 -prgq2fqhzc6lbtyzefqfx477sakkfumxv2i7psco6tdi7zr3yrma.b32.i2p:0 -pri376r6uuwgnbnevki7c363h4ryfwjza7pcbfswqqxk6hnrkhja.b32.i2p:0 -pscw5yzaj5js2fn7gzrzoj6teonlsohlbnvdco65ubdefpnpwhpa.b32.i2p:0 -pv6g7uin653rerdiivdgtoirjvokjowi4b3fwatszdlteyos3i2a.b32.i2p:0 -pw42656k2vbwxmvrc2qbsz3jslvcxahln7rehsbia5jdio2knh3q.b32.i2p:0 -q4o7bf37e6afx7evwdyovsqptjwo6td3c6qtjh4rtdngp3trwi3a.b32.i2p:0 -qaqvxmyvq2m4wombmtaz3our3qmp7eet3qle5flnrs3a5wgfhxba.b32.i2p:0 -qawed5ou5vb42ugi42goxr2s6cqzpyh3s5atkhvfvyhyc6anxyaa.b32.i2p:0 -qelsaseevnmz2unpovh4nbpjpshjg45iudiaf5zbngealwwuxe2a.b32.i2p:0 -qf3fj25vq2dbp6bvvmcroixohcsk4qfvx3t33kztomgmyu5vdkza.b32.i2p:0 -qfnafktekhndrriu6mkd3dxao5lpm5hdgezot2ngvtu4jxjh6fmq.b32.i2p:0 -qg76yse42g7rjhy52hhyo34jcpdmqfp3jh3dqeg4yxsk2bzsp4tq.b32.i2p:0 -qgemqcxwh34xaotjlik26ygvu7hgjzp3zp4fqzs3gy3stcgzdqpq.b32.i2p:0 -qgeudiusyeltzl5ghvhjhdhs5cqa5jjspjlcshdsqk6kkk7t727a.b32.i2p:0 -qh6w3hgua5ftynnmg4bqpposs2qwgfmxk2smxirne56lbbetspda.b32.i2p:0 -qj26ldkxdaa5pgvmifp6uvwlk2rbg2l5vnew3vewevhivjzazzhq.b32.i2p:0 -qllztpshewimlfgxfv7gyqu76akuutu77a3qo24ubz44kk7cnffa.b32.i2p:0 -qlvxgvl6kmfuclivjj2hdliuhqp6cu6tl2gqbp4sxxlw254a7xcq.b32.i2p:0 -qm6vfq4pfvjg3r4g22xkg47xc4d2y5c7qlsoqyhfppsvh3grjfka.b32.i2p:0 -qnqojlthym7z4gwizcblhpd2thy7v4a6ifme57bzyl3nxzkj6ica.b32.i2p:0 -qorzdjceszf432obxa73tnwhqb7ltxrxlfkkqmw2flmfjhoyv36a.b32.i2p:0 -qpe55twml5tsuow2sfxac56a67hhf7gm4ogtsv5wqkfkrmpd4d2a.b32.i2p:0 -qslxyiesbbegxr6ksmh2lfk66pogbubvvbkglvowikkpgvdppbwa.b32.i2p:0 -qsqtfbta27nnygmsiimzu6exhc2jgps4aicfmw4dgmmj222siuaa.b32.i2p:0 -qtb5fd5yaytg4n5xviyaqpljdprj76bzektgyet7grlogm6gwwaa.b32.i2p:0 -qtubqd2rbzzftyje6r6zzcao35knliq2df5v5kzs77y7t5gaxwja.b32.i2p:0 -quzkrgzb5pmn4465647ke5lsfbseqnorr6ljvfsxcagj7rzl7hcq.b32.i2p:0 -qvuzgrsquvskvxpac3fyrh6ssho7jx3mcdrdgprdbel76o6yxcvq.b32.i2p:0 -qwdrunaogud3v34aod63v4upwcoawqs6hshrye3quktuxziorw5a.b32.i2p:0 -qwhvlprhk3ntswr5xntnc2hhgmvd3bbgzgkbombiibhrsj7k6gyq.b32.i2p:0 -qwtpmh6ssnkeowocnvl7uveuhfodht3hsgwwydhy3v4xmwqbwveq.b32.i2p:0 -rb7x26lmepfbcd7wtxu42pf4tdxbe5p5zsf3cwuukd4fs4zhxtba.b32.i2p:0 -rcsddyxkabmkkjrjf4rbf6cimlmcxxmvdbczq3bczlmyn5q3tqfa.b32.i2p:0 -rglf7mv553yknevqejaf3xleqofmm3cyjacbhv4jzosylrkrp5gq.b32.i2p:0 -rho4s4jbcb3dvzgxxzijbhqxic2manxm244zy6suw7irja5h2mqq.b32.i2p:0 -rlivtzxori6lpewmlr2jdm42iwxt3ex5sodwzhi2f6vjc7lur54a.b32.i2p:0 -rlvwiiu6emvj46hjukstww4dfknmsqf7xphmdy5tdsftyem5kpva.b32.i2p:0 -rnfc6sekfhk4hyyoa3ro74pg7kx7dgh6y5qs2huwz76bh7ymnk4a.b32.i2p:0 -rolicqq4ebyfgjgpl7xjokglkfwq7vy2b56aloe5bdhzpfzbt2uq.b32.i2p:0 -rqzsypuk7ewsyh2xtihabkp2iyshxgdatgrhghpnhhlythszoykq.b32.i2p:0 -rrm2pems425buhonptp7lbtbprmwwjhbftey4ujvk25nclx7rerq.b32.i2p:0 -rtwm6njef5tifwv5ols3b4nsboniig5kdw32ik5qbv3wmhoo3pba.b32.i2p:0 -ruccvtj2tlvj5s4yqexhgosk43xyyqdcfql5osxpufqn4u65wz4q.b32.i2p:0 -s2sa4qnikyaaiyv5s63l64w6qvb7dkq7elorsuen4ksnw4mu7xsa.b32.i2p:0 -s2x2k3gw2y4vtesxrezvpubo3qubpr5qckxolc47z7rbshjjhvpq.b32.i2p:0 -s3ct7nrzj3w3jpjvnsp4tdlyn4enl7rbf773kiklrdfrh3oj3g2a.b32.i2p:0 -s3sh2zyyphzyzvznhe7s3lbv7eeqwk6kmayqcoekdyggaza543yq.b32.i2p:0 -s7mu7i6gygygixd2ccrfex4doywbx34umcj2ba24atn6qbo34szq.b32.i2p:0 -sawmppomw6zlu3ruaobnlc5y7kg54tvgvfmhimwdfmorzmdmc7aa.b32.i2p:0 -sbalp2doxyedtr52kj57va2rmbi5npspv4drk4vxnujag72gtpiq.b32.i2p:0 -sedndhv5vpcgdmykyi5st4yqhdxl3hpdtglta4do435wupahhx6q.b32.i2p:0 -segnvtkjqqhzo52njxma3jgerwblnpvqrojjyeuqgzav7dwjlzoa.b32.i2p:0 -sjd2fpbiqucslisyynpxvsmxg2jydqpddyaodnkuptuwkiz3cjbq.b32.i2p:0 -sjpqyf3rq7ojcalldlybvyyh5lqiq5j3ade5w6txe3473ybhk3sa.b32.i2p:0 -sle3cbbdom6rknc3drqtawctpy635ica5d5gerjjdahfymkok4ma.b32.i2p:0 -slg46wsae25tx4mjbncrrhbs4rjfzxcwmm5jc425cnipruoo22ha.b32.i2p:0 -smrvlfmq4j4ddtlcpzwixyvlunhvh56omu2k5tyjkbdy3itqgadq.b32.i2p:0 -sszwxree3mlpsnpcjhgqjh2kxltan3xua5pyp3xob6sonphyxgka.b32.i2p:0 -swqpk36n4oyqc3e234eml63pn5hblxai6epryfuo23pdgfemsl2q.b32.i2p:0 -sxb7p33xjjinvolexb4y3k5kx7uwlzsnzvbv46i3lyorm7gsv6iq.b32.i2p:0 -sykset75mlxa4igxqgmfu6o5qyvlr5wtcsqkehf53fguuyt5rkla.b32.i2p:0 -tat2veaz5nwsv7g3czy2mxr4opg7bkeegegdfqjgaxlt6qvk2dma.b32.i2p:0 -tcx3ftsdl36ukysuuewydapdzuu4alewyg22squei2wda4a74tba.b32.i2p:0 -tdvomapjxmxg6ktoedyrndhrjtk3ex4rll5ijkmdcvakzamubslq.b32.i2p:0 -tiomg3tuu3uza3nmdztsode67rn7v6yv4f2npb57l6gnwoenfdza.b32.i2p:0 -tjfdp6mel3wzdpxkhbyhrmfrha7gekv3gghalnxezrmvnhy2ncra.b32.i2p:0 -tk63xbzug7def6esivofwq2h2c53ar3ot7hsezdq3amxqqaoyr5a.b32.i2p:0 -tl3xkknuukvyinyhvt7saz3tvz24ptgyqtzy3igygyfapcf2o3lq.b32.i2p:0 -tnvg4ol42joykttvxs66yoyrvdidhy3vr7mrjf7ona5sf4h36txq.b32.i2p:0 -tsdpkr6llyohtsarxgepqehdauo3vpdcqdml6evevu5mhuu4bsyq.b32.i2p:0 -tsrlbxayhihugr723z6rkyafglnhcyzi2zhojzsyfdjsqkkd53bq.b32.i2p:0 -tsxwmahei6rt2vwgygdvzh6dyp3boh3ixpwq6l5yw43eq5sfgy2q.b32.i2p:0 -tvbutrv73xhwqbtosmbp3cesdyc5bbtslay4gjsf7rzdx4ztgzaq.b32.i2p:0 -twu4qyvf3sttu6vsjwujjqbd37wlkthndbi5so6undt2abj72bqa.b32.i2p:0 -twwjmbvrcfkl7s3hh473jwmxdys2zxo2ozlfivsjvbh2kobl3vsq.b32.i2p:0 -tyvsuqy36cx2yvf7jhnkd5ojc52g6vxl2rw5qshqwpk63ptovdda.b32.i2p:0 -u465w7hete2bpjhsn655oan4ryxbrb2muvc6abhv7wy2hw54vcwq.b32.i2p:0 -u4enqhila7pkwbwuyfbfd36qllbyv7y3p4nelxekrf3fizp4htza.b32.i2p:0 -uc52rzz4xu5ikx6hl6r6sqxfmiyyxsffpcu5frrtepczidwjwuha.b32.i2p:0 -ufepan7c77blkedldhiygt7363boe3xwi3oy5es6eapfdd2nivka.b32.i2p:0 -uhkfrosqc2uqczwcktbb7ups5b5t2up7yhmicryrzqknkj334rnq.b32.i2p:0 -uiz5w66ez6dyncfivv6ihsnccx6jigyjbnfv7voztugyuqrnt3xq.b32.i2p:0 -ujfge4rusfh4bcnuuenva5cch5eji6rxwox7e337dy23om4sci2q.b32.i2p:0 -ujzgzob27kxdc3gtj46qgaewdfhex7q34njlzcm22pq2suyubr7q.b32.i2p:0 -ul6hbnoyd6gdhm32dw2la46ik34b2hhjc5wo4rqilw6wbvbqbvoq.b32.i2p:0 -uls757zxmryrazn36okmcdkzolfohv5ftetsclteibv2dwnuxm7a.b32.i2p:0 -umlbkwpm35dpp66ggxt23tdzsqh3t2ancdyrga5nxidn2lnkdgxq.b32.i2p:0 -uncalsdoypwylzugunja667sdynbf56f6makgjkygyanuklb7lda.b32.i2p:0 -uohuxnjd27cftarbf6kh4czmotwvstpon2sgs2vpffqkgmg7guxa.b32.i2p:0 -usgqijrwhtwgoekjcr26yqcgpncwpsescrr3eek35e3rhkrtptoa.b32.i2p:0 -usvobohlqeb6hre3dkqjqgzul54cn2s2htppk36bsxjcz6ngajba.b32.i2p:0 -uu2nvtd5jeppiovo7wksv7lrgl56kog3e5js4cxpgik3wwqj3w3a.b32.i2p:0 -uxq6sz3jptldm3r3o3ogwqbxqhpqg3hrroyiy4lpvjjqf4i5pata.b32.i2p:0 -uyy4dbfyx2i2x3goobc6uxj4nb7ktzsu72zlksypjfisgka3xnta.b32.i2p:0 -uz4fa7nlzuqgmwfukqm4jkkng5pwfolyrbd4qtsorv7qa7cxcmsq.b32.i2p:0 -v3ob2c7arrot324zel5w7ibmfmud6lyhkqyyldiwnxphdhm2e7xq.b32.i2p:0 -vavpoevto45dv5spd4csk3ut3afe5cldtzvoceuiix4ingmfhxla.b32.i2p:0 -vicxbb4ts6jmqj52hhx32mxnwpur5covzxotaiy6zhaansldlodq.b32.i2p:0 -vlmixyf7yg5xqe54r4htfrjdrsci7k2broic5n7vugry46m5xuoa.b32.i2p:0 -vo22o2zy6gb4nsmcteelpyoa4khh3hogoe3jsgis6yglyrtxzloq.b32.i2p:0 -vrrkgdrlov6obcqqyu6rbcsu37heehxetutnacl6qgr3clm7aeza.b32.i2p:0 -vuqk76jvxfk55bkovqcmmkvycmndee7j3tuv7ezdb2slrfpjyvoa.b32.i2p:0 -vwbls7ihzlzwu3uapbnzfsudy75dp3ih2fp2psffli3ir4iuezgq.b32.i2p:0 -vxjkydkgnpl4j7pt4qrf3ec3ds4ks3ucb347k5xae5jg6f5offga.b32.i2p:0 -vxs2es6f7uw2uuneslb7ipvmg6kqh6ytpjezoj2ptwx7od4jqmxa.b32.i2p:0 -vycnqqqrlbexyr37ytulbzesazy3voozq5sz7j3o6vedxic7ionq.b32.i2p:0 -w3iu6clea65cckmimaclxdvuxsudbghfytphejcsp5ufyfgfppra.b32.i2p:0 -w4moc55z2f47lfyumqap4td2zfcjrjd34ung3vircwrpp3ts7oiq.b32.i2p:0 -w6jl2gubyscdpubizes5bp6s42cito4k27xwcjwh76rvuik2prha.b32.i2p:0 -w7fsijz4juktjzpksc2iec2ljtdykgxere3m3dwfnqztl2fto2ca.b32.i2p:0 -wacfewi6ehmfxvftxqmracfh7se2t7ozl62u4hsuyd4c5xfzuajq.b32.i2p:0 -wagprvzeuinlzec7hxrggjxpex66uikbvh32lhdv44ez2z5vgxfq.b32.i2p:0 -wfrvnaeqad6zevflyme66n3p77b4axymni33fu42bhsaei6cmrpa.b32.i2p:0 -wll2w3rtszujy6lmfrvexgyv46czhfx4ym7fiyf3mdwl3mnbzcgq.b32.i2p:0 -woyjnznau675j4mazibi5cjkr3ts4sqtp6ufidi7zozanczdyicq.b32.i2p:0 -wpnewole7fofvwvrvkkgf45sgcverlodocu7fstm2axp5jfykraq.b32.i2p:0 -wrqu543ssub7kiwzfug4o7m6lc5ibmaamdc3o4uo6a7ntxiqzd4q.b32.i2p:0 -wshmvsvqjnzlvsajbqr34vr5hlqxdywees24eubv5swignloww2a.b32.i2p:0 -wsulywnyo6kuppkz7lcaecca3kvqjpynbd2ysvvuj6dylnd3vf2a.b32.i2p:0 -wtdyush2aybxg2ga46txd7oiv2nmulrhv3bfzilzg7rbzf4mbu3a.b32.i2p:0 -wtfebbwmsxoywu6nw5cowlxqhtokxrxftve2zee6flvrpqg4j6ma.b32.i2p:0 -wwbw7nqr3ahkqv62cuqfwgtneekvvpnuc4i4f6yo7tpoqjswvcwa.b32.i2p:0 -wx7cpx6i263dmx7vkhveuzyazdjy5pfrrt4f2y6fhiev24v26gtq.b32.i2p:0 -wy2udklgydh7iknnffbzvldoiwsct6dy3o7fjcsjcdjoq4b65vha.b32.i2p:0 -x3mabmgx32hljbx46xqjobh6l3tvrridnxgrla4q7s2bgkk63aqa.b32.i2p:0 -x4tbcqodj4dbatrsjjznx6srdycgmcfknqkoo6asb7aisc4wtmxa.b32.i2p:0 -x6vn35i2xv7lwpeasn3eihdii56v5wllemaallxlwq56j42du34q.b32.i2p:0 -xateuy7lebnitxx634irwytrprp3s6o7agee62pm4oytvffbk2ea.b32.i2p:0 -xcjjg4k6fss4b3lpihknh5ws2esug7i6j5gehjta6ejxawxlotma.b32.i2p:0 -xcoq7v26jvysna4zqwbfswfqqb5hjmdqys46j7oczzu4g3craegq.b32.i2p:0 -xdmcmjahaeyue2mknpavqkflccaznfdosl4jxltzo2suqdyc3mla.b32.i2p:0 -xfrlfngubzadfa4bvqdirlkzlo5uunvcvlwppvxbz5vgf64tm54q.b32.i2p:0 -xfyzfugo3qtfpq3s5zccbbqrxfkgy3ttlqhz6t6ovmtgrsuyce7q.b32.i2p:0 -xgbz5vpek6vaeej2zejxrjloqg2sqb67gim72qqpodqfq62rflvq.b32.i2p:0 -xm5nole53h2rwys6uiz6qc65yw4dkqkfxuobgxrmvo5fwqgxeohq.b32.i2p:0 -xn2wekjcxrhkm66vnvea2lx7yxsu3yx5cbmkjbcdct66wlj2jfta.b32.i2p:0 -xn5dz3dzloj5g6nr2qzw5ldz6rlcainm7ddpstjfopyirctw2hkq.b32.i2p:0 -xnvsgbonlja7cmeokr2msvdelqlasbkwgqndqg7eakw43t3m465q.b32.i2p:0 -xrwuqylcgkr2ovsf4pziosd27ywd7pfaohnreoyzm72qlnvoktrq.b32.i2p:0 -xvlj55kzoy7qtdqfs4o4dqyuajw6bkmydiymdi6nbrpr33toj2xa.b32.i2p:0 -xwlkpubkvsdsyaeylqfmxfk43juk6sz3hxnmwe4zencjq77aznea.b32.i2p:0 -xxxqbqzrtilchxwuqyqrfmuhwbpia2kurv5ho7g5q6a7bvsvd3gq.b32.i2p:0 -xylrnmpubtdsdhab37syiiaj7shmg4bmhgss4vkdyvsogp45fdrq.b32.i2p:0 -xzo2nvkiin53drbnir65zxq42sfkybnbgx4ozmeayszvjjrppfpa.b32.i2p:0 -y3kqvifjucu52hg3f27f572vc4lburush7s7q4kuepbxmnlroolq.b32.i2p:0 -y3occl5rqc2mz64esu5mqzoyfzlbxop7tttf2b3gyxjust57txfq.b32.i2p:0 -y5wr2bw3rt4rvw7hqqj7qtlf7vdds6zk6cs3mu3myyduasieqoka.b32.i2p:0 -ybbmx7a3zau7c7ax3glgj75mza5e5dpibzy5j4p5qduttgo4xgbq.b32.i2p:0 -ybdhpsgmtw4eewreo7kswclgexdztzk32a5x4pbr5ws6nm42gpoq.b32.i2p:0 -ybx3kj4hfjcpxtifqy4ziztx3pqyijindks7zdacq3vk3cjzyztq.b32.i2p:0 -ygtc5m4mh3qhi7tct44gxqbenhkasp2y4ydjn5qua4l5vh35osdq.b32.i2p:0 -yodn52qhw4v5aoaoqfsunvfecbbl6cyk5j4aq2pfm4otu63qlp6a.b32.i2p:0 -yphmy6w3myyy3am5awdksfyhbmmleqmblru3pfoajhjdilktwdca.b32.i2p:0 -yradzf5ip7f3qq6kdyqm6qqafygk7a5spov6a2miha2dk2u4me3q.b32.i2p:0 -yrpsrh7tn3qfgnu5djdubjca6oodvxaheanpcmwh2cwkekqrtida.b32.i2p:0 -ysenhmvz3jo56h57zzzvr45y3t57rvt7vi37p2kdiz6fpfrbmucq.b32.i2p:0 -ywlcceffoptf6vynbgut777k4w4agc7tvhvvlnlwtdzq35v5mvga.b32.i2p:0 -yzsnqd236vyo77afhxnbmrnie5fepnuuvpwqyz5lvmqeihx6z4ia.b32.i2p:0 -z4zjvj27uxkzwmltkyd4jslrkqpeqtkztfql2nlsunetkkkl7vma.b32.i2p:0 -z6g6lmwuhnldiazyf72zlsvtwbql5mfvpmyaipuvjfwnb6slel6a.b32.i2p:0 -z6mlyrxcjddpcaoumxnw5peulnkvj56hgwqmnc5adoutp7piujaa.b32.i2p:0 -zaq7uso4bgzhv5beqjrwlciyevzv3g3kyalvtftombe3m43myesq.b32.i2p:0 -zas4vpvbzsno3hmqu3tlw4mkalvu5xiollxveapgsolub2mcimuq.b32.i2p:0 -zbymohtlahzy2ygf4pw3kcxg5mzu6mjhzonucfks6txhv54f2uoa.b32.i2p:0 -zckxrkzbo66y5k442djsd3cgffvp5t2us2ewv2i6f6dwpaxxaxpa.b32.i2p:0 -zcrenbrluidv3wbzdsvw6jvkhymp7yric76zcd4dfdcrr2n4kpga.b32.i2p:0 -zcwgqw7hlw7437a7au6n6obljdb4arnshoibdqo6voree4xiznoq.b32.i2p:0 -zd7xacyuee22h2qjmf4e77vr7zylardqnehldv7j4uxu7urfljka.b32.i2p:0 -zh34uj3cwyr7zs2uc4aeyrhffgumxd5uzpfpbmbuyetqkd3xy4ia.b32.i2p:0 -zhqbovteqcfmhg77wcrpre4njrguxkc3au42sf4wmzeb6mjyggfa.b32.i2p:0 -ziijxo742secxdbebrvaxf4pbbr7hip53lgnexnswvaoaxap64ua.b32.i2p:0 -znt6mdvmstxcdaqeiuo67k2ug4e422gjftrnm7ov2izaeuh73d5q.b32.i2p:0 -zs3a5qtz7ruxlp6gppcqw5wneafdwbn66j757xg4adpjyt3ec5ja.b32.i2p:0 -ztr3c7qz6v4hrnegmkzjsr52wyi4u6ery4m74sk3m77oup2ws4ka.b32.i2p:0 -zvgkzfbaqzkxfhc7bnwim3srvcmgwq6ndihhv2zpbymtwkloxm2a.b32.i2p:0 -zvs53qyzauufv33zdsd76tf337kyimj5edep3xqjimhc5t7rfv4q.b32.i2p:0 -zzpgfcs2vuybf4t337fpeidybrsfqkuetvkg353ja3juhjimlmqa.b32.i2p:0 -zzx4goazsdha3hvdzmppxp4sxenhzz6g2mlz3inanbzaw76s7coq.b32.i2p:0 -1.1.189.28:8333 # AS23969 -1.34.178.212:8333 # AS3462 -2.13.146.228:8333 # AS3215 -2.56.245.204:8333 # AS213250 -2.86.50.136:8333 # AS6799 -3.123.190.28:8333 # AS16509 -5.35.15.93:8333 # AS50340 -5.78.108.233:8333 # AS212317 -5.79.71.147:8333 # AS60781 -5.149.248.152:8333 # AS59711 -5.186.60.13:8333 # AS44869 -8.209.97.98:8333 # AS45102 -12.221.144.189:8333 # AS398337 -14.203.57.50:8333 # AS7545 -18.169.180.38:8333 # AS8987 -20.74.80.10:8333 # AS8075 -23.111.172.18:8333 # AS29802 -23.142.145.238:8333 # AS210000 -23.175.0.202:8333 # AS395502 -23.242.4.83:8333 # AS20001 -24.0.172.162:8333 # AS33659 -24.49.240.218:8333 # AS11290 -24.90.140.41:8333 # AS12271 -24.118.34.69:8333 # AS13367 -24.125.96.34:8333 # AS7725 -24.146.33.13:8333 # AS7992 -24.152.147.11:8333 # AS10242 -24.164.176.84:8333 # AS12271 -24.210.23.136:8333 # AS10796 -24.220.72.43:8333 # AS11232 -31.18.200.28:8333 # AS3209 -31.47.202.112:8333 # AS34385 -31.164.229.252:8333 # AS6730 -31.189.53.251:8333 # AS24608 -31.207.53.11:8333 # AS8758 -32.220.61.208:8333 # AS46690 -34.40.131.0:8333 # AS396982 -35.204.253.254:8333 # AS396982 -35.214.111.72:8333 # AS15169 -35.217.18.242:8333 # AS15169 -37.179.155.30:8333 # AS30722 -37.204.171.82:8333 # AS42610 -37.209.87.163:8333 # AS3209 -37.251.41.41:8333 # AS1136 -38.40.110.66:8333 # AS398721 -38.41.59.162:8333 # AS397422 -38.42.237.194:8333 # AS395354 -38.75.215.250:8333 # AS397377 -38.172.75.57:8333 # AS13693 -38.180.242.6:8333 # AS58061 -43.156.93.235:8333 # AS132203 -45.45.27.233:8333 # AS5769 -45.79.223.168:8333 # AS63949 -45.83.220.102:8333 # AS39351 -45.88.106.107:8333 # AS204601 -45.150.66.10:8333 # AS215402 -45.154.252.162:8333 # AS41281 -45.159.230.118:8333 # AS51167 -45.190.192.174:8333 # AS269868 -46.10.215.188:8333 # AS8866 -46.23.87.218:8333 # AS60131 -46.39.187.205:8333 # AS31246 -46.59.13.35:8333 # AS8473 -46.136.116.252:8333 # AS12430 -46.146.231.187:8333 # AS12768 -46.148.235.36:8333 # AS49505 -46.150.161.43:8333 # AS49106 -46.226.18.135:8333 # AS52176 -46.229.238.187:8333 # AS29405 -46.254.212.21:8333 # AS204779 -47.144.231.35:8333 # AS5650 -47.147.169.80:8333 # AS5650 -47.254.178.44:8333 # AS45102 -50.20.212.8:8333 # AS20432 -50.37.113.212:8333 # AS27017 -50.43.49.155:8333 # AS27017 -50.99.219.56:8333 # AS852 -50.125.114.46:8333 # AS20055 -51.159.223.13:8333 # AS12876 -51.194.13.25:8333 # AS5607 -51.255.94.190:8333 # AS16276 -52.165.88.21:8333 # AS8075 -52.205.29.182:8333 # AS14618 -54.170.73.194:8333 # AS16509 -54.211.187.0:8333 # AS14618 -58.96.73.95:8333 # AS10143 -61.7.163.41:8333 # AS131090 -62.12.168.100:8333 # AS15623 -62.57.94.187:8333 # AS6739 -64.31.61.150:8333 # AS46475 -64.67.80.177:8333 # AS3737 -64.156.192.61:8333 # AS21581 -64.187.168.198:8333 # AS11404 -64.226.146.203:8333 # AS26831 -65.183.252.105:8333 # AS15267 -65.190.216.137:8333 # AS11426 -66.29.147.20:8333 # AS22612 -66.30.198.179:8333 # AS7015 -66.35.84.14:8333 # AS2734 -66.37.25.18:8333 # AS19237 -66.37.25.30:8333 # AS19237 -66.94.126.184:8333 # AS40021 -66.228.28.63:8333 # AS11233 -67.80.209.16:8333 # AS6128 -67.144.32.64:8333 # AS19901 -67.145.204.18:8333 # AS19901 -67.240.148.148:8333 # AS11351 -68.37.43.81:8333 # AS33668 -68.41.204.141:8333 # AS33668 -68.54.100.248:8333 # AS13367 -68.172.45.230:8333 # AS11351 -69.59.18.35:8333 # AS397444 -69.64.51.41:8333 # AS30083 -69.67.150.71:8333 # AS262287 -69.172.131.118:8333 # AS3580 -69.246.248.54:8333 # AS33491 -70.121.50.147:8333 # AS11427 -70.122.134.79:8333 # AS11427 -70.127.40.118:8333 # AS33363 -71.29.150.207:8333 # AS7029 -71.52.48.60:8333 # AS209 -71.86.10.194:8333 # AS20115 -71.196.181.115:8333 # AS33652 -72.46.131.18:8333 # AS36114 -72.104.31.113:8333 # AS6167 -73.52.208.234:8333 # AS7016 -73.113.14.233:8333 # AS22909 -73.117.132.138:8333 # AS7016 -73.128.36.145:8333 # AS33657 -73.129.38.38:8333 # AS33657 -73.131.84.183:8333 # AS33489 -73.140.121.110:8333 # AS33650 -73.166.131.61:8333 # AS33662 -73.185.74.222:8333 # AS33667 -73.241.228.74:8333 # AS33651 -74.15.8.154:8333 # AS577 -74.88.231.79:8333 # AS6128 -74.112.115.219:8333 # AS11525 -74.207.168.63:8333 # AS14543 -76.25.208.232:8333 # AS33652 -76.140.90.174:8333 # AS33660 -76.145.236.222:8333 # AS7725 -77.48.31.240:8333 # AS16019 -77.78.126.46:8333 # AS15685 -77.95.229.224:8333 # AS62370 -77.101.237.159:8333 # AS5089 -77.105.164.118:8333 # AS214422 -77.237.238.26:8333 # AS51167 -77.239.42.73:8333 # AS15600 -77.240.190.41:8333 # AS24641 -77.247.178.158:8333 # AS43350 -78.44.219.42:8333 # AS16019 -78.140.183.229:8333 # AS35415 -79.77.133.30:8333 # AS19905 -79.116.189.111:8333 # AS57269 -79.127.230.250:8333 # AS60068 -79.135.106.88:8333 # AS62371 -79.148.50.92:8333 # AS3352 -79.154.247.191:8333 # AS3352 -79.201.52.144:8333 # AS3320 -80.64.211.102:8333 # AS200295 -80.90.4.178:8333 # AS20546 -80.188.97.250:8333 # AS5610 -80.203.83.135:8333 # AS29695 -80.209.231.126:8333 # AS62282 -80.221.244.201:8333 # AS1759 -80.254.174.149:8333 # AS1836 -81.83.214.134:8333 # AS6848 -81.162.196.43:8333 # AS34955 -81.172.214.101:8333 # AS15435 -81.174.2.16:8333 # AS35612 -81.197.182.195:8333 # AS719 -81.229.234.87:8333 # AS3301 -82.4.47.42:8333 # AS5089 -82.64.89.125:8333 # AS12322 -82.64.133.129:8333 # AS12322 -82.96.96.40:8333 # AS29686 -82.136.98.249:8333 # AS8821 -83.69.176.70:8333 # AS42767 -83.168.65.186:8333 # AS31304 -83.253.62.50:8333 # AS1257 -84.20.63.156:8333 # AS21040 -84.32.32.132:8333 # AS204770 -84.32.186.158:8333 # AS59642 -84.75.26.217:8333 # AS6730 -84.115.128.225:8333 # AS8412 -84.217.134.213:8333 # AS2119 -84.255.238.120:8333 # AS34779 -85.7.24.206:8333 # AS3303 -85.14.79.26:8333 # AS31242 -85.147.2.227:8333 # AS33915 -85.159.237.71:8333 # AS43350 -85.163.23.103:8333 # AS28725 -85.195.201.131:8333 # AS13030 -85.195.244.202:8333 # AS13030 -85.198.116.246:8333 # AS29182 -85.208.69.13:8333 # AS42275 -85.208.117.14:8333 # AS18978 -85.214.161.252:8333 # AS6724 -85.215.75.210:8333 # AS8560 -86.84.198.19:8333 # AS1136 -86.97.84.57:8333 # AS5384 -86.104.228.10:8333 # AS45021 -86.104.228.20:8333 # AS45021 -86.111.48.71:8333 # AS50304 -86.136.1.60:8333 # AS2856 -86.157.171.157:8333 # AS2856 -87.211.224.212:8333 # AS13127 -87.228.184.201:8333 # AS6866 -88.85.88.133:8333 # AS35415 -88.99.167.178:8333 # AS24940 -88.101.101.227:8333 # AS5610 -88.119.128.36:8333 # AS8764 -88.137.109.62:8333 # AS15557 -88.201.175.250:8333 # AS35807 -89.24.174.30:8333 # AS13036 -89.39.141.90:8333 # AS56478 -89.58.70.141:8333 # AS44656 -89.129.78.173:8333 # AS12479 -89.207.131.19:8333 # AS62370 -89.247.224.28:8333 # AS8881 -89.250.73.38:8333 # AS41420 -90.89.251.147:8333 # AS3215 -90.156.26.148:8333 # AS43939 -90.250.10.165:8333 # AS5378 -91.92.152.118:8333 # AS61098 -91.110.16.244:8333 # AS12576 -91.123.182.164:8333 # AS51648 -91.132.42.25:8333 # AS206238 -91.183.207.58:8333 # AS5432 -91.194.12.244:8333 # AS42995 -91.202.4.65:8333 # AS43641 -91.231.182.94:8333 # AS214379 -91.235.255.7:8333 # AS198509 -91.236.251.137:8333 # AS57944 -92.96.219.197:8333 # AS5384 -92.101.99.58:8333 # AS12389 -92.186.67.107:8333 # AS12479 -92.205.232.47:8333 # AS21499 -92.206.105.31:8333 # AS16202 -92.240.185.182:8333 # AS16246 -93.28.33.141:8333 # AS198949 -93.55.255.176:8333 # AS12874 -93.123.180.164:8333 # AS35539 -93.160.66.70:8333 # AS3292 -93.174.188.110:8333 # AS47506 -93.177.188.74:8333 # AS16010 -93.189.25.250:8333 # AS44133 -93.190.143.76:8333 # AS49981 -94.19.128.204:8333 # AS35807 -94.54.154.209:8333 # AS47524 -94.60.103.81:8333 # AS12353 -94.74.105.231:8333 # AS136907 -94.79.55.28:8333 # AS48614 -94.136.185.80:8333 # AS141995 -94.154.159.99:8333 # AS62240 -94.157.34.0:8333 # AS50266 -94.210.254.143:8333 # AS33915 -95.82.130.223:8333 # AS31246 -95.83.73.31:8333 # AS35728 -95.98.239.70:8333 # AS50266 -95.105.192.217:8333 # AS15962 -95.168.169.227:8333 # AS60781 -95.169.196.247:8333 # AS201133 -95.179.216.148:8333 # AS20473 -95.213.145.218:8333 # AS49505 -95.214.235.86:8333 # AS30860 -96.41.133.58:8333 # AS20115 -96.43.142.163:8333 # AS19969 -96.53.92.166:8333 # AS6327 -96.77.181.25:8333 # AS33660 -96.81.219.106:8333 # AS33491 -96.238.29.2:8333 # AS701 -97.75.144.9:8333 # AS22709 -97.119.208.128:8333 # AS209 -98.56.168.78:8333 # AS33667 -98.143.182.206:8333 # AS23481 -98.168.198.50:8333 # AS22773 -98.169.1.164:8333 # AS22773 -98.195.93.125:8333 # AS33662 -99.184.57.234:8333 # AS7018 -99.229.184.94:8333 # AS812 -99.248.151.172:8333 # AS812 -101.47.131.207:8333 # AS150436 -101.99.88.33:8333 # AS19324 -101.100.139.249:8333 # AS9790 -101.173.27.162:8333 # AS1221 -103.74.116.139:8333 # AS63759 -103.99.169.110:8333 # AS54415 -103.99.171.171:8333 # AS54415 -103.231.42.36:8333 # AS18229 -103.233.83.28:8333 # AS4213 -103.246.186.143:8333 # AS401199 -103.246.186.234:8333 # AS401199 -104.143.2.195:8333 # AS26863 -104.200.67.161:8333 # AS8100 -104.243.38.148:8333 # AS23470 -106.246.195.13:8333 # AS3786 -107.13.105.120:8333 # AS11426 -107.173.244.87:8333 # AS36352 -107.178.115.244:8333 # AS3223 -108.20.173.160:8333 # AS701 -108.170.133.169:8333 # AS40788 -108.175.176.253:8333 # AS21565 -108.181.55.173:8333 # AS40676 -109.130.50.200:8333 # AS5432 -109.190.58.34:8333 # AS35540 -109.190.140.89:8333 # AS35540 -111.90.158.46:8333 # AS19324 -114.4.204.184:8333 # AS4761 -115.85.88.107:8333 # AS23953 -116.58.171.67:8333 # AS2514 -118.67.199.102:8333 # AS64073 -121.98.22.147:8333 # AS9790 -122.32.38.201:8333 # AS17858 -122.37.248.225:8333 # AS17858 -122.155.9.25:8333 # AS9335 -124.241.11.196:8333 # AS17961 -125.77.173.152:8333 # AS133776 -128.0.98.214:8333 # AS42652 -129.13.189.215:8333 # AS34878 -129.151.196.119:8333 # AS31898 -129.213.158.163:8333 # AS31898 -130.44.176.111:8333 # AS6079 -131.153.232.61:8333 # AS19437 -131.153.242.129:8333 # AS19437 -132.147.192.5:8333 # AS10750 -135.23.202.6:8333 # AS5645 -135.129.105.93:8333 # AS394195 -135.181.180.80:8333 # AS24940 -136.28.1.41:8333 # AS19165 -136.56.56.93:8333 # AS16591 -136.62.243.153:8333 # AS16591 -139.84.193.137:8333 # AS20473 -141.98.81.120:8333 # AS209588 -141.98.219.12:8333 # AS20326 -142.117.176.19:8333 # AS577 -143.110.231.111:8333 # AS14061 -144.2.72.68:8333 # AS57370 -144.2.104.35:8333 # AS57370 -144.6.192.154:8333 # AS4764 -144.126.147.55:8333 # AS40021 -146.0.74.196:8333 # AS57043 -146.70.49.38:8333 # AS9009 -146.71.69.103:8333 # AS396006 -147.28.163.54:8333 # AS54825 -147.28.185.150:8333 # AS54825 -147.32.95.62:8333 # AS2852 -148.113.159.109:8333 # AS16276 -148.163.68.23:8333 # AS3223 -149.7.16.137:8333 # AS63023 -149.143.32.144:8333 # AS15435 -151.115.74.102:8333 # AS12876 -151.236.34.245:8333 # AS29550 -151.248.167.250:8333 # AS8821 -152.42.229.252:8333 # AS14061 -152.53.18.161:8333 # AS197540 -152.53.37.21:8333 # AS42473 -154.57.6.171:8333 # AS200736 -156.57.38.205:8333 # AS855 -157.131.74.56:8333 # AS1299 -159.138.87.18:8333 # AS136907 -159.246.25.53:8333 # AS30491 -161.29.221.26:8333 # AS140220 -162.120.69.182:8333 # AS62240 -162.156.205.178:8333 # AS852 -162.207.122.215:8333 # AS7018 -163.123.215.229:8333 # AS63152 -164.152.167.208:8333 # AS59253 -165.173.18.251:8333 # AS56300 -166.70.65.79:8333 # AS6315 -167.224.189.201:8333 # AS395662 -167.248.185.196:8333 # AS398721 -169.150.206.200:8333 # AS60068 -170.39.103.163:8333 # AS33724 -170.205.178.76:8333 # AS22646 -172.92.108.184:8333 # AS11404 -172.96.142.246:8333 # AS23470 -172.234.29.229:8333 # AS63949 -172.241.70.236:8333 # AS7979 -173.23.232.48:8333 # AS30036 -173.164.210.49:8333 # AS33651 -173.169.42.150:8333 # AS33363 -173.208.166.82:8333 # AS32097 -173.208.236.58:8333 # AS32097 -173.236.10.158:8333 # AS32475 -173.241.227.243:8333 # AS19009 -174.2.93.93:8333 # AS6327 -174.177.29.211:8333 # AS22909 -175.41.191.135:8333 # AS8987 -176.57.213.53:8333 # AS9123 -176.99.2.90:8333 # AS197695 -176.113.167.35:8333 # AS56835 -176.166.34.226:8333 # AS5410 -176.172.173.205:8333 # AS5410 -177.39.12.242:8333 # AS52790 -178.115.246.157:8333 # AS25255 -178.143.180.249:8333 # AS15962 -178.192.9.193:8333 # AS3303 -178.232.204.112:8333 # AS25400 -178.250.232.111:8333 # AS31197 -179.43.172.23:8333 # AS51852 -179.214.122.129:8333 # AS28573 -180.150.46.187:8333 # AS4764 -184.56.122.69:8333 # AS10796 -184.83.140.189:8333 # AS11232 -184.105.131.181:8333 # AS6939 -184.162.91.24:8333 # AS5769 -185.8.106.179:8333 # AS204770 -185.31.136.172:8333 # AS60414 -185.63.97.216:8333 # AS50825 -185.68.249.91:8333 # AS51184 -185.70.43.192:8333 # AS62371 -185.87.191.80:8333 # AS199736 -185.92.72.157:8333 # AS200904 -185.95.37.16:8333 # AS200799 -185.119.118.68:8333 # AS44133 -185.133.42.54:8333 # AS57494 -185.143.48.4:8333 # AS20742 -185.148.146.24:8333 # AS44901 -185.150.160.208:8333 # AS34197 -185.156.37.30:8333 # AS202605 -185.161.6.75:8333 # AS43915 -185.181.230.117:8333 # AS60602 -185.194.93.135:8333 # AS197869 -185.197.160.61:8333 # AS60144 -185.251.88.100:8333 # AS35278 -186.75.66.162:8333 # AS11556 -188.68.54.170:8333 # AS197540 -188.120.222.69:8333 # AS49985 -188.138.88.47:8333 # AS8972 -188.212.113.16:8333 # AS206238 -188.214.129.26:8333 # AS16125 -188.214.129.217:8333 # AS16125 -188.237.167.51:8333 # AS8926 -190.64.134.52:8333 # AS6057 -192.3.11.20:8333 # AS36352 -192.119.148.210:8333 # AS393892 -192.145.127.190:8333 # AS9009 -192.187.121.46:8333 # AS33387 -192.227.73.9:8333 # AS13886 -192.243.215.102:8333 # AS63297 -193.22.128.10:8333 # AS56469 -193.22.128.12:8333 # AS56469 -193.72.32.187:8333 # AS33965 -193.238.16.12:8333 # AS39907 -194.1.163.112:8333 # AS8298 -194.14.247.35:8333 # AS50066 -194.106.127.43:8333 # AS3249 -194.233.69.180:8333 # AS141995 -195.62.52.19:8333 # AS44812 -195.133.68.203:8333 # AS48614 -195.139.85.46:8333 # AS2116 -195.189.97.38:8333 # AS59642 -195.216.214.27:8333 # AS25057 -197.87.144.126:8333 # AS3741 -197.155.6.43:8333 # AS37199 -198.16.178.88:8333 # AS1403 -199.85.210.133:8333 # AS22612 -199.230.127.169:8333 # AS398844 -201.131.200.50:8333 # AS28387 -202.177.24.140:8333 # AS7479 -203.123.97.227:8333 # AS38195 -203.132.94.196:8333 # AS38195 -204.15.11.35:8333 # AS13331 -204.16.245.163:8333 # AS20326 -204.83.161.154:8333 # AS803 -204.107.27.48:8333 # AS54303 -204.194.220.39:8333 # AS20055 -205.209.118.254:8333 # AS19318 -206.204.104.6:8333 # AS212947 -206.204.106.8:8333 # AS212947 -207.47.156.175:8333 # AS803 -207.158.15.96:8333 # AS21581 -207.178.119.175:8333 # AS27425 -207.182.146.85:8333 # AS10297 -208.53.32.26:8333 # AS13767 -209.59.150.4:8333 # AS32244 -209.71.50.11:8333 # AS20259 -209.141.37.57:8333 # AS53667 -209.205.204.210:8333 # AS55081 -209.227.228.193:8333 # AS31034 -209.253.210.114:8333 # AS7029 -210.179.103.74:8333 # AS4766 -211.58.126.101:8333 # AS9318 -212.24.104.116:8333 # AS62282 -212.39.67.41:8333 # AS8866 -212.86.55.47:8333 # AS15366 -212.90.85.145:8333 # AS16086 -212.112.65.254:8333 # AS48815 -212.159.75.247:8333 # AS6871 -212.227.211.87:8333 # AS8560 -212.241.94.177:8333 # AS1299 -212.251.164.10:8333 # AS2119 -213.14.190.184:8333 # AS34984 -213.139.207.219:8333 # AS395092 -213.183.46.51:8333 # AS56630 -216.41.130.41:8333 # AS396287 -216.53.190.99:8333 # AS14288 -216.172.82.150:8333 # AS53818 -216.219.91.82:8333 # AS19318 -216.226.128.189:8333 # AS13706 -217.15.178.11:8333 # AS25534 -217.20.131.64:8333 # AS5483 -217.23.3.251:8333 # AS49981 -217.79.247.130:8333 # AS29802 -217.94.254.57:8333 # AS3320 -217.173.236.25:8333 # AS20634 -217.180.216.148:8333 # AS30600 -218.39.61.122:8333 # AS9318 -218.102.232.50:8333 # AS4760 -220.86.25.1:8333 # AS4766 -[2001:13d8:1c01:21:215:17ff:fe63:2a7e]:8333 # AS3790 -[2001:1620:542c:210::100]:8333 # AS13030 -[2001:1620:5566:100::62c]:8333 # AS13030 -[2001:18b8:0:100:0:b00b:420:69]:8333 # AS29789 -[2001:1970:5a22:4500::4f9c]:8333 # AS7992 -[2001:19f0:4401:e8a:5400:4ff:fe8e:d398]:8333 # AS20473 -[2001:19f0:5000:1a80:5400:4ff:fe71:aac5]:8333 # AS20473 -[2001:19f0:5:2b12:5400:4ff:fe6e:3afe]:8333 # AS20473 -[2001:19f0:5:5b81:5e6f:69ff:fe57:94d0]:8333 # AS20473 -[2001:19f0:6801:6ec:2::1]:8333 # AS20473 -[2001:19f0:c800:2ce5:5400:4ff:fed7:663d]:8333 # AS20473 -[2001:19f0:c:6da:5e6f:69ff:fe56:a650]:8333 # AS20473 -[2001:1bc0:c1::2000]:8333 # AS29686 -[2001:2043:180e:400::47]:8333 # AS3301 -[2001:250:1001:1621:401a:5c40:322f:9ea3]:8333 # AS24353 -[2001:4060:4419:8001::42]:8333 # AS6772 -[2001:41d0:2:7b3d::1]:8333 # AS16276 -[2001:41d0:2:7ba8::]:8333 # AS16276 -[2001:41d0:602:34f0::1]:8333 # AS16276 -[2001:41d0:800:10c0::]:8333 # AS16276 -[2001:41d0:800:364d::]:8333 # AS16276 -[2001:448a:2071:150d:1c3f:135e:6675:a69b]:8333 # AS7713 -[2001:470:1a34:2:a804:86ff:fec2:863a]:8333 # AS6939 -[2001:470:1f0a:89a::2]:8333 # AS6939 -[2001:470:28:b17::2]:8333 # AS6939 -[2001:470:7984::1337]:8333 # AS6939 -[2001:470:88ff:2e::1]:8333 # AS6939 -[2001:470:8a71:2::200]:8333 # AS6939 -[2001:470:8ca0:2:7646:a0ff:fe9b:e662]:8333 # AS6939 -[2001:470:a:c13::2]:8333 # AS6939 -[2001:470:da72::2:3]:8333 # AS6939 -[2001:470:dee0:1::3]:8333 # AS6939 -[2001:4dd0:3564:0:30b7:1d7b:6fec:4c5c]:8333 # AS8422 -[2001:4dd0:3564:0:88e:b4ff:2ad0:699b]:8333 # AS8422 -[2001:4dd0:3564:0:9c1c:cc31:9fe8:5505]:8333 # AS8422 -[2001:4dd0:3564:0:a0c4:d41f:4c4:1bb0]:8333 # AS8422 -[2001:4dd0:3564:0:fd76:c1d3:1854:5bd9]:8333 # AS8422 -[2001:4dd0:3564:1::7676:8090]:8333 # AS8422 -[2001:4dd0:3564:1:b977:bd71:4612:8e40]:8333 # AS8422 -[2001:4dd0:af0e:3564:0:69:90:8333]:8333 # AS8422 -[2001:4dd0:af0e:3564::69:1]:8333 # AS8422 -[2001:4dd0:af0e:3564::69:90]:8333 # AS8422 -[2001:550:af00:7:0:1:aff9:18]:8333 # AS174 -[2001:569:5079:abd2::c9]:8333 # AS852 -[2001:569:713f:4800:e9af:dd81:7b94:f105]:8333 # AS852 -[2001:569:bed3:3100:ac3e:c5d8:c4e:56fe]:8333 # AS852 -[2001:5a8:40db:2000:8668:a702:c89:bdd4]:8333 # AS7065 -[2001:5a8:40db:2000:867b:8aa6:2010:879a]:8333 # AS7065 -[2001:5a8:4164:7a00::506]:8333 # AS7065 -[2001:5a8:60c0:d500::7840]:8333 # AS7065 -[2001:648:2800:131:4b1f:f6fc:20f7:f99f]:8333 # AS5470 -[2001:678:68c:fffb::195]:8333 # AS13259 -[2001:678:d78:22d0:5065:c1ff:fef2:3f65]:8333 # AS8298 -[2001:67c:1220:808::93e5:81f]:8333 # AS197451 -[2001:67c:1254:d2:6b9c::1]:8333 # AS4455 -[2001:67c:26b4:ff00::44]:8333 # AS57672 -[2001:67c:440:688:91:236:251:137]:8333 # AS57944 -[2001:67c:440:f887:194:147:140:37]:8333 # AS57944 -[2001:7c0:2310:0:f816:3eff:fe6c:4f58]:8333 # AS34878 -[2001:8003:d117:3500:bfc5:7e90:9da5:a8c0]:8333 # AS1221 -[2001:818:df59:5800:f8a4:ceff:fefd:d63a]:8333 # AS12353 -[2001:818:e9f4:5400:e65f:1ff:fecd:69ad]:8333 # AS12353 -[2001:861:3200:64a0:92b1:1cff:fe91:137f]:8333 # AS5410 -[2001:8b0:ba7b:c965::8:85]:8333 # AS20712 -[2001:8f8:1b69:13ef:48ab:74ff:fe36:2313]:8333 # AS8966 -[2001:a61:101b:b201:dea6:32ff:fefb:f7da]:8333 # AS8767 -[2001:b011:7008:31b7:9624:d01c:8f94:e6f7]:8333 # AS3462 -[2001:b030:2422::208d]:8333 # AS3462 -[2001:b07:5d2e:3604:1125:c712:2aac:5c0]:8333 # AS12874 -[2001:b07:6440:3a98:a280:5d86:d5a3:3fc4]:8333 # AS12874 -[2001:b07:644c:1b5a:566f:23e4:9a34:a619]:8333 # AS12874 -[2001:b07:6461:7811:489:d2da:e07:1af7]:8333 # AS12874 -[2001:b07:646d:caf:3c06:693f:73a9:e71b]:8333 # AS12874 -[2001:b07:6474:51d8:6156:84e7:397a:a847]:8333 # AS12874 -[2001:b07:6474:51d8:c27e:427e:fe37:6356]:8333 # AS12874 -[2001:b07:6474:51d8:f31f:fdc:1c90:67ac]:8333 # AS12874 -[2001:b07:ae6:3b99:7270:fcff:fe02:33c0]:8333 # AS12874 -[2001:bc8:1201:701:ca1f:66ff:fec9:221c]:8333 # AS12876 -[2001:bc8:1201:715:ca1f:66ff:fec9:5ff0]:8333 # AS12876 -[2001:bc8:1201:71a:2e59:e5ff:fe42:52f4]:8333 # AS12876 -[2001:bc8:1201:900:46a8:42ff:fe26:9501]:8333 # AS12876 -[2001:bc8:1600:0:208:a2ff:fe0c:8a2e]:8333 # AS12876 -[2001:bc8:3e54:6b02::1]:8333 # AS12876 -[2001:bc8:610:9:46a8:42ff:fe0c:d385]:8333 # AS12876 -[2001:bc8:701:409:b683:51ff:fe06:75f4]:8333 # AS12876 -[2001:bc8:701:40d:ae16:2dff:fea6:e868]:8333 # AS12876 -[2001:e68:541b:9472:c86:6c6b:8f1e:eb8d]:8333 # AS4788 -[2001:f40:94e:426:7270:fcff:fe05:3cd]:8333 # AS9930 -[2003:c0:6f34:d600:201:2eff:fe6b:c20c]:8333 # AS3320 -[2003:ca:e74b:ea58:dea6:32ff:fe26:b6fb]:8333 # AS3320 -[2003:d6:270a:ea00:5a47:caff:fe73:450c]:8333 # AS3320 -[2003:e6:3742:b00:9209:d0ff:fe0f:9ea7]:8333 # AS3320 -[2003:f0:df07:c202:aaa1:59ff:fe57:7779]:8333 # AS3320 -[2003:f6:3f48:7000:4c9f:7620:8324:d4a7]:8333 # AS3320 -[2400:3b00:20:c:bacb:29ff:feab:8886]:8333 # AS18229 -[2400:4053:1203:3f00:1:1:1:134]:8333 # AS4713 -[2400:6180:0:d2::78b7:6000]:8333 # AS14061 -[2400:6180:0:d2::fd91:9000]:8333 # AS14061 -[2400:8901::f03c:92ff:fe3e:e1d6]:8333 # AS63949 -[2400:8901::f03c:92ff:fe4e:95f3]:8333 # AS63949 -[2400:8902::f03c:94ff:fe53:568]:8333 # AS63949 -[2400:8905::f03c:94ff:fecc:1466]:8333 # AS48337 -[2400:8907::f03c:94ff:fed9:9696]:8333 # AS63949 -[2400:a848:4045:1:be24:11ff:fe88:7852]:8333 # AS134090 -[2400:adc1:18e:7c00:8243:2452:89af:6cbb]:8333 # AS9541 -[2400:d321:2231:5973::1]:8333 # AS141995 -[2401:b140:1::100:220]:8333 # AS54415 -[2401:b140:3::44:110]:8333 # AS54415 -[2401:b140:3::44:120]:8333 # AS54415 -[2401:d002:2103:400:211:32ff:fe9e:7ae3]:8333 # AS38195 -[2401:d002:3902:700:d72c:5e22:4e95:389d]:8333 # AS38195 -[2402:1f00:8000:21a::]:8333 # AS16276 -[2402:a7c0:8100:a015::6f2:79a5]:8333 # AS59253 -[2403:580c:c505:0:6955:67d3:6229:88e7]:8333 # AS4764 -[2403:71c0:2000:b3e0::101]:8333 # AS23959 -[2403:71c0:2000:b3e0::7693]:8333 # AS23959 -[2404:4400:411a:6000::7d73]:8333 # AS9790 -[2404:4400:416c:f400:4a21:bff:fe32:571]:8333 # AS9790 -[2404:4408:6397:8201::250]:8333 # AS9790 -[2404:7a81:17a0:f000:e4b1:aef3:2a2e:d54]:8333 # AS2518 -[2405:6582:de0:4400:8ce:2b80:2960:7b4e]:8333 # AS4685 -[2405:6582:de0:4400:f:854d:5057:4fc9]:8333 # AS4685 -[2406:3400:31f:61d0:b7f5:6b3e:2241:bc44]:8333 # AS10143 -[2406:3400:31f:61d0:f25b:ae67:d9ed:b31c]:8333 # AS10143 -[2406:3400:912:4940:1e45:e8cc:2d24:8250]:8333 # AS10143 -[2406:da14:335:b600:38cc:a776:1818:1285]:8333 # AS16509 -[2407:3640:2107:1278::1]:8333 # AS141995 -[2407:8800:bc61:2220:3cf5:57ac:851b:2b1e]:8333 # AS7545 -[2407:8800:bc61:2220:555b:7e78:78a0:eb32]:8333 # AS7545 -[2408:820c:a93a:8f00:101b:7dc4:98f9:e065]:8333 # AS17621 -[2408:824c:3618:e8f1:d43c:7c0f:6300:dd39]:8333 # AS4837 -[2409:8a44:9116:2740:63b0:124d:1ce7:8836]:8333 # AS24445 -[240b:11:5501:5e00:10f2:46c7:c6f6:6e25]:8333 # AS2516 -[240b:250:2221:b100:f0fb:1424:b379:5c1]:8333 # AS2516 -[2600:1015:a032:1ca1:8c04:c837:a14:b1da]:8333 # AS6167 -[2600:1700:488:10::421]:8333 # AS7018 -[2600:1700:488:10::614]:8333 # AS7018 -[2600:1700:5453:69e::109]:8333 # AS7018 -[2600:1700:5af3:2c10:46a8:42ff:fe08:5835]:8333 # AS7018 -[2600:1700:6f20:abc4::c65]:8333 # AS7018 -[2600:1700:944c:e00f:2a27:f664:1801:599f]:8333 # AS7018 -[2600:1700:e41:2040:9ab7:85ff:fe20:621]:8333 # AS7018 -[2600:1700:ec7b:5730::48]:8333 # AS7018 -[2600:1702:57f0:11c0::19d8]:8333 # AS7018 -[2600:1702:6d33:ec10::22]:8333 # AS7018 -[2600:1900:4000:7be1::]:8333 # AS396982 -[2600:1900:4020:65f:0:1::]:8333 # AS396982 -[2600:1900:4060:40b::]:8333 # AS396982 -[2600:1900:4090:5db:0:1::]:8333 # AS396982 -[2600:1900:40b0:3af2::]:8333 # AS396982 -[2600:1900:40c0:5470:0:1::]:8333 # AS396982 -[2600:1900:40e0:3cdc::]:8333 # AS396982 -[2600:1900:40f0:964b::]:8333 # AS396982 -[2600:1900:4170:ca4e::]:8333 # AS396982 -[2600:1901:8170:4bb:0:1::]:8333 # AS396982 -[2600:1f14:40e:e300:c97e:fc1c:c0db:fe83]:8333 # AS16509 -[2600:1f14:40e:e300:cf69:2dac:5fa1:19fa]:8333 # AS16509 -[2600:1f18:64d9:1603:4436:871e:2bfe:7403]:8333 # AS14618 -[2600:1f18:66fc:d700:214c:9628:5325:67fc]:8333 # AS14618 -[2600:1f18:66fc:d700:3ea6:7dc2:83c6:cd91]:8333 # AS14618 -[2600:1f18:66fc:d700:be6f:27a6:7449:b1c3]:8333 # AS14618 -[2600:1f18:66fc:d700:fb0f:3b9d:a7c9:84cd]:8333 # AS14618 -[2600:1f18:719a:e302:2758:8042:929f:a384]:8333 # AS14618 -[2600:1f18:719a:e302:4c90:e1e6:2a59:82c4]:8333 # AS14618 -[2600:1f18:719a:e302:e6c0:8878:401c:27c2]:8333 # AS14618 -[2600:1f18:719a:e302:ef0c:40ab:f8f:6d6c]:8333 # AS14618 -[2600:2104:1003:c5ab:dc5e:90ff:fe18:1d08]:8333 # AS11404 -[2600:3c00::f03c:94ff:fe7c:86e2]:8333 # AS63949 -[2600:3c00::f03c:94ff:feb7:4dd7]:8333 # AS63949 -[2600:3c02::f03c:92ff:fe5d:9fb]:8333 # AS63949 -[2600:3c02::f03c:93ff:fe14:a4f2]:8333 # AS63949 -[2600:3c0e::f03c:94ff:fe63:2e90]:8333 # AS63949 -[2600:3c0e::f03c:94ff:fe72:bfe0]:8333 # AS63949 -[2600:6c4e:a00:cd0:428d:5cff:fe58:4884]:8333 # AS20115 -[2600:6c54:7100:1ad1:c92e:36d:651:bd18]:8333 # AS20115 -[2600:6c67:2100:670:b179:be4c:8cca:e8f0]:8333 # AS33588 -[2600:8801:2f80:ac::173e]:8333 # AS22773 -[2600:8806:2101:9a80:c2f5:5e1:445a:bb74]:8333 # AS22773 -[2601:147:4c80:c97:3eec:efff:fe79:3b74]:8333 # AS33657 -[2601:185:8301:d9d0:61a2:a7e4:bfc9:f771]:8333 # AS7015 -[2601:246:4d7f:83e9:d74b:87c9:b119:cf8b]:8333 # AS33491 -[2601:280:5c00:43d:4aba:4eff:fef8:6e5d]:8333 # AS33652 -[2601:41:c200:bf0b:92b1:1cff:fe96:b198]:8333 # AS33287 -[2601:41:c300:f109:2e44:fdff:fe0e:68ca]:8333 # AS33287 -[2601:602:d200:19f8:86a6:59a9:2976:2dfd]:8333 # AS33650 -[2601:603:5300:83b7:0:ff:fe00:4209]:8333 # AS33650 -[2601:645:c680:5be:e0a4:381d:a60:b498]:8333 # AS33651 -[2602:47:d441:5e01:52eb:f6ff:fe7f:f0db]:8333 # AS209 -[2602:61:7800:9300::1]:8333 # AS209 -[2602:f996:4:4000:be24:11ff:fee0:6f6a]:8333 # AS13717 -[2602:fa59:6:f6::1]:8333 # AS14956 -[2602:fc16:3:65::62b5]:8333 # AS203380 -[2602:fd23:3:1::1:213]:8333 # AS33185 -[2602:fd72:20e:9c00:213:efff:fef5:f172]:8333 # AS2740 -[2602:fec3:0:1::69]:8333 # AS62563 -[2602:fec3:101:1::5:73]:8333 # AS62563 -[2602:ffb6:4:739e:f816:3eff:fe00:c2b3]:8333 # AS174 -[2602:ffb6:4:7b8e:f816:3eff:fe9d:9dc2]:8333 # AS174 -[2602:ffc5:200:1e01:241d:e589:9650:c773]:8333 # AS20473 -[2603:3003:11b:e100:20c:29ff:fe38:bbc0]:8333 # AS33657 -[2603:3003:4eac:100:4e5f:e7a6:2059:91d8]:8333 # AS33657 -[2603:3005:418e:8100:3af7:cdff:feca:1af8]:8333 # AS7015 -[2603:3005:418e:8100::9a8a]:8333 # AS7015 -[2603:3005:549d:2201:20b5:71ff:fedc:bc9a]:8333 # AS7015 -[2603:300a:912:627a:be24:11ff:fe7b:39c3]:8333 # AS33491 -[2603:3020:708:6e00:4f6:a091:350c:cbcb]:8333 # AS20214 -[2603:3024:1828:1ac1::83]:8333 # AS33651 -[2603:3024:18ee:8000:20e:c4ff:fed1:ef15]:8333 # AS33651 -[2603:3024:2005:8000:85f4:879d:4710:1110]:8333 # AS33651 -[2603:800c:700:6a43:5b80:9ce0:a54:8b95]:8333 # AS20001 -[2603:8080:1f07:6fdd:7de2:d969:78c9:b7ea]:8333 # AS11427 -[2603:8081:6c00:4bbc:215:5dff:fe02:1555]:8333 # AS11427 -[2603:80a0:700:1886::39]:8333 # AS11427 -[2603:9001:3600:1902::b]:8333 # AS33363 -[2604:2dc0:100:24ce::]:8333 # AS16276 -[2604:4500:6:285::18]:8333 # AS29802 -[2604:55c0:100:222::2]:8333 # AS4138 -[2604:86c0:3001:5::12:73]:8333 # AS63023 -[2604:a00:50:39:c514:becd:bece:ad3a]:8333 # AS19318 -[2604:a880:2:d1::63:4001]:8333 # AS14061 -[2604:a880:400:d1::849:6001]:8333 # AS14061 -[2604:a880:800:c1::233:1]:8333 # AS14061 -[2604:a880:cad:d0::75b2:3001]:8333 # AS14061 -[2604:a880:cad:d0::75b2:3002]:8333 # AS14061 -[2605:1080:0:f00::70]:8333 # AS23367 -[2605:21c0:2000:11:204:194:220:40]:8333 # AS20055 -[2605:3380:422e:1::50]:8333 # AS397444 -[2605:59c8:2666:1a00::113c]:8333 # AS14593 -[2605:59c8:325:b800:2efd:a1ff:fedc:f8d4]:8333 # AS14593 -[2605:59c8:788:5000:5054:ff:feb8:380]:8333 # AS14593 -[2605:6400:30:f220::]:8333 # AS53667 -[2605:6440:d000:252:ae1f:6bff:fef5:2d86]:8333 # AS396356 -[2605:6f80:0:7:fc1b:ccff:fe8a:d822]:8333 # AS36114 -[2605:a140:2228:8423::1]:8333 # AS51167 -[2605:a143:2162:7067::1]:8333 # AS51167 -[2605:ae00:203::203]:8333 # AS7819 -[2606:6d00:194:f03:3d2:f06a:c2e8:a54]:8333 # AS1403 -[2607:4480:2:1:38:102:69:70]:8333 # AS40470 -[2607:5300:203:293e::1]:8333 # AS16276 -[2607:5300:60:614::1]:8333 # AS16276 -[2607:5300:60:7477::]:8333 # AS16276 -[2607:9280:b:73b:250:56ff:fe14:25b5]:8333 # AS395502 -[2607:9280:b:73b:250:56ff:fe21:9c2f]:8333 # AS395502 -[2607:9280:b:73b:250:56ff:fe21:bf32]:8333 # AS395502 -[2607:9280:b:73b:250:56ff:fe33:4d1b]:8333 # AS395502 -[2607:9280:b:73b:250:56ff:fe3d:401]:8333 # AS395502 -[2607:f2c0:e7b1:fac0::444b]:8333 # AS5645 -[2607:f2c0:f00e:300::54]:8333 # AS5645 -[2607:fe90:4:b6:a001:3fff:fef2:8770]:8333 # AS19237 -[2607:fea8:601e:7d01:be24:11ff:fe89:27f3]:8333 # AS812 -[2620:11c:5001:1118:d267:e5ff:fee9:e673]:8333 # AS13331 -[2620:11c:5001:2199:d267:e5ff:fee9:e673]:8333 # AS13331 -[2620:6:2003:105:67c:16ff:fe51:58bf]:8333 # AS395460 -[2620:6e:a000:1:42:42:42:42]:8333 # AS397444 -[2620:a6:2000:1:1:0:d:7f1d]:8333 # AS27566 -[2800:150:11d:1093:c9e3:1ef4:bc4:250d]:8333 # AS22047 -[2800:40:17:ccb:abfd:6021:2e22:e11e]:8333 # AS16814 -[2800:40:38:cfef:a236:bcff:fe58:b6ec]:8333 # AS16814 -[2800:40:74:4b8b:f673:db63:6f6f:2310]:8333 # AS16814 -[2800:40:79:fa39:930c:ace4:77fa:a15f]:8333 # AS16814 -[2800:cd0:7b14:b400:c090:e030:50ea:5fee]:8333 # AS6568 -[2803:9800:9003:babc:1188:44f0:b55d:79e4]:8333 # AS11664 -[2803:9800:9447:84bb:325a:3aff:fe6b:f795]:8333 # AS11664 -[2803:9800:a007:8391:1fd7:c263:a55b:b9fb]:8333 # AS11664 -[2804:14c:87e0:8e2e:6aca:9e19:8c0d:bfd7]:8333 # AS28573 -[2804:431:e038:cd01:aaa1:59ff:fe0d:44b8]:8333 # AS27699 -[2804:d45:b01c:be00:797b:b8d2:fb39:45]:8333 # AS7738 -[2804:d4b:7d55:5800:32b9:6a01:dea3:7a4]:8333 # AS7738 -[2804:d56:e88:7300:fcf5:a432:eb7:c2d4]:8333 # AS8167 -[2806:267:148a:1d10:5e4:fde0:8744:8c17]:8333 # AS13999 -[2806:2f0:5680:fd99:1088:b524:75e3:49d5]:8333 # AS17072 -[2a00:1169:114:dc00::]:8333 # AS21499 -[2a00:1190:c013::be:1337]:8333 # AS16302 -[2a00:1298:8001::6542]:8333 # AS5578 -[2a00:12d8:7005::1e]:8333 # AS12586 -[2a00:12e0:101:99:20c:29ff:fe29:d03f]:8333 # AS6798 -[2a00:1398:4:2a03:3eec:efff:fe05:d93e]:8333 # AS34878 -[2a00:1398:4:2a03::bc03]:8333 # AS34878 -[2a00:13a0:3015:1:85:14:79:26]:8333 # AS31242 -[2a00:1768:2001:27::ef6a]:8333 # AS43350 -[2a00:1a08:ffff:5::11]:8333 # AS25534 -[2a00:1f40:5001:108:5d17:7703:b0f5:4133]:8333 # AS42864 -[2a00:23c5:fe80:7301:d6ae:52ff:fed5:56a5]:8333 # AS2856 -[2a00:4d80::1]:8333 # AS43150 -[2a00:5980:93::135]:8333 # AS197869 -[2a00:6020:4722:8920:5054:ff:fe06:56cf]:8333 # AS60294 -[2a00:6020:4722:8920::1b05]:8333 # AS60294 -[2a00:6020:4914:5700:db31:ca50:797:c468]:8333 # AS60294 -[2a00:6020:4a80:6978::10]:8333 # AS60294 -[2a00:6020:509e:a400:211:32ff:fe5c:369c]:8333 # AS60294 -[2a00:6020:a79f:8700:52eb:f6ff:feef:6e1f]:8333 # AS60294 -[2a00:6020:b406:e00:79e:9ad6:9181:ebb8]:8333 # AS60294 -[2a00:6020:b489:2000:42:c0ff:fea8:b209]:8333 # AS60294 -[2a00:7c80:0:4e::2]:8333 # AS49981 -[2a00:7c80:0:4e:b7c0::2001]:8333 # AS49981 -[2a00:8a60:e012:a00::9001]:8333 # AS47610 -[2a00:bbe0:0:221f::246]:8333 # AS60414 -[2a00:c6c0:0:142:1::1]:8333 # AS47172 -[2a00:d420:8:5d00:69c2:164b:29d7:fa9e]:8333 # AS15600 -[2a00:d4e0:ff:fc02:7af2:9eff:fe90:31e0]:8333 # AS15600 -[2a00:d880:5:c2::d329]:8333 # AS198203 -[2a01:238:425f:4600:bbb8:16d6:e907:cb6f]:8333 # AS6724 -[2a01:261:218:3f00:8d0f:2105:c657:4ae7]:8333 # AS34779 -[2a01:4b00:807c:3100:262f:d0ff:fef9:fdd9]:8333 # AS56478 -[2a01:4b00:8256:1110:d2bf:9cff:fe45:9a60]:8333 # AS56478 -[2a01:4b00:bf1b:7200:d826:7d6f:b13:276c]:8333 # AS56478 -[2a01:4f8:160:60aa:fee::1]:8333 # AS24940 -[2a01:4f8:171:210f::2]:8333 # AS24940 -[2a01:4f8:172:109b::2]:8333 # AS24940 -[2a01:4f8:172:2695::2]:8333 # AS24940 -[2a01:4f8:173:2742::2]:8333 # AS24940 -[2a01:4f8:1c0c:b00d::1]:8333 # AS24940 -[2a01:4f8:202:4205::2]:8333 # AS24940 -[2a01:4f8:c2c:7f8e::1]:8333 # AS24940 -[2a01:4f9:3080:1447::2]:8333 # AS24940 -[2a01:4f9:3b:1edc::2]:8333 # AS24940 -[2a01:4ff:1f0:8517::1]:8333 # AS212317 -[2a01:4ff:1f0:c3c1::1]:8333 # AS212317 -[2a01:4ff:f0:e4e9::1]:8333 # AS213230 -[2a01:5a8:302:ff6e::1]:8333 # AS8866 -[2a01:7a7:2:2804:ae1f:6bff:fe9d:6c94]:8333 # AS29066 -[2a01:7a7:2:3d3a:ae1f:6bff:fef2:e12]:8333 # AS29066 -[2a01:7c8:aaac:89:5054:ff:feb7:f5cb]:8333 # AS20857 -[2a01:7c8:aac2:180:5054:ff:fe56:8d10]:8333 # AS20857 -[2a01:8740:1:753::e5cb]:8333 # AS203380 -[2a01:cb00:1428:ea00:56bf:64ff:fe1e:3403]:8333 # AS3215 -[2a01:e0a:165:5d70:92e6:baff:fe9f:98b]:8333 # AS12322 -[2a01:e0a:316:d560:be24:11ff:fe28:5390]:8333 # AS12322 -[2a01:e0a:366:5920:e6b9:7aff:feea:d6c5]:8333 # AS12322 -[2a01:e0a:3bf:6aa0:1e69:7aff:fe06:a27c]:8333 # AS12322 -[2a01:e0a:57b:a0:7039:12e3:6547:2849]:8333 # AS12322 -[2a01:e0a:83d:dd30:246a:4af7:53f4:8d65]:8333 # AS12322 -[2a01:e0a:9a1:f240:f223:e414:342a:3263]:8333 # AS12322 -[2a01:e0a:b73:bcf0:803a:3a03:8f6b:a726]:8333 # AS12322 -[2a01:e0a:d:1840:59ee:9933:1350:59df]:8333 # AS12322 -[2a01:e0a:df:b9a0:b62e:99ff:fece:1395]:8333 # AS12322 -[2a01:e11:100c:70:39f3:e3c9:832f:37a]:8333 # AS29447 -[2a01:e11:1404:7870:d2:303d:bafd:c6e]:8333 # AS29447 -[2a02:1210:4aba:e800:21ec:346:a29f:90be]:8333 # AS3303 -[2a02:1210:60e0:800:8d6e:134d:a0ca:ef24]:8333 # AS3303 -[2a02:13b8:f000:101::a]:8333 # AS15614 -[2a02:168:2000:97::26]:8333 # AS13030 -[2a02:168:420b:7::7]:8333 # AS13030 -[2a02:168:420b:a::20]:8333 # AS13030 -[2a02:168:62a7::b1c]:8333 # AS13030 -[2a02:168:66c1:0:3f6b:3380:5c04:41f5]:8333 # AS13030 -[2a02:168:b5cf:4::]:8333 # AS13030 -[2a02:1748:f7df:95b1:96c6:91ff:fe1d:e0b6]:8333 # AS51184 -[2a02:1748:fafe:d081:add:f1d7:6345:374c]:8333 # AS51184 -[2a02:180:6:1::3e]:8333 # AS35366 -[2a02:21b4:2089:9100:c7f8:bc95:5df1:cc2f]:8333 # AS57370 -[2a02:22a0:bbb3:dc10:50e1:57ff:fe70:9492]:8333 # AS28685 -[2a02:247a:215:3e00::1]:8333 # AS8560 -[2a02:247a:22d:c000:1::1]:8333 # AS8560 -[2a02:247a:243:7b00::1]:8333 # AS8560 -[2a02:2780:9000:70::f]:8333 # AS35434 -[2a02:2780::e01a]:8333 # AS35434 -[2a02:2f0a:1022:4c00:d112:9624:fbb1:6e38]:8333 # AS8708 -[2a02:3102:4d5c:f000:dea6:32ff:febb:b9cb]:8333 # AS6805 -[2a02:390:9000:0:aaa1:59ff:fe43:b57b]:8333 # AS12496 -[2a02:6ea0:d14a::a921:e257]:8333 # AS60068 -[2a02:768:f92b:db46:5e46:772b:71d:29b7]:8333 # AS44489 -[2a02:7a01::91:228:45:130]:8333 # AS197895 -[2a02:7b40:50d1:e77e::1]:8333 # AS62282 -[2a02:7b40:b0df:8f88::1]:8333 # AS62282 -[2a02:7b40:b945:3599::1]:8333 # AS62282 -[2a02:7b40:d418:6d9a::1]:8333 # AS62282 -[2a02:7b40:d418:6dfe::1]:8333 # AS62282 -[2a02:8108:8126:4f00::2000]:8333 # AS3209 -[2a02:8108:8a8a:8a00:42:acff:fe10:6402]:8333 # AS3209 -[2a02:8108:8ab2:400:d250:99ff:fe9e:792a]:8333 # AS3209 -[2a02:810b:1800:3400:1616:fdd9:da09:e7fb]:8333 # AS3209 -[2a02:8308:8188:5100:ab4b:4802:166:fa84]:8333 # AS16019 -[2a02:8388:e302:7980:6f85:a0b3:4b4d:8b0f]:8333 # AS8412 -[2a02:8388:e5c3:4a80:201:2eff:fe82:b3cc]:8333 # AS8412 -[2a02:908:1a76:7900:7a01:da0c:ee2f:f04b]:8333 # AS3209 -[2a02:908:c200:6d00:caad:5e32:35e7:3157]:8333 # AS3209 -[2a02:a213:273d:8b00:596e:701f:1a74:6857]:8333 # AS33915 -[2a02:a313:21db:6780::5c25]:8333 # AS6830 -[2a02:a45a:94cd:f00d::1]:8333 # AS1136 -[2a02:a461:40f8:2:cb28:93e5:28ab:6c55]:8333 # AS1136 -[2a02:a465:80f4:1:f369:4ef5:aa12:7566]:8333 # AS1136 -[2a02:a469:3eda:1:7e83:34ff:feb6:13f2]:8333 # AS1136 -[2a02:ab88:20b:ce00:223:24ff:fe56:6202]:8333 # AS21334 -[2a02:ab8:201:403::126]:8333 # AS48943 -[2a02:ab8:201:403:b87a:46a1:aece:21ed]:8333 # AS48943 -[2a02:c206:2044:9826::1]:8333 # AS51167 -[2a02:c206:2129:6277::1]:8333 # AS51167 -[2a02:c206:2172:2852::1]:8333 # AS51167 -[2a02:c206:2179:6690::1]:8333 # AS51167 -[2a02:c206:2222:6547::1]:8333 # AS51167 -[2a02:c206:3013:5531::1]:8333 # AS51167 -[2a02:c206:3015:9030::1]:8333 # AS51167 -[2a02:c207:2043:5542::1]:8333 # AS51167 -[2a02:cb43:4000::178]:8333 # AS20546 -[2a02:e5e:1:10::27]:8333 # AS25057 -[2a02:e98:20:1504::1]:8333 # AS24641 -[2a03:1ac0:2e92:e7bb:4fa4:3148:829e:ca00]:8333 # AS12768 -[2a03:4000:21:251:28cf:6cff:fe9a:8efb]:8333 # AS197540 -[2a03:4000:2a:9f:a474:d5ff:feb2:3f72]:8333 # AS197540 -[2a03:4000:4d:f1:b4a7:38ff:fe8e:fd75]:8333 # AS197540 -[2a03:4000:5f:cfc:14c3:eff:feb5:1c1a]:8333 # AS197540 -[2a03:4000:63:dc7:d418:2dff:fef3:94d9]:8333 # AS197540 -[2a03:4000:6:3044:481:f8ff:fe11:f7fa]:8333 # AS197540 -[2a03:4000:6:e161:d844:adff:fe11:3f2]:8333 # AS197540 -[2a03:4000:6a:2b3:d88a:d2ff:fe23:ac21]:8333 # AS197540 -[2a03:4000:6b:c6:24e9:1dff:fefc:87d4]:8333 # AS197540 -[2a03:4000:9:7d9:c88f:1dff:fe4e:44d]:8333 # AS197540 -[2a03:6000:870:0:46:23:87:218]:8333 # AS60131 -[2a03:6f01:1:2::8c2e]:8333 # AS9123 -[2a03:94e0:ffff:185:243:218:0:19]:8333 # AS56655 -[2a03:b0c0:2:d0::df0:d001]:8333 # AS14061 -[2a03:b0c0:2:f0::1bed:9001]:8333 # AS14061 -[2a03:b0c0:3:f0::2cc5:3001]:8333 # AS14061 -[2a03:cfc0:8000:2a::9532:650b]:8333 # AS201814 -[2a03:cfc0:8000:2a::9532:6514]:8333 # AS201814 -[2a03:cfc0:8000:2a::9532:6521]:8333 # AS201814 -[2a03:cfc0:8000:2a::9532:6523]:8333 # AS201814 -[2a03:e2c0:4f9d:5555:29d6:7012:676d:1de]:8333 # AS205125 -[2a03:ec0:0:928::701:701]:8333 # AS199669 -[2a04:52c0:102:2219::1]:8333 # AS60404 -[2a04:52c0:102:49af::1]:8333 # AS60404 -[2a04:52c0:104:160c::1]:8333 # AS60404 -[2a04:9740:115:6e00:3e87:b950:5382:7ec]:8333 # AS196954 -[2a05:3580:d101:3700::]:8333 # AS35807 -[2a05:3580:dc0b:1600:9a5:3d0e:ed14:79ce]:8333 # AS35807 -[2a05:4cc0:0:321::2]:8333 # AS8772 -[2a05:6d40:b94e:d100:230:48ff:fedf:1432]:8333 # AS202128 -[2a05:d014:a55:4000:7705:3a9c:bd4f:aa38]:8333 # AS16509 -[2a05:d016:98f:5200:2110:bfc6:f5c:5009]:8333 # AS16509 -[2a05:d016:98f:5200:6ea8:d9cb:7cc8:17e6]:8333 # AS16509 -[2a05:d016:98f:5200:c7d5:4f51:fd31:d4f4]:8333 # AS16509 -[2a05:d01a:b7b:3c00:659c:239d:953b:23a8]:8333 # AS16509 -[2a05:d01a:b7b:3c00:766c:dbd4:f5be:2d61]:8333 # AS16509 -[2a05:d01c:672:9200:b4e5:d5f6:f633:a59a]:8333 # AS16509 -[2a05:f480:2c00:100c:5400:4ff:fed7:dead]:8333 # AS20473 -[2a05:f480:3000:2b4e:5400:4ff:fed7:4206]:8333 # AS20473 -[2a06:dd00:10:0:225:90ff:fe33:56e8]:8333 # AS56694 -[2a06:dd01::36:0:0:1]:8333 # AS42474 -[2a06:e881:3408:2::2]:8333 # AS205165 -[2a07:7200:ffff:0:3016:d5ff:fe5e:1114]:8333 # AS34197 -[2a07:7200:ffff:0:60d1:eff:fe09:3886]:8333 # AS34197 -[2a07:7200:ffff:0:c43e:80ff:fe3c:e0cd]:8333 # AS34197 -[2a07:7200:ffff:0:f4d3:aff:febe:ad99]:8333 # AS34197 -[2a07:9a07:3::2:1]:8333 # AS202605 -[2a07:b242:1000:1300:f250:8f0a:cdba:4d76]:8333 # AS202618 -[2a07:d884::127e]:8333 # AS23959 -[2a09:2681:1001::23]:8333 # AS61282 -[2a0a:4580:101d::1]:8333 # AS29670 -[2a0a:4cc0:0:21b1:400:e0ff:fe79:9797]:8333 # AS42473 -[2a0a:4cc0:1:1174:98f6:3cff:fe03:c19c]:8333 # AS42473 -[2a0a:a504:117:bf00:661a:85b2:5f5d:8738]:8333 # AS210619 -[2a0a:ef40:e51:d001:9d3d:f687:b0dd:3131]:8333 # AS5378 -[2a0b:3202:a:108::142]:8333 # AS201080 -[2a0b:4880::266e:96ff:fedb:7cdc]:8333 # AS48614 -[2a0b:f300:2:6::2]:8333 # AS62240 -[2a0b:f4c0:c1:920e:b25a:daff:fe87:77b4]:8333 # AS205100 -[2a0c:5a87:9206:2e00:6ebf:b5ff:fe02:cb4f]:8333 # AS57269 -[2a0c:b641:6f0:193::]:8333 # AS214379 -[2a0d:3002:2100:a001:4::]:8333 # AS205544 -[2a0d:3344:1d2:9100:428d:5cff:fe5f:902d]:8333 # AS14593 -[2a0e:8086:0:3ce:6972:c5a6:f5ab:c78d]:8333 # AS50340 -[2a0e:8f02:21d1:144::101]:8333 # AS203528 -[2a0e:cb01:63:d5ad:69:69:69:69]:8333 # AS60377 -[2a0e:e701:103e::4]:8333 # AS2027 -[2a0f:b780:300:1::2]:8333 # AS49095 -[2a10:3781:2c19::1]:8333 # AS206238 -[2a10:3781:3a73:25::25]:8333 # AS206238 -[2a10:3781:3a73:25:a177:ad25:b14a:176a]:8333 # AS206238 -[2a10:3781:3fff::1]:8333 # AS206238 -[2a10:3781:84b:1:8002:99d3:191f:c738]:8333 # AS206238 -[2a10:c941:100:24::2:1001]:8333 # AS35277 -[2a11:d540:531:b00b::5]:8333 # AS207586 -[2a12:8e40:5668:e40a::1]:8333 # AS45021 -[2a12:8e40:5668:e40b::1]:8333 # AS45021 -[2a12:8e40:5668:e40f::1]:8333 # AS45021 -[2a12:8e40:5668:e410::1]:8333 # AS45021 -[2a12:8e40:5668:e412::1]:8333 # AS45021 -[2a12:8e40:5668:e418::1]:8333 # AS45021 -[2a12:8e40:5668:e41a::1]:8333 # AS45021 -[2a12:8e40:5668:e41d::1]:8333 # AS45021 -[2a12:8e40:5668:e41e::1]:8333 # AS45021 -[2a12:8e40:5668:e420::1]:8333 # AS45021 -[2c0f:2a80:2540:1ac4:73f0:cfa4:1821:d1bd]:8333 # AS14593 -[2c0f:fb18:402:5::3]:8333 # AS37199 -2aiycr24bdfx5s6yj4i2n2xbnha6rjn3pc23i4rbrwo5ays653xzygad.onion:8333 -2bj3dc3e6dh4f7fd5uta3qp32bbqxzyqjs7ixy4lwdkx3n5jisfc7uid.onion:8333 -2bpccmeaduwlo4t52pangngxdxp235teqe2cflkdwjcwjvyl5f63m4id.onion:8333 -2byffyqnely7vwuncdvodoo3ip6jdi2b32bxjtnlwcdurjipsxdktqid.onion:8333 -2d7uxq7ylxssdgonks6burn4lwcyiogrp4qkaxk5djbs52l3bvgxzuid.onion:8333 -2f2rq7wy2sm77re4diudcsrfzb7bje3rl52zkhkpr7k22je542r5mcid.onion:8333 -2ga7wdrdxpmuto3qprdabf7urx4rzr2ivwku3ee5ufit56qsqoi5vjid.onion:8333 -2hbr4fvgnvmesbsevctosba2fu5mx5ckbibhjphi4oxjlgowmcsqz6yd.onion:8333 -2jclw2ujx5qt6miolhjxfrxbrltr7vcw5zyctuhyofc366upqksvxhqd.onion:8333 -2kpblheyfrv5hxt7ird4r6fi7albfmyopcwk2eljmyzhqp3rfoodtwqd.onion:8333 -2tvfkr74olmbaqjsngyp442bvqgi6iqu6mmikrgf7bu6mmedkxdiveqd.onion:8333 -2v6izgcdz4lmmbw3wj6jzn7srwjlbxsf5czwew53qm677kc3rwilexqd.onion:8333 -36ps7lbzekepdlhmmyzfuajltjxljjaltkcdkwr44a7df5sl2sxokjad.onion:8333 -3747dbbz7ewdraacetcxl65fk5lqvcsf2ix4wndstbmx4k7rnfxidoad.onion:8333 -37gfddnf4zfnvfpbgebqq4i2v76lrtw3kf7xba5dymcwtxqunx36eqid.onion:8333 -37tyqqa4m4lkilvtcl6d2sedpxthemknrkriivmig47uv3ojql37nqyd.onion:8333 -3agbdvmp4iyo4rpdygeedidpbon5txv4efo2xxvqbzr22puwtjywtqid.onion:8333 -3alygctgneenzovtwcxz7ykn2i735yqro6d2sflkijdvnanots6vz5ad.onion:8333 -3daur2nkfusuli6utbrizb3gwcimduu4wch5iozzoros7wcvypjledqd.onion:8333 -3dp4nrdk4vvivichtplza4d6gtt5v3c5phwxihyh5gcqzhxlqa3jsxqd.onion:8333 -3efpmp6aeatzis3vyrw32fv6nwffcql43e4wkquifgt3eldw4qer6gid.onion:8333 -3erp3rwr5psstk5ruc7oau4boat6ey4vtqyrpy5dbagg7wnzqszgfkid.onion:8333 -3fivvsg6ccrbjx5nopgy7ryqvdvjjn6eqen4qosd6ghvj743camgemid.onion:8333 -3hu7ofcwhxx2rinbq2bprefd2fejed53ehqa4bm3daxd2qmlfugsyjyd.onion:8333 -3jyb2gfpv4mhbzhohvyig6bi3xqlvqurzzr7xqyv5epnxeru7a4ohbqd.onion:8333 -3lqycokbjq76rx4vmhhde2lz2awrnt3c5zu5t2av3nda5amxwinu2cyd.onion:8333 -3q7iq64qokniakeumucz5pgmrndtqixvdx5uto7svkcguabxbku56mid.onion:8333 -3v7wckih3yvx7monqrg7udkrqxrsvzpd3wry7kq66zgedezph2iozbqd.onion:8333 -3vcobxubomismocgkyhjl34nu5mt3ruzy2byrtf3q7pdn5zlommgwiid.onion:8333 -3walt7bg6swhhewgtd56lv3beglutkfkp7gxq7nj74emzu4wr7bxsyyd.onion:8333 -3xu65qtcywnuz63viyi2wuih3o7fb27bwo3uu2klaoj5b56prmegyvid.onion:8333 -3zfpnxo5n636stb22b7xaxb7qtmvjldqcnjdr5hemh3aljm4amlal2qd.onion:8333 -43syalmelgy76zzyoiamtmagfq2woaicmqyon42fno4lhm4vopja7qid.onion:8333 -44lptd6pipnpn3xfmzj54kyqvzuwv45fhiaiywijpshrtk3hlgedieyd.onion:8333 -45py5s2panediepr3aftali4tjsyfyu6y7ykzkadl2sqwtptxtkml6id.onion:8333 -46h53i2fa4ysbtngmxk2oegqfpool3a7glcps5ef5o4webpuq4ukmgid.onion:8333 -46xek5lgozwwt4ij7ymvbogulimsd6kan6yd23fwgd65kor7jio7cdad.onion:8333 -4a3vkisqwv6v46xsbv6rnr34zfph2tfvvtgmlzbymtru2ijv666augid.onion:8333 -4bxdjq6ixzcey3io6jhuapkwlfbcpfeesfmtcy4qb3bf7dlwbzktnxad.onion:8333 -4c5rrmtci7bg7ydyfh5shzvufy3c7prx5ryezc7cnx2jy7vsbhevnsyd.onion:8333 -4flszdgtvl7jlu2jioofb7wgmtbxwhqcmkhu522wphsdvr64yz67umyd.onion:8333 -4gggjxzg6do2ija6mjflubduvv3iqfmkdy4b7vw6tl3k7g7oa5msdlid.onion:8333 -4juzngo2n5fbxlqcfpcnstl3pexuzwtxocfutn3vtyhxtaztaa7axbyd.onion:8333 -4kle6afrjdhu6mranj33n2xw4aj3iqnysqmsc5letdhkthxyf5n35jyd.onion:8333 -4niu7lryc4pqoqvosaxt3bzmq7ulku2vevqxizzkstyisi772apsvjqd.onion:8333 -4nlcxxoygmvjbuqge3y2yhvk5c2525qwdnswhgpxrercggcb2pxy3cid.onion:8333 -4np5xojfk2ventfumyep7azy4rzu3inmpsre7vabfi66n2mgspcinxad.onion:8333 -4p5uvmwkpwu6wf373x4mg6zgwodrzytkd5nbsawc27gf6bhbtsh4b5qd.onion:8333 -4phsfbspp7cr7kzd7wapmgz3zxzobih46rw2a5v6qa4m6rdlphl4wrad.onion:8333 -4s3utndbk43f3npxvvgvekns25c5r3f6v5cfe7vhjso2qo2ru5wcmqqd.onion:8333 -4sijy5qfaw3sq5jku5qsufvxxconuzvdrixh64za6qzlv4l3kikaedyd.onion:8333 -4u3nymzyg52nzi2xaqws6abqgfwk6myc3pj3jr7aqtuac7cko7nr7fid.onion:8333 -4w3qj7as7qhnfuu2peyiiosgiudjc7rnptic6ynq6xp65onnbhrpd3id.onion:8333 -4x3lpzj7ptne45h5rdm5vnpyu4ch4m3u6ljd6dfialtne4cvnbhgjgyd.onion:8333 -574lyz5mrtwoewaejdzzase6iwapmvyfvrdbwn7iupcmf6wcxdorylqd.onion:8333 -5f2w5mff4ij5inqjjjmzwgrkegis4lknkbti7xrh3qg5xfps7q2lvnad.onion:8333 -5gxylibgass6p562vvpzx6zzbaxlru4r5en7ahvcu5nfigr57ytkaeyd.onion:8333 -5hdcmynihsr4r55a3gtxhz6ifmsg7quozgo4wx2bp7agcegwkj4ataid.onion:8333 -5j7z5fovfahxe3gwqt2lthhyxvotcveopld375l2k4rvqccc36lexbad.onion:8333 -5k7zlyo5qeqtbzl7khepw3pblxodcfyzvgdh25hh27bxgvauegnqq3qd.onion:8333 -5ktcl4ysombbuq7g7q6hwahdeafh6nootlpwj5yyt3bvfnizwmhrigyd.onion:8333 -5lijk4k3tzozjo62uj3heeh3nprtl5cibi3xdfp2xm4bahlboh7zjvid.onion:8333 -5mcxoegbgp7vwocusjxshwjncdcnzntzry5fwfk7v5xqylxqlpube2qd.onion:8333 -5nptruq2k5654ajq5h7f5ty3adkhs6gglkrbp6l2x2xlykpkj4cdjzyd.onion:8333 -5ntg7na72bods6fuegoymzboiufgebd4cbaztavi5xcqanohtx6kw6yd.onion:8333 -5p54wr7ppdfwjnapdylo6cysrrzd6shkzgk72y42rwt66fhbhypixjqd.onion:8333 -5piafwsopd7qywfp6gobskqtmxr4c7ndovsefuktml2xih7nnjsukzad.onion:8333 -5pn3tgpv2ldcmtrisda6okg2c3owgaoq776fzn74htqwbfcdzp23wpqd.onion:8333 -5pynehkenulugwn3dvzx7bwqfg7qplnu3vtye5mvlmxxhvkoenznk4ad.onion:8333 -5q7px73cw6egdz622ly524udqwiewdajvpkklrd2gji2uvyrccujvjid.onion:8333 -63en4ruxj3tfgm3ooyrli5ujhai4eygr5mncq7jvbqf7c5vqusrywayd.onion:8333 -65qyyjh7muzlq3poxjwxb43dvuxoulpo57z7rcpx57h7gfzq6gqghlad.onion:8333 -66m72tq6lbsm2y3yn3bwj2uk5ihjqvqkymf2t4pqevtnymqujwmynmid.onion:8333 -6es5e5uprvbtqiv7dxhvfaqb2zvzvvtv2h2ildvqbnikqg57py3nmkqd.onion:8333 -6f3d2ak44y6celpfy3pj22ak4ioitm4k3xfegej5mmeonm6xwg4dnvqd.onion:8333 -6f4mtuv4n5pwturdta3qruhqhuvwlzxyfxtfukydane7y6yuxklo23ad.onion:8333 -6fhojzpkw76kepjqogqf5ldmhs5avbmhrnjj4lnead3b447cgkzysbid.onion:8333 -6gpl5psk63ktxafvhi6guueyy2cgz2zuqwxckvzpi47pr2t5r7p4aqid.onion:8333 -6hg7kc6lmodjyrgq2557dauxibugbejgfynxlptacrmo2lzbcf2ylaad.onion:8333 -6jwjohqnlmk2dbz37dk2nqp3nelnd6xwrx6hjvsw72ujdcdqxsv5k3id.onion:8333 -6nwabl7vks2jieb74akgjmariirzchzeionxdwthsgjsenbfr3qgqzad.onion:8333 -6t3yyuem6d4a4cc5pparbksrjh426jpejo5jal32tcbx7zgz4achr6ad.onion:8333 -6t555fluey3jj3scizdz5fuiaseyqok4fkpm7hznvp2s4j7qjnbrzcad.onion:8333 -6t5nbr3td6jmr3aami2nrljlfpfvg25m3gbg6qcsana7r5cyug7553qd.onion:8333 -6udpyvm7hj2zgdbuga6r3cden2nwb2rokzejihn3sdpzolh3w4xwujyd.onion:8333 -6vncy3bxmb6wyiio7kxqvuoz34yityyullty2l7grqqv6qhfkkyg7mqd.onion:8333 -6vu6tncy3n4btqlizlgen67oktqwpu2qd452dvcgadbis2v7wwdrhcqd.onion:8333 -6wutlymogzxat6ltpht5wvdvujdpa5zqxpfkjfofaaesm7gfjxoabmqd.onion:8333 -6zkyfpp6el5e2ip2hlrdgzerwknqcpslkpdttiwfljcmcrtwqeticbyd.onion:8333 -6zvl2xxq5qejxblrr75jsqpvv7amdn6trvlqzapqn5nexl5x2ojefuqd.onion:8333 -766lviokylelmp3on5an3im2arnqakdj3jvw7mso6zfx47oi35l4ogid.onion:8333 -77bylqq6gq267jt4g4olprft3akdlpvztlgp7vfiw4xffrthm35x7byd.onion:8333 -7bjwdnx5umef3bchtn4coz4qawx2st4752ckrmwqr27ueg45w6mouaid.onion:8333 -7crojipnref3cqh2nguvcu6icypzpnqs7ijuybar6e454rphegmu4cyd.onion:8333 -7ecbffupljjuxl6lymosq5dv644nkxonwsnlkcglczpucp5rj5fhueqd.onion:8333 -7fbqlafzdcj3r4swjgzdi6wy23fm5iyenwgo52gz34ktg2whtremm7ad.onion:8333 -7gfywfzshst2fmwdmtjuooac4dsow5pj6rxrxohw7isklec4k75pksad.onion:8333 -7izddvivyjvdlcbccnkspcczvbupybsr72jnfcnu6saaehc6ltvtqcqd.onion:8333 -7jvf4xx3m4xxxvwwtei2abomezat4n6k7el7jq5ncot3jb6mdjvbdtid.onion:8333 -7mdm6ofk6kvgbceokc5ri53peq7o4rjgq2cv5ivzuemqgxfptzgtltyd.onion:8333 -7nitakbrzn53lgiju5eekd2b7a3txr7a4jb5c2wv3bi2rndsshoxrvid.onion:8333 -7ogrf4k24permd3plwfaeblheozyynk4rlxy4tpqvg3cvwibghppvoqd.onion:8333 -7p64efzhcxtpkbr3ji2cvhud74fremdrhgrgwkgnucn5a5mpcxxv7bad.onion:8333 -7rpbm65elgnrsavh77nhczathp2vwuik2cyrma5qby2fxft5jk77l4qd.onion:8333 -7rxvg4xgt6q6zyojbfpqecvkfpb76myiqnzndsive7uooxkk7m6jmcyd.onion:8333 -7stzoywo4sn5antnxihprap4phpsiplx4j576yneqy3nqejt62hrbhqd.onion:8333 -a63cg6bmbefpb7jckgijq3tlzzj5nvy6px2jyyvsy52gkyadwqfu5cad.onion:8333 -afgn5w7cpcb2p35a5boqbcv5c2lvxu3634tli5e5fnca3z3ay5yxtoad.onion:8333 -agpipxpyeyk2fboa6m6nvvt3m65p33hymmd3p5q3so5rccavidg4h3id.onion:8333 -aigknmwtshitht4oo7ohyixhbkvnxkwokrkz4ud76bgsipfb2tgmx5ad.onion:8333 -akufshjn2rz23kdcxeexxf7obw7vrlc6cwcobyjnelkdgyjtrcazetid.onion:8333 -ao3tuhoe7ay6cjqsibxk5jamg33ckjyutq5uspot24bdimajgkq7scid.onion:8333 -arlrtxrmw4npffxopvthsz37z3mbefc65svjk7mflxzzuprs4hc5jgqd.onion:8333 -atib3y336joeumqewfgeam6a7di3e3r6kmkmyh6ajcaktb6u7umlsaid.onion:8333 -au5ujsa3xd3tt7xttev5e7bandnio46gbdfzg7n4ad3hv7j5jkc2foad.onion:8333 -av5ezwtzojuzylip3gjhjxyzg3c5g46u7fx4dhp5o2s2j7wfwa2en2ad.onion:8333 -azpysq5tc3lnbx2rawenpjdyghi4prcvlhjdhyh6zlsrpuwlxwacktad.onion:8333 -b2fw3a52vmuu74evg5dezgfhpr4v6tnjzn7pm2ffoxpeyikceqefmiad.onion:8333 -b43cgetszokuo7sbbzwpevpeharvravm3fud7rbarm2sivll3upyekad.onion:8333 -be7bw6vrdr6ko6fbjb7a2buzibqx6thqxrv3mhqtlw3jqe7uhxrundqd.onion:8333 -bhhy5mgq57onfqtopw4kizm5rowugm37jrtfujs5avkcfafltay5huad.onion:8333 -bitcoin6twde6mauc5flogkenljfxk3bemqobjse73bf2bnfjaxnfgyd.onion:8333 -bjaqsd4v6376d2pp7ho3dmijblwipuzxbcac6aaxb7qnqxuzlsxbppyd.onion:8333 -bokoy72uqqlmltkiicvcukpi5wxeubl52aumyf4dhnacyghz53bepoqd.onion:8333 -bpi6oysws4nidjwmpadn7mtzma5jahbnhjgffcwdsjym2qq3zwhdjkad.onion:8333 -btx5ae2sxbezq6deplr74qlk7rjwu3cqnvw352huf2voqhtkqkav4jyd.onion:8333 -bumlvs3fdli4cagjnksntyxkrqz42c6tejeppz3k33yfeyw7z6m7u2id.onion:8333 -buz3ocrzjyiecbwtfpmoydn3c773jorlr37bw4kjoq6f6wpt6qn76aid.onion:8333 -bvikscuyoorgo57ifwh5jbdx3mmeyoumxtnyvjicjosce3egqegdefid.onion:8333 -bxpiyizma4j6xwg5lf7z7td3xbv7ffi4x3bntyftio3mszogl2a5v7qd.onion:8333 -byqslyvvxybu62i7w3yjh4aoim4go22g7gwdhbpcbnvyhhajrff5ktqd.onion:8333 -bz5v3ztsfl24gqxhc22x763icdrp6hbgqllx4oblnx7eduas7cdxubad.onion:8333 -bzhf6w2sajkk4lsty3hz64kygen4ty2lk4swo6fz3wzsr2uofsannpid.onion:8333 -c5gkqgv7br7xirqcpfbupyxyesx7fbif4gqr4hogirlngre46oewk4yd.onion:8333 -c6tktxgcu54pvdfw52bd6udbpydesdivyxlaveubanon3oay452r4lqd.onion:8333 -c6upbdl5ro7l4r6hqnzxy4spsye3wu2myop4ntzcw57zwjlrhzppihid.onion:8333 -c7hwtt7psq6rtcl4yfiuzkphrrjusicge7kfzs7i6bpdgpbf2as3egid.onion:8333 -chltdbogcrolm4wwhop3qizo4cxrn22wkhvgb5pcervzs3bzx7u2f7id.onion:8333 -cjm24gef2dpbnwznbv6ad5lrod4gvet4f4dm2su5vm6wpdpt2bnajryd.onion:8333 -cjzcwym4hv2ie6yhgqp5ex3hvwueoqvt2aqucvv5glodixw4ldbmtqyd.onion:8333 -cmm4777ii7j7y5ufu3k4izuhx54ldrq2lehaoaowim66tkbtkeolyhyd.onion:8333 -cmxivv7cbrdqneyxaii5bls6yvknpa7zbrridnyk3ztpwnxkjkoi5uyd.onion:8333 -cqm26nhpdlmfzpooozujsyuokqtuixjt2bdr26rdsilebntnighjliid.onion:8333 -crfh3vjreblr3tepu6lkpwkqagfom6k5gc3c2bn74atw5xiuxv53sdid.onion:8333 -cs2uedzkwwlhihdi2mm7popaiydm4wp6uwakut4or6mwjfbmrxjjrmid.onion:8333 -csjxou6mxjf2yljlg6zkqezsntvm5xzpgsg3ymnd4xhpj5zffmfip5id.onion:8333 -ctl5rsuuaakuz5zlcjpzj2y3wuba2apoasggznnrg63bqfdhjyeueoid.onion:8333 -d2klz5ggkyc6657hwi4xoyq7jbv5wj7vtlb5uqv6huihhw264esi6xqd.onion:8333 -d2lbtmbrdozfd3wsq5vbw632k6n6jjo3h45v5qigx2qcqfuclzifh6qd.onion:8333 -d4xkamq3szbc3tznyzjcdtvfbiaaq32dekaudma6dkzp2l5ogpy4uaid.onion:8333 -d6vg4wbrl2inoe6tfqf5fo4xivqoavxbzgd6qmduoap7k34hgomekiqd.onion:8333 -ddhrkj3l527e45tdqmfmm7olmisgrkisgx7243x2klax7h4jytmsjlqd.onion:8333 -dku2lusultkhvdh2nbnty7blcv3fdwqh3qblmzhydprdsnjjiwp7wpqd.onion:8333 -dnmb4ifydabk2n7dwy73xyc75mrksl6rnhidr2p7xsxgk64vcvghwxyd.onion:8333 -dnwbaxecn4xxupvtqvigoopzeys5cstvqv6u5zpfj2u37uqmq6s77kqd.onion:8333 -dwz5ycilgykv3npjcn55t5nqf6nkabtwmxqthvs3spsael2dlfrksoqd.onion:8333 -e47xwhzcnz3nakum3wbouqm2uhb6try5dn4hcdzfz65ie5kw3mnu3jqd.onion:8333 -e4khd6hsooslfwexrcwlpwba5uinfpvziv6sgigvkzymrlfzposj64id.onion:8333 -e5c2dam2twutxqsv6j2lhq5y7o7t3hcsiyfgqfe3qe73t3nhrqapddid.onion:8333 -e5ju4gc3jd2p56syoyci7etmyjg7tfbd4722nbtxr3rqhfm7eew7icyd.onion:8333 -eaertx5wvxzhlfjd3rskz2f6a3unblufagmadrtpycj3dpfrwopvs7qd.onion:8333 -eaix3x3rlogmpdnvwpwgsyj5fiuiwnsfpgxtmztacp7van64l7d4ebad.onion:8333 -eaui3zjivtoohv2hd2nupoe5ujpeksl4zvbgqxtvb3d6tbpin4tzhrid.onion:8333 -eebfo5fk3xzipldarvwyjsn2jchpl6calkine3gnvbrfyqkqndlnzhqd.onion:8333 -efvwrivcbtr7dk2vr7ofqpjerusgfxritkq4agqnsceh6qcpgjmp6cyd.onion:8333 -ehxiikephektrexse6hl3otmqgrfletdkkuop4ifufhe6sby2okkq5id.onion:8333 -eikoeq43vloeieb37nm4znqwll6kbmvuzmtdch4y2a7fw5icrrloeaid.onion:8333 -ej5sof7pylkojmz3fvmouzgzmrjkyhvvpy6lns7737djzuf77y3theyd.onion:8333 -ej6xgq5vapglcqtzf7gae6tmenhu4ve3twg4hdanbftii7k4f2x2k2ad.onion:8333 -ejmir5e6doj2k5upakum4koucthtw5dq3uledahecsdjq4bo75z3jsyd.onion:8333 -enchh7j5453cay2ygonpuot5bcikdc6flqy6mfd2wsw3z7sxv2ehouad.onion:8333 -enhp5lczc4mjig5t6hdcxkokdtzngejapxiuyw72soggajggyefn25ad.onion:8333 -eph75gzxeibberoljtyftb5jmawm7rxkvfqx2saxbu7z6eimo3xcn5ad.onion:8333 -er7exr6r5w77r4c3i5wb5r64d6wzwo2a7ndzze7ob5sgl3a5fgvlzoqd.onion:8333 -erzm3rr663nb5rjcwm4vejxhgbwt7ahkw5yywl7h7y52uyfk6p6gdqid.onion:8333 -eu5feoa7bdme6pfvcyp3rj6u4plarlpvsuzv5ux7sbd5cduygsdsyzqd.onion:8333 -evircgqqrc6vhdivhjpuathfpzmek5qp62gsf2ohoaiyeynffssdpgad.onion:8333 -evrts3xnjcmijzaokev3eiocbvqkberud7ugk5e3vgaotww2ihlxl2id.onion:8333 -f3kh5b3boak5zkwnpwyostmfxo63wna5rvmsh6r7mfdbaogeimtv2eyd.onion:8333 -fbh63e5uysamticqogfkd3f7yoo33pip2yloun7wc62zvexzoabltnad.onion:8333 -fckjnfmhw37jpevtexlcxr5v3lm43pdotlz42ajpmpu3zio6etv2qiid.onion:8333 -fdcthm6b3ltzjz7d6cvccltcwxvyoxaol3awjzghhbpotskzouuv2kqd.onion:8333 -ffycrr4d6pwyq5x4r5onwtyxtvd3iqj2mlf33srxdu6opezzpfofa2id.onion:8333 -fhh2tfv2rbqytnqprobxqp5fy6wlmfoge6punxj47k2dddpc2qgq2cqd.onion:8333 -fj4wuboarofhshcrkwqd7iponopb6wb3dn2fsmvj6finmgl6hicwpeqd.onion:8333 -fjgyfvbloy5aqcxmdtjq6qwngs42dzml7hodo5uivm4r2gji2grqpqyd.onion:8333 -fk6vmbqusfbphq6prkeugchlgssviohw6p2zki3osoc2c3jqhfx3rwad.onion:8333 -fkxtgwkswxdbmb5kmdblw4gautm7zh6mds4xyvzd3cyeygh33ggiooyd.onion:8333 -fmbxkhm3ykpjod4nnxrbk3jk4pn5bcv6ysmfaam36sepcb3vqwybfnqd.onion:8333 -fonc2zpwyprpa5i4wvcayeyezizvxom3jnbibdhs7vjg6xti7fohjkad.onion:8333 -fpt7t244pgquaqciv6s2kpm3dmifp6hajwlaenaotwpi3smuutxsaaqd.onion:8333 -fqczapitclhatilusvmsw5qkvg2nksjoju464dvrltvyqq5zy2kftsyd.onion:8333 -fqd7k2geb3klth3n3hzaywl2pc4akwkzo64vjofs5egqvq3okbrxlgid.onion:8333 -fqgtcdbevgyc2qs5lkxkxtdjkdbwbg5fpodlkx25peulsgzn7nqlxgyd.onion:8333 -frtcgu6iecmpkx5vsh3togf475oiwjlxpuh3rreetjkryh3ghahkjyid.onion:8333 -fugsghemfzgdgc7kgbs3nc5pysyicn2mqlnc6ah2uxfbls7rac3k5hid.onion:8333 -fvq4fy4ilsn2y6sktykb7qjdhpvylg2cayuhngxnyorprr4lcs7vgkqd.onion:8333 -g2b7vvsv5xf6jewazsoommk5zqbv7rlnu4m7wtvmhc76mpn7ho2ydsyd.onion:8333 -g4hhckbn3we7nkdprpb5vzdzgvrrrg7b3ubkf4t3g4c35yx5rqwrroyd.onion:8333 -g53laknf2qomk2npziez55ekrgutveojja4cdxx7bx4fqpjd5o4oahyd.onion:8333 -g65soedj325yp4y276egzf7tgexjom4diygzbmtxmlpqkunltpkb4hqd.onion:8333 -g73ujt2n2l3zbpwvcb757nalpfb5tkprqgh2m2sk3rpl7g6hjp4zu3ad.onion:8333 -gaeaun5gf5tc5dhhwp2uzs5r7zumr55jptp5gxxmcmwapnqv6rvkw2yd.onion:8333 -gbv2yflw7wyo4ivwcf5vtgjhdikewxahwpuw6zy2rykigsn4fq5shxqd.onion:8333 -gfo24oosqklizwom7nlok5i5ioi5yriqpp5vtgut3rtukndix22lsbad.onion:8333 -gfq2z63ggmeszsqpdzg5cfhsou6st3qhkj256beege6yyfodhmbc2iad.onion:8333 -gjyyjdpa6tryaikzun52iiyalsmeop7n6t5ss6aglo24it4ufbejeaqd.onion:8333 -gkxu3524ncgpml53cwdyhrxfpdyflrh2elwqmu765lccc4ckuobvmbid.onion:8333 -glhm6srmyanw4f5yjq4z5kultmpea6syepzgxtqechrn25lc3anpvlid.onion:8333 -glijfi4brh3zq2xvnzy5gaqkifoceuiyzyeyecojdlqe75nwoetcwpad.onion:8333 -gm2b3s5mqvccelokh47aypsu7wduyg3lkety6czu6k4phzfxczcoswqd.onion:8333 -gmjyc3qivk2bme4wimykhewlanx5z3sxli23nizo4kiuerptcytqsxid.onion:8333 -gmnoid5e7uhsjxw2uuwanm7k7tbyutbcpiacuxyqztqqy4onbofzuxyd.onion:8333 -goxkenocpqn3ibvslm5eccprmkcszelvpsrgrtd3fd43qr2xzl2la6id.onion:8333 -grbpww77jgvl52eyzjhrnx5dc2fqnb3dgxcm7fr6jjigc7aihvay2yqd.onion:8333 -gruccg4k5yq7wnkytjqndfbhc4pbdfiwuzlbsjwyjwzg3nfitb273lad.onion:8333 -h2jikhew7toufyhusvt33engo6bdvjdv4fvxsk7k5z7yfr6sjcb4giad.onion:8333 -h6mzk6q4mlf22npreupmfvuhukbrgsjlvrzilnuigyujmtfmi5ltiqyd.onion:8333 -h7nka6o3t7dn7mkvnhg62jfftvtsoi4f755xjheuxslklmei23fos4qd.onion:8333 -h7xyscykodwdzvyzluapacbe2dmpelmes6xjhqmbrwrza65utpyn2zid.onion:8333 -hbjqnzqygl4fdkjwyaxcizzwrnwl24dtjppy3vxqqii6ilpl3ysbtlyd.onion:8333 -hbqkqjt5y4c3sgwmg6mir2qv6z6anxrxr2riqj6x7r6jayc22gvbriid.onion:8333 -hc3ebdu3sgrqfz47yhh7gfupzgesxmdrmfcfaqr436nodujhysajapqd.onion:8333 -hc6a3ccuvdmtvgndynhzfuje2aqgpiyqzbm3s52rekbxmron6w7ckbqd.onion:8333 -hcqtdywbzpgp7hwbelbws5s3ykks6i34yu5gznitupfcli2t6og6qnad.onion:8333 -hd5rdhy2gjkjmqlxayeoqd2notpzsbf4zp3y5ndzpvimudia2zrqoqid.onion:8333 -hgk34cet3cktfevkakzwwlz4zzqcmpo75crlfmyddfr7ikg77iftmsad.onion:8333 -hj6feb7d6ovgutaflry4337kyyczirc6y67js4gn5lsdfqfbqeiodnid.onion:8333 -hjxcacppbndvot7klgy75xglwtfu2elxfwtt2esquzwsdxukklvl53yd.onion:8333 -hlcoisik6mlwnat3wbwfntkeh32yhymhq52tgo23bivrkuq2lmaqmxad.onion:8333 -hmr55kh2n4l65yrxpmje7yn6oyu3pdtutgvk6tgllkhodqxazlrmp6qd.onion:8333 -hryul5rtv327up2esowuvlip644udinwxr3f6tvo3vahffggkk3ogmqd.onion:8333 -hsce76s6kpkzlnechwpoiudlyygbr4s2ct3hcxi4icgiwk7kehwz6bad.onion:8333 -hujowynr3flk2zadfx2jbka42is7rsguxmp5npiaqpngpabvrakthrid.onion:8333 -hvwiqbxy5rfxvmq65dd4baitrt7e62a72so4myiacur2tirwavk4eaad.onion:8333 -hyddoxcoyckwa6lloendglu7rvlvwph4gf4xxgteb2hbmbfvk7zlabid.onion:8333 -hyiqykrejh2m5mchbuox7qcjpnctfa4t6t33xs3gt27gn2zdauub2qqd.onion:8333 -hzbrybvl7253k4ilw64bmow6xf6kcfjpluoyxcyxnzjhvkcwazm3dtid.onion:8333 -i6gsjwkdrj2jfyzd2vkb3auajfsj3kfopngtouipisk5n3ztpyj7iead.onion:8333 -ic7xuyb3vjewgcivsod5fylon2uefdrtbujm53aqeeiwsr66bn2qriyd.onion:8333 -ielfpoctimb6d76zfwe247ivufhlqixcmto3ajycx6jhc32au7nnjnqd.onion:8333 -iljvoqv6gthbhneadvnnngt75cmchef4e56emu2q2rkvyd6yvene3byd.onion:8333 -iqr6sqjcywscdns25gsizkaqngc3p4zjxmnsyj76aewnujp5yl47t6yd.onion:8333 -irstdqvwsgdbac2suvkdrv76yut3ronokffskydore6va2ucgqwqpcqd.onion:8333 -ivdhohrfnmupqpv2fdsrgocivsrfxeraxjl373v2ucprnf6nm4mj5ayd.onion:8333 -ixrkhtcfbads4dakl6dl4nlsv4f67ld7huogpp3crelpuufcpcwbusad.onion:8333 -ixxeuquydo5vzhs4t26svdpuogj57n3n4c2txtudumqcl72y7ppwwoqd.onion:8333 -j4j46tzv4rqkssjyz74ojbwr2er7gpsuwbplylt2yiuphla5jmg2wcyd.onion:8333 -j5bnioq3mo7au2hzknw7c4nlagtrovncwmanei46okq2e753dshti2qd.onion:8333 -j6klkyq5gqepr5fr366us5g6rprcq2k4wkszia4a5w4r5nkotajetvad.onion:8333 -jbfdgru6e2xkp6cs2vqcjin2rtlm3hdwfzc54iupupyugtbijurqc7yd.onion:8333 -jdzoeerhme3wt3msiabxho3aokqksecqtrbau7yldmmrcdl53vh4ntyd.onion:8333 -jjsfftvm3szpjr2clthujnniwmm7xpzn4eacipdsmne2nw7cotxejeqd.onion:8333 -jljo2fgeo3en24rfjsu5bhcuvgqc2kt3q6qpbdhcrmns56pepvrrdkyd.onion:8333 -jnvqw3jyfragx7vf2gvedjuqarblwmgzi2nvzncnqygxqkq3l3psi5yd.onion:8333 -jo436cjqpu5kho6jvnf53snalahyno2pkrezdiecrblzk2ndiicnulqd.onion:8333 -jxry2vsra3roinmemrv2t6r2gxgkr6r47dsyni6hda6pulutgp5gsryd.onion:8333 -jxwalubi4vmffetqrm62crkz2lyuwbq3m5jdanremtkift3ncmfmupad.onion:8333 -k42ycrbazmkne2eerker3pwvsrumjdc3nbocoppixhcslbtin6szxmyd.onion:8333 -k6xqminlvsasqfltb4pqccoodaye4dlpdcof2v7g5bhcc6z2hkqbo2id.onion:8333 -k7xabakio354gnlnfop4nb3hvwnonncjkiar55yqr5m6t55johp3ebid.onion:8333 -kbnqritxjzxijflvhybdyew3zfrd56qyhfv3j6kkujd6ageeg64h2qad.onion:8333 -kdyhkqz7hcnbq4yg262l7qscyhwm62klcomy7wim4ohd5gxp745yxgqd.onion:8333 -khi4dspqnbjqr6kuzo3vr4os3i4ucp3iqztjuvy6hmvc3pvenbkvpvqd.onion:8333 -khxoiv2fs6b5q6z7cdc2emq75xrxyv2k72qb7qiccx2ecqikkoevhkyd.onion:8333 -kj4ifgsla7bufutpr5pgfim3ukzc6odrqmxyaih3yht7bwolrvg7psqd.onion:8333 -kmamezicky3ssry3lnxwrsqo5edkx52vgklnvaxozk5sdpnjtohenjad.onion:8333 -koopg7cpbkyzt2xeii3blytcwzzbegdjulf2k27tkd6qpgtfa2ckqhyd.onion:8333 -kp4sx6yum3trevgiyftnr52z3v5tkoemjp3ja6ugbsp5fefyyv3jgxqd.onion:8333 -kpawddtnppkta5ldam3pkwsapk7bkpkv7euxgkh255kw7gcmuavlkvqd.onion:8333 -kqvdvecikfk3bvg2qt2supapuzci6yj3sz3jlremzydu34ty57imlbqd.onion:8333 -krthkvdasakdnocof45vpiybugof2ju2rqpvtwbns6udjlbodyluulyd.onion:8333 -kycmxoatbewdk2vfdd7gr6iyzpkqv4sua2i4p2qqfpepsna4bum3y7ad.onion:8333 -l4dlgqyla7dobxaa7hhrhe5mwbqw3stmwq4qqcsbly32qfc4stetq6ad.onion:8333 -lieapdss4vndhmtlb7t6afjwsrf52mdkxstrkfq6as65zxqlufa3aqyd.onion:8333 -ljlclqmyl5usdo546twyb3m4zfjwebfsx6suuibhkorcwhy4ufukycqd.onion:8333 -lllr3l5y3tlsbmlzlyr4g5znrer6g3riolkuxvwtajxqerm7yju3aeqd.onion:8333 -lptjkpwvnj4syw4zcv4v7wvzvkzi7nlnakfxag5uvfzdwud77ltn2pid.onion:8333 -lpzalkzwl7e7y7arsjspc6brbl4pxfhrkvo5vh3u2ioxiezuzkrnkvyd.onion:8333 -lqsqk3waohi3rmknfmed27lm6ofva33zngehz6oodil45zmtdnzhqxqd.onion:8333 -lwsayeaakdsfyw3lsycpc3d5lrcf6jbpkn43y23zr6nxjiwwstnefaad.onion:8333 -lx3c3ljioj2cgecp6de5kgxjayhd3wgm2er6xtrdxj3ndudvu3jyz3yd.onion:8333 -ly43npqw74bztp37tgkx6gqk3bs53lso5zmg6uwnuzlaqdlraecz5tqd.onion:8333 -lzyhfdkmvsutea4twa6zooefirubmalci7fu6h4wmo2nmztnntpslrad.onion:8333 -m22ni2zjfwlq5pfzbfothsk6fn2wthkbst6gpje6uqyz4nsjywm5fwqd.onion:8333 -m2j25j6quucpfwxlh57kdnv6ntsp5yr6s5ueimkdu3w2tvqko6ne2sid.onion:8333 -m2lkzmtdkabgckmn42pfncswyud7jqmxk2s3vxfnnnwqxclhxcbiccid.onion:8333 -m665l2x4zmaphdm4gd2qa72eerw2du2msfzxs6ia2znkyndy33elktyd.onion:8333 -mdb7aqlwyt4jqjuxgzmupfuxwktypj2tkrdfkds3d4wgviary7oykkid.onion:8333 -mgwp4j6bhbf4ez7753yy7o6keil6pmc2ie42dtdfm5zz4ky5jb5sldid.onion:8333 -mmooebax2ks5ucswdzilx4gaoff37a2qtvi2tfe36clnjtdgggundbad.onion:8333 -msrmkyfkgcztmcsi4ei4tsyeadaw4byzf7vcffrd45l5kxnyjycpixad.onion:8333 -mtdf23ghhwwtliy5cj2gyv5wb7gkpbwjyh45nqppnnb6jxncht5w5uqd.onion:8333 -mzu7hum45gvgbnqhfbkls4sgoo2pfildd6cev4wfkowwvu5gapr2xyid.onion:8333 -n3dcluaorh7u6ilie2dqpmtqf5gplvpuoxjo65655mlw2hqbn7mxqxqd.onion:8333 -n57bfzhlq23h3mx4zfhytwyrpgxy2vyw3qd766lb4ysvmbdmanrahhyd.onion:8333 -n6e3inyt7quzwk5sam7v27sw5kuc5zeleomzbfjmygkoitxsej4nusad.onion:8333 -n7fxhdsmopuvrweux6ms5bg35cmpmbhxwbk5ralq7mhjdml2s77genyd.onion:8333 -n7p7ed2ejwz2zr224azq2nov3zyqnvhosorpvhmu24pqwacshahpn7yd.onion:8333 -nb4a43pfqy7guc27ksfu524bznmkgsqsfpmwzhru6iqu4pulbgaigdyd.onion:8333 -nbjbv6epmsktqfsiw76mvpyonnkom5xvnogzeyyjgxnm3s2mjfgncnid.onion:8333 -nkpl5epgo47qiqya6ijwtohpnuyueym7ux3dt2ccnfbgvy3gqeyhy2id.onion:8333 -nqy3yoi3xuse2rxibk4vo5drjmeuuwnecaewbyxnt3ffg6gsebmarjqd.onion:8333 -nsgdxf3pwioxj5onc7kb3cwp5icbifc2x4obj65bekw7dnn534vjeoad.onion:8333 -nv4weo4xp3r37texgd4mxzknblovxnhcs2laswtump7vhjllgf3mvlqd.onion:8333 -o3nctwf7tmsoylnlreuwwrwpzpofwqurzpsk4cnotyg5uwyngce6nqid.onion:8333 -o4l6ihjktvg73rzkoiz3amxkszmpp5thfhr7otpvwqx72ii6tmuwqxyd.onion:8333 -o4vb2emnbbzob4yuwiiz533fd3dbnbhz2wjnmfqu3cp4gjo6d46sh4qd.onion:8333 -obhiondywyso46m5egizaum7fsqnwgi24tpd6phcizoytsjhro7bbpad.onion:8333 -oe4xlteqwjffy7ljpbrij5inbrrkni5v6fkr2efswqtnd5l6cw7ix2yd.onion:8333 -oex25ysc3h73aqxvp6rmh37s6v5ko7oybdeq6wf5zfvx4tuvgbno5fyd.onion:8333 -ogydkr7744s6yth76pphjha5jcsj7k64rdrhaqtqugqp56jpb2hn6ayd.onion:8333 -oklrf5acndz5gtpmtgnfvc6yo6kyadp3yjouehjgxhljwjtpmxqyjwid.onion:8333 -oms65ve4z7hcvlxnubwvfe33hhn5jwjzjtv4gmolqjeolzv2aq6a4xqd.onion:8333 -ooobxdrhewee5xn2mypadgsq7pysih2l4g4cfvf7ch6lp5qbzt7eipyd.onion:8333 -os54ay3mffzaf3ednkgyeuirayo4bothbmcvm275h6af3luszoxcd5qd.onion:8333 -os6eoqu4sjkya7xvedx4jrwlt72frbzw6p5w2rsswpw2dxmkfkxsibqd.onion:8333 -osfazvr657jukhdyj7rostfg57lzy6c7gvaxbh7ul3jakppktisckbyd.onion:8333 -ot4n2e4xwnxpvpva46swsxwxiiaumy7gohasuow7v2qvefdc4txej6yd.onion:8333 -ovazpzdtupsqfygs73we3wq4lpodegsh5eggomazb2kxigd4mjpyakad.onion:8333 -ovtx3d4svetdt7kav6jghbasol3fhq6zwuud4njngyrnhvkdwetko6qd.onion:8333 -oyavbcj33zt6abvjfwtjel7ac4jqaz5pjdu2xmcknudr4ul5fyjc5wad.onion:8333 -oyb7xtoiteb32pku7fwgl76pwe4gsc7gsk4hk4yi2fgyxissck2vxtad.onion:8333 -oyxipyliagkpfvhlgegfzye2oxmsdt7xjcy7dpq2xhp6j4ljld3xglid.onion:8333 -ozq7iyucv6squep2d2jn5zmozyy7yxbdmw72lv6i2jb2weq2vtn3czid.onion:8333 -p5lrtmxtzlrg66t763gjeosmwulxhniss7ct73nsqymujozepxpzo7ad.onion:8333 -p7xhbz4hkgc3h4t3sgqixxyaal76no42faet57znpmaorwafwi42ofqd.onion:8333 -pbhxzwdx7v5wtduqpmfoc72mxhwlyxg4unak3zyhfnuusfmizffvrbad.onion:8333 -pd7euoerq3yycf2bwpape5f2aubhqxxzu7a5dnrpukrzycs4zkr6goad.onion:8333 -pddjxch6t3f62isaxkrmtzblrlszlr3vpttplhwexfvcnxxx5u7wtbqd.onion:8333 -pdjfo2ehm7t2mkssadyneia6ftdb2tfuebeuxaqmnlkmvqv3urnj3yid.onion:8333 -peynxnxmdwdiqmmolcttpjyrlqorwexyv5hhkfclobetp6shtu37pcad.onion:8333 -pf2y6twnz6seo2pn3zzawyndgkqaibllnv4pzchvox3j7krcbathhpad.onion:8333 -pf4esnp4qy654vedxpfcxumznjasdqa3c2cnzdda6uqpcuxtd2o7fuyd.onion:8333 -pjbvklsqecs4gcfvq7wqicoeb5ir6ch3jwwavjth3xwg5ag7rem7sxqd.onion:8333 -pjte4dnxasrmst4nduwbcgm7mnd2qdrlnd7vq3c7mkxxmt47d6omf4qd.onion:8333 -pmb7nsm66jp6ewkjro6udhshkwcoc5tna67td7g2gx46bmuvtttkxkqd.onion:8333 -pookub6jfnna5nzonaruqzkjfekutzfunrppjuziqvnyfk3645ttrmqd.onion:8333 -prjdltjghrherdhw6ieu6lg5zgzzyx4ykc6ad57z5pz6uxmt7kop7jad.onion:8333 -pt2rsnb42lx4zlr54oomzj54dlbdeuiwmk6tac3ovkk4g734hawjyaqd.onion:8333 -pttgdou3m24yywbnky23b5qf63inr3ebi2fejjvjmltsd5l5f4hxtfqd.onion:8333 -pwiob4nt2tmpngmvdb6gzhaku5d44fjv55f76o7c4dudwofzr7ww5lid.onion:8333 -q3hnj7stbm5kdbekxy4vgmhalj5n67kftcrh6r3xz7o5lsxgwgqtbxqd.onion:8333 -q4dfybgsjoiqcngc2xbol7tohvppag6jqkkuu2rsp2a7idlobh35bqad.onion:8333 -qcb6bwlr27whuehk365cu6cjcjj7oww3vhosav3xx5ftnbhgoqrcfcqd.onion:8333 -qck7qr76h6yuc64zfn43toxkry7k3ts4jlhjssnkutzzxlc6v5qfuiqd.onion:8333 -qdgtqkxl4cxt4aqhh7vvwnxseyk3mvrwqanecfd2nxblqi3pfskiq5id.onion:8333 -qfpzcma5oslkrab4jelcudhpvllsnsiqpgxh4gctomslru34x72pl7yd.onion:8333 -qfxtc2jo4mx5r7ietkjekszkhobe3cqdcacynopjxykdvolsxhohpeyd.onion:8333 -qgin7f47k3qpomijhrtonrm5p4aliqfc7itbbc4pe52orxtqaqetmvid.onion:8333 -qhj64xgjcv54jdqerpjojhr3jcm5gluq7hqfgb37t3ycrmpwjhyx3uqd.onion:8333 -qk3fp73k77e6rj6t7wrpxigvfsgdqdwdbeglslviqdcrzp7ige4cuyyd.onion:8333 -qkx25lac74ejv3v7p2g3zabca5y2g2rxzo72wx5qhtmlom2ly4bdl2qd.onion:8333 -qlw4ciqorajhp27vglas4x3phn7nvpr7amqmqmfnvn2uhnm72k4pb7yd.onion:8333 -qmab7yqvjqsr5dc4rwthpufbfmmnrldq2efcysxom7677wusy2jg3hid.onion:8333 -qmi6hz2v4ivx4w5qtn4u5ud5mh4nayhautvfvynyebtpjyahr6pp43yd.onion:8333 -qpgdab6fgosymur4pmambbdpczizjp3zm65o7n7kdndgfqefigt5vpid.onion:8333 -qpjsvyu5odt6yib3bpu7pogt77frjzzmn5bdeik5qqgof2onf3ebg2id.onion:8333 -qsxyclpzutl4anwfkhthhmbd5oui6ec753vnzvncowabjuiu5r33myad.onion:8333 -qtma3kofgmj4x52kyejgh26n2defiziwgrc3pjumaewwu7sxh7xyvfyd.onion:8333 -qujnwayjsdllqelffiy67n23mb6u23mih3wbd2zdvjeoyo35mdzi3eid.onion:8333 -ra32r3e3tse5ogch6fxld66nu5am3kqmhw7b5c7yo2popvf2opl3wlad.onion:8333 -rbnzskapgz3zn6z3dpgbj6rxlrnml56cyrx22vw2exh4n5apx7rmhgid.onion:8333 -rjqrut64oo3tgpnsrmy4wrujlsufxifslx2bw6vqzfk3mhqsnchqimad.onion:8333 -rl35ajhf44k7jd2j3vajy7cnbmnylcvn7lx62avhhvdk2zvmhchfu2qd.onion:8333 -rlncglnpdcrywcjqj6wxkn63uzwzxl3gtgbzqvfcetzbwg2me54ediqd.onion:8333 -rludpttjgyegce6isc6nzkso5ysyhtlxni2p5j4uae5knbgs2xfakryd.onion:8333 -rlx42j3ymomkf4wq5lgenopcjkp76xpymlqg5kao7m4cecekcvx2akad.onion:8333 -rmkubfilpxxvf7w7csnpmx63hjz7hpvmodhu53cbliyqhun53jzl6wyd.onion:8333 -rpux6zj6wokq3kp27mc34gkdb6vk3kxly6imgqzukmzlhe2sc3l5kfyd.onion:8333 -rr3nr2ooywwa5r5k4eafo7lxkkee3piebceqlriciumwetdsrgoc7jid.onion:8333 -rrdo76cf6ctl6qgxzacogwabh7rohapfhg7z6wllyt2okw664wxytcqd.onion:8333 -rtfyx3pxozf36lan77kz4x2w6ixm7wvyqmvtnlmy3wosd7koe6xvttqd.onion:8333 -rzq2ys5wtk6qku23jbhplm5kp5wzebcfxv65uvk3zqtytrj3fa3t2cid.onion:8333 -s3ig5iv5eldufmzblnvfcfnqq7kgg7mlexwrawn3mk7it2bpgxfdcbqd.onion:8333 -s3ojmryuqyyxdbl3hygkboxz6lpnageat6zcz2leywrzsm3jr7w65wyd.onion:8333 -s46rmgxjd5stdldxdlb4sssdgmqrgoeksnybkfxugaw7vhrsdr2mzfyd.onion:8333 -s762tz3hwhnz7ock2wap76rndat3mckse24e2gaag75ko4wi3w7tjzid.onion:8333 -s7btvxgflc7cakgqar6dmknlqcqr5am3ebdtovei43bz4w3dkakk53yd.onion:8333 -sa4etkehfhzbksvlxwyf2iko52zgrhl6h66e27u2mhw2ayu3o5z6urid.onion:8333 -sacohs43bokospkyarsb5fclzpdsf3o2nrqqejcig3l56remrzz2dyad.onion:8333 -sancv2jnekemexmfxga4ktmt25yje2cb7ai4ywb5xxjthbzbonyephyd.onion:8333 -sf6qzwfh5aau2zt3iinynzwww6ika26tdj4spxws3jscdvssuohd4qqd.onion:8333 -simvzuopsv2h2xnwefu7jxbtghhnqtz73d4nsxcr4xdq2nxnt7tcksqd.onion:8333 -smle73emjpctbblug5gf3hkny77wyff4y6cvc2swnqrlsihjsgh46xqd.onion:8333 -sniximp2psj5i464i3d36nlmo73762h4jckszwqqx7kkuxppophnfeqd.onion:8333 -spevwedct5byy727a76ug3n3fjmod6we7tfqoecchbw2l47roitrncyd.onion:8333 -sxcohqssgaccsjfktizwrjgrv55eqx4zv6h6yqr6smnszllrli44utqd.onion:8333 -t25lvcr7nihqe7w653xtdnjumkg2ya3gpgvenqsbwxy4hs2tqyah7syd.onion:8333 -t2e3qzuaft25zolwmojp6r3p5g5nak4pxixh54tft4khvhheczfr6xid.onion:8333 -t3knwe6h4rrkbumb2foe4qszqf3prw7dqkm2i6zuyzbke7qin3ysjkid.onion:8333 -t45gsyqahwexyg7yjpv5xq3cgjdnk4ob633ly64kxo66h2oh2zq3coad.onion:8333 -t4t7otcbxphyz2mfb77h3zjpeo4av7xx6y4ryjigylec5nlhaof5hlid.onion:8333 -t65bcyf2eni3vxlqsdg57g3yjxtk2ruy57a2r542mwjnqdvxdaop32yd.onion:8333 -t74jhdmey6isfgyuyvdfmhxrbzhzs2fhj3mdvpox3da2nslkisazjkyd.onion:8333 -t7owetuja5t4cdb3fhznmiezndkc6ldvpbquszkf6gcipvo3sy5vkjqd.onion:8333 -tax3bgihfuogisukzr5ztu645xcxhnfjyqhvd7kurnmt7faelkutf7qd.onion:8333 -tckqucjlhho76dgrpc4iyuhmjzwddt46dzcergxaie5fxf7g4nrnj7ad.onion:8333 -tdhcehjcvo3yubiseyhtseu4mqomrpfyedbd2rmf3trcmxxr2iktvhyd.onion:8333 -tgupedfsi5g52wftxdefnnbzagzqgom7u54atpamqze3pcz52nu2raid.onion:8333 -thure4gzkkxo7f3gp4fcf2ay6mikepx6mcwql5xrotxanzxuro5dcfyd.onion:8333 -ti4yzr5lqyldgyu67nkii5pk2i6hi2qvq6p5qsjqkxly6imxu56o3cyd.onion:8333 -tjkqn2tsn5tvaazdxbfsgqna2ve5kx5ip46j3acmqqh45t4j3ikseiad.onion:8333 -tndqqjft7p7ouqvv7lz6y4sqcncero3lffrukzugkuoztgwubqfcbwid.onion:8333 -tseke6n4lykhvdezwkf3kwmxitgmrjjbyma6nol5eh2qnbk3ocvhnfyd.onion:8333 -twuhobnvoi27o6zk2uwyhc26vdnpvpqq6qgceioxc6sbtm36wo55udyd.onion:8333 -tyfxlylakchnkvbks7bypu2jq4bzexvxybzabxrenxgra6di3fjywgqd.onion:8333 -u2hd6xck2bpmuvaatgo5nmioejk2voaa6lmv3msbuvpo4xbirernxwad.onion:8333 -u3edrtzedv5tmzizamlj6n4kmpfrn4ekvxfjpzauxoy4jps3orzftiyd.onion:8333 -u4sovrilfl5zwq6vzekes7slvyzws2phc6r5dvibj5fnbqxdmmuci4yd.onion:8333 -u7phavksrlzphv5upw3nty3kh6rzmkxlg3uaa7hqadt7dhjgffkc2uqd.onion:8333 -u7wxfxdpptoj2dacj4h7ykahvturudanyirjpj3qpk2r726x6skj3sqd.onion:8333 -ufehxvatqb3pyfrdvcdibgfdribzmwvaf5xsxymeaq6l5a6nqukr4wad.onion:8333 -ufm43yp3x46sq7io44mi5sn5kizl4fcpnuxhwafgr4h3jn7hhjjf6byd.onion:8333 -uiobofaykuraqarsedt6ookshgmuxt7sefgiloixn5zgambnt4kfrdyd.onion:8333 -ujf2zphfaywzy36o5brby4ioberpv2tbu6ezyoi4qyojbfaio5pwrpad.onion:8333 -umesgylwjb6x57zhqnk7jozvblkbq3sovmffxxppfufg27kconydnwid.onion:8333 -uslbkjk7xdiug4zga56ybayvxttxttvnvj43yuomn36sn2iviattrmid.onion:8333 -uw5gml332m5mns3y63phwuj5trn5ojkrtb2shptzkas2ckdopzbbbzid.onion:8333 -uwavujkkmgl4kcyvyvfreuatkpfxh7giifug4pn6r2nuuoergp7vuoid.onion:8333 -uxahghkwzt2lty762rfbf3vn5xlehfhhjrawdrwkmuyw2o6yep4nxeid.onion:8333 -uygew6jxykss3v4byk2m54bdtqnftcpw7xdrtdudlvxjag66hgsrm5id.onion:8333 -v2ke6hp47qxkgkpifftjdr6qb3o7n7d2sribivrerskifefik3iar4id.onion:8333 -v4crdrenwd7tqirnxqcbf5w4r3cg6xaf3hfz3sgp5zej7haygxeiciad.onion:8333 -v4uf3ssnetuqduflgjroutwk6cvscqbhbsxdmhx733xcekudyovuxnid.onion:8333 -v67jkpeiaekszv4vyvt4r25xzh6dm2q2cl2bkrac74ltibuxabc7xmyd.onion:8333 -vbfx6jffhiynj7pmt5bwfmzzql5hkw3pfzlgg27l5j2mxu5e2oabbzid.onion:8333 -vd6azdeefrxp5crdqptbxcawff4w64mmtokmu6iwdwquscwlde5htaid.onion:8333 -vdjby26wyqioxkp5vrkb3ohsx7qp4kyavgq2ejjdakicvvff4bkyunyd.onion:8333 -veqxagt2ag5xv7tnogcueswb3e2likgy546ckjl5zzp6t37ibklkuoid.onion:8333 -vjbvzvngmdzxk4v5tohrtth7eragfoiuhkhpgifndap45qlhdiuprjqd.onion:8333 -vkjhzgxumv24pje46y6jcl6xul5v62nuwutgzhwqx3orm4fh62mzjdqd.onion:8333 -voaubwpvly2eghhrr7u23ylyele74t4u6r6x2tykhcoeo4ie4bflpcyd.onion:8333 -vobatph2s4eqchnexixgqsec7tg7enomdlqc33qlsx6futliyue6n4qd.onion:8333 -vqvipjsibngsr3jsuwhqr5zk6hv5ggfhshwxioefbg54j3y2vdpqo4ad.onion:8333 -vsfc6o36vi4dbctysdomxqs36mncamm7udtkvlxjyzplifpnqtrwlaad.onion:8333 -vsfexay3chere7t5rdr2hmv3lp3kyggurzorr63ustjog2zzgvozuryd.onion:8333 -vsgwevkqyxtcjqov4ybj76airaedrvenrcbjkhjpddoddhd52a7fysqd.onion:8333 -vvcnpfykwjgmtjxirwwacbiwzcdraatmwu4le3fy6ycyz6ud7eamtxad.onion:8333 -vw3gmeqdsxbluya3nnc4rivdrgdm56fuavkzyrnjcpeqic2wlcgr25qd.onion:8333 -w2blxbcvpl2jlq4rtk6qvvckzmqwyei3j4foe57up4cmfyeofupabpqd.onion:8333 -w4xrzo64lhnrjdojd3ae4fko3kqkwazo3yhb5yxymnuel7k6hafviaad.onion:8333 -w7lfx5wfof2w73umxulyffg4t7e7vr72zuej4i2ws7i4bhdxfmkbljad.onion:8333 -wadatcpr2zkcvbh4lgkn4rtfuufnz5qozftvgk35mqiojjjeqgjrapyd.onion:8333 -wf7pumlk4w2lm7rr5fp3b47yljuwraz3fl66mw2iozm4lmhkopoq24ad.onion:8333 -wflg2vztk4y73m44olz5qnbhzsvvjfi5tz3wmdnps7rf7tntlj2vpbyd.onion:8333 -wgy6iwuhf3kltbxoftaf3s4s5or3ewwzdla2ukfgecgqwjm6xtfva4qd.onion:8333 -wkmf7wnecgkz7giunadfmyslotwtry42y6hw42wxlc6qhpa46qoui5ad.onion:8333 -wlmymukrfjh2isrwats2ozbmoiavqklavfycq2ziht4fckpkodktasqd.onion:8333 -woiilwjxzciokmzx4rq4dbg36nhnocnapinq3v4pgpgmkpbxtugfv3qd.onion:8333 -woz3p5rshuz6zccjjjqn4bt6m6ri4pbh557pzdvbo247jmhejr5wmqad.onion:8333 -wpgzpf7mnaj7pqhvwyfjarekp2ojoc3hc3hudgii6dyhka7p3xqxf3id.onion:8333 -wrounxy4wxcj3ptznwfoainrjbiukff6vbxse3lvrgzg5cjfncfctnid.onion:8333 -wrs65mjvgzo5q5en7zz4fluwx4qjdn7pwm3twfrrviinqgzhs3vambyd.onion:8333 -wt5an3mgpzd6karuvzkiigm5h5rlla7gx4sfawzsx47aou5tghovc3yd.onion:8333 -wz5kfeeen5vnzoxknfu5p5ymrhid7gi4v5uloumo2kuiwj6q5legi7ad.onion:8333 -x6hsaqopoftbekwibf62a3y6ooy34i7dilkdgrbiwtu2fmnfhibr4tad.onion:8333 -xasfd2ui4djkzrblpj4dbf5senrren7jtqwcqwtda7kzx3cgud2pzeqd.onion:8333 -xekjpcli3gqh6anqr7txupvvavxmyghodw4vy6p4dnieu2kidqe56pad.onion:8333 -xf5rfb3ockyfcdklqrlqxdxsqhjn32gygiwtncqcsef7ve4e7h6exjad.onion:8333 -xgvwwaezo6tzt2fzshhrhis2e7qnkxegvljs3di4lxfim6l6imgpu7yd.onion:8333 -xk6keofl55jt6cwnjjntsdlt7gr3isfekponsblz2e66xujeuv5ew3yd.onion:8333 -xkkaspfulmvoz25vvsvuwwlzhbq252cvxeghqy6qxa4frf5pvn3ehfad.onion:8333 -xlghuegqlq4fzckjwizb2e5lxlsk76neok7rnxsutazqkkiakdk7riad.onion:8333 -xli6i7xjcx66s3lfq7u3zmewxydpo62bezeocplcsn6gd6zx43qi5zad.onion:8333 -xme4lbeqtbdepl7ghpzuelqqtutuw6lxlbu4vwhxeos7qdv5h7at7zad.onion:8333 -xohcyhfyr5yyljypqgz2ho64ban36pwy53hybsvwbtuadfoak3knqjyd.onion:8333 -xpqyiwgmabsxdmgtgiah7zceeseleklnnanb7g2ajgzktls75faz4iyd.onion:8333 -xuenjyogv6irymjv7muohv2455nncrkjv4mkopfs5dqgwk4q4rpfezid.onion:8333 -xunegc456hyc72rcfvrmmulqak3dgj64wcdjrjv5o7h3nvbsfs3vvuid.onion:8333 -xz463kgdshepjf7gtnsxibjaomtbuksh2wc447xgawmrl4bbfbzg4dyd.onion:8333 -y2ths7kf2pifp4ajoe5ii2ftk3wixcfqmsnmrphlh53jj3342c4hksid.onion:8333 -y36aipkodbtcjiyf5w3h6oo5dvfa7lptl2sbp2xwqlyqcojs7kypejyd.onion:8333 -y3v4djoqsoocvivs463yyif657s6mjcd2n4eztrkqrtte3i2aydi6uid.onion:8333 -y42vk3myp77lncrn6uvrixabdnvppb6ccwtkh3yxhqim7zrjrdo3saad.onion:8333 -y5ibjg4ub542wp6pwozwchkkfqfpu5kup3v6454pumverlvpfff467yd.onion:8333 -yftuiua74fspnqanvait246qn6vmab4aoympjd3omppu46jkq777axid.onion:8333 -yfzxfi6ceyx7ufvrket65o7klryiqsscrd4b7mjteb2yulv37bewumad.onion:8333 -ygv3engdifduzejgjy2qkx6wub2r73h3h3niuqv3chdlk2zm22qb5vqd.onion:8333 -yh5bggjwpbau6wtdvlbkyomtxrh3xf5y5cwd7fqi7ptzazw5c4lbglad.onion:8333 -yh5us7dk25ttxkt6miers3bazlm3jiums5nwz6mzd4i6kn5oizjccuqd.onion:8333 -yjc7fnkd3b4v4vkrdncyts3koskuetqhcgpzupbywwxea4bhhx3qmpid.onion:8333 -yjtnadoumitivwzl53lb5453t4ko24flrpfvtsiyd5dnf7jaqdgwjdid.onion:8333 -yksivr6h6qreccdtpe7uwji2hmgqy5acbqd7zrsdlixrbfijdmqxrgyd.onion:8333 -yojzhgbtxvnrzuqawvyfnpkjnxre6rzuih4etfe6dd2la3jrupc7qzad.onion:8333 -yorpx7sgfswvju3g2whr25s4mkbqihfqxxicuyrfavtjpp3holjopkid.onion:8333 -ypsy5kvuctqnjnvlels7dozlbpxltbtlczicswpz3fwstxupb4e2piid.onion:8333 -yq4bqleayx2ilaxhdxjhvidx3tdrr4m23g2oegfmnpog4b2libezwfad.onion:8333 -yrv6u2spxa5kyj224bu2leoswmqi2woocntt5stnab4e3ab5xai4kdad.onion:8333 -yxf7inhfo435bjotzmzaelgt7cnerf5eq67h4sb4ynurspl75ed6upad.onion:8333 -z2g55fvlczxsnuijx7e4p3bgxph2udp6x4kn6xjmqzrkpdne35tkoead.onion:8333 -z3ebnsxe6awfedmwqd5btg2zrdtjm6izaqsiodbo36tpxluujg45dsid.onion:8333 -z3gm6oghblimyiubqkiven73wgoytsq2jklwtz4sswukaeekihx4htyd.onion:8333 -zahrvinucuxpxu56h6nkiiw7cvutxrua65l4jynvwkzt2bzmeuvdpuqd.onion:8333 -zdnr3dc7b5lx4pph3cj73nmojgqy6h2kgcrf3xw7za2qdnh4ychb23yd.onion:8333 -zej7mizjlb26qecppzvgyswervt7ov6f4x6fwrot7obvab23xsv5jjid.onion:8333 -zgfkpi57f3hybfhh6vltjklxyqvfu2nzkpipqyiyurfccmkdwlatuqqd.onion:8333 -zgj5kqoqgccoccgysrygfeydfsn4z2qx42xjp6mdlbqfzqthj5z4vead.onion:8333 -zgrpshddeijmdp34xfyw2kz22la4jxgwce42pupjp3bo6xtchsorrxqd.onion:8333 -zifp76tjeur73gokktvwyy5lwh5vgjerokbv32carsizgfki3pbfuuad.onion:8333 -zkvdpnuo5gv3hvvlkit3vyyjoeq3vkg27ihqmbif32beoqf6ftcnf6id.onion:8333 -zlpztcqey4osd3omtpsm7micrh6jrxuqzeeendpngk25iyfhleieekqd.onion:8333 -zm2ox7js5spqbslqqgjags3mn53jalknoi3zlva3iihdvykmbjzcbpad.onion:8333 -zmerkoegw6pxcgimoezzhykpyhe62l4xurglh3lnqwknaciyos2qg5yd.onion:8333 -znb6fuo3hgbfmscgkyjvexukok2diyankdfzdt7pde5jnze5hhrdf5yd.onion:8333 -zujw742s3kqa3cqjkg5s624rfjpodtbnuguw2wyhdp7mnqngeeeqiaad.onion:8333 -zv63heoa7jstwhq3wg2nibip36bw4icd7jphccy3li3nut7gp2gojqqd.onion:8333 -zvnhw2gbxdyxhrjjmyxotvxaibgo34k2i5sw72ogtydi6sqsns5te5qd.onion:8333 -zwyshlkggvehzqs26clcvuskdxen2ry5zbl5axe36x4brzsk7b55ypyd.onion:8333 -zyetfkanxicfp6tt5tegkxlkoz5rl2i3zsc6hyyqizahywbktezfuwid.onion:8333 -zyku4bk6pdifla26hympigytlwsx4htajcn43hhobdbrv4tfojv3snqd.onion:8333 -zyphknlr4ogrknj5t64qya246kdaasgirn4iercvesggqplzzxsisbid.onion:8333 diff --git a/contrib/seeds/nodes_signet.txt b/contrib/seeds/nodes_signet.txt deleted file mode 100644 index e84fbcf6a575..000000000000 --- a/contrib/seeds/nodes_signet.txt +++ /dev/null @@ -1,140 +0,0 @@ -[fc10:efa7:ca6:1548:f8c:6bb9:1cc4:63ae]:38333 -[fc1f:22c3:95dc:a3af:4a93:8251:beb9:1858]:38333 -[fc32:2c16:d0d0:f1fb:3b27:c187:8cb5:9201]:38333 -[fccb:248:11a6:1042:bca:1218:f7ce:7d3d]:38333 -3cxteqanevzjd5iufktxxh3l5abj6fs6udqg3bomphzofqjl4aqa.b32.i2p:0 -kmmq64ijxhaalfpatq7q6yyrf3rdfvjk3tsb5xc2rrmkgdqf3vwq.b32.i2p:0 -nmmoytmmcwq4aclmtrxk3askrv7mgy6l27uw67ozvyolwca2dr6a.b32.i2p:0 -qhlt7irano6s2pjfn2v4qrtynjj4peo7tfsnv2x6bm4e4vowptaq.b32.i2p:0 -qn7uwi6nx6tuakxvzhjnjeuxwpcq6wcv4diecrv63ugain2tdopa.b32.i2p:0 -regl2o33xgkhnuu5ywr7tw72dio46j6tylz7zpdl6pfaqsktboea.b32.i2p:0 -rkf5lugxqdjrxva2n5wl43okxrqmm6prlf7arci4bgg4md55oo2a.b32.i2p:0 -5.189.136.209:38333 # AS51167 -15.235.55.158:38333 # AS16276 -18.141.143.94:38333 # AS16509 -18.216.1.71:38333 # AS8987 -23.137.57.100:38333 # AS1002 -23.226.164.192:38333 # AS3801 -34.16.103.64:38333 # AS396982 -35.217.29.66:38333 # AS15169 -37.27.45.224:38333 # AS24940 -38.88.125.238:38333 # AS394256 -44.210.109.64:38333 # AS14618 -45.32.127.199:38333 # AS20473 -51.79.29.216:38333 # AS16276 -54.255.186.152:38333 # AS16509 -63.34.82.20:38333 # AS8987 -65.109.54.101:38333 # AS24940 -67.209.52.138:38333 # AS20326 -85.190.242.80:38333 # AS51167 -89.155.238.72:38333 # AS2860 -103.16.128.63:38333 # AS133159 -104.248.42.204:38333 # AS14061 -116.163.20.113:38333 # AS4837 -121.78.241.71:38333 # AS9286 -124.156.198.249:38333 # AS132203 -131.153.11.131:38333 # AS20454 -135.180.99.74:38333 # AS1299 -136.144.237.250:38333 # AS20857 -143.42.65.56:38333 # AS63949 -144.24.238.157:38333 # AS31898 -144.24.241.206:38333 # AS31898 -148.51.196.40:38333 # AS12025 -152.53.3.192:38333 # AS47147 -153.126.143.201:38333 # AS7684 -159.203.133.144:38333 # AS14061 -172.105.179.233:38333 # AS63949 -174.50.212.60:38333 # AS22909 -175.110.114.74:38333 # AS49981 -178.250.189.42:38333 # AS214379 -185.148.37.170:38333 # AS48347 -202.182.105.108:38333 # AS20473 -205.209.114.30:38333 # AS19318 -208.68.4.71:38333 # AS397444 -[2001:19f0:4400:63c7:5400:4ff:fecc:fc1e]:38333 # AS20473 -[2001:19f0:7001:48b2:5400:4ff:fecf:6e5]:38333 # AS20473 -[2001:41d0:304:400::d0a]:38333 # AS16276 -[2001:41d0:306:4505::]:38333 # AS16276 -[2001:41d0:347:e00::]:38333 # AS16276 -[2001:41d0:403:4ecb::]:38333 # AS16276 -[2001:41d0:800:330f::]:38333 # AS16276 -[2001:5a8:4164:7a00::506]:38333 # AS7065 -[2400:8907::f03c:92ff:fe6f:ee2b]:38333 # AS63949 -[2401:2500:102:3007:153:126:143:201]:38333 # AS7684 -[2604:a880:4:1d0::352:6000]:38333 # AS14061 -[2604:a880:800:14::3880:3000]:38333 # AS14061 -[2605:3380:422e:1::50]:38333 # AS397444 -[2607:5300:203:7467::]:38333 # AS16276 -[2607:5300:203:a29e::]:38333 # AS16276 -[2607:5300:205:300::1b0]:38333 # AS16276 -[2607:fdc0:1c1:5:632:1ff:fe54:ba56]:38333 # AS20326 -[2620:6e:a0a0:1::71]:38333 # AS397444 -[2a01:4f8:121:4072::2]:38333 # AS24940 -[2a01:4f8:13a:c56::2]:38333 # AS24940 -[2a01:4f8:2190:1692::2]:38333 # AS24940 -[2a01:4f8:2220:1a70::2]:38333 # AS24940 -[2a01:4f8:231:3d6f::2]:38333 # AS24940 -[2a01:4f8:c17:bff8::1]:38333 # AS24940 -[2a01:4f9:3080:3496::2]:38333 # AS24940 -[2a01:4f9:3a:2496::2]:38333 # AS24940 -[2a01:4f9:6b:301a::2]:38333 # AS24940 -[2a01:4f9:6b:47ce::2]:38333 # AS24940 -[2a01:7c8:d008:e9::3]:38333 # AS20857 -[2a0c:b641:6f1:6::2]:38333 # AS214379 -2ycyu2aba3xsqjr35beqporp5f64ntqs2sau2amn5ztq4j5q76amhqyd.onion:38333 -3qeedpzgciv65tdy2tsdmjxswhyep4aj65jtboznf5nnwcyo2lbmiyqd.onion:38333 -3xvum5nnvcchvfxwlbc2it7nbfxhml6ovt7xehjw2potempk2om4eoqd.onion:38333 -4n2rlrrnxcpnfrft4ivlsvsjiahk5ffxizcyfr5amjcqfwt4biitjpid.onion:38333 -5ofovtlx424wnxyoohnsxqjktwqd4i2kiqawox3srsdttsp2pdrx6yyd.onion:38333 -6fy45vxzgc6siecr7en4k6oft4k4ix47jvkxqyzopalzwyphqc3hv2ad.onion:38333 -6ivh4quupqu3w3glr2puyi5bitjapbbl6ehvbjsvleopyy2yzjgp4oqd.onion:38333 -7mgfpo4urwysuafbo6sb3u6vh5f7pkvgddrqohcobhbkblqrrozhn7ad.onion:38333 -a7mvea5xgpknsqaifyvfstdn2utjvph564i6ti3nbdr2cksby5jhykid.onion:38333 -b3sbqhjstq34ae7lsrw3syhxcjdu2ssuf3f3kvbnyrvbp7cvuuopmbqd.onion:38333 -ba3rwqombmuji3wxpmydrk7vcxfpq7pnn5bfw74wvvqyo6rrhwqrt6id.onion:38333 -bodh6zsjtn6kvdk36ukx6fns5hqiiw3zhkqmcmj54nrtkz5tdtb6yayd.onion:38333 -bux5jwkwzccba57zthctdgsuwp5mi3wocxndtuf6jg2qqab3vpnqnqqd.onion:38333 -ckbugjazj2iotosxah7odbxfozxivuk6zu5npf3iwfphvoh5brdjfqad.onion:38333 -cq3td34eu5xjymlxl7aq4rsskxjt4ag267i6mzhdqhdpfzcqctus6aid.onion:38333 -d27tvdmi6wjjlffjyhm5mogwsw3433jxkaiwhti32eagvljdzseilqqd.onion:38333 -dpzlvj7kmbifhbttfe7vwl6fgpy5os62iiznel6eocsaarssudtdzoyd.onion:38333 -e6xhvtrt2ppjfxckbinu7a4jxmy7usjnvjx6st2cipmvlnnhxg7krbid.onion:38333 -ecx2z3x4nwbzjh6dh6vyccljkhnxya2o2o2tz3pzvetxfjjmujxhctid.onion:38333 -ehnxcigc6t34smlk5lftfyb7rntcsbwhlu3pe7ltft76gl6y262ekdqd.onion:38333 -ejgeimjypsfuijpxzy5xpwmmjmkr4izwze6od5pw74csjglflib6nsid.onion:38333 -eqhrqtvxkyjcggbkmzgocynaskblynl2bqeuel4lqs4w3f3rgpfpnkad.onion:38333 -f7xfq5hijqptsdak6qjx3komxrff2hw3xa46d7cs3d7igvm5tylotbid.onion:38333 -fo7cekwzd3ibyoxuo53mfqoxffgfaupg5ydxbl3rofvwxtzbvgy3ciqd.onion:38333 -hztyx76iaz4h3emavmzbuizqfg3q37ehfwr2k3afadtcmcepjsxhmeqd.onion:38333 -immdwqfyz2hhcmxmyypstz7syq2cygaklr43mqjmqefnmtcyuspwkbad.onion:38333 -jahtu4veqnvjldtbyxjiibdrltqiiighauai7hmvknwxhptsb4xat4qd.onion:38333 -k4d6h4eyeqjn35b3x46f4s3g3eykn4bms52paxuxenkre6nmhfvy6bqd.onion:38333 -kklfzzodnlinc3toltn7dlft4vzjf2ckmdw2n3dn4lx3pzw5di2womyd.onion:38333 -litqgemqmpesu6gi2ctd4ubrpxdn4mcm2t6p7xhkfxnkk7lzpdx75vyd.onion:38333 -lkgnafoa5nfd34pzyxpz5gnmpwkbdk5a5h6h7hk3rs53soh6nkb3snqd.onion:38333 -lwiqghlmljzlarwn4gwdrvskd3nibtw63o5ok7ugx4nwuvh7b422ifad.onion:38333 -lxied2447sbmnoi64xbrdtcekdfyneoo3xb3m6vscj452orvdi2cjsqd.onion:38333 -n6tf5dfz25i4pprczevdkyo5bkpgfa3xigenn6skpjqqynbxpxzilfid.onion:38333 -o2fumu43ugk6xayo2nvadn7ohqlxharakt4flqh3hjgxdbwzrwignmyd.onion:38333 -oowqbk36g76cs37sk7myfoq62e7ly42etcfugol3p7haw6ewyn5qhiqd.onion:38333 -ouohm2bcplkfvzgg4f5ltvtqt2obzyvaadb3jep7bb4gasdusqkkupad.onion:38333 -oz5puzgtybzjisyw5kimddtmsnc32zwflkj5r43clfddawunk7wtsiad.onion:38333 -pkpiv6cqqba3mb5cpccdvz5v5p3u5acrjv2zj2u4auzznceqculjrkid.onion:38333 -pmjm644pzkp2khwixyis2c7mnfbte33bnmwxdx5lk6t6owvtmapdbhqd.onion:38333 -q3z526imdoo2pdujkfp5vslshni2niewlbxfokejfkddkezxutagezyd.onion:38333 -qpgnrxuwxc6474hvy3j5uk2hbm3ry4ikwrenoit6zjeqqqythsvjdvid.onion:38333 -qzf5vm2exowrli5ksuowrhshtnef43exhtha76qdxz357hdqfq65zhid.onion:38333 -r4y5pqyvdzq3bzg2fqu46ql4a32fadkftwejtxzckeyohd7wvqnnwtqd.onion:38333 -tev7cdwka3av6ektydsjfpofmcam3r6qcw7sxbpkohckjvihtzp7hgyd.onion:38333 -tgqpfwoxjidlwd5rgpj5zfuhctxrevsfueqndih4vx5hgxpmyg34jqyd.onion:38333 -tsq7clffbfe636zfszymheqgy6tyzbsjogad2qet7qeijua5c53ye6ad.onion:38333 -w7d4rwjt5igozi5v7z2m3in2wm3zsf2lhsizqqohkyrokbbie5equoad.onion:38333 -wevmujl2p6mckcwaxnmtusweros7bu3bxf2g3lzutnfdkjl5gwbu36yd.onion:38333 -ww4jycomjwnf7jtrrrngeahokqkcl32iufmjzvvk272svieavabjyiqd.onion:38333 -xbulvl2bb4wvnlafmq3j3fzrjhsmnfz7ubyvl6yy3syeded4tqiubkad.onion:38333 -xm4kxluodmeolmaugmaxnexnefrg3vsxnqo2ezu7rqmdct7i7xevcxad.onion:38333 -y5f4rtma4uneqrkzkoghoiec2sy3mee44xs466hhsi74w5roccqxlzqd.onion:38333 -yjhagyj65xcxu6b5yktu6ntkwsyd5rhjlrsb7sexq5lzchatdqmoqnqd.onion:38333 -ypi6qgnmabcqlmjfkcnqzpjdjihwmebxkd32tjwt6mrhgm2strfml6ad.onion:38333 -yrzulzu5xxcd2vio34ciyj5h7bpnevikslbunm6yb4tjkty62fxl7uid.onion:38333 -zgkvv542e4ewviremw3qp4bi52f2sxt4g4mrjrbwonbnfb5oujd44lid.onion:38333 diff --git a/contrib/seeds/nodes_test.txt b/contrib/seeds/nodes_test.txt deleted file mode 100644 index 2d6a0e1dbc0a..000000000000 --- a/contrib/seeds/nodes_test.txt +++ /dev/null @@ -1,219 +0,0 @@ -[fc10:efa7:ca6:1548:f8c:6bb9:1cc4:63ae]:18333 -[fc1f:22c3:95dc:a3af:4a93:8251:beb9:1858]:18333 -[fc2b:f62e:6a76:cdb5:dceb:2fdd:a0f8:3d88]:18333 -[fc32:2c16:d0d0:f1fb:3b27:c187:8cb5:9201]:18333 -[fccb:248:11a6:1042:bca:1218:f7ce:7d3d]:18333 -66lkz2cfzyrz3tde6gflrty63jqr4knyy6uv4dvldrsecpnfx4dq.b32.i2p:0 -hedmbfis4h4inqrwo2uzmku5xu6xaq74tg7sofnetqikdvndtvja.b32.i2p:0 -i7vrfdmgolc6dqfmsak5fvwgmn46y4ghtan44uhn2aw66cbk5nfa.b32.i2p:0 -nhla3xzibmhvav7meemluh2d2jxdrlwicq636a2sohwqhrfgqi4a.b32.i2p:0 -o6j3b33bv26vthoqzjy3h7a3qsuqbtbe3ulajmjzsl43vaqyieyq.b32.i2p:0 -ocqipbbxx4paopgkkbnj234ie7opzrtca5gtiwr6oda3h32rzgsa.b32.i2p:0 -xgctj4seo3ofstiymoyeuzq74bvddrbr6jtia6erodlf5va3cz5a.b32.i2p:0 -xy6ytjxel5ku4naqumj4f6hn4agrzh3w44gqcs6xkkzwm5s3jdgq.b32.i2p:0 -zklt7hncdrl2hupfwnlbt3qaayhjayjhvwvj2m3fok3z36tlnxhq.b32.i2p:0 -2.59.133.20:18333 # AS58212 -2.86.50.136:18333 # AS6799 -4.246.195.240:18333 # AS8075 -5.39.218.162:18333 # AS57043 -5.255.97.91:18333 # AS60404 -5.255.97.92:18333 # AS60404 -8.217.160.32:18333 # AS45102 -18.168.119.254:18333 # AS8987 -18.209.9.240:18333 # AS8987 -23.227.223.209:18333 # AS44486 -27.148.206.140:18333 # AS133774 -34.65.45.157:18333 # AS396982 -34.69.221.24:18333 # AS396982 -34.254.97.244:18333 # AS16509 -43.133.47.138:18333 # AS132203 -43.247.184.50:18333 # AS23724 -44.208.161.158:18333 # AS14618 -45.77.25.14:18333 # AS20473 -51.79.82.75:18333 # AS16276 -52.193.79.181:18333 # AS16509 -54.236.59.55:18333 # AS14618 -59.186.7.131:18333 # AS3786 -62.210.207.63:18333 # AS12876 -66.94.114.229:18333 # AS40021 -67.4.82.9:18333 # AS209 -69.61.32.242:18333 # AS141518 -69.197.185.106:18333 # AS32097 -70.114.196.140:18333 # AS11427 -72.211.1.222:18333 # AS22773 -73.22.9.231:18333 # AS33491 -74.118.136.46:18333 # AS20326 -85.203.53.149:18333 # AS39351 -85.208.69.12:18333 # AS42275 -85.208.69.13:18333 # AS42275 -89.58.9.219:18333 # AS197540 -89.155.238.72:18333 # AS2860 -90.79.184.226:18333 # AS3215 -91.109.204.214:18333 # AS199669 -91.123.182.164:18333 # AS51648 -92.115.99.159:18333 # AS8926 -122.208.117.197:18333 # AS17506 -124.236.16.91:18333 # AS134760 -129.153.149.46:18333 # AS31898 -129.213.114.91:18333 # AS31898 -129.226.198.211:18333 # AS132203 -134.195.89.130:18333 # AS63473 -135.180.99.74:18333 # AS1299 -137.184.2.124:18333 # AS14061 -141.98.219.199:18333 # AS20326 -147.182.251.92:18333 # AS14061 -148.51.196.40:18333 # AS12025 -148.251.4.19:18333 # AS24940 -149.202.79.199:18333 # AS16276 -161.97.119.128:18333 # AS51167 -162.55.243.11:18333 # AS24940 -169.155.171.252:18333 # AS44486 -176.108.193.97:18333 # AS47914 -185.28.96.16:18333 # AS59845 -185.44.206.111:18333 # AS44051 -185.107.68.135:18333 # AS43350 -185.130.224.146:18333 # AS57043 -185.186.208.124:18333 # AS206428 -185.210.125.33:18333 # AS205671 -186.154.207.228:18333 # AS19429 -188.117.132.82:18333 # AS31242 -188.213.90.149:18333 # AS206238 -193.30.123.70:18333 # AS197540 -194.9.6.11:18333 # AS58212 -194.95.66.129:18333 # AS680 -194.110.169.133:18333 # AS203576 -195.154.241.13:18333 # AS12876 -200.143.224.99:18333 # AS1916 -203.132.94.196:18333 # AS38195 -205.209.120.167:18333 # AS19318 -206.204.104.7:18333 # AS212947 -208.68.4.71:18333 # AS397444 -213.199.42.73:18333 # AS51167 -216.219.91.82:18333 # AS19318 -219.117.221.162:18333 # AS2514 -[2001:41d0:303:146e::]:18333 # AS16276 -[2001:41d0:306:4505::]:18333 # AS16276 -[2001:41d0:306:a3a::]:18333 # AS16276 -[2001:41d0:700:544c::]:18333 # AS16276 -[2001:41d0:800:1d55::]:18333 # AS16276 -[2001:41d0:800:3e7f::]:18333 # AS16276 -[2001:470:1f05:4e5::2020]:18333 # AS6939 -[2001:5a8:4164:7a00::506]:18333 # AS7065 -[2401:c080:1000:4cb2:3eec:efff:feb9:8604]:18333 # AS20473 -[2401:d002:3902:700:8708:37c4:e231:d3d8]:18333 # AS38195 -[2402:1f00:8101:713::]:18333 # AS16276 -[2604:1380:4531:1700::5]:18333 # AS54825 -[2604:a00:50:58:216:3eff:fe2c:8371]:18333 # AS19318 -[2605:3380:422e:1::50]:18333 # AS397444 -[2605:4840:3:2c23::1]:18333 # AS63473 -[2605:a141:2239:7674::1]:18333 # AS51167 -[2607:5300:205:300::1b0]:18333 # AS16276 -[2607:5300:60:85a9::]:18333 # AS16276 -[2607:5300:60:8702::]:18333 # AS16276 -[2620:6e:a000:1:43:43:43:43]:18333 # AS397444 -[2620:6e:a0a0:1::71]:18333 # AS397444 -[2804:431:e038:cd01:aaa1:59ff:fe0d:44b8]:18333 # AS27699 -[2a01:4f8:121:4072::2]:18333 # AS24940 -[2a01:4f8:160:1083::2]:18333 # AS24940 -[2a01:4f8:173:1ed8::2]:18333 # AS24940 -[2a01:4f8:173:230a::2]:18333 # AS24940 -[2a01:4f8:190:4026::2]:18333 # AS24940 -[2a01:4f9:2a:309d::2]:18333 # AS24940 -[2a01:4f9:3070:26e2::2]:18333 # AS24940 -[2a01:4f9:3071:2154::2]:18333 # AS24940 -[2a01:4f9:3071:219d::2]:18333 # AS24940 -[2a01:4f9:6b:2768::2]:18333 # AS24940 -[2a02:c202:2238:2255::1]:18333 # AS51167 -[2a02:c206:2239:7671::1]:18333 # AS51167 -[2a02:c206:2240:1506::1]:18333 # AS51167 -[2a03:4000:2a:514::]:18333 # AS197540 -[2a04:52c0:102:2219::1]:18333 # AS60404 -[2a04:52c0:102:49af::1]:18333 # AS60404 -[2a04:52c0:104:160c::1]:18333 # AS60404 -2lsncqdflwk272dhydrxf7ikfy23ppnmm54dnynyxiym6lqf3wowrmqd.onion:18333 -2mvycpm7ni6ix2pr4lkkfkqlivgo77mt4jx3s3dmhdlg3ogq46s6qbyd.onion:18333 -36fwktckggarkclbpu2pumsdpck46ahe6cwpozd2gm6q7kgdqljclmad.onion:18333 -3dt6kgfrilc3nwliwy5wbmc6oa2b5y3t33nkxlrxrkunr2hoaj56kgyd.onion:18333 -3vnbi5o3hyzk4cm3hhnyo3h7tclr6pybmhmqwkbyclslfhqtg72pq2id.onion:18333 -44sgcv5dvpplt32enlneddyl4gd4z3tbezl2scedwccndyzrrp6lcgyd.onion:18333 -4w3f2mxe4ftodocermsazs3qlpo37igkdgne6ka2p6wnnrgwpzqw65yd.onion:18333 -5axx4qyub7qtgssrvbbqudu6uqjbuknbvbld2wdscv5p6kh2hsfzjxqd.onion:18333 -5qdgulsryjejkjinocpvknazwtnbqtuf4f4pui2at4jpedwwpg427qyd.onion:18333 -67l6l2k7mqbl2btyvo5h5lki3kxcrgbunlk7brcloyaoaftbs5mnsuad.onion:18333 -6bhop3n32rreiynu35epznhc2exxkhuleromdhnida2hgmu2bhczgmqd.onion:18333 -6fdbuqf2kgeweeoeikmwfezauys657lzezzus4nxmekkumouptg5ezad.onion:18333 -6rnqpqqcpllqhjoa4gwrtq5yi6fdch6uqzapdee2gq67gxgsl73v4uqd.onion:18333 -7ph7mrc24te57mvppajfkfj4mk7zuz4teukymt3wgpdpw6vpndeivtyd.onion:18333 -7poqajl6svz4vr3aqi7vdtar2t56crbrtj6yi75ydrt3ighyx7q6qvyd.onion:18333 -7zlqrihb5do5ebbmjwgspxigqfdmkfslkqtg2ngdc6ypsunzb4iootqd.onion:18333 -aesy6tfufadkut6flu2bsqgnw2422ur2ynjalguxlzuzuktg3zehttqd.onion:18333 -axaaplqtf4z22xfj2j2xn6fhtj6ksv74bs7vae6rfw67qofdnqoacbid.onion:18333 -ayx35r2mhwydczzoqu7b6dl3sup4oht74sgnlrjkxybzh2hmfnaix3qd.onion:18333 -bizdwmm7naqq5pehkbfggznqtena5eodz3kprvsbj4nkkax4fvxx53id.onion:18333 -bjqttlyt5kxcn7sitpiavf2cuhdf6rlwigericlh7um7gzkqyyefqnqd.onion:18333 -bkzo7mpxuar7rhsbiwdaxqcymixarcbdmb3sdaqtv6yb2svqttz2s6ad.onion:18333 -bzn63lsmsuvzlg4uqadyylxaggdcrzkb56muw2b43ft5qkynvzfopbyd.onion:18333 -c7zrq2yqt6rtn5dxkczp5bv62k2jncv3mscoo24c24rljbplr2dvhsid.onion:18333 -dskf46hfkefyr6nio5gtqp7em7rh6aqwrugdegfooaoxcux5ym6bkuqd.onion:18333 -euvmh5f637qwqgktjs5zwauvayybfdkiopnflnh5yjt7ouqat3427pqd.onion:18333 -f472j4pynbgltb63mr2lhyvhecfqdjdcfmr2s2id4rreemyn32xtjuid.onion:18333 -fbimesnyhzubbzqc3uaufzkbyfmnkxvypoxaveaub7rzpzh2foxrn2yd.onion:18333 -gggan3nuzxpd655lafnsunqfxgy56bvsxuuzucgmaowyvq3d7a7o7jad.onion:18333 -gsw6sn27quwf6u3swgra6o7lrp5qau6kt3ymuyoxgkth6wntzm2bjwyd.onion:18333 -guudgx24aokistytvm3hj7u5cbvdkr2b643r5t33pa536ekfn2lfykid.onion:18333 -gwtx5qluopwaxjhedlifnr6pptw2eihojzhq3stnv2gfbvqbgqdhi5qd.onion:18333 -gy6nih4pmp5esyvvnhlj6qvk7zkbjuoswkxffyiip3dbkvsfxwz5zcqd.onion:18333 -hj2txlxajdlh7jsfwqxtp3cltlptsr33ctjkbxhbzbyirkmcpfhsnyad.onion:18333 -hjwzovgwou3py6ncemgmzpvcihay5cuzuxvqdn74axndmll25p4mwjqd.onion:18333 -hqkdgpzzsv2qvafhdkdocszquj7o2ittxfmm5fc2arxqw7ikottozoid.onion:18333 -htkiqaqoql7pjstenmw6v4blm6l57d6hl6mewxkmfi3qumozflx3gzyd.onion:18333 -hvbmmzvqrpgps2x5u4ip4ksf3e5m2fneac754gtnhjn2rsevni6cz3ad.onion:18333 -hvtxymvdb55u7lhdw6775akqy46inunl3uup27gnsxm2bqmv55wbacqd.onion:18333 -i5fjp7ggx62zlfkibzn7s6glpjp3h2ypfom3lmqixig7qbdgej35wfyd.onion:18333 -i5gphw2d224tniqkjebxdwz5ygbbo5gcushoyevv7x7o454b6qlrzeid.onion:18333 -iysx2dl4tpojiclh32iyhel6z7h227c7o7buzk5wuqw6qhuytvsu66yd.onion:18333 -j53y5paeb7xcrptntut7epccjglduquldjlzjlho4lj2msabnygrljqd.onion:18333 -jsc4frvvnl2d3bhzyofsc72xpztgm23nl4fnb4dwkzsxr6fhij2q5iyd.onion:18333 -jtvqgaccxbtzshtulk5xlsb4wkoil3psmpn5avqyp2i5vm4hqh5cicyd.onion:18333 -jun6gdmbgasr57bhr4zs3dfhc6pzpaw27nqb4dadbai7yrbq55zskeid.onion:18333 -kamanho5clcpn5l3sc6ih3vb4skmfhgxw3h2mgs7e5idfezu5dw5oxyd.onion:18333 -kwjxlauwjtecjfsiwopbl5pvn5n6z5rz76uk6osmlurd3uyuymcw7aid.onion:18333 -lka74booetkbmat2q64haawcytbwx7mnctvo63ww4jgi4yuqnl6p3kad.onion:18333 -lwfecq35ocqjfbdq4h2qmcwl3cfcyiyycxtvrz36ihdbuczehi3bmrad.onion:18333 -n23anw4zb7f3paroac626oc2sqy3yn5kjfpcqvb3lvdyx7dzzpovd3id.onion:18333 -n4e6fp6xoyo2glsafjwbaq3wirhldpjw4mskn5lzkm4o5lhh5n5k7uqd.onion:18333 -nmazvezejolohnbza4rmqrwvjcprhi7w22fqvlbxp5sw3c25xy3dunqd.onion:18333 -nyrekcbm2ici6wv2umogtmwg7o2ivu4vm7bpcge5fayos5l377zldlqd.onion:18333 -o4zdqfdoe4jfvn35twqtjkzmptmk3bsg45sp46wuxanceg3euqtwdjqd.onion:18333 -ohqcfz5kk6ufouxmhtq7nxyo2lyui4vjlhr2kftvra2ewgzxu3hsrxad.onion:18333 -oobwtn5csi4auevb2ns2b5rrjnxmhlzdmay4zxtzvkj7tayrgwfddiqd.onion:18333 -ppe2pepzphox3swftj5lbyi7ckigspbih5qnyuhrb3r6bn3g7k7bp4qd.onion:18333 -pqkhkpkvqmjcql5jccyxg5nahow6vixnjrvtsc6clnk7dab4weknvpqd.onion:18333 -q5qox756id5nfdu6ht4dghc35jezls4bgjcdnrds3pwndvdx32zmwlad.onion:18333 -qiep4hvuovedbbc36hl7nwslwi6ah6uw4nnseyjdtc73cc5rfdauvnad.onion:18333 -qzx5f2ig2rk2ssrbopz2zlljq5mkeh3izhhx3t3cepse5qnhvpo2tzid.onion:18333 -rfi2hdpjhhknalltbwdvyuhskh5yjs66rqzpy6ley7xtu4kvbeob6fqd.onion:18333 -rw6reu6rdetz6rnpzoyn2hfy7sxpbja4v5ktmaicqqgszi2eata5lhqd.onion:18333 -s3bxrurro4bmvsmntw74qf4vw3xl25xtnvqegayvlwj3b6t7d76kkwid.onion:18333 -slpigm5ep4zan3a65bybne67phjiyesbuk5s3bodefuhnx2cfdtit6qd.onion:18333 -sxm6kwrdp6f2ggaozhrl47xuy3es3sgm3ivppmh4xm3hfmetvwbyrcad.onion:18333 -t6hfkkujktjyzpepmphskoaivflu6fieyuxrshxfzwriwvoa2uccvvqd.onion:18333 -ueyykmnyqk2bnmbgvmqrb4jfbjvpgeew6cuq4gaqe7v2oiyxaubkx4qd.onion:18333 -urhagmjceyqbzhjitpa7j7mygivxw3wlwqzkibw6zezrxeantkikgcyd.onion:18333 -vctlwaqgmu53eutz2hewuakcipfgtyljsd7czut4dd62xr3rp6fqezad.onion:18333 -vi3z4khdvopuiljdjdhpetnxztuzsct2aacuzcm5ba27h4j3cfwsvjad.onion:18333 -vqnkdmpmecc5kondj32jwbemmruhmd5gkmfngkscetibzozryp4elkad.onion:18333 -wgc4wp25gtnb54vd7x5h2xtetzrdoiizeyyh6fv3vxzp3bbalejbd3ad.onion:18333 -wpsahjbejxehpz772kzxonj777pejol2akcicduqov2r7ktm2b6l5pid.onion:18333 -wui5m2y5b7cms36ai6shzyqsg6qteejwmxsf26nyms6vcykxbvmh4uad.onion:18333 -xafcyh6mxwebvcsgw4wcbuw7n4v7vbqhcznhwqcpqcu6dww2mjuw4nad.onion:18333 -y5h652jz6sgmb4bkcfnfxnj24gnczqf7lhd5lqbvdhf5mpll4gye5kid.onion:18333 -ya6s7ov7myixz3ql23u45hty7moxo3r4d26qainw55z656vtau676xid.onion:18333 -yda7kwpii33j2qpq32ftf6lp22znknswipjwaccvsqj7l337jvfesnid.onion:18333 -zcsn3j6aswnrf56xj2n5jn4tlwmyoq4benjn5ujcgz46co2y5tm642id.onion:18333 -zefnna2a3ga4ez2nutvypma7my35prw3ycinbqwva7v4pf3aurqhjcyd.onion:18333 -zhiju2obxifqpjbcm6xtlgjdbof7jhoctvw3x57vhiftstb5hi3gmsqd.onion:18333 -zkqddzui5pkrqvjj2zwsf5kln7stlbmw5pmn6ut46fobvzyv2sn2ryid.onion:18333 -zmvizz7fd5hdue6wt3lwqumd6qwt4ijymmmotfzh75curq3mzjm53hyd.onion:18333 -zmxlrzoxg4fmso6l2xuq5tdxmlyakdqellzujh3a23iuzg4zlatnogqd.onion:18333 -zsmxmusdzrcqusk5h6syfq6a3ph6lwx3wpiltun4dmkrt3pa2fp7qaid.onion:18333 diff --git a/contrib/seeds/nodes_testnet4.txt b/contrib/seeds/nodes_testnet4.txt deleted file mode 100644 index 98608b29d530..000000000000 --- a/contrib/seeds/nodes_testnet4.txt +++ /dev/null @@ -1,151 +0,0 @@ -[fc10:efa7:ca6:1548:f8c:6bb9:1cc4:63ae]:48333 -[fc1f:22c3:95dc:a3af:4a93:8251:beb9:1858]:48333 -[fc32:2c16:d0d0:f1fb:3b27:c187:8cb5:9201]:48333 -[fccb:248:11a6:1042:bca:1218:f7ce:7d3d]:48333 -7rn2pojst5aurdaes2qcwiigis55ewzjjhxfbxnua5calwuigxdq.b32.i2p:0 -a7jpzmbtvn5qgvnxez2zc4nvabso4xmllbrqmuoavxz537ttbdtq.b32.i2p:0 -augssnqnvo2w66vbrfzctc5rnhaxe3io7wnkvr5xp6wwkxmrggra.b32.i2p:0 -axxwcwzqlw42hjbpzupvffvdsjvniyt5apyt53sdxijqy6y6pdha.b32.i2p:0 -nl2qej33ywfqllz3exxce5jxmz35cnovhh6qobwvfc7igm2vdz2q.b32.i2p:0 -q376dmbdqpt4qgwf6za2ai7c4fs3va5tdmtb3ag6awk6wnv4mqcq.b32.i2p:0 -rdpe5wgl565yvgeialkhlf53akawdm7npy6bl7asl2ncntoyn7la.b32.i2p:0 -2.59.134.244:48333 # AS58212 -3.235.188.91:48333 # AS14618 -3.250.145.197:48333 # AS16509 -5.182.4.106:48333 # AS49505 -18.175.220.215:48333 # AS8987 -18.189.156.102:48333 # AS8987 -34.232.31.111:48333 # AS14618 -38.242.219.220:48333 # AS51167 -45.94.168.5:48333 # AS400810 -45.142.17.140:48333 # AS206238 -50.126.96.22:48333 # AS27017 -51.79.29.216:48333 # AS16276 -51.81.245.218:48333 # AS16276 -54.78.90.72:48333 # AS16509 -65.108.39.171:48333 # AS24940 -66.94.123.141:48333 # AS40021 -77.247.127.71:48333 # AS62240 -78.24.181.215:48333 # AS49505 -82.67.102.15:48333 # AS12322 -89.117.152.94:48333 # AS46475 -103.99.168.207:48333 # AS54415 -103.99.168.211:48333 # AS54415 -103.165.192.203:48333 # AS142052 -103.165.192.206:48333 # AS142052 -134.195.88.56:48333 # AS63473 -135.180.99.74:48333 # AS1299 -138.197.188.212:48333 # AS14061 -148.51.196.40:48333 # AS12025 -158.220.90.103:48333 # AS51167 -168.119.150.247:48333 # AS24940 -172.234.197.251:48333 # AS63949 -175.45.182.145:48333 # AS133159 -185.232.70.226:48333 # AS197540 -185.254.97.76:48333 # AS58212 -192.145.44.30:48333 # AS197540 -192.241.131.95:48333 # AS14061 -193.107.109.220:48333 # AS214379 -199.119.138.36:48333 # AS216382 -199.195.248.11:48333 # AS53667 -203.132.94.196:48333 # AS38195 -208.68.4.71:48333 # AS397444 -209.146.51.202:48333 # AS174 -209.146.51.203:48333 # AS174 -[2001:41d0:a:555c::1]:48333 # AS16276 -[2001:5a8:4164:7a00::506]:48333 # AS7065 -[2001:df6:7280::92:202]:48333 # AS142052 -[2001:df6:7280::92:203]:48333 # AS142052 -[2001:df6:7280::92:204]:48333 # AS142052 -[2001:df6:7280::92:205]:48333 # AS142052 -[2001:df6:7280::92:207]:48333 # AS142052 -[2001:df6:7280::92:208]:48333 # AS142052 -[2001:df6:7280::92:209]:48333 # AS142052 -[2001:df6:7280::92:210]:48333 # AS142052 -[2001:df6:7280::92:211]:48333 # AS142052 -[2001:df6:7280::92:212]:48333 # AS142052 -[2401:b140:4::92:202]:48333 # AS54415 -[2401:b140:4::92:204]:48333 # AS54415 -[2401:b140:4::92:205]:48333 # AS54415 -[2401:b140:4::92:206]:48333 # AS54415 -[2401:b140:4::92:207]:48333 # AS54415 -[2401:b140:4::92:208]:48333 # AS54415 -[2401:b140:4::92:209]:48333 # AS54415 -[2401:b140:4::92:210]:48333 # AS54415 -[2401:b140:4::92:211]:48333 # AS54415 -[2401:b140::92:204]:48333 # AS54415 -[2405:1204:c235:9700:605f:5035:d51b:b05b]:48333 # AS9824 -[2405:1204:c235:9700:9141:402c:de91:81c0]:48333 # AS9824 -[2405:1204:c235:9700::6c]:48333 # AS9824 -[2600:3c00::f03c:91ff:fe5b:4cf3]:48333 # AS63949 -[2602:ffb6:4:8185:f816:3eff:fe4a:acbf]:48333 # AS174 -[2602:ffb6:4:8185:f816:3eff:fe4d:6dae]:48333 # AS174 -[2602:ffb6:4:8185:f816:3eff:fe50:b078]:48333 # AS174 -[2602:ffb6:4:8185:f816:3eff:fe8a:3155]:48333 # AS174 -[2604:2dc0:200:13da::]:48333 # AS16276 -[2605:3380:422e:1::50]:48333 # AS397444 -[2605:a141:2240:4224::1]:48333 # AS51167 -[2607:5300:205:300::1b0]:48333 # AS16276 -[2607:5300:60:7f72::1]:48333 # AS16276 -[2620:6e:a0a0:1::71]:48333 # AS397444 -[2a01:4f8:172:33c1::2]:48333 # AS24940 -[2a01:4f8:2190:1692::2]:48333 # AS24940 -[2a01:4f8:262:139f::2]:48333 # AS24940 -[2a01:4f9:3080:3496::2]:48333 # AS24940 -[2a01:e0a:e6e:6bb0:2e0:4cff:fe68:232]:48333 # AS12322 -[2a02:c202:2234:7688::1]:48333 # AS51167 -[2a03:4000:42:22f:816:bbff:fe4c:d4a1]:48333 # AS197540 -[2a0a:8dc0:a000:40::2]:48333 # AS62240 -[2a0a:8dc0:a041::a]:48333 # AS62240 -[2a0c:b641:6f1:8c::2]:48333 # AS214379 -2sltzrq7ts5t4il5nimp75og2jksbwdjmgbdykz5ljeoqrxemzlakeyd.onion:48333 -4uzerod2wrqtjuaea6vr43uddq2sg3cgfuk4khqotqsqdsxpwdmcphqd.onion:48333 -57k43lgf2ciorl7gfz6qu3yo27zdkojd7lbzrwzcbksq3uujts5h6uid.onion:48333 -5fkz5ijh76cgfwvxz4pyl4br4hekqflijz7d467ldey3xme2trqrgjad.onion:48333 -5p6eqvrins6vj7q3tpdljhtomu6nqameilbuz5sjnu2i333ve2zpnhqd.onion:48333 -5sdzs2qu3ygb44jwo45y2kmbnqc6ijzpndaqn43zgngsiwq7mx6b7yyd.onion:48333 -6g6dwtby74ic2ggnzkbfqy7saslopho7or6z4uad737c2tq24fj3ltyd.onion:48333 -6po3e27t4nxgls3mwnostpy47crhtc3ae6fcsn4yyfh5dfcaq3q3q3yd.onion:48333 -7gcsfynynr26cya4uf2u74bx47jmzaidikh6lqo7nu5uwy7bra3roqyd.onion:48333 -7jd422hqevrz334ax3fh77wzww7clnr4kpyos25oe64nifg623bjqfqd.onion:48333 -7kwh7rg3a4e5lgjvybesixzhwzxvf6dqo3gc4h7k5vilwmdjvtzidtid.onion:48333 -7slxjz7hmpu6rpybl62egedth5c4zo6mwzm4sdbvqtwc5zikvx4e53id.onion:48333 -7xr2k6gg47calskl3emvqav42jf6l4dtgiwevy2vx7gej6d2osh4oiyd.onion:48333 -a6yijgwn4vtmmhl7uybtbuyvtl7mtj7arld5f4csqsx4syeii4gt3vqd.onion:48333 -aqabn424rm7qq5faw2ecckkzxfdw57oncivjrurrrn5wgjdqjqxvxjad.onion:48333 -c2u7kz2pv7vyufovwndoureyqijbd7kwpy7anulf4fxt3d3buf2yk2yd.onion:48333 -clqr2to2r6fn4jo6f7xy3dppxgn4ewvnmwbxsdrrhnesyacmw5noaeqd.onion:48333 -dnshzxr6osjf2l5gjsbattjtoefgkzmd3p3fdyatr5ltz243zspsilyd.onion:48333 -ebhtfcmjhilcqtuls437pxu65dznqkpt5qv3yeq6zipnqd7ichz5htyd.onion:48333 -ej4ozb3o5pzvvtvgaars5obzwvhrfs3chkmvb5pxmedykd4bgh6cpgyd.onion:48333 -ezbq3ydfxmgvgbbn7mrx5jzyig6tz2zjkaqdtkx7avnijrt5riv4j5yd.onion:48333 -fsijrllgzgeg4pa5ebq4qy3swmplxkzvuvji5swt36quy42dznq3t3ad.onion:48333 -fvbppnodd4dlxulzlvhikg2ijtnxemcjjpfhcg2rropun45aqhp5noid.onion:48333 -fwsrcrhnggi3qy5rsfiad3cwep3bf7uovcupgockbntjcfvoqxzr75id.onion:48333 -gc66muikqqzxwj2tdvvap6gpcbitthjvscawgkclim4vgmajrccjtmqd.onion:48333 -gujxforhwszry5falvnarfcyajjxxsuvqevx6gk6meou5ordrxw3mdad.onion:48333 -havkohvjhg5tglbdecf4ufhz5es3f33ctj3b6loebj4pi6qrtjemfbyd.onion:48333 -hb44egze5hjbi3n2rc6w4pwahr6zltc4ilfzin3kkdi2rmozvxlo65qd.onion:48333 -i22efh4itlcfthvaavcz2rvigu4x6jqvlwuksz44bukslhg76bsgrxqd.onion:48333 -i63l2yfy5e4kvm5c6la67qxpq6zn4xbdx6cdm474milv4dameu3z35qd.onion:48333 -irwyrdkcrcdgwtsltcrqexqylwc3ezjhhra7u4i3gkwktezcut36buqd.onion:48333 -jfyjcgithmk6fmndgg5kljttu5ctlokcvqjvsrxrxvnevhwx57xhpsqd.onion:48333 -kf6q2wza2ebo7cxln5ejcjjwvrew4vb2hf4vd5wo4nyzbnjv3yccduqd.onion:48333 -ko55e2ityiaqeckthmnnbcv6bbwll7rtdiv527muoqdpg4hye2it2pyd.onion:48333 -mavvwxts5f3axuz4cyjqpz75veijkdkdueavekb5hia67zk257eg7tqd.onion:48333 -mdiwdijucocysdvx5dk2iyo5wsav3ehyiggegzfk3ezfcce6nstp4nid.onion:48333 -nbq63hx63psrcqv26uadmcxkeap76un2xaombe4ivojkt3ysbgountid.onion:48333 -ns56enpcbigc2dovrj3agdbgudebmwtg43d27wtpvm5nwomectn2kmad.onion:48333 -ol5rcztxxugtup5mswhkt6hdf4pvcidimy3du6owufnja5lr3czk2zyd.onion:48333 -prilx36yi6wiz4ll77tapskzwzh5onphrnn6w5d56zrzdat4kjo3q3yd.onion:48333 -qmd5qvyhnanqj6wyf4klrvfqoypuz6xjajhx2n272vr5il7nlwyoosqd.onion:48333 -qmw73e4zh2i6pvmlgx5642vwtynibghgvjdoox574hjxxv7fvd2oxyid.onion:48333 -rah46hr3opyfbikrkub6g23idrml2ugmealjt4bcxlj6nonoxdqp4jqd.onion:48333 -riyvgzynuzj2vx2az6a7kvca5bythmj6rgb4asrecdw6vfmvt33uxqid.onion:48333 -rv7l5gtjqr5n5nlersakfuzwhfflyfizv5cmtiizlsn544qumvuekwqd.onion:48333 -vfqxysj7olxstghkohezoembjnsyvpp2ph7kc4jaatvszyx2ajz627ad.onion:48333 -we5rsalvz6fhp3345jydracg6wytxw5smsxzgusljvgcojadyfv2bzyd.onion:48333 -wkvaxtftpwmmvrptqavx6mwhrcwiecbodtshuenvot3cjgxsycuurcid.onion:48333 -x66at4pel4ody42wujl4upr2tbulbpn54nzvrk7gomzv4dwkhazfjdqd.onion:48333 -zjttaesjhj7ail437ag4emdufr775h5rtgoohlbca5rwc4re6dr5k7ad.onion:48333 -zmd4eq6svwn3qgm56dyodktagzi3xo4smxebgjdk2jbjkbmvn7gjm5qd.onion:48333 diff --git a/contrib/signet/README.md b/contrib/signet/README.md deleted file mode 100644 index 499479857197..000000000000 --- a/contrib/signet/README.md +++ /dev/null @@ -1,83 +0,0 @@ -Contents -======== -This directory contains tools related to Signet, both for running a Signet yourself and for using one. - -getcoins.py -=========== - -A script to call a faucet to get Signet coins. - -Syntax: `getcoins.py [-h|--help] [-c|--cmd=] [-f|--faucet=] [-a|--addr=] [-p|--password=] [--] []` - -* `--cmd` lets you customize the bitcoin-cli path. By default it will look for it in the PATH -* `--faucet` lets you specify which faucet to use; the faucet is assumed to be compatible with https://github.com/kallewoof/bitcoin-faucet -* `--addr` lets you specify a Signet address; by default, the address must be a bech32 address. This and `--cmd` above complement each other (i.e. you do not need `bitcoin-cli` if you use `--addr`) -* `--password` lets you specify a faucet password; this is handy if you are in a classroom and set up your own faucet for your students; (above faucet does not limit by IP when password is enabled) - -If using the default network, invoking the script with no arguments should be sufficient under normal -circumstances, but if multiple people are behind the same IP address, the faucet will by default only -accept one claim per day. See `--password` above. - -miner -===== - -You will first need to pick a difficulty target. Since signet chains are primarily protected by a signature rather than proof of work, there is no need to spend as much energy as possible mining, however you may wish to choose to spend more time than the absolute minimum. The calibrate subcommand can be used to pick a target appropriate for your hardware, eg: - - MINER="./contrib/signet/miner" - GRIND="./build/bin/bitcoin-util grind" - $MINER calibrate --grind-cmd="$GRIND" - nbits=1e00f403 for 25s average mining time - -It defaults to estimating an nbits value resulting in 25s average time to find a block, but the --seconds parameter can be used to pick a different target, or the --nbits parameter can be used to estimate how long it will take for a given difficulty. - -To mine the first block in your custom chain, you can run: - - CLI="./build/bin/bitcoin-cli -conf=mysignet.conf" - ADDR=$($CLI -signet getnewaddress) - NBITS=1e00f403 - $MINER --cli="$CLI" generate --grind-cmd="$GRIND" --address="$ADDR" --nbits=$NBITS - -This will mine a single block with a backdated timestamp designed to allow 100 blocks to be mined as quickly as possible, so that it is possible to do transactions. - -Adding the --ongoing parameter will then cause the signet miner to create blocks indefinitely. It will pick the time between blocks so that difficulty is adjusted to match the provided --nbits value. - - $MINER --cli="$CLI" generate --grind-cmd="$GRIND" --address="$ADDR" --nbits=$NBITS --ongoing - -Other options -------------- - -The --debug and --quiet options are available to control how noisy the signet miner's output is. Note that the --debug, --quiet and --cli parameters must all appear before the subcommand (generate, calibrate, etc) if used. - -Instead of specifying --ongoing, you can specify --max-blocks=N to mine N blocks and stop. - -The --set-block-time option is available to manually move timestamps forward or backward (subject to the rules that blocktime must be greater than mediantime, and dates can't be more than two hours in the future). It can only be used when mining a single block (ie, not when using --ongoing or --max-blocks greater than 1). - -Instead of using a single address, a ranged descriptor may be provided via the --descriptor parameter, with the reward for the block at height H being sent to the H'th address generated from the descriptor. - -Instead of calculating a specific nbits value, --min-nbits can be specified instead, in which case the minimum signet difficulty will be targeted. Signet's minimum difficulty corresponds to --nbits=1e0377ae. - -By default, the signet miner mines blocks at fixed intervals with minimal variation. If you want blocks to appear more randomly, as they do in mainnet, specify the --poisson option. - -Using the --multiminer parameter allows mining to be distributed amongst multiple miners. For example, if you have 3 miners and want to share blocks between them, specify --multiminer=1/3 on one, --multiminer=2/3 on another, and --multiminer=3/3 on the last one. If you want one to do 10% of blocks and two others to do 45% each, --multiminer=1-10/100 on the first, and --multiminer=11-55 and --multiminer=56-100 on the others. Note that which miner mines which block is determined by the previous block hash, so occasional runs of one miner doing many blocks in a row is to be expected. - -When --multiminer is used, if a miner is down and does not mine a block within five minutes of when it is due, the other miners will automatically act as redundant backups ensuring the chain does not halt. The --backup-delay parameter can be used to change how long a given miner waits, allowing one to be the primary backup (after five minutes) and another to be the secondary backup (after six minutes, eg). - -The --standby-delay parameter can be used to make a backup miner that only mines if a block doesn't arrive on time. This can be combined with --multiminer if desired. Setting --standby-delay also prevents the first block from being mined immediately. - -Advanced usage --------------- - -The process generate follows internally is to get a block template, convert that into a PSBT, sign the PSBT, move the signature from the signed PSBT into the block template's coinbase, grind proof of work for the block, and then submit the block to the network. - -These steps can instead be done explicitly: - - $CLI -signet getblocktemplate '{"rules": ["signet","segwit"]}' | - $MINER --cli="$CLI" genpsbt --address="$ADDR" | - $CLI -signet -stdin walletprocesspsbt | - jq -r .psbt | - $MINER --cli="$CLI" solvepsbt --grind-cmd="$GRIND" | - $CLI -signet -stdin submitblock - -This is intended to allow you to replace part of the pipeline for further experimentation (eg, to sign the block with a hardware wallet). - -For custom signets with a trivial challenge such as `OP_TRUE` and `OP_2` the walletprocesspsbt step can be skipped. diff --git a/contrib/signet/getcoins.py b/contrib/signet/getcoins.py deleted file mode 100755 index 75430e5b1aa3..000000000000 --- a/contrib/signet/getcoins.py +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2020-2022 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -import argparse -import io -import requests -import subprocess -import sys -import xml.etree.ElementTree - -DEFAULT_GLOBAL_FAUCET = 'https://signetfaucet.com/claim' -DEFAULT_GLOBAL_CAPTCHA = 'https://signetfaucet.com/captcha' -GLOBAL_FIRST_BLOCK_HASH = '00000086d6b2636cb2a392d45edc4ec544a10024d30141c9adf4bfd9de533b53' - -# braille unicode block -BASE = 0x2800 -BIT_PER_PIXEL = [ - [0x01, 0x08], - [0x02, 0x10], - [0x04, 0x20], - [0x40, 0x80], -] -BW = 2 -BH = 4 - -# imagemagick or compatible fork (used for converting SVG) -CONVERT = 'convert' - -class PPMImage: - ''' - Load a PPM image (Pillow-ish API). - ''' - def __init__(self, f): - if f.readline() != b'P6\n': - raise ValueError('Invalid ppm format: header') - line = f.readline() - (width, height) = (int(x) for x in line.rstrip().split(b' ')) - if f.readline() != b'255\n': - raise ValueError('Invalid ppm format: color depth') - data = f.read(width * height * 3) - stride = width * 3 - self.size = (width, height) - self._grid = [[tuple(data[stride * y + 3 * x:stride * y + 3 * (x + 1)]) for x in range(width)] for y in range(height)] - - def getpixel(self, pos): - return self._grid[pos[1]][pos[0]] - -def print_image(img, threshold=128): - '''Print black-and-white image to terminal in braille unicode characters.''' - x_blocks = (img.size[0] + BW - 1) // BW - y_blocks = (img.size[1] + BH - 1) // BH - - for yb in range(y_blocks): - line = [] - for xb in range(x_blocks): - ch = BASE - for y in range(BH): - for x in range(BW): - try: - val = img.getpixel((xb * BW + x, yb * BH + y)) - except IndexError: - pass - else: - if val[0] < threshold: - ch |= BIT_PER_PIXEL[y][x] - line.append(chr(ch)) - print(''.join(line)) - -parser = argparse.ArgumentParser(description='Script to get coins from a faucet.', epilog='You may need to start with double-dash (--) when providing bitcoin-cli arguments.') -parser.add_argument('-c', '--cmd', dest='cmd', default='bitcoin-cli', help='bitcoin-cli command to use') -parser.add_argument('-f', '--faucet', dest='faucet', default=DEFAULT_GLOBAL_FAUCET, help='URL of the faucet') -parser.add_argument('-g', '--captcha', dest='captcha', default=DEFAULT_GLOBAL_CAPTCHA, help='URL of the faucet captcha, or empty if no captcha is needed') -parser.add_argument('-a', '--addr', dest='addr', default='', help='Bitcoin address to which the faucet should send') -parser.add_argument('-p', '--password', dest='password', default='', help='Faucet password, if any') -parser.add_argument('-n', '--amount', dest='amount', default='0.001', help='Amount to request (0.001-0.1, default is 0.001)') -parser.add_argument('-i', '--imagemagick', dest='imagemagick', default=CONVERT, help='Path to imagemagick convert utility') -parser.add_argument('bitcoin_cli_args', nargs='*', help='Arguments to pass on to bitcoin-cli (default: -signet)') - -args = parser.parse_args() - -if args.bitcoin_cli_args == []: - args.bitcoin_cli_args = ['-signet'] - - -def bitcoin_cli(rpc_command_and_params): - argv = [args.cmd] + args.bitcoin_cli_args + rpc_command_and_params - try: - return subprocess.check_output(argv).strip().decode() - except FileNotFoundError: - raise SystemExit(f"The binary {args.cmd} could not be found") - except subprocess.CalledProcessError: - cmdline = ' '.join(argv) - raise SystemExit(f"-----\nError while calling {cmdline} (see output above).") - - -if args.faucet.lower() == DEFAULT_GLOBAL_FAUCET: - # Get the hash of the block at height 1 of the currently active signet chain - curr_signet_hash = bitcoin_cli(['getblockhash', '1']) - if curr_signet_hash != GLOBAL_FIRST_BLOCK_HASH: - raise SystemExit('The global faucet cannot be used with a custom Signet network. Please use the global signet or setup your custom faucet to use this functionality.\n') -else: - # For custom faucets, don't request captcha by default. - if args.captcha == DEFAULT_GLOBAL_CAPTCHA: - args.captcha = '' - -if args.addr == '': - # get address for receiving coins - args.addr = bitcoin_cli(['getnewaddress', 'faucet', 'bech32']) - -data = {'address': args.addr, 'password': args.password, 'amount': args.amount} - -# Store cookies -# for debugging: print(session.cookies.get_dict()) -session = requests.Session() - -if args.captcha != '': # Retrieve a captcha - try: - res = session.get(args.captcha) - res.raise_for_status() - except requests.exceptions.RequestException as e: - raise SystemExit(f"Unexpected error when contacting faucet: {e}") - - # Size limitation - svg = xml.etree.ElementTree.fromstring(res.content) - if svg.attrib.get('width') != '150' or svg.attrib.get('height') != '50': - raise SystemExit("Captcha size doesn't match expected dimensions 150x50") - - # Convert SVG image to PPM, and load it - try: - rv = subprocess.run([args.imagemagick, 'svg:-', '-depth', '8', 'ppm:-'], input=res.content, check=True, capture_output=True) - except FileNotFoundError: - raise SystemExit(f"The binary {args.imagemagick} could not be found. Please make sure ImageMagick (or a compatible fork) is installed and that the correct path is specified.") - - img = PPMImage(io.BytesIO(rv.stdout)) - - # Terminal interaction - print_image(img) - print(f"Captcha from URL {args.captcha}") - data['captcha'] = input('Enter captcha: ') - -try: - res = session.post(args.faucet, data=data) -except Exception: - raise SystemExit(f"Unexpected error when contacting faucet: {sys.exc_info()[0]}") - -# Display the output as per the returned status code -if res: - # When the return code is in between 200 and 400 i.e. successful - print(res.text) -elif res.status_code == 404: - print('The specified faucet URL does not exist. Please check for any server issues/typo.') -elif res.status_code == 429: - print('The script does not allow for repeated transactions as the global faucet is rate-limited to 1 request/IP/day. You can access the faucet website to get more coins manually') -else: - print(f'Returned Error Code {res.status_code}\n{res.text}\n') - print('Please check the provided arguments for their validity and/or any possible typo.') diff --git a/contrib/signet/miner b/contrib/signet/miner deleted file mode 100755 index 8c7edc56a32f..000000000000 --- a/contrib/signet/miner +++ /dev/null @@ -1,604 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2020 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -import argparse -import json -import logging -import math -import os -import re -import shlex -import sys -import time -import subprocess - -PATH_BASE_CONTRIB_SIGNET = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) -PATH_BASE_TEST_FUNCTIONAL = os.path.abspath(os.path.join(PATH_BASE_CONTRIB_SIGNET, "..", "..", "test", "functional")) -sys.path.insert(0, PATH_BASE_TEST_FUNCTIONAL) - -from test_framework.blocktools import get_witness_script, script_BIP34_coinbase_height, SIGNET_HEADER # noqa: E402 -from test_framework.messages import CBlock, CBlockHeader, COutPoint, CTransaction, CTxIn, CTxInWitness, CTxOut, from_binary, from_hex, ser_string, ser_uint256, tx_from_hex, MAX_SEQUENCE_NONFINAL # noqa: E402 -from test_framework.psbt import PSBT, PSBTMap, PSBT_GLOBAL_UNSIGNED_TX, PSBT_IN_FINAL_SCRIPTSIG, PSBT_IN_FINAL_SCRIPTWITNESS, PSBT_IN_NON_WITNESS_UTXO, PSBT_IN_SIGHASH_TYPE # noqa: E402 -from test_framework.script import CScript, CScriptOp # noqa: E402 - -logging.basicConfig( - format='%(asctime)s %(levelname)s %(message)s', - level=logging.INFO, - datefmt='%Y-%m-%d %H:%M:%S') - -PSBT_SIGNET_BLOCK = b"\xfc\x06signetb" # proprietary PSBT global field holding the block being signed -RE_MULTIMINER = re.compile(r"^(\d+)(-(\d+))?/(\d+)$") - -def signet_txs(block, challenge): - # assumes signet solution has not been added yet so does not need - # to be removed - - txs = block.vtx[:] - txs[0] = CTransaction(txs[0]) - txs[0].vout[-1].scriptPubKey += CScriptOp.encode_op_pushdata(SIGNET_HEADER) - hashes = [] - for tx in txs: - hashes.append(ser_uint256(tx.txid_int)) - mroot = block.get_merkle_root(hashes) - - sd = b"" - sd += block.nVersion.to_bytes(4, "little", signed=True) - sd += ser_uint256(block.hashPrevBlock) - sd += ser_uint256(mroot) - sd += block.nTime.to_bytes(4, "little") - - to_spend = CTransaction() - to_spend.version = 0 - to_spend.nLockTime = 0 - to_spend.vin = [CTxIn(COutPoint(0, 0xFFFFFFFF), b"\x00" + CScriptOp.encode_op_pushdata(sd), 0)] - to_spend.vout = [CTxOut(0, challenge)] - - spend = CTransaction() - spend.version = 0 - spend.nLockTime = 0 - spend.vin = [CTxIn(COutPoint(to_spend.txid_int, 0), b"", 0)] - spend.vout = [CTxOut(0, b"\x6a")] - - return spend, to_spend - -def decode_challenge_psbt(b64psbt): - psbt = PSBT.from_base64(b64psbt) - - assert len(psbt.tx.vin) == 1 - assert len(psbt.tx.vout) == 1 - assert PSBT_SIGNET_BLOCK in psbt.g.map - return psbt - -def get_block_from_psbt(psbt): - return from_binary(CBlock, psbt.g.map[PSBT_SIGNET_BLOCK]) - -def get_solution_from_psbt(psbt, emptyok=False): - scriptSig = psbt.i[0].map.get(PSBT_IN_FINAL_SCRIPTSIG, b"") - scriptWitness = psbt.i[0].map.get(PSBT_IN_FINAL_SCRIPTWITNESS, b"\x00") - if emptyok and len(scriptSig) == 0 and scriptWitness == b"\x00": - return None - return ser_string(scriptSig) + scriptWitness - -def finish_block(block, signet_solution, grind_cmd): - if signet_solution is None: - pass # Don't need to add a signet commitment if there's no signet signature needed - else: - block.vtx[0].vout[-1].scriptPubKey += CScriptOp.encode_op_pushdata(SIGNET_HEADER + signet_solution) - block.hashMerkleRoot = block.calc_merkle_root() - if grind_cmd is None: - block.solve() - else: - headhex = CBlockHeader.serialize(block).hex() - cmd = shlex.split(grind_cmd) + [headhex] - newheadhex = subprocess.run(cmd, stdout=subprocess.PIPE, input=b"", check=True).stdout.strip() - newhead = from_hex(CBlockHeader(), newheadhex.decode('utf8')) - block.nNonce = newhead.nNonce - return block - -def new_block(tmpl, reward_spk, *, blocktime=None, poolid=None): - scriptSig = script_BIP34_coinbase_height(tmpl["height"]) - if poolid is not None: - scriptSig = CScript(b"" + scriptSig + CScriptOp.encode_op_pushdata(poolid)) - - cbtx = CTransaction() - cbtx.nLockTime = tmpl["height"] - 1 - cbtx.vin = [CTxIn(COutPoint(0, 0xffffffff), scriptSig, MAX_SEQUENCE_NONFINAL)] - cbtx.vout = [CTxOut(tmpl["coinbasevalue"], reward_spk)] - cbtx.vin[0].nSequence = 2**32-2 - - block = CBlock() - block.nVersion = tmpl["version"] - block.hashPrevBlock = int(tmpl["previousblockhash"], 16) - block.nTime = tmpl["curtime"] if blocktime is None else blocktime - if block.nTime < tmpl["mintime"]: - block.nTime = tmpl["mintime"] - block.nBits = int(tmpl["bits"], 16) - block.nNonce = 0 - block.vtx = [cbtx] + [tx_from_hex(t["data"]) for t in tmpl["transactions"]] - - witnonce = 0 - witroot = block.calc_witness_merkle_root() - cbwit = CTxInWitness() - cbwit.scriptWitness.stack = [ser_uint256(witnonce)] - block.vtx[0].wit.vtxinwit = [cbwit] - block.vtx[0].vout.append(CTxOut(0, bytes(get_witness_script(witroot, witnonce)))) - - block.hashMerkleRoot = block.calc_merkle_root() - - return block - -def generate_psbt(block, signet_spk): - signet_spk_bin = bytes.fromhex(signet_spk) - signme, spendme = signet_txs(block, signet_spk_bin) - psbt = PSBT() - psbt.g = PSBTMap( {PSBT_GLOBAL_UNSIGNED_TX: signme.serialize(), - PSBT_SIGNET_BLOCK: block.serialize() - } ) - psbt.i = [ PSBTMap( {PSBT_IN_NON_WITNESS_UTXO: spendme.serialize(), - PSBT_IN_SIGHASH_TYPE: bytes([1,0,0,0])}) - ] - psbt.o = [ PSBTMap() ] - return psbt.to_base64() - -def get_poolid(args): - if args.poolid is not None: - return args.poolid.encode('utf8') - elif args.poolnum is not None: - return b"/signet:%d/" % (args.poolnum) - else: - return None - -def get_reward_addr_spk(args, height): - assert args.address is not None or args.descriptor is not None - - if hasattr(args, "reward_spk"): - return args.address, args.reward_spk - - if args.address is not None: - reward_addr = args.address - elif '*' not in args.descriptor: - reward_addr = args.address = json.loads(args.bcli("deriveaddresses", args.descriptor))[0] - else: - remove = [k for k in args.derived_addresses.keys() if k+20 <= height] - for k in remove: - del args.derived_addresses[k] - if height not in args.derived_addresses: - addrs = json.loads(args.bcli("deriveaddresses", args.descriptor, "[%d,%d]" % (height, height+20))) - for k, a in enumerate(addrs): - args.derived_addresses[height+k] = a - reward_addr = args.derived_addresses[height] - - reward_spk = bytes.fromhex(json.loads(args.bcli("getaddressinfo", reward_addr))["scriptPubKey"]) - if args.address is not None: - # will always be the same, so cache - args.reward_spk = reward_spk - - return reward_addr, reward_spk - -def do_genpsbt(args): - poolid = get_poolid(args) - tmpl = json.load(sys.stdin) - signet_spk = tmpl["signet_challenge"] - _, reward_spk = get_reward_addr_spk(args, tmpl["height"]) - block = new_block(tmpl, reward_spk, poolid=poolid) - psbt = generate_psbt(block, signet_spk) - print(psbt) - -def do_solvepsbt(args): - psbt = decode_challenge_psbt(sys.stdin.read()) - block = get_block_from_psbt(psbt) - signet_solution = get_solution_from_psbt(psbt, emptyok=True) - block = finish_block(block, signet_solution, args.grind_cmd) - print(block.serialize().hex()) - -def nbits_to_target(nbits): - shift = (nbits >> 24) & 0xff - return (nbits & 0x00ffffff) * 2**(8*(shift - 3)) - -def target_to_nbits(target): - tstr = "{0:x}".format(target) - if len(tstr) < 6: - tstr = ("000000"+tstr)[-6:] - if len(tstr) % 2 != 0: - tstr = "0" + tstr - if int(tstr[0],16) >= 0x8: - # avoid "negative" - tstr = "00" + tstr - fix = int(tstr[:6], 16) - sz = len(tstr)//2 - if tstr[6:] != "0"*(sz*2-6): - fix += 1 - - return int("%02x%06x" % (sz,fix), 16) - -def seconds_to_hms(s): - if s == 0: - return "0s" - neg = (s < 0) - if neg: - s = -s - out = "" - if s % 60 > 0: - out = "%ds" % (s % 60) - s //= 60 - if s % 60 > 0: - out = "%dm%s" % (s % 60, out) - s //= 60 - if s > 0: - out = "%dh%s" % (s, out) - if neg: - out = "-" + out - return out - -def trivial_challenge(spkhex): - """ - BIP325 allows omitting the signet commitment when scriptSig and - scriptWitness are both empty. This is the case for trivial - challenges such as OP_TRUE or a single data push. - """ - spk = bytes.fromhex(spkhex) - if len(spk) == 1 and 0x51 <= spk[0] <= 0x60: - # OP_TRUE/OP_1...OP_16 - return True - elif 2 <= len(spk) <= 76 and spk[0] + 1 == len(spk): - # Single fixed push of 1-75 bytes - return True - return False - -class Generate: - INTERVAL = 600.0*2016/2015 # 10 minutes, adjusted for the off-by-one bug - - - def __init__(self, multiminer=None, ultimate_target=None, poisson=False, max_interval=1800, - standby_delay=0, backup_delay=0, set_block_time=None, - poolid=None): - if multiminer is None: - multiminer = (0, 1, 1) - (self.multi_low, self.multi_high, self.multi_period) = multiminer - self.ultimate_target = ultimate_target - self.poisson = poisson - self.max_interval = max_interval - self.standby_delay = standby_delay - self.backup_delay = backup_delay - self.set_block_time = set_block_time - self.poolid = poolid - - def next_block_delta(self, last_nbits, last_hash): - # strategy: - # 1) work out how far off our desired target we are - # 2) cap it to a factor of 4 since that's the best we can do in a single retarget period - # 3) use that to work out the desired average interval in this retarget period - # 4) if doing poisson, use the last hash to pick a uniformly random number in [0,1), and work out a random multiplier to vary the average by - # 5) cap the resulting interval between 1 second and 1 hour to avoid extremes - - current_target = nbits_to_target(last_nbits) - retarget_factor = self.ultimate_target / current_target - retarget_factor = max(0.25, min(retarget_factor, 4.0)) - - avg_interval = self.INTERVAL * retarget_factor - - if self.poisson: - det_rand = int(last_hash[-8:], 16) * 2**-32 - this_interval_variance = -math.log1p(-det_rand) - else: - this_interval_variance = 1 - - this_interval = avg_interval * this_interval_variance - this_interval = max(1, min(this_interval, self.max_interval)) - - return this_interval - - def next_block_is_mine(self, last_hash): - det_rand = int(last_hash[-16:-8], 16) - return self.multi_low <= (det_rand % self.multi_period) < self.multi_high - - def next_block_time(self, now, bestheader, is_first_block): - if self.set_block_time is not None: - logging.debug("Setting start time to %d", self.set_block_time) - self.mine_time = self.set_block_time - self.action_time = now - self.is_mine = True - elif bestheader["height"] == 0: - time_delta = self.INTERVAL * 100 # plenty of time to mine 100 blocks - logging.info("Backdating time for first block to %d minutes ago" % (time_delta/60)) - self.mine_time = now - time_delta - self.action_time = now - self.is_mine = True - else: - time_delta = self.next_block_delta(int(bestheader["bits"], 16), bestheader["hash"]) - self.mine_time = bestheader["time"] + time_delta - - self.is_mine = self.next_block_is_mine(bestheader["hash"]) - - self.action_time = self.mine_time - if not self.is_mine: - self.action_time += self.backup_delay - - if self.standby_delay > 0: - self.action_time += self.standby_delay - elif is_first_block: - # for non-standby, always mine immediately on startup, - # even if the next block shouldn't be ours - self.action_time = now - - # don't want fractional times so round down - self.mine_time = int(self.mine_time) - self.action_time = int(self.action_time) - - # can't mine a block 2h in the future; 1h55m for some safety - self.action_time = max(self.action_time, self.mine_time - 6900) - - def gbt(self, bcli, bestblockhash, now): - tmpl = json.loads(bcli("getblocktemplate", '{"rules":["signet","segwit"]}')) - if tmpl["previousblockhash"] != bestblockhash: - logging.warning("GBT based off unexpected block (%s not %s), retrying", tmpl["previousblockhash"], bci["bestblockhash"]) - time.sleep(1) - return None - - if tmpl["mintime"] > self.mine_time: - logging.info("Updating block time from %d to %d", self.mine_time, tmpl["mintime"]) - self.mine_time = tmpl["mintime"] - if self.mine_time > now: - logging.error("GBT mintime is in the future: %d is %d seconds later than %d", self.mine_time, (self.mine_time-now), now) - return None - - return tmpl - - def mine(self, bcli, grind_cmd, tmpl, reward_spk): - block = new_block(tmpl, reward_spk, blocktime=self.mine_time, poolid=self.poolid) - - signet_spk = tmpl["signet_challenge"] - if trivial_challenge(signet_spk): - signet_solution = None - else: - psbt = generate_psbt(block, signet_spk) - input_stream = os.linesep.join([psbt, "true", "ALL"]).encode('utf8') - psbt_signed = json.loads(bcli("-stdin", "walletprocesspsbt", input=input_stream)) - if not psbt_signed.get("complete",False): - logging.debug("Generated PSBT: %s" % (psbt,)) - sys.stderr.write("PSBT signing failed\n") - return None - psbt = decode_challenge_psbt(psbt_signed["psbt"]) - signet_solution = get_solution_from_psbt(psbt) - - return finish_block(block, signet_solution, grind_cmd) - -def do_generate(args): - if args.set_block_time is not None: - max_blocks = 1 - elif args.max_blocks is not None: - if args.max_blocks < 1: - logging.error("--max_blocks must specify a positive integer") - return 1 - max_blocks = args.max_blocks - elif args.ongoing: - max_blocks = None - else: - max_blocks = 1 - - if args.set_block_time is not None and args.set_block_time < 0: - args.set_block_time = time.time() - logging.info("Treating negative block time as current time (%d)" % (args.set_block_time)) - - if args.min_nbits: - args.nbits = "1e0377ae" - logging.info("Using nbits=%s" % (args.nbits)) - - if args.set_block_time is None: - if args.nbits is None or len(args.nbits) != 8: - logging.error("Must specify --nbits (use calibrate command to determine value)") - return 1 - - if args.multiminer is None: - my_blocks = (0,1,1) - else: - if not args.ongoing: - logging.error("Cannot specify --multiminer without --ongoing") - return 1 - m = RE_MULTIMINER.match(args.multiminer) - if m is None: - logging.error("--multiminer argument must be k/m or j-k/m") - return 1 - start,_,stop,total = m.groups() - if stop is None: - stop = start - start, stop, total = map(int, (start, stop, total)) - if stop < start or start <= 0 or total < stop or total == 0: - logging.error("Inconsistent values for --multiminer") - return 1 - my_blocks = (start-1, stop, total) - - if args.max_interval < 960: - logging.error("--max-interval must be at least 960 (16 minutes)") - return 1 - - poolid = get_poolid(args) - - ultimate_target = nbits_to_target(int(args.nbits,16)) - - gen = Generate(multiminer=my_blocks, ultimate_target=ultimate_target, poisson=args.poisson, max_interval=args.max_interval, - standby_delay=args.standby_delay, backup_delay=args.backup_delay, set_block_time=args.set_block_time, poolid=poolid) - - mined_blocks = 0 - bestheader = {"hash": None} - lastheader = None - while max_blocks is None or mined_blocks < max_blocks: - - # current status? - bci = json.loads(args.bcli("getblockchaininfo")) - - if bestheader["hash"] != bci["bestblockhash"]: - bestheader = json.loads(args.bcli("getblockheader", bci["bestblockhash"])) - - if lastheader is None: - lastheader = bestheader["hash"] - elif bestheader["hash"] != lastheader: - next_delta = gen.next_block_delta(int(bestheader["bits"], 16), bestheader["hash"]) - next_delta += bestheader["time"] - time.time() - next_is_mine = gen.next_block_is_mine(bestheader["hash"]) - logging.info("Received new block at height %d; next in %s (%s)", bestheader["height"], seconds_to_hms(next_delta), ("mine" if next_is_mine else "backup")) - lastheader = bestheader["hash"] - - # when is the next block due to be mined? - now = time.time() - gen.next_block_time(now, bestheader, (mined_blocks == 0)) - - # ready to go? otherwise sleep and check for new block - if now < gen.action_time: - sleep_for = min(gen.action_time - now, 60) - if gen.mine_time < now: - # someone else might have mined the block, - # so check frequently, so we don't end up late - # mining the next block if it's ours - sleep_for = min(20, sleep_for) - minestr = "mine" if gen.is_mine else "backup" - logging.debug("Sleeping for %s, next block due in %s (%s)" % (seconds_to_hms(sleep_for), seconds_to_hms(gen.mine_time - now), minestr)) - time.sleep(sleep_for) - continue - - # gbt - tmpl = gen.gbt(args.bcli, bci["bestblockhash"], now) - if tmpl is None: - continue - - logging.debug("GBT template: %s", tmpl) - - # address for reward - reward_addr, reward_spk = get_reward_addr_spk(args, tmpl["height"]) - - # mine block - logging.debug("Mining block delta=%s start=%s mine=%s", seconds_to_hms(gen.mine_time-bestheader["time"]), gen.mine_time, gen.is_mine) - mined_blocks += 1 - block = gen.mine(args.bcli, args.grind_cmd, tmpl, reward_spk) - if block is None: - return 1 - - # submit block - r = args.bcli("-stdin", "submitblock", input=block.serialize().hex().encode('utf8')) - - # report - bstr = "block" if gen.is_mine else "backup block" - - next_delta = gen.next_block_delta(block.nBits, block.hash_hex) - next_delta += block.nTime - time.time() - next_is_mine = gen.next_block_is_mine(block.hash_hex) - - logging.debug("Block hash %s payout to %s", block.hash_hex, reward_addr) - logging.info("Mined %s at height %d; next in %s (%s)", bstr, tmpl["height"], seconds_to_hms(next_delta), ("mine" if next_is_mine else "backup")) - if r != "": - logging.warning("submitblock returned %s for height %d hash %s", r, tmpl["height"], block.hash_hex) - lastheader = block.hash_hex - -def do_calibrate(args): - if args.nbits is not None and args.seconds is not None: - sys.stderr.write("Can only specify one of --nbits or --seconds\n") - return 1 - if args.nbits is not None and len(args.nbits) != 8: - sys.stderr.write("Must specify 8 hex digits for --nbits\n") - return 1 - - TRIALS = 600 # gets variance down pretty low - TRIAL_BITS = 0x1e3ea75f # takes about 5m to do 600 trials - - header = CBlockHeader() - header.nBits = TRIAL_BITS - targ = nbits_to_target(header.nBits) - - start = time.time() - count = 0 - for i in range(TRIALS): - header.nTime = i - header.nNonce = 0 - headhex = header.serialize().hex() - cmd = shlex.split(args.grind_cmd) + [headhex] - newheadhex = subprocess.run(cmd, stdout=subprocess.PIPE, input=b"", check=True).stdout.strip() - - avg = (time.time() - start) * 1.0 / TRIALS - - if args.nbits is not None: - want_targ = nbits_to_target(int(args.nbits,16)) - want_time = avg*targ/want_targ - else: - want_time = args.seconds if args.seconds is not None else 25 - want_targ = int(targ*(avg/want_time)) - - print("nbits=%08x for %ds average mining time" % (target_to_nbits(want_targ), want_time)) - return 0 - -def bitcoin_cli(basecmd, args, **kwargs): - cmd = basecmd + ["-signet"] + args - logging.debug("Calling bitcoin-cli: %r", cmd) - out = subprocess.run(cmd, stdout=subprocess.PIPE, **kwargs, check=True).stdout - if isinstance(out, bytes): - out = out.decode('utf8') - return out.strip() - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("--cli", default="bitcoin-cli", type=str, help="bitcoin-cli command") - parser.add_argument("--debug", action="store_true", help="Print debugging info") - parser.add_argument("--quiet", action="store_true", help="Only print warnings/errors") - - cmds = parser.add_subparsers(help="sub-commands") - genpsbt = cmds.add_parser("genpsbt", help="Generate a block PSBT for signing") - genpsbt.set_defaults(fn=do_genpsbt) - - solvepsbt = cmds.add_parser("solvepsbt", help="Solve a signed block PSBT") - solvepsbt.set_defaults(fn=do_solvepsbt) - - generate = cmds.add_parser("generate", help="Mine blocks") - generate.set_defaults(fn=do_generate) - howmany = generate.add_mutually_exclusive_group() - howmany.add_argument("--ongoing", action="store_true", help="Keep mining blocks") - howmany.add_argument("--max-blocks", default=None, type=int, help="Max blocks to mine (default=1)") - howmany.add_argument("--set-block-time", default=None, type=int, help="Set block time (unix timestamp); implies --max-blocks=1") - nbit_target = generate.add_mutually_exclusive_group() - nbit_target.add_argument("--nbits", default=None, type=str, help="Target nBits (specify difficulty)") - nbit_target.add_argument("--min-nbits", action="store_true", help="Target minimum nBits (use min difficulty)") - generate.add_argument("--poisson", action="store_true", help="Simulate randomised block times") - generate.add_argument("--multiminer", default=None, type=str, help="Specify which set of blocks to mine (eg: 1-40/100 for the first 40%%, 2/3 for the second 3rd)") - generate.add_argument("--backup-delay", default=300, type=int, help="Seconds to delay before mining blocks reserved for other miners (default=300)") - generate.add_argument("--standby-delay", default=0, type=int, help="Seconds to delay before mining blocks (default=0)") - generate.add_argument("--max-interval", default=1800, type=int, help="Maximum interblock interval (seconds)") - - calibrate = cmds.add_parser("calibrate", help="Calibrate difficulty") - calibrate.set_defaults(fn=do_calibrate) - calibrate_by = calibrate.add_mutually_exclusive_group() - calibrate_by.add_argument("--nbits", type=str, default=None) - calibrate_by.add_argument("--seconds", type=int, default=None) - - for sp in [genpsbt, generate]: - payto = sp.add_mutually_exclusive_group(required=True) - payto.add_argument("--address", default=None, type=str, help="Address for block reward payment") - payto.add_argument("--descriptor", default=None, type=str, help="Descriptor for block reward payment") - pool = sp.add_mutually_exclusive_group() - pool.add_argument("--poolnum", default=None, type=int, help="Identify blocks that you mine") - pool.add_argument("--poolid", default=None, type=str, help="Identify blocks that you mine (eg: /signet:1/)") - - for sp in [solvepsbt, generate, calibrate]: - sp.add_argument("--grind-cmd", default=None, type=str, required=(sp==calibrate), help="Command to grind a block header for proof-of-work") - - args = parser.parse_args(sys.argv[1:]) - - args.bcli = lambda *a, input=b"", **kwargs: bitcoin_cli(shlex.split(args.cli), list(a), input=input, **kwargs) - - if hasattr(args, "address") and hasattr(args, "descriptor"): - args.derived_addresses = {} - - if args.debug: - logging.getLogger().setLevel(logging.DEBUG) - elif args.quiet: - logging.getLogger().setLevel(logging.WARNING) - else: - logging.getLogger().setLevel(logging.INFO) - - if hasattr(args, "fn"): - return args.fn(args) - else: - logging.error("Must specify command") - return 1 - -if __name__ == "__main__": - main() diff --git a/contrib/utxo-tools/utxo_to_sqlite.py b/contrib/utxo-tools/utxo_to_sqlite.py deleted file mode 100755 index 4758fe39aaa5..000000000000 --- a/contrib/utxo-tools/utxo_to_sqlite.py +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2024-present The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Tool to convert a compact-serialized UTXO set to a SQLite3 database. - -The input UTXO set can be generated by Bitcoin Core with the `dumptxoutset` RPC: -$ bitcoin-cli dumptxoutset ~/utxos.dat latest - -The created database contains a table `utxos` with the following schema: -(txid TEXT, vout INT, value INT, coinbase INT, height INT, scriptpubkey TEXT) -""" -import argparse -import os -import sqlite3 -import sys -import time - - -UTXO_DUMP_MAGIC = b'utxo\xff' -UTXO_DUMP_VERSION = 2 -NET_MAGIC_BYTES = { - b"\xf9\xbe\xb4\xd9": "Mainnet", - b"\x0a\x03\xcf\x40": "Signet", - b"\x0b\x11\x09\x07": "Testnet3", - b"\x1c\x16\x3f\x28": "Testnet4", - b"\xfa\xbf\xb5\xda": "Regtest", -} - - -def read_varint(f): - """Equivalent of `ReadVarInt()` (see serialization module).""" - n = 0 - while True: - dat = f.read(1)[0] - n = (n << 7) | (dat & 0x7f) - if (dat & 0x80) > 0: - n += 1 - else: - return n - - -def read_compactsize(f): - """Equivalent of `ReadCompactSize()` (see serialization module).""" - n = f.read(1)[0] - if n == 253: - n = int.from_bytes(f.read(2), "little") - elif n == 254: - n = int.from_bytes(f.read(4), "little") - elif n == 255: - n = int.from_bytes(f.read(8), "little") - return n - - -def decompress_amount(x): - """Equivalent of `DecompressAmount()` (see compressor module).""" - if x == 0: - return 0 - x -= 1 - e = x % 10 - x //= 10 - n = 0 - if e < 9: - d = (x % 9) + 1 - x //= 9 - n = x * 10 + d - else: - n = x + 1 - while e > 0: - n *= 10 - e -= 1 - return n - - -def decompress_script(f): - """Equivalent of `DecompressScript()` (see compressor module).""" - size = read_varint(f) # sizes 0-5 encode compressed script types - if size == 0: # P2PKH - return bytes([0x76, 0xa9, 20]) + f.read(20) + bytes([0x88, 0xac]) - elif size == 1: # P2SH - return bytes([0xa9, 20]) + f.read(20) + bytes([0x87]) - elif size in (2, 3): # P2PK (compressed) - return bytes([33, size]) + f.read(32) + bytes([0xac]) - elif size in (4, 5): # P2PK (uncompressed) - compressed_pubkey = bytes([size - 2]) + f.read(32) - return bytes([65]) + decompress_pubkey(compressed_pubkey) + bytes([0xac]) - else: # others (bare multisig, segwit etc.) - size -= 6 - assert size <= 10000, f"too long script with size {size}" - return f.read(size) - - -def decompress_pubkey(compressed_pubkey): - """Decompress pubkey by calculating y = sqrt(x^3 + 7) % p - (see functions `secp256k1_eckey_pubkey_parse` and `secp256k1_ge_set_xo_var`). - """ - P = 2**256 - 2**32 - 977 # secp256k1 field size - assert len(compressed_pubkey) == 33 and compressed_pubkey[0] in (2, 3) - x = int.from_bytes(compressed_pubkey[1:], 'big') - rhs = (x**3 + 7) % P - y = pow(rhs, (P + 1)//4, P) # get sqrt using Tonelli-Shanks algorithm (for p % 4 = 3) - assert pow(y, 2, P) == rhs, f"pubkey is not on curve ({compressed_pubkey.hex()})" - tag_is_odd = compressed_pubkey[0] == 3 - y_is_odd = (y & 1) == 1 - if tag_is_odd != y_is_odd: # fix parity (even/odd) if necessary - y = P - y - return bytes([4]) + x.to_bytes(32, 'big') + y.to_bytes(32, 'big') - - -def main(): - parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument('infile', help='filename of compact-serialized UTXO set (input)') - parser.add_argument('outfile', help='filename of created SQLite3 database (output)') - parser.add_argument('-v', '--verbose', action='store_true', help='show details about each UTXO') - args = parser.parse_args() - - if not os.path.exists(args.infile): - print(f"Error: provided input file '{args.infile}' doesn't exist.") - sys.exit(1) - - if os.path.exists(args.outfile): - print(f"Error: provided output file '{args.outfile}' already exists.") - sys.exit(1) - - # create database table - con = sqlite3.connect(args.outfile) - con.execute("CREATE TABLE utxos(txid TEXT, vout INT, value INT, coinbase INT, height INT, scriptpubkey TEXT)") - - # read metadata (magic bytes, version, network magic, block hash, UTXO count) - f = open(args.infile, 'rb') - magic_bytes = f.read(5) - version = int.from_bytes(f.read(2), 'little') - network_magic = f.read(4) - block_hash = f.read(32) - num_utxos = int.from_bytes(f.read(8), 'little') - if magic_bytes != UTXO_DUMP_MAGIC: - print(f"Error: provided input file '{args.infile}' is not an UTXO dump.") - sys.exit(1) - if version != UTXO_DUMP_VERSION: - print(f"Error: provided input file '{args.infile}' has unknown UTXO dump version {version} " - f"(only version {UTXO_DUMP_VERSION} supported)") - sys.exit(1) - network_string = NET_MAGIC_BYTES.get(network_magic, f"unknown network ({network_magic.hex()})") - print(f"UTXO Snapshot for {network_string} at block hash " - f"{block_hash[::-1].hex()[:32]}..., contains {num_utxos} coins") - - start_time = time.time() - write_batch = [] - coins_per_hash_left = 0 - prevout_hash = None - max_height = 0 - - for coin_idx in range(1, num_utxos+1): - # read key (COutPoint) - if coins_per_hash_left == 0: # read next prevout hash - prevout_hash = f.read(32)[::-1].hex() - coins_per_hash_left = read_compactsize(f) - prevout_index = read_compactsize(f) - # read value (Coin) - code = read_varint(f) - height = code >> 1 - is_coinbase = code & 1 - amount = decompress_amount(read_varint(f)) - scriptpubkey = decompress_script(f).hex() - write_batch.append((prevout_hash, prevout_index, amount, is_coinbase, height, scriptpubkey)) - if height > max_height: - max_height = height - coins_per_hash_left -= 1 - - if args.verbose: - print(f"Coin {coin_idx}/{num_utxos}:") - print(f" prevout = {prevout_hash}:{prevout_index}") - print(f" amount = {amount}, height = {height}, coinbase = {is_coinbase}") - print(f" scriptPubKey = {scriptpubkey}\n") - - if coin_idx % (16*1024) == 0 or coin_idx == num_utxos: - # write utxo batch to database - con.executemany("INSERT INTO utxos VALUES(?, ?, ?, ?, ?, ?)", write_batch) - con.commit() - write_batch.clear() - - if coin_idx % (1024*1024) == 0: - elapsed = time.time() - start_time - print(f"{coin_idx} coins converted [{coin_idx/num_utxos*100:.2f}%], " + - f"{elapsed:.3f}s passed since start") - con.close() - - print(f"TOTAL: {num_utxos} coins written to {args.outfile}, snapshot height is {max_height}.") - if f.read(1) != b'': # EOF should be reached by now - print(f"WARNING: input file {args.infile} has not reached EOF yet!") - sys.exit(1) - - -if __name__ == '__main__': - main() diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp index 7960f9c8e4f2..39e0ee0188b1 100644 --- a/contrib/valgrind.supp +++ b/contrib/valgrind.supp @@ -2,14 +2,14 @@ # dependencies that cannot be fixed in-tree. # # Example use: -# $ valgrind --suppressions=contrib/valgrind.supp build/bin/test_bitcoin +# $ valgrind --suppressions=contrib/valgrind.supp build/bin/test_sv2 # $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ -# --show-leak-kinds=all build/bin/test_bitcoin +# --show-leak-kinds=all build/bin/test_sv2 # # To create suppressions for found issues, use the --gen-suppressions=all option: # $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ # --show-leak-kinds=all --gen-suppressions=all --show-reachable=yes \ -# --error-limit=no build/bin/test_bitcoin +# --error-limit=no build/bin/test_sv2 # # Note that suppressions may depend on OS and/or library versions. # Tested on aarch64 and x86_64 with Ubuntu Noble system libs, using clang-16 diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py deleted file mode 100755 index b2290a6c5b60..000000000000 --- a/contrib/zmq/zmq_sub.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2014-2021 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -""" - ZMQ example using python3's asyncio - - Bitcoin should be started with the command line arguments: - bitcoind -testnet4 -daemon \ - -zmqpubrawtx=tcp://127.0.0.1:28332 \ - -zmqpubrawblock=tcp://127.0.0.1:28332 \ - -zmqpubhashtx=tcp://127.0.0.1:28332 \ - -zmqpubhashblock=tcp://127.0.0.1:28332 \ - -zmqpubsequence=tcp://127.0.0.1:28332 - - We use the asyncio library here. `self.handle()` installs itself as a - future at the end of the function. Since it never returns with the event - loop having an empty stack of futures, this creates an infinite loop. An - alternative is to wrap the contents of `handle` inside `while True`. - - A blocking example using python 2.7 can be obtained from the git history: - https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py -""" - -import asyncio -import zmq -import zmq.asyncio -import signal -import struct -import sys - -if (sys.version_info.major, sys.version_info.minor) < (3, 5): - print("This example only works with Python 3.5 and greater") - sys.exit(1) - -port = 28332 - -class ZMQHandler(): - def __init__(self): - self.loop = asyncio.get_event_loop() - self.zmqContext = zmq.asyncio.Context() - - self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) - self.zmqSubSocket.setsockopt(zmq.RCVHWM, 0) - self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock") - self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx") - self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock") - self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx") - self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "sequence") - self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) - - async def handle(self) : - topic, body, seq = await self.zmqSubSocket.recv_multipart() - sequence = "Unknown" - if len(seq) == 4: - sequence = str(struct.unpack(' $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_qttranslations_sha256_hash) $($(package)_source_dir)/$($(package)_qttranslations_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmakelists_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmakelists_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmake_ecmoptionaladdsubdirectory_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmake_qttoplevelhelpers_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmake_qttoplevelhelpers_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir qtbase && \ - $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ - mkdir qttranslations && \ - $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ - mkdir qttools && \ - $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools && \ - cp $($(package)_source_dir)/$($(package)_top_cmakelists_file_name)-$($(package)_version) ./$($(package)_top_cmakelists_file_name) && \ - mkdir cmake && \ - cp $($(package)_source_dir)/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name)-$($(package)_version) cmake/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name) && \ - cp $($(package)_source_dir)/$($(package)_top_cmake_qttoplevelhelpers_file_name)-$($(package)_version) cmake/$($(package)_top_cmake_qttoplevelhelpers_file_name) -endef - -define $(package)_preprocess_cmds - patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase-moc-ignore-gcc-macro.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_skip_tools.patch && \ - patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch && \ - patch -p1 -i $($(package)_patch_dir)/qttools_skip_dependencies.patch -endef - -define $(package)_config_cmds - cd qtbase && \ - ./configure -top-level $($(package)_config_opts) -- $($(package)_cmake_opts) -endef - -define $(package)_build_cmds - cmake --build . -- $$(filter -j%,$$(MAKEFLAGS)) -endef - -define $(package)_stage_cmds - cmake --install . --prefix $($(package)_staging_prefix_dir) -endef - -define $(package)_postprocess_cmds - rm -rf doc/ && \ - mv translations/ .. -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 4fee4e18a396..7f8f35a895a6 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -2,24 +2,6 @@ packages:= boost_packages = boost -libevent_packages = libevent - -qrencode_linux_packages = qrencode -qrencode_darwin_packages = qrencode -qrencode_mingw32_packages = qrencode - -qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon libxcb_util libxcb_util_cursor libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm -qt_freebsd_packages:=$(qt_linux_packages) -qt_darwin_packages=qt -qt_mingw32_packages=qt -ifneq ($(host),$(build)) -qt_native_packages := native_qt -endif - -sqlite_packages=sqlite - -zmq_packages=zeromq - ipc_packages = capnp multiprocess_native_packages = native_libmultiprocess native_capnp diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk deleted file mode 100644 index e3f614091db0..000000000000 --- a/depends/packages/qrencode.mk +++ /dev/null @@ -1,34 +0,0 @@ -package=qrencode -$(package)_version=4.1.1 -$(package)_download_path=https://fukuchi.org/works/qrencode/ -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=da448ed4f52aba6bcb0cd48cac0dd51b8692bccc4cd127431402fca6f8171e8e -$(package)_patches=cmake_fixups.patch - -define $(package)_set_vars -$(package)_config_opts := -DWITH_TOOLS=NO -DWITH_TESTS=NO -DGPROF=OFF -DCOVERAGE=OFF -$(package)_config_opts += -DCMAKE_DISABLE_FIND_PACKAGE_PNG=TRUE -DWITHOUT_PNG=ON -$(package)_config_opts += -DCMAKE_DISABLE_FIND_PACKAGE_ICONV=TRUE -$(package)_cflags += -Wno-int-conversion -Wno-implicit-function-declaration -endef - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/cmake_fixups.patch -endef - - -define $(package)_config_cmds - $($(package)_cmake) -S . -B . -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm -rf share -endef diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk deleted file mode 100644 index 4daffeb1aa38..000000000000 --- a/depends/packages/qt.mk +++ /dev/null @@ -1,286 +0,0 @@ -package=qt -include packages/qt_details.mk -$(package)_version=$(qt_details_version) -$(package)_download_path=$(qt_details_download_path) -$(package)_file_name=$(qt_details_qtbase_file_name) -$(package)_sha256_hash=$(qt_details_qtbase_sha256_hash) -ifneq ($(host),$(build)) -$(package)_dependencies := native_$(package) -endif -$(package)_linux_dependencies := freetype fontconfig libxcb libxkbcommon libxcb_util libxcb_util_cursor libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm -$(package)_freebsd_dependencies := $($(package)_linux_dependencies) -$(package)_patches_path := $(qt_details_patches_path) -$(package)_patches := dont_hardcode_pwd.patch -$(package)_patches += qtbase-moc-ignore-gcc-macro.patch -$(package)_patches += qtbase_avoid_native_float16.patch -$(package)_patches += qtbase_avoid_qmain.patch -$(package)_patches += qtbase_platformsupport.patch -$(package)_patches += qtbase_plugins_cocoa.patch -$(package)_patches += qtbase_skip_tools.patch -$(package)_patches += rcc_hardcode_timestamp.patch -$(package)_patches += qttools_skip_dependencies.patch - -$(package)_qttranslations_file_name=$(qt_details_qttranslations_file_name) -$(package)_qttranslations_sha256_hash=$(qt_details_qttranslations_sha256_hash) - -$(package)_qttools_file_name=$(qt_details_qttools_file_name) -$(package)_qttools_sha256_hash=$(qt_details_qttools_sha256_hash) - -$(package)_extra_sources := $($(package)_qttranslations_file_name) -$(package)_extra_sources += $($(package)_qttools_file_name) - -$(package)_top_download_path=$(qt_details_top_download_path) -$(package)_top_cmakelists_file_name=$(qt_details_top_cmakelists_file_name) -$(package)_top_cmakelists_download_file=$(qt_details_top_cmakelists_download_file) -$(package)_top_cmakelists_sha256_hash=$(qt_details_top_cmakelists_sha256_hash) -$(package)_top_cmake_download_path=$(qt_details_top_cmake_download_path) -$(package)_top_cmake_ecmoptionaladdsubdirectory_file_name=$(qt_details_top_cmake_ecmoptionaladdsubdirectory_file_name) -$(package)_top_cmake_ecmoptionaladdsubdirectory_download_file=$(qt_details_top_cmake_ecmoptionaladdsubdirectory_download_file) -$(package)_top_cmake_ecmoptionaladdsubdirectory_sha256_hash=$(qt_details_top_cmake_ecmoptionaladdsubdirectory_sha256_hash) -$(package)_top_cmake_qttoplevelhelpers_file_name=$(qt_details_top_cmake_qttoplevelhelpers_file_name) -$(package)_top_cmake_qttoplevelhelpers_download_file=$(qt_details_top_cmake_qttoplevelhelpers_download_file) -$(package)_top_cmake_qttoplevelhelpers_sha256_hash=$(qt_details_top_cmake_qttoplevelhelpers_sha256_hash) - -$(package)_extra_sources += $($(package)_top_cmakelists_file_name)-$($(package)_version) -$(package)_extra_sources += $($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name)-$($(package)_version) -$(package)_extra_sources += $($(package)_top_cmake_qttoplevelhelpers_file_name)-$($(package)_version) - -define $(package)_set_vars -$(package)_config_opts_release := -release -$(package)_config_opts_debug := -debug -$(package)_config_opts := -no-egl -$(package)_config_opts += -no-eglfs -$(package)_config_opts += -no-evdev -$(package)_config_opts += -no-gif -$(package)_config_opts += -no-glib -$(package)_config_opts += -no-icu -$(package)_config_opts += -no-ico -$(package)_config_opts += -no-kms -$(package)_config_opts += -no-linuxfb -$(package)_config_opts += -no-libjpeg -$(package)_config_opts += -no-libproxy -$(package)_config_opts += -no-libudev -$(package)_config_opts += -no-mtdev -$(package)_config_opts += -no-opengl -$(package)_config_opts += -no-openssl -$(package)_config_opts += -no-openvg -$(package)_config_opts += -no-reduce-relocations -$(package)_config_opts += -no-schannel -$(package)_config_opts += -no-sctp -$(package)_config_opts += -no-securetransport -$(package)_config_opts += -no-system-proxies -$(package)_config_opts += -no-use-gold-linker -$(package)_config_opts += -no-zstd -$(package)_config_opts += -nomake examples -$(package)_config_opts += -nomake tests -$(package)_config_opts += -prefix $(host_prefix) -$(package)_config_opts += -qt-doubleconversion -$(package)_config_opts += -qt-harfbuzz -ifneq ($(host),$(build)) -$(package)_config_opts += -qt-host-path $(build_prefix) -endif -$(package)_config_opts += -qt-libpng -$(package)_config_opts += -qt-pcre -$(package)_config_opts += -qt-zlib -$(package)_config_opts += -static -$(package)_config_opts += -no-feature-backtrace -$(package)_config_opts += -no-feature-colordialog -$(package)_config_opts += -no-feature-concurrent -$(package)_config_opts += -no-feature-dial -$(package)_config_opts += -no-feature-gssapi -$(package)_config_opts += -no-feature-http -$(package)_config_opts += -no-feature-image_heuristic_mask -$(package)_config_opts += -no-feature-keysequenceedit -$(package)_config_opts += -no-feature-lcdnumber -$(package)_config_opts += -no-feature-libresolv -$(package)_config_opts += -no-feature-networkdiskcache -$(package)_config_opts += -no-feature-networkproxy -$(package)_config_opts += -no-feature-printsupport -$(package)_config_opts += -no-feature-sessionmanager -$(package)_config_opts += -no-feature-socks5 -$(package)_config_opts += -no-feature-sql -$(package)_config_opts += -no-feature-textmarkdownreader -$(package)_config_opts += -no-feature-textmarkdownwriter -$(package)_config_opts += -no-feature-textodfwriter -$(package)_config_opts += -no-feature-topleveldomain -$(package)_config_opts += -no-feature-udpsocket -$(package)_config_opts += -no-feature-undocommand -$(package)_config_opts += -no-feature-undogroup -$(package)_config_opts += -no-feature-undostack -$(package)_config_opts += -no-feature-undoview -$(package)_config_opts += -no-feature-vnc -$(package)_config_opts += -no-feature-vulkan - -# Core tools. -$(package)_config_opts += -no-feature-androiddeployqt -$(package)_config_opts += -no-feature-macdeployqt -$(package)_config_opts += -no-feature-qmake -$(package)_config_opts += -no-feature-windeployqt - -ifeq ($(host),$(build)) -# Qt Tools module. -$(package)_config_opts += -feature-linguist -$(package)_config_opts += -no-feature-assistant -$(package)_config_opts += -no-feature-clang -$(package)_config_opts += -no-feature-clangcpp -$(package)_config_opts += -no-feature-designer -$(package)_config_opts += -no-feature-pixeltool -$(package)_config_opts += -no-feature-qdoc -$(package)_config_opts += -no-feature-qtattributionsscanner -$(package)_config_opts += -no-feature-qtdiag -$(package)_config_opts += -no-feature-qtplugininfo -endif - -$(package)_config_opts_darwin := -no-dbus -$(package)_config_opts_darwin += -no-feature-printsupport -$(package)_config_opts_darwin += -no-freetype -$(package)_config_opts_darwin += -no-pkg-config - -$(package)_config_opts_linux := -dbus-runtime -$(package)_config_opts_linux += -fontconfig -$(package)_config_opts_linux += -no-feature-process -$(package)_config_opts_linux += -no-feature-xlib -$(package)_config_opts_linux += -no-xcb-xlib -$(package)_config_opts_linux += -pkg-config -$(package)_config_opts_linux += -system-freetype -$(package)_config_opts_linux += -xcb -ifneq ($(LTO),) -$(package)_config_opts_linux += -ltcg -endif -$(package)_config_opts_freebsd := $$($(package)_config_opts_linux) - -$(package)_config_opts_mingw32 := -no-dbus -$(package)_config_opts_mingw32 += -no-freetype -$(package)_config_opts_mingw32 += -no-pkg-config - -# CMake build options. -$(package)_config_env := CC="$$($(package)_cc)" -$(package)_config_env += CXX="$$($(package)_cxx)" -$(package)_config_env_darwin := OBJC="$$($(package)_cc)" -$(package)_config_env_darwin += OBJCXX="$$($(package)_cxx)" - -$(package)_cmake_opts := -DCMAKE_PREFIX_PATH=$(host_prefix) -$(package)_cmake_opts += -DQT_FEATURE_cxx20=ON -$(package)_cmake_opts += -DQT_ENABLE_CXX_EXTENSIONS=OFF -ifneq ($(V),) -$(package)_cmake_opts += --log-level=STATUS -endif - -$(package)_cmake_opts += -DQT_USE_DEFAULT_CMAKE_OPTIMIZATION_FLAGS=ON -$(package)_cmake_opts += -DCMAKE_C_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" -$(package)_cmake_opts += -DCMAKE_C_FLAGS_RELEASE="$$($$($(package)_type)_release_CFLAGS)" -$(package)_cmake_opts += -DCMAKE_C_FLAGS_DEBUG="$$($$($(package)_type)_debug_CFLAGS)" -$(package)_cmake_opts += -DCMAKE_CXX_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CXXFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" -$(package)_cmake_opts += -DCMAKE_CXX_FLAGS_RELEASE="$$($$($(package)_type)_release_CXXFLAGS)" -$(package)_cmake_opts += -DCMAKE_CXX_FLAGS_DEBUG="$$($$($(package)_type)_debug_CXXFLAGS)" -ifeq ($(host_os),darwin) -$(package)_cmake_opts += -DCMAKE_OBJC_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" -$(package)_cmake_opts += -DCMAKE_OBJC_FLAGS_RELEASE="$$($$($(package)_type)_release_CFLAGS)" -$(package)_cmake_opts += -DCMAKE_OBJC_FLAGS_DEBUG="$$($$($(package)_type)_debug_CFLAGS)" -$(package)_cmake_opts += -DCMAKE_OBJCXX_FLAGS="$$($(package)_cppflags) $$($$($(package)_type)_CXXFLAGS) -ffile-prefix-map=$$($(package)_extract_dir)=/usr" -$(package)_cmake_opts += -DCMAKE_OBJCXX_FLAGS_RELEASE="$$($$($(package)_type)_release_CXXFLAGS)" -$(package)_cmake_opts += -DCMAKE_OBJCXX_FLAGS_DEBUG="$$($$($(package)_type)_debug_CXXFLAGS)" -endif -$(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS="$$($$($(package)_type)_LDFLAGS)" -$(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS_RELEASE="$$($$($(package)_type)_release_LDFLAGS)" -$(package)_cmake_opts += -DCMAKE_EXE_LINKER_FLAGS_DEBUG="$$($$($(package)_type)_debug_LDFLAGS)" - -ifneq ($(host),$(build)) -$(package)_cmake_opts += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system_name) -$(package)_cmake_opts += -DCMAKE_SYSTEM_VERSION=$($(host_os)_cmake_system_version) -$(package)_cmake_opts += -DCMAKE_SYSTEM_PROCESSOR=$(host_arch) -# Native packages cannot be used during cross-compiling. However, -# Qt still unconditionally tries to find them, which causes issues -# in some cases, such as when cross-compiling from macOS to Windows. -# Explicitly disable this unnecessary Qt behaviour. -$(package)_cmake_opts += -DCMAKE_DISABLE_FIND_PACKAGE_Libb2=TRUE -$(package)_cmake_opts += -DCMAKE_DISABLE_FIND_PACKAGE_WrapSystemDoubleConversion=TRUE -$(package)_cmake_opts += -DCMAKE_DISABLE_FIND_PACKAGE_WrapSystemMd4c=TRUE -$(package)_cmake_opts += -DCMAKE_DISABLE_FIND_PACKAGE_WrapZSTD=TRUE -endif -ifeq ($(host_os),darwin) -$(package)_cmake_opts += -DCMAKE_INSTALL_NAME_TOOL=true -$(package)_cmake_opts += -DCMAKE_FRAMEWORK_PATH=$(OSX_SDK)/System/Library/Frameworks -$(package)_cmake_opts += -DQT_INTERNAL_APPLE_SDK_VERSION=$(OSX_SDK_VERSION) -$(package)_cmake_opts += -DQT_INTERNAL_XCODE_VERSION=$(XCODE_VERSION) -$(package)_cmake_opts += -DQT_NO_APPLE_SDK_MAX_VERSION_CHECK=ON -endif -endef - -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_qttranslations_file_name),$($(package)_qttranslations_file_name),$($(package)_qttranslations_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_qttools_file_name),$($(package)_qttools_file_name),$($(package)_qttools_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_top_download_path),$($(package)_top_cmakelists_download_file),$($(package)_top_cmakelists_file_name)-$($(package)_version),$($(package)_top_cmakelists_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_top_cmake_download_path),$($(package)_top_cmake_ecmoptionaladdsubdirectory_download_file),$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name)-$($(package)_version),$($(package)_top_cmake_ecmoptionaladdsubdirectory_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_top_cmake_download_path),$($(package)_top_cmake_qttoplevelhelpers_download_file),$($(package)_top_cmake_qttoplevelhelpers_file_name)-$($(package)_version),$($(package)_top_cmake_qttoplevelhelpers_sha256_hash)) -endef - -ifeq ($(host),$(build)) -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_qttranslations_sha256_hash) $($(package)_source_dir)/$($(package)_qttranslations_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmakelists_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmakelists_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmake_ecmoptionaladdsubdirectory_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmake_qttoplevelhelpers_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmake_qttoplevelhelpers_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir qtbase && \ - $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ - mkdir qttranslations && \ - $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ - mkdir qttools && \ - $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools && \ - cp $($(package)_source_dir)/$($(package)_top_cmakelists_file_name)-$($(package)_version) ./$($(package)_top_cmakelists_file_name) && \ - mkdir cmake && \ - cp $($(package)_source_dir)/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name)-$($(package)_version) cmake/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name) && \ - cp $($(package)_source_dir)/$($(package)_top_cmake_qttoplevelhelpers_file_name)-$($(package)_version) cmake/$($(package)_top_cmake_qttoplevelhelpers_file_name) -endef -else -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmakelists_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmakelists_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmake_ecmoptionaladdsubdirectory_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_top_cmake_qttoplevelhelpers_sha256_hash) $($(package)_source_dir)/$($(package)_top_cmake_qttoplevelhelpers_file_name)-$($(package)_version)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir qtbase && \ - $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ - cp $($(package)_source_dir)/$($(package)_top_cmakelists_file_name)-$($(package)_version) ./$($(package)_top_cmakelists_file_name) && \ - mkdir cmake && \ - cp $($(package)_source_dir)/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name)-$($(package)_version) cmake/$($(package)_top_cmake_ecmoptionaladdsubdirectory_file_name) && \ - cp $($(package)_source_dir)/$($(package)_top_cmake_qttoplevelhelpers_file_name)-$($(package)_version) cmake/$($(package)_top_cmake_qttoplevelhelpers_file_name) -endef -endif - -define $(package)_preprocess_cmds - patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase-moc-ignore-gcc-macro.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_avoid_native_float16.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_avoid_qmain.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_platformsupport.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_plugins_cocoa.patch && \ - patch -p1 -i $($(package)_patch_dir)/qtbase_skip_tools.patch && \ - patch -p1 -i $($(package)_patch_dir)/rcc_hardcode_timestamp.patch -endef -ifeq ($(host),$(build)) - $(package)_preprocess_cmds += && patch -p1 -i $($(package)_patch_dir)/qttools_skip_dependencies.patch -endif - -define $(package)_config_cmds - cd qtbase && \ - ./configure -top-level $($(package)_config_opts) -- $($(package)_cmake_opts) -endef - -define $(package)_build_cmds - cmake --build . -- $$(filter -j%,$$(MAKEFLAGS)) -endef - -define $(package)_stage_cmds - cmake --install . --prefix $($(package)_staging_prefix_dir) -endef - -define $(package)_postprocess_cmds - rm -rf doc/ -endef diff --git a/depends/packages/qt_details.mk b/depends/packages/qt_details.mk deleted file mode 100644 index 341448149e3d..000000000000 --- a/depends/packages/qt_details.mk +++ /dev/null @@ -1,26 +0,0 @@ -qt_details_version := 6.7.3 -qt_details_download_path := https://download.qt.io/archive/qt/6.7/$(qt_details_version)/submodules -qt_details_suffix := everywhere-src-$(qt_details_version).tar.xz - -qt_details_qtbase_file_name := qtbase-$(qt_details_suffix) -qt_details_qtbase_sha256_hash := 8ccbb9ab055205ac76632c9eeddd1ed6fc66936fc56afc2ed0fd5d9e23da3097 - -qt_details_qttranslations_file_name := qttranslations-$(qt_details_suffix) -qt_details_qttranslations_sha256_hash := dcc762acac043b9bb5e4d369b6d6f53e0ecfcf76a408fe0db5f7ef071c9d6dc8 - -qt_details_qttools_file_name := qttools-$(qt_details_suffix) -qt_details_qttools_sha256_hash := f03bb7df619cd9ac9dba110e30b7bcab5dd88eb8bdc9cc752563b4367233203f - -qt_details_patches_path := $(PATCHES_PATH)/qt - -qt_details_top_download_path := https://code.qt.io/cgit/qt/qt5.git/plain -qt_details_top_cmakelists_file_name := CMakeLists.txt -qt_details_top_cmakelists_download_file := $(qt_details_top_cmakelists_file_name)?h=$(qt_details_version) -qt_details_top_cmakelists_sha256_hash := 9fb720a633c0c0a21c31fe62a34bf617726fed72480d4064f29ca5d6973d513f -qt_details_top_cmake_download_path := $(qt_details_top_download_path)/cmake -qt_details_top_cmake_ecmoptionaladdsubdirectory_file_name := ECMOptionalAddSubdirectory.cmake -qt_details_top_cmake_ecmoptionaladdsubdirectory_download_file := $(qt_details_top_cmake_ecmoptionaladdsubdirectory_file_name)?h=$(qt_details_version) -qt_details_top_cmake_ecmoptionaladdsubdirectory_sha256_hash := 97ee8bbfcb0a4bdcc6c1af77e467a1da0c5b386c42be2aa97d840247af5f6f70 -qt_details_top_cmake_qttoplevelhelpers_file_name := QtTopLevelHelpers.cmake -qt_details_top_cmake_qttoplevelhelpers_download_file := $(qt_details_top_cmake_qttoplevelhelpers_file_name)?h=$(qt_details_version) -qt_details_top_cmake_qttoplevelhelpers_sha256_hash := 5ac2a7159ee27b5b86d26ecff44922e7b8f319aa847b7b5766dc17932fd4a294 diff --git a/depends/packages/sqlite.mk b/depends/packages/sqlite.mk deleted file mode 100644 index 67b7719eb880..000000000000 --- a/depends/packages/sqlite.mk +++ /dev/null @@ -1,35 +0,0 @@ -package=sqlite -$(package)_version=3460100 -$(package)_download_path=https://sqlite.org/2024/ -$(package)_file_name=sqlite-autoconf-$($(package)_version).tar.gz -$(package)_sha256_hash=67d3fe6d268e6eaddcae3727fce58fcc8e9c53869bdd07a0c61e38ddf2965071 - -define $(package)_set_vars -$(package)_config_opts=--disable-shared --disable-readline --disable-dynamic-extensions --enable-option-checking -$(package)_config_opts+= --disable-rtree --disable-fts4 --disable-fts5 -# We avoid using `--enable-debug` because it overrides CFLAGS, a behavior we want to prevent. -$(package)_cppflags_debug += -DSQLITE_DEBUG -$(package)_cppflags+=-DSQLITE_DQS=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_OMIT_DEPRECATED -$(package)_cppflags+=-DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_JSON -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -$(package)_cppflags+=-DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_AUTOINIT -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) libsqlite3.la -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-includeHEADERS -endef - -define $(package)_postprocess_cmds - rm lib/*.la -endef diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk deleted file mode 100644 index 6e1c5a10a87b..000000000000 --- a/depends/packages/xcb_proto.mk +++ /dev/null @@ -1,21 +0,0 @@ -package=xcb_proto -$(package)_version=1.15.2 -$(package)_download_path=https://xorg.freedesktop.org/archive/individual/proto -$(package)_file_name=xcb-proto-$($(package)_version).tar.xz -$(package)_sha256_hash=7072beb1f680a2fe3f9e535b797c146d22528990c72f63ddb49d2f350a3653ed - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm -rf lib/python*/site-packages/xcbgen/__pycache__ -endef diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk deleted file mode 100644 index 0a534556ee4a..000000000000 --- a/depends/packages/xproto.mk +++ /dev/null @@ -1,28 +0,0 @@ -package=xproto -$(package)_version=7.0.31 -$(package)_download_path=https://xorg.freedesktop.org/releases/individual/proto -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=6d755eaae27b45c5cc75529a12855fed5de5969b367ed05003944cf901ed43c7 - -define $(package)_set_vars -$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs -$(package)_config_opts += --disable-dependency-tracking --enable-option-checking -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -endef - -# mkdir detection is broken on Alpine. Set MKDIRPROG to ensure we always -# use "mkdir -p", and avoid parallelism issues during install. -define $(package)_stage_cmds - $(MAKE) MKDIRPROG="mkdir -p" DESTDIR=$($(package)_staging_dir) install -endef diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk deleted file mode 100644 index 8bf84b1f1cba..000000000000 --- a/depends/packages/zeromq.mk +++ /dev/null @@ -1,49 +0,0 @@ -package=zeromq -$(package)_version=4.3.5 -$(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=6653ef5910f17954861fe72332e68b03ca6e4d9c7160eb3a8de5a5a913bfab43 -$(package)_build_subdir=build -$(package)_patches = macos_mktemp_check.patch -$(package)_patches += builtin_sha1.patch -$(package)_patches += fix_have_windows.patch -$(package)_patches += openbsd_kqueue_headers.patch -$(package)_patches += cmake_minimum.patch -$(package)_patches += cacheline_undefined.patch -$(package)_patches += no_librt.patch - -define $(package)_set_vars - $(package)_config_opts := -DCMAKE_BUILD_TYPE=None -DWITH_DOCS=OFF -DWITH_LIBSODIUM=OFF - $(package)_config_opts += -DWITH_LIBBSD=OFF -DENABLE_CURVE=OFF -DENABLE_CPACK=OFF - $(package)_config_opts += -DBUILD_SHARED=OFF -DBUILD_TESTS=OFF -DZMQ_BUILD_TESTS=OFF - $(package)_config_opts += -DENABLE_DRAFTS=OFF -DZMQ_BUILD_TESTS=OFF - $(package)_cxxflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr - $(package)_config_opts_mingw32 += -DZMQ_WIN32_WINNT=0x0A00 -DZMQ_HAVE_IPC=OFF -endef - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/macos_mktemp_check.patch && \ - patch -p1 < $($(package)_patch_dir)/builtin_sha1.patch && \ - patch -p1 < $($(package)_patch_dir)/cacheline_undefined.patch && \ - patch -p1 < $($(package)_patch_dir)/fix_have_windows.patch && \ - patch -p1 < $($(package)_patch_dir)/openbsd_kqueue_headers.patch && \ - patch -p1 < $($(package)_patch_dir)/cmake_minimum.patch && \ - patch -p1 < $($(package)_patch_dir)/no_librt.patch -endef - -define $(package)_config_cmds - $($(package)_cmake) -S .. -B . -endef - -define $(package)_build_cmds - $(MAKE) -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install -endef - -define $(package)_postprocess_cmds - rm -rf share && \ - rm -rf lib/pkgconfig -endef diff --git a/depends/patches/expat/cmake_minimum.patch b/depends/patches/expat/cmake_minimum.patch deleted file mode 100644 index a849a82a3375..000000000000 --- a/depends/patches/expat/cmake_minimum.patch +++ /dev/null @@ -1,13 +0,0 @@ -build: set minimum required CMake to 3.16 - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -33,7 +33,7 @@ - # Unlike most of Expat, - # this file is copyrighted under the BSD-license for buildsystem files of KDE. - --cmake_minimum_required(VERSION 3.1.3) -+cmake_minimum_required(VERSION 3.16) - - # This allows controlling documented build time switches - # when Expat is pulled in using the add_subdirectory function, e.g. diff --git a/depends/patches/fontconfig/gperf_header_regen.patch b/depends/patches/fontconfig/gperf_header_regen.patch deleted file mode 100644 index b1a70d5fb12c..000000000000 --- a/depends/patches/fontconfig/gperf_header_regen.patch +++ /dev/null @@ -1,24 +0,0 @@ -commit 7b6eb33ecd88768b28c67ce5d2d68a7eed5936b6 -Author: fanquake -Date: Tue Aug 25 14:34:53 2020 +0800 - - Remove rule that causes inadvertent header regeneration - - Otherwise the makefile will needlessly attempt to re-generate the - headers with gperf. This can be dropped once the upstream build is fixed. - - See #10851. - -diff --git a/src/Makefile.in b/src/Makefile.in -index f4626ad..4ae1b00 100644 ---- a/src/Makefile.in -+++ b/src/Makefile.in -@@ -912,7 +912,7 @@ - ' - > $@.tmp && \ - mv -f $@.tmp fcobjshash.gperf && touch $@ || ( $(RM) $@.tmp && false ) - --fcobjshash.h: Makefile fcobjshash.gperf -+fcobjshash.h: - $(AM_V_GEN) $(GPERF) --pic -m 100 fcobjshash.gperf > $@.tmp && \ - mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) - diff --git a/depends/patches/freetype/cmake_minimum.patch b/depends/patches/freetype/cmake_minimum.patch deleted file mode 100644 index 0a976f8ab8d9..000000000000 --- a/depends/patches/freetype/cmake_minimum.patch +++ /dev/null @@ -1,13 +0,0 @@ -build: set minimum required CMake to 3.12 - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -97,7 +97,7 @@ - # FreeType explicitly marks the API to be exported and relies on the compiler - # to hide all other symbols. CMake supports a C_VISBILITY_PRESET property - # starting with 2.8.12. --cmake_minimum_required(VERSION 2.8.12) -+cmake_minimum_required(VERSION 3.12) - - if (NOT CMAKE_VERSION VERSION_LESS 3.3) - # Allow symbol visibility settings also on static libraries. CMake < 3.3 diff --git a/depends/patches/libevent/cmake_fixups.patch b/depends/patches/libevent/cmake_fixups.patch deleted file mode 100644 index a8812afd1e1b..000000000000 --- a/depends/patches/libevent/cmake_fixups.patch +++ /dev/null @@ -1,13 +0,0 @@ -cmake: set minimum version to 3.5 - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -19,7 +19,7 @@ - # start libevent.sln - # - --cmake_minimum_required(VERSION 3.1 FATAL_ERROR) -+cmake_minimum_required(VERSION 3.5 FATAL_ERROR) - - if (POLICY CMP0054) - cmake_policy(SET CMP0054 NEW) diff --git a/depends/patches/libevent/netbsd_fixup.patch b/depends/patches/libevent/netbsd_fixup.patch deleted file mode 100644 index 21d96aaf452c..000000000000 --- a/depends/patches/libevent/netbsd_fixup.patch +++ /dev/null @@ -1,23 +0,0 @@ -Improve portability on NetBSD - -According to GCC documentation, "the various `-std` options disable -certain keywords". -This change adheres to GCC's recommendation by replacing the `typeof` -keyword with its alternative, `__typeof__`. - -See https://github.com/libevent/libevent/commit/1759485e9a59147a47a674f5132fcfe764e7748c. - - ---- a/kqueue.c -+++ b/kqueue.c -@@ -52,8 +52,8 @@ - * intptr_t, whereas others define it as void*. There doesn't seem to be an - * easy way to tell them apart via autoconf, so we need to use OS macros. */ - #if defined(__NetBSD__) --#define PTR_TO_UDATA(x) ((typeof(((struct kevent *)0)->udata))(x)) --#define INT_TO_UDATA(x) ((typeof(((struct kevent *)0)->udata))(intptr_t)(x)) -+#define PTR_TO_UDATA(x) ((__typeof__(((struct kevent *)0)->udata))(x)) -+#define INT_TO_UDATA(x) ((__typeof__(((struct kevent *)0)->udata))(intptr_t)(x)) - #elif defined(EVENT__HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__) && !defined(__CloudABI__) - #define PTR_TO_UDATA(x) ((intptr_t)(x)) - #define INT_TO_UDATA(x) ((intptr_t)(x)) diff --git a/depends/patches/libevent/winver_fixup.patch b/depends/patches/libevent/winver_fixup.patch deleted file mode 100644 index 4995c356f942..000000000000 --- a/depends/patches/libevent/winver_fixup.patch +++ /dev/null @@ -1,122 +0,0 @@ -Cherry-picked from a14ff91254f40cf36e0fee199e26fb11260fab49. - -move _WIN32_WINNT defintions before first #include - -_WIN32_WINNT and WIN32_LEAN_AND_MEAN need to be defined -before the windows.h is included for the first time. -Avoid the confusion of indirect #include by defining -before any. - -diff --git a/event_iocp.c b/event_iocp.c -index 6b2a2e15..4955e426 100644 ---- a/event_iocp.c -+++ b/event_iocp.c -@@ -23,12 +23,14 @@ - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ --#include "evconfig-private.h" - - #ifndef _WIN32_WINNT - /* Minimum required for InitializeCriticalSectionAndSpinCount */ - #define _WIN32_WINNT 0x0403 - #endif -+ -+#include "evconfig-private.h" -+ - #include - #include - #include -diff --git a/evthread_win32.c b/evthread_win32.c -index 2ec80560..8647f72b 100644 ---- a/evthread_win32.c -+++ b/evthread_win32.c -@@ -23,18 +23,21 @@ - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ --#include "event2/event-config.h" --#include "evconfig-private.h" - - #ifdef _WIN32 - #ifndef _WIN32_WINNT - /* Minimum required for InitializeCriticalSectionAndSpinCount */ - #define _WIN32_WINNT 0x0403 - #endif --#include - #define WIN32_LEAN_AND_MEAN -+#endif -+ -+#include "event2/event-config.h" -+#include "evconfig-private.h" -+ -+#ifdef _WIN32 -+#include - #include --#undef WIN32_LEAN_AND_MEAN - #include - #endif - -diff --git a/evutil.c b/evutil.c -index 9817f086..8537ffe8 100644 ---- a/evutil.c -+++ b/evutil.c -@@ -24,6 +24,14 @@ - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -+#ifdef _WIN32 -+#ifndef _WIN32_WINNT -+/* For structs needed by GetAdaptersAddresses */ -+#define _WIN32_WINNT 0x0501 -+#endif -+#define WIN32_LEAN_AND_MEAN -+#endif -+ - #include "event2/event-config.h" - #include "evconfig-private.h" - -@@ -31,15 +39,10 @@ - #include - #include - #include --#define WIN32_LEAN_AND_MEAN - #include --#undef WIN32_LEAN_AND_MEAN - #include - #include - #include --#undef _WIN32_WINNT --/* For structs needed by GetAdaptersAddresses */ --#define _WIN32_WINNT 0x0501 - #include - #include - #endif -diff --git a/listener.c b/listener.c -index f5c00c9c..d1080e76 100644 ---- a/listener.c -+++ b/listener.c -@@ -24,16 +24,19 @@ - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -+#ifdef _WIN32 -+#ifndef _WIN32_WINNT -+/* Minimum required for InitializeCriticalSectionAndSpinCount */ -+#define _WIN32_WINNT 0x0403 -+#endif -+#endif -+ - #include "event2/event-config.h" - #include "evconfig-private.h" - - #include - - #ifdef _WIN32 --#ifndef _WIN32_WINNT --/* Minimum required for InitializeCriticalSectionAndSpinCount */ --#define _WIN32_WINNT 0x0403 --#endif - #include - #include - #include diff --git a/depends/patches/libxcb/remove_pthread_stubs.patch b/depends/patches/libxcb/remove_pthread_stubs.patch deleted file mode 100644 index 1f32dea527e2..000000000000 --- a/depends/patches/libxcb/remove_pthread_stubs.patch +++ /dev/null @@ -1,12 +0,0 @@ -Remove uneeded pthread-stubs dependency ---- a/configure -+++ b/configure -@@ -19695,7 +19695,7 @@ fi - NEEDED="xau >= 0.99.2" - case $host_os in - linux*) ;; -- *) NEEDED="$NEEDED pthread-stubs" ;; -+ *) NEEDED="$NEEDED" ;; - esac - - pkg_failed=no diff --git a/depends/patches/qrencode/cmake_fixups.patch b/depends/patches/qrencode/cmake_fixups.patch deleted file mode 100644 index 7518d756cb28..000000000000 --- a/depends/patches/qrencode/cmake_fixups.patch +++ /dev/null @@ -1,23 +0,0 @@ -cmake: set minimum version to 3.5 - -Correct some dev warning output. - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 773e037..a558145 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -1,4 +1,4 @@ --cmake_minimum_required(VERSION 3.1.0) -+cmake_minimum_required(VERSION 3.5) - - project(QRencode VERSION 4.1.1 LANGUAGES C) - -@@ -20,7 +20,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - set(CMAKE_THREAD_PREFER_PTHREAD ON) - find_package(Threads) - find_package(PNG) --find_package(Iconv) -+find_package(ICONV) - - if(CMAKE_USE_PTHREADS_INIT) - add_definitions(-DHAVE_LIBPTHREAD=1) diff --git a/depends/patches/qt/dont_hardcode_pwd.patch b/depends/patches/qt/dont_hardcode_pwd.patch deleted file mode 100644 index 217b6bec15b2..000000000000 --- a/depends/patches/qt/dont_hardcode_pwd.patch +++ /dev/null @@ -1,51 +0,0 @@ -Do not assume FHS in scripts - -On systems that do not follow the Filesystem Hierarchy Standard, such as -guix, the hardcoded `/bin/pwd` will fail to be found so that the script -will fail. - -Use `pwd`, instead, so that the command can be found through the normal -path search mechanism. - -See https://github.com/qt/qtbase/commit/3388de698bfb9bbc456c08f03e83bf3e749df35c. - -diff --git a/qtbase/configure b/qtbase/configure -index 08b49a8d..faea5b55 100755 ---- a/qtbase/configure -+++ b/qtbase/configure -@@ -9,9 +9,9 @@ - - # the directory of this script is the "source tree" - relpath=`dirname "$0"` --relpath=`(cd "$relpath"; /bin/pwd)` -+relpath=`(cd "$relpath"; pwd)` - # the current directory is the "build tree" or "object tree" --outpath=`/bin/pwd` -+outpath=`pwd` - outpathPrefix=$outpath - - # do this early so we don't store it in config.status - ---- a/qtbase/bin/qt-cmake.in -+++ b/qtbase/bin/qt-cmake.in -@@ -2,7 +2,7 @@ - - # The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory. - script_dir_path=`dirname $0` --script_dir_path=`(cd "$script_dir_path"; /bin/pwd)` -+script_dir_path=`(cd "$script_dir_path"; pwd)` - - # Try to use original cmake, otherwise to make it relocatable, use any cmake found in PATH. - original_cmake_path="@CMAKE_COMMAND@" - ---- a/qtbase/bin/qt-configure-module.in -+++ b/qtbase/bin/qt-configure-module.in -@@ -2,7 +2,7 @@ - set -eu - - script_dir_path=`dirname $0` --script_dir_path=`(cd "$script_dir_path"; /bin/pwd)` -+script_dir_path=`(cd "$script_dir_path"; pwd)` - - printUsage() - { diff --git a/depends/patches/qt/memory_resource.patch b/depends/patches/qt/memory_resource.patch deleted file mode 100644 index 14e25121c00a..000000000000 --- a/depends/patches/qt/memory_resource.patch +++ /dev/null @@ -1,16 +0,0 @@ -Fix unusable memory_resource on macos - -See https://bugreports.qt.io/browse/QTBUG-117484 -and https://bugreports.qt.io/browse/QTBUG-114316 - ---- a/qtbase/src/corelib/tools/qduplicatetracker_p.h -+++ b/qtbase/src/corelib/tools/qduplicatetracker_p.h -@@ -52,7 +52,7 @@ - - #include - --#if QT_HAS_INCLUDE() && __cplusplus > 201402L -+#ifdef __cpp_lib_memory_resource - # include - # include - #else diff --git a/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch b/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch deleted file mode 100644 index e5e7b126f628..000000000000 --- a/depends/patches/qt/qtbase-moc-ignore-gcc-macro.patch +++ /dev/null @@ -1,17 +0,0 @@ -The moc executable loops through headers on CPLUS_INCLUDE_PATH and stumbles -on the GCC internal _GLIBCXX_VISIBILITY macro. Tell it to ignore it as it is -not supposed to be looking there to begin with. - -Upstream report: https://bugreports.qt.io/browse/QTBUG-83160 - -diff --git a/qtbase/src/tools/moc/main.cpp b/qtbase/src/tools/moc/main.cpp ---- a/qtbase/src/tools/moc/main.cpp -+++ b/qtbase/src/tools/moc/main.cpp -@@ -186,6 +186,7 @@ int runMoc(int argc, char **argv) - dummyVariadicFunctionMacro.arguments += Symbol(0, PP_IDENTIFIER, "__VA_ARGS__"); - pp.macros["__attribute__"] = dummyVariadicFunctionMacro; - pp.macros["__declspec"] = dummyVariadicFunctionMacro; -+ pp.macros["_GLIBCXX_VISIBILITY"] = dummyVariadicFunctionMacro; - - QString filename; - QString output; diff --git a/depends/patches/qt/qtbase_avoid_native_float16.patch b/depends/patches/qt/qtbase_avoid_native_float16.patch deleted file mode 100644 index ec03d140e3f3..000000000000 --- a/depends/patches/qt/qtbase_avoid_native_float16.patch +++ /dev/null @@ -1,37 +0,0 @@ -Avoid using native float16 types in Qt's qfloat16 - -Using native float16 types may introduce compatibility issues -in release binaries for Linux platforms. - -See: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=e42d2d2a20f2bb59928bc895ec9f46503a1b5c73 - -This patch can be dropped once the minimum required libgcc version -is updated to 12.x or newer. - - ---- a/qtbase/src/corelib/global/qtypes.h -+++ b/qtbase/src/corelib/global/qtypes.h -@@ -258,23 +258,8 @@ using qsizetype = QIntegerForSizeof::Signed; - - // Define a native float16 type - namespace QtPrivate { --#if defined(__STDCPP_FLOAT16_T__) --# define QFLOAT16_IS_NATIVE 1 --using NativeFloat16Type = std::float16_t; --#elif defined(Q_CC_CLANG) && defined(__FLT16_MAX__) && 0 --// disabled due to https://github.com/llvm/llvm-project/issues/56963 --# define QFLOAT16_IS_NATIVE 1 --using NativeFloat16Type = decltype(__FLT16_MAX__); --#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) && defined(__ARM_FP16_FORMAT_IEEE) --# define QFLOAT16_IS_NATIVE 1 --using NativeFloat16Type = __fp16; --#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) && defined(__SSE2__) --# define QFLOAT16_IS_NATIVE 1 --using NativeFloat16Type = _Float16; --#else - # define QFLOAT16_IS_NATIVE 0 - using NativeFloat16Type = void; --#endif - } // QtPrivate - - #endif // __cplusplus diff --git a/depends/patches/qt/qtbase_avoid_qmain.patch b/depends/patches/qt/qtbase_avoid_qmain.patch deleted file mode 100644 index 45a54fe881eb..000000000000 --- a/depends/patches/qt/qtbase_avoid_qmain.patch +++ /dev/null @@ -1,21 +0,0 @@ -Avoid defining QT_NEEDS_QMAIN macro - -Qt's QT_NEEDS_QMAIN macro renames our main() function to qMain(), -which breaks our assumptions regarding exported symbols. In particular, -the CONTROL_FLOW security check fails for Windows builds in Guix. - -The QT_NEEDS_QMAIN macro is required for linking to the Qt DLLs only, -so we can safely disable it. - - ---- a/qtbase/src/entrypoint/CMakeLists.txt -+++ b/qtbase/src/entrypoint/CMakeLists.txt -@@ -104,8 +104,6 @@ if(WIN32) - APPEND PROPERTY INTERFACE_QT_MODULE_LDFLAGS "-lmingw32" - ) - -- target_compile_definitions(EntryPointPrivate INTERFACE QT_NEEDS_QMAIN) -- qt_internal_extend_target(EntryPointImplementation DEFINES QT_NEEDS_QMAIN) - endif() - - qt_internal_add_sync_header_dependencies(EntryPointImplementation Core) diff --git a/depends/patches/qt/qtbase_platformsupport.patch b/depends/patches/qt/qtbase_platformsupport.patch deleted file mode 100644 index 45ccaea53a7d..000000000000 --- a/depends/patches/qt/qtbase_platformsupport.patch +++ /dev/null @@ -1,34 +0,0 @@ -CMake: Prevent creation of empty InputSupportPrivate module - -The combination of - -no-feature-evdev - -no-feature-tslib - -no-feature-libinput -led to the creation of the InputSupportPrivate module without source -files. - -This triggered CMake upstream issue 23464 when using CMake < 3.25. - -Fix this by adjusting the inexact condition that decides whether to -build InputSupportPrivate. - - -See: https://codereview.qt-project.org/c/qt/qtbase/+/633612 - - ---- a/qtbase/src/platformsupport/CMakeLists.txt -+++ b/qtbase/src/platformsupport/CMakeLists.txt -@@ -3,7 +3,12 @@ - - add_subdirectory(devicediscovery) - add_subdirectory(fbconvenience) --if(QT_FEATURE_evdev OR QT_FEATURE_integrityhid OR QT_FEATURE_libinput OR QT_FEATURE_tslib OR QT_FEATURE_xkbcommon) -+if(QT_FEATURE_evdev -+ OR QT_FEATURE_vxworksevdev -+ OR QT_FEATURE_integrityhid -+ OR QT_FEATURE_libinput -+ OR QT_FEATURE_tslib -+ OR (QT_FEATURE_libinput AND QT_FEATURE_xkbcommon)) - add_subdirectory(input) - endif() - if(QT_FEATURE_kms) diff --git a/depends/patches/qt/qtbase_plugins_cocoa.patch b/depends/patches/qt/qtbase_plugins_cocoa.patch deleted file mode 100644 index 118a72d66e73..000000000000 --- a/depends/patches/qt/qtbase_plugins_cocoa.patch +++ /dev/null @@ -1,21 +0,0 @@ -CMake: Fix macOS -no-feature-sessionmanager build with CMake < 3.25 - -Work around CMake issue 23464. - - -See: https://codereview.qt-project.org/c/qt/qtbase/+/634002 - - ---- a/qtbase/src/plugins/platforms/cocoa/CMakeLists.txt -+++ b/qtbase/src/plugins/platforms/cocoa/CMakeLists.txt -@@ -102,3 +102,10 @@ qt_internal_extend_target(QCocoaIntegrationPlugin CONDITION QT_FEATURE_sessionma - SOURCES - qcocoasessionmanager.cpp qcocoasessionmanager.h - ) -+ -+# Work around CMake issue 23464 -+if(CMAKE_VERSION VERSION_LESS "3.25" AND NOT QT_FEATURE_sessionmanager) -+ set_target_properties(QCocoaIntegrationPlugin PROPERTIES -+ DISABLE_PRECOMPILE_HEADERS ON -+ ) -+endif() diff --git a/depends/patches/qt/qtbase_skip_tools.patch b/depends/patches/qt/qtbase_skip_tools.patch deleted file mode 100644 index bbd87e8689ff..000000000000 --- a/depends/patches/qt/qtbase_skip_tools.patch +++ /dev/null @@ -1,61 +0,0 @@ -Skip building/installing unneeded tools: - -1. Wrapper CMake scripts. -2. CI support files. -3. tracepointgen and tracegen tools. -4. Qt Look Ahead LR Parser Generator (qlalr). -5. Qt Vulkan Header Generator (qvkgen). - - ---- a/qtbase/cmake/QtBaseGlobalTargets.cmake -+++ b/qtbase/cmake/QtBaseGlobalTargets.cmake -@@ -118,9 +118,6 @@ qt_generate_global_module_pri_file() - qt_generate_global_device_pri_file() - qt_generate_qmake_and_qtpaths_wrapper_for_target() - --# Depends on the global features being evaluated. --qt_internal_create_wrapper_scripts() -- - add_library(Qt::GlobalConfig ALIAS GlobalConfig) - - add_library(GlobalConfigPrivate INTERFACE) - ---- a/qtbase/cmake/QtBaseGlobalTargets.cmake -+++ b/qtbase/cmake/QtBaseGlobalTargets.cmake -@@ -349,12 +349,3 @@ elseif(WASM) - qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" - DESTINATION "${INSTALL_LIBEXECDIR}") - endif() -- --# Install CI support files to libexec. --qt_path_join(__qt_libexec_install_dir "${QT_INSTALL_DIR}" "${INSTALL_LIBEXECDIR}") --qt_copy_or_install(FILES coin/instructions/qmake/ensure_pro_file.cmake -- DESTINATION "${__qt_libexec_install_dir}") --qt_copy_or_install(PROGRAMS "util/testrunner/qt-testrunner.py" -- DESTINATION "${__qt_libexec_install_dir}") --qt_copy_or_install(PROGRAMS "util/testrunner/sanitizer-testrunner.py" -- DESTINATION "${__qt_libexec_install_dir}") - - ---- a/qtbase/src/CMakeLists.txt -+++ b/qtbase/src/CMakeLists.txt -@@ -21,8 +21,6 @@ function(find_or_build_bootstrap_names) - endif() - add_subdirectory(tools/moc) - add_subdirectory(tools/rcc) -- add_subdirectory(tools/tracepointgen) -- add_subdirectory(tools/tracegen) - add_subdirectory(tools/cmake_automoc_parser) - endfunction() - ---- a/qtbase/src/tools/CMakeLists.txt -+++ b/qtbase/src/tools/CMakeLists.txt -@@ -11,8 +11,6 @@ if (QT_FEATURE_dbus) - add_subdirectory(qdbuscpp2xml) - add_subdirectory(qdbusxml2cpp) - endif() --add_subdirectory(qlalr) --add_subdirectory(qvkgen) - if (QT_FEATURE_commandlineparser) - add_subdirectory(qtpaths) - endif() diff --git a/depends/patches/qt/qttools_skip_dependencies.patch b/depends/patches/qt/qttools_skip_dependencies.patch deleted file mode 100644 index 09f66f4497f6..000000000000 --- a/depends/patches/qt/qttools_skip_dependencies.patch +++ /dev/null @@ -1,36 +0,0 @@ -QtTools: Skip unnecessary dependencies: - -1. The LLVM installatiion. -2. Build only required tools. - - ---- a/qttools/configure.cmake -+++ b/qttools/configure.cmake -@@ -17,7 +17,7 @@ - # Presumably because 6.0 ClangConfig.cmake files are not good enough? - # In any case explicitly request a minimum version of 8.x for now, otherwise - # building with CMake will fail at compilation time. --qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang) -+#qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang) - # special case end - - if(TARGET WrapLibClang::WrapLibClang) - ---- a/qttools/src/linguist/CMakeLists.txt -+++ b/qttools/src/linguist/CMakeLists.txt -@@ -9,15 +9,8 @@ if(NOT QT_FEATURE_linguist) - return() - endif() - add_subdirectory(lconvert) --add_subdirectory(lprodump) - add_subdirectory(lrelease) --add_subdirectory(lrelease-pro) - add_subdirectory(lupdate) --add_subdirectory(lupdate-pro) --if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton -- AND QT_FEATURE_png AND QT_FEATURE_printsupport AND TARGET Qt::Widgets) -- add_subdirectory(linguist) --endif() - - # Create a fake module that would emulate the Qt5::LinguistTools CMake Config package - qt_internal_add_module(Linguist diff --git a/depends/patches/qt/rcc_hardcode_timestamp.patch b/depends/patches/qt/rcc_hardcode_timestamp.patch deleted file mode 100644 index e72f4bd037fb..000000000000 --- a/depends/patches/qt/rcc_hardcode_timestamp.patch +++ /dev/null @@ -1,24 +0,0 @@ -Hardcode last modified timestamp in Qt RCC - -This change allows the already built qt package to be reused even with -the SOURCE_DATE_EPOCH variable set, e.g., for Guix builds. - - ---- old/qtbase/src/tools/rcc/rcc.cpp -+++ new/qtbase/src/tools/rcc/rcc.cpp -@@ -201,14 +201,7 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib) - - if (lib.formatVersion() >= 2) { - // last modified time stamp -- const QDateTime lastModified = m_fileInfo.lastModified(QTimeZone::UTC); -- quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0); -- static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong(); -- if (sourceDate != 0) -- lastmod = sourceDate; -- static const quint64 sourceDate2 = 1000 * qgetenv("SOURCE_DATE_EPOCH").toULongLong(); -- if (sourceDate2 != 0) -- lastmod = sourceDate2; -+ quint64 lastmod = quint64(1); - lib.writeNumber8(lastmod); - if (text || pass1) - lib.writeChar('\n'); diff --git a/depends/patches/zeromq/builtin_sha1.patch b/depends/patches/zeromq/builtin_sha1.patch deleted file mode 100644 index 5481c9dbddef..000000000000 --- a/depends/patches/zeromq/builtin_sha1.patch +++ /dev/null @@ -1,17 +0,0 @@ -Don't use builtin sha1 if not using ws - -The builtin SHA1 (ZMQ_USE_BUILTIN_SHA1) is only used in the websocket -engine (ws_engine.cpp). -Upstreamed in https://github.com/zeromq/libzmq/pull/4670. - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -234,7 +234,7 @@ if(NOT ZMQ_USE_GNUTLS) - endif() - endif() - endif() -- if(NOT ZMQ_USE_NSS) -+ if(ENABLE_WS AND NOT ZMQ_USE_NSS) - list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/external/sha1/sha1.c - ${CMAKE_CURRENT_SOURCE_DIR}/external/sha1/sha1.h) - message(STATUS "Using builtin sha1") diff --git a/depends/patches/zeromq/cacheline_undefined.patch b/depends/patches/zeromq/cacheline_undefined.patch deleted file mode 100644 index 02bd2a5fe5d5..000000000000 --- a/depends/patches/zeromq/cacheline_undefined.patch +++ /dev/null @@ -1,15 +0,0 @@ -Use proper STREQUAL instead of EQUAL to compare strings.txt - -See: https://github.com/zeromq/libzmq/pull/4711. - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -476,7 +476,7 @@ execute_process( - if(CACHELINE_SIZE STREQUAL "" - OR CACHELINE_SIZE EQUAL 0 - OR CACHELINE_SIZE EQUAL -1 -- OR CACHELINE_SIZE EQUAL "undefined") -+ OR CACHELINE_SIZE STREQUAL "undefined") - set(ZMQ_CACHELINE_SIZE 64) - else() - set(ZMQ_CACHELINE_SIZE ${CACHELINE_SIZE}) diff --git a/depends/patches/zeromq/cmake_minimum.patch b/depends/patches/zeromq/cmake_minimum.patch deleted file mode 100644 index d6b6b5fae7ba..000000000000 --- a/depends/patches/zeromq/cmake_minimum.patch +++ /dev/null @@ -1,18 +0,0 @@ -Set a more sane cmake_minimum_required. - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -1,12 +1,7 @@ - # CMake build script for ZeroMQ -+cmake_minimum_required(VERSION 3.16) - project(ZeroMQ) - --if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) -- cmake_minimum_required(VERSION 3.0.2) --else() -- cmake_minimum_required(VERSION 2.8.12) --endif() -- - include(CheckIncludeFiles) - include(CheckCCompilerFlag) - include(CheckCXXCompilerFlag) diff --git a/depends/patches/zeromq/fix_have_windows.patch b/depends/patches/zeromq/fix_have_windows.patch deleted file mode 100644 index e77ef31adfae..000000000000 --- a/depends/patches/zeromq/fix_have_windows.patch +++ /dev/null @@ -1,54 +0,0 @@ -This fixes several instances where _MSC_VER was -used to determine whether to use afunix.h or not. - -See https://github.com/zeromq/libzmq/pull/4678. ---- a/src/ipc_address.hpp -+++ b/src/ipc_address.hpp -@@ -7,7 +7,7 @@ - - #include - --#if defined _MSC_VER -+#if defined ZMQ_HAVE_WINDOWS - #include - #else - #include -diff --git a/src/ipc_connecter.cpp b/src/ipc_connecter.cpp -index 3f988745..ed2a0645 100644 ---- a/src/ipc_connecter.cpp -+++ b/src/ipc_connecter.cpp -@@ -16,7 +16,7 @@ - #include "ipc_address.hpp" - #include "session_base.hpp" - --#ifdef _MSC_VER -+#if defined ZMQ_HAVE_WINDOWS - #include - #else - #include -diff --git a/src/ipc_listener.cpp b/src/ipc_listener.cpp -index 50126040..5428579b 100644 ---- a/src/ipc_listener.cpp -+++ b/src/ipc_listener.cpp -@@ -17,7 +17,7 @@ - #include "socket_base.hpp" - #include "address.hpp" - --#ifdef _MSC_VER -+#ifdef ZMQ_HAVE_WINDOWS - #ifdef ZMQ_IOTHREAD_POLLER_USE_SELECT - #error On Windows, IPC does not work with POLLER=select, use POLLER=epoll instead, or disable IPC transport - #endif -diff --git a/tests/testutil.cpp b/tests/testutil.cpp -index bdc80283..6f21e8f6 100644 ---- a/tests/testutil.cpp -+++ b/tests/testutil.cpp -@@ -7,7 +7,7 @@ - - #if defined _WIN32 - #include "../src/windows.hpp" --#if defined _MSC_VER -+#if defined ZMQ_HAVE_WINDOWS - #if defined ZMQ_HAVE_IPC - #include - #include diff --git a/depends/patches/zeromq/macos_mktemp_check.patch b/depends/patches/zeromq/macos_mktemp_check.patch deleted file mode 100644 index c703abcd718e..000000000000 --- a/depends/patches/zeromq/macos_mktemp_check.patch +++ /dev/null @@ -1,16 +0,0 @@ -build: fix mkdtemp check on macOS - -On macOS, mkdtemp is in unistd.h. Fix the CMake check so that is works. -Upstreamed in https://github.com/zeromq/libzmq/pull/4668. - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -599,7 +599,7 @@ if(NOT MSVC) - - check_cxx_symbol_exists(fork unistd.h HAVE_FORK) - check_cxx_symbol_exists(gethrtime sys/time.h HAVE_GETHRTIME) -- check_cxx_symbol_exists(mkdtemp stdlib.h HAVE_MKDTEMP) -+ check_cxx_symbol_exists(mkdtemp "stdlib.h;unistd.h" HAVE_MKDTEMP) - check_cxx_symbol_exists(accept4 sys/socket.h HAVE_ACCEPT4) - check_cxx_symbol_exists(strnlen string.h HAVE_STRNLEN) - else() diff --git a/depends/patches/zeromq/no_librt.patch b/depends/patches/zeromq/no_librt.patch deleted file mode 100644 index b63854c95b28..000000000000 --- a/depends/patches/zeromq/no_librt.patch +++ /dev/null @@ -1,54 +0,0 @@ -We don't use librt, so don't try and link against it. - -Related to: https://github.com/zeromq/libzmq/pull/4702. - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 03462271..87ceab3c 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -564,13 +564,6 @@ else() - check_cxx_symbol_exists(SO_BUSY_POLL sys/socket.h ZMQ_HAVE_BUSY_POLL) - endif() - --if(NOT MINGW) -- find_library(RT_LIBRARY rt) -- if(RT_LIBRARY) -- set(pkg_config_libs_private "${pkg_config_libs_private} -lrt") -- endif() --endif() -- - find_package(Threads) - - if(WIN32 AND NOT CYGWIN) -@@ -588,9 +581,7 @@ if(WIN32 AND NOT CYGWIN) - endif() - - if(NOT MSVC) -- set(CMAKE_REQUIRED_LIBRARIES rt) - check_cxx_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME) -- set(CMAKE_REQUIRED_LIBRARIES) - - check_cxx_symbol_exists(fork unistd.h HAVE_FORK) - check_cxx_symbol_exists(gethrtime sys/time.h HAVE_GETHRTIME) -@@ -1503,10 +1494,6 @@ if(BUILD_SHARED) - target_link_libraries(libzmq iphlpapi) - endif() - -- if(RT_LIBRARY) -- target_link_libraries(libzmq -lrt) -- endif() -- - if(norm_FOUND) - target_link_libraries(libzmq norm::norm) - endif() -@@ -1553,10 +1540,6 @@ if(BUILD_STATIC) - target_link_libraries(libzmq-static iphlpapi) - endif() - -- if(RT_LIBRARY) -- target_link_libraries(libzmq-static -lrt) -- endif() -- - if(CMAKE_SYSTEM_NAME MATCHES "QNX") - add_definitions(-DUNITY_EXCLUDE_MATH_H) - endif() diff --git a/depends/patches/zeromq/openbsd_kqueue_headers.patch b/depends/patches/zeromq/openbsd_kqueue_headers.patch deleted file mode 100644 index 7000e209fe46..000000000000 --- a/depends/patches/zeromq/openbsd_kqueue_headers.patch +++ /dev/null @@ -1,24 +0,0 @@ -commit ff231d267370493814f933d151441866bf1e200b -Author: Min RK -Date: Fri Feb 23 13:21:08 2024 +0100 - - Problem: cmake search for kqueue missing headers - - Solution: include sys/types.h and sys/time.h as documented by kqueue - and used in autotools - - fixes kqueue detection on openbsd - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index f956f3fd..814d5d46 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -380,7 +380,7 @@ endif(WIN32) - - if(NOT MSVC) - if(POLLER STREQUAL "") -- check_cxx_symbol_exists(kqueue sys/event.h HAVE_KQUEUE) -+ check_cxx_symbol_exists(kqueue "sys/types.h;sys/event.h;sys/time.h" HAVE_KQUEUE) - if(HAVE_KQUEUE) - set(POLLER "kqueue") - endif() diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in index 46b84a689ade..c6910942cb07 100644 --- a/depends/toolchain.cmake.in +++ b/depends/toolchain.cmake.in @@ -90,7 +90,6 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(QT_TRANSLATIONS_DIR "${CMAKE_CURRENT_LIST_DIR}/translations") # The following is only necessary when using cmake from Nix or NixOS, because # Nix patches cmake to remove the root directory `/` from @@ -134,30 +133,6 @@ endif() # The depends/Makefile can generate values with "not-set" # semantics as empty strings or strings containing only spaces. # Therefore, MATCHES must be used rather than STREQUAL. -if("@qt_packages@" MATCHES "^[ ]*$") - set(BUILD_GUI OFF CACHE BOOL "") -else() - set(BUILD_GUI ON CACHE BOOL "") - set(Qt6_ROOT "${CMAKE_CURRENT_LIST_DIR}" CACHE PATH "") -endif() - -if("@qrencode_packages@" MATCHES "^[ ]*$") - set(WITH_QRENCODE OFF CACHE BOOL "") -else() - set(WITH_QRENCODE ON CACHE BOOL "") -endif() - -if("@zmq_packages@" MATCHES "^[ ]*$") - set(WITH_ZMQ OFF CACHE BOOL "") -else() - set(WITH_ZMQ ON CACHE BOOL "") -endif() - -if("@wallet_packages@" MATCHES "^[ ]*$") - set(ENABLE_WALLET OFF CACHE BOOL "") -else() - set(ENABLE_WALLET ON CACHE BOOL "") -endif() if("@usdt_packages@" MATCHES "^[ ]*$") set(WITH_USDT OFF CACHE BOOL "") @@ -166,12 +141,6 @@ else() endif() set(ipc_packages @ipc_packages@) -if("${ipc_packages}" STREQUAL "") - set(ENABLE_IPC OFF CACHE BOOL "") - set(WITH_SV2 OFF CACHE BOOL "") -else() - set(ENABLE_IPC ON CACHE BOOL "") - set(MPGEN_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/native/bin/mpgen" CACHE FILEPATH "") - set(CAPNP_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/native/bin/capnp" CACHE FILEPATH "") - set(CAPNPC_CXX_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/native/bin/capnpc-c++" CACHE FILEPATH "") -endif() +set(MPGEN_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/native/bin/mpgen" CACHE FILEPATH "") +set(CAPNP_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/native/bin/capnp" CACHE FILEPATH "") +set(CAPNPC_CXX_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/native/bin/capnpc-c++" CACHE FILEPATH "") diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index cbbb6551f1b4..365c3c463be4 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "Bitcoin Core" +PROJECT_NAME = "Sv2 Template Provider" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -189,14 +189,6 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is @@ -1341,69 +1333,6 @@ BINARY_TOC = NO TOC_EXPAND = NO -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in @@ -2071,7 +2000,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = ENABLE_EXTERNAL_SIGNER +PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/doc/JSON-RPC-interface.md b/doc/JSON-RPC-interface.md deleted file mode 100644 index e7f085a377ab..000000000000 --- a/doc/JSON-RPC-interface.md +++ /dev/null @@ -1,216 +0,0 @@ -# JSON-RPC Interface - -The headless daemon `bitcoind` has the JSON-RPC API enabled by default, the GUI -`bitcoin-qt` has it disabled by default. This can be changed with the `-server` -option. In the GUI it is possible to execute RPC methods in the Debug Console -Dialog. - -## Endpoints - -There are two JSON-RPC endpoints on the server: - -1. `/` -2. `/wallet//` - -### `/` endpoint - -This endpoint is always active. -It can always service non-wallet requests and can service wallet requests when -exactly one wallet is loaded. - -### `/wallet//` endpoint - -This endpoint is only activated when the wallet component has been compiled in. -It can service both wallet and non-wallet requests. -It MUST be used for wallet requests when two or more wallets are loaded. - -This is the endpoint used by bitcoin-cli when a `-rpcwallet=` parameter is passed in. - -Best practice would dictate using the `/wallet//` endpoint for ALL -requests when multiple wallets are in use. - -### Examples - -```sh -# Get block count from the / endpoint when rpcuser=alice and rpcport=38332 -$ curl --user alice --data-binary '{"jsonrpc": "2.0", "id": "0", "method": "getblockcount", "params": []}' -H 'content-type: application/json' localhost:38332/ - -# Get balance from the /wallet/walletname endpoint when rpcuser=alice, rpcport=38332 and rpcwallet=desc-wallet -$ curl --user alice --data-binary '{"jsonrpc": "2.0", "id": "0", "method": "getbalance", "params": []}' -H 'content-type: application/json' localhost:38332/wallet/desc-wallet - -``` - -## Parameter passing - -The JSON-RPC server supports both _by-position_ and _by-name_ [parameter -structures](https://www.jsonrpc.org/specification#parameter_structures) -described in the JSON-RPC specification. For extra convenience, to avoid the -need to name every parameter value, all RPC methods accept a named parameter -called `args`, which can be set to an array of initial positional values that -are combined with named values. - -Examples: - -```sh -# "params": ["mywallet", false, false, "", false, false, true] -bitcoin-cli createwallet mywallet false false "" false false true - -# "params": {"wallet_name": "mywallet", "load_on_startup": true} -bitcoin-cli -named createwallet wallet_name=mywallet load_on_startup=true - -# "params": {"args": ["mywallet"], "load_on_startup": true} -bitcoin-cli -named createwallet mywallet load_on_startup=true -``` - -`bitcoin rpc` can also be substituted for `bitcoin-cli -named`, and is a newer alternative. - -## Versioning - -The RPC interface might change from one major version of Bitcoin Core to the -next. This makes the RPC interface implicitly versioned on the major version. -The version tuple can be retrieved by e.g. the `getnetworkinfo` RPC in -`version`. - -Usually deprecated features can be re-enabled during the grace-period of one -major version via the `-deprecatedrpc=` command line option. The release notes -of a new major release come with detailed instructions on what RPC features -were deprecated and how to re-enable them temporarily. - -## JSON-RPC 1.1 vs 2.0 - -The server recognizes [JSON-RPC v2.0](https://www.jsonrpc.org/specification) requests -and responds accordingly. A 2.0 request is identified by the presence of -`"jsonrpc": "2.0"` in the request body. If that key + value is not present in a request, -the legacy JSON-RPC v1.1 protocol is followed instead, which was the only available -protocol in v27.0 and prior releases. - -|| 1.1 | 2.0 | -|-|-|-| -| Request marker | `"version": "1.1"` (or none) | `"jsonrpc": "2.0"` | -| Response marker | (none) | `"jsonrpc": "2.0"` | -| `"error"` and `"result"` fields in response | both present | only one is present | -| HTTP codes in response | `200` unless there is any kind of RPC error (invalid parameters, method not found, etc) | Always `200` unless there is an actual HTTP server error (request parsing error, endpoint not found, etc) | -| Notifications: requests that get no reply | (not supported) | Supported for requests that exclude the "id" field. Returns HTTP status `204` "No Content" | - -## Security - -The RPC interface allows other programs to control Bitcoin Core, -including the ability to spend funds from your wallets, affect consensus -verification, read private data, and otherwise perform operations that -can cause loss of money, data, or privacy. This section suggests how -you should use and configure Bitcoin Core to reduce the risk that its -RPC interface will be abused. - -- **Securing the executable:** Anyone with physical or remote access to - the computer, container, or virtual machine running Bitcoin Core can - compromise either the whole program or just the RPC interface. This - includes being able to record any passphrases you enter for unlocking - your encrypted wallets or changing settings so that your Bitcoin Core - program tells you that certain transactions have multiple - confirmations even when they aren't part of the best block chain. For - this reason, you should not use Bitcoin Core for security sensitive - operations on systems you do not exclusively control, such as shared - computers or virtual private servers. - -- **Securing local network access:** By default, the RPC interface can - only be accessed by a client running on the same computer and only - after the client provides a valid authentication credential (username - and passphrase). Any program on your computer with access to the file - system and local network can obtain this level of access. - Additionally, other programs on your computer can attempt to provide - an RPC interface on the same port as used by Bitcoin Core in order to - trick you into revealing your authentication credentials. For this - reason, it is important to only use Bitcoin Core for - security-sensitive operations on a computer whose other programs you - trust. - -- **Securing remote network access:** You may optionally allow other - computers to remotely control Bitcoin Core by setting the `rpcallowip` - and `rpcbind` configuration parameters. These settings are only meant - for enabling connections over secure private networks or connections - that have been otherwise secured (e.g. using a VPN or port forwarding - with SSH or stunnel). **Do not enable RPC connections over the public - Internet.** Although Bitcoin Core's RPC interface does use - authentication, it does not use encryption, so your login credentials - are sent as clear text that can be read by anyone on your network - path. Additionally, the RPC interface has not been hardened to - withstand arbitrary Internet traffic, so changing the above settings - to expose it to the Internet (even using something like a Tor onion - service) could expose you to unconsidered vulnerabilities. See - `bitcoind -help` for more information about these settings and other - settings described in this document. - - Related, if you use Bitcoin Core inside a Docker container, you may - need to expose the RPC port to the host system. The default way to - do this in Docker also exposes the port to the public Internet. - Instead, expose it only on the host system's localhost, for example: - `-p 127.0.0.1:8332:8332` - -- **Secure authentication:** By default, when no `rpcpassword` is specified, Bitcoin Core generates unique - login credentials each time it restarts and puts them into a file - readable only by the user that started Bitcoin Core, allowing any of - that user's RPC clients with read access to the file to login - automatically. The file is `.cookie` in the Bitcoin Core - configuration directory, and using these credentials is the preferred - RPC authentication method. If you need to generate static login - credentials for your programs, you can use the script in the - `share/rpcauth` directory in the Bitcoin Core source tree. As a final - fallback, you can directly use manually-chosen `rpcuser` and - `rpcpassword` configuration parameters---but you must ensure that you - choose a strong and unique passphrase (and still don't use insecure - networks, as mentioned above). - -- **Secure string handling:** The RPC interface does not guarantee any - escaping of data beyond what's necessary to encode it as JSON, - although it does usually provide serialized data using a hex - representation of the bytes. If you use RPC data in your programs or - provide its data to other programs, you must ensure any problem strings - are properly escaped. For example, the `createwallet` RPC accepts - arguments such as `wallet_name` which is a string and could be used - for a path traversal attack without application level checks. Multiple - websites have been manipulated because they displayed decoded hex strings - that included HTML ` - - - -
- - - -)DELIM"; -} - -char const* pyperf() noexcept { - return R"DELIM({ - "benchmarks": [ - { - "runs": [ - { - "values": [ -{{#measurement}} {{elapsed}}{{^-last}}, -{{/last}}{{/measurement}} - ] - } - ] - } - ], - "metadata": { - "loops": {{sum(iterations)}}, - "inner_loops": {{batch}}, - "name": "{{title}}", - "unit": "second" - }, - "version": "1.0" -})DELIM"; -} - -char const* json() noexcept { - return R"DELIM({ - "results": [ -{{#result}} { - "title": "{{title}}", - "name": "{{name}}", - "unit": "{{unit}}", - "batch": {{batch}}, - "complexityN": {{complexityN}}, - "epochs": {{epochs}}, - "clockResolution": {{clockResolution}}, - "clockResolutionMultiple": {{clockResolutionMultiple}}, - "maxEpochTime": {{maxEpochTime}}, - "minEpochTime": {{minEpochTime}}, - "minEpochIterations": {{minEpochIterations}}, - "epochIterations": {{epochIterations}}, - "warmup": {{warmup}}, - "relative": {{relative}}, - "median(elapsed)": {{median(elapsed)}}, - "medianAbsolutePercentError(elapsed)": {{medianAbsolutePercentError(elapsed)}}, - "median(instructions)": {{median(instructions)}}, - "medianAbsolutePercentError(instructions)": {{medianAbsolutePercentError(instructions)}}, - "median(cpucycles)": {{median(cpucycles)}}, - "median(contextswitches)": {{median(contextswitches)}}, - "median(pagefaults)": {{median(pagefaults)}}, - "median(branchinstructions)": {{median(branchinstructions)}}, - "median(branchmisses)": {{median(branchmisses)}}, - "totalTime": {{sumProduct(iterations, elapsed)}}, - "measurements": [ -{{#measurement}} { - "iterations": {{iterations}}, - "elapsed": {{elapsed}}, - "pagefaults": {{pagefaults}}, - "cpucycles": {{cpucycles}}, - "contextswitches": {{contextswitches}}, - "instructions": {{instructions}}, - "branchinstructions": {{branchinstructions}}, - "branchmisses": {{branchmisses}} - }{{^-last}},{{/-last}} -{{/measurement}} ] - }{{^-last}},{{/-last}} -{{/result}} ] -})DELIM"; -} - -ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) -struct Node { - enum class Type { tag, content, section, inverted_section }; - - char const* begin; - char const* end; - std::vector children; - Type type; - - template - // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) - bool operator==(char const (&str)[N]) const noexcept { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay) - return static_cast(std::distance(begin, end) + 1) == N && 0 == strncmp(str, begin, N - 1); - } -}; -ANKERL_NANOBENCH(IGNORE_PADDED_POP) - -// NOLINTNEXTLINE(misc-no-recursion) -static std::vector parseMustacheTemplate(char const** tpl) { - std::vector nodes; - - while (true) { - auto const* begin = std::strstr(*tpl, "{{"); - auto const* end = begin; - if (begin != nullptr) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - begin += 2; - end = std::strstr(begin, "}}"); - } - - if (begin == nullptr || end == nullptr) { - // nothing found, finish node - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - nodes.emplace_back(Node{*tpl, *tpl + std::strlen(*tpl), std::vector{}, Node::Type::content}); - return nodes; - } - - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - nodes.emplace_back(Node{*tpl, begin - 2, std::vector{}, Node::Type::content}); - - // we found a tag - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - *tpl = end + 2; - switch (*begin) { - case '/': - // finished! bail out - return nodes; - - case '#': - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - nodes.emplace_back(Node{begin + 1, end, parseMustacheTemplate(tpl), Node::Type::section}); - break; - - case '^': - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - nodes.emplace_back(Node{begin + 1, end, parseMustacheTemplate(tpl), Node::Type::inverted_section}); - break; - - default: - nodes.emplace_back(Node{begin, end, std::vector{}, Node::Type::tag}); - break; - } - } -} - -static bool generateFirstLast(Node const& n, size_t idx, size_t size, std::ostream& out) { - ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); - bool const matchFirst = n == "-first"; - bool const matchLast = n == "-last"; - if (!matchFirst && !matchLast) { - return false; - } - - bool doWrite = false; - if (n.type == Node::Type::section) { - doWrite = (matchFirst && idx == 0) || (matchLast && idx == size - 1); - } else if (n.type == Node::Type::inverted_section) { - doWrite = (matchFirst && idx != 0) || (matchLast && idx != size - 1); - } - - if (doWrite) { - for (auto const& child : n.children) { - if (child.type == Node::Type::content) { - out.write(child.begin, std::distance(child.begin, child.end)); - } - } - } - return true; -} - -static bool matchCmdArgs(std::string const& str, std::vector& matchResult) { - matchResult.clear(); - auto idxOpen = str.find('('); - auto idxClose = str.find(')', idxOpen); - if (idxClose == std::string::npos) { - return false; - } - - matchResult.emplace_back(str.substr(0, idxOpen)); - - // split by comma - matchResult.emplace_back(); - for (size_t i = idxOpen + 1; i != idxClose; ++i) { - if (str[i] == ' ' || str[i] == '\t') { - // skip whitespace - continue; - } - if (str[i] == ',') { - // got a comma => new string - matchResult.emplace_back(); - continue; - } - // no whitespace no comma, append - matchResult.back() += str[i]; - } - return true; -} - -static bool generateConfigTag(Node const& n, Config const& config, std::ostream& out) { - using detail::d; - - if (n == "title") { - out << config.mBenchmarkTitle; - return true; - } - if (n == "name") { - out << config.mBenchmarkName; - return true; - } - if (n == "unit") { - out << config.mUnit; - return true; - } - if (n == "batch") { - out << config.mBatch; - return true; - } - if (n == "complexityN") { - out << config.mComplexityN; - return true; - } - if (n == "epochs") { - out << config.mNumEpochs; - return true; - } - if (n == "clockResolution") { - out << d(detail::clockResolution()); - return true; - } - if (n == "clockResolutionMultiple") { - out << config.mClockResolutionMultiple; - return true; - } - if (n == "maxEpochTime") { - out << d(config.mMaxEpochTime); - return true; - } - if (n == "minEpochTime") { - out << d(config.mMinEpochTime); - return true; - } - if (n == "minEpochIterations") { - out << config.mMinEpochIterations; - return true; - } - if (n == "epochIterations") { - out << config.mEpochIterations; - return true; - } - if (n == "warmup") { - out << config.mWarmup; - return true; - } - if (n == "relative") { - out << config.mIsRelative; - return true; - } - return false; -} - -// NOLINTNEXTLINE(readability-function-cognitive-complexity) -static std::ostream& generateResultTag(Node const& n, Result const& r, std::ostream& out) { - if (generateConfigTag(n, r.config(), out)) { - return out; - } - // match e.g. "median(elapsed)" - // g++ 4.8 doesn't implement std::regex :( - // static std::regex const regOpArg1("^([a-zA-Z]+)\\(([a-zA-Z]*)\\)$"); - // std::cmatch matchResult; - // if (std::regex_match(n.begin, n.end, matchResult, regOpArg1)) { - std::vector matchResult; - if (matchCmdArgs(std::string(n.begin, n.end), matchResult)) { - if (matchResult.size() == 2) { - if (matchResult[0] == "context") { - return out << r.context(matchResult[1]); - } - - auto m = Result::fromString(matchResult[1]); - if (m == Result::Measure::_size) { - return out << 0.0; - } - - if (matchResult[0] == "median") { - return out << r.median(m); - } - if (matchResult[0] == "average") { - return out << r.average(m); - } - if (matchResult[0] == "medianAbsolutePercentError") { - return out << r.medianAbsolutePercentError(m); - } - if (matchResult[0] == "sum") { - return out << r.sum(m); - } - if (matchResult[0] == "minimum") { - return out << r.minimum(m); - } - if (matchResult[0] == "maximum") { - return out << r.maximum(m); - } - } else if (matchResult.size() == 3) { - auto m1 = Result::fromString(matchResult[1]); - auto m2 = Result::fromString(matchResult[2]); - if (m1 == Result::Measure::_size || m2 == Result::Measure::_size) { - return out << 0.0; - } - - if (matchResult[0] == "sumProduct") { - return out << r.sumProduct(m1, m2); - } - } - } - - // match e.g. "sumProduct(elapsed, iterations)" - // static std::regex const regOpArg2("^([a-zA-Z]+)\\(([a-zA-Z]*)\\s*,\\s+([a-zA-Z]*)\\)$"); - - // nothing matches :( - throw std::runtime_error("command '" + std::string(n.begin, n.end) + "' not understood"); -} - -static void generateResultMeasurement(std::vector const& nodes, size_t idx, Result const& r, std::ostream& out) { - for (auto const& n : nodes) { - if (!generateFirstLast(n, idx, r.size(), out)) { - ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); - switch (n.type) { - case Node::Type::content: - out.write(n.begin, std::distance(n.begin, n.end)); - break; - - case Node::Type::inverted_section: - throw std::runtime_error("got a inverted section inside measurement"); - - case Node::Type::section: - throw std::runtime_error("got a section inside measurement"); - - case Node::Type::tag: { - auto m = Result::fromString(std::string(n.begin, n.end)); - if (m == Result::Measure::_size || !r.has(m)) { - out << 0.0; - } else { - out << r.get(idx, m); - } - break; - } - } - } - } -} - -static void generateResult(std::vector const& nodes, size_t idx, std::vector const& results, std::ostream& out) { - auto const& r = results[idx]; - for (auto const& n : nodes) { - if (!generateFirstLast(n, idx, results.size(), out)) { - ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); - switch (n.type) { - case Node::Type::content: - out.write(n.begin, std::distance(n.begin, n.end)); - break; - - case Node::Type::inverted_section: - throw std::runtime_error("got a inverted section inside result"); - - case Node::Type::section: - if (n == "measurement") { - for (size_t i = 0; i < r.size(); ++i) { - generateResultMeasurement(n.children, i, r, out); - } - } else { - throw std::runtime_error("got a section inside result"); - } - break; - - case Node::Type::tag: - generateResultTag(n, r, out); - break; - } - } - } -} - -} // namespace templates - -// helper stuff that only intended to be used internally -namespace detail { - -char const* getEnv(char const* name); -bool isEndlessRunning(std::string const& name); -bool isWarningsEnabled(); - -template -T parseFile(std::string const& filename, bool* fail); - -void gatherStabilityInformation(std::vector& warnings, std::vector& recommendations); -void printStabilityInformationOnce(std::ostream* outStream); - -// remembers the last table settings used. When it changes, a new table header is automatically written for the new entry. -uint64_t& singletonHeaderHash() noexcept; - -// determines resolution of the given clock. This is done by measuring multiple times and returning the minimum time difference. -Clock::duration calcClockResolution(size_t numEvaluations) noexcept; - -// formatting utilities -namespace fmt { - -// adds thousands separator to numbers -ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) -class NumSep : public std::numpunct { -public: - explicit NumSep(char sep); - char do_thousands_sep() const override; - std::string do_grouping() const override; - -private: - char mSep; -}; -ANKERL_NANOBENCH(IGNORE_PADDED_POP) - -// RAII to save & restore a stream's state -ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) -class StreamStateRestorer { -public: - explicit StreamStateRestorer(std::ostream& s); - ~StreamStateRestorer(); - - // sets back all stream info that we remembered at construction - void restore(); - - // don't allow copying / moving - StreamStateRestorer(StreamStateRestorer const&) = delete; - StreamStateRestorer& operator=(StreamStateRestorer const&) = delete; - StreamStateRestorer(StreamStateRestorer&&) = delete; - StreamStateRestorer& operator=(StreamStateRestorer&&) = delete; - -private: - std::ostream& mStream; - std::locale mLocale; - std::streamsize const mPrecision; - std::streamsize const mWidth; - std::ostream::char_type const mFill; - std::ostream::fmtflags const mFmtFlags; -}; -ANKERL_NANOBENCH(IGNORE_PADDED_POP) - -// Number formatter -class Number { -public: - Number(int width, int precision, double value); - Number(int width, int precision, int64_t value); - ANKERL_NANOBENCH(NODISCARD) std::string to_s() const; - -private: - friend std::ostream& operator<<(std::ostream& os, Number const& n); - std::ostream& write(std::ostream& os) const; - - int mWidth; - int mPrecision; - double mValue; -}; - -// helper replacement for std::to_string of signed/unsigned numbers so we are locale independent -std::string to_s(uint64_t n); - -std::ostream& operator<<(std::ostream& os, Number const& n); - -class MarkDownColumn { -public: - MarkDownColumn(int w, int prec, std::string tit, std::string suff, double val) noexcept; - ANKERL_NANOBENCH(NODISCARD) std::string title() const; - ANKERL_NANOBENCH(NODISCARD) std::string separator() const; - ANKERL_NANOBENCH(NODISCARD) std::string invalid() const; - ANKERL_NANOBENCH(NODISCARD) std::string value() const; - -private: - int mWidth; - int mPrecision; - std::string mTitle; - std::string mSuffix; - double mValue; -}; - -// Formats any text as markdown code, escaping backticks. -class MarkDownCode { -public: - explicit MarkDownCode(std::string const& what); - -private: - friend std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode); - std::ostream& write(std::ostream& os) const; - - std::string mWhat{}; -}; - -std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode); - -} // namespace fmt -} // namespace detail -} // namespace nanobench -} // namespace ankerl - -// implementation ///////////////////////////////////////////////////////////////////////////////// - -namespace ankerl { -namespace nanobench { - -// NOLINTNEXTLINE(readability-function-cognitive-complexity) -void render(char const* mustacheTemplate, std::vector const& results, std::ostream& out) { - detail::fmt::StreamStateRestorer const restorer(out); - - out.precision(std::numeric_limits::digits10); - auto nodes = templates::parseMustacheTemplate(&mustacheTemplate); - - for (auto const& n : nodes) { - ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); - switch (n.type) { - case templates::Node::Type::content: - out.write(n.begin, std::distance(n.begin, n.end)); - break; - - case templates::Node::Type::inverted_section: - throw std::runtime_error("unknown list '" + std::string(n.begin, n.end) + "'"); - - case templates::Node::Type::section: - if (n == "result") { - const size_t nbResults = results.size(); - for (size_t i = 0; i < nbResults; ++i) { - generateResult(n.children, i, results, out); - } - } else if (n == "measurement") { - if (results.size() != 1) { - throw std::runtime_error( - "render: can only use section 'measurement' here if there is a single result, but there are " + - detail::fmt::to_s(results.size())); - } - // when we only have a single result, we can immediately go into its measurement. - auto const& r = results.front(); - for (size_t i = 0; i < r.size(); ++i) { - generateResultMeasurement(n.children, i, r, out); - } - } else { - throw std::runtime_error("render: unknown section '" + std::string(n.begin, n.end) + "'"); - } - break; - - case templates::Node::Type::tag: - if (results.size() == 1) { - // result & config are both supported there - generateResultTag(n, results.front(), out); - } else { - // This just uses the last result's config. - if (!generateConfigTag(n, results.back().config(), out)) { - throw std::runtime_error("unknown tag '" + std::string(n.begin, n.end) + "'"); - } - } - break; - } - } -} - -void render(std::string const& mustacheTemplate, std::vector const& results, std::ostream& out) { - render(mustacheTemplate.c_str(), results, out); -} - -void render(char const* mustacheTemplate, const Bench& bench, std::ostream& out) { - render(mustacheTemplate, bench.results(), out); -} - -void render(std::string const& mustacheTemplate, const Bench& bench, std::ostream& out) { - render(mustacheTemplate.c_str(), bench.results(), out); -} - -namespace detail { - -PerformanceCounters& performanceCounters() { -# if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wexit-time-destructors" -# endif - static PerformanceCounters pc; -# if defined(__clang__) -# pragma clang diagnostic pop -# endif - return pc; -} - -// Windows version of doNotOptimizeAway -// see https://github.com/google/benchmark/blob/v1.7.1/include/benchmark/benchmark.h#L514 -// see https://github.com/facebook/folly/blob/v2023.01.30.00/folly/lang/Hint-inl.h#L54-L58 -// see https://learn.microsoft.com/en-us/cpp/preprocessor/optimize -# if defined(_MSC_VER) -# pragma optimize("", off) -void doNotOptimizeAwaySink(void const*) {} -# pragma optimize("", on) -# endif - -template -T parseFile(std::string const& filename, bool* fail) { - std::ifstream fin(filename); // NOLINT(misc-const-correctness) - T num{}; - fin >> num; - if (fail != nullptr) { - *fail = fin.fail(); - } - return num; -} - -char const* getEnv(char const* name) { -# if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4996) // getenv': This function or variable may be unsafe. -# endif - return std::getenv(name); // NOLINT(concurrency-mt-unsafe) -# if defined(_MSC_VER) -# pragma warning(pop) -# endif -} - -bool isEndlessRunning(std::string const& name) { - auto const* const endless = getEnv("NANOBENCH_ENDLESS"); - return nullptr != endless && endless == name; -} - -// True when environment variable NANOBENCH_SUPPRESS_WARNINGS is either not set at all, or set to "0" -bool isWarningsEnabled() { - auto const* const suppression = getEnv("NANOBENCH_SUPPRESS_WARNINGS"); - return nullptr == suppression || suppression == std::string("0"); -} - -void gatherStabilityInformation(std::vector& warnings, std::vector& recommendations) { - warnings.clear(); - recommendations.clear(); - -# if defined(DEBUG) - warnings.emplace_back("DEBUG defined"); - bool const recommendCheckFlags = true; -# else - bool const recommendCheckFlags = false; -# endif - - bool recommendPyPerf = false; -# if defined(__linux__) - auto nprocs = sysconf(_SC_NPROCESSORS_CONF); - if (nprocs <= 0) { - warnings.emplace_back("couldn't figure out number of processors - no governor, turbo check possible"); - } else { - // check frequency scaling - for (long id = 0; id < nprocs; ++id) { - auto idStr = detail::fmt::to_s(static_cast(id)); - auto sysCpu = "/sys/devices/system/cpu/cpu" + idStr; - auto minFreq = parseFile(sysCpu + "/cpufreq/scaling_min_freq", nullptr); - auto maxFreq = parseFile(sysCpu + "/cpufreq/scaling_max_freq", nullptr); - if (minFreq != maxFreq) { - auto minMHz = d(minFreq) / 1000.0; - auto maxMHz = d(maxFreq) / 1000.0; - warnings.emplace_back("CPU frequency scaling enabled: CPU " + idStr + " between " + - detail::fmt::Number(1, 1, minMHz).to_s() + " and " + detail::fmt::Number(1, 1, maxMHz).to_s() + - " MHz"); - recommendPyPerf = true; - break; - } - } - - auto fail = false; - auto currentGovernor = parseFile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", &fail); - if (!fail && "performance" != currentGovernor) { - warnings.emplace_back("CPU governor is '" + currentGovernor + "' but should be 'performance'"); - recommendPyPerf = true; - } - - auto noTurbo = parseFile("/sys/devices/system/cpu/intel_pstate/no_turbo", &fail); - if (!fail && noTurbo == 0) { - warnings.emplace_back("Turbo is enabled, CPU frequency will fluctuate"); - recommendPyPerf = true; - } - } -# endif - - if (recommendCheckFlags) { - recommendations.emplace_back("Make sure you compile for Release"); - } - if (recommendPyPerf) { - recommendations.emplace_back("Use 'pyperf system tune' before benchmarking. See https://github.com/psf/pyperf"); - } -} - -void printStabilityInformationOnce(std::ostream* outStream) { - static bool shouldPrint = true; - if (shouldPrint && (nullptr != outStream) && isWarningsEnabled()) { - auto& os = *outStream; - shouldPrint = false; - std::vector warnings; - std::vector recommendations; - gatherStabilityInformation(warnings, recommendations); - if (warnings.empty()) { - return; - } - - os << "Warning, results might be unstable:" << std::endl; - for (auto const& w : warnings) { - os << "* " << w << std::endl; - } - - os << std::endl << "Recommendations" << std::endl; - for (auto const& r : recommendations) { - os << "* " << r << std::endl; - } - } -} - -// remembers the last table settings used. When it changes, a new table header is automatically written for the new entry. -uint64_t& singletonHeaderHash() noexcept { - static uint64_t sHeaderHash{}; - return sHeaderHash; -} - -ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") -inline uint64_t hash_combine(uint64_t seed, uint64_t val) { - return seed ^ (val + UINT64_C(0x9e3779b9) + (seed << 6U) + (seed >> 2U)); -} - -// determines resolution of the given clock. This is done by measuring multiple times and returning the minimum time difference. -Clock::duration calcClockResolution(size_t numEvaluations) noexcept { - auto bestDuration = Clock::duration::max(); - Clock::time_point tBegin; - Clock::time_point tEnd; - for (size_t i = 0; i < numEvaluations; ++i) { - tBegin = Clock::now(); - do { - tEnd = Clock::now(); - } while (tBegin == tEnd); - bestDuration = (std::min)(bestDuration, tEnd - tBegin); - } - return bestDuration; -} - -// Calculates clock resolution once, and remembers the result -Clock::duration clockResolution() noexcept { - static Clock::duration const sResolution = calcClockResolution(20); - return sResolution; -} - -ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) -struct IterationLogic::Impl { - enum class State { warmup, upscaling_runtime, measuring, endless }; - - explicit Impl(Bench const& bench) - : mBench(bench) - , mResult(bench.config()) { - printStabilityInformationOnce(mBench.output()); - - // determine target runtime per epoch - mTargetRuntimePerEpoch = detail::clockResolution() * mBench.clockResolutionMultiple(); - if (mTargetRuntimePerEpoch > mBench.maxEpochTime()) { - mTargetRuntimePerEpoch = mBench.maxEpochTime(); - } - if (mTargetRuntimePerEpoch < mBench.minEpochTime()) { - mTargetRuntimePerEpoch = mBench.minEpochTime(); - } - - if (isEndlessRunning(mBench.name())) { - std::cerr << "NANOBENCH_ENDLESS set: running '" << mBench.name() << "' endlessly" << std::endl; - mNumIters = (std::numeric_limits::max)(); - mState = State::endless; - } else if (0 != mBench.warmup()) { - mNumIters = mBench.warmup(); - mState = State::warmup; - } else if (0 != mBench.epochIterations()) { - // exact number of iterations - mNumIters = mBench.epochIterations(); - mState = State::measuring; - } else { - mNumIters = mBench.minEpochIterations(); - mState = State::upscaling_runtime; - } - } - - // directly calculates new iters based on elapsed&iters, and adds a 10% noise. Makes sure we don't underflow. - ANKERL_NANOBENCH(NODISCARD) uint64_t calcBestNumIters(std::chrono::nanoseconds elapsed, uint64_t iters) noexcept { - auto doubleElapsed = d(elapsed); - auto doubleTargetRuntimePerEpoch = d(mTargetRuntimePerEpoch); - auto doubleNewIters = doubleTargetRuntimePerEpoch / doubleElapsed * d(iters); - - auto doubleMinEpochIters = d(mBench.minEpochIterations()); - if (doubleNewIters < doubleMinEpochIters) { - doubleNewIters = doubleMinEpochIters; - } - doubleNewIters *= 1.0 + 0.2 * mRng.uniform01(); - - // +0.5 for correct rounding when casting - // NOLINTNEXTLINE(bugprone-incorrect-roundings) - return static_cast(doubleNewIters + 0.5); - } - - ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") void upscale(std::chrono::nanoseconds elapsed) { - if (elapsed * 10 < mTargetRuntimePerEpoch) { - // we are far below the target runtime. Multiply iterations by 10 (with overflow check) - if (mNumIters * 10 < mNumIters) { - // overflow :-( - showResult("iterations overflow. Maybe your code got optimized away?"); - mNumIters = 0; - return; - } - mNumIters *= 10; - } else { - mNumIters = calcBestNumIters(elapsed, mNumIters); - } - } - - void add(std::chrono::nanoseconds elapsed, PerformanceCounters const& pc) noexcept { -# if defined(ANKERL_NANOBENCH_LOG_ENABLED) - auto oldIters = mNumIters; -# endif - - switch (mState) { - case State::warmup: - if (isCloseEnoughForMeasurements(elapsed)) { - // if elapsed is close enough, we can skip upscaling and go right to measurements - // still, we don't add the result to the measurements. - mState = State::measuring; - mNumIters = calcBestNumIters(elapsed, mNumIters); - } else { - // not close enough: switch to upscaling - mState = State::upscaling_runtime; - upscale(elapsed); - } - break; - - case State::upscaling_runtime: - if (isCloseEnoughForMeasurements(elapsed)) { - // if we are close enough, add measurement and switch to always measuring - mState = State::measuring; - mTotalElapsed += elapsed; - mTotalNumIters += mNumIters; - mResult.add(elapsed, mNumIters, pc); - mNumIters = calcBestNumIters(mTotalElapsed, mTotalNumIters); - } else { - upscale(elapsed); - } - break; - - case State::measuring: - // just add measurements - no questions asked. Even when runtime is low. But we can't ignore - // that fluctuation, or else we would bias the result - mTotalElapsed += elapsed; - mTotalNumIters += mNumIters; - mResult.add(elapsed, mNumIters, pc); - if (0 != mBench.epochIterations()) { - mNumIters = mBench.epochIterations(); - } else { - mNumIters = calcBestNumIters(mTotalElapsed, mTotalNumIters); - } - break; - - case State::endless: - mNumIters = (std::numeric_limits::max)(); - break; - } - - if (static_cast(mResult.size()) == mBench.epochs()) { - // we got all the results that we need, finish it - showResult(""); - mNumIters = 0; - } - - ANKERL_NANOBENCH_LOG(mBench.name() << ": " << detail::fmt::Number(20, 3, d(elapsed.count())) << " elapsed, " - << detail::fmt::Number(20, 3, d(mTargetRuntimePerEpoch.count())) << " target. oldIters=" - << oldIters << ", mNumIters=" << mNumIters << ", mState=" << static_cast(mState)); - } - - // NOLINTNEXTLINE(readability-function-cognitive-complexity) - void showResult(std::string const& errorMessage) const { - ANKERL_NANOBENCH_LOG(errorMessage); - - if (mBench.output() != nullptr) { - // prepare column data /////// - std::vector columns; - - auto rMedian = mResult.median(Result::Measure::elapsed); - - if (mBench.relative()) { - double d = 100.0; - if (!mBench.results().empty()) { - d = rMedian <= 0.0 ? 0.0 : mBench.results().front().median(Result::Measure::elapsed) / rMedian * 100.0; - } - columns.emplace_back(11, 1, "relative", "%", d); - } - - if (mBench.complexityN() > 0) { - columns.emplace_back(14, 0, "complexityN", "", mBench.complexityN()); - } - - columns.emplace_back(22, 2, mBench.timeUnitName() + "/" + mBench.unit(), "", - rMedian / (mBench.timeUnit().count() * mBench.batch())); - columns.emplace_back(22, 2, mBench.unit() + "/s", "", rMedian <= 0.0 ? 0.0 : mBench.batch() / rMedian); - - double const rErrorMedian = mResult.medianAbsolutePercentError(Result::Measure::elapsed); - columns.emplace_back(10, 1, "err%", "%", rErrorMedian * 100.0); - - double rInsMedian = -1.0; - if (mBench.performanceCounters() && mResult.has(Result::Measure::instructions)) { - rInsMedian = mResult.median(Result::Measure::instructions); - columns.emplace_back(18, 2, "ins/" + mBench.unit(), "", rInsMedian / mBench.batch()); - } - - double rCycMedian = -1.0; - if (mBench.performanceCounters() && mResult.has(Result::Measure::cpucycles)) { - rCycMedian = mResult.median(Result::Measure::cpucycles); - columns.emplace_back(18, 2, "cyc/" + mBench.unit(), "", rCycMedian / mBench.batch()); - } - if (rInsMedian > 0.0 && rCycMedian > 0.0) { - columns.emplace_back(9, 3, "IPC", "", rCycMedian <= 0.0 ? 0.0 : rInsMedian / rCycMedian); - } - if (mBench.performanceCounters() && mResult.has(Result::Measure::branchinstructions)) { - double const rBraMedian = mResult.median(Result::Measure::branchinstructions); - columns.emplace_back(17, 2, "bra/" + mBench.unit(), "", rBraMedian / mBench.batch()); - if (mResult.has(Result::Measure::branchmisses)) { - double p = 0.0; - if (rBraMedian >= 1e-9) { - p = 100.0 * mResult.median(Result::Measure::branchmisses) / rBraMedian; - } - columns.emplace_back(10, 1, "miss%", "%", p); - } - } - - columns.emplace_back(12, 2, "total", "", mResult.sumProduct(Result::Measure::iterations, Result::Measure::elapsed)); - - // write everything - auto& os = *mBench.output(); - - // combine all elements that are relevant for printing the header - uint64_t hash = 0; - hash = hash_combine(std::hash{}(mBench.unit()), hash); - hash = hash_combine(std::hash{}(mBench.title()), hash); - hash = hash_combine(std::hash{}(mBench.timeUnitName()), hash); - hash = hash_combine(std::hash{}(mBench.timeUnit().count()), hash); - hash = hash_combine(std::hash{}(mBench.relative()), hash); - hash = hash_combine(std::hash{}(mBench.performanceCounters()), hash); - - if (hash != singletonHeaderHash()) { - singletonHeaderHash() = hash; - - // no result yet, print header - os << std::endl; - for (auto const& col : columns) { - os << col.title(); - } - os << "| " << mBench.title() << std::endl; - - for (auto const& col : columns) { - os << col.separator(); - } - os << "|:" << std::string(mBench.title().size() + 1U, '-') << std::endl; - } - - if (!errorMessage.empty()) { - for (auto const& col : columns) { - os << col.invalid(); - } - os << "| :boom: " << fmt::MarkDownCode(mBench.name()) << " (" << errorMessage << ')' << std::endl; - } else { - for (auto const& col : columns) { - os << col.value(); - } - os << "| "; - auto showUnstable = isWarningsEnabled() && rErrorMedian >= 0.05; - if (showUnstable) { - os << ":wavy_dash: "; - } - os << fmt::MarkDownCode(mBench.name()); - if (showUnstable) { - auto avgIters = d(mTotalNumIters) / d(mBench.epochs()); - // NOLINTNEXTLINE(bugprone-incorrect-roundings) - auto suggestedIters = static_cast(avgIters * 10 + 0.5); - - os << " (Unstable with ~" << detail::fmt::Number(1, 1, avgIters) - << " iters. Increase `minEpochIterations` to e.g. " << suggestedIters << ")"; - } - os << std::endl; - } - } - } - - ANKERL_NANOBENCH(NODISCARD) bool isCloseEnoughForMeasurements(std::chrono::nanoseconds elapsed) const noexcept { - return elapsed * 3 >= mTargetRuntimePerEpoch * 2; - } - - uint64_t mNumIters = 1; // NOLINT(misc-non-private-member-variables-in-classes) - Bench const& mBench; // NOLINT(misc-non-private-member-variables-in-classes) - std::chrono::nanoseconds mTargetRuntimePerEpoch{}; // NOLINT(misc-non-private-member-variables-in-classes) - Result mResult; // NOLINT(misc-non-private-member-variables-in-classes) - Rng mRng{123}; // NOLINT(misc-non-private-member-variables-in-classes) - std::chrono::nanoseconds mTotalElapsed{}; // NOLINT(misc-non-private-member-variables-in-classes) - uint64_t mTotalNumIters = 0; // NOLINT(misc-non-private-member-variables-in-classes) - State mState = State::upscaling_runtime; // NOLINT(misc-non-private-member-variables-in-classes) -}; -ANKERL_NANOBENCH(IGNORE_PADDED_POP) - -IterationLogic::IterationLogic(Bench const& bench) - : mPimpl(new Impl(bench)) {} - -IterationLogic::~IterationLogic() { - delete mPimpl; -} - -uint64_t IterationLogic::numIters() const noexcept { - ANKERL_NANOBENCH_LOG(mPimpl->mBench.name() << ": mNumIters=" << mPimpl->mNumIters); - return mPimpl->mNumIters; -} - -void IterationLogic::add(std::chrono::nanoseconds elapsed, PerformanceCounters const& pc) noexcept { - mPimpl->add(elapsed, pc); -} - -void IterationLogic::moveResultTo(std::vector& results) noexcept { - results.emplace_back(std::move(mPimpl->mResult)); -} - -# if ANKERL_NANOBENCH(PERF_COUNTERS) - -ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) -class LinuxPerformanceCounters { -public: - struct Target { - Target(uint64_t* targetValue_, bool correctMeasuringOverhead_, bool correctLoopOverhead_) - : targetValue(targetValue_) - , correctMeasuringOverhead(correctMeasuringOverhead_) - , correctLoopOverhead(correctLoopOverhead_) {} - - uint64_t* targetValue{}; // NOLINT(misc-non-private-member-variables-in-classes) - bool correctMeasuringOverhead{}; // NOLINT(misc-non-private-member-variables-in-classes) - bool correctLoopOverhead{}; // NOLINT(misc-non-private-member-variables-in-classes) - }; - - LinuxPerformanceCounters() = default; - LinuxPerformanceCounters(LinuxPerformanceCounters const&) = delete; - LinuxPerformanceCounters(LinuxPerformanceCounters&&) = delete; - LinuxPerformanceCounters& operator=(LinuxPerformanceCounters const&) = delete; - LinuxPerformanceCounters& operator=(LinuxPerformanceCounters&&) = delete; - ~LinuxPerformanceCounters(); - - // quick operation - inline void start() {} - - inline void stop() {} - - bool monitor(perf_sw_ids swId, Target target); - bool monitor(perf_hw_id hwId, Target target); - - ANKERL_NANOBENCH(NODISCARD) bool hasError() const noexcept { - return mHasError; - } - - // Just reading data is faster than enable & disabling. - // we subtract data ourselves. - inline void beginMeasure() { - if (mHasError) { - return; - } - - // NOLINTNEXTLINE(hicpp-signed-bitwise,cppcoreguidelines-pro-type-vararg) - mHasError = -1 == ioctl(mFd, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP); - if (mHasError) { - return; - } - - // NOLINTNEXTLINE(hicpp-signed-bitwise,cppcoreguidelines-pro-type-vararg) - mHasError = -1 == ioctl(mFd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP); - } - - inline void endMeasure() { - if (mHasError) { - return; - } - - // NOLINTNEXTLINE(hicpp-signed-bitwise,cppcoreguidelines-pro-type-vararg) - mHasError = (-1 == ioctl(mFd, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP)); - if (mHasError) { - return; - } - - auto const numBytes = sizeof(uint64_t) * mCounters.size(); - auto ret = read(mFd, mCounters.data(), numBytes); - mHasError = ret != static_cast(numBytes); - } - - void updateResults(uint64_t numIters); - - // rounded integer division - template - static inline T divRounded(T a, T divisor) { - return (a + divisor / 2) / divisor; - } - - ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") - static inline uint32_t mix(uint32_t x) noexcept { - x ^= x << 13U; - x ^= x >> 17U; - x ^= x << 5U; - return x; - } - - template - ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") - void calibrate(Op&& op) { - // clear current calibration data, - for (auto& v : mCalibratedOverhead) { - v = UINT64_C(0); - } - - // create new calibration data - auto newCalibration = mCalibratedOverhead; - for (auto& v : newCalibration) { - v = (std::numeric_limits::max)(); - } - for (size_t iter = 0; iter < 100; ++iter) { - beginMeasure(); - op(); - endMeasure(); - if (mHasError) { - return; - } - - for (size_t i = 0; i < newCalibration.size(); ++i) { - auto diff = mCounters[i]; - if (newCalibration[i] > diff) { - newCalibration[i] = diff; - } - } - } - - mCalibratedOverhead = std::move(newCalibration); - - { - // calibrate loop overhead. For branches & instructions this makes sense, not so much for everything else like cycles. - // marsaglia's xorshift: mov, sal/shr, xor. Times 3. - // This has the nice property that the compiler doesn't seem to be able to optimize multiple calls any further. - // see https://godbolt.org/z/49RVQ5 - uint64_t const numIters = 100000U + (std::random_device{}() & 3U); - uint64_t n = numIters; - uint32_t x = 1234567; - - beginMeasure(); - while (n-- > 0) { - x = mix(x); - } - endMeasure(); - detail::doNotOptimizeAway(x); - auto measure1 = mCounters; - - n = numIters; - beginMeasure(); - while (n-- > 0) { - // we now run *twice* so we can easily calculate the overhead - x = mix(x); - x = mix(x); - } - endMeasure(); - detail::doNotOptimizeAway(x); - auto measure2 = mCounters; - - for (size_t i = 0; i < mCounters.size(); ++i) { - // factor 2 because we have two instructions per loop - auto m1 = measure1[i] > mCalibratedOverhead[i] ? measure1[i] - mCalibratedOverhead[i] : 0; - auto m2 = measure2[i] > mCalibratedOverhead[i] ? measure2[i] - mCalibratedOverhead[i] : 0; - auto overhead = m1 * 2 > m2 ? m1 * 2 - m2 : 0; - - mLoopOverhead[i] = divRounded(overhead, numIters); - } - } - } - -private: - bool monitor(uint32_t type, uint64_t eventid, Target target); - - std::map mIdToTarget{}; - - // start with minimum size of 3 for read_format - std::vector mCounters{3}; - std::vector mCalibratedOverhead{3}; - std::vector mLoopOverhead{3}; - - uint64_t mTimeEnabledNanos = 0; - uint64_t mTimeRunningNanos = 0; - int mFd = -1; - bool mHasError = false; -}; -ANKERL_NANOBENCH(IGNORE_PADDED_POP) - -LinuxPerformanceCounters::~LinuxPerformanceCounters() { - if (-1 != mFd) { - close(mFd); - } -} - -bool LinuxPerformanceCounters::monitor(perf_sw_ids swId, LinuxPerformanceCounters::Target target) { - return monitor(PERF_TYPE_SOFTWARE, swId, target); -} - -bool LinuxPerformanceCounters::monitor(perf_hw_id hwId, LinuxPerformanceCounters::Target target) { - return monitor(PERF_TYPE_HARDWARE, hwId, target); -} - -// overflow is ok, it's checked -ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") -void LinuxPerformanceCounters::updateResults(uint64_t numIters) { - // clear old data - for (auto& id_value : mIdToTarget) { - *id_value.second.targetValue = UINT64_C(0); - } - - if (mHasError) { - return; - } - - mTimeEnabledNanos = mCounters[1] - mCalibratedOverhead[1]; - mTimeRunningNanos = mCounters[2] - mCalibratedOverhead[2]; - - for (uint64_t i = 0; i < mCounters[0]; ++i) { - auto idx = static_cast(3 + i * 2 + 0); - auto id = mCounters[idx + 1U]; - - auto it = mIdToTarget.find(id); - if (it != mIdToTarget.end()) { - - auto& tgt = it->second; - *tgt.targetValue = mCounters[idx]; - if (tgt.correctMeasuringOverhead) { - if (*tgt.targetValue >= mCalibratedOverhead[idx]) { - *tgt.targetValue -= mCalibratedOverhead[idx]; - } else { - *tgt.targetValue = 0U; - } - } - if (tgt.correctLoopOverhead) { - auto correctionVal = mLoopOverhead[idx] * numIters; - if (*tgt.targetValue >= correctionVal) { - *tgt.targetValue -= correctionVal; - } else { - *tgt.targetValue = 0U; - } - } - } - } -} - -bool LinuxPerformanceCounters::monitor(uint32_t type, uint64_t eventid, Target target) { - *target.targetValue = (std::numeric_limits::max)(); - if (mHasError) { - return false; - } - - auto pea = perf_event_attr(); - std::memset(&pea, 0, sizeof(perf_event_attr)); - pea.type = type; - pea.size = sizeof(perf_event_attr); - pea.config = eventid; - pea.disabled = 1; // start counter as disabled - pea.exclude_kernel = 1; - pea.exclude_hv = 1; - - // NOLINTNEXTLINE(hicpp-signed-bitwise) - pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; - - const int pid = 0; // the current process - const int cpu = -1; // all CPUs -# if defined(PERF_FLAG_FD_CLOEXEC) // since Linux 3.14 - const unsigned long flags = PERF_FLAG_FD_CLOEXEC; -# else - const unsigned long flags = 0; -# endif - - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) - auto fd = static_cast(syscall(__NR_perf_event_open, &pea, pid, cpu, mFd, flags)); - if (-1 == fd) { - return false; - } - if (-1 == mFd) { - // first call: set to fd, and use this from now on - mFd = fd; - } - uint64_t id = 0; - // NOLINTNEXTLINE(hicpp-signed-bitwise,cppcoreguidelines-pro-type-vararg) - if (-1 == ioctl(fd, PERF_EVENT_IOC_ID, &id)) { - // couldn't get id - return false; - } - - // insert into map, rely on the fact that map's references are constant. - mIdToTarget.emplace(id, target); - - // prepare readformat with the correct size (after the insert) - auto size = 3 + 2 * mIdToTarget.size(); - mCounters.resize(size); - mCalibratedOverhead.resize(size); - mLoopOverhead.resize(size); - - return true; -} - -PerformanceCounters::PerformanceCounters() - : mPc(new LinuxPerformanceCounters()) - , mVal() - , mHas() { - - // HW events - mHas.cpuCycles = mPc->monitor(PERF_COUNT_HW_REF_CPU_CYCLES, LinuxPerformanceCounters::Target(&mVal.cpuCycles, true, false)); - if (!mHas.cpuCycles) { - // Fallback to cycles counter, reference cycles not available in many systems. - mHas.cpuCycles = mPc->monitor(PERF_COUNT_HW_CPU_CYCLES, LinuxPerformanceCounters::Target(&mVal.cpuCycles, true, false)); - } - mHas.instructions = mPc->monitor(PERF_COUNT_HW_INSTRUCTIONS, LinuxPerformanceCounters::Target(&mVal.instructions, true, true)); - mHas.branchInstructions = - mPc->monitor(PERF_COUNT_HW_BRANCH_INSTRUCTIONS, LinuxPerformanceCounters::Target(&mVal.branchInstructions, true, false)); - mHas.branchMisses = mPc->monitor(PERF_COUNT_HW_BRANCH_MISSES, LinuxPerformanceCounters::Target(&mVal.branchMisses, true, false)); - // mHas.branchMisses = false; - - // SW events - mHas.pageFaults = mPc->monitor(PERF_COUNT_SW_PAGE_FAULTS, LinuxPerformanceCounters::Target(&mVal.pageFaults, true, false)); - mHas.contextSwitches = - mPc->monitor(PERF_COUNT_SW_CONTEXT_SWITCHES, LinuxPerformanceCounters::Target(&mVal.contextSwitches, true, false)); - - mPc->start(); - mPc->calibrate([] { - auto before = ankerl::nanobench::Clock::now(); - auto after = ankerl::nanobench::Clock::now(); - (void)before; - (void)after; - }); - - if (mPc->hasError()) { - // something failed, don't monitor anything. - mHas = PerfCountSet{}; - } -} - -PerformanceCounters::~PerformanceCounters() { - // no need to check for nullptr, delete nullptr has no effect - delete mPc; -} - -void PerformanceCounters::beginMeasure() { - mPc->beginMeasure(); -} - -void PerformanceCounters::endMeasure() { - mPc->endMeasure(); -} - -void PerformanceCounters::updateResults(uint64_t numIters) { - mPc->updateResults(numIters); -} - -# else - -PerformanceCounters::PerformanceCounters() = default; -PerformanceCounters::~PerformanceCounters() = default; -void PerformanceCounters::beginMeasure() {} -void PerformanceCounters::endMeasure() {} -void PerformanceCounters::updateResults(uint64_t) {} - -# endif - -ANKERL_NANOBENCH(NODISCARD) PerfCountSet const& PerformanceCounters::val() const noexcept { - return mVal; -} -ANKERL_NANOBENCH(NODISCARD) PerfCountSet const& PerformanceCounters::has() const noexcept { - return mHas; -} - -// formatting utilities -namespace fmt { - -// adds thousands separator to numbers -NumSep::NumSep(char sep) - : mSep(sep) {} - -char NumSep::do_thousands_sep() const { - return mSep; -} - -std::string NumSep::do_grouping() const { - return "\003"; -} - -// RAII to save & restore a stream's state -StreamStateRestorer::StreamStateRestorer(std::ostream& s) - : mStream(s) - , mLocale(s.getloc()) - , mPrecision(s.precision()) - , mWidth(s.width()) - , mFill(s.fill()) - , mFmtFlags(s.flags()) {} - -StreamStateRestorer::~StreamStateRestorer() { - restore(); -} - -// sets back all stream info that we remembered at construction -void StreamStateRestorer::restore() { - mStream.imbue(mLocale); - mStream.precision(mPrecision); - mStream.width(mWidth); - mStream.fill(mFill); - mStream.flags(mFmtFlags); -} - -Number::Number(int width, int precision, int64_t value) - : mWidth(width) - , mPrecision(precision) - , mValue(d(value)) {} - -Number::Number(int width, int precision, double value) - : mWidth(width) - , mPrecision(precision) - , mValue(value) {} - -std::ostream& Number::write(std::ostream& os) const { - StreamStateRestorer const restorer(os); - os.imbue(std::locale(os.getloc(), new NumSep(','))); - os << std::setw(mWidth) << std::setprecision(mPrecision) << std::fixed << mValue; - return os; -} - -std::string Number::to_s() const { - std::stringstream ss; - write(ss); - return ss.str(); -} - -std::string to_s(uint64_t n) { - std::string str; - do { - str += static_cast('0' + static_cast(n % 10)); - n /= 10; - } while (n != 0); - std::reverse(str.begin(), str.end()); - return str; -} - -std::ostream& operator<<(std::ostream& os, Number const& n) { - return n.write(os); -} - -MarkDownColumn::MarkDownColumn(int w, int prec, std::string tit, std::string suff, double val) noexcept - : mWidth(w) - , mPrecision(prec) - , mTitle(std::move(tit)) - , mSuffix(std::move(suff)) - , mValue(val) {} - -std::string MarkDownColumn::title() const { - std::stringstream ss; - ss << '|' << std::setw(mWidth - 2) << std::right << mTitle << ' '; - return ss.str(); -} - -std::string MarkDownColumn::separator() const { - std::string sep(static_cast(mWidth), '-'); - sep.front() = '|'; - sep.back() = ':'; - return sep; -} - -std::string MarkDownColumn::invalid() const { - std::string sep(static_cast(mWidth), ' '); - sep.front() = '|'; - sep[sep.size() - 2] = '-'; - return sep; -} - -std::string MarkDownColumn::value() const { - std::stringstream ss; - auto width = mWidth - 2 - static_cast(mSuffix.size()); - ss << '|' << Number(width, mPrecision, mValue) << mSuffix << ' '; - return ss.str(); -} - -// Formats any text as markdown code, escaping backticks. -MarkDownCode::MarkDownCode(std::string const& what) { - mWhat.reserve(what.size() + 2); - mWhat.push_back('`'); - for (char const c : what) { - mWhat.push_back(c); - if ('`' == c) { - mWhat.push_back('`'); - } - } - mWhat.push_back('`'); -} - -std::ostream& MarkDownCode::write(std::ostream& os) const { - return os << mWhat; -} - -std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode) { - return mdCode.write(os); -} -} // namespace fmt -} // namespace detail - -// provide implementation here so it's only generated once -Config::Config() = default; -Config::~Config() = default; -Config& Config::operator=(Config const&) = default; -Config& Config::operator=(Config&&) noexcept(ANKERL_NANOBENCH(NOEXCEPT_STRING_MOVE)) = default; -Config::Config(Config const&) = default; -Config::Config(Config&&) noexcept = default; - -// provide implementation here so it's only generated once -Result::~Result() = default; -Result& Result::operator=(Result const&) = default; -Result& Result::operator=(Result&&) noexcept(ANKERL_NANOBENCH(NOEXCEPT_STRING_MOVE)) = default; -Result::Result(Result const&) = default; -Result::Result(Result&&) noexcept = default; - -namespace detail { -template -inline constexpr typename std::underlying_type::type u(T val) noexcept { - return static_cast::type>(val); -} -} // namespace detail - -// Result returned after a benchmark has finished. Can be used as a baseline for relative(). -Result::Result(Config benchmarkConfig) - : mConfig(std::move(benchmarkConfig)) - , mNameToMeasurements{detail::u(Result::Measure::_size)} {} - -void Result::add(Clock::duration totalElapsed, uint64_t iters, detail::PerformanceCounters const& pc) { - using detail::d; - using detail::u; - - double const dIters = d(iters); - mNameToMeasurements[u(Result::Measure::iterations)].push_back(dIters); - - mNameToMeasurements[u(Result::Measure::elapsed)].push_back(d(totalElapsed) / dIters); - if (pc.has().pageFaults) { - mNameToMeasurements[u(Result::Measure::pagefaults)].push_back(d(pc.val().pageFaults) / dIters); - } - if (pc.has().cpuCycles) { - mNameToMeasurements[u(Result::Measure::cpucycles)].push_back(d(pc.val().cpuCycles) / dIters); - } - if (pc.has().contextSwitches) { - mNameToMeasurements[u(Result::Measure::contextswitches)].push_back(d(pc.val().contextSwitches) / dIters); - } - if (pc.has().instructions) { - mNameToMeasurements[u(Result::Measure::instructions)].push_back(d(pc.val().instructions) / dIters); - } - if (pc.has().branchInstructions) { - double branchInstructions = 0.0; - // correcting branches: remove branch introduced by the while (...) loop for each iteration. - if (pc.val().branchInstructions > iters + 1U) { - branchInstructions = d(pc.val().branchInstructions - (iters + 1U)); - } - mNameToMeasurements[u(Result::Measure::branchinstructions)].push_back(branchInstructions / dIters); - - if (pc.has().branchMisses) { - // correcting branch misses - double branchMisses = d(pc.val().branchMisses); - if (branchMisses > branchInstructions) { - // can't have branch misses when there were branches... - branchMisses = branchInstructions; - } - - // assuming at least one missed branch for the loop - branchMisses -= 1.0; - if (branchMisses < 1.0) { - branchMisses = 1.0; - } - mNameToMeasurements[u(Result::Measure::branchmisses)].push_back(branchMisses / dIters); - } - } -} - -Config const& Result::config() const noexcept { - return mConfig; -} - -inline double calcMedian(std::vector& data) { - if (data.empty()) { - return 0.0; - } - std::sort(data.begin(), data.end()); - - auto midIdx = data.size() / 2U; - if (1U == (data.size() & 1U)) { - return data[midIdx]; - } - return (data[midIdx - 1U] + data[midIdx]) / 2U; -} - -double Result::median(Measure m) const { - // create a copy so we can sort - auto data = mNameToMeasurements[detail::u(m)]; - return calcMedian(data); -} - -double Result::average(Measure m) const { - using detail::d; - auto const& data = mNameToMeasurements[detail::u(m)]; - if (data.empty()) { - return 0.0; - } - - // create a copy so we can sort - return sum(m) / d(data.size()); -} - -double Result::medianAbsolutePercentError(Measure m) const { - // create copy - auto data = mNameToMeasurements[detail::u(m)]; - - // calculates MdAPE which is the median of percentage error - // see https://support.numxl.com/hc/en-us/articles/115001223503-MdAPE-Median-Absolute-Percentage-Error - auto med = calcMedian(data); - - // transform the data to absolute error - for (auto& x : data) { - x = (x - med) / x; - if (x < 0) { - x = -x; - } - } - return calcMedian(data); -} - -double Result::sum(Measure m) const noexcept { - auto const& data = mNameToMeasurements[detail::u(m)]; - return std::accumulate(data.begin(), data.end(), 0.0); -} - -double Result::sumProduct(Measure m1, Measure m2) const noexcept { - auto const& data1 = mNameToMeasurements[detail::u(m1)]; - auto const& data2 = mNameToMeasurements[detail::u(m2)]; - - if (data1.size() != data2.size()) { - return 0.0; - } - - double result = 0.0; - for (size_t i = 0, s = data1.size(); i != s; ++i) { - result += data1[i] * data2[i]; - } - return result; -} - -bool Result::has(Measure m) const noexcept { - return !mNameToMeasurements[detail::u(m)].empty(); -} - -double Result::get(size_t idx, Measure m) const { - auto const& data = mNameToMeasurements[detail::u(m)]; - return data.at(idx); -} - -bool Result::empty() const noexcept { - return 0U == size(); -} - -size_t Result::size() const noexcept { - auto const& data = mNameToMeasurements[detail::u(Measure::elapsed)]; - return data.size(); -} - -double Result::minimum(Measure m) const noexcept { - auto const& data = mNameToMeasurements[detail::u(m)]; - if (data.empty()) { - return 0.0; - } - - // here its save to assume that at least one element is there - return *std::min_element(data.begin(), data.end()); -} - -double Result::maximum(Measure m) const noexcept { - auto const& data = mNameToMeasurements[detail::u(m)]; - if (data.empty()) { - return 0.0; - } - - // here its save to assume that at least one element is there - return *std::max_element(data.begin(), data.end()); -} - -std::string const& Result::context(char const* variableName) const { - return mConfig.mContext.at(variableName); -} - -std::string const& Result::context(std::string const& variableName) const { - return mConfig.mContext.at(variableName); -} - -Result::Measure Result::fromString(std::string const& str) { - if (str == "elapsed") { - return Measure::elapsed; - } - if (str == "iterations") { - return Measure::iterations; - } - if (str == "pagefaults") { - return Measure::pagefaults; - } - if (str == "cpucycles") { - return Measure::cpucycles; - } - if (str == "contextswitches") { - return Measure::contextswitches; - } - if (str == "instructions") { - return Measure::instructions; - } - if (str == "branchinstructions") { - return Measure::branchinstructions; - } - if (str == "branchmisses") { - return Measure::branchmisses; - } - // not found, return _size - return Measure::_size; -} - -// Configuration of a microbenchmark. -Bench::Bench() { - mConfig.mOut = &std::cout; -} - -Bench::Bench(Bench&&) noexcept = default; -Bench& Bench::operator=(Bench&&) noexcept(ANKERL_NANOBENCH(NOEXCEPT_STRING_MOVE)) = default; -Bench::Bench(Bench const&) = default; -Bench& Bench::operator=(Bench const&) = default; -Bench::~Bench() noexcept = default; - -double Bench::batch() const noexcept { - return mConfig.mBatch; -} - -double Bench::complexityN() const noexcept { - return mConfig.mComplexityN; -} - -// Set a baseline to compare it to. 100% it is exactly as fast as the baseline, >100% means it is faster than the baseline, <100% -// means it is slower than the baseline. -Bench& Bench::relative(bool isRelativeEnabled) noexcept { - mConfig.mIsRelative = isRelativeEnabled; - return *this; -} -bool Bench::relative() const noexcept { - return mConfig.mIsRelative; -} - -Bench& Bench::performanceCounters(bool showPerformanceCounters) noexcept { - mConfig.mShowPerformanceCounters = showPerformanceCounters; - return *this; -} -bool Bench::performanceCounters() const noexcept { - return mConfig.mShowPerformanceCounters; -} - -// Operation unit. Defaults to "op", could be e.g. "byte" for string processing. -// If u differs from currently set unit, the stored results will be cleared. -// Use singular (byte, not bytes). -Bench& Bench::unit(char const* u) { - if (u != mConfig.mUnit) { - mResults.clear(); - } - mConfig.mUnit = u; - return *this; -} - -Bench& Bench::unit(std::string const& u) { - return unit(u.c_str()); -} - -std::string const& Bench::unit() const noexcept { - return mConfig.mUnit; -} - -Bench& Bench::timeUnit(std::chrono::duration const& tu, std::string const& tuName) { - mConfig.mTimeUnit = tu; - mConfig.mTimeUnitName = tuName; - return *this; -} - -std::string const& Bench::timeUnitName() const noexcept { - return mConfig.mTimeUnitName; -} - -std::chrono::duration const& Bench::timeUnit() const noexcept { - return mConfig.mTimeUnit; -} - -// If benchmarkTitle differs from currently set title, the stored results will be cleared. -Bench& Bench::title(const char* benchmarkTitle) { - if (benchmarkTitle != mConfig.mBenchmarkTitle) { - mResults.clear(); - } - mConfig.mBenchmarkTitle = benchmarkTitle; - return *this; -} -Bench& Bench::title(std::string const& benchmarkTitle) { - if (benchmarkTitle != mConfig.mBenchmarkTitle) { - mResults.clear(); - } - mConfig.mBenchmarkTitle = benchmarkTitle; - return *this; -} - -std::string const& Bench::title() const noexcept { - return mConfig.mBenchmarkTitle; -} - -Bench& Bench::name(const char* benchmarkName) { - mConfig.mBenchmarkName = benchmarkName; - return *this; -} - -Bench& Bench::name(std::string const& benchmarkName) { - mConfig.mBenchmarkName = benchmarkName; - return *this; -} - -std::string const& Bench::name() const noexcept { - return mConfig.mBenchmarkName; -} - -Bench& Bench::context(char const* variableName, char const* variableValue) { - mConfig.mContext[variableName] = variableValue; - return *this; -} - -Bench& Bench::context(std::string const& variableName, std::string const& variableValue) { - mConfig.mContext[variableName] = variableValue; - return *this; -} - -Bench& Bench::clearContext() { - mConfig.mContext.clear(); - return *this; -} - -// Number of epochs to evaluate. The reported result will be the median of evaluation of each epoch. -Bench& Bench::epochs(size_t numEpochs) noexcept { - mConfig.mNumEpochs = numEpochs; - return *this; -} -size_t Bench::epochs() const noexcept { - return mConfig.mNumEpochs; -} - -// Desired evaluation time is a multiple of clock resolution. Default is to be 1000 times above this measurement precision. -Bench& Bench::clockResolutionMultiple(size_t multiple) noexcept { - mConfig.mClockResolutionMultiple = multiple; - return *this; -} -size_t Bench::clockResolutionMultiple() const noexcept { - return mConfig.mClockResolutionMultiple; -} - -// Sets the maximum time each epoch should take. Default is 100ms. -Bench& Bench::maxEpochTime(std::chrono::nanoseconds t) noexcept { - mConfig.mMaxEpochTime = t; - return *this; -} -std::chrono::nanoseconds Bench::maxEpochTime() const noexcept { - return mConfig.mMaxEpochTime; -} - -// Sets the maximum time each epoch should take. Default is 100ms. -Bench& Bench::minEpochTime(std::chrono::nanoseconds t) noexcept { - mConfig.mMinEpochTime = t; - return *this; -} -std::chrono::nanoseconds Bench::minEpochTime() const noexcept { - return mConfig.mMinEpochTime; -} - -Bench& Bench::minEpochIterations(uint64_t numIters) noexcept { - mConfig.mMinEpochIterations = (numIters == 0) ? 1 : numIters; - return *this; -} -uint64_t Bench::minEpochIterations() const noexcept { - return mConfig.mMinEpochIterations; -} - -Bench& Bench::epochIterations(uint64_t numIters) noexcept { - mConfig.mEpochIterations = numIters; - return *this; -} -uint64_t Bench::epochIterations() const noexcept { - return mConfig.mEpochIterations; -} - -Bench& Bench::warmup(uint64_t numWarmupIters) noexcept { - mConfig.mWarmup = numWarmupIters; - return *this; -} -uint64_t Bench::warmup() const noexcept { - return mConfig.mWarmup; -} - -Bench& Bench::config(Config const& benchmarkConfig) { - mConfig = benchmarkConfig; - return *this; -} -Config const& Bench::config() const noexcept { - return mConfig; -} - -Bench& Bench::output(std::ostream* outstream) noexcept { - mConfig.mOut = outstream; - return *this; -} - -ANKERL_NANOBENCH(NODISCARD) std::ostream* Bench::output() const noexcept { - return mConfig.mOut; -} - -std::vector const& Bench::results() const noexcept { - return mResults; -} - -Bench& Bench::render(char const* templateContent, std::ostream& os) { - ::ankerl::nanobench::render(templateContent, *this, os); - return *this; -} - -Bench& Bench::render(std::string const& templateContent, std::ostream& os) { - ::ankerl::nanobench::render(templateContent, *this, os); - return *this; -} - -std::vector Bench::complexityBigO() const { - std::vector bigOs; - auto rangeMeasure = BigO::collectRangeMeasure(mResults); - bigOs.emplace_back("O(1)", rangeMeasure, [](double) { - return 1.0; - }); - bigOs.emplace_back("O(n)", rangeMeasure, [](double n) { - return n; - }); - bigOs.emplace_back("O(log n)", rangeMeasure, [](double n) { - return std::log2(n); - }); - bigOs.emplace_back("O(n log n)", rangeMeasure, [](double n) { - return n * std::log2(n); - }); - bigOs.emplace_back("O(n^2)", rangeMeasure, [](double n) { - return n * n; - }); - bigOs.emplace_back("O(n^3)", rangeMeasure, [](double n) { - return n * n * n; - }); - std::sort(bigOs.begin(), bigOs.end()); - return bigOs; -} - -Rng::Rng() - : mX(0) - , mY(0) { - std::random_device rd; - std::uniform_int_distribution dist; - do { - mX = dist(rd); - mY = dist(rd); - } while (mX == 0 && mY == 0); -} - -ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") -uint64_t splitMix64(uint64_t& state) noexcept { - uint64_t z = (state += UINT64_C(0x9e3779b97f4a7c15)); - z = (z ^ (z >> 30U)) * UINT64_C(0xbf58476d1ce4e5b9); - z = (z ^ (z >> 27U)) * UINT64_C(0x94d049bb133111eb); - return z ^ (z >> 31U); -} - -// Seeded as described in romu paper (update april 2020) -Rng::Rng(uint64_t seed) noexcept - : mX(splitMix64(seed)) - , mY(splitMix64(seed)) { - for (size_t i = 0; i < 10; ++i) { - operator()(); - } -} - -// only internally used to copy the RNG. -Rng::Rng(uint64_t x, uint64_t y) noexcept - : mX(x) - , mY(y) {} - -Rng Rng::copy() const noexcept { - return Rng{mX, mY}; -} - -Rng::Rng(std::vector const& data) - : mX(0) - , mY(0) { - if (data.size() != 2) { - throw std::runtime_error("ankerl::nanobench::Rng::Rng: needed exactly 2 entries in data, but got " + - detail::fmt::to_s(data.size())); - } - mX = data[0]; - mY = data[1]; -} - -std::vector Rng::state() const { - std::vector data(2); - data[0] = mX; - data[1] = mY; - return data; -} - -BigO::RangeMeasure BigO::collectRangeMeasure(std::vector const& results) { - BigO::RangeMeasure rangeMeasure; - for (auto const& result : results) { - if (result.config().mComplexityN > 0.0) { - rangeMeasure.emplace_back(result.config().mComplexityN, result.median(Result::Measure::elapsed)); - } - } - return rangeMeasure; -} - -BigO::BigO(std::string bigOName, RangeMeasure const& rangeMeasure) - : mName(std::move(bigOName)) { - - // estimate the constant factor - double sumRangeMeasure = 0.0; - double sumRangeRange = 0.0; - - for (const auto& rm : rangeMeasure) { - sumRangeMeasure += rm.first * rm.second; - sumRangeRange += rm.first * rm.first; - } - mConstant = sumRangeMeasure / sumRangeRange; - - // calculate root mean square - double err = 0.0; - double sumMeasure = 0.0; - for (const auto& rm : rangeMeasure) { - auto diff = mConstant * rm.first - rm.second; - err += diff * diff; - - sumMeasure += rm.second; - } - - auto n = detail::d(rangeMeasure.size()); - auto mean = sumMeasure / n; - mNormalizedRootMeanSquare = std::sqrt(err / n) / mean; -} - -BigO::BigO(const char* bigOName, RangeMeasure const& rangeMeasure) - : BigO(std::string(bigOName), rangeMeasure) {} - -std::string const& BigO::name() const noexcept { - return mName; -} - -double BigO::constant() const noexcept { - return mConstant; -} - -double BigO::normalizedRootMeanSquare() const noexcept { - return mNormalizedRootMeanSquare; -} - -bool BigO::operator<(BigO const& other) const noexcept { - return std::tie(mNormalizedRootMeanSquare, mName) < std::tie(other.mNormalizedRootMeanSquare, other.mName); -} - -std::ostream& operator<<(std::ostream& os, BigO const& bigO) { - return os << bigO.constant() << " * " << bigO.name() << ", rms=" << bigO.normalizedRootMeanSquare(); -} - -std::ostream& operator<<(std::ostream& os, std::vector const& bigOs) { - detail::fmt::StreamStateRestorer const restorer(os); - os << std::endl << "| coefficient | err% | complexity" << std::endl << "|--------------:|-------:|------------" << std::endl; - for (auto const& bigO : bigOs) { - os << "|" << std::setw(14) << std::setprecision(7) << std::scientific << bigO.constant() << " "; - os << "|" << detail::fmt::Number(6, 1, bigO.normalizedRootMeanSquare() * 100.0) << "% "; - os << "| " << bigO.name(); - os << std::endl; - } - return os; -} - -} // namespace nanobench -} // namespace ankerl - -#endif // ANKERL_NANOBENCH_IMPLEMENT -#endif // ANKERL_NANOBENCH_H_INCLUDED diff --git a/src/bench/obfuscation.cpp b/src/bench/obfuscation.cpp deleted file mode 100644 index 178be56a5d5a..000000000000 --- a/src/bench/obfuscation.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or https://opensource.org/license/mit/. - -#include -#include -#include - -#include -#include - -static void ObfuscationBench(benchmark::Bench& bench) -{ - FastRandomContext frc{/*fDeterministic=*/true}; - auto data{frc.randbytes(1024)}; - const Obfuscation obfuscation{frc.randbytes()}; - - size_t offset{0}; - bench.batch(data.size()).unit("byte").run([&] { - obfuscation(data, offset++); // mutated differently each time - ankerl::nanobench::doNotOptimizeAway(data); - }); -} - -BENCHMARK(ObfuscationBench, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/parse_hex.cpp b/src/bench/parse_hex.cpp deleted file mode 100644 index fa08f5d84a1b..000000000000 --- a/src/bench/parse_hex.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2024-present The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include - -#include -#include -#include -#include - -std::string generateHexString(size_t length) { - const auto hex_digits = "0123456789ABCDEF"; - FastRandomContext rng(/*fDeterministic=*/true); - - std::string data; - while (data.size() < length) { - auto digit = hex_digits[rng.randbits(4)]; - data.push_back(digit); - } - return data; -} - -static void HexParse(benchmark::Bench& bench) -{ - auto data = generateHexString(130); // Generates 678B0EDA0A1FD30904D5A65E3568DB82DB2D918B0AD8DEA18A63FECCB877D07CAD1495C7157584D877420EF38B8DA473A6348B4F51811AC13C786B962BEE5668F9 by default - - bench.batch(data.size()).unit("base16").run([&] { - auto result = TryParseHex(data); - assert(result != std::nullopt); // make sure we're measuring the successful case - ankerl::nanobench::doNotOptimizeAway(result); - }); -} - -BENCHMARK(HexParse, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/peer_eviction.cpp b/src/bench/peer_eviction.cpp deleted file mode 100644 index 5b08cc758bef..000000000000 --- a/src/bench/peer_eviction.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2021-2022 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include -#include -#include - -#include -#include -#include - -static void EvictionProtectionCommon( - benchmark::Bench& bench, - int num_candidates, - std::function candidate_setup_fn) -{ - using Candidates = std::vector; - FastRandomContext random_context{true}; - - Candidates candidates{GetRandomNodeEvictionCandidates(num_candidates, random_context)}; - for (auto& c : candidates) { - candidate_setup_fn(c); - } - - - bench.run([&] { - // creating a copy has an overhead of about 3%, so it does not influence the benchmark results much. - auto copy = candidates; - ProtectEvictionCandidatesByRatio(copy); - }); -} - -/* Benchmarks */ - -static void EvictionProtection0Networks250Candidates(benchmark::Bench& bench) -{ - EvictionProtectionCommon( - bench, - /*num_candidates=*/250, - [](NodeEvictionCandidate& c) { - c.m_connected = std::chrono::seconds{c.id}; - c.m_network = NET_IPV4; - }); -} - -static void EvictionProtection1Networks250Candidates(benchmark::Bench& bench) -{ - EvictionProtectionCommon( - bench, - /*num_candidates=*/250, - [](NodeEvictionCandidate& c) { - c.m_connected = std::chrono::seconds{c.id}; - c.m_is_local = false; - if (c.id >= 130 && c.id < 240) { // 110 Tor - c.m_network = NET_ONION; - } else { - c.m_network = NET_IPV4; - } - }); -} - -static void EvictionProtection2Networks250Candidates(benchmark::Bench& bench) -{ - EvictionProtectionCommon( - bench, - /*num_candidates=*/250, - [](NodeEvictionCandidate& c) { - c.m_connected = std::chrono::seconds{c.id}; - c.m_is_local = false; - if (c.id >= 90 && c.id < 160) { // 70 Tor - c.m_network = NET_ONION; - } else if (c.id >= 170 && c.id < 250) { // 80 I2P - c.m_network = NET_I2P; - } else { - c.m_network = NET_IPV4; - } - }); -} - -static void EvictionProtection3Networks050Candidates(benchmark::Bench& bench) -{ - EvictionProtectionCommon( - bench, - /*num_candidates=*/50, - [](NodeEvictionCandidate& c) { - c.m_connected = std::chrono::seconds{c.id}; - c.m_is_local = (c.id == 28 || c.id == 47); // 2 localhost - if (c.id >= 30 && c.id < 47) { // 17 I2P - c.m_network = NET_I2P; - } else if (c.id >= 24 && c.id < 28) { // 4 Tor - c.m_network = NET_ONION; - } else { - c.m_network = NET_IPV4; - } - }); -} - -static void EvictionProtection3Networks100Candidates(benchmark::Bench& bench) -{ - EvictionProtectionCommon( - bench, - /*num_candidates=*/100, - [](NodeEvictionCandidate& c) { - c.m_connected = std::chrono::seconds{c.id}; - c.m_is_local = (c.id >= 55 && c.id < 60); // 5 localhost - if (c.id >= 70 && c.id < 80) { // 10 I2P - c.m_network = NET_I2P; - } else if (c.id >= 80 && c.id < 96) { // 16 Tor - c.m_network = NET_ONION; - } else { - c.m_network = NET_IPV4; - } - }); -} - -static void EvictionProtection3Networks250Candidates(benchmark::Bench& bench) -{ - EvictionProtectionCommon( - bench, - /*num_candidates=*/250, - [](NodeEvictionCandidate& c) { - c.m_connected = std::chrono::seconds{c.id}; - c.m_is_local = (c.id >= 140 && c.id < 160); // 20 localhost - if (c.id >= 170 && c.id < 180) { // 10 I2P - c.m_network = NET_I2P; - } else if (c.id >= 190 && c.id < 240) { // 50 Tor - c.m_network = NET_ONION; - } else { - c.m_network = NET_IPV4; - } - }); -} - -// Candidate numbers used for the benchmarks: -// - 50 candidates simulates a possible use of -maxconnections -// - 100 candidates approximates an average node with default settings -// - 250 candidates is the number of peers reported by operators of busy nodes - -// No disadvantaged networks, with 250 eviction candidates. -BENCHMARK(EvictionProtection0Networks250Candidates, benchmark::PriorityLevel::HIGH); - -// 1 disadvantaged network (Tor) with 250 eviction candidates. -BENCHMARK(EvictionProtection1Networks250Candidates, benchmark::PriorityLevel::HIGH); - -// 2 disadvantaged networks (I2P, Tor) with 250 eviction candidates. -BENCHMARK(EvictionProtection2Networks250Candidates, benchmark::PriorityLevel::HIGH); - -// 3 disadvantaged networks (I2P/localhost/Tor) with 50/100/250 eviction candidates. -BENCHMARK(EvictionProtection3Networks050Candidates, benchmark::PriorityLevel::HIGH); -BENCHMARK(EvictionProtection3Networks100Candidates, benchmark::PriorityLevel::HIGH); -BENCHMARK(EvictionProtection3Networks250Candidates, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/poly1305.cpp b/src/bench/poly1305.cpp deleted file mode 100644 index f58afe984511..000000000000 --- a/src/bench/poly1305.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2019-2022 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#include -#include -#include - -#include -#include -#include - -/* Number of bytes to process per iteration */ -static constexpr uint64_t BUFFER_SIZE_TINY = 64; -static constexpr uint64_t BUFFER_SIZE_SMALL = 256; -static constexpr uint64_t BUFFER_SIZE_LARGE = 1024*1024; - -static void POLY1305(benchmark::Bench& bench, size_t buffersize) -{ - std::vector tag(Poly1305::TAGLEN, {}); - std::vector key(Poly1305::KEYLEN, {}); - std::vector in(buffersize, {}); - bench.batch(in.size()).unit("byte").run([&] { - Poly1305{key}.Update(in).Finalize(tag); - }); -} - -static void POLY1305_64BYTES(benchmark::Bench& bench) -{ - POLY1305(bench, BUFFER_SIZE_TINY); -} - -static void POLY1305_256BYTES(benchmark::Bench& bench) -{ - POLY1305(bench, BUFFER_SIZE_SMALL); -} - -static void POLY1305_1MB(benchmark::Bench& bench) -{ - POLY1305(bench, BUFFER_SIZE_LARGE); -} - -BENCHMARK(POLY1305_64BYTES, benchmark::PriorityLevel::HIGH); -BENCHMARK(POLY1305_256BYTES, benchmark::PriorityLevel::HIGH); -BENCHMARK(POLY1305_1MB, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/pool.cpp b/src/bench/pool.cpp deleted file mode 100644 index 40b098f54c46..000000000000 --- a/src/bench/pool.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2022 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include - -#include -#include -#include -#include -#include - -template -void BenchFillClearMap(benchmark::Bench& bench, Map& map) -{ - size_t batch_size = 5000; - - // make sure each iteration of the benchmark contains exactly 5000 inserts and one clear. - // do this at least 10 times so we get reasonable accurate results - - bench.batch(batch_size).minEpochIterations(10).run([&] { - auto rng = ankerl::nanobench::Rng(1234); - for (size_t i = 0; i < batch_size; ++i) { - map[rng()]; - } - map.clear(); - }); -} - -static void PoolAllocator_StdUnorderedMap(benchmark::Bench& bench) -{ - auto map = std::unordered_map(); - BenchFillClearMap(bench, map); -} - -static void PoolAllocator_StdUnorderedMapWithPoolResource(benchmark::Bench& bench) -{ - using Map = std::unordered_map, - std::equal_to, - PoolAllocator, - sizeof(std::pair) + 4 * sizeof(void*)>>; - - // make sure the resource supports large enough pools to hold the node. We do this by adding the size of a few pointers to it. - auto pool_resource = Map::allocator_type::ResourceType(); - auto map = Map{0, std::hash{}, std::equal_to{}, &pool_resource}; - BenchFillClearMap(bench, map); -} - -BENCHMARK(PoolAllocator_StdUnorderedMap, benchmark::PriorityLevel::HIGH); -BENCHMARK(PoolAllocator_StdUnorderedMapWithPoolResource, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/prevector.cpp b/src/bench/prevector.cpp deleted file mode 100644 index 2d4e19cf3cc9..000000000000 --- a/src/bench/prevector.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2015-2022 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include - -#include -#include