mirror of
https://github.com/SChernykh/p2pool.git
synced 2025-01-03 09:19:24 +00:00
Added BlockTemplate tests
This commit is contained in:
parent
9283677a2b
commit
4bb1982806
6 changed files with 133 additions and 22 deletions
|
@ -39,8 +39,9 @@ static constexpr size_t MAX_BLOCK_TEMPLATE_SIZE = 128 * 1024 - (1 + sizeof(uint3
|
|||
|
||||
namespace p2pool {
|
||||
|
||||
BlockTemplate::BlockTemplate(p2pool* pool)
|
||||
: m_pool(pool)
|
||||
BlockTemplate::BlockTemplate(SideChain* sidechain, RandomX_Hasher_Base* hasher)
|
||||
: m_sidechain(sidechain)
|
||||
, m_hasher(hasher)
|
||||
, m_templateId(0)
|
||||
, m_lastUpdated(seconds_since_epoch())
|
||||
, m_blockHeaderSize(0)
|
||||
|
@ -75,7 +76,7 @@ BlockTemplate::BlockTemplate(p2pool* pool)
|
|||
m_mempoolTxs.reserve(1024);
|
||||
m_mempoolTxsOrder.reserve(1024);
|
||||
m_mempoolTxsOrder2.reserve(1024);
|
||||
m_shares.reserve(m_pool->side_chain().chain_window_size() * 2);
|
||||
m_shares.reserve(m_sidechain->chain_window_size() * 2);
|
||||
|
||||
for (size_t i = 0; i < array_size(&BlockTemplate::m_oldTemplates); ++i) {
|
||||
m_oldTemplates[i] = new BlockTemplate(*this);
|
||||
|
@ -113,7 +114,8 @@ BlockTemplate& BlockTemplate::operator=(const BlockTemplate& b)
|
|||
|
||||
WriteLock lock(m_lock);
|
||||
|
||||
m_pool = b.m_pool;
|
||||
m_sidechain = b.m_sidechain;
|
||||
m_hasher = b.m_hasher;
|
||||
m_templateId = b.m_templateId;
|
||||
m_lastUpdated = b.m_lastUpdated.load();
|
||||
m_blockTemplateBlob = b.m_blockTemplateBlob;
|
||||
|
@ -256,7 +258,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet
|
|||
|
||||
m_blockHeaderSize = m_blockHeader.size();
|
||||
|
||||
m_pool->side_chain().fill_sidechain_data(*m_poolBlockTemplate, miner_wallet, m_txkeySec, m_shares);
|
||||
m_sidechain->fill_sidechain_data(*m_poolBlockTemplate, miner_wallet, m_txkeySec, m_shares);
|
||||
|
||||
// Only choose transactions that were received 10 or more seconds ago
|
||||
size_t total_mempool_transactions;
|
||||
|
@ -596,7 +598,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet
|
|||
buf.insert(buf.end(), sidechain_data.begin(), sidechain_data.end());
|
||||
|
||||
PoolBlock check;
|
||||
const int result = check.deserialize(buf.data(), buf.size(), m_pool->side_chain(), nullptr, false);
|
||||
const int result = check.deserialize(buf.data(), buf.size(), *m_sidechain, nullptr, false);
|
||||
if (result != 0) {
|
||||
LOGERR(1, "pool block blob generation and/or parsing is broken, error " << result);
|
||||
}
|
||||
|
@ -626,6 +628,7 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet
|
|||
m_rewards.clear();
|
||||
m_mempoolTxs.clear();
|
||||
m_mempoolTxsOrder.clear();
|
||||
m_mempoolTxsOrder2.clear();
|
||||
}
|
||||
|
||||
#if TEST_MEMPOOL_PICKING_ALGORITHM
|
||||
|
@ -832,7 +835,7 @@ hash BlockTemplate::calc_sidechain_hash() const
|
|||
const int sidechain_hash_offset = static_cast<int>(m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize) + 2;
|
||||
const int blob_size = static_cast<int>(m_blockTemplateBlob.size());
|
||||
|
||||
const std::vector<uint8_t>& consensus_id = m_pool->side_chain().consensus_id();
|
||||
const std::vector<uint8_t>& consensus_id = m_sidechain->consensus_id();
|
||||
const std::vector<uint8_t> sidechain_data = m_poolBlockTemplate->serialize_sidechain_data();
|
||||
|
||||
keccak_custom([this, sidechain_hash_offset, blob_size, consensus_id, &sidechain_data](int offset) -> uint8_t {
|
||||
|
@ -1120,8 +1123,6 @@ void BlockTemplate::submit_sidechain_block(uint32_t template_id, uint32_t nonce,
|
|||
m_poolBlockTemplate->m_nonce = nonce;
|
||||
m_poolBlockTemplate->m_extraNonce = extra_nonce;
|
||||
|
||||
SideChain& side_chain = m_pool->side_chain();
|
||||
|
||||
#if POOL_BLOCK_DEBUG
|
||||
{
|
||||
std::vector<uint8_t> buf = m_poolBlockTemplate->serialize_mainchain_data();
|
||||
|
@ -1133,25 +1134,27 @@ void BlockTemplate::submit_sidechain_block(uint32_t template_id, uint32_t nonce,
|
|||
buf.insert(buf.end(), sidechain_data.begin(), sidechain_data.end());
|
||||
|
||||
PoolBlock check;
|
||||
const int result = check.deserialize(buf.data(), buf.size(), side_chain, nullptr, false);
|
||||
const int result = check.deserialize(buf.data(), buf.size(), *m_sidechain, nullptr, false);
|
||||
if (result != 0) {
|
||||
LOGERR(1, "pool block blob generation and/or parsing is broken, error " << result);
|
||||
}
|
||||
|
||||
if (m_hasher) {
|
||||
hash pow_hash;
|
||||
if (!check.get_pow_hash(m_pool->hasher(), check.m_txinGenHeight, m_seedHash, pow_hash)) {
|
||||
if (!check.get_pow_hash(m_hasher, check.m_txinGenHeight, m_seedHash, pow_hash)) {
|
||||
LOGERR(1, "PoW check failed for the sidechain block. Fix it! ");
|
||||
}
|
||||
else if (!check.m_difficulty.check_pow(pow_hash)) {
|
||||
LOGERR(1, "Sidechain block has wrong PoW. Fix it! ");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_poolBlockTemplate->m_verified = true;
|
||||
if (!side_chain.block_seen(*m_poolBlockTemplate)) {
|
||||
if (!m_sidechain->block_seen(*m_poolBlockTemplate)) {
|
||||
m_poolBlockTemplate->m_wantBroadcast = true;
|
||||
side_chain.add_block(*m_poolBlockTemplate);
|
||||
m_sidechain->add_block(*m_poolBlockTemplate);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
|
||||
namespace p2pool {
|
||||
|
||||
class p2pool;
|
||||
class SideChain;
|
||||
class RandomX_Hasher_Base;
|
||||
class Mempool;
|
||||
class Wallet;
|
||||
struct PoolBlock;
|
||||
|
@ -32,7 +33,7 @@ struct MinerShare;
|
|||
class BlockTemplate
|
||||
{
|
||||
public:
|
||||
explicit BlockTemplate(p2pool* pool);
|
||||
explicit BlockTemplate(SideChain* sidechain, RandomX_Hasher_Base* hasher);
|
||||
~BlockTemplate();
|
||||
|
||||
BlockTemplate(const BlockTemplate& b);
|
||||
|
@ -55,9 +56,11 @@ public:
|
|||
void submit_sidechain_block(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce);
|
||||
|
||||
FORCEINLINE const std::vector<MinerShare>& shares() const { return m_shares; }
|
||||
FORCEINLINE const PoolBlock* pool_block_template() const { return m_poolBlockTemplate; }
|
||||
|
||||
private:
|
||||
p2pool* m_pool;
|
||||
SideChain* m_sidechain;
|
||||
RandomX_Hasher_Base* m_hasher;
|
||||
|
||||
private:
|
||||
int create_miner_tx(const MinerData& data, const std::vector<MinerShare>& shares, uint64_t max_reward_amounts_weight, bool dry_run);
|
||||
|
|
|
@ -162,7 +162,7 @@ p2pool::p2pool(int argc, char* argv[])
|
|||
m_hasher = new RandomX_Hasher_RPC(this);
|
||||
#endif
|
||||
|
||||
m_blockTemplate = new BlockTemplate(this);
|
||||
m_blockTemplate = new BlockTemplate(m_sideChain, m_hasher);
|
||||
m_mempool = new Mempool();
|
||||
|
||||
try {
|
||||
|
|
|
@ -238,6 +238,9 @@ std::istream& operator>>(std::istream& s, hash& h)
|
|||
found_number = true;
|
||||
h.h[index >> 1] = (h.h[index >> 1] << 4) | digit;
|
||||
++index;
|
||||
if (index >= HASH_SIZE * 2) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
else if (found_number) {
|
||||
return s;
|
||||
|
|
|
@ -22,6 +22,7 @@ set(HEADERS
|
|||
)
|
||||
|
||||
set(SOURCES
|
||||
src/block_template_tests.cpp
|
||||
src/crypto_tests.cpp
|
||||
src/difficulty_type_tests.cpp
|
||||
src/hash_tests.cpp
|
||||
|
|
101
tests/src/block_template_tests.cpp
Normal file
101
tests/src/block_template_tests.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
|
||||
* Copyright (c) 2021 SChernykh <https://github.com/SChernykh>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "crypto.h"
|
||||
#include "block_template.h"
|
||||
#include "mempool.h"
|
||||
#include "side_chain.h"
|
||||
#include "wallet.h"
|
||||
#include "keccak.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
TEST(block_template, update)
|
||||
{
|
||||
init_crypto_cache();
|
||||
|
||||
SideChain sidechain(nullptr, NetworkType::Mainnet);
|
||||
BlockTemplate tpl(&sidechain, nullptr);
|
||||
|
||||
auto H = [](const char* s)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << s;
|
||||
hash result;
|
||||
ss >> result;
|
||||
return result;
|
||||
};
|
||||
|
||||
MinerData data;
|
||||
data.major_version = 16;
|
||||
data.height = 2762973;
|
||||
data.prev_id = H("81a0260b29d5224e88d04b11faff321fbdc11c4570779386b2a1817a86dc622c");
|
||||
data.seed_hash = H("33d0fb381466f04d6a1919ced3b698f54a28add3da5a6479b096c67df7a4974c");
|
||||
data.difficulty = { 300346053753ULL, 0 };
|
||||
data.median_weight = 300000;
|
||||
data.already_generated_coins = 18204981557254756780ULL;
|
||||
data.median_timestamp = (1ULL << 35) - 2;
|
||||
|
||||
Mempool mempool;
|
||||
Wallet wallet("44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg");
|
||||
|
||||
// Test 1: empty template
|
||||
tpl.update(data, mempool, &wallet);
|
||||
|
||||
const PoolBlock* b = tpl.pool_block_template();
|
||||
ASSERT_EQ(b->m_sidechainId, H("b708e3e456d97c43a7fcbd7b4e7aa29bdf45cd909bba07f915cb5f1d805433e6"));
|
||||
|
||||
std::vector<uint8_t> blobs;
|
||||
uint64_t height;
|
||||
difficulty_type diff, sidechain_diff;
|
||||
hash seed_hash;
|
||||
size_t nonce_offset;
|
||||
uint32_t template_id;
|
||||
tpl.get_hashing_blobs(0, 10000, blobs, height, diff, sidechain_diff, seed_hash, nonce_offset, template_id);
|
||||
|
||||
ASSERT_EQ(height, 2762973);
|
||||
ASSERT_EQ(diff, 300346053753ULL);
|
||||
ASSERT_EQ(sidechain_diff, sidechain.difficulty());
|
||||
ASSERT_EQ(seed_hash, data.seed_hash);
|
||||
ASSERT_EQ(nonce_offset, 39);
|
||||
ASSERT_EQ(template_id, 1);
|
||||
|
||||
hash blobs_hash;
|
||||
keccak(blobs.data(), static_cast<int>(blobs.size()), blobs_hash.h, HASH_SIZE);
|
||||
ASSERT_EQ(blobs_hash, H("e9154971a27c412175562d23ab458b0d3cf780a8bcecf62ff3f667fed9d3bc1d"));
|
||||
|
||||
// Test 2: mempool with high fee and low fee transactions, it must choose high fee transactions
|
||||
for (uint64_t i = 0; i < 512; ++i) {
|
||||
TxMempoolData tx;
|
||||
*reinterpret_cast<uint64_t*>(tx.id.h) = i;
|
||||
tx.fee = (i < 256) ? 30000000 : 60000000;
|
||||
tx.weight = 1500;
|
||||
mempool.add(tx);
|
||||
}
|
||||
|
||||
tpl.update(data, mempool, &wallet);
|
||||
|
||||
for (size_t i = 1; i < b->m_transactions.size(); ++i) {
|
||||
ASSERT_GE(*reinterpret_cast<const uint64_t*>(b->m_transactions[i].h), 256);
|
||||
}
|
||||
|
||||
destroy_crypto_cache();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue