Compare commits

..

38 Commits

Author SHA1 Message Date
SChernykh 2ed63ab3ac p2pool v3.7
C/C++ CI / build-alpine-static (map[arch:aarch64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline -mfix-cortex-a53-835769 -mfix-cortex-a53-843419]) (push) Has been cancelled
C/C++ CI / build-alpine-static (map[arch:x86_64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-11 cpp:g++-11 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-12 cpp:g++-12 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-static-libs (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:clang cxx:clang++ flags:-flto -ffunction-sections -fuse-ld=lld -Wno-unused-command-line-argument]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:gcc cxx:g++ flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:OFF vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:ON upnp:ON vs:Visual Studio 16 2019]) (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-22.04 name:freebsd version:12.4]) (push) Has been cancelled
C/C++ CI / build-openbsd (map[architecture:x86-64 host:ubuntu-22.04 name:openbsd version:7.2]) (push) Has been cancelled
clang-tidy / clang-tidy (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
cppcheck / cppcheck-ubuntu (push) Has been cancelled
cppcheck / cppcheck-windows (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
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-macos (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
2023-09-30 11:19:13 +02:00
SChernykh d99a48d87d Added a reserve domain for seed node lists 2023-09-30 08:43:29 +02:00
SChernykh 27375e7382 StratumServer: removed an unnecessary check 2023-09-29 11:55:25 +02:00
SChernykh a81d3c4989 ZMQ: fixed bind port error message 2023-09-26 19:35:30 +02:00
SChernykh b922440fc7 Refactored software id code
Show a warning when an unknown software id is seen
2023-09-23 18:04:02 +02:00
SChernykh 6ca6f2ed3d HTML: update min payout 2023-09-18 18:22:12 +02:00
SChernykh 954b9252c1 StratumServer: fixed data race in api update 2023-09-17 22:30:21 +02:00
SChernykh e355f45544 Merge pull request #278 from BadTigrou/master
Adding workers data to api
2023-09-17 21:51:32 +02:00
charlie ed32664b9e Adding workers data to api in stratum files 2023-09-17 20:09:53 +02:00
SChernykh 8619057224 Log: set locale for data output 2023-09-17 19:30:39 +02:00
SChernykh 10978c59e4 Made custom worker names safe for JSON data
And comma-separated lists too.
2023-09-17 11:32:56 +02:00
SChernykh ed56206c30 More log tests 2023-09-17 10:38:46 +02:00
SChernykh 513c2dfc3b Updated copyright 2023-09-16 22:29:32 +02:00
SChernykh 0b544bf55a API: removed file size limitation 2023-09-16 19:38:16 +02:00
SChernykh a9d39f0803 Better error messages 2023-09-13 21:37:07 +02:00
SChernykh 2248739dd5 Don't update api when shutting down 2023-09-13 21:12:01 +02:00
SChernykh b83b691714 TCPServer: cleaned up IPv4 address handling 2023-09-11 19:43:28 +02:00
SChernykh 887611c9d8 P2Pool: normalized peer list IPv4/IPv6 data 2023-09-09 20:22:43 +02:00
SChernykh 390cf0257e StratumServer: fixed data races on disconnect 2023-09-08 15:19:59 +02:00
SChernykh 2503dca0e3 Docker: updated priority node 2023-09-06 22:06:13 +02:00
SChernykh 8fd45cc977 Docker: expose port 18083 together with RPC port 2023-09-06 19:26:23 +02:00
SChernykh 8d9b9e505e Added ARM errata mitigations
Reworked #189
2023-09-06 16:32:09 +02:00
SChernykh 2453c08194 SideChain: fixed use-after-free in precalc code 2023-09-06 10:05:55 +02:00
SChernykh f149613d54 Removed unnecessary async call 2023-09-04 20:38:01 +02:00
SChernykh 2c5cfb6442 Fixed data races when using uv_async_send 2023-09-04 19:33:31 +02:00
SChernykh cfddaf1508 TCPServer: added thread check on connection close 2023-09-03 23:17:04 +02:00
SChernykh 6eff190f87 Sync test: use macOS release build settings 2023-09-03 17:56:34 +02:00
SChernykh e40c5190b1 macOS aarch64 build: disabled LTO 2023-09-03 17:45:05 +02:00
SChernykh 2584799415 TCPServer: fixed ASAN code 2023-09-03 17:13:22 +02:00
SChernykh 0463901db7 Run thread sanitizer test with static libs 2023-09-03 16:23:11 +02:00
SChernykh c2704af523 Sync test: increased countdown length 2023-09-03 14:35:12 +02:00
SChernykh 328e9cade9 SideChain: fixed read from uninitialized buffer 2023-09-03 14:16:09 +02:00
SChernykh 2b61fff449 Sync test: increase test load 2023-09-03 13:44:06 +02:00
SChernykh d8bbe2110e P2PServer: fixed a data race when banning peers 2023-09-03 13:15:45 +02:00
SChernykh 1ef88622d6 p2pool v3.6.2
C/C++ CI / build-alpine-static (map[arch:aarch64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-alpine-static (map[arch:x86_64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-11 cpp:g++-11 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-12 cpp:g++-12 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-static-libs (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:clang cxx:clang++ flags:-flto -ffunction-sections -fuse-ld=lld -Wno-unused-command-line-argument]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:gcc cxx:g++ flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:OFF vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:ON upnp:ON vs:Visual Studio 16 2019]) (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-22.04 name:freebsd version:12.4]) (push) Has been cancelled
C/C++ CI / build-openbsd (map[architecture:x86-64 host:ubuntu-22.04 name:openbsd version:7.2]) (push) Has been cancelled
clang-tidy / clang-tidy (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
cppcheck / cppcheck-ubuntu (push) Has been cancelled
cppcheck / cppcheck-windows (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
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-macos (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
2023-09-03 09:49:31 +02:00
SChernykh b1d3fb63f3 Use the old compiler for macOS-aarch64 build 2023-09-02 18:41:11 +02:00
SChernykh f44ffd1959 Sync test: rewrote stratum connection code 2023-09-01 18:20:50 +02:00
SChernykh e7545db663 Sync test: make sure stratum logs are saved 2023-09-01 17:12:22 +02:00
40 changed files with 567 additions and 212 deletions
+9 -9
View File
@@ -19,7 +19,7 @@ jobs:
matrix: matrix:
config: config:
- {arch: x86_64, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline"} - {arch: x86_64, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline"}
- {arch: aarch64, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline"} - {arch: aarch64, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline -mfix-cortex-a53-835769 -mfix-cortex-a53-843419"}
steps: steps:
- name: Setup Alpine Linux - name: Setup Alpine Linux
@@ -68,7 +68,7 @@ jobs:
run: | run: |
mkdir build mkdir build
cd build cd build
cmake .. -DCMAKE_C_FLAGS='${{ matrix.config.flags }} -Wl,-s -Wl,--gc-sections' -DCMAKE_CXX_FLAGS='${{ matrix.config.flags }} -Wl,-s -Wl,--gc-sections' -DSTATIC_BINARY=ON cmake .. -DCMAKE_C_FLAGS='${{ matrix.config.flags }} -Wl,-s -Wl,--gc-sections' -DCMAKE_CXX_FLAGS='${{ matrix.config.flags }} -Wl,-s -Wl,--gc-sections' -DSTATIC_BINARY=ON -DARCH_ID=${{ matrix.config.arch }}
make -j$(nproc) make -j$(nproc)
- name: Run RandomX tests - name: Run RandomX tests
@@ -83,7 +83,7 @@ jobs:
cd tests cd tests
mkdir build mkdir build
cd build cd build
cmake .. -DCMAKE_C_FLAGS='${{ matrix.config.flags }} -Wl,-s -Wl,--gc-sections' -DCMAKE_CXX_FLAGS='${{ matrix.config.flags }} -Wl,-s -Wl,--gc-sections' -DSTATIC_LIBS=ON cmake .. -DCMAKE_C_FLAGS='${{ matrix.config.flags }} -Wl,-s -Wl,--gc-sections' -DCMAKE_CXX_FLAGS='${{ matrix.config.flags }} -Wl,-s -Wl,--gc-sections' -DSTATIC_LIBS=ON -DARCH_ID=${{ matrix.config.arch }}
make -j$(nproc) make -j$(nproc)
- name: Run tests - name: Run tests
@@ -246,8 +246,8 @@ jobs:
strategy: strategy:
matrix: matrix:
config: config:
- {os: ubuntu-20.04, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections"} - {os: ubuntu-20.04, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419"}
- {os: ubuntu-22.04, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections"} - {os: ubuntu-22.04, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419"}
steps: steps:
- name: Install dependencies - name: Install dependencies
@@ -533,7 +533,7 @@ jobs:
- name: Build libcurl - name: Build libcurl
run: | run: |
cd external/src/curl cd external/src/curl
cmake . -DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@15)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@15)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-Os -flto -target arm64-apple-macos-11" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_ZLIB=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 -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF cmake . -DCMAKE_C_FLAGS="-Os -target arm64-apple-macos-11" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_ZLIB=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 -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF
make -j3 make -j3
cd lib && mkdir .libs && cp libcurl.a .libs cd lib && mkdir .libs && cp libcurl.a .libs
@@ -542,7 +542,7 @@ jobs:
cd external/src/libuv cd external/src/libuv
mkdir build mkdir build
cd build cd build
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@15)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@15)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -flto -target arm64-apple-macos-11' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF cmake .. -DCMAKE_C_FLAGS='-Os -target arm64-apple-macos-11' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j3 make -j3
- name: Build libzmq - name: Build libzmq
@@ -550,14 +550,14 @@ jobs:
cd external/src/libzmq cd external/src/libzmq
mkdir build mkdir build
cd build cd build
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@15)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@15)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@15)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -flto -target arm64-apple-macos-11' -DCMAKE_CXX_FLAGS='-Os -flto -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_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 make -j3
- name: Build p2pool - name: Build p2pool
run: | run: |
mkdir build mkdir build
cd build cd build
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@15)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@15)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@15)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-flto -target arm64-apple-macos-11" -DCMAKE_CXX_FLAGS="-flto -target arm64-apple-macos-11" -DSTATIC_LIBS=ON -DARCH_ID=aarch64 cmake .. -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 make -j3
- name: Archive binary - name: Archive binary
+58 -12
View File
@@ -23,18 +23,41 @@ jobs:
run: | run: |
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt update sudo apt update
sudo apt install -y git build-essential cmake libuv1-dev libzmq3-dev libsodium-dev libpgm-dev libnorm-dev libgss-dev libcurl4-openssl-dev libidn2-0-dev gcc-12 g++-12 sudo apt install -y git build-essential cmake gcc-12 g++-12
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
submodules: true submodules: true
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_C_FLAGS='-fsanitize=thread -Os -fno-omit-frame-pointer -g' -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_ZLIB=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 -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF
make -j$(nproc)
cd lib && mkdir .libs && cp libcurl.a .libs
- name: Build libuv
run: |
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_C_FLAGS='-fsanitize=thread -Os -fno-omit-frame-pointer -g' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j$(nproc)
- name: Build libzmq
run: |
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12 -DCMAKE_C_FLAGS='-fsanitize=thread -Os -fno-omit-frame-pointer -g' -DCMAKE_CXX_FLAGS='-fsanitize=thread -Os -fno-omit-frame-pointer -g' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
make -j$(nproc)
- name: Build p2pool - name: Build p2pool
run: | run: |
mkdir build mkdir build
cd build cd build
cmake .. -DDEV_TEST_SYNC=ON -DDEV_WITH_TSAN=ON -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12 -DCMAKE_C_FLAGS="-flto=2" -DCMAKE_CXX_FLAGS="-flto=2" cmake .. -DDEV_TEST_SYNC=ON -DDEV_WITH_TSAN=ON -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12 -DWITH_LTO=OFF -DSTATIC_LIBS=ON
make -j$(nproc) make -j$(nproc)
- name: Run p2pool - name: Run p2pool
@@ -44,7 +67,7 @@ jobs:
python ../tests/src/stratum_dummy.py 1 & python ../tests/src/stratum_dummy.py 1 &
python ../tests/src/stratum_dummy.py 2 & python ../tests/src/stratum_dummy.py 2 &
python ../tests/src/stratum_dummy.py 3 & python ../tests/src/stratum_dummy.py 3 &
TSAN_OPTIONS="suppressions=../tests/src/tsan_sup.txt halt_on_error=1" ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --data-api data --local-api --loglevel 6 TSAN_OPTIONS="suppressions=../tests/src/tsan_sup.txt halt_on_error=1" ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log - name: Check p2pool.log
run: | run: |
@@ -129,7 +152,7 @@ jobs:
python ../tests/src/stratum_dummy.py 1 & python ../tests/src/stratum_dummy.py 1 &
python ../tests/src/stratum_dummy.py 2 & python ../tests/src/stratum_dummy.py 2 &
python ../tests/src/stratum_dummy.py 3 & python ../tests/src/stratum_dummy.py 3 &
MSAN_OPTIONS="halt_on_error=1" ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --data-api data --local-api --loglevel 6 MSAN_OPTIONS="halt_on_error=1" ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log - name: Check p2pool.log
run: | run: |
@@ -175,7 +198,7 @@ jobs:
python ../tests/src/stratum_dummy.py 1 & python ../tests/src/stratum_dummy.py 1 &
python ../tests/src/stratum_dummy.py 2 & python ../tests/src/stratum_dummy.py 2 &
python ../tests/src/stratum_dummy.py 3 & python ../tests/src/stratum_dummy.py 3 &
UBSAN_OPTIONS="suppressions=../tests/src/ubsan_sup.txt halt_on_error=1" ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --data-api data --local-api --loglevel 6 UBSAN_OPTIONS="suppressions=../tests/src/ubsan_sup.txt halt_on_error=1" ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log - name: Check p2pool.log
run: | run: |
@@ -221,7 +244,7 @@ jobs:
python ../tests/src/stratum_dummy.py 1 & python ../tests/src/stratum_dummy.py 1 &
python ../tests/src/stratum_dummy.py 2 & python ../tests/src/stratum_dummy.py 2 &
python ../tests/src/stratum_dummy.py 3 & python ../tests/src/stratum_dummy.py 3 &
ASAN_OPTIONS="detect_stack_use_after_return=1 atexit=1" ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --data-api data --local-api --loglevel 6 ASAN_OPTIONS="detect_stack_use_after_return=1 atexit=1" ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log - name: Check p2pool.log
run: | run: |
@@ -239,7 +262,7 @@ jobs:
sync-test-macos: sync-test-macos:
timeout-minutes: 30 timeout-minutes: 30
runs-on: macos-13 runs-on: macos-11
steps: steps:
- name: Checkout repository - name: Checkout repository
@@ -249,14 +272,37 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake libuv zmq libpgm curl pyenv HOMEBREW_NO_AUTO_UPDATE=1 brew install pyenv
pyenv install 3:latest pyenv install 3:latest
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@15)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@15)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-Os -flto" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_ZLIB=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 -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF -DUSE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF -DENABLE_UNIX_SOCKETS=OFF
make -j3
cd lib && mkdir .libs && cp libcurl.a .libs
- name: Build libuv
run: |
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" -DCMAKE_AR="$(brew --prefix llvm@15)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@15)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -flto' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j3
- name: Build libzmq
run: |
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@15)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@15)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@15)/bin/llvm-ranlib" -DCMAKE_C_FLAGS='-Os -flto' -DCMAKE_CXX_FLAGS='-Os -flto' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
make -j3
- name: Build p2pool - name: Build p2pool
run: | run: |
mkdir build mkdir build
cd build cd build
cmake .. -DDEV_TEST_SYNC=ON cmake .. -DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm@15)/bin/clang++" -DCMAKE_AR="$(brew --prefix llvm@15)/bin/llvm-ar" -DCMAKE_RANLIB="$(brew --prefix llvm@15)/bin/llvm-ranlib" -DCMAKE_C_FLAGS="-flto" -DCMAKE_CXX_FLAGS="-flto" -DSTATIC_LIBS=ON -DDEV_TEST_SYNC=ON
make -j3 make -j3
- name: Run p2pool - name: Run p2pool
@@ -266,7 +312,7 @@ jobs:
python3 ../tests/src/stratum_dummy.py 1 & python3 ../tests/src/stratum_dummy.py 1 &
python3 ../tests/src/stratum_dummy.py 2 & python3 ../tests/src/stratum_dummy.py 2 &
python3 ../tests/src/stratum_dummy.py 3 & python3 ../tests/src/stratum_dummy.py 3 &
./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --data-api data --local-api --loglevel 6 ./p2pool --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log - name: Check p2pool.log
run: | run: |
@@ -309,7 +355,7 @@ jobs:
Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 1" Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 1"
Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 2" Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 2"
Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 3" Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 3"
./p2pool.exe --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --data-api data --local-api --loglevel 6 ./p2pool.exe --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log - name: Check p2pool.log
run: | run: |
@@ -352,7 +398,7 @@ jobs:
Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 1" Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 1"
Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 2" Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 2"
Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 3" Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 3"
./p2pool.exe --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --data-api data --local-api --loglevel 6 ./p2pool.exe --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log - name: Check p2pool.log
run: | run: |
+7
View File
@@ -359,3 +359,10 @@ if (STATIC_BINARY OR STATIC_LIBS)
else() else()
target_link_libraries(${CMAKE_PROJECT_NAME} debug ${ZMQ_LIBRARY_DEBUG} debug ${UV_LIBRARY_DEBUG} debug ${CURL_LIBRARY_DEBUG} optimized ${ZMQ_LIBRARY} optimized ${UV_LIBRARY} optimized ${CURL_LIBRARY} ${LIBS}) target_link_libraries(${CMAKE_PROJECT_NAME} debug ${ZMQ_LIBRARY_DEBUG} debug ${UV_LIBRARY_DEBUG} debug ${CURL_LIBRARY_DEBUG} optimized ${ZMQ_LIBRARY} optimized ${UV_LIBRARY} optimized ${CURL_LIBRARY} ${LIBS})
endif() endif()
message(STATUS "Summary of build options:
C compiler: ${CMAKE_C_COMPILER} (${CMAKE_C_COMPILER_ID})
CXX compiler: ${CMAKE_CXX_COMPILER} (${CMAKE_CXX_COMPILER_ID})
C_FLAGS: ${CMAKE_C_FLAGS}
CXX_FLAGS: ${CMAKE_CXX_FLAGS}
")
+20
View File
@@ -5,9 +5,24 @@ set(CMAKE_CXX_STANDARD 14)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
if(NOT ARCH_ID)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "")
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR})
endif()
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCH_ID)
endif()
if (ARCH_ID MATCHES "^(aarch64|arm64|armv8-a)$")
set(ARMv8 1)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES GNU) if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(GENERAL_FLAGS "-pthread") set(GENERAL_FLAGS "-pthread")
if (ARMv8)
set(GENERAL_FLAGS "${GENERAL_FLAGS} -mfix-cortex-a53-835769 -mfix-cortex-a53-843419")
endif()
if (DEV_WITH_TSAN) if (DEV_WITH_TSAN)
set(GENERAL_FLAGS "${GENERAL_FLAGS} -fno-omit-frame-pointer -fsanitize=thread") set(GENERAL_FLAGS "${GENERAL_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
endif() endif()
@@ -69,11 +84,16 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
if (WIN32) if (WIN32)
set(GENERAL_FLAGS "")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
else() else()
set(GENERAL_FLAGS "-pthread") set(GENERAL_FLAGS "-pthread")
endif() endif()
if (ARMv8)
set(GENERAL_FLAGS "${GENERAL_FLAGS} -mfix-cortex-a53-835769")
endif()
set(WARNING_FLAGS "-Wall -Wextra -Wno-undefined-internal -Wunreachable-code-aggressive -Wmissing-prototypes -Wmissing-variable-declarations -Werror") set(WARNING_FLAGS "-Wall -Wextra -Wno-undefined-internal -Wunreachable-code-aggressive -Wmissing-prototypes -Wmissing-variable-declarations -Werror")
if (DEV_WITH_MSAN) if (DEV_WITH_MSAN)
+1 -1
View File
@@ -111,7 +111,7 @@ class MoneroHelpBox(HelpBoxBase):
], ],
"Expose RPC Port": [ "Expose RPC Port": [
"Expose restricted RPC API port to your network so external services", "Expose restricted RPC API port to your network so external services",
"(wallets for example) can connect", "(wallets for example) can connect. Port 18083 (ZMQ-pub) will also be exposed.",
"Note: You may choose to open this port in your hosts firewall and/or", "Note: You may choose to open this port in your hosts firewall and/or",
" router to allow services outside your network to connect", " router to allow services outside your network to connect",
], ],
+2 -1
View File
@@ -109,6 +109,7 @@ services:
- 18080:18080/tcp - 18080:18080/tcp
{% if expose_rpc_port == True %} {% if expose_rpc_port == True %}
- {{ rpc_port }}:18081/tcp - {{ rpc_port }}:18081/tcp
- 18083:18083/tcp
{% endif %} {% endif %}
volumes: volumes:
- monero:/home/monero/.bitmonero:rw - monero:/home/monero/.bitmonero:rw
@@ -122,7 +123,7 @@ services:
--out-peers 32 --out-peers 32
--in-peers 16 --in-peers 16
--add-priority-node=nodes.hashvault.pro:18080 --add-priority-node=nodes.hashvault.pro:18080
--add-priority-node=node.supportxmr.com:18080 --add-priority-node=p2pmd.xmrvsbeast.com:18080
--non-interactive --non-interactive
--p2p-bind-ip=0.0.0.0 --p2p-bind-ip=0.0.0.0
--p2p-bind-port=18080 --p2p-bind-port=18080
+1 -1
View File
@@ -99,7 +99,7 @@ services:
--out-peers 32 --out-peers 32
--in-peers 16 --in-peers 16
--add-priority-node=nodes.hashvault.pro:18080 --add-priority-node=nodes.hashvault.pro:18080
--add-priority-node=node.supportxmr.com:18080 --add-priority-node=p2pmd.xmrvsbeast.com:18080
--non-interactive --non-interactive
--p2p-bind-ip=0.0.0.0 --p2p-bind-ip=0.0.0.0
--p2p-bind-port=18080 --p2p-bind-port=18080
+3 -1
View File
@@ -86,10 +86,12 @@ async function load_data() {
let pool_hashrate = pool_stats.pool_statistics.hashRate / 1e6; let pool_hashrate = pool_stats.pool_statistics.hashRate / 1e6;
let pplns_duration = pool_stats.pool_statistics.pplnsWeight / pool_stats.pool_statistics.hashRate; let pplns_duration = pool_stats.pool_statistics.pplnsWeight / pool_stats.pool_statistics.hashRate;
let min_payout = 0.6 * pool_stats.pool_statistics.sidechainDifficulty / pool_stats.pool_statistics.pplnsWeight;
document.getElementById("pool_hashrate").innerHTML = pool_hashrate.toFixed(3) + ' MH/s'; document.getElementById("pool_hashrate").innerHTML = pool_hashrate.toFixed(3) + ' MH/s';
document.getElementById("pplns_duration").innerHTML = elapsedTimeStr(0, pplns_duration, 0) + ' ' + Math.floor(pplns_duration % 60) + 's'; document.getElementById("pplns_duration").innerHTML = elapsedTimeStr(0, pplns_duration, 0) + ' ' + Math.floor(pplns_duration % 60) + 's';
document.getElementById("pool_miners").innerHTML = pool_stats.pool_statistics.miners; document.getElementById("pool_miners").innerHTML = pool_stats.pool_statistics.miners;
document.getElementById("min_payout").innerHTML = min_payout.toFixed(5) + ' XMR';
let ts = Math.floor(Date.now() / 1000); let ts = Math.floor(Date.now() / 1000);
@@ -208,7 +210,7 @@ function toggle_menu(name) {
<tr><td>Average effort<br><div style="text-align:center;font-size:0.9rem">last 50 blocks</div></td><td><span id="average_effort">N/A</span></td><td></td></tr> <tr><td>Average effort<br><div style="text-align:center;font-size:0.9rem">last 50 blocks</div></td><td><span id="average_effort">N/A</span></td><td></td></tr>
<tr><td>&nbsp;</td><td></td><td></td></tr> <tr><td>&nbsp;</td><td></td><td></td></tr>
<tr><td>Fee</td><td>0%</td><td></td></tr> <tr><td>Fee</td><td>0%</td><td></td></tr>
<tr><td>Min payout</td><td>0.0003 XMR</td><td></td></tr> <tr><td>Min payout</td><td><span id="min_payout">0.00027 XMR</span></td><td></td></tr>
<tr><td>Payout scheme</td><td><a href="https://en.wikipedia.org/wiki/Mining_pool#Pay-per-last-N-shares" target="_blank">PPLNS</a></td><td></td></tr> <tr><td>Payout scheme</td><td><a href="https://en.wikipedia.org/wiki/Mining_pool#Pay-per-last-N-shares" target="_blank">PPLNS</a></td><td></td></tr>
<tr><td>&nbsp;</td><td></td><td></td></tr> <tr><td>&nbsp;</td><td></td><td></td></tr>
<tr><td>Statistics</td><td><a href="https://p2pool.observer/" target="_blank">P2Pool observer</a></td><td></td></tr> <tr><td>Statistics</td><td><a href="https://p2pool.observer/" target="_blank">P2Pool observer</a></td><td></td></tr>
+3 -1
View File
@@ -86,10 +86,12 @@ async function load_data() {
let pool_hashrate = pool_stats.pool_statistics.hashRate / 1e6; let pool_hashrate = pool_stats.pool_statistics.hashRate / 1e6;
let pplns_duration = pool_stats.pool_statistics.pplnsWeight / pool_stats.pool_statistics.hashRate; let pplns_duration = pool_stats.pool_statistics.pplnsWeight / pool_stats.pool_statistics.hashRate;
let min_payout = 0.6 * pool_stats.pool_statistics.sidechainDifficulty / pool_stats.pool_statistics.pplnsWeight;
document.getElementById("pool_hashrate").innerHTML = pool_hashrate.toFixed(3) + ' MH/s'; document.getElementById("pool_hashrate").innerHTML = pool_hashrate.toFixed(3) + ' MH/s';
document.getElementById("pplns_duration").innerHTML = elapsedTimeStr(0, pplns_duration, 0) + ' ' + Math.floor(pplns_duration % 60) + 's'; document.getElementById("pplns_duration").innerHTML = elapsedTimeStr(0, pplns_duration, 0) + ' ' + Math.floor(pplns_duration % 60) + 's';
document.getElementById("pool_miners").innerHTML = pool_stats.pool_statistics.miners; document.getElementById("pool_miners").innerHTML = pool_stats.pool_statistics.miners;
document.getElementById("min_payout").innerHTML = min_payout.toFixed(5) + ' XMR';
let ts = Math.floor(Date.now() / 1000); let ts = Math.floor(Date.now() / 1000);
@@ -208,7 +210,7 @@ function toggle_menu(name) {
<tr><td>Average effort<br><div style="text-align:center;font-size:0.9rem">last 50 blocks</div></td><td><span id="average_effort">N/A</span></td><td></td></tr> <tr><td>Average effort<br><div style="text-align:center;font-size:0.9rem">last 50 blocks</div></td><td><span id="average_effort">N/A</span></td><td></td></tr>
<tr><td>&nbsp;</td><td></td><td></td></tr> <tr><td>&nbsp;</td><td></td><td></td></tr>
<tr><td>Fee</td><td>0%</td><td></td></tr> <tr><td>Fee</td><td>0%</td><td></td></tr>
<tr><td>Min payout</td><td>0.0003 XMR</td><td></td></tr> <tr><td>Min payout</td><td><span id="min_payout">0.00027 XMR</span></td><td></td></tr>
<tr><td>Payout scheme</td><td><a href="https://en.wikipedia.org/wiki/Mining_pool#Pay-per-last-N-shares" target="_blank">PPLNS</a></td><td></td></tr> <tr><td>Payout scheme</td><td><a href="https://en.wikipedia.org/wiki/Mining_pool#Pay-per-last-N-shares" target="_blank">PPLNS</a></td><td></td></tr>
<tr><td>&nbsp;</td><td></td><td></td></tr> <tr><td>&nbsp;</td><td></td><td></td></tr>
<tr><td>Statistics</td><td><a href="https://mini.p2pool.observer/" target="_blank">P2Pool observer</a></td><td></td></tr> <tr><td>Statistics</td><td><a href="https://mini.p2pool.observer/" target="_blank">P2Pool observer</a></td><td></td></tr>
+1
View File
@@ -97,6 +97,7 @@
#endif #endif
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
#define P2POOL_ASAN
#define ASAN_POISON_MEMORY_REGION(addr, size) __asan_poison_memory_region((addr), (size)) #define ASAN_POISON_MEMORY_REGION(addr, size) __asan_poison_memory_region((addr), (size))
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) __asan_unpoison_memory_region((addr), (size)) #define ASAN_UNPOISON_MEMORY_REGION(addr, size) __asan_unpoison_memory_region((addr), (size))
extern "C" void __asan_poison_memory_region(void const volatile* addr, size_t size); extern "C" void __asan_poison_memory_region(void const volatile* addr, size_t size);
+3
View File
@@ -22,6 +22,7 @@
#include <fstream> #include <fstream>
#include <thread> #include <thread>
#include <stdlib.h> #include <stdlib.h>
#include <clocale>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4996) #pragma warning(disable : 4996)
@@ -63,6 +64,8 @@ public:
{ {
set_main_thread(); set_main_thread();
std::setlocale(LC_ALL, "en_001");
m_logFile.open(log_file_name, std::ios::app | std::ios::binary); m_logFile.open(log_file_name, std::ios::app | std::ios::binary);
m_buf.resize(BUF_SIZE); m_buf.resize(BUF_SIZE);
+15 -7
View File
@@ -38,9 +38,18 @@ struct Stream
enum params : int { BUF_SIZE = 1024 - 1 }; enum params : int { BUF_SIZE = 1024 - 1 };
template<size_t N> template<size_t N>
explicit FORCEINLINE Stream(char (&buf)[N]) : m_pos(0), m_numberWidth(1), m_buf(buf), m_bufSize(N - 1) {} explicit FORCEINLINE Stream(char (&buf)[N]) : m_pos(0), m_numberWidth(1), m_buf(buf), m_bufSize(N - 1), m_spilled(0) {}
FORCEINLINE Stream(void* buf, size_t size) : m_pos(0), m_numberWidth(1), m_buf(reinterpret_cast<char*>(buf)), m_bufSize(static_cast<int>(size) - 1) {} FORCEINLINE Stream(void* buf, size_t size) { reset(buf, size); }
FORCEINLINE void reset(void* buf, size_t size)
{
m_pos = 0;
m_numberWidth = 1;
m_buf = reinterpret_cast<char*>(buf);
m_bufSize = static_cast<int>(size) - 1;
m_spilled = 0;
}
template<typename T> template<typename T>
struct Entry struct Entry
@@ -70,16 +79,13 @@ struct Stream
{ {
static_assert(1 < base && base <= 64, "Invalid base"); static_assert(1 < base && base <= 64, "Invalid base");
const T data_with_sign = data; const bool negative = is_negative(data);
data = abs(data); std::make_unsigned_t<T> udata = abs(data);
const bool negative = (data != data_with_sign);
char buf[32]; char buf[32];
size_t k = sizeof(buf); size_t k = sizeof(buf);
int w = m_numberWidth; int w = m_numberWidth;
std::make_unsigned_t<T> udata = static_cast<std::make_unsigned_t<T>>(data);
do { do {
buf[--k] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"[udata % base]; buf[--k] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"[udata % base];
udata /= base; udata /= base;
@@ -98,6 +104,7 @@ struct Stream
const int n = static_cast<int>(n0); const int n = static_cast<int>(n0);
const int pos = m_pos; const int pos = m_pos;
if (pos + n > m_bufSize) { if (pos + n > m_bufSize) {
m_spilled += n;
return; return;
} }
memcpy(m_buf + pos, buf, n); memcpy(m_buf + pos, buf, n);
@@ -111,6 +118,7 @@ struct Stream
int m_numberWidth; int m_numberWidth;
char* m_buf; char* m_buf;
int m_bufSize; int m_bufSize;
int m_spilled;
}; };
struct Writer : public Stream struct Writer : public Stream
+1 -1
View File
@@ -119,7 +119,7 @@ void Miner::on_block(const BlockTemplate& block)
m_nonceTimestamp = cur_ts; m_nonceTimestamp = cur_ts;
m_totalHashes += hash_count; m_totalHashes += hash_count;
if (m_pool->api() && m_pool->params().m_localStats) { if (m_pool->api() && m_pool->params().m_localStats && !m_pool->stopped()) {
const double block_reward_share_percent = m_pool->side_chain().get_reward_share(m_pool->params().m_wallet) * 100.0; const double block_reward_share_percent = m_pool->side_chain().get_reward_share(m_pool->params().m_wallet) * 100.0;
m_pool->api()->set(p2pool_api::Category::LOCAL, "miner", m_pool->api()->set(p2pool_api::Category::LOCAL, "miner",
+98 -67
View File
@@ -34,8 +34,8 @@
LOG_CATEGORY(P2PServer) LOG_CATEGORY(P2PServer)
static constexpr char saved_peer_list_file_name[] = "p2pool_peers.txt"; static constexpr char saved_peer_list_file_name[] = "p2pool_peers.txt";
static const char* seed_nodes[] = { "seeds.p2pool.io", ""}; static const char* seed_nodes[] = { "seeds.p2pool.io", "main.p2poolpeers.net", ""};
static const char* seed_nodes_mini[] = { "seeds-mini.p2pool.io", "" }; static const char* seed_nodes_mini[] = { "seeds-mini.p2pool.io", "mini.p2poolpeers.net", "" };
static constexpr int DEFAULT_BACKLOG = 16; static constexpr int DEFAULT_BACKLOG = 16;
static constexpr uint64_t DEFAULT_BAN_TIME = 600; static constexpr uint64_t DEFAULT_BAN_TIME = 600;
@@ -91,6 +91,7 @@ P2PServer::P2PServer(p2pool* pool)
uv_mutex_init_checked(&m_broadcastLock); uv_mutex_init_checked(&m_broadcastLock);
uv_rwlock_init_checked(&m_cachedBlocksLock); uv_rwlock_init_checked(&m_cachedBlocksLock);
uv_mutex_init_checked(&m_connectToPeersLock); uv_mutex_init_checked(&m_connectToPeersLock);
uv_mutex_init_checked(&m_showPeersLock);
int err = uv_async_init(&m_loop, &m_broadcastAsync, on_broadcast); int err = uv_async_init(&m_loop, &m_broadcastAsync, on_broadcast);
if (err) { if (err) {
@@ -149,6 +150,7 @@ P2PServer::~P2PServer()
uv_rwlock_destroy(&m_cachedBlocksLock); uv_rwlock_destroy(&m_cachedBlocksLock);
uv_mutex_destroy(&m_connectToPeersLock); uv_mutex_destroy(&m_connectToPeersLock);
uv_mutex_destroy(&m_showPeersLock);
delete m_block; delete m_block;
delete m_cache; delete m_cache;
@@ -205,13 +207,12 @@ void P2PServer::store_in_cache(const PoolBlock& block)
void P2PServer::connect_to_peers_async(const char* peer_list) void P2PServer::connect_to_peers_async(const char* peer_list)
{ {
{ MutexLock lock(m_connectToPeersLock);
MutexLock lock(m_connectToPeersLock);
if (!m_connectToPeersData.empty()) { if (!m_connectToPeersData.empty()) {
m_connectToPeersData.append(1, ','); m_connectToPeersData.append(1, ',');
}
m_connectToPeersData.append(peer_list);
} }
m_connectToPeersData.append(peer_list);
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_connectToPeersAsync))) { if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_connectToPeersAsync))) {
uv_async_send(&m_connectToPeersAsync); uv_async_send(&m_connectToPeersAsync);
@@ -460,7 +461,7 @@ void P2PServer::save_peer_list()
} }
else { else {
in_addr addr{}; in_addr addr{};
memcpy(&addr.s_addr, p.m_addr.data + 12, sizeof(addr.s_addr)); memcpy(&addr.s_addr, p.m_addr.data + sizeof(raw_ip::ipv4_prefix), sizeof(addr.s_addr));
addr_str = inet_ntop(AF_INET, &addr, addr_str_buf, sizeof(addr_str_buf)); addr_str = inet_ntop(AF_INET, &addr, addr_str_buf, sizeof(addr_str_buf));
if (addr_str) { if (addr_str) {
f << addr_str << ':' << p.m_port << '\n'; f << addr_str << ':' << p.m_port << '\n';
@@ -594,10 +595,11 @@ void P2PServer::load_peer_list()
return; return;
} }
p.m_isV6 = is_v6; p.m_isV6 = is_v6;
p.normalize();
bool already_added = false; bool already_added = false;
for (const Peer& peer : m_peerList) { for (const Peer& peer : m_peerList) {
if ((peer.m_isV6 == p.m_isV6) && (peer.m_addr == p.m_addr)) { if (peer.m_addr == p.m_addr) {
already_added = true; already_added = true;
break; break;
} }
@@ -699,10 +701,13 @@ void P2PServer::update_peer_in_list(bool is_v6, const raw_ip& ip, int port)
{ {
const uint64_t cur_time = seconds_since_epoch(); const uint64_t cur_time = seconds_since_epoch();
Peer peer{ is_v6, ip, port, 0, cur_time };
peer.normalize();
MutexLock lock(m_peerListLock); MutexLock lock(m_peerListLock);
for (Peer& p : m_peerList) { for (Peer& p : m_peerList) {
if ((p.m_isV6 == is_v6) && (p.m_addr == ip)) { if (p.m_addr == peer.m_addr) {
p.m_port = port; p.m_port = port;
p.m_numFailedConnections = 0; p.m_numFailedConnections = 0;
p.m_lastSeen = cur_time; p.m_lastSeen = cur_time;
@@ -710,8 +715,8 @@ void P2PServer::update_peer_in_list(bool is_v6, const raw_ip& ip, int port)
} }
} }
if (!is_banned(is_v6, ip)) { if (!is_banned(peer.m_isV6, peer.m_addr)) {
m_peerList.emplace_back(Peer{ is_v6, ip, port, 0, cur_time }); m_peerList.push_back(peer);
} }
} }
@@ -741,6 +746,17 @@ void P2PServer::remove_peer_from_list(const raw_ip& ip)
} }
} }
void P2PServer::Peer::normalize()
{
if (m_isV6 && m_addr.is_ipv4_prefix()) {
m_isV6 = false;
}
else if (!m_isV6) {
// Fill in default bytes for IPv4 addresses
memcpy(m_addr.data, raw_ip::ipv4_prefix, sizeof(raw_ip::ipv4_prefix));
}
}
void P2PServer::broadcast(const PoolBlock& block, const PoolBlock* parent) void P2PServer::broadcast(const PoolBlock& block, const PoolBlock* parent)
{ {
MinerData miner_data = m_pool->miner_data(); MinerData miner_data = m_pool->miner_data();
@@ -827,33 +843,21 @@ void P2PServer::broadcast(const PoolBlock& block, const PoolBlock* parent)
LOGINFO(5, "Broadcasting block " << block.m_sidechainId << " (height " << block.m_sidechainHeight << "): " << data->compact_blob.size() << '/' << data->pruned_blob.size() << '/' << data->blob.size() << " bytes (compact/pruned/full)"); LOGINFO(5, "Broadcasting block " << block.m_sidechainId << " (height " << block.m_sidechainHeight << "): " << data->compact_blob.size() << '/' << data->pruned_blob.size() << '/' << data->blob.size() << " bytes (compact/pruned/full)");
{ MutexLock lock(m_broadcastLock);
MutexLock lock(m_broadcastLock);
m_broadcastQueue.push_back(data);
}
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_broadcastAsync))) { if (uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_broadcastAsync))) {
delete data;
return; return;
} }
m_broadcastQueue.push_back(data);
const int err = uv_async_send(&m_broadcastAsync); const int err = uv_async_send(&m_broadcastAsync);
if (err) { if (err) {
LOGERR(1, "uv_async_send failed, error " << uv_err_name(err)); LOGERR(1, "uv_async_send failed, error " << uv_err_name(err));
bool found = false; m_broadcastQueue.pop_back();
{ delete data;
MutexLock lock(m_broadcastLock);
auto it = std::find(m_broadcastQueue.begin(), m_broadcastQueue.end(), data);
if (it != m_broadcastQueue.end()) {
found = true;
m_broadcastQueue.erase(it);
}
}
if (found) {
delete data;
}
} }
} }
@@ -988,6 +992,8 @@ void P2PServer::print_status()
void P2PServer::show_peers_async() void P2PServer::show_peers_async()
{ {
MutexLock lock(m_showPeersLock);
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_showPeersAsync))) { if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_showPeersAsync))) {
uv_async_send(&m_showPeersAsync); uv_async_send(&m_showPeersAsync);
} }
@@ -1218,7 +1224,7 @@ void P2PServer::check_host()
for (const PoolBlock* b = side_chain.chainTip(); b && (b->m_txinGenHeight >= height + 2); b = side_chain.find_block(b->m_parent)) { for (const PoolBlock* b = side_chain.chainTip(); b && (b->m_txinGenHeight >= height + 2); b = side_chain.find_block(b->m_parent)) {
if (--counter == 0) { if (--counter == 0) {
const Params::Host& host = m_pool->current_host(); const Params::Host& host = m_pool->current_host();
LOGERR(1, host.m_displayName << " seems to be stuck, reconnecting"); LOGERR(1, "Host " << host.m_displayName << " seems to be stuck, reconnecting");
m_pool->reconnect_to_host(); m_pool->reconnect_to_host();
return; return;
} }
@@ -1231,7 +1237,7 @@ void P2PServer::check_host()
if (cur_time >= last_active + 300) { if (cur_time >= last_active + 300) {
const uint64_t dt = static_cast<uint64_t>(cur_time - last_active); const uint64_t dt = static_cast<uint64_t>(cur_time - last_active);
const Params::Host& host = m_pool->current_host(); const Params::Host& host = m_pool->current_host();
LOGERR(1, "no ZMQ messages received from " << host.m_displayName << " in the last " << dt << " seconds, check your monerod/p2pool/network/firewall setup!!!"); LOGERR(1, "no ZMQ messages received from host " << host.m_displayName << " in the last " << dt << " seconds, check your monerod/p2pool/network/firewall setup!!!");
m_pool->reconnect_to_host(); m_pool->reconnect_to_host();
} }
} }
@@ -1266,7 +1272,7 @@ P2PServer::P2PClient::P2PClient()
, m_peerListPendingRequests(0) , m_peerListPendingRequests(0)
, m_protocolVersion(PROTOCOL_VERSION_1_0) , m_protocolVersion(PROTOCOL_VERSION_1_0)
, m_SoftwareVersion(0) , m_SoftwareVersion(0)
, m_SoftwareID(0) , m_SoftwareID(SoftwareID::P2Pool)
, m_pingTime(-1) , m_pingTime(-1)
, m_lastAlive(0) , m_lastAlive(0)
, m_lastBroadcastTimestamp(0) , m_lastBroadcastTimestamp(0)
@@ -1283,14 +1289,23 @@ void P2PServer::on_shutdown()
uv_timer_stop(&m_timer); uv_timer_stop(&m_timer);
uv_close(reinterpret_cast<uv_handle_t*>(&m_timer), nullptr); uv_close(reinterpret_cast<uv_handle_t*>(&m_timer), nullptr);
uv_close(reinterpret_cast<uv_handle_t*>(&m_broadcastAsync), nullptr); {
uv_close(reinterpret_cast<uv_handle_t*>(&m_connectToPeersAsync), nullptr); MutexLock lock(m_broadcastLock);
uv_close(reinterpret_cast<uv_handle_t*>(&m_showPeersAsync), nullptr); uv_close(reinterpret_cast<uv_handle_t*>(&m_broadcastAsync), nullptr);
}
{
MutexLock lock(m_connectToPeersLock);
uv_close(reinterpret_cast<uv_handle_t*>(&m_connectToPeersAsync), nullptr);
}
{
MutexLock lock(m_showPeersLock);
uv_close(reinterpret_cast<uv_handle_t*>(&m_showPeersAsync), nullptr);
}
} }
void P2PServer::api_update_local_stats() void P2PServer::api_update_local_stats()
{ {
if (!m_pool->api() || !m_pool->params().m_localStats || ((m_timerCounter % 30) != 5)) { if (!m_pool->api() || !m_pool->params().m_localStats || m_pool->stopped() || ((m_timerCounter % 30) != 5)) {
return; return;
} }
@@ -1299,9 +1314,15 @@ void P2PServer::api_update_local_stats()
{ {
const uint64_t cur_time = seconds_since_epoch(); const uint64_t cur_time = seconds_since_epoch();
size_t peer_list_size;
{
MutexLock lock(m_peerListLock);
peer_list_size = m_peerList.size();
}
s << "{\"connections\":" << m_numConnections.load() s << "{\"connections\":" << m_numConnections.load()
<< ",\"incoming_connections\":" << m_numIncomingConnections.load() << ",\"incoming_connections\":" << m_numIncomingConnections.load()
<< ",\"peer_list_size\":" << m_peerList.size() << ",\"peer_list_size\":" << peer_list_size
<< ",\"peers\":["; << ",\"peers\":[";
bool first = true; bool first = true;
@@ -1327,10 +1348,6 @@ void P2PServer::api_update_local_stats()
<< static_cast<char*>(client->m_addrString) << static_cast<char*>(client->m_addrString)
<< '"'; << '"';
if (s.m_pos + 128 >= s.m_bufSize) {
break;
}
first = false; first = false;
} }
} }
@@ -1368,7 +1385,7 @@ void P2PServer::P2PClient::reset()
m_peerListPendingRequests = 0; m_peerListPendingRequests = 0;
m_protocolVersion = PROTOCOL_VERSION_1_0; m_protocolVersion = PROTOCOL_VERSION_1_0;
m_SoftwareVersion = 0; m_SoftwareVersion = 0;
m_SoftwareID = 0; m_SoftwareID = SoftwareID::P2Pool;
m_pingTime = -1; m_pingTime = -1;
m_blockPendingRequests.clear(); m_blockPendingRequests.clear();
m_lastAlive = 0; m_lastAlive = 0;
@@ -2248,7 +2265,8 @@ bool P2PServer::P2PClient::on_peer_list_request(const uint8_t*)
peers[0] = {}; peers[0] = {};
*reinterpret_cast<uint32_t*>(peers[0].m_addr.data) = SUPPORTED_PROTOCOL_VERSION; *reinterpret_cast<uint32_t*>(peers[0].m_addr.data) = SUPPORTED_PROTOCOL_VERSION;
*reinterpret_cast<uint32_t*>(peers[0].m_addr.data + 4) = (P2POOL_VERSION_MAJOR << 16) | P2POOL_VERSION_MINOR; *reinterpret_cast<uint32_t*>(peers[0].m_addr.data + 4) = (P2POOL_VERSION_MAJOR << 16) | P2POOL_VERSION_MINOR;
*reinterpret_cast<uint32_t*>(peers[0].m_addr.data + 12) = 0xFFFFFFFFU; *reinterpret_cast<uint32_t*>(peers[0].m_addr.data + 8) = static_cast<uint32_t>(SoftwareID::P2Pool);
*reinterpret_cast<uint32_t*>(peers[0].m_addr.data + sizeof(raw_ip::ipv4_prefix)) = 0xFFFFFFFFU;
peers[0].m_port = 0xFFFF; peers[0].m_port = 0xFFFF;
if (num_selected_peers == 0) { if (num_selected_peers == 0) {
@@ -2317,7 +2335,7 @@ void P2PServer::P2PClient::on_peer_list_response(const uint8_t* buf)
// Ignore 0.0.0.0/8 (special-purpose range for "this network") and 224.0.0.0/3 (IP multicast and reserved ranges) // Ignore 0.0.0.0/8 (special-purpose range for "this network") and 224.0.0.0/3 (IP multicast and reserved ranges)
// Check for protocol version message // Check for protocol version message
if ((*reinterpret_cast<uint32_t*>(ip.data + 12) == 0xFFFFFFFFU) && (port == 0xFFFF)) { if ((*reinterpret_cast<uint32_t*>(ip.data + sizeof(raw_ip::ipv4_prefix)) == 0xFFFFFFFFU) && (port == 0xFFFF)) {
const uint32_t version = *reinterpret_cast<uint32_t*>(ip.data); const uint32_t version = *reinterpret_cast<uint32_t*>(ip.data);
// Clients with different major protocol versions communicate using v1.0 protocol // Clients with different major protocol versions communicate using v1.0 protocol
@@ -2330,24 +2348,30 @@ void P2PServer::P2PClient::on_peer_list_response(const uint8_t* buf)
} }
m_SoftwareVersion = *reinterpret_cast<uint32_t*>(ip.data + 4); m_SoftwareVersion = *reinterpret_cast<uint32_t*>(ip.data + 4);
m_SoftwareID = *reinterpret_cast<uint32_t*>(ip.data + 8); const uint32_t id_value = *reinterpret_cast<uint32_t*>(ip.data + 8);
m_SoftwareID = get_software_id(id_value);
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor()
<< " supports protocol version " << (m_protocolVersion >> 16) << '.' << (m_protocolVersion & 0xFFFF) << " supports protocol version " << (m_protocolVersion >> 16) << '.' << (m_protocolVersion & 0xFFFF)
<< ", runs " << software_name() << " v" << (m_SoftwareVersion >> 16) << '.' << (m_SoftwareVersion & 0xFFFF) << ", runs " << software_name() << " v" << (m_SoftwareVersion >> 16) << '.' << (m_SoftwareVersion & 0xFFFF)
); );
if (m_SoftwareID == SoftwareID::Unknown) {
LOGWARN(4, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor()
<< "runs an unknown software with id = " << log::Hex(id_value)
);
}
} }
continue; continue;
} }
// Fill in default bytes for IPv4 addresses // Fill in default bytes for IPv4 addresses
memset(ip.data, 0, 10); memcpy(ip.data, raw_ip::ipv4_prefix, sizeof(raw_ip::ipv4_prefix));
ip.data[10] = 0xFF;
ip.data[11] = 0xFF;
} }
bool already_added = false; bool already_added = false;
for (Peer& p : server->m_peerList) { for (Peer& p : server->m_peerList) {
if ((p.m_isV6 == is_v6) && (p.m_addr == ip)) { if (p.m_addr == ip) {
already_added = true; already_added = true;
p.m_lastSeen = cur_time; p.m_lastSeen = cur_time;
break; break;
@@ -2355,7 +2379,9 @@ void P2PServer::P2PClient::on_peer_list_response(const uint8_t* buf)
} }
if (!already_added && !server->is_banned(is_v6, ip)) { if (!already_added && !server->is_banned(is_v6, ip)) {
server->m_peerList.emplace_back(Peer{ is_v6, ip, port, 0, cur_time }); Peer p{ is_v6, ip, port, 0, cur_time };
p.normalize();
server->m_peerList.push_back(p);
} }
} }
} }
@@ -2474,9 +2500,10 @@ bool P2PServer::P2PClient::handle_incoming_block_async(const PoolBlock* block, u
bool client_isV6; bool client_isV6;
raw_ip client_ip; raw_ip client_ip;
std::vector<hash> missing_blocks; std::vector<hash> missing_blocks;
bool result;
}; };
Work* work = new Work{ {}, *block, this, server, m_resetCounter.load(), m_isV6, m_addr, {} }; Work* work = new Work{ {}, *block, this, server, m_resetCounter.load(), m_isV6, m_addr, {}, true };
work->req.data = work; work->req.data = work;
const int err = uv_queue_work(&server->m_loop, &work->req, const int err = uv_queue_work(&server->m_loop, &work->req,
@@ -2484,12 +2511,12 @@ bool P2PServer::P2PClient::handle_incoming_block_async(const PoolBlock* block, u
{ {
BACKGROUND_JOB_START(P2PServer::handle_incoming_block_async); BACKGROUND_JOB_START(P2PServer::handle_incoming_block_async);
Work* work = reinterpret_cast<Work*>(req->data); Work* work = reinterpret_cast<Work*>(req->data);
work->client->handle_incoming_block(work->server->m_pool, work->block, work->client_reset_counter, work->client_isV6, work->client_ip, work->missing_blocks); work->client->handle_incoming_block(work->server->m_pool, work->block, work->missing_blocks, work->result);
}, },
[](uv_work_t* req, int /*status*/) [](uv_work_t* req, int /*status*/)
{ {
Work* work = reinterpret_cast<Work*>(req->data); Work* work = reinterpret_cast<Work*>(req->data);
work->client->post_handle_incoming_block(work->block, work->client_reset_counter, work->missing_blocks); work->client->post_handle_incoming_block(work->server->m_pool, work->block, work->client_reset_counter, work->client_isV6, work->client_ip, work->missing_blocks, work->result);
delete work; delete work;
BACKGROUND_JOB_STOP(P2PServer::handle_incoming_block_async); BACKGROUND_JOB_STOP(P2PServer::handle_incoming_block_async);
}); });
@@ -2503,11 +2530,18 @@ bool P2PServer::P2PClient::handle_incoming_block_async(const PoolBlock* block, u
return true; return true;
} }
void P2PServer::P2PClient::handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, bool is_v6, const raw_ip& addr, std::vector<hash>& missing_blocks) void P2PServer::P2PClient::handle_incoming_block(p2pool* pool, PoolBlock& block, std::vector<hash>& missing_blocks, bool& result)
{ {
if (!pool->side_chain().add_external_block(block, missing_blocks)) { result = pool->side_chain().add_external_block(block, missing_blocks);
}
void P2PServer::P2PClient::post_handle_incoming_block(p2pool* pool, const PoolBlock& block, const uint32_t reset_counter, bool is_v6, const raw_ip& addr, std::vector<hash>& missing_blocks, const bool result)
{
const uint32_t new_reset_counter = m_resetCounter.load();
if (!result) {
// Client sent bad data, disconnect and ban it // Client sent bad data, disconnect and ban it
if (reset_counter == m_resetCounter.load()) { if (reset_counter == new_reset_counter) {
close(); close();
LOGWARN(3, "peer " << static_cast<char*>(m_addrString) << " banned for " << DEFAULT_BAN_TIME << " seconds"); LOGWARN(3, "peer " << static_cast<char*>(m_addrString) << " banned for " << DEFAULT_BAN_TIME << " seconds");
} }
@@ -2519,13 +2553,10 @@ void P2PServer::P2PClient::handle_incoming_block(p2pool* pool, PoolBlock& block,
server->ban(is_v6, addr, DEFAULT_BAN_TIME); server->ban(is_v6, addr, DEFAULT_BAN_TIME);
server->remove_peer_from_list(addr); server->remove_peer_from_list(addr);
} }
}
void P2PServer::P2PClient::post_handle_incoming_block(const PoolBlock& block, const uint32_t reset_counter, std::vector<hash>& missing_blocks)
{
// We might have been disconnected while side_chain was adding the block // We might have been disconnected while side_chain was adding the block
// In this case we can't send BLOCK_REQUEST messages on this connection anymore // In this case we can't send BLOCK_REQUEST messages on this connection anymore
if (reset_counter != m_resetCounter.load()) { if (reset_counter != new_reset_counter) {
return; return;
} }
@@ -2540,7 +2571,7 @@ void P2PServer::P2PClient::post_handle_incoming_block(const PoolBlock& block, co
P2PClient* c = server->m_fastestPeer; P2PClient* c = server->m_fastestPeer;
if (c && (c != this) && (c->m_broadcastMaxHeight >= block.m_sidechainHeight)) { if (c && (c != this) && (c->m_broadcastMaxHeight >= block.m_sidechainHeight)) {
LOGINFO(5, "peer " << static_cast<char*>(c->m_addrString) << " is faster, sending BLOCK_REQUEST to it instead"); LOGINFO(5, "peer " << static_cast<char*>(c->m_addrString) << " is faster, sending BLOCK_REQUEST to it instead");
c->post_handle_incoming_block(block, c->m_resetCounter.load(), missing_blocks); c->post_handle_incoming_block(pool, block, c->m_resetCounter.load(), c->m_isV6, c->m_addr, missing_blocks, true);
return; return;
} }
} }
@@ -2561,7 +2592,7 @@ void P2PServer::P2PClient::post_handle_incoming_block(const PoolBlock& block, co
continue; continue;
} }
const bool result = server->send(this, const bool send_result = server->send(this,
[this, &id](uint8_t* buf, size_t buf_size) -> size_t [this, &id](uint8_t* buf, size_t buf_size) -> size_t
{ {
LOGINFO(5, "[post_handle_incoming_block] sending BLOCK_REQUEST for id = " << id << " to " << static_cast<char*>(m_addrString)); LOGINFO(5, "[post_handle_incoming_block] sending BLOCK_REQUEST for id = " << id << " to " << static_cast<char*>(m_addrString));
@@ -2580,7 +2611,7 @@ void P2PServer::P2PClient::post_handle_incoming_block(const PoolBlock& block, co
return p - buf; return p - buf;
}); });
if (!result) { if (!send_result) {
return; return;
} }
@@ -2591,9 +2622,9 @@ void P2PServer::P2PClient::post_handle_incoming_block(const PoolBlock& block, co
const char* P2PServer::P2PClient::software_name() const const char* P2PServer::P2PClient::software_name() const
{ {
switch (m_SoftwareID) { switch (m_SoftwareID) {
case 0: case SoftwareID::P2Pool:
return "P2Pool"; return "P2Pool";
case 0x624F6F47UL: case SoftwareID::GoObserver:
return "GoObserver"; return "GoObserver";
default: default:
return "Unknown"; return "Unknown";
+6 -3
View File
@@ -115,8 +115,8 @@ public:
void on_block_notify(const uint8_t* buf); void on_block_notify(const uint8_t* buf);
bool handle_incoming_block_async(const PoolBlock* block, uint64_t max_time_delta = 0); bool handle_incoming_block_async(const PoolBlock* block, uint64_t max_time_delta = 0);
void handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, bool is_v6, const raw_ip& addr, std::vector<hash>& missing_blocks); void handle_incoming_block(p2pool* pool, PoolBlock& block, std::vector<hash>& missing_blocks, bool& result);
void post_handle_incoming_block(const PoolBlock& block, const uint32_t reset_counter, std::vector<hash>& missing_blocks); void post_handle_incoming_block(p2pool* pool, const PoolBlock& block, const uint32_t reset_counter, bool is_v6, const raw_ip& addr, std::vector<hash>& missing_blocks, const bool result);
bool is_good() const { return m_handshakeComplete && !m_handshakeInvalid && (m_listenPort >= 0); } bool is_good() const { return m_handshakeComplete && !m_handshakeInvalid && (m_listenPort >= 0); }
@@ -142,7 +142,7 @@ public:
uint32_t m_protocolVersion; uint32_t m_protocolVersion;
uint32_t m_SoftwareVersion; uint32_t m_SoftwareVersion;
uint32_t m_SoftwareID; SoftwareID m_SoftwareID;
int64_t m_pingTime; int64_t m_pingTime;
@@ -226,6 +226,8 @@ private:
struct Peer struct Peer
{ {
void normalize();
bool m_isV6; bool m_isV6;
raw_ip m_addr; raw_ip m_addr;
int m_port; int m_port;
@@ -267,6 +269,7 @@ private:
static void on_connect_to_peers(uv_async_t* handle); static void on_connect_to_peers(uv_async_t* handle);
uv_mutex_t m_showPeersLock;
uv_async_t m_showPeersAsync; uv_async_t m_showPeersAsync;
static void on_show_peers(uv_async_t* handle) { reinterpret_cast<P2PServer*>(handle->data)->show_peers(); } static void on_show_peers(uv_async_t* handle) { reinterpret_cast<P2PServer*>(handle->data)->show_peers(); }
+7 -7
View File
@@ -913,7 +913,7 @@ void p2pool::get_info()
[this, host](const char* data, size_t size, double) [this, host](const char* data, size_t size, double)
{ {
if (size > 0) { if (size > 0) {
LOGWARN(1, "get_info RPC request to " << host.m_displayName << " failed: error " << log::const_buf(data, size) << ", trying again in 1 second"); LOGWARN(1, "get_info RPC request to host " << host.m_displayName << " failed: error " << log::const_buf(data, size) << ", trying again in 1 second");
if (!m_stopped) { if (!m_stopped) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::this_thread::sleep_for(std::chrono::milliseconds(1000));
switch_host(); switch_host();
@@ -925,7 +925,7 @@ void p2pool::get_info()
void p2pool::load_found_blocks() void p2pool::load_found_blocks()
{ {
if (!m_api) { if (!m_api || m_stopped) {
return; return;
} }
@@ -1107,7 +1107,7 @@ void p2pool::get_miner_data(bool retry)
[this, host, retry](const char* data, size_t size, double) [this, host, retry](const char* data, size_t size, double)
{ {
if (size > 0) { if (size > 0) {
LOGWARN(1, "get_miner_data RPC request to " << host.m_displayName << " failed: error " << log::const_buf(data, size) << (retry ? ", trying again in 1 second" : "")); LOGWARN(1, "get_miner_data RPC request to host " << host.m_displayName << " failed: error " << log::const_buf(data, size) << (retry ? ", trying again in 1 second" : ""));
if (!m_stopped && retry) { if (!m_stopped && retry) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::this_thread::sleep_for(std::chrono::milliseconds(1000));
m_getMinerDataPending = false; m_getMinerDataPending = false;
@@ -1277,7 +1277,7 @@ uint32_t p2pool::parse_block_headers_range(const char* data, size_t size)
void p2pool::api_update_network_stats() void p2pool::api_update_network_stats()
{ {
if (!m_api) { if (!m_api || m_stopped) {
return; return;
} }
@@ -1308,7 +1308,7 @@ void p2pool::api_update_network_stats()
void p2pool::api_update_pool_stats() void p2pool::api_update_pool_stats()
{ {
if (!m_api) { if (!m_api || m_stopped) {
return; return;
} }
@@ -1360,7 +1360,7 @@ void p2pool::api_update_pool_stats()
void p2pool::api_update_stats_mod() void p2pool::api_update_stats_mod()
{ {
if (!m_api) { if (!m_api || m_stopped) {
return; return;
} }
@@ -1453,7 +1453,7 @@ void p2pool::cleanup_mainchain_data(uint64_t height)
void p2pool::api_update_block_found(const ChainMain* data, const PoolBlock* block) void p2pool::api_update_block_found(const ChainMain* data, const PoolBlock* block)
{ {
if (!m_api) { if (!m_api || m_stopped) {
return; return;
} }
+13 -5
View File
@@ -100,14 +100,24 @@ void p2pool_api::create_dir(const std::string& path)
void p2pool_api::on_stop() void p2pool_api::on_stop()
{ {
MutexLock lock(m_dumpDataLock);
uv_close(reinterpret_cast<uv_handle_t*>(&m_dumpToFileAsync), nullptr); uv_close(reinterpret_cast<uv_handle_t*>(&m_dumpToFileAsync), nullptr);
} }
void p2pool_api::dump_to_file_async_internal(Category category, const char* filename, Callback<void, log::Stream&>::Base&& callback) void p2pool_api::dump_to_file_async_internal(Category category, const char* filename, Callback<void, log::Stream&>::Base&& callback)
{ {
std::vector<char> buf(16384); std::vector<char> buf(1024);
log::Stream s(buf.data(), buf.size()); log::Stream s(buf.data(), buf.size());
callback(s); callback(s);
// If the buffer was too small, try again with big enough buffer
if (s.m_spilled) {
// Assume that the second call will use no more than 2X bytes
buf.resize((static_cast<ptrdiff_t>(s.m_pos) + s.m_spilled) * 2 + 1);
s.reset(buf.data(), buf.size());
callback(s);
}
buf.resize(s.m_pos); buf.resize(s.m_pos);
std::string path; std::string path;
@@ -119,10 +129,8 @@ void p2pool_api::dump_to_file_async_internal(Category category, const char* file
case Category::LOCAL: path = m_localPath + filename; break; case Category::LOCAL: path = m_localPath + filename; break;
} }
{ MutexLock lock(m_dumpDataLock);
MutexLock lock(m_dumpDataLock); m_dumpData[path] = std::move(buf);
m_dumpData[path] = std::move(buf);
}
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_dumpToFileAsync))) { if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_dumpToFileAsync))) {
uv_async_send(&m_dumpToFileAsync); uv_async_send(&m_dumpToFileAsync);
+2 -5
View File
@@ -396,7 +396,6 @@ RandomX_Hasher_RPC::RandomX_Hasher_RPC(p2pool* pool)
GetLoopUserData(&m_loop); GetLoopUserData(&m_loop);
uv_async_init_checked(&m_loop, &m_shutdownAsync, on_shutdown); uv_async_init_checked(&m_loop, &m_shutdownAsync, on_shutdown);
uv_async_init_checked(&m_loop, &m_kickTheLoopAsync, nullptr);
m_shutdownAsync.data = this; m_shutdownAsync.data = this;
uv_mutex_init_checked(&m_requestMutex); uv_mutex_init_checked(&m_requestMutex);
@@ -456,8 +455,8 @@ bool RandomX_Hasher_RPC::calculate(const void* data_ptr, size_t size, uint64_t h
",\"block_blob\":\"" << log::hex_buf(data, size) << '"' << ",\"block_blob\":\"" << log::hex_buf(data, size) << '"' <<
",\"seed_hash\":\"\"}}\0"; ",\"seed_hash\":\"\"}}\0";
volatile int result = 0; std::atomic<int> result{ 0 };
volatile bool done = false; std::atomic<bool> done{ false };
const Params& params = m_pool->params(); const Params& params = m_pool->params();
const Params::Host& host = m_pool->current_host(); const Params::Host& host = m_pool->current_host();
@@ -485,8 +484,6 @@ bool RandomX_Hasher_RPC::calculate(const void* data_ptr, size_t size, uint64_t h
uv_cond_signal(&m_cond); uv_cond_signal(&m_cond);
}, &m_loop); }, &m_loop);
uv_async_send(&m_kickTheLoopAsync);
{ {
MutexLock lock2(m_condMutex); MutexLock lock2(m_condMutex);
while (!done) { while (!done) {
-2
View File
@@ -115,13 +115,11 @@ private:
uv_cond_t m_cond; uv_cond_t m_cond;
uv_async_t m_shutdownAsync; uv_async_t m_shutdownAsync;
uv_async_t m_kickTheLoopAsync;
static void on_shutdown(uv_async_t* async) static void on_shutdown(uv_async_t* async)
{ {
RandomX_Hasher_RPC* server = reinterpret_cast<RandomX_Hasher_RPC*>(async->data); RandomX_Hasher_RPC* server = reinterpret_cast<RandomX_Hasher_RPC*>(async->data);
uv_close(reinterpret_cast<uv_handle_t*>(&server->m_shutdownAsync), nullptr); uv_close(reinterpret_cast<uv_handle_t*>(&server->m_shutdownAsync), nullptr);
uv_close(reinterpret_cast<uv_handle_t*>(&server->m_kickTheLoopAsync), nullptr);
delete GetLoopUserData(&server->m_loop, false); delete GetLoopUserData(&server->m_loop, false);
} }
+12 -8
View File
@@ -114,11 +114,11 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name)
constexpr char mini_config[] = "mainnet\0" "mini\0" "\0" "10\0" "100000\0" "2160\0" "20\0"; constexpr char mini_config[] = "mainnet\0" "mini\0" "\0" "10\0" "100000\0" "2160\0" "20\0";
// Hardcoded default consensus ID // Hardcoded default consensus ID
if (memcmp(buf, default_config, sizeof(default_config) - 1) == 0) { if ((s.m_pos == sizeof(default_config) - 1) && (memcmp(buf, default_config, sizeof(default_config) - 1) == 0)) {
m_consensusId.assign(default_consensus_id, default_consensus_id + HASH_SIZE); m_consensusId.assign(default_consensus_id, default_consensus_id + HASH_SIZE);
} }
// Hardcoded mini consensus ID // Hardcoded mini consensus ID
else if (memcmp(buf, mini_config, sizeof(mini_config) - 1) == 0) { else if ((s.m_pos == sizeof(mini_config) - 1) && (memcmp(buf, mini_config, sizeof(mini_config) - 1) == 0)) {
m_consensusId.assign(mini_consensus_id, mini_consensus_id + HASH_SIZE); m_consensusId.assign(mini_consensus_id, mini_consensus_id + HASH_SIZE);
} }
else { else {
@@ -2061,21 +2061,20 @@ void SideChain::prune_old_blocks()
const uint64_t h = tip->m_sidechainHeight - prune_distance; const uint64_t h = tip->m_sidechainHeight - prune_distance;
uint64_t num_blocks_pruned = 0; std::vector<PoolBlock*> blocks_to_prune;
for (auto it = m_blocksByHeight.begin(); (it != m_blocksByHeight.end()) && (it->first <= h);) { for (auto it = m_blocksByHeight.begin(); (it != m_blocksByHeight.end()) && (it->first <= h);) {
const uint64_t height = it->first; const uint64_t height = it->first;
std::vector<PoolBlock*>& v = it->second; std::vector<PoolBlock*>& v = it->second;
v.erase(std::remove_if(v.begin(), v.end(), v.erase(std::remove_if(v.begin(), v.end(),
[this, prune_distance, cur_time, prune_delay, &num_blocks_pruned, height](PoolBlock* block) [this, prune_distance, cur_time, prune_delay, &blocks_to_prune, height](PoolBlock* block)
{ {
if ((block->m_depth >= prune_distance) || (cur_time >= block->m_localTimestamp + prune_delay)) { if ((block->m_depth >= prune_distance) || (cur_time >= block->m_localTimestamp + prune_delay)) {
auto it2 = m_blocksById.find(block->m_sidechainId); auto it2 = m_blocksById.find(block->m_sidechainId);
if (it2 != m_blocksById.end()) { if (it2 != m_blocksById.end()) {
m_blocksById.erase(it2); m_blocksById.erase(it2);
delete block; blocks_to_prune.push_back(block);
++num_blocks_pruned;
} }
else { else {
LOGERR(1, "m_blocksByHeight and m_blocksById are inconsistent at height " << height << ". Fix the code!"); LOGERR(1, "m_blocksByHeight and m_blocksById are inconsistent at height " << height << ". Fix the code!");
@@ -2093,8 +2092,8 @@ void SideChain::prune_old_blocks()
} }
} }
if (num_blocks_pruned) { if (!blocks_to_prune.empty()) {
LOGINFO(4, "pruned " << num_blocks_pruned << " old blocks at heights <= " << h); LOGINFO(4, "pruned " << blocks_to_prune.size() << " old blocks at heights <= " << h);
// If side-chain started pruning blocks it means the initial sync is complete // If side-chain started pruning blocks it means the initial sync is complete
// It's now safe to delete cached blocks // It's now safe to delete cached blocks
@@ -2105,6 +2104,11 @@ void SideChain::prune_old_blocks()
// Pre-calc workers are not needed anymore // Pre-calc workers are not needed anymore
finish_precalc(); finish_precalc();
// We can only delete old blocks after the precalc is stopped because it can still use some of them
for (const PoolBlock* b : blocks_to_prune) {
delete b;
}
#ifdef DEV_TEST_SYNC #ifdef DEV_TEST_SYNC
if (m_firstPruneTime == 0) { if (m_firstPruneTime == 0) {
m_firstPruneTime = seconds_since_epoch(); m_firstPruneTime = seconds_since_epoch();
+78 -41
View File
@@ -63,6 +63,7 @@ StratumServer::StratumServer(p2pool* pool)
m_hashrateData[0] = { seconds_since_epoch(), 0 }; m_hashrateData[0] = { seconds_since_epoch(), 0 };
uv_mutex_init_checked(&m_blobsQueueLock); uv_mutex_init_checked(&m_blobsQueueLock);
uv_mutex_init_checked(&m_showWorkersLock);
uv_mutex_init_checked(&m_rngLock); uv_mutex_init_checked(&m_rngLock);
uv_rwlock_init_checked(&m_hashrateDataLock); uv_rwlock_init_checked(&m_hashrateDataLock);
@@ -91,6 +92,7 @@ StratumServer::~StratumServer()
shutdown_tcp(); shutdown_tcp();
uv_mutex_destroy(&m_blobsQueueLock); uv_mutex_destroy(&m_blobsQueueLock);
uv_mutex_destroy(&m_showWorkersLock);
uv_mutex_destroy(&m_rngLock); uv_mutex_destroy(&m_rngLock);
uv_rwlock_destroy(&m_hashrateDataLock); uv_rwlock_destroy(&m_hashrateDataLock);
@@ -161,29 +163,19 @@ void StratumServer::on_block(const BlockTemplate& block)
{ {
MutexLock lock(m_blobsQueueLock); MutexLock lock(m_blobsQueueLock);
m_blobsQueue.push_back(blobs_data);
}
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_blobsAsync))) { if (uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_blobsAsync))) {
return; delete blobs_data;
} return;
const int err = uv_async_send(&m_blobsAsync);
if (err) {
LOGERR(1, "uv_async_send failed, error " << uv_err_name(err));
bool found = false;
{
MutexLock lock(m_blobsQueueLock);
auto it = std::find(m_blobsQueue.begin(), m_blobsQueue.end(), blobs_data);
if (it != m_blobsQueue.end()) {
found = true;
m_blobsQueue.erase(it);
}
} }
if (found) { m_blobsQueue.push_back(blobs_data);
const int err = uv_async_send(&m_blobsAsync);
if (err) {
LOGERR(1, "uv_async_send failed, error " << uv_err_name(err));
m_blobsQueue.pop_back();
delete blobs_data; delete blobs_data;
} }
} }
@@ -205,8 +197,8 @@ static bool get_custom_user(const char* s, char (&user)[N])
if ((c == '+') || (c == '.')) { if ((c == '+') || (c == '.')) {
break; break;
} }
// Limit to printable ASCII characters // Limit to printable ASCII characters, also skip comma and JSON special characters
if (c >= ' ' && c <= '~') { if (c >= ' ' && c <= '~' && c != ',' && c != '"' && c != '\\') {
user[len++] = c; user[len++] = c;
} }
++s; ++s;
@@ -246,6 +238,11 @@ static bool get_custom_diff(const char* s, difficulty_type& diff)
bool StratumServer::on_login(StratumClient* client, uint32_t id, const char* login) bool StratumServer::on_login(StratumClient* client, uint32_t id, const char* login)
{ {
if (client->m_rpcId) {
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " tried to login, but it's already logged in");
return false;
}
const uint32_t extra_nonce = m_extraNonce.fetch_add(1); const uint32_t extra_nonce = m_extraNonce.fetch_add(1);
uint8_t hashing_blob[128]; uint8_t hashing_blob[128];
@@ -412,6 +409,8 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo
share->m_client = client; share->m_client = client;
share->m_clientIPv6 = client->m_isV6; share->m_clientIPv6 = client->m_isV6;
share->m_clientAddr = client->m_addr; share->m_clientAddr = client->m_addr;
memcpy(share->m_clientAddrString, client->m_addrString, sizeof(share->m_clientAddrString));
memcpy(share->m_clientCustomUser, client->m_customUser, sizeof(share->m_clientCustomUser));
share->m_clientResetCounter = client->m_resetCounter.load(); share->m_clientResetCounter = client->m_resetCounter.load();
share->m_rpcId = client->m_rpcId; share->m_rpcId = client->m_rpcId;
share->m_id = id; share->m_id = id;
@@ -487,6 +486,8 @@ void StratumServer::print_status()
void StratumServer::show_workers_async() void StratumServer::show_workers_async()
{ {
MutexLock lock(m_showWorkersLock);
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_showWorkersAsync))) { if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_showWorkersAsync))) {
uv_async_send(&m_showWorkersAsync); uv_async_send(&m_showWorkersAsync);
} }
@@ -859,7 +860,6 @@ void StratumServer::on_share_found(uv_work_t* req)
BACKGROUND_JOB_START(StratumServer::on_share_found); BACKGROUND_JOB_START(StratumServer::on_share_found);
} }
StratumClient* client = share->m_client;
p2pool* pool = server->m_pool; p2pool* pool = server->m_pool;
const uint64_t target = share->m_target; const uint64_t target = share->m_target;
@@ -879,7 +879,7 @@ void StratumServer::on_share_found(uv_work_t* req)
const uint32_t blob_size = pool->block_template().get_hashing_blob(share->m_templateId, share->m_extraNonce, blob, height, difficulty, sidechain_difficulty, seed_hash, nonce_offset); const uint32_t blob_size = pool->block_template().get_hashing_blob(share->m_templateId, share->m_extraNonce, blob, height, difficulty, sidechain_difficulty, seed_hash, nonce_offset);
if (!blob_size) { if (!blob_size) {
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " got a stale share"); LOGWARN(4, "client " << static_cast<char*>(share->m_clientAddrString) << " got a stale share");
share->m_result = SubmittedShare::Result::STALE; share->m_result = SubmittedShare::Result::STALE;
return; return;
} }
@@ -891,13 +891,13 @@ void StratumServer::on_share_found(uv_work_t* req)
hash pow_hash; hash pow_hash;
if (!pool->calculate_hash(blob, blob_size, height, seed_hash, pow_hash, false)) { if (!pool->calculate_hash(blob, blob_size, height, seed_hash, pow_hash, false)) {
LOGWARN(3, "client " << static_cast<char*>(client->m_addrString) << " couldn't check share PoW"); LOGWARN(3, "client " << static_cast<char*>(share->m_clientAddrString) << " couldn't check share PoW");
share->m_result = SubmittedShare::Result::COULDNT_CHECK_POW; share->m_result = SubmittedShare::Result::COULDNT_CHECK_POW;
return; return;
} }
if (pow_hash != share->m_resultHash) { if (pow_hash != share->m_resultHash) {
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " submitted a share with invalid PoW"); LOGWARN(4, "client " << static_cast<char*>(share->m_clientAddrString) << " submitted a share with invalid PoW");
share->m_result = SubmittedShare::Result::INVALID_POW; share->m_result = SubmittedShare::Result::INVALID_POW;
share->m_score = BAD_SHARE_POINTS; share->m_score = BAD_SHARE_POINTS;
@@ -944,7 +944,7 @@ void StratumServer::on_share_found(uv_work_t* req)
share->m_result = SubmittedShare::Result::OK; share->m_result = SubmittedShare::Result::OK;
} }
else { else {
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " got a low diff share"); LOGWARN(4, "client " << static_cast<char*>(share->m_clientAddrString) << " got a low diff share");
share->m_result = SubmittedShare::Result::LOW_DIFF; share->m_result = SubmittedShare::Result::LOW_DIFF;
share->m_score = BAD_SHARE_POINTS; share->m_score = BAD_SHARE_POINTS;
} }
@@ -953,13 +953,11 @@ void StratumServer::on_share_found(uv_work_t* req)
void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/) void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
{ {
SubmittedShare* share = reinterpret_cast<SubmittedShare*>(req->data); SubmittedShare* share = reinterpret_cast<SubmittedShare*>(req->data);
StratumClient* client = share->m_client;
client->m_score += share->m_score;
if (share->m_highEnoughDifficulty) { if (share->m_highEnoughDifficulty) {
const char* s = client->m_customUser; const char* s = share->m_clientCustomUser;
if (share->m_result == SubmittedShare::Result::OK) { if (share->m_result == SubmittedShare::Result::OK) {
LOGINFO(0, log::Green() << "SHARE FOUND: mainchain height " << share->m_mainchainHeight << ", sidechain height " << share->m_sidechainHeight << ", diff " << share->m_sidechainDifficulty << ", client " << static_cast<char*>(client->m_addrString) << (*s ? ", user " : "") << s << ", effort " << share->m_effort << '%'); LOGINFO(0, log::Green() << "SHARE FOUND: mainchain height " << share->m_mainchainHeight << ", sidechain height " << share->m_sidechainHeight << ", diff " << share->m_sidechainDifficulty << ", client " << static_cast<char*>(share->m_clientAddrString) << (*s ? ", user " : "") << s << ", effort " << share->m_effort << '%');
} }
else { else {
static const char* reason_list[] = { static const char* reason_list[] = {
@@ -973,7 +971,7 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
const size_t k = static_cast<size_t>(share->m_result); const size_t k = static_cast<size_t>(share->m_result);
const char* reason = (k < array_size(reason_list)) ? reason_list[k] : "unknown"; const char* reason = (k < array_size(reason_list)) ? reason_list[k] : "unknown";
LOGWARN(0, "INVALID SHARE: mainchain height " << share->m_mainchainHeight << ", sidechain height " << share->m_sidechainHeight << ", diff " << share->m_sidechainDifficulty << ", client " << static_cast<char*>(client->m_addrString) << (*s ? ", user " : "") << s << ", reason: " << reason); LOGWARN(0, "INVALID SHARE: mainchain height " << share->m_mainchainHeight << ", sidechain height " << share->m_sidechainHeight << ", diff " << share->m_sidechainDifficulty << ", client " << static_cast<char*>(share->m_clientAddrString) << (*s ? ", user " : "") << s << ", reason: " << reason);
} }
BACKGROUND_JOB_STOP(StratumServer::on_share_found); BACKGROUND_JOB_STOP(StratumServer::on_share_found);
} }
@@ -988,7 +986,9 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
const bool bad_share = (share->m_result == SubmittedShare::Result::LOW_DIFF) || (share->m_result == SubmittedShare::Result::INVALID_POW); const bool bad_share = (share->m_result == SubmittedShare::Result::LOW_DIFF) || (share->m_result == SubmittedShare::Result::INVALID_POW);
if ((client->m_resetCounter.load() == share->m_clientResetCounter) && (client->m_rpcId == share->m_rpcId)) { StratumClient* client = share->m_client;
if (client->m_resetCounter.load() == share->m_clientResetCounter) {
const bool result = server->send(client, const bool result = server->send(client,
[share](uint8_t* buf, size_t buf_size) [share](uint8_t* buf, size_t buf_size)
{ {
@@ -1016,6 +1016,8 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
return s.m_pos; return s.m_pos;
}); });
client->m_score += share->m_score;
if (bad_share && (client->m_score <= BAN_THRESHOLD_POINTS)) { if (bad_share && (client->m_score <= BAN_THRESHOLD_POINTS)) {
client->ban(DEFAULT_BAN_TIME); client->ban(DEFAULT_BAN_TIME);
client->close(); client->close();
@@ -1031,8 +1033,14 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
void StratumServer::on_shutdown() void StratumServer::on_shutdown()
{ {
uv_close(reinterpret_cast<uv_handle_t*>(&m_blobsAsync), nullptr); {
uv_close(reinterpret_cast<uv_handle_t*>(&m_showWorkersAsync), nullptr); MutexLock lock(m_blobsQueueLock);
uv_close(reinterpret_cast<uv_handle_t*>(&m_blobsAsync), nullptr);
}
{
MutexLock lock(m_showWorkersLock);
uv_close(reinterpret_cast<uv_handle_t*>(&m_showWorkersAsync), nullptr);
}
} }
StratumServer::StratumClient::StratumClient() StratumServer::StratumClient::StratumClient()
@@ -1266,7 +1274,7 @@ bool StratumServer::StratumClient::process_submit(rapidjson::Document& doc, uint
void StratumServer::api_update_local_stats(uint64_t timestamp) void StratumServer::api_update_local_stats(uint64_t timestamp)
{ {
if (!m_pool->api() || !m_pool->params().m_localStats) { if (!m_pool->api() || !m_pool->params().m_localStats || m_pool->stopped()) {
return; return;
} }
@@ -1329,10 +1337,9 @@ void StratumServer::api_update_local_stats(uint64_t timestamp)
const double block_reward_share_percent = m_pool->side_chain().get_reward_share(m_pool->params().m_wallet) * 100.0; const double block_reward_share_percent = m_pool->side_chain().get_reward_share(m_pool->params().m_wallet) * 100.0;
m_pool->api()->set(p2pool_api::Category::LOCAL, "stratum", CallOnLoop(&m_loop, [=]() {
[hashrate_15m, hashrate_1h, hashrate_24h, total_hashes, shares_found, shares_failed, average_effort, current_effort, connections, incoming_connections, block_reward_share_percent](log::Stream& s) m_pool->api()->set(p2pool_api::Category::LOCAL, "stratum", [=](log::Stream& s) {
{ s << "{\"hashrate_15m\":" << hashrate_15m
s << "{\"hashrate_15m\":" << hashrate_15m
<< ",\"hashrate_1h\":" << hashrate_1h << ",\"hashrate_1h\":" << hashrate_1h
<< ",\"hashrate_24h\":" << hashrate_24h << ",\"hashrate_24h\":" << hashrate_24h
<< ",\"total_hashes\":" << total_hashes << ",\"total_hashes\":" << total_hashes
@@ -1343,8 +1350,38 @@ void StratumServer::api_update_local_stats(uint64_t timestamp)
<< ",\"connections\":" << connections << ",\"connections\":" << connections
<< ",\"incoming_connections\":" << incoming_connections << ",\"incoming_connections\":" << incoming_connections
<< ",\"block_reward_share_percent\":" << block_reward_share_percent << ",\"block_reward_share_percent\":" << block_reward_share_percent
<< "}"; << ",\"workers\":[";
const difficulty_type pool_diff = m_pool->side_chain().difficulty();
bool first = true;
for (const StratumClient* client = static_cast<StratumClient*>(m_connectedClientsList->m_next); client != m_connectedClientsList; client = static_cast<StratumClient*>(client->m_next)) {
if (!first) {
s << ',';
}
difficulty_type diff = pool_diff;
if (client->m_lastJobTarget > 1) {
uint64_t r;
diff.lo = udiv128(1, 0, client->m_lastJobTarget, &r);
diff.hi = 0;
if (r) {
++diff.lo;
}
}
s << '"' << static_cast<const char*>(client->m_addrString) << ','
<< (timestamp - client->m_connectedTime) << ','
<< diff << ','
<< (client->m_autoDiff.lo / AUTO_DIFF_TARGET_TIME) << ','
<< (client->m_rpcId ? client->m_customUser : "not logged in")
<< '"';
first = false;
}
s << "]}";
}); });
});
} }
} // namespace p2pool } // namespace p2pool
+5 -1
View File
@@ -61,6 +61,7 @@ public:
enum { enum {
JOBS_SIZE = 4, JOBS_SIZE = 4,
AUTO_DIFF_SIZE = 64, AUTO_DIFF_SIZE = 64,
CUSTOM_USER_SIZE = 32,
}; };
struct SavedJob { struct SavedJob {
@@ -80,7 +81,7 @@ public:
difficulty_type m_customDiff; difficulty_type m_customDiff;
difficulty_type m_autoDiff; difficulty_type m_autoDiff;
char m_customUser[32]; char m_customUser[CUSTOM_USER_SIZE];
uint64_t m_lastJobTarget; uint64_t m_lastJobTarget;
@@ -127,6 +128,7 @@ private:
static void on_blobs_ready(uv_async_t* handle) { reinterpret_cast<StratumServer*>(handle->data)->on_blobs_ready(); } static void on_blobs_ready(uv_async_t* handle) { reinterpret_cast<StratumServer*>(handle->data)->on_blobs_ready(); }
void on_blobs_ready(); void on_blobs_ready();
uv_mutex_t m_showWorkersLock;
uv_async_t m_showWorkersAsync; uv_async_t m_showWorkersAsync;
static void on_show_workers(uv_async_t* handle) { reinterpret_cast<StratumServer*>(handle->data)->show_workers(); } static void on_show_workers(uv_async_t* handle) { reinterpret_cast<StratumServer*>(handle->data)->show_workers(); }
@@ -144,6 +146,8 @@ private:
StratumClient* m_client; StratumClient* m_client;
bool m_clientIPv6; bool m_clientIPv6;
raw_ip m_clientAddr; raw_ip m_clientAddr;
char m_clientAddrString[Client::ADDR_STRING_SIZE];
char m_clientCustomUser[StratumClient::CUSTOM_USER_SIZE];
uint32_t m_clientResetCounter; uint32_t m_clientResetCounter;
uint32_t m_rpcId; uint32_t m_rpcId;
uint32_t m_id; uint32_t m_id;
+29 -13
View File
@@ -381,7 +381,7 @@ bool TCPServer::connect_to_peer(Client* client)
else { else {
sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(&addr); sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(&addr);
addr4->sin_family = AF_INET; addr4->sin_family = AF_INET;
memcpy(&addr4->sin_addr, client->m_addr.data + 12, sizeof(in_addr)); memcpy(&addr4->sin_addr, client->m_addr.data + sizeof(raw_ip::ipv4_prefix), sizeof(in_addr));
addr4->sin_port = htons(static_cast<uint16_t>(client->m_port)); addr4->sin_port = htons(static_cast<uint16_t>(client->m_port));
} }
} }
@@ -395,7 +395,7 @@ bool TCPServer::connect_to_peer(Client* client)
else { else {
sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(&addr); sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(&addr);
addr4->sin_family = AF_INET; addr4->sin_family = AF_INET;
memcpy(&addr4->sin_addr, m_socks5ProxyIP.data + 12, sizeof(in_addr)); memcpy(&addr4->sin_addr, m_socks5ProxyIP.data + sizeof(raw_ip::ipv4_prefix), sizeof(in_addr));
addr4->sin_port = htons(static_cast<uint16_t>(m_socks5ProxyPort)); addr4->sin_port = htons(static_cast<uint16_t>(m_socks5ProxyPort));
} }
} }
@@ -419,6 +419,7 @@ void TCPServer::check_event_loop_thread(const char* func) const
{ {
if (server_event_loop_thread != this) { if (server_event_loop_thread != this) {
LOGERR(1, func << " called from another thread, this is not thread safe"); LOGERR(1, func << " called from another thread, this is not thread safe");
PANIC_STOP();
} }
} }
#endif #endif
@@ -597,8 +598,7 @@ void TCPServer::loop(void* data)
Client* c = server->m_allocateNewClient(); Client* c = server->m_allocateNewClient();
ASAN_POISON_MEMORY_REGION(wb, sizeof(WriteBuf)); ASAN_POISON_MEMORY_REGION(wb, sizeof(WriteBuf));
ASAN_POISON_MEMORY_REGION(c, c->size()); c->asan_poison_this();
ASAN_UNPOISON_MEMORY_REGION(&c->m_resetCounter, sizeof(c->m_resetCounter));
server->m_writeBuffers.emplace(capacity, wb); server->m_writeBuffers.emplace(capacity, wb);
server->m_preallocatedClients.emplace_back(c); server->m_preallocatedClients.emplace_back(c);
@@ -782,10 +782,8 @@ void TCPServer::on_new_client(uv_stream_t* server, Client* client)
client->m_port = ntohs(reinterpret_cast<sockaddr_in6*>(&peer_addr)->sin6_port); client->m_port = ntohs(reinterpret_cast<sockaddr_in6*>(&peer_addr)->sin6_port);
} }
else { else {
client->m_addr = {}; memcpy(client->m_addr.data, raw_ip::ipv4_prefix, sizeof(raw_ip::ipv4_prefix));
client->m_addr.data[10] = 0xFF; memcpy(client->m_addr.data + sizeof(raw_ip::ipv4_prefix), &reinterpret_cast<sockaddr_in*>(&peer_addr)->sin_addr, sizeof(in_addr));
client->m_addr.data[11] = 0xFF;
memcpy(client->m_addr.data + 12, &reinterpret_cast<sockaddr_in*>(&peer_addr)->sin_addr, sizeof(in_addr));
client->m_port = ntohs(reinterpret_cast<sockaddr_in*>(&peer_addr)->sin_port); client->m_port = ntohs(reinterpret_cast<sockaddr_in*>(&peer_addr)->sin_port);
} }
@@ -862,7 +860,12 @@ void TCPServer::on_shutdown(uv_async_t* async)
uv_timer_init(&s->m_loop, &s->m_shutdownTimer); uv_timer_init(&s->m_loop, &s->m_shutdownTimer);
s->m_shutdownTimer.data = s; s->m_shutdownTimer.data = s;
#ifdef DEV_TEST_SYNC
s->m_shutdownCountdown = 300;
#else
s->m_shutdownCountdown = 30; s->m_shutdownCountdown = 30;
#endif
uv_timer_start(&s->m_shutdownTimer, uv_timer_start(&s->m_shutdownTimer,
[](uv_timer_t* h) [](uv_timer_t* h)
@@ -962,8 +965,7 @@ TCPServer::Client* TCPServer::get_client()
void TCPServer::return_client(Client* c) void TCPServer::return_client(Client* c)
{ {
ASAN_POISON_MEMORY_REGION(c, c->size()); c->asan_poison_this();
ASAN_UNPOISON_MEMORY_REGION(&c->m_resetCounter, sizeof(c->m_resetCounter));
m_preallocatedClients.push_back(c); m_preallocatedClients.push_back(c);
} }
@@ -1105,7 +1107,7 @@ bool TCPServer::Client::on_proxy_handshake(char* data, uint32_t size)
} }
else { else {
buf[3] = 1; // ATYP buf[3] = 1; // ATYP
memcpy(buf + 4, m_addr.data + 12, 4); memcpy(buf + 4, m_addr.data + sizeof(raw_ip::ipv4_prefix), 4);
buf[8] = static_cast<uint8_t>(m_port >> 8); buf[8] = static_cast<uint8_t>(m_port >> 8);
buf[9] = static_cast<uint8_t>(m_port & 0xFF); buf[9] = static_cast<uint8_t>(m_port & 0xFF);
} }
@@ -1210,9 +1212,10 @@ void TCPServer::Client::close()
// Already closed // Already closed
return; return;
} }
m_isClosing = true; m_isClosing = true;
m_owner->check_event_loop_thread(__func__);
uv_read_stop(reinterpret_cast<uv_stream_t*>(&m_socket)); uv_read_stop(reinterpret_cast<uv_stream_t*>(&m_socket));
uv_tcp_t* s = &m_socket; uv_tcp_t* s = &m_socket;
@@ -1243,7 +1246,7 @@ void TCPServer::Client::init_addr_string()
addr_str = inet_ntop(AF_INET6, m_addr.data, addr_str_buf, sizeof(addr_str_buf)); addr_str = inet_ntop(AF_INET6, m_addr.data, addr_str_buf, sizeof(addr_str_buf));
} }
else { else {
addr_str = inet_ntop(AF_INET, m_addr.data + 12, addr_str_buf, sizeof(addr_str_buf)); addr_str = inet_ntop(AF_INET, m_addr.data + sizeof(raw_ip::ipv4_prefix), addr_str_buf, sizeof(addr_str_buf));
} }
if (addr_str) { if (addr_str) {
@@ -1262,4 +1265,17 @@ void TCPServer::Client::init_addr_string()
} }
} }
void TCPServer::Client::asan_poison_this() const
{
#ifdef P2POOL_ASAN
const uint8_t* begin = reinterpret_cast<const uint8_t*>(this);
const uint8_t* counter_begin = reinterpret_cast<const uint8_t*>(&m_resetCounter);
const uint8_t* counter_end = counter_begin + sizeof(m_resetCounter);
const uint8_t* end = begin + size();
ASAN_POISON_MEMORY_REGION(begin, counter_begin - begin);
ASAN_POISON_MEMORY_REGION(counter_end, end - counter_end);
#endif
}
} // namespace p2pool } // namespace p2pool
+7 -1
View File
@@ -70,6 +70,8 @@ public:
void init_addr_string(); void init_addr_string();
void asan_poison_this() const;
char* m_readBuf; char* m_readBuf;
uint32_t m_readBufSize; uint32_t m_readBufSize;
@@ -87,9 +89,13 @@ public:
bool m_isClosing; bool m_isClosing;
uint32_t m_numRead; uint32_t m_numRead;
enum {
ADDR_STRING_SIZE = 72,
};
raw_ip m_addr; raw_ip m_addr;
int m_port; int m_port;
char m_addrString[72]; char m_addrString[ADDR_STRING_SIZE];
enum class Socks5ProxyState { enum class Socks5ProxyState {
Default, Default,
+16 -4
View File
@@ -60,6 +60,20 @@ const char* VERSION = "v" STR2(P2POOL_VERSION_MAJOR) "." STR2(P2POOL_VERSION_MIN
#endif #endif
" on " __DATE__ ")"; " on " __DATE__ ")";
SoftwareID get_software_id(uint32_t value)
{
switch (value) {
case static_cast<uint32_t>(SoftwareID::P2Pool):
return SoftwareID::P2Pool;
case static_cast<uint32_t>(SoftwareID::GoObserver):
return SoftwareID::GoObserver;
default:
return SoftwareID::Unknown;
}
}
const raw_ip raw_ip::localhost_ipv4 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01 }; const raw_ip raw_ip::localhost_ipv4 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01 };
const raw_ip raw_ip::localhost_ipv6 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; const raw_ip raw_ip::localhost_ipv6 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
@@ -608,10 +622,8 @@ bool str_to_ip(bool is_v6, const char* ip, raw_ip& result)
LOGERR(1, "failed to parse IPv4 address " << ip << ", error " << uv_err_name(err)); LOGERR(1, "failed to parse IPv4 address " << ip << ", error " << uv_err_name(err));
return false; return false;
} }
result = {}; memcpy(result.data, raw_ip::ipv4_prefix, sizeof(raw_ip::ipv4_prefix));
result.data[10] = 0xFF; memcpy(result.data + sizeof(raw_ip::ipv4_prefix), &addr4->sin_addr, sizeof(in_addr));
result.data[11] = 0xFF;
memcpy(result.data + 12, &addr4->sin_addr, sizeof(in_addr));
} }
return true; return true;
+18 -4
View File
@@ -35,11 +35,19 @@
namespace p2pool { namespace p2pool {
#define P2POOL_VERSION_MAJOR 3 #define P2POOL_VERSION_MAJOR 3
#define P2POOL_VERSION_MINOR 6 #define P2POOL_VERSION_MINOR 7
#define P2POOL_VERSION_PATCH 1 #define P2POOL_VERSION_PATCH 0
extern const char* VERSION; extern const char* VERSION;
enum class SoftwareID : uint32_t {
P2Pool = 0,
GoObserver = 0x624F6F47UL,
Unknown = 0xFFFFFFFFUL,
};
SoftwareID get_software_id(uint32_t value);
template<typename T> struct not_implemented { enum { value = 0 }; }; template<typename T> struct not_implemented { enum { value = 0 }; };
struct nocopy_nomove struct nocopy_nomove
@@ -91,11 +99,17 @@ static FORCEINLINE bool from_hex(char c, T& out_value) {
return false; return false;
} }
template<typename T, bool is_signed> struct is_negative_helper {};
template<typename T> struct is_negative_helper<T, false> { static FORCEINLINE bool value(T) { return false; } };
template<typename T> struct is_negative_helper<T, true> { static FORCEINLINE bool value(T x) { return (x < 0); } };
template<typename T> FORCEINLINE bool is_negative(T x) { return is_negative_helper<T, std::is_signed<T>::value>::value(x); }
template<typename T, bool is_signed> struct abs_helper {}; template<typename T, bool is_signed> struct abs_helper {};
template<typename T> struct abs_helper<T, false> { static FORCEINLINE T value(T x) { return x; } }; template<typename T> struct abs_helper<T, false> { static FORCEINLINE T value(T x) { return x; } };
template<typename T> struct abs_helper<T, true> { static FORCEINLINE T value(T x) { return (x >= 0) ? x : -x; } }; template<typename T> struct abs_helper<T, true> { static FORCEINLINE std::make_unsigned_t<T> value(T x) { return (x < 0) ? -x : x; } };
template<typename T> FORCEINLINE T abs(T x) { return abs_helper<T, std::is_signed<T>::value>::value(x); } template<typename T> FORCEINLINE std::make_unsigned_t<T> abs(T x) { return abs_helper<T, std::is_signed<T>::value>::value(x); }
template<typename T, typename U> template<typename T, typename U>
FORCEINLINE void writeVarint(T value, U&& callback) FORCEINLINE void writeVarint(T value, U&& callback)
+1 -1
View File
@@ -51,7 +51,7 @@ ZMQReader::ZMQReader(const std::string& address, uint32_t zmq_port, const std::s
break; break;
} }
catch (const std::exception& e) { catch (const std::exception& e) {
LOGWARN(1, "failed to to bind port " << i << " for ZMQ publisher, error " << e.what()); LOGWARN(1, "failed to to bind port " << port << " for ZMQ publisher, error " << e.what());
} }
} }
+1
View File
@@ -33,6 +33,7 @@ set(SOURCES
src/difficulty_type_tests.cpp src/difficulty_type_tests.cpp
src/hash_tests.cpp src/hash_tests.cpp
src/keccak_tests.cpp src/keccak_tests.cpp
src/log_tests.cpp
src/main.cpp src/main.cpp
src/pool_block_tests.cpp src/pool_block_tests.cpp
src/util_tests.cpp src/util_tests.cpp
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
+113
View File
@@ -0,0 +1,113 @@
/*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
*
* 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 "gtest/gtest.h"
namespace p2pool {
TEST(log, stream)
{
constexpr int N = 63;
char buf[N + 1] = {};
log::Stream s(buf);
for (int iter = 0; iter < 2; ++iter) {
ASSERT_EQ(s.m_bufSize, N);
for (int i = 0; i < N; ++i) {
s << ' ';
ASSERT_EQ(s.m_pos, i + 1);
ASSERT_EQ(s.m_spilled, 0);
}
s << ' ';
ASSERT_EQ(s.m_pos, N);
ASSERT_EQ(s.m_spilled, 1);
for (int i = 0; i < N; ++i) {
ASSERT_EQ(buf[i], ' ');
}
ASSERT_EQ(buf[N], '\0');
s.reset(buf, N + 1);
}
}
TEST(log, pad_right)
{
constexpr int N = 63;
char buf[N + 1] = {};
log::Stream s(buf);
s << log::pad_right('1', N);
ASSERT_EQ(s.m_pos, N);
ASSERT_EQ(s.m_spilled, 0);
ASSERT_EQ(buf[0], '1');
for (int i = 1; i < N; ++i) {
ASSERT_EQ(buf[i], ' ');
}
ASSERT_EQ(buf[N], '\0');
}
template<typename T, bool hex>
void check_number(T value)
{
constexpr size_t N = 64;
char buf[N];
memset(buf, -1, N);
log::Stream s(buf);
s << log::BasedValue<T, hex ? 16 : 10>(value) << '\0';
char buf2[N];
memset(buf2, -1, N);
snprintf(buf2, N, hex ? "%llx" : (std::is_signed<T>::value ? "%lld" : "%llu"), value);
ASSERT_EQ(memcmp(buf, buf2, N), 0);
}
TEST(log, numbers)
{
for (int64_t i = -1024; i <= 1024; ++i) {
check_number<int64_t, false>(i);
if (i >= 0) {
check_number<int64_t, true>(i);
check_number<uint64_t, false>(i);
check_number<uint64_t, true>(i);
}
}
check_number<int64_t, false>(std::numeric_limits<int64_t>::min());
check_number<int64_t, false>(std::numeric_limits<int64_t>::max());
check_number<int64_t, true>(std::numeric_limits<int64_t>::max());
check_number<uint64_t, false>(std::numeric_limits<uint64_t>::max());
check_number<uint64_t, true>(std::numeric_limits<uint64_t>::max());
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
+28 -6
View File
@@ -1,3 +1,18 @@
# This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
# Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
#
# 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/>.
import socket import socket
import time import time
import sys import sys
@@ -5,19 +20,26 @@ import json
f = open('stratum_dummy' + sys.argv[1] + '.log', 'wb') f = open('stratum_dummy' + sys.argv[1] + '.log', 'wb')
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
sock.setblocking(True)
f.write(b'Connecting') f.write(b'Connecting')
time.sleep(5) f.flush()
while True:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
sock.setblocking(True)
if sock.connect_ex(('127.0.0.1', 3333)) == 0:
break;
sock.close()
while sock.connect_ex(('127.0.0.1', 3333)) != 0:
f.write(b'.') f.write(b'.')
f.flush()
print('.') print('.')
time.sleep(1) time.sleep(1)
f.write(b'\n') f.write(b'\n')
f.flush()
diff = '' diff = ''
-1
View File
@@ -1,4 +1,3 @@
race:p2pool::log::Worker::run() race:p2pool::log::Worker::run()
race:p2pool::log::Worker::write race:p2pool::log::Worker::write
called_from_lib:libzmq.so
race_top:do_loglevel race_top:do_loglevel
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021-2022 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool> * This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh> * Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by