diff --git a/src/wallet/api/subaddress_account.cpp b/src/wallet/api/subaddress_account.cpp index 2f308e098..b72763052 100644 --- a/src/wallet/api/subaddress_account.cpp +++ b/src/wallet/api/subaddress_account.cpp @@ -65,7 +65,9 @@ void SubaddressAccountImpl::refresh() m_wallet->m_wallet->get_subaddress_as_str({i,0}), m_wallet->m_wallet->get_subaddress_label({i,0}), cryptonote::print_money(m_wallet->m_wallet->balance(i, "SAL", false)), - cryptonote::print_money(m_wallet->m_wallet->unlocked_balance(i, "SAL", false)) + cryptonote::print_money(m_wallet->m_wallet->unlocked_balance(i, "SAL", false)), + cryptonote::print_money(m_wallet->m_wallet->balance(i, "SAL1", false)), + cryptonote::print_money(m_wallet->m_wallet->unlocked_balance(i, "SAL1", false)) )); } } diff --git a/src/wallet/api/transaction_history.cpp b/src/wallet/api/transaction_history.cpp index 84212a4a4..badd7f06c 100644 --- a/src/wallet/api/transaction_history.cpp +++ b/src/wallet/api/transaction_history.cpp @@ -151,6 +151,7 @@ void TransactionHistoryImpl::refresh() ti->m_confirmations = (wallet_height > pd.m_block_height) ? wallet_height - pd.m_block_height : 0; ti->m_unlock_time = pd.m_unlock_time; ti->m_type = static_cast(static_cast(pd.m_tx_type)); + ti->m_asset = pd.m_asset_type; m_history.push_back(ti); } @@ -195,10 +196,11 @@ void TransactionHistoryImpl::refresh() ti->m_timestamp = pd.m_timestamp; ti->m_confirmations = (wallet_height > pd.m_block_height) ? wallet_height - pd.m_block_height : 0; ti->m_type = static_cast(static_cast(pd.m_tx.type)); + ti->m_asset = pd.m_tx.source_asset_type; // single output transaction might contain multiple transfers for (const auto &d: pd.m_dests) { - ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)}); + ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id), d.asset_type}); } m_history.push_back(ti); @@ -232,9 +234,10 @@ void TransactionHistoryImpl::refresh() ti->m_timestamp = pd.m_timestamp; ti->m_confirmations = 0; ti->m_type = static_cast(static_cast(pd.m_tx.type)); + ti->m_asset = pd.m_tx.source_asset_type; for (const auto &d : pd.m_dests) { - ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)}); + ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id), d.asset_type}); } m_history.push_back(ti); } @@ -262,6 +265,7 @@ void TransactionHistoryImpl::refresh() ti->m_timestamp = pd.m_timestamp; ti->m_confirmations = 0; ti->m_type = static_cast(static_cast(pd.m_tx_type)); + ti->m_asset = pd.m_asset_type; m_history.push_back(ti); LOG_PRINT_L1(__FUNCTION__ << ": Unconfirmed payment found " << pd.m_amount); diff --git a/src/wallet/api/transaction_info.cpp b/src/wallet/api/transaction_info.cpp index 687623f0c..da3711637 100644 --- a/src/wallet/api/transaction_info.cpp +++ b/src/wallet/api/transaction_info.cpp @@ -37,8 +37,8 @@ namespace Monero { TransactionInfo::~TransactionInfo() {} -TransactionInfo::Transfer::Transfer(uint64_t _amount, const string &_address) - : amount(_amount), address(_address) {} +TransactionInfo::Transfer::Transfer(uint64_t _amount, const string &_address, const string &_asset) + : amount(_amount), address(_address), asset(_asset) {} TransactionInfoImpl::TransactionInfoImpl() @@ -153,5 +153,10 @@ Monero::transaction_type TransactionInfoImpl::type() const { return m_type; } + +string TransactionInfoImpl::asset() const +{ + return m_asset; +} } // namespace diff --git a/src/wallet/api/transaction_info.h b/src/wallet/api/transaction_info.h index a2cd120ce..40f52e36a 100644 --- a/src/wallet/api/transaction_info.h +++ b/src/wallet/api/transaction_info.h @@ -55,6 +55,7 @@ public: virtual std::set subaddrIndex() const override; virtual uint32_t subaddrAccount() const override; virtual std::string label() const override; + virtual std::string asset() const override; virtual std::string hash() const override; virtual std::time_t timestamp() const override; @@ -73,6 +74,7 @@ private: uint64_t m_fee; uint64_t m_blockheight; std::string m_description; + std::string m_asset; std::set m_subaddrIndex; // always unique index for incoming transfers; can be multiple indices for outgoing transfers uint32_t m_subaddrAccount; std::string m_label; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index ba405de38..174c91978 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -946,14 +946,14 @@ void WalletImpl::setSubaddressLookahead(uint32_t major, uint32_t minor) m_wallet->set_subaddress_lookahead(major, minor); } -uint64_t WalletImpl::balance(uint32_t accountIndex) const +uint64_t WalletImpl::balance(const std::string& asset, uint32_t accountIndex) const { - return m_wallet->balance(accountIndex, "SAL", false); + return m_wallet->balance(accountIndex, asset, false); } -uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const +uint64_t WalletImpl::unlockedBalance(const std::string& asset, uint32_t accountIndex) const { - return m_wallet->unlocked_balance(accountIndex, "SAL", false); + return m_wallet->unlocked_balance(accountIndex, asset, false); } uint64_t WalletImpl::blockChainHeight() const @@ -1436,7 +1436,7 @@ PendingTransaction *WalletImpl::createStakeTransaction(uint64_t amount, uint32_t // Need to populate {dst_entr, payment_id, asset_type, is_return} const string dst_addr = m_wallet->get_subaddress_as_str({subaddr_account, 0});//MY LOCAL (SUB)ADDRESS const string payment_id = ""; - const string asset_type = "SAL"; + const string asset_type = "SAL1"; const bool is_return = false; LOG_ERROR("createStakeTransaction: called"); @@ -1568,9 +1568,30 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transact adjusted_priority, extra, subaddr_account, subaddr_indices); } else { - transaction->m_pending_tx = m_wallet->create_transactions_all(0, converted_tx_type, asset_type, info.address, info.is_subaddress, 1, fake_outs_count, 0 /* unlock_time */, - adjusted_priority, - extra, subaddr_account, subaddr_indices); + std::vector m_pending_txs; + for (auto it = subaddr_indices.begin(); it != subaddr_indices.end(); ++it) { + + // Skip this wallet if there is no balance unlocked to audit + const auto unlocked_balance_per_subaddr = m_wallet->unlocked_balance_per_subaddress(subaddr_account, "SAL", true); + if (unlocked_balance_per_subaddr.count(*it) == 0) continue; + + const auto result = m_wallet->create_transactions_all( + 0, + converted_tx_type, + asset_type, + m_wallet->get_subaddress({subaddr_account, *it}), + ((*it) > 0), + 1, + fake_outs_count, + 0 /* unlock_time */, + adjusted_priority, + extra, + subaddr_account, + std::set {*it} + ); + m_pending_txs.insert(m_pending_txs.end(), result.begin(), result.end()); + } + transaction->m_pending_tx = m_pending_txs; } pendingTxPostProcess(transaction); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index cfdf13779..54cde79ca 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -111,8 +111,8 @@ public: void setTrustedDaemon(bool arg) override; bool trustedDaemon() const override; bool setProxy(const std::string &address) override; - uint64_t balance(uint32_t accountIndex = 0) const override; - uint64_t unlockedBalance(uint32_t accountIndex = 0) const override; + uint64_t balance(const std::string& asset, uint32_t accountIndex = 0) const override; + uint64_t unlockedBalance(const std::string& asset, uint32_t accountIndex = 0) const override; uint64_t blockChainHeight() const override; uint64_t approximateBlockChainHeight() const override; uint64_t estimateBlockChainHeight() const override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 071142d8d..bb3cc4a37 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -209,9 +209,10 @@ struct TransactionInfo }; struct Transfer { - Transfer(uint64_t _amount, const std::string &address); + Transfer(uint64_t _amount, const std::string &address, const std::string &asset); const uint64_t amount; const std::string address; + const std::string asset; }; virtual ~TransactionInfo() = 0; @@ -228,6 +229,7 @@ struct TransactionInfo virtual std::string label() const = 0; virtual uint64_t confirmations() const = 0; virtual uint64_t unlockTime() const = 0; + virtual std::string asset() const = 0; //! transaction_id virtual std::string hash() const = 0; virtual std::time_t timestamp() const = 0; @@ -326,25 +328,35 @@ struct Subaddress struct SubaddressAccountRow { public: - SubaddressAccountRow(std::size_t _rowId, const std::string &_address, const std::string &_label, const std::string &_balance, const std::string &_unlockedBalance): + SubaddressAccountRow(std::size_t _rowId, const std::string &_address, const std::string &_label, const std::string &_balance, const std::string &_unlockedBalance, const std::string &_balance_sal1, const std::string &_unlockedBalance_sal1): m_rowId(_rowId), m_address(_address), m_label(_label), - m_balance(_balance), - m_unlockedBalance(_unlockedBalance) {} + m_balance_sal(_balance), + m_unlockedBalance_sal(_unlockedBalance), + m_balance_sal1(_balance_sal1), + m_unlockedBalance_sal1(_unlockedBalance_sal1) {} private: std::size_t m_rowId; std::string m_address; std::string m_label; - std::string m_balance; - std::string m_unlockedBalance; + std::string m_balance_sal; + std::string m_balance_sal1; + std::string m_unlockedBalance_sal; + std::string m_unlockedBalance_sal1; public: std::string extra; std::string getAddress() const {return m_address;} std::string getLabel() const {return m_label;} - std::string getBalance() const {return m_balance;} - std::string getUnlockedBalance() const {return m_unlockedBalance;} + std::string getBalance(const std::string& asset) const { + if (asset == "SAL") return m_balance_sal; + else return m_balance_sal1; + } + std::string getUnlockedBalance(const std::string& asset) const { + if (asset == "SAL") return m_unlockedBalance_sal; + else return m_unlockedBalance_sal1; + } std::size_t getRowId() const {return m_rowId;} }; @@ -642,18 +654,18 @@ struct Wallet virtual void setTrustedDaemon(bool arg) = 0; virtual bool trustedDaemon() const = 0; virtual bool setProxy(const std::string &address) = 0; - virtual uint64_t balance(uint32_t accountIndex = 0) const = 0; - uint64_t balanceAll() const { + virtual uint64_t balance(const std::string &asset, uint32_t accountIndex = 0) const = 0; + uint64_t balanceAll(const std::string &asset) const { uint64_t result = 0; for (uint32_t i = 0; i < numSubaddressAccounts(); ++i) - result += balance(i); + result += balance(asset, i); return result; } - virtual uint64_t unlockedBalance(uint32_t accountIndex = 0) const = 0; - uint64_t unlockedBalanceAll() const { + virtual uint64_t unlockedBalance(const std::string &asset, uint32_t accountIndex = 0) const = 0; + uint64_t unlockedBalanceAll(const std::string &asset) const { uint64_t result = 0; for (uint32_t i = 0; i < numSubaddressAccounts(); ++i) - result += unlockedBalance(i); + result += unlockedBalance(asset, i); return result; } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index cd1a2a722..c1566d001 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2573,10 +2573,16 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote if (!miner_tx && !pool) process_unconfirmed(txid, tx, height); - std::string source_asset = - (tx.type == cryptonote::transaction_type::MINER) ? "SAL" : - (tx.type == cryptonote::transaction_type::PROTOCOL) ? "SAL" : - tx.source_asset_type; + std::string source_asset; + if (use_fork_rules(get_salvium_one_proofs_fork(), 0)) { + if (tx.type == cryptonote::transaction_type::MINER && tx.type == cryptonote::transaction_type::PROTOCOL) { + source_asset = "SAL1"; + } + } else if (tx.type == cryptonote::transaction_type::MINER && tx.type == cryptonote::transaction_type::PROTOCOL) { + source_asset = "SAL"; + } else { + source_asset = tx.source_asset_type; + } // per receiving subaddress index std::unordered_map> tx_money_got_in_outs; @@ -7060,18 +7066,21 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, const std::string& asse std::map wallet2::balance_per_subaddress(uint32_t index_major, const std::string& asset_type, bool strict) const { std::map amount_per_subaddr; - for (const auto& idx: m_transfers_indices.at(asset_type)) - { - const transfer_details& td = m_transfers[idx]; - if (td.m_subaddr_index.major == index_major && !is_spent(td, strict) && !td.m_frozen) + if (m_transfers_indices.count(asset_type) > 0) { + for (const auto& idx: m_transfers_indices.at(asset_type)) { - auto found = amount_per_subaddr.find(td.m_subaddr_index.minor); - if (found == amount_per_subaddr.end()) - amount_per_subaddr[td.m_subaddr_index.minor] = td.amount(); - else - found->second += td.amount(); + const transfer_details& td = m_transfers[idx]; + if (td.m_subaddr_index.major == index_major && !is_spent(td, strict) && !td.m_frozen) + { + auto found = amount_per_subaddr.find(td.m_subaddr_index.minor); + if (found == amount_per_subaddr.end()) + amount_per_subaddr[td.m_subaddr_index.minor] = td.amount(); + else + found->second += td.amount(); + } } } + if (!strict) { for (const auto& utx: m_unconfirmed_txs) @@ -7118,6 +7127,10 @@ std::map>> wallet2:: std::map>> amount_per_subaddr; const uint64_t blockchain_height = get_blockchain_current_height(); const uint64_t now = time(NULL); + if (m_transfers_indices.count(asset_type) == 0) { + return amount_per_subaddr; + } + for(const auto& idx: m_transfers_indices[asset_type]) { transfer_details& td = m_transfers[idx];