mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-23 03:49:23 +00:00
Workaround for duplicate sidechain IDs
Place transactions in the block template in random order, so two different p2pool nodes mining to the same wallet will get different sidechain IDs with high probability if there's more than 2-3 transactions in mempool.
This commit is contained in:
parent
d8bb85a1d8
commit
02405bb8ff
2 changed files with 26 additions and 6 deletions
|
@ -54,7 +54,11 @@ BlockTemplate::BlockTemplate(p2pool* pool)
|
|||
, m_txkeySec{}
|
||||
, m_poolBlockTemplate(new PoolBlock())
|
||||
, m_finalReward(0)
|
||||
, m_rng(RandomDeviceSeed::instance)
|
||||
{
|
||||
// Diffuse the initial state in case it has low quality
|
||||
m_rng.discard(10000);
|
||||
|
||||
uv_rwlock_init_checked(&m_lock);
|
||||
|
||||
m_blockHeader.reserve(64);
|
||||
|
@ -133,6 +137,8 @@ BlockTemplate& BlockTemplate::operator=(const BlockTemplate& b)
|
|||
m_mempoolTxsOrder.clear();
|
||||
m_shares.clear();
|
||||
|
||||
m_rng = b.m_rng;
|
||||
|
||||
#if TEST_MEMPOOL_PICKING_ALGORITHM
|
||||
m_knapsack.clear();
|
||||
#endif
|
||||
|
@ -171,6 +177,14 @@ static FORCEINLINE uint64_t get_block_reward(uint64_t base_reward, uint64_t medi
|
|||
return reward + fees;
|
||||
}
|
||||
|
||||
void BlockTemplate::shuffle_tx_order()
|
||||
{
|
||||
const int64_t n = static_cast<int64_t>(m_mempoolTxsOrder.size());
|
||||
for (int64_t i = n - 1; i > 0; --i) {
|
||||
std::swap(m_mempoolTxsOrder[i], m_mempoolTxsOrder[m_rng() % (i + 1)]);
|
||||
}
|
||||
}
|
||||
|
||||
void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet* miner_wallet)
|
||||
{
|
||||
if (data.major_version > HARDFORK_SUPPORTED_VERSION) {
|
||||
|
@ -315,16 +329,16 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet
|
|||
|
||||
// if a block doesn't get into the penalty zone, just pick all transactions
|
||||
if (total_tx_weight + miner_tx_weight <= data.median_weight) {
|
||||
m_numTransactionHashes = 0;
|
||||
|
||||
final_fees = 0;
|
||||
final_weight = miner_tx_weight;
|
||||
|
||||
m_transactionHashes.assign(HASH_SIZE, 0);
|
||||
for (const TxMempoolData& tx : m_mempoolTxs) {
|
||||
m_transactionHashes.insert(m_transactionHashes.end(), tx.id.h, tx.id.h + HASH_SIZE);
|
||||
++m_numTransactionHashes;
|
||||
shuffle_tx_order();
|
||||
|
||||
m_numTransactionHashes = m_mempoolTxsOrder.size();
|
||||
m_transactionHashes.assign(HASH_SIZE, 0);
|
||||
for (size_t i = 0; i < m_mempoolTxsOrder.size(); ++i) {
|
||||
const TxMempoolData& tx = m_mempoolTxs[m_mempoolTxsOrder[i]];
|
||||
m_transactionHashes.insert(m_transactionHashes.end(), tx.id.h, tx.id.h + HASH_SIZE);
|
||||
final_fees += tx.fee;
|
||||
final_weight += tx.weight;
|
||||
}
|
||||
|
@ -398,6 +412,8 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet
|
|||
final_fees = 0;
|
||||
final_weight = miner_tx_weight;
|
||||
|
||||
shuffle_tx_order();
|
||||
|
||||
m_numTransactionHashes = m_mempoolTxsOrder.size();
|
||||
m_transactionHashes.assign(HASH_SIZE, 0);
|
||||
for (size_t i = 0; i < m_mempoolTxsOrder.size(); ++i) {
|
||||
|
|
|
@ -106,6 +106,10 @@ private:
|
|||
std::vector<int> m_mempoolTxsOrder;
|
||||
std::vector<MinerShare> m_shares;
|
||||
|
||||
std::mt19937_64 m_rng;
|
||||
|
||||
void shuffle_tx_order();
|
||||
|
||||
#if TEST_MEMPOOL_PICKING_ALGORITHM
|
||||
void fill_optimal_knapsack(const MinerData& data, uint64_t base_reward, uint64_t miner_tx_weight, uint64_t& best_reward, uint64_t& final_fees, uint64_t& final_weight);
|
||||
|
||||
|
|
Loading…
Reference in a new issue