Store Merkle tree root in the merge mining tag

This commit is contained in:
SChernykh 2023-10-25 15:49:25 +02:00
parent 963514667d
commit 2d1158af64
4 changed files with 49 additions and 29 deletions

View file

@ -662,6 +662,11 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
m_poolBlockTemplate->m_extraNonce = 0; m_poolBlockTemplate->m_extraNonce = 0;
m_poolBlockTemplate->m_sidechainId = {}; m_poolBlockTemplate->m_sidechainId = {};
// TODO: fill in merkle tree data here
m_poolBlockTemplate->m_merkleTreeDataSize = 1;
m_poolBlockTemplate->m_merkleTreeData = 0;
m_poolBlockTemplate->m_merkleRoot = {};
const std::vector<uint8_t> sidechain_data = m_poolBlockTemplate->serialize_sidechain_data(); const std::vector<uint8_t> sidechain_data = m_poolBlockTemplate->serialize_sidechain_data();
const std::vector<uint8_t>& consensus_id = m_sidechain->consensus_id(); const std::vector<uint8_t>& consensus_id = m_sidechain->consensus_id();
@ -693,9 +698,13 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
m_poolBlockTemplate->m_sidechainId = calc_sidechain_hash(0); m_poolBlockTemplate->m_sidechainId = calc_sidechain_hash(0);
// TODO: fill in merkle tree data here
m_poolBlockTemplate->m_merkleTreeDataSize = 1;
m_poolBlockTemplate->m_merkleTreeData = 0;
m_poolBlockTemplate->m_merkleRoot = m_poolBlockTemplate->m_sidechainId;
if (pool_block_debug()) { if (pool_block_debug()) {
// TODO: fix it, it will change depending on mm_data varint size const size_t sidechain_hash_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize;
const size_t sidechain_hash_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 3;
memcpy(m_blockTemplateBlob.data() + sidechain_hash_offset, m_poolBlockTemplate->m_sidechainId.h, HASH_SIZE); memcpy(m_blockTemplateBlob.data() + sidechain_hash_offset, m_poolBlockTemplate->m_sidechainId.h, HASH_SIZE);
memcpy(m_fullDataBlob.data() + sidechain_hash_offset, m_poolBlockTemplate->m_sidechainId.h, HASH_SIZE); memcpy(m_fullDataBlob.data() + sidechain_hash_offset, m_poolBlockTemplate->m_sidechainId.h, HASH_SIZE);
@ -934,11 +943,9 @@ int BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Mine
m_poolBlockTemplate->m_extraNonceSize = corrected_extra_nonce_size; m_poolBlockTemplate->m_extraNonceSize = corrected_extra_nonce_size;
// Valid for tree size = 1 (no other merge mined chains)
// TODO: insert mm_data and merkle root here
m_minerTxExtra.push_back(TX_EXTRA_MERGE_MINING_TAG); m_minerTxExtra.push_back(TX_EXTRA_MERGE_MINING_TAG);
m_minerTxExtra.push_back(1 + HASH_SIZE); m_minerTxExtra.push_back(static_cast<uint8_t>(m_poolBlockTemplate->m_merkleTreeDataSize + HASH_SIZE));
m_minerTxExtra.push_back(0); writeVarint(m_poolBlockTemplate->m_merkleTreeData, m_minerTxExtra);
m_minerTxExtra.insert(m_minerTxExtra.end(), HASH_SIZE, 0); m_minerTxExtra.insert(m_minerTxExtra.end(), HASH_SIZE, 0);
// TX_EXTRA end // TX_EXTRA end
@ -1024,8 +1031,7 @@ hash BlockTemplate::calc_miner_tx_hash(uint32_t extra_nonce) const
// Calculate sidechain id with this extra_nonce // Calculate sidechain id with this extra_nonce
const hash sidechain_id = calc_sidechain_hash(extra_nonce); const hash sidechain_id = calc_sidechain_hash(extra_nonce);
// TODO: fix it, it will change depending on mm_data varint size const size_t sidechain_hash_offset = extra_nonce_offset + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize;
const size_t sidechain_hash_offset = extra_nonce_offset + m_poolBlockTemplate->m_extraNonceSize + 3;
// 1. Prefix (everything except vin_rct_type byte in the end) // 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 // Apply extra_nonce in-place because we can't write to the block template here
@ -1291,7 +1297,7 @@ std::vector<uint8_t> BlockTemplate::get_block_template_blob(uint32_t template_id
nonce_offset = m_nonceOffset; nonce_offset = m_nonceOffset;
extra_nonce_offset = m_extraNonceOffsetInTemplate; extra_nonce_offset = m_extraNonceOffsetInTemplate;
sidechain_id_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 3; sidechain_id_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize;
sidechain_id = calc_sidechain_hash(sidechain_extra_nonce); sidechain_id = calc_sidechain_hash(sidechain_extra_nonce);
return m_blockTemplateBlob; return m_blockTemplateBlob;
} }
@ -1306,6 +1312,11 @@ bool BlockTemplate::submit_sidechain_block(uint32_t template_id, uint32_t nonce,
m_poolBlockTemplate->m_sidechainId = calc_sidechain_hash(extra_nonce); m_poolBlockTemplate->m_sidechainId = calc_sidechain_hash(extra_nonce);
m_poolBlockTemplate->m_sidechainExtraBuf[3] = extra_nonce; m_poolBlockTemplate->m_sidechainExtraBuf[3] = extra_nonce;
// TODO: fill in merkle tree data here
m_poolBlockTemplate->m_merkleTreeDataSize = 1;
m_poolBlockTemplate->m_merkleTreeData = 0;
m_poolBlockTemplate->m_merkleRoot = m_poolBlockTemplate->m_sidechainId;
if (pool_block_debug()) { if (pool_block_debug()) {
std::vector<uint8_t> buf = m_poolBlockTemplate->serialize_mainchain_data(); std::vector<uint8_t> buf = m_poolBlockTemplate->serialize_mainchain_data();
const std::vector<uint8_t> sidechain_data = m_poolBlockTemplate->serialize_sidechain_data(); const std::vector<uint8_t> sidechain_data = m_poolBlockTemplate->serialize_sidechain_data();

View file

@ -39,6 +39,9 @@ PoolBlock::PoolBlock()
, m_txkeyPub{} , m_txkeyPub{}
, m_extraNonceSize(0) , m_extraNonceSize(0)
, m_extraNonce(0) , m_extraNonce(0)
, m_merkleTreeDataSize(1)
, m_merkleTreeData(0)
, m_merkleRoot{}
, m_txkeySecSeed{} , m_txkeySecSeed{}
, m_txkeySec{} , m_txkeySec{}
, m_parent{} , m_parent{}
@ -85,6 +88,9 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b)
m_txkeyPub = b.m_txkeyPub; m_txkeyPub = b.m_txkeyPub;
m_extraNonceSize = b.m_extraNonceSize; m_extraNonceSize = b.m_extraNonceSize;
m_extraNonce = b.m_extraNonce; m_extraNonce = b.m_extraNonce;
m_merkleTreeDataSize = b.m_merkleTreeDataSize;
m_merkleTreeData = b.m_merkleTreeData;
m_merkleRoot = b.m_merkleRoot;
m_transactions = b.m_transactions; m_transactions = b.m_transactions;
m_minerWallet = b.m_minerWallet; m_minerWallet = b.m_minerWallet;
m_txkeySecSeed = b.m_txkeySecSeed; m_txkeySecSeed = b.m_txkeySecSeed;
@ -187,12 +193,10 @@ std::vector<uint8_t> PoolBlock::serialize_mainchain_data(size_t* header_size, si
p += extra_nonce_size - EXTRA_NONCE_SIZE; p += extra_nonce_size - EXTRA_NONCE_SIZE;
} }
// Valid for tree size = 1 (no other merge mined chains)
// TODO: insert mm_data and merkle root here
*(p++) = TX_EXTRA_MERGE_MINING_TAG; *(p++) = TX_EXTRA_MERGE_MINING_TAG;
*(p++) = 1 + HASH_SIZE; *(p++) = static_cast<uint8_t>(m_merkleTreeDataSize + HASH_SIZE);
*(p++) = 0; writeVarint(m_merkleTreeData, [&p](const uint8_t b) { *(p++) = b; });
memcpy(p, m_sidechainId.h, HASH_SIZE); memcpy(p, m_merkleRoot.h, HASH_SIZE);
p += HASH_SIZE; p += HASH_SIZE;
writeVarint(static_cast<size_t>(p - tx_extra), data); writeVarint(static_cast<size_t>(p - tx_extra), data);

View file

@ -101,6 +101,10 @@ struct PoolBlock
uint64_t m_extraNonceSize; uint64_t m_extraNonceSize;
uint32_t m_extraNonce; uint32_t m_extraNonce;
uint32_t m_merkleTreeDataSize;
uint64_t m_merkleTreeData;
hash m_merkleRoot;
// All block transaction hashes including the miner transaction hash at index 0 // All block transaction hashes including the miner transaction hash at index 0
std::vector<hash> m_transactions; std::vector<hash> m_transactions;
@ -171,6 +175,14 @@ struct PoolBlock
} }
hash calculate_tx_key_seed() const; hash calculate_tx_key_seed() const;
FORCEINLINE void decode_merkle_tree_data(uint32_t& mm_n_aux_chains, uint32_t& mm_nonce) const
{
const uint32_t k = static_cast<uint32_t>(m_merkleTreeData);
const uint32_t n = 1U + (k & 7U);
mm_n_aux_chains = 1U + ((k >> 3U) & ((1U << n) - 1U));
mm_nonce = static_cast<uint32_t>(m_merkleTreeData >> (3U + n));
}
}; };
} // namespace p2pool } // namespace p2pool

View file

@ -188,26 +188,19 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
uint64_t mm_field_size; uint64_t mm_field_size;
READ_VARINT(mm_field_size); READ_VARINT(mm_field_size);
const int mm_field_begin = static_cast<int>(data - data_begin); const uint8_t* const mm_field_begin = data;
uint64_t mm_data; READ_VARINT(m_merkleTreeData);
READ_VARINT(mm_data);
if (mm_data > std::numeric_limits<uint32_t>::max()) { m_merkleTreeDataSize = static_cast<uint32_t>(data - mm_field_begin);
return __LINE__;
}
const uint32_t mm_n_bits = 1 + (mm_data & 7); uint32_t mm_n_aux_chains, mm_nonce;
const uint32_t mm_n_aux_chains = 1 + ((mm_data >> 3) & ((1 << mm_n_bits) - 1)); decode_merkle_tree_data(mm_n_aux_chains, mm_nonce);
const uint32_t mm_nonce = static_cast<uint32_t>(mm_data >> (3 + mm_n_bits));
const int mm_root_hash_offset = static_cast<int>((data - data_begin) + outputs_blob_size_diff); const int mm_root_hash_offset = static_cast<int>((data - data_begin) + outputs_blob_size_diff);
hash mm_root; READ_BUF(m_merkleRoot.h, HASH_SIZE);
READ_BUF(mm_root.h, HASH_SIZE);
const int mm_field_end = static_cast<int>(data - data_begin); if (static_cast<uint64_t>(data - mm_field_begin) != mm_field_size) {
if (static_cast<uint64_t>(mm_field_end - mm_field_begin) != mm_field_size) {
return __LINE__; return __LINE__;
} }
@ -432,7 +425,7 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
const uint32_t mm_aux_slot = get_aux_slot(sidechain.consensus_hash(), mm_nonce, mm_n_aux_chains); const uint32_t mm_aux_slot = get_aux_slot(sidechain.consensus_hash(), mm_nonce, mm_n_aux_chains);
if (!verify_merkle_proof(check, m_merkleProof, mm_aux_slot, mm_n_aux_chains, mm_root)) { if (!verify_merkle_proof(check, m_merkleProof, mm_aux_slot, mm_n_aux_chains, m_merkleRoot)) {
return __LINE__; return __LINE__;
} }