From db56a03ff2820f85da21c3c8fc4cc60e64c5b88d Mon Sep 17 00:00:00 2001 From: Jaquee Date: Thu, 12 Jan 2017 18:23:23 +0100 Subject: [PATCH] Wallet2 + API: Callbacks for unconfirmed transfers --- src/simplewallet/simplewallet.cpp | 5 ++++ src/simplewallet/simplewallet.h | 1 + src/wallet/api/transaction_history.cpp | 36 ++++++++++++++++++++++---- src/wallet/api/transaction_info.cpp | 6 +++++ src/wallet/api/transaction_info.h | 2 ++ src/wallet/api/wallet.cpp | 15 +++++++++++ src/wallet/wallet2.cpp | 5 +++- src/wallet/wallet2.h | 1 + src/wallet/wallet2_api.h | 8 ++++++ tests/libwallet_api_tests/main.cpp | 10 +++++++ 10 files changed, 83 insertions(+), 6 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 088d5e2a..051fbef8 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1542,6 +1542,11 @@ void simple_wallet::on_money_received(uint64_t height, const cryptonote::transac m_refresh_progress_reporter.update(height, true); } //---------------------------------------------------------------------------------------------------- +void simple_wallet::on_unconfirmed_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount) +{ + // Not implemented in CLI wallet +} +//---------------------------------------------------------------------------------------------------- void simple_wallet::on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx) { message_writer(epee::log_space::console_color_magenta, false) << "\r" << diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 753bca74..4dbd3876 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -184,6 +184,7 @@ namespace cryptonote //----------------- i_wallet2_callback --------------------- virtual void on_new_block(uint64_t height, const cryptonote::block& block); virtual void on_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount); + virtual void on_unconfirmed_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount); virtual void on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx); virtual void on_skip_transaction(uint64_t height, const cryptonote::transaction& tx); //---------------------------------------------------------- diff --git a/src/wallet/api/transaction_history.cpp b/src/wallet/api/transaction_history.cpp index 5f52438c..1e50652c 100644 --- a/src/wallet/api/transaction_history.cpp +++ b/src/wallet/api/transaction_history.cpp @@ -102,6 +102,7 @@ void TransactionHistoryImpl::refresh() // TODO: configurable values; uint64_t min_height = 0; uint64_t max_height = (uint64_t)-1; + uint64_t wallet_height = m_wallet->blockChainHeight(); // delete old transactions; for (auto t : m_history) @@ -123,15 +124,14 @@ void TransactionHistoryImpl::refresh() std::string payment_id = string_tools::pod_to_hex(i->first); if (payment_id.substr(16).find_first_not_of('0') == std::string::npos) payment_id = payment_id.substr(0,16); - // TODO TransactionInfoImpl * ti = new TransactionInfoImpl(); ti->m_paymentid = payment_id; ti->m_amount = pd.m_amount; ti->m_direction = TransactionInfo::Direction_In; ti->m_hash = string_tools::pod_to_hex(pd.m_tx_hash); ti->m_blockheight = pd.m_block_height; - // TODO: ti->m_timestamp = pd.m_timestamp; + ti->m_confirmations = wallet_height - pd.m_block_height; m_history.push_back(ti); /* output.insert(std::make_pair(pd.m_block_height, std::make_pair(true, (boost::format("%20.20s %s %s %s") @@ -174,6 +174,7 @@ void TransactionHistoryImpl::refresh() ti->m_hash = string_tools::pod_to_hex(hash); ti->m_blockheight = pd.m_block_height; ti->m_timestamp = pd.m_timestamp; + ti->m_confirmations = wallet_height - pd.m_block_height; // single output transaction might contain multiple transfers for (const auto &d: pd.m_dests) { @@ -183,9 +184,9 @@ void TransactionHistoryImpl::refresh() } // unconfirmed output transactions - std::list> upayments; - m_wallet->m_wallet->get_unconfirmed_payments_out(upayments); - for (std::list>::const_iterator i = upayments.begin(); i != upayments.end(); ++i) { + std::list> upayments_out; + m_wallet->m_wallet->get_unconfirmed_payments_out(upayments_out); + for (std::list>::const_iterator i = upayments_out.begin(); i != upayments_out.end(); ++i) { const tools::wallet2::unconfirmed_transfer_details &pd = i->second; const crypto::hash &hash = i->first; uint64_t amount = pd.m_amount_in; @@ -204,8 +205,33 @@ void TransactionHistoryImpl::refresh() ti->m_pending = true; ti->m_hash = string_tools::pod_to_hex(hash); ti->m_timestamp = pd.m_timestamp; + ti->m_confirmations = 0; m_history.push_back(ti); } + + + // unconfirmed payments (tx pool) + std::list> upayments; + m_wallet->m_wallet->get_unconfirmed_payments(upayments); + for (std::list>::const_iterator i = upayments.begin(); i != upayments.end(); ++i) { + const tools::wallet2::payment_details &pd = i->second; + std::string payment_id = string_tools::pod_to_hex(i->first); + if (payment_id.substr(16).find_first_not_of('0') == std::string::npos) + payment_id = payment_id.substr(0,16); + TransactionInfoImpl * ti = new TransactionInfoImpl(); + ti->m_paymentid = payment_id; + ti->m_amount = pd.m_amount; + ti->m_direction = TransactionInfo::Direction_In; + ti->m_hash = string_tools::pod_to_hex(pd.m_tx_hash); + ti->m_blockheight = pd.m_block_height; + ti->m_pending = true; + ti->m_timestamp = pd.m_timestamp; + ti->m_confirmations = 0; + m_history.push_back(ti); + + LOG_PRINT_L1(__FUNCTION__ << ": Unconfirmed payment found " << pd.m_amount); + } + } } // namespace diff --git a/src/wallet/api/transaction_info.cpp b/src/wallet/api/transaction_info.cpp index 8d26f203..576ae853 100644 --- a/src/wallet/api/transaction_info.cpp +++ b/src/wallet/api/transaction_info.cpp @@ -49,6 +49,7 @@ TransactionInfoImpl::TransactionInfoImpl() , m_fee(0) , m_blockheight(0) , m_timestamp(0) + , m_confirmations(0) { } @@ -109,6 +110,11 @@ const std::vector &TransactionInfoImpl::transfers() c return m_transfers; } +uint64_t TransactionInfoImpl::confirmations() const +{ + return m_confirmations; +} + } // namespace namespace Bitmonero = Monero; diff --git a/src/wallet/api/transaction_info.h b/src/wallet/api/transaction_info.h index 14efebac..af9696da 100644 --- a/src/wallet/api/transaction_info.h +++ b/src/wallet/api/transaction_info.h @@ -55,6 +55,7 @@ public: virtual std::time_t timestamp() const; virtual std::string paymentId() const; virtual const std::vector &transfers() const; + virtual uint64_t confirmations() const; private: int m_direction; @@ -67,6 +68,7 @@ private: std::time_t m_timestamp; std::string m_paymentid; std::vector m_transfers; + uint64_t m_confirmations; friend class TransactionHistoryImpl; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index da5f776f..a9e46728 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -103,6 +103,21 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback } } + virtual void on_unconfirmed_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount) + { + + std::string tx_hash = epee::string_tools::pod_to_hex(get_transaction_hash(tx)); + + LOG_PRINT_L3(__FUNCTION__ << ": unconfirmed money received. height: " << height + << ", tx: " << tx_hash + << ", amount: " << print_money(amount)); + // do not signal on received tx if wallet is not syncronized completely + if (m_listener && m_wallet->synchronized()) { + m_listener->unconfirmedMoneyReceived(tx_hash, amount); + m_listener->updated(); + } + } + virtual void on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx) { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 1550787e..7578295d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1004,8 +1004,11 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s payment.m_block_height = height; payment.m_unlock_time = tx.unlock_time; payment.m_timestamp = ts; - if (pool) + if (pool) { m_unconfirmed_payments.emplace(payment_id, payment); + if (0 != m_callback) + m_callback->on_unconfirmed_money_received(height, tx, payment.m_amount); + } else m_payments.emplace(payment_id, payment); LOG_PRINT_L2("Payment found in " << (pool ? "pool" : "block") << ": " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index e1eafbae..1da3c260 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -67,6 +67,7 @@ namespace tools public: virtual void on_new_block(uint64_t height, const cryptonote::block& block) {} virtual void on_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount) {} + virtual void on_unconfirmed_money_received(uint64_t height, const cryptonote::transaction& tx, uint64_t amount) {} virtual void on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, uint64_t amount, const cryptonote::transaction& spend_tx) {} virtual void on_skip_transaction(uint64_t height, const cryptonote::transaction& tx) {} virtual ~i_wallet2_callback() {} diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h index fcb4ef2e..75f5d413 100644 --- a/src/wallet/wallet2_api.h +++ b/src/wallet/wallet2_api.h @@ -112,6 +112,7 @@ struct TransactionInfo virtual uint64_t amount() const = 0; virtual uint64_t fee() const = 0; virtual uint64_t blockHeight() const = 0; + virtual uint64_t confirmations() const = 0; //! transaction_id virtual std::string hash() const = 0; virtual std::time_t timestamp() const = 0; @@ -194,6 +195,13 @@ struct WalletListener * @param amount - amount */ virtual void moneyReceived(const std::string &txId, uint64_t amount) = 0; + + /** + * @brief unconfirmedMoneyReceived - called when payment arrived in tx pool + * @param txId - transaction id + * @param amount - amount + */ + virtual void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) = 0; /** * @brief newBlock - called when new block received diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp index 671832ad..6f33684c 100644 --- a/tests/libwallet_api_tests/main.cpp +++ b/tests/libwallet_api_tests/main.cpp @@ -831,6 +831,16 @@ struct MyWalletListener : public Monero::WalletListener cv_receive.notify_one(); } + virtual void unconfirmedMoneyReceived(const string &txId, uint64_t amount) + { + std::cout << "wallet: " << wallet->address() << "**** just received unconfirmed money (" + << txId << ", " << wallet->displayAmount(amount) << ")" << std::endl; + // Don't trigger recieve until tx is mined + // total_rx += amount; + // receive_triggered = true; + // cv_receive.notify_one(); + } + virtual void newBlock(uint64_t height) { // std::cout << "wallet: " << wallet->address()