From 8a82655fa4749528b500fc1daee329a6799e7067 Mon Sep 17 00:00:00 2001 From: Some Random Crypto Guy Date: Wed, 31 Jul 2024 12:39:06 +0100 Subject: [PATCH] added GUI yield support --- src/simplewallet/simplewallet.cpp | 2 +- src/version.cpp.in | 2 +- src/wallet/api/CMakeLists.txt | 2 + src/wallet/api/wallet.cpp | 8 +++ src/wallet/api/wallet.h | 4 ++ src/wallet/api/wallet2_api.h | 25 ++++++++ src/wallet/wallet2.cpp | 99 +++++++++++++++++++++++++++++++ src/wallet/wallet2.h | 9 +++ 8 files changed, 149 insertions(+), 2 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 3de42b6..e43c628 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -8444,7 +8444,7 @@ bool simple_wallet::yield_info(const std::vector &args) { % print_money(total_yield) % print_money(yield_per_stake); - // Now summarise our own YIELD TXs that are yet to amture + // Now summarise our own YIELD TXs that are yet to mature tools::wallet2::transfer_container transfers; m_wallet->get_transfers(transfers); if (transfers.empty()) diff --git a/src/version.cpp.in b/src/version.cpp.in index 07dc12d..366c57a 100644 --- a/src/version.cpp.in +++ b/src/version.cpp.in @@ -1,5 +1,5 @@ #define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@" -#define DEF_SALVIUM_VERSION "0.4.1" +#define DEF_SALVIUM_VERSION "0.4.2" #define DEF_MONERO_VERSION_TAG "release" #define DEF_MONERO_VERSION "0.18.3.3" #define DEF_MONERO_RELEASE_NAME "Zero" diff --git a/src/wallet/api/CMakeLists.txt b/src/wallet/api/CMakeLists.txt index af7948d..1100201 100644 --- a/src/wallet/api/CMakeLists.txt +++ b/src/wallet/api/CMakeLists.txt @@ -35,6 +35,7 @@ set(wallet_api_sources wallet_manager.cpp transaction_info.cpp transaction_history.cpp + yield_info.cpp pending_transaction.cpp utils.cpp address_book.cpp @@ -50,6 +51,7 @@ set(wallet_api_private_headers wallet_manager.h transaction_info.h transaction_history.h + yield_info.h pending_transaction.h common_defines.h address_book.h diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 43090ba..94b0c19 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -30,6 +30,7 @@ #include "wallet.h" +#include "yield_info.h" #include "pending_transaction.h" #include "unsigned_transaction.h" #include "transaction_history.h" @@ -2607,4 +2608,11 @@ uint64_t WalletImpl::getBytesSent() return m_wallet->get_bytes_sent(); } +YieldInfo * WalletImpl::getYieldInfo() +{ + auto yi = new YieldInfoImpl(*this); + bool ok = m_wallet->get_yield_summary_info(yi->m_burnt, yi->m_supply, yi->m_locked, yi->m_yield, yi->m_yield_per_stake, yi->m_num_entries, yi->m_payouts); + return yi; +} + } // namespace diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 802846a..709bb8d 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -42,6 +42,7 @@ namespace Monero { class TransactionHistoryImpl; +class YieldInfoImpl; class PendingTransactionImpl; class UnsignedTransactionImpl; class AddressBookImpl; @@ -233,6 +234,8 @@ public: virtual uint64_t getBytesReceived() override; virtual uint64_t getBytesSent() override; + YieldInfo * getYieldInfo() override; + private: void clearStatus() const; void setStatusError(const std::string& message) const; @@ -247,6 +250,7 @@ private: bool doInit(const std::string &daemon_address, const std::string &proxy_address, uint64_t upper_transaction_size_limit = 0, bool ssl = false); private: + friend class YieldInfoImpl; friend class PendingTransactionImpl; friend class UnsignedTransactionImpl; friend class TransactionHistoryImpl; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 7c6a548..884f720 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -79,6 +79,28 @@ enum transaction_type { bool set; }; +struct YieldInfo +{ + enum Status { + Status_Ok, + Status_Error + }; + + virtual ~YieldInfo() = 0; + virtual int status() const = 0; + virtual std::string errorString() const = 0; + virtual bool update() = 0; + virtual uint64_t burnt() const = 0; + virtual uint64_t locked() const = 0; + virtual uint64_t supply() const = 0; + virtual uint64_t ybi_data_size() const = 0; + virtual uint64_t yield() const = 0; + virtual uint64_t yield_per_stake() const = 0; + virtual std::string period() const = 0; + virtual std::vector> payouts() const = 0; +}; + + /** * @brief Transaction-like interface for sending money */ @@ -1129,6 +1151,9 @@ struct Wallet //! get bytes sent virtual uint64_t getBytesSent() = 0; + + //! get yield information + virtual YieldInfo * getYieldInfo() = 0; }; /** diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index bb13ae1..0800d8d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2380,6 +2380,105 @@ bool wallet2::get_yield_info(std::vector& ybi_data } } //---------------------------------------------------------------------------------------------------- +bool wallet2::get_yield_summary_info(uint64_t &total_burnt, + uint64_t &total_supply, + uint64_t &total_locked, + uint64_t &total_yield, + uint64_t &yield_per_stake, + uint64_t &ybi_data_size, + std::vector> &payouts + ) +{ + // Get the total circulating supply of SALs + std::vector> supply_amounts; + if(!get_circulating_supply(supply_amounts)) { + return false; + } + boost::multiprecision::uint128_t total_supply_128 = 0; + for (auto supply_asset: supply_amounts) { + if (supply_asset.first == "SAL") { + boost::multiprecision::uint128_t supply_128(supply_asset.second); + total_supply_128 = supply_128; + break; + } + } + total_supply = total_supply_128.convert_to(); + + // Get the yield data from the blockchain + std::vector ybi_data; + bool r = get_yield_info(ybi_data); + if (!r) + return false; + + ybi_data_size = ybi_data.size(); + + // Scan the entries we have received to gather the state (total yield over period captured) + total_burnt = 0; + total_yield = 0; + yield_per_stake = 0; + for (size_t idx=1; idx 0) { + boost::multiprecision::uint128_t yield_per_stake_128 = ybi_data.back().slippage_total_this_block; + yield_per_stake_128 *= COIN; + yield_per_stake_128 /= ybi_data.back().locked_coins_tally; + yield_per_stake = yield_per_stake_128.convert_to(); + } + + // Iterate over the transfers in our wallet + std::map map_payouts; + 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)); + } 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)); + } + } else if (td.m_tx.type == cryptonote::transaction_type::PROTOCOL) { + // Store list of reverse-lookup indices to tell YIELD TXs how much they earned + if (m_transfers[td.m_td_origin_idx].m_tx.type == cryptonote::transaction_type::STAKE) + map_payouts[td.m_td_origin_idx] = idx; + } + } + + // Return success to caller + return true; +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::get_yield_payouts(std::vector> &payouts) { + + // Iterate over the transfers in our wallet + std::map map_payouts; + 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)); + } 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)); + } + } else if (td.m_tx.type == cryptonote::transaction_type::PROTOCOL) { + // Store list of reverse-lookup indices to tell YIELD TXs how much they earned + if (m_transfers[td.m_td_origin_idx].m_tx.type == cryptonote::transaction_type::STAKE) + map_payouts[td.m_td_origin_idx] = idx; + } + } + return true; +} +//---------------------------------------------------------------------------------------------------- void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector &o_indices, const std::vector &asset_type_output_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data, std::map, size_t> *output_tracker_cache, bool ignore_callbacks) { PERF_TIMER(process_new_transaction); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 4cb4c97..d14ff92 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1747,6 +1747,15 @@ private: bool get_pricing_record(oracle::pricing_record& pr, const uint64_t height); bool get_circulating_supply(std::vector> &amounts); bool get_yield_info(std::vector& ybi_data); + bool get_yield_summary_info(uint64_t &total_burnt, + uint64_t &total_supply, + uint64_t &total_locked, + uint64_t &total_yield, + uint64_t &yield_per_stake, + uint64_t &ybi_data_size, + std::vector> &payouts + ); + bool get_yield_payouts(std::vector> &payouts); private: /*!