Monero
tx_pool.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2018, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30 
31 #pragma once
32 #include "include_base_utils.h"
33 
34 #include <set>
35 #include <unordered_map>
36 #include <unordered_set>
37 #include <queue>
38 #include <boost/serialization/version.hpp>
39 #include <boost/utility.hpp>
40 
41 #include "string_tools.h"
42 #include "syncobj.h"
43 #include "math_helper.h"
47 #include "crypto/hash.h"
50 
51 namespace cryptonote
52 {
53  class Blockchain;
54  /************************************************************************/
55  /* */
56  /************************************************************************/
57 
59  typedef std::pair<std::pair<double, std::time_t>, crypto::hash> tx_by_fee_and_receive_time_entry;
60 
61  class txCompare
62  {
63  public:
65  {
66  // sort by greatest first, not least
67  if (a.first.first > b.first.first) return true;
68  else if (a.first.first < b.first.first) return false;
69  else if (a.first.second < b.first.second) return true;
70  else if (a.first.second > b.first.second) return false;
71  else if (a.second != b.second) return true;
72  else return false;
73  }
74  };
75 
77  typedef std::set<tx_by_fee_and_receive_time_entry, txCompare> sorted_tx_container;
78 
93  class tx_memory_pool: boost::noncopyable
94  {
95  public:
101  tx_memory_pool(Blockchain& bchs);
102 
103 
110  bool add_tx(transaction &tx, const crypto::hash &id, size_t tx_weight, tx_verification_context& tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version);
111 
129  bool add_tx(transaction &tx, tx_verification_context& tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version);
130 
144  bool take_tx(const crypto::hash &id, transaction &tx, size_t& tx_weight, uint64_t& fee, bool &relayed, bool &do_not_relay, bool &double_spend_seen);
145 
153  bool have_tx(const crypto::hash &id) const;
154 
165  bool on_blockchain_inc(uint64_t new_block_height, const crypto::hash& top_block_id);
166 
177  bool on_blockchain_dec(uint64_t new_block_height, const crypto::hash& top_block_id);
178 
184  void on_idle();
185 
189  void lock() const;
190 
194  void unlock() const;
195 
196  // load/store operations
197 
205  bool init(size_t max_txpool_weight = 0);
206 
216  bool deinit();
217 
231  bool fill_block_template(block &bl, size_t median_weight, uint64_t already_generated_coins, size_t &total_weight, uint64_t &fee, uint64_t &expected_reward, uint8_t version);
232 
240  void get_transactions(std::vector<transaction>& txs, bool include_unrelayed_txes = true) const;
241 
249  void get_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const;
250 
258  void get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_unrelayed_txes = true) const;
259 
267  void get_transaction_stats(struct txpool_stats& stats, bool include_unrelayed_txes = true) const;
268 
280  bool get_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_sensitive_data = true) const;
281 
292  bool get_pool_for_rpc(std::vector<cryptonote::rpc::tx_in_pool>& tx_infos, cryptonote::rpc::key_images_with_tx_hashes& key_image_infos) const;
293 
302  bool check_for_key_images(const std::vector<crypto::key_image>& key_images, std::vector<bool> spent) const;
303 
312  bool get_transaction(const crypto::hash& h, cryptonote::blobdata& txblob) const;
313 
327  bool get_relayable_transactions(std::vector<std::pair<crypto::hash, cryptonote::blobdata>>& txs) const;
328 
334  void set_relayed(const std::vector<std::pair<crypto::hash, cryptonote::blobdata>>& txs);
335 
341  size_t get_transactions_count(bool include_unrelayed_txes = true) const;
342 
350  std::string print_pool(bool short_format) const;
351 
363  size_t validate(uint8_t version);
364 
370  uint64_t cookie() const { return m_cookie; }
371 
377  size_t get_txpool_weight() const;
378 
384  void set_txpool_max_weight(size_t bytes);
385 
386 #define CURRENT_MEMPOOL_ARCHIVE_VER 11
387 #define CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER 13
388 
392  struct tx_details
393  {
395  size_t blob_size;
396  size_t weight;
397  uint64_t fee;
400 
402 
406 
408 
413 
415 
420 
421  time_t receive_time;
422 
424  bool relayed;
426 
428  };
429 
430  private:
431 
437  bool insert_key_images(const transaction &tx, bool kept_by_block);
438 
449 
457  bool have_tx_keyimg_as_spent(const crypto::key_image& key_im) const;
458 
471  bool have_tx_keyimges_as_spent(const transaction& tx) const;
472 
485 
494  static bool have_key_images(const std::unordered_set<crypto::key_image>& kic, const transaction& tx);
495 
504  static bool append_key_images(std::unordered_set<crypto::key_image>& kic, const transaction& tx);
505 
516  bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const;
517 
521  void mark_double_spend(const transaction &tx);
522 
528  void prune(size_t bytes = 0);
529 
530  //TODO: confirm the below comments and investigate whether or not this
531  // is the desired behavior
533 
539  typedef std::unordered_map<crypto::key_image, std::unordered_set<crypto::hash> > key_images_container;
540 
541 #if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
542 public:
543 #endif
544  mutable epee::critical_section m_transactions_lock;
545 #if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
546 private:
547 #endif
548 
551 
552  //TODO: this time should be a named constant somewhere, not hard-coded
554  epee::math_helper::once_a_time_seconds<30> m_remove_stuck_tx_interval;
555 
556  //TODO: look into doing this better
559 
560  std::atomic<uint64_t> m_cookie;
561 
569  sorted_tx_container::iterator find_tx_in_sorted_container(const crypto::hash& id) const;
570 
572  bool check_tx_inputs(const std::function<cryptonote::transaction&(void)> &get_tx, const crypto::hash &txid, uint64_t &max_used_block_height, crypto::hash &max_used_block_id, tx_verification_context &tvc, bool kept_by_block = false) const;
573 
575 
578  std::unordered_set<crypto::hash> m_timed_out_transactions;
579 
581 
584 
585  mutable std::unordered_map<crypto::hash, std::tuple<bool, tx_verification_context, uint64_t, crypto::hash>> m_input_cache;
586  };
587 }
588 
589 namespace boost
590 {
591  namespace serialization
592  {
593  template<class archive_t>
594  void serialize(archive_t & ar, cryptonote::tx_memory_pool::tx_details& td, const unsigned int version)
595  {
596  ar & td.blob_size;
597  ar & td.fee;
598  ar & td.tx;
599  ar & td.max_used_block_height;
600  ar & td.max_used_block_id;
601  ar & td.last_failed_height;
602  ar & td.last_failed_id;
603  ar & td.receive_time;
604  ar & td.last_relayed_time;
605  ar & td.relayed;
606  if (version < 11)
607  return;
608  ar & td.kept_by_block;
609  if (version < 12)
610  return;
611  ar & td.do_not_relay;
612  if (version < 13)
613  return;
614  ar & td.weight;
615  }
616  }
617 }
620 
621 
622 
void on_idle()
action to take periodically
Definition: tx_pool.cpp:499
Definition: binary_utils.h:36
#define CURRENT_MEMPOOL_ARCHIVE_VER
Definition: tx_pool.h:386
bool relayed
whether or not the transaction has been relayed to the network
Definition: tx_pool.h:424
uint64_t cookie() const
return the cookie
Definition: tx_pool.h:370
crypto::hash max_used_block_id
the hash of the highest block referenced by an input
Definition: tx_pool.h:398
crypto::hash last_failed_id
the hash of the highest block the transaction referenced when last checking it failed ...
Definition: tx_pool.h:419
uint64_t max_used_block_height
the height of the highest block referenced by an input
Definition: tx_pool.h:399
Definition: tx_pool.h:61
bool operator()(const tx_by_fee_and_receive_time_entry &a, const tx_by_fee_and_receive_time_entry &b)
Definition: tx_pool.h:64
Definition: unordered_containers_boost_serialization.h:37
bool take_tx(const crypto::hash &id, transaction &tx, size_t &tx_weight, uint64_t &fee, bool &relayed, bool &do_not_relay, bool &double_spend_seen)
takes a transaction with the given hash from the pool
Definition: tx_pool.cpp:453
Definition: cryptonote_basic.h:366
void serialize(Archive &a, std::unordered_map< h_key, hval > &x, const boost::serialization::version_type ver)
Definition: unordered_containers_boost_serialization.h:126
void get_transactions(std::vector< transaction > &txs, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
Definition: tx_pool.cpp:641
size_t get_txpool_weight() const
get the cumulative txpool weight in bytes
Definition: tx_pool.cpp:331
key_images_container m_spent_key_images
container for spent key images from the transactions in the pool
Definition: tx_pool.h:550
bool remove_stuck_transactions()
remove old transactions from the pool
Definition: tx_pool.cpp:514
epee::critical_section m_transactions_lock
lock for the pool
Definition: tx_pool.h:544
void get_transaction_hashes(std::vector< crypto::hash > &txs, bool include_unrelayed_txes=true) const
get a list of all transaction hashes in the pool
Definition: tx_pool.cpp:659
void mark_double_spend(const transaction &tx)
mark all transactions double spending the one passed
Definition: tx_pool.cpp:1066
std::unordered_set< crypto::hash > m_timed_out_transactions
transactions which are unlikely to be included in blocks
Definition: tx_pool.h:578
transaction tx
the transaction
Definition: tx_pool.h:394
sorted_tx_container::iterator find_tx_in_sorted_container(const crypto::hash &id) const
get an iterator to a transaction in the sorted container
Definition: tx_pool.cpp:504
bool do_not_relay
to avoid relay this transaction to the network
Definition: tx_pool.h:425
bool check_tx_inputs(const std::function< cryptonote::transaction &(void)> &get_tx, const crypto::hash &txid, uint64_t &max_used_block_height, crypto::hash &max_used_block_id, tx_verification_context &tvc, bool kept_by_block=false) const
cache/call Blockchain::check_tx_inputs results
Definition: tx_pool.cpp:960
size_t get_transactions_count(bool include_unrelayed_txes=true) const
get the total number of transactions in the pool
Definition: tx_pool.cpp:634
time_t receive_time
the time when the transaction entered the pool
Definition: tx_pool.h:421
std::unordered_map< crypto::key_image, std::vector< crypto::hash > > key_images_with_tx_hashes
Definition: message_data_structs.h:102
#define CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER
Definition: tx_pool.h:387
BOOST_CLASS_VERSION(nodetool::node_server< cryptonote::t_cryptonote_protocol_handler< cryptonote::core > >, 1)
bool init(size_t max_txpool_weight=0)
loads pool state (if any) from disk, and initializes pool
Definition: tx_pool.cpp:1328
Holds cryptonote related classes and helpers.
Definition: db_bdb.cpp:224
Definition: verification_context.h:37
bool on_blockchain_inc(uint64_t new_block_height, const crypto::hash &top_block_id)
action to take when notified of a block added to the blockchain
Definition: tx_pool.cpp:910
size_t validate(uint8_t version)
remove transactions from the pool which are no longer valid
Definition: tx_pool.cpp:1265
std::unordered_map< crypto::hash, std::tuple< bool, tx_verification_context, uint64_t, crypto::hash > > m_input_cache
Definition: tx_pool.h:585
bool insert_key_images(const transaction &tx, bool kept_by_block)
insert key images into m_spent_key_images
Definition: tx_pool.cpp:401
bool have_tx_keyimg_as_spent(const crypto::key_image &key_im) const
check if a transaction in the pool has a given spent key image
Definition: tx_pool.cpp:944
std::pair< std::pair< double, std::time_t >, crypto::hash > tx_by_fee_and_receive_time_entry
pair of <transaction fee, transaction hash> for organization
Definition: tx_pool.h:53
size_t blob_size
the transaction&#39;s size
Definition: tx_pool.h:395
int b
Definition: base.py:1
uint64_t last_failed_height
the highest block the transaction referenced when last checking it failed
Definition: tx_pool.h:412
void set_relayed(const std::vector< std::pair< crypto::hash, cryptonote::blobdata >> &txs)
tell the pool that certain transactions were just relayed
Definition: tx_pool.cpp:608
bool get_transactions_and_spent_keys_info(std::vector< tx_info > &tx_infos, std::vector< spent_key_image_info > &key_image_infos, bool include_sensitive_data=true) const
get information about all transactions and key images in the pool
Definition: tx_pool.cpp:760
bool is_transaction_ready_to_go(txpool_tx_meta_t &txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const
check if a transaction is a valid candidate for inclusion in a block
Definition: tx_pool.cpp:979
uint64_t fee
the transaction&#39;s fee amount
Definition: tx_pool.h:397
size_t m_txpool_weight
Definition: tx_pool.h:583
void get_transaction_backlog(std::vector< tx_backlog_entry > &backlog, bool include_unrelayed_txes=true) const
get (weight, fee, receive time) for all transaction in the pool
Definition: tx_pool.cpp:670
tx_memory_pool(Blockchain &bchs)
Constructor.
Definition: tx_pool.cpp:109
bool add_tx(transaction &tx, const crypto::hash &id, size_t tx_weight, tx_verification_context &tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version)
Definition: tx_pool.cpp:114
size_t weight
the transaction&#39;s weight
Definition: tx_pool.h:396
uint8_t version
Definition: blockchain.cpp:87
bool check_for_key_images(const std::vector< crypto::key_image > &key_images, std::vector< bool > spent) const
check for presence of key images in the pool
Definition: tx_pool.cpp:881
bool remove_transaction_keyimages(const transaction &tx)
forget a transaction&#39;s spent key images
Definition: tx_pool.cpp:421
Transaction pool, handles transactions which are not part of a block.
Definition: tx_pool.h:93
std::string blobdata
Definition: blobdatatype.h:35
Definition: core_rpc_server_commands_defs.h:1540
void unlock() const
unlocks the transaction pool
Definition: tx_pool.cpp:955
bool deinit()
attempts to save the transaction pool state to disk
Definition: tx_pool.cpp:1390
bool have_tx_keyimges_as_spent(const transaction &tx) const
check if any spent key image in a transaction is in the pool
Definition: tx_pool.cpp:931
bool get_transaction(const crypto::hash &h, cryptonote::blobdata &txblob) const
get a specific transaction from the pool
Definition: tx_pool.cpp:896
information about a single transaction
Definition: tx_pool.h:392
POD_CLASS key_image
Definition: crypto.h:89
std::set< tx_by_fee_and_receive_time_entry, txCompare > sorted_tx_container
container for sorting transactions by fee per unit size
Definition: tx_pool.h:77
a struct containing txpool per transaction metadata
Definition: blockchain_db.h:136
void set_txpool_max_weight(size_t bytes)
set the max cumulative txpool weight in bytes
Definition: tx_pool.cpp:337
bool kept_by_block
whether or not the transaction has been in a block before
Definition: tx_pool.h:405
string a
Definition: MakeCryptoOps.py:15
bool have_tx(const crypto::hash &id) const
checks if the pool has a transaction with the given hash
Definition: tx_pool.cpp:924
bool fill_block_template(block &bl, size_t median_weight, uint64_t already_generated_coins, size_t &total_weight, uint64_t &fee, uint64_t &expected_reward, uint8_t version)
Chooses transactions for a block to include.
Definition: tx_pool.cpp:1141
void prune(size_t bytes=0)
prune lowest fee/byte txes till we&#39;re not above bytes
Definition: tx_pool.cpp:343
static bool have_key_images(const std::unordered_set< crypto::key_image > &kic, const transaction &tx)
check if any of a transaction&#39;s spent key images are present in a given set
Definition: tx_pool.cpp:1044
epee::math_helper::once_a_time_seconds< 30 > m_remove_stuck_tx_interval
interval on which to check for stale/"stuck" transactions
Definition: tx_pool.h:554
POD_CLASS hash
Definition: hash.h:49
bool on_blockchain_dec(uint64_t new_block_height, const crypto::hash &top_block_id)
action to take when notified of a block removed from the blockchain
Definition: tx_pool.cpp:917
time_t last_relayed_time
the last time the transaction was relayed to the network
Definition: tx_pool.h:423
size_t m_txpool_max_weight
Definition: tx_pool.h:582
static bool append_key_images(std::unordered_set< crypto::key_image > &kic, const transaction &tx)
append the key images from a transaction to the given set
Definition: tx_pool.cpp:1055
sorted_tx_container m_txs_by_fee_and_receive_time
< container for transactions organized by fee per size and receive time
Definition: tx_pool.h:558
void lock() const
locks the transaction pool
Definition: tx_pool.cpp:950
bool double_spend_seen
true iff another tx was seen double spending this one
Definition: tx_pool.h:427
Blockchain & m_blockchain
reference to the Blockchain object
Definition: tx_pool.h:580
void get_transaction_stats(struct txpool_stats &stats, bool include_unrelayed_txes=true) const
get a summary statistics of all transaction hashes in the pool
Definition: tx_pool.cpp:682
Definition: cryptonote_basic.h:182
bool get_pool_for_rpc(std::vector< cryptonote::rpc::tx_in_pool > &tx_infos, cryptonote::rpc::key_images_with_tx_hashes &key_image_infos) const
get information about all transactions and key images in the pool
Definition: tx_pool.cpp:833
std::atomic< uint64_t > m_cookie
incremented at each change
Definition: tx_pool.h:560
std::string print_pool(bool short_format) const
get a string containing human-readable pool information
Definition: tx_pool.cpp:1109
Definition: blockchain.h:77
bool get_relayable_transactions(std::vector< std::pair< crypto::hash, cryptonote::blobdata >> &txs) const
get a list of all relayable transactions and their hashes
Definition: tx_pool.cpp:575
std::unordered_map< crypto::key_image, std::unordered_set< crypto::hash > > key_images_container
map key images to transactions which spent them
Definition: tx_pool.h:539