Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ed63ab3ac | |||
| d99a48d87d | |||
| 27375e7382 | |||
| a81d3c4989 | |||
| b922440fc7 | |||
| 6ca6f2ed3d | |||
| 954b9252c1 | |||
| e355f45544 | |||
| ed32664b9e | |||
| 8619057224 | |||
| 10978c59e4 | |||
| ed56206c30 | |||
| 513c2dfc3b | |||
| 0b544bf55a | |||
| a9d39f0803 | |||
| 2248739dd5 | |||
| b83b691714 | |||
| 887611c9d8 | |||
| 390cf0257e | |||
| 2503dca0e3 | |||
| 8fd45cc977 | |||
| 8d9b9e505e | |||
| 2453c08194 | |||
| f149613d54 | |||
| 2c5cfb6442 | |||
| cfddaf1508 | |||
| 6eff190f87 | |||
| e40c5190b1 | |||
| 2584799415 | |||
| 0463901db7 | |||
| c2704af523 | |||
| 328e9cade9 | |||
| 2b61fff449 | |||
| d8bbe2110e | |||
| 1ef88622d6 | |||
| b1d3fb63f3 | |||
| f44ffd1959 | |||
| e7545db663 |
@@ -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
|
||||||
|
|||||||
@@ -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: |
|
||||||
|
|||||||
@@ -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}
|
||||||
|
")
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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> </td><td></td><td></td></tr>
|
<tr><td> </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> </td><td></td><td></td></tr>
|
<tr><td> </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>
|
||||||
|
|||||||
@@ -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> </td><td></td><td></td></tr>
|
<tr><td> </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> </td><td></td><td></td></tr>
|
<tr><td> </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>
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,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,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,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,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,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
|
||||||
|
|||||||
@@ -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
@@ -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,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,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,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,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,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
|
||||||
|
|||||||
Reference in New Issue
Block a user