mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-22 19:39:22 +00:00
Removed redundant m_mainChainData
This commit is contained in:
parent
2daa7f9fea
commit
6a66615f37
10 changed files with 138 additions and 110 deletions
|
@ -165,7 +165,9 @@ BlockCache::~BlockCache()
|
||||||
|
|
||||||
void BlockCache::store(const PoolBlock& block)
|
void BlockCache::store(const PoolBlock& block)
|
||||||
{
|
{
|
||||||
const size_t n1 = block.m_mainChainData.size();
|
const std::vector<uint8_t> mainchain_data = block.serialize_mainchain_data();
|
||||||
|
|
||||||
|
const size_t n1 = mainchain_data.size();
|
||||||
const size_t n2 = block.m_sideChainData.size();
|
const size_t n2 = block.m_sideChainData.size();
|
||||||
|
|
||||||
if (!m_impl->m_data || (sizeof(uint32_t) + n1 + n2 > BLOCK_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<size_t>((m_storeIndex++) % NUM_BLOCKS) * BLOCK_SIZE);
|
uint8_t* data = m_impl->m_data + (static_cast<size_t>((m_storeIndex++) % NUM_BLOCKS) * BLOCK_SIZE);
|
||||||
|
|
||||||
*reinterpret_cast<uint32_t*>(data) = static_cast<uint32_t>(n1 + n2);
|
*reinterpret_cast<uint32_t*>(data) = static_cast<uint32_t>(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);
|
memcpy(data + sizeof(uint32_t) + n1, block.m_sideChainData.data(), n2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_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);
|
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 POOL_BLOCK_DEBUG
|
||||||
if (m_poolBlockTemplate->m_mainChainData != m_blockTemplateBlob) {
|
const std::vector<uint8_t> mainchain_data = m_poolBlockTemplate->serialize_mainchain_data();
|
||||||
|
|
||||||
|
if (mainchain_data != m_blockTemplateBlob) {
|
||||||
LOGERR(1, "serialize_mainchain_data() has a bug, fix it! ");
|
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());
|
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) {
|
for (size_t i = 0, n = std::min(mainchain_data.size(), m_blockTemplateBlob.size()); i < n; ++i) {
|
||||||
if (m_poolBlockTemplate->m_mainChainData[i] != m_blockTemplateBlob[i]) {
|
if (mainchain_data[i] != m_blockTemplateBlob[i]) {
|
||||||
LOGERR(1, "m_poolBlockTemplate->m_mainChainData is different at offset " << i);
|
LOGERR(1, "m_poolBlockTemplate->m_mainChainData is different at offset " << i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1067,14 +1067,16 @@ void BlockTemplate::submit_sidechain_block(uint32_t template_id, uint32_t nonce,
|
||||||
if (template_id == m_templateId) {
|
if (template_id == m_templateId) {
|
||||||
m_poolBlockTemplate->m_nonce = nonce;
|
m_poolBlockTemplate->m_nonce = nonce;
|
||||||
m_poolBlockTemplate->m_extraNonce = extra_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();
|
SideChain& side_chain = m_pool->side_chain();
|
||||||
|
|
||||||
#if POOL_BLOCK_DEBUG
|
#if POOL_BLOCK_DEBUG
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> buf = m_poolBlockTemplate->m_mainChainData;
|
std::vector<uint8_t> 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());
|
buf.insert(buf.end(), m_poolBlockTemplate->m_sideChainData.begin(), m_poolBlockTemplate->m_sideChainData.end());
|
||||||
|
|
||||||
PoolBlock check;
|
PoolBlock check;
|
||||||
|
|
|
@ -747,12 +747,15 @@ void P2PServer::broadcast(const PoolBlock& block)
|
||||||
|
|
||||||
Broadcast* data = new Broadcast();
|
Broadcast* data = new Broadcast();
|
||||||
|
|
||||||
data->blob.reserve(block.m_mainChainData.size() + block.m_sideChainData.size());
|
int outputs_offset, outputs_blob_size;
|
||||||
data->blob = block.m_mainChainData;
|
const std::vector<uint8_t> 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->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.reserve(mainchain_data.size() + block.m_sideChainData.size() + 16 - outputs_blob_size);
|
||||||
data->pruned_blob.assign(block.m_mainChainData.begin(), block.m_mainChainData.begin() + block.m_mainChainOutputsOffset);
|
data->pruned_blob.assign(mainchain_data.begin(), mainchain_data.begin() + outputs_offset);
|
||||||
|
|
||||||
// 0 outputs in the pruned blob
|
// 0 outputs in the pruned blob
|
||||||
data->pruned_blob.push_back(0);
|
data->pruned_blob.push_back(0);
|
||||||
|
@ -764,9 +767,9 @@ void P2PServer::broadcast(const PoolBlock& block)
|
||||||
});
|
});
|
||||||
|
|
||||||
writeVarint(total_reward, data->pruned_blob);
|
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->pruned_blob.insert(data->pruned_blob.end(), block.m_sideChainData.begin(), block.m_sideChainData.end());
|
||||||
|
|
||||||
data->ancestor_hashes.reserve(block.m_uncles.size() + 1);
|
data->ancestor_hashes.reserve(block.m_uncles.size() + 1);
|
||||||
|
|
|
@ -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<uint8_t>& blob)
|
void p2pool::submit_block_async(std::vector<uint8_t>&& blob)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
MutexLock lock(m_submitBlockDataLock);
|
MutexLock lock(m_submitBlockDataLock);
|
||||||
|
@ -448,7 +448,7 @@ void p2pool::submit_block_async(const std::vector<uint8_t>& blob)
|
||||||
m_submitBlockData.template_id = 0;
|
m_submitBlockData.template_id = 0;
|
||||||
m_submitBlockData.nonce = 0;
|
m_submitBlockData.nonce = 0;
|
||||||
m_submitBlockData.extra_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
|
// If p2pool is stopped, m_submitBlockAsync is most likely already closed
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
virtual void handle_chain_main(ChainMain& data, const char* extra) override;
|
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(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce);
|
||||||
void submit_block_async(const std::vector<uint8_t>& blob);
|
void submit_block_async(std::vector<uint8_t>&& blob);
|
||||||
void submit_sidechain_block(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce);
|
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);
|
void update_block_template_async(bool is_alternative_block = false);
|
||||||
|
|
|
@ -29,11 +29,7 @@ static constexpr char log_category_prefix[] = "PoolBlock ";
|
||||||
namespace p2pool {
|
namespace p2pool {
|
||||||
|
|
||||||
PoolBlock::PoolBlock()
|
PoolBlock::PoolBlock()
|
||||||
: m_mainChainHeaderSize(0)
|
: m_majorVersion(0)
|
||||||
, m_mainChainMinerTxSize(0)
|
|
||||||
, m_mainChainOutputsOffset(0)
|
|
||||||
, m_mainChainOutputsBlobSize(0)
|
|
||||||
, m_majorVersion(0)
|
|
||||||
, m_minorVersion(0)
|
, m_minorVersion(0)
|
||||||
, m_timestamp(0)
|
, m_timestamp(0)
|
||||||
, m_prevId{}
|
, m_prevId{}
|
||||||
|
@ -58,7 +54,6 @@ PoolBlock::PoolBlock()
|
||||||
{
|
{
|
||||||
uv_mutex_init_checked(&m_lock);
|
uv_mutex_init_checked(&m_lock);
|
||||||
|
|
||||||
m_mainChainData.reserve(48 * 1024);
|
|
||||||
m_outputs.reserve(2048);
|
m_outputs.reserve(2048);
|
||||||
m_transactions.reserve(256);
|
m_transactions.reserve(256);
|
||||||
m_sideChainData.reserve(512);
|
m_sideChainData.reserve(512);
|
||||||
|
@ -83,11 +78,10 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b)
|
||||||
LOGERR(1, "operator= uv_mutex_trylock failed. Fix the code!");
|
LOGERR(1, "operator= uv_mutex_trylock failed. Fix the code!");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mainChainData = b.m_mainChainData;
|
#if POOL_BLOCK_DEBUG
|
||||||
m_mainChainHeaderSize = b.m_mainChainHeaderSize;
|
m_mainChainDataDebug = b.m_mainChainDataDebug;
|
||||||
m_mainChainMinerTxSize = b.m_mainChainMinerTxSize;
|
#endif
|
||||||
m_mainChainOutputsOffset = b.m_mainChainOutputsOffset;
|
|
||||||
m_mainChainOutputsBlobSize = b.m_mainChainOutputsBlobSize;
|
|
||||||
m_majorVersion = b.m_majorVersion;
|
m_majorVersion = b.m_majorVersion;
|
||||||
m_minorVersion = b.m_minorVersion;
|
m_minorVersion = b.m_minorVersion;
|
||||||
m_timestamp = b.m_timestamp;
|
m_timestamp = b.m_timestamp;
|
||||||
|
@ -129,43 +123,56 @@ PoolBlock::~PoolBlock()
|
||||||
uv_mutex_destroy(&m_lock);
|
uv_mutex_destroy(&m_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PoolBlock::serialize_mainchain_data(uint32_t nonce, uint32_t extra_nonce, const hash& sidechain_hash)
|
std::vector<uint8_t> 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);
|
MutexLock lock(m_lock);
|
||||||
|
return serialize_mainchain_data_nolock(header_size, miner_tx_size, outputs_offset, outputs_blob_size);
|
||||||
|
}
|
||||||
|
|
||||||
m_mainChainData.clear();
|
std::vector<uint8_t> PoolBlock::serialize_mainchain_data_nolock(size_t* header_size, size_t* miner_tx_size, int* outputs_offset, int* outputs_blob_size) const
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
data.reserve(128 + m_outputs.size() * 39 + m_transactions.size() * HASH_SIZE);
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
m_mainChainData.push_back(m_majorVersion);
|
data.push_back(m_majorVersion);
|
||||||
m_mainChainData.push_back(m_minorVersion);
|
data.push_back(m_minorVersion);
|
||||||
writeVarint(m_timestamp, m_mainChainData);
|
writeVarint(m_timestamp, data);
|
||||||
m_mainChainData.insert(m_mainChainData.end(), m_prevId.h, m_prevId.h + HASH_SIZE);
|
data.insert(data.end(), m_prevId.h, m_prevId.h + HASH_SIZE);
|
||||||
m_mainChainData.insert(m_mainChainData.end(), reinterpret_cast<uint8_t*>(&nonce), reinterpret_cast<uint8_t*>(&nonce) + NONCE_SIZE);
|
data.insert(data.end(), reinterpret_cast<const uint8_t*>(&m_nonce), reinterpret_cast<const uint8_t*>(&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
|
// Miner tx
|
||||||
m_mainChainData.push_back(TX_VERSION);
|
data.push_back(TX_VERSION);
|
||||||
writeVarint(m_txinGenHeight + MINER_REWARD_UNLOCK_TIME, m_mainChainData);
|
writeVarint(m_txinGenHeight + MINER_REWARD_UNLOCK_TIME, data);
|
||||||
m_mainChainData.push_back(1);
|
data.push_back(1);
|
||||||
m_mainChainData.push_back(TXIN_GEN);
|
data.push_back(TXIN_GEN);
|
||||||
writeVarint(m_txinGenHeight, m_mainChainData);
|
writeVarint(m_txinGenHeight, data);
|
||||||
|
|
||||||
m_mainChainOutputsOffset = static_cast<int>(m_mainChainData.size());
|
const int outputs_offset0 = static_cast<int>(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) {
|
for (const TxOutput& output : m_outputs) {
|
||||||
writeVarint(output.m_reward, m_mainChainData);
|
writeVarint(output.m_reward, data);
|
||||||
m_mainChainData.push_back(output.m_txType);
|
data.push_back(output.m_txType);
|
||||||
m_mainChainData.insert(m_mainChainData.end(), output.m_ephPublicKey.h, output.m_ephPublicKey.h + HASH_SIZE);
|
data.insert(data.end(), output.m_ephPublicKey.h, output.m_ephPublicKey.h + HASH_SIZE);
|
||||||
|
|
||||||
if (output.m_txType == TXOUT_TO_TAGGED_KEY) {
|
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<int>(m_mainChainData.size()) - m_mainChainOutputsOffset;
|
if (outputs_blob_size) {
|
||||||
|
*outputs_blob_size = static_cast<int>(data.size()) - outputs_offset0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t tx_extra[128];
|
uint8_t tx_extra[128];
|
||||||
uint8_t* p = tx_extra;
|
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++) = TX_EXTRA_NONCE;
|
||||||
*(p++) = static_cast<uint8_t>(extra_nonce_size);
|
*(p++) = static_cast<uint8_t>(extra_nonce_size);
|
||||||
|
|
||||||
m_extraNonce = extra_nonce;
|
|
||||||
memcpy(p, &m_extraNonce, EXTRA_NONCE_SIZE);
|
memcpy(p, &m_extraNonce, EXTRA_NONCE_SIZE);
|
||||||
p += EXTRA_NONCE_SIZE;
|
p += EXTRA_NONCE_SIZE;
|
||||||
if (extra_nonce_size > 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++) = TX_EXTRA_MERGE_MINING_TAG;
|
||||||
*(p++) = HASH_SIZE;
|
*(p++) = HASH_SIZE;
|
||||||
memcpy(p, sidechain_hash.h, HASH_SIZE);
|
memcpy(p, m_sidechainId.h, HASH_SIZE);
|
||||||
p += HASH_SIZE;
|
p += HASH_SIZE;
|
||||||
|
|
||||||
writeVarint(static_cast<size_t>(p - tx_extra), m_mainChainData);
|
writeVarint(static_cast<size_t>(p - tx_extra), data);
|
||||||
m_mainChainData.insert(m_mainChainData.end(), tx_extra, p);
|
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);
|
writeVarint(m_transactions.size() - 1, data);
|
||||||
const uint8_t* data = reinterpret_cast<const uint8_t*>(m_transactions.data());
|
const uint8_t* t = reinterpret_cast<const uint8_t*>(m_transactions.data());
|
||||||
m_mainChainData.insert(m_mainChainData.end(), data + HASH_SIZE, data + m_transactions.size() * HASH_SIZE);
|
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()
|
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);
|
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<uint8_t> 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");
|
LOGERR(1, "tried to calculate PoW of uninitialized block");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
blob_size = m_mainChainHeaderSize;
|
blob_size = header_size;
|
||||||
memcpy(blob, m_mainChainData.data(), blob_size);
|
memcpy(blob, mainchain_data.data(), blob_size);
|
||||||
|
|
||||||
uint8_t* miner_tx = m_mainChainData.data() + m_mainChainHeaderSize;
|
const uint8_t* miner_tx = mainchain_data.data() + header_size;
|
||||||
keccak(miner_tx, static_cast<int>(m_mainChainMinerTxSize) - 1, reinterpret_cast<uint8_t*>(hashes), HASH_SIZE);
|
keccak(miner_tx, static_cast<int>(miner_tx_size) - 1, reinterpret_cast<uint8_t*>(hashes), HASH_SIZE);
|
||||||
|
|
||||||
count = m_transactions.size();
|
count = m_transactions.size();
|
||||||
uint8_t* h = reinterpret_cast<uint8_t*>(m_transactions.data());
|
uint8_t* h = reinterpret_cast<uint8_t*>(m_transactions.data());
|
||||||
|
|
|
@ -63,13 +63,11 @@ struct PoolBlock
|
||||||
|
|
||||||
mutable uv_mutex_t m_lock;
|
mutable uv_mutex_t m_lock;
|
||||||
|
|
||||||
// Monero block template
|
#if POOL_BLOCK_DEBUG
|
||||||
std::vector<uint8_t> m_mainChainData;
|
std::vector<uint8_t> m_mainChainDataDebug;
|
||||||
size_t m_mainChainHeaderSize;
|
#endif
|
||||||
size_t m_mainChainMinerTxSize;
|
|
||||||
int m_mainChainOutputsOffset;
|
|
||||||
int m_mainChainOutputsBlobSize;
|
|
||||||
|
|
||||||
|
// Monero block template
|
||||||
uint8_t m_majorVersion;
|
uint8_t m_majorVersion;
|
||||||
uint8_t m_minorVersion;
|
uint8_t m_minorVersion;
|
||||||
uint64_t m_timestamp;
|
uint64_t m_timestamp;
|
||||||
|
@ -134,7 +132,8 @@ struct PoolBlock
|
||||||
|
|
||||||
uint64_t m_localTimestamp;
|
uint64_t m_localTimestamp;
|
||||||
|
|
||||||
void serialize_mainchain_data(uint32_t nonce, uint32_t extra_nonce, const hash& sidechain_hash);
|
std::vector<uint8_t> 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<uint8_t> 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();
|
void serialize_sidechain_data();
|
||||||
|
|
||||||
int deserialize(const uint8_t* data, size_t size, const SideChain& sidechain, uv_loop_t* loop);
|
int deserialize(const uint8_t* data, size_t size, const SideChain& sidechain, uv_loop_t* loop);
|
||||||
|
|
|
@ -75,8 +75,6 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
|
||||||
const int nonce_offset = static_cast<int>(data - data_begin);
|
const int nonce_offset = static_cast<int>(data - data_begin);
|
||||||
READ_BUF(&m_nonce, NONCE_SIZE);
|
READ_BUF(&m_nonce, NONCE_SIZE);
|
||||||
|
|
||||||
m_mainChainHeaderSize = data - data_begin;
|
|
||||||
|
|
||||||
EXPECT_BYTE(TX_VERSION);
|
EXPECT_BYTE(TX_VERSION);
|
||||||
|
|
||||||
uint64_t unlock_height;
|
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__;
|
if (unlock_height != m_txinGenHeight + MINER_REWARD_UNLOCK_TIME) return __LINE__;
|
||||||
|
|
||||||
std::vector<uint8_t> outputs_blob;
|
std::vector<uint8_t> outputs_blob;
|
||||||
m_mainChainOutputsOffset = static_cast<int>(data - data_begin);
|
const int outputs_offset = static_cast<int>(data - data_begin);
|
||||||
|
|
||||||
uint64_t num_outputs;
|
uint64_t num_outputs;
|
||||||
READ_VARINT(num_outputs);
|
READ_VARINT(num_outputs);
|
||||||
|
|
||||||
uint64_t total_reward = 0;
|
uint64_t total_reward = 0;
|
||||||
|
int outputs_blob_size;
|
||||||
|
|
||||||
if (num_outputs > 0) {
|
if (num_outputs > 0) {
|
||||||
// Outputs are in the buffer, just read them
|
// 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<uint64_t>::max() / MIN_OUTPUT_SIZE) return __LINE__;
|
if (num_outputs > std::numeric_limits<uint64_t>::max() / MIN_OUTPUT_SIZE) return __LINE__;
|
||||||
if (static_cast<uint64_t>(data_end - data) < num_outputs * MIN_OUTPUT_SIZE) return __LINE__;
|
if (static_cast<uint64_t>(data_end - data) < num_outputs * MIN_OUTPUT_SIZE) return __LINE__;
|
||||||
|
|
||||||
m_outputs.clear();
|
m_outputs.resize(num_outputs);
|
||||||
m_outputs.reserve(num_outputs);
|
m_outputs.shrink_to_fit();
|
||||||
|
|
||||||
const uint8_t expected_tx_type = get_tx_type();
|
const uint8_t expected_tx_type = get_tx_type();
|
||||||
|
|
||||||
for (uint64_t i = 0; i < num_outputs; ++i) {
|
for (uint64_t i = 0; i < num_outputs; ++i) {
|
||||||
TxOutput t;
|
TxOutput& t = m_outputs[i];
|
||||||
|
|
||||||
READ_VARINT(t.m_reward);
|
READ_VARINT(t.m_reward);
|
||||||
total_reward += 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) {
|
if (expected_tx_type == TXOUT_TO_TAGGED_KEY) {
|
||||||
READ_BYTE(t.m_viewTag);
|
READ_BYTE(t.m_viewTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_outputs.emplace_back(std::move(t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mainChainOutputsBlobSize = static_cast<int>(data - data_begin) - m_mainChainOutputsOffset;
|
outputs_blob_size = static_cast<int>(data - data_begin) - outputs_offset;
|
||||||
outputs_blob.assign(data_begin + m_mainChainOutputsOffset, data);
|
outputs_blob.assign(data_begin + outputs_offset, data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Outputs are not in the buffer and must be calculated from sidechain data
|
// 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__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mainChainOutputsBlobSize = static_cast<int>(tmp);
|
outputs_blob_size = static_cast<int>(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Technically some p2pool node could keep stuffing block with transactions until reward is less than 0.6 XMR
|
// 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__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int outputs_actual_blob_size = static_cast<int>(data - data_begin) - m_mainChainOutputsOffset;
|
const int outputs_actual_blob_size = static_cast<int>(data - data_begin) - outputs_offset;
|
||||||
|
if (outputs_blob_size < outputs_actual_blob_size) {
|
||||||
if (m_mainChainOutputsBlobSize < outputs_actual_blob_size) {
|
|
||||||
return __LINE__;
|
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;
|
uint64_t tx_extra_size;
|
||||||
READ_VARINT(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);
|
EXPECT_BYTE(0);
|
||||||
|
|
||||||
m_mainChainMinerTxSize = (data - data_begin) + outputs_blob_size_diff - m_mainChainHeaderSize;
|
|
||||||
|
|
||||||
uint64_t num_transactions;
|
uint64_t num_transactions;
|
||||||
READ_VARINT(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_transactions.emplace_back(std::move(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mainChainData.reserve((data - data_begin) + outputs_blob_size_diff);
|
#if POOL_BLOCK_DEBUG
|
||||||
m_mainChainData.assign(data_begin, data_begin + m_mainChainOutputsOffset);
|
m_mainChainDataDebug.reserve((data - data_begin) + outputs_blob_size_diff);
|
||||||
m_mainChainData.insert(m_mainChainData.end(), m_mainChainOutputsBlobSize, 0);
|
m_mainChainDataDebug.assign(data_begin, data_begin + outputs_offset);
|
||||||
m_mainChainData.insert(m_mainChainData.end(), data_begin + m_mainChainOutputsOffset + outputs_actual_blob_size, data);
|
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;
|
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__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static_cast<int>(outputs_blob.size()) != m_mainChainOutputsBlobSize) {
|
if (static_cast<int>(outputs_blob.size()) != outputs_blob_size) {
|
||||||
return __LINE__;
|
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;
|
hash check;
|
||||||
const std::vector<uint8_t>& consensus_id = sidechain.consensus_id();
|
const std::vector<uint8_t>& consensus_id = sidechain.consensus_id();
|
||||||
keccak_custom(
|
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<uint32_t>(offset - nonce_offset);
|
uint32_t k = static_cast<uint32_t>(offset - nonce_offset);
|
||||||
if (k < NONCE_SIZE) {
|
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<int>((data_end - data_begin) + outputs_blob_size_diff);
|
const int data_size = static_cast<int>((data_end - data_begin) + outputs_blob_size_diff);
|
||||||
if (offset < data_size) {
|
if (offset < data_size) {
|
||||||
if (offset < m_mainChainOutputsOffset) {
|
if (offset < outputs_offset) {
|
||||||
return data_begin[offset];
|
return data_begin[offset];
|
||||||
}
|
}
|
||||||
else if (offset < m_mainChainOutputsOffset + m_mainChainOutputsBlobSize) {
|
else if (offset < outputs_offset + outputs_blob_size) {
|
||||||
const int tmp = offset - m_mainChainOutputsOffset;
|
const int tmp = offset - outputs_offset;
|
||||||
return outputs_blob[tmp];
|
return outputs_blob[tmp];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -527,7 +527,7 @@ bool SideChain::add_external_block(PoolBlock& block, std::vector<hash>& missing_
|
||||||
MinerData miner_data = m_pool->miner_data();
|
MinerData miner_data = m_pool->miner_data();
|
||||||
if ((block.m_prevId == miner_data.prev_id) && miner_data.difficulty.check_pow(pow_hash)) {
|
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");
|
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 {
|
else {
|
||||||
difficulty_type diff;
|
difficulty_type diff;
|
||||||
|
@ -536,7 +536,7 @@ bool SideChain::add_external_block(PoolBlock& block, std::vector<hash>& missing_
|
||||||
}
|
}
|
||||||
else if (diff.check_pow(pow_hash)) {
|
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");
|
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<uint8_t>& blob) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
blob.reserve(block->m_mainChainData.size() + block->m_sideChainData.size());
|
blob = block->serialize_mainchain_data();
|
||||||
|
|
||||||
blob = block->m_mainChainData;
|
|
||||||
blob.insert(blob.end(), block->m_sideChainData.begin(), block->m_sideChainData.end());
|
blob.insert(blob.end(), block->m_sideChainData.begin(), block->m_sideChainData.end());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,16 @@ TEST(pool_block, deserialize)
|
||||||
|
|
||||||
ASSERT_EQ(b.deserialize(buf.data(), buf.size(), sidechain, nullptr), 0);
|
ASSERT_EQ(b.deserialize(buf.data(), buf.size(), sidechain, nullptr), 0);
|
||||||
|
|
||||||
ASSERT_EQ(b.m_mainChainData.size(), 5607);
|
size_t header_size, miner_tx_size;
|
||||||
ASSERT_EQ(b.m_mainChainHeaderSize, 43);
|
int outputs_offset, outputs_blob_size;
|
||||||
ASSERT_EQ(b.m_mainChainMinerTxSize, 506);
|
const std::vector<uint8_t> mainchain_data = b.serialize_mainchain_data(&header_size, &miner_tx_size, &outputs_offset, &outputs_blob_size);
|
||||||
ASSERT_EQ(b.m_mainChainOutputsOffset, 54);
|
|
||||||
ASSERT_EQ(b.m_mainChainOutputsBlobSize, 420);
|
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_majorVersion, 14);
|
||||||
ASSERT_EQ(b.m_minorVersion, 14);
|
ASSERT_EQ(b.m_minorVersion, 14);
|
||||||
ASSERT_EQ(b.m_timestamp, 1630934403);
|
ASSERT_EQ(b.m_timestamp, 1630934403);
|
||||||
|
|
Loading…
Reference in a new issue