2021-08-22 10:20:59 +00:00
/*
* This file is part of the Monero P2Pool < https : //github.com/SChernykh/p2pool>
2024-01-02 13:06:19 +00:00
* Copyright ( c ) 2021 - 2024 SChernykh < https : //github.com/SChernykh>
2021-08-22 10:20:59 +00:00
*
* 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"
2021-10-01 13:21:32 +00:00
# include "crypto.h"
2021-08-22 10:20:59 +00:00
# include "p2pool.h"
2021-09-18 08:03:06 +00:00
# include "stratum_server.h"
# include "p2p_server.h"
2022-06-07 14:02:08 +00:00
# include <curl/curl.h>
2024-12-04 18:41:05 +00:00
# include <filesystem>
2021-08-22 10:20:59 +00:00
2023-08-23 14:46:19 +00:00
# ifdef WITH_RANDOMX
# include "randomx.h"
# endif
2024-12-03 20:05:27 +00:00
# if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
# include <DbgHelp.h>
# pragma comment(lib, "Dbghelp.lib")
# endif
2022-02-21 07:02:36 +00:00
void p2pool_usage ( )
2021-08-22 10:20:59 +00:00
{
2021-10-02 15:06:48 +00:00
printf ( " P2Pool %s \n "
2021-08-22 10:20:59 +00:00
" \n Usage: \n \n " \
" --wallet Wallet address to mine to. Subaddresses and integrated addresses are not supported! \n "
" --host IP address of your Monero node, default is 127.0.0.1 \n "
" --rpc-port monerod RPC API port number, default is 18081 \n "
" --zmq-port monerod ZMQ pub port number, default is 18083 (same port as in monerod's \" --zmq-pub \" command line parameter) \n "
" --stratum Comma-separated list of IP:port for stratum server to listen on \n "
" --p2p Comma-separated list of IP:port for p2p server to listen on \n "
" --addpeers Comma-separated list of IP:port of other p2pool nodes to connect to \n "
" --light-mode Don't allocate RandomX dataset, saves 2GB of RAM \n "
2021-10-14 11:47:30 +00:00
" --loglevel Verbosity of the log, integer number between 0 and %d \n "
2024-12-04 14:20:43 +00:00
" --data-dir Path to store general p2pool files (log, cache, peer data, etc.), default is current directory \n "
2024-12-17 13:36:40 +00:00
" --config Deprecated, will be removed in the next version. Use --sidechain-config instead \n "
" --sidechain-config Name of the p2pool sidechain parameters file (only use it if you run your own sidechain) \n "
2024-12-04 14:20:43 +00:00
" --data-api Path to the p2pool JSON data (use it in tandem with an external web-server). Not affected by --data-dir setting! \n "
2022-01-24 09:25:20 +00:00
" --local-api Enable /local/ path in api path for Stratum Server and built-in miner statistics \n "
" --stratum-api An alias for --local-api \n "
2021-10-16 11:45:28 +00:00
" --no-cache Disable p2pool.cache \n "
2021-10-27 14:21:56 +00:00
" --no-color Disable colors in console output \n "
2023-03-20 09:04:43 +00:00
# ifdef WITH_RANDOMX
2021-11-20 10:51:22 +00:00
" --no-randomx Disable internal RandomX hasher: p2pool will use RPC calls to monerod to check PoW hashes \n "
2023-03-20 09:04:43 +00:00
# endif
2022-09-20 08:39:55 +00:00
" --out-peers N Maximum number of outgoing connections for p2p server (any value between 10 and 450) \n "
" --in-peers N Maximum number of incoming connections for p2p server (any value between 10 and 450) \n "
2022-01-22 22:09:29 +00:00
" --start-mining N Start built-in miner using N threads (any value between 1 and 64) \n "
2022-05-08 10:30:22 +00:00
" --mini Connect to p2pool-mini sidechain. Note that it will also change default p2p port from %d to %d \n "
2023-02-21 08:17:42 +00:00
" --no-autodiff Disable automatic difficulty adjustment for miners connected to stratum (WARNING: incompatible with Nicehash and MRR) \n "
2022-06-04 11:16:05 +00:00
" --rpc-login Specify username[:password] required for Monero RPC server \n "
2022-08-31 14:37:33 +00:00
" --socks5 Specify IP:port of a SOCKS5 proxy to use for outgoing connections \n "
2023-03-19 21:54:18 +00:00
" --no-dns Disable DNS queries, use only IP addresses to connect to peers (seed node DNS will be unavailable too) \n "
" --p2p-external-port Port number that your router uses for mapping to your local p2p port. Use it if you are behind a NAT and still want to accept incoming connections \n "
# ifdef WITH_UPNP
" --no-upnp Disable UPnP port forwarding \n "
2023-03-21 18:31:18 +00:00
" --no-igd An alias for --no-upnp \n "
2023-03-20 12:32:17 +00:00
" --upnp-stratum Port forward Stratum port (it's not forwarded by default) \n "
2023-03-19 21:54:18 +00:00
# endif
2024-04-23 16:59:04 +00:00
" --merge-mine IP:port and wallet address for another blockchain to merge mine with \n "
2023-04-17 13:37:05 +00:00
" --version Print p2pool's version and build details \n "
2024-08-07 19:21:24 +00:00
# ifdef WITH_TLS
" --tls-cert file Load TLS certificate chain from \" file \" in the PEM format \n "
" --tls-cert-key file Load TLS certificate private key from \" file \" in the PEM format \n "
# endif
2024-12-17 10:39:49 +00:00
" --no-stratum-http Disable HTTP on Stratum ports \n "
2021-08-22 10:20:59 +00:00
" --help Show this help message \n \n "
" Example command line: \n \n "
2021-09-18 08:03:06 +00:00
" %s --host 127.0.0.1 --rpc-port 18081 --zmq-port 18083 --wallet YOUR_WALLET_ADDRESS --stratum 0.0.0.0:%d --p2p 0.0.0.0:%d \n \n " ,
2021-10-02 15:06:48 +00:00
p2pool : : VERSION ,
2021-10-14 11:47:30 +00:00
p2pool : : log : : MAX_GLOBAL_LOG_LEVEL ,
2022-02-14 12:57:59 +00:00
p2pool : : DEFAULT_P2P_PORT ,
p2pool : : DEFAULT_P2P_PORT_MINI ,
2021-08-22 10:20:59 +00:00
# ifdef _WIN32
" p2pool.exe "
# else
" ./p2pool "
# endif
2021-09-18 08:03:06 +00:00
, p2pool : : DEFAULT_STRATUM_PORT
, p2pool : : DEFAULT_P2P_PORT
2021-08-22 10:20:59 +00:00
) ;
}
2023-04-17 13:37:05 +00:00
void p2pool_version ( )
{
printf ( " P2Pool %s \n " , p2pool : : VERSION ) ;
}
2023-08-23 14:46:19 +00:00
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 ;
}
2023-10-18 11:43:40 +00:00
{
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 ( ) ;
}
}
2023-08-23 14:46:19 +00:00
randomx_release_cache ( myCache ) ;
randomx_vm * myMachine = randomx_create_vm ( flags , nullptr , myDataset ) ;
if ( ! myMachine ) {
printf ( " Failed to create a virtual machine " ) ;
return 1 ;
}
2023-10-18 09:01:16 +00:00
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 ) ;
}
2023-08-23 14:46:19 +00:00
char buf [ RANDOMX_HASH_SIZE * 2 + 1 ] = { } ;
p2pool : : log : : Stream s ( buf ) ;
2023-10-18 09:01:16 +00:00
s < < p2pool : : log : : hex_buf ( hash , RANDOMX_HASH_SIZE ) < < ' \0 ' ;
constexpr char expected_hash [ ] = " 3b5ecc2bb14f467161a04fe476b541194fba82dbbbfc7c320961f922a0294dee " ;
2023-08-23 14:46:19 +00:00
2023-10-18 09:01:16 +00:00
if ( memcmp ( buf , expected_hash , RANDOMX_HASH_SIZE * 2 ) ! = 0 ) {
printf ( " Invalid hash calculated: expected %s, got %s \n " , expected_hash , buf ) ;
2023-08-23 14:46:19 +00:00
return 1 ;
}
randomx_destroy_vm ( myMachine ) ;
randomx_release_dataset ( myDataset ) ;
# endif
printf ( " Self-test passed \n " ) ;
return 0 ;
}
2021-08-22 10:20:59 +00:00
int main ( int argc , char * argv [ ] )
{
if ( argc = = 1 ) {
2022-02-21 07:02:36 +00:00
p2pool_usage ( ) ;
2021-08-22 10:20:59 +00:00
return 0 ;
}
for ( int i = 1 ; i < argc ; + + i ) {
if ( ! strcmp ( argv [ i ] , " --help " ) | | ! strcmp ( argv [ i ] , " /help " ) | | ! strcmp ( argv [ i ] , " -h " ) | | ! strcmp ( argv [ i ] , " /h " ) ) {
2022-02-21 07:02:36 +00:00
p2pool_usage ( ) ;
2021-08-22 10:20:59 +00:00
return 0 ;
}
2023-04-17 13:37:05 +00:00
2023-04-17 21:28:03 +00:00
if ( ! strcmp ( argv [ i ] , " --version " ) | | ! strcmp ( argv [ i ] , " /version " ) | | ! strcmp ( argv [ i ] , " -v " ) | | ! strcmp ( argv [ i ] , " /v " ) ) {
2023-04-17 13:37:05 +00:00
p2pool_version ( ) ;
return 0 ;
}
2023-08-23 14:46:19 +00:00
if ( ! strcmp ( argv [ i ] , " --test " ) ) {
return p2pool_test ( ) ;
}
2024-12-04 14:20:43 +00:00
if ( ( strcmp ( argv [ i ] , " --data-dir " ) = = 0 ) & & ( i + 1 < argc ) ) {
std : : string path = argv [ + + i ] ;
if ( ! path . empty ( ) & & ( path . back ( ) ! = ' / ' )
# ifdef _WIN32
& & ( path . back ( ) ! = ' \\ ' )
# endif
) {
path . append ( 1 , ' / ' ) ;
}
p2pool : : DATA_DIR = std : : move ( path ) ;
2024-12-04 18:41:05 +00:00
// Try to create it if it doesn't exist
if ( ! p2pool : : DATA_DIR . empty ( ) ) {
std : : error_code err ;
std : : filesystem : : create_directories ( p2pool : : DATA_DIR , err ) ;
}
2024-12-04 14:20:43 +00:00
}
2021-08-22 10:20:59 +00:00
}
2024-12-03 20:05:27 +00:00
# if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
SymInitialize ( GetCurrentProcess ( ) , NULL , TRUE ) ;
# endif
2021-08-26 21:27:05 +00:00
memory_tracking_start ( ) ;
2021-10-01 13:21:32 +00:00
2024-12-03 20:05:27 +00:00
// Create default loop here
uv_default_loop ( ) ;
p2pool : : log : : start ( ) ;
2021-10-01 13:21:32 +00:00
p2pool : : init_crypto_cache ( ) ;
2022-05-23 07:37:11 +00:00
2022-06-07 14:02:08 +00:00
int result = static_cast < int > ( curl_global_init_mem ( CURL_GLOBAL_ALL , p2pool : : malloc_hook , p2pool : : free_hook , p2pool : : realloc_hook , p2pool : : strdup_hook , p2pool : : calloc_hook ) ) ;
if ( result ! = CURLE_OK ) {
return result ;
}
2022-05-23 07:37:11 +00:00
try {
2021-08-26 21:27:05 +00:00
p2pool : : p2pool pool ( argc , argv ) ;
result = pool . run ( ) ;
}
2022-05-23 07:37:11 +00:00
catch ( . . . ) {
result = 1 ;
}
2022-06-07 14:02:08 +00:00
curl_global_cleanup ( ) ;
2021-10-01 13:21:32 +00:00
p2pool : : destroy_crypto_cache ( ) ;
2024-12-03 20:05:27 +00:00
p2pool : : log : : stop ( ) ;
uv_loop_close ( uv_default_loop ( ) ) ;
# if ((UV_VERSION_MAJOR > 1) || ((UV_VERSION_MAJOR == 1) && (UV_VERSION_MINOR >= 38)))
uv_library_shutdown ( ) ;
# endif
2023-07-19 11:13:00 +00:00
if ( ! memory_tracking_stop ( ) ) {
result = 1 ;
}
2021-08-26 21:27:05 +00:00
2024-12-03 20:05:27 +00:00
# if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
SymCleanup ( GetCurrentProcess ( ) ) ;
# endif
2021-08-26 21:27:05 +00:00
return result ;
2021-08-22 10:20:59 +00:00
}