diff --git a/docs/COMMAND_LINE.MD b/docs/COMMAND_LINE.MD index dc7fa2a..20193e8 100644 --- a/docs/COMMAND_LINE.MD +++ b/docs/COMMAND_LINE.MD @@ -22,6 +22,7 @@ --in-peers N Maximum number of incoming connections for p2p server (any value between 10 and 450) --start-mining N Start built-in miner using N threads (any value between 1 and 64) --mini Connect to p2pool-mini sidechain. Note that it will also change default p2p port from 37889 to 37888 +--nano Connect to p2pool-nano sidechain. Note that it will also change default p2p port from 37889 to 37890 --no-autodiff Disable automatic difficulty adjustment for miners connected to stratum (WARNING: incompatible with Nicehash and MRR) --rpc-login Specify username[:password] required for Monero RPC server --socks5 Specify IP:port of a SOCKS5 proxy to use for outgoing connections diff --git a/src/main.cpp b/src/main.cpp index 3eb8925..e5dd2f9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -62,6 +62,7 @@ void p2pool_usage() "--in-peers N Maximum number of incoming connections for p2p server (any value between 10 and 450)\n" "--start-mining N Start built-in miner using N threads (any value between 1 and 64)\n" "--mini Connect to p2pool-mini sidechain. Note that it will also change default p2p port from %d to %d\n" + "--nano Connect to p2pool-nano sidechain. Note that it will also change default p2p port from %d to %d\n" "--no-autodiff Disable automatic difficulty adjustment for miners connected to stratum (WARNING: incompatible with Nicehash and MRR)\n" "--rpc-login Specify username[:password] required for Monero RPC server\n" "--socks5 Specify IP:port of a SOCKS5 proxy to use for outgoing connections\n" @@ -88,6 +89,8 @@ void p2pool_usage() p2pool::log::MAX_GLOBAL_LOG_LEVEL, p2pool::DEFAULT_P2P_PORT, p2pool::DEFAULT_P2P_PORT_MINI, + p2pool::DEFAULT_P2P_PORT, + p2pool::DEFAULT_P2P_PORT_NANO, #ifdef _WIN32 "p2pool.exe" #else diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index 08937ff..0b3dbe8 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -47,6 +47,7 @@ LOG_CATEGORY(P2PServer) static constexpr char saved_peer_list_file_name[] = "p2pool_peers.txt"; static const char* seed_nodes[] = { "seeds.p2pool.io", "main.p2poolpeers.net", "main.gupax.io", "" }; static const char* seed_nodes_mini[] = { "seeds-mini.p2pool.io", "mini.p2poolpeers.net", "mini.gupax.io", "" }; +static const char* seed_nodes_nano[] = { "seeds-nano.p2pool.io", "nano.p2poolpeers.net", "nano.gupax.io", ""}; static constexpr int DEFAULT_BACKLOG = 16; static constexpr uint64_t DEFAULT_BAN_TIME = 600; @@ -606,6 +607,9 @@ void P2PServer::load_peer_list() else if (m_pool->side_chain().is_mini()) { load_from_seed_nodes(seed_nodes_mini, DEFAULT_P2P_PORT_MINI); } + else if (m_pool->side_chain().is_nano()) { + load_from_seed_nodes(seed_nodes_nano, DEFAULT_P2P_PORT_NANO); + } } // Finally load peers from p2pool_peers.txt @@ -698,7 +702,7 @@ void P2PServer::load_monerod_peer_list() #undef ERR_STR - const int port = m_pool->side_chain().is_mini() ? DEFAULT_P2P_PORT_MINI : DEFAULT_P2P_PORT; + const int port = m_pool->side_chain().is_mini() ? DEFAULT_P2P_PORT_MINI : (m_pool->side_chain().is_nano() ? DEFAULT_P2P_PORT_NANO : DEFAULT_P2P_PORT); const SizeType n = white_list.Size(); diff --git a/src/p2p_server.h b/src/p2p_server.h index 66e9d53..d9fddbd 100644 --- a/src/p2p_server.h +++ b/src/p2p_server.h @@ -34,6 +34,7 @@ static_assert((P2P_BUF_SIZE & (P2P_BUF_SIZE - 1)) == 0, "P2P_BUF_SIZE is not a p static constexpr size_t PEER_LIST_RESPONSE_MAX_PEERS = 16; static constexpr int DEFAULT_P2P_PORT = 37889; static constexpr int DEFAULT_P2P_PORT_MINI = 37888; +static constexpr int DEFAULT_P2P_PORT_NANO = 37890; static constexpr uint32_t PROTOCOL_VERSION_1_0 = 0x00010000UL; static constexpr uint32_t PROTOCOL_VERSION_1_1 = 0x00010001UL; diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 6e272f2..f162950 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -49,8 +49,6 @@ LOG_CATEGORY(P2Pool) -constexpr int BLOCK_HEADERS_REQUIRED = 720; - constexpr uint64_t SEEDHASH_EPOCH_BLOCKS = 2048; constexpr uint64_t SEEDHASH_EPOCH_LAG = 64; @@ -58,6 +56,8 @@ constexpr char FOUND_BLOCKS_FILE[] = "p2pool.blocks"; namespace p2pool { +static uint64_t BLOCK_HEADERS_REQUIRED = 720; + p2pool::p2pool(int argc, char* argv[]) : m_stopped(false) , m_updateSeed(true) @@ -78,6 +78,11 @@ p2pool::p2pool(int argc, char* argv[]) m_params = p; + // P2Pool-nano requires more Monero blocks for the initial sync + if (m_params->m_nano) { + BLOCK_HEADERS_REQUIRED = 1440; + } + bkg_jobs_tracker = new BackgroundJobTracker(); #ifdef WITH_UPNP @@ -175,10 +180,10 @@ p2pool::p2pool(int argc, char* argv[]) throw std::exception(); } - m_sideChain = new SideChain(this, type, p->m_mini ? "mini" : nullptr); + m_sideChain = new SideChain(this, type, p->m_mini ? "mini" : (p->m_nano ? "nano" : nullptr)); if (p->m_p2pAddresses.empty()) { - const int p2p_port = m_sideChain->is_mini() ? DEFAULT_P2P_PORT_MINI : DEFAULT_P2P_PORT; + const int p2p_port = m_sideChain->is_mini() ? DEFAULT_P2P_PORT_MINI : (m_sideChain->is_nano() ? DEFAULT_P2P_PORT_NANO : DEFAULT_P2P_PORT); char buf[48] = {}; log::Stream s(buf); @@ -1864,7 +1869,7 @@ void p2pool::cleanup_mainchain_data(uint64_t height) // Expects m_mainchainLock to be already locked here // Deletes everything older than 720 blocks, except for the 3 latest RandomX seed heights - constexpr uint64_t PRUNE_DISTANCE = BLOCK_HEADERS_REQUIRED; + const uint64_t PRUNE_DISTANCE = BLOCK_HEADERS_REQUIRED; const uint64_t seed_height = get_seed_height(height); const std::array seed_heights{ seed_height, seed_height - SEEDHASH_EPOCH_BLOCKS, seed_height - SEEDHASH_EPOCH_BLOCKS * 2 }; diff --git a/src/params.cpp b/src/params.cpp index 9e2d642..247d350 100644 --- a/src/params.cpp +++ b/src/params.cpp @@ -153,6 +153,11 @@ Params::Params(int argc, char* const argv[]) ok = true; } + if (strcmp(argv[i], "--nano") == 0) { + m_nano = true; + ok = true; + } + if (strcmp(argv[i], "--no-autodiff") == 0) { m_autoDiff = false; ok = true; @@ -300,6 +305,11 @@ bool Params::valid() const } #endif + if (m_mini && m_nano) { + LOGERR(1, "You can't have both --mini and --nano in the command line"); + return false; + } + return true; } diff --git a/src/params.h b/src/params.h index d02a1c0..e8c8a84 100644 --- a/src/params.h +++ b/src/params.h @@ -85,6 +85,7 @@ struct Params uint32_t m_maxIncomingPeers = 450; uint32_t m_minerThreads = 0; bool m_mini = false; + bool m_nano = false; bool m_autoDiff = true; std::string m_socks5Proxy; bool m_dns = true; diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 682b776..05d0ae5 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -57,6 +57,7 @@ namespace p2pool { static constexpr uint8_t default_consensus_id[HASH_SIZE] = { 34,175,126,231,181,11,104,146,227,153,218,107,44,108,68,39,178,81,4,212,169,4,142,0,177,110,157,240,68,7,249,24 }; static constexpr uint8_t mini_consensus_id[HASH_SIZE] = { 57,130,201,26,149,174,199,250,66,80,189,18,108,216,194,220,136,23,63,24,64,113,221,44,219,86,39,163,53,24,126,196 }; +static constexpr uint8_t nano_consensus_id[HASH_SIZE] = { 171,248,206,148,210,226,114,99,250,145,221,96,13,216,23,63,104,53,129,168,244,80,141,138,157,250,50,54,37,189,5,89 }; NetworkType SideChain::s_networkType = NetworkType::Invalid; @@ -104,6 +105,11 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) LOGINFO(1, "generating consensus ID"); + if (m_poolName == "nano") { + m_targetBlockTime = 30; + m_unclePenalty = 10; + } + char buf[log::Stream::BUF_SIZE + 1]; // cppcheck-suppress uninitvar log::Stream s(buf); @@ -118,6 +124,7 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) constexpr char default_config[] = "mainnet\0" "default\0" "\0" "10\0" "100000\0" "2160\0" "20\0"; constexpr char mini_config[] = "mainnet\0" "mini\0" "\0" "10\0" "100000\0" "2160\0" "20\0"; + constexpr char nano_config[] = "mainnet\0" "nano\0" "\0" "30\0" "100000\0" "2160\0" "10\0"; // Hardcoded default consensus ID if ((s.m_pos == sizeof(default_config) - 1) && (memcmp(buf, default_config, sizeof(default_config) - 1) == 0)) { @@ -127,6 +134,10 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) else if ((s.m_pos == sizeof(mini_config) - 1) && (memcmp(buf, mini_config, sizeof(mini_config) - 1) == 0)) { m_consensusId.assign(mini_consensus_id, mini_consensus_id + HASH_SIZE); } + // Hardcoded nano consensus ID + else if ((s.m_pos == sizeof(nano_config) - 1) && (memcmp(buf, nano_config, sizeof(nano_config) - 1) == 0)) { + m_consensusId.assign(nano_consensus_id, nano_consensus_id + HASH_SIZE); + } else { #ifdef WITH_RANDOMX const randomx_flags flags = randomx_get_flags(); @@ -1062,7 +1073,7 @@ void SideChain::print_status(bool obtain_sidechain_lock) const "\nMonero node = " << m_pool->current_host().m_displayName << "\nMain chain height = " << m_pool->block_template().height() << "\nMain chain hashrate = " << log::Hashrate(network_hashrate) << - "\nSide chain ID = " << (is_default() ? "default" : (is_mini() ? "mini" : m_consensusIdDisplayStr.c_str())) << + "\nSide chain ID = " << (is_default() ? "default" : (is_mini() ? "mini" : (is_nano() ? "nano" : m_consensusIdDisplayStr.c_str()))) << "\nSide chain height = " << tip_height + 1 << "\nSide chain hashrate = " << log::Hashrate(pool_hashrate) << (hashrate_est ? "\nYour hashrate (pool-side) = " : "") << (hashrate_est ? log::Hashrate(hashrate_est) : log::Hashrate()) << @@ -1185,6 +1196,11 @@ bool SideChain::is_mini() const return (memcmp(m_consensusId.data(), mini_consensus_id, HASH_SIZE) == 0); } +bool SideChain::is_nano() const +{ + return (memcmp(m_consensusId.data(), nano_consensus_id, HASH_SIZE) == 0); +} + uint64_t SideChain::bottom_height(const PoolBlock* tip) const { if (!tip) { diff --git a/src/side_chain.h b/src/side_chain.h index 27988e4..90aff7a 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -79,6 +79,7 @@ public: [[nodiscard]] uint64_t last_updated() const; [[nodiscard]] bool is_default() const; [[nodiscard]] bool is_mini() const; + [[nodiscard]] bool is_nano() const; [[nodiscard]] uint64_t bottom_height(const PoolBlock* tip) const; [[nodiscard]] const PoolBlock* chainTip() const { return m_chainTip; } diff --git a/src/stratum_server.cpp b/src/stratum_server.cpp index 86b7d82..d305cda 100644 --- a/src/stratum_server.cpp +++ b/src/stratum_server.cpp @@ -891,6 +891,26 @@ void StratumServer::update_hashrate_data(uint64_t hashes, uint64_t timestamp) if (hashes) { m_cumulativeHashes += hashes; ++m_totalStratumShares; + + // P2Pool-nano warning +#ifndef P2POOL_LOG_DISABLE + // Check the hashrate when enough shares is found + if (((m_totalStratumShares & 63) == 0) && m_pool->side_chain().is_nano()) { + const HashrateData& head = m_hashrateData[m_hashrateDataHead]; + const HashrateData& tail = m_hashrateData[m_hashrateDataTail_24h]; + + const int64_t dt = static_cast(head.m_timestamp - tail.m_timestamp); + + if (dt > 0) { + const uint64_t total_hashes = head.m_cumulativeHashes - tail.m_cumulativeHashes; + const uint64_t hashrate = total_hashes / dt; + + if (hashrate > 30000) { + LOGINFO(0, log::LightRed() << "Your hashrate is " << log::Hashrate(hashrate) << ". Please switch from P2Pool-nano to P2Pool-mini or P2Pool-main. P2Pool-nano is recommended only for small-scale miners."); + } + } + } +#endif // P2POOL_LOG_DISABLE } HashrateData* data = m_hashrateData;