diff --git a/src/block_cache.cpp b/src/block_cache.cpp index a1bed33..7953103 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -165,7 +165,9 @@ BlockCache::~BlockCache() void BlockCache::store(const PoolBlock& block) { - const size_t n1 = block.m_mainChainData.size(); + const std::vector mainchain_data = block.serialize_mainchain_data(); + + const size_t n1 = mainchain_data.size(); const size_t n2 = block.m_sideChainData.size(); if (!m_impl->m_data || (sizeof(uint32_t) + n1 + n2 > BLOCK_SIZE)) { @@ -175,7 +177,7 @@ void BlockCache::store(const PoolBlock& block) uint8_t* data = m_impl->m_data + (static_cast((m_storeIndex++) % NUM_BLOCKS) * BLOCK_SIZE); *reinterpret_cast(data) = static_cast(n1 + n2); - memcpy(data + sizeof(uint32_t), block.m_mainChainData.data(), n1); + memcpy(data + sizeof(uint32_t), mainchain_data.data(), n1); memcpy(data + sizeof(uint32_t) + n1, block.m_sideChainData.data(), n2); } diff --git a/src/block_template.cpp b/src/block_template.cpp index 8e7b48d..64ab7a5 100644 --- a/src/block_template.cpp +++ b/src/block_template.cpp @@ -528,15 +528,15 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet memcpy(m_blockTemplateBlob.data() + sidechain_hash_offset, m_poolBlockTemplate->m_sidechainId.h, HASH_SIZE); memcpy(m_minerTx.data() + sidechain_hash_offset - m_minerTxOffsetInTemplate, m_poolBlockTemplate->m_sidechainId.h, HASH_SIZE); - m_poolBlockTemplate->serialize_mainchain_data(0, 0, m_poolBlockTemplate->m_sidechainId); - #if POOL_BLOCK_DEBUG - if (m_poolBlockTemplate->m_mainChainData != m_blockTemplateBlob) { + const std::vector mainchain_data = m_poolBlockTemplate->serialize_mainchain_data(); + + if (mainchain_data != m_blockTemplateBlob) { LOGERR(1, "serialize_mainchain_data() has a bug, fix it! "); - LOGERR(1, "m_poolBlockTemplate->m_mainChainData.size() = " << m_poolBlockTemplate->m_mainChainData.size()); + LOGERR(1, "m_poolBlockTemplate->m_mainChainData.size() = " << mainchain_data.size()); LOGERR(1, "m_blockTemplateBlob.size() = " << m_blockTemplateBlob.size()); - for (size_t i = 0, n = std::min(m_poolBlockTemplate->m_mainChainData.size(), m_blockTemplateBlob.size()); i < n; ++i) { - if (m_poolBlockTemplate->m_mainChainData[i] != m_blockTemplateBlob[i]) { + for (size_t i = 0, n = std::min(mainchain_data.size(), m_blockTemplateBlob.size()); i < n; ++i) { + if (mainchain_data[i] != m_blockTemplateBlob[i]) { LOGERR(1, "m_poolBlockTemplate->m_mainChainData is different at offset " << i); break; } @@ -1067,14 +1067,16 @@ void BlockTemplate::submit_sidechain_block(uint32_t template_id, uint32_t nonce, if (template_id == m_templateId) { m_poolBlockTemplate->m_nonce = nonce; m_poolBlockTemplate->m_extraNonce = extra_nonce; - memcpy(m_poolBlockTemplate->m_mainChainData.data() + m_nonceOffset, &nonce, NONCE_SIZE); - memcpy(m_poolBlockTemplate->m_mainChainData.data() + m_extraNonceOffsetInTemplate, &extra_nonce, EXTRA_NONCE_SIZE); SideChain& side_chain = m_pool->side_chain(); #if POOL_BLOCK_DEBUG { - std::vector buf = m_poolBlockTemplate->m_mainChainData; + std::vector buf = m_poolBlockTemplate->serialize_mainchain_data(); + + memcpy(buf.data() + m_nonceOffset, &nonce, NONCE_SIZE); + memcpy(buf.data() + m_extraNonceOffsetInTemplate, &extra_nonce, EXTRA_NONCE_SIZE); + buf.insert(buf.end(), m_poolBlockTemplate->m_sideChainData.begin(), m_poolBlockTemplate->m_sideChainData.end()); PoolBlock check; diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index 8323c54..8e538a1 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -747,12 +747,15 @@ void P2PServer::broadcast(const PoolBlock& block) Broadcast* data = new Broadcast(); - data->blob.reserve(block.m_mainChainData.size() + block.m_sideChainData.size()); - data->blob = block.m_mainChainData; + int outputs_offset, outputs_blob_size; + const std::vector mainchain_data = block.serialize_mainchain_data(nullptr, nullptr, &outputs_offset, &outputs_blob_size); + + data->blob.reserve(mainchain_data.size() + block.m_sideChainData.size()); + data->blob = mainchain_data; data->blob.insert(data->blob.end(), block.m_sideChainData.begin(), block.m_sideChainData.end()); - data->pruned_blob.reserve(block.m_mainChainData.size() + block.m_sideChainData.size() + 16 - block.m_mainChainOutputsBlobSize); - data->pruned_blob.assign(block.m_mainChainData.begin(), block.m_mainChainData.begin() + block.m_mainChainOutputsOffset); + data->pruned_blob.reserve(mainchain_data.size() + block.m_sideChainData.size() + 16 - outputs_blob_size); + data->pruned_blob.assign(mainchain_data.begin(), mainchain_data.begin() + outputs_offset); // 0 outputs in the pruned blob data->pruned_blob.push_back(0); @@ -764,9 +767,9 @@ void P2PServer::broadcast(const PoolBlock& block) }); writeVarint(total_reward, data->pruned_blob); - writeVarint(block.m_mainChainOutputsBlobSize, data->pruned_blob); + writeVarint(outputs_blob_size, data->pruned_blob); - data->pruned_blob.insert(data->pruned_blob.end(), block.m_mainChainData.begin() + block.m_mainChainOutputsOffset + block.m_mainChainOutputsBlobSize, block.m_mainChainData.end()); + data->pruned_blob.insert(data->pruned_blob.end(), mainchain_data.begin() + outputs_offset + outputs_blob_size, mainchain_data.end()); data->pruned_blob.insert(data->pruned_blob.end(), block.m_sideChainData.begin(), block.m_sideChainData.end()); data->ancestor_hashes.reserve(block.m_uncles.size() + 1); diff --git a/src/p2pool.cpp b/src/p2pool.cpp index daa9198..bd52d00 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -440,7 +440,7 @@ void p2pool::submit_block_async(uint32_t template_id, uint32_t nonce, uint32_t e } } -void p2pool::submit_block_async(const std::vector& blob) +void p2pool::submit_block_async(std::vector&& blob) { { MutexLock lock(m_submitBlockDataLock); @@ -448,7 +448,7 @@ void p2pool::submit_block_async(const std::vector& blob) m_submitBlockData.template_id = 0; m_submitBlockData.nonce = 0; m_submitBlockData.extra_nonce = 0; - m_submitBlockData.blob = blob; + m_submitBlockData.blob = std::move(blob); } // If p2pool is stopped, m_submitBlockAsync is most likely already closed diff --git a/src/p2pool.h b/src/p2pool.h index 3638271..1869ab7 100644 --- a/src/p2pool.h +++ b/src/p2pool.h @@ -74,7 +74,7 @@ public: virtual void handle_chain_main(ChainMain& data, const char* extra) override; void submit_block_async(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce); - void submit_block_async(const std::vector& blob); + void submit_block_async(std::vector&& blob); void submit_sidechain_block(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce); void update_block_template_async(bool is_alternative_block = false); diff --git a/src/pool_block.cpp b/src/pool_block.cpp index 15710d4..e9cb05a 100644 --- a/src/pool_block.cpp +++ b/src/pool_block.cpp @@ -29,11 +29,7 @@ static constexpr char log_category_prefix[] = "PoolBlock "; namespace p2pool { PoolBlock::PoolBlock() - : m_mainChainHeaderSize(0) - , m_mainChainMinerTxSize(0) - , m_mainChainOutputsOffset(0) - , m_mainChainOutputsBlobSize(0) - , m_majorVersion(0) + : m_majorVersion(0) , m_minorVersion(0) , m_timestamp(0) , m_prevId{} @@ -58,7 +54,6 @@ PoolBlock::PoolBlock() { uv_mutex_init_checked(&m_lock); - m_mainChainData.reserve(48 * 1024); m_outputs.reserve(2048); m_transactions.reserve(256); m_sideChainData.reserve(512); @@ -83,11 +78,10 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b) LOGERR(1, "operator= uv_mutex_trylock failed. Fix the code!"); } - m_mainChainData = b.m_mainChainData; - m_mainChainHeaderSize = b.m_mainChainHeaderSize; - m_mainChainMinerTxSize = b.m_mainChainMinerTxSize; - m_mainChainOutputsOffset = b.m_mainChainOutputsOffset; - m_mainChainOutputsBlobSize = b.m_mainChainOutputsBlobSize; +#if POOL_BLOCK_DEBUG + m_mainChainDataDebug = b.m_mainChainDataDebug; +#endif + m_majorVersion = b.m_majorVersion; m_minorVersion = b.m_minorVersion; m_timestamp = b.m_timestamp; @@ -129,43 +123,56 @@ PoolBlock::~PoolBlock() uv_mutex_destroy(&m_lock); } -void PoolBlock::serialize_mainchain_data(uint32_t nonce, uint32_t extra_nonce, const hash& sidechain_hash) +std::vector PoolBlock::serialize_mainchain_data(size_t* header_size, size_t* miner_tx_size, int* outputs_offset, int* outputs_blob_size) const { MutexLock lock(m_lock); + return serialize_mainchain_data_nolock(header_size, miner_tx_size, outputs_offset, outputs_blob_size); +} - m_mainChainData.clear(); +std::vector PoolBlock::serialize_mainchain_data_nolock(size_t* header_size, size_t* miner_tx_size, int* outputs_offset, int* outputs_blob_size) const +{ + std::vector data; + data.reserve(128 + m_outputs.size() * 39 + m_transactions.size() * HASH_SIZE); // Header - m_mainChainData.push_back(m_majorVersion); - m_mainChainData.push_back(m_minorVersion); - writeVarint(m_timestamp, m_mainChainData); - m_mainChainData.insert(m_mainChainData.end(), m_prevId.h, m_prevId.h + HASH_SIZE); - m_mainChainData.insert(m_mainChainData.end(), reinterpret_cast(&nonce), reinterpret_cast(&nonce) + NONCE_SIZE); + data.push_back(m_majorVersion); + data.push_back(m_minorVersion); + writeVarint(m_timestamp, data); + data.insert(data.end(), m_prevId.h, m_prevId.h + HASH_SIZE); + data.insert(data.end(), reinterpret_cast(&m_nonce), reinterpret_cast(&m_nonce) + NONCE_SIZE); - m_mainChainHeaderSize = m_mainChainData.size(); + const size_t header_size0 = data.size(); + if (header_size) { + *header_size = header_size0; + } // Miner tx - m_mainChainData.push_back(TX_VERSION); - writeVarint(m_txinGenHeight + MINER_REWARD_UNLOCK_TIME, m_mainChainData); - m_mainChainData.push_back(1); - m_mainChainData.push_back(TXIN_GEN); - writeVarint(m_txinGenHeight, m_mainChainData); + data.push_back(TX_VERSION); + writeVarint(m_txinGenHeight + MINER_REWARD_UNLOCK_TIME, data); + data.push_back(1); + data.push_back(TXIN_GEN); + writeVarint(m_txinGenHeight, data); - m_mainChainOutputsOffset = static_cast(m_mainChainData.size()); + const int outputs_offset0 = static_cast(data.size()); + if (outputs_offset) { + *outputs_offset = outputs_offset0; + } - writeVarint(m_outputs.size(), m_mainChainData); + writeVarint(m_outputs.size(), data); - for (TxOutput& output : m_outputs) { - writeVarint(output.m_reward, m_mainChainData); - m_mainChainData.push_back(output.m_txType); - m_mainChainData.insert(m_mainChainData.end(), output.m_ephPublicKey.h, output.m_ephPublicKey.h + HASH_SIZE); + for (const TxOutput& output : m_outputs) { + writeVarint(output.m_reward, data); + data.push_back(output.m_txType); + data.insert(data.end(), output.m_ephPublicKey.h, output.m_ephPublicKey.h + HASH_SIZE); if (output.m_txType == TXOUT_TO_TAGGED_KEY) { - m_mainChainData.push_back(output.m_viewTag); + data.push_back(output.m_viewTag); } } - m_mainChainOutputsBlobSize = static_cast(m_mainChainData.size()) - m_mainChainOutputsOffset; + if (outputs_blob_size) { + *outputs_blob_size = static_cast(data.size()) - outputs_offset0; + } uint8_t tx_extra[128]; uint8_t* p = tx_extra; @@ -183,7 +190,6 @@ void PoolBlock::serialize_mainchain_data(uint32_t nonce, uint32_t extra_nonce, c *(p++) = TX_EXTRA_NONCE; *(p++) = static_cast(extra_nonce_size); - m_extraNonce = extra_nonce; memcpy(p, &m_extraNonce, EXTRA_NONCE_SIZE); p += EXTRA_NONCE_SIZE; if (extra_nonce_size > EXTRA_NONCE_SIZE) { @@ -193,19 +199,30 @@ void PoolBlock::serialize_mainchain_data(uint32_t nonce, uint32_t extra_nonce, c *(p++) = TX_EXTRA_MERGE_MINING_TAG; *(p++) = HASH_SIZE; - memcpy(p, sidechain_hash.h, HASH_SIZE); + memcpy(p, m_sidechainId.h, HASH_SIZE); p += HASH_SIZE; - writeVarint(static_cast(p - tx_extra), m_mainChainData); - m_mainChainData.insert(m_mainChainData.end(), tx_extra, p); + writeVarint(static_cast(p - tx_extra), data); + data.insert(data.end(), tx_extra, p); - m_mainChainData.push_back(0); + data.push_back(0); - m_mainChainMinerTxSize = m_mainChainData.size() - m_mainChainHeaderSize; + if (miner_tx_size) { + *miner_tx_size = data.size() - header_size0; + } - writeVarint(m_transactions.size() - 1, m_mainChainData); - const uint8_t* data = reinterpret_cast(m_transactions.data()); - m_mainChainData.insert(m_mainChainData.end(), data + HASH_SIZE, data + m_transactions.size() * HASH_SIZE); + writeVarint(m_transactions.size() - 1, data); + const uint8_t* t = reinterpret_cast(m_transactions.data()); + data.insert(data.end(), t + HASH_SIZE, t + m_transactions.size() * HASH_SIZE); + +#if POOL_BLOCK_DEBUG + if (!m_mainChainDataDebug.empty() && (data != m_mainChainDataDebug)) { + LOGERR(1, "serialize_mainchain_data() has a bug, fix it!"); + panic(); + } +#endif + + return data; } void PoolBlock::serialize_sidechain_data() @@ -274,16 +291,19 @@ bool PoolBlock::get_pow_hash(RandomX_Hasher_Base* hasher, uint64_t height, const { MutexLock lock(m_lock); - if (!m_mainChainHeaderSize || !m_mainChainMinerTxSize || (m_mainChainData.size() < m_mainChainHeaderSize + m_mainChainMinerTxSize)) { + size_t header_size, miner_tx_size; + const std::vector mainchain_data = serialize_mainchain_data_nolock(&header_size, &miner_tx_size, nullptr, nullptr); + + if (!header_size || !miner_tx_size || (mainchain_data.size() < header_size + miner_tx_size)) { LOGERR(1, "tried to calculate PoW of uninitialized block"); return false; } - blob_size = m_mainChainHeaderSize; - memcpy(blob, m_mainChainData.data(), blob_size); + blob_size = header_size; + memcpy(blob, mainchain_data.data(), blob_size); - uint8_t* miner_tx = m_mainChainData.data() + m_mainChainHeaderSize; - keccak(miner_tx, static_cast(m_mainChainMinerTxSize) - 1, reinterpret_cast(hashes), HASH_SIZE); + const uint8_t* miner_tx = mainchain_data.data() + header_size; + keccak(miner_tx, static_cast(miner_tx_size) - 1, reinterpret_cast(hashes), HASH_SIZE); count = m_transactions.size(); uint8_t* h = reinterpret_cast(m_transactions.data()); diff --git a/src/pool_block.h b/src/pool_block.h index 8231d18..521b6bc 100644 --- a/src/pool_block.h +++ b/src/pool_block.h @@ -63,13 +63,11 @@ struct PoolBlock mutable uv_mutex_t m_lock; - // Monero block template - std::vector m_mainChainData; - size_t m_mainChainHeaderSize; - size_t m_mainChainMinerTxSize; - int m_mainChainOutputsOffset; - int m_mainChainOutputsBlobSize; +#if POOL_BLOCK_DEBUG + std::vector m_mainChainDataDebug; +#endif + // Monero block template uint8_t m_majorVersion; uint8_t m_minorVersion; uint64_t m_timestamp; @@ -134,7 +132,8 @@ struct PoolBlock uint64_t m_localTimestamp; - void serialize_mainchain_data(uint32_t nonce, uint32_t extra_nonce, const hash& sidechain_hash); + std::vector serialize_mainchain_data(size_t* header_size = nullptr, size_t* miner_tx_size = nullptr, int* outputs_offset = nullptr, int* outputs_blob_size = nullptr) const; + std::vector serialize_mainchain_data_nolock(size_t* header_size, size_t* miner_tx_size, int* outputs_offset, int* outputs_blob_size) const; void serialize_sidechain_data(); int deserialize(const uint8_t* data, size_t size, const SideChain& sidechain, uv_loop_t* loop); diff --git a/src/pool_block_parser.inl b/src/pool_block_parser.inl index 98f358a..9f92674 100644 --- a/src/pool_block_parser.inl +++ b/src/pool_block_parser.inl @@ -75,8 +75,6 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si const int nonce_offset = static_cast(data - data_begin); READ_BUF(&m_nonce, NONCE_SIZE); - m_mainChainHeaderSize = data - data_begin; - EXPECT_BYTE(TX_VERSION); uint64_t unlock_height; @@ -89,12 +87,13 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si if (unlock_height != m_txinGenHeight + MINER_REWARD_UNLOCK_TIME) return __LINE__; std::vector outputs_blob; - m_mainChainOutputsOffset = static_cast(data - data_begin); + const int outputs_offset = static_cast(data - data_begin); uint64_t num_outputs; READ_VARINT(num_outputs); uint64_t total_reward = 0; + int outputs_blob_size; if (num_outputs > 0) { // Outputs are in the buffer, just read them @@ -105,13 +104,13 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si if (num_outputs > std::numeric_limits::max() / MIN_OUTPUT_SIZE) return __LINE__; if (static_cast(data_end - data) < num_outputs * MIN_OUTPUT_SIZE) return __LINE__; - m_outputs.clear(); - m_outputs.reserve(num_outputs); + m_outputs.resize(num_outputs); + m_outputs.shrink_to_fit(); const uint8_t expected_tx_type = get_tx_type(); for (uint64_t i = 0; i < num_outputs; ++i) { - TxOutput t; + TxOutput& t = m_outputs[i]; READ_VARINT(t.m_reward); total_reward += t.m_reward; @@ -124,12 +123,10 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si if (expected_tx_type == TXOUT_TO_TAGGED_KEY) { READ_BYTE(t.m_viewTag); } - - m_outputs.emplace_back(std::move(t)); } - m_mainChainOutputsBlobSize = static_cast(data - data_begin) - m_mainChainOutputsOffset; - outputs_blob.assign(data_begin + m_mainChainOutputsOffset, data); + outputs_blob_size = static_cast(data - data_begin) - outputs_offset; + outputs_blob.assign(data_begin + outputs_offset, data); } else { // Outputs are not in the buffer and must be calculated from sidechain data @@ -144,7 +141,7 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si return __LINE__; } - m_mainChainOutputsBlobSize = static_cast(tmp); + outputs_blob_size = static_cast(tmp); } // Technically some p2pool node could keep stuffing block with transactions until reward is less than 0.6 XMR @@ -153,13 +150,12 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si return __LINE__; } - const int outputs_actual_blob_size = static_cast(data - data_begin) - m_mainChainOutputsOffset; - - if (m_mainChainOutputsBlobSize < outputs_actual_blob_size) { + const int outputs_actual_blob_size = static_cast(data - data_begin) - outputs_offset; + if (outputs_blob_size < outputs_actual_blob_size) { return __LINE__; } - const int outputs_blob_size_diff = m_mainChainOutputsBlobSize - outputs_actual_blob_size; + const int outputs_blob_size_diff = outputs_blob_size - outputs_actual_blob_size; uint64_t tx_extra_size; READ_VARINT(tx_extra_size); @@ -191,8 +187,6 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si EXPECT_BYTE(0); - m_mainChainMinerTxSize = (data - data_begin) + outputs_blob_size_diff - m_mainChainHeaderSize; - uint64_t num_transactions; READ_VARINT(num_transactions); @@ -208,10 +202,12 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si m_transactions.emplace_back(std::move(id)); } - m_mainChainData.reserve((data - data_begin) + outputs_blob_size_diff); - m_mainChainData.assign(data_begin, data_begin + m_mainChainOutputsOffset); - m_mainChainData.insert(m_mainChainData.end(), m_mainChainOutputsBlobSize, 0); - m_mainChainData.insert(m_mainChainData.end(), data_begin + m_mainChainOutputsOffset + outputs_actual_blob_size, data); +#if POOL_BLOCK_DEBUG + m_mainChainDataDebug.reserve((data - data_begin) + outputs_blob_size_diff); + m_mainChainDataDebug.assign(data_begin, data_begin + outputs_offset); + m_mainChainDataDebug.insert(m_mainChainDataDebug.end(), outputs_blob_size, 0); + m_mainChainDataDebug.insert(m_mainChainDataDebug.end(), data_begin + outputs_offset + outputs_actual_blob_size, data); +#endif const uint8_t* sidechain_data_begin = data; @@ -276,16 +272,18 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si return __LINE__; } - if (static_cast(outputs_blob.size()) != m_mainChainOutputsBlobSize) { + if (static_cast(outputs_blob.size()) != outputs_blob_size) { return __LINE__; } - memcpy(m_mainChainData.data() + m_mainChainOutputsOffset, outputs_blob.data(), m_mainChainOutputsBlobSize); +#if POOL_BLOCK_DEBUG + memcpy(m_mainChainDataDebug.data() + outputs_offset, outputs_blob.data(), outputs_blob_size); +#endif hash check; const std::vector& consensus_id = sidechain.consensus_id(); keccak_custom( - [this, nonce_offset, extra_nonce_offset, sidechain_hash_offset, data_begin, data_end, &consensus_id, &outputs_blob, outputs_blob_size_diff](int offset) -> uint8_t + [nonce_offset, extra_nonce_offset, sidechain_hash_offset, data_begin, data_end, &consensus_id, &outputs_blob, outputs_blob_size_diff, outputs_offset, outputs_blob_size](int offset) -> uint8_t { uint32_t k = static_cast(offset - nonce_offset); if (k < NONCE_SIZE) { @@ -304,11 +302,11 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si const int data_size = static_cast((data_end - data_begin) + outputs_blob_size_diff); if (offset < data_size) { - if (offset < m_mainChainOutputsOffset) { + if (offset < outputs_offset) { return data_begin[offset]; } - else if (offset < m_mainChainOutputsOffset + m_mainChainOutputsBlobSize) { - const int tmp = offset - m_mainChainOutputsOffset; + else if (offset < outputs_offset + outputs_blob_size) { + const int tmp = offset - outputs_offset; return outputs_blob[tmp]; } else { diff --git a/src/side_chain.cpp b/src/side_chain.cpp index f1e9994..f6f3b2b 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -527,7 +527,7 @@ bool SideChain::add_external_block(PoolBlock& block, std::vector& missing_ MinerData miner_data = m_pool->miner_data(); if ((block.m_prevId == miner_data.prev_id) && miner_data.difficulty.check_pow(pow_hash)) { LOGINFO(0, log::LightGreen() << "add_external_block: block " << block.m_sidechainId << " has enough PoW for Monero network, submitting it"); - m_pool->submit_block_async(block.m_mainChainData); + m_pool->submit_block_async(block.serialize_mainchain_data()); } else { difficulty_type diff; @@ -536,7 +536,7 @@ bool SideChain::add_external_block(PoolBlock& block, std::vector& missing_ } else if (diff.check_pow(pow_hash)) { LOGINFO(0, log::LightGreen() << "add_external_block: block " << block.m_sidechainId << " has enough PoW for Monero height " << block.m_txinGenHeight << ", submitting it"); - m_pool->submit_block_async(block.m_mainChainData); + m_pool->submit_block_async(block.serialize_mainchain_data()); } } @@ -675,10 +675,9 @@ bool SideChain::get_block_blob(const hash& id, std::vector& blob) const return false; } - blob.reserve(block->m_mainChainData.size() + block->m_sideChainData.size()); - - blob = block->m_mainChainData; + blob = block->serialize_mainchain_data(); blob.insert(blob.end(), block->m_sideChainData.begin(), block->m_sideChainData.end()); + return true; } diff --git a/tests/src/pool_block_tests.cpp b/tests/src/pool_block_tests.cpp index 4d644c0..d51b3db 100644 --- a/tests/src/pool_block_tests.cpp +++ b/tests/src/pool_block_tests.cpp @@ -51,11 +51,16 @@ TEST(pool_block, deserialize) ASSERT_EQ(b.deserialize(buf.data(), buf.size(), sidechain, nullptr), 0); - ASSERT_EQ(b.m_mainChainData.size(), 5607); - ASSERT_EQ(b.m_mainChainHeaderSize, 43); - ASSERT_EQ(b.m_mainChainMinerTxSize, 506); - ASSERT_EQ(b.m_mainChainOutputsOffset, 54); - ASSERT_EQ(b.m_mainChainOutputsBlobSize, 420); + size_t header_size, miner_tx_size; + int outputs_offset, outputs_blob_size; + const std::vector mainchain_data = b.serialize_mainchain_data(&header_size, &miner_tx_size, &outputs_offset, &outputs_blob_size); + + ASSERT_EQ(mainchain_data.size(), 5607); + ASSERT_EQ(header_size, 43); + ASSERT_EQ(miner_tx_size, 506); + ASSERT_EQ(outputs_offset, 54); + ASSERT_EQ(outputs_blob_size, 420); + ASSERT_EQ(b.m_majorVersion, 14); ASSERT_EQ(b.m_minorVersion, 14); ASSERT_EQ(b.m_timestamp, 1630934403);