Fixed miner tx creation

This commit is contained in:
SChernykh 2022-03-28 11:28:56 +02:00
parent 292e2580e5
commit a7aed2f221
4 changed files with 53 additions and 16 deletions

View file

@ -278,18 +278,21 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet
return;
}
const uint64_t max_reward_amounts_weight = std::accumulate(m_rewards.begin(), m_rewards.end(), 0ULL,
[](uint64_t a, uint64_t b)
{
writeVarint(b, [&a](uint8_t) { ++a; });
return a;
});
auto get_reward_amounts_weight = [this]() {
return std::accumulate(m_rewards.begin(), m_rewards.end(), 0ULL,
[](uint64_t a, uint64_t b)
{
writeVarint(b, [&a](uint8_t) { ++a; });
return a;
});
};
uint64_t max_reward_amounts_weight = get_reward_amounts_weight();
if (!create_miner_tx(data, m_shares, max_reward_amounts_weight, true)) {
if (create_miner_tx(data, m_shares, max_reward_amounts_weight, true) < 0) {
return;
}
const uint64_t miner_tx_weight = m_minerTx.size();
uint64_t miner_tx_weight = m_minerTx.size();
// Select transactions from the mempool
uint64_t final_reward, final_fees, final_weight;
@ -432,8 +435,37 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, Wallet
m_finalReward = final_reward;
if (!create_miner_tx(data, m_shares, max_reward_amounts_weight, false)) {
return;
const int create_miner_tx_result = create_miner_tx(data, m_shares, max_reward_amounts_weight, false);
if (create_miner_tx_result < 0) {
if (create_miner_tx_result == -3) {
// Too many extra bytes were added, refine max_reward_amounts_weight and miner_tx_weight
if (!SideChain::split_reward(base_reward + final_fees, m_shares, m_rewards)) {
return;
}
max_reward_amounts_weight = get_reward_amounts_weight();
if (create_miner_tx(data, m_shares, max_reward_amounts_weight, true) < 0) {
return;
}
final_weight -= miner_tx_weight;
final_weight += m_minerTx.size();
miner_tx_weight = m_minerTx.size();
final_reward = get_block_reward(base_reward, data.median_weight, final_fees, final_weight);
if (!SideChain::split_reward(final_reward, m_shares, m_rewards)) {
return;
}
if (create_miner_tx(data, m_shares, max_reward_amounts_weight, false) < 0) {
return;
}
}
else {
return;
}
}
if (m_minerTx.size() != miner_tx_weight) {
@ -600,7 +632,7 @@ void BlockTemplate::fill_optimal_knapsack(const MinerData& data, uint64_t base_r
}
#endif
bool BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<MinerShare>& shares, uint64_t max_reward_amounts_weight, bool dry_run)
int BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<MinerShare>& shares, uint64_t max_reward_amounts_weight, bool dry_run)
{
// Miner transaction (coinbase)
m_minerTx.clear();
@ -655,12 +687,12 @@ bool BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Min
if (dry_run) {
if (reward_amounts_weight != max_reward_amounts_weight) {
LOGERR(1, "create_miner_tx: incorrect miner rewards during the dry run (" << reward_amounts_weight << " != " << max_reward_amounts_weight << ")");
return false;
return -1;
}
}
else if (reward_amounts_weight > max_reward_amounts_weight) {
LOGERR(1, "create_miner_tx: incorrect miner rewards during the real run (" << reward_amounts_weight << " > " << max_reward_amounts_weight << ")");
return false;
return -2;
}
m_poolBlockTemplate->m_txkeyPub = m_txkeyPub;
@ -676,6 +708,10 @@ bool BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Min
const uint64_t corrected_extra_nonce_size = EXTRA_NONCE_SIZE + max_reward_amounts_weight - reward_amounts_weight;
if (corrected_extra_nonce_size > EXTRA_NONCE_SIZE) {
if (corrected_extra_nonce_size > EXTRA_NONCE_MAX_SIZE) {
LOGWARN(4, "create_miner_tx: corrected_extra_nonce_size (" << corrected_extra_nonce_size << ") is too large");
return -3;
}
LOGINFO(4, "increased EXTRA_NONCE from " << EXTRA_NONCE_SIZE << " to " << corrected_extra_nonce_size << " bytes to maintain miner tx weight");
}
writeVarint(corrected_extra_nonce_size, m_minerTxExtra);
@ -701,7 +737,7 @@ bool BlockTemplate::create_miner_tx(const MinerData& data, const std::vector<Min
// Not a part of transaction hash data
m_minerTx.push_back(0);
return true;
return 1;
}
hash BlockTemplate::calc_sidechain_hash() const

View file

@ -61,7 +61,7 @@ private:
p2pool* m_pool;
private:
bool create_miner_tx(const MinerData& data, const std::vector<MinerShare>& shares, uint64_t max_reward_amounts_weight, bool dry_run);
int create_miner_tx(const MinerData& data, const std::vector<MinerShare>& shares, uint64_t max_reward_amounts_weight, bool dry_run);
hash calc_sidechain_hash() const;
hash calc_miner_tx_hash(uint32_t extra_nonce) const;
void calc_merkle_tree_main_branch();

View file

@ -85,6 +85,7 @@ constexpr uint8_t HARDFORK_SUPPORTED_VERSION = 14;
constexpr uint8_t MINER_REWARD_UNLOCK_TIME = 60;
constexpr uint8_t NONCE_SIZE = 4;
constexpr uint8_t EXTRA_NONCE_SIZE = 4;
constexpr uint8_t EXTRA_NONCE_MAX_SIZE = EXTRA_NONCE_SIZE + 10;
constexpr uint8_t TX_VERSION = 2;
constexpr uint8_t TXIN_GEN = 0xFF;
constexpr uint8_t TXOUT_TO_KEY = 2;

View file

@ -187,7 +187,7 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, SideChain& sidechai
READ_VARINT(m_extraNonceSize);
// Sanity check
if ((m_extraNonceSize < EXTRA_NONCE_SIZE) || (m_extraNonceSize > EXTRA_NONCE_SIZE + 10)) return __LINE__;
if ((m_extraNonceSize < EXTRA_NONCE_SIZE) || (m_extraNonceSize > EXTRA_NONCE_MAX_SIZE)) return __LINE__;
const int extra_nonce_offset = static_cast<int>((data - data_begin) + outputs_blob_size_diff);
READ_BUF(&m_extraNonce, EXTRA_NONCE_SIZE);