aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp19
-rw-r--r--src/cryptonote_core/blockchain.h6
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp11
-rw-r--r--src/cryptonote_core/cryptonote_core.h7
-rw-r--r--src/cryptonote_core/tx_pool.cpp36
-rw-r--r--src/cryptonote_core/tx_pool.h4
6 files changed, 47 insertions, 36 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 77b6d0b69..19cc90b61 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -2530,7 +2530,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
}
}
- if (hf_version >= HF_VERSION_MIN_MIXIN_10 && mixin != 10)
+ if (((hf_version == HF_VERSION_MIN_MIXIN_10 || hf_version == HF_VERSION_MIN_MIXIN_10+1) && mixin != 10) || (hf_version >= HF_VERSION_MIN_MIXIN_10+2 && mixin > 10))
{
MERROR_VER("Tx " << get_transaction_hash(tx) << " has invalid ring size (" << (mixin + 1) << "), it should be 11");
tvc.m_low_mixin = true;
@@ -3786,8 +3786,7 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync)
}
//------------------------------------------------------------------
-//FIXME: unused parameter txs
-void Blockchain::output_scan_worker(const uint64_t amount, const std::vector<uint64_t> &offsets, std::vector<output_data_t> &outputs, std::unordered_map<crypto::hash, cryptonote::transaction> &txs) const
+void Blockchain::output_scan_worker(const uint64_t amount, const std::vector<uint64_t> &offsets, std::vector<output_data_t> &outputs) const
{
try
{
@@ -4164,21 +4163,19 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
offsets.second.erase(last, offsets.second.end());
}
- // [output] stores all transactions for each tx_out_index::hash found
- std::vector<std::unordered_map<crypto::hash, cryptonote::transaction>> transactions(amounts.size());
-
+ // gather all the output keys
threads = tpool.get_max_concurrency();
if (!m_db->can_thread_bulk_indices())
threads = 1;
- if (threads > 1)
+ if (threads > 1 && amounts.size() > 1)
{
tools::threadpool::waiter waiter;
for (size_t i = 0; i < amounts.size(); i++)
{
uint64_t amount = amounts[i];
- tpool.submit(&waiter, boost::bind(&Blockchain::output_scan_worker, this, amount, std::cref(offset_map[amount]), std::ref(tx_map[amount]), std::ref(transactions[i])), true);
+ tpool.submit(&waiter, boost::bind(&Blockchain::output_scan_worker, this, amount, std::cref(offset_map[amount]), std::ref(tx_map[amount])), true);
}
waiter.wait(&tpool);
}
@@ -4187,7 +4184,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
for (size_t i = 0; i < amounts.size(); i++)
{
uint64_t amount = amounts[i];
- output_scan_worker(amount, offset_map[amount], tx_map[amount], transactions[i]);
+ output_scan_worker(amount, offset_map[amount], tx_map[amount]);
}
}
@@ -4254,9 +4251,9 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
return true;
}
-void Blockchain::add_txpool_tx(transaction &tx, const txpool_tx_meta_t &meta)
+void Blockchain::add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t &meta)
{
- m_db->add_txpool_tx(tx, meta);
+ m_db->add_txpool_tx(txid, blob, meta);
}
void Blockchain::update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t &meta)
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index f140d7719..dfe833fb4 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -916,11 +916,9 @@ namespace cryptonote
* @param amount the amount
* @param offsets the indices (indexed to the amount) of the outputs
* @param outputs return-by-reference the outputs collected
- * @param txs unused, candidate for removal
*/
void output_scan_worker(const uint64_t amount,const std::vector<uint64_t> &offsets,
- std::vector<output_data_t> &outputs, std::unordered_map<crypto::hash,
- cryptonote::transaction> &txs) const;
+ std::vector<output_data_t> &outputs) const;
/**
* @brief computes the "short" and "long" hashes for a set of blocks
@@ -939,7 +937,7 @@ namespace cryptonote
*/
std::list<std::pair<block_extended_info,std::vector<crypto::hash>>> get_alternative_chains() const;
- void add_txpool_tx(transaction &tx, const txpool_tx_meta_t &meta);
+ void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t &meta);
void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t &meta);
void remove_txpool_tx(const crypto::hash &txid);
uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const;
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index d8c38bf9e..10ab3fe65 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -909,7 +909,7 @@ namespace cryptonote
}
const size_t weight = get_transaction_weight(results[i].tx, it->size());
- ok &= add_new_tx(results[i].tx, results[i].hash, results[i].prefix_hash, weight, tvc[i], keeped_by_block, relayed, do_not_relay);
+ ok &= add_new_tx(results[i].tx, results[i].hash, tx_blobs[i], results[i].prefix_hash, weight, tvc[i], keeped_by_block, relayed, do_not_relay);
if(tvc[i].m_verifivation_failed)
{MERROR_VER("Transaction verification failed: " << results[i].hash);}
else if(tvc[i].m_verifivation_impossible)
@@ -1127,7 +1127,7 @@ namespace cryptonote
blobdata bl;
t_serializable_object_to_blob(tx, bl);
size_t tx_weight = get_transaction_weight(tx, bl.size());
- return add_new_tx(tx, tx_hash, tx_prefix_hash, tx_weight, tvc, keeped_by_block, relayed, do_not_relay);
+ return add_new_tx(tx, tx_hash, bl, tx_prefix_hash, tx_weight, tvc, keeped_by_block, relayed, do_not_relay);
}
//-----------------------------------------------------------------------------------------------
size_t core::get_blockchain_total_transactions() const
@@ -1135,7 +1135,7 @@ namespace cryptonote
return m_blockchain_storage.get_total_transactions();
}
//-----------------------------------------------------------------------------------------------
- bool core::add_new_tx(transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t tx_weight, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::add_new_tx(transaction& tx, const crypto::hash& tx_hash, const cryptonote::blobdata &blob, const crypto::hash& tx_prefix_hash, size_t tx_weight, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
{
if (keeped_by_block)
get_blockchain_storage().on_new_tx_from_block(tx);
@@ -1153,7 +1153,7 @@ namespace cryptonote
}
uint8_t version = m_blockchain_storage.get_current_hard_fork_version();
- return m_mempool.add_tx(tx, tx_hash, tx_weight, tvc, keeped_by_block, relayed, do_not_relay, version);
+ return m_mempool.add_tx(tx, tx_hash, blob, tx_weight, tvc, keeped_by_block, relayed, do_not_relay, version);
}
//-----------------------------------------------------------------------------------------------
bool core::relay_txpool_transactions()
@@ -1716,7 +1716,8 @@ namespace cryptonote
for (size_t n = 0; n < sizeof(seconds)/sizeof(seconds[0]); ++n)
{
unsigned int b = 0;
- for (time_t ts: timestamps) b += ts >= now - seconds[n];
+ const time_t time_boundary = now - static_cast<time_t>(seconds[n]);
+ for (time_t ts: timestamps) b += ts >= time_boundary;
const double p = probability(b, seconds[n] / DIFFICULTY_TARGET_V2);
MDEBUG("blocks in the last " << seconds[n] / 60 << " minutes: " << b << " (probability " << p << ")");
if (p < threshold)
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 80c452f53..2eb6c842b 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -117,7 +117,7 @@ namespace cryptonote
* @param relayed whether or not the transaction was relayed to us
* @param do_not_relay whether to prevent the transaction from being relayed
*
- * @return true if the transaction made it to the transaction pool, otherwise false
+ * @return true if the transaction was accepted, false otherwise
*/
bool handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay);
@@ -133,7 +133,7 @@ namespace cryptonote
* @param relayed whether or not the transactions were relayed to us
* @param do_not_relay whether to prevent the transactions from being relayed
*
- * @return true if the transactions made it to the transaction pool, otherwise false
+ * @return true if the transactions were accepted, false otherwise
*/
bool handle_incoming_txs(const std::vector<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay);
@@ -783,13 +783,14 @@ namespace cryptonote
* @copydoc add_new_tx(transaction&, tx_verification_context&, bool)
*
* @param tx_hash the transaction's hash
+ * @param blob the transaction as a blob
* @param tx_prefix_hash the transaction prefix' hash
* @param tx_weight the weight of the transaction
* @param relayed whether or not the transaction was relayed to us
* @param do_not_relay whether to prevent the transaction from being relayed
*
*/
- bool add_new_tx(transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t tx_weight, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay);
+ bool add_new_tx(transaction& tx, const crypto::hash& tx_hash, const cryptonote::blobdata &blob, const crypto::hash& tx_prefix_hash, size_t tx_weight, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay);
/**
* @brief add a new transaction to the transaction pool
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 553a22298..2d340dd41 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -111,7 +111,7 @@ namespace cryptonote
}
//---------------------------------------------------------------------------------
- bool tx_memory_pool::add_tx(transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ 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)
+ bool tx_memory_pool::add_tx(transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ 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)
{
// this should already be called with that lock, but let's make it explicit for clarity
CRITICAL_REGION_LOCAL(m_transactions_lock);
@@ -247,9 +247,11 @@ namespace cryptonote
memset(meta.padding, 0, sizeof(meta.padding));
try
{
+ if (kept_by_block)
+ m_parsed_tx_cache.insert(std::make_pair(id, tx));
CRITICAL_REGION_LOCAL1(m_blockchain);
LockedTXN lock(m_blockchain);
- m_blockchain.add_txpool_tx(tx, meta);
+ m_blockchain.add_txpool_tx(id, blob, meta);
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);
@@ -288,12 +290,13 @@ namespace cryptonote
try
{
+ if (kept_by_block)
+ m_parsed_tx_cache.insert(std::make_pair(id, tx));
CRITICAL_REGION_LOCAL1(m_blockchain);
LockedTXN lock(m_blockchain);
- 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, txid, kept_by_block))
+ m_blockchain.remove_txpool_tx(id);
+ m_blockchain.add_txpool_tx(id, blob, meta);
+ 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);
}
@@ -324,9 +327,11 @@ namespace cryptonote
{
crypto::hash h = null_hash;
size_t blob_size = 0;
- if (!get_transaction_hash(tx, h, blob_size) || blob_size == 0)
+ cryptonote::blobdata bl;
+ t_serializable_object_to_blob(tx, bl);
+ if (bl.size() == 0 || !get_transaction_hash(tx, h))
return false;
- return add_tx(tx, h, get_transaction_weight(tx, blob_size), tvc, keeped_by_block, relayed, do_not_relay, version);
+ return add_tx(tx, h, bl, get_transaction_weight(tx, bl.size()), tvc, keeped_by_block, relayed, do_not_relay, version);
}
//---------------------------------------------------------------------------------
size_t tx_memory_pool::get_txpool_weight() const
@@ -379,11 +384,11 @@ namespace cryptonote
return;
}
// remove first, in case this throws, so key images aren't removed
- MINFO("Pruning tx " << txid << " from txpool: weight: " << it->first.second << ", fee/byte: " << it->first.first);
+ MINFO("Pruning tx " << txid << " from txpool: weight: " << meta.weight << ", fee/byte: " << it->first.first);
m_blockchain.remove_txpool_tx(txid);
- m_txpool_weight -= it->first.second;
+ m_txpool_weight -= meta.weight;
remove_transaction_keyimages(tx, txid);
- MINFO("Pruned tx " << txid << " from txpool: weight: " << it->first.second << ", fee/byte: " << it->first.first);
+ MINFO("Pruned tx " << txid << " from txpool: weight: " << meta.weight << ", fee/byte: " << it->first.first);
m_txs_by_fee_and_receive_time.erase(it--);
changed = true;
}
@@ -467,7 +472,12 @@ namespace cryptonote
return false;
}
cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(id);
- if (!parse_and_validate_tx_from_blob(txblob, tx))
+ auto ci = m_parsed_tx_cache.find(id);
+ if (ci != m_parsed_tx_cache.end())
+ {
+ tx = ci->second;
+ }
+ else if (!parse_and_validate_tx_from_blob(txblob, tx))
{
MERROR("Failed to parse tx from txpool");
return false;
@@ -910,6 +920,7 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
m_input_cache.clear();
+ m_parsed_tx_cache.clear();
return true;
}
//---------------------------------------------------------------------------------
@@ -917,6 +928,7 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
m_input_cache.clear();
+ m_parsed_tx_cache.clear();
return true;
}
//---------------------------------------------------------------------------------
diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h
index be00f8fc1..670d70d77 100644
--- a/src/cryptonote_core/tx_pool.h
+++ b/src/cryptonote_core/tx_pool.h
@@ -107,7 +107,7 @@ namespace cryptonote
* @param id the transaction's hash
* @param tx_weight the transaction's weight
*/
- 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);
+ 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);
/**
* @brief add a transaction to the transaction pool
@@ -584,6 +584,8 @@ private:
size_t m_txpool_weight;
mutable 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;
};
}