fixed #23 : If multiple inputs get sent on a single transaction, then return_payment will not return all those inputs

fixed #20 : Audit transaction is showing in yield_info, but says 0 yield
fixed #19 : if you send SAL1, while the tx is pending it shows in the sal balance
fixed #18 : yield_info display is showing the wrong unlock time (TESTNET)
fixed #17 : SAL appears to be accrued during audit
This commit is contained in:
Some Random Crypto Guy
2025-01-29 22:32:41 +00:00
parent a7c1ba652b
commit 0180051a8c
3 changed files with 62 additions and 31 deletions
+32 -17
View File
@@ -8105,9 +8105,8 @@ bool simple_wallet::return_payment(const std::vector<std::string> &args_)
}
}
// We found the one we were looking for - take a copy of the key_image, etc.
// We found the one(s) we were looking for - take a copy of the key_image, etc.
transfers_indices.push_back(idx);
break;
}
// Check we have a valid key_image
@@ -8132,21 +8131,32 @@ bool simple_wallet::return_payment(const std::vector<std::string> &args_)
fail_msg_writer() << tr("Multiple transactions are created, which is not supposed to happen");
return true;
}
if (ptx_vector[0].selected_transfers.size() != 1)
if (ptx_vector[0].selected_transfers.size() != transfers_indices.size())
{
fail_msg_writer() << tr("The transaction uses multiple or no inputs, which is not supposed to happen");
fail_msg_writer() << tr("The transaction uses incorrect number of inputs, which is not supposed to happen");
return true;
}
// give user total and fee, and prompt to confirm
uint64_t total_fee = ptx_vector[0].fee;
uint64_t total_sent = m_wallet->get_transfer_details(ptx_vector[0].selected_transfers.front()).amount();
uint64_t total_sent = 0;
std::string asset_type;
for (auto idx: ptx_vector[0].selected_transfers) {
const tools::wallet2::transfer_details &td = m_wallet->get_transfer_details(idx);
uint64_t sent = td.amount();
if (total_sent + sent < total_sent) {
fail_msg_writer() << tr("amount overflow detected");
return true;
}
total_sent += sent;
asset_type = td.asset_type;
}
std::ostringstream prompt;
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
return true;
prompt << boost::format(tr("Returning %s for a total fee of %s. Is this okay?")) %
print_money(total_sent) %
print_money(total_fee);
prompt << boost::format(tr("Returning %s %s for a total fee of %s %s. Is this okay?")) %
print_money(total_sent) % asset_type %
print_money(total_fee) % asset_type;
std::string accepted = input_line(prompt.str(), true);
if (std::cin.eof())
return true;
@@ -8488,7 +8498,7 @@ bool simple_wallet::yield_info(const std::vector<std::string> &args) {
// EXPERIMENTAL - change to get_yield_summary_info() method
uint64_t t_burnt, t_supply, t_locked, t_yield, yps, ybi_size;
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> yield_payouts;
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> yield_payouts;
if (!m_wallet->get_yield_summary_info(t_burnt, t_supply, t_locked, t_yield, yps, ybi_size, yield_payouts)) {
fail_msg_writer() << "failed to get yield info. Make sure you are connected to a daemon.";
return false;
@@ -8501,25 +8511,30 @@ bool simple_wallet::yield_info(const std::vector<std::string> &args) {
message_writer(console_color_default, false) << boost::format(tr("\nSTAKED FUNDS:"));
for (auto &p: yield_payouts) {
uint64_t height, burnt, yield;
std::string txid;
std::tie(height, txid, burnt, yield) = p;
std::string txid, asset_type;
std::tie(height, txid, asset_type, burnt, yield) = p;
epee::console_colors asset_type_color = (asset_type == "SAL") ? console_color_green : (asset_type == "SAL1") ? console_color_blue : console_color_green;
if (blockchain_height > ybi_size + height)
message_writer(console_color_green, true) << boost::format(tr("Height %d, txid %s, staked %s SAL, earned %s SAL"))
message_writer(asset_type_color, true) << boost::format(tr("Height %d, txid %s, staked %s %s, earned %s %s"))
% height
% txid
% print_money(burnt)
% print_money(yield);
% asset_type
% print_money(yield)
% asset_type;
else
message_writer(console_color_green, false) << boost::format(tr("Height %d (matures %d), txid %s, staked %s SAL, %s SAL accrued so far"))
message_writer(asset_type_color, false) << boost::format(tr("Height %d (matures %d), txid %s, staked %s %s, %s %s accrued so far"))
% height
% (height + stake_lock_period)
% txid
% print_money(burnt)
% print_money(yield);
}
% asset_type
% print_money(yield)
% asset_type;
}
// Output the necessary information about yield stats
message_writer(console_color_default, false) << boost::format(tr("\nYIELD INFO:\n\tSupply coins burnt over last %s: %d\n\tTotal coins locked: %d\n\tYield accrued over last %s: %d\n\tYield per SAL staked: %d"))
message_writer(console_color_default, false) << boost::format(tr("\nYIELD INFO:\n\tSupply coins burnt over last %s: %d\n\tTotal coins locked: %d\n\tYield accrued over last %s: %d\n\tYield per coin staked: %d"))
% get_human_readable_timespan((ybi_size-1) * DIFFICULTY_TARGET_V2)
% print_money(t_burnt)
% print_money(t_locked)
+26 -13
View File
@@ -2402,7 +2402,7 @@ bool wallet2::get_yield_summary_info(uint64_t &total_burnt,
uint64_t &total_yield,
uint64_t &yield_per_stake,
uint64_t &ybi_data_size,
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> &payouts
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> &payouts
)
{
// Get the total circulating supply of SALs
@@ -2430,17 +2430,17 @@ bool wallet2::get_yield_summary_info(uint64_t &total_burnt,
// Iterate over the transfers in our wallet
std::map<size_t, size_t> map_payouts;
std::map<std::string, std::pair<size_t, std::pair<uint64_t, uint64_t>>> payouts_active;
std::map<std::string, std::tuple<size_t, std::string, uint64_t, uint64_t>> payouts_active;
if (m_transfers.size() > 0) {
for (size_t idx = m_transfers.size()-1; idx>0; --idx) {
const tools::wallet2::transfer_details& td = m_transfers[idx];
//if (td.m_block_height < ybi_data[0].block_height) break;
if (td.m_tx.type == cryptonote::transaction_type::STAKE) {
if (map_payouts.count(idx)) {
payouts.push_back(std::make_tuple(td.m_block_height, epee::string_tools::pod_to_hex(td.m_txid), td.m_tx.amount_burnt, m_transfers[map_payouts[idx]].m_amount - td.m_tx.amount_burnt));
payouts.push_back(std::make_tuple(td.m_block_height, epee::string_tools::pod_to_hex(td.m_txid), td.asset_type, td.m_tx.amount_burnt, m_transfers[map_payouts[idx]].m_amount - td.m_tx.amount_burnt));
} else {
//payouts.push_back(std::make_tuple(td.m_block_height, epee::string_tools::pod_to_hex(td.m_txid), td.m_tx.amount_burnt, 0));
payouts_active[epee::string_tools::pod_to_hex(td.m_txid)] = std::make_pair(td.m_block_height, std::make_pair(td.m_tx.amount_burnt, 0));
payouts_active[epee::string_tools::pod_to_hex(td.m_txid)] = std::make_tuple(td.m_block_height, td.asset_type, td.m_tx.amount_burnt, 0);
}
} else if (td.m_tx.type == cryptonote::transaction_type::PROTOCOL) {
// Store list of reverse-lookup indices to tell YIELD TXs how much they earned
@@ -2462,18 +2462,21 @@ bool wallet2::get_yield_summary_info(uint64_t &total_burnt,
// EXPERIMENTAL - add up yield earned for active STAKE TXs
for (auto &payout: payouts_active) {
if (ybi_data[idx].block_height < payout.second.first) continue;
auto&[height,asset_type,total_burnt,total_accrued] = payout.second;
if (ybi_data[idx].block_height < height) continue;
boost::multiprecision::uint128_t amount_128 = ybi_data[idx].slippage_total_this_block;
amount_128 *= payout.second.second.first;
amount_128 *= total_burnt;
amount_128 /= ybi_data[idx].locked_coins_tally;
payout.second.second.second += amount_128.convert_to<uint64_t>();
total_accrued += amount_128.convert_to<uint64_t>();
}
}
}
for (auto &payout: payouts_active) {
// Copy to the list of payouts proper
payouts.push_back(std::make_tuple(payout.second.first, payout.first, payout.second.second.first, payout.second.second.second));
auto&[height,asset_type,total_burnt,total_accrued] = payout.second;
payouts.push_back(std::make_tuple(height, payout.first, asset_type, total_burnt, total_accrued));
}
// Get the total currently locked
@@ -2905,7 +2908,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
// Additionally, with STAKE and AUDIT TXs, we need to update our "balance staked" subtotal, because otherwise our balance is out by the staked coins until they mature!
// SRCG: must remember to deduct the number of staked coins when they mature!!
LOG_PRINT_L1("***** STAKED/AUDITED COINS : " << tx.amount_burnt << " *****");
m_locked_coins.insert({P_change, {0, tx.amount_burnt}});
m_locked_coins.insert({P_change, {0, tx.amount_burnt, tx.source_asset_type}});
}
} else if (tx.type == cryptonote::transaction_type::TRANSFER) {
@@ -7026,10 +7029,12 @@ uint64_t wallet2::balance(uint32_t index_major, const std::string& asset_type, b
uint64_t amount = 0;
for (const auto& i : balance_per_subaddress(index_major, asset_type, strict))
amount += i.second;
if (index_major == 0 && asset_type == "SAL") {
// Iterate over the locked coins, adding them to the _locked_ balance
for (const auto& i : m_locked_coins)
// Iterate over the locked coins, adding them to the _locked_ balance
for (const auto& i : m_locked_coins) {
if (index_major == 0 && asset_type == i.second.m_asset_type) {
amount += i.second.m_amount;
}
}
return amount;
}
@@ -11505,7 +11510,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt
std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector<size_t> transfers_indices)
{
// Get the asset_type and associated information
THROW_WALLET_EXCEPTION_IF(transfers_indices.empty() || transfers_indices.size()>1, error::wallet_internal_error, tr("Incorrect number of transfers_indices on return_payment"));
THROW_WALLET_EXCEPTION_IF(transfers_indices.empty() || transfers_indices.size()>15, error::wallet_internal_error, tr("Incorrect number of transfers_indices on return_payment"));
size_t idx = transfers_indices[0];
THROW_WALLET_EXCEPTION_IF(idx >= get_num_transfer_details(), error::wallet_internal_error, tr("cannot locate return_payment origin index in m_transfers"));
const transfer_details& td_origin = get_transfer_details(idx);
@@ -11518,6 +11523,14 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector
uint32_t priority = adjust_priority(0);
std::vector<uint8_t> extra; // No need for a TX extra beyond that which will be calculated herein
// Verify that all the indices share an origin
for (const auto &td_idx : transfers_indices) {
THROW_WALLET_EXCEPTION_IF(td_idx >= get_num_transfer_details(), error::wallet_internal_error, tr("cannot locate return_payment origin index in m_transfers"));
const transfer_details &td = get_transfer_details(td_idx);
THROW_WALLET_EXCEPTION_IF(td.m_txid != td_origin.m_txid, error::wallet_internal_error, tr("TX hashes do not match for inputs to return_payment"));
THROW_WALLET_EXCEPTION_IF(td.asset_type != td_origin.asset_type, error::wallet_internal_error, tr("TX asset_type values do not match for inputs to return_payment"));
}
// To return a payment, we need to know the y value to process the F value
// ...but the y value is calculated differently depending on the original TX
ec_scalar y;
+4 -1
View File
@@ -486,11 +486,13 @@ private:
{
uint32_t m_index_major;
uint64_t m_amount;
std::string m_asset_type;
BEGIN_SERIALIZE_OBJECT()
VERSION_FIELD(0)
VARINT_FIELD(m_index_major)
VARINT_FIELD(m_amount)
FIELD(m_asset_type)
END_SERIALIZE()
};
@@ -1755,7 +1757,7 @@ private:
uint64_t &total_yield,
uint64_t &yield_per_stake,
uint64_t &ybi_data_size,
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> &payouts
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> &payouts
);
private:
@@ -2365,6 +2367,7 @@ namespace boost
{
a & x.m_index_major;
a & x.m_amount;
a & x.m_asset_type;
}
template <class Archive>