diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..3772cc8e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,879 @@ +############################################################################### +# Copyright (c) 2014-2025 libbitcoin-server developers (see COPYING). +# +# GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY +# +############################################################################### + +name: Continuous Integration Build + +on: [ pull_request, push, workflow_dispatch ] + +jobs: + autotools: + + strategy: + fail-fast: false + + matrix: + include: + - os: ubuntu-24.04 + cxx: "clang++-16" + link: "dynamic" + optimization: "debug" + assert: "debug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "clang-16" + flags: "-Og -fPIE" + options: "--enable-isystem" + packager: "apt" + packages: "" + + - os: ubuntu-24.04 + cxx: "clang++-16" + link: "static" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "--build-icu --with-icu" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "clang-16" + flags: "-Os -fPIE" + options: "--enable-isystem" + packager: "apt" + packages: "" + + - os: ubuntu-24.04 + cxx: "g++-12" + link: "dynamic" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "gcc-12" + flags: "-Os -fPIE" + options: "--enable-isystem" + packager: "apt" + packages: "" + + - os: ubuntu-24.04 + cxx: "g++" + link: "static" + optimization: "size" + assert: "ndebug" + coverage: "cov" + detectcpuflags: "detect" + boost: "--build-boost" + icu: "--build-icu --with-icu" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "gcc" + flags: "-Os -g --coverage -fPIE" + options: "--enable-isystem" + packager: "apt" + packages: "lcov" + + - os: macos-latest + cxx: "clang++" + link: "dynamic" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "llvm@16" + secp256k1: "--build-secp256k1" + cc: "clang" + flags: "-Os -fPIE" + options: "--enable-isystem" + packager: "brew" + packages: "llvm@16 icu4c" + + - os: macos-latest + cxx: "clang++" + link: "static" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "llvm@16" + secp256k1: "--build-secp256k1" + cc: "clang" + flags: "-Os -fvisibility=hidden -fPIE" + options: "--enable-isystem" + packager: "brew" + packages: "llvm@16 icu4c" + + + runs-on: ${{ matrix.os }} + + env: + CC: '${{ matrix.cc }}' + CXX: '${{ matrix.cxx }}' + CFLAGS: '${{ matrix.flags }}' + CXXFLAGS: '${{ matrix.flags }}' + CI_REPOSITORY: '${{ github.repository }}' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Prepare toolchain [generic] + run: | + git config --global init.defaultBranch master + + - name: Prepare toolchain [apt] + if: ${{ matrix.packager == 'apt' }} + run: | + sudo apt-get update + sudo apt-get install git build-essential autoconf automake libtool pkg-config ${{ matrix.packages }} + + - name: Prepare toolchain [brew] + if: ${{ matrix.packager == 'brew' }} + run: | + brew install autoconf automake libtool ${{ matrix.packages }} + if [[ -n ${{ matrix.llvm }} ]]; then + echo "PATH=/opt/homebrew/opt/${{ matrix.llvm }}/bin:$PATH" >> $GITHUB_ENV + fi + + - name: Determine CPU flags + shell: bash + run: | + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " sse4_1 ") ]]; then + echo "CPU_SUPPORT_SSE41=--enable-sse41" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " avx " | grep " avx2 ") ]]; then + echo "CPU_SUPPORT_AVX2=--enable-avx2" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " avx512bw ") ]]; then + echo "CPU_SUPPORT_AVX512=--enable-avx512" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " sha_ni ") ]]; then + echo "CPU_SUPPORT_SHANI=--enable-shani" >> $GITHUB_ENV + fi + + if [[ ${{ matrix.detectcpuflags }} == 'detect' ]]; then + echo "CPU_SUPPORTED_FLAGS='$CPU_SUPPORT_SSE41 $CPU_SUPPORT_AVX2 $CPU_SUPPORT_AVX512 $CPU_SUPPORT_SHANI'" >> $GITHUB_ENV + fi + + - name: Denormalize parameterization + shell: bash + run: | + WORKSPACE_SUBPATH="${GITHUB_WORKSPACE%libbitcoin-server}" + echo "LIBBITCOIN_SRC_PATH=${WORKSPACE_SUBPATH}" >> $GITHUB_ENV + if [[ ${{ matrix.assert }} == 'ndebug' ]]; then + echo "ASSERT_NDEBUG=--enable-ndebug" >> $GITHUB_ENV + else + echo "ASSERT_NDEBUG=--disable-ndebug" >> $GITHUB_ENV + fi + if [[ ${{ matrix.link }} == 'dynamic' ]]; then + echo "LINKAGE=--disable-static" >> $GITHUB_ENV + else + echo "LINKAGE=--disable-shared" >> $GITHUB_ENV + fi + if [[ ${{ matrix.link }} == 'dynamic' ]]; then + echo "LDFLAGS=-Wl,-rpath,${WORKSPACE_SUBPATH}prefix/lib" >> $GITHUB_ENV + fi + + - name: Display Compiler details + shell: bash + run: | + ${CC} -v + ${CXX} -v + + - name: Display CPU details + if: ${{ (runner.os == 'Linux') }} + shell: bash + run: | + lscpu + + - name: Execute install.sh + run: > + ./install.sh + --build-dir=${{ env.LIBBITCOIN_SRC_PATH }} ${{ matrix.options }} + --prefix=${{ env.LIBBITCOIN_SRC_PATH }}prefix + ${{ env.LINKAGE }} + ${{ env.ASSERT_NDEBUG }} + ${{ env.CPU_SUPPORTED_FLAGS }} + ${{ matrix.boost }} + ${{ matrix.icu }} + ${{ matrix.secp256k1 }} + + - name: Coveralls Calculation + if: ${{ matrix.coverage == 'cov' }} + run: | + lcov --ignore-errors version,gcov,mismatch --directory . --capture --output-file coverage.info + lcov --ignore-errors unused --remove coverage.info "/usr/*" "${{ env.LIBBITCOIN_SRC_PATH }}prefix/*" "${{ github.workspace }}/examples/*" "${{ github.workspace }}/test/*" --output-file coverage.info + lcov --list coverage.info + + - name: Coveralls.io Upload + if: ${{ matrix.coverage == 'cov' }} + uses: coverallsapp/github-action@v2.3.0 + with: + format: lcov + files: "./coverage.info" + github-token: ${{ secrets.github_token }} + + - name: Failure display available binaries + if: ${{ failure() }} + run: | + ls -la /usr/bin + + - name: Failure display selected compiler version + if: ${{ failure() }} + run: | + ${CC} -v + ${CXX} -v + + - name: Failure display default compiler version + if: ${{ failure() }} + run: | + clang -v + gcc -v + + - name: Failure display env + if: ${{ failure() }} + run: | + env + + - name: Failure list libdir + if: ${{ failure() }} + run: | + ls -la ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib + + - name: Failure display boost bootstrap.log [--build-boost] + if: ${{ failure() && (matrix.boost == '--build-boost') }} + run: | + cat ${{ github.workspace }}/build/build-*/bootstrap.log + + + - name: Failure display otool output + if: ${{ failure() && startsWith(matrix.os, 'macos') }} + run: | + otool -L ${{ github.workspace }}/test/.libs/libbitcoin-server-test + + - name: Failure display DYLD_PRINT_LIBRARIES + if: ${{ failure() && startsWith(matrix.os, 'macos') }} + run: | + DYLD_PRINT_LIBRARIES=1 ${{ github.workspace }}/test/.libs/libbitcoin-server-test + + - name: Failure display pkgconfig + if: ${{ failure() }} + run: | + ls ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib/pkgconfig/ + cat ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib/pkgconfig/*.pc + + cmake: + + strategy: + fail-fast: false + + matrix: + include: + - os: ubuntu-24.04 + cxx: "clang++-16" + link: "dynamic" + optimization: "debug" + assert: "debug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "clang-16" + flags: "-Og -fPIE" + options: "" + packager: "apt" + packages: "" + + - os: ubuntu-24.04 + cxx: "clang++-16" + link: "static" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "--build-icu --with-icu" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "clang-16" + flags: "-Os -fPIE" + options: "" + packager: "apt" + packages: "" + + - os: ubuntu-24.04 + cxx: "g++-12" + link: "dynamic" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "gcc-12" + flags: "-Os -fPIE" + options: "" + packager: "apt" + packages: "" + + - os: ubuntu-24.04 + cxx: "g++-12" + link: "static" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "--build-icu --with-icu" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "gcc-12" + flags: "-Os -fPIE" + options: "" + packager: "apt" + packages: "" + + - os: macos-latest + cxx: "clang++" + link: "dynamic" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "llvm@16" + secp256k1: "--build-secp256k1" + cc: "clang" + flags: "-Os -fPIE" + options: "" + packager: "brew" + packages: "llvm@16 icu4c" + + - os: macos-latest + cxx: "clang++" + link: "static" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "llvm@16" + secp256k1: "--build-secp256k1" + cc: "clang" + flags: "-Os -fvisibility=hidden -fPIE" + options: "" + packager: "brew" + packages: "llvm@16 icu4c" + + + runs-on: ${{ matrix.os }} + + env: + CC: '${{ matrix.cc }}' + CXX: '${{ matrix.cxx }}' + CFLAGS: '${{ matrix.flags }}' + CXXFLAGS: '${{ matrix.flags }}' + CI_REPOSITORY: '${{ github.repository }}' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Prepare toolchain [generic] + run: | + git config --global init.defaultBranch master + + - name: Prepare toolchain [apt] + if: ${{ matrix.packager == 'apt' }} + run: | + sudo apt-get update + sudo apt-get install git build-essential autoconf automake libtool pkg-config ${{ matrix.packages }} + + - name: Prepare toolchain [brew] + if: ${{ matrix.packager == 'brew' }} + run: | + brew install autoconf automake libtool ${{ matrix.packages }} + if [[ -n ${{ matrix.llvm }} ]]; then + echo "PATH=/opt/homebrew/opt/${{ matrix.llvm }}/bin:$PATH" >> $GITHUB_ENV + fi + + - name: Determine CPU flags + shell: bash + run: | + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " sse4_1 ") ]]; then + echo "CPU_SUPPORT_SSE41=-Denable-sse41=on" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " avx " | grep " avx2 ") ]]; then + echo "CPU_SUPPORT_AVX2=-Denable-avx2=on" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " avx512bw ") ]]; then + echo "CPU_SUPPORT_AVX512=-Denable-avx512=on" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " sha_ni ") ]]; then + echo "CPU_SUPPORT_SHANI=-Denable-shani=on" >> $GITHUB_ENV + fi + + if [[ ${{ matrix.detectcpuflags }} == 'detect' ]]; then + echo "CPU_SUPPORTED_FLAGS='$CPU_SUPPORT_SSE41 $CPU_SUPPORT_AVX2 $CPU_SUPPORT_AVX512 $CPU_SUPPORT_SHANI'" >> $GITHUB_ENV + fi + + - name: Denormalize parameterization + shell: bash + run: | + WORKSPACE_SUBPATH="${GITHUB_WORKSPACE%libbitcoin-server}" + echo "LIBBITCOIN_SRC_PATH=${WORKSPACE_SUBPATH}" >> $GITHUB_ENV + if [[ ${{ matrix.packager }} == 'brew' ]]; then + echo "CMAKE_LIBRARY_PATH=/usr/local/lib" >> $GITHUB_ENV + fi + if [[ ${{ matrix.assert }} == 'ndebug' ]]; then + echo "ASSERT_NDEBUG=--enable-ndebug -Denable-ndebug=yes" >> $GITHUB_ENV + else + echo "ASSERT_NDEBUG=--disable-ndebug -Denable-ndebug=no" >> $GITHUB_ENV + fi + if [[ ${{ matrix.link }} == 'dynamic' ]]; then + echo "LINKAGE=--disable-static" >> $GITHUB_ENV + else + echo "LINKAGE=--disable-shared" >> $GITHUB_ENV + fi + if [[ ${{ matrix.link }} == 'dynamic' ]]; then + echo "LDFLAGS=-Wl,-rpath,${WORKSPACE_SUBPATH}prefix/lib" >> $GITHUB_ENV + fi + + - name: Display Compiler details + shell: bash + run: | + ${CC} -v + ${CXX} -v + + - name: Display CPU details + if: ${{ (runner.os == 'Linux') }} + shell: bash + run: | + lscpu + + - name: Execute install-cmake.sh + run: > + ./install-cmake.sh + --build-dir=${{ env.LIBBITCOIN_SRC_PATH }} ${{ matrix.options }} + --prefix=${{ env.LIBBITCOIN_SRC_PATH }}prefix + ${{ env.LINKAGE }} + ${{ env.ASSERT_NDEBUG }} + ${{ env.CPU_SUPPORTED_FLAGS }} + ${{ matrix.boost }} + ${{ matrix.icu }} + ${{ matrix.secp256k1 }} + + - name: Coveralls Calculation + if: ${{ matrix.coverage == 'cov' }} + run: | + lcov --ignore-errors version,gcov,mismatch --directory . --capture --output-file coverage.info + lcov --ignore-errors unused --remove coverage.info "/usr/*" "${{ env.LIBBITCOIN_SRC_PATH }}prefix/*" "${{ github.workspace }}/examples/*" "${{ github.workspace }}/test/*" --output-file coverage.info + lcov --list coverage.info + + - name: Coveralls.io Upload + if: ${{ matrix.coverage == 'cov' }} + uses: coverallsapp/github-action@v2.3.0 + with: + format: lcov + files: "./coverage.info" + github-token: ${{ secrets.github_token }} + + - name: Failure display available binaries + if: ${{ failure() }} + run: | + ls -la /usr/bin + + - name: Failure display selected compiler version + if: ${{ failure() }} + run: | + ${CC} -v + ${CXX} -v + + - name: Failure display default compiler version + if: ${{ failure() }} + run: | + clang -v + gcc -v + + - name: Failure display env + if: ${{ failure() }} + run: | + env + + - name: Failure list libdir + if: ${{ failure() }} + run: | + ls -la ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib + + - name: Failure display boost bootstrap.log [--build-boost] + if: ${{ failure() && (matrix.boost == '--build-boost') }} + run: | + cat ${{ github.workspace }}/build/build-*/bootstrap.log + + + - name: Failure display otool output + if: ${{ failure() && startsWith(matrix.os, 'macos') }} + run: | + otool -L ${{ github.workspace }}/test/.libs/libbitcoin-server-test + + - name: Failure display DYLD_PRINT_LIBRARIES + if: ${{ failure() && startsWith(matrix.os, 'macos') }} + run: | + DYLD_PRINT_LIBRARIES=1 ${{ github.workspace }}/test/.libs/libbitcoin-server-test + + - name: Failure display pkgconfig + if: ${{ failure() }} + run: | + ls ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib/pkgconfig/ + cat ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib/pkgconfig/*.pc + + - name: Failure display cmake specific libraries + if: ${{ failure() }} + run: | + ls ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib/cmake + + - name: Failure display cmake LastTest.log + if: ${{ failure() }} + run: | + cat ${{ github.workspace }}/Testing/Temporary/LastTest.log + + preset: + + strategy: + fail-fast: false + + matrix: + include: + - os: ubuntu-24.04 + preset: "nix-gnu-debug-shared" + cxx: "clang++-16" + link: "dynamic" + optimization: "debug" + assert: "debug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "clang-16" + flags: "-Og -fPIE" + options: "" + packager: "apt" + packages: "" + + - os: ubuntu-24.04 + preset: "nix-gnu-release-static" + cxx: "clang++-16" + link: "static" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "--build-icu --with-icu" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "clang-16" + flags: "-Os -fPIE" + options: "" + packager: "apt" + packages: "" + + - os: ubuntu-24.04 + preset: "nix-gnu-release-shared" + cxx: "g++-12" + link: "dynamic" + optimization: "size" + assert: "ndebug" + coverage: "nocov" + detectcpuflags: "ignore" + boost: "--build-boost" + icu: "" + llvm: "" + secp256k1: "--build-secp256k1" + cc: "gcc-12" + flags: "-Os -fPIE" + options: "" + packager: "apt" + packages: "" + + + runs-on: ${{ matrix.os }} + + env: + CC: '${{ matrix.cc }}' + CXX: '${{ matrix.cxx }}' + CFLAGS: '${{ matrix.flags }}' + CXXFLAGS: '${{ matrix.flags }}' + CI_REPOSITORY: '${{ github.repository }}' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Prepare toolchain [generic] + run: | + git config --global init.defaultBranch master + + - name: Prepare toolchain [apt] + if: ${{ matrix.packager == 'apt' }} + run: | + sudo apt-get update + sudo apt-get install git build-essential autoconf automake libtool pkg-config ${{ matrix.packages }} + + - name: Prepare toolchain [brew] + if: ${{ matrix.packager == 'brew' }} + run: | + brew install autoconf automake libtool ${{ matrix.packages }} + if [[ -n ${{ matrix.llvm }} ]]; then + echo "PATH=/opt/homebrew/opt/${{ matrix.llvm }}/bin:$PATH" >> $GITHUB_ENV + fi + + - name: Determine CPU flags + shell: bash + run: | + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " sse4_1 ") ]]; then + echo "CPU_SUPPORT_SSE41=-Denable-sse41=on" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " avx " | grep " avx2 ") ]]; then + echo "CPU_SUPPORT_AVX2=-Denable-avx2=on" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " avx512bw ") ]]; then + echo "CPU_SUPPORT_AVX512=-Denable-avx512=on" >> $GITHUB_ENV + fi + + if [[ -n $(cat /proc/cpuinfo | grep flags | grep " sha_ni ") ]]; then + echo "CPU_SUPPORT_SHANI=-Denable-shani=on" >> $GITHUB_ENV + fi + + if [[ ${{ matrix.detectcpuflags }} == 'detect' ]]; then + echo "CPU_SUPPORTED_FLAGS='$CPU_SUPPORT_SSE41 $CPU_SUPPORT_AVX2 $CPU_SUPPORT_AVX512 $CPU_SUPPORT_SHANI'" >> $GITHUB_ENV + fi + + - name: Denormalize parameterization + shell: bash + run: | + WORKSPACE_SUBPATH="${GITHUB_WORKSPACE%libbitcoin-server}" + echo "LIBBITCOIN_SRC_PATH=${WORKSPACE_SUBPATH}" >> $GITHUB_ENV + if [[ ${{ matrix.packager }} == 'brew' ]]; then + echo "CMAKE_LIBRARY_PATH=/usr/local/lib" >> $GITHUB_ENV + fi + if [[ ${{ matrix.assert }} == 'ndebug' ]]; then + echo "ASSERT_NDEBUG=--enable-ndebug -Denable-ndebug=yes" >> $GITHUB_ENV + else + echo "ASSERT_NDEBUG=--disable-ndebug -Denable-ndebug=no" >> $GITHUB_ENV + fi + if [[ ${{ matrix.link }} == 'dynamic' ]]; then + echo "LINKAGE=--disable-static" >> $GITHUB_ENV + else + echo "LINKAGE=--disable-shared" >> $GITHUB_ENV + fi + if [[ ${{ matrix.link }} == 'dynamic' ]]; then + echo "LDFLAGS=-Wl,-rpath,${WORKSPACE_SUBPATH}prefix/${{ matrix.preset }}/lib" >> $GITHUB_ENV + fi + + - name: Display Compiler details + shell: bash + run: | + ${CC} -v + ${CXX} -v + + - name: Display CPU details + if: ${{ (runner.os == 'Linux') }} + shell: bash + run: | + lscpu + + - name: Execute install-cmakepresets.sh + run: > + ./install-cmakepresets.sh + --build-dir=${{ env.LIBBITCOIN_SRC_PATH }} ${{ matrix.options }} + --prefix=${{ env.LIBBITCOIN_SRC_PATH }}prefix/${{ matrix.preset }} + --preset=${{ matrix.preset }} + ${{ env.LINKAGE }} + ${{ env.ASSERT_NDEBUG }} + ${{ env.CPU_SUPPORTED_FLAGS }} + ${{ matrix.boost }} + ${{ matrix.icu }} + ${{ matrix.secp256k1 }} + + - name: Coveralls Calculation + if: ${{ matrix.coverage == 'cov' }} + run: | + lcov --ignore-errors version,gcov,mismatch --directory . --capture --output-file coverage.info + lcov --ignore-errors unused --remove coverage.info "/usr/*" "${{ env.LIBBITCOIN_SRC_PATH }}prefix/*" "${{ github.workspace }}/examples/*" "${{ github.workspace }}/test/*" --output-file coverage.info + lcov --list coverage.info + + - name: Coveralls.io Upload + if: ${{ matrix.coverage == 'cov' }} + uses: coverallsapp/github-action@v2.3.0 + with: + format: lcov + files: "./coverage.info" + github-token: ${{ secrets.github_token }} + + - name: Failure display available binaries + if: ${{ failure() }} + run: | + ls -la /usr/bin + + - name: Failure display selected compiler version + if: ${{ failure() }} + run: | + ${CC} -v + ${CXX} -v + + - name: Failure display default compiler version + if: ${{ failure() }} + run: | + clang -v + gcc -v + + - name: Failure display env + if: ${{ failure() }} + run: | + env + + - name: Failure list libdir + if: ${{ failure() }} + run: | + ls -la ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib + + - name: Failure display boost bootstrap.log [--build-boost] + if: ${{ failure() && (matrix.boost == '--build-boost') }} + run: | + cat ${{ github.workspace }}/build/build-*/bootstrap.log + + + - name: Failure display otool output + if: ${{ failure() && startsWith(matrix.os, 'macos') }} + run: | + otool -L ${{ github.workspace }}/test/.libs/libbitcoin-server-test + + - name: Failure display DYLD_PRINT_LIBRARIES + if: ${{ failure() && startsWith(matrix.os, 'macos') }} + run: | + DYLD_PRINT_LIBRARIES=1 ${{ github.workspace }}/test/.libs/libbitcoin-server-test + + - name: Failure display pkgconfig + if: ${{ failure() }} + run: | + ls ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib/pkgconfig/ + cat ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib/pkgconfig/*.pc + + - name: Failure display cmake specific libraries + if: ${{ failure() }} + run: | + ls ${{ env.LIBBITCOIN_SRC_PATH }}prefix/lib/cmake + + - name: Failure display cmake LastTest.log + if: ${{ failure() }} + run: | + cat ${{ github.workspace }}/Testing/Temporary/LastTest.log + + msbuild: + strategy: + fail-fast: false + + matrix: + include: + - os: windows-latest + configuration: "StaticDebug" + platform: "x64" + version: "vs2022" + tests: "*" + + - os: windows-latest + configuration: "StaticRelease" + platform: "x64" + version: "vs2022" + tests: "*" + + runs-on: ${{ matrix.os }} + + steps: + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v2 + with: + msbuild-architecture: x64 + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize SDK + shell: powershell + run: | + try { + Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/p/?LinkId=323507" -OutFile "sdksetup.exe" + + $FeatureList = "OptionId.WindowsDesktopSoftwareDevelopmentKit OptionId.NetFxSoftwareDevelopmentKit" + $Args = "/q /norestart /features $FeatureList" + $setup = Start-Process -PassThru -FilePath "sdksetup.exe" -ArgumentList $Args + + $setup.WaitForExit() + if ($setup.ExitCode -ne 0) { + Write-Host "Test execution failure: " $setup.ExitCode -ForegroundColor Red; + exit $setup.ExitCode; + } + } + catch { + $ERR = $_; + Write-Host "Initialization failure: " $ERR -ForegroundColor Red; + exit $ERR; + } + + - name: Execute build + run: .\build.cmd .. ${{ matrix.platform }} ${{ matrix.configuration }} x64 ${{ matrix.version }} + + - name: Execute tests + shell: powershell + run: | + Write-Host "Locating test executables..." -ForegroundColor Yellow; + $BC_TEST_EXES = @(Get-ChildItem -Path "$env:${{ github.workspace }}\bin" -recurse | Where-Object { $_.Name -eq "libbitcoin-server-test.exe" }); + If ($BC_TEST_EXES.Count -ne 1) { + Write-Host "Failure, invalid count of test executables." -ForegroundColor Red; + exit 1; + } + Write-Host "Found single test executable: " $BC_TEST_EXES.FullName -ForegroundColor Green; + $BC_TEST_SINGLETON = $BC_TEST_EXES.FullName; + Write-Host "Executing $BC_TEST_SINGLETON $env:BOOST_UNIT_TEST_OPTIONS" -ForegroundColor Yellow; + try { + Invoke-Expression "$BC_TEST_SINGLETON --log_level=warning --run_test=${{ matrix.tests }} $env:BOOST_UNIT_TEST_OPTIONS" + } + catch { + $ERR = $_; + Write-Host "Test execution failure: " $ERR -ForegroundColor Red; + exit $ERR; + } + Write-Host "Test execution complete." -ForegroundColor Green; diff --git a/Makefile.am b/Makefile.am index 707b105d..fe039e0e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,11 +51,6 @@ src_libbitcoin_server_la_SOURCES = \ src/services/heartbeat_service.cpp \ src/services/query_service.cpp \ src/services/transaction_service.cpp \ - src/web/block_socket.cpp \ - src/web/default_page_data.cpp \ - src/web/heartbeat_socket.cpp \ - src/web/query_socket.cpp \ - src/web/transaction_socket.cpp \ src/workers/authenticator.cpp \ src/workers/notification_worker.cpp \ src/workers/query_worker.cpp @@ -126,14 +121,6 @@ include_bitcoin_server_services_HEADERS = \ include/bitcoin/server/services/query_service.hpp \ include/bitcoin/server/services/transaction_service.hpp -include_bitcoin_server_webdir = ${includedir}/bitcoin/server/web -include_bitcoin_server_web_HEADERS = \ - include/bitcoin/server/web/block_socket.hpp \ - include/bitcoin/server/web/default_page_data.hpp \ - include/bitcoin/server/web/heartbeat_socket.hpp \ - include/bitcoin/server/web/query_socket.hpp \ - include/bitcoin/server/web/transaction_socket.hpp - include_bitcoin_server_workersdir = ${includedir}/bitcoin/server/workers include_bitcoin_server_workers_HEADERS = \ include/bitcoin/server/workers/authenticator.hpp \ diff --git a/builds/cmake/CMakeLists.txt b/builds/cmake/CMakeLists.txt index 2daabc8e..6d4983a7 100644 --- a/builds/cmake/CMakeLists.txt +++ b/builds/cmake/CMakeLists.txt @@ -148,7 +148,7 @@ endif() # Find boost #------------------------------------------------------------------------------ -find_package( Boost 1.76.0 REQUIRED COMPONENTS +find_package( Boost 1.86.0 REQUIRED COMPONENTS unit_test_framework ) set( boost_unit_test_framework_LIBS "-lboost_unit_test_framework" ) @@ -263,11 +263,6 @@ add_library( ${CANONICAL_LIB_NAME} "../../src/services/heartbeat_service.cpp" "../../src/services/query_service.cpp" "../../src/services/transaction_service.cpp" - "../../src/web/block_socket.cpp" - "../../src/web/default_page_data.cpp" - "../../src/web/heartbeat_socket.cpp" - "../../src/web/query_socket.cpp" - "../../src/web/transaction_socket.cpp" "../../src/workers/authenticator.cpp" "../../src/workers/notification_worker.cpp" "../../src/workers/query_worker.cpp" ) diff --git a/builds/msvc/vs2022/bs/bs.vcxproj b/builds/msvc/vs2022/bs/bs.vcxproj index dbe73723..0bf3d169 100644 --- a/builds/msvc/vs2022/bs/bs.vcxproj +++ b/builds/msvc/vs2022/bs/bs.vcxproj @@ -61,6 +61,54 @@ ReleaseSEXE x64 + + DebugDEXE + ARM + + + ReleaseDEXE + ARM + + + DebugDEXE + ARM64 + + + ReleaseDEXE + ARM64 + + + DebugLEXE + ARM + + + ReleaseLEXE + ARM + + + DebugLEXE + ARM64 + + + ReleaseLEXE + ARM64 + + + DebugSEXE + ARM + + + ReleaseSEXE + ARM + + + DebugSEXE + ARM64 + + + ReleaseSEXE + ARM64 + @@ -86,34 +134,26 @@ - - - - - - - - - + + + + + - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - + + + + + - + diff --git a/builds/msvc/vs2022/bs/packages.config b/builds/msvc/vs2022/bs/packages.config index ab1228ed..1ba18fd0 100644 --- a/builds/msvc/vs2022/bs/packages.config +++ b/builds/msvc/vs2022/bs/packages.config @@ -6,16 +6,12 @@ | --> - - - - - - - - - + + + + + - + diff --git a/builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.props b/builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.props index 77306830..35b507d4 100644 --- a/builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.props +++ b/builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.props @@ -12,7 +12,6 @@ false - BOOST_TEST_DYN_LINK;%(PreprocessorDefinitions) "$(TargetPath)" --log_level=warning --run_test=* --show_progress=no --build_info=yes diff --git a/builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.vcxproj b/builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.vcxproj index b4cd25e1..b9d4fb03 100644 --- a/builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-server-test/libbitcoin-server-test.vcxproj @@ -61,6 +61,54 @@ ReleaseSEXE x64 + + DebugDEXE + ARM + + + ReleaseDEXE + ARM + + + DebugDEXE + ARM64 + + + ReleaseDEXE + ARM64 + + + DebugLEXE + ARM + + + ReleaseLEXE + ARM + + + DebugLEXE + ARM64 + + + ReleaseLEXE + ARM64 + + + DebugSEXE + ARM + + + ReleaseSEXE + ARM + + + DebugSEXE + ARM64 + + + ReleaseSEXE + ARM64 + @@ -79,37 +127,29 @@ - - - - - - - - - + + + + + - + - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - + + + + + - + - + diff --git a/builds/msvc/vs2022/libbitcoin-server-test/packages.config b/builds/msvc/vs2022/libbitcoin-server-test/packages.config index 302b7b5e..cef1f9e0 100644 --- a/builds/msvc/vs2022/libbitcoin-server-test/packages.config +++ b/builds/msvc/vs2022/libbitcoin-server-test/packages.config @@ -6,17 +6,13 @@ | --> - - - - - - - - - + + + + + - + - + diff --git a/builds/msvc/vs2022/libbitcoin-server.sln b/builds/msvc/vs2022/libbitcoin-server.sln index ca69e20b..a4cb6791 100644 --- a/builds/msvc/vs2022/libbitcoin-server.sln +++ b/builds/msvc/vs2022/libbitcoin-server.sln @@ -15,6 +15,10 @@ Global StaticDebug|x64 = StaticDebug|x64 StaticRelease|Win32 = StaticRelease|Win32 StaticRelease|x64 = StaticRelease|x64 + StaticDebug|ARM = StaticDebug|ARM + StaticDebug|ARM64 = StaticDebug|ARM64 + StaticRelease|ARM = StaticRelease|ARM + StaticRelease|ARM64 = StaticRelease|ARM64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticDebug|Win32.ActiveCfg = DebugLIB|Win32 @@ -25,6 +29,14 @@ Global {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticRelease|Win32.Build.0 = ReleaseLIB|Win32 {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticRelease|x64.ActiveCfg = ReleaseLIB|x64 {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticRelease|x64.Build.0 = ReleaseLIB|x64 + {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticDebug|ARM.ActiveCfg = DebugLIB|ARM + {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticDebug|ARM.Build.0 = DebugLIB|ARM + {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticDebug|ARM64.ActiveCfg = DebugLIB|ARM64 + {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticDebug|ARM64.Build.0 = DebugLIB|ARM64 + {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticRelease|ARM.ActiveCfg = ReleaseLIB|ARM + {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticRelease|ARM.Build.0 = ReleaseLIB|ARM + {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticRelease|ARM64.ActiveCfg = ReleaseLIB|ARM64 + {73CE0AC2-ECB2-4E8D-A136-17840C0371A0}.StaticRelease|ARM64.Build.0 = ReleaseLIB|ARM64 {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticDebug|Win32.ActiveCfg = DebugSEXE|Win32 {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticDebug|Win32.Build.0 = DebugSEXE|Win32 {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticDebug|x64.ActiveCfg = DebugSEXE|x64 @@ -33,6 +45,14 @@ Global {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticRelease|Win32.Build.0 = ReleaseSEXE|Win32 {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticRelease|x64.ActiveCfg = ReleaseSEXE|x64 {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticRelease|x64.Build.0 = ReleaseSEXE|x64 + {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticDebug|ARM.ActiveCfg = DebugSEXE|ARM + {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticDebug|ARM.Build.0 = DebugSEXE|ARM + {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticDebug|ARM64.ActiveCfg = DebugSEXE|ARM64 + {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticDebug|ARM64.Build.0 = DebugSEXE|ARM64 + {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticRelease|ARM.ActiveCfg = ReleaseSEXE|ARM + {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticRelease|ARM.Build.0 = ReleaseSEXE|ARM + {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticRelease|ARM64.ActiveCfg = ReleaseSEXE|ARM64 + {66A0E586-2E3A-448F-BCD0-348AFEB0D5EA}.StaticRelease|ARM64.Build.0 = ReleaseSEXE|ARM64 {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticDebug|Win32.ActiveCfg = DebugSEXE|Win32 {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticDebug|Win32.Build.0 = DebugSEXE|Win32 {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticDebug|x64.ActiveCfg = DebugSEXE|x64 @@ -41,6 +61,14 @@ Global {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticRelease|Win32.Build.0 = ReleaseSEXE|Win32 {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticRelease|x64.ActiveCfg = ReleaseSEXE|x64 {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticRelease|x64.Build.0 = ReleaseSEXE|x64 + {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticDebug|ARM.ActiveCfg = DebugSEXE|ARM + {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticDebug|ARM.Build.0 = DebugSEXE|ARM + {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticDebug|ARM64.ActiveCfg = DebugSEXE|ARM64 + {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticDebug|ARM64.Build.0 = DebugSEXE|ARM64 + {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticRelease|ARM.ActiveCfg = ReleaseSEXE|ARM + {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticRelease|ARM.Build.0 = ReleaseSEXE|ARM + {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticRelease|ARM64.ActiveCfg = ReleaseSEXE|ARM64 + {F45B7D90-90BC-41EF-9AD1-9B29256A09FE}.StaticRelease|ARM64.Build.0 = ReleaseSEXE|ARM64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj b/builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj index be13c913..dfc02599 100644 --- a/builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj @@ -59,6 +59,54 @@ ReleaseLIB x64 + + + DebugDLL + ARM + + + ReleaseDLL + ARM + + + DebugDLL + ARM64 + + + ReleaseDLL + ARM64 + + + DebugLTCG + ARM + + + ReleaseLTCG + ARM + + + DebugLTCG + ARM64 + + + ReleaseLTCG + ARM64 + + + DebugLIB + ARM + + + ReleaseLIB + ARM + + + DebugLIB + ARM64 + + + ReleaseLIB + ARM64 @@ -89,11 +137,6 @@ - - - - - @@ -118,11 +161,6 @@ - - - - - @@ -137,34 +175,26 @@ - - - - - - - - - + + + + + - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - + + + + + - + diff --git a/builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj.filters index 237977f6..d7270d58 100644 --- a/builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-server/libbitcoin-server.vcxproj.filters @@ -8,31 +8,28 @@ - {73CE0AC2-ECB2-4E8D-0000-000000000006} + {73CE0AC2-ECB2-4E8D-0000-000000000005} - {73CE0AC2-ECB2-4E8D-0000-000000000007} + {73CE0AC2-ECB2-4E8D-0000-000000000006} - {73CE0AC2-ECB2-4E8D-0000-000000000008} + {73CE0AC2-ECB2-4E8D-0000-000000000007} - {73CE0AC2-ECB2-4E8D-0000-000000000009} + {73CE0AC2-ECB2-4E8D-0000-000000000008} - {73CE0AC2-ECB2-4E8D-0000-00000000000A} + {73CE0AC2-ECB2-4E8D-0000-000000000009} - {73CE0AC2-ECB2-4E8D-0000-00000000000B} - - - {73CE0AC2-ECB2-4E8D-0000-00000000000C} + {73CE0AC2-ECB2-4E8D-0000-00000000000A} - {73CE0AC2-ECB2-4E8D-0000-00000000000D} + {73CE0AC2-ECB2-4E8D-0000-00000000000B} - {73CE0AC2-ECB2-4E8D-0000-00000000000E} + {73CE0AC2-ECB2-4E8D-0000-00000000000C} {73CE0AC2-ECB2-4E8D-0000-000000000000} @@ -46,11 +43,8 @@ {73CE0AC2-ECB2-4E8D-0000-000000000003} - - {73CE0AC2-ECB2-4E8D-0000-000000000004} - - {73CE0AC2-ECB2-4E8D-0000-000000000005} + {73CE0AC2-ECB2-4E8D-0000-000000000004} @@ -102,21 +96,6 @@ src - - src\web - - - src\web - - - src\web - - - src\web - - - src\web - src\workers @@ -185,21 +164,6 @@ include\bitcoin\server - - include\bitcoin\server\web - - - include\bitcoin\server\web - - - include\bitcoin\server\web - - - include\bitcoin\server\web - - - include\bitcoin\server\web - include\bitcoin\server\workers diff --git a/builds/msvc/vs2022/libbitcoin-server/packages.config b/builds/msvc/vs2022/libbitcoin-server/packages.config index ab1228ed..1ba18fd0 100644 --- a/builds/msvc/vs2022/libbitcoin-server/packages.config +++ b/builds/msvc/vs2022/libbitcoin-server/packages.config @@ -6,16 +6,12 @@ | --> - - - - - - - - - + + + + + - + diff --git a/builds/msvc/vs2022/libbitcoin-system.import.props b/builds/msvc/vs2022/libbitcoin-system.import.props index bb11eeb3..662fa27e 100644 --- a/builds/msvc/vs2022/libbitcoin-system.import.props +++ b/builds/msvc/vs2022/libbitcoin-system.import.props @@ -50,6 +50,8 @@ WITH_ICU;WIN32_LEAN_AND_MEAN;NOMINMAX;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) + + BOOST_JSON_NO_LIB;BOOST_CONTAINER_NO_LIB;%(PreprocessorDefinitions) BC_STATIC;%(PreprocessorDefinitions) _CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions) diff --git a/configure.ac b/configure.ac index dd8de5cc..9d9792bb 100644 --- a/configure.ac +++ b/configure.ac @@ -236,17 +236,17 @@ AS_CASE([${CC}], [*], # Check dependencies. #============================================================================== -# Require Boost of at least version 1.76.0 and output ${boost_CPPFLAGS/LDFLAGS}. +# Require Boost of at least version 1.86.0 and output ${boost_CPPFLAGS/LDFLAGS}. #------------------------------------------------------------------------------ AS_CASE([${CC}], [*], - [AX_BOOST_BASE([1.76.0], + [AX_BOOST_BASE([1.86.0], [AC_SUBST([boost_CPPFLAGS], [${BOOST_CPPFLAGS}]) AC_SUBST([boost_ISYS_CPPFLAGS], [`echo ${BOOST_CPPFLAGS} | $SED s/^-I/-isystem/g | $SED s/' -I'/' -isystem'/g`]) AC_SUBST([boost_LDFLAGS], [${BOOST_LDFLAGS}]) AC_MSG_NOTICE([boost_CPPFLAGS : ${boost_CPPFLAGS}]) AC_MSG_NOTICE([boost_ISYS_CPPFLAGS : ${boost_ISYS_CPPFLAGS}]) AC_MSG_NOTICE([boost_LDFLAGS : ${boost_LDFLAGS}])], - [AC_MSG_ERROR([Boost 1.76.0 or later is required but was not found.])])]) + [AC_MSG_ERROR([Boost 1.86.0 or later is required but was not found.])])]) AS_CASE([${enable_isystem}],[yes], [AC_SUBST([boost_BUILD_CPPFLAGS], [${boost_ISYS_CPPFLAGS}])], diff --git a/console/executor.cpp b/console/executor.cpp index 86a37e3e..865ad1a9 100644 --- a/console/executor.cpp +++ b/console/executor.cpp @@ -19,9 +19,7 @@ #include "executor.hpp" #include -#include #include -#include #include #include #include diff --git a/console/executor.hpp b/console/executor.hpp index a87ecf59..740c5b46 100644 --- a/console/executor.hpp +++ b/console/executor.hpp @@ -20,7 +20,6 @@ #define LIBBITCOIN_SERVER_EXECUTOR_HPP #include -#include #include #include @@ -72,16 +71,16 @@ class executor bool run(); // Termination state. - static std::promise stopping_; + static std::promise stopping_{}; parser& metadata_; std::ostream& output_; std::ostream& error_; network::logger log_{}; std::promise stopped_{}; - server_node::ptr node_; - server_node::store store_; - server_node::query query_; + server_node::ptr node_{}; + server_node::store store_{}; + server_node::query query_{}; }; // Localizable messages. diff --git a/console/main.cpp b/console/main.cpp index b5d06249..a47b5a54 100644 --- a/console/main.cpp +++ b/console/main.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) * * This file is part of libbitcoin. * @@ -16,32 +16,99 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#include +#include +#include #include #include "executor.hpp" +////// This is some experimental code to explore emission of win32 stack dump. +////#ifdef HAVE_MSC +////#include "stack_trace.hpp" + +namespace libbitcoin { +namespace system { + std::istream& cin = cin_stream(); + std::ostream& cout = cout_stream(); + std::ostream& cerr = cerr_stream(); + int main(int argc, char* argv[]); +} // namespace system +} // namespace libbitcoin + +namespace bc = libbitcoin; +////std::filesystem::path symbols_path{}; +//// +////int wmain(int argc, wchar_t* argv[]) +////{ +//// __try +//// { +//// return bc::system::call_utf8_main(argc, argv, &bc::system::main); +//// } +//// __except (dump_stack_trace(GetExceptionCode(), GetExceptionInformation())) +//// { +//// return -1; +//// } +////} +//// +////// This is invoked by dump_stack_trace. +////void handle_stack_trace(const std::string& trace) +////{ +//// if (trace.empty()) +//// { +//// bc::system::cout << "<>" << std::endl; +//// return; +//// } +//// +//// bc::system::cout << "<>" << std::endl; +//// bc::system::cout << trace << std::endl; +//// bc::system::cout << "<>" << std::endl; +////} +//// +////// This is invoked by dump_stack_trace. +////std::wstring pdb_path() +////{ +//// return bc::system::to_extended_path(symbols_path); +////} +//// +////#else BC_USE_LIBBITCOIN_MAIN +////#endif -/** - * Invoke this program with the raw arguments provided on the command line. - * All console input and output streams for the application originate here. - * @param argc The number of elements in the argv array. - * @param argv The array of arguments, including the process. - * @return The numeric result to return via console exit. - */ +/// Invoke this program with the raw arguments provided on the command line. +/// All console input and output streams for the application originate here. int bc::system::main(int argc, char* argv[]) { using namespace bc; using namespace bc::server; using namespace bc::system; + // en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio + std::ios_base::sync_with_stdio(false); + set_utf8_stdio(); - bc::server::parser metadata(config::settings::mainnet); + parser metadata(chain::selection::mainnet); const auto& args = const_cast(argv); if (!metadata.parse(argc, args, cerr)) - return console_result::failure; + return -1; + +////#if defined(HAVE_MSC) +//// symbols_path = metadata.configured.log.symbols; +////#endif + +// requires _WIN32_WINNT set to 0x0602 (defaults 0x0602 in vc++ 2022). +#if defined(HAVE_MSC) && defined(MEMORY_PRIORITY_INFORMATION) + + // Set low memory priority on the current process. + const MEMORY_PRIORITY_INFORMATION priority{ MEMORY_PRIORITY_LOW }; + SetProcessInformation( + GetCurrentProcess(), + ProcessMemoryPriority, + &priority, + sizeof(priority)); + +#endif executor host(metadata, cin, cout, cerr); - return host.menu() ? console_result::okay : console_result::failure; + ////return host.dispatch() ? 0 : -1; + return host.menu() ? 0 : -1; } diff --git a/include/bitcoin/server.hpp b/include/bitcoin/server.hpp index eff1eef5..59a46f04 100644 --- a/include/bitcoin/server.hpp +++ b/include/bitcoin/server.hpp @@ -34,11 +34,6 @@ #include #include #include -#include -#include -#include -#include -#include #include #include #include diff --git a/include/bitcoin/server/configuration.hpp b/include/bitcoin/server/configuration.hpp index b91bd38c..1e2434ca 100644 --- a/include/bitcoin/server/configuration.hpp +++ b/include/bitcoin/server/configuration.hpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) * * This file is part of libbitcoin. * @@ -21,35 +21,52 @@ #include #include -#include #include #include namespace libbitcoin { namespace server { -// Not localizable. -#define BS_HELP_VARIABLE "help" -#define BS_SETTINGS_VARIABLE "settings" -#define BS_VERSION_VARIABLE "version" - -// This must be lower case but the env var part can be any case. -#define BS_CONFIG_VARIABLE "config" - -// This must match the case of the env var. -#define BS_ENVIRONMENT_VARIABLE_PREFIX "BS_" - -/// Full server node configuration, thread safe. +/// Server configuration, thread safe. class BCS_API configuration - : public node::configuration { public: - configuration(system::settings context); + DEFAULT_COPY_MOVE_DESTRUCT(configuration); + + configuration(system::chain::selection context) NOEXCEPT; + + /// Environment. + std::filesystem::path file{}; + + /// Information. + bool help{}; + bool hardware{}; + bool settings{}; + bool version{}; + + /// Actions. + bool newstore{}; + bool backup{}; + bool restore{}; + + /// Chain scans. + bool flags{}; + bool information{}; + bool slabs{}; + bool buckets{}; + bool collisions{}; + + /// Ad-hoc Testing. + bool test{}; + bool write{}; /// Settings. - bc::server::settings server; - bc::protocol::settings protocol; - bc::blockchain::settings blockchain; + log::settings log; + server::settings server; + node::settings node; + network::settings network; + database::settings database; + system::settings bitcoin; }; } // namespace server diff --git a/include/bitcoin/server/define.hpp b/include/bitcoin/server/define.hpp index 62f73cad..5aba1802 100644 --- a/include/bitcoin/server/define.hpp +++ b/include/bitcoin/server/define.hpp @@ -42,12 +42,12 @@ #define LOG_SERVER_HTTP "http" // Avoid namespace conflict between boost::placeholders and std::placeholders. -#define BOOST_BIND_NO_PLACEHOLDERS +////#define BOOST_BIND_NO_PLACEHOLDERS -#include -#include -#include -#include -#include +////#include +////#include +////#include +////#include +////#include #endif diff --git a/include/bitcoin/server/interface/blockchain.hpp b/include/bitcoin/server/interface/blockchain.hpp index f9e914f7..ea428bc7 100644 --- a/include/bitcoin/server/interface/blockchain.hpp +++ b/include/bitcoin/server/interface/blockchain.hpp @@ -19,9 +19,6 @@ #ifndef LIBBITCOIN_SERVER_BLOCKCHAIN_HPP #define LIBBITCOIN_SERVER_BLOCKCHAIN_HPP -#include -#include -#include #include #include #include diff --git a/include/bitcoin/server/messages/message.hpp b/include/bitcoin/server/messages/message.hpp index e39a7d51..3b80e435 100644 --- a/include/bitcoin/server/messages/message.hpp +++ b/include/bitcoin/server/messages/message.hpp @@ -19,8 +19,6 @@ #ifndef LIBBITCOIN_SERVER_MESSAGE #define LIBBITCOIN_SERVER_MESSAGE -#include -#include #include #include #include diff --git a/include/bitcoin/server/messages/route.hpp b/include/bitcoin/server/messages/route.hpp index 70a99021..23041e16 100644 --- a/include/bitcoin/server/messages/route.hpp +++ b/include/bitcoin/server/messages/route.hpp @@ -19,8 +19,6 @@ #ifndef LIBBITCOIN_SERVER_ROUTE #define LIBBITCOIN_SERVER_ROUTE -#include -#include #include #include diff --git a/include/bitcoin/server/messages/subscription.hpp b/include/bitcoin/server/messages/subscription.hpp index b547bad3..ba82ddb2 100644 --- a/include/bitcoin/server/messages/subscription.hpp +++ b/include/bitcoin/server/messages/subscription.hpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/include/bitcoin/server/parser.hpp b/include/bitcoin/server/parser.hpp index 7ffb5c44..d2702884 100644 --- a/include/bitcoin/server/parser.hpp +++ b/include/bitcoin/server/parser.hpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) * * This file is part of libbitcoin. * @@ -19,37 +19,64 @@ #ifndef LIBBITCOIN_SERVER_PARSER_HPP #define LIBBITCOIN_SERVER_PARSER_HPP -#include #include #include #include +// Not localizable. +#define BS_HELP_VARIABLE "help" +#define BS_HARDWARE_VARIABLE "hardware" +#define BS_SETTINGS_VARIABLE "settings" +#define BS_VERSION_VARIABLE "version" +#define BS_NEWSTORE_VARIABLE "newstore" +#define BS_BACKUP_VARIABLE "backup" +#define BS_RESTORE_VARIABLE "restore" + +#define BS_FLAGS_VARIABLE "flags" +#define BS_SLABS_VARIABLE "slabs" +#define BS_BUCKETS_VARIABLE "buckets" +#define BS_COLLISIONS_VARIABLE "collisions" +#define BS_INFORMATION_VARIABLE "information" + +#define BS_READ_VARIABLE "test" +#define BS_WRITE_VARIABLE "write" + +// This must be lower case but the env var part can be any case. +#define BS_CONFIG_VARIABLE "config" + +// This must match the case of the env var. +#define BS_ENVIRONMENT_VARIABLE_PREFIX "BS_" + namespace libbitcoin { namespace server { +// TODO: derive from node parser and add new settings. +// TODO: implement parsers in downlevel libraries. + /// Parse configurable values from environment variables, settings file, and /// command line positional and non-positional options. class BCS_API parser : public system::config::parser { public: - parser(system::settings context); - parser(const configuration& defaults); - - /// Parse all configuration into member settings. - virtual bool parse(int argc, const char* argv[], std::ostream& error); + parser(system::chain::selection context) NOEXCEPT; + parser(const configuration& defaults) NOEXCEPT; /// Load command line options (named). - virtual options_metadata load_options(); + virtual options_metadata load_options() THROWS; /// Load command line arguments (positional). - virtual arguments_metadata load_arguments(); + virtual arguments_metadata load_arguments() THROWS; + + /// Load environment variable settings. + virtual options_metadata load_environment() THROWS; /// Load configuration file settings. - virtual options_metadata load_settings(); + virtual options_metadata load_settings() THROWS; - /// Load environment variable settings. - virtual options_metadata load_environment(); + /// Parse all configuration into member settings. + virtual bool parse(int argc, const char* argv[], + std::ostream& error) THROWS; /// The populated configuration settings values. configuration configured; diff --git a/include/bitcoin/server/server_node.hpp b/include/bitcoin/server/server_node.hpp index c0dccdf9..d6a82169 100644 --- a/include/bitcoin/server/server_node.hpp +++ b/include/bitcoin/server/server_node.hpp @@ -19,7 +19,6 @@ #ifndef LIBBITCOIN_SERVER_SERVER_NODE_HPP #define LIBBITCOIN_SERVER_SERVER_NODE_HPP -#include #include #include #include diff --git a/include/bitcoin/server/services/block_service.hpp b/include/bitcoin/server/services/block_service.hpp index 4779cb83..c1f5bda1 100644 --- a/include/bitcoin/server/services/block_service.hpp +++ b/include/bitcoin/server/services/block_service.hpp @@ -19,10 +19,7 @@ #ifndef LIBBITCOIN_SERVER_BLOCK_SERVICE_HPP #define LIBBITCOIN_SERVER_BLOCK_SERVICE_HPP -#include -#include #include -#include #include #include #include diff --git a/include/bitcoin/server/services/heartbeat_service.hpp b/include/bitcoin/server/services/heartbeat_service.hpp index a00d1d79..c1e636c6 100644 --- a/include/bitcoin/server/services/heartbeat_service.hpp +++ b/include/bitcoin/server/services/heartbeat_service.hpp @@ -19,9 +19,7 @@ #ifndef LIBBITCOIN_SERVER_HEARTBEAT_SERVICE_HPP #define LIBBITCOIN_SERVER_HEARTBEAT_SERVICE_HPP -#include #include -#include #include #include #include diff --git a/include/bitcoin/server/services/query_service.hpp b/include/bitcoin/server/services/query_service.hpp index 81a5b307..20dd2a51 100644 --- a/include/bitcoin/server/services/query_service.hpp +++ b/include/bitcoin/server/services/query_service.hpp @@ -20,7 +20,6 @@ #define LIBBITCOIN_SERVER_QUERY_SERVICE_HPP #include -#include #include #include #include diff --git a/include/bitcoin/server/services/transaction_service.hpp b/include/bitcoin/server/services/transaction_service.hpp index 0a601952..12f2af9c 100644 --- a/include/bitcoin/server/services/transaction_service.hpp +++ b/include/bitcoin/server/services/transaction_service.hpp @@ -19,9 +19,7 @@ #ifndef LIBBITCOIN_SERVER_TRANSACTION_SERVICE_HPP #define LIBBITCOIN_SERVER_TRANSACTION_SERVICE_HPP -#include #include -#include #include #include #include diff --git a/include/bitcoin/server/settings.hpp b/include/bitcoin/server/settings.hpp index ae1ad16b..424a34e4 100644 --- a/include/bitcoin/server/settings.hpp +++ b/include/bitcoin/server/settings.hpp @@ -19,9 +19,7 @@ #ifndef LIBBITCOIN_SERVER_SETTINGS_HPP #define LIBBITCOIN_SERVER_SETTINGS_HPP -#include -#include -#include +#include #include #include #include @@ -34,21 +32,18 @@ class BCS_API settings { public: settings(); - settings(system::settings context); + settings(system::chain::selection context); - /// Helpers. - network::asio::steady_timer heartbeat_interval() const; - network::asio::steady_timer subscription_expiration() const; + /// Times. + std::chrono::steady_clock::duration heartbeat_service() const; + std::chrono::steady_clock::duration subscription_expiration() const; + + /// Endpoints. const protocol::endpoint& zeromq_query_endpoint(bool secure) const; const protocol::endpoint& zeromq_heartbeat_endpoint(bool secure) const; const protocol::endpoint& zeromq_block_endpoint(bool secure) const; const protocol::endpoint& zeromq_transaction_endpoint(bool secure) const; - const protocol::endpoint& websockets_query_endpoint(bool secure) const; - const protocol::endpoint& websockets_heartbeat_endpoint(bool secure) const; - const protocol::endpoint& websockets_block_endpoint(bool secure) const; - const protocol::endpoint& websockets_transaction_endpoint(bool secure) const; - /// [server] bool priority; bool secure_only; @@ -58,35 +53,24 @@ class BCS_API settings uint32_t heartbeat_service_seconds; bool block_service_enabled; bool transaction_service_enabled; - network::config::authorities client_addresses; - network::config::authorities blacklists; - - /// [websockets] - protocol::endpoint websockets_secure_query_endpoint; - protocol::endpoint websockets_secure_heartbeat_endpoint; - protocol::endpoint websockets_secure_block_endpoint; - protocol::endpoint websockets_secure_transaction_endpoint; - - protocol::endpoint websockets_public_query_endpoint; - protocol::endpoint websockets_public_heartbeat_endpoint; - protocol::endpoint websockets_public_block_endpoint; - protocol::endpoint websockets_public_transaction_endpoint; - - bool websockets_enabled; + protocol::authorities clients{}; + protocol::authorities blacklists{}; - /// [zeromq] + /// [zeromq] secure protocol::endpoint zeromq_secure_query_endpoint; protocol::endpoint zeromq_secure_heartbeat_endpoint; protocol::endpoint zeromq_secure_block_endpoint; protocol::endpoint zeromq_secure_transaction_endpoint; + /// [zeromq] clear protocol::endpoint zeromq_public_query_endpoint; protocol::endpoint zeromq_public_heartbeat_endpoint; protocol::endpoint zeromq_public_block_endpoint; protocol::endpoint zeromq_public_transaction_endpoint; - protocol::sodium zeromq_server_private_key; - protocol::sodium::list zeromq_client_public_keys; + /// [zeromq] keys + protocol::sodium zeromq_server_private_key{}; + protocol::sodiums zeromq_client_public_keys{}; }; } // namespace server diff --git a/include/bitcoin/server/web/block_socket.hpp b/include/bitcoin/server/web/block_socket.hpp deleted file mode 100644 index a145e248..00000000 --- a/include/bitcoin/server/web/block_socket.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#ifndef LIBBITCOIN_SERVER_WEB_BLOCK_SOCKET_HPP -#define LIBBITCOIN_SERVER_WEB_BLOCK_SOCKET_HPP - -#include -#include -#include - -namespace libbitcoin { -namespace server { - -class server_node; - -// This class is thread safe. -// Subscribe to block acceptances from a dedicated socket endpoint. -class BCS_API block_socket - : public bc::protocol::http::socket -{ -public: - typedef std::shared_ptr ptr; - - /// Construct a block socket service endpoint. - block_socket(bc::protocol::zmq::context& context, server_node& node, - bool secure); - -protected: - // Implement the service. - virtual void work() override; - - virtual const bc::protocol::endpoint& zeromq_endpoint() const override; - virtual const bc::protocol::endpoint& websocket_endpoint() const override; - -private: - bool handle_block(bc::protocol::zmq::socket& subscriber); - - const bc::server::settings& settings_; - const bc::protocol::settings& protocol_settings_; -}; - -} // namespace server -} // namespace libbitcoin - -#endif diff --git a/include/bitcoin/server/web/default_page_data.hpp b/include/bitcoin/server/web/default_page_data.hpp deleted file mode 100644 index 171fe130..00000000 --- a/include/bitcoin/server/web/default_page_data.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#ifndef LIBBITCOIN_SERVER_WEB_DEFAULT_PAGE_DATA_HPP -#define LIBBITCOIN_SERVER_WEB_DEFAULT_PAGE_DATA_HPP - -#include -#include - -namespace libbitcoin { -namespace server { - -/// Given endpoints for each web service based on user configuration, -/// we can generate default page data. -std::string get_default_page_data(const bc::system::config::endpoint& query, - const bc::system::config::endpoint& heartbeat, - const bc::system::config::endpoint& block, - const bc::system::config::endpoint& transaction); - -} // namespace server -} // namespace libbitcoin - -#endif diff --git a/include/bitcoin/server/web/heartbeat_socket.hpp b/include/bitcoin/server/web/heartbeat_socket.hpp deleted file mode 100644 index b016c517..00000000 --- a/include/bitcoin/server/web/heartbeat_socket.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#ifndef LIBBITCOIN_SERVER_WEB_HEARTBEAT_SOCKET_HPP -#define LIBBITCOIN_SERVER_WEB_HEARTBEAT_SOCKET_HPP - -#include -#include -#include - -namespace libbitcoin { -namespace server { - -class server_node; - -// This class is thread safe. -// Subscribe to a pulse from a dedicated socket endpoint. -class BCS_API heartbeat_socket - : public bc::protocol::http::socket -{ -public: - typedef std::shared_ptr ptr; - - /// Construct a heartbeat socket service endpoint. - heartbeat_socket(bc::protocol::zmq::context& context, server_node& node, - bool secure); - -protected: - - // Implement the service. - virtual void work() override; - - virtual const bc::protocol::endpoint& zeromq_endpoint() const override; - virtual const bc::protocol::endpoint& websocket_endpoint() const override; - -private: - bool handle_heartbeat(bc::protocol::zmq::socket& subscriber); - - const bc::server::settings& settings_; - const bc::protocol::settings& protocol_settings_; -}; - -} // namespace server -} // namespace libbitcoin - -#endif diff --git a/include/bitcoin/server/web/query_socket.hpp b/include/bitcoin/server/web/query_socket.hpp deleted file mode 100644 index d5796044..00000000 --- a/include/bitcoin/server/web/query_socket.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#ifndef LIBBITCOIN_SERVER_WEB_QUERY_SOCKET_HPP -#define LIBBITCOIN_SERVER_WEB_QUERY_SOCKET_HPP - -#include -#include -#include - -namespace libbitcoin { -namespace server { - -class server_node; - -// This class is thread safe. -// Submit queries and address subscriptions and receive address -// notifications on a dedicated socket endpoint. -class BCS_API query_socket - : public bc::protocol::http::socket -{ -public: - typedef std::shared_ptr ptr; - - /// Construct a query socket service endpoint. - query_socket(bc::protocol::zmq::context& context, server_node& node, - bool secure); - -protected: - // Implement the socket. - virtual void work() override; - - virtual bool start_websocket_handler() override; - - // Initialize the query specific zmq socket. - virtual void handle_websockets() override; - - virtual const system::config::endpoint& zeromq_endpoint() const override; - virtual const system::config::endpoint& websocket_endpoint() const override; - virtual const std::shared_ptr service() - const override; - - const system::config::endpoint& query_endpoint() const; - -private: - bool handle_query(bc::protocol::zmq::socket& dealer); - - const bc::server::settings& settings_; - const bc::protocol::settings& protocol_settings_; - std::shared_ptr service_; -}; - -} // namespace server -} // namespace libbitcoin - -#endif diff --git a/include/bitcoin/server/web/transaction_socket.hpp b/include/bitcoin/server/web/transaction_socket.hpp deleted file mode 100644 index 2e639693..00000000 --- a/include/bitcoin/server/web/transaction_socket.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#ifndef LIBBITCOIN_SERVER_WEB_TRANSACTION_SOCKET_HPP -#define LIBBITCOIN_SERVER_WEB_TRANSACTION_SOCKET_HPP - -#include -#include -#include - -namespace libbitcoin { -namespace server { - -class server_node; - -// This class is thread safe. -// Subscribe to tx acceptances into the pool from a dedicated socket endpoint. -class BCS_API transaction_socket - : public bc::protocol::http::socket -{ -public: - typedef std::shared_ptr ptr; - - /// Construct a transaction socket service endpoint. - transaction_socket(bc::protocol::zmq::context& context, server_node& node, - bool secure); - -protected: - - // Implement the service. - virtual void work() override; - - virtual const bc::protocol::endpoint& zeromq_endpoint() const override; - virtual const bc::protocol::endpoint& websocket_endpoint() const override; - -private: - bool handle_transaction(bc::protocol::zmq::socket& subscriber); - - const bc::server::settings& settings_; - const bc::protocol::settings& protocol_settings_; -}; - -} // namespace server -} // namespace libbitcoin - -#endif diff --git a/include/bitcoin/server/workers/notification_worker.hpp b/include/bitcoin/server/workers/notification_worker.hpp index d7b0d003..5fdec84c 100644 --- a/include/bitcoin/server/workers/notification_worker.hpp +++ b/include/bitcoin/server/workers/notification_worker.hpp @@ -20,10 +20,7 @@ #define LIBBITCOIN_SERVER_NOTIFICATION_WORKER_HPP #include -#include -#include #include -#include #include #include #include diff --git a/include/bitcoin/server/workers/query_worker.hpp b/include/bitcoin/server/workers/query_worker.hpp index 3eef9a7f..4ca19052 100644 --- a/include/bitcoin/server/workers/query_worker.hpp +++ b/include/bitcoin/server/workers/query_worker.hpp @@ -20,8 +20,6 @@ #define LIBBITCOIN_SERVER_QUERY_WORKER_HPP #include -#include -#include #include #include #include diff --git a/install-cmake.sh b/install-cmake.sh index c8e410d0..416e2b0b 100755 --- a/install-cmake.sh +++ b/install-cmake.sh @@ -79,8 +79,8 @@ ZMQ_ARCHIVE="zeromq-4.3.5.tar.gz" # Boost archive. #------------------------------------------------------------------------------ -BOOST_URL="https://archives.boost.io/release/1.78.0/source/boost_1_78_0.tar.bz2" -BOOST_ARCHIVE="boost_1_78_0.tar.bz2" +BOOST_URL="https://archives.boost.io/release/1.86.0/source/boost_1_86_0.tar.bz2" +BOOST_ARCHIVE="boost_1_86_0.tar.bz2" # Define utility functions. @@ -1053,13 +1053,10 @@ ICU_OPTIONS=( # Define boost options. #------------------------------------------------------------------------------ BOOST_OPTIONS=( -"--with-chrono" \ "--with-iostreams" \ -"--with-json" \ "--with-locale" \ "--with-program_options" \ "--with-regex" \ -"--with-system" \ "--with-thread" \ "--with-test") diff --git a/install-cmakepresets.sh b/install-cmakepresets.sh index 2dc60ab4..67751889 100755 --- a/install-cmakepresets.sh +++ b/install-cmakepresets.sh @@ -1109,13 +1109,10 @@ ICU_OPTIONS=( # Define boost options. #------------------------------------------------------------------------------ BOOST_OPTIONS=( -"--with-chrono" \ "--with-iostreams" \ -"--with-json" \ "--with-locale" \ "--with-program_options" \ "--with-regex" \ -"--with-system" \ "--with-thread" \ "--with-test") diff --git a/install.sh b/install.sh index c5b89e84..b63b40c3 100755 --- a/install.sh +++ b/install.sh @@ -79,8 +79,8 @@ ZMQ_ARCHIVE="zeromq-4.3.5.tar.gz" # Boost archive. #------------------------------------------------------------------------------ -BOOST_URL="https://archives.boost.io/release/1.78.0/source/boost_1_78_0.tar.bz2" -BOOST_ARCHIVE="boost_1_78_0.tar.bz2" +BOOST_URL="https://archives.boost.io/release/1.86.0/source/boost_1_86_0.tar.bz2" +BOOST_ARCHIVE="boost_1_86_0.tar.bz2" # Define utility functions. @@ -927,13 +927,10 @@ ICU_OPTIONS=( # Define boost options. #------------------------------------------------------------------------------ BOOST_OPTIONS=( -"--with-chrono" \ "--with-iostreams" \ -"--with-json" \ "--with-locale" \ "--with-program_options" \ "--with-regex" \ -"--with-system" \ "--with-thread" \ "--with-test") diff --git a/src/configuration.cpp b/src/configuration.cpp index db81b82f..81d9ae53 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -18,18 +18,22 @@ */ #include +#include +#include +#include #include namespace libbitcoin { namespace server { -using namespace bc::system; - // Construct with defaults derived from given context. -configuration::configuration(config::settings context) - : node::configuration(context), +configuration::configuration(system::chain::selection context) NOEXCEPT + : log(context), server(context), - blockchain(context) + node(context), + network(context), + database(context), + bitcoin(context) { } diff --git a/src/interface/blockchain.cpp b/src/interface/blockchain.cpp index c0c5f202..58bdf7c6 100644 --- a/src/interface/blockchain.cpp +++ b/src/interface/blockchain.cpp @@ -18,11 +18,7 @@ */ #include -#include -#include -#include #include -#include #include #include #include diff --git a/src/interface/subscribe.cpp b/src/interface/subscribe.cpp index 8f34e7b5..3d0dee0e 100644 --- a/src/interface/subscribe.cpp +++ b/src/interface/subscribe.cpp @@ -18,9 +18,6 @@ */ #include -#include -#include -#include #include #include #include diff --git a/src/interface/transaction_pool.cpp b/src/interface/transaction_pool.cpp index 079f94ae..017098ba 100644 --- a/src/interface/transaction_pool.cpp +++ b/src/interface/transaction_pool.cpp @@ -18,9 +18,6 @@ */ #include -#include -#include -#include #include #include #include diff --git a/src/interface/unsubscribe.cpp b/src/interface/unsubscribe.cpp index 213e9c47..6f015784 100644 --- a/src/interface/unsubscribe.cpp +++ b/src/interface/unsubscribe.cpp @@ -18,9 +18,6 @@ */ #include -#include -#include -#include #include #include #include diff --git a/src/messages/message.cpp b/src/messages/message.cpp index 17a61a2b..58073686 100644 --- a/src/messages/message.cpp +++ b/src/messages/message.cpp @@ -18,8 +18,6 @@ */ #include -#include -#include #include #include #include diff --git a/src/messages/route.cpp b/src/messages/route.cpp index e92532cb..82ec4d81 100644 --- a/src/messages/route.cpp +++ b/src/messages/route.cpp @@ -18,7 +18,6 @@ */ #include -#include #include namespace libbitcoin { diff --git a/src/messages/subscription.cpp b/src/messages/subscription.cpp index 1e9a41b6..97d7a62b 100644 --- a/src/messages/subscription.cpp +++ b/src/messages/subscription.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/src/parser.cpp b/src/parser.cpp index 10b56025..8677e3bb 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) + * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS) * * This file is part of libbitcoin. * @@ -18,69 +18,148 @@ */ #include -#include -#include -#include -#include +#include #include #include #include -#include -#include - -BC_DECLARE_CONFIG_DEFAULT_PATH("libbitcoin" / "bs.cfg") +#include -// TODO: localize descriptions. +std::filesystem::path config_default_path() NOEXCEPT +{ + return { "libbitcoin/bs.cfg" }; +} namespace libbitcoin { namespace server { -using namespace boost::filesystem; -using namespace boost::program_options; -using namespace bc::network; using namespace bc::system; using namespace bc::system::config; +using namespace boost::program_options; // Initialize configuration by copying the given instance. -parser::parser(const configuration& defaults) +parser::parser(const configuration& defaults) NOEXCEPT : configured(defaults) { } // Initialize configuration using defaults of the given context. -parser::parser(config::settings context) +parser::parser(system::chain::selection context) NOEXCEPT : configured(context) { - using serve = message::version::service; + // node - // Logs will slow things if not rotated. - configured.network.rotation_size = 10000000; + configured.node.snapshot_bytes = 0; + configured.node.snapshot_valid = 0; + configured.node.snapshot_confirm = 0; - // It is a public network. - configured.network.inbound_connections = 100; + // network - // Optimal for sync and network penetration. - configured.network.outbound_connections = 8; + using level = network::messages::level; + using service = network::messages::service; - // A node allows 10000 host names by default. + configured.network.threads = 16; + configured.network.enable_address = true; + configured.network.enable_transaction = true; configured.network.host_pool_capacity = 10000; + configured.network.outbound_connections = 100; + configured.network.protocol_minimum = level::headers_protocol; + configured.network.protocol_maximum = level::bip130; + + // services_minimum must be node_witness to be a witness node. + configured.network.services_minimum = service::node_network | + service::node_witness; + configured.network.services_maximum = service::node_network | + service::node_witness; + + // SCALE: LF2.2 @ 850K. + + // database (archive) + + configured.database.header_buckets = 386'364; + configured.database.header_size = 21'000'000; + configured.database.header_rate = 5; + + configured.database.input_size = 92'500'000'000; + configured.database.input_rate = 5; + + configured.database.output_size = 25'300'000'000; + configured.database.output_rate = 5; + + configured.database.point_buckets = 1'194'185'278; + configured.database.point_size = 25'700'000'000; + configured.database.point_rate = 5; + + configured.database.ins_size = 8'550'000'000; + configured.database.ins_rate = 5; + + configured.database.outs_size = 3'700'000'000; + configured.database.outs_rate = 5; - // Expose full node (1) and witness (8) network services by default. - configured.network.services = serve::node_network | serve::node_witness; + configured.database.tx_buckets = 469'222'525; + configured.database.tx_size = 17'000'000'000; + configured.database.tx_rate = 5; - // TODO: set this independently on each public endpoint. - configured.protocol.message_size_limit = max_block_size + 100; + configured.database.txs_buckets = 850'001; + configured.database.txs_size = 1'050'000'000; + configured.database.txs_rate = 5; + + // database (indexes) + + configured.database.candidate_size = 2'575'500; + configured.database.candidate_rate = 5; + + configured.database.confirmed_size = 2'575'500; + configured.database.confirmed_rate = 5; + + configured.database.strong_tx_buckets = 469'222'525; + configured.database.strong_tx_size = 2'900'000'000; + configured.database.strong_tx_rate = 5; + + // database (caches) + + configured.database.duplicate_buckets = 10; + configured.database.duplicate_size = 44; + configured.database.duplicate_rate = 5; + + configured.database.prevout_buckets = 850'001; + configured.database.prevout_size = 5'250'000'000; + configured.database.prevout_rate = 5; + + configured.database.validated_bk_buckets = 850'001; + configured.database.validated_bk_size = 1'700'000; + configured.database.validated_bk_rate = 5; + + configured.database.validated_tx_buckets = 1; + configured.database.validated_tx_size = 1; + configured.database.validated_tx_rate = 5; + + // database (optionals) + + configured.database.address_buckets = 1; + configured.database.address_size = 1; + configured.database.address_rate = 5; + + // also disabled by filter_tx + configured.database.filter_bk_buckets = 0; + configured.database.filter_bk_size = 1; + configured.database.filter_bk_rate = 5; + + // also disabled by filter_bk + configured.database.filter_tx_buckets = 0; + configured.database.filter_tx_size = 1; + configured.database.filter_tx_rate = 5; } -options_metadata parser::load_options() +options_metadata parser::load_options() THROWS { options_metadata description("options"); description.add_options() ( BS_CONFIG_VARIABLE ",c", - value(&configured.file), + value(&configured.file), "Specify path to a configuration settings file." ) + // Information. ( BS_HELP_VARIABLE ",h", value(&configured.help)-> @@ -88,10 +167,10 @@ options_metadata parser::load_options() "Display command line options." ) ( - "initchain,i", - value(&configured.initchain)-> + BS_HARDWARE_VARIABLE ",d", + value(&configured.hardware)-> default_value(false)->zero_tokens(), - "Initialize blockchain in the configured directory." + "Display hardware compatibility." ) ( BS_SETTINGS_VARIABLE ",s", @@ -104,28 +183,91 @@ options_metadata parser::load_options() value(&configured.version)-> default_value(false)->zero_tokens(), "Display version information." + ) + // Actions. + ( + BS_NEWSTORE_VARIABLE ",n", + value(&configured.newstore)-> + default_value(false)->zero_tokens(), + "Create new store in configured directory." + ) + ( + BS_BACKUP_VARIABLE ",b", + value(&configured.backup)-> + default_value(false)->zero_tokens(), + "Backup to a snapshot (can also do live)." + ) + ( + BS_RESTORE_VARIABLE ",r", + value(&configured.restore)-> + default_value(false)->zero_tokens(), + "Restore from most recent snapshot." + ) + // Chain scans. + ( + BS_FLAGS_VARIABLE ",f", + value(&configured.flags)-> + default_value(false)->zero_tokens(), + "Scan and display all flag transitions." + ) + ( + BS_SLABS_VARIABLE ",a", + value(&configured.slabs)-> + default_value(false)->zero_tokens(), + "Scan and display store slab measures." + ) + ( + BS_BUCKETS_VARIABLE ",k", + value(&configured.buckets)-> + default_value(false)->zero_tokens(), + "Scan and display all bucket densities." + ) + ( + BS_COLLISIONS_VARIABLE ",l", + value(&configured.collisions)-> + default_value(false)->zero_tokens(), + "Scan and display hashmap collision stats (may exceed RAM and result in SIGKILL)." + ) + ( + BS_INFORMATION_VARIABLE ",i", + value(&configured.information)-> + default_value(false)->zero_tokens(), + "Scan and display store information." + ) + // Ad-hoc Testing. + ( + BS_READ_VARIABLE ",t", + value(&configured.test)-> + default_value(false)->zero_tokens(), + "Run built-in read test and display." + ) + ( + BS_WRITE_VARIABLE ",w", + value(&configured.write)-> + default_value(false)->zero_tokens(), + "Run built-in write test and display." ); return description; } -arguments_metadata parser::load_arguments() +arguments_metadata parser::load_arguments() THROWS { arguments_metadata description; return description .add(BS_CONFIG_VARIABLE, 1); } -options_metadata parser::load_environment() +options_metadata parser::load_environment() THROWS { options_metadata description("environment"); description.add_options() ( // For some reason po requires this to be a lower case name. // The case must match the other declarations for it to compose. - // This composes with the cmdline options and inits to system path. + // This composes with the cmdline options and inits to default path. BS_CONFIG_VARIABLE, - value(&configured.file)->composing() + value(&configured.file)->composing() ->default_value(config_default_path()), "The path to the configuration settings file." ); @@ -133,59 +275,119 @@ options_metadata parser::load_environment() return description; } -options_metadata parser::load_settings() +options_metadata parser::load_settings() THROWS { options_metadata description("settings"); description.add_options() - /* [log] */ + /* [forks] */ ( - "log.debug_file", - value(&configured.network.debug_file), - "The debug log file path, defaults to 'debug.log'." + "forks.difficult", + value(&configured.bitcoin.forks.difficult), + "Require difficult blocks, defaults to true (use false for testnet)." ) ( - "log.error_file", - value(&configured.network.error_file), - "The error log file path, defaults to 'error.log'." + "forks.retarget", + value(&configured.bitcoin.forks.retarget), + "Retarget difficulty, defaults to true." ) ( - "log.archive_directory", - value(&configured.network.archive_directory), - "The log archive directory, defaults to 'archive'." + "forks.bip16", + value(&configured.bitcoin.forks.bip16), + "Add pay-to-script-hash processing, defaults to true (soft fork)." ) ( - "log.rotation_size", - value(&configured.network.rotation_size), - "The size at which a log is archived, defaults to 10000000 (0 disables)." + "forks.bip30", + value(&configured.bitcoin.forks.bip30), + "Disallow collision of unspent transaction hashes, defaults to true (soft fork)." ) ( - "log.minimum_free_space", - value(&configured.network.minimum_free_space), - "The minimum free space required in the archive directory, defaults to 0." + "forks.bip34", + value(&configured.bitcoin.forks.bip34), + "Require coinbase input includes block height, defaults to true (soft fork)." ) ( - "log.maximum_archive_size", - value(&configured.network.maximum_archive_size), - "The maximum combined size of archived logs, defaults to 0 (maximum)." + "forks.bip42", + value(&configured.bitcoin.forks.bip42), + "Finite monetary supply, defaults to true (soft fork)." ) ( - "log.maximum_archive_files", - value(&configured.network.maximum_archive_files), - "The maximum number of logs to archive, defaults to 0 (maximum)." + "forks.bip66", + value(&configured.bitcoin.forks.bip66), + "Require strict signature encoding, defaults to true (soft fork)." ) ( - "log.statistics_server", - value(&configured.network.statistics_server), - "The address of the statistics collection server, defaults to none." + "forks.bip65", + value(&configured.bitcoin.forks.bip65), + "Add check-locktime-verify op code, defaults to true (soft fork)." ) ( - "log.verbose", - value(&configured.network.verbose), - "Enable verbose logging, defaults to false." + "forks.bip90", + value(&configured.bitcoin.forks.bip90), + "Assume bip34, bip65, and bip66 activation if enabled, defaults to true (hard fork)." + ) + ( + "forks.bip68", + value(&configured.bitcoin.forks.bip68), + "Add relative locktime enforcement, defaults to true (soft fork)." + ) + ( + "forks.bip112", + value(&configured.bitcoin.forks.bip112), + "Add check-sequence-verify op code, defaults to true (soft fork)." + ) + ( + "forks.bip113", + value(&configured.bitcoin.forks.bip113), + "Use median time past for locktime, defaults to true (soft fork)." + ) + ( + "forks.bip141", + value(&configured.bitcoin.forks.bip141), + "Segregated witness consensus layer, defaults to true (soft fork)." + ) + ( + "forks.bip143", + value(&configured.bitcoin.forks.bip143), + "Version 0 transaction digest, defaults to true (soft fork)." + ) + ( + "forks.bip147", + value(&configured.bitcoin.forks.bip147), + "Prevent dummy value malleability, defaults to true (soft fork)." + ) + ( + "forks.time_warp_patch", + value(&configured.bitcoin.forks.time_warp_patch), + "Fix time warp bug, defaults to false (hard fork)." + ) + ( + "forks.retarget_overflow_patch", + value(&configured.bitcoin.forks.retarget_overflow_patch), + "Fix target overflow for very low difficulty, defaults to false (hard fork)." + ) + ( + "forks.scrypt_proof_of_work", + value(&configured.bitcoin.forks.scrypt_proof_of_work), + "Use scrypt hashing for proof of work, defaults to false (hard fork)." ) /* [bitcoin] */ + ( + "bitcoin.initial_block_subsidy_bitcoin", + value(&configured.bitcoin.initial_subsidy_bitcoin), + "The initial block subsidy, defaults to 50." + ) + ( + "bitcoin.subsidy_interval", + value(&configured.bitcoin.subsidy_interval_blocks), + "The subsidy halving period, defaults to 210000." + ) + ( + "bitcoin.timestamp_limit_seconds", + value(&configured.bitcoin.timestamp_limit_seconds), + "The future timestamp allowance, defaults to 7200." + ) ( "bitcoin.retargeting_factor", value(&configured.bitcoin.retargeting_factor), @@ -201,108 +403,144 @@ options_metadata parser::load_settings() value(&configured.bitcoin.block_spacing_seconds), "The target block period, defaults to 600." ) - ( - "bitcoin.timestamp_limit_seconds", - value(&configured.bitcoin.timestamp_limit_seconds), - "The future timestamp allowance, defaults to 7200." - ) ( "bitcoin.proof_of_work_limit", value(&configured.bitcoin.proof_of_work_limit), "The proof of work limit, defaults to 486604799." ) - ( - "bitcoin.initial_block_subsidy_bitcoin", - value(&configured.bitcoin.initial_subsidy_bitcoin), - "The initial block subsidy, defaults to 50." - ) - ( - "bitcoin.subsidy_interval", - value(&configured.bitcoin.subsidy_interval_blocks), - "The subsidy halving period, defaults to 210000." - ) ( "bitcoin.genesis_block", value(&configured.bitcoin.genesis_block), "The genesis block, defaults to mainnet." ) ( - "bitcoin.activation_threshold", - value(&configured.bitcoin.activation_threshold), + "bitcoin.checkpoint", + value(&configured.bitcoin.checkpoints), + "The blockchain checkpoints, defaults to the consensus set." + ) + // [version properties excluded here] + ( + "bitcoin.bip34_activation_threshold", + value(&configured.bitcoin.bip34_activation_threshold), "The number of new version blocks required for bip34 style soft fork activation, defaults to 750." ) ( - "bitcoin.enforcement_threshold", - value(&configured.bitcoin.enforcement_threshold), + "bitcoin.bip34_enforcement_threshold", + value(&configured.bitcoin.bip34_enforcement_threshold), "The number of new version blocks required for bip34 style soft fork enforcement, defaults to 950." ) ( - "bitcoin.activation_sample", - value(&configured.bitcoin.activation_sample), + "bitcoin.bip34_activation_sample", + value(&configured.bitcoin.bip34_activation_sample), "The number of blocks considered for bip34 style soft fork activation, defaults to 1000." ) ( "bitcoin.bip65_freeze", - value(&configured.bitcoin.bip65_freeze), - "The block height to freeze the bip65 softfork as in bip90, defaults to 388381." + value(&configured.bitcoin.bip90_bip65_height), + "The block height to freeze the bip65 softfork for bip90, defaults to 388381." ) ( "bitcoin.bip66_freeze", - value(&configured.bitcoin.bip66_freeze), - "The block height to freeze the bip66 softfork as in bip90, defaults to 363725." + value(&configured.bitcoin.bip90_bip66_height), + "The block height to freeze the bip66 softfork for bip90, defaults to 363725." ) ( "bitcoin.bip34_freeze", - value(&configured.bitcoin.bip34_freeze), - "The block height to freeze the bip34 softfork as in bip90, defaults to 227931." + value(&configured.bitcoin.bip90_bip34_height), + "The block height to freeze the bip34 softfork for bip90, defaults to 227931." ) ( "bitcoin.bip16_activation_time", value(&configured.bitcoin.bip16_activation_time), "The activation time for bip16 in unix time, defaults to 1333238400." ) - ( - "bitcoin.bip34_active_checkpoint", - value(&configured.bitcoin.bip34_active_checkpoint), - "The hash:height checkpoint for bip34 activation, defaults to 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8:227931." - ) ( "bitcoin.bip9_bit0_active_checkpoint", - value(&configured.bitcoin.bip9_bit0_active_checkpoint), + value(&configured.bitcoin.bip9_bit0_active_checkpoint), "The hash:height checkpoint for bip9 bit0 activation, defaults to 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5:419328." ) ( - "bitcoin.bip9_bit1_active_checkpoint", - value(&configured.bitcoin.bip9_bit1_active_checkpoint), - "The hash:height checkpoint for bip9 bit1 activation, defaults to 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893:481824." + "bitcoin.milestone", + value(&configured.bitcoin.milestone), + "A block presumed to be valid but not required to be present, defaults to 00000000000000000002a0b5db2a7f8d9087464c2586b546be7bce8eb53b8187:850000." + ) + ( + "bitcoin.minimum_work", + value(&configured.bitcoin.minimum_work), + "The minimum work for any branch to be considered valid, defaults to 000000000000000000000000000000000000000052b2559353df4117b7348b64." ) /* [network] */ ( "network.threads", value(&configured.network.threads), - "The minimum number of threads in the network threadpool, defaults to 0 (physical cores)." + "The minimum number of threads in the network threadpool, defaults to 16." + ) + ( + "network.address_upper", + value(&configured.network.address_upper), + "The upper bound for address selection divisor, defaults to 10." + ) + ( + "network.address_lower", + value(&configured.network.address_lower), + "The lower bound for address selection divisor, defaults to 5." ) ( "network.protocol_maximum", value(&configured.network.protocol_maximum), - "The maximum network protocol version, defaults to 70013." + "The maximum network protocol version, defaults to 70012." ) ( "network.protocol_minimum", value(&configured.network.protocol_minimum), - "The minimum network protocol version, defaults to 31402." + "The minimum network protocol version, defaults to 31800." ) ( - "network.services", - value(&configured.network.services), - "The services exposed by network connections, defaults to 9 (full node, witness)." + "network.services_maximum", + value(&configured.network.services_maximum), + "The maximum services exposed by network connections, defaults to 9 (full node, witness)." + ) + ( + "network.services_minimum", + value(&configured.network.services_minimum), + "The minimum services exposed by network connections, defaults to 9 (full node, witness)." ) ( "network.invalid_services", value(&configured.network.invalid_services), "The advertised services that cause a peer to be dropped, defaults to 176." ) + ( + "network.enable_address", + value(&configured.network.enable_address), + "Enable address messages, defaults to true." + ) + ( + "network.enable_alert", + value(&configured.network.enable_alert), + "Enable alert messages, defaults to false." + ) + ( + "network.enable_reject", + value(&configured.network.enable_reject), + "Enable reject messages, defaults to false." + ) + ( + "network.enable_transaction", + value(&configured.network.enable_transaction), + "Enable transaction relay, defaults to true." + ) + ( + "network.enable_ipv6", + value(&configured.network.enable_ipv6), + "Enable internet protocol version 6 (IPv6), defaults to false." + ) + ( + "network.enable_loopback", + value(&configured.network.enable_loopback), + "Allow connections from the node to itself, defaults to false." + ) ( "network.validate_checksum", value(&configured.network.validate_checksum), @@ -313,44 +551,39 @@ options_metadata parser::load_settings() value(&configured.network.identifier), "The magic number for message headers, defaults to 3652501241." ) - ( - "network.inbound_port", - value(&configured.network.inbound_port), - "The port for incoming connections, defaults to 8333." - ) ( "network.inbound_connections", - value(&configured.network.inbound_connections), + value(&configured.network.inbound_connections), "The target number of incoming network connections, defaults to 0." ) ( "network.outbound_connections", - value(&configured.network.outbound_connections), - "The target number of outgoing network connections, defaults to 2." - ) - ( - "network.manual_attempt_limit", - value(&configured.network.manual_attempt_limit), - "The attempt limit for manual connection establishment, defaults to 0 (forever)." + value(&configured.network.outbound_connections), + "The target number of outgoing network connections, defaults to 100." ) ( "network.connect_batch_size", - value(&configured.network.connect_batch_size), + value(&configured.network.connect_batch_size), "The number of concurrent attempts to establish one connection, defaults to 5." ) + ( + "network.retry_timeout_seconds", + value(&configured.network.retry_timeout_seconds), + "The time delay for failed connection retry, defaults to 1." + ) ( "network.connect_timeout_seconds", value(&configured.network.connect_timeout_seconds), "The time limit for connection establishment, defaults to 5." ) ( - "network.channel_handshake_seconds", - value(&configured.network.channel_handshake_seconds), + "network.handshake_timeout_seconds", + value(&configured.network.handshake_timeout_seconds), "The time limit to complete the connection handshake, defaults to 30." ) ( - "network.channel_germination_seconds", - value(&configured.network.channel_germination_seconds), + "network.seeding_timeout_seconds", + value(&configured.network.seeding_timeout_seconds), "The time limit for obtaining seed addresses, defaults to 30." ) ( @@ -361,7 +594,7 @@ options_metadata parser::load_settings() ( "network.channel_inactivity_minutes", value(&configured.network.channel_inactivity_minutes), - "The inactivity time limit for any connection, defaults to 30." + "The inactivity time limit for any connection, defaults to 10." ) ( "network.channel_expiration_minutes", @@ -374,493 +607,515 @@ options_metadata parser::load_settings() "The maximum number of peer hosts in the pool, defaults to 10000." ) ( - "network.hosts_file", - value(&configured.network.hosts_file), - "The peer hosts cache file path, defaults to 'hosts.cache'." + "network.minimum_buffer", + value(&configured.network.minimum_buffer), + "The minimum retained read buffer size, defaults to 4000000." ) ( - "network.self", - value(&configured.network.self), - "The advertised public address of this node, defaults to none." + "network.rate_limit", + value(&configured.network.rate_limit), + "The peer download rate limit in bytes per second, defaults to 1024 (not implemented)." ) ( - "network.blacklist", - value(&configured.network.blacklists), - "IP address to disallow as a peer, multiple entries allowed." + "network.user_agent", + value(&configured.network.user_agent), + "The node user agent string, defaults to '" BC_USER_AGENT "'." ) ( - "network.peer", - value(&configured.network.peers), - "A persistent peer node, multiple entries allowed." + "network.path", + value(&configured.network.path), + "The peer address cache file directory, defaults to empty." ) ( - "network.seed", - value(&configured.network.seeds), - "A seed node for initializing the host pool, multiple entries allowed." - ) - - /* [database] */ - ( - "database.directory", - value(&configured.database.directory), - "The blockchain database directory, defaults to 'blockchain'." + "network.bind", + value(&configured.network.binds), + "IP address to bind, multiple entries allowed, defaults to 0.0.0.0:8333." ) ( - "database.flush_writes", - value(&configured.database.flush_writes), - "Flush each write to disk, defaults to false." - ) - ( - "database.cache_capacity", - value(&configured.database.cache_capacity), - "The maximum number of entries in the unspent outputs cache, defaults to 10000." - ) - ( - "database.file_growth_rate", - value(&configured.database.file_growth_rate), - "Full database files increase by this percentage, defaults to 5." - ) - ( - "database.block_table_buckets", - value(&configured.database.block_table_buckets), - "Block hash table size, defaults to 650000." - ) - ( - "database.transaction_table_buckets", - value(&configured.database.transaction_table_buckets), - "Transaction hash table size, defaults to 110000000." + "network.self", + value(&configured.network.selfs), + "IP address to advertise, multiple entries allowed." ) ( - "database.payment_table_buckets", - value(&configured.database.payment_table_buckets), - "Payment hash table size, defaults to 107000000." + "network.blacklist", + value(&configured.network.blacklists), + "IP address to disallow as a peer, multiple entries allowed." ) ( - "database.block_table_size", - value(&configured.database.block_table_size), - "Block table minimum file size, defaults to 80000000." + "network.whitelist", + value(&configured.network.whitelists), + "IP address to allow as a peer, multiple entries allowed." ) ( - "database.candidate_index_size", - value(&configured.database.candidate_index_size), - "Candidate index minimum file size, defaults to 3000000." + "network.peer", + value(&configured.network.peers), + "A persistent peer node, multiple entries allowed." ) ( - "database.confirmed_index_size", - value(&configured.database.confirmed_index_size), - "Confirmed index minimum file size, defaults to 3000000." + "network.seed", + value(&configured.network.seeds), + "A seed node for initializing the host pool, multiple entries allowed." ) + + /* [database] */ ( - "database.transaction_index_size", - value(&configured.database.transaction_index_size), - "Transaction index minimum file size, defaults to 3000000000." + "database.path", + value(&configured.database.path), + "The blockchain database directory, defaults to 'blockchain'." ) + + /* header */ ( - "database.transaction_table_size", - value(&configured.database.transaction_table_size), - "Transaction table minimum file size, defaults to 220000000000." + "database.header_buckets", + value(&configured.database.header_buckets), + "The log2 number of buckets in the header table head, defaults to '386364'." ) ( - "database.payment_index_size", - value(&configured.database.payment_index_size), - "Payment index minimum file size, defaults to 100000000000." + "database.header_size", + value(&configured.database.header_size), + "The minimum allocation of the header table body, defaults to '21000000'." ) ( - "database.payment_table_size", - value(&configured.database.payment_table_size), - "Payment table minimum file size, defaults to 100000000." + "database.header_rate", + value(&configured.database.header_rate), + "The percentage expansion of the header table body, defaults to '5'." ) + + /* input */ ( - "database.neutrino_filter_table_buckets", - value(&configured.database.neutrino_filter_table_buckets), - "Neutrino filter hash table size, defaults to 650000." + "database.input_size", + value(&configured.database.input_size), + "The minimum allocation of the input table body, defaults to '92500000000'." ) ( - "database.neutrino_filter_table_size", - value(&configured.database.neutrino_filter_table_size), - "Neutrino filter table minimum file size, defaults to 80000000." + "database.input_rate", + value(&configured.database.input_rate), + "The percentage expansion of the input table body, defaults to '5'." ) - /* [blockchain] */ + /* output */ ( - "blockchain.cores", - value(&configured.chain.cores), - "The number of cores dedicated to block validation, defaults to 0 (physical cores)." + "database.output_size", + value(&configured.database.output_size), + "The minimum allocation of the output table body, defaults to '25300000000'." ) ( - "blockchain.priority", - value(&configured.chain.priority), - "Use high thread priority for block validation, defaults to true." + "database.output_rate", + value(&configured.database.output_rate), + "The percentage expansion of the output table body, defaults to '5'." ) + + /* point */ ( - "blockchain.use_libconsensus", - value(&configured.chain.use_libconsensus), - "Use libconsensus for script validation if integrated, defaults to false." + "database.point_buckets", + value(&configured.database.point_buckets), + "The log2 number of buckets in the spend table head, defaults to '1194185278'." ) ( - "blockchain.reorganization_limit", - value(&configured.chain.reorganization_limit), - "The maximum reorganization depth, defaults to 0 (unlimited)." + "database.point_size", + value(&configured.database.point_size), + "The minimum allocation of the point table body, defaults to '25700000000'." ) ( - "blockchain.block_buffer_limit", - value(&configured.chain.block_buffer_limit), - "The maximum number of blocks to buffer, defaults to 0 (none)." + "database.point_rate", + value(&configured.database.point_rate), + "The percentage expansion of the point table body, defaults to '5'." ) + + /* ins */ ( - "blockchain.checkpoint", - value(&configured.chain.checkpoints), - "A hash:height checkpoint, multiple entries allowed." + "database.ins_size", + value(&configured.database.ins_size), + "The minimum allocation of the point table body, defaults to '8550000000'." ) ( - "blockchain.bip158", - value(&configured.chain.bip158), - "Neutrino filter (bip158 basic filter) support, defaults to false." + "database.ins_rate", + value(&configured.database.ins_rate), + "The percentage expansion of the ins table body, defaults to '5'." ) - /* [fork] */ + /* outs */ ( - "fork.difficult", - value(&configured.chain.difficult), - "Require difficult blocks, defaults to true (use false for testnet)." + "database.outs_size", + value(&configured.database.outs_size), + "The minimum allocation of the puts table body, defaults to '3700000000'." ) ( - "fork.retarget", - value(&configured.chain.retarget), - "Retarget difficulty, defaults to true." + "database.outs_rate", + value(&configured.database.outs_rate), + "The percentage expansion of the puts table body, defaults to '5'." ) + + /* tx */ ( - "fork.bip16", - value(&configured.chain.bip16), - "Add pay-to-script-hash processing, defaults to true (soft fork)." + "database.tx_buckets", + value(&configured.database.tx_buckets), + "The log2 number of buckets in the tx table head, defaults to '469222525'." ) ( - "fork.bip30", - value(&configured.chain.bip30), - "Disallow collision of unspent transaction hashes, defaults to true (soft fork)." + "database.tx_size", + value(&configured.database.tx_size), + "The minimum allocation of the tx table body, defaults to '17000000000'." ) ( - "fork.bip34", - value(&configured.chain.bip34), - "Require coinbase input includes block height, defaults to true (soft fork)." + "database.tx_rate", + value(&configured.database.tx_rate), + "The percentage expansion of the tx table body, defaults to '5'." ) + + /* txs */ ( - "fork.bip42", - value(&configured.chain.bip42), - "Finite monetary supply, defaults to true (soft fork)." + "database.txs_buckets", + value(&configured.database.txs_buckets), + "The log2 number of buckets in the txs table head, defaults to '850001'." ) ( - "fork.bip66", - value(&configured.chain.bip66), - "Require strict signature encoding, defaults to true (soft fork)." + "database.txs_size", + value(&configured.database.txs_size), + "The minimum allocation of the txs table body, defaults to '1050000000'." ) ( - "fork.bip65", - value(&configured.chain.bip65), - "Add check-locktime-verify op code, defaults to true (soft fork)." + "database.txs_rate", + value(&configured.database.txs_rate), + "The percentage expansion of the txs table body, defaults to '5'." ) + + /* candidate */ ( - "fork.bip90", - value(&configured.chain.bip90), - "Assume bip34, bip65, and bip66 activation if enabled, defaults to true (hard fork)." + "database.candidate_size", + value(&configured.database.candidate_size), + "The minimum allocation of the candidate table body, defaults to '2575500'." ) ( - "fork.bip68", - value(&configured.chain.bip68), - "Add relative locktime enforcement, defaults to true (soft fork)." + "database.candidate_rate", + value(&configured.database.candidate_rate), + "The percentage expansion of the candidate table body, defaults to '5'." ) + + /* confirmed */ ( - "fork.bip112", - value(&configured.chain.bip112), - "Add check-sequence-verify op code, defaults to true (soft fork)." + "database.confirmed_size", + value(&configured.database.confirmed_size), + "The minimum allocation of the candidate table body, defaults to '2575500'." ) ( - "fork.bip113", - value(&configured.chain.bip113), - "Use median time past for locktime, defaults to true (soft fork)." + "database.confirmed_rate", + value(&configured.database.confirmed_rate), + "The percentage expansion of the candidate table body, defaults to '5'." ) + + /* strong_tx */ ( - "fork.bip141", - value(&configured.chain.bip141), - "Segregated witness consensus layer, defaults to true (soft fork)." + "database.strong_tx_buckets", + value(&configured.database.strong_tx_buckets), + "The log2 number of buckets in the strong_tx table head, defaults to '469222525'." ) ( - "fork.bip143", - value(&configured.chain.bip143), - "Version 0 transaction digest, defaults to true (soft fork)." + "database.strong_tx_size", + value(&configured.database.strong_tx_size), + "The minimum allocation of the strong_tx table body, defaults to '2900000000'." ) ( - "fork.bip147", - value(&configured.chain.bip147), - "Prevent dummy value malleability, defaults to true (soft fork)." + "database.strong_tx_rate", + value(&configured.database.strong_tx_rate), + "The percentage expansion of the strong_tx table body, defaults to '5'." ) + + /* duplicate */ ( - "fork.time_warp_patch", - value(&configured.chain.time_warp_patch), - "Fix time warp bug, defaults to false (hard fork)." + "database.duplicate_buckets", + value(&configured.database.duplicate_buckets), + "The minimum number of buckets in the duplicate table head, defaults to '10'." ) ( - "fork.retarget_overflow_patch", - value(&configured.chain.retarget_overflow_patch), - "Fix target overflow for very low difficulty, defaults to false (hard fork)." + "database.duplicate_size", + value(&configured.database.duplicate_size), + "The minimum allocation of the duplicate table body, defaults to '44'." ) ( - "fork.scrypt_proof_of_work", - value(&configured.chain.scrypt_proof_of_work), - "Use scrypt hashing for proof of work, defaults to false (hard fork)." + "database.duplicate_rate", + value(&configured.database.duplicate_rate), + "The percentage expansion of the duplicate table, defaults to '5'." ) - /* [node] */ - ( - "node.maximum_deviation", - value(&configured.node.maximum_deviation), - "The response rate standard deviation below which a peer is dropped, defaults to 1.5." - ) - ( - "node.block_latency_seconds", - value(&configured.node.block_latency_seconds), - "The maximum time to wait for a requested block, defaults to 5." - ) + /* prevout */ ( - /* Internally this is blockchain, but it is conceptually a node setting. */ - "node.notify_limit_hours", - value(&configured.chain.notify_limit_hours), - "Disable relay when top block age exceeds, defaults to 24 (0 disables)." + "database.prevout_buckets", + value(&configured.database.prevout_buckets), + "The minimum number of buckets in the prevout table head, defaults to '850001'." ) ( - /* Internally this is blockchain, but it is conceptually a node setting. */ - "node.byte_fee_satoshis", - value(&configured.chain.byte_fee_satoshis), - "The minimum fee per byte, cumulative for conflicts, defaults to 1." + "database.prevout_size", + value(&configured.database.prevout_size), + "The minimum allocation of the prevout table body, defaults to '5250000000'." ) ( - /* Internally this is blockchain, but it is conceptually a node setting. */ - "node.sigop_fee_satoshis", - value(&configured.chain.sigop_fee_satoshis), - "The minimum fee per sigop, additional to byte fee, defaults to 100." + "database.prevout_rate", + value(&configured.database.prevout_rate), + "The percentage expansion of the prevout table, defaults to '5'." ) + + /* validated_bk */ ( - /* Internally this is blockchain, but it is conceptually a node setting. */ - "node.minimum_output_satoshis", - value(&configured.chain.minimum_output_satoshis), - "The minimum output value, defaults to 500." + "database.validated_bk_buckets", + value(&configured.database.validated_bk_buckets), + "The log2 number of buckets in the validated_bk table head, defaults to '850001'." ) ( - /* Internally this is network, but it is conceptually a node setting. */ - "node.relay_transactions", - value(&configured.network.relay_transactions), - "Request that peers relay transactions, defaults to false." + "database.validated_bk_size", + value(&configured.database.validated_bk_size), + "The minimum allocation of the validated_bk table body, defaults to '1700000'." ) ( - "node.refresh_transactions", - value(&configured.node.refresh_transactions), - "Request transactions on each channel start, defaults to false." + "database.validated_bk_rate", + value(&configured.database.validated_bk_rate), + "The percentage expansion of the validated_bk table body, defaults to '5'." ) - /* [server] */ + /* validated_tx */ ( - /* Internally this is chain, but it applies to server and not node. */ - "server.index_payments", - value(&configured.chain.index_payments), - "Enable payment indexing, defaults to true." + "database.validated_tx_buckets", + value(&configured.database.validated_tx_buckets), + "The number of buckets in the validated_tx table head, defaults to '1'." ) ( - /* Internally this is protocol, but application to server is more intuitive. */ - "server.send_high_water", - value(&configured.protocol.send_high_water), - "Drop messages at this outgoing backlog level, defaults to 100." + "database.validated_tx_size", + value(&configured.database.validated_tx_size), + "The minimum allocation of the validated_tx table body, defaults to '1'." ) ( - /* Internally this is protocol, but application to server is more intuitive. */ - "server.receive_high_water", - value(&configured.protocol.receive_high_water), - "Drop messages at this incoming backlog level, defaults to 100." - ) - ( - /* Internally this is protocol, but application to server is more intuitive. */ - "server.handshake_seconds", - value(&configured.protocol.handshake_seconds), - "The time limit to complete the connection handshake, defaults to 30." + "database.validated_tx_rate", + value(&configured.database.validated_tx_rate), + "The percentage expansion of the validated_tx table body, defaults to '5'." ) + + /* address */ ( - "server.secure_only", - value(&configured.server.secure_only), - "Disable public endpoints, defaults to false." + "database.address_buckets", + value(&configured.database.address_buckets), + "The log2 number of buckets in the address table head, defaults to '1' (0|1 disables)." ) ( - "server.query_workers", - value(&configured.server.query_workers), - "The number of query worker threads per endpoint, defaults to 1 (0 disables service)." + "database.address_size", + value(&configured.database.address_size), + "The minimum allocation of the address table body, defaults to '1'." ) ( - "server.subscription_limit", - value(&configured.server.subscription_limit), - "The maximum number of query subscriptions, defaults to 1000 (0 disables subscribe)." + "database.address_rate", + value(&configured.database.address_rate), + "The percentage expansion of the address table body, defaults to '5'." ) + + /* filter_bk */ ( - "server.subscription_expiration_minutes", - value(&configured.server.subscription_expiration_minutes), - "The query subscription expiration time, defaults to 10 (0 disables expiration)." + "database.filter_bk_buckets", + value(&configured.database.filter_bk_buckets), + "The log2 number of buckets in the filter_bk table head, defaults to '0' (0 disables)." ) ( - "server.heartbeat_service_seconds", - value(&configured.server.heartbeat_service_seconds), - "The heartbeat service interval, defaults to 5 (0 disables service)." + "database.filter_bk_size", + value(&configured.database.filter_bk_size), + "The minimum allocation of the filter_bk table body, defaults to '1'." ) ( - "server.block_service_enabled", - value(&configured.server.block_service_enabled), - "Enable the block publishing service, defaults to false." + "database.filter_bk_rate", + value(&configured.database.filter_bk_rate), + "The percentage expansion of the filter_bk table body, defaults to '5'." ) + + /* filter_tx */ ( - "server.transaction_service_enabled", - value(&configured.server.transaction_service_enabled), - "Enable the transaction publishing service, defaults to false." + "database.filter_tx_buckets", + value(&configured.database.filter_tx_buckets), + "The log2 number of buckets in the filter_tx table head, defaults to '0' (0 disables)." ) ( - "server.client_address", - value(&configured.server.client_addresses), - "Allowed client IP address, multiple entries allowed." + "database.filter_tx_size", + value(&configured.database.filter_tx_size), + "The minimum allocation of the filter_tx table body, defaults to '1'." ) ( - "server.blacklist", - value(&configured.server.blacklists), - "Blocked client IP address, multiple entries allowed." + "database.filter_tx_rate", + value(&configured.database.filter_tx_rate), + "The percentage expansion of the filter_tx table body, defaults to '5'." ) - /* [websockets] */ + /* [node] */ ( - "websockets.secure_query_endpoint", - value(&configured.server.websockets_secure_query_endpoint), - "The secure query websocket endpoint, defaults to 'tcp://*:9061'." + "node.threads", + value(&configured.node.threads), + "The number of threads in the validation threadpool, defaults to 16." ) ( - "websockets.secure_heartbeat_endpoint", - value(&configured.server.websockets_secure_heartbeat_endpoint), - "The secure heartbeat websocket endpoint, defaults to 'tcp://*:9062'." + "node.priority", + value(&configured.node.priority), + "Set the validation threadpool to high priority, defaults to true." ) ( - "websockets.secure_block_endpoint", - value(&configured.server.websockets_secure_block_endpoint), - "The secure block publishing websocket endpoint, defaults to 'tcp://*:9063'." + "node.headers_first", + value(&configured.node.headers_first), + "Obtain current header chain before obtaining associated blocks, defaults to true." ) ( - "websockets.secure_transaction_endpoint", - value(&configured.server.websockets_secure_transaction_endpoint), - "The secure transaction publishing websocket endpoint, defaults to 'tcp://*:9064'." + "node.allowed_deviation", + value(&configured.node.allowed_deviation), + "Allowable underperformance standard deviation, defaults to 1.5 (0 disables)." ) ( - "websockets.public_query_endpoint", - value(&configured.server.websockets_public_query_endpoint), - "The public query websocket endpoint, defaults to 'tcp://*:9071'." + "node.allocation_multiple", + value(&configured.node.allocation_multiple), + "Block deserialization buffer multiple of wire size, defaults to 20 (0 disables)." ) ( - "websockets.public_heartbeat_endpoint", - value(&configured.server.websockets_public_heartbeat_endpoint), - "The public heartbeat websocket endpoint, defaults to 'tcp://*:9072'." + "node.maximum_height", + value(&configured.node.maximum_height), + "Maximum block height to populate, defaults to 0 (unlimited)." ) ( - "websockets.public_block_endpoint", - value(&configured.server.websockets_public_block_endpoint), - "The public block publishing websocket endpoint, defaults to 'tcp://*:9073'." + "node.maximum_concurrency", + value(&configured.node.maximum_concurrency), + "Maximum number of blocks to download concurrently, defaults to '50000' (0 disables)." ) ( - "websockets.public_transaction_endpoint", - value(&configured.server.websockets_public_transaction_endpoint), - "The public transaction websocket publishing endpoint, defaults to 'tcp://*:9074'." + "node.snapshot_bytes", + value(&configured.node.snapshot_bytes), + "Downloaded bytes that triggers snapshot, defaults to '0' (0 disables)." ) ( - "websockets.enabled", - value(&configured.server.websockets_enabled), - "Enable websocket endpoints, defaults to true." + "node.snapshot_valid", + value(&configured.node.snapshot_valid), + "Completed validations that trigger snapshot, defaults to '0' (0 disables)." ) ( - "websockets.root", - value(&configured.protocol.web_root), - "The optional directory for serving files via HTTP/S, defaults to 'web'." + "node.snapshot_confirm", + value(&configured.node.snapshot_confirm), + "Completed confirmations that trigger snapshot, defaults to '0' (0 disables)." ) ( - "websockets.ca_certificate", - value(&configured.protocol.web_ca_certificate), - "The SSL certificate authority file, defaults to '', enables secure endpoints." + "node.sample_period_seconds", + value(&configured.node.sample_period_seconds), + "Sampling period for drop of stalled channels, defaults to 10 (0 disables)." ) ( - "websockets.server_private_key", - value(&configured.protocol.web_server_private_key), - "The SSL private key file, defaults to 'key.pem', enables secure endpoints." + "node.currency_window_minutes", + value(&configured.node.currency_window_minutes), + "Time from present that blocks are considered current, defaults to 60 (0 disables)." ) + // ####################### + ////( + //// "node.notify_limit_hours", + //// value(&configured.node.notify_limit_hours), + //// "Disable relay when top block age exceeds, defaults to 24 (0 disables)." + ////) + ////( + //// "node.byte_fee_satoshis", + //// value(&configured.node.byte_fee_satoshis), + //// "The minimum fee per byte, cumulative for conflicts, defaults to 1." + ////) + ////( + //// "node.sigop_fee_satoshis", + //// value(&configured.node.sigop_fee_satoshis), + //// "The minimum fee per sigop, additional to byte fee, defaults to 100." + ////) + ////( + //// "node.minimum_output_satoshis", + //// value(&configured.node.minimum_output_satoshis), + //// "The minimum output value, defaults to 500." + ////) + + /* [log] */ +#if defined(HAVE_LOGA) ( - "websockets.server_certificate", - value(&configured.protocol.web_server_certificate), - "The SSL certificate file, defaults to 'server.pem', enables secure endpoints." + "log.application", + value(&configured.log.application), + "Enable application logging, defaults to true." ) +#endif +#if defined(HAVE_LOGN) ( - "websockets.client_certificates", - value(&configured.protocol.web_client_certificates), - "The SSL client certificates directory, defaults to 'clients'." + "log.news", + value(&configured.log.news), + "Enable news logging, defaults to true." ) +#endif +#if defined(HAVE_LOGS) ( - "websockets.origin", - value(&configured.protocol.web_origins), - "Allowed websocket origin, multiple entries allowed." + "log.session", + value(&configured.log.session), + "Enable session logging, defaults to true." ) - - /* [zeromq] */ +#endif +#if defined(HAVE_LOGP) ( - "zeromq.secure_query_endpoint", - value(&configured.server.zeromq_secure_query_endpoint), - "The secure query zeromq endpoint, defaults to 'tcp://*:9081'." + "log.protocol", + value(&configured.log.protocol), + "Enable protocol logging, defaults to false." ) +#endif +#if defined(HAVE_LOGX) ( - "zeromq.secure_heartbeat_endpoint", - value(&configured.server.zeromq_secure_heartbeat_endpoint), - "The secure heartbeat zeromq endpoint, defaults to 'tcp://*:9082'." + "log.proxy", + value(&configured.log.proxy), + "Enable proxy logging, defaults to false." ) +#endif +#if defined(HAVE_LOGR) ( - "zeromq.secure_block_endpoint", - value(&configured.server.zeromq_secure_block_endpoint), - "The secure block publishing zeromq endpoint, defaults to 'tcp://*:9083'." + "log.remote", + value(&configured.log.remote), + "Enable remote fault logging, defaults to true." ) +#endif +#if defined(HAVE_LOGF) ( - "zeromq.secure_transaction_endpoint", - value(&configured.server.zeromq_secure_transaction_endpoint), - "The secure transaction publishing zeromq endpoint, defaults to 'tcp://*:9084'." + "log.fault", + value(&configured.log.fault), + "Enable local fault logging, defaults to true." ) +#endif +#if defined(HAVE_LOGQ) ( - "zeromq.public_query_endpoint", - value(&configured.server.zeromq_public_query_endpoint), - "The public query zeromq endpoint, defaults to 'tcp://*:9091'." + "log.quitting", + value(&configured.log.quitting), + "Enable quitting logging, defaults to false." ) +#endif +#if defined(HAVE_LOGO) ( - "zeromq.public_heartbeat_endpoint", - value(&configured.server.zeromq_public_heartbeat_endpoint), - "The public heartbeat zeromq endpoint, defaults to 'tcp://*:9092'." + "log.objects", + value(&configured.log.objects), + "Enable objects logging, defaults to false." ) +#endif +#if defined(HAVE_LOGV) ( - "zeromq.public_block_endpoint", - value(&configured.server.zeromq_public_block_endpoint), - "The public block publishing zeromq endpoint, defaults to 'tcp://*:9093'." + "log.verbose", + value(&configured.log.verbose), + "Enable verbose logging, defaults to false." ) +#endif ( - "zeromq.public_transaction_endpoint", - value(&configured.server.zeromq_public_transaction_endpoint), - "The public transaction publishing zeromq endpoint, defaults to 'tcp://*:9094'." + "log.maximum_size", + value(&configured.log.maximum_size), + "The maximum byte size of each pair of rotated log files, defaults to 1000000." ) +#if defined (HAVE_MSC) ( - "zeromq.server_private_key", - value(&configured.server.zeromq_server_private_key), - "The Z85-encoded private key of the server, enables secure endpoints." + "log.symbols", + value(&configured.log.symbols), + "Path to windows debug build symbols file (.pdb)." ) +#endif ( - "zeromq.client_public_key", - value(&configured.server.zeromq_client_public_keys), - "Allowed Z85-encoded public key of the client, multiple entries allowed." + "log.path", + value(&configured.log.path), + "The log files directory, defaults to empty." ); return description; } -bool parser::parse(int argc, const char* argv[], std::ostream& error) +bool parser::parse(int argc, const char* argv[], std::ostream& error) THROWS { try { @@ -869,7 +1124,7 @@ bool parser::parse(int argc, const char* argv[], std::ostream& error) load_command_variables(variables, argc, argv); load_environment_variables(variables, BS_ENVIRONMENT_VARIABLE_PREFIX); - // Don't load the rest if any of these options are specified. + // Don't load config file if any of these options are specified. if (!get_option(variables, BS_VERSION_VARIABLE) && !get_option(variables, BS_SETTINGS_VARIABLE) && !get_option(variables, BS_HELP_VARIABLE)) diff --git a/src/server_node.cpp b/src/server_node.cpp index 5fce2e43..c9ca6e9e 100644 --- a/src/server_node.cpp +++ b/src/server_node.cpp @@ -18,8 +18,6 @@ */ #include -#include -#include #include #include #include diff --git a/src/services/block_service.cpp b/src/services/block_service.cpp index a56cff00..52f6197b 100644 --- a/src/services/block_service.cpp +++ b/src/services/block_service.cpp @@ -18,8 +18,6 @@ */ #include -#include -#include #include #include #include diff --git a/src/services/heartbeat_service.cpp b/src/services/heartbeat_service.cpp index e7b56130..e41d86af 100644 --- a/src/services/heartbeat_service.cpp +++ b/src/services/heartbeat_service.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/src/services/transaction_service.cpp b/src/services/transaction_service.cpp index 63ef43a7..b0feaa04 100644 --- a/src/services/transaction_service.cpp +++ b/src/services/transaction_service.cpp @@ -18,7 +18,6 @@ */ #include -#include #include #include #include diff --git a/src/settings.cpp b/src/settings.cpp index 198f1dcf..7a3d9fe6 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -18,16 +18,20 @@ */ #include +#include #include +#include namespace libbitcoin { namespace server { -using namespace bc::system; -using namespace bc::system::asio; +using namespace system; +using namespace protocol; +using namespace std::chrono; settings::settings() - : priority(false), + : // [server] + priority(false), secure_only(false), query_workers(1), subscription_limit(1000), @@ -36,12 +40,13 @@ settings::settings() block_service_enabled(true), transaction_service_enabled(true), - // [zeromq] + // [zeromq] secure zeromq_secure_query_endpoint("tcp://*:9081"), zeromq_secure_heartbeat_endpoint("tcp://*:9082"), zeromq_secure_block_endpoint("tcp://*:9083"), zeromq_secure_transaction_endpoint("tcp://*:9084"), + // [zeromq] clear zeromq_public_query_endpoint("tcp://*:9091"), zeromq_public_heartbeat_endpoint("tcp://*:9092"), zeromq_public_block_endpoint("tcp://*:9093"), @@ -49,41 +54,40 @@ settings::settings() { } -// There are no current distinctions spanning chain contexts. -settings::settings(config::settings) +settings::settings(chain::selection context) : settings() { } -duration settings::heartbeat_interval() const +steady_clock::duration settings::heartbeat_service() const { return seconds(heartbeat_service_seconds); } -duration settings::subscription_expiration() const +steady_clock::duration settings::subscription_expiration() const { return minutes(subscription_expiration_minutes); } -const config::endpoint& settings::zeromq_query_endpoint(bool secure) const +const endpoint& settings::zeromq_query_endpoint(bool secure) const { return secure ? zeromq_secure_query_endpoint : zeromq_public_query_endpoint; } -const config::endpoint& settings::zeromq_heartbeat_endpoint(bool secure) const +const endpoint& settings::zeromq_heartbeat_endpoint(bool secure) const { return secure ? zeromq_secure_heartbeat_endpoint : zeromq_public_heartbeat_endpoint; } -const config::endpoint& settings::zeromq_block_endpoint(bool secure) const +const endpoint& settings::zeromq_block_endpoint(bool secure) const { return secure ? zeromq_secure_block_endpoint : zeromq_public_block_endpoint; } -const config::endpoint& settings::zeromq_transaction_endpoint(bool secure) const +const endpoint& settings::zeromq_transaction_endpoint(bool secure) const { return secure ? zeromq_secure_transaction_endpoint : zeromq_public_transaction_endpoint; diff --git a/src/web/block_socket.cpp b/src/web/block_socket.cpp deleted file mode 100644 index ce522b69..00000000 --- a/src/web/block_socket.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace libbitcoin { -namespace server { - -using namespace bc::protocol; -using namespace bc::system; -using namespace bc::system::chain; -using namespace bc::system::config; -using role = zmq::socket::role; - -static constexpr auto poll_interval_milliseconds = 100u; - -block_socket::block_socket(zmq::context& context, server_node& node, - bool secure) - : http::socket(context, node.protocol_settings(), secure), - settings_(node.server_settings()), - protocol_settings_(node.protocol_settings()) -{ -} - -void block_socket::work() -{ - zmq::socket sub(context_, role::subscriber, protocol_settings_); - - const auto endpoint = zeromq_endpoint().to_local(); - const auto ec = sub.connect(endpoint); - - if (ec) - { - LOG_ERROR(LOG_SERVER) - << "Failed to connect to block service " << endpoint << ": " - << ec.message(); - return; - } - - if (!started(start_websocket_handler())) - { - LOG_ERROR(LOG_SERVER) - << "Failed to start " << security_ << " block websocket handler."; - return; - } - - LOG_INFO(LOG_SERVER) - << "Bound " << security_ << " websocket block service to " - << websocket_endpoint(); - - // Default page data can now be set since the base socket's manager has - // been initialized. - set_default_page_data(get_default_page_data( - settings_.websockets_query_endpoint(secure_), - settings_.websockets_heartbeat_endpoint(secure_), - settings_.websockets_block_endpoint(secure_), - settings_.websockets_transaction_endpoint(secure_))); - - // TODO: this should be hidden in socket base. - // Hold a shared reference to the websocket thread_ so that we can - // properly call stop_websocket_handler on cleanup. - const auto thread_ref = thread_; - - zmq::poller poller; - poller.add(sub); - - while (!poller.terminated() && !stopped()) - { - if (poller.wait(poll_interval_milliseconds).contains(sub.id()) && - !handle_block(sub)) - break; - } - - const auto sub_stop = sub.stop(); - const auto websocket_stop = stop_websocket_handler(); - - if (!sub_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to disconnect " << security_ - << " block websocket service."; - - if (!websocket_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to stop " << security_ << " block websocket handler."; - - finished(sub_stop && websocket_stop); -} - -// Called by this thread's work() method. -// Returns true to continue future notifications. -bool block_socket::handle_block(zmq::socket& subscriber) -{ - if (stopped()) - return false; - - zmq::message response; - subscriber.receive(response); - - static constexpr size_t block_message_size = 3; - if (response.empty() || response.size() != block_message_size) - { - LOG_WARNING(LOG_SERVER) - << "Failure handling block notification: invalid data"; - - // Don't let a failure here prevent future notifications. - return true; - } - - uint16_t sequence{}; - uint32_t height; - data_chunk block_data; - response.dequeue(sequence); - response.dequeue(height); - response.dequeue(block_data); - - // Format and send transaction to websocket subscribers. - const auto block = system::chain::block::factory(block_data, true); - broadcast(http::to_json(block, height, sequence)); - - LOG_VERBOSE(LOG_SERVER) - << "Broadcasted " << security_ << " socket block [" - << height << "]"; - return true; -} - -const endpoint& block_socket::zeromq_endpoint() const -{ - // The Websocket to zeromq backend internally always uses the - // local public zeromq endpoint since it does not affect the - // external security of the websocket endpoint and impacts - // configuration and performance for no additional gain. - return settings_.zeromq_block_endpoint(false /* secure_ */); -} - -const endpoint& block_socket::websocket_endpoint() const -{ - return settings_.websockets_block_endpoint(secure_); -} - -} // namespace server -} // namespace libbitcoin diff --git a/src/web/default_page_data.cpp b/src/web/default_page_data.cpp deleted file mode 100644 index 470e483d..00000000 --- a/src/web/default_page_data.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include - -#include - -namespace libbitcoin { -namespace server { - -using namespace bc::system; - -// TODO: Generate this file via libbitcoin-build(?) -std::string get_default_page_data(const config::endpoint& query, - const config::endpoint& heartbeat, const config::endpoint& block, - const config::endpoint& transaction) -{ - const char* pre_image = R"heredoc( - - - - - - - - - - Libbitcoin Realtime Web Explorer - - - - - -
-
- - - - -
- - - - - - - - - -
Heartbeat
Last updatedBlock Height
-
-
- - - - - - - - - - - -
Recent Blocks
Block HeightBlock HashBlock AgeBlock Version
-
-
- - - - - - - - - - - - -
Latest Transactions
Transaction HashTotal Transacted (BTC)# Inputs# OutputsReceived Time
-
-
-

Powered by Libbitcoin.

-
-
-
- -)heredoc"; - - const std::string websocket_scheme = "ws"; - - // Simplify by modifying bc::config::endpoint(?) - const auto query_ws_endpoint = config::endpoint(websocket_scheme, - query.host(), query.port()).to_local(); - const auto heartbeat_ws_endpoint = config::endpoint(websocket_scheme, - heartbeat.host(), heartbeat.port()).to_local(); - const auto block_ws_endpoint = config::endpoint(websocket_scheme, - block.host(), block.port()).to_local(); - const auto transaction_ws_endpoint = config::endpoint(websocket_scheme, - transaction.host(), transaction.port()).to_local(); - - std::stringstream ss; - ss << "let QUERY_SERVICE_URL = '" << query_ws_endpoint << "';\n"; - ss << "let HEARTBEAT_SERVICE_URL = '" << heartbeat_ws_endpoint << "';\n"; - ss << "let BLOCK_SERVICE_URL = '" << block_ws_endpoint << "';\n"; - ss << "let TRANSACTION_SERVICE_URL = '" << transaction_ws_endpoint << "';\n"; - - std::stringstream html; - html << pre_image << image << post_image; - auto pre_declarations = html.str(); - - const std::string marker = "DECLARATIONS;"; - const auto start = pre_declarations.find(marker); - - return pre_declarations.replace(pre_declarations.begin() + start, - pre_declarations.begin() + start + marker.size(), ss.str()); -} - -} // namespace server -} // namespace libbitcoin diff --git a/src/web/heartbeat_socket.cpp b/src/web/heartbeat_socket.cpp deleted file mode 100644 index f9a1f24f..00000000 --- a/src/web/heartbeat_socket.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include - -#include -#include -#include -#include -#include -#include - -namespace libbitcoin { -namespace server { - -static constexpr auto poll_interval_milliseconds = 100u; - -using namespace bc::protocol; -using namespace bc::system::config; -using role = zmq::socket::role; - -heartbeat_socket::heartbeat_socket(zmq::context& context, server_node& node, - bool secure) - : http::socket(context, node.protocol_settings(), secure), - settings_(node.server_settings()), - protocol_settings_(node.protocol_settings()) -{ -} - -void heartbeat_socket::work() -{ - zmq::socket sub(context_, role::subscriber, protocol_settings_); - - const auto endpoint = zeromq_endpoint().to_local(); - const auto ec = sub.connect(endpoint); - - if (ec) - { - LOG_ERROR(LOG_SERVER) - << "Failed to connect to heartbeat service " << endpoint << ": " - << ec.message(); - return; - } - - if (!started(start_websocket_handler())) - { - LOG_ERROR(LOG_SERVER) - << "Failed to start " << security_ - << " heartbeat websocket handler."; - return; - } - - LOG_INFO(LOG_SERVER) - << "Bound " << security_ << " websocket heartbeat service to " - << websocket_endpoint(); - - // Default page data can now be set since the base socket's manager has - // been initialized. - set_default_page_data(get_default_page_data( - settings_.websockets_query_endpoint(secure_), - settings_.websockets_heartbeat_endpoint(secure_), - settings_.websockets_block_endpoint(secure_), - settings_.websockets_transaction_endpoint(secure_))); - - // TODO: this should be hidden in socket base. - // Hold a shared reference to the websocket thread_ so that we can - // properly call stop_websocket_handler on cleanup. - const auto thread_ref = thread_; - - zmq::poller poller; - poller.add(sub); - - while (!poller.terminated() && !stopped()) - { - if (poller.wait(poll_interval_milliseconds).contains(sub.id()) && - !handle_heartbeat(sub)) - break; - } - - const auto sub_stop = sub.stop(); - const auto websocket_stop = stop_websocket_handler(); - - if (!sub_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to disconnect " << security_ - << " hearbeat websocket service."; - - if (!websocket_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to stop " << security_ - << " heartbeat websocket handler."; - - finished(sub_stop && websocket_stop); -} - -// Called by this thread's work() method. -// Returns true to continue future notifications. -bool heartbeat_socket::handle_heartbeat(zmq::socket& subscriber) -{ - if (stopped()) - return false; - - zmq::message response; - subscriber.receive(response); - - static constexpr size_t heartbeat_message_size = 2; - if (response.empty() || response.size() != heartbeat_message_size) - { - LOG_WARNING(LOG_SERVER) - << "Failure handling heartbeat notification: invalid data."; - - // Don't let a failure here prevent future notifications. - return true; - } - - uint16_t sequence{}; - uint64_t height; - response.dequeue(sequence); - response.dequeue(height); - - broadcast(http::to_json(height, sequence)); - - LOG_VERBOSE(LOG_SERVER) - << "Broadcasted " << security_ << " socket heartbeat [" << height - << ", " << sequence << "]"; - return true; -} - -const endpoint& heartbeat_socket::zeromq_endpoint() const -{ - // The Websocket to zeromq backend internally always uses the - // local public zeromq endpoint since it does not affect the - // external security of the websocket endpoint and impacts - // configuration and performance for no additional gain. - return settings_.zeromq_heartbeat_endpoint(false /* secure_ */); -} - -const endpoint& heartbeat_socket::websocket_endpoint() const -{ - return settings_.websockets_heartbeat_endpoint(secure_); -} - -} // namespace server -} // namespace libbitcoin diff --git a/src/web/query_socket.cpp b/src/web/query_socket.cpp deleted file mode 100644 index 2df7cae1..00000000 --- a/src/web/query_socket.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include - -#include -#include -#include -#include - -namespace libbitcoin { -namespace server { - -using namespace bc::protocol; -using namespace bc::system; -using namespace bc::system::config; -using namespace bc::system::machine; -using namespace std::placeholders; -using role = zmq::socket::role; -using connection_ptr = http::connection_ptr; - -static constexpr auto poll_interval_milliseconds = 100u; - -query_socket::query_socket(zmq::context& context, server_node& node, - bool secure) - : http::socket(context, node.protocol_settings(), secure), - settings_(node.server_settings()), - protocol_settings_(node.protocol_settings()) -{ - // JSON to ZMQ request encoders. - //------------------------------------------------------------------------- - - const auto encode_empty = [](zmq::message& request, - const std::string& command, const std::string& /* arguments */, - uint32_t id) - { - request.enqueue(command); - request.enqueue_little_endian(id); - request.enqueue(); - return true; - }; - - const auto encode_height = [](zmq::message& request, - const std::string& command, const std::string& arguments, uint32_t id) - { - uint32_t value; - if (!deserialize(value, arguments)) - return false; - - request.enqueue(command); - request.enqueue_little_endian(id); - request.enqueue_little_endian(value); - return true; - }; - - const auto encode_hash = [](zmq::message& request, - const std::string& command, const std::string& arguments, uint32_t id) - { - hash_digest hash; - if (!decode_hash(hash, arguments)) - return false; - - request.enqueue(command); - request.enqueue_little_endian(id); - request.enqueue(to_chunk(hash)); - return true; - }; - - const auto encode_hash_or_height = [&](zmq::message& request, - const std::string& command, const std::string& arguments, uint32_t id) - { - return encode_hash(request, command, arguments, id) || - encode_height(request, command, arguments, id); - }; - - // A local clone of the task_sender send logic, for the decoders - // below that don't need to use that mechanism since they're - // already guaranteed to be run on the web thread. - auto decode_send = [](connection_ptr connection, const std::string& json) - { - if (!connection || connection->closed()) - return false; - - if (json.size() > std::numeric_limits::max()) - { - LOG_ERROR(LOG_SERVER_HTTP) - << "Skipping JSON-RPC response of size " << json.size(); - return false; - } - - const int32_t json_size = static_cast(json.size()); - - if (!connection->json_rpc()) - return connection->write(json) == json_size; - - http::http_reply reply; - const auto response = reply.generate(http::protocol_status::ok, {}, - json_size, false) + json; - - LOG_VERBOSE(LOG_SERVER_HTTP) - << "Writing JSON-RPC response: " << response; - - return connection->write(response) == json_size; - }; - - // JSON to ZMQ response decoders. - // ------------------------------------------------------------------------- - // These all run on the websocket thread, so can write on the - // connection directly. - const auto decode_height_raw = [decode_send](const data_chunk& data, - const uint32_t id, connection_ptr connection, bool rpc) - { - data_source istream(data); - istream_reader source(istream); - const auto height = source.read_4_bytes_little_endian(); - const auto json = rpc ? http::rpc::to_json(height, id) : http::to_json( - height, id); - decode_send(connection, json); - }; - - const auto decode_transaction_raw = [&node, decode_send]( - const data_chunk& data, const uint32_t id, connection_ptr connection, - bool rpc) - { - const auto witness = chain::script::is_enabled( - node.blockchain_settings().enabled_forks(), rule_fork::bip141_rule); - const auto transaction = chain::transaction::factory(data, true, - witness); - const auto json = rpc ? http::rpc::to_json(transaction, id) : - http::to_json(transaction, id); - decode_send(connection, json); - }; - - const auto decode_block_raw = [&node, decode_send](const data_chunk& data, - const uint32_t id, connection_ptr connection, bool rpc) - { - const auto witness = chain::script::is_enabled( - node.blockchain_settings().enabled_forks(), rule_fork::bip141_rule); - const auto block = chain::block::factory(data, witness); - const auto json = rpc ? http::rpc::to_json(block, id) : - http::to_json(block, id); - decode_send(connection, json); - }; - - const auto decode_block_header_raw = [decode_send](const data_chunk& data, - const uint32_t id, connection_ptr connection, bool rpc) - { - const auto header = chain::header::factory(data, true); - const auto json = rpc ? http::rpc::to_json(header, id) : - http::to_json(header, id); - decode_send(connection, json); - }; - - const auto decode_block_hash_from_header_raw = [decode_send]( - const data_chunk& data, uint32_t id, connection_ptr connection, - bool rpc) - { - const auto header = chain::header::factory(data, true); - const auto json = rpc ? http::rpc::to_json(header.hash(), id) : - http::to_json(header.hash(), id); - decode_send(connection, json); - }; - -// Defines both handler variants based on the raw method, one for -// native and one for rpc. -#define BUILD_DECODER(name) \ - const auto name = std::bind(name##_raw, _1, _2, _3, false); \ - const auto name##_rpc = std::bind(name##_raw, _1, _2, _3, true) - - BUILD_DECODER(decode_height); - BUILD_DECODER(decode_transaction); - BUILD_DECODER(decode_block); - BUILD_DECODER(decode_block_header); - BUILD_DECODER(decode_block_hash_from_header); - -#undef BUILD_DECODER - -#define REGISTER_HANDLER(native, core, encoder, decoder) \ - handlers_[core] = handlers{ native, encoder, decoder }; \ - handlers_[native] = handlers{ native, encoder, decoder }; \ - rpc_handlers_[core] = handlers{ native, encoder, decoder##_rpc }; \ - rpc_handlers_[native] = handlers{ native, encoder, decoder##_rpc } - - REGISTER_HANDLER("blockchain.fetch_last_height", "getblockcount", - encode_empty, decode_height); - REGISTER_HANDLER("transaction_pool.fetch_transaction", "getrawtransaction", - encode_hash, decode_transaction); - REGISTER_HANDLER("blockchain.fetch_block", "getblock", - encode_hash_or_height, decode_block); - REGISTER_HANDLER("blockchain.fetch_block_header", "getblockheader", - encode_hash_or_height, decode_block_header); - REGISTER_HANDLER("blockchain.fetch_block_header", "getblockhash", - encode_height, decode_block_hash_from_header); - REGISTER_HANDLER("blockchain.fetch_block_height", "getblockheight", - encode_hash, decode_height); - -#undef REGISTER_HANDLER -} - -void query_socket::work() -{ - zmq::socket dealer(context_, role::dealer, protocol_settings_); - zmq::socket query_receiver(context_, role::pair, protocol_settings_); - - auto ec = query_receiver.bind(query_endpoint()); - - if (ec) - { - LOG_ERROR(LOG_SERVER) - << "Failed to bind " << security_ << " query internal socket: " - << ec.message(); - return; - } - - const auto endpoint = zeromq_endpoint().to_local(); - ec = dealer.connect(endpoint); - - if (ec) - { - LOG_ERROR(LOG_SERVER) - << "Failed to connect to " << security_ << " query socket " - << endpoint << ": " << ec.message(); - return; - } - - if (!started(start_websocket_handler())) - { - LOG_ERROR(LOG_SERVER) - << "Failed to start " << security_ << " websocket handler: " - << ec.message(); - return; - } - - LOG_INFO(LOG_SERVER) - << "Bound " << security_ << " websocket query service to " - << websocket_endpoint(); - - // Default page data can now be set since the base socket's manager has - // been initialized. - set_default_page_data(get_default_page_data( - settings_.websockets_query_endpoint(secure_), - settings_.websockets_heartbeat_endpoint(secure_), - settings_.websockets_block_endpoint(secure_), - settings_.websockets_transaction_endpoint(secure_))); - - // TODO: this should be hidden in socket base. - // Hold a shared reference to the websocket thread_ so that we can - // properly call stop_websocket_handler on cleanup. - const auto thread_ref = thread_; - - zmq::poller poller; - poller.add(dealer); - poller.add(query_receiver); - - while (!poller.terminated() && !stopped()) - { - const auto identifiers = poller.wait(poll_interval_milliseconds); - - if (identifiers.contains(query_receiver.id()) && - !forward(query_receiver, dealer)) - break; - - if (identifiers.contains(dealer.id()) && !handle_query(dealer)) - break; - } - - const auto query_stop = query_receiver.stop(); - const auto dealer_stop = dealer.stop(); - const auto websocket_stop = stop_websocket_handler(); - - if (!query_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to unbind " << security_ << " websocket query service."; - - if (!dealer_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to disconnect " << security_ << " query connection."; - - if (!websocket_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to stop " << security_ << " query websocket handler."; - - finished(query_stop && dealer_stop && websocket_stop); -} - -// Called by this thread's zmq work() method. Returns true to -// continue future notifications. -bool query_socket::handle_query(zmq::socket& dealer) -{ - if (stopped()) - return false; - - zmq::message response; - auto ec = dealer.receive(response); - - if (ec) - { - LOG_ERROR(LOG_SERVER) - << "Failed to receive response from dealer: " << ec.message(); - return true; - } - - static constexpr size_t query_message_size = 3; - if (response.empty() || response.size() != query_message_size) - { - LOG_WARNING(LOG_SERVER) - << "Failure handling query response: invalid data size."; - return true; - } - - uint32_t sequence{}; - data_chunk data; - std::string command; - - if (!response.dequeue(command) || !response.dequeue(sequence) || - !response.dequeue(data)) - { - LOG_WARNING(LOG_SERVER) - << "Failure handling query response: invalid data parts."; - return true; - } - - socket::queue_response(sequence, data, command); - return true; -} - -const endpoint& query_socket::zeromq_endpoint() const -{ - // The Websocket to zeromq backend internally always uses the - // local public zeromq endpoint since it does not affect the - // external security of the websocket endpoint and impacts - // configuration and performance for no additional gain. - return settings_.zeromq_query_endpoint(false /* secure_ */); -} - -const endpoint& query_socket::websocket_endpoint() const -{ - return settings_.websockets_query_endpoint(secure_); -} - -const endpoint& query_socket::query_endpoint() const -{ - static const endpoint secure_query("inproc://secure_query_websockets"); - static const endpoint public_query("inproc://public_query_websockets"); - return secure_ ? secure_query : public_query; -} - -const std::shared_ptr query_socket::service() const -{ - return service_; -} - -// This method is run by the web socket thread. -void query_socket::handle_websockets() -{ - // A zmq socket must remain on its single thread. - service_ = std::make_shared(context_, role::pair, - protocol_settings_); - - // Hold a reference to this service_ socket member by this thread - // method so that we can properly shutdown even if the query_socket - // object is destroyed. - const auto service_ref = service_; - const auto ec = service_ref->connect(query_endpoint()); - - if (ec) - { - LOG_ERROR(LOG_SERVER) - << "Failed to connect " << security_ << " query sender socket: " - << ec.message(); - socket_started_.set_value(false); - return; - } - - // socket::handle_websockets does web socket initialization and runs the - // web event loop. Inside that loop, socket::poll eventually calls into - // the static handle_event callback, which calls socket::notify_query_work, - // which uses this 'service_' zmq socket for sending incoming requests and - // reading the json web responses. - socket::handle_websockets(); - - if (!service_ref->stop()) - { - LOG_ERROR(LOG_SERVER) - << "Failed to disconnect " << security_ << " query sender."; - } -} - -bool query_socket::start_websocket_handler() -{ - auto started = socket_started_.get_future(); - thread_ = std::make_shared(&query_socket::handle_websockets, - this); - return started.get(); -} - -} // namespace server -} // namespace libbitcoin diff --git a/src/web/transaction_socket.cpp b/src/web/transaction_socket.cpp deleted file mode 100644 index e18f30aa..00000000 --- a/src/web/transaction_socket.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/** - * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) - * - * This file is part of libbitcoin. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -#include - -#include -#include -#include -#include -#include - -namespace libbitcoin { -namespace server { - -using namespace std::placeholders; -using namespace bc::protocol; -using namespace bc::system; -using namespace bc::system::chain; -using namespace bc::system::config; -using namespace bc::system::message; -using role = zmq::socket::role; - -static constexpr auto poll_interval_milliseconds = 100u; - -transaction_socket::transaction_socket(zmq::context& context, - server_node& node, bool secure) - : http::socket(context, node.protocol_settings(), secure), - settings_(node.server_settings()), - protocol_settings_(node.protocol_settings()) -{ -} - -void transaction_socket::work() -{ - zmq::socket sub(context_, role::subscriber, protocol_settings_); - - const auto endpoint = zeromq_endpoint().to_local(); - const auto ec = sub.connect(endpoint); - - if (ec) - { - LOG_ERROR(LOG_SERVER) - << "Failed to connect to transaction service " << endpoint << ": " - << ec.message(); - return; - } - - if (!started(start_websocket_handler())) - { - LOG_ERROR(LOG_SERVER) - << "Failed to start " << security_ - << " transaction websocket handler."; - return; - } - - LOG_INFO(LOG_SERVER) - << "Bound " << security_ << " websocket transaction service to " - << websocket_endpoint(); - - // Default page data can now be set since the base socket's manager has - // been initialized. - set_default_page_data(get_default_page_data( - settings_.websockets_query_endpoint(secure_), - settings_.websockets_heartbeat_endpoint(secure_), - settings_.websockets_block_endpoint(secure_), - settings_.websockets_transaction_endpoint(secure_))); - - // TODO: this should be hidden in socket base. - // Hold a shared reference to the websocket thread_ so that we can - // properly call stop_websocket_handler on cleanup. - const auto thread_ref = thread_; - - zmq::poller poller; - poller.add(sub); - - while (!poller.terminated() && !stopped()) - { - if (poller.wait(poll_interval_milliseconds).contains(sub.id()) && - !handle_transaction(sub)) - break; - } - - const auto sub_stop = sub.stop(); - const auto websocket_stop = stop_websocket_handler(); - - if (!sub_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to disconnect " << security_ - << " transaction websocket service."; - - if (!websocket_stop) - LOG_ERROR(LOG_SERVER) - << "Failed to stop " << security_ - << " transaction websocket handler."; - - finished(sub_stop && websocket_stop); -} - -// Called by this thread's work() method. -// Returns true to continue future notifications. -bool transaction_socket::handle_transaction(zmq::socket& subscriber) -{ - if (stopped()) - return false; - - zmq::message response; - subscriber.receive(response); - - static constexpr size_t transaction_message_size = 2; - if (response.empty() || response.size() != transaction_message_size) - { - LOG_WARNING(LOG_SERVER) - << "Failure handling transaction notification: invalid data"; - - // Don't let a failure here prevent future notifications. - return true; - } - - uint16_t sequence{}; - data_chunk transaction_data; - response.dequeue(sequence); - response.dequeue(transaction_data); - - chain::transaction tx; - if (!tx.from_data(transaction_data, true, true)) - { - LOG_WARNING(LOG_SERVER) - << "Failure handling transaction notification: invalid data"; - - // Don't let a failure here prevent future notifications. - return true; - } - - broadcast(http::to_json(tx, sequence)); - - LOG_VERBOSE(LOG_SERVER) - << "Broadcasted " << security_ << " socket tx [" - << encode_hash(tx.hash()) << "]"; - return true; -} - -const endpoint& transaction_socket::zeromq_endpoint() const -{ - // The Websocket to zeromq backend internally always uses the - // local public zeromq endpoint since it does not affect the - // external security of the websocket endpoint and impacts - // configuration and performance for no additional gain. - return settings_.zeromq_transaction_endpoint(false /* secure_ */); -} - -const endpoint& transaction_socket::websocket_endpoint() const -{ - return settings_.websockets_transaction_endpoint(secure_); -} - -} // namespace server -} // namespace libbitcoin diff --git a/src/workers/authenticator.cpp b/src/workers/authenticator.cpp index a9f8a10d..42164c1e 100644 --- a/src/workers/authenticator.cpp +++ b/src/workers/authenticator.cpp @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -46,7 +45,7 @@ authenticator::authenticator(server_node& node) } // Allow wins in case of conflict with deny (first writer). - for (const auto& address: settings.client_addresses) + for (const auto& address: settings.clients) { LOG_DEBUG(LOG_SERVER) << "Allow client address [" << address.to_hostname() << "]"; diff --git a/src/workers/notification_worker.cpp b/src/workers/notification_worker.cpp index 8aec6eba..72fa0cef 100644 --- a/src/workers/notification_worker.cpp +++ b/src/workers/notification_worker.cpp @@ -20,10 +20,7 @@ #include #include -#include -#include #include -#include #include #include #include diff --git a/src/workers/query_worker.cpp b/src/workers/query_worker.cpp index 474d5a65..102fb8b1 100644 --- a/src/workers/query_worker.cpp +++ b/src/workers/query_worker.cpp @@ -18,8 +18,6 @@ */ #include -#include -#include #include #include #include