mirror of
				https://github.com/monero-project/monero.git
				synced 2025-10-31 13:52:16 -04:00 
			
		
		
		
	wallet: add unconfirmed incoming txes from the txpool
Shown in show_transfers simplewallet command, and get_transfers RPC command, if req.pool is true.
This commit is contained in:
		
							parent
							
								
									8e143fcf1d
								
							
						
					
					
						commit
						b89b96394a
					
				
					 5 changed files with 242 additions and 53 deletions
				
			
		|  | @ -3082,6 +3082,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_) | |||
|   bool out = true; | ||||
|   bool pending = true; | ||||
|   bool failed = true; | ||||
|   bool pool = true; | ||||
|   uint64_t min_height = 0; | ||||
|   uint64_t max_height = (uint64_t)-1; | ||||
| 
 | ||||
|  | @ -3099,7 +3100,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_) | |||
|       local_args.erase(local_args.begin()); | ||||
|     } | ||||
|     else if (local_args[0] == "out" || local_args[0] == "outgoing") { | ||||
|       in = false; | ||||
|       in = pool = false; | ||||
|       local_args.erase(local_args.begin()); | ||||
|     } | ||||
|     else if (local_args[0] == "pending") { | ||||
|  | @ -3107,7 +3108,11 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_) | |||
|       local_args.erase(local_args.begin()); | ||||
|     } | ||||
|     else if (local_args[0] == "failed") { | ||||
|       in = out = pending = false; | ||||
|       in = out = pending = pool = false; | ||||
|       local_args.erase(local_args.begin()); | ||||
|     } | ||||
|     else if (local_args[0] == "pool") { | ||||
|       in = out = pending = failed = false; | ||||
|       local_args.erase(local_args.begin()); | ||||
|     } | ||||
|     else if (local_args[0] == "all" || local_args[0] == "both") { | ||||
|  | @ -3182,6 +3187,27 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_) | |||
|       ((unsigned long long)i->first) % (i->second.first ? tr("in") : tr("out")) % i->second.second; | ||||
|   } | ||||
| 
 | ||||
|   if (pool) { | ||||
|     try | ||||
|     { | ||||
|       m_wallet->update_pool_state(); | ||||
|       std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> payments; | ||||
|       m_wallet->get_unconfirmed_payments(payments); | ||||
|       for (std::list<std::pair<crypto::hash, tools::wallet2::payment_details>>::const_iterator i = payments.begin(); i != payments.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); | ||||
|         std::string note = m_wallet->get_tx_note(pd.m_tx_hash); | ||||
|         message_writer() << (boost::format("%8.8s %6.6s %16.16s %20.20s %s %s %s %s") % "pool" % "in" % get_human_readable_timestamp(pd.m_timestamp) % print_money(pd.m_amount) % string_tools::pod_to_hex(pd.m_tx_hash) % payment_id % "-" % note).str(); | ||||
|       } | ||||
|     } | ||||
|     catch (...) | ||||
|     { | ||||
|       fail_msg_writer() << "Failed to get pool state"; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // print unconfirmed last
 | ||||
|   if (pending || failed) { | ||||
|     std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>> upayments; | ||||
|  |  | |||
|  | @ -186,7 +186,7 @@ void wallet2::check_acc_out(const account_keys &acc, const tx_out &o, const cryp | |||
|   error = false; | ||||
| } | ||||
| //----------------------------------------------------------------------------------------------------
 | ||||
| void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx) | ||||
| void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx, bool pool) | ||||
| { | ||||
|   if (!miner_tx) | ||||
|     process_unconfirmed(tx, height); | ||||
|  | @ -318,16 +318,19 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ | |||
|       //usually we have only one transfer for user in transaction
 | ||||
|       cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request req = AUTO_VAL_INIT(req); | ||||
|       cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response res = AUTO_VAL_INIT(res); | ||||
|       req.txid = get_transaction_hash(tx); | ||||
|       m_daemon_rpc_mutex.lock(); | ||||
|       bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/get_o_indexes.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT); | ||||
|       m_daemon_rpc_mutex.unlock(); | ||||
|       THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_o_indexes.bin"); | ||||
|       THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin"); | ||||
|       THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status); | ||||
|       THROW_WALLET_EXCEPTION_IF(res.o_indexes.size() != tx.vout.size(), error::wallet_internal_error, | ||||
| 				"transactions outputs size=" + std::to_string(tx.vout.size()) + | ||||
| 				" not match with COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES response size=" + std::to_string(res.o_indexes.size())); | ||||
|       if (!pool) | ||||
|       { | ||||
|         req.txid = get_transaction_hash(tx); | ||||
|         m_daemon_rpc_mutex.lock(); | ||||
|         bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/get_o_indexes.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT); | ||||
|         m_daemon_rpc_mutex.unlock(); | ||||
|         THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_o_indexes.bin"); | ||||
|         THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin"); | ||||
|         THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status); | ||||
|         THROW_WALLET_EXCEPTION_IF(res.o_indexes.size() != tx.vout.size(), error::wallet_internal_error, | ||||
| 				  "transactions outputs size=" + std::to_string(tx.vout.size()) + | ||||
| 				  " not match with COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES response size=" + std::to_string(res.o_indexes.size())); | ||||
|       } | ||||
| 
 | ||||
|       BOOST_FOREACH(size_t o, outs) | ||||
|       { | ||||
|  | @ -347,18 +350,21 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ | |||
|             + ", m_transfers.size() is " + boost::lexical_cast<std::string>(m_transfers.size())); | ||||
|         if (kit == m_key_images.end()) | ||||
|         { | ||||
| 	  m_transfers.push_back(boost::value_initialized<transfer_details>()); | ||||
| 	  transfer_details& td = m_transfers.back(); | ||||
| 	  td.m_block_height = height; | ||||
| 	  td.m_internal_output_index = o; | ||||
| 	  td.m_global_output_index = res.o_indexes[o]; | ||||
| 	  td.m_tx = tx; | ||||
|           td.m_key_image = ki; | ||||
| 	  td.m_spent = false; | ||||
| 	  m_key_images[td.m_key_image] = m_transfers.size()-1; | ||||
| 	  LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx)); | ||||
| 	  if (0 != m_callback) | ||||
| 	    m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index); | ||||
|           if (!pool) | ||||
|           { | ||||
| 	    m_transfers.push_back(boost::value_initialized<transfer_details>()); | ||||
| 	    transfer_details& td = m_transfers.back(); | ||||
| 	    td.m_block_height = height; | ||||
| 	    td.m_internal_output_index = o; | ||||
| 	    td.m_global_output_index = res.o_indexes[o]; | ||||
| 	    td.m_tx = tx; | ||||
|             td.m_key_image = ki; | ||||
| 	    td.m_spent = false; | ||||
| 	    m_key_images[td.m_key_image] = m_transfers.size()-1; | ||||
| 	    LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx)); | ||||
| 	    if (0 != m_callback) | ||||
| 	      m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index); | ||||
|           } | ||||
|         } | ||||
| 	else if (m_transfers[kit->second].m_spent || m_transfers[kit->second].amount() >= tx.vout[o].amount) | ||||
|         { | ||||
|  | @ -375,17 +381,20 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ | |||
|           // The new larger output replaced a previous smaller one
 | ||||
|           tx_money_got_in_outs -= tx.vout[o].amount; | ||||
| 
 | ||||
|           transfer_details &td = m_transfers[kit->second]; | ||||
| 	  td.m_block_height = height; | ||||
| 	  td.m_internal_output_index = o; | ||||
| 	  td.m_global_output_index = res.o_indexes[o]; | ||||
| 	  td.m_tx = tx; | ||||
|           THROW_WALLET_EXCEPTION_IF(td.m_key_image != ki, error::wallet_internal_error, "Inconsistent key images"); | ||||
| 	  THROW_WALLET_EXCEPTION_IF(td.m_spent, error::wallet_internal_error, "Inconsistent spent status"); | ||||
|           if (!pool) | ||||
|           { | ||||
|             transfer_details &td = m_transfers[kit->second]; | ||||
| 	    td.m_block_height = height; | ||||
| 	    td.m_internal_output_index = o; | ||||
| 	    td.m_global_output_index = res.o_indexes[o]; | ||||
| 	    td.m_tx = tx; | ||||
|             THROW_WALLET_EXCEPTION_IF(td.m_key_image != ki, error::wallet_internal_error, "Inconsistent key images"); | ||||
| 	    THROW_WALLET_EXCEPTION_IF(td.m_spent, error::wallet_internal_error, "Inconsistent spent status"); | ||||
| 
 | ||||
| 	  LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx)); | ||||
| 	  if (0 != m_callback) | ||||
| 	    m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index); | ||||
| 	    LOG_PRINT_L0("Received money: " << print_money(td.amount()) << ", with tx: " << get_transaction_hash(tx)); | ||||
| 	    if (0 != m_callback) | ||||
| 	      m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | @ -462,8 +471,11 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ | |||
|     payment.m_block_height = height; | ||||
|     payment.m_unlock_time  = tx.unlock_time; | ||||
|     payment.m_timestamp    = ts; | ||||
|     m_payments.emplace(payment_id, payment); | ||||
|     LOG_PRINT_L2("Payment found: " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount); | ||||
|     if (pool) | ||||
|       m_unconfirmed_payments.emplace(payment_id, payment); | ||||
|     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); | ||||
|   } | ||||
| } | ||||
| //----------------------------------------------------------------------------------------------------
 | ||||
|  | @ -506,7 +518,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry | |||
|   if(b.timestamp + 60*60*24 > m_account.get_createtime() && height >= m_refresh_from_block_height) | ||||
|   { | ||||
|     TIME_MEASURE_START(miner_tx_handle_time); | ||||
|     process_new_transaction(b.miner_tx, height, b.timestamp, true); | ||||
|     process_new_transaction(b.miner_tx, height, b.timestamp, true, false); | ||||
|     TIME_MEASURE_FINISH(miner_tx_handle_time); | ||||
| 
 | ||||
|     TIME_MEASURE_START(txs_handle_time); | ||||
|  | @ -515,7 +527,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry | |||
|       cryptonote::transaction tx; | ||||
|       bool r = parse_and_validate_tx_from_blob(txblob, tx); | ||||
|       THROW_WALLET_EXCEPTION_IF(!r, error::tx_parse_error, txblob); | ||||
|       process_new_transaction(tx, height, b.timestamp, false); | ||||
|       process_new_transaction(tx, height, b.timestamp, false, false); | ||||
|     } | ||||
|     TIME_MEASURE_FINISH(txs_handle_time); | ||||
|     LOG_PRINT_L2("Processed block: " << bl_id << ", height " << height << ", " <<  miner_tx_handle_time + txs_handle_time << "(" << miner_tx_handle_time << "/" << txs_handle_time <<")ms"); | ||||
|  | @ -743,20 +755,16 @@ void wallet2::pull_next_blocks(uint64_t start_height, uint64_t &blocks_start_hei | |||
|   } | ||||
| } | ||||
| //----------------------------------------------------------------------------------------------------
 | ||||
| void wallet2::check_pending_txes() | ||||
| void wallet2::update_pool_state() | ||||
| { | ||||
|   // if we don't have any pending txes, we don't need to check anything
 | ||||
|   if (m_unconfirmed_txs.empty()) | ||||
|     return; | ||||
| 
 | ||||
|   // we have at least one pending tx, so get the pool state
 | ||||
|   // get the pool state
 | ||||
|   cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::request req; | ||||
|   cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::response res; | ||||
|   m_daemon_rpc_mutex.lock(); | ||||
|   bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/get_transaction_pool", req, res, m_http_client, 200000); | ||||
|   m_daemon_rpc_mutex.unlock(); | ||||
|   THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "check_pending_txes"); | ||||
|   THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent"); | ||||
|   THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_transaction_pool"); | ||||
|   THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_transaction_pool"); | ||||
|   THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); | ||||
| 
 | ||||
|   // remove any pending tx that's not in the pool
 | ||||
|  | @ -793,6 +801,120 @@ void wallet2::check_pending_txes() | |||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // remove pool txes to us that aren't in the pool anymore
 | ||||
|   std::unordered_map<crypto::hash, wallet2::payment_details>::iterator uit = m_unconfirmed_payments.begin(); | ||||
|   while (uit != m_unconfirmed_payments.end()) | ||||
|   { | ||||
|     const std::string txid = string_tools::pod_to_hex(uit->first); | ||||
|     bool found = false; | ||||
|     for (auto it2: res.transactions) | ||||
|     { | ||||
|       if (it2.id_hash == txid) | ||||
|       { | ||||
|         found = true; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     auto pit = uit++; | ||||
|     if (!found) | ||||
|     { | ||||
|       m_unconfirmed_payments.erase(pit); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // add new pool txes to us
 | ||||
|   for (auto it: res.transactions) | ||||
|   { | ||||
|     cryptonote::blobdata txid_data; | ||||
|     if(epee::string_tools::parse_hexstr_to_binbuff(it.id_hash, txid_data)) | ||||
|     { | ||||
|       const crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_data.data()); | ||||
|       if (m_unconfirmed_payments.find(txid) == m_unconfirmed_payments.end()) | ||||
|       { | ||||
|         LOG_PRINT_L1("Found new pool tx: " << txid); | ||||
|         bool found = false; | ||||
|         for (const auto &i: m_unconfirmed_txs) | ||||
|         { | ||||
|           if (i.first == txid) | ||||
|           { | ||||
|             found = true; | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|         if (!found) | ||||
|         { | ||||
|           // not one of those we sent ourselves
 | ||||
|           cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req; | ||||
|           cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res; | ||||
|           req.txs_hashes.push_back(it.id_hash); | ||||
|           req.decode_as_json = false; | ||||
|           m_daemon_rpc_mutex.lock(); | ||||
|           bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/gettransactions", req, res, m_http_client, 200000); | ||||
|           m_daemon_rpc_mutex.unlock(); | ||||
|           if (r && res.status == CORE_RPC_STATUS_OK) | ||||
|           { | ||||
|             if (res.txs.size() == 1) | ||||
|             { | ||||
|               // might have just been put in a block
 | ||||
|               if (res.txs[0].in_pool) | ||||
|               { | ||||
|                 cryptonote::transaction tx; | ||||
|                 cryptonote::blobdata bd; | ||||
|                 crypto::hash tx_hash, tx_prefix_hash; | ||||
|                 if (epee::string_tools::parse_hexstr_to_binbuff(res.txs[0].as_hex, bd)) | ||||
|                 { | ||||
|                   if (cryptonote::parse_and_validate_tx_from_blob(bd, tx, tx_hash, tx_prefix_hash)) | ||||
|                   { | ||||
|                     if (tx_hash == txid) | ||||
|                     { | ||||
|                       process_new_transaction(tx, 0, time(NULL), false, true); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                       LOG_PRINT_L0("Mismatched txids when processing unconfimed txes from pool"); | ||||
|                     } | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                     LOG_PRINT_L0("failed to validate transaction from daemon"); | ||||
|                   } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                   LOG_PRINT_L0("Failed to parse tx " << txid); | ||||
|                 } | ||||
|               } | ||||
|               else | ||||
|               { | ||||
|                 LOG_PRINT_L1("Tx " << txid << " was in pool, but is no more"); | ||||
|               } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|               LOG_PRINT_L0("Expected 1 tx, got " << res.txs.size()); | ||||
|             } | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             LOG_PRINT_L0("Error calling gettransactions daemon RPC: r " << r << ", status " << res.status); | ||||
|           } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|           LOG_PRINT_L1("We sent that one"); | ||||
|         } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         LOG_PRINT_L1("Already saw that one"); | ||||
|       } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       LOG_PRINT_L0("Failed to parse txid"); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| //----------------------------------------------------------------------------------------------------
 | ||||
| void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list<crypto::hash> &short_chain_history) | ||||
|  | @ -931,7 +1053,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re | |||
| 
 | ||||
|   try | ||||
|   { | ||||
|     check_pending_txes(); | ||||
|     update_pool_state(); | ||||
|   } | ||||
|   catch (...) | ||||
|   { | ||||
|  | @ -1733,6 +1855,13 @@ void wallet2::get_unconfirmed_payments_out(std::list<std::pair<crypto::hash,wall | |||
|   } | ||||
| } | ||||
| //----------------------------------------------------------------------------------------------------
 | ||||
| void wallet2::get_unconfirmed_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& unconfirmed_payments) const | ||||
| { | ||||
|   for (auto i = m_unconfirmed_payments.begin(); i != m_unconfirmed_payments.end(); ++i) { | ||||
|     unconfirmed_payments.push_back(*i); | ||||
|   } | ||||
| } | ||||
| //----------------------------------------------------------------------------------------------------
 | ||||
| void wallet2::rescan_spent() | ||||
| { | ||||
|   std::vector<std::string> key_images; | ||||
|  |  | |||
|  | @ -303,6 +303,8 @@ namespace tools | |||
|     void get_payments_out(std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>>& confirmed_payments, | ||||
|       uint64_t min_height, uint64_t max_height = (uint64_t)-1) const; | ||||
|     void get_unconfirmed_payments_out(std::list<std::pair<crypto::hash,wallet2::unconfirmed_transfer_details>>& unconfirmed_payments) const; | ||||
|     void get_unconfirmed_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& unconfirmed_payments) const; | ||||
| 
 | ||||
|     uint64_t get_blockchain_current_height() const { return m_local_bc_height; } | ||||
|     void rescan_spent(); | ||||
|     void rescan_blockchain(bool refresh = true); | ||||
|  | @ -334,6 +336,9 @@ namespace tools | |||
|       if(ver < 12) | ||||
|         return; | ||||
|       a & m_tx_notes; | ||||
|       if(ver < 13) | ||||
|         return; | ||||
|       a & m_unconfirmed_payments; | ||||
|     } | ||||
| 
 | ||||
|     /*!
 | ||||
|  | @ -389,6 +394,8 @@ namespace tools | |||
|     std::string sign(const std::string &data) const; | ||||
|     bool verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const; | ||||
| 
 | ||||
|     void update_pool_state(); | ||||
| 
 | ||||
|   private: | ||||
|     /*!
 | ||||
|      * \brief  Stores wallet information to wallet file. | ||||
|  | @ -404,7 +411,7 @@ namespace tools | |||
|      * \param password       Password of wallet file | ||||
|      */ | ||||
|     bool load_keys(const std::string& keys_file_name, const std::string& password); | ||||
|     void process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx); | ||||
|     void process_new_transaction(const cryptonote::transaction& tx, uint64_t height, uint64_t ts, bool miner_tx, bool pool); | ||||
|     void process_new_blockchain_entry(const cryptonote::block& b, const cryptonote::block_complete_entry& bche, const crypto::hash& bl_id, uint64_t height); | ||||
|     void detach_blockchain(uint64_t height); | ||||
|     void get_short_chain_history(std::list<crypto::hash>& ids) const; | ||||
|  | @ -428,7 +435,6 @@ namespace tools | |||
|     void check_acc_out(const cryptonote::account_keys &acc, const cryptonote::tx_out &o, const crypto::public_key &tx_pub_key, size_t i, uint64_t &money_transfered, bool &error) const; | ||||
|     void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const; | ||||
|     uint64_t get_upper_tranaction_size_limit(); | ||||
|     void check_pending_txes(); | ||||
|     std::vector<uint64_t> get_unspent_amounts_vector(); | ||||
|     uint64_t sanitize_fee_multiplier(uint64_t fee_multiplier) const; | ||||
| 
 | ||||
|  | @ -441,6 +447,7 @@ namespace tools | |||
|     std::atomic<uint64_t> m_local_bc_height; //temporary workaround
 | ||||
|     std::unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs; | ||||
|     std::unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs; | ||||
|     std::unordered_map<crypto::hash, payment_details> m_unconfirmed_payments; | ||||
|     std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys; | ||||
| 
 | ||||
|     transfer_container m_transfers; | ||||
|  | @ -469,7 +476,7 @@ namespace tools | |||
|     uint64_t m_refresh_from_block_height; | ||||
|   }; | ||||
| } | ||||
| BOOST_CLASS_VERSION(tools::wallet2, 12) | ||||
| BOOST_CLASS_VERSION(tools::wallet2, 13) | ||||
| BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1) | ||||
| BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 3) | ||||
| BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2) | ||||
|  |  | |||
|  | @ -918,8 +918,8 @@ namespace tools | |||
|       std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>> payments; | ||||
|       m_wallet.get_payments_out(payments, min_height, max_height); | ||||
|       for (std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) { | ||||
|         res.in.push_back(wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry()); | ||||
|         wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry &entry = res.in.back(); | ||||
|         res.out.push_back(wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry()); | ||||
|         wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry &entry = res.out.back(); | ||||
|         const tools::wallet2::confirmed_transfer_details &pd = i->second; | ||||
| 
 | ||||
|         entry.txid = string_tools::pod_to_hex(i->first); | ||||
|  | @ -969,6 +969,29 @@ namespace tools | |||
|       } | ||||
|     } | ||||
| 
 | ||||
|     if (req.pool) | ||||
|     { | ||||
|       m_wallet.update_pool_state(); | ||||
| 
 | ||||
|       std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> payments; | ||||
|       m_wallet.get_unconfirmed_payments(payments); | ||||
|       for (std::list<std::pair<crypto::hash, tools::wallet2::payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) { | ||||
|         res.pool.push_back(wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry()); | ||||
|         wallet_rpc::COMMAND_RPC_GET_TRANSFERS::entry &entry = res.pool.back(); | ||||
|         const tools::wallet2::payment_details &pd = i->second; | ||||
| 
 | ||||
|         entry.txid = string_tools::pod_to_hex(pd.m_tx_hash); | ||||
|         entry.payment_id = string_tools::pod_to_hex(i->first); | ||||
|         if (entry.payment_id.substr(16).find_first_not_of('0') == std::string::npos) | ||||
|           entry.payment_id = entry.payment_id.substr(0,16); | ||||
|         entry.height = 0; | ||||
|         entry.timestamp = pd.m_timestamp; | ||||
|         entry.amount = pd.m_amount; | ||||
|         entry.fee = 0; // TODO
 | ||||
|         entry.note = m_wallet.get_tx_note(pd.m_tx_hash); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
|   } | ||||
|   //------------------------------------------------------------------------------------------------------------------------------
 | ||||
|  |  | |||
|  | @ -496,6 +496,7 @@ namespace wallet_rpc | |||
|       bool out; | ||||
|       bool pending; | ||||
|       bool failed; | ||||
|       bool pool; | ||||
| 
 | ||||
|       bool filter_by_height; | ||||
|       uint64_t min_height; | ||||
|  | @ -506,6 +507,7 @@ namespace wallet_rpc | |||
|         KV_SERIALIZE(out); | ||||
|         KV_SERIALIZE(pending); | ||||
|         KV_SERIALIZE(failed); | ||||
|         KV_SERIALIZE(pool); | ||||
|         KV_SERIALIZE(filter_by_height); | ||||
|         KV_SERIALIZE(min_height); | ||||
|         KV_SERIALIZE(max_height); | ||||
|  | @ -541,12 +543,14 @@ namespace wallet_rpc | |||
|       std::list<entry> out; | ||||
|       std::list<entry> pending; | ||||
|       std::list<entry> failed; | ||||
|       std::list<entry> pool; | ||||
| 
 | ||||
|       BEGIN_KV_SERIALIZE_MAP() | ||||
|         KV_SERIALIZE(in); | ||||
|         KV_SERIALIZE(out); | ||||
|         KV_SERIALIZE(pending); | ||||
|         KV_SERIALIZE(failed); | ||||
|         KV_SERIALIZE(pool); | ||||
|       END_KV_SERIALIZE_MAP() | ||||
|     }; | ||||
|   }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 moneromooo-monero
						moneromooo-monero