Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ed63ab3ac | |||
| d99a48d87d | |||
| 27375e7382 | |||
| a81d3c4989 | |||
| b922440fc7 | |||
| 6ca6f2ed3d | |||
| 954b9252c1 | |||
| e355f45544 | |||
| ed32664b9e | |||
| 8619057224 | |||
| 10978c59e4 | |||
| ed56206c30 | |||
| 513c2dfc3b | |||
| 0b544bf55a | |||
| a9d39f0803 | |||
| 2248739dd5 | |||
| b83b691714 | |||
| 887611c9d8 | |||
| 390cf0257e | |||
| 2503dca0e3 | |||
| 8fd45cc977 | |||
| 8d9b9e505e | |||
| 2453c08194 | |||
| f149613d54 | |||
| 2c5cfb6442 | |||
| cfddaf1508 | |||
| 6eff190f87 | |||
| e40c5190b1 | |||
| 2584799415 | |||
| 0463901db7 | |||
| c2704af523 | |||
| 328e9cade9 | |||
| 2b61fff449 | |||
| d8bbe2110e | |||
| 1ef88622d6 | |||
| b1d3fb63f3 | |||
| f44ffd1959 | |||
| e7545db663 |
@@ -19,7 +19,7 @@ jobs:
|
||||
matrix:
|
||||
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
|
||||
@@ -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: |
|
||||
|
||||
@@ -359,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>
|
||||
|
||||
@@ -97,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
+29
-13
@@ -381,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));
|
||||
}
|
||||
}
|
||||
@@ -395,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));
|
||||
}
|
||||
}
|
||||
@@ -419,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
|
||||
@@ -597,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);
|
||||
@@ -782,10 +782,8 @@ void TCPServer::on_new_client(uv_stream_t* server, Client* client)
|
||||
client->m_port = ntohs(reinterpret_cast<sockaddr_in6*>(&peer_addr)->sin6_port);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -862,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)
|
||||
@@ -962,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);
|
||||
}
|
||||
|
||||
@@ -1105,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);
|
||||
}
|
||||
@@ -1210,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;
|
||||
@@ -1243,7 +1246,7 @@ void TCPServer::Client::init_addr_string()
|
||||
addr_str = inet_ntop(AF_INET6, m_addr.data, addr_str_buf, sizeof(addr_str_buf));
|
||||
}
|
||||
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) {
|
||||
@@ -1262,4 +1265,17 @@ void TCPServer::Client::init_addr_string()
|
||||
}
|
||||
}
|
||||
|
||||
void TCPServer::Client::asan_poison_this() const
|
||||
{
|
||||
#ifdef P2POOL_ASAN
|
||||
const uint8_t* begin = reinterpret_cast<const uint8_t*>(this);
|
||||
const uint8_t* counter_begin = reinterpret_cast<const uint8_t*>(&m_resetCounter);
|
||||
const uint8_t* counter_end = counter_begin + sizeof(m_resetCounter);
|
||||
const uint8_t* end = begin + size();
|
||||
|
||||
ASAN_POISON_MEMORY_REGION(begin, counter_begin - begin);
|
||||
ASAN_POISON_MEMORY_REGION(counter_end, end - counter_end);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
+7
-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,
|
||||
|
||||
+16
-4
@@ -60,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 };
|
||||
|
||||
@@ -608,10 +622,8 @@ bool str_to_ip(bool is_v6, const char* ip, raw_ip& result)
|
||||
LOGERR(1, "failed to parse IPv4 address " << ip << ", error " << uv_err_name(err));
|
||||
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
-4
@@ -35,11 +35,19 @@
|
||||
namespace p2pool {
|
||||
|
||||
#define P2POOL_VERSION_MAJOR 3
|
||||
#define P2POOL_VERSION_MINOR 6
|
||||
#define P2POOL_VERSION_PATCH 1
|
||||
#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
|
||||
@@ -91,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