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_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>& 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);
// 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()) {
// TODO: fix it, it will change depending on mm_data varint size
const size_t sidechain_hash_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 3;
const size_t sidechain_hash_offset = m_extraNonceOffsetInTemplate + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize;
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);
@ -934,11 +943,9 @@ int BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Mine
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(1 + HASH_SIZE);
m_minerTxExtra.push_back(0);
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
@ -1024,8 +1031,7 @@ hash BlockTemplate::calc_miner_tx_hash(uint32_t extra_nonce) const
// Calculate sidechain id with this 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 + 3;
const size_t sidechain_hash_offset = extra_nonce_offset + m_poolBlockTemplate->m_extraNonceSize + 2 + m_poolBlockTemplate->m_merkleTreeDataSize;
// 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
@ -1291,7 +1297,7 @@ std::vector<uint8_t> BlockTemplate::get_block_template_blob(uint32_t template_id
nonce_offset = m_nonceOffset;
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);
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_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()) {
std::vector<uint8_t> buf = m_poolBlockTemplate->serialize_mainchain_data();
const std::vector<uint8_t> sidechain_data = m_poolBlockTemplate->serialize_sidechain_data();

View file

@ -39,6 +39,9 @@ PoolBlock::PoolBlock()
, m_txkeyPub{}
, m_extraNonceSize(0)
, m_extraNonce(0)
, m_merkleTreeDataSize(1)
, m_merkleTreeData(0)
, m_merkleRoot{}
, m_txkeySecSeed{}
, m_txkeySec{}
, m_parent{}
@ -85,6 +88,9 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b)
m_txkeyPub = b.m_txkeyPub;
m_extraNonceSize = b.m_extraNonceSize;
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_minerWallet = b.m_minerWallet;
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;
}
// 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++) = 1 + HASH_SIZE;
*(p++) = 0;
memcpy(p, m_sidechainId.h, HASH_SIZE);
*(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);

View file

@ -101,6 +101,10 @@ struct PoolBlock
uint64_t m_extraNonceSize;
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
std::vector<hash> m_transactions;
@ -171,6 +175,14 @@ struct PoolBlock
}
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

View file

@ -188,26 +188,19 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
uint64_t 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(mm_data);
READ_VARINT(m_merkleTreeData);
if (mm_data > std::numeric_limits<uint32_t>::max()) {
return __LINE__;
}
m_merkleTreeDataSize = static_cast<uint32_t>(data - mm_field_begin);
const uint32_t mm_n_bits = 1 + (mm_data & 7);
const uint32_t mm_n_aux_chains = 1 + ((mm_data >> 3) & ((1 << mm_n_bits) - 1));
const uint32_t mm_nonce = static_cast<uint32_t>(mm_data >> (3 + mm_n_bits));
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);
hash mm_root;
READ_BUF(mm_root.h, HASH_SIZE);
READ_BUF(m_merkleRoot.h, HASH_SIZE);
const int mm_field_end = static_cast<int>(data - data_begin);
if (static_cast<uint64_t>(mm_field_end - mm_field_begin) != mm_field_size) {
if (static_cast<uint64_t>(data - mm_field_begin) != mm_field_size) {
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);
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__;
}