|
Monero
|
Transaction pool, handles transactions which are not part of a block. More...
#include <tx_pool.h>


Classes | |
| struct | tx_details |
| information about a single transaction More... | |
| struct | removed_tx_info |
Public Member Functions | |
| tx_memory_pool (Blockchain &bchs) | |
| Constructor. | |
| bool | add_tx (transaction &tx, const crypto::hash &id, const cryptonote::blobdata &blob, size_t tx_weight, tx_verification_context &tvc, relay_method tx_relay, bool relayed, uint8_t version, uint8_t nic_verified_hf_version=0) |
| bool | add_tx (transaction &tx, tx_verification_context &tvc, relay_method tx_relay, bool relayed, uint8_t version, uint8_t nic_verified_hf_version=0) |
| add a transaction to the transaction pool | |
| 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 &pruned, bool suppress_missing_msgs=false) |
| takes a transaction with the given hash from the pool | |
| bool | have_tx (const crypto::hash &id, relay_category tx_category) const |
| checks if the pool has a transaction with the given hash | |
| 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 | |
| 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 | |
| void | on_idle () |
| action to take periodically | |
| void | lock () const |
| locks the transaction pool | |
| void | unlock () const |
| unlocks the transaction pool | |
| bool | init (size_t max_txpool_weight=0, bool mine_stem_txes=false) |
| loads pool state (if any) from disk, and initializes pool | |
| bool | deinit () |
| attempts to save the transaction pool state to disk | |
| 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. | |
| void | get_transactions (std::vector< transaction > &txs, bool include_sensitive=false) const |
| get a list of all transactions in the pool | |
| void | get_transaction_hashes (std::vector< crypto::hash > &txs, bool include_sensitive=false) const |
| get a list of all transaction hashes in the pool | |
| void | get_transaction_backlog (std::vector< tx_backlog_entry > &backlog, bool include_sensitive=false) const |
| get (weight, fee, receive time) for all transaction in the pool | |
| void | get_block_template_backlog (std::vector< tx_block_template_backlog_entry > &backlog, bool include_sensitive=false) const |
| get (hash, weight, fee) for transactions in the pool - the minimum required information to create a block template | |
| void | get_transaction_stats (struct txpool_stats &stats, bool include_sensitive=false) const |
| get a summary statistics of all transaction hashes in the pool | |
| 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=false) const |
| get information about all transactions and key images in the pool | |
| 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 | |
| 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 | |
| bool | get_transaction (const crypto::hash &h, cryptonote::blobdata &txblob, relay_category tx_category) const |
| get a specific transaction from the pool | |
| bool | get_relayable_transactions (std::vector< std::tuple< crypto::hash, cryptonote::blobdata, relay_method > > &txs) |
| get a list of all relayable transactions and their hashes | |
| void | set_relayed (epee::span< const crypto::hash > hashes, relay_method tx_relay, std::vector< bool > &just_broadcasted) |
| tell the pool that certain transactions were just relayed | |
| size_t | get_transactions_count (bool include_sensitive=false) const |
| get the total number of transactions in the pool | |
| std::string | print_pool (bool short_format) const |
| get a string containing human-readable pool information | |
| size_t | validate (uint8_t version) |
| remove transactions from the pool which are no longer valid | |
| uint64_t | cookie () const |
| return the cookie | |
| size_t | get_txpool_weight () const |
| get the cumulative txpool weight in bytes | |
| void | set_txpool_max_weight (size_t bytes) |
| set the max cumulative txpool weight in bytes | |
| void | reduce_txpool_weight (size_t weight) |
| reduce the cumulative txpool weight by the weight provided | |
| bool | get_transaction_info (const crypto::hash &txid, tx_details &td, bool include_sensitive_data, bool include_blob=false) const |
| get infornation about a single transaction | |
| bool | get_transactions_info (const std::vector< crypto::hash > &txids, std::vector< std::pair< crypto::hash, tx_details > > &txs, bool include_sensitive_data=false) const |
| get information about multiple transactions | |
| bool | get_complement (const std::vector< crypto::hash > &hashes, std::vector< cryptonote::blobdata > &txes) const |
| get transactions not in the passed set | |
| bool | get_pool_info (time_t start_time, bool include_sensitive, size_t max_tx_count, std::vector< std::pair< crypto::hash, tx_details > > &added_txs, std::vector< crypto::hash > &remaining_added_txids, std::vector< crypto::hash > &removed_txs, bool &incremental) const |
| get info necessary for update of pool-related info in a wallet, preferably incremental | |
Private Types | |
| typedef std::unordered_map< crypto::key_image, std::unordered_set< crypto::hash > > | key_images_container |
| map key images to transactions which spent them | |
Private Member Functions | |
| bool | insert_key_images (const transaction_prefix &tx, const crypto::hash &txid, relay_method tx_relay) |
| insert key images into m_spent_key_images | |
| bool | remove_stuck_transactions () |
| remove old transactions from the pool | |
| bool | have_tx_keyimg_as_spent (const crypto::key_image &key_im, const crypto::hash &txid) const |
| check if a transaction in the pool has a given spent key image | |
| bool | have_tx_keyimges_as_spent (const transaction &tx, const crypto::hash &txid) const |
| check if any spent key image in a transaction is in the pool | |
| bool | remove_transaction_keyimages (const transaction_prefix &tx, const crypto::hash &txid) |
| forget a transaction's spent key images | |
| bool | is_transaction_ready_to_go (txpool_tx_meta_t &txd, const crypto::hash &txid, const cryptonote::blobdata_ref &txblob, transaction &tx) const |
| check if a transaction is a valid candidate for inclusion in a block | |
| bool | is_transaction_ready_to_go (txpool_tx_meta_t &txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const |
| void | mark_double_spend (const transaction &tx) |
| mark all transactions double spending the one passed | |
| void | prune (size_t bytes=0) |
| prune lowest fee/byte txes till we're not above bytes | |
| void | add_tx_to_transient_lists (const crypto::hash &txid, double fee, time_t receive_time) |
| void | remove_tx_from_transient_lists (const cryptonote::sorted_tx_container::iterator &sorted_it, const crypto::hash &txid, bool sensitive) |
| void | track_removed_tx (const crypto::hash &txid, bool sensitive) |
| sorted_tx_container::iterator | find_tx_in_sorted_container (const crypto::hash &id) const |
| get an iterator to a transaction in the sorted container | |
| 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 | |
Static Private Member Functions | |
| static bool | have_key_images (const std::unordered_set< crypto::key_image > &kic, const transaction_prefix &tx) |
| check if any of a transaction's spent key images are present in a given set | |
| static bool | append_key_images (std::unordered_set< crypto::key_image > &kic, const transaction_prefix &tx) |
| append the key images from a transaction to the given set | |
Private Attributes | |
| epee::critical_section | m_transactions_lock |
| lock for the pool | |
| key_images_container | m_spent_key_images |
| container for spent key images from the transactions in the pool | |
| epee::math_helper::once_a_time_seconds< 30 > | m_remove_stuck_tx_interval |
| interval on which to check for stale/"stuck" transactions | |
| sorted_tx_container | m_txs_by_fee_and_receive_time |
| < container for transactions organized by fee per size and receive time | |
| std::atomic< uint64_t > | m_cookie |
| incremented at each change | |
| std::unordered_map< crypto::hash, time_t > | m_added_txs_by_id |
| time_t | m_added_txs_start_time |
| std::multimap< time_t, removed_tx_info > | m_removed_txs_by_time |
| time_t | m_removed_txs_start_time |
| std::unordered_set< crypto::hash > | m_timed_out_transactions |
| transactions which are unlikely to be included in blocks | |
| Blockchain & | m_blockchain |
| reference to the Blockchain object | |
| size_t | m_txpool_max_weight |
| size_t | m_txpool_weight |
| bool | m_mine_stem_txes |
| std::unordered_map< crypto::hash, std::tuple< bool, tx_verification_context, uint64_t, crypto::hash > > | m_input_cache |
| std::unordered_map< crypto::hash, transaction > | m_parsed_tx_cache |
| std::atomic< time_t > | m_next_check |
| Next timestamp that a DB check for relayable txes is allowed. | |
Transaction pool, handles transactions which are not part of a block.
This class handles all transactions which have been received, but not as part of a block.
This handling includes: storing the transactions organizing the transactions by fee per weight unit taking/giving transactions to and from various other components saving the transactions to disk on shutdown helping create a new block template by choosing transactions for it
|
private |
map key images to transactions which spent them
this seems odd, but it seems that multiple transactions can exist in the pool which both have the same spent key. This would happen in the event of a reorg where someone creates a new/different transaction on the assumption that the original will not be in a block again.
| cryptonote::tx_memory_pool::tx_memory_pool | ( | Blockchain & | bchs | ) |
Constructor.
| bchs | a Blockchain class instance, for getting chain info |
| bool cryptonote::tx_memory_pool::add_tx | ( | transaction & | tx, |
| const crypto::hash & | id, | ||
| const cryptonote::blobdata & | blob, | ||
| size_t | tx_weight, | ||
| tx_verification_context & | tvc, | ||
| relay_method | tx_relay, | ||
| bool | relayed, | ||
| uint8_t | version, | ||
| uint8_t | nic_verified_hf_version = 0 ) |
| id | the transaction's hash @tx_relay how the transaction was received |
| tx_weight | the transaction's weight |
| bool cryptonote::tx_memory_pool::add_tx | ( | transaction & | tx, |
| tx_verification_context & | tvc, | ||
| relay_method | tx_relay, | ||
| bool | relayed, | ||
| uint8_t | version, | ||
| uint8_t | nic_verified_hf_version = 0 ) |
add a transaction to the transaction pool
Most likely the transaction will come from the network, but it is also possible for transactions to come from popped blocks during a reorg, or from local clients creating a transaction and submitting it to the network
| tx | the transaction to be added |
| tvc | return-by-reference status about the transaction verification @tx_relay how the transaction was received |
| relayed | was this transaction from the network or a local client? |
| version | the version used to create the transaction |
| nic_verified_hf_version | hard fork which "tx" is known to pass non-input consensus test |
If "nic_verified_hf_version" parameter is equal to "version" parameter, then we skip the asserting ver_non_input_consensus(tx), which greatly speeds up block popping and returning txs to mempool for txs which we know will pass the test. If nothing is known about how "tx" passes the non-input consensus tests (e.g. for newly received relayed txs), then leave "nic_verified_hf_version" as its default value of 0 (there is no v0 fork).
|
private |
|
staticprivate |
append the key images from a transaction to the given set
| kic | the set of key images to append to |
| tx | the transaction |
| bool cryptonote::tx_memory_pool::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
| key_images | [in] vector of key images to check |
| spent | [out] vector of bool to return |
|
private |
cache/call Blockchain::check_tx_inputs results
|
inline |
return the cookie
| bool cryptonote::tx_memory_pool::deinit | ( | ) |
attempts to save the transaction pool state to disk
Currently fails (returns false) if the data directory from init() does not exist and cannot be created, but returns true even if saving to disk is unsuccessful.
| bool cryptonote::tx_memory_pool::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.
| bl | return-by-reference the block to fill in with transactions |
| median_weight | the current median block weight |
| already_generated_coins | the current total number of coins "minted" |
| total_weight | return-by-reference the total weight of the new block |
| fee | return-by-reference the total of fees from the included transactions |
| expected_reward | return-by-reference the total reward awarded to the miner finding this block, including transaction fees |
| version | hard fork version to use for consensus rules |
|
private |
get an iterator to a transaction in the sorted container
| id | the hash of the transaction to look for |
| void cryptonote::tx_memory_pool::get_block_template_backlog | ( | std::vector< tx_block_template_backlog_entry > & | backlog, |
| bool | include_sensitive = false ) const |
get (hash, weight, fee) for transactions in the pool - the minimum required information to create a block template
Not all transactions in the pool will be returned for performance reasons If there are too many transactions in the pool, only the highest-paying transactions will be returned - but enough for the miner to create a full block
| backlog | return-by-reference that data |
| include_sensitive | return stempool, anonymity-pool, and unrelayed txes |
| bool cryptonote::tx_memory_pool::get_complement | ( | const std::vector< crypto::hash > & | hashes, |
| std::vector< cryptonote::blobdata > & | txes ) const |
get transactions not in the passed set
| bool cryptonote::tx_memory_pool::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
see documentation on tx_in_pool and key_images_with_tx_hashes for more details
| tx_infos | [out] the transactions' information |
| key_image_infos | [out] the spent key images' information |
| bool cryptonote::tx_memory_pool::get_pool_info | ( | time_t | start_time, |
| bool | include_sensitive, | ||
| size_t | max_tx_count, | ||
| std::vector< std::pair< crypto::hash, tx_details > > & | added_txs, | ||
| std::vector< crypto::hash > & | remaining_added_txids, | ||
| std::vector< crypto::hash > & | removed_txs, | ||
| bool & | incremental ) const |
get info necessary for update of pool-related info in a wallet, preferably incremental
| bool cryptonote::tx_memory_pool::get_relayable_transactions | ( | std::vector< std::tuple< crypto::hash, cryptonote::blobdata, relay_method > > & | txs | ) |
get a list of all relayable transactions and their hashes
"relayable" in this case means: nonzero fee hasn't been relayed too recently isn't old enough that relaying it is considered harmful Note a transaction can be "relayable" even if do_not_relay is true
This function will skip all DB checks if an insufficient amount of time since the last call.
| txs | return-by-reference the transactions and their hashes |
| bool cryptonote::tx_memory_pool::get_transaction | ( | const crypto::hash & | h, |
| cryptonote::blobdata & | txblob, | ||
| relay_category | tx_category ) const |
| void cryptonote::tx_memory_pool::get_transaction_backlog | ( | std::vector< tx_backlog_entry > & | backlog, |
| bool | include_sensitive = false ) const |
get (weight, fee, receive time) for all transaction in the pool
| txs | return-by-reference that data |
| include_sensitive | return stempool, anonymity-pool, and unrelayed txes |
| void cryptonote::tx_memory_pool::get_transaction_hashes | ( | std::vector< crypto::hash > & | txs, |
| bool | include_sensitive = false ) const |
get a list of all transaction hashes in the pool
| txs | return-by-reference the list of transactions |
| include_sensitive | return stempool, anonymity-pool, and unrelayed txes |
| bool cryptonote::tx_memory_pool::get_transaction_info | ( | const crypto::hash & | txid, |
| tx_details & | td, | ||
| bool | include_sensitive_data, | ||
| bool | include_blob = false ) const |
get infornation about a single transaction
| void cryptonote::tx_memory_pool::get_transaction_stats | ( | struct txpool_stats & | stats, |
| bool | include_sensitive = false ) const |
get a summary statistics of all transaction hashes in the pool
| stats | return-by-reference the pool statistics |
| include_sensitive | return stempool, anonymity-pool, and unrelayed txes |
| void cryptonote::tx_memory_pool::get_transactions | ( | std::vector< transaction > & | txs, |
| bool | include_sensitive = false ) const |
get a list of all transactions in the pool
| txs | return-by-reference the list of transactions |
| include_sensitive | return stempool, anonymity-pool, and unrelayed txes |
| bool cryptonote::tx_memory_pool::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 = false ) const |
get information about all transactions and key images in the pool
see documentation on tx_info and spent_key_image_info for more details
| tx_infos | return-by-reference the transactions' information |
| key_image_infos | return-by-reference the spent key images' information |
| include_sensitive_data | return stempool, anonymity-pool, and unrelayed txes and fields that are sensitive to the node privacy |
get the total number of transactions in the pool
| bool cryptonote::tx_memory_pool::get_transactions_info | ( | const std::vector< crypto::hash > & | txids, |
| std::vector< std::pair< crypto::hash, tx_details > > & | txs, | ||
| bool | include_sensitive_data = false ) const |
get information about multiple transactions
| size_t cryptonote::tx_memory_pool::get_txpool_weight | ( | ) | const |
get the cumulative txpool weight in bytes
|
staticprivate |
check if any of a transaction's spent key images are present in a given set
| kic | the set of key images to check against |
| tx | the transaction to check |
| bool cryptonote::tx_memory_pool::have_tx | ( | const crypto::hash & | id, |
| relay_category | tx_category ) const |
checks if the pool has a transaction with the given hash
| id | the hash to look for |
| tx_category | a filter for txes |
|
private |
check if a transaction in the pool has a given spent key image
| key_im | the spent key image to look for |
| txid | hash of the new transaction where key_im was seen. |
|
private |
check if any spent key image in a transaction is in the pool
Checks if any of the spent key images in a given transaction are present in any of the transactions in the transaction pool.
loads pool state (if any) from disk, and initializes pool
| max_txpool_weight | the max weight in bytes |
| mine_stem_txes | whether to mine txes in stem relay mode |
|
private |
insert key images into m_spent_key_images
|
private |
|
private |
check if a transaction is a valid candidate for inclusion in a block
| txd | the transaction to check (and info about it) |
| txid | the txid of the transaction to check |
| txblob | the transaction blob to check |
| tx | the parsed transaction, if successful |
| void cryptonote::tx_memory_pool::lock | ( | ) | const |
locks the transaction pool
|
private |
mark all transactions double spending the one passed
| bool cryptonote::tx_memory_pool::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
Currently does nothing
| new_block_height | the height of the blockchain after the change |
| top_block_id | the hash of the new top block |
| bool cryptonote::tx_memory_pool::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
Currently does nothing
| new_block_height | the height of the blockchain after the change |
| top_block_id | the hash of the new top block |
| void cryptonote::tx_memory_pool::on_idle | ( | ) |
action to take periodically
Currently checks transaction pool for stale ("stuck") transactions
| std::string cryptonote::tx_memory_pool::print_pool | ( | bool | short_format | ) | const |
get a string containing human-readable pool information
| short_format | whether to use a shortened format for the info |
|
private |
prune lowest fee/byte txes till we're not above bytes
if bytes is 0, use m_txpool_max_weight
| void cryptonote::tx_memory_pool::reduce_txpool_weight | ( | size_t | weight | ) |
reduce the cumulative txpool weight by the weight provided
| weight | the weight to reduce the total txpool weight by |
|
private |
remove old transactions from the pool
After a certain time, it is assumed that a transaction which has not yet been mined will likely not be mined. These transactions are removed from the pool to avoid buildup.
|
private |
forget a transaction's spent key images
Spent key images are stored separately from transactions for convenience/speed, so this is part of the process of removing a transaction from the pool.
| tx | the transaction |
| txid | the transaction's hash |
|
private |
| void cryptonote::tx_memory_pool::set_relayed | ( | epee::span< const crypto::hash > | hashes, |
| relay_method | tx_relay, | ||
| std::vector< bool > & | just_broadcasted ) |
tell the pool that certain transactions were just relayed
| hashes | list of tx hashes that are about to be relayed |
| tx_relay | update how the tx left this node |
| just_broadcasted | true if a tx was just broadcasted |
| void cryptonote::tx_memory_pool::set_txpool_max_weight | ( | size_t | bytes | ) |
set the max cumulative txpool weight in bytes
| bytes | the max cumulative txpool weight in bytes |
| bool cryptonote::tx_memory_pool::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 & | pruned, | ||
| bool | suppress_missing_msgs = false ) |
takes a transaction with the given hash from the pool
| id | the hash of the transaction |
| tx | return-by-reference the transaction taken |
| txblob | return-by-reference the transaction as a blob |
| tx_weight | return-by-reference the transaction's weight |
| fee | the transaction fee |
| relayed | return-by-reference was transaction relayed to us by the network? |
| do_not_relay | return-by-reference is transaction not to be relayed to the network? |
| double_spend_seen | return-by-reference was a double spend seen for that transaction? |
| pruned | return-by-reference is the tx pruned |
| suppress_missing_msgs | suppress warning msgs when txid is missing (optional, defaults to false) |
|
private |
| void cryptonote::tx_memory_pool::unlock | ( | ) | const |
unlocks the transaction pool
| size_t cryptonote::tx_memory_pool::validate | ( | uint8_t | version | ) |
remove transactions from the pool which are no longer valid
With new versions of the currency, what conditions render a transaction invalid may change. This function clears those which were received before a version change and no longer conform to requirements.
| version | the version the transactions must conform to |
|
private |
|
private |
|
private |
reference to the Blockchain object
|
private |
incremented at each change
|
mutableprivate |
|
private |
|
private |
Next timestamp that a DB check for relayable txes is allowed.
|
private |
|
private |
interval on which to check for stale/"stuck" transactions
|
private |
|
private |
|
private |
container for spent key images from the transactions in the pool
|
private |
transactions which are unlikely to be included in blocks
These transactions are kept in RAM in case they are included in a block eventually, but this container is not saved to disk.
|
mutableprivate |
lock for the pool
|
private |
|
private |
|
private |
< container for transactions organized by fee per size and receive time