Electroneum
Loading...
Searching...
No Matches
tx_pool.h
Go to the documentation of this file.
1// Copyrights(c) 2017-2021, The Electroneum Project
2// Copyrights(c) 2014-2019, The Monero Project
3//
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without modification, are
7// permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice, this list of
10// conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13// of conditions and the following disclaimer in the documentation and/or other
14// materials provided with the distribution.
15//
16// 3. Neither the name of the copyright holder nor the names of its contributors may be
17// used to endorse or promote products derived from this software without specific
18// prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31
32#pragma once
33#include "include_base_utils.h"
34
35#include <set>
36#include <unordered_map>
37#include <unordered_set>
38#include <queue>
39#include <boost/serialization/version.hpp>
40#include <boost/utility.hpp>
41
42#include "string_tools.h"
43#include "syncobj.h"
44#include "math_helper.h"
48#include "crypto/hash.h"
51
52namespace cryptonote
53{
54 class Blockchain;
55 /************************************************************************/
56 /* */
57 /************************************************************************/
58
60 typedef std::pair<std::pair<double, std::time_t>, crypto::hash> tx_by_fee_and_receive_time_entry;
61
63 {
64 public:
66 {
67 // sort by greatest first, not least
68 if (a.first.first > b.first.first) return true;
69 else if (a.first.first < b.first.first) return false;
70 else if (a.first.second < b.first.second) return true;
71 else if (a.first.second > b.first.second) return false;
72 else if (a.second != b.second) return true;
73 else return false;
74 }
75 };
76
78 typedef std::set<tx_by_fee_and_receive_time_entry, txCompare> sorted_tx_container;
79
94 class tx_memory_pool: boost::noncopyable
95 {
96 public:
103
104
111 bool add_tx(transaction &tx, const crypto::hash &id, const cryptonote::blobdata &blob, size_t tx_weight, tx_verification_context& tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version);
112
130 bool add_tx(transaction &tx, tx_verification_context& tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version);
131
147 bool take_tx(const crypto::hash &id, transaction &tx, cryptonote::blobdata &txblob, size_t& tx_weight, uint64_t& fee, bool &relayed, bool &do_not_relay, bool &double_spend_seen, bool &nonexistent_utxo_seen);
148
156 bool have_tx(const crypto::hash &id) const;
157
168 bool on_blockchain_inc(uint64_t new_block_height, const crypto::hash& top_block_id);
169
180 bool on_blockchain_dec(uint64_t new_block_height, const crypto::hash& top_block_id);
181
187 void on_idle();
188
192 void lock() const;
193
197 void unlock() const;
198
199 // load/store operations
200
208 bool init(size_t max_txpool_weight = 0);
209
219 bool deinit();
220
234 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);
235
243 void get_transactions(std::vector<transaction>& txs, bool include_unrelayed_txes = true) const;
244
252 void get_transaction_hashes(std::vector<crypto::hash>& txs, bool include_unrelayed_txes = true) const;
253
261 void get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_unrelayed_txes = true) const;
262
270 void get_transaction_stats(struct txpool_stats& stats, bool include_unrelayed_txes = true) const;
271
278 bool utxo_spent_in_pool(const txin_to_key_public& in) const;
279
291 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;
292
303 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;
304
313 bool check_for_key_images(const std::vector<crypto::key_image>& key_images, std::vector<bool> spent) const;
314
323 bool get_transaction(const crypto::hash& h, cryptonote::blobdata& txblob) const;
324
338 bool get_relayable_transactions(std::vector<std::pair<crypto::hash, cryptonote::blobdata>>& txs) const;
339
345 void set_relayed(const std::vector<std::pair<crypto::hash, cryptonote::blobdata>>& txs);
346
352 size_t get_transactions_count(bool include_unrelayed_txes = true) const;
353
361 std::string print_pool(bool short_format) const;
362
374 size_t validate(uint8_t version);
375
381 uint64_t cookie() const { return m_cookie; }
382
388 size_t get_txpool_weight() const;
389
395 void set_txpool_max_weight(size_t bytes);
396
397#define CURRENT_MEMPOOL_ARCHIVE_VER 11
398#define CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER 13
399
441
442 private:
443
449 bool insert_key_images(const transaction_prefix &tx, const crypto::hash &txid, bool kept_by_block);
450
451 bool insert_utxos(const transaction_prefix &tx, const crypto::hash &id, bool kept_by_block);
452
462 bool remove_stuck_transactions();
463
471 bool have_tx_keyimg_as_spent(const crypto::key_image& key_im) const;
472
473 bool have_tx_utxo_as_spent(const txin_to_key_public& in) const;
474
487
488 bool key_images_already_spent(const transaction &tx) const;
489
497
498 bool utxo_nonexistent(const transaction &tx) const;
499
500
513
514
515 bool remove_transaction_keyimages(const transaction_prefix& tx, const crypto::hash &txid);
516
525 static bool have_key_images(const std::unordered_set<crypto::key_image>& kic, const transaction_prefix& tx);
526
527 static bool have_utxos(const std::unordered_set<std::string>& utxos, const transaction_prefix& tx);
528
537 static bool append_key_images(std::unordered_set<crypto::key_image>& kic, const transaction_prefix& tx);
538
539 static bool append_utxos(std::unordered_set<std::string>& utxos, const transaction_prefix& tx);
540
551 bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction&tx) const;
552
556 void mark_double_spend_or_nonexistent_utxo(const transaction &tx);
557
563 void prune(size_t bytes = 0);
564
565 //TODO: confirm the below comments and investigate whether or not this
566 // is the desired behavior
568
574 typedef std::unordered_map<crypto::key_image, std::unordered_set<crypto::hash> > key_images_container;
575
576 typedef std::unordered_map<std::string, std::unordered_set<crypto::hash> > utxos_container;
577
578#if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
579public:
580#endif
581 mutable epee::critical_section m_transactions_lock;
582#if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
583private:
584#endif
585
587 key_images_container m_spent_key_images;
588
590 utxos_container m_spent_utxos;
591
592 //TODO: this time should be a named constant somewhere, not hard-coded
594 epee::math_helper::once_a_time_seconds<30> m_remove_stuck_tx_interval;
595
596 //TODO: look into doing this better
598 sorted_tx_container m_txs_by_fee_and_receive_time;
599
600 std::atomic<uint64_t> m_cookie;
601
609 sorted_tx_container::iterator find_tx_in_sorted_container(const crypto::hash& id) const;
610
612 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;
613
615
618 std::unordered_set<crypto::hash> m_timed_out_transactions;
619
620 Blockchain& m_blockchain;
621
622 size_t m_txpool_max_weight;
623 size_t m_txpool_weight;
624
625 mutable std::unordered_map<crypto::hash, std::tuple<bool, tx_verification_context, uint64_t, crypto::hash>> m_input_cache;
626
627 std::unordered_map<crypto::hash, transaction> m_parsed_tx_cache;
628 };
629}
630
631namespace boost
632{
633 namespace serialization
634 {
635 template<class archive_t>
636 void serialize(archive_t & ar, cryptonote::tx_memory_pool::tx_details& td, const unsigned int version)
637 {
638 ar & td.blob_size;
639 ar & td.fee;
640 ar & td.tx;
641 ar & td.max_used_block_height;
642 ar & td.max_used_block_id;
643 ar & td.last_failed_height;
644 ar & td.last_failed_id;
645 ar & td.receive_time;
646 ar & td.last_relayed_time;
647 ar & td.relayed;
648 if (version < 11)
649 return;
650 ar & td.kept_by_block;
651 if (version < 12)
652 return;
653 ar & td.do_not_relay;
654 if (version < 13)
655 return;
656 ar & td.weight;
657 }
658 }
659}
662
663
664
uint8_t version
Transaction pool, handles transactions which are not part of a block.
Definition tx_pool.h:95
void unlock() const
unlocks the transaction pool
Definition tx_pool.cpp:1279
void lock() const
locks the transaction pool
Definition tx_pool.cpp:1274
void on_idle()
action to take periodically
Definition tx_pool.cpp:777
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:1121
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:1207
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:1554
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:889
bool have_tx(const crypto::hash &id) const
checks if the pool has a transaction with the given hash
Definition tx_pool.cpp:1215
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:1199
bool utxo_spent_in_pool(const txin_to_key_public &in) const
get a summary statistics of all transaction hashes in the pool
Definition tx_pool.cpp:1239
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:942
bool add_tx(transaction &tx, const crypto::hash &id, const cryptonote::blobdata &blob, 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:122
uint64_t cookie() const
return the cookie
Definition tx_pool.h:381
void set_txpool_max_weight(size_t bytes)
set the max cumulative txpool weight in bytes
Definition tx_pool.cpp:560
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:923
bool take_tx(const crypto::hash &id, transaction &tx, cryptonote::blobdata &txblob, size_t &tx_weight, uint64_t &fee, bool &relayed, bool &do_not_relay, bool &double_spend_seen, bool &nonexistent_utxo_seen)
takes a transaction with the given hash from the pool
Definition tx_pool.cpp:721
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:1045
bool init(size_t max_txpool_weight=0)
loads pool state (if any) from disk, and initializes pool
Definition tx_pool.cpp:1750
std::string print_pool(bool short_format) const
get a string containing human-readable pool information
Definition tx_pool.cpp:1521
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:953
bool add_tx(transaction &tx, tx_verification_context &tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version)
add a transaction to the transaction pool
tx_memory_pool(Blockchain &bchs)
Constructor.
Definition tx_pool.cpp:117
size_t validate(uint8_t version)
remove transactions from the pool which are no longer valid
Definition tx_pool.cpp:1686
size_t get_txpool_weight() const
get the cumulative txpool weight in bytes
Definition tx_pool.cpp:554
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:965
size_t get_transactions_count(bool include_unrelayed_txes=true) const
get the total number of transactions in the pool
Definition tx_pool.cpp:916
bool get_transaction(const crypto::hash &h, cryptonote::blobdata &txblob) const
get a specific transaction from the pool
Definition tx_pool.cpp:1185
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:855
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:1170
bool deinit()
attempts to save the transaction pool state to disk
Definition tx_pool.cpp:1819
bool operator()(const tx_by_fee_and_receive_time_entry &a, const tx_by_fee_and_receive_time_entry &b) const
Definition tx_pool.h:65
BOOST_CLASS_VERSION(nodetool::node_server< cryptonote::t_cryptonote_protocol_handler< tests::proxy_core > >, 1)
void serialize(Archive &a, std::unordered_map< h_key, hval > &x, const boost::serialization::version_type ver)
POD_CLASS key_image
Definition crypto.h:105
POD_CLASS hash
Definition hash.h:50
std::unordered_map< crypto::key_image, std::vector< crypto::hash > > key_images_with_tx_hashes
Holds cryptonote related classes and helpers.
Definition ban.cpp:40
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:78
std::string blobdata
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:60
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
unsigned char uint8_t
Definition stdint.h:124
unsigned __int64 uint64_t
Definition stdint.h:136
information about a single transaction
Definition tx_pool.h:404
transaction tx
the transaction
Definition tx_pool.h:405
bool do_not_relay
to avoid relay this transaction to the network
Definition tx_pool.h:436
uint64_t max_used_block_height
the height of the highest block referenced by an input
Definition tx_pool.h:410
crypto::hash last_failed_id
the hash of the highest block the transaction referenced when last checking it failed
Definition tx_pool.h:430
uint64_t fee
the transaction's fee amount
Definition tx_pool.h:408
bool kept_by_block
whether or not the transaction has been in a block before
Definition tx_pool.h:416
size_t weight
the transaction's weight
Definition tx_pool.h:407
time_t last_relayed_time
the last time the transaction was relayed to the network
Definition tx_pool.h:434
bool relayed
whether or not the transaction has been relayed to the network
Definition tx_pool.h:435
crypto::hash max_used_block_id
the hash of the highest block referenced by an input
Definition tx_pool.h:409
size_t blob_size
the transaction's size
Definition tx_pool.h:406
uint64_t last_failed_height
the highest block the transaction referenced when last checking it failed
Definition tx_pool.h:423
bool double_spend_seen
true iff another tx was seen double spending this one
Definition tx_pool.h:438
time_t receive_time
the time when the transaction entered the pool
Definition tx_pool.h:432
a struct containing txpool per transaction metadata
#define CURRENT_MEMPOOL_ARCHIVE_VER
Definition tx_pool.h:397
#define CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER
Definition tx_pool.h:398