mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-22 11:29:23 +00:00
Added hardfork code
This commit is contained in:
parent
21326c5103
commit
899a908409
8 changed files with 121 additions and 53 deletions
|
@ -411,9 +411,15 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
|
|||
};
|
||||
uint64_t max_reward_amounts_weight = get_reward_amounts_weight();
|
||||
|
||||
m_poolBlockTemplate->m_merkleTreeData = PoolBlock::encode_merkle_tree_data(static_cast<uint32_t>(data.aux_chains.size() + 1), data.aux_nonce);
|
||||
m_poolBlockTemplate->m_merkleTreeDataSize = 0;
|
||||
writeVarint(m_poolBlockTemplate->m_merkleTreeData, [this](uint8_t) { ++m_poolBlockTemplate->m_merkleTreeDataSize; });
|
||||
if (m_poolBlockTemplate->merge_mining_enabled()) {
|
||||
m_poolBlockTemplate->m_merkleTreeData = PoolBlock::encode_merkle_tree_data(static_cast<uint32_t>(data.aux_chains.size() + 1), data.aux_nonce);
|
||||
m_poolBlockTemplate->m_merkleTreeDataSize = 0;
|
||||
writeVarint(m_poolBlockTemplate->m_merkleTreeData, [this](uint8_t) { ++m_poolBlockTemplate->m_merkleTreeDataSize; });
|
||||
}
|
||||
else {
|
||||
m_poolBlockTemplate->m_merkleTreeData = 0;
|
||||
m_poolBlockTemplate->m_merkleTreeDataSize = 0;
|
||||
}
|
||||
|
||||
if (create_miner_tx(data, m_shares, max_reward_amounts_weight, true) < 0) {
|
||||
use_old_template();
|
||||
|
@ -705,7 +711,10 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
|
|||
}
|
||||
|
||||
if (pool_block_debug()) {
|
||||
const size_t merkle_root_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize;
|
||||
const size_t merkle_root_offset =
|
||||
m_poolBlockTemplate->merge_mining_enabled()
|
||||
? (m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize)
|
||||
: (m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2);
|
||||
|
||||
memcpy(m_blockTemplateBlob.data() + merkle_root_offset, m_poolBlockTemplate->m_merkleRoot.h, HASH_SIZE);
|
||||
memcpy(m_fullDataBlob.data() + merkle_root_offset, m_poolBlockTemplate->m_merkleRoot.h, HASH_SIZE);
|
||||
|
@ -945,9 +954,16 @@ int BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Mine
|
|||
m_poolBlockTemplate->m_extraNonceSize = corrected_extra_nonce_size;
|
||||
|
||||
m_minerTxExtra.push_back(TX_EXTRA_MERGE_MINING_TAG);
|
||||
m_minerTxExtra.push_back(static_cast<uint8_t>(m_poolBlockTemplate->m_merkleTreeDataSize + HASH_SIZE));
|
||||
writeVarint(m_poolBlockTemplate->m_merkleTreeData, m_minerTxExtra);
|
||||
m_minerTxExtra.insert(m_minerTxExtra.end(), HASH_SIZE, 0);
|
||||
|
||||
if (!m_poolBlockTemplate->merge_mining_enabled()) {
|
||||
m_minerTxExtra.push_back(HASH_SIZE);
|
||||
m_minerTxExtra.insert(m_minerTxExtra.end(), HASH_SIZE, 0);
|
||||
}
|
||||
else {
|
||||
m_minerTxExtra.push_back(static_cast<uint8_t>(m_poolBlockTemplate->m_merkleTreeDataSize + HASH_SIZE));
|
||||
writeVarint(m_poolBlockTemplate->m_merkleTreeData, m_minerTxExtra);
|
||||
m_minerTxExtra.insert(m_minerTxExtra.end(), HASH_SIZE, 0);
|
||||
}
|
||||
// TX_EXTRA end
|
||||
|
||||
writeVarint(m_minerTxExtra.size(), m_minerTx);
|
||||
|
@ -1037,7 +1053,10 @@ hash BlockTemplate::calc_miner_tx_hash(uint32_t extra_nonce) const
|
|||
const uint32_t aux_slot = get_aux_slot(m_sidechain->consensus_hash(), m_poolBlockTemplate->m_auxNonce, n_aux_chains);
|
||||
merge_mining_root = get_root_from_proof(sidechain_id, m_poolBlockTemplate->m_merkleProof, aux_slot, n_aux_chains);
|
||||
}
|
||||
const size_t merkle_root_offset = extra_nonce_offset + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize;
|
||||
|
||||
const size_t merkle_root_offset = m_poolBlockTemplate->merge_mining_enabled()
|
||||
? (extra_nonce_offset + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize)
|
||||
: (extra_nonce_offset + m_poolBlockTemplate->m_extraNonceSize + 2);
|
||||
|
||||
// 1. Prefix (everything except vin_rct_type byte in the end)
|
||||
// Apply extra_nonce in-place because we can't write to the block template here
|
||||
|
@ -1374,7 +1393,9 @@ std::vector<uint8_t> BlockTemplate::get_block_template_blob(uint32_t template_id
|
|||
const uint32_t aux_slot = get_aux_slot(m_sidechain->consensus_hash(), m_poolBlockTemplate->m_auxNonce, n_aux_chains);
|
||||
merge_mining_root = get_root_from_proof(sidechain_id, m_poolBlockTemplate->m_merkleProof, aux_slot, n_aux_chains);
|
||||
|
||||
merkle_root_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize;
|
||||
merkle_root_offset = m_poolBlockTemplate->merge_mining_enabled()
|
||||
? (m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize)
|
||||
: (m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2);
|
||||
|
||||
*pThis = this;
|
||||
|
||||
|
|
|
@ -804,7 +804,10 @@ void P2PServer::broadcast(const PoolBlock& block, const PoolBlock* parent)
|
|||
|
||||
writeVarint(total_reward, data->pruned_blob);
|
||||
writeVarint(outputs_blob_size, data->pruned_blob);
|
||||
data->pruned_blob.insert(data->pruned_blob.end(), block.m_sidechainId.h, block.m_sidechainId.h + HASH_SIZE);
|
||||
|
||||
if (block.merge_mining_enabled()) {
|
||||
data->pruned_blob.insert(data->pruned_blob.end(), block.m_sidechainId.h, block.m_sidechainId.h + HASH_SIZE);
|
||||
}
|
||||
|
||||
data->pruned_blob.insert(data->pruned_blob.end(), mainchain_data.begin() + outputs_offset + outputs_blob_size, mainchain_data.end());
|
||||
|
||||
|
|
|
@ -201,10 +201,18 @@ std::vector<uint8_t> PoolBlock::serialize_mainchain_data(size_t* header_size, si
|
|||
}
|
||||
|
||||
*(p++) = TX_EXTRA_MERGE_MINING_TAG;
|
||||
*(p++) = static_cast<uint8_t>(m_merkleTreeDataSize + HASH_SIZE);
|
||||
writeVarint(m_merkleTreeData, [&p](const uint8_t b) { *(p++) = b; });
|
||||
memcpy(p, m_merkleRoot.h, HASH_SIZE);
|
||||
p += HASH_SIZE;
|
||||
|
||||
if (!merge_mining_enabled()) {
|
||||
*(p++) = HASH_SIZE;
|
||||
memcpy(p, m_sidechainId.h, HASH_SIZE);
|
||||
p += HASH_SIZE;
|
||||
}
|
||||
else {
|
||||
*(p++) = static_cast<uint8_t>(m_merkleTreeDataSize + HASH_SIZE);
|
||||
writeVarint(m_merkleTreeData, [&p](const uint8_t b) { *(p++) = b; });
|
||||
memcpy(p, m_merkleRoot.h, HASH_SIZE);
|
||||
p += HASH_SIZE;
|
||||
}
|
||||
|
||||
writeVarint(static_cast<size_t>(p - tx_extra), data);
|
||||
data.insert(data.end(), tx_extra, p);
|
||||
|
@ -257,12 +265,14 @@ std::vector<uint8_t> PoolBlock::serialize_sidechain_data() const
|
|||
writeVarint(m_cumulativeDifficulty.lo, data);
|
||||
writeVarint(m_cumulativeDifficulty.hi, data);
|
||||
|
||||
const uint8_t n = static_cast<uint8_t>(m_merkleProof.size());
|
||||
data.push_back(n);
|
||||
if (merge_mining_enabled()) {
|
||||
const uint8_t n = static_cast<uint8_t>(m_merkleProof.size());
|
||||
data.push_back(n);
|
||||
|
||||
for (uint8_t i = 0; i < n; ++i) {
|
||||
const hash& h = m_merkleProof[i];
|
||||
data.insert(data.end(), h.h, h.h + HASH_SIZE);
|
||||
for (uint8_t i = 0; i < n; ++i) {
|
||||
const hash& h = m_merkleProof[i];
|
||||
data.insert(data.end(), h.h, h.h + HASH_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t* p = reinterpret_cast<const uint8_t*>(m_sidechainExtraBuf);
|
||||
|
@ -401,4 +411,13 @@ hash PoolBlock::calculate_tx_key_seed() const
|
|||
return result;
|
||||
}
|
||||
|
||||
bool PoolBlock::merge_mining_enabled() const
|
||||
{
|
||||
#ifdef P2POOL_UNIT_TESTS
|
||||
return false;
|
||||
#else
|
||||
return (SideChain::network_type() != NetworkType::Mainnet) || (m_timestamp >= MERGE_MINING_FORK_TIME);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace p2pool
|
||||
|
|
|
@ -60,6 +60,9 @@ static constexpr difficulty_type MAX_CUMULATIVE_DIFFICULTY{ 13019633956666736640
|
|||
// 1000 years at 1 block/second. It should be enough for any normal use.
|
||||
static constexpr uint64_t MAX_SIDECHAIN_HEIGHT = 31556952000ULL;
|
||||
|
||||
// Jul 01 2024 00:00:00 GMT+0000
|
||||
static constexpr uint64_t MERGE_MINING_FORK_TIME = 1719792000;
|
||||
|
||||
struct DifficultyData
|
||||
{
|
||||
FORCEINLINE DifficultyData(uint64_t t, const difficulty_type& d) : m_timestamp(t), m_cumulativeDifficulty(d) {}
|
||||
|
@ -203,6 +206,8 @@ struct PoolBlock
|
|||
mm_n_aux_chains = 1U + ((k >> 3U) & ((1U << n) - 1U));
|
||||
mm_nonce = static_cast<uint32_t>(m_merkleTreeData >> (3U + n));
|
||||
}
|
||||
|
||||
bool merge_mining_enabled() const;
|
||||
};
|
||||
|
||||
} // namespace p2pool
|
||||
|
|
|
@ -148,7 +148,9 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
|
|||
outputs_blob_size = static_cast<int>(tmp);
|
||||
|
||||
// Required by sidechain.get_outputs_blob() to speed up repeated broadcasts from different peers
|
||||
READ_BUF(m_sidechainId.h, HASH_SIZE);
|
||||
if (merge_mining_enabled()) {
|
||||
READ_BUF(m_sidechainId.h, HASH_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// Technically some p2pool node could keep stuffing block with transactions until reward is less than 0.6 XMR
|
||||
|
@ -186,23 +188,39 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
|
|||
|
||||
EXPECT_BYTE(TX_EXTRA_MERGE_MINING_TAG);
|
||||
|
||||
uint64_t mm_field_size;
|
||||
READ_VARINT(mm_field_size);
|
||||
|
||||
const uint8_t* const mm_field_begin = data;
|
||||
|
||||
READ_VARINT(m_merkleTreeData);
|
||||
|
||||
m_merkleTreeDataSize = static_cast<uint32_t>(data - mm_field_begin);
|
||||
|
||||
int mm_root_hash_offset;
|
||||
uint32_t mm_n_aux_chains, mm_nonce;
|
||||
decode_merkle_tree_data(mm_n_aux_chains, mm_nonce);
|
||||
|
||||
const int mm_root_hash_offset = static_cast<int>((data - data_begin) + outputs_blob_size_diff);
|
||||
READ_BUF(m_merkleRoot.h, HASH_SIZE);
|
||||
if (!merge_mining_enabled()) {
|
||||
EXPECT_BYTE(HASH_SIZE);
|
||||
|
||||
if (static_cast<uint64_t>(data - mm_field_begin) != mm_field_size) {
|
||||
return __LINE__;
|
||||
mm_root_hash_offset = static_cast<int>((data - data_begin) + outputs_blob_size_diff);
|
||||
READ_BUF(m_sidechainId.h, HASH_SIZE);
|
||||
|
||||
mm_n_aux_chains = 1;
|
||||
mm_nonce = 0;
|
||||
|
||||
m_merkleRoot = static_cast<root_hash&>(m_sidechainId);
|
||||
m_merkleTreeDataSize = 0;
|
||||
}
|
||||
else {
|
||||
uint64_t mm_field_size;
|
||||
READ_VARINT(mm_field_size);
|
||||
|
||||
const uint8_t* const mm_field_begin = data;
|
||||
|
||||
READ_VARINT(m_merkleTreeData);
|
||||
|
||||
m_merkleTreeDataSize = static_cast<uint32_t>(data - mm_field_begin);
|
||||
|
||||
decode_merkle_tree_data(mm_n_aux_chains, mm_nonce);
|
||||
|
||||
mm_root_hash_offset = static_cast<int>((data - data_begin) + outputs_blob_size_diff);
|
||||
READ_BUF(m_merkleRoot.h, HASH_SIZE);
|
||||
|
||||
if (static_cast<uint64_t>(data - mm_field_begin) != mm_field_size) {
|
||||
return __LINE__;
|
||||
}
|
||||
}
|
||||
|
||||
if (static_cast<uint64_t>(data - tx_extra_begin) != tx_extra_size) return __LINE__;
|
||||
|
@ -340,20 +358,23 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
|
|||
return __LINE__;
|
||||
}
|
||||
|
||||
uint8_t merkle_proof_size;
|
||||
READ_BYTE(merkle_proof_size);
|
||||
|
||||
if (merkle_proof_size > 7) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
m_merkleProof.clear();
|
||||
m_merkleProof.reserve(merkle_proof_size);
|
||||
|
||||
for (uint8_t i = 0; i < merkle_proof_size; ++i) {
|
||||
hash h;
|
||||
READ_BUF(h.h, HASH_SIZE);
|
||||
m_merkleProof.emplace_back(h);
|
||||
if (merge_mining_enabled()) {
|
||||
uint8_t merkle_proof_size;
|
||||
READ_BYTE(merkle_proof_size);
|
||||
|
||||
if (merkle_proof_size > 8) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
m_merkleProof.reserve(merkle_proof_size);
|
||||
|
||||
for (uint8_t i = 0; i < merkle_proof_size; ++i) {
|
||||
hash h;
|
||||
READ_BUF(h.h, HASH_SIZE);
|
||||
m_merkleProof.emplace_back(h);
|
||||
}
|
||||
}
|
||||
|
||||
READ_BUF(m_sidechainExtraBuf, sizeof(m_sidechainExtraBuf));
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
LOG_CATEGORY(SideChain)
|
||||
|
||||
static constexpr uint64_t MIN_DIFFICULTY = 1000;
|
||||
static constexpr uint64_t MIN_DIFFICULTY = 100000;
|
||||
static constexpr size_t UNCLE_BLOCK_DEPTH = 3;
|
||||
|
||||
static_assert(1 <= UNCLE_BLOCK_DEPTH && UNCLE_BLOCK_DEPTH <= 10, "Invalid UNCLE_BLOCK_DEPTH");
|
||||
|
@ -63,7 +63,7 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name)
|
|||
, m_poolName(pool_name ? pool_name : "default")
|
||||
, m_targetBlockTime(10)
|
||||
, m_minDifficulty(MIN_DIFFICULTY, 0)
|
||||
, m_chainWindowSize(216)
|
||||
, m_chainWindowSize(2160)
|
||||
, m_unclePenalty(20)
|
||||
, m_precalcFinished(false)
|
||||
#ifdef DEV_TEST_SYNC
|
||||
|
@ -103,8 +103,7 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name)
|
|||
// cppcheck-suppress uninitvar
|
||||
log::Stream s(buf);
|
||||
|
||||
s << "mm" << '\0'
|
||||
<< s_networkType << '\0'
|
||||
s << s_networkType << '\0'
|
||||
<< m_poolName << '\0'
|
||||
<< m_poolPassword << '\0'
|
||||
<< m_targetBlockTime << '\0'
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
namespace p2pool {
|
||||
|
||||
TEST(block_template, DISABLED_update)
|
||||
TEST(block_template, update)
|
||||
{
|
||||
init_crypto_cache();
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
namespace p2pool {
|
||||
|
||||
TEST(pool_block, DISABLED_deserialize)
|
||||
TEST(pool_block, deserialize)
|
||||
{
|
||||
init_crypto_cache();
|
||||
|
||||
|
@ -132,7 +132,7 @@ TEST(pool_block, DISABLED_deserialize)
|
|||
destroy_crypto_cache();
|
||||
}
|
||||
|
||||
TEST(pool_block, DISABLED_verify)
|
||||
TEST(pool_block, verify)
|
||||
{
|
||||
init_crypto_cache();
|
||||
|
||||
|
|
Loading…
Reference in a new issue