diff --git a/src/block_template.cpp b/src/block_template.cpp index a073db0..34b7138 100644 --- a/src/block_template.cpp +++ b/src/block_template.cpp @@ -214,7 +214,7 @@ void BlockTemplate::shuffle_tx_order() } } -void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const Params* params) +void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const Params* params, bool in_donation_mode) { if (data.major_version > HARDFORK_SUPPORTED_VERSION) { LOGERR(1, "got hardfork version " << data.major_version << ", expected <= " << HARDFORK_SUPPORTED_VERSION); @@ -279,7 +279,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const m_blockHeaderSize = m_blockHeader.size(); - m_poolBlockTemplate->m_minerWallet = params->m_miningWallet; + m_poolBlockTemplate->m_minerWallet = in_donation_mode ? params->m_devWallet : params->m_miningWallet; if (!m_sidechain->fill_sidechain_data(*m_poolBlockTemplate, m_shares)) { use_old_template(); @@ -608,7 +608,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const m_poolBlockTemplate->m_transactions.push_back(m_mempoolTxs[m_mempoolTxsOrder[i]].id); } - m_poolBlockTemplate->m_minerWallet = params->m_miningWallet; + m_poolBlockTemplate->m_minerWallet = in_donation_mode ? params->m_devWallet : params->m_miningWallet; // Layout: [software id, version, random number, sidechain extra_nonce] uint32_t* sidechain_extra = m_poolBlockTemplate->m_sidechainExtraBuf; diff --git a/src/block_template.h b/src/block_template.h index 11fbdae..5a5b873 100644 --- a/src/block_template.h +++ b/src/block_template.h @@ -40,7 +40,7 @@ public: BlockTemplate(const BlockTemplate& b); BlockTemplate& operator=(const BlockTemplate& b); - void update(const MinerData& data, const Mempool& mempool, const Params* params); + void update(const MinerData& data, const Mempool& mempool, const Params* params, bool in_donation_mode = false); uint64_t last_updated() const { return m_lastUpdated.load(); } bool get_difficulties(const uint32_t template_id, uint64_t& height, uint64_t& sidechain_height, difficulty_type& mainchain_difficulty, difficulty_type& aux_diff, difficulty_type& sidechain_difficulty) const; diff --git a/src/main.cpp b/src/main.cpp index 66c8e1b..bc38bf3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -108,6 +108,7 @@ void p2pool_usage() "--full-validation Enables full share validation / increases CPU usage\n" "--onion-address Tell other peers to use this .onion address to connect to this node through TOR\n" "--no-clearnet-p2p Forces P2P server to listen on 127.0.0.1 and to not connect to clearnet IPs\n" + "--donate-time=N Dev donation: N minutes per 100 minute cycle (1-50, default: 1)\n" "--help Show this help message\n\n" "Example command line:\n\n" "%s-salvium --host 127.0.0.1 --rpc-port 19081 --zmq-port 19083 --wallet YOUR_WALLET_ADDRESS --stratum 0.0.0.0:%d --p2p 0.0.0.0:%d\n\n", diff --git a/src/p2pool.cpp b/src/p2pool.cpp index dd741c8..8acd603 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -16,6 +16,7 @@ */ #include "common.h" +#include #include "p2pool.h" #ifndef P2POOL_UNIT_TESTS #include "zmq_reader.h" @@ -70,6 +71,8 @@ p2pool::p2pool(int argc, char* argv[]) , m_zmqLastActive(0) , m_startTime(seconds_since_epoch()) , m_lastMinerDataReceived(0) + , m_donationCycleStart(std::chrono::steady_clock::now()) + , m_inDonationMode(false) { LOGINFO(1, log::LightCyan() << VERSION); @@ -350,6 +353,40 @@ void p2pool::print_hosts() const } } +bool p2pool::in_donation_mode() +{ + using namespace std::chrono; + + const auto now = steady_clock::now(); + const auto elapsed = duration_cast(now - m_donationCycleStart); + + const uint32_t cycle_minutes = 100; + const uint32_t donate_minutes = m_params->m_donateLevel; + const uint32_t normal_minutes = cycle_minutes - donate_minutes; + + // Check if we need to start a new cycle + if (elapsed >= minutes(cycle_minutes)) { + m_donationCycleStart = now; + m_inDonationMode = false; + return false; + } + + // Check if we should be in donation mode + const bool should_donate = (elapsed >= minutes(normal_minutes)); + + // Log transitions + if (should_donate && !m_inDonationMode) { + m_inDonationMode = true; + LOGINFO(0, log::LightCyan() << "Entering dev donation mode for " << log::LightGreen() << donate_minutes << log::LightCyan() << " minute(s)"); + } + else if (!should_donate && m_inDonationMode) { + m_inDonationMode = false; + LOGINFO(0, log::LightCyan() << "Dev donation cycle complete"); + } + + return m_inDonationMode; +} + bool p2pool::calculate_hash(const void* data, size_t size, uint64_t height, const hash& seed, hash& result, bool force_light_mode) { return m_hasher->calculate(data, size, height, seed, result, force_light_mode); @@ -1253,7 +1290,7 @@ void p2pool::update_block_template() if (m_updateSeed.exchange(false)) { m_hasher->set_seed_async(data.seed_hash); } - m_blockTemplate->update(data, *m_mempool, m_params); + m_blockTemplate->update(data, *m_mempool, m_params, in_donation_mode()); stratum_on_block(); api_update_pool_stats(); diff --git a/src/p2pool.h b/src/p2pool.h index e461999..f9d2f7f 100644 --- a/src/p2pool.h +++ b/src/p2pool.h @@ -49,6 +49,7 @@ public: void stop(); const Params& params() const { return *m_params; } + bool in_donation_mode(); BlockTemplate& block_template() { return *m_blockTemplate; } SideChain& side_chain() { return *m_sideChain; } @@ -292,6 +293,10 @@ private: std::atomic m_lastMinerDataReceived; + // Dev donation tracking + std::chrono::steady_clock::time_point m_donationCycleStart; + bool m_inDonationMode = false; + uv_timer_t m_timer; }; diff --git a/src/params.cpp b/src/params.cpp index eac9efe..a6d008e 100644 --- a/src/params.cpp +++ b/src/params.cpp @@ -92,6 +92,15 @@ Params::Params(int argc, char* const argv[]) ok = true; } + if ((strcmp(argv[i], "--donate-time") == 0) && (i + 1 < argc)) { + m_donateLevel = static_cast(atoi(argv[++i])); + if (m_donateLevel < 1 || m_donateLevel > 50) { + LOGERR(1, "Invalid donate level " << m_donateLevel << ", must be 1-50"); + m_donateLevel = 1; + } + ok = true; + } + if ((strcmp(argv[i], "--stratum") == 0) && (i + 1 < argc)) { m_stratumAddresses = argv[++i]; ok = true; @@ -345,6 +354,7 @@ Params::Params(int argc, char* const argv[]) char display_wallet_buf[Wallet::ADDRESS_LENGTH] = {}; + if (m_mainWallet.valid() && m_subaddress.valid()) { if (!m_miningWallet.assign(m_subaddress.spend_public_key(), m_mainWallet.view_public_key(), m_mainWallet.type(), false)) { LOGERR(1, "Failed to configure the mining wallet, falling back to " << m_mainWallet); @@ -360,6 +370,12 @@ Params::Params(int argc, char* const argv[]) m_mainWallet.encode(display_wallet_buf); } + // Initialize dev wallet + const char* dev_wallet_str = "SC11n4s2UEj9Rc8XxppPbegwQethVmREpG9JP3aJUBGRCuD3wEvS4qtYtBjhqSx3S1hw3WDCfmbWKHJqa9g5Vqyo3jrsReJ5vp"; + if (!m_devWallet.decode(dev_wallet_str)) { + LOGERR(1, "Failed to decode dev wallet address"); + } + m_displayWallet.assign(display_wallet_buf, Wallet::ADDRESS_LENGTH); } diff --git a/src/params.h b/src/params.h index 08e5c1f..7eea87d 100644 --- a/src/params.h +++ b/src/params.h @@ -82,6 +82,9 @@ struct Params std::string m_displayWallet; + uint32_t m_donateLevel = 1; // Minutes per 100 minutes (default 1%) + Wallet m_devWallet{ nullptr }; + std::string m_stratumAddresses; std::string m_p2pAddresses; std::string m_p2pPeerList;