Compare commits

...

123 Commits

Author SHA1 Message Date
SChernykh 837a33480e p2pool v3.8
C/C++ CI / build-alpine-static (map[arch:aarch64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline -mfix-cortex-a53-835769 -mfix-cortex-a53-843419]) (push) Has been cancelled
C/C++ CI / build-alpine-static (map[arch:x86_64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-11 cpp:g++-11 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-12 cpp:g++-12 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-static-libs (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:clang cxx:clang++ flags:-flto -ffunction-sections -fuse-ld=lld -Wno-unused-command-line-argument]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:gcc cxx:g++ flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[os:2019 rx:OFF upnp:OFF vs:Visual Studio 16 2019 vspath:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[os:2019 rx:OFF upnp:ON vs:Visual Studio 16 2019 vspath:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[os:2019 rx:ON upnp:ON vs:Visual Studio 16 2019 vspath:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise]) (push) Has been cancelled
C/C++ CI / build-macos (push) Has been cancelled
C/C++ CI / build-macos-aarch64 (push) Has been cancelled
C/C++ CI / build-freebsd (map[architecture:x86-64 host:ubuntu-22.04 name:freebsd version:12.4]) (push) Has been cancelled
C/C++ CI / build-openbsd (map[architecture:x86-64 host:ubuntu-22.04 name:openbsd version:7.2]) (push) Has been cancelled
clang-tidy / clang-tidy (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
cppcheck / cppcheck-ubuntu (push) Has been cancelled
cppcheck / cppcheck-windows (push) Has been cancelled
Microsoft C++ Code Analysis / Analyze (push) Has been cancelled
source-snapshot / source-snapshot (push) Has been cancelled
Sync test / sync-test-ubuntu-tsan (push) Has been cancelled
Sync test / sync-test-ubuntu-msan (push) Has been cancelled
Sync test / sync-test-ubuntu-ubsan (push) Has been cancelled
Sync test / sync-test-ubuntu-asan (push) Has been cancelled
Sync test / sync-test-macos (push) Has been cancelled
Sync test / sync-test-windows-debug-asan (push) Has been cancelled
Sync test / sync-test-windows-leaks (push) Has been cancelled
2023-10-31 12:32:36 +01:00
SChernykh 7b02c3d24a Documentation: recommend more in-peers
This will balance out peers which can only have outgoing connections.
2023-10-30 09:49:36 +01:00
SChernykh c59845e746 Fixed cppcheck errors 2023-10-29 09:43:22 +01:00
SChernykh 119782920a Warn if there are too many background jobs 2023-10-20 21:12:26 +02:00
SChernykh 30ba38c2b3 macOS aarch64 build: switch to clang 15 2023-10-19 19:57:37 +02:00
SChernykh 87547576de Update RandomX 2023-10-19 18:08:40 +02:00
SChernykh 5febb8c4e2 Self-test: multithreaded dataset initialization 2023-10-18 13:43:40 +02:00
SChernykh ddc6986401 Self-test: calculate 100 hashes instead of just 1 2023-10-18 11:18:57 +02:00
SChernykh c0cabc9739 Check for Windows 7 compatibility 2023-10-17 18:04:46 +02:00
SChernykh 9a1da5b7c2 Update README.md 2023-10-16 13:44:07 +02:00
SChernykh 5daa2b9dff Removed -Wcast-align
Not necessary because misaligned accesses will be detected by UB sanitizer
2023-10-11 19:59:14 +02:00
SChernykh 5988acb12b Fix CVE-2023-38545 2023-10-11 08:17:35 +02:00
SChernykh 011d05f7b6 Update RandomX 2023-10-09 18:42:45 +02:00
SChernykh 294d1a525e Update check now also checks for connected peer versions 2023-10-09 11:08:51 +02:00
SChernykh e5770a5343 Fixed cppcheck errors 2023-10-08 23:33:06 +02:00
SChernykh 7a65e1feb5 Check for updates in status and version commands 2023-10-08 21:01:50 +02:00
SChernykh 4e55f53fb4 Notify about new P2Pool versions 2023-10-08 18:52:06 +02:00
SChernykh 4d944d3dc3 HTML: added latest release URL 2023-10-08 18:11:07 +02:00
SChernykh 3d3b4837ff Update rapidjson 2023-10-05 13:33:59 +02:00
SChernykh 8270e0898b StratumServer: fixed memory leak on shutdown 2023-10-02 08:19:28 +02:00
SChernykh 2ed63ab3ac p2pool v3.7
C/C++ CI / build-alpine-static (map[arch:aarch64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline -mfix-cortex-a53-835769 -mfix-cortex-a53-843419]) (push) Has been cancelled
C/C++ CI / build-alpine-static (map[arch:x86_64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-11 cpp:g++-11 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-12 cpp:g++-12 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-static-libs (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -mfix-cortex-a53-835769 -mfix-cortex-a53-843419 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:clang cxx:clang++ flags:-flto -ffunction-sections -fuse-ld=lld -Wno-unused-command-line-argument]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:gcc cxx:g++ flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:OFF vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:ON upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-macos (push) Has been cancelled
C/C++ CI / build-macos-aarch64 (push) Has been cancelled
C/C++ CI / build-freebsd (map[architecture:x86-64 host:ubuntu-22.04 name:freebsd version:12.4]) (push) Has been cancelled
C/C++ CI / build-openbsd (map[architecture:x86-64 host:ubuntu-22.04 name:openbsd version:7.2]) (push) Has been cancelled
clang-tidy / clang-tidy (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
cppcheck / cppcheck-ubuntu (push) Has been cancelled
cppcheck / cppcheck-windows (push) Has been cancelled
Microsoft C++ Code Analysis / Analyze (push) Has been cancelled
source-snapshot / source-snapshot (push) Has been cancelled
Sync test / sync-test-ubuntu-tsan (push) Has been cancelled
Sync test / sync-test-ubuntu-msan (push) Has been cancelled
Sync test / sync-test-ubuntu-ubsan (push) Has been cancelled
Sync test / sync-test-ubuntu-asan (push) Has been cancelled
Sync test / sync-test-macos (push) Has been cancelled
Sync test / sync-test-windows-debug-asan (push) Has been cancelled
Sync test / sync-test-windows-leaks (push) Has been cancelled
2023-09-30 11:19:13 +02:00
SChernykh d99a48d87d Added a reserve domain for seed node lists 2023-09-30 08:43:29 +02:00
SChernykh 27375e7382 StratumServer: removed an unnecessary check 2023-09-29 11:55:25 +02:00
SChernykh a81d3c4989 ZMQ: fixed bind port error message 2023-09-26 19:35:30 +02:00
SChernykh b922440fc7 Refactored software id code
Show a warning when an unknown software id is seen
2023-09-23 18:04:02 +02:00
SChernykh 6ca6f2ed3d HTML: update min payout 2023-09-18 18:22:12 +02:00
SChernykh 954b9252c1 StratumServer: fixed data race in api update 2023-09-17 22:30:21 +02:00
SChernykh e355f45544 Merge pull request #278 from BadTigrou/master
Adding workers data to api
2023-09-17 21:51:32 +02:00
charlie ed32664b9e Adding workers data to api in stratum files 2023-09-17 20:09:53 +02:00
SChernykh 8619057224 Log: set locale for data output 2023-09-17 19:30:39 +02:00
SChernykh 10978c59e4 Made custom worker names safe for JSON data
And comma-separated lists too.
2023-09-17 11:32:56 +02:00
SChernykh ed56206c30 More log tests 2023-09-17 10:38:46 +02:00
SChernykh 513c2dfc3b Updated copyright 2023-09-16 22:29:32 +02:00
SChernykh 0b544bf55a API: removed file size limitation 2023-09-16 19:38:16 +02:00
SChernykh a9d39f0803 Better error messages 2023-09-13 21:37:07 +02:00
SChernykh 2248739dd5 Don't update api when shutting down 2023-09-13 21:12:01 +02:00
SChernykh b83b691714 TCPServer: cleaned up IPv4 address handling 2023-09-11 19:43:28 +02:00
SChernykh 887611c9d8 P2Pool: normalized peer list IPv4/IPv6 data 2023-09-09 20:22:43 +02:00
SChernykh 390cf0257e StratumServer: fixed data races on disconnect 2023-09-08 15:19:59 +02:00
SChernykh 2503dca0e3 Docker: updated priority node 2023-09-06 22:06:13 +02:00
SChernykh 8fd45cc977 Docker: expose port 18083 together with RPC port 2023-09-06 19:26:23 +02:00
SChernykh 8d9b9e505e Added ARM errata mitigations
Reworked #189
2023-09-06 16:32:09 +02:00
SChernykh 2453c08194 SideChain: fixed use-after-free in precalc code 2023-09-06 10:05:55 +02:00
SChernykh f149613d54 Removed unnecessary async call 2023-09-04 20:38:01 +02:00
SChernykh 2c5cfb6442 Fixed data races when using uv_async_send 2023-09-04 19:33:31 +02:00
SChernykh cfddaf1508 TCPServer: added thread check on connection close 2023-09-03 23:17:04 +02:00
SChernykh 6eff190f87 Sync test: use macOS release build settings 2023-09-03 17:56:34 +02:00
SChernykh e40c5190b1 macOS aarch64 build: disabled LTO 2023-09-03 17:45:05 +02:00
SChernykh 2584799415 TCPServer: fixed ASAN code 2023-09-03 17:13:22 +02:00
SChernykh 0463901db7 Run thread sanitizer test with static libs 2023-09-03 16:23:11 +02:00
SChernykh c2704af523 Sync test: increased countdown length 2023-09-03 14:35:12 +02:00
SChernykh 328e9cade9 SideChain: fixed read from uninitialized buffer 2023-09-03 14:16:09 +02:00
SChernykh 2b61fff449 Sync test: increase test load 2023-09-03 13:44:06 +02:00
SChernykh d8bbe2110e P2PServer: fixed a data race when banning peers 2023-09-03 13:15:45 +02:00
SChernykh 1ef88622d6 p2pool v3.6.2
C/C++ CI / build-alpine-static (map[arch:aarch64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-alpine-static (map[arch:x86_64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-11 cpp:g++-11 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-12 cpp:g++-12 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-static-libs (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:clang cxx:clang++ flags:-flto -ffunction-sections -fuse-ld=lld -Wno-unused-command-line-argument]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:gcc cxx:g++ flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:OFF vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:ON upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-macos (push) Has been cancelled
C/C++ CI / build-macos-aarch64 (push) Has been cancelled
C/C++ CI / build-freebsd (map[architecture:x86-64 host:ubuntu-22.04 name:freebsd version:12.4]) (push) Has been cancelled
C/C++ CI / build-openbsd (map[architecture:x86-64 host:ubuntu-22.04 name:openbsd version:7.2]) (push) Has been cancelled
clang-tidy / clang-tidy (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
cppcheck / cppcheck-ubuntu (push) Has been cancelled
cppcheck / cppcheck-windows (push) Has been cancelled
Microsoft C++ Code Analysis / Analyze (push) Has been cancelled
source-snapshot / source-snapshot (push) Has been cancelled
Sync test / sync-test-ubuntu-tsan (push) Has been cancelled
Sync test / sync-test-ubuntu-msan (push) Has been cancelled
Sync test / sync-test-ubuntu-ubsan (push) Has been cancelled
Sync test / sync-test-ubuntu-asan (push) Has been cancelled
Sync test / sync-test-macos (push) Has been cancelled
Sync test / sync-test-windows-debug-asan (push) Has been cancelled
Sync test / sync-test-windows-leaks (push) Has been cancelled
2023-09-03 09:49:31 +02:00
SChernykh b1d3fb63f3 Use the old compiler for macOS-aarch64 build 2023-09-02 18:41:11 +02:00
SChernykh f44ffd1959 Sync test: rewrote stratum connection code 2023-09-01 18:20:50 +02:00
SChernykh e7545db663 Sync test: make sure stratum logs are saved 2023-09-01 17:12:22 +02:00
SChernykh fcf9d2ad15 p2pool v3.6.1
C/C++ CI / build-alpine-static (map[arch:aarch64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-alpine-static (map[arch:x86_64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-11 cpp:g++-11 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-12 cpp:g++-12 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-static-libs (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:clang cxx:clang++ flags:-flto -ffunction-sections -fuse-ld=lld -Wno-unused-command-line-argument]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:gcc cxx:g++ flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:OFF vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:ON upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-macos (push) Has been cancelled
C/C++ CI / build-macos-aarch64 (push) Has been cancelled
C/C++ CI / build-freebsd (map[architecture:x86-64 host:ubuntu-22.04 name:freebsd version:12.4]) (push) Has been cancelled
C/C++ CI / build-openbsd (map[architecture:x86-64 host:ubuntu-22.04 name:openbsd version:7.2]) (push) Has been cancelled
clang-tidy / clang-tidy (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
cppcheck / cppcheck-ubuntu (push) Has been cancelled
cppcheck / cppcheck-windows (push) Has been cancelled
Microsoft C++ Code Analysis / Analyze (push) Has been cancelled
source-snapshot / source-snapshot (push) Has been cancelled
Sync test / sync-test-ubuntu-tsan (push) Has been cancelled
Sync test / sync-test-ubuntu-msan (push) Has been cancelled
Sync test / sync-test-ubuntu-ubsan (push) Has been cancelled
Sync test / sync-test-ubuntu-asan (push) Has been cancelled
Sync test / sync-test-macos (push) Has been cancelled
Sync test / sync-test-windows-debug-asan (push) Has been cancelled
Sync test / sync-test-windows-leaks (push) Has been cancelled
2023-09-01 12:39:07 +02:00
SChernykh 7986321a52 Fixed console commands startup 2023-08-31 17:50:31 +02:00
SChernykh 8e0f28ee30 Fixed Windows 7 compatibility 2023-08-31 16:21:59 +02:00
SChernykh fecfa18999 p2pool v3.6
C/C++ CI / build-alpine-static (map[arch:aarch64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-alpine-static (map[arch:x86_64 flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-11 cpp:g++-11 os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu (map[c:gcc-12 cpp:g++-12 os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-static-libs (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections os:ubuntu-20.04]) (push) Has been cancelled
C/C++ CI / build-ubuntu-aarch64 (map[flags:-flto=2 -fuse-linker-plugin -ffunction-sections os:ubuntu-22.04]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:clang cxx:clang++ flags:-flto -ffunction-sections -fuse-ld=lld -Wno-unused-command-line-argument]) (push) Has been cancelled
C/C++ CI / build-windows-msys2 (map[c:gcc cxx:g++ flags:-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:OFF vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:OFF upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-windows-msbuild (map[msbuild:C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\ os:2019 rx:ON upnp:ON vs:Visual Studio 16 2019]) (push) Has been cancelled
C/C++ CI / build-macos (push) Has been cancelled
C/C++ CI / build-macos-aarch64 (push) Has been cancelled
C/C++ CI / build-freebsd (map[architecture:x86-64 host:ubuntu-22.04 name:freebsd version:12.4]) (push) Has been cancelled
C/C++ CI / build-openbsd (map[architecture:x86-64 host:ubuntu-22.04 name:openbsd version:7.2]) (push) Has been cancelled
clang-tidy / clang-tidy (push) Has been cancelled
CodeQL / Analyze (cpp) (push) Has been cancelled
cppcheck / cppcheck-ubuntu (push) Has been cancelled
cppcheck / cppcheck-windows (push) Has been cancelled
Microsoft C++ Code Analysis / Analyze (push) Has been cancelled
source-snapshot / source-snapshot (push) Has been cancelled
Sync test / sync-test-ubuntu-tsan (push) Has been cancelled
Sync test / sync-test-ubuntu-msan (push) Has been cancelled
Sync test / sync-test-ubuntu-ubsan (push) Has been cancelled
Sync test / sync-test-ubuntu-asan (push) Has been cancelled
Sync test / sync-test-macos (push) Has been cancelled
Sync test / sync-test-windows-debug-asan (push) Has been cancelled
Sync test / sync-test-windows-leaks (push) Has been cancelled
2023-08-31 10:32:34 +02:00
SChernykh d8b23cd13c CI: fixed paths and file names 2023-08-26 21:00:23 +02:00
SChernykh 0e0101f507 CI: build libcxx_msan every time 2023-08-24 15:11:55 +02:00
SChernykh 17a17850ea Update libcxx_msan.tar.xz 2023-08-23 20:55:15 +02:00
SChernykh 71d4a6dab0 Tweaked macOS build parameters 2023-08-23 20:22:44 +02:00
SChernykh 936d3b5280 Added quick self-test 2023-08-23 17:01:01 +02:00
SChernykh fac9c23103 Fixed LTO in macOS builds 2023-08-23 16:23:48 +02:00
SChernykh 3674401923 Update RandomX 2023-08-23 13:37:07 +02:00
SChernykh 66d6d0dc33 CI: fixed BSD builds 2023-08-22 17:00:39 +02:00
SChernykh 31ce134413 Fixed INVALID SHARE log color 2023-08-21 21:24:04 +02:00
SChernykh b8e6aae289 Disabled RandomX tests 2023-08-21 20:49:45 +02:00
SChernykh 8f620712ef Update RandomX 2023-08-21 17:47:09 +02:00
SChernykh 1069d1c066 Fixed cppcheck error 2023-08-21 11:20:50 +02:00
SChernykh bc0634a541 RandomX: try to recover after an error 2023-08-21 11:01:57 +02:00
SChernykh 8d65a99fe4 Fixed data race 2023-08-18 21:57:51 +02:00
SChernykh 6e68714c26 CI: fixed libzmq cmake command line 2023-08-18 20:19:59 +02:00
SChernykh 06ff7b661a CI: added Alpine Linux static builds 2023-08-18 19:01:09 +02:00
SChernykh 70a6442b46 CI: reduced MacOS and FreeBSD binary sizes 2023-08-18 15:48:35 +02:00
SChernykh 9e7d394ae7 CI: reduced aarch64 binary sizes 2023-08-18 12:59:37 +02:00
SChernykh 326b2d7a04 Pool block test: check RandomX hash where possible 2023-08-18 12:01:14 +02:00
SChernykh f3045a5e80 Fixed possible thread handle leak 2023-08-17 10:16:51 +02:00
SChernykh b3d72cbfcb Update googletest 2023-08-16 14:55:48 +02:00
SChernykh 76c4573c39 CI: cleanup build warnings
Tests: fixed "unused const variable" warning
CMakeLists.txt: fixed deprecation warnings
2023-08-16 14:20:23 +02:00
SChernykh 741bec9874 CI: optimized msys2 binary sizes more 2023-08-16 12:03:48 +02:00
SChernykh 46aed06523 CI: optimized msys2 binary sizes 2023-08-15 22:19:48 +02:00
SChernykh 7630c1a883 CI: added msys2-clang Windows build 2023-08-15 19:53:22 +02:00
SChernykh 2877e5dfc1 Sync test: log stratum data when finished 2023-08-15 11:43:05 +02:00
SChernykh 05b88a48a3 CI: update to clang 17 2023-08-15 10:57:05 +02:00
SChernykh c74b567fe4 Update stratum_dummy.py 2023-08-15 08:00:11 +02:00
SChernykh a6b6cb0f09 TCPServer: tweaked ASAN support 2023-08-14 22:24:42 +02:00
SChernykh 86e9af6fd7 Sync test: submit more fake shares 2023-08-14 21:57:38 +02:00
SChernykh 8776f7dfbb Fixed MacOS sync test 2023-08-14 18:36:05 +02:00
SChernykh 929f908a86 Sync test: submit fake shares to test stratum 2023-08-14 17:10:36 +02:00
SChernykh 229d7b052a Create CONSOLE_COMMANDS.MD 2023-08-14 13:12:06 +02:00
SChernykh a5896f7ae8 Updated docs 2023-08-14 11:28:25 +02:00
SChernykh 114c2cee93 Updated dependencies
- cppzmq 4.10.0
- curl 8.2.1
- libuv 1.46
- latest libzmq
- latest miniupnp
- latest rapidjson
2023-08-13 21:05:39 +02:00
SChernykh 7f413ec994 Re-enabled CI jobs 2023-08-07 12:18:58 +02:00
SChernykh bd30a68e7d Fixed cppcheck error 2023-08-07 07:28:44 +02:00
SChernykh f4a18726b5 P2PServer: support future major protocol changes 2023-08-04 15:52:28 +02:00
SChernykh 50e284357c Disabled failing jobs 2023-08-01 16:16:56 +02:00
SChernykh 2ddb03e2be CI: tweaked memory leak output formatting 2023-07-19 16:15:48 +02:00
SChernykh ebae616138 CI: fixed error checking in sync test 2023-07-19 15:36:16 +02:00
SChernykh 0f88640575 CI: added sync test with memory leak detection 2023-07-19 13:59:57 +02:00
SChernykh 75cc82ae0c P2PServer: removed protocol version check for fastest peer 2023-07-12 12:48:52 +02:00
SChernykh 32dc235aa5 SideChain: fix for out of order blocks 2023-07-12 00:25:37 +02:00
SChernykh 6ffe1d81c2 P2PServer: ignore protocol versions higher than supported 2023-07-10 20:13:37 +02:00
SChernykh 5b245e64d3 Fixed a typo 2023-07-10 16:54:01 +02:00
SChernykh a067361d74 P2PServer: prefetch 2 blocks ahead during sync 2023-07-10 15:44:18 +02:00
SChernykh a7f66c8883 SideChain: filter duplicates from missing blocks 2023-07-10 14:11:22 +02:00
SChernykh e03e7d831e P2PServer: tweaked switching to the fastet peer when syncing 2023-07-10 11:40:48 +02:00
SChernykh 1219ed0dd6 P2PServer: check protocol version when choosing fastest peer 2023-07-07 23:49:43 +02:00
SChernykh fe2ff95f19 P2PServer: use BLOCK_NOTIFY to speed up syncing 2023-07-07 16:48:28 +02:00
SChernykh d72f0ce40c P2PServer: fixed some excess block requests 2023-07-07 14:52:47 +02:00
SChernykh df43e2c126 SideChain: tweaked precalc logic 2023-07-07 14:21:52 +02:00
SChernykh d8ecc1174d P2PServer: refactored BLOCK_NOTIFY logic
- Limit how many block requests can be in flight
- Don't send requests for the same block twice
2023-07-07 12:14:24 +02:00
SChernykh 3e269b49d4 Tweaked log level for BLOCK_NOTIFY 2023-07-05 19:06:49 +02:00
SChernykh 72c9f3b0db Fixed ping time calculation 2023-07-05 15:29:54 +02:00
SChernykh 2f5b0db786 P2PServer: request blocks coming from BLOCK_NOTIFY 2023-07-05 11:42:34 +02:00
SChernykh 8d9f16c387 P2PServer: sanity check message id 2023-07-04 16:47:14 +02:00
SChernykh d6cb0ee8a0 P2PServer: avoid unnecessary block broadcasts 2023-07-04 16:06:01 +02:00
SChernykh 5444701c38 Tweaked status code
Don't create stream when it's not needed
2023-07-02 15:33:51 +02:00
SChernykh 396479c2bf Fixed cppcheck errors 2023-07-02 13:10:05 +02:00
83 changed files with 2124 additions and 609 deletions
+221 -65
View File
@@ -1,8 +1,110 @@
name: C/C++ CI
on: [push, pull_request]
on:
push:
paths-ignore:
- 'docker-compose/**'
- 'docs/**'
- 'README.md'
pull_request:
jobs:
build-alpine-static:
timeout-minutes: 75
runs-on: ubuntu-22.04
strategy:
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 -mfix-cortex-a53-835769 -mfix-cortex-a53-843419"}
steps:
- name: Setup Alpine Linux
uses: jirutka/setup-alpine@v1
with:
arch: ${{ matrix.config.arch }}
- name: Install dependencies
shell: alpine.sh --root {0}
run: |
apk add git cmake gcc g++ make
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: true
- name: Build libcurl
shell: alpine.sh {0}
run: |
cd external/src/curl
cmake . -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
make -j$(nproc)
cd lib && mkdir .libs && cp libcurl.a .libs
- name: Build libuv
shell: alpine.sh {0}
run: |
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j$(nproc)
- name: Build libzmq
shell: alpine.sh {0}
run: |
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DCMAKE_CXX_FLAGS='-Os ${{ matrix.config.flags }}' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
make -j$(nproc)
- name: Build p2pool
shell: alpine.sh {0}
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 -DARCH_ID=${{ matrix.config.arch }}
make -j$(nproc)
- name: Run RandomX tests
shell: alpine.sh {0}
run: |
build/p2pool --test
build/external/src/RandomX/randomx-tests
- name: Build tests
shell: alpine.sh {0}
run: |
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 -DARCH_ID=${{ matrix.config.arch }}
make -j$(nproc)
- name: Run tests
shell: alpine.sh {0}
run: |
cd tests/build
gunzip *.gz
./p2pool_tests
- name: List directory
run: |
cd build
ls -la
file p2pool
- name: Archive binary
uses: actions/upload-artifact@v3
with:
name: p2pool-alpine-static-${{ matrix.config.arch }}
path: build/p2pool
build-ubuntu:
timeout-minutes: 10
@@ -30,15 +132,20 @@ jobs:
run: |
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_CXX_COMPILER=${{ matrix.config.cpp }}
cmake .. -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_CXX_COMPILER=${{ matrix.config.cpp }} -DCMAKE_C_FLAGS='-flto=2' -DCMAKE_CXX_FLAGS='-flto=2'
make -j$(nproc)
- name: Run RandomX tests
run: |
build/p2pool --test
build/external/src/RandomX/randomx-tests
- name: Build tests
run: |
cd tests
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_CXX_COMPILER=${{ matrix.config.cpp }}
cmake .. -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_CXX_COMPILER=${{ matrix.config.cpp }} -DCMAKE_C_FLAGS='-flto=2' -DCMAKE_CXX_FLAGS='-flto=2'
make -j$(nproc)
- name: Run tests
@@ -58,6 +165,11 @@ jobs:
timeout-minutes: 15
runs-on: ubuntu-22.04
strategy:
matrix:
config:
- {flags: "-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=inline"}
steps:
- name: Install dependencies
run: |
@@ -74,7 +186,7 @@ jobs:
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_C_FLAGS="-Os" -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 ${{ 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
make -j$(nproc)
cd lib && mkdir .libs && cp libcurl.a .libs
@@ -83,7 +195,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os' -DBUILD_TESTING=OFF
cmake .. -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j$(nproc)
- name: Build libzmq
@@ -91,22 +203,27 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os' -DCMAKE_CXX_FLAGS='-Os' -DWITH_TLS=OFF -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DWITH_PERF_TOOL=OFF
cmake .. -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DCMAKE_CXX_FLAGS='-Os ${{ matrix.config.flags }}' -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 .. -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
make -j$(nproc)
- name: Run RandomX tests
run: |
build/p2pool --test
build/external/src/RandomX/randomx-tests
- name: Build tests
run: |
cd tests
mkdir build
cd build
cmake .. -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
make -j$(nproc)
- name: Run tests
@@ -123,20 +240,20 @@ jobs:
build-ubuntu-aarch64:
timeout-minutes: 10
timeout-minutes: 15
runs-on: ${{ matrix.config.os }}
strategy:
matrix:
config:
- {os: ubuntu-20.04}
- {os: ubuntu-22.04}
- {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
run: |
sudo apt update
sudo apt install -y git build-essential cmake gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu
sudo apt install -y git build-essential cmake gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu qemu-user
- name: Checkout repository
uses: actions/checkout@v3
@@ -146,7 +263,7 @@ jobs:
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_C_FLAGS="-Os" -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_COMPILER=aarch64-linux-gnu-gcc -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
make -j$(nproc)
cd lib && mkdir .libs && cp libcurl.a .libs
@@ -155,7 +272,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_C_FLAGS='-Os' -DBUILD_TESTING=OFF
cmake .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j$(nproc)
- name: Build libzmq
@@ -163,16 +280,35 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_C_FLAGS='-Os' -DCMAKE_CXX_FLAGS='-Os' -DWITH_TLS=OFF -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DWITH_PERF_TOOL=OFF
cmake .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DCMAKE_CXX_FLAGS='-Os ${{ matrix.config.flags }}' -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 .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_STRIP=/usr/bin/aarch64-linux-gnu-strip -DSTATIC_LIBS=ON -DARCH_ID=aarch64
cmake .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_STRIP=/usr/bin/aarch64-linux-gnu-strip -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=aarch64
make -j$(nproc)
- name: Run RandomX tests
run: |
qemu-aarch64 -L /usr/aarch64-linux-gnu build/p2pool --test
qemu-aarch64 -L /usr/aarch64-linux-gnu build/external/src/RandomX/randomx-tests
- name: Build tests
run: |
cd tests
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_STRIP=/usr/bin/aarch64-linux-gnu-strip -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=aarch64
make -j$(nproc)
- name: Run tests
run: |
cd tests/build
gunzip *.gz
qemu-aarch64 -L /usr/aarch64-linux-gnu ./p2pool_tests
- name: Archive binary
uses: actions/upload-artifact@v3
with:
@@ -184,6 +320,12 @@ jobs:
timeout-minutes: 45
runs-on: windows-latest
strategy:
matrix:
config:
- {c: "gcc", cxx: "g++", flags: "-flto=2 -fuse-linker-plugin -ffunction-sections -Wno-error=maybe-uninitialized -Wno-error=attributes"}
- {c: "clang", cxx: "clang++", flags: "-flto -ffunction-sections -fuse-ld=lld -Wno-unused-command-line-argument"}
defaults:
run:
shell: msys2 {0}
@@ -198,12 +340,12 @@ jobs:
uses: eine/setup-msys2@v2
with:
update: true
install: mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake make
install: mingw-w64-x86_64-toolchain mingw-w64-x86_64-clang mingw-w64-x86_64-lld mingw-w64-x86_64-cmake make
- name: Build libcurl
run: |
cd external/src/curl
cmake . -G "Unix Makefiles" -DCMAKE_C_FLAGS="-Os" -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
@@ -212,7 +354,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -G "Unix Makefiles" -DCMAKE_C_FLAGS='-Os' -DBUILD_TESTING=OFF
cmake .. -G "Unix Makefiles" -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j$(nproc)
- name: Build libzmq
@@ -220,22 +362,27 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -G "Unix Makefiles" -DCMAKE_C_FLAGS='-Os' -DCMAKE_CXX_FLAGS='-Os' -DWITH_TLS=OFF -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DZMQ_HAVE_IPC=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DWITH_PERF_TOOL=OFF
cmake .. -G "Unix Makefiles" -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_CXX_COMPILER=${{ matrix.config.cxx }} -DCMAKE_C_FLAGS='-Os ${{ matrix.config.flags }}' -DCMAKE_CXX_FLAGS='-Os ${{ matrix.config.flags }}' -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DZMQ_HAVE_IPC=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DBUILD_SHARED=OFF
make -j$(nproc)
- name: Build p2pool
run: |
mkdir build
cd build
cmake .. -G "Unix Makefiles" -DSTATIC_LIBS=ON
cmake .. -G "Unix Makefiles" -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_CXX_COMPILER=${{ matrix.config.cxx }} -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
make -j$(nproc)
- name: Run RandomX tests
run: |
build/p2pool.exe --test
build/external/src/RandomX/randomx-tests.exe
- name: Build tests
run: |
cd tests
mkdir build
cd build
cmake .. -G "Unix Makefiles" -DSTATIC_LIBS=ON
cmake .. -G "Unix Makefiles" -DCMAKE_C_COMPILER=${{ matrix.config.c }} -DCMAKE_CXX_COMPILER=${{ matrix.config.cxx }} -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
make -j$(nproc)
- name: Run tests
@@ -247,7 +394,7 @@ jobs:
- name: Archive binary
uses: actions/upload-artifact@v3
with:
name: p2pool-msys2.exe
name: p2pool-msys2-${{ matrix.config.c }}.exe
path: build/p2pool.exe
build-windows-msbuild:
@@ -258,9 +405,9 @@ jobs:
strategy:
matrix:
config:
- {vs: Visual Studio 16 2019, os: 2019, msbuild: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Current\\Bin\\amd64\\", rx: "ON", upnp: "ON"}
- {vs: Visual Studio 16 2019, os: 2019, msbuild: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Current\\Bin\\amd64\\", rx: "OFF", upnp: "ON"}
- {vs: Visual Studio 16 2019, os: 2019, msbuild: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Current\\Bin\\amd64\\", rx: "OFF", upnp: "OFF"}
- {vs: Visual Studio 16 2019, os: 2019, vspath: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise", rx: "ON", upnp: "ON"}
- {vs: Visual Studio 16 2019, os: 2019, vspath: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise", rx: "OFF", upnp: "ON"}
- {vs: Visual Studio 16 2019, os: 2019, vspath: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise", rx: "OFF", upnp: "OFF"}
steps:
- name: Checkout repository
@@ -276,7 +423,23 @@ jobs:
mkdir build
cd build
cmake .. -G "${{ matrix.config.vs }}" -DWITH_RANDOMX=${{ matrix.config.rx }} -DWITH_UPNP=${{ matrix.config.upnp }}
& "${{ matrix.config.msbuild }}msbuild" /m /p:Configuration=Release p2pool.vcxproj
& "${{ matrix.config.vspath }}\\MSBuild\\Current\\Bin\\amd64\\msbuild" -v:m /m /p:Configuration=Release p2pool.vcxproj
- name: Check Windows 7 compatibility
shell: cmd
run: |
call "${{ matrix.config.vspath }}\\VC\\Auxiliary\\Build\\vcvarsall.bat" amd64
dumpbin /IMPORTS build/Release/p2pool.exe > 1.txt
findstr /R /C:"^ *[0-9A-F][0-9A-F]* [a-zA-Z][a-zA-Z0-9]*$" 1.txt > 2.txt
python tests/src/check_win7.py 2.txt
- name: Run RandomX tests
if: matrix.config.rx == 'ON'
run: |
build/Release/p2pool.exe --test
cd build/external/src/RandomX
& "${{ matrix.config.vspath }}\\MSBuild\\Current\\Bin\\amd64\\msbuild" -v:m /m /p:Configuration=Release randomx-tests.vcxproj
Release/randomx-tests.exe
- name: Build tests
run: |
@@ -284,7 +447,7 @@ jobs:
mkdir build
cd build
cmake .. -G "${{ matrix.config.vs }}"
& "${{ matrix.config.msbuild }}msbuild" /m /p:Configuration=Debug p2pool_tests.vcxproj
& "${{ matrix.config.vspath }}\\MSBuild\\Current\\Bin\\amd64\\msbuild" -v:m /m /p:Configuration=Debug p2pool_tests.vcxproj
- name: Run tests
run: |
@@ -295,17 +458,13 @@ jobs:
- name: Archive binary
uses: actions/upload-artifact@v3
with:
name: p2pool-msbuild-${{ matrix.config.os }}-randomx-${{ matrix.config.rx }}-upnp-${{ matrix.config.upnp }}.exe
name: p2pool-vs-${{ matrix.config.os }}-randomx-${{ matrix.config.rx }}-upnp-${{ matrix.config.upnp }}.exe
path: build/Release/p2pool.exe
build-macos:
timeout-minutes: 15
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-11, macos-12]
timeout-minutes: 20
runs-on: macos-11
steps:
- name: Checkout repository
@@ -313,13 +472,10 @@ jobs:
with:
submodules: recursive
- name: Install dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_C_FLAGS="-Os" -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_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
@@ -328,7 +484,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os' -DBUILD_TESTING=OFF
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
@@ -336,22 +492,27 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os' -DCMAKE_CXX_FLAGS='-Os' -DWITH_TLS=OFF -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DWITH_PERF_TOOL=OFF
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 .. -DSTATIC_BINARY=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
make -j3
- name: Run RandomX tests
run: |
build/p2pool --test
build/external/src/RandomX/randomx-tests
- name: Build tests
run: |
cd tests
mkdir build
cd build
cmake .. -DSTATIC_LIBS=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
make -j3
- name: Run tests
@@ -363,17 +524,13 @@ jobs:
- name: Archive binary
uses: actions/upload-artifact@v3
with:
name: p2pool-${{ matrix.os }}
name: p2pool-macos-11
path: build/p2pool
build-macos-aarch64:
timeout-minutes: 15
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-11, macos-12]
timeout-minutes: 20
runs-on: macos-11
steps:
- name: Checkout repository
@@ -381,13 +538,10 @@ jobs:
with:
submodules: recursive
- name: Install dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_C_FLAGS='-Os -target arm64-apple-${{ matrix.os }}' -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_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 -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
@@ -396,7 +550,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os -target arm64-apple-${{ matrix.os }}' -DBUILD_TESTING=OFF
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 -target arm64-apple-macos-11' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j3
- name: Build libzmq
@@ -404,20 +558,20 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os -target arm64-apple-${{ matrix.os }}' -DCMAKE_CXX_FLAGS='-Os -target arm64-apple-${{ matrix.os }}' -DWITH_TLS=OFF -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DWITH_PERF_TOOL=OFF
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 -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_FLAGS='-target arm64-apple-${{ matrix.os }}' -DCMAKE_CXX_FLAGS='-target arm64-apple-${{ matrix.os }}' -DSTATIC_BINARY=ON -DARCH_ID=aarch64
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="-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
uses: actions/upload-artifact@v3
with:
name: p2pool-${{ matrix.os }}-aarch64
name: p2pool-macos-11-aarch64
path: build/p2pool
build-freebsd:
@@ -440,7 +594,7 @@ jobs:
submodules: recursive
- name: Build p2pool
uses: cross-platform-actions/action@v0.10.0
uses: cross-platform-actions/action@v0.19.0
with:
operating_system: ${{ matrix.os.name }}
architecture: ${{ matrix.os.architecture }}
@@ -449,28 +603,30 @@ jobs:
run: |
sudo pkg install -y cmake
cd external/src/curl
cmake . -DCMAKE_C_FLAGS="-Os" -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 -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 -j2
cd lib && mkdir .libs && cp libcurl.a .libs
cd ../../libuv
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os' -DBUILD_TESTING=OFF
cmake .. -DCMAKE_C_FLAGS='-Os -flto' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j2
cd ../../libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_FLAGS='-Os' -DCMAKE_CXX_FLAGS='-Os' -DWITH_TLS=OFF -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DWITH_PERF_TOOL=OFF
cmake .. -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 -j2
cd ../../../..
mkdir build
cd build
cmake .. -DSTATIC_BINARY=ON
cmake .. -DCMAKE_C_FLAGS='-flto' -DCMAKE_CXX_FLAGS='-flto' -DSTATIC_LIBS=ON
make -j2
./p2pool --test
external/src/RandomX/randomx-tests
cd ../tests
mkdir build
cd build
cmake .. -DSTATIC_LIBS=ON
cmake .. -DCMAKE_C_FLAGS='-flto' -DCMAKE_CXX_FLAGS='-flto' -DSTATIC_LIBS=ON
make -j2
gunzip *.gz
./p2pool_tests
@@ -501,7 +657,7 @@ jobs:
submodules: recursive
- name: Build p2pool
uses: cross-platform-actions/action@v0.10.0
uses: cross-platform-actions/action@v0.19.0
with:
operating_system: ${{ matrix.os.name }}
architecture: ${{ matrix.os.architecture }}
+13 -7
View File
@@ -1,10 +1,16 @@
name: clang-tidy
on: [push, pull_request]
on:
push:
paths-ignore:
- 'docker-compose/**'
- 'docs/**'
- 'README.md'
pull_request:
jobs:
clang-tidy:
runs-on: ubuntu-22.04
steps:
@@ -17,9 +23,9 @@ jobs:
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 16
sudo apt-get install -y clang-tidy-16
clang-tidy-16 --verify-config
sudo ./llvm.sh 17
sudo apt-get install -y clang-tidy-17
clang-tidy-17 --verify-config
- name: Checkout repository
uses: actions/checkout@v3
@@ -30,9 +36,9 @@ jobs:
run: |
mkdir build
cd build
cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang-16 -DCMAKE_CXX_COMPILER=clang++-16 -DDEV_CLANG_TIDY=ON
cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 -DDEV_CLANG_TIDY=ON
- name: Run clang-tidy
run: |
cd src
clang-tidy-16 *.cpp -p ../build -checks=-clang-diagnostic-undefined-internal -warnings-as-errors=* -header-filter=^[^\.]
clang-tidy-17 *.cpp -p ../build -checks=-clang-diagnostic-undefined-internal -warnings-as-errors=* -header-filter=^[^\.]
+6
View File
@@ -13,7 +13,13 @@ name: "CodeQL"
on:
push:
paths-ignore:
- 'docker-compose/**'
- 'docs/**'
- 'README.md'
pull_request:
schedule:
- cron: '44 11 * * 0'
+6
View File
@@ -2,7 +2,13 @@ name: cppcheck
on:
push:
paths-ignore:
- 'docker-compose/**'
- 'docs/**'
- 'README.md'
pull_request:
schedule:
- cron: '57 0 * * *'
-36
View File
@@ -1,36 +0,0 @@
name: Build libc++ for MemorySanitizer
on: [workflow_dispatch]
jobs:
build-libcxx_msan:
runs-on: ubuntu-22.04
steps:
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y git cmake ninja-build
- name: Install clang
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 16
- name: Build libcxx_msan
run: |
git clone --depth=1 https://github.com/llvm/llvm-project -b release/16.x
cd llvm-project
mkdir build
cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" -DCMAKE_C_COMPILER=clang-16 -DCMAKE_CXX_COMPILER=clang++-16 -DLLVM_USE_SANITIZER=MemoryWithOrigins
ninja -C build cxx cxxabi
cd build
XZ_OPT=-e9 tar cfJ libcxx_msan.tar.xz include lib
- name: Archive libcxx_msan.tar.xz
uses: actions/upload-artifact@v3
with:
name: libcxx_msan
path: llvm-project/build/libcxx_msan.tar.xz
+6
View File
@@ -10,7 +10,13 @@ name: Microsoft C++ Code Analysis
on:
push:
paths-ignore:
- 'docker-compose/**'
- 'docs/**'
- 'README.md'
pull_request:
schedule:
- cron: '40 10 * * 0'
+24
View File
@@ -0,0 +1,24 @@
name: source-snapshot
on: [push, pull_request]
jobs:
source-snapshot:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: true
- name: Compress source code
run: |
mkdir build
XZ_OPT=-e9 tar --exclude=".git" --exclude="build" -f build/p2pool_source.tar.xz -c ../p2pool --xz
- name: Archive source code
uses: actions/upload-artifact@v3
with:
name: p2pool_source.tar.xz
path: build/p2pool_source.tar.xz
+156 -31
View File
@@ -2,7 +2,13 @@ name: Sync test
on:
push:
paths-ignore:
- 'docker-compose/**'
- 'docs/**'
- 'README.md'
pull_request:
schedule:
- cron: '17 0/3 * * *'
@@ -17,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
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
@@ -38,7 +67,11 @@ 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: |
cd build
grep 'Synchronization finished successfully' p2pool.log
- name: Archive p2pool.log
@@ -50,7 +83,6 @@ jobs:
build/data/
sync-test-ubuntu-msan:
timeout-minutes: 30
runs-on: ubuntu-22.04
@@ -58,30 +90,35 @@ jobs:
- name: Install dependencies
run: |
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
sudo apt install -y git build-essential cmake ninja-build
- name: Install clang
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 16
sudo ./llvm.sh 17
- name: Build libcxx_msan
run: |
git clone --depth=1 https://github.com/llvm/llvm-project -b release/17.x
cd llvm-project
mkdir build
cmake -G Ninja -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 -DLLVM_USE_SANITIZER=MemoryWithOrigins
ninja -C build cxx cxxabi
cd build
mkdir /tmp/libcxx_msan
cp -r include /tmp/libcxx_msan
cp -r lib /tmp/libcxx_msan
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: true
- name: Install libcxx_msan
run: |
mkdir /tmp/libcxx_msan
cp tests/src/libcxx_msan.tar.xz /tmp/libcxx_msan
cd /tmp/libcxx_msan
tar xvf libcxx_msan.tar.xz
- name: Build libcurl
run: |
cd external/src/curl
cmake . -DCMAKE_C_COMPILER=clang-16 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -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
cmake . -DCMAKE_C_COMPILER=clang-17 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -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
@@ -90,7 +127,7 @@ jobs:
cd external/src/libuv
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=clang-16 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -Os -fno-omit-frame-pointer -g' -DBUILD_TESTING=OFF
cmake .. -DCMAKE_C_COMPILER=clang-17 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -Os -fno-omit-frame-pointer -g' -DBUILD_TESTING=OFF -DLIBUV_BUILD_SHARED=OFF
make -j$(nproc)
- name: Build libzmq
@@ -98,14 +135,14 @@ jobs:
cd external/src/libzmq
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=clang-16 -DCMAKE_CXX_COMPILER=clang++-16 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -Os -fno-omit-frame-pointer -g' -DCMAKE_CXX_FLAGS='-nostdinc++ -nostdlib++ -fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -Os -fno-omit-frame-pointer -g -isystem /tmp/libcxx_msan/include/c++/v1 -L/tmp/libcxx_msan/lib -lc++ -lc++abi -Wno-unused-command-line-argument' -DWITH_TLS=OFF -DWITH_LIBSODIUM=OFF -DWITH_LIBBSD=OFF -DBUILD_TESTS=OFF -DWITH_DOCS=OFF -DENABLE_DRAFTS=OFF -DWITH_PERF_TOOL=OFF
cmake .. -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -Os -fno-omit-frame-pointer -g' -DCMAKE_CXX_FLAGS='-nostdinc++ -nostdlib++ -fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -Os -fno-omit-frame-pointer -g -isystem /tmp/libcxx_msan/include/c++/v1 -L/tmp/libcxx_msan/lib -lc++ -lc++abi -Wno-unused-command-line-argument' -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 .. -DCMAKE_C_COMPILER=clang-16 -DCMAKE_CXX_COMPILER=clang++-16 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -fno-omit-frame-pointer -g' -DCMAKE_CXX_FLAGS='-nostdinc++ -nostdlib++ -fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -isystem /tmp/libcxx_msan/include/c++/v1 -L/tmp/libcxx_msan/lib -Wl,-rpath /tmp/libcxx_msan/lib -lc++ -lc++abi -Wno-unused-command-line-argument -fuse-ld=lld-16 -fno-omit-frame-pointer -g' -DDEV_TEST_SYNC=ON -DDEV_WITH_MSAN=ON -DSTATIC_LIBS=ON
cmake .. -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 -DCMAKE_C_FLAGS='-fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -fno-omit-frame-pointer -g' -DCMAKE_CXX_FLAGS='-nostdinc++ -nostdlib++ -fsanitize=memory -fsanitize-recover -fsanitize-memory-track-origins -isystem /tmp/libcxx_msan/include/c++/v1 -L/tmp/libcxx_msan/lib -Wl,-rpath /tmp/libcxx_msan/lib -lc++ -lc++abi -Wno-unused-command-line-argument -fuse-ld=lld-17 -fno-omit-frame-pointer -g' -DDEV_TEST_SYNC=ON -DDEV_WITH_MSAN=ON -DSTATIC_LIBS=ON
make -j$(nproc)
- name: Run p2pool
@@ -115,7 +152,11 @@ 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: |
cd build
grep 'Synchronization finished successfully' p2pool.log
- name: Archive p2pool.log
@@ -147,7 +188,7 @@ jobs:
run: |
mkdir build
cd build
cmake .. -DDEV_TEST_SYNC=ON -DDEV_WITH_UBSAN=ON -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12
cmake .. -DDEV_TEST_SYNC=ON -DDEV_WITH_UBSAN=ON -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12 -DCMAKE_C_FLAGS="-flto=2" -DCMAKE_CXX_FLAGS="-flto=2"
make -j$(nproc)
- name: Run p2pool
@@ -157,7 +198,11 @@ 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: |
cd build
grep 'Synchronization finished successfully' p2pool.log
- name: Archive p2pool.log
@@ -189,7 +234,7 @@ jobs:
run: |
mkdir build
cd build
cmake .. -DDEV_TEST_SYNC=ON -DDEV_WITH_ASAN=ON -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12
cmake .. -DDEV_TEST_SYNC=ON -DDEV_WITH_ASAN=ON -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12 -DCMAKE_C_FLAGS="-flto=2" -DCMAKE_CXX_FLAGS="-flto=2"
make -j$(nproc)
- name: Run p2pool
@@ -199,7 +244,11 @@ 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: |
cd build
grep 'Synchronization finished successfully' p2pool.log
- name: Archive p2pool.log
@@ -213,7 +262,7 @@ jobs:
sync-test-macos:
timeout-minutes: 30
runs-on: macos-12
runs-on: macos-11
steps:
- name: Checkout repository
@@ -222,23 +271,52 @@ jobs:
submodules: recursive
- name: Install dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake libuv zmq libpgm curl
run: |
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
run: |
cd build
mkdir data
python ../tests/src/stratum_dummy.py 1 &
python ../tests/src/stratum_dummy.py 2 &
python ../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
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 --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log
run: |
cd build
grep 'Synchronization finished successfully' p2pool.log
- name: Archive p2pool.log
@@ -268,7 +346,7 @@ jobs:
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022" -DDEV_TEST_SYNC=ON
& "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Current\\Bin\\amd64\\msbuild" /m /p:Configuration=Debug p2pool.vcxproj
& "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Current\\Bin\\amd64\\msbuild" -v:m /m /p:Configuration=Debug p2pool.vcxproj
- name: Run p2pool
run: |
@@ -277,7 +355,11 @@ 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: |
cd build/Debug
findstr /C:"Synchronization finished successfully" p2pool.log
- name: Archive p2pool.log
@@ -287,3 +369,46 @@ jobs:
path: |
build/Debug/*.log
build/Debug/data/
sync-test-windows-leaks:
timeout-minutes: 30
runs-on: windows-2022
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: recursive
- name: Setup cmake
uses: lukka/get-cmake@latest
- name: Build p2pool
run: |
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022" -DDEV_TEST_SYNC=ON -DDEV_TRACK_MEMORY=ON
& "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Current\\Bin\\amd64\\msbuild" -v:m /m /p:Configuration=RelWithDebInfo p2pool.vcxproj
- name: Run p2pool
run: |
cd build/RelWithDebInfo
mkdir data
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 --mini --out-peers 200 --data-api data --local-api --loglevel 6
- name: Check p2pool.log
run: |
cd build/RelWithDebInfo
findstr /C:"Synchronization finished successfully" p2pool.log
- name: Archive p2pool.log
uses: actions/upload-artifact@v3
with:
name: p2pool_windows_data_leaks
path: |
build/RelWithDebInfo/*.log
build/RelWithDebInfo/data/
+18 -2
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.5)
project(p2pool)
option(STATIC_BINARY "Build static binary" OFF)
@@ -13,6 +13,7 @@ option(DEV_WITH_MSAN "[Developer only] Compile with memory sanitizer" OFF)
option(DEV_WITH_UBSAN "[Developer only] Compile with undefined behavior sanitizer" OFF)
option(DEV_WITH_ASAN "[Developer only] Compile with address sanitizer" OFF)
option(DEV_CLANG_TIDY "[Developer only] Compile for clang-tidy" OFF)
option(DEV_TRACK_MEMORY "[Developer only] Track memory allocations" OFF)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
@@ -56,6 +57,10 @@ if (DEV_CLANG_TIDY)
add_definitions(-DDEV_CLANG_TIDY)
endif()
if (DEV_TRACK_MEMORY)
add_definitions(-DDEV_TRACK_MEMORY)
endif()
include(cmake/flags.cmake)
set(HEADERS
@@ -159,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)
@@ -313,6 +320,8 @@ if (STATIC_BINARY OR STATIC_LIBS)
endif()
endif()
set(STATIC_LIBS "")
if (WITH_RANDOMX)
set(STATIC_LIBS randomx)
endif()
@@ -323,7 +332,7 @@ if (STATIC_BINARY OR STATIC_LIBS)
if (WIN32)
set(STATIC_LIBS ${STATIC_LIBS} ws2_32 iphlpapi userenv psapi dnsapi dbghelp)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
if ((CMAKE_CXX_COMPILER_ID MATCHES GNU) OR (CMAKE_CXX_COMPILER_ID MATCHES Clang))
set(STATIC_LIBS ${STATIC_LIBS} bcrypt)
endif()
elseif (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
@@ -350,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}
")
+23 -20
View File
@@ -22,7 +22,7 @@ These are 3rd-party pages. If they are down, it doesn't mean there is a problem
# Contents
- [Pool mining vs Solo mining vs P2Pool mining](#pool-mining-vs-solo-mining-vs-p2pool-mining)
- [Features](#features)
- [How PPLNS works in P2Pool](#how-pplns-works-in-p2pool)
- [How payouts work in P2Pool](#how-payouts-work-in-p2pool)
- [Default P2Pool parameters](#default-p2pool-parameters)
- [Monero version support](#monero-version-support)
- [How to mine on P2Pool](#how-to-mine-on-p2pool)
@@ -41,17 +41,17 @@ Here's the comparison table of the different ways of mining. While pool mining i
|-|-|-|-|-|-|-|-|
|Centralized pool|Regular|0-3%|0.001-0.01 XMR|Yes|Less stable due to pool server outages|Pool admin controls your mined funds, what you mine and can execute network attacks|Only miner software is required
|Solo|Rare|0%|0.6 XMR or more|No|As stable as your Monero node|100% under your control|Monero node + optional miner
|**P2Pool**|Regular|0%|~0.00027 XMR|No|Very stable: node failover and multiple Monero nodes are supported|100% under your control|Monero node(s) + P2Pool node(s) + miner(s)
|**P2Pool**|Regular|0%|~0.00027 XMR|No|Very stable: node failover and multiple Monero nodes are supported|100% under your control|Monero node(s) + P2Pool node(s) + optional miner(s)
## Features
* Decentralized: no central server that can be shutdown/blocked. P2Pool uses a separate blockchain to merge mine with Monero. Pool admin can't go rogue or be pressured to do an attack on the network because there is no pool admin!
* Permissionless: there is no one to decide who can mine on the pool and who can't.
* Trustless: there is no pool wallet, funds are never in custody. All pool blocks pay out to miners immediately.
* Trustless: there is no pool wallet, funds are never in custody. All pool blocks pay out to miners directly.
* PPLNS payout scheme
* **0% fee**
* **0 XMR payout fee**
* **~0.0003 XMR minimal payout**
* **~0.00027 XMR minimal payout**
* Fast block times, down to 1 second
* Uncle blocks are supported to avoid orphans - all your shares will be accounted for!
* Configurable PPLNS window size and block time
@@ -59,25 +59,28 @@ Here's the comparison table of the different ways of mining. While pool mining i
* Password protected private pools
* Highly reliable configurations are supported (multiple P2Pool nodes mining to the same wallet, each P2Pool node can use multiple Monero nodes and switch on the fly if an issue is detected)
## How PPLNS works in P2Pool
## How payouts work in P2Pool
First you need to find a pool share. This share will stay in PPLNS window for 2160 pool blocks (6 hours). The moment P2Pool finds a Monero block and you have at least 1 pool share in PPLNS window, you'll get a payout! Monero block reward is split between all miner wallets in PPLNS window. Each miner gets a part of block reward proportional to the total difficulty of his/her shares in PPLNS window.
First you need to find a pool share. This share will stay in [PPLNS](https://en.wikipedia.org/wiki/Mining_pool#Pay-per-last-N-shares) window for up to 2160 pool blocks (6 hours, auto adjustable to balance payout sizes and frequency). The moment P2Pool finds a Monero block and you have at least 1 pool share in PPLNS window, you'll get a payout! Monero block reward is split between all miner wallets in PPLNS window. Each miner gets a part of block reward proportional to the total difficulty of his/her shares in PPLNS window.
**NOTE** If P2Pool doesn't have enough hashrate to find Monero blocks faster than every 6 hours on average (~15 MH/s), **not all your pool shares will result in a payout**. Even if pool hashrate is higher, bad luck can sometimes result in a share going through PPLNS window without a payout. But in the long run it will be compensated by other shares receiving multiple payouts - your payouts will average out to what you'd get with regular pool mining.
## Default P2Pool parameters
* Block time: 10 seconds
* PPLNS window: up to 2160 blocks (6 hours), auto adjustable to balance payout sizes and frequency
* Minimum payout = Monero block reward/2160, ~0.0003 XMR
* PPLNS window: up to 2160 blocks (6 hours, auto adjustable to balance payout sizes and frequency)
* Minimum payout = Monero block reward/2160, ~0.00027 XMR
## Monero version support
Monero network upgrade happened on August 13th, 2022 (block 2,688,888). In order to continue mining, you must update both Monero and P2Pool software to the latest available versions as soon as they are released.
- The latest Monero network upgrade happened on August 13th, 2022 (block 2,688,888).
- The latest P2Pool network upgrade happened on March 18th, 2023 at 21:00 UTC.
In order to continue mining on P2Pool, you must update both Monero and P2Pool software to the latest available versions as soon as they are released.
|Monero protocol version|Required Monero software version|Required P2Pool version
|-|-|-|
|v15, v16 (active after August 13th, 2022)|v0.18.0.0 or newer, v0.18.2.2 recommended|v3.0 or newer
|v15, v16 (active after August 13th, 2022)|v0.18.0.0 or newer, v0.18.3.1 is recommended|v3.0 or newer
## How to mine on P2Pool
@@ -85,7 +88,7 @@ Monero network upgrade happened on August 13th, 2022 (block 2,688,888). In order
- In order to mine on P2Pool, a synced Monero node using monerod v0.18.0.0 or newer is required. If you don't currently have one, you can download the official Monero binaries, start `monerod` on your PC and wait until it's fully synced. Advanced Monero node setup instructions are [here](https://sethforprivacy.com/guides/run-a-monero-node-advanced/).
- It is highly recommended that you create a separate restricted user account (in your OS) for mining. While P2Pool has been battle-tested for a long time now, any software may have unknown bugs/vulnerabilities.
- You have to use a primary wallet address for mining. Subaddresses and integrated addresses are not supported, just like with monerod solo mining.
- You have to use a primary wallet address (the one starting with `4`) for mining. Subaddresses and integrated addresses are not supported, just like with monerod solo mining.
- You can add the `--mini` parameter to your P2Pool command to connect to the **p2pool-mini** sidechain. Note that it will also change the default p2p port from 37889 to 37888.
- Check that ports 18080 (Monero p2p port) and 37889/37888 (P2Pool/P2Pool mini p2p port) are open in your firewall to ensure better connectivity. If you're mining from a computer behind NAT (like a router) you could consider forwarding the ports to your local machine.
- You can connect multiple miners to the same P2Pool node. The more the better!
@@ -109,21 +112,21 @@ Monero network upgrade happened on August 13th, 2022 (block 2,688,888). In order
1. Download the latest P2Pool binaries [here](https://github.com/SChernykh/p2pool/releases/latest).
- Alternatively, grab the latest source code for P2Pool and [build it](#build-instructions).
2. Download the latest XMRig (linux-static-x64) binary [here](https://github.com/xmrig/xmrig/releases/latest).
3. Prepare enough huge pages (required for each instance of monerod/P2Pool/XMRig):
3. Prepare enough huge pages (each of monerod/P2Pool/XMRig needs them):
```
sudo sysctl vm.nr_hugepages=3072
```
4. Check that ports 18080 (Monero p2p port) and 37889/37888 (P2Pool/P2Pool mini p2p port) are open in your local firewall to ensure better connectivity.
5. Start `monerod` with the following command/options:
```
./monerod --zmq-pub tcp://127.0.0.1:18083 --out-peers 64 --in-peers 32 --add-priority-node=node.supportxmr.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist
./monerod --zmq-pub tcp://127.0.0.1:18083 --out-peers 32 --in-peers 64 --add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist
```
**Note:**
The `--zmq-pub` option is required for P2Pool to work properly.
`--out-peers 64 --in-peers 32` is needed to (1) have many connections to other nodes and (2) limit incoming connection count because it can grow uncontrollably and cause problems when it goes above 1000 (open files limit in Linux). If your network connection's **upload** bandwidth is less than **10 Mbit**, use `--out-peers 16 --in-peers 8` instead.
`--out-peers 32 --in-peers 64` is needed to (1) have many connections to other nodes and (2) limit incoming connection count because it can grow uncontrollably and cause problems when it goes above 1000 (open files limit in Linux). If your network connection's **upload** bandwidth is less than **10 Mbit**, use `--out-peers 8 --in-peers 16` instead.
`--add-priority-node=node.supportxmr.com:18080 --add-priority-node=nodes.hashvault.pro:18080` is needed to have guaranteed good working nodes in your connected peers.
`--add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080` is needed to have guaranteed good working nodes in your connected peers.
`--disable-dns-checkpoints` is needed to avoid periodical lags when DNS is updated (it's not needed when mining)
@@ -174,7 +177,7 @@ nocreate
2. Download the latest XMRig binary [here](https://github.com/xmrig/xmrig/releases/latest).
3. Expand the P2Pool binaries into an appropriate location (`%USERPROFILE%/bin` or `C:/bin/` are good options)
4. Expand XMRig binary into an appropriate location (the same folder as P2Pool is fine).
5. Prepare huge pages to work properly (each instance of monerod/P2Pool/XMRig needs them):
5. Prepare huge pages to work properly (each of monerod/P2Pool/XMRig needs them):
- On Windows 10 or above, run XMRig at least once as Administrator (right-click Run As Administrator)
- On earlier versions of Windows, you'll need to run XMRig as Administrator at least once per login.
6. Create "Monero" folder inside extracted P2Pool folder and copy Monero binaries there.
@@ -184,14 +187,14 @@ nocreate
8. Start `monerod` with the following command/options:
```
.\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --out-peers 64 --in-peers 32 --add-priority-node=node.supportxmr.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist
.\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --out-peers 32 --in-peers 64 --add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist
```
**Note:**
The `--zmq-pub` option is required for P2Pool to work properly.
`--out-peers 64 --in-peers 32` is needed to (1) have many connections to other nodes and (2) limit incoming connection count because it can grow uncontrollably and cause problems when it goes above 1000 (open files limit in Linux). If your network connection's **upload** bandwidth is less than **10 Mbit**, use `--out-peers 16 --in-peers 8` instead.
`--out-peers 32 --in-peers 64` is needed to (1) have many connections to other nodes and (2) limit incoming connection count because it can grow uncontrollably and cause problems when it goes above 1000 (open files limit in Linux). If your network connection's **upload** bandwidth is less than **10 Mbit**, use `--out-peers 8 --in-peers 16` instead.
`--add-priority-node=node.supportxmr.com:18080 --add-priority-node=nodes.hashvault.pro:18080` is needed to have guaranteed good working nodes in your connected peers.
`--add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080` is needed to have guaranteed good working nodes in your connected peers.
`--disable-dns-checkpoints` is needed to avoid periodical lags when DNS is updated (it's not needed when mining)
@@ -215,7 +218,7 @@ The `--zmq-pub` option is required for P2Pool to work properly.
13. *(Optional but highly recommended)* You can create a Quickstart by creating a batch (.bat) file with the following contents and placing it in your P2Pool directory along with `xmrig.exe`.
```
@ECHO OFF
start cmd /k %~dp0\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --out-peers 64 --in-peers 32 --add-priority-node=node.supportxmr.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist
start cmd /k %~dp0\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --out-peers 32 --in-peers 64 --add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist
ECHO Wait until the Monero daemon shows fully synced before continuing. This can take some time. Type 'status' in other window to check progress.
PAUSE
start cmd /k %~dp0\p2pool.exe --wallet YOUR_WALLET_ADDRESS --mini
+30 -3
View File
@@ -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()
@@ -20,7 +35,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(GENERAL_FLAGS "${GENERAL_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
endif()
set(WARNING_FLAGS "-Wall -Wextra -Wcast-align -Wcast-qual -Wlogical-op -Wstrict-overflow=2 -Wundef -Wformat=2 -Wpointer-arith -Werror")
set(WARNING_FLAGS "-Wall -Wextra -Wcast-qual -Wlogical-op -Wstrict-overflow=2 -Wundef -Wformat=2 -Wpointer-arith -Werror")
if (DEV_WITH_TSAN OR DEV_WITH_UBSAN OR DEV_WITH_ASAN)
set(OPTIMIZATION_FLAGS "-O2 -g")
@@ -68,10 +83,22 @@ 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)
set(GENERAL_FLAGS "-pthread")
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 (NOT DEV_WITH_MSAN)
if (DEV_WITH_MSAN)
set(OPTIMIZATION_FLAGS "-O2 -g")
else()
set(OPTIMIZATION_FLAGS "-Ofast -funroll-loops -fmerge-all-constants")
endif()
+1 -1
View File
@@ -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",
],
+4 -3
View File
@@ -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
@@ -119,10 +120,10 @@ services:
--zmq-pub tcp://0.0.0.0:18083
--disable-dns-checkpoints
--enable-dns-blocklist
--out-peers 32
--in-peers 16
--out-peers 16
--in-peers 32
--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
+3 -3
View File
@@ -96,10 +96,10 @@ services:
--zmq-pub tcp://0.0.0.0:18083
--disable-dns-checkpoints
--enable-dns-blocklist
--out-peers 32
--in-peers 16
--out-peers 16
--in-peers 32
--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
+20
View File
@@ -0,0 +1,20 @@
### P2Pool console commands
Command|Description
-|-
help|display list of commands
status|display p2pool status
loglevel **N**|set log level (**N** can be between 0 and 6)
addpeers **L**|**L** is a comma-separated list of IP:port of other p2pool nodes to connect to
droppeers|disconnect all currently connected peers
peers|show all currently connected peers (p2p)
workers|show all currently connected workers (stratum)
bans|show all banned IPs
hosts|show Monero hosts which were configured in the command line
next_host|switch to the next Monero host configured in the command line
outpeers **N**|set maximum number of outgoing connections (values above 50 are not recommended)
inpeers **N**|set maximum number of incoming connections (values above 50 are not recommended)
start_mining **T**|start mining (**T** is the number of threads to use, must be between 1 and 64)
stop_mining|stop mining
exit|terminate p2pool
version|show p2pool version
+11 -3
View File
@@ -80,16 +80,22 @@ async function load_data() {
let pool_stats_req = await fetch('api/pool/stats');
let pool_blocks_req = await fetch('api/pool/blocks');
let network_stats_req = await fetch('api/network/stats');
let latest_release_req = await fetch('api/latest_release');
let pool_stats = JSON.parse(await pool_stats_req.text());
let pool_blocks = JSON.parse(await pool_blocks_req.text());
let network_stats = JSON.parse(await network_stats_req.text());
let latest_release = JSON.parse(await latest_release_req.text());
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';
document.getElementById("latest_release").innerHTML = '<a href="' + latest_release.html_url + '" target="_blank">' + latest_release.name + '</a>';
let ts = Math.floor(Date.now() / 1000);
@@ -188,6 +194,7 @@ function toggle_menu(name) {
</head>
<body onload="load_data();setInterval(load_data, 2000);toggle_menu(window.location.hash.substr(1));">
<div style="font-size:3rem;text-align:center;">P2Pool</div><div style="font-size:1.1rem;text-align:center;">Decentralized Monero mining pool</div>
<div style="font-size:1rem;text-align:center;">Latest release: <span id="latest_release"><a href="https://github.com/SChernykh/p2pool/releases/latest" target="_blank">P2Pool</a></span></div>
<br>
<table id="main_menu" style="width:100%;margin-left:auto;margin-right:auto;table-layout:fixed;text-align:center;-ms-touch-action:none;touch-action:none;"><tr>
<td onclick="toggle_menu('pool')" id="button_pool">Pool</td>
@@ -208,7 +215,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>&nbsp;</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>&nbsp;</td><td></td><td></td></tr>
<tr><td>Statistics</td><td><a href="https://p2pool.observer/" target="_blank">P2Pool observer</a></td><td></td></tr>
@@ -241,8 +248,8 @@ It's highly recommended to create a new wallet for mining because wallet address
<ul>
<li>Download the latest Monero <a href="https://www.getmonero.org/downloads/" target="_blank">release</a>
<li>[Optional] Open port <span>18080</span> (Monero p2p port) in your firewall to ensure better connectivity
<li>Run <span>./monerod --zmq-pub tcp://127.0.0.1:18083 --out-peers 64 --in-peers 32 --add-priority-node=node.supportxmr.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist</span>
<li>If your network connection's upload bandwidth is less than 10 Mbit, use <span>--out-peers 16 --in-peers 8</span> instead.
<li>Run <span>./monerod --zmq-pub tcp://127.0.0.1:18083 --out-peers 32 --in-peers 64 --add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist</span>
<li>If your network connection's upload bandwidth is less than 10 Mbit, use <span>--out-peers 8 --in-peers 16</span> instead.
<li>Wait until it's fully synchronized. If you didn't run Monero node before, it can take up to several days to synchronize (5-6 hours on a modern PC with fast SSD and fast Internet connection). You can add <span>--prune-blockchain</span> argument to the command line to run a pruned node (3-4 times less disk usage)
</ul></details>
@@ -260,6 +267,7 @@ It's highly recommended to create a new wallet for mining because wallet address
<li>Once P2Pool sync is complete, XMRig should be able to connect to the stratum server on port <span>3333</span>
<li>Run <span>./xmrig -o 127.0.0.1:3333</span>. Note that you don't need to specify wallet address for xmrig. Wallet address set in xmrig config will be ignored!
<li>To set custom fixed difficulty for your miner (for example, <span>10000</span>), run <span>./xmrig -u x+10000 -o 127.0.0.1:3333</span>
<li>To connect another mining rig to your P2Pool node, run <span>./xmrig -o YOUR_P2POOL_NODE_IP:3333</span> on that mining rig
</ul></details>
<details><summary>Checking your progress</summary>
+12 -4
View File
@@ -80,16 +80,22 @@ async function load_data() {
let pool_stats_req = await fetch('api/pool/stats');
let pool_blocks_req = await fetch('api/pool/blocks');
let network_stats_req = await fetch('api/network/stats');
let latest_release_req = await fetch('api/latest_release');
let pool_stats = JSON.parse(await pool_stats_req.text());
let pool_blocks = JSON.parse(await pool_blocks_req.text());
let network_stats = JSON.parse(await network_stats_req.text());
let latest_release = JSON.parse(await latest_release_req.text());
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';
document.getElementById("latest_release").innerHTML = '<a href="' + latest_release.html_url + '" target="_blank">' + latest_release.name + '</a>';
let ts = Math.floor(Date.now() / 1000);
@@ -188,6 +194,7 @@ function toggle_menu(name) {
</head>
<body onload="load_data();setInterval(load_data, 2000);toggle_menu(window.location.hash.substr(1));">
<div style="font-size:3rem;text-align:center;">P2Pool mini</div><div style="font-size:1.1rem;text-align:center;">Decentralized Monero mining pool</div>
<div style="font-size:1rem;text-align:center;">Latest release: <span id="latest_release"><a href="https://github.com/SChernykh/p2pool/releases/latest" target="_blank">P2Pool</a></span></div>
<br>
<table id="main_menu" style="width:100%;margin-left:auto;margin-right:auto;table-layout:fixed;text-align:center;-ms-touch-action:none;touch-action:none;"><tr>
<td onclick="toggle_menu('pool')" id="button_pool">Pool</td>
@@ -208,7 +215,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>&nbsp;</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>&nbsp;</td><td></td><td></td></tr>
<tr><td>Statistics</td><td><a href="https://mini.p2pool.observer/" target="_blank">P2Pool observer</a></td><td></td></tr>
@@ -241,8 +248,8 @@ It's highly recommended to create a new wallet for mining because wallet address
<ul>
<li>Download the latest Monero <a href="https://www.getmonero.org/downloads/" target="_blank">release</a>
<li>[Optional] Open port <span>18080</span> (Monero p2p port) in your firewall to ensure better connectivity
<li>Run <span>./monerod --zmq-pub tcp://127.0.0.1:18083 --out-peers 64 --in-peers 32 --add-priority-node=node.supportxmr.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist</span>
<li>If your network connection's upload bandwidth is less than 10 Mbit, use <span>--out-peers 16 --in-peers 8</span> instead.
<li>Run <span>./monerod --zmq-pub tcp://127.0.0.1:18083 --out-peers 32 --in-peers 64 --add-priority-node=p2pmd.xmrvsbeast.com:18080 --add-priority-node=nodes.hashvault.pro:18080 --disable-dns-checkpoints --enable-dns-blocklist</span>
<li>If your network connection's upload bandwidth is less than 10 Mbit, use <span>--out-peers 8 --in-peers 16</span> instead.
<li>Wait until it's fully synchronized. If you didn't run Monero node before, it can take up to several days to synchronize (5-6 hours on a modern PC with fast SSD and fast Internet connection). You can add <span>--prune-blockchain</span> argument to the command line to run a pruned node (3-4 times less disk usage)
</ul></details>
@@ -260,6 +267,7 @@ It's highly recommended to create a new wallet for mining because wallet address
<li>Once P2Pool sync is complete, XMRig should be able to connect to the stratum server on port <span>3333</span>
<li>Run <span>./xmrig -o 127.0.0.1:3333</span>. Note that you don't need to specify wallet address for xmrig. Wallet address set in xmrig config will be ignored!
<li>To set custom fixed difficulty for your miner (for example, <span>10000</span>), run <span>./xmrig -u x+10000 -o 127.0.0.1:3333</span>
<li>To connect another mining rig to your P2Pool node, run <span>./xmrig -o YOUR_P2POOL_NODE_IP:3333</span> on that mining rig
</ul></details>
<details><summary>Checking your progress</summary>
@@ -306,4 +314,4 @@ Donate to support the project:<br><a href="monero:44MnN1f3Eto8DZYUWuE5XZNUtE3vcR
&nbsp;
</div>
</body>
</html>
</html>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -20,7 +20,7 @@
#include "pool_block.h"
#include "p2p_server.h"
static constexpr char log_category_prefix[] = "BlockCache ";
LOG_CATEGORY(BlockCache)
static constexpr uint32_t BLOCK_SIZE = 96 * 1024;
static constexpr uint32_t NUM_BLOCKS = 4608;
+2 -2
View File
@@ -32,7 +32,7 @@
#include <ctime>
#include <numeric>
static constexpr char log_category_prefix[] = "BlockTemplate ";
LOG_CATEGORY(BlockTemplate)
namespace p2pool {
@@ -646,7 +646,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
// Layout: [software id, version, random number, sidechain extra_nonce]
uint32_t* sidechain_extra = m_poolBlockTemplate->m_sidechainExtraBuf;
sidechain_extra[0] = 0;
sidechain_extra[0] = static_cast<uint32_t>(SoftwareID::P2Pool);
#ifdef P2POOL_SIDECHAIN_EXTRA_1
sidechain_extra[1] = P2POOL_SIDECHAIN_EXTRA_1;
#else
+17 -5
View File
@@ -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);
@@ -152,8 +161,8 @@ struct alignas(uint64_t) hash
FORCEINLINE bool operator<(const hash& other) const
{
const uint64_t* a = reinterpret_cast<const uint64_t*>(h);
const uint64_t* b = reinterpret_cast<const uint64_t*>(other.h);
const uint64_t* a = u64();
const uint64_t* b = other.u64();
if (a[3] < b[3]) return true;
if (a[3] > b[3]) return false;
@@ -169,18 +178,21 @@ struct alignas(uint64_t) hash
FORCEINLINE bool operator==(const hash& other) const
{
const uint64_t* a = reinterpret_cast<const uint64_t*>(h);
const uint64_t* b = reinterpret_cast<const uint64_t*>(other.h);
const uint64_t* a = u64();
const uint64_t* b = other.u64();
return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
}
FORCEINLINE bool operator!=(const hash& other) const { return !operator==(other); }
FORCEINLINE bool empty() const {
const uint64_t* a = reinterpret_cast<const uint64_t*>(h);
const uint64_t* a = u64();
return (a[0] == 0) && (a[1] == 0) && (a[2] == 0) && (a[3] == 0);
}
FORCEINLINE uint64_t* u64() { return reinterpret_cast<uint64_t*>(h); }
FORCEINLINE const uint64_t* u64() const { return reinterpret_cast<const uint64_t*>(h); }
friend std::ostream& operator<<(std::ostream& s, const hash& d);
friend std::istream& operator>>(std::istream& s, hash& d);
};
+75 -42
View File
@@ -28,7 +28,7 @@
#include "p2pool_api.h"
#include "params.h"
static constexpr char log_category_prefix[] = "ConsoleCommands ";
LOG_CATEGORY(ConsoleCommands)
static constexpr int DEFAULT_BACKLOG = 1;
@@ -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,14 @@ 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
{
return log_category_prefix;
}
typedef struct strconst {
@@ -182,13 +202,20 @@ static void do_status(p2pool *m_pool, const char * /* args */)
if (m_pool->stratum_server()) {
m_pool->stratum_server()->print_status();
}
if (m_pool->p2p_server()) {
m_pool->p2p_server()->print_status();
P2PServer* p2p = m_pool->p2p_server();
if (p2p) {
p2p->print_status();
}
#ifdef WITH_RANDOMX
m_pool->print_miner_status();
#endif
bkg_jobs_tracker.print_status();
if (p2p) {
p2p->check_for_updates(true);
}
}
static void do_loglevel(p2pool * /* m_pool */, const char *args)
@@ -292,9 +319,15 @@ static void do_exit(p2pool *m_pool, const char * /* args */)
m_pool->stop();
}
static void do_version(p2pool* /* m_pool */, const char* /* args */)
// cppcheck-suppress constParameterCallback
static void do_version(p2pool* m_pool, const char* /* args */)
{
LOGINFO(0, log::LightCyan() << VERSION);
const P2PServer* p2p = m_pool->p2p_server();
if (p2p) {
p2p->check_for_updates(true);
}
}
void ConsoleCommands::allocCallback(uv_handle_t* handle, size_t /*suggested_size*/, uv_buf_t* buf)
+1 -1
View File
@@ -50,7 +50,7 @@ public:
void on_shutdown() override;
private:
const char* get_category() const override { return "ConsoleCommands "; }
const char* get_log_category() const override;
p2pool* m_pool;
+10 -2
View File
@@ -20,7 +20,7 @@
#include "json_rpc_request.h"
#include <curl/curl.h>
static constexpr char log_category_prefix[] = "JSONRPCRequest ";
LOG_CATEGORY(JSONRPCRequest)
namespace p2pool {
namespace JSONRPCRequest {
@@ -176,6 +176,8 @@ CurlContext::CurlContext(const std::string& address, int port, const std::string
} \
} while (0)
curl_easy_setopt_checked(m_handle, CURLOPT_BUFFERSIZE, 102400L);
curl_easy_setopt_checked(m_handle, CURLOPT_WRITEFUNCTION, write_func);
curl_easy_setopt_checked(m_handle, CURLOPT_WRITEDATA, this);
@@ -228,7 +230,9 @@ CurlContext::~CurlContext()
double tcp_ping = 0.0;
if (m_error.empty() && !m_response.empty()) {
tcp_ping = static_cast<double>(m_connectedTime - m_startTime) / 1000.0;
if (m_connectedTime) {
tcp_ping = static_cast<double>(m_connectedTime - m_startTime) / 1000.0;
}
(*m_callback)(m_response.data(), m_response.size(), tcp_ping);
}
delete m_callback;
@@ -371,6 +375,10 @@ void CurlContext::on_timeout(uv_handle_t* req)
size_t CurlContext::on_write(const void* buffer, size_t size, size_t count)
{
if (!m_connectedTime) {
m_connectedTime = microseconds_since_epoch();
}
const size_t realsize = size * count;
const char* p = reinterpret_cast<const char*>(buffer);
m_response.insert(m_response.end(), p, p + realsize);
+5 -1
View File
@@ -22,12 +22,14 @@
#include <fstream>
#include <thread>
#include <stdlib.h>
#include <clocale>
#ifdef _MSC_VER
#pragma warning(disable : 4996)
#endif
static constexpr char log_category_prefix[] = "Log ";
LOG_CATEGORY(Log)
static constexpr char log_file_name[] = "p2pool.log";
namespace p2pool {
@@ -62,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);
+26 -12
View File
@@ -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
@@ -162,6 +170,7 @@ template<> struct Stream::Entry<const char*>
template<> struct Stream::Entry<char*>
{
// cppcheck-suppress constParameterPointer
static FORCEINLINE void put(char* data, Stream* wrapper) { wrapper->writeBuf(data, strlen(data)); }
};
@@ -287,7 +296,10 @@ template<> struct log::Stream::Entry<const_buf>
struct hex_buf
{
FORCEINLINE hex_buf(const uint8_t* data, size_t size) : m_data(data), m_size(size) {}
FORCEINLINE hex_buf(const void* data, size_t size) : m_data(reinterpret_cast<const uint8_t*>(data)), m_size(size) {}
template<typename T>
explicit FORCEINLINE hex_buf(const T* data) : m_data(reinterpret_cast<const uint8_t*>(data)), m_size(sizeof(T)) {}
const uint8_t* m_data;
size_t m_size;
@@ -506,17 +518,19 @@ struct DummyStream
}
#endif
#define LOG_CATEGORY(category) static constexpr char log_category_prefix[] = #category " ";
#ifdef P2POOL_LOG_DISABLE
#define LOGINFO(level, ...) SIDE_EFFECT_CHECK(level, __VA_ARGS__)
#define LOGWARN(level, ...) SIDE_EFFECT_CHECK(level, __VA_ARGS__)
#define LOGERR(level, ...) SIDE_EFFECT_CHECK(level, __VA_ARGS__)
#define LOGINFO(level, ...) SIDE_EFFECT_CHECK(level, log_category_prefix << __VA_ARGS__)
#define LOGWARN(level, ...) SIDE_EFFECT_CHECK(level, log_category_prefix << __VA_ARGS__)
#define LOGERR(level, ...) SIDE_EFFECT_CHECK(level, log_category_prefix << __VA_ARGS__)
#else
#define LOG(level, severity, ...) \
do { \
SIDE_EFFECT_CHECK(level, __VA_ARGS__); \
SIDE_EFFECT_CHECK(level, log_category_prefix << __VA_ARGS__); \
if ((level) <= log::GLOBAL_LOG_LEVEL) { \
log::Writer CONCAT(log_wrapper_, __LINE__)(severity); \
CONCAT(log_wrapper_, __LINE__) << log::Gray() << log_category_prefix; \
+85 -3
View File
@@ -22,6 +22,10 @@
#include "p2p_server.h"
#include <curl/curl.h>
#ifdef WITH_RANDOMX
#include "randomx.h"
#endif
void p2pool_usage()
{
printf("P2Pool %s\n"
@@ -81,8 +85,80 @@ void p2pool_version()
printf("P2Pool %s\n", p2pool::VERSION);
}
void memory_tracking_start();
void memory_tracking_stop();
int p2pool_test()
{
#ifdef WITH_RANDOMX
const char myKey[] = "test key 000";
const char myInput[] = "This is a test";
char hash[RANDOMX_HASH_SIZE];
const randomx_flags flags = randomx_get_flags() | RANDOMX_FLAG_FULL_MEM;
randomx_cache* myCache = randomx_alloc_cache(flags);
if (!myCache) {
printf("Cache allocation failed\n");
return 1;
}
randomx_init_cache(myCache, myKey, sizeof(myKey) - 1);
randomx_dataset* myDataset = randomx_alloc_dataset(flags);
if (!myDataset) {
printf("Dataset allocation failed\n");
return 1;
}
{
const uint32_t numThreads = std::max(std::thread::hardware_concurrency(), 1U);
const uint32_t numItems = randomx_dataset_item_count();
std::vector<std::thread> threads;
threads.reserve(numThreads);
for (uint32_t i = 1; i < numThreads; ++i) {
const uint32_t a = (numItems * i) / numThreads;
const uint32_t b = (numItems * (i + 1)) / numThreads;
threads.emplace_back([myDataset, myCache, a, b]() { randomx_init_dataset(myDataset, myCache, a, b - a); });
}
randomx_init_dataset(myDataset, myCache, 0, numItems / numThreads);
for (std::thread& t : threads) {
t.join();
}
}
randomx_release_cache(myCache);
randomx_vm* myMachine = randomx_create_vm(flags, nullptr, myDataset);
if (!myMachine) {
printf("Failed to create a virtual machine");
return 1;
}
memset(hash, 0, sizeof(hash));
memcpy(hash, myInput, sizeof(myInput));
for (size_t i = 0; i < 100; ++i) {
randomx_calculate_hash(myMachine, &hash, sizeof(hash), hash);
}
char buf[RANDOMX_HASH_SIZE * 2 + 1] = {};
p2pool::log::Stream s(buf);
s << p2pool::log::hex_buf(hash, RANDOMX_HASH_SIZE) << '\0';
constexpr char expected_hash[] = "3b5ecc2bb14f467161a04fe476b541194fba82dbbbfc7c320961f922a0294dee";
if (memcmp(buf, expected_hash, RANDOMX_HASH_SIZE * 2) != 0) {
printf("Invalid hash calculated: expected %s, got %s\n", expected_hash, buf);
return 1;
}
randomx_destroy_vm(myMachine);
randomx_release_dataset(myDataset);
#endif
printf("Self-test passed\n");
return 0;
}
int main(int argc, char* argv[])
{
@@ -101,6 +177,10 @@ int main(int argc, char* argv[])
p2pool_version();
return 0;
}
if (!strcmp(argv[i], "--test")) {
return p2pool_test();
}
}
memory_tracking_start();
@@ -124,7 +204,9 @@ int main(int argc, char* argv[])
p2pool::destroy_crypto_cache();
memory_tracking_stop();
if (!memory_tracking_stop()) {
result = 1;
}
return result;
}
+17 -5
View File
@@ -18,11 +18,12 @@
#include "common.h"
// Simple memory leak detector for Windows users, works best in RelWithDebInfo configuration.
#if defined(_WIN32) && 0
#if defined(_WIN32) && defined(DEV_TRACK_MEMORY)
#include "uv_util.h"
#include <atomic>
#include <type_traits>
#include <iostream>
#include <DbgHelp.h>
@@ -87,7 +88,7 @@ uint32_t num_allocations = 0;
uint64_t total_allocated = 0;
uint32_t cur_allocation_index = 1;
void show_top_10()
void show_top_10_allocations()
{
TrackedAllocation* buf = reinterpret_cast<TrackedAllocation*>(VirtualAlloc(nullptr, sizeof(TrackedAllocation) * N, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
if (!buf) {
@@ -122,7 +123,8 @@ void show_top_10()
std::sort(buf, end, [](const auto& a, const auto& b) { return a.allocated_size > b.allocated_size; });
printf("%I64u total bytes allocated\n", total_allocated);
printf("%I64u total bytes allocated\n\n", total_allocated);
printf("Top 10 allocations:\n\n");
for (TrackedAllocation* p = buf; (p < buf + 10) && (p < end); ++p) {
printf("%I64u bytes allocated at:\n", p->allocated_size);
@@ -130,6 +132,8 @@ void show_top_10()
}
}
printf("\n");
VirtualFree(buf, 0, MEM_RELEASE);
}
@@ -263,6 +267,9 @@ void* calloc_hook(size_t count, size_t size) noexcept
void memory_tracking_start()
{
// Trigger std::ostream initialization to avoid reporting it as leaks
std::cout << "Memory leak detection = " << 1 << std::endl;
SymInitialize(GetCurrentProcess(), NULL, TRUE);
using namespace p2pool;
@@ -272,7 +279,7 @@ void memory_tracking_start()
track_memory = true;
}
void memory_tracking_stop()
bool memory_tracking_stop()
{
using namespace p2pool;
@@ -296,8 +303,13 @@ void memory_tracking_stop()
if (total_leaks > 0) {
printf("%I64u bytes leaked\n\n", total_leaks);
}
else {
printf("No memory leaks detected\n\n");
}
SymCleanup(h);
return (total_leaks == 0);
}
NOINLINE void* operator new(size_t n) { return p2pool::allocate(n); }
@@ -313,7 +325,7 @@ NOINLINE void operator delete[](void* p, size_t) noexcept { p2pool::free_hook(p)
// cppcheck-suppress functionStatic
void memory_tracking_start() {}
// cppcheck-suppress functionStatic
void memory_tracking_stop() {}
bool memory_tracking_stop() { return true; }
namespace p2pool {
+1 -1
View File
@@ -19,7 +19,7 @@
#include "mempool.h"
#include "util.h"
static constexpr char log_category_prefix[] = "Mempool ";
LOG_CATEGORY(Mempool)
namespace p2pool {
+13 -4
View File
@@ -28,7 +28,7 @@
#include "p2p_server.h"
#include <thread>
static constexpr char log_category_prefix[] = "Miner ";
LOG_CATEGORY(Miner)
using namespace std::chrono;
@@ -85,11 +85,11 @@ void Miner::print_status()
const uint64_t hr = (dt > 0.0) ? static_cast<uint64_t>(hash_count / dt) : 0;
char shares_failed_buf[64] = {};
log::Stream s(shares_failed_buf);
const uint32_t shares_found = m_sharesFound;
const uint32_t shares_failed = m_sharesFailed;
if (shares_failed) {
log::Stream s(shares_failed_buf);
s << log::Yellow() << "\nShares failed = " << shares_failed << log::NoColor();
}
@@ -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",
@@ -224,7 +224,16 @@ void Miner::run(WorkerData* data)
job[index].set_nonce(static_cast<uint32_t>(full_nonce), static_cast<uint32_t>(full_nonce >> 32));
hash h;
randomx_calculate_hash_next(vm, job[index].m_blob, job[index].m_blobSize, &h);
try {
randomx_calculate_hash_next(vm, job[index].m_blob, job[index].m_blobSize, &h);
}
catch (const std::exception& e) {
LOGERR(0, "Failed to calculate RandomX hash: exception \"" << e.what() << "\". Is your CPU/RAM unstable?" <<
"\nFailed RandomX hash input: " << log::hex_buf(j.m_blob, j.m_blobSize));
// Make the result hash all FF's to fail difficulty checks
memset(h.h, -1, HASH_SIZE);
}
if (j.m_diff.check_pow(h)) {
LOGINFO(0, log::Green() << "worker thread " << data->m_index << '/' << data->m_count << " found a mainchain block at height " << j.m_height << ", submitting it");
+311 -101
View File
@@ -31,10 +31,11 @@
#include <fstream>
#include <numeric>
static constexpr char log_category_prefix[] = "P2PServer ";
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;
@@ -58,6 +59,7 @@ P2PServer::P2PServer(p2pool* pool)
, m_peerListLastSaved(0)
, m_lookForMissingBlocks(true)
, m_fastestPeer(nullptr)
, m_newP2PoolVersionDetected(false)
{
m_callbackBuf.resize(P2P_BUF_SIZE);
m_blockDeserializeBuf.reserve(MAX_BLOCK_SIZE);
@@ -90,6 +92,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) {
@@ -148,6 +151,7 @@ P2PServer::~P2PServer()
uv_rwlock_destroy(&m_cachedBlocksLock);
uv_mutex_destroy(&m_connectToPeersLock);
uv_mutex_destroy(&m_showPeersLock);
delete m_block;
delete m_cache;
@@ -204,13 +208,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);
@@ -268,6 +271,9 @@ void P2PServer::update_peer_connections()
bool has_good_peers = false;
m_fastestPeer = nullptr;
uint64_t total_outgoing_p2pool = 0;
uint64_t newer_version_p2pool = 0;
unordered_set<raw_ip> connected_clients;
connected_clients.reserve(m_numConnections);
@@ -301,9 +307,17 @@ void P2PServer::update_peer_connections()
if ((client->m_pingTime >= 0) && (!m_fastestPeer || (m_fastestPeer->m_pingTime > client->m_pingTime))) {
m_fastestPeer = client;
}
if ((client->m_SoftwareID == SoftwareID::P2Pool) && client->m_SoftwareVersion && !client->m_isIncoming) {
++total_outgoing_p2pool;
if (client->m_SoftwareVersion > ((P2POOL_VERSION_MAJOR << 16) | P2POOL_VERSION_MINOR)) {
++newer_version_p2pool;
}
}
}
}
m_newP2PoolVersionDetected = newer_version_p2pool * 5 > total_outgoing_p2pool;
std::vector<Peer> peer_list;
{
MutexLock lock(m_peerListLock);
@@ -459,7 +473,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';
@@ -593,10 +607,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;
}
@@ -698,10 +713,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;
@@ -709,8 +727,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);
}
}
@@ -740,6 +758,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();
@@ -826,33 +855,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;
}
}
@@ -883,12 +900,28 @@ void P2PServer::on_broadcast()
{
uint8_t* p = buf;
bool send_pruned = true;
bool send_compact = (client->m_protocolVersion >= PROTOCOL_VERSION_1_1) && !data->compact_blob.empty() && (data->compact_blob.size() < data->pruned_blob.size());
const hash* a = client->m_broadcastedHashes;
const hash* b = client->m_broadcastedHashes + array_size(&P2PClient::m_broadcastedHashes);
// If this peer already broadcasted this block to us, we don't need to broadcast it back, we just need to notify the peer
if ((client->m_protocolVersion >= PROTOCOL_VERSION_1_2) && (std::find(a, b, data->id) != b)) {
LOGINFO(6, "sending BLOCK_NOTIFY to " << log::Gray() << static_cast<char*>(client->m_addrString));
if (buf_size < 1 + HASH_SIZE) {
return 0;
}
*(p++) = static_cast<uint8_t>(MessageId::BLOCK_NOTIFY);
memcpy(p, data->id.h, HASH_SIZE);
p += HASH_SIZE;
return p - buf;
}
bool send_pruned = true;
bool send_compact = (client->m_protocolVersion >= PROTOCOL_VERSION_1_1) && !data->compact_blob.empty() && (data->compact_blob.size() < data->pruned_blob.size());
for (const hash& id : data->ancestor_hashes) {
if (std::find(a, b, id) == b) {
send_pruned = false;
@@ -898,7 +931,7 @@ void P2PServer::on_broadcast()
}
if (send_pruned) {
LOGINFO(6, "sending BLOCK_BROADCAST (" << (send_compact ? "compact" : "pruned") << ") to " << log::Gray() << static_cast<char*>(client->m_addrString));
LOGINFO(6, "sending BLOCK_BROADCAST " << (send_compact ? "(compact)" : "(pruned) ") << " to " << log::Gray() << static_cast<char*>(client->m_addrString));
const std::vector<uint8_t>& blob = send_compact ? data->compact_blob : data->pruned_blob;
const uint32_t len = static_cast<uint32_t>(blob.size());
@@ -917,7 +950,7 @@ void P2PServer::on_broadcast()
}
}
else {
LOGINFO(5, "sending BLOCK_BROADCAST (full) to " << log::Gray() << static_cast<char*>(client->m_addrString));
LOGINFO(5, "sending BLOCK_BROADCAST (full) to " << log::Gray() << static_cast<char*>(client->m_addrString));
const uint32_t len = static_cast<uint32_t>(data->blob.size());
if (buf_size < 1 + sizeof(uint32_t) + len) {
@@ -971,6 +1004,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);
}
@@ -986,8 +1021,8 @@ void P2PServer::show_peers() const
for (P2PClient* client = static_cast<P2PClient*>(m_connectedClientsList->m_next); client != m_connectedClientsList; client = static_cast<P2PClient*>(client->m_next)) {
if (client->m_listenPort >= 0) {
char buf[32] = {};
log::Stream s(buf);
if (client->m_SoftwareVersion) {
log::Stream s(buf);
s << client->software_name() << " v" << (client->m_SoftwareVersion >> 16) << '.' << (client->m_SoftwareVersion & 0xFFFF);
}
LOGINFO(0, (client->m_isIncoming ? "I\t" : "O\t")
@@ -1028,6 +1063,16 @@ int P2PServer::deserialize_block(const uint8_t* buf, uint32_t size, bool compact
return result;
}
const PoolBlock* P2PServer::find_block(const hash& id) const
{
return m_pool->side_chain().find_block(id);
}
const char* P2PServer::get_log_category() const
{
return log_category_prefix;
}
void P2PServer::on_timer()
{
if (m_pool->stopped()) {
@@ -1048,6 +1093,7 @@ void P2PServer::on_timer()
update_peer_connections();
check_host();
check_block_template();
check_for_updates();
api_update_local_stats();
}
@@ -1093,12 +1139,13 @@ void P2PServer::download_missing_blocks()
return;
}
std::vector<hash> missing_blocks;
unordered_set<hash> missing_blocks;
m_pool->side_chain().get_missing_blocks(missing_blocks);
if (missing_blocks.empty()) {
m_lookForMissingBlocks = false;
m_missingBlockRequests.clear();
m_blockNotifyRequests.clear();
return;
}
@@ -1125,8 +1172,12 @@ void P2PServer::download_missing_blocks()
for (const hash& id : missing_blocks) {
P2PClient* client = clients[get_random64() % clients.size()];
const uint64_t truncated_block_id = *reinterpret_cast<const uint64_t*>(id.h);
if (!m_missingBlockRequests.insert({ client->m_peerId, truncated_block_id }).second) {
if (client->m_blockPendingRequests.size() >= 25) {
// Too many pending requests to this peer
continue;
}
if (!m_missingBlockRequests.emplace(client->m_peerId, *id.u64()).second) {
// We already asked this peer about this block
// Don't try to ask another peer, leave it for another timer tick
continue;
@@ -1144,7 +1195,7 @@ void P2PServer::download_missing_blocks()
const bool result = send(client,
[&id, client](uint8_t* buf, size_t buf_size) -> size_t
{
LOGINFO(5, "sending BLOCK_REQUEST for id = " << id << " to " << static_cast<char*>(client->m_addrString));
LOGINFO(5, "[download_missing_blocks] sending BLOCK_REQUEST for id = " << id << " to " << static_cast<char*>(client->m_addrString));
if (buf_size < 1 + HASH_SIZE) {
return 0;
@@ -1161,7 +1212,7 @@ void P2PServer::download_missing_blocks()
});
if (result) {
client->m_blockPendingRequests.push_back(id);
client->m_blockPendingRequests.push_back(*id.u64());
}
}
}
@@ -1186,7 +1237,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;
}
@@ -1199,7 +1250,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();
}
}
@@ -1217,6 +1268,27 @@ void P2PServer::check_block_template()
}
}
void P2PServer::check_for_updates(bool forced) const
{
#ifdef DEV_TEST_SYNC
constexpr uint64_t check_interval = 60;
#else
constexpr uint64_t check_interval = 3600;
#endif
if (!forced && (m_timerCounter % (check_interval / m_timerInterval) != 0)) {
return;
}
const SideChain& s = m_pool->side_chain();
if ((forced || s.precalcFinished()) && m_newP2PoolVersionDetected && s.p2pool_update_available()) {
LOGINFO(0, log::LightCyan() << "********************************************************************************");
LOGINFO(0, log::LightCyan() << "* An updated P2Pool version is available, visit p2pool.io for more information *");
LOGINFO(0, log::LightCyan() << "********************************************************************************");
}
}
P2PServer::P2PClient::P2PClient()
: Client(m_p2pReadBuf, sizeof(m_p2pReadBuf))
, m_peerId(0)
@@ -1234,12 +1306,13 @@ 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)
, m_lastBlockrequestTimestamp(0)
, m_broadcastedHashes{}
, m_broadcastedHashesIndex(0)
{
m_p2pReadBuf[0] = '\0';
}
@@ -1250,14 +1323,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;
}
@@ -1266,9 +1348,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;
@@ -1294,10 +1382,6 @@ void P2PServer::api_update_local_stats()
<< static_cast<char*>(client->m_addrString)
<< '"';
if (s.m_pos + 128 >= s.m_bufSize) {
break;
}
first = false;
}
}
@@ -1335,7 +1419,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;
@@ -1401,7 +1485,14 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
uint32_t bytes_read;
do {
MessageId id = static_cast<MessageId>(buf[0]);
if (buf[0] > static_cast<uint8_t>(MessageId::LAST)) {
LOGWARN(5, "peer " << static_cast<char*>(m_addrString) << " sent an unknown message id " << buf[0]);
ban(DEFAULT_BAN_TIME);
server->remove_peer_from_list(this);
return false;
}
const MessageId id = static_cast<MessageId>(buf[0]);
// Peer must complete the handshake challenge before sending any other messages
if (!m_handshakeComplete && (id != m_expectedMessage)) {
@@ -1511,7 +1602,7 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
if (bytes_left >= 1 + sizeof(uint32_t) + block_size) {
bytes_read = 1 + sizeof(uint32_t) + block_size;
const hash expected_id = m_blockPendingRequests.front();
const uint64_t expected_id = m_blockPendingRequests.front();
m_blockPendingRequests.pop_front();
if (!on_block_response(buf + 1 + sizeof(uint32_t), block_size, expected_id)) {
@@ -1586,6 +1677,15 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
}
}
break;
case MessageId::BLOCK_NOTIFY:
LOGINFO(6, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_NOTIFY");
if (bytes_left >= 1 + HASH_SIZE) {
bytes_read = 1 + HASH_SIZE;
on_block_notify(buf + 1);
}
break;
}
if (bytes_read) {
@@ -1732,7 +1832,7 @@ void P2PServer::P2PClient::send_handshake_solution(const uint8_t (&challenge)[CH
return;
}
const uint64_t* value = reinterpret_cast<uint64_t*>(work->solution.h);
const uint64_t* value = work->solution.u64();
uint64_t high;
umul128(value[HASH_SIZE / sizeof(uint64_t) - 1], CHALLENGE_DIFFICULTY, &high);
@@ -1878,7 +1978,7 @@ bool P2PServer::P2PClient::on_handshake_solution(const uint8_t* buf)
// Check that incoming connection provided enough PoW
if (m_isIncoming) {
const uint64_t* value = reinterpret_cast<uint64_t*>(solution.h);
const uint64_t* value = solution.u64();
uint64_t high;
umul128(value[HASH_SIZE / sizeof(uint64_t) - 1], CHALLENGE_DIFFICULTY, &high);
@@ -1939,7 +2039,7 @@ void P2PServer::P2PClient::on_after_handshake(uint8_t* &p)
memcpy(p, zero_hash.h, HASH_SIZE);
p += HASH_SIZE;
m_blockPendingRequests.push_back(zero_hash);
m_blockPendingRequests.push_back(0);
m_lastBroadcastTimestamp = seconds_since_epoch();
}
@@ -1967,14 +2067,32 @@ bool P2PServer::P2PClient::on_block_request(const uint8_t* buf)
memcpy(id.h, buf, HASH_SIZE);
P2PServer* server = static_cast<P2PServer*>(m_owner);
const SideChain& sidechain = server->m_pool->side_chain();
std::vector<uint8_t> blob;
if (!server->m_pool->side_chain().get_block_blob(id, blob) && !id.empty()) {
const PoolBlock* block = sidechain.get_block_blob(id, blob);
if (!block && !id.empty()) {
LOGWARN(5, "got a request for block with id " << id << " but couldn't find it");
}
// Notifications about parent and uncle blocks to speed up syncing
std::vector<hash> notify_blocks;
if (block && (m_protocolVersion >= PROTOCOL_VERSION_1_2)) {
notify_blocks.reserve(block->m_uncles.size() + 2);
notify_blocks.push_back(block->m_parent);
notify_blocks.insert(notify_blocks.end(), block->m_uncles.begin(), block->m_uncles.end());
block = sidechain.find_block(block->m_parent);
if (block) {
notify_blocks.push_back(block->m_parent);
}
}
return server->send(this,
[this, &blob](uint8_t* buf, size_t buf_size) -> size_t
[this, &blob, &notify_blocks](uint8_t* buf, size_t buf_size) -> size_t
{
LOGINFO(5, "sending BLOCK_RESPONSE to " << static_cast<char*>(m_addrString));
@@ -1986,6 +2104,17 @@ bool P2PServer::P2PClient::on_block_request(const uint8_t* buf)
uint8_t* p = buf;
if (buf_size >= 1 + sizeof(uint32_t) + len + notify_blocks.size() * (1 + HASH_SIZE)) {
for (const hash& id : notify_blocks) {
LOGINFO(6, "sending BLOCK_NOTIFY for " << id << " to " << static_cast<char*>(m_addrString));
*(p++) = static_cast<uint8_t>(MessageId::BLOCK_NOTIFY);
memcpy(p, id.h, HASH_SIZE);
p += HASH_SIZE;
}
}
*(p++) = static_cast<uint8_t>(MessageId::BLOCK_RESPONSE);
memcpy(p, &len, sizeof(uint32_t));
@@ -2000,14 +2129,14 @@ bool P2PServer::P2PClient::on_block_request(const uint8_t* buf)
});
}
bool P2PServer::P2PClient::on_block_response(const uint8_t* buf, uint32_t size, const hash& expected_id)
bool P2PServer::P2PClient::on_block_response(const uint8_t* buf, uint32_t size, uint64_t expected_id)
{
P2PServer* server = static_cast<P2PServer*>(m_owner);
const uint64_t cur_time = seconds_since_epoch();
if (!size) {
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent an empty block response");
if (expected_id.empty() && (cur_time >= m_nextOutgoingPeerListRequest)) {
if ((expected_id == 0) && (cur_time >= m_nextOutgoingPeerListRequest)) {
server->send_peer_list_request(this, cur_time);
}
return true;
@@ -2026,7 +2155,7 @@ bool P2PServer::P2PClient::on_block_response(const uint8_t* buf, uint32_t size,
const PoolBlock* block = server->get_block();
// Chain tip request
if (expected_id.empty()) {
if (expected_id == 0) {
const uint64_t peer_height = block->m_txinGenHeight;
const uint64_t our_height = server->m_pool->miner_data().height;
@@ -2035,12 +2164,15 @@ bool P2PServer::P2PClient::on_block_response(const uint8_t* buf, uint32_t size,
return false;
}
m_broadcastMaxHeight = std::max(m_broadcastMaxHeight, block->m_sidechainHeight);
m_broadcastedHashes[m_broadcastedHashesIndex++ % array_size(&P2PClient::m_broadcastedHashes)] = block->m_sidechainId;
if (cur_time >= m_nextOutgoingPeerListRequest) {
server->send_peer_list_request(this, cur_time);
}
}
else if (block->m_sidechainId != expected_id) {
LOGWARN(3, "peer " << static_cast<char*>(m_addrString) << " sent a wrong block: expected " << expected_id << ", got " << block->m_sidechainId);
else if (*block->m_sidechainId.u64() != expected_id) {
LOGWARN(3, "peer " << static_cast<char*>(m_addrString) << " sent a wrong block: expected " << log::hex_buf(&expected_id) << ", got " << block->m_sidechainId);
return false;
}
@@ -2072,7 +2204,7 @@ bool P2PServer::P2PClient::on_block_broadcast(const uint8_t* buf, uint32_t size,
const PoolBlock* block = server->get_block();
m_broadcastMaxHeight = std::max(m_broadcastMaxHeight, block->m_sidechainHeight);
m_broadcastedHashes[m_broadcastedHashesIndex.fetch_add(1) % array_size(&P2PClient::m_broadcastedHashes)] = block->m_sidechainId;
m_broadcastedHashes[m_broadcastedHashesIndex++ % array_size(&P2PClient::m_broadcastedHashes)] = block->m_sidechainId;
MinerData miner_data = server->m_pool->miner_data();
@@ -2167,7 +2299,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) {
@@ -2236,27 +2369,43 @@ 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)) {
m_protocolVersion = *reinterpret_cast<uint32_t*>(ip.data);
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
// to reduce backwards compatibility requirements for newer clients
if ((version >> 16) != (SUPPORTED_PROTOCOL_VERSION >> 16)) {
m_protocolVersion = PROTOCOL_VERSION_1_0;
}
else {
m_protocolVersion = std::min(version, SUPPORTED_PROTOCOL_VERSION);
}
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;
@@ -2264,7 +2413,57 @@ 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);
}
}
}
void P2PServer::P2PClient::on_block_notify(const uint8_t* buf)
{
hash id;
memcpy(id.h, buf, HASH_SIZE);
m_broadcastedHashes[m_broadcastedHashesIndex++ % array_size(&P2PClient::m_broadcastedHashes)] = id;
P2PServer* server = static_cast<P2PServer*>(m_owner);
// If we don't know about this block, request it from this peer. The peer can do it to speed up our initial sync, for example.
if (!server->find_block(id)) {
LOGINFO(6, "Received an unknown block " << id << " in BLOCK_NOTIFY");
if (m_blockPendingRequests.size() >= 25) {
LOGINFO(5, "Too many pending block requests, ignoring it");
return;
}
if (!server->m_blockNotifyRequests.insert(*id.u64()).second || !server->m_missingBlockRequests.emplace(m_peerId, *id.u64()).second) {
LOGINFO(6, "BLOCK_REQUEST for id = " << id << " was already sent");
return;
}
const bool result = server->send(this,
[&id, this](uint8_t* buf, size_t buf_size) -> size_t
{
LOGINFO(5, "[on_block_notify] sending BLOCK_REQUEST for id = " << id << " to " << static_cast<char*>(m_addrString));
if (buf_size < 1 + HASH_SIZE) {
return 0;
}
uint8_t* p = buf;
*(p++) = static_cast<uint8_t>(MessageId::BLOCK_REQUEST);
memcpy(p, id.h, HASH_SIZE);
p += HASH_SIZE;
return p - buf;
});
if (result) {
m_blockPendingRequests.push_back(*id.u64());
}
}
}
@@ -2335,9 +2534,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,
@@ -2345,12 +2545,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->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);
});
@@ -2364,30 +2564,33 @@ 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");
}
else {
const log::hex_buf addr_hex(addr.data, sizeof(addr.data));
LOGWARN(3, "IP " << addr_hex << " banned for " << DEFAULT_BAN_TIME << " seconds");
LOGWARN(3, addr << " banned for " << DEFAULT_BAN_TIME << " seconds");
}
P2PServer* server = pool->p2p_server();
server->ban(is_v6, addr, DEFAULT_BAN_TIME);
server->remove_peer_from_list(addr);
}
}
void P2PServer::P2PClient::post_handle_incoming_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;
}
@@ -2397,11 +2600,14 @@ void P2PServer::P2PClient::post_handle_incoming_block(const uint32_t reset_count
P2PServer* server = static_cast<P2PServer*>(m_owner);
// If the initial sync is not finished yet, try to ask the fastest peer too
P2PClient* c = server->m_fastestPeer;
if (c && (c != this) && !server->m_pool->side_chain().precalcFinished()) {
LOGINFO(5, "peer " << static_cast<char*>(c->m_addrString) << " is faster, sending BLOCK_REQUEST to it too");
c->post_handle_incoming_block(c->m_resetCounter.load(), missing_blocks);
// If the initial sync is not finished yet, try to ask the fastest peer instead
if (!server->m_pool->side_chain().precalcFinished()) {
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(pool, block, c->m_resetCounter.load(), c->m_isV6, c->m_addr, missing_blocks, true);
return;
}
}
ReadLock lock(server->m_cachedBlocksLock);
@@ -2416,10 +2622,14 @@ void P2PServer::P2PClient::post_handle_incoming_block(const uint32_t reset_count
}
}
const bool result = server->send(this,
if (!server->m_missingBlockRequests.emplace(m_peerId, *id.u64()).second) {
continue;
}
const bool send_result = server->send(this,
[this, &id](uint8_t* buf, size_t buf_size) -> size_t
{
LOGINFO(5, "sending BLOCK_REQUEST for id = " << id << " to " << static_cast<char*>(m_addrString));
LOGINFO(5, "[post_handle_incoming_block] sending BLOCK_REQUEST for id = " << id << " to " << static_cast<char*>(m_addrString));
if (buf_size < 1 + HASH_SIZE) {
return 0;
@@ -2435,20 +2645,20 @@ void P2PServer::P2PClient::post_handle_incoming_block(const uint32_t reset_count
return p - buf;
});
if (!result) {
if (!send_result) {
return;
}
m_blockPendingRequests.push_back(id);
m_blockPendingRequests.push_back(*id.u64());
}
}
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";
+31 -18
View File
@@ -19,7 +19,7 @@
#include "tcp_server.h"
#include "pool_block.h"
#include <list>
#include <deque>
namespace p2pool {
@@ -37,22 +37,25 @@ static constexpr int DEFAULT_P2P_PORT_MINI = 37888;
static constexpr uint32_t PROTOCOL_VERSION_1_0 = 0x00010000UL;
static constexpr uint32_t PROTOCOL_VERSION_1_1 = 0x00010001UL;
static constexpr uint32_t PROTOCOL_VERSION_1_2 = 0x00010002UL;
static constexpr uint32_t SUPPORTED_PROTOCOL_VERSION = PROTOCOL_VERSION_1_1;
static constexpr uint32_t SUPPORTED_PROTOCOL_VERSION = PROTOCOL_VERSION_1_2;
class P2PServer : public TCPServer
{
public:
enum class MessageId {
HANDSHAKE_CHALLENGE = 0,
HANDSHAKE_SOLUTION = 1,
LISTEN_PORT = 2,
BLOCK_REQUEST = 3,
BLOCK_RESPONSE = 4,
BLOCK_BROADCAST = 5,
PEER_LIST_REQUEST = 6,
PEER_LIST_RESPONSE = 7,
BLOCK_BROADCAST_COMPACT = 8,
HANDSHAKE_CHALLENGE,
HANDSHAKE_SOLUTION,
LISTEN_PORT,
BLOCK_REQUEST,
BLOCK_RESPONSE,
BLOCK_BROADCAST,
PEER_LIST_REQUEST,
PEER_LIST_RESPONSE,
BLOCK_BROADCAST_COMPACT,
BLOCK_NOTIFY,
LAST = BLOCK_NOTIFY,
};
explicit P2PServer(p2pool *pool);
@@ -105,14 +108,15 @@ public:
void on_after_handshake(uint8_t* &p);
bool on_listen_port(const uint8_t* buf);
bool on_block_request(const uint8_t* buf);
bool on_block_response(const uint8_t* buf, uint32_t size, const hash& expected_id);
bool on_block_response(const uint8_t* buf, uint32_t size, uint64_t expected_id);
bool on_block_broadcast(const uint8_t* buf, uint32_t size, bool compact);
bool on_peer_list_request(const uint8_t* buf);
void on_peer_list_response(const uint8_t* buf);
void on_block_notify(const uint8_t* buf);
bool handle_incoming_block_async(const PoolBlock* block, uint64_t max_time_delta = 0);
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 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); }
@@ -138,18 +142,18 @@ public:
uint32_t m_protocolVersion;
uint32_t m_SoftwareVersion;
uint32_t m_SoftwareID;
SoftwareID m_SoftwareID;
int64_t m_pingTime;
std::list<hash> m_blockPendingRequests;
std::deque<uint64_t> m_blockPendingRequests;
uint64_t m_lastAlive;
uint64_t m_lastBroadcastTimestamp;
uint64_t m_lastBlockrequestTimestamp;
hash m_broadcastedHashes[8];
std::atomic<uint32_t> m_broadcastedHashesIndex{ 0 };
uint32_t m_broadcastedHashesIndex;
};
void broadcast(const PoolBlock& block, const PoolBlock* parent);
@@ -171,8 +175,12 @@ public:
int deserialize_block(const uint8_t* buf, uint32_t size, bool compact, uint64_t received_timestamp);
const PoolBlock* get_block() const { return m_block; }
const PoolBlock* find_block(const hash& id) const;
void check_for_updates(bool forced = false) const;
private:
const char* get_category() const override { return "P2PServer "; }
const char* get_log_category() const override;
p2pool* m_pool;
BlockCache* m_cache;
@@ -220,6 +228,8 @@ private:
struct Peer
{
void normalize();
bool m_isV6;
raw_ip m_addr;
int m_port;
@@ -248,8 +258,10 @@ private:
bool m_lookForMissingBlocks;
unordered_set<std::pair<uint64_t, uint64_t>> m_missingBlockRequests;
unordered_set<uint64_t> m_blockNotifyRequests;
P2PClient* m_fastestPeer;
std::atomic<bool> m_newP2PoolVersionDetected;
static void on_broadcast(uv_async_t* handle) { reinterpret_cast<P2PServer*>(handle->data)->on_broadcast(); }
void on_broadcast();
@@ -260,6 +272,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(); }
+10 -10
View File
@@ -40,7 +40,8 @@
#include <fstream>
#include <numeric>
constexpr char log_category_prefix[] = "P2Pool ";
LOG_CATEGORY(P2Pool)
constexpr int BLOCK_HEADERS_REQUIRED = 720;
constexpr uint64_t SEEDHASH_EPOCH_BLOCKS = 2048;
@@ -912,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();
@@ -924,7 +925,7 @@ void p2pool::get_info()
void p2pool::load_found_blocks()
{
if (!m_api) {
if (!m_api || m_stopped) {
return;
}
@@ -1106,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;
@@ -1276,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;
}
@@ -1307,7 +1308,7 @@ void p2pool::api_update_network_stats()
void p2pool::api_update_pool_stats()
{
if (!m_api) {
if (!m_api || m_stopped) {
return;
}
@@ -1359,7 +1360,7 @@ void p2pool::api_update_pool_stats()
void p2pool::api_update_stats_mod()
{
if (!m_api) {
if (!m_api || m_stopped) {
return;
}
@@ -1452,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;
}
@@ -1690,8 +1691,7 @@ int p2pool::run()
m_ZMQReader = nullptr;
}
catch (const std::exception& e) {
const char* s = e.what();
LOGERR(1, "exception " << s);
LOGERR(1, "exception " << e.what());
PANIC_STOP();
}
+14 -6
View File
@@ -24,7 +24,7 @@
#include <sys/stat.h>
#endif
static constexpr char log_category_prefix[] = "P2Pool API ";
LOG_CATEGORY(P2Pool API)
namespace p2pool {
@@ -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);
+1 -1
View File
@@ -20,7 +20,7 @@
#include "stratum_server.h"
#include "p2p_server.h"
constexpr char log_category_prefix[] = "P2Pool ";
LOG_CATEGORY(Params)
void p2pool_usage();
+1 -1
View File
@@ -22,7 +22,7 @@
#include "pow_hash.h"
#include "crypto.h"
static constexpr char log_category_prefix[] = "PoolBlock ";
LOG_CATEGORY(PoolBlock)
#include "pool_block_parser.inl"
+1 -2
View File
@@ -393,8 +393,7 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
}
}
catch (std::exception& e) {
const char* msg = e.what();
LOGERR(0, "Exception in PoolBlock::deserialize(): " << (msg ? msg : "unknown exception"));
LOGERR(0, "Exception in PoolBlock::deserialize(): " << e.what());
return __LINE__;
}
+22 -12
View File
@@ -29,7 +29,7 @@
#include <rapidjson/document.h>
#include <thread>
static constexpr char log_category_prefix[] = "RandomX_Hasher ";
LOG_CATEGORY(RandomX_Hasher)
namespace p2pool {
@@ -322,6 +322,22 @@ void RandomX_Hasher::sync_wait()
ReadLock lock2(m_cacheLock);
}
static bool randomx_calculate_hash_safe(randomx_vm* machine, const void* input, size_t inputSize, void* output)
{
// Try to calculate the hash again if something went wrong the first time (for example, because of an unstable CPU)
for (size_t i = 0; i < 2; ++i) {
try {
randomx_calculate_hash(machine, input, inputSize, output);
return true;
}
catch (const std::exception& e) {
LOGERR(0, "Failed to calculate RandomX hash: exception \"" << e.what() << "\". Is your CPU/RAM unstable?" <<
"\nFailed RandomX hash input: " << log::hex_buf(input, inputSize));
}
}
return false;
}
bool RandomX_Hasher::calculate(const void* data, size_t size, uint64_t /*height*/, const hash& seed, hash& result, bool force_light_mode)
{
// First try to use the dataset if it's ready
@@ -335,8 +351,7 @@ bool RandomX_Hasher::calculate(const void* data, size_t size, uint64_t /*height*
MutexLock lock(m_vm[FULL_DATASET_VM].mutex);
if (m_vm[FULL_DATASET_VM].vm && (seed == m_seed[m_index])) {
randomx_calculate_hash(m_vm[FULL_DATASET_VM].vm, data, size, &result);
return true;
return randomx_calculate_hash_safe(m_vm[FULL_DATASET_VM].vm, data, size, &result);
}
}
@@ -350,8 +365,7 @@ bool RandomX_Hasher::calculate(const void* data, size_t size, uint64_t /*height*
{
MutexLock lock2(m_vm[m_index].mutex);
if (m_vm[m_index].vm && (seed == m_seed[m_index])) {
randomx_calculate_hash(m_vm[m_index].vm, data, size, &result);
return true;
return randomx_calculate_hash_safe(m_vm[m_index].vm, data, size, &result);
}
}
@@ -360,8 +374,7 @@ bool RandomX_Hasher::calculate(const void* data, size_t size, uint64_t /*height*
MutexLock lock2(m_vm[prev_index].mutex);
if (m_vm[prev_index].vm && (seed == m_seed[prev_index])) {
randomx_calculate_hash(m_vm[prev_index].vm, data, size, &result);
return true;
return randomx_calculate_hash_safe(m_vm[prev_index].vm, data, size, &result);
}
return false;
@@ -383,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);
@@ -443,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();
@@ -472,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) {
-2
View File
@@ -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);
}
+128 -42
View File
@@ -40,7 +40,7 @@
#include <iterator>
#include <numeric>
static constexpr char log_category_prefix[] = "SideChain ";
LOG_CATEGORY(SideChain)
static constexpr uint64_t MIN_DIFFICULTY = 100000;
static constexpr size_t UNCLE_BLOCK_DEPTH = 3;
@@ -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 {
@@ -168,7 +168,8 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name)
// Hide most consensus ID bytes, we only want it on screen to show that we're on the right sidechain
memset(buf + 8, '*', HASH_SIZE * 2 - 16);
m_consensusIdDisplayStr.assign(buf);
m_consensusIdDisplayStr = buf;
LOGINFO(1, "consensus ID = " << log::LightCyan() << m_consensusIdDisplayStr.c_str());
memcpy(m_consensusHash.h, m_consensusId.data(), HASH_SIZE);
@@ -455,7 +456,7 @@ bool SideChain::get_shares(const PoolBlock* tip, std::vector<MinerShare>& shares
hash h;
keccak(tip->m_txkeySecSeed.h, HASH_SIZE, h.h);
uint64_t seed = *reinterpret_cast<uint64_t*>(h.h);
uint64_t seed = *h.u64();
if (seed == 0) seed = 1;
for (uint64_t i = 0, k; i < n - 1; ++i) {
@@ -701,9 +702,6 @@ bool SideChain::add_block(const PoolBlock& block)
m_blocksByHeight[new_block->m_sidechainHeight].push_back(new_block);
// Pre-calculate eph_public_keys during initial sync
launch_precalc(new_block);
update_depths(new_block);
if (new_block->m_verified) {
@@ -742,7 +740,7 @@ void SideChain::watch_mainchain_block(const ChainMain& data, const hash& possibl
m_watchBlockSidechainId = possible_id;
}
bool SideChain::get_block_blob(const hash& id, std::vector<uint8_t>& blob) const
const PoolBlock* SideChain::get_block_blob(const hash& id, std::vector<uint8_t>& blob) const
{
ReadLock lock(m_sidechainLock);
@@ -754,7 +752,7 @@ bool SideChain::get_block_blob(const hash& id, std::vector<uint8_t>& blob) const
// Don't return stale chain tip
if (block && (block->m_txinGenHeight + 2 < m_pool->miner_data().height)) {
return false;
return nullptr;
}
}
else {
@@ -765,14 +763,14 @@ bool SideChain::get_block_blob(const hash& id, std::vector<uint8_t>& blob) const
}
if (!block) {
return false;
return nullptr;
}
blob = block->serialize_mainchain_data();
const std::vector<uint8_t> sidechain_data = block->serialize_sidechain_data();
blob.insert(blob.end(), sidechain_data.begin(), sidechain_data.end());
return true;
return block;
}
bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::vector<uint8_t>& blob, uv_loop_t* loop) const
@@ -781,11 +779,12 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v
struct Data
{
FORCEINLINE Data() : counter(0) {}
FORCEINLINE Data() : blockMinerWallet(nullptr), counter(0) {}
Data(Data&&) = delete;
Data& operator=(Data&&) = delete;
std::vector<MinerShare> tmpShares;
Wallet blockMinerWallet;
hash txkeySec;
std::atomic<int> counter;
};
@@ -820,6 +819,7 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v
}
data = std::make_shared<Data>();
data->blockMinerWallet = block->m_minerWallet;
data->txkeySec = block->m_txkeySec;
if (!get_shares(block, data->tmpShares) || !split_reward(total_reward, data->tmpShares, tmpRewards) || (tmpRewards.size() != data->tmpShares.size())) {
@@ -833,6 +833,14 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v
// Helper jobs call get_eph_public_key with indices in descending order
// Current thread will process indices in ascending order so when they meet, everything will be cached
if (loop) {
// Avoid accessing block->m_minerWallet from other threads in "parallel_run" below
for (MinerShare& share : data->tmpShares) {
if (share.m_wallet == &block->m_minerWallet) {
share.m_wallet = &data->blockMinerWallet;
break;
}
}
parallel_run(loop, [data]() {
Data* d = data.get();
hash eph_public_key;
@@ -1296,6 +1304,30 @@ bool SideChain::get_difficulty(const PoolBlock* tip, std::vector<DifficultyData>
return true;
}
bool SideChain::p2pool_update_available() const
{
constexpr uint32_t version = (P2POOL_VERSION_MAJOR << 16) | P2POOL_VERSION_MINOR;
difficulty_type total_p2pool_diff, newer_p2pool_diff;
{
ReadLock lock(m_sidechainLock);
const PoolBlock* cur = m_chainTip;
for (uint64_t i = 0; (i < m_chainWindowSize) && cur; ++i, cur = get_parent(cur)) {
if (cur->m_sidechainExtraBuf[0] == static_cast<uint32_t>(SoftwareID::P2Pool)) {
total_p2pool_diff += cur->m_difficulty;
if (cur->m_sidechainExtraBuf[1] > version) {
newer_p2pool_diff += cur->m_difficulty;
}
}
}
}
// Assume that a new version is out if >= 20% of hashrate is using it already
return newer_p2pool_diff * 5 >= total_p2pool_diff;
}
void SideChain::verify_loop(PoolBlock* block)
{
// PoW is already checked at this point
@@ -1536,7 +1568,7 @@ void SideChain::verify(PoolBlock* block)
}
// Check that uncle and parent have the same ancestor (they must be on the same chain)
PoolBlock* tmp = parent;
const PoolBlock* tmp = parent;
while (tmp->m_sidechainHeight > uncle->m_sidechainHeight) {
tmp = get_parent(tmp);
if (!tmp) {
@@ -1559,7 +1591,7 @@ void SideChain::verify(PoolBlock* block)
}
bool same_chain = false;
PoolBlock* tmp2 = uncle;
const PoolBlock* tmp2 = uncle;
for (size_t j = 0; (j < UNCLE_BLOCK_DEPTH) && tmp && tmp2 && (tmp->m_sidechainHeight + UNCLE_BLOCK_DEPTH >= block->m_sidechainHeight); ++j) {
if (tmp->m_parent == tmp2->m_parent) {
same_chain = true;
@@ -1765,7 +1797,7 @@ void SideChain::update_chain_tip(const PoolBlock* block)
" is not a longer chain than " << tip->m_sidechainId <<
", height " << tip->m_sidechainHeight);
}
else if (block->m_sidechainHeight + UNCLE_BLOCK_DEPTH > tip->m_sidechainHeight) {
else if (m_pool && (block->m_sidechainHeight + UNCLE_BLOCK_DEPTH > tip->m_sidechainHeight)) {
LOGINFO(4, "possible uncle block: id = " << log::Gray() << block->m_sidechainId << log::NoColor() <<
", height = " << log::Gray() << block->m_sidechainHeight);
m_pool->update_block_template_async();
@@ -1779,13 +1811,8 @@ void SideChain::update_chain_tip(const PoolBlock* block)
PoolBlock* SideChain::get_parent(const PoolBlock* block) const
{
if (block) {
auto it = m_blocksById.find(block->m_parent);
if (it != m_blocksById.end()) {
return it->second;
}
}
return nullptr;
auto it = m_blocksById.find(block->m_parent);
return (it != m_blocksById.end()) ? it->second : nullptr;
}
bool SideChain::is_longer_chain(const PoolBlock* block, const PoolBlock* candidate, bool& is_alternative) const
@@ -1933,6 +1960,18 @@ bool SideChain::is_longer_chain(const PoolBlock* block, const PoolBlock* candida
void SideChain::update_depths(PoolBlock* block)
{
const uint64_t precalc_depth = m_chainWindowSize + UNCLE_BLOCK_DEPTH - 1;
auto update_depth = [this, precalc_depth](PoolBlock* b, const uint64_t new_depth) {
const uint64_t old_depth = b->m_depth;
if (old_depth < new_depth) {
b->m_depth = new_depth;
if ((old_depth < precalc_depth) && (new_depth >= precalc_depth)) {
launch_precalc(b);
}
}
};
for (size_t i = 1; i <= UNCLE_BLOCK_DEPTH; ++i) {
auto it = m_blocksByHeight.find(block->m_sidechainHeight + i);
if (it == m_blocksByHeight.end()) {
@@ -1945,12 +1984,12 @@ void SideChain::update_depths(PoolBlock* block)
return;
}
else {
block->m_depth = std::max(block->m_depth, child->m_depth + 1);
update_depth(block, child->m_depth + 1);
}
}
if (std::find(child->m_uncles.begin(), child->m_uncles.end(), block->m_sidechainId) != child->m_uncles.end()) {
block->m_depth = std::max(block->m_depth, child->m_depth + i);
update_depth(block, child->m_depth + i);
}
}
}
@@ -1966,6 +2005,36 @@ void SideChain::update_depths(PoolBlock* block)
verify_loop(block);
}
for (size_t i = 1; i <= UNCLE_BLOCK_DEPTH; ++i) {
auto it = m_blocksByHeight.find(block->m_sidechainHeight + i);
if (it == m_blocksByHeight.end()) {
continue;
}
for (PoolBlock* child : it->second) {
const uint64_t old_depth = child->m_depth;
if (child->m_parent == block->m_sidechainId) {
if (i != 1) {
LOGWARN(3, "Block " << block->m_sidechainId << ": m_sidechainHeight is inconsistent with child's m_sidechainHeight.");
return;
}
else if (block->m_depth > 0) {
update_depth(child, block->m_depth - 1);
}
}
if (std::find(child->m_uncles.begin(), child->m_uncles.end(), block->m_sidechainId) != child->m_uncles.end()) {
if (block->m_depth > i) {
update_depth(child, block->m_depth - i);
}
}
if (child->m_depth > old_depth) {
blocks_to_update.push_back(child);
}
}
}
auto it = m_blocksById.find(block->m_parent);
if (it != m_blocksById.end()) {
if (it->second->m_sidechainHeight + 1 != block->m_sidechainHeight) {
@@ -1974,7 +2043,7 @@ void SideChain::update_depths(PoolBlock* block)
}
if (it->second->m_depth < block->m_depth + 1) {
it->second->m_depth = block->m_depth + 1;
update_depth(it->second, block->m_depth + 1);
blocks_to_update.push_back(it->second);
}
}
@@ -1992,7 +2061,7 @@ void SideChain::update_depths(PoolBlock* block)
const uint64_t d = block->m_sidechainHeight - it->second->m_sidechainHeight;
if (it->second->m_depth < block->m_depth + d) {
it->second->m_depth = block->m_depth + d;
update_depth(it->second, block->m_depth + d);
blocks_to_update.push_back(it->second);
}
}
@@ -2016,21 +2085,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!");
@@ -2048,8 +2116,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
@@ -2060,6 +2128,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();
@@ -2068,23 +2141,36 @@ void SideChain::prune_old_blocks()
m_pool->reconnect_to_host();
}
if (cur_time >= m_firstPruneTime + 120) {
if ((cur_time >= m_firstPruneTime + 120) && !m_pool->stopped()) {
LOGINFO(0, log::LightGreen() << "[DEV] Synchronization finished successfully, stopping P2Pool now");
#ifdef DEV_TRACK_MEMORY
show_top_10_allocations();
#endif
print_status(false);
P2PServer* server = m_pool->p2p_server();
if (server) {
server->print_status();
server->print_bans();
server->show_peers_async();
StratumServer* server1 = m_pool->stratum_server();
P2PServer* server2 = m_pool->p2p_server();
if (server1 && server2) {
server1->print_status();
server2->print_status();
server1->print_bans();
server2->print_bans();
server1->show_workers_async();
server2->show_peers_async();
}
m_pool->print_hosts();
bkg_jobs_tracker.print_status();
m_pool->stop();
}
#endif
}
}
void SideChain::get_missing_blocks(std::vector<hash>& missing_blocks) const
void SideChain::get_missing_blocks(unordered_set<hash>& missing_blocks) const
{
missing_blocks.clear();
@@ -2096,14 +2182,14 @@ void SideChain::get_missing_blocks(std::vector<hash>& missing_blocks) const
}
if (!b.second->m_parent.empty() && (m_blocksById.find(b.second->m_parent) == m_blocksById.end())) {
missing_blocks.push_back(b.second->m_parent);
missing_blocks.insert(b.second->m_parent);
}
int num_missing_uncles = 0;
for (const hash& h : b.second->m_uncles) {
if (!h.empty() && (m_blocksById.find(h) == m_blocksById.end())) {
missing_blocks.push_back(h);
missing_blocks.insert(h);
// Get no more than 2 first missing uncles at a time from each block
// Blocks with more than 2 uncles are very rare and they will be processed in several steps
+5 -2
View File
@@ -52,12 +52,12 @@ public:
bool add_external_block(PoolBlock& block, std::vector<hash>& missing_blocks);
bool add_block(const PoolBlock& block);
void get_missing_blocks(std::vector<hash>& missing_blocks) const;
void get_missing_blocks(unordered_set<hash>& missing_blocks) const;
PoolBlock* find_block(const hash& id) const;
void watch_mainchain_block(const ChainMain& data, const hash& possible_id);
bool get_block_blob(const hash& id, std::vector<uint8_t>& blob) const;
const PoolBlock* get_block_blob(const hash& id, std::vector<uint8_t>& blob) const;
bool get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::vector<uint8_t>& blob, uv_loop_t* loop) const;
void print_status(bool obtain_sidechain_lock = true) const;
@@ -82,8 +82,11 @@ public:
const PoolBlock* chainTip() const { return m_chainTip; }
bool precalcFinished() const { return m_precalcFinished.load(); }
bool p2pool_update_available() const;
#ifdef P2POOL_UNIT_TESTS
difficulty_type m_testMainChainDiff;
const unordered_map<hash, PoolBlock*>& blocksById() const { return m_blocksById; }
#endif
static bool split_reward(uint64_t reward, const std::vector<MinerShare>& shares, std::vector<uint64_t>& rewards);
+100 -50
View File
@@ -23,7 +23,7 @@
#include "params.h"
#include "p2pool_api.h"
static constexpr char log_category_prefix[] = "StratumServer ";
LOG_CATEGORY(StratumServer)
static constexpr int DEFAULT_BACKLOG = 128;
static constexpr uint64_t DEFAULT_BAN_TIME = 600;
@@ -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);
@@ -90,7 +91,16 @@ StratumServer::~StratumServer()
{
shutdown_tcp();
{
MutexLock lock(m_blobsQueueLock);
for (BlobsData* data : m_blobsQueue) {
delete data;
}
}
uv_mutex_destroy(&m_blobsQueueLock);
uv_mutex_destroy(&m_showWorkersLock);
uv_mutex_destroy(&m_rngLock);
uv_rwlock_destroy(&m_hashrateDataLock);
@@ -161,29 +171,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 +205,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 +246,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];
@@ -293,7 +298,7 @@ bool StratumServer::on_login(StratumClient* client, uint32_t id, const char* log
client->m_rpcId = static_cast<StratumServer*>(client->m_owner)->get_random32();
} while (!client->m_rpcId);
log::hex_buf target_hex(reinterpret_cast<const uint8_t*>(&target), sizeof(uint64_t));
log::hex_buf target_hex(&target);
if (target >= TARGET_4_BYTES_LIMIT) {
target_hex.m_data += sizeof(uint32_t);
@@ -412,6 +417,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 +494,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);
}
@@ -544,6 +553,11 @@ void StratumServer::reset_share_counters()
m_totalFailedShares = 0;
}
const char* StratumServer::get_log_category() const
{
return log_category_prefix;
}
void StratumServer::print_stratum_status() const
{
uint64_t hashes_15m, hashes_1h, hashes_24h, total_hashes;
@@ -589,8 +603,8 @@ void StratumServer::print_stratum_status() const
const uint64_t hashrate_24h = (dt_24h > 0) ? (hashes_24h / dt_24h) : 0;
char shares_failed_buf[64] = {};
log::Stream s(shares_failed_buf);
if (shares_failed) {
log::Stream s(shares_failed_buf);
s << log::Yellow() << "\nShares failed = " << shares_failed << log::NoColor();
}
@@ -775,7 +789,7 @@ void StratumServer::on_blobs_ready()
const bool result = send(client,
[data, target, hashing_blob, job_id](uint8_t* buf, size_t buf_size)
{
log::hex_buf target_hex(reinterpret_cast<const uint8_t*>(&target), sizeof(uint64_t));
log::hex_buf target_hex(&target);
if (target >= TARGET_4_BYTES_LIMIT) {
target_hex.m_data += sizeof(uint32_t);
@@ -854,7 +868,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;
@@ -874,7 +887,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;
}
@@ -886,13 +899,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;
@@ -930,7 +943,7 @@ void StratumServer::on_share_found(uv_work_t* req)
}
// Send the response to miner
const uint64_t value = *reinterpret_cast<uint64_t*>(share->m_resultHash.h + HASH_SIZE - sizeof(uint64_t));
const uint64_t value = share->m_resultHash.u64()[HASH_SIZE / sizeof(uint64_t) - 1];
if (LIKELY(value < target)) {
const uint64_t timestamp = share->m_timestamp;
@@ -939,7 +952,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;
}
@@ -948,13 +961,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[] = {
@@ -968,22 +979,24 @@ 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, log::Green() << "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);
}
ON_SCOPE_LEAVE([share]()
StratumServer* server = share->m_server;
ON_SCOPE_LEAVE([share, server]()
{
ASAN_POISON_MEMORY_REGION(share, sizeof(SubmittedShare));
share->m_server->m_submittedSharesPool.push_back(share);
server->m_submittedSharesPool.push_back(share);
});
StratumServer* server = share->m_server;
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)
{
@@ -1011,6 +1024,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();
@@ -1026,8 +1041,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()
@@ -1261,7 +1282,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;
}
@@ -1324,10 +1345,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
@@ -1338,8 +1358,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
+6 -2
View File
@@ -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;
@@ -97,7 +98,7 @@ public:
void reset_share_counters();
private:
const char* get_category() const override { return "StratumServer "; }
const char* get_log_category() const override;
void print_stratum_status() const;
void update_auto_diff(StratumClient* client, const uint64_t timestamp, const uint64_t hashes);
@@ -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;
+39 -16
View File
@@ -27,7 +27,7 @@ TCPServer::TCPServer(int default_backlog, allocate_client_callback allocate_new_
: m_allocateNewClient(allocate_new_client)
, m_defaultBacklog(default_backlog)
, m_loopThread{}
, m_loopThreadRunning(false)
, m_loopThreadCreated(false)
#ifdef WITH_UPNP
, m_portMapping(0)
#endif
@@ -251,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)
@@ -379,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));
}
}
@@ -393,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));
}
}
@@ -417,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
@@ -474,7 +477,7 @@ void TCPServer::shutdown_tcp()
}
#endif
if (m_loopThreadRunning.load()) {
if (m_loopThreadCreated) {
uv_thread_join(&m_loopThread);
}
@@ -573,13 +576,16 @@ bool TCPServer::send_internal(Client* client, Callback<size_t, uint8_t*, size_t>
return true;
}
const char* TCPServer::get_log_category() const
{
return log_category_prefix;
}
void TCPServer::loop(void* data)
{
TCPServer* server = static_cast<TCPServer*>(data);
server->m_loopThreadRunning.exchange(true);
ON_SCOPE_LEAVE([server]() { server->m_loopThreadRunning.exchange(false); });
log_category_prefix = server->get_category();
log_category_prefix = server->get_log_category();
LOGINFO(1, "event loop started");
server_event_loop_thread = data;
@@ -592,7 +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());
c->asan_poison_this();
server->m_writeBuffers.emplace(capacity, wb);
server->m_preallocatedClients.emplace_back(c);
@@ -776,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);
}
@@ -856,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)
@@ -956,7 +965,7 @@ TCPServer::Client* TCPServer::get_client()
void TCPServer::return_client(Client* c)
{
ASAN_POISON_MEMORY_REGION(c, c->size());
c->asan_poison_this();
m_preallocatedClients.push_back(c);
}
@@ -1098,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);
}
@@ -1203,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;
@@ -1236,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) {
@@ -1255,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
+9 -3
View File
@@ -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,
@@ -143,13 +149,13 @@ private:
std::vector<uv_tcp_t*> m_listenSockets;
protected:
virtual const char* get_category() const { return "TCPServer "; }
virtual const char* get_log_category() const;
std::vector<uint8_t> m_callbackBuf;
int m_defaultBacklog;
uv_thread_t m_loopThread;
std::atomic<bool> m_loopThreadRunning;
std::atomic<bool> m_loopThreadCreated;
static void loop(void* data);
+33 -11
View File
@@ -40,11 +40,17 @@
#include <resolv.h>
#endif
static constexpr char log_category_prefix[] = "Util ";
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 };
@@ -141,7 +161,7 @@ NOINLINE difficulty_type& difficulty_type::operator/=(difficulty_type b)
NOINLINE bool difficulty_type::check_pow(const hash& pow_hash) const
{
const uint64_t* a = reinterpret_cast<const uint64_t*>(pow_hash.h);
const uint64_t* a = pow_hash.u64();
uint64_t result[6] = {};
uint64_t product[6] = {};
@@ -323,9 +343,13 @@ struct BackgroundJobTracker::Impl
{
MutexLock lock(m_lock);
auto it = m_jobs.insert({ name, 1 });
auto it = m_jobs.emplace(name, 1);
if (!it.second) {
++it.first->second;
const int32_t n = ++it.first->second;
// Print the warning only once as the number goes past 20
if (n == 20) {
LOGWARN(3, "Performance warning: there are " << n << " instances of " << name << " running in the background. This shouldn't be normally happening - check logs for other warnings and errors.");
}
}
}
@@ -339,8 +363,8 @@ struct BackgroundJobTracker::Impl
return;
}
--it->second;
if (it->second <= 0) {
const int32_t n = --it->second;
if (n <= 0) {
m_jobs.erase(it);
}
}
@@ -602,10 +626,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;
+24 -4
View File
@@ -35,10 +35,19 @@
namespace p2pool {
#define P2POOL_VERSION_MAJOR 3
#define P2POOL_VERSION_MINOR 5
#define P2POOL_VERSION_MINOR 8
#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)
@@ -301,12 +316,17 @@ bool get_dns_txt_records_base(const std::string& host, Callback<void, const char
template<typename T>
FORCEINLINE bool get_dns_txt_records(const std::string& host, T&& callback) { return get_dns_txt_records_base(host, Callback<void, const char*, size_t>::Derived<T>(std::move(callback))); }
#ifdef DEV_TRACK_MEMORY
void show_top_10_allocations();
#endif
} // namespace p2pool
void memory_tracking_start();
void memory_tracking_stop();
bool memory_tracking_stop();
void p2pool_usage();
void p2pool_version();
int p2pool_test();
namespace robin_hood {
+2 -2
View File
@@ -20,7 +20,7 @@
#include "json_parsers.h"
#include <rapidjson/document.h>
static constexpr char log_category_prefix[] = "ZMQReader ";
LOG_CATEGORY(ZMQReader)
namespace p2pool {
@@ -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());
}
}
+3 -2
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.5)
project(p2pool_tests)
option(STATIC_LIBS "Use locally built libuv and libzmq static libs" OFF)
@@ -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
@@ -96,7 +97,7 @@ include_directories(googletest/googletest/include)
if (WIN32)
set(LIBS ${LIBS} ws2_32 iphlpapi userenv psapi dnsapi dbghelp)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
if ((CMAKE_CXX_COMPILER_ID MATCHES GNU) OR (CMAKE_CXX_COMPILER_ID MATCHES Clang))
set(LIBS ${LIBS} bcrypt)
endif()
add_definitions(-DCURL_STATICLIB)
+7 -2
View File
@@ -27,7 +27,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
endif()
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(GENERAL_FLAGS "")
set(WARNING_FLAGS "/Wall /sdl")
set(WARNING_FLAGS "/W4 /sdl")
set(SECURITY_FLAGS "/GS /guard:cf")
set(OPTIMIZATION_FLAGS "/O2 /Oi /Ob2 /Ot /DNDEBUG /GL")
@@ -41,7 +41,12 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${GENERAL_FLAGS} ${WARNING_FLAGS} ${SECURITY_FLAGS} /Ob1 /Ot /Zi /MT")
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(GENERAL_FLAGS "-pthread")
if (WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
else()
set(GENERAL_FLAGS "-pthread")
endif()
set(WARNING_FLAGS "-Wall -Wextra -Wno-undefined-internal")
set(OPTIMIZATION_FLAGS "-Ofast -funroll-loops -fmerge-all-constants -flto")
+5 -5
View File
@@ -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
@@ -74,8 +74,8 @@ TEST(block_template, update)
ASSERT_EQ(diff, 300346053753ULL);
ASSERT_EQ(sidechain_diff, sidechain.difficulty());
ASSERT_EQ(seed_hash, data.seed_hash);
ASSERT_EQ(nonce_offset, 39);
ASSERT_EQ(template_id, 1);
ASSERT_EQ(nonce_offset, 39U);
ASSERT_EQ(template_id, 1U);
hash blobs_hash;
keccak(blobs.data(), static_cast<int>(blobs.size()), blobs_hash.h);
@@ -105,8 +105,8 @@ TEST(block_template, update)
ASSERT_EQ(diff, 300346053753ULL);
ASSERT_EQ(sidechain_diff, sidechain.difficulty());
ASSERT_EQ(seed_hash, data.seed_hash);
ASSERT_EQ(nonce_offset, 39);
ASSERT_EQ(template_id, 2);
ASSERT_EQ(nonce_offset, 39U);
ASSERT_EQ(template_id, 2U);
keccak(blobs.data(), static_cast<int>(blobs.size()), blobs_hash.h);
ASSERT_EQ(blobs_hash, H("c74d295a9cb7e808030284e2169a6f05b685a11c6c577a774d5eb8fad175d5cd"));
+281
View File
@@ -0,0 +1,281 @@
# 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 sys
allowedAPIs = {
"getaddrinfo",
"freeaddrinfo",
"WSAPoll",
"WSACreateEvent",
"WSACloseEvent",
"WSARecvFrom",
"WSASend",
"WSARecv",
"WSADuplicateSocketW",
"WSASocketW",
"WSAIoctl",
"getnameinfo",
"WSASocketA",
"GetAdaptersAddresses",
"GetBestInterface",
"DnsFree",
"LoadLibraryExW",
"RtlPcToFileHeader",
"RtlUnwindEx",
"GetCPInfo",
"GetStringTypeW",
"GetDriveTypeW",
"DecodePointer",
"EncodePointer",
"FreeLibraryAndExitThread",
"SystemTimeToTzSpecificLocalTime",
"CreateThread",
"LCMapStringEx",
"ExitThread",
"GetModuleHandleExW",
"SetStdHandle",
"FlsFree",
"FlsSetValue",
"FlsGetValue",
"SetFilePointer",
"SetEndOfFile",
"UnmapViewOfFile",
"GetLastError",
"FlushViewOfFile",
"CreateFileA",
"CloseHandle",
"CreateFileMappingA",
"MapViewOfFile",
"FlushFileBuffers",
"GetStdHandle",
"WriteConsoleA",
"SetConsoleMode",
"GetConsoleMode",
"FormatMessageA",
"SetThreadPriority",
"GetCurrentThread",
"SetThreadPriorityBoost",
"IsDebuggerPresent",
"Sleep",
"RaiseException",
"InitializeCriticalSection",
"EnterCriticalSection",
"LeaveCriticalSection",
"DeleteCriticalSection",
"QueryPerformanceCounter",
"QueryPerformanceFrequency",
"GetTickCount",
"FreeLibrary",
"GetProcAddress",
"LoadLibraryA",
"SetHandleInformation",
"WaitForSingleObject",
"GetCurrentThreadId",
"TryEnterCriticalSection",
"GetCurrentProcessId",
"GetHandleInformation",
"SetLastError",
"CreateIoCompletionPort",
"GetQueuedCompletionStatusEx",
"InitializeSRWLock",
"ReleaseSRWLockExclusive",
"ReleaseSRWLockShared",
"AcquireSRWLockExclusive",
"AcquireSRWLockShared",
"InitOnceExecuteOnce",
"GetTickCount64",
"GetModuleHandleW",
"SetFileCompletionNotificationModes",
"WideCharToMultiByte",
"DuplicateHandle",
"TryAcquireSRWLockShared",
"InitializeConditionVariable",
"WakeConditionVariable",
"WakeAllConditionVariable",
"SleepConditionVariableCS",
"SetEvent",
"ReleaseSemaphore",
"CreateEventA",
"GetCurrentProcess",
"ResumeThread",
"TlsAlloc",
"TlsGetValue",
"TlsSetValue",
"TlsFree",
"GetNativeSystemInfo",
"CreateSemaphoreA",
"GetFileType",
"PostQueuedCompletionStatus",
"CreateFileW",
"ResetEvent",
"QueueUserWorkItem",
"GetFileAttributesExW",
"UnregisterWait",
"GetNumberOfConsoleInputEvents",
"ReadConsoleInputW",
"ReadConsoleW",
"WriteConsoleW",
"FillConsoleOutputCharacterW",
"FillConsoleOutputAttribute",
"GetConsoleCursorInfo",
"SetConsoleCursorInfo",
"GetConsoleScreenBufferInfo",
"SetConsoleCursorPosition",
"SetConsoleTextAttribute",
"WriteConsoleInputW",
"ReadFile",
"WriteFile",
"ConnectNamedPipe",
"SetNamedPipeHandleState",
"PeekNamedPipe",
"CreateNamedPipeW",
"CancelIoEx",
"CancelSynchronousIo",
"SwitchToThread",
"LocalFree",
"GetNamedPipeHandleStateA",
"GetNamedPipeClientProcessId",
"GetNamedPipeServerProcessId",
"MultiByteToWideChar",
"SetConsoleCtrlHandler",
"SetErrorMode",
"GetQueuedCompletionStatus",
"CreateDirectoryW",
"FindClose",
"FindFirstFileW",
"FindNextFileW",
"RtlUnwind",
"GetFileAttributesW",
"GetFileInformationByHandle",
"GetFileSizeEx",
"GetFinalPathNameByHandleW",
"GetFullPathNameW",
"RemoveDirectoryW",
"SetFilePointerEx",
"SetFileTime",
"DeviceIoControl",
"GetSystemInfo",
"GetSystemTimeAsFileTime",
"ReOpenFile",
"CopyFileW",
"MoveFileExW",
"CreateHardLinkW",
"GetFileInformationByHandleEx",
"CreateSymbolicLinkW",
"CancelIo",
"DebugBreak",
"GetCurrentDirectoryW",
"TerminateProcess",
"GetExitCodeProcess",
"UnregisterWaitEx",
"LCMapStringW",
"GetLongPathNameW",
"ReadDirectoryChangesW",
"GetEnvironmentStringsW",
"FreeEnvironmentStringsW",
"SetEnvironmentVariableW",
"GetModuleFileNameW",
"FileTimeToSystemTime",
"GetModuleHandleA",
"LoadLibraryExA",
"GetStartupInfoW",
"FormatMessageW",
"InitializeCriticalSectionEx",
"GetSystemDirectoryA",
"WaitForSingleObjectEx",
"GetEnvironmentVariableA",
"SleepEx",
"VerSetConditionMask",
"VerifyVersionInfoW",
"VirtualProtect",
"VirtualFree",
"VirtualAlloc",
"GetLargePageMinimum",
"HeapFree",
"HeapAlloc",
"GetProcessHeap",
"FlsAlloc",
"SleepConditionVariableSRW",
"GetExitCodeThread",
"InitializeSListHead",
"CreateEventW",
"InitializeCriticalSectionAndSpinCount",
"IsProcessorFeaturePresent",
"SetUnhandledExceptionFilter",
"UnhandledExceptionFilter",
"RtlVirtualUnwind",
"RtlLookupFunctionEntry",
"SetFileAttributesW",
"GetConsoleOutputCP",
"ExitProcess",
"GetCommandLineA",
"GetCommandLineW",
"GetDateFormatW",
"GetTimeFormatW",
"CompareStringW",
"GetLocaleInfoW",
"IsValidLocale",
"GetUserDefaultLCID",
"EnumSystemLocalesW",
"HeapReAlloc",
"HeapSize",
"FindFirstFileExW",
"IsValidCodePage",
"GetACP",
"GetOEMCP",
"GetTimeZoneInformation",
"RegisterWaitForSingleObject",
"GetDiskFreeSpaceW",
"RtlCaptureContext",
"GetMessageA",
"GetSystemMetrics",
"MapVirtualKeyW",
"DispatchMessageA",
"TranslateMessage",
"AdjustTokenPrivileges",
"LookupPrivilegeValueA",
"CryptDestroyHash",
"CryptHashData",
"CryptCreateHash",
"CryptGetHashParam",
"CryptReleaseContext",
"CryptAcquireContextA",
"SystemFunction036",
"OpenProcessToken",
"SetSecurityDescriptorDacl",
"InitializeSecurityDescriptor",
"BCryptGenRandom",
"GetConsoleCP",
}
f = open(sys.argv[1], 'r')
lines = f.readlines()
f.close()
exit_code = 0
count = 0
for line in lines:
count += 1
api = line[29:].strip()
if api not in allowedAPIs:
print('API call "{}" is not checked for Windows 7 compatibility. Check it and then add it to the list in tests/src/check_imports.py'.format(api))
exit_code = 1
if exit_code == 0:
print('{} imports checked successfully'.format(count))
sys.exit(exit_code)
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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
@@ -567,8 +567,8 @@ TEST(difficulty_type, check_pow)
for (int i = 0; i < 1000; ++i) {
// Random difficulty between 300G and 400G
difficulty_type diff{ 300000000000ull + (r() % 100000000000ull), 0 };
hash h;
diff.lo = 300000000000ull + (r() % 100000000000ull);
diff.hi = 0;
// All zeros
memset(h.h, 0, HASH_SIZE);
+1 -1
View File
@@ -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 -1
View File
@@ -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
Binary file not shown.
+113
View File
@@ -0,0 +1,113 @@
/*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* Copyright (c) 2021-2023 SChernykh <https://github.com/SChernykh>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common.h"
#include "gtest/gtest.h"
namespace p2pool {
TEST(log, stream)
{
constexpr int N = 63;
char buf[N + 1] = {};
log::Stream s(buf);
for (int iter = 0; iter < 2; ++iter) {
ASSERT_EQ(s.m_bufSize, N);
for (int i = 0; i < N; ++i) {
s << ' ';
ASSERT_EQ(s.m_pos, i + 1);
ASSERT_EQ(s.m_spilled, 0);
}
s << ' ';
ASSERT_EQ(s.m_pos, N);
ASSERT_EQ(s.m_spilled, 1);
for (int i = 0; i < N; ++i) {
ASSERT_EQ(buf[i], ' ');
}
ASSERT_EQ(buf[N], '\0');
s.reset(buf, N + 1);
}
}
TEST(log, pad_right)
{
constexpr int N = 63;
char buf[N + 1] = {};
log::Stream s(buf);
s << log::pad_right('1', N);
ASSERT_EQ(s.m_pos, N);
ASSERT_EQ(s.m_spilled, 0);
ASSERT_EQ(buf[0], '1');
for (int i = 1; i < N; ++i) {
ASSERT_EQ(buf[i], ' ');
}
ASSERT_EQ(buf[N], '\0');
}
template<typename T, bool hex>
void check_number(T value)
{
constexpr size_t N = 64;
char buf[N];
memset(buf, -1, N);
log::Stream s(buf);
s << log::BasedValue<T, hex ? 16 : 10>(value) << '\0';
char buf2[N];
memset(buf2, -1, N);
snprintf(buf2, N, hex ? "%llx" : (std::is_signed<T>::value ? "%lld" : "%llu"), value);
ASSERT_EQ(memcmp(buf, buf2, N), 0);
}
TEST(log, numbers)
{
for (int64_t i = -1024; i <= 1024; ++i) {
check_number<int64_t, false>(i);
if (i >= 0) {
check_number<int64_t, true>(i);
check_number<uint64_t, false>(i);
check_number<uint64_t, true>(i);
}
}
check_number<int64_t, false>(std::numeric_limits<int64_t>::min());
check_number<int64_t, false>(std::numeric_limits<int64_t>::max());
check_number<int64_t, true>(std::numeric_limits<int64_t>::max());
check_number<uint64_t, false>(std::numeric_limits<uint64_t>::max());
check_number<uint64_t, true>(std::numeric_limits<uint64_t>::max());
}
}
+3 -1
View File
@@ -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
@@ -18,9 +18,11 @@
#include "gtest/gtest.h"
void p2pool_usage() {}
namespace p2pool { void set_main_thread(); }
int main(int argc, char** argv)
{
p2pool::set_main_thread();
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+61 -26
View File
@@ -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
@@ -57,33 +57,41 @@ TEST(pool_block, deserialize)
int outputs_offset, outputs_blob_size;
const std::vector<uint8_t> mainchain_data = b.serialize_mainchain_data(&header_size, &miner_tx_size, &outputs_offset, &outputs_blob_size);
ASSERT_EQ(mainchain_data.size(), 1757);
ASSERT_EQ(header_size, 43);
ASSERT_EQ(miner_tx_size, 1457);
ASSERT_EQ(mainchain_data.size(), 1757U);
ASSERT_EQ(header_size, 43U);
ASSERT_EQ(miner_tx_size, 1457U);
ASSERT_EQ(outputs_offset, 54);
ASSERT_EQ(outputs_blob_size, 1371);
ASSERT_EQ(b.m_majorVersion, 16);
ASSERT_EQ(b.m_minorVersion, 16);
ASSERT_EQ(b.m_timestamp, 1679221824);
ASSERT_EQ(b.m_nonce, 1247);
ASSERT_EQ(b.m_txinGenHeight, 2845298);
ASSERT_EQ(b.m_outputs.size(), 35);
ASSERT_EQ(b.m_extraNonceSize, 4);
ASSERT_EQ(b.m_extraNonce, 1482827308);
ASSERT_EQ(b.m_transactions.size(), 9);
ASSERT_EQ(b.m_uncles.size(), 0);
ASSERT_EQ(b.m_sidechainHeight, 4674483);
ASSERT_EQ(b.m_difficulty.lo, 1854596983);
ASSERT_EQ(b.m_difficulty.hi, 0);
ASSERT_EQ(b.m_majorVersion, 16U);
ASSERT_EQ(b.m_minorVersion, 16U);
ASSERT_EQ(b.m_timestamp, 1679221824U);
ASSERT_EQ(b.m_nonce, 1247U);
ASSERT_EQ(b.m_txinGenHeight, 2845298U);
ASSERT_EQ(b.m_outputs.size(), 35U);
ASSERT_EQ(b.m_extraNonceSize, 4U);
ASSERT_EQ(b.m_extraNonce, 1482827308U);
ASSERT_EQ(b.m_transactions.size(), 9U);
ASSERT_EQ(b.m_uncles.size(), 0U);
ASSERT_EQ(b.m_sidechainHeight, 4674483U);
ASSERT_EQ(b.m_difficulty.lo, 1854596983U);
ASSERT_EQ(b.m_difficulty.hi, 0U);
ASSERT_EQ(b.m_cumulativeDifficulty.lo, 7172845253120126ull);
ASSERT_EQ(b.m_cumulativeDifficulty.hi, 0);
ASSERT_EQ(b.m_depth, 0);
ASSERT_EQ(b.m_cumulativeDifficulty.hi, 0U);
ASSERT_EQ(b.m_depth, 0U);
ASSERT_EQ(b.m_verified, false);
ASSERT_EQ(b.m_invalid, false);
ASSERT_EQ(b.m_broadcasted, false);
ASSERT_EQ(b.m_wantBroadcast, false);
hash seed;
{
std::stringstream s;
s << "6fc9c4a55eb513eb31955c084d9342e0082987f9e42da042449b7c9001176d3a";
s >> seed;
}
#if defined(__FreeBSD__) || defined(__OpenBSD__)
class RandomX_Hasher_Test : public RandomX_Hasher_Base
{
public:
@@ -107,8 +115,12 @@ TEST(pool_block, deserialize)
return false;
}
} hasher;
#else
RandomX_Hasher hasher(nullptr);
hasher.set_seed(seed);
#endif
hash seed, pow_hash;
hash pow_hash;
ASSERT_EQ(b.get_pow_hash(&hasher, 0, seed, pow_hash), true);
std::stringstream s;
@@ -130,14 +142,14 @@ TEST(pool_block, verify)
const char* m_fileName;
uint64_t m_txinGenHeight;
uint64_t m_sidechainHeight;
bool m_shuffle;
} tests[2] = {
{ "default", "sidechain_dump.dat", 2870010, 4957203 },
{ "mini", "sidechain_dump_mini.dat", 2870010, 4414446 },
{ "default", "sidechain_dump.dat", 2870010, 4957203, true },
{ "mini", "sidechain_dump_mini.dat", 2870010, 4414446, false },
};
for (const STest& t : tests)
{
PoolBlock b;
SideChain sidechain(nullptr, NetworkType::Mainnet, t.m_poolName);
// Difficulty of block 2869248
@@ -151,17 +163,40 @@ TEST(pool_block, verify)
f.read(reinterpret_cast<char*>(buf.data()), buf.size());
ASSERT_EQ(f.good(), true);
std::vector<PoolBlock*> blocks;
for (const uint8_t *p = buf.data(), *e = buf.data() + buf.size(); p < e;) {
ASSERT_TRUE(p + sizeof(uint32_t) <= e);
const uint32_t n = *reinterpret_cast<const uint32_t*>(p);
p += sizeof(uint32_t);
ASSERT_TRUE(p + n <= e);
ASSERT_EQ(b.deserialize(p, n, sidechain, nullptr, false), 0);
PoolBlock* b = new PoolBlock();
ASSERT_EQ(b->deserialize(p, n, sidechain, nullptr, false), 0);
p += n;
ASSERT_TRUE(sidechain.add_block(b));
ASSERT_TRUE(sidechain.find_block(b.m_sidechainId) != nullptr);
blocks.push_back(b);
}
if (t.m_shuffle) {
std::mt19937_64 rng;
for (uint64_t i = 0, k, n = blocks.size(); i < n - 1; ++i) {
umul128(rng(), n - i, &k);
std::swap(blocks[i], blocks[i + k]);
}
}
for (uint64_t i = 0, n = blocks.size(); i < n; ++i) {
ASSERT_TRUE(sidechain.add_block(*blocks[i]));
ASSERT_TRUE(sidechain.find_block(blocks[i]->m_sidechainId) != nullptr);
delete blocks[i];
}
for (auto it = sidechain.blocksById().begin(); it != sidechain.blocksById().end(); ++it) {
const PoolBlock* b = it->second;
ASSERT_TRUE(b->m_verified);
ASSERT_FALSE(b->m_invalid);
}
const PoolBlock* tip = sidechain.chainTip();
+91 -14
View File
@@ -1,37 +1,114 @@
# 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
import json
f = open('stratum_dummy' + sys.argv[1] + '.log', 'wb');
f = open('stratum_dummy' + sys.argv[1] + '.log', 'wb')
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
sock.setblocking(True)
f.write(b'Connecting')
f.flush()
time.sleep(5)
while True:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
sock.setblocking(True)
while sock.connect_ex(('127.0.0.1', 3333)) != 0:
f.write(b'.\n')
if sock.connect_ex(('127.0.0.1', 3333)) == 0:
break;
sock.close()
f.write(b'.')
f.flush()
print('.')
time.sleep(1)
diff = '';
f.write(b'\n')
f.flush()
diff = ''
if (sys.argv[1] == '2'):
diff = '+1000';
diff = '+1000'
if (sys.argv[1] == '3'):
diff = '+10000000';
diff = '+10000000'
request = '{"id":1,"method":"login","params":{"login":"x' + diff + '"}}\n'
msg_id = 1
request = '{"id":' + str(msg_id) + ',"method":"login","params":{"login":"x' + diff + '"}}\n'
msg_id += 1
s = '-> ' + request
print(s, end='')
sock.sendall(request.encode('utf-8'))
f.write(s.encode('utf-8'))
f.flush()
rpc_id = ''
while True:
data = sock.recv(1024)
if len(data) == 0:
break;
f.write(data)
break
s = '<- ' + data.decode('utf-8')
print(s, end='')
f.write(s.encode('utf-8'))
f.flush()
print(data.decode('utf-8'))
obj = json.loads(data)
job_id = ''
if ('method' in obj) and ('params' in obj) and (obj['method'] == 'job'):
job_id = obj['params']['job_id']
target = obj['params']['target']
elif ('result' in obj) and ('job' in obj['result']):
if ('id' in obj['result']):
rpc_id = obj['result']['id']
job_id = obj['result']['job']['job_id']
target = obj['result']['job']['target']
if (job_id != ''):
if (msg_id < 4):
result = ('f' if (msg_id == 2) else '0') * 64
request = '{"id":' + str(msg_id) + ',"method":"submit","params":{"id":"' + rpc_id + '","job_id":"' + job_id + '","nonce":"ffffffff","result":"' + result + '"}}\n'
elif (msg_id == 4):
request = '{"id":' + str(msg_id) + ',"method":"keepalived"}\n'
else:
t = bytearray.fromhex(target)
for i in range(len(t)):
if (t[i] > 0):
t[i] -= 1
break
else:
t[i] = 255
result = ('f' * (64 - len(target))) + t.hex()
request = '{"id":' + str(msg_id) + ',"method":"submit","params":{"id":"' + rpc_id + '","job_id":"' + job_id + '","nonce":"ffffffff","result":"' + result + '"}}\n'
msg_id += 1
s = '-> ' + request
print(s, end='')
sock.sendall(request.encode('utf-8'))
f.write(s.encode('utf-8'))
f.flush()
sock.close()
f.close()
-1
View File
@@ -1,4 +1,3 @@
race:p2pool::log::Worker::run()
race:p2pool::log::Worker::write
called_from_lib:libzmq.so
race_top:do_loglevel
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
* 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 -1
View File
@@ -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