Add hardfork for stake carrot integration (#55)

* Add hardfork for stake carrot integration

* Add hardfork for stake carrot integration

* fixed assertion failure

* Add hardfork for stake carrot integration

* Add hardfork for stake carrot integration

---------

Co-authored-by: Some Random Crypto Guy <somerandomcryptoguy@protonmail.com>
This commit is contained in:
auruya
2025-09-03 18:00:34 +03:00
committed by GitHub
parent 0c4998b091
commit 041cd03098
6 changed files with 89 additions and 24 deletions
+29 -13
View File
@@ -1404,6 +1404,11 @@ bool Blockchain::prevalidate_protocol_transaction(const block& b, uint64_t heigh
CHECK_AND_ASSERT_MES(b.protocol_tx.version > 1, false, "Invalid coinbase protocol transaction version");
if (hf_version >= HF_VERSION_CARROT) {
CHECK_AND_ASSERT_MES(b.protocol_tx.version == TRANSACTION_VERSION_CARROT || 2, false, "protocol transaction has wrong version");
CHECK_AND_ASSERT_MES(b.protocol_tx.type == cryptonote::transaction_type::PROTOCOL, false, "protocol transaction has wrong type");
}
if (hf_version >= HF_VERSION_ENFORCE_CARROT) {
CHECK_AND_ASSERT_MES(b.protocol_tx.version == TRANSACTION_VERSION_CARROT, false, "protocol transaction has wrong version");
CHECK_AND_ASSERT_MES(b.protocol_tx.type == cryptonote::transaction_type::PROTOCOL, false, "protocol transaction has wrong type");
}
@@ -1516,6 +1521,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
case HF_VERSION_AUDIT2:
case HF_VERSION_AUDIT2_PAUSE:
case HF_VERSION_CARROT:
case HF_VERSION_ENFORCE_CARROT:
if (b.miner_tx.amount_burnt > 0) {
CHECK_AND_ASSERT_MES(money_in_use + b.miner_tx.amount_burnt > money_in_use, false, "miner transaction is overflowed by amount_burnt");
money_in_use += b.miner_tx.amount_burnt;
@@ -1583,7 +1589,7 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
LOG_PRINT_L1("Block at height: " << height << " - no yield payouts due - skipping");
} else {
// Iterate over the cached data for block yield, calculating the yield payouts due
if (hf_version >= HF_VERSION_CARROT) {
if (get_ideal_hard_fork_version(matured_height) >= HF_VERSION_CARROT) {
if (!calculate_yield_payouts(matured_height, carrot_yield_payouts)) {
LOG_ERROR("Block at height: " << height << " - Failed to obtain carrot yield payout information - aborting");
return false;
@@ -1981,11 +1987,14 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
cryptonote::yield_block_info ybi_matured;
bool ok = get_ybi_entry(start_height, ybi_matured);
if (ok && ybi_matured.locked_coins_this_block > 0) {
// Work out what the asset_type should be based on height of submission
uint8_t hf_submitted = m_hardfork->get_ideal_version(start_height);
// Iterate over the cached data for block yield, calculating the yield payouts due
std::vector<std::pair<yield_tx_info, uint64_t>> yield_payouts;
std::vector<std::pair<yield_tx_info_carrot, uint64_t>> carrot_yield_payouts;
if (b.major_version >= HF_VERSION_CARROT) {
std::vector<std::pair<yield_tx_info_carrot, uint64_t>> carrot_yield_payouts;
if (hf_submitted >= HF_VERSION_CARROT) {
if (!calculate_yield_payouts(start_height, carrot_yield_payouts)) {
LOG_ERROR("Failed to obtain yield payout information - aborting");
return false;
@@ -1997,11 +2006,8 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
}
}
// Work out what the asset_type should be based on height of submission
uint8_t hf_submitted = m_hardfork->get_ideal_version(start_height);
// Create the protocol_metadata entries here
if (b.major_version >= HF_VERSION_CARROT) {
if (!carrot_yield_payouts.empty()) {
for (const auto& yield_entry: carrot_yield_payouts) {
cryptonote::protocol_data_entry entry;
entry.amount_burnt = yield_entry.second;
@@ -2020,6 +2026,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
entry.origin_height = start_height;
entry.return_view_tag = yield_entry.first.return_view_tag;
entry.return_anchor_enc = yield_entry.first.return_anchor_enc;
entry.is_carrot = true;
protocol_entries.push_back(entry);
}
} else {
@@ -2040,6 +2047,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
entry.P_change = yield_entry.first.P_change;
entry.return_pubkey = yield_entry.first.return_pubkey;
entry.origin_height = start_height;
entry.is_carrot = false;
protocol_entries.push_back(entry);
}
}
@@ -4715,7 +4723,7 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
if (!yield_entries.size()) {
// Report error and abort
LOG_ERROR("calculate_yield_payouts() called, but no yield TXs found at height " << start_height << " - aborting");
LOG_ERROR("calculate_yield_payouts() called for carrot, but no yield TXs found at height " << start_height << " - aborting");
return false;
}
@@ -4751,10 +4759,14 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
// Iterate over the yield_container, adding each proportion of the yield
for (auto& entry: yield_container) {
boost::multiprecision::int128_t locked_coins_128 = entry.first.locked_coins;
boost::multiprecision::int128_t yield_128 = (slippage_128 * locked_coins_128) / locked_total_128;
entry.second += yield_128.convert_to<uint64_t>();
uint64_t yield_u64 = boost::numeric_cast<uint64_t>(yield_128);
if (entry.second + yield_u64 < entry.second) {
throw std::overflow_error("uint64_t addition overflow");
}
entry.second += yield_u64;
}
}
@@ -4813,10 +4825,14 @@ bool Blockchain::calculate_yield_payouts(const uint64_t start_height, std::vecto
// Iterate over the yield_container, adding each proportion of the yield
for (auto& entry: yield_container) {
boost::multiprecision::int128_t locked_coins_128 = entry.first.locked_coins;
boost::multiprecision::int128_t yield_128 = (slippage_128 * locked_coins_128) / locked_total_128;
entry.second += yield_128.convert_to<uint64_t>();
uint64_t yield_u64 = boost::numeric_cast<uint64_t>(yield_128);
if (entry.second + yield_u64 < entry.second) {
throw std::overflow_error("uint64_t addition overflow");
}
entry.second += yield_u64;
}
}