aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp29
-rw-r--r--src/cryptonote_core/blockchain.h11
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp31
-rw-r--r--src/cryptonote_core/cryptonote_core.h12
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp8
-rw-r--r--src/cryptonote_core/tx_pool.cpp52
-rw-r--r--src/cryptonote_core/tx_pool.h13
7 files changed, 109 insertions, 47 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index e94024ae5..5c6819fa9 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -52,6 +52,7 @@
#include "cryptonote_core.h"
#include "ringct/rctSigs.h"
#include "common/perf_timer.h"
+#include "common/notify.h"
#if defined(PER_BLOCK_CHECKPOINT)
#include "blocks/blocks.h"
#endif
@@ -137,8 +138,8 @@ static const struct {
{ 6, 971400, 0, 1501709789 },
{ 7, 1057027, 0, 1512211236 },
- { 8, 1057058, 0, 1515967497 },
- { 9, 1057778, 0, 1515967498 },
+ { 8, 1057058, 0, 1533211200 },
+ { 9, 1057778, 0, 1533297600 },
};
static const uint64_t testnet_hard_fork_version_1_till = 624633;
@@ -158,6 +159,8 @@ static const struct {
{ 5, 35000, 0, 1521360000 },
{ 6, 36000, 0, 1521480000 },
{ 7, 37000, 0, 1521600000 },
+ { 8, 176456, 0, 1537821770 },
+ { 9, 177176, 0, 1537821771 },
};
//------------------------------------------------------------------
@@ -341,6 +344,9 @@ uint64_t Blockchain::get_current_blockchain_height() const
bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options, difficulty_type fixed_difficulty)
{
LOG_PRINT_L3("Blockchain::" << __func__);
+
+ CHECK_AND_ASSERT_MES(nettype != FAKECHAIN || test_options, false, "fake chain network type used without options");
+
CRITICAL_REGION_LOCAL(m_tx_pool);
CRITICAL_REGION_LOCAL1(m_blockchain_lock);
@@ -1827,15 +1833,10 @@ bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height,
{
std::vector<uint64_t> heights;
heights.reserve(to_height + 1 - start_height);
- uint64_t real_start_height = start_height > 0 ? start_height-1 : start_height;
- for (uint64_t h = real_start_height; h <= to_height; ++h)
+ for (uint64_t h = start_height; h <= to_height; ++h)
heights.push_back(h);
distribution = m_db->get_block_cumulative_rct_outputs(heights);
- if (start_height > 0)
- {
- base = distribution[0];
- distribution.erase(distribution.begin());
- }
+ base = 0;
return true;
}
else
@@ -2375,7 +2376,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
const bool bulletproof = rct::is_rct_bulletproof(tx.rct_signatures.type);
if (bulletproof || !tx.rct_signatures.p.bulletproofs.empty())
{
- MERROR("Bulletproofs are not allowed before v8");
+ MERROR_VER("Bulletproofs are not allowed before v8");
tvc.m_invalid_output = true;
return false;
}
@@ -2388,7 +2389,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
const bool borromean = rct::is_rct_borromean(tx.rct_signatures.type);
if (borromean)
{
- MERROR("Borromean range proofs are not allowed after v8");
+ MERROR_VER("Borromean range proofs are not allowed after v8");
tvc.m_invalid_output = true;
return false;
}
@@ -3564,6 +3565,10 @@ leave:
get_difficulty_for_next_block(); // just to cache it
invalidate_block_template_cache();
+ std::shared_ptr<tools::Notify> block_notify = m_block_notify;
+ if (block_notify)
+ block_notify->notify(epee::string_tools::pod_to_hex(id).c_str());
+
return true;
}
//------------------------------------------------------------------
@@ -4410,7 +4415,7 @@ void Blockchain::cancel()
}
#if defined(PER_BLOCK_CHECKPOINT)
-static const char expected_block_hashes_hash[] = "0924bc1c47aae448321fde949554be192878dd800e6489379865218f84eacbca";
+static const char expected_block_hashes_hash[] = "954cb2bbfa2fe6f74b2cdd22a1a4c767aea249ad47ad4f7c9445f0f03260f511";
void Blockchain::load_compiled_in_block_hashes()
{
const bool testnet = m_nettype == TESTNET;
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index f56068db8..8ebe7b5ce 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -55,6 +55,8 @@
#include "cryptonote_basic/hardfork.h"
#include "blockchain_db/blockchain_db.h"
+namespace tools { class Notify; }
+
namespace cryptonote
{
class tx_memory_pool;
@@ -706,6 +708,13 @@ namespace cryptonote
blockchain_db_sync_mode sync_mode, bool fast_sync);
/**
+ * @brief sets a block notify object to call for every new block
+ *
+ * @param notify the notify object to cal at every new block
+ */
+ void set_block_notify(const std::shared_ptr<tools::Notify> &notify) { m_block_notify = notify; }
+
+ /**
* @brief Put DB in safe sync mode
*/
void safesyncmode(const bool onoff);
@@ -1037,6 +1046,8 @@ namespace cryptonote
uint64_t m_btc_expected_reward;
bool m_btc_valid;
+ std::shared_ptr<tools::Notify> m_block_notify;
+
/**
* @brief collects the keys for all outputs being "spent" as an input
*
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 7f8c60f73..735309aa9 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -53,6 +53,7 @@ using namespace epee;
#include "ringct/rctTypes.h"
#include "blockchain_db/blockchain_db.h"
#include "ringct/rctSigs.h"
+#include "common/notify.h"
#include "version.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
@@ -167,6 +168,11 @@ namespace cryptonote
, "Set maximum txpool weight in bytes."
, DEFAULT_TXPOOL_MAX_WEIGHT
};
+ static const command_line::arg_descriptor<std::string> arg_block_notify = {
+ "block-notify"
+ , "Run a program for each new block, '%s' will be replaced by the block hash"
+ , ""
+ };
//-----------------------------------------------------------------------------------------------
core::core(i_cryptonote_protocol* pprotocol):
@@ -181,7 +187,8 @@ namespace cryptonote
m_last_json_checkpoints_update(0),
m_disable_dns_checkpoints(false),
m_update_download(0),
- m_nettype(UNDEFINED)
+ m_nettype(UNDEFINED),
+ m_update_available(false)
{
m_checkpoints_updating.clear();
set_cryptonote_protocol(pprotocol);
@@ -275,6 +282,7 @@ namespace cryptonote
command_line::add_arg(desc, arg_offline);
command_line::add_arg(desc, arg_disable_dns_checkpoints);
command_line::add_arg(desc, arg_max_txpool_weight);
+ command_line::add_arg(desc, arg_block_notify);
miner::init_options(desc);
BlockchainDB::init_options(desc);
@@ -544,6 +552,16 @@ namespace cryptonote
m_blockchain_storage.set_user_options(blocks_threads,
sync_on_blocks, sync_threshold, sync_mode, fast_sync);
+ try
+ {
+ if (!command_line::is_arg_defaulted(vm, arg_block_notify))
+ m_blockchain_storage.set_block_notify(std::shared_ptr<tools::Notify>(new tools::Notify(command_line::get_arg(vm, arg_block_notify).c_str())));
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Failed to parse block notify spec");
+ }
+
const std::pair<uint8_t, uint64_t> regtest_hard_forks[3] = {std::make_pair(1, 0), std::make_pair(Blockchain::get_hard_fork_heights(MAINNET).back().version, 1), std::make_pair(0, 0)};
const cryptonote::test_options regtest_test_options = {
regtest_hard_forks
@@ -838,16 +856,19 @@ namespace cryptonote
}
waiter.wait(&tpool);
it = tx_blobs.begin();
+ std::vector<bool> already_have(tx_blobs.size(), false);
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
if (!results[i].res)
continue;
if(m_mempool.have_tx(results[i].hash))
{
LOG_PRINT_L2("tx " << results[i].hash << "already have transaction in tx_pool");
+ already_have[i] = true;
}
else if(m_blockchain_storage.have_tx(results[i].hash))
{
LOG_PRINT_L2("tx " << results[i].hash << " already have transaction in blockchain");
+ already_have[i] = true;
}
else
{
@@ -869,7 +890,7 @@ namespace cryptonote
std::vector<tx_verification_batch_info> tx_info;
tx_info.reserve(tx_blobs.size());
for (size_t i = 0; i < tx_blobs.size(); i++) {
- if (!results[i].res)
+ if (!results[i].res || already_have[i])
continue;
tx_info.push_back({&results[i].tx, results[i].hash, tvc[i], results[i].res});
}
@@ -879,6 +900,8 @@ namespace cryptonote
bool ok = true;
it = tx_blobs.begin();
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
+ if (already_have[i])
+ continue;
if (!results[i].res)
{
ok = false;
@@ -1542,10 +1565,14 @@ namespace cryptonote
return false;
if (tools::vercmp(version.c_str(), MONERO_VERSION) <= 0)
+ {
+ m_update_available = false;
return true;
+ }
std::string url = tools::get_update_url(software, subdir, buildtag, version, true);
MCLOG_CYAN(el::Level::Info, "global", "Version " << version << " of " << software << " for " << buildtag << " is available: " << url << ", SHA256 hash " << hash);
+ m_update_available = true;
if (check_updates_level == UPDATES_NOTIFY)
return true;
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index b2be05bf4..225edc137 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -739,6 +739,16 @@ namespace cryptonote
network_type get_nettype() const { return m_nettype; };
/**
+ * @brief check whether an update is known to be available or not
+ *
+ * This does not actually trigger a check, but returns the result
+ * of the last check
+ *
+ * @return whether an update is known to be available or not
+ */
+ bool is_update_available() const { return m_update_available; }
+
+ /**
* @brief get whether fluffy blocks are enabled
*
* @return whether fluffy blocks are enabled
@@ -974,6 +984,8 @@ namespace cryptonote
network_type m_nettype; //!< which network are we on?
+ std::atomic<bool> m_update_available;
+
std::string m_checkpoints_path; //!< path to json checkpoints file
time_t m_last_dns_checkpoints_update; //!< time when dns checkpoints were last updated
time_t m_last_json_checkpoints_update; //!< time when json checkpoints were last updated
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
index fb2af9ceb..4fc2736a6 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.cpp
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
@@ -38,6 +38,7 @@ using namespace epee;
#include "cryptonote_tx_utils.h"
#include "cryptonote_config.h"
#include "cryptonote_basic/miner.h"
+#include "cryptonote_basic/tx_extra.h"
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "ringct/rctSigs.h"
@@ -84,6 +85,8 @@ namespace cryptonote
if(!extra_nonce.empty())
if(!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce))
return false;
+ if (!sort_tx_extra(tx.extra, tx.extra))
+ return false;
txin_gen in;
in.height = height;
@@ -127,7 +130,7 @@ namespace cryptonote
out_amounts[1] += out_amounts[0];
for (size_t n = 1; n < out_amounts.size(); ++n)
out_amounts[n - 1] = out_amounts[n];
- out_amounts.resize(out_amounts.size() - 1);
+ out_amounts.pop_back();
}
}
else
@@ -434,6 +437,9 @@ namespace cryptonote
add_additional_tx_pub_keys_to_extra(tx.extra, additional_tx_public_keys);
}
+ if (!sort_tx_extra(tx.extra, tx.extra))
+ return false;
+
//check money
if(summary_outs_money > summary_inputs_money )
{
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index a725eac6e..553a22298 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -250,7 +250,7 @@ namespace cryptonote
CRITICAL_REGION_LOCAL1(m_blockchain);
LockedTXN lock(m_blockchain);
m_blockchain.add_txpool_tx(tx, meta);
- if (!insert_key_images(tx, kept_by_block))
+ if (!insert_key_images(tx, id, kept_by_block))
return false;
m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)tx_weight, receive_time), id);
}
@@ -290,9 +290,10 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL1(m_blockchain);
LockedTXN lock(m_blockchain);
- m_blockchain.remove_txpool_tx(get_transaction_hash(tx));
+ const crypto::hash txid = get_transaction_hash(tx);
+ m_blockchain.remove_txpool_tx(txid);
m_blockchain.add_txpool_tx(tx, meta);
- if (!insert_key_images(tx, kept_by_block))
+ if (!insert_key_images(tx, txid, kept_by_block))
return false;
m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)tx_weight, receive_time), id);
}
@@ -371,8 +372,8 @@ namespace cryptonote
continue;
}
cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid);
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(txblob, tx))
+ cryptonote::transaction_prefix tx;
+ if (!parse_and_validate_tx_prefix_from_blob(txblob, tx))
{
MERROR("Failed to parse tx from txpool");
return;
@@ -381,7 +382,7 @@ namespace cryptonote
MINFO("Pruning tx " << txid << " from txpool: weight: " << it->first.second << ", fee/byte: " << it->first.first);
m_blockchain.remove_txpool_tx(txid);
m_txpool_weight -= it->first.second;
- remove_transaction_keyimages(tx);
+ remove_transaction_keyimages(tx, txid);
MINFO("Pruned tx " << txid << " from txpool: weight: " << it->first.second << ", fee/byte: " << it->first.first);
m_txs_by_fee_and_receive_time.erase(it--);
changed = true;
@@ -398,11 +399,10 @@ namespace cryptonote
MINFO("Pool weight after pruning is larger than limit: " << m_txpool_weight << "/" << bytes);
}
//---------------------------------------------------------------------------------
- bool tx_memory_pool::insert_key_images(const transaction &tx, bool kept_by_block)
+ bool tx_memory_pool::insert_key_images(const transaction_prefix &tx, const crypto::hash &id, bool kept_by_block)
{
for(const auto& in: tx.vin)
{
- const crypto::hash id = get_transaction_hash(tx);
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, txin, false);
std::unordered_set<crypto::hash>& kei_image_set = m_spent_key_images[txin.k_image];
CHECK_AND_ASSERT_MES(kept_by_block || kei_image_set.size() == 0, false, "internal error: kept_by_block=" << kept_by_block
@@ -418,19 +418,17 @@ namespace cryptonote
//FIXME: Can return early before removal of all of the key images.
// At the least, need to make sure that a false return here
// is treated properly. Should probably not return early, however.
- bool tx_memory_pool::remove_transaction_keyimages(const transaction& tx)
+ bool tx_memory_pool::remove_transaction_keyimages(const transaction_prefix& tx, const crypto::hash &actual_hash)
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
// ND: Speedup
- // 1. Move transaction hash calcuation outside of loop. ._.
- crypto::hash actual_hash = get_transaction_hash(tx);
for(const txin_v& vi: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(vi, const txin_to_key, txin, false);
auto it = m_spent_key_images.find(txin.k_image);
CHECK_AND_ASSERT_MES(it != m_spent_key_images.end(), false, "failed to find transaction input in key images. img=" << txin.k_image << ENDL
- << "transaction id = " << get_transaction_hash(tx));
+ << "transaction id = " << actual_hash);
std::unordered_set<crypto::hash>& key_image_set = it->second;
CHECK_AND_ASSERT_MES(key_image_set.size(), false, "empty key_image set, img=" << txin.k_image << ENDL
<< "transaction id = " << actual_hash);
@@ -483,7 +481,7 @@ namespace cryptonote
// remove first, in case this throws, so key images aren't removed
m_blockchain.remove_txpool_tx(id);
m_txpool_weight -= tx_weight;
- remove_transaction_keyimages(tx);
+ remove_transaction_keyimages(tx, id);
}
catch (const std::exception &e)
{
@@ -515,7 +513,7 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
- std::unordered_set<crypto::hash> remove;
+ std::list<std::pair<crypto::hash, uint64_t>> remove;
m_blockchain.for_all_txpool_txes([this, &remove](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata*) {
uint64_t tx_age = time(nullptr) - meta.receive_time;
@@ -533,7 +531,7 @@ namespace cryptonote
m_txs_by_fee_and_receive_time.erase(sorted_it);
}
m_timed_out_transactions.insert(txid);
- remove.insert(txid);
+ remove.push_back(std::make_pair(txid, meta.weight));
}
return true;
}, false);
@@ -541,13 +539,14 @@ namespace cryptonote
if (!remove.empty())
{
LockedTXN lock(m_blockchain);
- for (const crypto::hash &txid: remove)
+ for (const std::pair<crypto::hash, uint64_t> &entry: remove)
{
+ const crypto::hash &txid = entry.first;
try
{
cryptonote::blobdata bd = m_blockchain.get_txpool_tx_blob(txid);
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(bd, tx))
+ cryptonote::transaction_prefix tx;
+ if (!parse_and_validate_tx_prefix_from_blob(bd, tx))
{
MERROR("Failed to parse tx from txpool");
// continue
@@ -556,8 +555,8 @@ namespace cryptonote
{
// remove first, so we only remove key images if the tx removal succeeds
m_blockchain.remove_txpool_tx(txid);
- m_txpool_weight -= get_transaction_weight(tx, bd.size());
- remove_transaction_keyimages(tx);
+ m_txpool_weight -= entry.second;
+ remove_transaction_keyimages(tx, txid);
}
}
catch (const std::exception &e)
@@ -1041,7 +1040,7 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------------------------
- bool tx_memory_pool::have_key_images(const std::unordered_set<crypto::key_image>& k_images, const transaction& tx)
+ bool tx_memory_pool::have_key_images(const std::unordered_set<crypto::key_image>& k_images, const transaction_prefix& tx)
{
for(size_t i = 0; i!= tx.vin.size(); i++)
{
@@ -1052,7 +1051,7 @@ namespace cryptonote
return false;
}
//---------------------------------------------------------------------------------
- bool tx_memory_pool::append_key_images(std::unordered_set<crypto::key_image>& k_images, const transaction& tx)
+ bool tx_memory_pool::append_key_images(std::unordered_set<crypto::key_image>& k_images, const transaction_prefix& tx)
{
for(size_t i = 0; i!= tx.vin.size(); i++)
{
@@ -1301,7 +1300,7 @@ namespace cryptonote
// remove tx from db first
m_blockchain.remove_txpool_tx(txid);
m_txpool_weight -= get_transaction_weight(tx, txblob.size());
- remove_transaction_keyimages(tx);
+ remove_transaction_keyimages(tx, txid);
auto sorted_it = find_tx_in_sorted_container(txid);
if (sorted_it == m_txs_by_fee_and_receive_time.end())
{
@@ -1344,13 +1343,14 @@ namespace cryptonote
bool r = m_blockchain.for_all_txpool_txes([this, &remove, kept](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd) {
if (!!kept != !!meta.kept_by_block)
return true;
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(*bd, tx))
+ cryptonote::transaction_prefix tx;
+ if (!parse_and_validate_tx_prefix_from_blob(*bd, tx))
{
MWARNING("Failed to parse tx from txpool, removing");
remove.push_back(txid);
+ return true;
}
- if (!insert_key_images(tx, meta.kept_by_block))
+ if (!insert_key_images(tx, txid, meta.kept_by_block))
{
MFATAL("Failed to insert key images from txpool tx");
return false;
diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h
index 892cadc69..7a0cc23bf 100644
--- a/src/cryptonote_core/tx_pool.h
+++ b/src/cryptonote_core/tx_pool.h
@@ -434,7 +434,7 @@ namespace cryptonote
*
* @return true on success, false on error
*/
- bool insert_key_images(const transaction &tx, bool kept_by_block);
+ bool insert_key_images(const transaction_prefix &tx, const crypto::hash &txid, bool kept_by_block);
/**
* @brief remove old transactions from the pool
@@ -478,10 +478,11 @@ namespace cryptonote
* a transaction from the pool.
*
* @param tx the transaction
+ * @param txid the transaction's hash
*
* @return false if any key images to be removed cannot be found, otherwise true
*/
- bool remove_transaction_keyimages(const transaction& tx);
+ bool remove_transaction_keyimages(const transaction_prefix& tx, const crypto::hash &txid);
/**
* @brief check if any of a transaction's spent key images are present in a given set
@@ -491,7 +492,7 @@ namespace cryptonote
*
* @return true if any key images present in the set, otherwise false
*/
- static bool have_key_images(const std::unordered_set<crypto::key_image>& kic, const transaction& tx);
+ static bool have_key_images(const std::unordered_set<crypto::key_image>& kic, const transaction_prefix& tx);
/**
* @brief append the key images from a transaction to the given set
@@ -501,7 +502,7 @@ namespace cryptonote
*
* @return false if any append fails, otherwise true
*/
- static bool append_key_images(std::unordered_set<crypto::key_image>& kic, const transaction& tx);
+ static bool append_key_images(std::unordered_set<crypto::key_image>& kic, const transaction_prefix& tx);
/**
* @brief check if a transaction is a valid candidate for inclusion in a block
@@ -509,11 +510,11 @@ namespace cryptonote
* @param txd the transaction to check (and info about it)
* @param txid the txid of the transaction to check
* @param txblob the transaction blob to check
- * @param tx the parsed transaction, if successful
+ * @param tx the parsed transaction prefix, if successful
*
* @return true if the transaction is good to go, otherwise false
*/
- bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const;
+ bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction&tx) const;
/**
* @brief mark all transactions double spending the one passed