From 5757c67e17d28d40f13b17a45a90d12a7941a9e4 Mon Sep 17 00:00:00 2001 From: Some Random Crypto Guy Date: Fri, 17 Jan 2025 11:55:34 +0000 Subject: [PATCH] updated provisional HF for audit; fixed wallet default asset type pre-fork; fixed circ_supply management (hopefully) --- src/blockchain_db/lmdb/db_lmdb.cpp | 94 ++++++++++++++++++++++-------- src/hardforks/hardforks.cpp | 4 +- src/simplewallet/simplewallet.cpp | 6 +- 3 files changed, 77 insertions(+), 27 deletions(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 57dd04906..e290832ab 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -1290,7 +1290,7 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons MDB_val_copy source_idx(cryptonote::asset_id_from_type(miner_asset_type)); boost::multiprecision::int128_t source_tally = 0; result = read_circulating_supply_data(m_cur_circ_supply_tally, source_idx, source_tally); - if (result && /*(m_height>0 ||*/ result != MDB_NOTFOUND/*)*/) + if (result && result != MDB_NOTFOUND) throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when adding db transaction: ", result).c_str())); boost::multiprecision::int128_t final_source_tally = source_tally; for (const auto& out: tx.vout) { @@ -1304,12 +1304,15 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons } write_circulating_supply_data(m_cur_circ_supply_tally, source_idx, final_source_tally); LOG_PRINT_L1("tx ID " << tx_id << "\n\tTally before burn = " << source_tally.str() << "\n\tTally after burn = " << final_source_tally.str()); - + MDB_val_copy burn_idx(cryptonote::asset_id_from_type("BURN")); boost::multiprecision::int128_t burn_tally = 0; result = read_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, burn_tally); - if (result && /*(m_height>0 ||*/ result != MDB_NOTFOUND/*)*/) + if (result && result != MDB_NOTFOUND) throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when adding db transaction: ", result).c_str())); + // Sanity check - prevent overflow + if (burn_tally > burn_tally + tx.amount_burnt) + throw0(DB_ERROR("burn overflow detected when adding miner_tx for db transaction")); boost::multiprecision::int128_t final_burn_tally = burn_tally + tx.amount_burnt; write_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, final_burn_tally); } @@ -1323,6 +1326,9 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons boost::multiprecision::int128_t final_source_tally = source_tally - tx.amount_burnt - tx.rct_signatures.txnFee; if (result) throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when adding db transaction: ", result).c_str())); + // Sanity check - prevent underflow + if (source_tally < final_source_tally) + throw0(DB_ERROR("numeric underflow detected when processing C/B/S/A/T for db transaction")); write_circulating_supply_data(m_cur_circ_supply_tally, source_idx, final_source_tally); LOG_PRINT_L1("tx ID " << tx_id << "\n\tTally before burn = " << source_tally.str() << "\n\tTally after burn = " << final_source_tally.str()); @@ -1331,7 +1337,10 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons result = read_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, burn_tally); if (result && /*(m_height>0 ||*/ result != MDB_NOTFOUND/*)*/) throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when adding db transaction: ", result).c_str())); - boost::multiprecision::int128_t final_burn_tally = burn_tally + tx.amount_burnt; + boost::multiprecision::int128_t final_burn_tally = burn_tally + tx.amount_burnt + tx.rct_signatures.txnFee; + // Sanity check - prevent underflow + if (burn_tally > final_burn_tally) + throw0(DB_ERROR("burn overflow detected when adding tx for db transaction")); write_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, final_burn_tally); } @@ -1356,25 +1365,23 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons MDB_val_copy source_idx(asset.first); boost::multiprecision::int128_t source_tally = 0; result = read_circulating_supply_data(m_cur_circ_supply_tally, source_idx, source_tally); - if (result) + if (result == MDB_NOTFOUND) + throw0(DB_ERROR("minted asset not found")); + else if (result) throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when adding db transaction: ", result).c_str())); + if (source_tally > source_tally + asset.second) + throw0(DB_ERROR("add_transaction_data() - mint overflow")); boost::multiprecision::int128_t final_source_tally = source_tally + asset.second; - /* - boost::multiprecision::int128_t coinbase = get_block_already_generated_coins(m_height-1); - if (source_tally == 0 && result == MDB_NOTFOUND) { - if (tx.source_asset_type == "SAL") { - final_source_tally += coinbase; - } - } - */ write_circulating_supply_data(m_cur_circ_supply_tally, source_idx, final_source_tally); LOG_PRINT_L1("tx ID " << tx_id << "\n\tAsset Type = " << cryptonote::asset_type_from_id(asset.first) << "\n\tTally before burn =" << source_tally.str() << "\n\tTally after burn =" << final_source_tally.str()); MDB_val_copy burn_idx(cryptonote::asset_id_from_type("BURN")); boost::multiprecision::int128_t burn_tally = 0; result = read_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, burn_tally); - if (result && /*(m_height>0 ||*/ result != MDB_NOTFOUND/*)*/) + if (result && result != MDB_NOTFOUND) throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when adding db transaction: ", result).c_str())); + if (burn_tally < asset.second) + throw0(DB_ERROR("add_transaction_data() - burn underflow")); boost::multiprecision::int128_t final_burn_tally = burn_tally - asset.second; write_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, final_burn_tally); } @@ -1554,26 +1561,43 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const throw1(DB_ERROR(lmdb_error("Failed to add removal of prunable hash tx to db transaction: ", result).c_str())); } + const uint8_t hf_version = m_hardfork->get_ideal_version(m_height); if (tx.type == cryptonote::transaction_type::MINER) { // Update the circulating supply tally because of potentially burnt block_reward proportion - MDB_val_copy source_idx(cryptonote::asset_id_from_type("SAL")); + std::string miner_asset_type = "SAL"; + if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) { + miner_asset_type = "SAL1"; + } + + MDB_val_copy source_idx(cryptonote::asset_id_from_type(miner_asset_type)); boost::multiprecision::int128_t source_tally = 0; result = read_circulating_supply_data(m_cur_circ_supply_tally, source_idx, source_tally); - if (result && (m_height>0 || result != MDB_NOTFOUND)) + if (result && result != MDB_NOTFOUND) throw0(DB_ERROR(lmdb_error("remove_transaction_data() - Failed to get circulating supply tally when removing db transaction: ", result).c_str())); boost::multiprecision::int128_t final_source_tally = source_tally; for (const auto& out: tx.vout) { // Sanity check - prevent underflow if (final_source_tally < final_source_tally - out.amount) - throw0(DB_ERROR("remove_transaction_data() - numeric underflow detected when removing miner_tx for db transaction")); + throw0(DB_ERROR("numeric underflow detected when removing miner_tx for db transaction")); // Fetch the amount for this output final_source_tally -= out.amount; } write_circulating_supply_data(m_cur_circ_supply_tally, source_idx, final_source_tally); LOG_PRINT_L1("tx ID " << tip->data.tx_id << "\n\tTally before burn = " << source_tally.str() << "\n\tTally after burn = " << final_source_tally.str()); + + MDB_val_copy burn_idx(cryptonote::asset_id_from_type("BURN")); + boost::multiprecision::int128_t burn_tally = 0; + result = read_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, burn_tally); + if (result && result != MDB_NOTFOUND) + throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when adding db transaction: ", result).c_str())); + // Sanity check - prevent underflow + if (burn_tally < tx.amount_burnt) + throw0(DB_ERROR("burn underflow detected when removing miner_tx for db transaction")); + boost::multiprecision::int128_t final_burn_tally = burn_tally - tx.amount_burnt; + write_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, final_burn_tally); } if (tx.type == cryptonote::transaction_type::BURN || tx.type == cryptonote::transaction_type::CONVERT || tx.type == cryptonote::transaction_type::STAKE || tx.type == cryptonote::transaction_type::AUDIT || tx.type == cryptonote::transaction_type::TRANSFER) { @@ -1582,14 +1606,25 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const MDB_val_copy source_idx(cryptonote::asset_id_from_type(tx.source_asset_type)); boost::multiprecision::int128_t source_tally = 0; result = read_circulating_supply_data(m_cur_circ_supply_tally, source_idx, source_tally); - if (result == MDB_NOTFOUND) - throw0(DB_ERROR("remove_transaction_data() - minted asset not found")); - // Sanity check - prevent overflow - if (source_tally > source_tally + tx.amount_burnt + tx.rct_signatures.txnFee) - throw0(DB_ERROR("remove_transaction_data() - numeric overflow detected when processing C/B/S for db transaction")); boost::multiprecision::int128_t final_source_tally = source_tally + tx.amount_burnt + tx.rct_signatures.txnFee; + if (result) + throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when removing db transaction: ", result).c_str())); + // Sanity check - prevent overflow + if (source_tally > final_source_tally) + throw0(DB_ERROR("numeric overflow detected when processing C/B/S/A/T for db transaction")); write_circulating_supply_data(m_cur_circ_supply_tally, source_idx, final_source_tally); LOG_PRINT_L1("tx ID " << tip->data.tx_id << "\n\tTally before remint =" << source_tally.str() << "\n\tTally after remint =" << final_source_tally.str()); + + MDB_val_copy burn_idx(cryptonote::asset_id_from_type("BURN")); + boost::multiprecision::int128_t burn_tally = 0; + result = read_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, burn_tally); + if (result && /*(m_height>0 ||*/ result != MDB_NOTFOUND/*)*/) + throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when adding db transaction: ", result).c_str())); + boost::multiprecision::int128_t final_burn_tally = burn_tally - tx.amount_burnt - tx.rct_signatures.txnFee; + // Sanity check - prevent underflow + if (burn_tally < (tx.amount_burnt + tx.rct_signatures.txnFee)) + throw0(DB_ERROR("burn underflow detected when removing tx for db transaction")); + write_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, final_burn_tally); } if (tx.type == cryptonote::transaction_type::PROTOCOL) { @@ -1603,7 +1638,6 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const bool ok = cryptonote::get_output_asset_type(out, asset_type); if (!ok) throw0(DB_ERROR("failed to get output asset type (needed to update the circulating supply data for the PROTOCOL_TX)")); - minted_amounts[cryptonote::asset_id_from_type(asset_type)] += out.amount; } @@ -1615,12 +1649,24 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const boost::multiprecision::int128_t source_tally = 0; result = read_circulating_supply_data(m_cur_circ_supply_tally, source_idx, source_tally); if (result == MDB_NOTFOUND) - throw0(DB_ERROR("remove_transaction_data() - minted asset not found")); + throw0(DB_ERROR("minted asset not found")); + else if (result) + throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when removing db transaction: ", result).c_str())); if (source_tally < asset.second) throw0(DB_ERROR("remove_transaction_data() - mint underflow")); boost::multiprecision::int128_t final_source_tally = source_tally - asset.second; write_circulating_supply_data(m_cur_circ_supply_tally, source_idx, final_source_tally); LOG_PRINT_L1("tx ID " << tip->data.tx_id << "\n\tAsset Type = " << cryptonote::asset_type_from_id(asset.first) << "\n\tTally before undoing mint =" << source_tally.str() << "\n\tTally after undoing mint =" << final_source_tally.str()); + + MDB_val_copy burn_idx(cryptonote::asset_id_from_type("BURN")); + boost::multiprecision::int128_t burn_tally = 0; + result = read_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, burn_tally); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to get circulating supply tally when removing db transaction: ", result).c_str())); + if (burn_tally > burn_tally + asset.second) + throw0(DB_ERROR("remove_transaction_data() - burn overflow")); + boost::multiprecision::int128_t final_burn_tally = burn_tally + asset.second; + write_circulating_supply_data(m_cur_circ_supply_tally, burn_idx, final_burn_tally); } } remove_tx_outputs(tip->data.tx_id, tx); diff --git a/src/hardforks/hardforks.cpp b/src/hardforks/hardforks.cpp index ec4d1a7bb..207962471 100644 --- a/src/hardforks/hardforks.cpp +++ b/src/hardforks/hardforks.cpp @@ -47,8 +47,8 @@ const hardfork_t mainnet_hard_forks[] = { // version 5 starts from block 136100, which is on or around the 9th of January, 2025. Fork time finalised on 2025-01-08. No fork voting occurs for the v5 fork. { 5, 136100, 0, 1736265945 }, - // version 6 starts from block 141100, which is on or around the 16th of January, 2025. Fork time finalised on 2025-01-11. No fork voting occurs for the v6 fork. - //{ 6, 141100, 0, 1736592100 }, + // version 6 starts from block 146146, which is on or around the 23rd of January, 2025. Fork time finalised on 2025-01-17. No fork voting occurs for the v6 fork. + //{ 6, 146146, 0, 1736592100 }, }; const size_t num_mainnet_hard_forks = sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]); const uint64_t mainnet_hard_fork_version_1_till = ((uint64_t)-1); diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 0324e0847..620094fe9 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -7263,7 +7263,11 @@ bool simple_wallet::transfer(const std::vector &args_) } // Get the source asset type - std::string source_asset = "SAL1"; + std::string source_asset = "SAL"; + if (m_wallet->get_current_hard_fork() >= HF_VERSION_SALVIUM_ONE_PROOFS) { + // Default to "SAL1" post-HF + source_asset = "SAL1"; + } std::string strLastArg = local_args.back(); std::transform(strLastArg.begin(), strLastArg.end(), strLastArg.begin(), ::toupper); if (strLastArg == "SAL" or strLastArg == "SAL1") {