Removed --donate-time CLI option and donatetime console command, Removed time-based donation tracking, Replace time-based donation with deterministic blockchain-height-based donation, All nodes calculate donation mode identically based on block height, Eliminated need for sidechain file on mainnet - defualts to salvium_main now

This commit is contained in:
Matt Hess
2025-11-17 04:10:38 +00:00
parent cde94c9ea2
commit ec4f5d914d
9 changed files with 44 additions and 71 deletions

View File

@@ -781,7 +781,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
calc_merkle_tree_main_branch();
// DEBUG: Log block template structure
LOGINFO(0, "DEBUG P2POOL TEMPLATE (" << m_blockTemplateBlob.size() << " bytes)");
LOGINFO(5, "DEBUG P2POOL TEMPLATE (" << m_blockTemplateBlob.size() << " bytes)");
std::string hex;
hex.reserve(400);
for (size_t i = 0; i < std::min<size_t>(200, m_blockTemplateBlob.size()); ++i) {
@@ -789,7 +789,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
snprintf(buf, 3, "%02x", m_blockTemplateBlob[i]);
hex += buf;
}
LOGINFO(0, "P2POOL FIRST 200 BYTES: " << hex);
LOGINFO(5, "P2POOL FIRST 200 BYTES: " << hex);
LOGINFO(3, "final reward = " << log::Gray() << log::XMRAmount(final_reward) << log::NoColor() <<
", weight = " << log::Gray() << final_weight << log::NoColor() <<
@@ -954,7 +954,6 @@ int BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Mine
m_minerTx.clear();
const size_t num_outputs = shares.size();
LOGINFO(0, "DEBUG: Creating miner_tx with " << num_outputs << " outputs from " << num_outputs << " unique miners");
m_minerTx.reserve(num_outputs * 39 + 55);
// tx version

View File

@@ -165,7 +165,7 @@ typedef struct cmd {
cmdfunc *func;
} cmd;
static cmdfunc do_help, do_status, do_loglevel, do_addpeers, do_droppeers, do_showpeers, do_showworkers, do_showbans, do_showhosts, do_nexthost, do_outpeers, do_inpeers, do_donatetime, do_exit, do_version;
static cmdfunc do_help, do_status, do_loglevel, do_addpeers, do_droppeers, do_showpeers, do_showworkers, do_showbans, do_showhosts, do_nexthost, do_outpeers, do_inpeers, do_exit, do_version;
#ifdef WITH_RANDOMX
static cmdfunc do_start_mining, do_stop_mining;
@@ -188,7 +188,6 @@ static cmd cmds[] = {
{ STRCONST("start_mining"), "<threads>", "start mining", do_start_mining },
{ STRCONST("stop_mining"), "", "stop mining", do_stop_mining },
#endif
{ STRCONST("donate_time"), "<N>", "set donation time (1-50 minutes per 100)", do_donatetime },
{ STRCONST("exit"), "", "terminate p2pool", do_exit },
{ STRCONST("version"), "", "show p2pool version", do_version },
{ STRCNULL, NULL, NULL, NULL }
@@ -229,8 +228,6 @@ static void do_status(p2pool *m_pool, const char * /* args */)
indexed_hash::print_status();
#endif
LOGINFO(0, "Dev donation: " << log::LightCyan() << m_pool->params().m_donateLevel << log::NoColor() << " minute(s) per 100 minute cycle");
bkg_jobs_tracker->print_status();
if (p2p) {
@@ -379,20 +376,6 @@ static void do_inpeers(p2pool* m_pool, const char* args)
}
}
static void do_donatetime(p2pool* m_pool, const char* args)
{
uint32_t minutes = strtoul(args, nullptr, 10);
if (minutes < 1 || minutes > 50) {
LOGERR(0, "Invalid donation time " << minutes << ", must be 1-50");
return;
}
// Cast away const - params are mutable at runtime for console commands
const_cast<Params&>(m_pool->params()).m_donateLevel = minutes;
LOGINFO(0, log::LightCyan() << "Dev donation time updated to " << log::LightGreen() << minutes << log::LightCyan() << " minute(s) per 100 minute cycle");
}
#ifdef WITH_RANDOMX
static void do_start_mining(p2pool* m_pool, const char* args)
{

View File

@@ -108,7 +108,6 @@ 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",

View File

@@ -71,8 +71,6 @@ 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);
@@ -206,7 +204,7 @@ p2pool::p2pool(int argc, char* argv[])
throw std::exception();
}
m_sideChain = new SideChain(this, type, p->m_mini ? "mini" : (p->m_nano ? "nano" : nullptr));
m_sideChain = new SideChain(this, type, p->m_mini ? "mini" : (p->m_nano ? "nano" : nullptr), &p->m_devWallet);
const int p2p_port = m_sideChain->is_mini() ? DEFAULT_P2P_PORT_MINI : (m_sideChain->is_nano() ? DEFAULT_P2P_PORT_NANO : DEFAULT_P2P_PORT);
@@ -355,40 +353,18 @@ 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<minutes>(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)) {
// Log completion if we were in donation mode when cycle ended
if (m_inDonationMode) {
LOGINFO(0, log::LightCyan() << "Dev donation cycle complete");
}
m_donationCycleStart = now;
m_inDonationMode = false;
const PoolBlock* tip = m_sideChain->chainTip();
if (!tip) {
return false;
}
// Check if we should be in donation mode
const bool should_donate = (elapsed >= minutes(normal_minutes));
// Check the NEXT block height (the one being created), not current tip
const uint64_t next_height = tip->m_sidechainHeight + 1;
// 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");
}
// Donate every 100th block (blocks 100, 200, 300, etc.)
const uint64_t cycle_length = 100;
return m_inDonationMode;
return (next_height % cycle_length) == 0;
}
bool p2pool::calculate_hash(const void* data, size_t size, uint64_t height, const hash& seed, hash& result, bool force_light_mode)

View File

@@ -293,10 +293,6 @@ private:
std::atomic<uint64_t> m_lastMinerDataReceived;
// Dev donation tracking
std::chrono::steady_clock::time_point m_donationCycleStart;
bool m_inDonationMode = false;
uv_timer_t m_timer;
};

View File

@@ -92,15 +92,6 @@ Params::Params(int argc, char* const argv[])
ok = true;
}
if ((strcmp(argv[i], "--donate-time") == 0) && (i + 1 < argc)) {
m_donateLevel = static_cast<uint32_t>(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;

View File

@@ -82,7 +82,6 @@ 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;

View File

@@ -61,11 +61,12 @@ static constexpr uint8_t nano_consensus_id[HASH_SIZE] = { 83,65,76,78,210,226,11
NetworkType SideChain::s_networkType = NetworkType::Invalid;
SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name)
SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name, const Wallet* dev_wallet)
: m_pool(pool)
, m_chainTip{ nullptr }
, m_seenWalletsLastPruneTime(0)
, m_poolName(pool_name ? pool_name : "default")
, m_poolName(pool_name ? pool_name : "salvium_main")
, m_devWallet(dev_wallet)
, m_targetBlockTime(10)
, m_minDifficulty(MIN_DIFFICULTY, 0)
, m_chainWindowSize(2160)
@@ -864,6 +865,24 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v
if (!get_shares(block, data->tmpShares) || !split_reward(total_reward, data->tmpShares, tmpRewards) || (tmpRewards.size() != data->tmpShares.size())) {
return false;
}
// Handle donation mode during validation - match block creation logic
const uint64_t block_height = block->m_sidechainHeight;
if ((block_height % 100) == 0 && m_devWallet) {
// This is a donation block - replace all shares with single dev wallet output
difficulty_type total_weight;
for (const auto& share : data->tmpShares) {
total_weight += share.m_weight;
}
data->tmpShares.clear();
data->tmpShares.emplace_back(total_weight, m_devWallet);
// Recalculate rewards for the single dev wallet output
tmpRewards.clear();
if (!split_reward(total_reward, data->tmpShares, tmpRewards)) {
return false;
}
}
}
const size_t n = data->tmpShares.size();
@@ -1752,6 +1771,16 @@ void SideChain::verify(PoolBlock* block)
return;
}
// Handle donation mode during verification - match block creation logic
if ((block->m_sidechainHeight % 100) == 0 && m_devWallet) {
difficulty_type total_weight;
for (const auto& share : shares) {
total_weight += share.m_weight;
}
shares.clear();
shares.emplace_back(total_weight, m_devWallet);
}
if (shares.size() != block->m_outputAmounts.size()) {
LOGWARN(3, "block at height = " << block->m_sidechainHeight <<
", id = " << block->m_sidechainId <<

View File

@@ -40,7 +40,7 @@ struct MinerShare
class SideChain : public nocopy_nomove
{
public:
SideChain(p2pool* pool, NetworkType type, const char* pool_name = nullptr);
SideChain(p2pool* pool, NetworkType type, const char* pool_name = nullptr, const Wallet* dev_wallet = nullptr);
~SideChain();
[[nodiscard]] bool fill_sidechain_data(PoolBlock& block, std::vector<MinerShare>& shares) const;
@@ -138,6 +138,7 @@ private:
std::vector<DifficultyData> m_difficultyData;
std::string m_poolName;
const Wallet* m_devWallet;
std::string m_poolPassword;
uint64_t m_targetBlockTime;
difficulty_type m_minDifficulty;