Compare commits

..

19 Commits

Author SHA1 Message Date
SChernykh 7ca1beeb73 P2PServer fixes (peer list loading, peer id and other smaller fixes)
C/C++ CI / build-alpine-static (map[arch:aarch64 branch:latest-stable flags:-ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419]) (push) Failing after 31s
C/C++ CI / build-alpine-static (map[arch:riscv64 branch:latest-stable flags:-ffunction-sections]) (push) Failing after 7s
C/C++ CI / build-alpine-static (map[arch:x86_64 branch:latest-stable flags:-ffunction-sections]) (push) Failing after 9s
C/C++ CI / build-ubuntu (map[c:gcc-10 cpp:g++-10 flags: os:ubuntu-22.04]) (push) Failing after 10m28s
C/C++ CI / build-ubuntu (map[c:gcc-11 cpp:g++-11 flags: os:ubuntu-22.04]) (push) Failing after 9m1s
Sync test / sync-test-ubuntu-msan (push) Has been cancelled
Sync test / sync-test-ubuntu-ubsan (push) Has been cancelled
Sync test / sync-test-ubuntu-asan (push) Has been cancelled
Sync test / sync-test-ubuntu-tysan (push) Has been cancelled
Sync test / sync-test-macos (map[flags: os:macos-26-intel]) (push) Has been cancelled
Sync test / sync-test-macos (map[flags:-target arm64-apple-macos-11 os:macos-26]) (push) Has been cancelled
Sync test / sync-test-windows-debug-asan (push) Has been cancelled
Sync test / sync-test-windows-leaks (push) Has been cancelled
clang-tidy / clang-tidy (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
Code coverage / coverage (push) Has been cancelled
cppcheck / cppcheck-ubuntu (push) Has been cancelled
cppcheck / cppcheck-windows (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-13 cpp:g++-13 flags: os:ubuntu-24.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-14 cpp:g++-14 flags: os:ubuntu-24.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-9 cpp:g++-9 flags: os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-static-libs (map[flags:-fuse-linker-plugin -ffunction-sections]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419 os:ubuntu-22.04-arm]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:gcc cxx:g++ flags:-ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes -Wno-attributes]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[grpc:OFF os:2022 rx:OFF tls:OFF upnp:OFF vs:Visual Studio 17 2022 vspath:C:\Program Files\Microsoft Visual Studio\2022\Enterprise]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[grpc:OFF os:2022 rx:OFF tls:ON upnp:OFF vs:Visual Studio 17 2022 vspath:C:\Program Files\Microsoft Visual Studio\2022\Enterprise]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[grpc:OFF os:2022 rx:OFF tls:ON upnp:ON vs:Visual Studio 17 2022 vspath:C:\Program Files\Microsoft Visual Studio\2022\Enterprise]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[grpc:OFF os:2022 rx:ON tls:ON upnp:ON vs:Visual Studio 17 2022 vspath:C:\Program Files\Microsoft Visual Studio\2022\Enterprise]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[grpc:ON os:2022 rx:ON tls:ON upnp:ON vs:Visual Studio 17 2022 vspath:C:\Program Files\Microsoft Visual Studio\2022\Enterprise]) (push) Has been cancelled
C/C++ CI / build-macos (push) Has been cancelled
C/C++ CI / build-macos-aarch64 (push) Has been cancelled
C/C++ CI / build-freebsd (map[architecture:x86-64 host:ubuntu-latest name:freebsd version:13.3]) (push) Has been cancelled
C/C++ CI / build-openbsd (map[architecture:x86-64 host:ubuntu-latest name:openbsd version:7.4]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-12 cpp:g++-12 flags: os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:clang cxx:clang++ flags:-fuse-ld=lld -Wno-unused-command-line-argument -Wno-nan-infinity-disabled -Wno-attributes]) (push) Has been cancelled
Microsoft C++ Code Analysis / Analyze (push) Has been cancelled
source-snapshot / source-snapshot (push) Has been cancelled
Sync test / sync-test-ubuntu-tsan (push) Has been cancelled
2026-04-25 10:25:48 +02:00
SChernykh 85750521bb TCPServer fixes 2026-04-24 23:30:37 +02:00
SChernykh 0255b801e5 CI: use macos-26 2026-04-24 19:37:01 +02:00
SChernykh fa53bdea55 More fixes and refactoring 2026-04-24 18:05:13 +02:00
SChernykh e1acf7b786 Fixed cppcheck error 2026-04-24 16:03:17 +02:00
SChernykh 54e0d3f3eb Refactored merge mining code 2026-04-24 11:01:59 +02:00
SChernykh eaee503d05 Updated dependencies 2026-04-20 11:21:59 +02:00
SChernykh 35f97b999c Build scripts: updated versions 2026-04-12 07:41:53 +02:00
SChernykh 44ea8e4557 CI: updated actions versions 2026-04-10 20:21:48 +02:00
SChernykh f3d97dc3d6 Fixed CI errors 2026-04-10 18:19:28 +02:00
SChernykh a32b4a6336 CI: use clang-22 2026-04-10 16:39:58 +02:00
jpk68 34f21e6236 Fixed for i2p 2026-03-13 16:12:03 +01:00
SChernykh 964e4a6163 Updated i2p seed node 2026-03-13 10:58:58 +01:00
SChernykh f1b2c3c51f Updated curl to 8.19.0 2026-03-11 10:03:02 +01:00
SChernykh b05361653e More cleanup and tests 2026-03-08 20:30:07 +01:00
SChernykh 0019d9ff0d Cleanup, compilation error fixes 2026-03-08 17:18:49 +01:00
jpk68 941e5114d8 Add I2P support 2026-03-08 16:50:02 +01:00
SChernykh bec1a56f7d Fix compile error 2026-03-07 20:43:44 +01:00
SChernykh dcfc64da42 Updated libuv to v1.52.1 2026-03-07 18:44:03 +01:00
47 changed files with 1072 additions and 478 deletions
+37 -37
View File
@@ -36,7 +36,7 @@ jobs:
apk add git cmake gcc g++ make linux-headers xz
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -53,7 +53,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='-Os -flto=auto ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='-Os -flto=auto ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j$(nproc)
- name: Build libzmq
@@ -104,7 +104,7 @@ jobs:
file p2pool
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-alpine-static-${{ matrix.config.arch }}
path: build/p2pool
@@ -132,7 +132,7 @@ jobs:
sudo apt install -y git build-essential cmake libuv1-dev libzmq3-dev libgss-dev libcurl4-openssl-dev libidn2-0-dev xz-utils ${{ matrix.config.c }} ${{ matrix.config.cpp }}
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -165,7 +165,7 @@ jobs:
./p2pool_tests
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-${{ matrix.config.os }}-${{ matrix.config.c }}
path: build/p2pool
@@ -189,7 +189,7 @@ jobs:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 --slave /usr/bin/g++ g++ /usr/bin/g++-12 --slave /usr/bin/gcov gcov /usr/bin/gcov-12
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -204,7 +204,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='-Os -flto=auto ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='-Os -flto=auto ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j$(nproc)
- name: Build libzmq
@@ -244,7 +244,7 @@ jobs:
./p2pool_tests
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-ubuntu-static-libs
path: build/p2pool
@@ -266,7 +266,7 @@ jobs:
sudo apt install -y git build-essential cmake xz-utils
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -281,7 +281,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='-Os -flto=auto ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='-Os -flto=auto ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j$(nproc)
- name: Build libzmq
@@ -321,7 +321,7 @@ jobs:
./p2pool_tests
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-${{ matrix.config.os }}-aarch64
path: build/p2pool
@@ -343,7 +343,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -368,7 +368,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j$(nproc)
- name: Build libzmq
@@ -408,7 +408,7 @@ jobs:
./p2pool_tests.exe
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-msys2-${{ matrix.config.c }}.exe
path: build/p2pool.exe
@@ -429,7 +429,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -480,7 +480,7 @@ jobs:
p2pool_tests.exe
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-vs-${{ matrix.config.os }}-randomx-${{ matrix.config.rx }}-upnp-${{ matrix.config.upnp }}-grpc-${{ matrix.config.grpc }}-tls-${{ matrix.config.tls }}.exe
path: build/Release/p2pool.exe
@@ -488,18 +488,18 @@ jobs:
build-macos:
timeout-minutes: 90
runs-on: macos-15-intel
runs-on: macos-26-intel
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-Os -flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DCURL_ENABLE_EXPORT_TARGET=OFF -DCURL_DISABLE_HEADERS_API=ON -DCURL_DISABLE_BINDLOCAL=ON -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_DISABLE_ALTSVC=ON -DCURL_DISABLE_COOKIES=ON -DCURL_DISABLE_DOH=ON -DCURL_DISABLE_GETOPTIONS=ON -DCURL_DISABLE_HSTS=ON -DCURL_DISABLE_LIBCURL_OPTION=ON -DCURL_DISABLE_MIME=ON -DCURL_DISABLE_NETRC=ON -DCURL_DISABLE_NTLM=ON -DCURL_DISABLE_PARSEDATE=ON -DCURL_DISABLE_PROGRESS_METER=ON -DCURL_DISABLE_SHUFFLE_DNS=ON -DCURL_DISABLE_SOCKETPAIR=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_DISABLE_WEBSOCKETS=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_DISABLE_TESTS=ON -DUSE_NGHTTP2=OFF -DBUILD_EXAMPLES=OFF -DP2POOL_BORINGSSL=ON -DCURL_DISABLE_SRP=ON -DCURL_DISABLE_AWS=ON -DCURL_DISABLE_BASIC_AUTH=ON -DCURL_DISABLE_BEARER_AUTH=ON -DCURL_DISABLE_KERBEROS_AUTH=ON -DCURL_DISABLE_NEGOTIATE_AUTH=ON -DOPENSSL_INCLUDE_DIR=../grpc/third_party/boringssl-with-bazel/include
cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-Os -flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DCURL_ENABLE_EXPORT_TARGET=OFF -DCURL_DISABLE_HEADERS_API=ON -DCURL_DISABLE_BINDLOCAL=ON -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_DISABLE_ALTSVC=ON -DCURL_DISABLE_COOKIES=ON -DCURL_DISABLE_DOH=ON -DCURL_DISABLE_GETOPTIONS=ON -DCURL_DISABLE_HSTS=ON -DCURL_DISABLE_LIBCURL_OPTION=ON -DCURL_DISABLE_MIME=ON -DCURL_DISABLE_NETRC=ON -DCURL_DISABLE_NTLM=ON -DCURL_DISABLE_PARSEDATE=ON -DCURL_DISABLE_PROGRESS_METER=ON -DCURL_DISABLE_SHUFFLE_DNS=ON -DCURL_DISABLE_SOCKETPAIR=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_DISABLE_WEBSOCKETS=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_DISABLE_TESTS=ON -DUSE_NGHTTP2=OFF -DBUILD_EXAMPLES=OFF -DP2POOL_BORINGSSL=ON -DCURL_DISABLE_SRP=ON -DCURL_DISABLE_AWS=ON -DCURL_DISABLE_BASIC_AUTH=ON -DCURL_DISABLE_BEARER_AUTH=ON -DCURL_DISABLE_KERBEROS_AUTH=ON -DCURL_DISABLE_NEGOTIATE_AUTH=ON -DOPENSSL_INCLUDE_DIR=../grpc/third_party/boringssl-with-bazel/include
make -j4
- name: Build libuv
@@ -507,7 +507,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j4
- name: Build libzmq
@@ -515,14 +515,14 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@18)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_CXX_FLAGS='-Os -flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@20)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_CXX_FLAGS='-Os -flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
make -j4
- name: Build p2pool
run: |
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@18)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_CXX_FLAGS='-flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_ASM_FLAGS='-target x86_64-apple-macos10.13' -DSTATIC_LIBS=ON
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@20)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_CXX_FLAGS='-flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_ASM_FLAGS='-target x86_64-apple-macos10.13' -DSTATIC_LIBS=ON
make -j4 p2pool
- name: Run RandomX tests
@@ -537,7 +537,7 @@ jobs:
cd tests
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@18)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_CXX_FLAGS='-flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_ASM_FLAGS='-target x86_64-apple-macos10.13' -DSTATIC_LIBS=ON
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@20)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_CXX_FLAGS='-flto -target x86_64-apple-macos10.13 -Wno-overriding-t-option' -DCMAKE_ASM_FLAGS='-target x86_64-apple-macos10.13' -DSTATIC_LIBS=ON
make -j4 p2pool_tests
- name: Run tests
@@ -547,7 +547,7 @@ jobs:
./p2pool_tests
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-macos
path: build/p2pool
@@ -555,18 +555,18 @@ jobs:
build-macos-aarch64:
timeout-minutes: 30
runs-on: macos-15
runs-on: macos-26
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-Os -target arm64-apple-macos-11" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DCURL_ENABLE_EXPORT_TARGET=OFF -DCURL_DISABLE_HEADERS_API=ON -DCURL_DISABLE_BINDLOCAL=ON -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_DISABLE_ALTSVC=ON -DCURL_DISABLE_COOKIES=ON -DCURL_DISABLE_DOH=ON -DCURL_DISABLE_GETOPTIONS=ON -DCURL_DISABLE_HSTS=ON -DCURL_DISABLE_LIBCURL_OPTION=ON -DCURL_DISABLE_MIME=ON -DCURL_DISABLE_NETRC=ON -DCURL_DISABLE_NTLM=ON -DCURL_DISABLE_PARSEDATE=ON -DCURL_DISABLE_PROGRESS_METER=ON -DCURL_DISABLE_SHUFFLE_DNS=ON -DCURL_DISABLE_SOCKETPAIR=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_DISABLE_WEBSOCKETS=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_DISABLE_TESTS=ON -DUSE_NGHTTP2=OFF -DBUILD_EXAMPLES=OFF -DP2POOL_BORINGSSL=ON -DCURL_DISABLE_SRP=ON -DCURL_DISABLE_AWS=ON -DCURL_DISABLE_BASIC_AUTH=ON -DCURL_DISABLE_BEARER_AUTH=ON -DCURL_DISABLE_KERBEROS_AUTH=ON -DCURL_DISABLE_NEGOTIATE_AUTH=ON -DOPENSSL_INCLUDE_DIR=../grpc/third_party/boringssl-with-bazel/include
cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-Os -target arm64-apple-macos-11" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DCURL_ENABLE_EXPORT_TARGET=OFF -DCURL_DISABLE_HEADERS_API=ON -DCURL_DISABLE_BINDLOCAL=ON -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_DISABLE_ALTSVC=ON -DCURL_DISABLE_COOKIES=ON -DCURL_DISABLE_DOH=ON -DCURL_DISABLE_GETOPTIONS=ON -DCURL_DISABLE_HSTS=ON -DCURL_DISABLE_LIBCURL_OPTION=ON -DCURL_DISABLE_MIME=ON -DCURL_DISABLE_NETRC=ON -DCURL_DISABLE_NTLM=ON -DCURL_DISABLE_PARSEDATE=ON -DCURL_DISABLE_PROGRESS_METER=ON -DCURL_DISABLE_SHUFFLE_DNS=ON -DCURL_DISABLE_SOCKETPAIR=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_DISABLE_WEBSOCKETS=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_DISABLE_TESTS=ON -DUSE_NGHTTP2=OFF -DBUILD_EXAMPLES=OFF -DP2POOL_BORINGSSL=ON -DCURL_DISABLE_SRP=ON -DCURL_DISABLE_AWS=ON -DCURL_DISABLE_BASIC_AUTH=ON -DCURL_DISABLE_BEARER_AUTH=ON -DCURL_DISABLE_KERBEROS_AUTH=ON -DCURL_DISABLE_NEGOTIATE_AUTH=ON -DOPENSSL_INCLUDE_DIR=../grpc/third_party/boringssl-with-bazel/include
make -j3
- name: Build libuv
@@ -574,7 +574,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -target arm64-apple-macos-11' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -target arm64-apple-macos-11' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j3
- name: Build libzmq
@@ -582,14 +582,14 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@18)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -target arm64-apple-macos-11' -DCMAKE_CXX_FLAGS='-Os -target arm64-apple-macos-11' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@20)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -target arm64-apple-macos-11' -DCMAKE_CXX_FLAGS='-Os -target arm64-apple-macos-11' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
make -j3
- name: Build p2pool
run: |
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@18)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-target arm64-apple-macos-11" -DCMAKE_CXX_FLAGS="-target arm64-apple-macos-11" -DSTATIC_LIBS=ON -DWITH_LTO=OFF -DARCH_ID=aarch64
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@20)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-target arm64-apple-macos-11" -DCMAKE_CXX_FLAGS="-target arm64-apple-macos-11" -DSTATIC_LIBS=ON -DWITH_LTO=OFF -DARCH_ID=aarch64
make -j3 p2pool
- name: Run RandomX tests
@@ -604,7 +604,7 @@ jobs:
cd tests
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@18)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-target arm64-apple-macos-11" -DCMAKE_CXX_FLAGS="-target arm64-apple-macos-11" -DSTATIC_LIBS=ON -DWITH_LTO=OFF -DARCH_ID=aarch64
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@20)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-target arm64-apple-macos-11" -DCMAKE_CXX_FLAGS="-target arm64-apple-macos-11" -DSTATIC_LIBS=ON -DWITH_LTO=OFF -DARCH_ID=aarch64
make -j3 p2pool_tests
- name: Run tests
@@ -614,7 +614,7 @@ jobs:
./p2pool_tests
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-macos-aarch64
path: build/p2pool
@@ -634,7 +634,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -660,7 +660,7 @@ jobs:
cd ../libuv
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='-Os -flto' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS='-Os -flto' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j4
cd ../../libzmq
mkdir build
@@ -684,7 +684,7 @@ jobs:
./p2pool_tests
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-${{ matrix.os.name }}-${{ matrix.os.version }}
path: build/p2pool
@@ -704,7 +704,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -735,7 +735,7 @@ jobs:
./p2pool_tests
- name: Archive binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-${{ matrix.os.name }}-${{ matrix.os.version }}
path: build/p2pool
+6 -6
View File
@@ -19,12 +19,12 @@ jobs:
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 21
sudo apt-get install -y clang-tidy-21
clang-tidy-21 --verify-config
sudo ./llvm.sh 22
sudo apt-get install -y clang-tidy-22
clang-tidy-22 --verify-config
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -32,9 +32,9 @@ jobs:
run: |
mkdir build
cd build
cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang-21 -DCMAKE_CXX_COMPILER=clang++-21 -DDEV_CLANG_TIDY=ON -DSTATIC_LIBS=ON -DWITH_INDEXED_HASHES=ON -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang-22 -DCMAKE_CXX_COMPILER=clang++-22 -DDEV_CLANG_TIDY=ON -DSTATIC_LIBS=ON -DWITH_INDEXED_HASHES=ON -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
- name: Run clang-tidy
run: |
cd src
clang-tidy-21 *.cpp -p ../build -checks=bugprone-*,clang-analyzer-*,llvm-*,cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-cstyle-cast,cppcoreguidelines-rvalue-reference-param-not-moved,hicpp-use-emplace,hicpp-use-override,-bugprone-easily-swappable-parameters,-bugprone-empty-catch,-llvm-include-order -warnings-as-errors=* -header-filter=^[^\./]
clang-tidy-22 *.cpp -p ../build -checks=bugprone-*,clang-analyzer-*,llvm-*,cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-cstyle-cast,cppcoreguidelines-rvalue-reference-param-not-moved,hicpp-use-emplace,hicpp-use-override,-bugprone-easily-swappable-parameters,-bugprone-empty-catch,-llvm-include-order,-bugprone-random-generator-seed,-llvm-use-ranges,-bugprone-throwing-static-initialization -warnings-as-errors=* -header-filter=^[^\./]
+1 -1
View File
@@ -48,7 +48,7 @@ jobs:
sudo apt update && sudo apt install git build-essential cmake libuv1-dev libzmq3-dev libgss-dev libcurl4-openssl-dev libidn2-0-dev
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
+7 -7
View File
@@ -26,10 +26,10 @@ jobs:
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 21 all
sudo ./llvm.sh 22 all
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -38,7 +38,7 @@ jobs:
cd tests
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DDEV_DEBUG=ON -DWITH_INDEXED_HASHES=ON -DWITH_COVERAGE=ON -DCMAKE_C_COMPILER=clang-21 -DCMAKE_CXX_COMPILER=clang++-21 -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
cmake .. -DCMAKE_BUILD_TYPE=Release -DDEV_DEBUG=ON -DWITH_INDEXED_HASHES=ON -DWITH_COVERAGE=ON -DCMAKE_C_COMPILER=clang-22 -DCMAKE_CXX_COMPILER=clang++-22 -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
make -j$(nproc) p2pool_tests
- name: Run tests
@@ -50,12 +50,12 @@ jobs:
- name: Merge profile data
run: |
cd tests/build
llvm-profdata-21 merge -sparse ./p2pool_tests.profraw -o ./p2pool_tests.profdata
llvm-profdata-22 merge -sparse ./p2pool_tests.profraw -o ./p2pool_tests.profdata
- name: Export profile data
run: |
cd tests/build
llvm-cov-21 export ./p2pool_tests -format=lcov -instr-profile=./p2pool_tests.profdata > coverage.info
llvm-cov-22 export ./p2pool_tests -format=lcov -instr-profile=./p2pool_tests.profdata > coverage.info
- name: Run genhtml
run: |
@@ -63,7 +63,7 @@ jobs:
genhtml --demangle-cpp -o coverage coverage.info
- name: Checkout GitHub Pages repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
repository: SChernykh/SChernykh.github.io
token: ${{ secrets.PAGES_DEPLOY_TOKEN }}
@@ -85,7 +85,7 @@ jobs:
- name: Archive coverage data
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool-coverage
path: tests/build/coverage
+6 -6
View File
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -48,14 +48,14 @@ jobs:
- name: Archive full error list
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: errors_full-linux
path: cppcheck/errors_full.txt
- name: Archive checkers report
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: checkers_report-linux
path: cppcheck/checkers_report.txt
@@ -67,7 +67,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -96,14 +96,14 @@ jobs:
- name: Archive full error list
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: errors_full-windows
path: cppcheck/errors_full.txt
- name: Archive checkers report
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: checkers_report-windows
path: cppcheck/checkers_report.txt
+3 -3
View File
@@ -34,7 +34,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -58,13 +58,13 @@ jobs:
# Upload SARIF file to GitHub Code Scanning Alerts
- name: Upload SARIF to GitHub
uses: github/codeql-action/upload-sarif@v3
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: ${{ steps.run-analysis.outputs.sarif }}
# Upload SARIF file as an Artifact to download and view
- name: Upload SARIF as an Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: sarif-file
path: ${{ steps.run-analysis.outputs.sarif }}
+2 -2
View File
@@ -12,7 +12,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -22,7 +22,7 @@ jobs:
XZ_OPT=-e9 tar --exclude=".git" --exclude="build" -f build/p2pool_source.tar.xz -c ../p2pool --xz
- name: Archive source code
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_source.tar.xz
path: build/p2pool_source.tar.xz
+32 -32
View File
@@ -27,7 +27,7 @@ jobs:
sudo apt install -y git build-essential cmake gcc-12 g++-12
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -42,7 +42,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_C_FLAGS='-fsanitize=thread -Og -fno-omit-frame-pointer -g' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_C_FLAGS='-fsanitize=thread -Og -fno-omit-frame-pointer -g' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j$(nproc)
- name: Build libzmq
@@ -82,7 +82,7 @@ jobs:
- name: Archive p2pool.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_ubuntu_data_tsan
path: |
@@ -103,14 +103,14 @@ jobs:
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 21 all
sudo ./llvm.sh 22 all
- name: Build libcxx_msan
run: |
git clone --depth=1 https://github.com/llvm/llvm-project -b release/21.x
git clone --depth=1 https://github.com/llvm/llvm-project -b release/22.x
cd llvm-project
mkdir build
cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" -DCMAKE_C_COMPILER=clang-21 -DCMAKE_CXX_COMPILER=clang++-21 -DLLVM_USE_SANITIZER=MemoryWithOrigins -DLIBCXXABI_USE_LLVM_UNWINDER=OFF
cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" -DCMAKE_C_COMPILER=clang-22 -DCMAKE_CXX_COMPILER=clang++-22 -DLLVM_USE_SANITIZER=MemoryWithOrigins -DLIBCXXABI_USE_LLVM_UNWINDER=OFF
ninja -C build cxx cxxabi
cd build
mkdir /tmp/libcxx_msan
@@ -118,14 +118,14 @@ jobs:
cp -r lib /tmp/libcxx_msan
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-21 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -O0 -fno-omit-frame-pointer -g3' -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DCURL_ENABLE_EXPORT_TARGET=OFF -DCURL_DISABLE_HEADERS_API=ON -DCURL_DISABLE_BINDLOCAL=ON -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_DISABLE_ALTSVC=ON -DCURL_DISABLE_COOKIES=ON -DCURL_DISABLE_DOH=ON -DCURL_DISABLE_GETOPTIONS=ON -DCURL_DISABLE_HSTS=ON -DCURL_DISABLE_LIBCURL_OPTION=ON -DCURL_DISABLE_MIME=ON -DCURL_DISABLE_NETRC=ON -DCURL_DISABLE_NTLM=ON -DCURL_DISABLE_PARSEDATE=ON -DCURL_DISABLE_PROGRESS_METER=ON -DCURL_DISABLE_SHUFFLE_DNS=ON -DCURL_DISABLE_SOCKETPAIR=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_DISABLE_WEBSOCKETS=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_DISABLE_TESTS=ON -DUSE_NGHTTP2=OFF -DBUILD_EXAMPLES=OFF -DP2POOL_BORINGSSL=ON -DCURL_DISABLE_SRP=ON -DCURL_DISABLE_AWS=ON -DCURL_DISABLE_BASIC_AUTH=ON -DCURL_DISABLE_BEARER_AUTH=ON -DCURL_DISABLE_KERBEROS_AUTH=ON -DCURL_DISABLE_NEGOTIATE_AUTH=ON -DOPENSSL_INCLUDE_DIR=../grpc/third_party/boringssl-with-bazel/include
cmake . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-22 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -O0 -fno-omit-frame-pointer -g3' -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DCURL_ENABLE_EXPORT_TARGET=OFF -DCURL_DISABLE_HEADERS_API=ON -DCURL_DISABLE_BINDLOCAL=ON -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_DISABLE_ALTSVC=ON -DCURL_DISABLE_COOKIES=ON -DCURL_DISABLE_DOH=ON -DCURL_DISABLE_GETOPTIONS=ON -DCURL_DISABLE_HSTS=ON -DCURL_DISABLE_LIBCURL_OPTION=ON -DCURL_DISABLE_MIME=ON -DCURL_DISABLE_NETRC=ON -DCURL_DISABLE_NTLM=ON -DCURL_DISABLE_PARSEDATE=ON -DCURL_DISABLE_PROGRESS_METER=ON -DCURL_DISABLE_SHUFFLE_DNS=ON -DCURL_DISABLE_SOCKETPAIR=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_DISABLE_WEBSOCKETS=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_DISABLE_TESTS=ON -DUSE_NGHTTP2=OFF -DBUILD_EXAMPLES=OFF -DP2POOL_BORINGSSL=ON -DCURL_DISABLE_SRP=ON -DCURL_DISABLE_AWS=ON -DCURL_DISABLE_BASIC_AUTH=ON -DCURL_DISABLE_BEARER_AUTH=ON -DCURL_DISABLE_KERBEROS_AUTH=ON -DCURL_DISABLE_NEGOTIATE_AUTH=ON -DOPENSSL_INCLUDE_DIR=../grpc/third_party/boringssl-with-bazel/include
make -j$(nproc)
- name: Build libuv
@@ -133,7 +133,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-21 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -O0 -fno-omit-frame-pointer -g3' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-22 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -O0 -fno-omit-frame-pointer -g3' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j$(nproc)
- name: Build libzmq
@@ -141,14 +141,14 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-21 -DCMAKE_CXX_COMPILER=clang++-21 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -O0 -fno-omit-frame-pointer -g3' -DCMAKE_CXX_FLAGS='-nostdinc++ -nostdlib++ -fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -isystem /tmp/libcxx_msan/include/c++/v1 -O0 -fno-omit-frame-pointer -g3' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-22 -DCMAKE_CXX_COMPILER=clang++-22 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -O0 -fno-omit-frame-pointer -g3' -DCMAKE_CXX_FLAGS='-nostdinc++ -nostdlib++ -fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -isystem /tmp/libcxx_msan/include/c++/v1 -O0 -fno-omit-frame-pointer -g3' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
make -j$(nproc)
- name: Build p2pool
run: |
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-21 -DCMAKE_CXX_COMPILER=clang++-21 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -fno-omit-frame-pointer' -DCMAKE_CXX_FLAGS='-nostdinc++ -nostdlib++ -fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -isystem /tmp/libcxx_msan/include/c++/v1 -L/tmp/libcxx_msan/lib -Wl,-rpath /tmp/libcxx_msan/lib -lc++ -lc++abi -Wno-unused-command-line-argument -fuse-ld=lld-21 -fno-omit-frame-pointer' -DDEV_TEST_SYNC=ON -DDEV_WITH_MSAN=ON -DWITH_LTO=OFF -DSTATIC_LIBS=ON -DWITH_INDEXED_HASHES=ON -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-22 -DCMAKE_CXX_COMPILER=clang++-22 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -fno-omit-frame-pointer' -DCMAKE_CXX_FLAGS='-nostdinc++ -nostdlib++ -fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -isystem /tmp/libcxx_msan/include/c++/v1 -L/tmp/libcxx_msan/lib -Wl,-rpath /tmp/libcxx_msan/lib -lc++ -lc++abi -Wno-unused-command-line-argument -fuse-ld=lld-22 -fno-omit-frame-pointer' -DDEV_TEST_SYNC=ON -DDEV_WITH_MSAN=ON -DWITH_LTO=OFF -DSTATIC_LIBS=ON -DWITH_INDEXED_HASHES=ON -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
make -j$(nproc) p2pool
- name: Run p2pool
@@ -173,7 +173,7 @@ jobs:
- name: Archive p2pool.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_ubuntu_data_msan
path: |
@@ -193,7 +193,7 @@ jobs:
sudo apt install -y git build-essential cmake libuv1-dev libzmq3-dev libgss-dev libcurl4-openssl-dev libidn2-0-dev gcc-12 g++-12
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -226,7 +226,7 @@ jobs:
- name: Archive p2pool.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_ubuntu_data_ubsan
path: |
@@ -246,7 +246,7 @@ jobs:
sudo apt install -y git build-essential cmake libuv1-dev libzmq3-dev libgss-dev libcurl4-openssl-dev libidn2-0-dev gcc-12 g++-12
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -279,7 +279,7 @@ jobs:
- name: Archive p2pool.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_ubuntu_data_asan
path: |
@@ -301,10 +301,10 @@ jobs:
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 21 all
sudo ./llvm.sh 22 all
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -312,7 +312,7 @@ jobs:
run: |
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-21 -DCMAKE_CXX_COMPILER=clang++-21 -DDEV_TEST_SYNC=ON -DDEV_DEBUG=ON -DDEV_WITH_TYSAN=ON -DWITH_LTO=OFF -DWITH_INDEXED_HASHES=ON -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang-22 -DCMAKE_CXX_COMPILER=clang++-22 -DDEV_TEST_SYNC=ON -DDEV_DEBUG=ON -DDEV_WITH_TYSAN=ON -DWITH_LTO=OFF -DWITH_INDEXED_HASHES=ON -DCMAKE_POLICY_VERSION_MINIMUM="3.5"
make -j$(nproc) p2pool
- name: Run p2pool
@@ -337,7 +337,7 @@ jobs:
- name: Archive p2pool.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_ubuntu_data_tysan
path: |
@@ -352,19 +352,19 @@ jobs:
strategy:
matrix:
config:
- {os: macos-15-intel, flags: ""}
- {os: macos-15, flags: "-target arm64-apple-macos-11"}
- {os: macos-26-intel, flags: ""}
- {os: macos-26, flags: "-target arm64-apple-macos-11"}
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="${{ matrix.config.flags }}" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DCURL_ENABLE_EXPORT_TARGET=OFF -DCURL_DISABLE_HEADERS_API=ON -DCURL_DISABLE_BINDLOCAL=ON -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_DISABLE_ALTSVC=ON -DCURL_DISABLE_COOKIES=ON -DCURL_DISABLE_DOH=ON -DCURL_DISABLE_GETOPTIONS=ON -DCURL_DISABLE_HSTS=ON -DCURL_DISABLE_LIBCURL_OPTION=ON -DCURL_DISABLE_MIME=ON -DCURL_DISABLE_NETRC=ON -DCURL_DISABLE_NTLM=ON -DCURL_DISABLE_PARSEDATE=ON -DCURL_DISABLE_PROGRESS_METER=ON -DCURL_DISABLE_SHUFFLE_DNS=ON -DCURL_DISABLE_SOCKETPAIR=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_DISABLE_WEBSOCKETS=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_DISABLE_TESTS=ON -DUSE_NGHTTP2=OFF -DBUILD_EXAMPLES=OFF -DP2POOL_BORINGSSL=ON -DCURL_DISABLE_SRP=ON -DCURL_DISABLE_AWS=ON -DCURL_DISABLE_BASIC_AUTH=ON -DCURL_DISABLE_BEARER_AUTH=ON -DCURL_DISABLE_KERBEROS_AUTH=ON -DCURL_DISABLE_NEGOTIATE_AUTH=ON -DOPENSSL_INCLUDE_DIR=../grpc/third_party/boringssl-with-bazel/include
cmake . -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="${{ matrix.config.flags }}" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DCURL_ENABLE_EXPORT_TARGET=OFF -DCURL_DISABLE_HEADERS_API=ON -DCURL_DISABLE_BINDLOCAL=ON -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF -DCURL_DISABLE_ALTSVC=ON -DCURL_DISABLE_COOKIES=ON -DCURL_DISABLE_DOH=ON -DCURL_DISABLE_GETOPTIONS=ON -DCURL_DISABLE_HSTS=ON -DCURL_DISABLE_LIBCURL_OPTION=ON -DCURL_DISABLE_MIME=ON -DCURL_DISABLE_NETRC=ON -DCURL_DISABLE_NTLM=ON -DCURL_DISABLE_PARSEDATE=ON -DCURL_DISABLE_PROGRESS_METER=ON -DCURL_DISABLE_SHUFFLE_DNS=ON -DCURL_DISABLE_SOCKETPAIR=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DCURL_DISABLE_WEBSOCKETS=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF -DCURL_DISABLE_TESTS=ON -DUSE_NGHTTP2=OFF -DBUILD_EXAMPLES=OFF -DP2POOL_BORINGSSL=ON -DCURL_DISABLE_SRP=ON -DCURL_DISABLE_AWS=ON -DCURL_DISABLE_BASIC_AUTH=ON -DCURL_DISABLE_BEARER_AUTH=ON -DCURL_DISABLE_KERBEROS_AUTH=ON -DCURL_DISABLE_NEGOTIATE_AUTH=ON -DOPENSSL_INCLUDE_DIR=../grpc/third_party/boringssl-with-bazel/include
make -j4
- name: Build libuv
@@ -372,7 +372,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF -DENABLE_CLANG_TIDY=OFF
make -j4
- name: Build libzmq
@@ -380,14 +380,14 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@18)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='${{ matrix.config.flags }}' -DCMAKE_CXX_FLAGS='${{ matrix.config.flags }}' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@20)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='${{ matrix.config.flags }}' -DCMAKE_CXX_FLAGS='${{ matrix.config.flags }}' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
make -j4
- name: Build p2pool
run: |
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@18)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@18)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@18)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@18)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='${{ matrix.config.flags }}' -DCMAKE_CXX_FLAGS='${{ matrix.config.flags }}' -DWITH_LTO=OFF -DSTATIC_LIBS=ON -DDEV_TEST_SYNC=ON -DDEV_DEBUG=ON -DWITH_INDEXED_HASHES=ON
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@20)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@20)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@20)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@20)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='${{ matrix.config.flags }}' -DCMAKE_CXX_FLAGS='${{ matrix.config.flags }}' -DWITH_LTO=OFF -DSTATIC_LIBS=ON -DDEV_TEST_SYNC=ON -DDEV_DEBUG=ON -DWITH_INDEXED_HASHES=ON
make -j4 p2pool
- name: Run p2pool
@@ -411,7 +411,7 @@ jobs:
- name: Archive p2pool.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_${{ matrix.config.os }}_data
path: |
@@ -425,7 +425,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -457,7 +457,7 @@ jobs:
- name: Archive p2pool.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_windows_data_debug_asan
path: |
@@ -471,7 +471,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
submodules: recursive
@@ -502,7 +502,7 @@ jobs:
- name: Archive p2pool.log
if: '!cancelled()'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: p2pool_windows_data_leaks
path: |
+2
View File
@@ -131,6 +131,7 @@ set(HEADERS
src/uv_util.h
src/wallet.h
src/zmq_reader.h
src/i2p.h
)
set(SOURCES
@@ -164,6 +165,7 @@ set(SOURCES
src/util.cpp
src/wallet.cpp
src/zmq_reader.cpp
src/i2p.cpp
)
if (AMD64)
+19 -19
View File
@@ -66,7 +66,7 @@ Here's the comparison table of the different ways of mining. While pool mining i
* Advanced mempool picking algorithm, it creates blocks with better reward than what monerod solo mining does
* Password protected private pools
* Highly reliable configurations are supported (multiple P2Pool nodes mining to the same wallet, each P2Pool node can use multiple Monero nodes and switch on the fly if an issue is detected)
* Mining through [TOR](docs/TOR.MD) is fully supported
* Mining through [TOR](docs/TOR.MD) and [I2P](docs/I2P.MD) are fully supported
## How payouts work in P2Pool
@@ -96,7 +96,7 @@ In order to continue mining on P2Pool, you must update both Monero and P2Pool so
### General Considerations
- In order to mine on P2Pool, a synced Monero node using monerod v0.18.0.0 or newer is required. If you don't currently have one, you can download the [official Monero binaries](https://www.getmonero.org/downloads/), start `monerod` on your PC and wait until it's fully synced. Advanced Monero node setup instructions are [here](https://sethforprivacy.com/guides/run-a-monero-node-advanced/).
- It is highly recommended that you create a separate restricted user account (in your OS) for mining. While P2Pool has been battle-tested for a long time now, any software may have unknown bugs/vulnerabilities.
- It is highly recommended that you create a separate restricted user account (in your OS) for mining. While P2Pool has been battle-tested for a long time now, any software may have unknown bugs/vulnerabilities.
- You can mine to a primary wallet address (the one starting with `4`) for mining. If you want to mine to a subaddress, you will need to provide both the main address (starting with 4) and the subaddress (starting with 8) using `--wallet` and `--subaddress` command line parameters.
- You can add the `--mini` or `--nano` parameter to your P2Pool command to connect to the respective sidechain.
> [!NOTE]
@@ -105,7 +105,7 @@ In order to continue mining on P2Pool, you must update both Monero and P2Pool so
> Using `--nano` will change the p2p port to 37890.<br>
- Check that ports 18080 (Monero p2p port) and 37889/37888/37890 (P2Pool default/mini/nano p2p port) are open in your firewall to ensure better connectivity. If you're mining from a computer behind NAT (like a router) you could consider forwarding the ports to your local machine.
- You can connect multiple miners to the same P2Pool node. The more the better!
- The steps below assume that you run everything on the same machine. If it's not the case, change `127.0.0.1` to appropriate IP addresses for your setup.
- The steps below assume that you run everything on the same machine. If it's not the case, change `127.0.0.1` to appropriate IP addresses for your setup.
- It is highly recommended to create a new mainnet wallet for P2Pool mining because **wallet addresses are public on P2Pool**.
**Wallet software compatible with P2Pool payouts**
@@ -157,15 +157,15 @@ Note that Tari will be mined in solo mode (only full Tari blocks can be mined fo
1. Download the latest P2Pool binaries [here](https://github.com/SChernykh/p2pool/releases/latest).
- Alternatively, grab the latest source code for P2Pool and [build it](#build-instructions).
2. Download the latest XMRig (linux-static-x64) binary [here](https://github.com/xmrig/xmrig/releases/latest).
3. Prepare enough huge pages (each of monerod/P2Pool/XMRig needs them):
3. Prepare enough huge pages (each of monerod/P2Pool/XMRig needs them):
```
sudo sysctl vm.nr_hugepages=3072
```
4. Check that ports 18080 (Monero p2p port) and 37889/37888/37890 (P2Pool default/mini/nano p2p port) are open in your local firewall to ensure better connectivity.
5. Start `monerod` with the following command/options:
4. Check that ports 18080 (Monero p2p port) and 37889/37888/37890 (P2Pool default/mini/nano p2p port) are open in your local firewall to ensure better connectivity.
5. Start `monerod` with the following command/options:
```
./monerod --zmq-pub tcp://127.0.0.1:18083 --out-peers 32 --in-peers 64 --add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --enforce-dns-checkpointing --enable-dns-blocklist
```
```
**Note:**
The `--zmq-pub` option is required for P2Pool to work properly.
@@ -187,16 +187,16 @@ The `--zmq-pub` option is required for P2Pool to work properly.
```
./xmrig -o 127.0.0.1:3333
```
- Note that you don't need to specify your wallet address for XMRig. **Wallet addresses set in XMRig config will be ignored!**
- To set a custom fixed difficulty for your miner (for example, 10000), instead start XMRig with the following options:
- Note that you don't need to specify your wallet address for XMRig. **Wallet addresses set in XMRig config will be ignored!**
- To set a custom fixed difficulty for your miner (for example, 10000), instead start XMRig with the following options:
```
./xmrig -u x+10000 -o 127.0.0.1:3333
```
9. XMRig should connect and start mining!
**Additional Information:**
**Additional Information:**
- For a more in-depth beginner friendly walk-through with the option of using Docker, please see SethForPrivacy's guide at: https://sethforprivacy.com/guides/run-a-p2pool-node/
- You can check the p2pool.log for any warnings or errors using the following command:
- You can check the p2pool.log for any warnings or errors using the following command:
```
grep -E 'WARNING|ERROR' p2pool.log
```
@@ -213,7 +213,7 @@ nocreate
}
```
### Windows
### Windows
**Note:** *Windows SmartScreen may block incoming connections by files that are "Downloaded from the Internet". You can allow 'p2pool.exe' and 'monerod.exe' by double-clicking them, clicking "More Info", then click "Run Anyway" and then closing them immediately so you can run them from the command line. Advanced users can use the PowerShell cmdlet `Unblock-File` to remove this flag.*
@@ -221,8 +221,8 @@ nocreate
- Alternatively, grab the latest source code for P2Pool and [build it](#build-instructions).
2. Download the latest XMRig binary [here](https://github.com/xmrig/xmrig/releases/latest).
3. Expand the P2Pool binaries into an appropriate location (`%USERPROFILE%/bin` or `C:/bin/` are good options)
4. Expand XMRig binary into an appropriate location (the same folder as P2Pool is fine).
5. Prepare huge pages to work properly (each of monerod/P2Pool/XMRig needs them):
4. Expand XMRig binary into an appropriate location (the same folder as P2Pool is fine).
5. Prepare huge pages to work properly (each of monerod/P2Pool/XMRig needs them):
- On Windows 10 or above, run XMRig at least once as Administrator (right-click Run As Administrator)
- On earlier versions of Windows, you'll need to run XMRig as Administrator at least once per login.
6. Create "Monero" folder inside extracted P2Pool folder and copy Monero binaries there.
@@ -230,7 +230,7 @@ nocreate
**Note:** *When running the below commands, Windows Firewall may prompt to allow connections, click "Allow" if prompted.*
8. Start `monerod` with the following command/options:
8. Start `monerod` with the following command/options:
```
.\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --out-peers 32 --in-peers 64 --add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --enforce-dns-checkpointing --enable-dns-blocklist
```
@@ -254,8 +254,8 @@ The `--zmq-pub` option is required for P2Pool to work properly.
```
.\xmrig.exe -o 127.0.0.1:3333
```
- Note that you don't need to specify your wallet address for XMRig. **Wallet addresses set in XMRig config will be ignored!**
- To set a custom fixed difficulty for your miner (for example, 10000), instead start XMRig with the following options:
- Note that you don't need to specify your wallet address for XMRig. **Wallet addresses set in XMRig config will be ignored!**
- To set a custom fixed difficulty for your miner (for example, 10000), instead start XMRig with the following options:
```
xmrig.exe -u x+10000 -o 127.0.0.1:3333
```
@@ -299,7 +299,7 @@ pacman -S p2pool
### [Nix/NixOS](https://nixos.org)
This is a flake only project. So you have to use [nixUnstable with nix flakes](https://nixos.wiki/wiki/Flakes) to build or install P2Pool.
This is a flake only project. So you have to use [nixUnstable with nix flakes](https://nixos.wiki/wiki/Flakes) to build or install P2Pool.
The commands below use the new flake specific reference-format, so be sure to also set `ca-references` in `--experimental-features`.
Because this project has submodules which are not fixed in _nixUnstable_ yet you have to use the `nix/master` branch:
@@ -330,7 +330,7 @@ cmake .. -G "Visual Studio 16 2019"
```
then open generated build\p2pool.sln in Visual Studio and build it there
Alternatively, you can select "Clone a repository" within the GUI, then select "Build" from the menu.
Alternatively, you can select "Clone a repository" within the GUI, then select "Build" from the menu.
### macOS
+45
View File
@@ -0,0 +1,45 @@
## Running P2Pool with I2P
P2Pool has several command-line options that should be used for I2P setup:
- `--socks5 IP:port` to specify your I2P SOCKS proxy address (usually `127.0.0.1:4447` if you are using i2pd or followed the guide below)
- `--socks5-proxy-type i2p` to specify the type of SOCKS5 proxy being used
- `--no-dns` to disable all DNS queries and prevent DNS leaks. P2Pool only ever makes DNS requests to get a list of seed nodes, to resolve your Monero node's domain (if it's not set as an IP address), and to resolve manually added peers
- `--no-upnp` to disable UPnP requests (they are sent to your router, so use this option if you are not on your home network)
- `--i2p-address` your hidden service's `.b32.i2p` address (without port number). This address will be broadcast to other peers when you mine a share in P2Pool. This is to prevent address spamming - you have to mine a real share to be able to broadcast your I2P address.
- **Attention: this also links the I2P address with the Monero wallet you use for mining. Create a new I2P address when mining through I2P, don't use your existing addresses to avoid metadata leaks.**
- `--no-clearnet-p2p` to never connect to clearnet P2Pool nodes.
## Setting up I2P tunnels for P2Pool (i2pd on Linux)
Follow [these instructions](https://docs.i2pd.website/en/latest/user-guide/install/) to install i2pd on your system.
First, ensure the SOCKS proxy tunnel is enabled (as it should be by default). See [here](https://docs.i2pd.website/en/latest/user-guide/configuration/) for more information.
You will need to modify some lines in the `tunnels.conf` file, usually located in `/var/lib/i2pd/tunnels.conf` on Linux.
Add a server tunnel to allow inbound connections from peers:
```ini
[p2pool]
type = server
host = 127.0.0.1
port = 28723
keys = p2pool.dat
```
This will create a hidden service key in `/var/lib/i2pd/p2pool.dat`; you may want to back this up.
Please note that you **must** use the port number shown above in order for other peers to be able to find you.
Restart i2pd:
```bash
sudo systemctl restart i2pd.service
```
Get the hostname of your hidden service:
```bash
curl -s http://127.0.0.1:7070/?page=i2p_tunnels | grep -Eo "[a-zA-Z0-9./?=_%:-]*" | grep "28723"
```
The resulting `.b32.i2p` address should then be used for the `--i2p-address` command-line parameter.
## Command line example
```bash
./p2pool --host MONERO_NODE_IP --wallet YOUR_WALLET --socks5 127.0.0.1:4447 --socks5-proxy-type i2p --no-dns --no-upnp --i2p-address YOUR_I2P_ADDRESS
```
+7 -7
View File
@@ -6,24 +6,24 @@ set -e
_7ZIP_VERSION=2600
BINUTILS_VERSION=2_46
CLANG_VERSION=21.1.8
CMAKE_VERSION=4.2.3
CMAKE_VERSION=4.3.1
FREEBSD_VERSION=12.4
GCC_VERSION=15.2.0
GLIBC_VERSION=2.43
LINUX_HEADERS_VERSION=6.19.3
LINUX_HEADERS_VERSION=6.19.12
MACOSX_SDK_VERSION=26.1
OSXCROSS_VERSION=2bc739ebe45db5d72e176d2a4e1c7dd95464e8e2
MAKE_VERSION=4.4.1
MINGW_VERSION=13.0.0
XZ_VERSION=5.8.2
MINGW_VERSION=14.0.0
XZ_VERSION=5.8.3
TAR_VERSION=1.35
_7ZIP_SHA256="c74dc4a48492cde43f5fec10d53fb2a66f520e4a62a69d630c44cb22c477edc6"
CMAKE_SHA256="5bb505d5e0cca0480a330f7f27ccf52c2b8b5214c5bba97df08899f5ef650c23"
CMAKE_SHA256="208d76804009cbe8ec9aea0aa052c857c6e59bd289b43b9941c99324dc78b1d8"
FREEBSD_AARCH64_SHA256="6c401819bfb93e810c9f9aa670a1e4685f924df5e7e0c9c6397dd6c16c954fa2"
FREEBSD_X86_64_SHA256="581c7edacfd2fca2bdf5791f667402d22fccd8a5e184635e0cac075564d57aa8"
GLIBC_SHA256="d9c86c6b5dbddb43a3e08270c5844fc5177d19442cf5b8df4be7c07cd5fa3831"
HEADERS_SHA256="0e474968adfcbee32916fd01a89d8ccfd1168d8d32569e76a5c664c793198ebe"
HEADERS_SHA256="ce5c4f1205f9729286b569b037649591555f31ca1e03cc504bd3b70b8e58a8d5"
MACOSX_SDK_SHA256="beee7212d265a6d2867d0236cc069314b38d5fb3486a6515734e76fa210c784c"
MAKE_SHA256="dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3"
TAR_SHA256="4d62ff37342ec7aed748535323930c7cf94acf71c3591882b26a7ea50f3edc16"
@@ -227,7 +227,7 @@ cd /root
tar xvf $CMAKE_FILE
cp $CMAKE_NAME/bin/* /usr/local/bin
cp -r $CMAKE_NAME/share/cmake-4.2 /usr/local/share
cp -r $CMAKE_NAME/share/cmake-4.3 /usr/local/share
echo "Install clang"
+15 -7
View File
@@ -213,7 +213,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
// Block template construction is relatively slow, but it's better to keep the lock the whole time
// instead of using temporary variables and making a quick swap in the end
//
//
// All readers will line up for the new template instead of using the outdated template
WriteLock lock(m_lock);
@@ -617,7 +617,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
m_poolBlockTemplate->m_auxNonce = data.aux_nonce;
m_poolBlockTemplate->m_mergeMiningExtra.clear();
for (const AuxChainData& c : data.aux_chains) {
std::vector<uint8_t> v;
v.reserve(HASH_SIZE + 16);
@@ -644,6 +644,13 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
m_poolBlockTemplate->m_mergeMiningExtra.emplace(keccak_onion_address_v3, std::vector(buf, buf + sizeof(buf)));
}
if (!params.m_i2pDestinationHash.empty()) {
uint8_t buf[HASH_SIZE + 2] = {};
memcpy(buf, params.m_i2pDestinationHash.h, HASH_SIZE);
m_poolBlockTemplate->m_mergeMiningExtra.emplace(keccak_i2p_b32_address, std::vector(buf, buf + sizeof(buf)));
}
init_merge_mining_merkle_proof();
const std::vector<uint8_t> sidechain_data = m_poolBlockTemplate->serialize_sidechain_data();
@@ -752,7 +759,7 @@ void BlockTemplate::fill_optimal_knapsack(const MinerData& data, uint64_t base_r
{
// Find the maximum possible fee for every weight value and remember which tx leads to this fee/weight
// Run time is O(N*W) where N is the number of transactions and W is the maximum block weight
//
//
// Actual run time is 0.02-0.05 seconds on real full blocks
// It's too slow and uses too much memory to be practical
@@ -975,7 +982,7 @@ int BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Mine
LOGINFO(4, "increased EXTRA_NONCE from " << EXTRA_NONCE_SIZE << " to " << corrected_extra_nonce_size << " bytes to maintain miner tx weight");
}
writeVarint(corrected_extra_nonce_size, m_minerTxExtra);
uint64_t extraNonceOffsetInMinerTx = m_minerTxExtra.size();
m_minerTxExtra.insert(m_minerTxExtra.end(), corrected_extra_nonce_size, 0);
@@ -1406,7 +1413,7 @@ bool BlockTemplate::get_aux_proof(const uint32_t template_id, uint32_t extra_non
uint32_t path2 = 0;
const bool result2 = get_merkle_proof(tree, h, proof2, path2);
if ((result2 != result) || (proof2 != proof) || (path2 != path)) {
LOGERR(1, "get_aux_proof: merkle_hash_with_proof and get_merkle_proof returned different results. Fix the code!");
}
@@ -1553,7 +1560,8 @@ void BlockTemplate::init_merge_mining_merkle_proof()
}
root_hash root;
if (!merkle_hash_with_proof(hashes, aux_slot, m_poolBlockTemplate->m_merkleProof, m_poolBlockTemplate->m_merkleProofPath, root)) {
uint32_t merkle_proof_path;
if (!merkle_hash_with_proof(hashes, aux_slot, m_poolBlockTemplate->m_merkleProof, merkle_proof_path, root)) {
LOGERR(1, "init_merge_mining_merkle_proof: merkle_hash_with_proof failed. Fix the code!");
return;
}
@@ -1570,7 +1578,7 @@ void BlockTemplate::init_merge_mining_merkle_proof()
return;
}
if ((proof != m_poolBlockTemplate->m_merkleProof) || (path != m_poolBlockTemplate->m_merkleProofPath)) {
if ((proof != m_poolBlockTemplate->m_merkleProof) || (path != merkle_proof_path)) {
LOGERR(1, "init_merge_mining_merkle_proof: merkle_hash_with_proof and get_merkle_proof returned different results. Fix the code!");
}
}
+16
View File
@@ -172,6 +172,22 @@ struct alignas(uint64_t) hash
}
}
explicit constexpr hash(const char (&s)[HASH_SIZE * 2 + 1]) : h{} {
for (size_t i = 0; i < HASH_SIZE * 2; ++i) {
char c = s[i];
if ('0' <= c && c <= '9') {
c -= '0';
} else if ('a' <= c && c <= 'f') {
c = (c - 'a') + 10;
} else if ('A' <= c && c <= 'F') {
c = (c - 'A') + 10;
}
h[i / 2] = (h[i / 2] << 4) | static_cast<uint8_t>(c);
}
}
FORCEINLINE bool operator<(const hash& other) const
{
const uint64_t* a = u64();
+76
View File
@@ -0,0 +1,76 @@
/*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021-2026 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2026 jpk68
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common.h"
#include "util.h"
#include "i2p.h"
LOG_CATEGORY(I2P)
namespace p2pool {
hash from_i2p_b32(const std::string& address)
{
if ((address.length() < 8) || (address.find(".b32.i2p") != address.length() - 8)) {
LOGWARN(3, "Invalid I2P address \"" << address << "\": doesn't end with \".b32.i2p\"");
return {};
}
if (address.length() != 60) {
LOGWARN(3, "Invalid I2P address \"" << address << "\": expected length 60, got " << address.length());
return {};
}
const hash result = from_i2p_b32_const(address.c_str());
if (result.empty()) {
LOGWARN(3, "Invalid I2P address \"" << address << "\": has invalid character(s)");
return {};
}
return result;
}
std::string to_i2p_b32(const hash& dest_hash)
{
uint8_t buf[HASH_SIZE + 1];
memcpy(buf, dest_hash.h, HASH_SIZE);
buf[HASH_SIZE] = 0;
std::string result;
result.reserve(60);
uint64_t data = 0;
uint64_t bit_size = 0;
for (size_t i = 0; i < HASH_SIZE + 1; ++i) {
data = (data << 8) | buf[i];
bit_size += 8;
while (bit_size >= 5) {
bit_size -= 5;
result += base32_alphabet[(data >> bit_size) & 31];
}
}
result.append(".b32.i2p");
return result;
}
} // namespace p2pool
+73
View File
@@ -0,0 +1,73 @@
/*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021-2026 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2026 jpk68
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common.h"
#include <string>
#include <uv.h>
namespace p2pool {
static FORCEINLINE constexpr hash from_i2p_b32_const(const char* dest_hash)
{
uint8_t buf[HASH_SIZE + 4] = {};
uint8_t* p = buf;
uint64_t data = 0;
uint64_t bit_size = 0;
for (size_t i = 0; i < 52; ++i) {
const char c = dest_hash[i];
uint64_t digit = 0;
if ('a' <= c && c <= 'z') {
digit = static_cast<uint64_t>(c - 'a');
}
else if ('A' <= c && c <= 'Z') {
digit = static_cast<uint64_t>(c - 'A');
}
else if ('2' <= c && c <= '7') {
digit = static_cast<uint64_t>(c - '2') + 26;
}
else {
return {};
}
data = (data << 5) | digit;
bit_size += 5;
while (bit_size >= 8) {
bit_size -= 8;
*(p++) = static_cast<uint8_t>(data >> bit_size);
}
}
hash result;
for (size_t i = 0; i < HASH_SIZE; ++i) {
result.h[i] = buf[i];
}
return result;
}
hash from_i2p_b32(const std::string& address);
std::string to_i2p_b32(const hash& dest_hash);
} // namespace p2pool
+3 -2
View File
@@ -25,14 +25,14 @@ namespace ConstexprKeccak
template<int ROUNDS>
static FORCEINLINE constexpr void keccakf(std::array<uint64_t, 25>& st)
{
constexpr uint64_t round_constants[24] =
constexpr uint64_t round_constants[24] =
{
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
};
@@ -107,6 +107,7 @@ static constexpr hash keccak(const char (&input)[len])
constexpr hash keccak_0x00 = keccak("\0");
constexpr hash keccak_subaddress_viewpub = keccak("subaddress_viewpub");
constexpr hash keccak_onion_address_v3 = keccak("onion_address_v3");
constexpr hash keccak_i2p_b32_address = keccak("i2p_b32_address");
static_assert(keccak_0x00.u64<0>() == 0x14281E7A9E7836BCULL, "constexpr keccak code check failed");
+2 -1
View File
@@ -89,7 +89,7 @@ void p2pool_usage()
"--no-autodiff Disable automatic difficulty adjustment for miners connected to stratum (WARNING: incompatible with Nicehash and MRR)\n"
"--rpc-login Specify username[:password] required for Monero RPC server\n"
"--socks5 Specify IP:port of a SOCKS5 proxy to use for outgoing connections\n"
"--socks5-proxy-type The type of SOCKS5 proxy. Can be one of the following values: auto, plain, tor. Default is auto (auto-detect by the port number)\n"
"--socks5-proxy-type The type of SOCKS5 proxy. Can be one of the following values: auto, plain, tor, i2p. Default is auto (auto-detected by the port number)\n"
"--no-dns Disable DNS queries, use only IP addresses to connect to peers (seed node DNS will be unavailable too)\n"
"--p2p-external-port Port number that your router uses for mapping to your local p2p port. Use it if you are behind a NAT and still want to accept incoming connections\n"
#ifdef WITH_UPNP
@@ -110,6 +110,7 @@ void p2pool_usage()
"--no-stratum-http Disable HTTP on Stratum ports\n"
"--full-validation Enables full share validation / increases CPU usage\n"
"--onion-address Tell other peers to use this .onion address to connect to this node through TOR\n"
"--i2p-address Tell other peers to use this .b32.i2p address to connect to this node through I2P\n"
"--no-clearnet-p2p Forces P2P server to listen on 127.0.0.1 and to not connect to clearnet IPs\n"
"--params-file File name to load parameters from. It can't be used together with any other command line parameters\n"
"--help Show this help message\n\n"
+263 -1
View File
@@ -23,10 +23,19 @@
#include "merge_mining_client_tari.h"
#endif
LOG_CATEGORY(MergeMiningClient)
#include "p2pool.h"
#include "params.h"
#include "pool_block.h"
#include "keccak_constexpr.h"
#include "side_chain.h"
#include "merkle.h"
static thread_local const char* log_category_prefix = "MergeMiningClient ";
namespace p2pool {
static constexpr hash Tari_ChainID{ "01f0cf665bd4cd31cbb2b2470236389c483522b350335e10a4a5dca34cb85990" };
IMergeMiningClient* IMergeMiningClient::create(p2pool* pool, const std::string& host, const std::string& wallet) noexcept
{
try {
@@ -43,4 +52,257 @@ IMergeMiningClient* IMergeMiningClient::create(p2pool* pool, const std::string&
return nullptr;
}
MergeMiningClientShared::MergeMiningClientShared(p2pool* pool, const std::string& wallet)
: m_chainParamsLock{}
, m_chainParams{}
, m_chainParamsTimestamp(0)
, m_auxWallet(wallet)
, m_pool(pool)
, m_previousAuxHashes{}
, m_previousAuxHashesIndex(0)
, m_previousAuxHashesFoundIndex(std::numeric_limits<uint32_t>::max())
{
uv_rwlock_init_checked(&m_chainParamsLock);
}
MergeMiningClientShared::~MergeMiningClientShared()
{
uv_rwlock_destroy(&m_chainParamsLock);
}
void MergeMiningClientShared::on_external_block(const PoolBlock& block)
{
#ifdef WITH_MERGE_MINING_DONATION
// The rest of the code is needed only when this node is sending donation messages
if (m_pool->params().m_authorKeyFile.empty()) {
return;
}
const char* old_log_category_prefix = log_category_prefix;
log_category_prefix = get_log_category();
ON_SCOPE_LEAVE([old_log_category_prefix]() { log_category_prefix = old_log_category_prefix; });
// Sanity check
if (block.m_transactions.empty() || block.m_hashingBlob.empty() || (block.m_hashingBlob.size() > 128)) {
LOGWARN(3, "on_external_block: sanity check failed - " << block.m_transactions.size() << " transactions, hashing blob size = " << block.m_hashingBlob.size());
return;
}
ChainParameters chain_params;
hash previous_aux_hashes[NUM_PREVIOUS_HASHES];
{
ReadLock lock(m_chainParamsLock);
chain_params = m_chainParams;
std::copy(m_previousAuxHashes, m_previousAuxHashes + NUM_PREVIOUS_HASHES, previous_aux_hashes);
}
// Don't continue if our aux chain is not there
if (block.m_mergeMiningExtra.find(chain_params.aux_id) == block.m_mergeMiningExtra.end()) {
return;
}
// All aux chains in this block + the P2Pool sidechain
std::vector<hash> aux_ids;
// All aux chains in this block
std::vector<AuxChainData> aux_chains;
aux_ids.reserve(block.m_mergeMiningExtra.size() + 1);
aux_chains.reserve(block.m_mergeMiningExtra.size() + 1);
uint64_t mm_extra_size = 0;
for (const auto& i : block.m_mergeMiningExtra) {
// Filter aux chain data only
if ((i.first == keccak_subaddress_viewpub) || (i.first == keccak_onion_address_v3) || (i.first == keccak_i2p_b32_address)) {
continue;
}
++mm_extra_size;
hash data;
difficulty_type diff;
{
const std::vector<uint8_t>& v = i.second;
if (v.size() < HASH_SIZE) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '1');
return;
}
const uint8_t* p = v.data();
const uint8_t* e = v.data() + v.size();
memcpy(data.h, p, HASH_SIZE);
p += HASH_SIZE;
p = readVarint(p, e, diff.lo);
if (!p) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '2');
diff.lo = 0;
}
else {
p = readVarint(p, e, diff.hi);
if (!p) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '3');
diff.hi = 0;
}
}
}
// If it's our aux chain, check that it's the same job and that there is enough PoW
if (i.first == chain_params.aux_id) {
const bool different_hash = (data != chain_params.aux_hash);
if (different_hash || (diff != chain_params.aux_diff)) {
uint32_t index = std::numeric_limits<uint32_t>::max();
if (different_hash) {
for (uint32_t k = 0; k < NUM_PREVIOUS_HASHES; ++k) {
if (previous_aux_hashes[k] == data) {
index = k;
break;
}
}
}
m_previousAuxHashesFoundIndex = index;
if (different_hash && (index == std::numeric_limits<uint32_t>::max())) {
LOGINFO(4, "External aux job solution found, but it's for another miner");
return;
}
LOGINFO(4, "External aux job solution found, but it's stale");
chain_params.aux_hash = data;
chain_params.aux_diff = diff;
}
else {
m_previousAuxHashesFoundIndex = std::numeric_limits<uint32_t>::max();
}
if (!diff.check_pow(block.m_powHash)) {
#ifndef P2POOL_LOG_DISABLE
const char* name = ((chain_params.aux_id == Tari_ChainID) ? "Tari" : "aux");
#endif
LOGINFO(4, "External aux job solution found, but it doesn't have enough PoW (block diff = " << block.m_difficulty << ", " << name << " diff = " << diff << ')');
return;
}
}
aux_ids.emplace_back(i.first);
aux_chains.emplace_back(i.first, data, diff);
}
aux_ids.emplace_back(m_pool->side_chain().consensus_hash());
LOGINFO(0, log::LightGreen() << "External aux job solution found. Processing it!");
// coinbase_merkle_proof
root_hash root;
std::vector<hash> proof;
uint32_t path;
#ifdef WITH_INDEXED_HASHES
std::vector<hash> transactions;
transactions.reserve(block.m_transactions.size());
for (const auto& h : block.m_transactions) {
transactions.emplace_back(h);
}
#else
const std::vector<hash>& transactions = block.m_transactions;
#endif
if (!merkle_hash_with_proof(transactions, 0, proof, path, root)) {
LOGWARN(3, "on_external_block: merkle_hash_with_proof failed for coinbase transaction");
return;
}
if (!verify_merkle_proof(transactions[0], proof, path, root)) {
LOGWARN(3, "on_external_block: verify_merkle_proof failed for coinbase transaction");
return;
}
std::vector<uint8_t> coinbase_merkle_proof;
coinbase_merkle_proof.reserve(proof.size() * HASH_SIZE);
for (const hash& h : proof) {
coinbase_merkle_proof.insert(coinbase_merkle_proof.end(), h.h, h.h + HASH_SIZE);
}
// hashing_blob
uint8_t hashing_blob[128] = {};
memcpy(hashing_blob, block.m_hashingBlob.data(), block.m_hashingBlob.size());
// nonce_offset and blob
size_t header_size = 0;
const std::vector<uint8_t> blob = block.serialize_mainchain_data(&header_size);
if (header_size <= NONCE_SIZE) {
LOGWARN(3, "on_external_block: invalid header_size");
return;
}
const uint32_t nonce_offset = static_cast<uint32_t>(header_size - NONCE_SIZE);
// aux_merkle_proof, aux_merkle_proof_path
std::vector<hash> aux_merkle_proof;
uint32_t aux_merkle_proof_path = 0;
const hash sidechain_id = block.m_sidechainId;
const uint32_t n_aux_chains = static_cast<uint32_t>(mm_extra_size + 1);
std::vector<hash> hashes(n_aux_chains);
uint32_t aux_nonce;
if (!find_aux_nonce(aux_ids, aux_nonce, 1000)) {
LOGWARN(3, "on_external_block: failed to find aux_nonce");
return;
}
for (const AuxChainData& aux_data : aux_chains) {
const uint32_t aux_slot = get_aux_slot(aux_data.unique_id, aux_nonce, n_aux_chains);
if (!hashes[aux_slot].empty()) {
LOGWARN(3, "on_external_block: found an incorrect aux_nonce " << '1');
return;
}
hashes[aux_slot] = aux_data.data;
}
const uint32_t aux_slot = get_aux_slot(m_pool->side_chain().consensus_hash(), aux_nonce, n_aux_chains);
if (!hashes[aux_slot].empty()) {
LOGWARN(3, "on_external_block: found an incorrect aux_nonce " << '2');
return;
}
hashes[aux_slot] = sidechain_id;
if (!merkle_hash_with_proof(hashes, chain_params.aux_hash, aux_merkle_proof, aux_merkle_proof_path, root)) {
LOGWARN(3, "on_external_block: merkle_hash_with_proof failed for the aux hash");
return;
}
if (root != block.m_merkleRoot) {
LOGWARN(3, "on_external_block: merkle root didn't match");
return;
}
if (!verify_merkle_proof(chain_params.aux_hash, aux_merkle_proof, aux_merkle_proof_path, root)) {
LOGWARN(3, "on_external_block: verify_merkle_proof failed for the aux hash");
return;
}
submit_solution(coinbase_merkle_proof, hashing_blob, nonce_offset, block.m_seed, blob, aux_merkle_proof, aux_merkle_proof_path);
#else // WITH_MERGE_MINING_DONATION
(void)block;
#endif // WITH_MERGE_MINING_DONATION
}
} // namespace p2pool
+32
View File
@@ -17,6 +17,8 @@
#pragma once
#include "uv_util.h"
namespace p2pool {
class p2pool;
@@ -53,4 +55,34 @@ public:
virtual void api_status(log::Stream&) const = 0;
};
class MergeMiningClientShared : public IMergeMiningClient, public nocopy_nomove
{
public:
MergeMiningClientShared(p2pool* pool, const std::string& wallet);
~MergeMiningClientShared() override;
void on_external_block(const PoolBlock& block) override;
virtual const char* get_log_category() const = 0;
protected:
mutable uv_rwlock_t m_chainParamsLock;
ChainParameters m_chainParams;
uint64_t m_chainParamsTimestamp;
std::string m_auxWallet;
p2pool* m_pool;
enum {
NUM_PREVIOUS_HASHES = 8,
};
hash m_previousAuxHashes[NUM_PREVIOUS_HASHES];
uint32_t m_previousAuxHashesIndex;
std::atomic<uint32_t> m_previousAuxHashesFoundIndex;
};
} // namespace p2pool
+48 -24
View File
@@ -29,12 +29,9 @@ LOG_CATEGORY(MergeMiningClientJSON_RPC)
namespace p2pool {
MergeMiningClientJSON_RPC::MergeMiningClientJSON_RPC(p2pool* pool, const std::string& host, const std::string& wallet)
: m_host(host)
: MergeMiningClientShared(pool, wallet)
, m_host(host)
, m_port(80)
, m_chainParamsTimestamp(0)
, m_auxWallet(wallet)
, m_ping(0.0)
, m_pool(pool)
, m_loop{}
, m_loopThread{}
, m_timer{}
@@ -44,6 +41,13 @@ MergeMiningClientJSON_RPC::MergeMiningClientJSON_RPC(p2pool* pool, const std::st
const size_t k = host.find_last_of(':');
if (k != std::string::npos) {
m_host = host.substr(0, k);
// Handle IPv6 addresses
if ((m_host.length() > 2) && (m_host.find_first_of(':') != std::string::npos) && (m_host.front() == '[') && (m_host.back() == ']')) {
m_host.erase(m_host.begin());
m_host.pop_back();
}
m_port = static_cast<int32_t>(std::stol(host.substr(k + 1), nullptr, 10));
}
@@ -77,8 +81,6 @@ MergeMiningClientJSON_RPC::MergeMiningClientJSON_RPC(p2pool* pool, const std::st
}
m_timer.data = this;
uv_rwlock_init_checked(&m_lock);
err = uv_thread_create(&m_loopThread, loop, this);
if (err) {
LOGERR(1, "failed to start event loop thread, error " << uv_err_name(err));
@@ -94,8 +96,6 @@ MergeMiningClientJSON_RPC::~MergeMiningClientJSON_RPC()
uv_async_send(&m_shutdownAsync);
uv_thread_join(&m_loopThread);
uv_rwlock_destroy(&m_lock);
LOGINFO(1, "stopped");
}
@@ -115,15 +115,14 @@ void MergeMiningClientJSON_RPC::merge_mining_get_chain_id()
JSONRPCRequest::call(m_host, m_port, req, std::string(), m_pool->params().m_socks5Proxy, false, std::string(),
[this](const char* data, size_t size, double ping) {
WriteLock lock(m_lock);
WriteLock lock(m_chainParamsLock);
if (parse_merge_mining_get_chain_id(data, size)) {
if (ping > 0.0) {
m_ping = ping;
}
LOGINFO(1, m_host << ':' << m_port << " uses chain_id " << log::LightCyan() << m_chainParams.aux_id);
LOGINFO(1, m_host << ':' << m_port << " ping is " << m_ping << " ms");
if (ping > 0.0) {
LOGINFO(1, m_host << ':' << m_port << " ping is " << ping << " ms");
}
// Chain ID received successfully, we can start polling for new mining jobs now
const int err = uv_timer_start(&m_timer, on_timer, 0, 500);
@@ -191,7 +190,7 @@ void MergeMiningClientJSON_RPC::merge_mining_get_aux_block(uint64_t height, cons
hash aux_hash;
{
ReadLock lock(m_lock);
ReadLock lock(m_chainParamsLock);
aux_hash = m_chainParams.aux_hash;
}
@@ -207,14 +206,29 @@ void MergeMiningClientJSON_RPC::merge_mining_get_aux_block(uint64_t height, cons
bool changed = false;
hash chain_id;
hash prev_aux_hash;
std::vector<uint8_t> prev_aux_blob;
{
WriteLock lock(m_lock);
WriteLock lock(m_chainParamsLock);
prev_aux_hash = m_chainParams.aux_hash;
prev_aux_blob = m_chainParams.aux_blob;
if (parse_merge_mining_get_aux_block(data, size, changed)) {
chain_id = m_chainParams.aux_id;
}
}
if (changed && !chain_id.empty()) {
{
WriteLock lock(m_chainParamsLock);
const uint32_t index = (m_previousAuxHashesIndex++) % NUM_PREVIOUS_HASHES;
m_previousAuxHashes[index] = prev_aux_hash;
m_previousAuxBlobs[index] = prev_aux_blob;
}
m_pool->update_aux_data(chain_id);
}
},
@@ -293,14 +307,19 @@ bool MergeMiningClientJSON_RPC::parse_merge_mining_get_aux_block(const char* dat
void MergeMiningClientJSON_RPC::submit_solution(const std::vector<uint8_t>& /*coinbase_merkle_proof*/, const uint8_t (&/*hashing_blob*/)[128], size_t /*nonce_offset*/, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof, uint32_t merkle_proof_path)
{
ReadLock lock(m_lock);
ReadLock lock(m_chainParamsLock);
std::vector<char> buf((m_chainParams.aux_blob.size() + HASH_SIZE + blob.size()) * 2 + merkle_proof.size() * (HASH_SIZE * 2 + 3) + 256);
const uint32_t index = m_previousAuxHashesFoundIndex.exchange(std::numeric_limits<uint32_t>::max());
const std::vector<uint8_t>& aux_blob = (index < NUM_PREVIOUS_HASHES) ? m_previousAuxBlobs[index] : m_chainParams.aux_blob;
const hash& aux_hash = (index < NUM_PREVIOUS_HASHES) ? m_previousAuxHashes[index] : m_chainParams.aux_hash;
std::vector<char> buf((aux_blob.size() + HASH_SIZE + blob.size()) * 2 + merkle_proof.size() * (HASH_SIZE * 2 + 3) + 256);
log::Stream s(buf.data(), buf.size());
s << "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"merge_mining_submit_solution\",\"params\":{"
<< "\"aux_blob\":\"" << log::hex_buf(m_chainParams.aux_blob.data(), m_chainParams.aux_blob.size()) << '"'
<< ",\"aux_hash\":\"" << m_chainParams.aux_hash << '"'
<< "\"aux_blob\":\"" << log::hex_buf(aux_blob.data(), aux_blob.size()) << '"'
<< ",\"aux_hash\":\"" << aux_hash << '"'
<< ",\"blob\":\"" << log::hex_buf(blob.data(), blob.size()) << '"'
<< ",\"merkle_proof\":[";
@@ -329,7 +348,7 @@ void MergeMiningClientJSON_RPC::submit_solution(const std::vector<uint8_t>& /*co
void MergeMiningClientJSON_RPC::print_status() const
{
ReadLock lock(m_lock);
ReadLock lock(m_chainParamsLock);
LOGINFO(0, "status" <<
"\nHost = " << m_host << ':' << m_port <<
@@ -340,7 +359,7 @@ void MergeMiningClientJSON_RPC::print_status() const
void MergeMiningClientJSON_RPC::api_status(log::Stream& s) const
{
ReadLock lock(m_lock);
ReadLock lock(m_chainParamsLock);
s << '{'
<< "\"api\":\"JSON RPC\","
@@ -356,7 +375,7 @@ bool MergeMiningClientJSON_RPC::get_params(ChainParameters& out_params) const
{
const uint64_t t = seconds_since_epoch();
ReadLock lock(m_lock);
ReadLock lock(m_chainParamsLock);
if (m_chainParams.aux_id.empty() || m_chainParams.aux_diff.empty()) {
return false;
@@ -448,4 +467,9 @@ void MergeMiningClientJSON_RPC::on_shutdown()
uv_close(reinterpret_cast<uv_handle_t*>(&m_timer), nullptr);
}
const char* MergeMiningClientJSON_RPC::get_log_category() const
{
return log_category_prefix;
}
} // namespace p2pool
+5 -13
View File
@@ -24,19 +24,20 @@ namespace p2pool {
class p2pool;
struct PoolBlock;
class MergeMiningClientJSON_RPC : public IMergeMiningClient
class MergeMiningClientJSON_RPC : public MergeMiningClientShared
{
public:
MergeMiningClientJSON_RPC(p2pool* pool, const std::string& host, const std::string& wallet);
~MergeMiningClientJSON_RPC() override;
bool get_params(ChainParameters& out_params) const override;
void on_external_block(const PoolBlock& /*block*/) override {}
void submit_solution(const std::vector<uint8_t>& coinbase_merkle_proof, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof, uint32_t merkle_proof_path) override;
void print_status() const override;
void api_status(log::Stream&) const override;
const char* get_log_category() const override;
private:
static void loop(void* data);
@@ -51,20 +52,11 @@ private:
bool parse_merge_mining_submit_solution(const char* data, size_t size) const;
std::vector<uint8_t> m_previousAuxBlobs[NUM_PREVIOUS_HASHES];
std::string m_host;
int32_t m_port;
mutable uv_rwlock_t m_lock;
ChainParameters m_chainParams;
uint64_t m_chainParamsTimestamp;
std::string m_auxWallet;
double m_ping;
p2pool* m_pool;
uv_loop_t m_loop;
uv_thread_t m_loopThread;
+20 -240
View File
@@ -34,13 +34,7 @@ using namespace tari::rpc;
namespace p2pool {
MergeMiningClientTari::MergeMiningClientTari(p2pool* pool, std::string host, const std::string& wallet)
: m_chainParams{}
, m_chainParamsTimestamp(0)
, m_previousAuxHashes{}
, m_previousAuxHashesIndex(0)
, m_previousAuxHashesFoundIndex(std::numeric_limits<uint32_t>::max())
, m_auxWallet(wallet)
, m_pool(pool)
: MergeMiningClientShared(pool, wallet)
, m_tariJobParams{}
, m_server(new TariServer(pool->params().m_socks5Proxy, pool->params().m_socks5ProxyType))
, m_hostStr(host)
@@ -78,8 +72,6 @@ MergeMiningClientTari::MergeMiningClientTari(p2pool* pool, std::string host, con
throw std::exception();
}
uv_rwlock_init_checked(&m_chainParamsLock);
if (!m_server->start()) {
throw std::exception();
}
@@ -89,7 +81,7 @@ MergeMiningClientTari::MergeMiningClientTari(p2pool* pool, std::string host, con
s << "127.0.0.1:" << m_server->external_listen_port();
m_channelArgs.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, 1000);
m_channelArgs.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, 1000);
m_channelArgs.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, 10000);
@@ -102,15 +94,15 @@ MergeMiningClientTari::MergeMiningClientTari(p2pool* pool, std::string host, con
uv_mutex_init_checked(&m_workerLock);
uv_cond_init_checked(&m_workerCond);
uv_mutex_init_checked(&m_pushBlockLock);
uv_cond_init_checked(&m_pushBlockCond);
int err = uv_thread_create(&m_worker, run_wrapper, this);
if (err) {
LOGERR(1, "failed to start worker thread, error " << uv_err_name(err));
throw std::exception();
}
uv_mutex_init_checked(&m_pushBlockLock);
uv_cond_init_checked(&m_pushBlockCond);
std::ifstream f("tari_nodes.txt");
if (f.is_open()) {
@@ -170,8 +162,6 @@ MergeMiningClientTari::~MergeMiningClientTari()
m_TariNode.reset();
m_channel.reset();
uv_rwlock_destroy(&m_chainParamsLock);
uv_mutex_destroy(&m_workerLock);
uv_cond_destroy(&m_workerCond);
@@ -207,230 +197,6 @@ bool MergeMiningClientTari::get_params(ChainParameters& out_params) const
return true;
}
void MergeMiningClientTari::on_external_block(const PoolBlock& block)
{
#ifdef WITH_MERGE_MINING_DONATION
// The rest of the code is needed only when this node is sending donation messages
if (m_pool->params().m_authorKeyFile.empty()) {
return;
}
// Sanity check
if (block.m_transactions.empty() || block.m_hashingBlob.empty() || (block.m_hashingBlob.size() > 128)) {
LOGWARN(3, "on_external_block: sanity check failed - " << block.m_transactions.size() << " transactions, hashing blob size = " << block.m_hashingBlob.size());
return;
}
ChainParameters chain_params;
uint64_t previous_aux_hashes[NUM_PREVIOUS_HASHES];
{
ReadLock lock(m_chainParamsLock);
chain_params = m_chainParams;
memcpy(previous_aux_hashes, m_previousAuxHashes, sizeof(m_previousAuxHashes));
}
// Don't continue if our aux chain is not there
if (block.m_mergeMiningExtra.find(chain_params.aux_id) == block.m_mergeMiningExtra.end()) {
return;
}
// All aux chains in this block + the P2Pool sidechain
std::vector<hash> aux_ids;
// All aux chains in this block
std::vector<AuxChainData> aux_chains;
aux_ids.reserve(block.m_mergeMiningExtra.size() + 1);
aux_chains.reserve(block.m_mergeMiningExtra.size() + 1);
uint64_t mm_extra_size = 0;
for (const auto& i : block.m_mergeMiningExtra) {
// Filter aux chain data only
if ((i.first == keccak_subaddress_viewpub) || (i.first == keccak_onion_address_v3)) {
continue;
}
++mm_extra_size;
hash data;
difficulty_type diff;
{
const std::vector<uint8_t>& v = i.second;
const uint8_t* p = v.data();
const uint8_t* e = v.data() + v.size();
if (p + HASH_SIZE > e) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '1');
return;
}
memcpy(data.h, p, HASH_SIZE);
p += HASH_SIZE;
p = readVarint(p, e, diff.lo);
if (!p) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '2');
diff.lo = 0;
}
else {
p = readVarint(p, e, diff.hi);
if (!p) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '3');
diff.hi = 0;
}
}
}
// If it's our aux chain, check that it's the same job and that there is enough PoW
if (i.first == chain_params.aux_id) {
if ((data != chain_params.aux_hash) || (diff != chain_params.aux_diff)) {
uint32_t index = std::numeric_limits<uint32_t>::max();
for (uint32_t k = 0; k < NUM_PREVIOUS_HASHES; ++k) {
if (previous_aux_hashes[k] == *data.u64()) {
index = k;
break;
}
}
m_previousAuxHashesFoundIndex = index;
if (index == std::numeric_limits<uint32_t>::max()) {
LOGINFO(4, "External aux job solution found, but it's for another miner");
return;
}
LOGINFO(4, "External aux job solution found, but it's stale");
chain_params.aux_hash = data;
chain_params.aux_diff = diff;
}
else {
m_previousAuxHashesFoundIndex = std::numeric_limits<uint32_t>::max();
}
if (!diff.check_pow(block.m_powHash)) {
LOGINFO(4, "External aux job solution found, but it doesn't have enough PoW (block diff = " << block.m_difficulty << ", Tari diff = " << diff << ')');
return;
}
}
aux_ids.emplace_back(i.first);
aux_chains.emplace_back(i.first, data, diff);
}
aux_ids.emplace_back(m_pool->side_chain().consensus_hash());
LOGINFO(0, log::LightGreen() << "External aux job solution found. Processing it!");
// coinbase_merkle_proof
root_hash root;
std::vector<hash> proof;
uint32_t path;
#ifdef WITH_INDEXED_HASHES
std::vector<hash> transactions;
transactions.reserve(block.m_transactions.size());
for (const auto& h : block.m_transactions) {
transactions.emplace_back(h);
}
#else
const std::vector<hash>& transactions = block.m_transactions;
#endif
if (!merkle_hash_with_proof(transactions, 0, proof, path, root)) {
LOGWARN(3, "on_external_block: merkle_hash_with_proof failed for coinbase transaction");
return;
}
if (!verify_merkle_proof(transactions[0], proof, path, root)) {
LOGWARN(3, "on_external_block: verify_merkle_proof failed for coinbase transaction");
return;
}
std::vector<uint8_t> coinbase_merkle_proof;
coinbase_merkle_proof.reserve(proof.size() * HASH_SIZE);
for (const hash& h : proof) {
coinbase_merkle_proof.insert(coinbase_merkle_proof.end(), h.h, h.h + HASH_SIZE);
}
// hashing_blob
uint8_t hashing_blob[128] = {};
memcpy(hashing_blob, block.m_hashingBlob.data(), block.m_hashingBlob.size());
// nonce_offset and blob
size_t header_size = 0;
const std::vector<uint8_t> blob = block.serialize_mainchain_data(&header_size);
if (header_size <= NONCE_SIZE) {
LOGWARN(3, "on_external_block: invalid header_size");
return;
}
const uint32_t nonce_offset = static_cast<uint32_t>(header_size - NONCE_SIZE);
// aux_merkle_proof, aux_merkle_proof_path
std::vector<hash> aux_merkle_proof;
uint32_t aux_merkle_proof_path = 0;
const hash sidechain_id = block.m_sidechainId;
const uint32_t n_aux_chains = static_cast<uint32_t>(mm_extra_size + 1);
std::vector<hash> hashes(n_aux_chains);
uint32_t aux_nonce;
if (!find_aux_nonce(aux_ids, aux_nonce, 1000)) {
LOGWARN(3, "on_external_block: failed to find aux_nonce");
return;
}
for (const AuxChainData& aux_data : aux_chains) {
const uint32_t aux_slot = get_aux_slot(aux_data.unique_id, aux_nonce, n_aux_chains);
if (!hashes[aux_slot].empty()) {
LOGWARN(3, "on_external_block: found an incorrect aux_nonce " << '1');
return;
}
hashes[aux_slot] = aux_data.data;
}
const uint32_t aux_slot = get_aux_slot(m_pool->side_chain().consensus_hash(), aux_nonce, n_aux_chains);
if (!hashes[aux_slot].empty()) {
LOGWARN(3, "on_external_block: found an incorrect aux_nonce " << '2');
return;
}
hashes[aux_slot] = sidechain_id;
if (!merkle_hash_with_proof(hashes, chain_params.aux_hash, aux_merkle_proof, aux_merkle_proof_path, root)) {
LOGWARN(3, "on_external_block: merkle_hash_with_proof failed for the aux hash");
return;
}
if (root != block.m_merkleRoot) {
LOGWARN(3, "on_external_block: merkle root didn't match");
return;
}
if (!verify_merkle_proof(chain_params.aux_hash, aux_merkle_proof, aux_merkle_proof_path, root)) {
LOGWARN(3, "on_external_block: verify_merkle_proof failed for the aux hash");
return;
}
submit_solution(coinbase_merkle_proof, hashing_blob, nonce_offset, block.m_seed, blob, aux_merkle_proof, aux_merkle_proof_path);
#else // WITH_MERGE_MINING_DONATION
(void) block;
#endif // WITH_MERGE_MINING_DONATION
}
void MergeMiningClientTari::submit_solution(const std::vector<uint8_t>& coinbase_merkle_proof, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof, uint32_t merkle_proof_path)
{
Block block;
@@ -820,7 +586,7 @@ void MergeMiningClientTari::run()
const uint32_t index = (m_previousAuxHashesIndex++) % NUM_PREVIOUS_HASHES;
m_previousAuxHashes[index] = *m_chainParams.aux_hash.u64();
m_previousAuxHashes[index] = m_chainParams.aux_hash;
m_previousTariBlocks[index] = std::move(m_tariBlock);
std::copy(mm_hash.begin(), mm_hash.end(), m_chainParams.aux_hash.h);
@@ -1085,6 +851,8 @@ void MergeMiningClientTari::push_blocks_to(const std::string& node_address)
LOGINFO(4, node_address << " is at block height " << tip_info.metadata().best_block_height());
}
std::string prev_header_hash;
while (!m_pushBlockStop) {
Block block;
{
@@ -1099,6 +867,13 @@ void MergeMiningClientTari::push_blocks_to(const std::string& node_address)
}
const std::string& h = block.header().hash();
// Don't push the same block twice
if (h == prev_header_hash) {
continue;
}
prev_header_hash = h;
LOGINFO(4, "Pushing block " << log::hex_buf(h.data(), h.size()) << " to " << node_address);
grpc::ClientContext ctx;
@@ -1119,4 +894,9 @@ void MergeMiningClientTari::push_blocks_to(const std::string& node_address)
}
}
const char* MergeMiningClientTari::get_log_category() const
{
return log_category_prefix;
}
} // namespace p2pool
+3 -18
View File
@@ -25,7 +25,7 @@ namespace p2pool {
class p2pool;
struct PoolBlock;
class MergeMiningClientTari : public IMergeMiningClient, public nocopy_nomove
class MergeMiningClientTari : public MergeMiningClientShared
{
public:
MergeMiningClientTari(p2pool* pool, std::string host, const std::string& wallet);
@@ -34,33 +34,18 @@ public:
static constexpr char TARI_PREFIX[] = "tari://";
bool get_params(ChainParameters& out_params) const override;
void on_external_block(const PoolBlock& block) override;
void submit_solution(const std::vector<uint8_t>& coinbase_merkle_proof, const uint8_t (&hashing_blob)[128], size_t nonce_offset, const hash& seed_hash, const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof, uint32_t merkle_proof_path) override;
void print_status() const override;
void api_status(log::Stream&) const override;
const char* get_log_category() const override;
private:
mutable uv_rwlock_t m_chainParamsLock;
ChainParameters m_chainParams;
uint64_t m_chainParamsTimestamp;
enum {
NUM_PREVIOUS_HASHES = 8,
};
uint64_t m_previousAuxHashes[NUM_PREVIOUS_HASHES];
tari::rpc::Block m_previousTariBlocks[NUM_PREVIOUS_HASHES];
uint32_t m_previousAuxHashesIndex;
std::atomic<uint32_t> m_previousAuxHashesFoundIndex;
tari::rpc::Block m_tariBlock;
std::string m_auxWallet;
p2pool* m_pool;
struct TariJobParams
{
uint64_t height;
+125 -17
View File
@@ -33,6 +33,7 @@
#include "rapidjson_wrapper.h"
#include "merge_mining_client.h"
#include "sha256.h"
#include "i2p.h"
#ifdef WITH_TLS
#include <openssl/curve25519.h>
@@ -48,6 +49,7 @@ LOG_CATEGORY(P2PServer)
static constexpr char saved_peer_list_file_name[] = "p2pool_peers.txt";
static constexpr char saved_onion_peer_list_file_name[] = "p2pool_onion_peers.txt";
static constexpr char saved_i2p_peer_list_file_name[] = "p2pool_i2p_peers.txt";
static const char* seed_nodes[] = { "seeds.p2pool.io", "main.p2poolpeers.net", "" };
static const char* seed_nodes_mini[] = { "seeds-mini.p2pool.io", "mini.p2poolpeers.net", "" };
static const char* seed_nodes_nano[] = { "seeds-nano.p2pool.io", "nano.p2poolpeers.net", ""};
@@ -63,6 +65,10 @@ static constexpr hash seed_onion_nodes[] = {
from_onion_v3_const("p2pseedtwyepi4crkf4akceen4twejcptnsbm6gjmzdfgxua57hiijid.onion")
};
static constexpr hash seed_i2p_nodes[] = {
from_i2p_b32_const("h6jrh53yvlvzqqyy7abzjp2t4kidtheee7e7nfbynecroc7yvbjq.b32.i2p")
};
P2PServer::P2PServer(p2pool* pool)
: TCPServer(DEFAULT_BACKLOG, P2PClient::allocate, pool->params().m_socks5Proxy, pool->params().m_socks5ProxyType, pool->params().m_p2pProxyProtocol)
, m_pool(pool)
@@ -79,6 +85,8 @@ P2PServer::P2PServer(p2pool* pool)
, m_seenGoodPeers(false)
, m_peerListLastSaved(0)
, m_numOnionConnections(0)
, m_numI2PConnections(0)
, m_isI2P(pool->params().m_socks5ProxyType == Params::ProxyType::I2P)
, m_lookForMissingBlocks(true)
, m_fastestPeer(nullptr)
, m_newP2PoolVersionDetected(false)
@@ -93,8 +101,10 @@ P2PServer::P2PServer(p2pool* pool)
// Diffuse the initial state in case it has low quality
m_rng.discard(10000);
m_peerId = m_rng();
m_peerId_TOR = m_rng();
// Make sure peer IDs are not 0
do { m_peerId = m_rng(); } while (!m_peerId);
do { m_peerId_TOR = m_rng(); } while (!m_peerId_TOR);
do { m_peerId_I2P = m_rng(); } while (!m_peerId_I2P);
const Params& params = pool->params();
@@ -459,6 +469,39 @@ void P2PServer::update_peer_connections()
}
}
// Try to have at least N/2 (or N if clearnet P2P is disabled) outgoing I2P connections
if (!m_socks5Proxy.empty() && (m_socks5ProxyType == Params::ProxyType::I2P)) {
std::vector<hash> dest_hashes = m_pool->side_chain().seen_i2p_dest_hashes();
// Add seed nodes
dest_hashes.insert(dest_hashes.end(), seed_i2p_nodes, seed_i2p_nodes + array_size(seed_i2p_nodes));
const uint32_t n = m_pool->params().m_noClearnetP2P ? N : (N / 2);
for (uint32_t i = m_numI2PConnections; (i < n) && !dest_hashes.empty();) {
const uint64_t k = get_random64() % dest_hashes.size();
const std::string addr = to_i2p_b32(dest_hashes[k]);
int port = DEFAULT_P2P_PORT_I2P;
for (const hash& seed_i2p : seed_i2p_nodes) {
if (dest_hashes[k] == seed_i2p) {
const SideChain& s = m_pool->side_chain();
port = s.is_mini() ? DEFAULT_P2P_PORT_MINI : (s.is_nano() ? DEFAULT_P2P_PORT_NANO : DEFAULT_P2P_PORT);
break;
}
}
if ((connected_clients_domain.find(addr) == connected_clients_domain.end()) && connect_to_peer(addr, port)) {
++i;
++num_outgoing;
}
dest_hashes[k] = dest_hashes.back();
dest_hashes.pop_back();
}
}
// Try to have at least N outgoing connections (N defaults to 10, can be set via --out-peers command line parameter)
if (!m_pool->params().m_noClearnetP2P) {
while ((num_outgoing < N) && !peer_list.empty()) {
@@ -631,6 +674,28 @@ void P2PServer::save_peer_list()
}
}
if (s.i2p_dest_hashes_count() > 0) {
const std::string i2p_path = params.m_dataDir + saved_i2p_peer_list_file_name;
f.open(i2p_path, std::ios::binary);
if (!f.is_open()) {
LOGERR(1, "failed to save I2P peer list " << i2p_path << ": error " << errno);
}
else {
const std::vector<hash> dest_hashes = s.seen_i2p_dest_hashes();
for (const hash& h : dest_hashes) {
f << to_i2p_b32(h) << '\n';
}
f.flush();
f.close();
LOGINFO(5, "I2P peer list saved (" << dest_hashes.size() << " peers)");
}
}
m_peerListLastSaved = seconds_since_epoch();
}
@@ -732,10 +797,16 @@ void P2PServer::load_peer_list()
std::vector<std::string> paths;
paths.resize(Params::ProxyType::MAX);
paths[Params::ProxyType::PLAIN] = saved_peer_list_file_name;
const Params& params = m_pool->params();
paths[Params::ProxyType::PLAIN] = params.m_dataDir + saved_peer_list_file_name;
if (!m_socks5Proxy.empty() && (m_socks5ProxyType == Params::ProxyType::TOR)) {
paths[Params::ProxyType::TOR] = saved_onion_peer_list_file_name;
paths[Params::ProxyType::TOR] = params.m_dataDir + saved_onion_peer_list_file_name;
}
if (!m_socks5Proxy.empty() && (m_socks5ProxyType == Params::ProxyType::I2P)) {
paths[Params::ProxyType::I2P] = params.m_dataDir + saved_i2p_peer_list_file_name;
}
for (int i = Params::ProxyType::PLAIN; i < Params::ProxyType::MAX; ++i) {
@@ -761,6 +832,12 @@ void P2PServer::load_peer_list()
pubkeys.emplace_back(h);
}
}
else if (i == Params::ProxyType::I2P) {
const hash h = from_i2p_b32(address);
if (!h.empty()) {
pubkeys.emplace_back(h);
}
}
else {
if (!saved_list.empty()) {
saved_list += ',';
@@ -774,6 +851,9 @@ void P2PServer::load_peer_list()
if (i == Params::ProxyType::TOR) {
s.add_onion_pubkeys(pubkeys);
}
else if (i == Params::ProxyType::I2P) {
s.add_i2p_dest_hashes(pubkeys);
}
}
}
@@ -1214,13 +1294,17 @@ uint64_t P2PServer::get_random64()
void P2PServer::print_status()
{
const uint64_t onion_list_size = m_pool->side_chain().onion_pubkeys_count();
const uint64_t i2p_list_size = m_pool->side_chain().i2p_dest_hashes_count();
MutexLock lock(m_peerListLock);
LOGINFO(0, "status" <<
"\nConnections = " << m_numConnections.load() << " (" << m_numIncomingConnections.load() << " incoming, " << m_numOnionConnections.load() << " onion)"
"\nConnections = " << m_numConnections.load() <<
" (" << m_numIncomingConnections.load() <<
" incoming, " << m_numOnionConnections.load() << " onion, " << m_numI2PConnections.load() << " I2P)" <<
"\nPeer list size = " << m_peerList.size() <<
"\nOnion list size = " << onion_list_size <<
"\nI2P list size = " << i2p_list_size <<
"\nUptime = " << log::Duration(seconds_since_epoch() - m_pool->start_time())
);
}
@@ -1911,7 +1995,11 @@ void P2PServer::P2PClient::reset()
server->m_fastestPeer = nullptr;
}
if ((m_addressType == AddressType::DomainName) && m_connectedTime) {
--server->m_numOnionConnections;
if (server->m_isI2P == true) {
--server->m_numI2PConnections;
} else {
--server->m_numOnionConnections;
}
}
}
@@ -1971,7 +2059,11 @@ bool P2PServer::P2PClient::on_connect()
}
if (m_addressType == AddressType::DomainName) {
++server->m_numOnionConnections;
if (server->m_isI2P == true) {
++server->m_numI2PConnections;
} else {
++server->m_numOnionConnections;
}
}
const uint64_t cur_time = seconds_since_epoch();
@@ -2014,7 +2106,7 @@ bool P2PServer::P2PClient::on_read(const char* data, uint32_t size)
const MessageId id = static_cast<MessageId>(buf[0]);
// Peer must complete the handshake challenge before sending any other messages
if (!m_handshakeComplete && (id != m_expectedMessage)) {
if ((!m_handshakeComplete || m_handshakeInvalid) && (id != m_expectedMessage)) {
LOGWARN(5, "peer " << static_cast<char*>(m_addrString) << " didn't send handshake messages first");
ban(DEFAULT_BAN_TIME);
server->remove_peer_from_list(this);
@@ -2308,7 +2400,18 @@ bool P2PServer::P2PClient::send_handshake_challenge()
k >>= 8;
}
k = owner->get_peerId((m_addressType == AddressType::DomainName) && (strstr(m_addrString, ".onion:")));
bool is_tor = false;
if ((m_addressType == AddressType::DomainName) && (strstr(m_addrString, ".onion:"))) {
// We're connecting to an .onion address
is_tor = true;
}
else if (!owner->m_pool->params().m_onionPubkey.empty() && m_isIncoming && (m_addressType != AddressType::DomainName) && m_addr.is_localhost()) {
// We published our .onion address, and it's an incoming connection on localhost interface, so it's likely an incoming tor connection
is_tor = true;
}
k = owner->get_peerId(is_tor, owner->m_isI2P);
memcpy(p, &k, sizeof(uint64_t));
p += sizeof(uint64_t);
@@ -2501,7 +2604,7 @@ bool P2PServer::P2PClient::on_handshake_challenge(const uint8_t* buf)
uint64_t peer_id;
memcpy(&peer_id, buf + CHALLENGE_SIZE, sizeof(uint64_t));
if ((peer_id == server->get_peerId(false)) || (peer_id == server->get_peerId(true))) {
if ((peer_id == server->m_peerId) || (peer_id == server->m_peerId_TOR) || (peer_id == server->m_peerId_I2P)) {
LOGWARN(5, "tried to connect to self at " << static_cast<const char*>(m_addrString));
return false;
}
@@ -2599,7 +2702,7 @@ bool P2PServer::P2PClient::on_listen_port(const uint8_t* buf)
int32_t port;
memcpy(&port, buf, sizeof(port));
if ((port < 0) || (port >= 65536)) {
if ((port <= 0) || (port >= 65536)) {
LOGWARN(5, "peer " << static_cast<char*>(m_addrString) << " sent an invalid listen port number");
return false;
}
@@ -3043,7 +3146,7 @@ bool P2PServer::P2PClient::on_aux_job_donation(const uint8_t* buf, uint32_t size
const time_t cur_time = time(nullptr);
// Layout of the message:
//
//
// 32 bytes | Secondary public key
// 8 bytes | Secondary public key's expiration timestamp
// 64 bytes | Master key signature signing the above 40 bytes
@@ -3062,11 +3165,11 @@ bool P2PServer::P2PClient::on_aux_job_donation(const uint8_t* buf, uint32_t size
}
// Layout of the data:
//
//
// 8 bytes | timestamp
//
//
// Next come one or multiple data entries:
//
//
// 32 bytes | aux_id
// 32 bytes | aux_hash
// 16 bytes | aux_diff
@@ -3113,6 +3216,11 @@ bool P2PServer::P2PClient::on_aux_job_donation(const uint8_t* buf, uint32_t size
p += sizeof(int64_t);
// Ignore outdated messages
if (data_timestamp > std::numeric_limits<int64_t>::max() - AUX_JOB_TIMEOUT) {
LOGWARN(4, "peer " << static_cast<char*>(m_addrString) << " sent an invalid AUX_JOB_DONATION message (timestamp = " << data_timestamp << ')');
return false;
}
if (cur_time >= data_timestamp + AUX_JOB_TIMEOUT) {
LOGWARN(4, "peer " << static_cast<char*>(m_addrString) << " sent an outdated AUX_JOB_DONATION message (" << cur_time << " >= " << data_timestamp << " + " << static_cast<int>(AUX_JOB_TIMEOUT) << ')');
return true;
@@ -3120,7 +3228,7 @@ bool P2PServer::P2PClient::on_aux_job_donation(const uint8_t* buf, uint32_t size
if ((data_end - p) % DATA_ENTRY_SIZE) {
LOGWARN(4, "peer " << static_cast<char*>(m_addrString) << " sent an invalid AUX_JOB_DONATION message (" << (data_end - p) << " is not a multiple of " << DATA_ENTRY_SIZE << ')');
return true;
return false;
}
hash digest;
@@ -3262,7 +3370,7 @@ bool P2PServer::P2PClient::on_monero_block_broadcast(const uint8_t* buf, uint32_
std::vector<uint8_t> blob;
blob.reserve(data.header_size + HASH_SIZE + 2);
blob.insert(blob.end(), buf, buf + data.header_size);
blob.insert(blob.end(), root.h, root.h + HASH_SIZE);
writeVarint(num_transactions + 1, blob);
+7 -3
View File
@@ -37,6 +37,7 @@ static constexpr int DEFAULT_P2P_PORT_MINI = 37888;
static constexpr int DEFAULT_P2P_PORT_NANO = 37890;
static constexpr int DEFAULT_P2P_PORT_ONION = 28722;
static constexpr int DEFAULT_P2P_PORT_I2P = 28723;
static constexpr uint32_t PROTOCOL_VERSION_1_0 = 0x00010000UL;
static constexpr uint32_t PROTOCOL_VERSION_1_1 = 0x00010001UL;
@@ -95,9 +96,9 @@ public:
// Both peers send handshake challenge immediately after a connection is established
// Both peers must have the same consensus ID for handshake to succeed
// Consensus ID is never sent over the network
//
//
// Handshake sequence:
//
//
// - Both peers send 8-byte random challenges (and 8 bytes of peer ID) to each other
// - Each peer receives 8-byte challenge, chooses 8-byte random SALT and calculates H = KECCAK(CHALLENGE|CONSENSUS_ID|SALT)
// - Both peers send their H and SALT, calculate H of the other peer and check if it matches with what other peer calculated
@@ -191,7 +192,7 @@ public:
void broadcast(const PoolBlock& block, const PoolBlock* parent);
[[nodiscard]] uint64_t get_random64();
[[nodiscard]] uint64_t get_peerId(bool is_tor) const { return is_tor ? m_peerId_TOR : m_peerId; }
[[nodiscard]] uint64_t get_peerId(bool is_tor, bool is_i2p) const { return is_tor ? m_peerId_TOR : (is_i2p ? m_peerId_I2P : m_peerId); }
void print_status() override;
void show_peers_async();
@@ -271,6 +272,7 @@ private:
uint64_t m_peerId;
uint64_t m_peerId_TOR;
uint64_t m_peerId_I2P;
mutable uv_mutex_t m_peerListLock;
@@ -291,6 +293,8 @@ private:
std::atomic<uint64_t> m_peerListLastSaved;
std::atomic<uint32_t> m_numOnionConnections;
std::atomic<uint32_t> m_numI2PConnections;
bool m_isI2P;
uv_mutex_t m_broadcastLock;
uv_async_t m_broadcastAsync;
+20
View File
@@ -19,6 +19,7 @@
#include "params.h"
#include "stratum_server.h"
#include "p2p_server.h"
#include "i2p.h"
#include <fstream>
#ifdef WITH_GRPC
@@ -59,6 +60,15 @@ Params::Params(const std::vector<std::vector<std::string>>& args)
}
}
if (!m_i2pAddress.empty()) {
m_i2pDestinationHash = from_i2p_b32(m_i2pAddress);
if (m_i2pDestinationHash.empty()) {
LOGERR(1, "Failed to parse \"" << m_i2pAddress << '"');
throw std::exception();
}
}
auto invalid_host = [](const Host& h)
{
if (!h.valid()) {
@@ -180,6 +190,10 @@ Params::Params(const std::vector<std::vector<std::string>>& args)
m_socks5ProxyType = ProxyType::TOR;
break;
case 4447:
m_socks5ProxyType = ProxyType::I2P;
break;
default:
m_socks5ProxyType = ProxyType::PLAIN;
break;
@@ -394,6 +408,7 @@ bool Params::process_arg(const std::vector<std::string>& arg)
if (s == "auto") m_socks5ProxyType = ProxyType::AUTO;
if (s == "plain") m_socks5ProxyType = ProxyType::PLAIN;
if (s == "tor") m_socks5ProxyType = ProxyType::TOR;
if (s == "i2p") m_socks5ProxyType = ProxyType::I2P;
return m_socks5ProxyType != ProxyType::INVALID;
}
@@ -460,6 +475,11 @@ bool Params::process_arg(const std::vector<std::string>& arg)
return true;
}
if ((arg[0] == "i2p-address") && has1(arg)) {
m_i2pAddress = arg[1];
return true;
}
if (arg[0] == "no-clearnet-p2p") {
m_noClearnetP2P = true;
return true;
+8 -1
View File
@@ -116,7 +116,8 @@ struct Params
AUTO = 0,
PLAIN = 1,
TOR = 2,
MAX = 3,
I2P = 3,
MAX = 4,
} m_socks5ProxyType = ProxyType::AUTO;
bool m_dns = true;
@@ -148,6 +149,12 @@ struct Params
std::string m_onionAddress;
hash m_onionPubkey;
// Hidden service address provided by the user
std::string m_i2pAddress;
// Raw hash of the destination info; decoded Base32 address with suffix removed
hash m_i2pDestinationHash;
bool m_noClearnetP2P = false;
bool m_stratumProxyProtocol = false;
bool m_p2pProxyProtocol = false;
+1 -3
View File
@@ -51,7 +51,6 @@ PoolBlock::PoolBlock()
, m_difficulty{}
, m_cumulativeDifficulty{}
, m_merkleProof{}
, m_merkleProofPath(0)
, m_mergeMiningExtra{}
, m_sidechainExtraBuf{}
, m_sidechainId{}
@@ -108,7 +107,6 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b)
m_difficulty = b.m_difficulty;
m_cumulativeDifficulty = b.m_cumulativeDifficulty;
m_merkleProof = b.m_merkleProof;
m_merkleProofPath = b.m_merkleProofPath;
m_mergeMiningExtra = b.m_mergeMiningExtra;
memcpy(m_sidechainExtraBuf, b.m_sidechainExtraBuf, sizeof(m_sidechainExtraBuf));
m_sidechainId = b.m_sidechainId;
@@ -200,7 +198,7 @@ std::vector<uint8_t> PoolBlock::serialize_mainchain_data(size_t* header_size, si
}
*(p++) = TX_EXTRA_NONCE;
*(p++) = static_cast<uint8_t>(extra_nonce_size);
writeVarint(extra_nonce_size, [&p](uint8_t value) { *(p++) = value; });
if (!extra_nonce) {
extra_nonce = &m_extraNonce;
+3 -1
View File
@@ -62,6 +62,9 @@ static constexpr difficulty_type MAX_CUMULATIVE_DIFFICULTY{ 13019633956666736640
// 1000 years at 1 block/second. It should be enough for any normal use.
static constexpr uint64_t MAX_SIDECHAIN_HEIGHT = 31556952000ULL;
// Taken from Monero's cryptonote_config.h
static constexpr uint64_t CRYPTONOTE_MAX_BLOCK_NUMBER = 500000000ULL;
// Limited by the format of the Merkle tree parameters in tx_extra
static constexpr uint64_t MERGE_MINING_MAX_CHAINS = 256;
static constexpr uint64_t LOG2_MERGE_MINING_MAX_CHAINS = 8;
@@ -140,7 +143,6 @@ struct PoolBlock
// Merkle proof for merge mining
std::vector<hash> m_merkleProof;
uint32_t m_merkleProofPath;
// Merge mining extra data
//
+16 -9
View File
@@ -79,11 +79,13 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
uint64_t unlock_height;
READ_VARINT(unlock_height);
if (unlock_height > CRYPTONOTE_MAX_BLOCK_NUMBER) return __LINE__;
EXPECT_BYTE(1);
EXPECT_BYTE(TXIN_GEN);
READ_VARINT(m_txinGenHeight);
if (m_txinGenHeight > CRYPTONOTE_MAX_BLOCK_NUMBER) return __LINE__;
if (m_majorVersion != sidechain.network_major_version(m_txinGenHeight)) return __LINE__;
if (unlock_height != m_txinGenHeight + MINER_REWARD_UNLOCK_TIME) return __LINE__;
@@ -99,8 +101,8 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
if (num_outputs > 0) {
// Outputs are in the buffer, just read them
// Each output is at least 34 bytes, exit early if there's not enough data left
// 1 byte for reward, 1 byte for tx_type, 32 bytes for eph_pub_key
constexpr uint64_t MIN_OUTPUT_SIZE = 34;
// 1 byte for reward, 1 byte for tx_type, 32 bytes for eph_pub_key, 1 byte for view_tag
constexpr uint64_t MIN_OUTPUT_SIZE = 35;
if (num_outputs > std::numeric_limits<uint64_t>::max() / MIN_OUTPUT_SIZE) return __LINE__;
if (static_cast<uint64_t>(data_end - data) < num_outputs * MIN_OUTPUT_SIZE) return __LINE__;
@@ -123,6 +125,8 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
}
t.m_reward = reward;
if (total_reward + reward < total_reward) return __LINE__;
total_reward += reward;
EXPECT_BYTE(TXOUT_TO_TAGGED_KEY);
@@ -269,6 +273,12 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
const int transactions_blob_size = static_cast<int>(num_transactions) * HASH_SIZE;
const int transactions_blob_size_diff = transactions_blob_size - transactions_actual_blob_size;
const int data_size = static_cast<int>((data_end - data_begin) + outputs_blob_size_diff + transactions_blob_size_diff);
if (data_size > static_cast<int>(MAX_BLOCK_SIZE)) {
return __LINE__;
}
#if POOL_BLOCK_DEBUG
m_mainChainDataDebug.reserve((data - data_begin) + outputs_blob_size_diff + transactions_blob_size_diff);
m_mainChainDataDebug.assign(data_begin, data_begin + outputs_offset);
@@ -413,9 +423,11 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
if (static_cast<uint64_t>(data_end - data) < n) return __LINE__;
std::vector<uint8_t> t;
t.resize(n);
READ_BUF(t.data(), n);
if (n > 0) {
t.resize(n);
READ_BUF(t.data(), n);
}
m_mergeMiningExtra.emplace(chain_id, std::move(t));
}
@@ -449,11 +461,6 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
hash check;
const std::vector<uint8_t>& consensus_id = sidechain.consensus_id();
const int data_size = static_cast<int>((data_end - data_begin) + outputs_blob_size_diff + transactions_blob_size_diff);
if (data_size > static_cast<int>(MAX_BLOCK_SIZE)) {
return __LINE__;
}
keccak_custom(
[nonce_offset, extra_nonce_offset, mm_root_hash_offset, data_begin, data_size, &consensus_id, &outputs_blob, outputs_blob_size_diff, outputs_offset, outputs_blob_size, transactions_blob, transactions_blob_size_diff, transactions_offset, transactions_blob_size](int offset) -> uint8_t
+42 -2
View File
@@ -702,6 +702,13 @@ bool SideChain::add_block(const PoolBlock& block)
m_seenOnionPubkeys[h] = new_block->m_localTimestamp;
}
auto it2 = new_block->m_mergeMiningExtra.find(keccak_i2p_b32_address);
if ((it2 != new_block->m_mergeMiningExtra.end()) && (it2->second.size() >= HASH_SIZE)) {
hash h;
memcpy(h.h, it2->second.data(), HASH_SIZE);
m_seenI2PDestHashes[h] = new_block->m_localTimestamp;
}
prune_seen_data();
}
@@ -1156,7 +1163,7 @@ void SideChain::prune_seen_data()
{
const uint64_t cur_time = seconds_since_epoch();
// Every 5 minutes, delete wallets that weren't seen for more than 72 hours and onion pubkeys that weren't seen for more than 12 hours
// Every 5 minutes, delete wallets that haven't been seen for more than 72 hours and onion/I2P identifiers that haven't been seen for more than 12 hours
if (m_seenWalletsLastPruneTime + 5ul * 60ul <= cur_time) {
auto prune = [cur_time](auto& data, uint64_t timeout) {
for (auto it = data.begin(); it != data.end();) {
@@ -1173,6 +1180,7 @@ void SideChain::prune_seen_data()
prune(m_seenWallets, 72 * hour);
prune(m_seenOnionPubkeys, 12 * hour);
prune(m_seenI2PDestHashes, 12 * hour);
m_seenWalletsLastPruneTime = cur_time;
}
@@ -1401,6 +1409,38 @@ void SideChain::add_onion_pubkeys(const std::vector<hash>& pubkeys)
}
}
std::vector<hash> SideChain::seen_i2p_dest_hashes() const
{
std::vector<hash> result;
ReadLock lock(m_seenDataLock);
result.reserve(m_seenI2PDestHashes.size());
for (const auto& it : m_seenI2PDestHashes) {
result.push_back(it.first);
}
return result;
}
void SideChain::add_i2p_dest_hashes(const std::vector<hash>& dest_hashes)
{
if (dest_hashes.empty()) {
return;
}
const uint64_t cur_time = seconds_since_epoch();
WriteLock lock(m_seenDataLock);
for (const hash& h : dest_hashes) {
if (!h.empty()) {
m_seenI2PDestHashes[h] = cur_time;
}
}
}
void SideChain::verify_loop(PoolBlock* block)
{
// PoW is already checked at this point
@@ -2445,7 +2485,7 @@ void SideChain::precalc_worker()
do {
const PoolBlock* job;
{
MutexLock lock(m_precalcJobsMutex);
+5
View File
@@ -76,6 +76,7 @@ public:
[[nodiscard]] uint64_t block_time() const { return m_targetBlockTime; }
[[nodiscard]] FORCEINLINE uint64_t miner_count() const { ReadLock lock(m_seenDataLock); return m_seenWallets.size(); }
[[nodiscard]] FORCEINLINE uint64_t onion_pubkeys_count() const { ReadLock lock(m_seenDataLock); return m_seenOnionPubkeys.size(); }
[[nodiscard]] FORCEINLINE uint64_t i2p_dest_hashes_count() const { ReadLock lock(m_seenDataLock); return m_seenI2PDestHashes.size(); }
[[nodiscard]] uint64_t last_updated() const;
[[nodiscard]] bool is_default() const;
[[nodiscard]] bool is_mini() const;
@@ -90,6 +91,9 @@ public:
[[nodiscard]] std::vector<hash> seen_onion_pubkeys() const;
void add_onion_pubkeys(const std::vector<hash>& pubkeys);
[[nodiscard]] std::vector<hash> seen_i2p_dest_hashes() const;
void add_i2p_dest_hashes(const std::vector<hash>& dest_hashes);
#ifdef P2POOL_UNIT_TESTS
difficulty_type m_testMainChainDiff;
const unordered_map<hash, PoolBlock*>& blocksById() const { return m_blocksById; }
@@ -129,6 +133,7 @@ private:
mutable ReadWriteLock m_seenDataLock;
unordered_map<hash, uint64_t> m_seenWallets;
unordered_map<hash, uint64_t> m_seenOnionPubkeys;
unordered_map<hash, uint64_t> m_seenI2PDestHashes;
uint64_t m_seenWalletsLastPruneTime;
// Used to quickly cut off multiple broadcasts of the same block by different peers. Only the first broadcast will be processed.
+19 -3
View File
@@ -128,7 +128,7 @@ void TCPServer::parse_address_list_internal(const std::string& address_list, con
}
}
const uint32_t port = std::stoul(address.substr(k2 + 1), nullptr, 10);
const uint32_t port = strtoul(address.c_str() + k2 + 1, nullptr, 10);
if ((port > 0) && (port < 65536)) {
callback(is_v6, address, ip, static_cast<int>(port));
}
@@ -340,6 +340,7 @@ bool TCPServer::connect_to_peer(const std::string& domain, int port)
if (s.m_spilled) {
LOGERR(1, "Can't connect to " << domain << ": too long domain name");
return_client(client);
return false;
}
@@ -429,6 +430,7 @@ bool TCPServer::connect_to_peer(Client* client)
}
else {
LOGWARN(5, "failed to initiate tcp connection to " << static_cast<const char*>(client->m_addrString) << ": domain name is unresolved and SOCKS5 proxy is not enabled");
uv_close(reinterpret_cast<uv_handle_t*>(&client->m_socket), on_connection_error);
return false;
}
}
@@ -582,6 +584,11 @@ bool TCPServer::send_internal(Client* client, const Callback<size_t, uint8_t*, s
return true;
}
if (m_callbackBuf.empty()) {
LOGERR(1, "callback buf is not initialized");
return false;
}
const size_t bytes_written = callback(m_callbackBuf.data(), m_callbackBuf.size());
if (bytes_written > m_callbackBuf.size()) {
@@ -613,7 +620,7 @@ bool TCPServer::send_internal(Client* client, const Callback<size_t, uint8_t*, s
uv_buf_t bufs[1];
bufs[0].base = reinterpret_cast<char*>(buf->m_data);
bufs[0].len = static_cast<int>(size);
bufs[0].len = static_cast<uint32_t>(size);
const int err = uv_write(&buf->m_write, reinterpret_cast<uv_stream_t*>(&client->m_socket), bufs, 1, Client::on_write);
if (err) {
@@ -937,6 +944,7 @@ void TCPServer::on_new_client(uv_stream_t* server, Client* client)
}
else {
client->close();
return;
}
}
}
@@ -1258,7 +1266,8 @@ bool TCPServer::Client::on_proxy_handshake(const char* data, uint32_t size)
m_socks5ProxyState = Socks5ProxyState::ConnectRequestSent;
}
else {
close();
LOGWARN(5, "Failed to send SOCKS5 proxy connect request");
return false;
}
}
break;
@@ -1466,6 +1475,13 @@ void TCPServer::Client::on_write(uv_write_t* req, int status)
if (server) {
server->return_write_buffer(buf);
}
else {
// no server to return buf to, so just delete it
if (buf->m_data) {
free_hook(buf->m_data);
}
delete buf;
}
if (status != 0) {
LOGWARN(5, "client " << static_cast<const char*>(client->m_addrString) << " failed to write data to client connection, error " << uv_err_name(status));
+22 -5
View File
@@ -232,7 +232,16 @@ bool ServerTls::on_read_internal(const char* data, uint32_t size, const ReadCall
return false;
}
if (!BIO_write_all(SSL_get_rbio(ssl), data, size)) {
BIO* rbio = SSL_get_rbio(ssl);
if (!rbio) {
return false;
}
if (!BIO_write_all(rbio, data, size)) {
return false;
}
if (BIO_ctrl_pending(rbio) > 32768u) {
return false;
}
@@ -266,9 +275,12 @@ bool ServerTls::on_read_internal(const char* data, uint32_t size, const ReadCall
}
}
if ((result < 0) && (SSL_get_error(ssl, result) == SSL_ERROR_WANT_READ)) {
// Continue handshake, nothing to read yet
return true;
if (result < 0) {
const int err = SSL_get_error(ssl, result);
if ((err == SSL_ERROR_WANT_READ) || (err == SSL_ERROR_WANT_WRITE)) {
// Continue handshake, nothing to read yet
return true;
}
}
if (result == 1) {
@@ -289,11 +301,16 @@ bool ServerTls::on_read_internal(const char* data, uint32_t size, const ReadCall
}
}
return true;
const int err = SSL_get_error(ssl, bytes_read);
return (err == SSL_ERROR_WANT_READ) || (err == SSL_ERROR_WANT_WRITE);
}
bool ServerTls::on_write_internal(const uint8_t* data, size_t size, const WriteCallback::Base& write_callback)
{
if (size > static_cast<size_t>(std::numeric_limits<int>::max())) {
return false;
}
SSL* ssl = m_ssl.get();
if (!ssl) {
return false;
+1 -1
View File
@@ -986,7 +986,7 @@ std::string to_onion_v3(const hash& pubkey)
while (bit_size >= 5) {
bit_size -= 5;
result += "abcdefghijklmnopqrstuvwxyz234567"[(data >> bit_size) & 31];
result += base32_alphabet[(data >> bit_size) & 31];
}
}
+2
View File
@@ -407,6 +407,8 @@ FORCEINLINE std::string tolower(const std::string& s)
return result;
}
constexpr char base32_alphabet[] = "abcdefghijklmnopqrstuvwxyz234567";
std::string to_onion_v3(const hash& pubkey);
hash from_onion_v3(const std::string& address);
+3 -1
View File
@@ -15,7 +15,7 @@ endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
if (${CMAKE_VERSION} VERSION_GREATER "3.5.2")
if (${CMAKE_VERSION} VERSION_GREATER "3.5.2")
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT p2pool_tests)
endif()
@@ -60,6 +60,7 @@ set(SOURCES
src/sha256_tests.cpp
src/util_tests.cpp
src/wallet_tests.cpp
src/i2p_tests.cpp
../external/src/crypto/sha256.c
../external/src/cryptonote/crypto-ops-data.c
../external/src/cryptonote/crypto-ops.c
@@ -84,6 +85,7 @@ set(SOURCES
../src/tcp_server.cpp
../src/util.cpp
../src/wallet.cpp
../src/i2p.cpp
)
if (WITH_INDEXED_HASHES)
+1
View File
@@ -13,6 +13,7 @@ set(WITH_DOCS OFF CACHE BOOL "")
set(ENABLE_DRAFTS OFF CACHE BOOL "")
set(BUILD_SHARED OFF CACHE BOOL "")
set(ENABLE_CLANG OFF CACHE BOOL "")
set(ENABLE_CLANG_TIDY OFF CACHE BOOL "")
set(CURL_TARGET_WINDOWS_VERSION "0x0600" CACHE STRING "")
set(BUILD_CURL_EXE OFF CACHE BOOL "")
+10
View File
@@ -33,6 +33,16 @@ TEST(hash, constructor)
memset(h.h, -1, HASH_SIZE);
h = {};
ASSERT_EQ(memcmp(h.h, buf, HASH_SIZE), 0);
hash h2{ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" };
for (uint8_t i = 0; i < HASH_SIZE; ++i) {
ASSERT_EQ(h2.h[i], i);
}
hash h3{ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" };
for (uint8_t i = 0; i < HASH_SIZE; ++i) {
ASSERT_EQ(h3.h[i], i);
}
}
TEST(hash, compare)
+58
View File
@@ -0,0 +1,58 @@
/*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021-2024 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2026 jpk68
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common.h"
#include "i2p.h"
#include "gtest/gtest.h"
namespace p2pool {
TEST(i2p, decode_encode)
{
const hash expected{
0xad, 0xcc, 0x78, 0x7e, 0x8e, 0x46, 0xd9, 0xd4,
0xd2, 0xa5, 0x56, 0x9d, 0x36, 0x5d, 0x67, 0xe4,
0x0f, 0x60, 0xf3, 0x57, 0x18, 0x71, 0x32, 0x1e,
0x60, 0x3c, 0x08, 0xa9, 0x38, 0x4b, 0x11, 0x27
};
const std::string addr1 = "vxghq7uoi3m5juvfk2otmxlh4qhwb42xdbytehtahqeksoclcetq.b32.i2p";
const hash result1 = from_i2p_b32(addr1);
EXPECT_EQ(result1, expected);
EXPECT_EQ(to_i2p_b32(result1), addr1);
// Uppercase
const std::string addr2 = "VXGHQ7uoi3m5juvfk2otmxlh4qhwb42xdbytehtahqeksoclcetq.b32.i2p";
EXPECT_EQ(from_i2p_b32(addr2), expected);
// Invalid character
const std::string addr3 = "1xghq7uoi3m5juvfk2otmxlh4qhwb42xdbytehtahqeksoclcetq.b32.i2p";
EXPECT_EQ(from_i2p_b32(addr3), hash());
// Too short
EXPECT_EQ(from_i2p_b32(""), hash());
// No suffix
EXPECT_EQ(from_i2p_b32("vxghq7uoi3m5juvfk2otmxlh4qhwb42xdbytehtahqeksoclcetq"), hash());
// Too long
EXPECT_EQ(from_i2p_b32("vxghq7uoi3m5juvfk2otmxlh4qhwb42xdbytehtahqeksoclcetq2.b32.i2p"), hash());
}
} // namespace p2pool