Optimized TxOutput struct

pull/206/head
SChernykh 2022-10-04 20:48:19 +02:00
parent 45674ef554
commit 077837054b
6 changed files with 38 additions and 26 deletions

View File

@ -713,7 +713,7 @@ int BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Mine
LOGERR(1, "get_eph_public_key failed at index " << i); LOGERR(1, "get_eph_public_key failed at index " << i);
} }
m_minerTx.insert(m_minerTx.end(), eph_public_key.h, eph_public_key.h + HASH_SIZE); m_minerTx.insert(m_minerTx.end(), eph_public_key.h, eph_public_key.h + HASH_SIZE);
m_poolBlockTemplate->m_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) { if (tx_type == TXOUT_TO_TAGGED_KEY) {

View File

@ -154,7 +154,7 @@ static FORCEINLINE void derivation_to_scalar(const hash& derivation, size_t outp
hash_to_scalar(data, static_cast<int>(p - data), res); hash_to_scalar(data, static_cast<int>(p - data), res);
} }
class Cache class Cache : public nocopy_nomove
{ {
public: public:
Cache() Cache()

View File

@ -53,10 +53,6 @@ PoolBlock::PoolBlock()
, m_localTimestamp(seconds_since_epoch()) , m_localTimestamp(seconds_since_epoch())
{ {
uv_mutex_init_checked(&m_lock); uv_mutex_init_checked(&m_lock);
m_outputs.reserve(2048);
m_transactions.reserve(256);
m_uncles.reserve(8);
} }
PoolBlock::PoolBlock(const PoolBlock& b) PoolBlock::PoolBlock(const PoolBlock& b)
@ -159,13 +155,15 @@ std::vector<uint8_t> PoolBlock::serialize_mainchain_data_nolock(size_t* header_s
writeVarint(m_outputs.size(), data); writeVarint(m_outputs.size(), data);
const uint8_t tx_type = get_tx_type();
for (const TxOutput& output : m_outputs) { for (const TxOutput& output : m_outputs) {
writeVarint(output.m_reward, data); 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); data.insert(data.end(), output.m_ephPublicKey.h, output.m_ephPublicKey.h + HASH_SIZE);
if (output.m_txType == TXOUT_TO_TAGGED_KEY) { if (tx_type == TXOUT_TO_TAGGED_KEY) {
data.push_back(output.m_viewTag); data.push_back(static_cast<uint8_t>(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 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) { for (size_t i = 0, n = m_outputs.size(); i < n; ++i) {
const TxOutput& out = m_outputs[i]; const TxOutput& out = m_outputs[i];
hash eph_public_key; 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)) { 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; return out.m_reward;
} }

View File

@ -80,15 +80,16 @@ struct PoolBlock
struct TxOutput struct TxOutput
{ {
FORCEINLINE TxOutput() : m_reward(0), m_ephPublicKey(), m_txType(0), m_viewTag(0) {} FORCEINLINE TxOutput() : m_ephPublicKey(), m_reward(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(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; hash m_ephPublicKey;
uint8_t m_txType; uint64_t m_reward : 56;
uint8_t m_viewTag; 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<TxOutput> m_outputs; std::vector<TxOutput> m_outputs;
hash m_txkeyPub; hash m_txkeyPub;

View File

@ -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) { for (uint64_t i = 0; i < num_outputs; ++i) {
TxOutput& t = m_outputs[i]; TxOutput& t = m_outputs[i];
READ_VARINT(t.m_reward); uint64_t reward;
total_reward += t.m_reward; READ_VARINT(reward);
t.m_reward = reward;
total_reward += reward;
EXPECT_BYTE(expected_tx_type); EXPECT_BYTE(expected_tx_type);
t.m_txType = expected_tx_type;
READ_BUF(t.m_ephPublicKey.h, HASH_SIZE); READ_BUF(t.m_ephPublicKey.h, HASH_SIZE);
if (expected_tx_type == TXOUT_TO_TAGGED_KEY) { 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;
} }
} }

View File

@ -700,13 +700,15 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v
blob.reserve(n * 39 + 64); blob.reserve(n * 39 + 64);
writeVarint(n, blob); writeVarint(n, blob);
const uint8_t tx_type = b->get_tx_type();
for (const PoolBlock::TxOutput& output : b->m_outputs) { for (const PoolBlock::TxOutput& output : b->m_outputs) {
writeVarint(output.m_reward, blob); 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); blob.insert(blob.end(), output.m_ephPublicKey.h, output.m_ephPublicKey.h + HASH_SIZE);
if (output.m_txType == TXOUT_TO_TAGGED_KEY) { if (tx_type == TXOUT_TO_TAGGED_KEY) {
blob.emplace_back(output.m_viewTag); blob.emplace_back(static_cast<uint8_t>(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); 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) { if (loop) {
// this will cause all helper jobs to finish immediately // this will cause all helper jobs to finish immediately
counter = -1; counter = -1;
@ -915,12 +919,13 @@ void SideChain::print_status(bool obtain_sidechain_lock) const
} }
const Wallet& w = m_pool->params().m_wallet; const Wallet& w = m_pool->params().m_wallet;
const uint8_t tx_type = tip->get_tx_type();
hash eph_public_key; hash eph_public_key;
for (size_t i = 0, n = tip->m_outputs.size(); i < n; ++i) { for (size_t i = 0, n = tip->m_outputs.size(); i < n; ++i) {
const PoolBlock::TxOutput& out = tip->m_outputs[i]; const PoolBlock::TxOutput& out = tip->m_outputs[i];
if (!your_reward) { 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)) { 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; your_reward = out.m_reward;
} }
@ -987,11 +992,12 @@ double SideChain::get_reward_share(const Wallet& w) const
const PoolBlock* tip = m_chainTip; const PoolBlock* tip = m_chainTip;
if (tip) { if (tip) {
const uint8_t tx_type = tip->get_tx_type();
hash eph_public_key; hash eph_public_key;
for (size_t i = 0, n = tip->m_outputs.size(); i < n; ++i) { for (size_t i = 0, n = tip->m_outputs.size(); i < n; ++i) {
const PoolBlock::TxOutput& out = tip->m_outputs[i]; const PoolBlock::TxOutput& out = tip->m_outputs[i];
if (!reward) { 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)) { 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; reward = out.m_reward;
} }
@ -1542,6 +1548,8 @@ void SideChain::verify(PoolBlock* block)
return; return;
} }
const uint8_t tx_type = block->get_tx_type();
for (size_t i = 0, n = rewards.size(); i < n; ++i) { for (size_t i = 0, n = rewards.size(); i < n; ++i) {
const PoolBlock::TxOutput& out = block->m_outputs[i]; const PoolBlock::TxOutput& out = block->m_outputs[i];
@ -1565,7 +1573,7 @@ void SideChain::verify(PoolBlock* block)
return; 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 << LOGWARN(3, "block at height = " << block->m_sidechainHeight <<
", id = " << block->m_sidechainId << ", id = " << block->m_sidechainId <<
", mainchain height = " << block->m_txinGenHeight << ", mainchain height = " << block->m_txinGenHeight <<