Compare commits
41 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 | |||
| fcf9d2ad15 | |||
| 7986321a52 | |||
| 8e0f28ee30 |
+10
-10
@@ -19,7 +19,7 @@ jobs:
|
||||
matrix:
|
||||
config:
|
||||
- {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:
|
||||
- name: Setup Alpine Linux
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
run: |
|
||||
mkdir 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)
|
||||
|
||||
- name: Run RandomX tests
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
cd tests
|
||||
mkdir 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)
|
||||
|
||||
- name: Run tests
|
||||
@@ -246,8 +246,8 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- {os: ubuntu-20.04, flags: "-flto=2 -fuse-linker-plugin -ffunction-sections"}
|
||||
- {os: ubuntu-22.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 -mfix-cortex-a53-835769 -mfix-cortex-a53-843419"}
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
@@ -345,7 +345,7 @@ jobs:
|
||||
- name: Build libcurl
|
||||
run: |
|
||||
cd external/src/curl
|
||||
cmake . -G "Unix Makefiles" -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_C_FLAGS="-Os ${{ matrix.config.flags }}" -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 . -G "Unix Makefiles" -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_C_FLAGS="-Os ${{ matrix.config.flags }}" -DCURL_TARGET_WINDOWS_VERSION=0x0600 -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
|
||||
|
||||
@@ -533,7 +533,7 @@ jobs:
|
||||
- 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 -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
|
||||
cd lib && mkdir .libs && cp libcurl.a .libs
|
||||
|
||||
@@ -542,7 +542,7 @@ jobs:
|
||||
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 -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
|
||||
|
||||
- name: Build libzmq
|
||||
@@ -550,14 +550,14 @@ jobs:
|
||||
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 -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
|
||||
|
||||
- name: Build p2pool
|
||||
run: |
|
||||
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="-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
|
||||
|
||||
- name: Archive binary
|
||||
|
||||
@@ -23,18 +23,41 @@ jobs:
|
||||
run: |
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
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
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
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
|
||||
run: |
|
||||
mkdir 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)
|
||||
|
||||
- name: Run p2pool
|
||||
@@ -44,7 +67,7 @@ jobs:
|
||||
python ../tests/src/stratum_dummy.py 1 &
|
||||
python ../tests/src/stratum_dummy.py 2 &
|
||||
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
|
||||
run: |
|
||||
@@ -129,7 +152,7 @@ jobs:
|
||||
python ../tests/src/stratum_dummy.py 1 &
|
||||
python ../tests/src/stratum_dummy.py 2 &
|
||||
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
|
||||
run: |
|
||||
@@ -175,7 +198,7 @@ jobs:
|
||||
python ../tests/src/stratum_dummy.py 1 &
|
||||
python ../tests/src/stratum_dummy.py 2 &
|
||||
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
|
||||
run: |
|
||||
@@ -221,7 +244,7 @@ jobs:
|
||||
python ../tests/src/stratum_dummy.py 1 &
|
||||
python ../tests/src/stratum_dummy.py 2 &
|
||||
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
|
||||
run: |
|
||||
@@ -239,7 +262,7 @@ jobs:
|
||||
sync-test-macos:
|
||||
|
||||
timeout-minutes: 30
|
||||
runs-on: macos-13
|
||||
runs-on: macos-11
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -249,14 +272,37 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
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
|
||||
|
||||
- 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
|
||||
run: |
|
||||
mkdir 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
|
||||
|
||||
- name: Run p2pool
|
||||
@@ -266,7 +312,7 @@ jobs:
|
||||
python3 ../tests/src/stratum_dummy.py 1 &
|
||||
python3 ../tests/src/stratum_dummy.py 2 &
|
||||
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
|
||||
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 2"
|
||||
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
|
||||
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 2"
|
||||
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
|
||||
run: |
|
||||
|
||||
@@ -164,6 +164,8 @@ if (WIN32)
|
||||
set(LIBS ${LIBS} bcrypt)
|
||||
endif()
|
||||
add_definitions(-DCURL_STATICLIB)
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||
add_definitions(-D_WIN32_WINNT=0x0600)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
|
||||
set(LIBS ${LIBS} pthread)
|
||||
elseif (NOT APPLE)
|
||||
@@ -357,3 +359,10 @@ if (STATIC_BINARY OR STATIC_LIBS)
|
||||
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})
|
||||
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_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)
|
||||
set(GENERAL_FLAGS "-pthread")
|
||||
|
||||
if (ARMv8)
|
||||
set(GENERAL_FLAGS "${GENERAL_FLAGS} -mfix-cortex-a53-835769 -mfix-cortex-a53-843419")
|
||||
endif()
|
||||
|
||||
if (DEV_WITH_TSAN)
|
||||
set(GENERAL_FLAGS "${GENERAL_FLAGS} -fno-omit-frame-pointer -fsanitize=thread")
|
||||
endif()
|
||||
@@ -69,11 +84,16 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
if (WIN32)
|
||||
set(GENERAL_FLAGS "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||
else()
|
||||
set(GENERAL_FLAGS "-pthread")
|
||||
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")
|
||||
|
||||
if (DEV_WITH_MSAN)
|
||||
|
||||
@@ -111,7 +111,7 @@ class MoneroHelpBox(HelpBoxBase):
|
||||
],
|
||||
"Expose RPC Port": [
|
||||
"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",
|
||||
" router to allow services outside your network to connect",
|
||||
],
|
||||
|
||||
@@ -109,6 +109,7 @@ services:
|
||||
- 18080:18080/tcp
|
||||
{% if expose_rpc_port == True %}
|
||||
- {{ rpc_port }}:18081/tcp
|
||||
- 18083:18083/tcp
|
||||
{% endif %}
|
||||
volumes:
|
||||
- monero:/home/monero/.bitmonero:rw
|
||||
@@ -122,7 +123,7 @@ services:
|
||||
--out-peers 32
|
||||
--in-peers 16
|
||||
--add-priority-node=nodes.hashvault.pro:18080
|
||||
--add-priority-node=node.supportxmr.com:18080
|
||||
--add-priority-node=p2pmd.xmrvsbeast.com:18080
|
||||
--non-interactive
|
||||
--p2p-bind-ip=0.0.0.0
|
||||
--p2p-bind-port=18080
|
||||
|
||||
@@ -99,7 +99,7 @@ services:
|
||||
--out-peers 32
|
||||
--in-peers 16
|
||||
--add-priority-node=nodes.hashvault.pro:18080
|
||||
--add-priority-node=node.supportxmr.com:18080
|
||||
--add-priority-node=p2pmd.xmrvsbeast.com:18080
|
||||
--non-interactive
|
||||
--p2p-bind-ip=0.0.0.0
|
||||
--p2p-bind-port=18080
|
||||
|
||||
@@ -86,10 +86,12 @@ async function load_data() {
|
||||
|
||||
let pool_hashrate = pool_stats.pool_statistics.hashRate / 1e6;
|
||||
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("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("min_payout").innerHTML = min_payout.toFixed(5) + ' XMR';
|
||||
|
||||
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> </td><td></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> </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>
|
||||
|
||||
@@ -86,10 +86,12 @@ async function load_data() {
|
||||
|
||||
let pool_hashrate = pool_stats.pool_statistics.hashRate / 1e6;
|
||||
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("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("min_payout").innerHTML = min_payout.toFixed(5) + ' XMR';
|
||||
|
||||
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> </td><td></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> </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>
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+1
-1
Submodule external/src/libuv updated: 701acd5940...26d43f49ff
@@ -67,10 +67,18 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#elif defined(__linux__) || defined(__unix__) || defined(_POSIX_VERSION) || defined(__MACH__)
|
||||
@@ -89,6 +97,7 @@
|
||||
#endif
|
||||
|
||||
#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_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);
|
||||
|
||||
+53
-38
@@ -47,7 +47,41 @@ ConsoleCommands::ConsoleCommands(p2pool* pool)
|
||||
LOGINFO(3, "uv_guess_handle returned " << static_cast<int>(stdin_type));
|
||||
if (stdin_type != UV_TTY && stdin_type != UV_NAMED_PIPE) {
|
||||
LOGERR(1, "tty or named pipe is not available");
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
int err;
|
||||
|
||||
if (stdin_type == UV_TTY) {
|
||||
LOGINFO(3, "processing stdin as UV_TTY");
|
||||
err = uv_tty_init(&m_loop, &m_tty, 0, 1);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_tty_init failed, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
m_stdin_handle = reinterpret_cast<uv_stream_t*>(&m_tty);
|
||||
}
|
||||
else if (stdin_type == UV_NAMED_PIPE) {
|
||||
LOGINFO(3, "processing stdin as UV_NAMED_PIPE");
|
||||
err = uv_pipe_init(&m_loop, &m_stdin_pipe, 0);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_pipe_init failed, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
m_stdin_handle = reinterpret_cast<uv_stream_t*>(&m_stdin_pipe);
|
||||
err = uv_pipe_open(&m_stdin_pipe, 0);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_pipe_open failed, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_stdin_handle) {
|
||||
m_stdin_handle->data = this;
|
||||
err = uv_read_start(m_stdin_handle, allocCallback, stdinReadCallback);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_read_start failed, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
std::random_device rd;
|
||||
@@ -67,50 +101,29 @@ ConsoleCommands::ConsoleCommands(p2pool* pool)
|
||||
m_pool->api()->set(p2pool_api::Category::LOCAL, "console",
|
||||
[stdin_type, this](log::Stream& s)
|
||||
{
|
||||
s << "{\"mode\":" << ((stdin_type == UV_TTY) ? "\"tty\"" : "\"pipe\"")
|
||||
<< ",\"tcp_port\":" << m_listenPort
|
||||
<< "}";
|
||||
s << "{\"mode\":\"";
|
||||
|
||||
if (stdin_type == UV_TTY) {
|
||||
s << "tty";
|
||||
}
|
||||
else if (stdin_type == UV_NAMED_PIPE) {
|
||||
s << "pipe";
|
||||
}
|
||||
else {
|
||||
s << static_cast<int>(stdin_type);
|
||||
}
|
||||
|
||||
s << "\",\"tcp_port\":" << m_listenPort << '}';
|
||||
});
|
||||
}
|
||||
|
||||
int err;
|
||||
|
||||
if (stdin_type == UV_TTY) {
|
||||
LOGINFO(3, "processing stdin as UV_TTY");
|
||||
err = uv_tty_init(&m_loop, &m_tty, 0, 1);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_tty_init failed, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
m_stdin_handle = reinterpret_cast<uv_stream_t*>(&m_tty);
|
||||
}
|
||||
else {
|
||||
LOGINFO(3, "processing stdin as UV_NAMED_PIPE");
|
||||
err = uv_pipe_init(&m_loop, &m_stdin_pipe, 0);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_pipe_init failed, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
m_stdin_handle = reinterpret_cast<uv_stream_t*>(&m_stdin_pipe);
|
||||
err = uv_pipe_open(&m_stdin_pipe, 0);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_pipe_open failed, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
m_stdin_handle->data = this;
|
||||
|
||||
err = uv_read_start(m_stdin_handle, allocCallback, stdinReadCallback);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_read_start failed, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
err = uv_thread_create(&m_loopThread, loop, this);
|
||||
if (err) {
|
||||
LOGERR(1, "failed to start event loop thread, error " << uv_err_name(err));
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
m_loopThreadCreated = true;
|
||||
}
|
||||
|
||||
ConsoleCommands::~ConsoleCommands()
|
||||
@@ -120,7 +133,9 @@ ConsoleCommands::~ConsoleCommands()
|
||||
|
||||
void ConsoleCommands::on_shutdown()
|
||||
{
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_stdin_handle), nullptr);
|
||||
if (m_stdin_handle) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_stdin_handle), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
const char* ConsoleCommands::get_log_category() const
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include <stdlib.h>
|
||||
#include <clocale>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4996)
|
||||
@@ -63,6 +64,8 @@ public:
|
||||
{
|
||||
set_main_thread();
|
||||
|
||||
std::setlocale(LC_ALL, "en_001");
|
||||
|
||||
m_logFile.open(log_file_name, std::ios::app | std::ios::binary);
|
||||
|
||||
m_buf.resize(BUF_SIZE);
|
||||
|
||||
@@ -38,9 +38,18 @@ struct Stream
|
||||
enum params : int { BUF_SIZE = 1024 - 1 };
|
||||
|
||||
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>
|
||||
struct Entry
|
||||
@@ -70,16 +79,13 @@ struct Stream
|
||||
{
|
||||
static_assert(1 < base && base <= 64, "Invalid base");
|
||||
|
||||
const T data_with_sign = data;
|
||||
data = abs(data);
|
||||
const bool negative = (data != data_with_sign);
|
||||
const bool negative = is_negative(data);
|
||||
std::make_unsigned_t<T> udata = abs(data);
|
||||
|
||||
char buf[32];
|
||||
size_t k = sizeof(buf);
|
||||
int w = m_numberWidth;
|
||||
|
||||
std::make_unsigned_t<T> udata = static_cast<std::make_unsigned_t<T>>(data);
|
||||
|
||||
do {
|
||||
buf[--k] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"[udata % base];
|
||||
udata /= base;
|
||||
@@ -98,6 +104,7 @@ struct Stream
|
||||
const int n = static_cast<int>(n0);
|
||||
const int pos = m_pos;
|
||||
if (pos + n > m_bufSize) {
|
||||
m_spilled += n;
|
||||
return;
|
||||
}
|
||||
memcpy(m_buf + pos, buf, n);
|
||||
@@ -111,6 +118,7 @@ struct Stream
|
||||
int m_numberWidth;
|
||||
char* m_buf;
|
||||
int m_bufSize;
|
||||
int m_spilled;
|
||||
};
|
||||
|
||||
struct Writer : public Stream
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ void Miner::on_block(const BlockTemplate& block)
|
||||
m_nonceTimestamp = cur_ts;
|
||||
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;
|
||||
|
||||
m_pool->api()->set(p2pool_api::Category::LOCAL, "miner",
|
||||
|
||||
+98
-67
@@ -34,8 +34,8 @@
|
||||
LOG_CATEGORY(P2PServer)
|
||||
|
||||
static constexpr char saved_peer_list_file_name[] = "p2pool_peers.txt";
|
||||
static const char* seed_nodes[] = { "seeds.p2pool.io", ""};
|
||||
static const char* seed_nodes_mini[] = { "seeds-mini.p2pool.io", "" };
|
||||
static const char* seed_nodes[] = { "seeds.p2pool.io", "main.p2poolpeers.net", ""};
|
||||
static const char* seed_nodes_mini[] = { "seeds-mini.p2pool.io", "mini.p2poolpeers.net", "" };
|
||||
|
||||
static constexpr int DEFAULT_BACKLOG = 16;
|
||||
static constexpr uint64_t DEFAULT_BAN_TIME = 600;
|
||||
@@ -91,6 +91,7 @@ P2PServer::P2PServer(p2pool* pool)
|
||||
uv_mutex_init_checked(&m_broadcastLock);
|
||||
uv_rwlock_init_checked(&m_cachedBlocksLock);
|
||||
uv_mutex_init_checked(&m_connectToPeersLock);
|
||||
uv_mutex_init_checked(&m_showPeersLock);
|
||||
|
||||
int err = uv_async_init(&m_loop, &m_broadcastAsync, on_broadcast);
|
||||
if (err) {
|
||||
@@ -149,6 +150,7 @@ P2PServer::~P2PServer()
|
||||
uv_rwlock_destroy(&m_cachedBlocksLock);
|
||||
|
||||
uv_mutex_destroy(&m_connectToPeersLock);
|
||||
uv_mutex_destroy(&m_showPeersLock);
|
||||
|
||||
delete m_block;
|
||||
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)
|
||||
{
|
||||
{
|
||||
MutexLock lock(m_connectToPeersLock);
|
||||
if (!m_connectToPeersData.empty()) {
|
||||
m_connectToPeersData.append(1, ',');
|
||||
}
|
||||
m_connectToPeersData.append(peer_list);
|
||||
MutexLock lock(m_connectToPeersLock);
|
||||
|
||||
if (!m_connectToPeersData.empty()) {
|
||||
m_connectToPeersData.append(1, ',');
|
||||
}
|
||||
m_connectToPeersData.append(peer_list);
|
||||
|
||||
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_connectToPeersAsync))) {
|
||||
uv_async_send(&m_connectToPeersAsync);
|
||||
@@ -460,7 +461,7 @@ void P2PServer::save_peer_list()
|
||||
}
|
||||
else {
|
||||
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));
|
||||
if (addr_str) {
|
||||
f << addr_str << ':' << p.m_port << '\n';
|
||||
@@ -594,10 +595,11 @@ void P2PServer::load_peer_list()
|
||||
return;
|
||||
}
|
||||
p.m_isV6 = is_v6;
|
||||
p.normalize();
|
||||
|
||||
bool already_added = false;
|
||||
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;
|
||||
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();
|
||||
|
||||
Peer peer{ is_v6, ip, port, 0, cur_time };
|
||||
peer.normalize();
|
||||
|
||||
MutexLock lock(m_peerListLock);
|
||||
|
||||
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_numFailedConnections = 0;
|
||||
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)) {
|
||||
m_peerList.emplace_back(Peer{ is_v6, ip, port, 0, cur_time });
|
||||
if (!is_banned(peer.m_isV6, peer.m_addr)) {
|
||||
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)
|
||||
{
|
||||
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)");
|
||||
|
||||
{
|
||||
MutexLock lock(m_broadcastLock);
|
||||
m_broadcastQueue.push_back(data);
|
||||
}
|
||||
MutexLock lock(m_broadcastLock);
|
||||
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_broadcastAsync))) {
|
||||
delete data;
|
||||
return;
|
||||
}
|
||||
|
||||
m_broadcastQueue.push_back(data);
|
||||
|
||||
const int err = uv_async_send(&m_broadcastAsync);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_async_send failed, error " << uv_err_name(err));
|
||||
|
||||
bool found = false;
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_broadcastQueue.pop_back();
|
||||
delete data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,6 +992,8 @@ void P2PServer::print_status()
|
||||
|
||||
void P2PServer::show_peers_async()
|
||||
{
|
||||
MutexLock lock(m_showPeersLock);
|
||||
|
||||
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&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)) {
|
||||
if (--counter == 0) {
|
||||
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();
|
||||
return;
|
||||
}
|
||||
@@ -1231,7 +1237,7 @@ void P2PServer::check_host()
|
||||
if (cur_time >= last_active + 300) {
|
||||
const uint64_t dt = static_cast<uint64_t>(cur_time - last_active);
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1266,7 +1272,7 @@ P2PServer::P2PClient::P2PClient()
|
||||
, m_peerListPendingRequests(0)
|
||||
, m_protocolVersion(PROTOCOL_VERSION_1_0)
|
||||
, m_SoftwareVersion(0)
|
||||
, m_SoftwareID(0)
|
||||
, m_SoftwareID(SoftwareID::P2Pool)
|
||||
, m_pingTime(-1)
|
||||
, m_lastAlive(0)
|
||||
, m_lastBroadcastTimestamp(0)
|
||||
@@ -1283,14 +1289,23 @@ void P2PServer::on_shutdown()
|
||||
|
||||
uv_timer_stop(&m_timer);
|
||||
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);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(&m_showPeersAsync), nullptr);
|
||||
{
|
||||
MutexLock lock(m_broadcastLock);
|
||||
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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1299,9 +1314,15 @@ void P2PServer::api_update_local_stats()
|
||||
{
|
||||
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()
|
||||
<< ",\"incoming_connections\":" << m_numIncomingConnections.load()
|
||||
<< ",\"peer_list_size\":" << m_peerList.size()
|
||||
<< ",\"peer_list_size\":" << peer_list_size
|
||||
<< ",\"peers\":[";
|
||||
|
||||
bool first = true;
|
||||
@@ -1327,10 +1348,6 @@ void P2PServer::api_update_local_stats()
|
||||
<< static_cast<char*>(client->m_addrString)
|
||||
<< '"';
|
||||
|
||||
if (s.m_pos + 128 >= s.m_bufSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
@@ -1368,7 +1385,7 @@ void P2PServer::P2PClient::reset()
|
||||
m_peerListPendingRequests = 0;
|
||||
m_protocolVersion = PROTOCOL_VERSION_1_0;
|
||||
m_SoftwareVersion = 0;
|
||||
m_SoftwareID = 0;
|
||||
m_SoftwareID = SoftwareID::P2Pool;
|
||||
m_pingTime = -1;
|
||||
m_blockPendingRequests.clear();
|
||||
m_lastAlive = 0;
|
||||
@@ -2248,7 +2265,8 @@ bool P2PServer::P2PClient::on_peer_list_request(const uint8_t*)
|
||||
peers[0] = {};
|
||||
*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 + 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;
|
||||
|
||||
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)
|
||||
|
||||
// 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);
|
||||
|
||||
// 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_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()
|
||||
<< " supports protocol version " << (m_protocolVersion >> 16) << '.' << (m_protocolVersion & 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;
|
||||
}
|
||||
|
||||
// Fill in default bytes for IPv4 addresses
|
||||
memset(ip.data, 0, 10);
|
||||
ip.data[10] = 0xFF;
|
||||
ip.data[11] = 0xFF;
|
||||
memcpy(ip.data, raw_ip::ipv4_prefix, sizeof(raw_ip::ipv4_prefix));
|
||||
}
|
||||
|
||||
bool already_added = false;
|
||||
for (Peer& p : server->m_peerList) {
|
||||
if ((p.m_isV6 == is_v6) && (p.m_addr == ip)) {
|
||||
if (p.m_addr == ip) {
|
||||
already_added = true;
|
||||
p.m_lastSeen = cur_time;
|
||||
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)) {
|
||||
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;
|
||||
raw_ip client_ip;
|
||||
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;
|
||||
|
||||
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);
|
||||
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*/)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
if (reset_counter == m_resetCounter.load()) {
|
||||
if (reset_counter == new_reset_counter) {
|
||||
close();
|
||||
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->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
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -2540,7 +2571,7 @@ void P2PServer::P2PClient::post_handle_incoming_block(const PoolBlock& block, co
|
||||
P2PClient* c = server->m_fastestPeer;
|
||||
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");
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -2561,7 +2592,7 @@ void P2PServer::P2PClient::post_handle_incoming_block(const PoolBlock& block, co
|
||||
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
|
||||
{
|
||||
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;
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
if (!send_result) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2591,9 +2622,9 @@ void P2PServer::P2PClient::post_handle_incoming_block(const PoolBlock& block, co
|
||||
const char* P2PServer::P2PClient::software_name() const
|
||||
{
|
||||
switch (m_SoftwareID) {
|
||||
case 0:
|
||||
case SoftwareID::P2Pool:
|
||||
return "P2Pool";
|
||||
case 0x624F6F47UL:
|
||||
case SoftwareID::GoObserver:
|
||||
return "GoObserver";
|
||||
default:
|
||||
return "Unknown";
|
||||
|
||||
+6
-3
@@ -115,8 +115,8 @@ public:
|
||||
void on_block_notify(const uint8_t* buf);
|
||||
|
||||
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 post_handle_incoming_block(const PoolBlock& block, const uint32_t reset_counter, 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(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); }
|
||||
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
|
||||
uint32_t m_protocolVersion;
|
||||
uint32_t m_SoftwareVersion;
|
||||
uint32_t m_SoftwareID;
|
||||
SoftwareID m_SoftwareID;
|
||||
|
||||
int64_t m_pingTime;
|
||||
|
||||
@@ -226,6 +226,8 @@ private:
|
||||
|
||||
struct Peer
|
||||
{
|
||||
void normalize();
|
||||
|
||||
bool m_isV6;
|
||||
raw_ip m_addr;
|
||||
int m_port;
|
||||
@@ -267,6 +269,7 @@ private:
|
||||
|
||||
static void on_connect_to_peers(uv_async_t* handle);
|
||||
|
||||
uv_mutex_t m_showPeersLock;
|
||||
uv_async_t m_showPeersAsync;
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
switch_host();
|
||||
@@ -925,7 +925,7 @@ void p2pool::get_info()
|
||||
|
||||
void p2pool::load_found_blocks()
|
||||
{
|
||||
if (!m_api) {
|
||||
if (!m_api || m_stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1107,7 +1107,7 @@ void p2pool::get_miner_data(bool retry)
|
||||
[this, host, retry](const char* data, size_t size, double)
|
||||
{
|
||||
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) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
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()
|
||||
{
|
||||
if (!m_api) {
|
||||
if (!m_api || m_stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1308,7 +1308,7 @@ void p2pool::api_update_network_stats()
|
||||
|
||||
void p2pool::api_update_pool_stats()
|
||||
{
|
||||
if (!m_api) {
|
||||
if (!m_api || m_stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1360,7 +1360,7 @@ void p2pool::api_update_pool_stats()
|
||||
|
||||
void p2pool::api_update_stats_mod()
|
||||
{
|
||||
if (!m_api) {
|
||||
if (!m_api || m_stopped) {
|
||||
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)
|
||||
{
|
||||
if (!m_api) {
|
||||
if (!m_api || m_stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+13
-5
@@ -100,14 +100,24 @@ void p2pool_api::create_dir(const std::string& path)
|
||||
|
||||
void p2pool_api::on_stop()
|
||||
{
|
||||
MutexLock lock(m_dumpDataLock);
|
||||
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)
|
||||
{
|
||||
std::vector<char> buf(16384);
|
||||
std::vector<char> buf(1024);
|
||||
log::Stream s(buf.data(), buf.size());
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
{
|
||||
MutexLock lock(m_dumpDataLock);
|
||||
m_dumpData[path] = std::move(buf);
|
||||
}
|
||||
MutexLock lock(m_dumpDataLock);
|
||||
m_dumpData[path] = std::move(buf);
|
||||
|
||||
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_dumpToFileAsync))) {
|
||||
uv_async_send(&m_dumpToFileAsync);
|
||||
|
||||
+2
-5
@@ -396,7 +396,6 @@ RandomX_Hasher_RPC::RandomX_Hasher_RPC(p2pool* pool)
|
||||
GetLoopUserData(&m_loop);
|
||||
|
||||
uv_async_init_checked(&m_loop, &m_shutdownAsync, on_shutdown);
|
||||
uv_async_init_checked(&m_loop, &m_kickTheLoopAsync, nullptr);
|
||||
m_shutdownAsync.data = this;
|
||||
|
||||
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) << '"' <<
|
||||
",\"seed_hash\":\"\"}}\0";
|
||||
|
||||
volatile int result = 0;
|
||||
volatile bool done = false;
|
||||
std::atomic<int> result{ 0 };
|
||||
std::atomic<bool> done{ false };
|
||||
|
||||
const Params& params = m_pool->params();
|
||||
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);
|
||||
}, &m_loop);
|
||||
|
||||
uv_async_send(&m_kickTheLoopAsync);
|
||||
|
||||
{
|
||||
MutexLock lock2(m_condMutex);
|
||||
while (!done) {
|
||||
|
||||
@@ -115,13 +115,11 @@ private:
|
||||
uv_cond_t m_cond;
|
||||
|
||||
uv_async_t m_shutdownAsync;
|
||||
uv_async_t m_kickTheLoopAsync;
|
||||
|
||||
static void on_shutdown(uv_async_t* async)
|
||||
{
|
||||
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_kickTheLoopAsync), nullptr);
|
||||
|
||||
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";
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
else {
|
||||
@@ -2061,21 +2061,20 @@ void SideChain::prune_old_blocks()
|
||||
|
||||
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);) {
|
||||
const uint64_t height = it->first;
|
||||
std::vector<PoolBlock*>& v = it->second;
|
||||
|
||||
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)) {
|
||||
auto it2 = m_blocksById.find(block->m_sidechainId);
|
||||
if (it2 != m_blocksById.end()) {
|
||||
m_blocksById.erase(it2);
|
||||
delete block;
|
||||
++num_blocks_pruned;
|
||||
blocks_to_prune.push_back(block);
|
||||
}
|
||||
else {
|
||||
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) {
|
||||
LOGINFO(4, "pruned " << num_blocks_pruned << " old blocks at heights <= " << h);
|
||||
if (!blocks_to_prune.empty()) {
|
||||
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
|
||||
// It's now safe to delete cached blocks
|
||||
@@ -2105,6 +2104,11 @@ void SideChain::prune_old_blocks()
|
||||
// Pre-calc workers are not needed anymore
|
||||
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
|
||||
if (m_firstPruneTime == 0) {
|
||||
m_firstPruneTime = seconds_since_epoch();
|
||||
|
||||
+78
-41
@@ -63,6 +63,7 @@ StratumServer::StratumServer(p2pool* pool)
|
||||
m_hashrateData[0] = { seconds_since_epoch(), 0 };
|
||||
|
||||
uv_mutex_init_checked(&m_blobsQueueLock);
|
||||
uv_mutex_init_checked(&m_showWorkersLock);
|
||||
uv_mutex_init_checked(&m_rngLock);
|
||||
uv_rwlock_init_checked(&m_hashrateDataLock);
|
||||
|
||||
@@ -91,6 +92,7 @@ StratumServer::~StratumServer()
|
||||
shutdown_tcp();
|
||||
|
||||
uv_mutex_destroy(&m_blobsQueueLock);
|
||||
uv_mutex_destroy(&m_showWorkersLock);
|
||||
uv_mutex_destroy(&m_rngLock);
|
||||
uv_rwlock_destroy(&m_hashrateDataLock);
|
||||
|
||||
@@ -161,29 +163,19 @@ void StratumServer::on_block(const BlockTemplate& block)
|
||||
|
||||
{
|
||||
MutexLock lock(m_blobsQueueLock);
|
||||
m_blobsQueue.push_back(blobs_data);
|
||||
}
|
||||
|
||||
if (uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_blobsAsync))) {
|
||||
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 (uv_is_closing(reinterpret_cast<uv_handle_t*>(&m_blobsAsync))) {
|
||||
delete blobs_data;
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -205,8 +197,8 @@ static bool get_custom_user(const char* s, char (&user)[N])
|
||||
if ((c == '+') || (c == '.')) {
|
||||
break;
|
||||
}
|
||||
// Limit to printable ASCII characters
|
||||
if (c >= ' ' && c <= '~') {
|
||||
// Limit to printable ASCII characters, also skip comma and JSON special characters
|
||||
if (c >= ' ' && c <= '~' && c != ',' && c != '"' && c != '\\') {
|
||||
user[len++] = c;
|
||||
}
|
||||
++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)
|
||||
{
|
||||
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);
|
||||
|
||||
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_clientIPv6 = client->m_isV6;
|
||||
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_rpcId = client->m_rpcId;
|
||||
share->m_id = id;
|
||||
@@ -487,6 +486,8 @@ void StratumServer::print_status()
|
||||
|
||||
void StratumServer::show_workers_async()
|
||||
{
|
||||
MutexLock lock(m_showWorkersLock);
|
||||
|
||||
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(&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);
|
||||
}
|
||||
|
||||
StratumClient* client = share->m_client;
|
||||
p2pool* pool = server->m_pool;
|
||||
|
||||
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);
|
||||
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;
|
||||
return;
|
||||
}
|
||||
@@ -891,13 +891,13 @@ void StratumServer::on_share_found(uv_work_t* req)
|
||||
|
||||
hash pow_hash;
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
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_score = BAD_SHARE_POINTS;
|
||||
|
||||
@@ -944,7 +944,7 @@ void StratumServer::on_share_found(uv_work_t* req)
|
||||
share->m_result = SubmittedShare::Result::OK;
|
||||
}
|
||||
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_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*/)
|
||||
{
|
||||
SubmittedShare* share = reinterpret_cast<SubmittedShare*>(req->data);
|
||||
StratumClient* client = share->m_client;
|
||||
client->m_score += share->m_score;
|
||||
|
||||
if (share->m_highEnoughDifficulty) {
|
||||
const char* s = client->m_customUser;
|
||||
const char* s = share->m_clientCustomUser;
|
||||
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 {
|
||||
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 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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
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,
|
||||
[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;
|
||||
});
|
||||
|
||||
client->m_score += share->m_score;
|
||||
|
||||
if (bad_share && (client->m_score <= BAN_THRESHOLD_POINTS)) {
|
||||
client->ban(DEFAULT_BAN_TIME);
|
||||
client->close();
|
||||
@@ -1031,8 +1033,14 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
|
||||
|
||||
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()
|
||||
@@ -1266,7 +1274,7 @@ bool StratumServer::StratumClient::process_submit(rapidjson::Document& doc, uint
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
m_pool->api()->set(p2pool_api::Category::LOCAL, "stratum",
|
||||
[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)
|
||||
{
|
||||
s << "{\"hashrate_15m\":" << hashrate_15m
|
||||
CallOnLoop(&m_loop, [=]() {
|
||||
m_pool->api()->set(p2pool_api::Category::LOCAL, "stratum", [=](log::Stream& s) {
|
||||
s << "{\"hashrate_15m\":" << hashrate_15m
|
||||
<< ",\"hashrate_1h\":" << hashrate_1h
|
||||
<< ",\"hashrate_24h\":" << hashrate_24h
|
||||
<< ",\"total_hashes\":" << total_hashes
|
||||
@@ -1343,8 +1350,38 @@ void StratumServer::api_update_local_stats(uint64_t timestamp)
|
||||
<< ",\"connections\":" << connections
|
||||
<< ",\"incoming_connections\":" << incoming_connections
|
||||
<< ",\"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
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
enum {
|
||||
JOBS_SIZE = 4,
|
||||
AUTO_DIFF_SIZE = 64,
|
||||
CUSTOM_USER_SIZE = 32,
|
||||
};
|
||||
|
||||
struct SavedJob {
|
||||
@@ -80,7 +81,7 @@ public:
|
||||
|
||||
difficulty_type m_customDiff;
|
||||
difficulty_type m_autoDiff;
|
||||
char m_customUser[32];
|
||||
char m_customUser[CUSTOM_USER_SIZE];
|
||||
|
||||
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(); }
|
||||
void on_blobs_ready();
|
||||
|
||||
uv_mutex_t m_showWorkersLock;
|
||||
uv_async_t m_showWorkersAsync;
|
||||
|
||||
static void on_show_workers(uv_async_t* handle) { reinterpret_cast<StratumServer*>(handle->data)->show_workers(); }
|
||||
@@ -144,6 +146,8 @@ private:
|
||||
StratumClient* m_client;
|
||||
bool m_clientIPv6;
|
||||
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_rpcId;
|
||||
uint32_t m_id;
|
||||
|
||||
+35
-14
@@ -27,6 +27,7 @@ TCPServer::TCPServer(int default_backlog, allocate_client_callback allocate_new_
|
||||
: m_allocateNewClient(allocate_new_client)
|
||||
, m_defaultBacklog(default_backlog)
|
||||
, m_loopThread{}
|
||||
, m_loopThreadCreated(false)
|
||||
#ifdef WITH_UPNP
|
||||
, m_portMapping(0)
|
||||
#endif
|
||||
@@ -250,6 +251,8 @@ void TCPServer::start_listening(const std::string& listen_addresses, bool upnp)
|
||||
LOGERR(1, "failed to start event loop thread, error " << uv_err_name(err));
|
||||
PANIC_STOP();
|
||||
}
|
||||
|
||||
m_loopThreadCreated = true;
|
||||
}
|
||||
|
||||
bool TCPServer::connect_to_peer(bool is_v6, const char* ip, int port)
|
||||
@@ -378,7 +381,7 @@ bool TCPServer::connect_to_peer(Client* client)
|
||||
else {
|
||||
sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(&addr);
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -392,7 +395,7 @@ bool TCPServer::connect_to_peer(Client* client)
|
||||
else {
|
||||
sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(&addr);
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -416,6 +419,7 @@ void TCPServer::check_event_loop_thread(const char* func) const
|
||||
{
|
||||
if (server_event_loop_thread != this) {
|
||||
LOGERR(1, func << " called from another thread, this is not thread safe");
|
||||
PANIC_STOP();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -473,7 +477,9 @@ void TCPServer::shutdown_tcp()
|
||||
}
|
||||
#endif
|
||||
|
||||
uv_thread_join(&m_loopThread);
|
||||
if (m_loopThreadCreated) {
|
||||
uv_thread_join(&m_loopThread);
|
||||
}
|
||||
|
||||
uv_mutex_destroy(&m_bansLock);
|
||||
|
||||
@@ -592,8 +598,7 @@ void TCPServer::loop(void* data)
|
||||
Client* c = server->m_allocateNewClient();
|
||||
|
||||
ASAN_POISON_MEMORY_REGION(wb, sizeof(WriteBuf));
|
||||
ASAN_POISON_MEMORY_REGION(c, c->size());
|
||||
ASAN_UNPOISON_MEMORY_REGION(&c->m_resetCounter, sizeof(c->m_resetCounter));
|
||||
c->asan_poison_this();
|
||||
|
||||
server->m_writeBuffers.emplace(capacity, wb);
|
||||
server->m_preallocatedClients.emplace_back(c);
|
||||
@@ -777,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);
|
||||
}
|
||||
else {
|
||||
client->m_addr = {};
|
||||
client->m_addr.data[10] = 0xFF;
|
||||
client->m_addr.data[11] = 0xFF;
|
||||
memcpy(client->m_addr.data + 12, &reinterpret_cast<sockaddr_in*>(&peer_addr)->sin_addr, sizeof(in_addr));
|
||||
memcpy(client->m_addr.data, raw_ip::ipv4_prefix, sizeof(raw_ip::ipv4_prefix));
|
||||
memcpy(client->m_addr.data + sizeof(raw_ip::ipv4_prefix), &reinterpret_cast<sockaddr_in*>(&peer_addr)->sin_addr, sizeof(in_addr));
|
||||
client->m_port = ntohs(reinterpret_cast<sockaddr_in*>(&peer_addr)->sin_port);
|
||||
}
|
||||
|
||||
@@ -857,7 +860,12 @@ void TCPServer::on_shutdown(uv_async_t* async)
|
||||
|
||||
uv_timer_init(&s->m_loop, &s->m_shutdownTimer);
|
||||
s->m_shutdownTimer.data = s;
|
||||
|
||||
#ifdef DEV_TEST_SYNC
|
||||
s->m_shutdownCountdown = 300;
|
||||
#else
|
||||
s->m_shutdownCountdown = 30;
|
||||
#endif
|
||||
|
||||
uv_timer_start(&s->m_shutdownTimer,
|
||||
[](uv_timer_t* h)
|
||||
@@ -957,8 +965,7 @@ TCPServer::Client* TCPServer::get_client()
|
||||
|
||||
void TCPServer::return_client(Client* c)
|
||||
{
|
||||
ASAN_POISON_MEMORY_REGION(c, c->size());
|
||||
ASAN_UNPOISON_MEMORY_REGION(&c->m_resetCounter, sizeof(c->m_resetCounter));
|
||||
c->asan_poison_this();
|
||||
m_preallocatedClients.push_back(c);
|
||||
}
|
||||
|
||||
@@ -1100,7 +1107,7 @@ bool TCPServer::Client::on_proxy_handshake(char* data, uint32_t size)
|
||||
}
|
||||
else {
|
||||
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[9] = static_cast<uint8_t>(m_port & 0xFF);
|
||||
}
|
||||
@@ -1205,9 +1212,10 @@ void TCPServer::Client::close()
|
||||
// Already closed
|
||||
return;
|
||||
}
|
||||
|
||||
m_isClosing = true;
|
||||
|
||||
m_owner->check_event_loop_thread(__func__);
|
||||
|
||||
uv_read_stop(reinterpret_cast<uv_stream_t*>(&m_socket));
|
||||
|
||||
uv_tcp_t* s = &m_socket;
|
||||
@@ -1238,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));
|
||||
}
|
||||
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) {
|
||||
@@ -1257,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
|
||||
|
||||
+8
-1
@@ -70,6 +70,8 @@ public:
|
||||
|
||||
void init_addr_string();
|
||||
|
||||
void asan_poison_this() const;
|
||||
|
||||
char* m_readBuf;
|
||||
uint32_t m_readBufSize;
|
||||
|
||||
@@ -87,9 +89,13 @@ public:
|
||||
bool m_isClosing;
|
||||
uint32_t m_numRead;
|
||||
|
||||
enum {
|
||||
ADDR_STRING_SIZE = 72,
|
||||
};
|
||||
|
||||
raw_ip m_addr;
|
||||
int m_port;
|
||||
char m_addrString[72];
|
||||
char m_addrString[ADDR_STRING_SIZE];
|
||||
|
||||
enum class Socks5ProxyState {
|
||||
Default,
|
||||
@@ -149,6 +155,7 @@ protected:
|
||||
int m_defaultBacklog;
|
||||
|
||||
uv_thread_t m_loopThread;
|
||||
std::atomic<bool> m_loopThreadCreated;
|
||||
|
||||
static void loop(void* data);
|
||||
|
||||
|
||||
+23
-5
@@ -44,7 +44,13 @@ LOG_CATEGORY(Util)
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
const char* VERSION = "v" STR2(P2POOL_VERSION_MAJOR) "." STR2(P2POOL_VERSION_MINOR) " (built"
|
||||
#if defined(P2POOL_VERSION_PATCH) && (P2POOL_VERSION_PATCH > 0)
|
||||
#define P2POOL_VERSION_PATCH_STR "." STR2(P2POOL_VERSION_PATCH)
|
||||
#else
|
||||
#define P2POOL_VERSION_PATCH_STR ""
|
||||
#endif
|
||||
|
||||
const char* VERSION = "v" STR2(P2POOL_VERSION_MAJOR) "." STR2(P2POOL_VERSION_MINOR) P2POOL_VERSION_PATCH_STR " (built"
|
||||
#if defined(__clang__)
|
||||
" with clang/" __clang_version__
|
||||
#elif defined(__GNUC__)
|
||||
@@ -54,6 +60,20 @@ const char* VERSION = "v" STR2(P2POOL_VERSION_MAJOR) "." STR2(P2POOL_VERSION_MIN
|
||||
#endif
|
||||
" 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_ipv6 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
|
||||
|
||||
@@ -602,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));
|
||||
return false;
|
||||
}
|
||||
result = {};
|
||||
result.data[10] = 0xFF;
|
||||
result.data[11] = 0xFF;
|
||||
memcpy(result.data + 12, &addr4->sin_addr, sizeof(in_addr));
|
||||
memcpy(result.data, raw_ip::ipv4_prefix, sizeof(raw_ip::ipv4_prefix));
|
||||
memcpy(result.data + sizeof(raw_ip::ipv4_prefix), &addr4->sin_addr, sizeof(in_addr));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+18
-3
@@ -35,10 +35,19 @@
|
||||
namespace p2pool {
|
||||
|
||||
#define P2POOL_VERSION_MAJOR 3
|
||||
#define P2POOL_VERSION_MINOR 6
|
||||
#define P2POOL_VERSION_MINOR 7
|
||||
#define P2POOL_VERSION_PATCH 0
|
||||
|
||||
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 }; };
|
||||
|
||||
struct nocopy_nomove
|
||||
@@ -90,11 +99,17 @@ static FORCEINLINE bool from_hex(char c, T& out_value) {
|
||||
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> 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>
|
||||
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;
|
||||
}
|
||||
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/hash_tests.cpp
|
||||
src/keccak_tests.cpp
|
||||
src/log_tests.cpp
|
||||
src/main.cpp
|
||||
src/pool_block_tests.cpp
|
||||
src/util_tests.cpp
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* 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>
|
||||
* 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
|
||||
* 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>
|
||||
* 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
|
||||
* 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>
|
||||
* 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
|
||||
* 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>
|
||||
* 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
|
||||
* 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>
|
||||
* 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
|
||||
* 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>
|
||||
* 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
|
||||
* 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 time
|
||||
import sys
|
||||
@@ -5,19 +20,26 @@ import json
|
||||
|
||||
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')
|
||||
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.flush()
|
||||
print('.')
|
||||
time.sleep(1)
|
||||
|
||||
f.write(b'\n')
|
||||
f.flush()
|
||||
|
||||
diff = ''
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
race:p2pool::log::Worker::run()
|
||||
race:p2pool::log::Worker::write
|
||||
called_from_lib:libzmq.so
|
||||
race_top:do_loglevel
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* 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>
|
||||
* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
Reference in New Issue
Block a user