diff --git a/src/block_template.cpp b/src/block_template.cpp index bd46945..acf5afb 100644 --- a/src/block_template.cpp +++ b/src/block_template.cpp @@ -713,7 +713,7 @@ int BlockTemplate::create_miner_tx(const MinerData& data, const std::vectorm_outputs.emplace_back(m_rewards[i], eph_public_key, tx_type, view_tag); + m_poolBlockTemplate->m_outputs.emplace_back(m_rewards[i], eph_public_key, view_tag); } if (tx_type == TXOUT_TO_TAGGED_KEY) { diff --git a/src/crypto.cpp b/src/crypto.cpp index b061b7e..1b42c94 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -154,7 +154,7 @@ static FORCEINLINE void derivation_to_scalar(const hash& derivation, size_t outp hash_to_scalar(data, static_cast(p - data), res); } -class Cache +class Cache : public nocopy_nomove { public: Cache() diff --git a/src/pool_block.cpp b/src/pool_block.cpp index 2a4f854..6e2e5f2 100644 --- a/src/pool_block.cpp +++ b/src/pool_block.cpp @@ -53,10 +53,6 @@ PoolBlock::PoolBlock() , m_localTimestamp(seconds_since_epoch()) { uv_mutex_init_checked(&m_lock); - - m_outputs.reserve(2048); - m_transactions.reserve(256); - m_uncles.reserve(8); } PoolBlock::PoolBlock(const PoolBlock& b) @@ -159,13 +155,15 @@ std::vector PoolBlock::serialize_mainchain_data_nolock(size_t* header_s writeVarint(m_outputs.size(), data); + const uint8_t tx_type = get_tx_type(); + for (const TxOutput& output : m_outputs) { writeVarint(output.m_reward, data); - data.push_back(output.m_txType); + data.push_back(tx_type); data.insert(data.end(), output.m_ephPublicKey.h, output.m_ephPublicKey.h + HASH_SIZE); - if (output.m_txType == TXOUT_TO_TAGGED_KEY) { - data.push_back(output.m_viewTag); + if (tx_type == TXOUT_TO_TAGGED_KEY) { + data.push_back(static_cast(output.m_viewTag)); } } @@ -358,11 +356,13 @@ bool PoolBlock::get_pow_hash(RandomX_Hasher_Base* hasher, uint64_t height, const uint64_t PoolBlock::get_payout(const Wallet& w) const { + const uint8_t tx_type = get_tx_type(); + for (size_t i = 0, n = m_outputs.size(); i < n; ++i) { const TxOutput& out = m_outputs[i]; hash eph_public_key; - if (out.m_txType == TXOUT_TO_TAGGED_KEY) { + if (tx_type == TXOUT_TO_TAGGED_KEY) { if (w.get_eph_public_key_with_view_tag(m_txkeySec, i, eph_public_key, out.m_viewTag) && (eph_public_key == out.m_ephPublicKey)) { return out.m_reward; } diff --git a/src/pool_block.h b/src/pool_block.h index 8b06978..ba06155 100644 --- a/src/pool_block.h +++ b/src/pool_block.h @@ -80,15 +80,16 @@ struct PoolBlock struct TxOutput { - FORCEINLINE TxOutput() : m_reward(0), m_ephPublicKey(), m_txType(0), m_viewTag(0) {} - FORCEINLINE TxOutput(uint64_t r, const hash& k, uint8_t tx_type, uint8_t view_tag) : m_reward(r), m_ephPublicKey(k), m_txType(tx_type), m_viewTag(view_tag) {} + FORCEINLINE TxOutput() : m_ephPublicKey(), m_reward(0), m_viewTag(0) {} + FORCEINLINE TxOutput(uint64_t r, const hash& k, uint8_t view_tag) : m_ephPublicKey(k), m_reward(r), m_viewTag(view_tag) {} - uint64_t m_reward; hash m_ephPublicKey; - uint8_t m_txType; - uint8_t m_viewTag; + uint64_t m_reward : 56; + uint64_t m_viewTag : 8; }; + static_assert(sizeof(TxOutput) == sizeof(hash) + sizeof(uint64_t), "TxOutput bit packing didn't work with this compiler, fix the code!"); + std::vector m_outputs; hash m_txkeyPub; diff --git a/src/pool_block_parser.inl b/src/pool_block_parser.inl index f4aba67..3d21626 100644 --- a/src/pool_block_parser.inl +++ b/src/pool_block_parser.inl @@ -112,16 +112,19 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si for (uint64_t i = 0; i < num_outputs; ++i) { TxOutput& t = m_outputs[i]; - READ_VARINT(t.m_reward); - total_reward += t.m_reward; + uint64_t reward; + READ_VARINT(reward); + t.m_reward = reward; + total_reward += reward; EXPECT_BYTE(expected_tx_type); - t.m_txType = expected_tx_type; READ_BUF(t.m_ephPublicKey.h, HASH_SIZE); if (expected_tx_type == TXOUT_TO_TAGGED_KEY) { - READ_BYTE(t.m_viewTag); + uint8_t view_tag; + READ_BYTE(view_tag); + t.m_viewTag = view_tag; } } diff --git a/src/side_chain.cpp b/src/side_chain.cpp index e9220db..fb937a5 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -700,13 +700,15 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v blob.reserve(n * 39 + 64); writeVarint(n, blob); + const uint8_t tx_type = b->get_tx_type(); + for (const PoolBlock::TxOutput& output : b->m_outputs) { writeVarint(output.m_reward, blob); - blob.emplace_back(output.m_txType); + blob.emplace_back(tx_type); blob.insert(blob.end(), output.m_ephPublicKey.h, output.m_ephPublicKey.h + HASH_SIZE); - if (output.m_txType == TXOUT_TO_TAGGED_KEY) { - blob.emplace_back(output.m_viewTag); + if (tx_type == TXOUT_TO_TAGGED_KEY) { + blob.emplace_back(static_cast(output.m_viewTag)); } } @@ -812,9 +814,11 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v blob.emplace_back(view_tag); } - block->m_outputs.emplace_back(tmpRewards[i], eph_public_key, tx_type, view_tag); + block->m_outputs.emplace_back(tmpRewards[i], eph_public_key, view_tag); } + block->m_outputs.shrink_to_fit(); + if (loop) { // this will cause all helper jobs to finish immediately counter = -1; @@ -915,12 +919,13 @@ void SideChain::print_status(bool obtain_sidechain_lock) const } const Wallet& w = m_pool->params().m_wallet; + const uint8_t tx_type = tip->get_tx_type(); hash eph_public_key; for (size_t i = 0, n = tip->m_outputs.size(); i < n; ++i) { const PoolBlock::TxOutput& out = tip->m_outputs[i]; if (!your_reward) { - if (out.m_txType == TXOUT_TO_TAGGED_KEY) { + if (tx_type == TXOUT_TO_TAGGED_KEY) { if (w.get_eph_public_key_with_view_tag(tip->m_txkeySec, i, eph_public_key, out.m_viewTag) && (out.m_ephPublicKey == eph_public_key)) { your_reward = out.m_reward; } @@ -987,11 +992,12 @@ double SideChain::get_reward_share(const Wallet& w) const const PoolBlock* tip = m_chainTip; if (tip) { + const uint8_t tx_type = tip->get_tx_type(); hash eph_public_key; for (size_t i = 0, n = tip->m_outputs.size(); i < n; ++i) { const PoolBlock::TxOutput& out = tip->m_outputs[i]; if (!reward) { - if (out.m_txType == TXOUT_TO_TAGGED_KEY) { + if (tx_type == TXOUT_TO_TAGGED_KEY) { if (w.get_eph_public_key_with_view_tag(tip->m_txkeySec, i, eph_public_key, out.m_viewTag) && (out.m_ephPublicKey == eph_public_key)) { reward = out.m_reward; } @@ -1542,6 +1548,8 @@ void SideChain::verify(PoolBlock* block) return; } + const uint8_t tx_type = block->get_tx_type(); + for (size_t i = 0, n = rewards.size(); i < n; ++i) { const PoolBlock::TxOutput& out = block->m_outputs[i]; @@ -1565,7 +1573,7 @@ void SideChain::verify(PoolBlock* block) return; } - if ((out.m_txType == TXOUT_TO_TAGGED_KEY) && (out.m_viewTag != view_tag)) { + if ((tx_type == TXOUT_TO_TAGGED_KEY) && (out.m_viewTag != view_tag)) { LOGWARN(3, "block at height = " << block->m_sidechainHeight << ", id = " << block->m_sidechainId << ", mainchain height = " << block->m_txinGenHeight <<