mirror of
https://github.com/wownero/p2pool-wow.git
synced 2026-10-30 04:28:40 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0db57e5047 | ||
|
|
e7919514d4 | ||
|
|
7ab21c6afd | ||
|
|
2209e0cc70 | ||
|
|
a73b4616a4 | ||
|
|
9593311332 | ||
|
|
9a09d15bea | ||
|
|
f082488e4b | ||
|
|
c56773d4d6 | ||
|
|
752e2381d6 | ||
|
|
03f829e18c | ||
|
|
06b66c99db | ||
|
|
0b0ad9ff82 | ||
|
|
de9f13d393 | ||
|
|
272d206741 | ||
|
|
c9493ec7fa | ||
|
|
5ef4134955 | ||
|
|
8045c40026 | ||
|
|
d4a1b14820 | ||
|
|
cc6ce4a366 | ||
|
|
25e5f80a81 | ||
|
|
d4b339b1a3 | ||
|
|
4bdd524d84 | ||
|
|
b78fe02405 | ||
|
|
dfa0c7ffb1 | ||
|
|
ec97a14da7 | ||
|
|
3a2e9e8b94 | ||
|
|
069c96aa1d |
@@ -159,13 +159,29 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake libuv zmq libpgm
|
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake
|
||||||
|
|
||||||
|
- name: Build libuv
|
||||||
|
run: |
|
||||||
|
cd external/src/libuv
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
make -j3
|
||||||
|
|
||||||
|
- name: Build libzmq
|
||||||
|
run: |
|
||||||
|
cd external/src/libzmq
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -DWITH_TLS=OFF -DWITH_LIBSODIUM=OFF
|
||||||
|
make -j3
|
||||||
|
|
||||||
- name: Build p2pool
|
- name: Build p2pool
|
||||||
run: |
|
run: |
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake ..
|
cmake .. -DSTATIC_BINARY=ON
|
||||||
make -j3
|
make -j3
|
||||||
|
|
||||||
- name: Build tests
|
- name: Build tests
|
||||||
@@ -173,7 +189,7 @@ jobs:
|
|||||||
cd tests
|
cd tests
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake ..
|
cmake .. -DSTATIC_LIBS=ON
|
||||||
make -j3
|
make -j3
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -G "Visual Studio 16 2019"
|
cmake .. -G "Visual Studio 17 2022"
|
||||||
|
|
||||||
- name: Run cppcheck
|
- name: Run cppcheck
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+8
-5
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
project(p2pool)
|
project(p2pool)
|
||||||
|
|
||||||
option(STATIC_LINUX_BINARY "Build static Linux binary" OFF)
|
option(STATIC_BINARY "Build static binary" OFF)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
@@ -124,15 +124,18 @@ add_definitions(/DZMQ_STATIC)
|
|||||||
|
|
||||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})
|
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})
|
||||||
|
|
||||||
if (STATIC_LINUX_BINARY)
|
if (STATIC_BINARY)
|
||||||
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} ${CMAKE_PROJECT_NAME})
|
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} ${CMAKE_PROJECT_NAME})
|
||||||
|
|
||||||
|
set(STATIC_LIBS randomx)
|
||||||
|
if (NOT APPLE)
|
||||||
|
set(STATIC_LIBS ${STATIC_LIBS} pthread dl)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||||
"${CMAKE_SOURCE_DIR}/external/src/libsodium/src/libsodium/.libs/libsodium.a"
|
|
||||||
"${CMAKE_SOURCE_DIR}/external/src/libzmq/build/lib/libzmq.a"
|
"${CMAKE_SOURCE_DIR}/external/src/libzmq/build/lib/libzmq.a"
|
||||||
"${CMAKE_SOURCE_DIR}/external/src/libuv/build/libuv_a.a"
|
"${CMAKE_SOURCE_DIR}/external/src/libuv/build/libuv_a.a"
|
||||||
randomx
|
${STATIC_LIBS}
|
||||||
pthread
|
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME} debug ${ZMQ_LIBRARY_DEBUG} debug ${UV_LIBRARY_DEBUG} optimized ${ZMQ_LIBRARY} optimized ${UV_LIBRARY} ${LIBS})
|
target_link_libraries(${CMAKE_PROJECT_NAME} debug ${ZMQ_LIBRARY_DEBUG} debug ${UV_LIBRARY_DEBUG} optimized ${ZMQ_LIBRARY} optimized ${UV_LIBRARY} ${LIBS})
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Decentralized pool for Monero mining.
|
|||||||
|
|
||||||
Pool status and monitoring pages can be found at https://p2pool.io/ and https://p2pool.observer/
|
Pool status and monitoring pages can be found at https://p2pool.io/ and https://p2pool.observer/
|
||||||
|
|
||||||
### Build status
|
### Build Status
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
@@ -14,6 +14,17 @@ Pool status and monitoring pages can be found at https://p2pool.io/ and https://
|
|||||||
<img alt="Coverity Scan Build Status"
|
<img alt="Coverity Scan Build Status"
|
||||||
src="https://scan.coverity.com/projects/23659/badge.svg"/>
|
src="https://scan.coverity.com/projects/23659/badge.svg"/>
|
||||||
</a>
|
</a>
|
||||||
|
# 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)
|
||||||
|
- [Default P2Pool parameters](#default-p2pool-parameters)
|
||||||
|
- [How to mine on P2Pool](#how-to-mine-on-p2pool)
|
||||||
|
- [General Considerations](#general-considerations)
|
||||||
|
- [GNU/Linux](#gnulinux)
|
||||||
|
- [Windows](#windows)
|
||||||
|
- [Build instructions](#build-instructions)
|
||||||
|
- [Donations](#donations)
|
||||||
|
|
||||||
## Pool mining vs Solo mining vs P2Pool mining
|
## Pool mining vs Solo mining vs P2Pool mining
|
||||||
|
|
||||||
@@ -54,72 +65,113 @@ First you need to find a pool share. This share will stay in PPLNS window for 21
|
|||||||
|
|
||||||
## How to mine on P2Pool
|
## How to mine on P2Pool
|
||||||
|
|
||||||
This guide assumes that you run everything on the same machine. If it's not the case, change `127.0.0.1` to appropriate IP addresses for your setup. It's highly recommended to create a new mainnet wallet for mining because **wallet addresses are public on p2pool**.
|
### General Considerations
|
||||||
|
|
||||||
**Wallet software compatible with p2pool payouts**
|
- In order to mine on P2Pool, a synced Monero node using monerod v0.17.3.0 or newer is required. If you do not currently have one configured, you can find instructions to do so [here](https://sethforprivacy.com/guides/run-a-monero-node-advanced/).
|
||||||
- Official Monero CLI and GUI v0.17.2.3 and newer
|
- It is highly recommended that you create a separate restricted user account for mining. P2Pool is still relatively new and may still have serious bugs/vulnerabilities.
|
||||||
- Monerujo v2.1.0 "Vertant" and newer
|
- You have to use a primary wallet address for mining. Subaddresses and integrated addresses are not supported, just like with monerod solo mining.
|
||||||
- Cake Wallet v4.2.7 and newer
|
- Starting from P2Pool v1.7, 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.
|
||||||
- Feather Wallet v1.0.0 and newer
|
- 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.
|
||||||
- MyMonero
|
- You can connect multiple miners to the same P2Pool node. The more the better!
|
||||||
|
- The below steps assume that you run everything on the same machine. If it's not the case, change `127.0.0.1` to appropriate IP addresses for your setup.
|
||||||
|
- It is highly recommended to create a new mainnet wallet for P2Pool mining because **wallet addresses are public on P2Pool**.
|
||||||
|
|
||||||
**General Considerations**
|
**Wallet software compatible with P2Pool payouts**
|
||||||
|
- [Official Monero CLI and GUI v0.17.2.3 and newer](https://www.getmonero.org/downloads/)
|
||||||
- Create a separate restricted user account for mining. p2pool is relatively new and may still have serious bugs/vulnerabilities!
|
- [Monerujo v2.1.0 "Vertant" and newer](https://www.monerujo.io/)
|
||||||
- You have to use the primary wallet address for mining. Subaddresses and integrated addresses are not supported, just like with monerod solo mining.
|
- [Cake Wallet v4.2.7 and newer](https://cakewallet.com/)
|
||||||
- Check that ports 18080 (Monero p2p port) and 37889 (p2pool 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.
|
- [Monero.com by Cake Wallet](https://monero.com/)
|
||||||
- You can connect multiple miners to the same p2pool node. The more the better!
|
- [Feather Wallet v1.0.0 and newer](https://featherwallet.org/)
|
||||||
- Starting from p2pool v1.7, you can add `--mini` to p2pool command line to connect to the **p2pool-mini** sidechain. Note that it will also change the default p2p port from 37889 to 37888.
|
- [MyMonero](https://mymonero.com/)
|
||||||
|
|
||||||
Step-by-step guide:
|
|
||||||
|
|
||||||
### GNU/Linux
|
### GNU/Linux
|
||||||
|
|
||||||
- Download binaries from https://github.com/SChernykh/p2pool/releases/latest
|
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
|
- Alternatively, grab the latest source code for P2Pool and [build it](#build-instructions).
|
||||||
- Prepare enough huge pages (each of monerod/p2pool/xmrig needs them): `sudo sysctl vm.nr_hugepages=3072`
|
2. Download the latest XMRig (linux-static-x64) binary [here](https://github.com/xmrig/xmrig/releases/latest).
|
||||||
- Get xmrig (linux-static-x64) binary from https://github.com/xmrig/xmrig/releases/latest
|
3. Prepare enough huge pages (required for each instance of monerod/P2Pool/XMRig):
|
||||||
- Check that ports 18080 (Monero p2p port) and 37889 (p2pool p2p port) are open in your firewall to ensure better connectivity
|
```
|
||||||
- Use the `monerod` binary v0.17.3.0 or newer
|
sudo sysctl vm.nr_hugepages=3072
|
||||||
- Run `./monerod --zmq-pub tcp://127.0.0.1:18083 --disable-dns-checkpoints --enable-dns-blocklist` **don't forget --zmq-pub parameter in the command line**
|
```
|
||||||
- Run `./p2pool --host 127.0.0.1 --wallet YOUR_WALLET_ADDRESS`
|
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.
|
||||||
- p2pool has verbose logging by default, you can reduce it by using "loglevel N" command where N is between 0 and 6. Default loglevel is 3.
|
5. Start `monerod` with the following command/options:
|
||||||
- You can use `logrotate` with a config like this to control logfile growth:
|
```
|
||||||
```
|
./monerod --zmq-pub tcp://127.0.0.1:18083 --disable-dns-checkpoints --enable-dns-blocklist
|
||||||
<path-to-logfile>
|
```
|
||||||
{
|
**Note:** The `--zmq-pub` option is required for P2Pool to work properly.
|
||||||
rotate 7
|
|
||||||
daily
|
6. Start P2Pool with the following command/options:
|
||||||
missingok
|
```
|
||||||
delaycompress
|
./p2pool --host 127.0.0.1 --wallet YOUR_WALLET_ADDRESS
|
||||||
nocreate
|
```
|
||||||
}
|
7. Wait until the initial P2Pool sync is finished (shouldn't take more than 5-10 minutes).
|
||||||
```
|
8. Start XMRig with the following command/options:
|
||||||
- Wait until initial p2pool sync is finished, it shouldn't take more than 5-10 minutes, once completed xmrig should be able to connect to the stratum server on port 3333.
|
```
|
||||||
- Run `./xmrig -o 127.0.0.1:3333`. Note that you don't need to specify wallet address for xmrig. **Wallet address set in xmrig config will be ignored!**
|
./xmrig -o 127.0.0.1:3333
|
||||||
- To set custom fixed difficulty for your miner (for example, 10000), run `./xmrig -u x+10000 -o 127.0.0.1:3333`
|
```
|
||||||
- xmrig should connect and start mining
|
- Note that you don't need to specify your wallet address for XMRig. **Wallet addresses set in XMRig config will be ignored!**
|
||||||
- Also check p2pool.log for any warnings and errors: `grep -E 'WARNING|ERROR' p2pool.log`
|
- To set a custom fixed difficulty for your miner (for example, 10000), instead start XMRig with the following options:
|
||||||
|
```
|
||||||
|
./xmrig -u x+10000 -o 127.0.0.1:3333
|
||||||
|
```
|
||||||
|
9. XMRig should connect and start mining!
|
||||||
|
|
||||||
|
**Additional Information:**
|
||||||
|
- For a more in-depth beginner friendly walk-through with the option of using Docker, please see SethForPrivacy's guide at: https://sethforprivacy.com/guides/run-a-p2pool-node/
|
||||||
|
- You can check the p2pool.log for any warnings or errors using the following command:
|
||||||
|
```
|
||||||
|
grep -E 'WARNING|ERROR' p2pool.log
|
||||||
|
```
|
||||||
|
- P2Pool has verbose logging by default, you can reduce it by using "loglevel N" command where N is between 0 and 6. Default loglevel is 3.
|
||||||
|
- You can use `logrotate` with a config like this to control logfile growth:
|
||||||
|
```
|
||||||
|
<path-to-logfile>
|
||||||
|
{
|
||||||
|
rotate 7
|
||||||
|
daily
|
||||||
|
missingok
|
||||||
|
delaycompress
|
||||||
|
nocreate
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
*NOTE: Windows SmartScreen may block incoming connections by files that are "Downloaded from the Internet". You can allow 'p2pool.exe' and 'monerod.exe' by double-clicking them, clicking "More Info", then click "Run Anyway" and then closing them immediately so you can run them from the command line. Advanced users can use the PowerShell cmdlet `Unblock-File` to remove this flag.*
|
**Note:** *Windows SmartScreen may block incoming connections by files that are "Downloaded from the Internet". You can allow 'p2pool.exe' and 'monerod.exe' by double-clicking them, clicking "More Info", then click "Run Anyway" and then closing them immediately so you can run them from the command line. Advanced users can use the PowerShell cmdlet `Unblock-File` to remove this flag.*
|
||||||
|
|
||||||
- Download p2pool binaries from https://github.com/SChernykh/p2pool/releases/latest
|
1. Download the latest P2Pool binaries [here](https://github.com/SChernykh/p2pool/releases/latest).
|
||||||
- Download xmrig binary from https://github.com/xmrig/xmrig/releases/latest *(xmrig-6.15.2-gcc-win64.zip is the current version)*
|
- Alternatively, grab the latest source code for P2Pool and [build it](#build-instructions).
|
||||||
- Expand the p2pool binaries into an appropriate location (`%USERPROFILE%/bin` or `C:/bin/` are good options)
|
2. Download the latest XMRig binary [here](https://github.com/xmrig/xmrig/releases/latest).
|
||||||
- Expand xmrig binary into appropriate location (same folder as p2pool is fine)
|
3. Expand the P2Pool binaries into an appropriate location (`%USERPROFILE%/bin` or `C:/bin/` are good options)
|
||||||
- Prepare huge pages (each of monerod/p2pool/xmrig needs them):
|
4. Expand XMRig binary into an appropriate location (the same folder as P2Pool is fine).
|
||||||
- On Windows 10 or above, run xmrig at least once as Administrator (right-click Run As Administrator)
|
5. Prepare huge pages to work properly (each instance of monerod/P2Pool/XMRig needs them):
|
||||||
- On earlier versions of Windows, you'll need to run it as admin at least once per login.
|
- On Windows 10 or above, run XMRig at least once as Administrator (right-click Run As Administrator)
|
||||||
- Open a command prompt and navigate to the folder where you extracted p2pool.
|
- On earlier versions of Windows, you'll need to run XMRig as Administrator at least once per login.
|
||||||
- *When running these commands, Windows Firewall may prompt to allow connections, click "Allow"*
|
6. Open a command prompt and navigate to the folder where you extracted P2Pool.
|
||||||
- Run `.\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --disable-dns-checkpoints --enable-dns-blocklist` *NOTE: don't forget --zmq-pub parameter in the command line*
|
|
||||||
- Run `.\p2pool.exe --host 127.0.0.1 --wallet YOUR_WALLET_ADDRESS`
|
**Note:** *When running the below commands, Windows Firewall may prompt to allow connections, click "Allow" if prompted.*
|
||||||
- Wait until initial p2pool sync is finished, it shouldn't take more than 5-10 minutes, once completed xmrig should be able to connect to the stratum server on port 3333.
|
|
||||||
- Run `.\xmrig.exe -o 127.0.0.1:3333`. Note that you don't need to specify wallet address for xmrig. **Wallet address set in xmrig config will be ignored!**
|
7. Start `monerod` with the following command/options:
|
||||||
- To set custom fixed difficulty for your miner (for example, 10000), run `xmrig.exe -u x+10000 -o 127.0.0.1:3333`
|
```
|
||||||
- Windows Quickstart: Create a batch (.bat) file with the following contents and place it in your p2pool directory along with xmrig.exe.
|
.\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --disable-dns-checkpoints --enable-dns-blocklist
|
||||||
|
```
|
||||||
|
**Note:** The `--zmq-pub` option is required for P2Pool to work properly.
|
||||||
|
8. Start P2Pool with the following command/options:
|
||||||
|
```
|
||||||
|
.\p2pool.exe --host 127.0.0.1 --wallet YOUR_WALLET_ADDRESS
|
||||||
|
```
|
||||||
|
9. Wait until the initial P2Pool sync is finished (shouldn't take more than 5-10 minutes).
|
||||||
|
10. Start XMRig with the following command/options:
|
||||||
|
```
|
||||||
|
.\xmrig.exe -o 127.0.0.1:3333
|
||||||
|
```
|
||||||
|
- Note that you don't need to specify your wallet address for XMRig. **Wallet addresses set in XMRig config will be ignored!**
|
||||||
|
- To set a custom fixed difficulty for your miner (for example, 10000), instead start XMRig with the following options:
|
||||||
|
```
|
||||||
|
xmrig.exe -u x+10000 -o 127.0.0.1:3333
|
||||||
|
```
|
||||||
|
11. XMRig should connect and start mining!
|
||||||
|
12. *(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
|
@ECHO OFF
|
||||||
start cmd /k %~dp0\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --disable-dns-checkpoints --enable-dns-blocklist
|
start cmd /k %~dp0\Monero\monerod.exe --zmq-pub tcp://127.0.0.1:18083 --disable-dns-checkpoints --enable-dns-blocklist
|
||||||
@@ -132,10 +184,11 @@ PAUSE
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Build instructions
|
## Build instructions
|
||||||
|
Please see the relevant instructions for your platform:
|
||||||
|
|
||||||
### Ubuntu 20.04
|
### Ubuntu 20.04
|
||||||
|
|
||||||
p2pool binary:
|
Run the following commands to install the necessary prerequisites, clone this repo, and build P2Pool locally on Ubuntu 20.04:
|
||||||
```
|
```
|
||||||
sudo apt update && sudo apt install git build-essential cmake libuv1-dev libzmq3-dev libsodium-dev libpgm-dev libnorm-dev libgss-dev
|
sudo apt update && sudo apt install git build-essential cmake libuv1-dev libzmq3-dev libsodium-dev libpgm-dev libnorm-dev libgss-dev
|
||||||
git clone --recursive https://github.com/SChernykh/p2pool
|
git clone --recursive https://github.com/SChernykh/p2pool
|
||||||
@@ -151,7 +204,7 @@ Make the package: [p2pool-git](https://aur.archlinux.org/packages/p2pool-git/)
|
|||||||
|
|
||||||
### [Nix/NixOS](https://nixos.org)
|
### [Nix/NixOS](https://nixos.org)
|
||||||
|
|
||||||
This is a flake only project. So you have to use [nixUnstable with nix flakes](https://nixos.wiki/wiki/Flakes) to build or install p2pool.
|
This is a flake only project. So you have to use [nixUnstable with nix flakes](https://nixos.wiki/wiki/Flakes) to build or install P2Pool.
|
||||||
The commands below use the new flake specific reference-format, so be sure to also set `ca-references` in `--experimental-features`.
|
The commands below use the new flake specific reference-format, so be sure to also set `ca-references` in `--experimental-features`.
|
||||||
|
|
||||||
Because this project has submodules which are not fixed in _nixUnstable_ yet you have to use the `nix/master` branch:
|
Because this project has submodules which are not fixed in _nixUnstable_ yet you have to use the `nix/master` branch:
|
||||||
@@ -169,21 +222,9 @@ Run the binary with arguments:
|
|||||||
nix run git+https://github.com/SChernykh/p2pool?ref=master -- --help
|
nix run git+https://github.com/SChernykh/p2pool?ref=master -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### macOS
|
|
||||||
|
|
||||||
p2pool binary:
|
|
||||||
```
|
|
||||||
brew update && brew install git cmake libuv zmq libpgm
|
|
||||||
git clone --recursive https://github.com/SChernykh/p2pool
|
|
||||||
cd p2pool
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake ..
|
|
||||||
make -j$(sysctl -n hw.logicalcpu)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
p2pool binary (Visual Studio Community 2019 build):
|
P2Pool binary (Visual Studio Community 2019 build):
|
||||||
*NOTE: You need to have the "Desktop Development with C++" module installed.*
|
*NOTE: You need to have the "Desktop Development with C++" module installed.*
|
||||||
```
|
```
|
||||||
git clone --recursive https://github.com/SChernykh/p2pool
|
git clone --recursive https://github.com/SChernykh/p2pool
|
||||||
@@ -196,6 +237,17 @@ then open generated build\p2pool.sln in Visual Studio and build it there
|
|||||||
|
|
||||||
Alternatively, you can select "Clone a repository" within the GUI, then select "Build" from the menu.
|
Alternatively, you can select "Clone a repository" within the GUI, then select "Build" from the menu.
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
Run the following commands to install the necessary prerequisites, clone this repo, and build P2Pool locally on your Mac:
|
||||||
|
```
|
||||||
|
brew update && brew install git cmake libuv zmq libpgm
|
||||||
|
git clone --recursive https://github.com/SChernykh/p2pool
|
||||||
|
cd p2pool
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
make -j$(sysctl -n hw.logicalcpu)
|
||||||
|
```
|
||||||
|
|
||||||
## Donations
|
## Donations
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
|||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||||
else()
|
else()
|
||||||
if (STATIC_LINUX_BINARY)
|
if (STATIC_BINARY)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||||
|
|||||||
+11
-7
@@ -5,14 +5,14 @@ WALLET_ADDRESS="44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F
|
|||||||
##
|
##
|
||||||
# p2pool settings
|
# p2pool settings
|
||||||
#
|
#
|
||||||
|
# Use p2pool-mini (uncomment to enable)
|
||||||
|
#P2POOL_MINI="--mini"
|
||||||
|
#
|
||||||
# Which port to listen for miner connections
|
# Which port to listen for miner connections
|
||||||
P2POOL_STRATUM_PORT=3333
|
P2POOL_STRATUM_PORT=3333
|
||||||
#
|
#
|
||||||
# How much logging - (Less) 0 - 6 (More)
|
# How much logging - (Less) 0 - 6 (More)
|
||||||
P2POOL_LOGLEVEL=2
|
P2POOL_LOGLEVEL=2
|
||||||
#
|
|
||||||
# The name of docker volume to hold p2pool data (created automatically if it doesnt exist)
|
|
||||||
P2POOL_VOLUME=p2pool
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -24,8 +24,8 @@ MONERO_GIT_TAG=latest
|
|||||||
# Limit the size of the blockchain on disk (comment to disable)
|
# Limit the size of the blockchain on disk (comment to disable)
|
||||||
PRUNE_NODE="--prune-blockchain"
|
PRUNE_NODE="--prune-blockchain"
|
||||||
#
|
#
|
||||||
# The name of docker volume to hold p2pool data (created automatically if it doesnt exist)
|
# Other monerod commandline options
|
||||||
MONERO_VOLUME=monero
|
MONERO_EXTRA_OPTIONS=""
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -34,5 +34,9 @@ MONERO_VOLUME=monero
|
|||||||
# Submit shares at a lower fixed difficulty to show mining progress (comment to disable, edit to customize)
|
# Submit shares at a lower fixed difficulty to show mining progress (comment to disable, edit to customize)
|
||||||
FIXED_MINING_DIFFICULTY="-u x+500000"
|
FIXED_MINING_DIFFICULTY="-u x+500000"
|
||||||
#
|
#
|
||||||
# Limit the number of CPU cores to use for mining (uncomment to enable, edit to customize)
|
# set process priority (0 idle, 2 normal to 5 highest)
|
||||||
#NUM_MINING_CPU="-t 4"
|
MINING_CPU_PRIORITY="--cpu-priority=2"
|
||||||
|
#
|
||||||
|
# Other XMRIG commandline options
|
||||||
|
# See: https://xmrig.com/docs/miner/command-line-options
|
||||||
|
XMRIG_EXTRA_OPTIONS=""
|
||||||
|
|||||||
@@ -31,15 +31,18 @@ docker-compose up
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Optional
|
#### Optional
|
||||||
* Open ports 18080 (Monero p2p port) and 37889 (P2Pool p2p port) 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
|
* Open ports 18080 (Monero p2p port) and 37889 (P2Pool p2p port) or 37888 (P2Pool-mini p2p port) 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
|
||||||
* An XMRig CPU miner is included by default, but you can connect additional miners to this same p2pool node using port 3333
|
* An XMRig CPU miner is included by default, but you can connect additional miners to this same p2pool node using port 3333
|
||||||
* Configure your kernel for maximum mining performance: [XMRig RandomX Optimization Guide](https://xmrig.com/docs/miner/randomx-optimization-guide)
|
* Configure your kernel for maximum mining performance: [XMRig RandomX Optimization Guide](https://xmrig.com/docs/miner/randomx-optimization-guide)
|
||||||
|
* Small miners can mine on p2pool-mini by editing the .env file
|
||||||
|
|
||||||
|
|
||||||
#### Other usefull commands
|
#### Other usefull commands
|
||||||
* You can **run everythng in the background** by adding the "-d" argument to the "docker-compose up" command: ```docker-compose up -d```
|
* You can **run everythng in the background** by adding the "-d" argument to the "docker-compose up" command: ```docker-compose up -d```
|
||||||
* You can **stop everything** with CTRL-C or ```docker-compose down```
|
* You can **stop everything** with CTRL-C or ```docker-compose down```
|
||||||
* You can see logs when running in the background for with the "docker logs" command: ```docker logs -f p2pool-xmrig``` or ```docker logs -f p2pool-p2pool``` or ```docker logs -f p2pool-monero```
|
* You can see logs when running in the background for with the "docker logs" command: ```docker logs -f p2pool-xmrig``` or ```docker logs -f p2pool-p2pool``` or ```docker logs -f p2pool-monero```
|
||||||
|
* You can pause mining with: ```docker-compose pause xmrig``` and resume mining with: ```docker-compose unpause xmrig```
|
||||||
|
* You can disable mining with: ```docker-compose stop xmrig``` and re-enable mining with: ```docker-compose start xmrig```
|
||||||
|
|
||||||
|
|
||||||
#### Uninstall
|
#### Uninstall
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ networks:
|
|||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
p2pool:
|
p2pool:
|
||||||
name: ${P2POOL_VOLUME}
|
name: p2pool
|
||||||
monero:
|
monero:
|
||||||
name: ${MONERO_VOLUME}
|
name: monero
|
||||||
|
|
||||||
services:
|
services:
|
||||||
monero:
|
monero:
|
||||||
@@ -17,7 +17,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: monero
|
context: monero
|
||||||
args:
|
args:
|
||||||
- MONERO_GIT_TAG=$MONERO_GIT_TAG
|
- MONERO_GIT_TAG=${MONERO_GIT_TAG}
|
||||||
container_name: p2pool-monero
|
container_name: p2pool-monero
|
||||||
networks:
|
networks:
|
||||||
- p2pool
|
- p2pool
|
||||||
@@ -39,6 +39,7 @@ services:
|
|||||||
--rpc-bind-port=18081
|
--rpc-bind-port=18081
|
||||||
--confirm-external-bind
|
--confirm-external-bind
|
||||||
${PRUNE_NODE}
|
${PRUNE_NODE}
|
||||||
|
${MONERO_EXTRA_OPTIONS}
|
||||||
|
|
||||||
p2pool:
|
p2pool:
|
||||||
image: p2pool:latest
|
image: p2pool:latest
|
||||||
@@ -48,6 +49,7 @@ services:
|
|||||||
- p2pool
|
- p2pool
|
||||||
ports:
|
ports:
|
||||||
- ${P2POOL_STRATUM_PORT}:3333/tcp
|
- ${P2POOL_STRATUM_PORT}:3333/tcp
|
||||||
|
- 37888:37888/tcp
|
||||||
- 37889:37889/tcp
|
- 37889:37889/tcp
|
||||||
volumes:
|
volumes:
|
||||||
- p2pool:/home/p2pool/.p2pool:rw
|
- p2pool:/home/p2pool/.p2pool:rw
|
||||||
@@ -60,6 +62,7 @@ services:
|
|||||||
--host monero
|
--host monero
|
||||||
--wallet ${WALLET_ADDRESS}
|
--wallet ${WALLET_ADDRESS}
|
||||||
--loglevel ${P2POOL_LOGLEVEL}
|
--loglevel ${P2POOL_LOGLEVEL}
|
||||||
|
${P2POOL_MINI}
|
||||||
|
|
||||||
xmrig:
|
xmrig:
|
||||||
image: xmrig:latest
|
image: xmrig:latest
|
||||||
@@ -77,7 +80,7 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: >-
|
command: >-
|
||||||
${FIXED_MINING_DIFFICULTY}
|
${FIXED_MINING_DIFFICULTY}
|
||||||
${NUM_MINING_CPU}
|
${MINING_CPU_PRIORITY}
|
||||||
|
${XMRIG_EXTRA_OPTIONS}
|
||||||
--randomx-1gb-pages
|
--randomx-1gb-pages
|
||||||
-o p2pool:3333
|
-o p2pool:3333
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ FORCEINLINE uint64_t udiv128(uint64_t hi, uint64_t lo, uint64_t divisor, uint64_
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<typename T> FORCEINLINE T round_up(T a, size_t granularity) { return static_cast<T>(((a + (granularity - static_cast<size_t>(1))) / granularity) * granularity); }
|
||||||
|
|
||||||
struct hash
|
struct hash
|
||||||
{
|
{
|
||||||
alignas(8) uint8_t h[HASH_SIZE];
|
alignas(8) uint8_t h[HASH_SIZE];
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ typedef struct cmd {
|
|||||||
cmdfunc *func;
|
cmdfunc *func;
|
||||||
} cmd;
|
} cmd;
|
||||||
|
|
||||||
static cmdfunc do_help, do_status, do_loglevel, do_addpeers, do_droppeers, do_showpeers, do_outpeers, do_inpeers, do_start_mining, do_stop_mining, do_exit;
|
static cmdfunc do_help, do_status, do_loglevel, do_addpeers, do_droppeers, do_showpeers, do_showbans, do_outpeers, do_inpeers, do_start_mining, do_stop_mining, do_exit;
|
||||||
|
|
||||||
static cmd cmds[] = {
|
static cmd cmds[] = {
|
||||||
{ STRCONST("help"), "", "display list of commands", do_help },
|
{ STRCONST("help"), "", "display list of commands", do_help },
|
||||||
@@ -79,6 +79,7 @@ static cmd cmds[] = {
|
|||||||
{ STRCONST("addpeers"), "<peeraddr>", "add peer", do_addpeers },
|
{ STRCONST("addpeers"), "<peeraddr>", "add peer", do_addpeers },
|
||||||
{ STRCONST("droppeers"), "", "disconnect all peers", do_droppeers },
|
{ STRCONST("droppeers"), "", "disconnect all peers", do_droppeers },
|
||||||
{ STRCONST("peers"), "", "show all peers", do_showpeers },
|
{ STRCONST("peers"), "", "show all peers", do_showpeers },
|
||||||
|
{ STRCONST("bans"), "", "show all banned IPs", do_showbans },
|
||||||
{ STRCONST("outpeers"), "", "set maximum number of outgoing connections", do_outpeers },
|
{ STRCONST("outpeers"), "", "set maximum number of outgoing connections", do_outpeers },
|
||||||
{ STRCONST("inpeers"), "", "set maximum number of incoming connections", do_inpeers },
|
{ STRCONST("inpeers"), "", "set maximum number of incoming connections", do_inpeers },
|
||||||
{ STRCONST("start_mining"), "<threads>", "start mining", do_start_mining },
|
{ STRCONST("start_mining"), "<threads>", "start mining", do_start_mining },
|
||||||
@@ -145,6 +146,17 @@ static int do_showpeers(p2pool* m_pool, const char* /* args */)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_showbans(p2pool* m_pool, const char* /* args */)
|
||||||
|
{
|
||||||
|
if (m_pool->stratum_server()) {
|
||||||
|
m_pool->stratum_server()->print_bans();
|
||||||
|
}
|
||||||
|
if (m_pool->p2p_server()) {
|
||||||
|
m_pool->p2p_server()->print_bans();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_outpeers(p2pool* m_pool, const char* args)
|
static int do_outpeers(p2pool* m_pool, const char* args)
|
||||||
{
|
{
|
||||||
if (m_pool->p2p_server()) {
|
if (m_pool->p2p_server()) {
|
||||||
|
|||||||
@@ -55,13 +55,25 @@ JSONRPCRequest::JSONRPCRequest(const char* address, int port, const char* req, C
|
|||||||
m_connect.data = this;
|
m_connect.data = this;
|
||||||
m_write.data = this;
|
m_write.data = this;
|
||||||
|
|
||||||
const size_t len = strlen(req);
|
const char* uri = "/json_rpc";
|
||||||
|
|
||||||
|
size_t len = req ? strlen(req) : 0;
|
||||||
|
if (!len) {
|
||||||
|
LOGERR(1, "Empty JSONRPCRequest, fix the code!");
|
||||||
|
m_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req[0] == '/') {
|
||||||
|
uri = req;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
m_request.reserve(std::max<size_t>(len + 128, log::Stream::BUF_SIZE + 1));
|
m_request.reserve(std::max<size_t>(len + 128, log::Stream::BUF_SIZE + 1));
|
||||||
m_request.resize(log::Stream::BUF_SIZE + 1);
|
m_request.resize(log::Stream::BUF_SIZE + 1);
|
||||||
|
|
||||||
log::Stream s(m_request.data());
|
log::Stream s(m_request.data());
|
||||||
s << "POST /json_rpc HTTP/1.1\nContent-Type: application/json\nContent-Length: " << len << "\n\n";
|
s << "POST " << uri << " HTTP/1.1\nContent-Type: application/json\nContent-Length: " << len << "\n\n";
|
||||||
|
|
||||||
m_request.resize(s.m_pos);
|
m_request.resize(s.m_pos);
|
||||||
m_request.insert(m_request.end(), req, req + len);
|
m_request.insert(m_request.end(), req, req + len);
|
||||||
|
|||||||
+29
-2
@@ -91,9 +91,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE ~Worker()
|
~Worker()
|
||||||
{
|
{
|
||||||
stop();
|
try {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE void stop()
|
FORCEINLINE void stop()
|
||||||
@@ -320,6 +324,29 @@ NOINLINE void Stream::writeCurrentTime()
|
|||||||
m_numberWidth = 1;
|
m_numberWidth = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NOINLINE void put_rawip(const raw_ip& value, Stream* wrapper)
|
||||||
|
{
|
||||||
|
const char* addr_str;
|
||||||
|
char addr_str_buf[64];
|
||||||
|
|
||||||
|
static constexpr uint8_t ipv4_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255 };
|
||||||
|
const bool is_v6 = (memcmp(value.data, ipv4_prefix, 12) != 0);
|
||||||
|
|
||||||
|
if (is_v6) {
|
||||||
|
addr_str = inet_ntop(AF_INET6, value.data, addr_str_buf, sizeof(addr_str_buf));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addr_str = inet_ntop(AF_INET, value.data + 12, addr_str_buf, sizeof(addr_str_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr_str) {
|
||||||
|
*wrapper << addr_str;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*wrapper << "N/A";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace log
|
} // namespace log
|
||||||
|
|
||||||
} // namespace p2pool
|
} // namespace p2pool
|
||||||
|
|||||||
@@ -384,6 +384,13 @@ template<> struct log::Stream::Entry<NetworkType>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void put_rawip(const raw_ip& value, Stream* wrapper);
|
||||||
|
|
||||||
|
template<> struct log::Stream::Entry<raw_ip>
|
||||||
|
{
|
||||||
|
static FORCEINLINE void put(const raw_ip& value, Stream* wrapper) { put_rawip(value, wrapper); }
|
||||||
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template<log::Severity severity> void apply_severity(log::Stream&);
|
template<log::Severity severity> void apply_severity(log::Stream&);
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -21,7 +21,7 @@
|
|||||||
#include "stratum_server.h"
|
#include "stratum_server.h"
|
||||||
#include "p2p_server.h"
|
#include "p2p_server.h"
|
||||||
|
|
||||||
static void usage()
|
void p2pool_usage()
|
||||||
{
|
{
|
||||||
printf("P2Pool %s\n"
|
printf("P2Pool %s\n"
|
||||||
"\nUsage:\n\n" \
|
"\nUsage:\n\n" \
|
||||||
@@ -68,13 +68,13 @@ void memory_tracking_stop();
|
|||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
usage();
|
p2pool_usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "/help") || !strcmp(argv[i], "-h") || !strcmp(argv[i], "/h")) {
|
if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "/help") || !strcmp(argv[i], "-h") || !strcmp(argv[i], "/h")) {
|
||||||
usage();
|
p2pool_usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+185
-13
@@ -23,6 +23,9 @@
|
|||||||
#include "side_chain.h"
|
#include "side_chain.h"
|
||||||
#include "pool_block.h"
|
#include "pool_block.h"
|
||||||
#include "block_cache.h"
|
#include "block_cache.h"
|
||||||
|
#include "json_rpc_request.h"
|
||||||
|
#include "json_parsers.h"
|
||||||
|
#include <rapidjson/document.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
@@ -49,6 +52,7 @@ P2PServer::P2PServer(p2pool* pool)
|
|||||||
, m_block(new PoolBlock())
|
, m_block(new PoolBlock())
|
||||||
, m_timer{}
|
, m_timer{}
|
||||||
, m_timerCounter(0)
|
, m_timerCounter(0)
|
||||||
|
, m_timerInterval(2)
|
||||||
, m_peerId(m_rng())
|
, m_peerId(m_rng())
|
||||||
, m_peerListLastSaved(0)
|
, m_peerListLastSaved(0)
|
||||||
{
|
{
|
||||||
@@ -83,7 +87,7 @@ P2PServer::P2PServer(p2pool* pool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_timer.data = this;
|
m_timer.data = this;
|
||||||
err = uv_timer_start(&m_timer, on_timer, 1000, 2000);
|
err = uv_timer_start(&m_timer, on_timer, 1000, m_timerInterval * 1000);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOGERR(1, "failed to start timer, error " << uv_err_name(err));
|
LOGERR(1, "failed to start timer, error " << uv_err_name(err));
|
||||||
panic();
|
panic();
|
||||||
@@ -173,6 +177,8 @@ void P2PServer::update_peer_connections()
|
|||||||
const time_t cur_time = time(nullptr);
|
const time_t cur_time = time(nullptr);
|
||||||
const time_t last_updated = m_pool->side_chain().last_updated();
|
const time_t last_updated = m_pool->side_chain().last_updated();
|
||||||
|
|
||||||
|
bool has_good_peers = false;
|
||||||
|
|
||||||
std::vector<raw_ip> connected_clients;
|
std::vector<raw_ip> connected_clients;
|
||||||
{
|
{
|
||||||
MutexLock lock(m_clientsListLock);
|
MutexLock lock(m_clientsListLock);
|
||||||
@@ -205,6 +211,9 @@ void P2PServer::update_peer_connections()
|
|||||||
|
|
||||||
if (!disconnected) {
|
if (!disconnected) {
|
||||||
connected_clients.emplace_back(client->m_addr);
|
connected_clients.emplace_back(client->m_addr);
|
||||||
|
if (client->m_handshakeComplete && !client->m_handshakeInvalid && (client->m_listenPort >= 0)) {
|
||||||
|
has_good_peers = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,8 +237,20 @@ void P2PServer::update_peer_connections()
|
|||||||
peer_list = m_peerList;
|
peer_list = m_peerList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t N = m_maxOutgoingPeers;
|
||||||
|
|
||||||
|
// Special case: when we can't find p2pool peers, scan through monerod peers (try 25 peers at a time)
|
||||||
|
if (!has_good_peers && !m_peerListMonero.empty()) {
|
||||||
|
LOGINFO(3, "Scanning monerod peers, " << m_peerListMonero.size() << " left");
|
||||||
|
for (uint32_t i = 0; (i < 25) && !m_peerListMonero.empty(); ++i) {
|
||||||
|
peer_list.push_back(m_peerListMonero.back());
|
||||||
|
m_peerListMonero.pop_back();
|
||||||
|
}
|
||||||
|
N = static_cast<uint32_t>(peer_list.size());
|
||||||
|
}
|
||||||
|
|
||||||
// Try to have at least N outgoing connections (N defaults to 10, can be set via --out-peers command line parameter)
|
// Try to have at least N outgoing connections (N defaults to 10, can be set via --out-peers command line parameter)
|
||||||
for (uint32_t i = m_numConnections - m_numIncomingConnections; (i < m_maxOutgoingPeers) && !peer_list.empty();) {
|
for (uint32_t i = m_numConnections - m_numIncomingConnections; (i < N) && !peer_list.empty();) {
|
||||||
const uint64_t k = get_random64() % peer_list.size();
|
const uint64_t k = get_random64() % peer_list.size();
|
||||||
const Peer& peer = peer_list[k];
|
const Peer& peer = peer_list[k];
|
||||||
|
|
||||||
@@ -251,14 +272,16 @@ void P2PServer::update_peer_connections()
|
|||||||
peer_list.pop_back();
|
peer_list.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_numConnections == 0) && ((m_timerCounter % 30) == 0)) {
|
if (!has_good_peers && ((m_timerCounter % 30) == 0)) {
|
||||||
LOGERR(1, "no connections to other p2pool nodes, check your monerod/p2pool/network/firewall setup!!!");
|
LOGERR(1, "no connections to other p2pool nodes, check your monerod/p2pool/network/firewall setup!!!");
|
||||||
|
if (m_peerListMonero.empty()) {
|
||||||
|
load_monerod_peer_list();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void P2PServer::update_peer_list()
|
void P2PServer::update_peer_list()
|
||||||
{
|
{
|
||||||
const time_t cur_time = time(nullptr);
|
|
||||||
{
|
{
|
||||||
MutexLock lock(m_clientsListLock);
|
MutexLock lock(m_clientsListLock);
|
||||||
|
|
||||||
@@ -267,9 +290,9 @@ void P2PServer::update_peer_list()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_time >= client->m_nextPeerListRequest) {
|
if (m_timerCounter >= client->m_nextOutgoingPeerListRequest) {
|
||||||
// Send peer list requests at random intervals (60-120 seconds)
|
// Send peer list requests at random intervals (60-120 seconds)
|
||||||
client->m_nextPeerListRequest = cur_time + 60 + (get_random64() % 61);
|
client->m_nextOutgoingPeerListRequest = m_timerCounter + (60 + (get_random64() % 61)) / m_timerInterval;
|
||||||
|
|
||||||
const bool result = send(client,
|
const bool result = send(client,
|
||||||
[](void* buf)
|
[](void* buf)
|
||||||
@@ -280,7 +303,7 @@ void P2PServer::update_peer_list()
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
client->m_lastPeerListRequestTime = std::chrono::system_clock::now();
|
client->m_lastPeerListRequestTime = std::chrono::high_resolution_clock::now();
|
||||||
++client->m_peerListPendingRequests;
|
++client->m_peerListPendingRequests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,6 +392,7 @@ void P2PServer::save_peer_list()
|
|||||||
void P2PServer::load_peer_list()
|
void P2PServer::load_peer_list()
|
||||||
{
|
{
|
||||||
std::string saved_list;
|
std::string saved_list;
|
||||||
|
const size_t old_size = m_peerList.size();
|
||||||
|
|
||||||
// Load peers from seed nodes if we're on the default or mini sidechain
|
// Load peers from seed nodes if we're on the default or mini sidechain
|
||||||
auto load_from_seed_nodes = [&saved_list](const char** nodes, int p2p_port) {
|
auto load_from_seed_nodes = [&saved_list](const char** nodes, int p2p_port) {
|
||||||
@@ -493,7 +517,102 @@ void P2PServer::load_peer_list()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
LOGINFO(4, "peer list loaded (" << m_peerList.size() << " peers)");
|
LOGINFO(4, "peer list loaded (" << (m_peerList.size() - old_size) << " peers)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void P2PServer::load_monerod_peer_list()
|
||||||
|
{
|
||||||
|
const Params& params = m_pool->params();
|
||||||
|
|
||||||
|
JSONRPCRequest::call(params.m_host.c_str(), params.m_rpcPort, "/get_peer_list",
|
||||||
|
[this](const char* data, size_t size)
|
||||||
|
{
|
||||||
|
constexpr char err_str[] = "/get_peer_list RPC request returned invalid JSON ";
|
||||||
|
|
||||||
|
using namespace rapidjson;
|
||||||
|
|
||||||
|
Document doc;
|
||||||
|
if (doc.Parse(data, size).HasParseError()) {
|
||||||
|
LOGWARN(4, err_str << "(parse error)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc.IsObject()) {
|
||||||
|
LOGWARN(4, err_str << "(not an object)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc.HasMember("white_list")) {
|
||||||
|
LOGWARN(4, err_str << "('white_list' not found)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& white_list = doc["white_list"];
|
||||||
|
|
||||||
|
if (!white_list.IsArray()) {
|
||||||
|
LOGWARN(4, err_str << "('white_list' is not an array)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int port = m_pool->side_chain().is_mini() ? DEFAULT_P2P_PORT_MINI : DEFAULT_P2P_PORT;
|
||||||
|
|
||||||
|
const SizeType n = white_list.Size();
|
||||||
|
|
||||||
|
m_peerListMonero.clear();
|
||||||
|
m_peerListMonero.reserve(n);
|
||||||
|
|
||||||
|
for (SizeType i = 0; i < n; ++i) {
|
||||||
|
auto& v = white_list[i];
|
||||||
|
const char* ip;
|
||||||
|
uint64_t last_seen;
|
||||||
|
if (!parseValue(v, "host", ip) || !parseValue(v, "last_seen", last_seen)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Peer p;
|
||||||
|
p.m_lastSeen = last_seen;
|
||||||
|
|
||||||
|
if (strchr(ip, ':')) {
|
||||||
|
sockaddr_in6 addr6;
|
||||||
|
const int err = uv_ip6_addr(ip, port, &addr6);
|
||||||
|
if (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p.m_isV6 = true;
|
||||||
|
memcpy(p.m_addr.data, &addr6.sin6_addr, sizeof(in6_addr));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sockaddr_in addr4;
|
||||||
|
const int err = uv_ip4_addr(ip, port, &addr4);
|
||||||
|
if (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p.m_isV6 = false;
|
||||||
|
p.m_addr = {};
|
||||||
|
p.m_addr.data[10] = 0xFF;
|
||||||
|
p.m_addr.data[11] = 0xFF;
|
||||||
|
memcpy(p.m_addr.data + 12, &addr4.sin_addr, sizeof(in_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
p.m_port = port;
|
||||||
|
p.m_numFailedConnections = 0;
|
||||||
|
|
||||||
|
if (!is_banned(p.m_addr)) {
|
||||||
|
m_peerListMonero.push_back(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put recently active peers first in the list
|
||||||
|
std::sort(m_peerListMonero.begin(), m_peerListMonero.end(), [](const Peer& a, const Peer& b) { return a.m_lastSeen > b.m_lastSeen; });
|
||||||
|
|
||||||
|
LOGINFO(4, "monerod peer list loaded (" << m_peerListMonero.size() << " peers)");
|
||||||
|
},
|
||||||
|
[](const char* data, size_t size)
|
||||||
|
{
|
||||||
|
if (size > 0) {
|
||||||
|
LOGWARN(4, "/get_peer_list RPC request failed: error " << log::const_buf(data, size));
|
||||||
|
}
|
||||||
|
}, &m_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void P2PServer::update_peer_in_list(bool is_v6, const raw_ip& ip, int port)
|
void P2PServer::update_peer_in_list(bool is_v6, const raw_ip& ip, int port)
|
||||||
@@ -682,7 +801,7 @@ void P2PServer::on_broadcast()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return p - p0;
|
return p - p0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -826,7 +945,7 @@ void P2PServer::download_missing_blocks()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send(client,
|
const bool result = send(client,
|
||||||
[&id](void* buf)
|
[&id](void* buf)
|
||||||
{
|
{
|
||||||
uint8_t* p0 = reinterpret_cast<uint8_t*>(buf);
|
uint8_t* p0 = reinterpret_cast<uint8_t*>(buf);
|
||||||
@@ -840,6 +959,10 @@ void P2PServer::download_missing_blocks()
|
|||||||
|
|
||||||
return p - p0;
|
return p - p0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
++client->m_blockPendingRequests;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,10 +989,13 @@ P2PServer::P2PClient::P2PClient()
|
|||||||
, m_handshakeComplete(false)
|
, m_handshakeComplete(false)
|
||||||
, m_handshakeInvalid(false)
|
, m_handshakeInvalid(false)
|
||||||
, m_listenPort(-1)
|
, m_listenPort(-1)
|
||||||
, m_nextPeerListRequest(0)
|
, m_fastPeerListRequestCount(0)
|
||||||
|
, m_prevIncomingPeerListRequest{}
|
||||||
|
, m_nextOutgoingPeerListRequest(0)
|
||||||
, m_lastPeerListRequestTime{}
|
, m_lastPeerListRequestTime{}
|
||||||
, m_peerListPendingRequests(0)
|
, m_peerListPendingRequests(0)
|
||||||
, m_pingTime(0)
|
, m_pingTime(0)
|
||||||
|
, m_blockPendingRequests(0)
|
||||||
, m_lastAlive(0)
|
, m_lastAlive(0)
|
||||||
, m_lastBroadcastTimestamp(0)
|
, m_lastBroadcastTimestamp(0)
|
||||||
, m_lastBlockrequestTimestamp(0)
|
, m_lastBlockrequestTimestamp(0)
|
||||||
@@ -892,10 +1018,13 @@ void P2PServer::P2PClient::reset()
|
|||||||
m_handshakeComplete = false;
|
m_handshakeComplete = false;
|
||||||
m_handshakeInvalid = false;
|
m_handshakeInvalid = false;
|
||||||
m_listenPort = -1;
|
m_listenPort = -1;
|
||||||
m_nextPeerListRequest = 0;
|
m_fastPeerListRequestCount = 0;
|
||||||
|
m_prevIncomingPeerListRequest = {};
|
||||||
|
m_nextOutgoingPeerListRequest = 0;
|
||||||
m_lastPeerListRequestTime = {};
|
m_lastPeerListRequestTime = {};
|
||||||
m_peerListPendingRequests = 0;
|
m_peerListPendingRequests = 0;
|
||||||
m_pingTime = 0;
|
m_pingTime = 0;
|
||||||
|
m_blockPendingRequests = 0;
|
||||||
m_lastAlive = 0;
|
m_lastAlive = 0;
|
||||||
m_lastBroadcastTimestamp = 0;
|
m_lastBroadcastTimestamp = 0;
|
||||||
m_lastBlockrequestTimestamp = 0;
|
m_lastBlockrequestTimestamp = 0;
|
||||||
@@ -952,6 +1081,8 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
|||||||
uint8_t* buf = buf_begin;
|
uint8_t* buf = buf_begin;
|
||||||
uint32_t bytes_left = m_numRead;
|
uint32_t bytes_left = m_numRead;
|
||||||
|
|
||||||
|
uint32_t num_block_requests = 0;
|
||||||
|
|
||||||
uint32_t bytes_read;
|
uint32_t bytes_read;
|
||||||
do {
|
do {
|
||||||
MessageId id = static_cast<MessageId>(buf[0]);
|
MessageId id = static_cast<MessageId>(buf[0]);
|
||||||
@@ -1009,6 +1140,13 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MessageId::LISTEN_PORT:
|
case MessageId::LISTEN_PORT:
|
||||||
|
if (m_listenPort >= 0) {
|
||||||
|
LOGWARN(4, "peer " << static_cast<char*>(m_addrString) << " sent an unexpected LISTEN_PORT");
|
||||||
|
ban(DEFAULT_BAN_TIME);
|
||||||
|
server->remove_peer_from_list(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent LISTEN_PORT");
|
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent LISTEN_PORT");
|
||||||
|
|
||||||
if (bytes_left >= 1 + sizeof(int32_t)) {
|
if (bytes_left >= 1 + sizeof(int32_t)) {
|
||||||
@@ -1022,6 +1160,14 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MessageId::BLOCK_REQUEST:
|
case MessageId::BLOCK_REQUEST:
|
||||||
|
++num_block_requests;
|
||||||
|
if (num_block_requests > 100) {
|
||||||
|
LOGWARN(4, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent too many BLOCK_REQUEST messages at once");
|
||||||
|
ban(DEFAULT_BAN_TIME);
|
||||||
|
server->remove_peer_from_list(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_REQUEST");
|
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_REQUEST");
|
||||||
|
|
||||||
if (bytes_left >= 1 + HASH_SIZE) {
|
if (bytes_left >= 1 + HASH_SIZE) {
|
||||||
@@ -1035,12 +1181,21 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MessageId::BLOCK_RESPONSE:
|
case MessageId::BLOCK_RESPONSE:
|
||||||
|
if (m_blockPendingRequests <= 0) {
|
||||||
|
LOGWARN(4, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent an unexpected BLOCK_RESPONSE");
|
||||||
|
ban(DEFAULT_BAN_TIME);
|
||||||
|
server->remove_peer_from_list(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_RESPONSE");
|
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_RESPONSE");
|
||||||
|
|
||||||
if (bytes_left >= 1 + sizeof(uint32_t)) {
|
if (bytes_left >= 1 + sizeof(uint32_t)) {
|
||||||
const uint32_t block_size = *reinterpret_cast<uint32_t*>(buf + 1);
|
const uint32_t block_size = *reinterpret_cast<uint32_t*>(buf + 1);
|
||||||
if (bytes_left >= 1 + sizeof(uint32_t) + block_size) {
|
if (bytes_left >= 1 + sizeof(uint32_t) + block_size) {
|
||||||
bytes_read = 1 + sizeof(uint32_t) + block_size;
|
bytes_read = 1 + sizeof(uint32_t) + block_size;
|
||||||
|
|
||||||
|
--m_blockPendingRequests;
|
||||||
if (!on_block_response(buf + 1 + sizeof(uint32_t), block_size)) {
|
if (!on_block_response(buf + 1 + sizeof(uint32_t), block_size)) {
|
||||||
ban(DEFAULT_BAN_TIME);
|
ban(DEFAULT_BAN_TIME);
|
||||||
server->remove_peer_from_list(this);
|
server->remove_peer_from_list(this);
|
||||||
@@ -1102,7 +1257,7 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
|||||||
bytes_read = 2u + num_peers * 19u;
|
bytes_read = 2u + num_peers * 19u;
|
||||||
|
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
m_pingTime = duration_cast<milliseconds>(system_clock::now() - m_lastPeerListRequestTime).count();
|
m_pingTime = duration_cast<milliseconds>(high_resolution_clock::now() - m_lastPeerListRequestTime).count();
|
||||||
|
|
||||||
--m_peerListPendingRequests;
|
--m_peerListPendingRequests;
|
||||||
if (!on_peer_list_response(buf + 1)) {
|
if (!on_peer_list_response(buf + 1)) {
|
||||||
@@ -1452,6 +1607,7 @@ void P2PServer::P2PClient::on_after_handshake(uint8_t* &p)
|
|||||||
memcpy(p, empty.h, HASH_SIZE);
|
memcpy(p, empty.h, HASH_SIZE);
|
||||||
p += HASH_SIZE;
|
p += HASH_SIZE;
|
||||||
|
|
||||||
|
++m_blockPendingRequests;
|
||||||
m_lastBroadcastTimestamp = time(nullptr);
|
m_lastBroadcastTimestamp = time(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1586,7 +1742,21 @@ bool P2PServer::P2PClient::on_block_broadcast(const uint8_t* buf, uint32_t size)
|
|||||||
|
|
||||||
bool P2PServer::P2PClient::on_peer_list_request(const uint8_t*)
|
bool P2PServer::P2PClient::on_peer_list_request(const uint8_t*)
|
||||||
{
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
P2PServer* server = static_cast<P2PServer*>(m_owner);
|
P2PServer* server = static_cast<P2PServer*>(m_owner);
|
||||||
|
const auto cur_time = steady_clock::now();
|
||||||
|
|
||||||
|
// Allow peer list requests no more than once every 30 seconds
|
||||||
|
if (duration_cast<seconds>(cur_time - m_prevIncomingPeerListRequest).count() < 30) {
|
||||||
|
++m_fastPeerListRequestCount;
|
||||||
|
if (m_fastPeerListRequestCount >= 3) {
|
||||||
|
LOGWARN(4, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " is sending PEER_LIST_REQUEST too often");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_prevIncomingPeerListRequest = cur_time;
|
||||||
|
|
||||||
Peer peers[PEER_LIST_RESPONSE_MAX_PEERS];
|
Peer peers[PEER_LIST_RESPONSE_MAX_PEERS];
|
||||||
uint32_t num_selected_peers = 0;
|
uint32_t num_selected_peers = 0;
|
||||||
@@ -1797,6 +1967,8 @@ void P2PServer::P2PClient::post_handle_incoming_block(const uint32_t reset_count
|
|||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++m_blockPendingRequests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -110,11 +110,15 @@ public:
|
|||||||
bool m_handshakeInvalid;
|
bool m_handshakeInvalid;
|
||||||
int m_listenPort;
|
int m_listenPort;
|
||||||
|
|
||||||
time_t m_nextPeerListRequest;
|
uint32_t m_fastPeerListRequestCount;
|
||||||
std::chrono::system_clock::time_point m_lastPeerListRequestTime;
|
std::chrono::steady_clock::time_point m_prevIncomingPeerListRequest;
|
||||||
|
uint64_t m_nextOutgoingPeerListRequest;
|
||||||
|
std::chrono::high_resolution_clock::time_point m_lastPeerListRequestTime;
|
||||||
int m_peerListPendingRequests;
|
int m_peerListPendingRequests;
|
||||||
int64_t m_pingTime;
|
int64_t m_pingTime;
|
||||||
|
|
||||||
|
int m_blockPendingRequests;
|
||||||
|
|
||||||
time_t m_lastAlive;
|
time_t m_lastAlive;
|
||||||
time_t m_lastBroadcastTimestamp;
|
time_t m_lastBroadcastTimestamp;
|
||||||
time_t m_lastBlockrequestTimestamp;
|
time_t m_lastBlockrequestTimestamp;
|
||||||
@@ -160,6 +164,7 @@ private:
|
|||||||
void save_peer_list_async();
|
void save_peer_list_async();
|
||||||
void save_peer_list();
|
void save_peer_list();
|
||||||
void load_peer_list();
|
void load_peer_list();
|
||||||
|
void load_monerod_peer_list();
|
||||||
void update_peer_in_list(bool is_v6, const raw_ip& ip, int port);
|
void update_peer_in_list(bool is_v6, const raw_ip& ip, int port);
|
||||||
void remove_peer_from_list(P2PClient* client);
|
void remove_peer_from_list(P2PClient* client);
|
||||||
void remove_peer_from_list(const raw_ip& ip);
|
void remove_peer_from_list(const raw_ip& ip);
|
||||||
@@ -172,7 +177,8 @@ private:
|
|||||||
PoolBlock* m_block;
|
PoolBlock* m_block;
|
||||||
|
|
||||||
uv_timer_t m_timer;
|
uv_timer_t m_timer;
|
||||||
uint32_t m_timerCounter;
|
uint64_t m_timerCounter;
|
||||||
|
uint64_t m_timerInterval;
|
||||||
|
|
||||||
uint64_t m_peerId;
|
uint64_t m_peerId;
|
||||||
|
|
||||||
@@ -188,6 +194,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Peer> m_peerList;
|
std::vector<Peer> m_peerList;
|
||||||
|
std::vector<Peer> m_peerListMonero;
|
||||||
time_t m_peerListLastSaved;
|
time_t m_peerListLastSaved;
|
||||||
|
|
||||||
struct Broadcast
|
struct Broadcast
|
||||||
|
|||||||
+6
-1
@@ -111,6 +111,11 @@ p2pool::p2pool(int argc, char* argv[])
|
|||||||
|
|
||||||
m_api = m_params->m_apiPath.empty() ? nullptr : new p2pool_api(m_params->m_apiPath, m_params->m_localStats);
|
m_api = m_params->m_apiPath.empty() ? nullptr : new p2pool_api(m_params->m_apiPath, m_params->m_localStats);
|
||||||
|
|
||||||
|
if (m_params->m_localStats && !m_api) {
|
||||||
|
LOGERR(1, "--local-api and --stratum-api command line parameters can't be used without --data-api");
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
m_sideChain = new SideChain(this, type, m_params->m_mini ? "mini" : nullptr);
|
m_sideChain = new SideChain(this, type, m_params->m_mini ? "mini" : nullptr);
|
||||||
|
|
||||||
if (m_params->m_p2pAddresses.empty()) {
|
if (m_params->m_p2pAddresses.empty()) {
|
||||||
@@ -1114,7 +1119,7 @@ void p2pool::api_update_stats_mod()
|
|||||||
m_api->set(p2pool_api::Category::GLOBAL, "stats_mod",
|
m_api->set(p2pool_api::Category::GLOBAL, "stats_mod",
|
||||||
[&mainnet_tip, last_block_found_time, &last_block_found_buf, last_block_found_height, miners, hashrate, round_hashes, stratum_port](log::Stream& s)
|
[&mainnet_tip, last_block_found_time, &last_block_found_buf, last_block_found_height, miners, hashrate, round_hashes, stratum_port](log::Stream& s)
|
||||||
{
|
{
|
||||||
s << "{\"config\":{\"ports\":[{\"port\":" << stratum_port << ",\"tls\":false}],\"fee\":0,\"minPaymentThreshold\":400000000},\"network\":{\"height\":"
|
s << "{\"config\":{\"ports\":[{\"port\":" << stratum_port << ",\"tls\":false}],\"fee\":0,\"minPaymentThreshold\":300000000},\"network\":{\"height\":"
|
||||||
<< mainnet_tip.height << "},\"pool\":{\"stats\":{\"lastBlockFound\":\""
|
<< mainnet_tip.height << "},\"pool\":{\"stats\":{\"lastBlockFound\":\""
|
||||||
<< last_block_found_time << "000\"},\"blocks\":[\""
|
<< last_block_found_time << "000\"},\"blocks\":[\""
|
||||||
<< static_cast<char*>(last_block_found_buf) << static_cast<char*>(last_block_found_buf) + HASH_SIZE * 2 - 4 << ':'
|
<< static_cast<char*>(last_block_found_buf) << static_cast<char*>(last_block_found_buf) + HASH_SIZE * 2 - 4 << ':'
|
||||||
|
|||||||
@@ -20,86 +20,115 @@
|
|||||||
#include "stratum_server.h"
|
#include "stratum_server.h"
|
||||||
#include "p2p_server.h"
|
#include "p2p_server.h"
|
||||||
|
|
||||||
|
void p2pool_usage();
|
||||||
|
|
||||||
namespace p2pool {
|
namespace p2pool {
|
||||||
|
|
||||||
Params::Params(int argc, char* argv[])
|
Params::Params(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--host") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--host") == 0) && (i + 1 < argc)) {
|
||||||
m_host = argv[++i];
|
m_host = argv[++i];
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--rpc-port") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--rpc-port") == 0) && (i + 1 < argc)) {
|
||||||
m_rpcPort = strtoul(argv[++i], nullptr, 10);
|
m_rpcPort = strtoul(argv[++i], nullptr, 10);
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--zmq-port") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--zmq-port") == 0) && (i + 1 < argc)) {
|
||||||
m_zmqPort = strtoul(argv[++i], nullptr, 10);
|
m_zmqPort = strtoul(argv[++i], nullptr, 10);
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "--light-mode") == 0) {
|
if (strcmp(argv[i], "--light-mode") == 0) {
|
||||||
m_lightMode = true;
|
m_lightMode = true;
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--wallet") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--wallet") == 0) && (i + 1 < argc)) {
|
||||||
m_wallet.decode(argv[++i]);
|
m_wallet.decode(argv[++i]);
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--stratum") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--stratum") == 0) && (i + 1 < argc)) {
|
||||||
m_stratumAddresses = argv[++i];
|
m_stratumAddresses = argv[++i];
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--p2p") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--p2p") == 0) && (i + 1 < argc)) {
|
||||||
m_p2pAddresses = argv[++i];
|
m_p2pAddresses = argv[++i];
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--addpeers") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--addpeers") == 0) && (i + 1 < argc)) {
|
||||||
m_p2pPeerList = argv[++i];
|
m_p2pPeerList = argv[++i];
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--loglevel") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--loglevel") == 0) && (i + 1 < argc)) {
|
||||||
const int level = std::min(std::max<int>(strtol(argv[++i], nullptr, 10), 0), log::MAX_GLOBAL_LOG_LEVEL);
|
const int level = std::min(std::max<int>(strtol(argv[++i], nullptr, 10), 0), log::MAX_GLOBAL_LOG_LEVEL);
|
||||||
log::GLOBAL_LOG_LEVEL = level;
|
log::GLOBAL_LOG_LEVEL = level;
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--config") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--config") == 0) && (i + 1 < argc)) {
|
||||||
m_config = argv[++i];
|
m_config = argv[++i];
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--data-api") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--data-api") == 0) && (i + 1 < argc)) {
|
||||||
m_apiPath = argv[++i];
|
m_apiPath = argv[++i];
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--local-api") == 0) || (strcmp(argv[i], "--stratum-api") == 0)) {
|
if ((strcmp(argv[i], "--local-api") == 0) || (strcmp(argv[i], "--stratum-api") == 0)) {
|
||||||
m_localStats = true;
|
m_localStats = true;
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "--no-cache") == 0) {
|
if (strcmp(argv[i], "--no-cache") == 0) {
|
||||||
m_blockCache = false;
|
m_blockCache = false;
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "--no-color") == 0) {
|
if (strcmp(argv[i], "--no-color") == 0) {
|
||||||
log::CONSOLE_COLORS = false;
|
log::CONSOLE_COLORS = false;
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "--no-randomx") == 0) {
|
if (strcmp(argv[i], "--no-randomx") == 0) {
|
||||||
m_disableRandomX = true;
|
m_disableRandomX = true;
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--out-peers") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--out-peers") == 0) && (i + 1 < argc)) {
|
||||||
m_maxOutgoingPeers = std::min(std::max(strtoul(argv[++i], nullptr, 10), 10UL), 1000UL);
|
m_maxOutgoingPeers = std::min(std::max(strtoul(argv[++i], nullptr, 10), 10UL), 1000UL);
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--in-peers") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--in-peers") == 0) && (i + 1 < argc)) {
|
||||||
m_maxIncomingPeers = std::min(std::max(strtoul(argv[++i], nullptr, 10), 10UL), 1000UL);
|
m_maxIncomingPeers = std::min(std::max(strtoul(argv[++i], nullptr, 10), 10UL), 1000UL);
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(argv[i], "--start-mining") == 0) && (i + 1 < argc)) {
|
if ((strcmp(argv[i], "--start-mining") == 0) && (i + 1 < argc)) {
|
||||||
m_minerThreads = std::min(std::max(strtoul(argv[++i], nullptr, 10), 1UL), 64UL);
|
m_minerThreads = std::min(std::max(strtoul(argv[++i], nullptr, 10), 1UL), 64UL);
|
||||||
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "--mini") == 0) {
|
if (strcmp(argv[i], "--mini") == 0) {
|
||||||
m_mini = true;
|
m_mini = true;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
fprintf(stderr, "Unknown command line parameter %s\n\n", argv[i]);
|
||||||
|
p2pool_usage();
|
||||||
|
panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-3
@@ -27,6 +27,7 @@
|
|||||||
#include "intrin_portable.h"
|
#include "intrin_portable.h"
|
||||||
#include "keccak.h"
|
#include "keccak.h"
|
||||||
#include "p2p_server.h"
|
#include "p2p_server.h"
|
||||||
|
#include "stratum_server.h"
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
#include "json_parsers.h"
|
#include "json_parsers.h"
|
||||||
#include <rapidjson/document.h>
|
#include <rapidjson/document.h>
|
||||||
@@ -985,7 +986,8 @@ void SideChain::verify_loop(PoolBlock* block)
|
|||||||
|
|
||||||
// This block is now verified
|
// This block is now verified
|
||||||
|
|
||||||
if (is_longer_chain(highest_block, block)) {
|
bool is_alternative;
|
||||||
|
if (is_longer_chain(highest_block, block, is_alternative)) {
|
||||||
highest_block = block;
|
highest_block = block;
|
||||||
}
|
}
|
||||||
else if (highest_block && (highest_block->m_sidechainHeight > block->m_sidechainHeight)) {
|
else if (highest_block && (highest_block->m_sidechainHeight > block->m_sidechainHeight)) {
|
||||||
@@ -1330,7 +1332,8 @@ void SideChain::update_chain_tip(PoolBlock* block)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_longer_chain(m_chainTip, block)) {
|
bool is_alternative;
|
||||||
|
if (is_longer_chain(m_chainTip, block, is_alternative)) {
|
||||||
difficulty_type diff;
|
difficulty_type diff;
|
||||||
if (get_difficulty(block, m_difficultyData, diff)) {
|
if (get_difficulty(block, m_difficultyData, diff)) {
|
||||||
m_chainTip = block;
|
m_chainTip = block;
|
||||||
@@ -1343,6 +1346,12 @@ void SideChain::update_chain_tip(PoolBlock* block)
|
|||||||
block->m_wantBroadcast = true;
|
block->m_wantBroadcast = true;
|
||||||
if (m_pool) {
|
if (m_pool) {
|
||||||
m_pool->update_block_template_async();
|
m_pool->update_block_template_async();
|
||||||
|
|
||||||
|
// Reset stratum share counters when switching to an alternative chain to avoid confusion
|
||||||
|
StratumServer* s = m_pool->stratum_server();
|
||||||
|
if (s && is_alternative) {
|
||||||
|
s->reset_share_counters();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
prune_old_blocks();
|
prune_old_blocks();
|
||||||
}
|
}
|
||||||
@@ -1405,8 +1414,10 @@ PoolBlock* SideChain::get_parent(const PoolBlock* block)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SideChain::is_longer_chain(const PoolBlock* block, const PoolBlock* candidate)
|
bool SideChain::is_longer_chain(const PoolBlock* block, const PoolBlock* candidate, bool& is_alternative)
|
||||||
{
|
{
|
||||||
|
is_alternative = false;
|
||||||
|
|
||||||
if (!candidate || !candidate->m_verified || candidate->m_invalid) {
|
if (!candidate || !candidate->m_verified || candidate->m_invalid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1449,6 +1460,8 @@ bool SideChain::is_longer_chain(const PoolBlock* block, const PoolBlock* candida
|
|||||||
}
|
}
|
||||||
|
|
||||||
// They're on totally different chains. Compare total difficulties over the last m_chainWindowSize blocks
|
// They're on totally different chains. Compare total difficulties over the last m_chainWindowSize blocks
|
||||||
|
is_alternative = true;
|
||||||
|
|
||||||
difficulty_type block_total_diff;
|
difficulty_type block_total_diff;
|
||||||
difficulty_type candidate_total_diff;
|
difficulty_type candidate_total_diff;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -91,7 +91,7 @@ private:
|
|||||||
PoolBlock* get_parent(const PoolBlock* block);
|
PoolBlock* get_parent(const PoolBlock* block);
|
||||||
|
|
||||||
// Checks if "candidate" has longer (higher difficulty) chain than "block"
|
// Checks if "candidate" has longer (higher difficulty) chain than "block"
|
||||||
bool is_longer_chain(const PoolBlock* block, const PoolBlock* candidate);
|
bool is_longer_chain(const PoolBlock* block, const PoolBlock* candidate, bool& is_alternative);
|
||||||
void update_depths(PoolBlock* block);
|
void update_depths(PoolBlock* block);
|
||||||
void prune_old_blocks();
|
void prune_old_blocks();
|
||||||
|
|
||||||
|
|||||||
+13
-4
@@ -439,6 +439,13 @@ void StratumServer::print_status()
|
|||||||
print_stratum_status();
|
print_stratum_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StratumServer::reset_share_counters()
|
||||||
|
{
|
||||||
|
m_cumulativeHashesAtLastShare = 0;
|
||||||
|
m_cumulativeFoundSharesDiff = 0.0;
|
||||||
|
m_totalFoundShares = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void StratumServer::print_stratum_status() const
|
void StratumServer::print_stratum_status() const
|
||||||
{
|
{
|
||||||
uint64_t hashes_15m, hashes_1h, hashes_24h, total_hashes;
|
uint64_t hashes_15m, hashes_1h, hashes_24h, total_hashes;
|
||||||
@@ -473,8 +480,9 @@ void StratumServer::print_stratum_status() const
|
|||||||
const uint64_t hashrate_24h = (dt_24h > 0) ? (hashes_24h / dt_24h) : 0;
|
const uint64_t hashrate_24h = (dt_24h > 0) ? (hashes_24h / dt_24h) : 0;
|
||||||
|
|
||||||
double average_effort = 0.0;
|
double average_effort = 0.0;
|
||||||
if (m_cumulativeFoundSharesDiff > 0.0) {
|
const double diff = m_cumulativeFoundSharesDiff;
|
||||||
average_effort = static_cast<double>(m_cumulativeHashesAtLastShare) * 100.0 / m_cumulativeFoundSharesDiff;
|
if (diff > 0.0) {
|
||||||
|
average_effort = static_cast<double>(m_cumulativeHashesAtLastShare) * 100.0 / diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGINFO(0, "status" <<
|
LOGINFO(0, "status" <<
|
||||||
@@ -1028,8 +1036,9 @@ void StratumServer::api_update_local_stats(time_t timestamp)
|
|||||||
const uint64_t hashrate_24h = (dt_24h > 0) ? (hashes_24h / dt_24h) : 0;
|
const uint64_t hashrate_24h = (dt_24h > 0) ? (hashes_24h / dt_24h) : 0;
|
||||||
|
|
||||||
double average_effort = 0.0;
|
double average_effort = 0.0;
|
||||||
if (m_cumulativeFoundSharesDiff > 0.0) {
|
const double diff = m_cumulativeFoundSharesDiff;
|
||||||
average_effort = static_cast<double>(m_cumulativeHashesAtLastShare) * 100.0 / m_cumulativeFoundSharesDiff;
|
if (diff > 0.0) {
|
||||||
|
average_effort = static_cast<double>(m_cumulativeHashesAtLastShare) * 100.0 / diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
int shares_found = m_totalFoundShares;
|
int shares_found = m_totalFoundShares;
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ public:
|
|||||||
|
|
||||||
void print_status() override;
|
void print_status() override;
|
||||||
|
|
||||||
|
void reset_share_counters();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void print_stratum_status() const;
|
void print_stratum_status() const;
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -48,6 +48,7 @@ public:
|
|||||||
virtual void on_connect_failed(bool is_v6, const raw_ip& ip, int port);
|
virtual void on_connect_failed(bool is_v6, const raw_ip& ip, int port);
|
||||||
|
|
||||||
void ban(const raw_ip& ip, uint64_t seconds);
|
void ban(const raw_ip& ip, uint64_t seconds);
|
||||||
|
virtual void print_bans();
|
||||||
|
|
||||||
struct Client
|
struct Client
|
||||||
{
|
{
|
||||||
@@ -95,9 +96,9 @@ public:
|
|||||||
|
|
||||||
struct WriteBuf
|
struct WriteBuf
|
||||||
{
|
{
|
||||||
Client* m_client;
|
Client* m_client = nullptr;
|
||||||
uv_write_t m_write;
|
uv_write_t m_write = {};
|
||||||
char m_data[WRITE_BUF_SIZE];
|
std::vector<uint8_t> m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
uv_mutex_t m_writeBuffersLock;
|
uv_mutex_t m_writeBuffersLock;
|
||||||
@@ -160,7 +161,7 @@ protected:
|
|||||||
uint32_t m_numIncomingConnections;
|
uint32_t m_numIncomingConnections;
|
||||||
|
|
||||||
uv_mutex_t m_bansLock;
|
uv_mutex_t m_bansLock;
|
||||||
unordered_map<raw_ip, time_t> m_bans;
|
unordered_map<raw_ip, std::chrono::steady_clock::time_point> m_bans;
|
||||||
|
|
||||||
bool is_banned(const raw_ip& ip);
|
bool is_banned(const raw_ip& ip);
|
||||||
|
|
||||||
|
|||||||
+40
-8
@@ -322,11 +322,13 @@ void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::on_connect_failed(bool, const raw
|
|||||||
template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
|
template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
|
||||||
bool TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::is_banned(const raw_ip& ip)
|
bool TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::is_banned(const raw_ip& ip)
|
||||||
{
|
{
|
||||||
|
const auto cur_time = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
MutexLock lock(m_bansLock);
|
MutexLock lock(m_bansLock);
|
||||||
|
|
||||||
auto it = m_bans.find(ip);
|
auto it = m_bans.find(ip);
|
||||||
if (it != m_bans.end()) {
|
if (it != m_bans.end()) {
|
||||||
const bool banned = (time(nullptr) < it->second);
|
const bool banned = (cur_time < it->second);
|
||||||
if (!banned) {
|
if (!banned) {
|
||||||
m_bans.erase(it);
|
m_bans.erase(it);
|
||||||
}
|
}
|
||||||
@@ -435,14 +437,14 @@ void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::shutdown_tcp()
|
|||||||
|
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
|
||||||
const system_clock::time_point start_time = system_clock::now();
|
const auto start_time = steady_clock::now();
|
||||||
int64_t counter = 0;
|
int64_t counter = 0;
|
||||||
uv_async_t asy;
|
uv_async_t asy;
|
||||||
|
|
||||||
constexpr uint32_t timeout_seconds = 30;
|
constexpr uint32_t timeout_seconds = 30;
|
||||||
|
|
||||||
while (!m_loopStopped) {
|
while (!m_loopStopped) {
|
||||||
const int64_t elapsed_time = duration_cast<milliseconds>(system_clock::now() - start_time).count();
|
const int64_t elapsed_time = duration_cast<milliseconds>(steady_clock::now() - start_time).count();
|
||||||
|
|
||||||
if (elapsed_time >= (counter + 1) * 1000) {
|
if (elapsed_time >= (counter + 1) * 1000) {
|
||||||
++counter;
|
++counter;
|
||||||
@@ -493,8 +495,34 @@ void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::print_status()
|
|||||||
template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
|
template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
|
||||||
void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::ban(const raw_ip& ip, uint64_t seconds)
|
void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::ban(const raw_ip& ip, uint64_t seconds)
|
||||||
{
|
{
|
||||||
|
const auto ban_time = std::chrono::steady_clock::now() + std::chrono::seconds(seconds);
|
||||||
|
|
||||||
MutexLock lock(m_bansLock);
|
MutexLock lock(m_bansLock);
|
||||||
m_bans[ip] = time(nullptr) + seconds;
|
m_bans[ip] = ban_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
|
||||||
|
void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::print_bans()
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
const auto cur_time = steady_clock::now();
|
||||||
|
|
||||||
|
std::vector<std::pair<raw_ip, std::chrono::steady_clock::time_point>> bans;
|
||||||
|
{
|
||||||
|
MutexLock lock(m_bansLock);
|
||||||
|
|
||||||
|
bans.reserve(m_bans.size());
|
||||||
|
for (const auto& b : m_bans) {
|
||||||
|
bans.emplace_back(std::make_pair(b.first, b.second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& b : bans) {
|
||||||
|
if (cur_time < b.second) {
|
||||||
|
const uint64_t t = duration_cast<seconds>(b.second - cur_time).count();
|
||||||
|
LOGINFO(0, b.first << " is banned (" << t << " seconds left)");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
|
template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
|
||||||
@@ -520,10 +548,12 @@ bool TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::send_internal(Client* client, Sen
|
|||||||
buf = new WriteBuf();
|
buf = new WriteBuf();
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t bytes_written = callback(buf->m_data);
|
// callback_buf is used in only 1 thread, so it's safe
|
||||||
|
static uint8_t callback_buf[WRITE_BUF_SIZE];
|
||||||
|
const size_t bytes_written = callback(callback_buf);
|
||||||
|
|
||||||
if (bytes_written > sizeof(buf->m_data)) {
|
if (bytes_written > WRITE_BUF_SIZE) {
|
||||||
LOGERR(0, "send callback wrote " << bytes_written << " bytes, expected no more than " << sizeof(buf->m_data) << " bytes");
|
LOGERR(0, "send callback wrote " << bytes_written << " bytes, expected no more than " << WRITE_BUF_SIZE << " bytes");
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,9 +568,11 @@ bool TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::send_internal(Client* client, Sen
|
|||||||
|
|
||||||
buf->m_client = client;
|
buf->m_client = client;
|
||||||
buf->m_write.data = buf;
|
buf->m_write.data = buf;
|
||||||
|
buf->m_data.reserve(round_up(bytes_written, 64));
|
||||||
|
buf->m_data.assign(callback_buf, callback_buf + bytes_written);
|
||||||
|
|
||||||
uv_buf_t bufs[1];
|
uv_buf_t bufs[1];
|
||||||
bufs[0].base = buf->m_data;
|
bufs[0].base = reinterpret_cast<char*>(buf->m_data.data());
|
||||||
bufs[0].len = static_cast<int>(bytes_written);
|
bufs[0].len = static_cast<int>(bytes_written);
|
||||||
|
|
||||||
const int err = uv_write(&buf->m_write, reinterpret_cast<uv_stream_t*>(&client->m_socket), bufs, 1, Client::on_write);
|
const int err = uv_write(&buf->m_write, reinterpret_cast<uv_stream_t*>(&client->m_socket), bufs, 1, Client::on_write);
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ namespace p2pool {
|
|||||||
#define STR2(X) STR(X)
|
#define STR2(X) STR(X)
|
||||||
#define STR(X) #X
|
#define STR(X) #X
|
||||||
|
|
||||||
const char* VERSION = "v1.7 (built"
|
const char* VERSION = "v1.8 (built"
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
" with clang/" __clang_version__
|
" with clang/" __clang_version__
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ static_assert(rev_alphabet.num_symbols == 58, "Check alphabet");
|
|||||||
|
|
||||||
namespace p2pool {
|
namespace p2pool {
|
||||||
|
|
||||||
Wallet::Wallet(const char* address)
|
Wallet::Wallet(const char* address) : m_prefix(0), m_checksum(0), m_type(NetworkType::Invalid)
|
||||||
{
|
{
|
||||||
decode(address);
|
decode(address);
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-15
@@ -1,6 +1,8 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
project(p2pool_tests)
|
project(p2pool_tests)
|
||||||
|
|
||||||
|
option(STATIC_LIBS "Use locally built libuv and libzmq static libs" OFF)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
@@ -119,17 +121,28 @@ elseif (NOT APPLE)
|
|||||||
set(LIBS ${LIBS} pthread gss dl)
|
set(LIBS ${LIBS} pthread gss dl)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
if (STATIC_LIBS)
|
||||||
find_library(ZMQ_LIBRARY_DEBUG NAMES libzmq-v142-mt-sgd-4_3_5 PATHS "../external/lib/libzmq/Debug")
|
set(ZMQ_LIBRARY "${CMAKE_SOURCE_DIR}/../external/src/libzmq/build/lib/libzmq.a")
|
||||||
find_library(ZMQ_LIBRARY NAMES libzmq-v142-mt-s-4_3_5 PATHS "../external/lib/libzmq/Release")
|
set(ZMQ_LIBRARY_DEBUG "${CMAKE_SOURCE_DIR}/../external/src/libzmq/build/lib/libzmq.a")
|
||||||
find_library(UV_LIBRARY_DEBUG NAMES uv_a PATHS "../external/lib/libuv/Debug")
|
set(UV_LIBRARY_DEBUG "${CMAKE_SOURCE_DIR}/../external/src/libuv/build/libuv_a.a")
|
||||||
find_library(UV_LIBRARY NAMES uv_a PATHS "../external/lib/libuv/Release")
|
set(UV_LIBRARY "${CMAKE_SOURCE_DIR}/../external/src/libuv/build/libuv_a.a")
|
||||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
else()
|
||||||
find_library(ZMQ_LIBRARY_DEBUG NAMES zmq libzmq.a)
|
if (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
|
||||||
find_library(ZMQ_LIBRARY NAMES zmq libzmq.a)
|
find_library(ZMQ_LIBRARY_DEBUG NAMES libzmq-v142-mt-sgd-4_3_5 PATHS "../external/lib/libzmq/Debug")
|
||||||
find_library(UV_LIBRARY_DEBUG NAMES uv libuv.a)
|
find_library(ZMQ_LIBRARY NAMES libzmq-v142-mt-s-4_3_5 PATHS "../external/lib/libzmq/Release")
|
||||||
find_library(UV_LIBRARY NAMES uv libuv.a)
|
find_library(UV_LIBRARY_DEBUG NAMES uv_a PATHS "../external/lib/libuv/Debug")
|
||||||
find_library(SODIUM_LIBRARY sodium)
|
find_library(UV_LIBRARY NAMES uv_a PATHS "../external/lib/libuv/Release")
|
||||||
|
elseif (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||||
|
find_library(ZMQ_LIBRARY_DEBUG NAMES zmq libzmq.a)
|
||||||
|
find_library(ZMQ_LIBRARY NAMES zmq libzmq.a)
|
||||||
|
find_library(UV_LIBRARY_DEBUG NAMES uv libuv.a)
|
||||||
|
find_library(UV_LIBRARY NAMES uv libuv.a)
|
||||||
|
find_library(SODIUM_LIBRARY sodium)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (SODIUM_LIBRARY)
|
||||||
|
set(LIBS ${LIBS} ${SODIUM_LIBRARY})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_library(PGM_LIBRARY pgm)
|
find_library(PGM_LIBRARY pgm)
|
||||||
@@ -143,10 +156,6 @@ if (NORM_LIBRARY)
|
|||||||
set(LIBS ${LIBS} ${NORM_LIBRARY})
|
set(LIBS ${LIBS} ${NORM_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (SODIUM_LIBRARY)
|
|
||||||
set(LIBS ${LIBS} ${SODIUM_LIBRARY})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_definitions(/DZMQ_STATIC /DP2POOL_LOG_DISABLE)
|
add_definitions(/DZMQ_STATIC /DP2POOL_LOG_DISABLE)
|
||||||
|
|
||||||
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})
|
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
void p2pool_usage() {}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
|||||||
Reference in New Issue
Block a user