diff --git a/src/pool_block.cpp b/src/pool_block.cpp index 18e3fa0..c481e23 100644 --- a/src/pool_block.cpp +++ b/src/pool_block.cpp @@ -224,7 +224,7 @@ std::vector PoolBlock::serialize_mainchain_data_nolock(size_t* header_s data.insert(data.end(), t + HASH_SIZE, t + m_transactions.size() * HASH_SIZE); #if POOL_BLOCK_DEBUG - if (!m_mainChainDataDebug.empty() && (data != m_mainChainDataDebug)) { + if (!nonce && !extra_nonce && !m_mainChainDataDebug.empty() && (data != m_mainChainDataDebug)) { LOGERR(1, "serialize_mainchain_data() has a bug, fix it!"); panic(); } diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 75d92c0..b3f247b 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -158,6 +158,8 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) m_consensusIdDisplayStr.assign(buf); LOGINFO(1, "consensus ID = " << log::LightCyan() << m_consensusIdDisplayStr.c_str()); + memcpy(m_consensusHash.h, m_consensusId.data(), HASH_SIZE); + uv_cond_init_checked(&m_precalcJobsCond); uv_mutex_init_checked(&m_precalcJobsMutex); m_precalcJobs.reserve(16); @@ -217,7 +219,7 @@ void SideChain::fill_sidechain_data(PoolBlock& block, std::vector& s block.m_cumulativeDifficulty = m_minDifficulty; if (sidechain_version > 1) { - block.m_txkeySecSeed = {}; + block.m_txkeySecSeed = m_consensusHash; get_tx_keys(block.m_txkeyPub, block.m_txkeySec, block.m_txkeySecSeed, block.m_prevId); } @@ -327,6 +329,10 @@ P2PServer* SideChain::p2pServer() const bool SideChain::get_shares(const PoolBlock* tip, std::vector& shares, bool quiet) const { + if (tip->m_txkeySecSeed.empty()) { + LOGERR(1, "tx key seed is not set, fix the code!"); + } + const int L = quiet ? 6 : 3; shares.clear(); @@ -353,7 +359,8 @@ bool SideChain::get_shares(const PoolBlock* tip, std::vector& shares // Dynamic PPLNS window starting from v2 // Limit PPLNS weight to 2x of the Monero difficulty (max 2 blocks per PPLNS window on average) - const difficulty_type max_pplns_weight = (tip->get_sidechain_version() > 1) ? (mainchain_diff * 2) : diff_max; + const int sidechain_version = tip->get_sidechain_version(); + const difficulty_type max_pplns_weight = (sidechain_version > 1) ? (mainchain_diff * 2) : diff_max; difficulty_type pplns_weight; do { @@ -436,8 +443,17 @@ bool SideChain::get_shares(const PoolBlock* tip, std::vector& shares } shares.resize(k + 1); - LOGINFO(6, "get_shares: " << k + 1 << " unique wallets in PPLNS window"); + + // Shuffle shares + if (sidechain_version > 1) { + std::mt19937_64 rng(*reinterpret_cast(tip->m_txkeySecSeed.h)); + + for (int64_t i = k; i > 0; --i) { + std::swap(shares[i], shares[rng() % (i + 1)]); + } + } + return true; } @@ -1350,7 +1366,7 @@ void SideChain::verify(PoolBlock* block) !block->m_uncles.empty() || (block->m_difficulty != m_minDifficulty) || (block->m_cumulativeDifficulty != m_minDifficulty) || - ((sidechain_version > 1) && !block->m_txkeySecSeed.empty())) + ((sidechain_version > 1) && (block->m_txkeySecSeed != m_consensusHash))) { block->m_invalid = true; } diff --git a/src/side_chain.h b/src/side_chain.h index 8b1741b..c8b84ab 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -149,6 +149,8 @@ private: std::atomic m_precalcFinished; + hash m_consensusHash; + void launch_precalc(const PoolBlock* block); void precalc_worker(); void finish_precalc(); diff --git a/tests/src/block_template_tests.cpp b/tests/src/block_template_tests.cpp index 37c5d93..405f0bb 100644 --- a/tests/src/block_template_tests.cpp +++ b/tests/src/block_template_tests.cpp @@ -60,7 +60,7 @@ TEST(block_template, update) tpl.update(data, mempool, &wallet); const PoolBlock* b = tpl.pool_block_template(); - ASSERT_EQ(b->m_sidechainId, H("3085dc0425d94fb2752e21e5d5a4fbad42105a189f9678cadabb69cf55a321ee")); + ASSERT_EQ(b->m_sidechainId, H("742f581765311fa069d3a90e3338fcffbc3d28de8598ee9fc968ebc092353246")); std::vector blobs; uint64_t height; @@ -79,7 +79,7 @@ TEST(block_template, update) hash blobs_hash; keccak(blobs.data(), static_cast(blobs.size()), blobs_hash.h); - ASSERT_EQ(blobs_hash, H("c1211e083d27ddb81eddb125af4f10b6df16efd418cf684f6d0e8e49a5ffaf3f")); + ASSERT_EQ(blobs_hash, H("082b9eb9d35e38cb3c8eb0fae6e03398ea865adba6103db25ed4a33c5face942")); // Test 2: mempool with high fee and low fee transactions, it must choose high fee transactions for (uint64_t i = 0; i < 512; ++i) { diff --git a/tests/src/pool_block_tests.cpp b/tests/src/pool_block_tests.cpp index cbe4378..ea3e468 100644 --- a/tests/src/pool_block_tests.cpp +++ b/tests/src/pool_block_tests.cpp @@ -27,6 +27,8 @@ namespace p2pool { TEST(pool_block, deserialize) { + init_crypto_cache(); + PoolBlock b; SideChain sidechain(nullptr, NetworkType::Mainnet, "mainnet test 2"); @@ -101,6 +103,8 @@ TEST(pool_block, deserialize) ASSERT_EQ(s.str(), "f76d731c61c9c9b6c3f46be2e60c9478930b49b4455feecd41ecb9420d000000"); ASSERT_EQ(b.m_difficulty.check_pow(pow_hash), true); + + destroy_crypto_cache(); } TEST(pool_block, verify)