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:
@@ -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
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user