aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core/cryptonote_core.cpp
diff options
context:
space:
mode:
authorluigi1111 <luigi1111w@gmail.com>2019-12-12 13:32:35 -0600
committerluigi1111 <luigi1111w@gmail.com>2019-12-12 13:32:35 -0600
commit3531cc5fd2889ec5cdd3aecd0e3ba6672fec2e02 (patch)
treea0abff5ebc21fce520afcdb60a6955b9ffb3c183 /src/cryptonote_core/cryptonote_core.cpp
parent411f1b0ee30f1d424621eb856841dc82d2f161c2 (diff)
parent5d7ae2d2791c0244a221872a7ac62627abb81896 (diff)
downloadmonzero-core-3531cc5fd2889ec5cdd3aecd0e3ba6672fec2e02.tar.gz
monzero-core-3531cc5fd2889ec5cdd3aecd0e3ba6672fec2e02.tar.xz
monzero-core-3531cc5fd2889ec5cdd3aecd0e3ba6672fec2e02.zip
Merge pull request #5965
5d7ae2d Adding support for hidden (anonymity) txpool (vtnerd)
Diffstat (limited to 'src/cryptonote_core/cryptonote_core.cpp')
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp120
1 files changed, 70 insertions, 50 deletions
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 02620996e..cf23a652c 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -29,6 +29,7 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include <boost/algorithm/string.hpp>
+#include <boost/uuid/nil_generator.hpp>
#include "string_tools.h"
using namespace epee;
@@ -753,7 +754,7 @@ namespace cryptonote
return false;
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_tx_pre(const tx_blob_entry& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::handle_incoming_tx_pre(const tx_blob_entry& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash)
{
tvc = {};
@@ -817,7 +818,7 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_tx_post(const tx_blob_entry& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::handle_incoming_tx_post(const tx_blob_entry& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash)
{
if(!check_tx_syntax(tx))
{
@@ -946,23 +947,29 @@ namespace cryptonote
return ret;
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_txs(const std::vector<tx_blob_entry>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::handle_incoming_txs(const epee::span<const tx_blob_entry> tx_blobs, epee::span<tx_verification_context> tvc, relay_method tx_relay, bool relayed)
{
TRY_ENTRY();
- CRITICAL_REGION_LOCAL(m_incoming_tx_lock);
+
+ if (tx_blobs.size() != tvc.size())
+ {
+ MERROR("tx_blobs and tx_verification_context spans must have equal size");
+ return false;
+ }
struct result { bool res; cryptonote::transaction tx; crypto::hash hash; };
std::vector<result> results(tx_blobs.size());
- tvc.resize(tx_blobs.size());
+ CRITICAL_REGION_LOCAL(m_incoming_tx_lock);
+
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool::waiter waiter;
- std::vector<tx_blob_entry>::const_iterator it = tx_blobs.begin();
+ epee::span<tx_blob_entry>::const_iterator it = tx_blobs.begin();
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
tpool.submit(&waiter, [&, i, it] {
try
{
- results[i].res = handle_incoming_tx_pre(*it, tvc[i], results[i].tx, results[i].hash, keeped_by_block, relayed, do_not_relay);
+ results[i].res = handle_incoming_tx_pre(*it, tvc[i], results[i].tx, results[i].hash);
}
catch (const std::exception &e)
{
@@ -978,7 +985,7 @@ namespace cryptonote
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
if (!results[i].res)
continue;
- if(m_mempool.have_tx(results[i].hash))
+ if(m_mempool.have_tx(results[i].hash, relay_category::legacy))
{
LOG_PRINT_L2("tx " << results[i].hash << "already have transaction in tx_pool");
already_have[i] = true;
@@ -993,7 +1000,7 @@ namespace cryptonote
tpool.submit(&waiter, [&, i, it] {
try
{
- results[i].res = handle_incoming_tx_post(*it, tvc[i], results[i].tx, results[i].hash, keeped_by_block, relayed, do_not_relay);
+ results[i].res = handle_incoming_tx_post(*it, tvc[i], results[i].tx, results[i].hash);
}
catch (const std::exception &e)
{
@@ -1014,7 +1021,7 @@ namespace cryptonote
tx_info.push_back({&results[i].tx, results[i].hash, tvc[i], results[i].res});
}
if (!tx_info.empty())
- handle_incoming_tx_accumulated_batch(tx_info, keeped_by_block);
+ handle_incoming_tx_accumulated_batch(tx_info, tx_relay == relay_method::block);
bool ok = true;
it = tx_blobs.begin();
@@ -1024,13 +1031,14 @@ namespace cryptonote
ok = false;
continue;
}
- if (keeped_by_block)
+ if (tx_relay == relay_method::block)
get_blockchain_storage().on_new_tx_from_block(results[i].tx);
if (already_have[i])
continue;
const uint64_t weight = results[i].tx.pruned ? get_pruned_transaction_weight(results[i].tx) : get_transaction_weight(results[i].tx, it->blob.size());
- ok &= add_new_tx(results[i].tx, results[i].hash, tx_blobs[i].blob, weight, tvc[i], keeped_by_block, relayed, do_not_relay);
+ ok &= add_new_tx(results[i].tx, results[i].hash, tx_blobs[i].blob, weight, tvc[i], tx_relay, relayed);
+
if(tvc[i].m_verifivation_failed)
{MERROR_VER("Transaction verification failed: " << results[i].hash);}
else if(tvc[i].m_verifivation_impossible)
@@ -1044,19 +1052,9 @@ namespace cryptonote
CATCH_ENTRY_L0("core::handle_incoming_txs()", false);
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_tx(const tx_blob_entry& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
- {
- std::vector<tx_blob_entry> tx_blobs;
- tx_blobs.push_back(tx_blob);
- std::vector<tx_verification_context> tvcv(1);
- bool r = handle_incoming_txs(tx_blobs, tvcv, keeped_by_block, relayed, do_not_relay);
- tvc = tvcv[0];
- return r;
- }
- //-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::handle_incoming_tx(const tx_blob_entry& tx_blob, tx_verification_context& tvc, relay_method tx_relay, bool relayed)
{
- return handle_incoming_tx({tx_blob, crypto::null_hash}, tvc, keeped_by_block, relayed, do_not_relay);
+ return handle_incoming_txs({std::addressof(tx_blob), 1}, {std::addressof(tvc), 1}, tx_relay, relayed);
}
//-----------------------------------------------------------------------------------------------
bool core::get_stat_info(core_stat_info& st_inf) const
@@ -1246,13 +1244,13 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
- bool core::add_new_tx(transaction& tx, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::add_new_tx(transaction& tx, tx_verification_context& tvc, relay_method tx_relay, bool relayed)
{
crypto::hash tx_hash = get_transaction_hash(tx);
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, bl, tx_weight, tvc, keeped_by_block, relayed, do_not_relay);
+ return add_new_tx(tx, tx_hash, bl, tx_weight, tvc, tx_relay, relayed);
}
//-----------------------------------------------------------------------------------------------
size_t core::get_blockchain_total_transactions() const
@@ -1260,9 +1258,9 @@ namespace cryptonote
return m_blockchain_storage.get_total_transactions();
}
//-----------------------------------------------------------------------------------------------
- bool core::add_new_tx(transaction& tx, const crypto::hash& tx_hash, const cryptonote::blobdata &blob, 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, size_t tx_weight, tx_verification_context& tvc, relay_method tx_relay, bool relayed)
{
- if(m_mempool.have_tx(tx_hash))
+ if(m_mempool.have_tx(tx_hash, relay_category::legacy))
{
LOG_PRINT_L2("tx " << tx_hash << "already have transaction in tx_pool");
return true;
@@ -1275,40 +1273,62 @@ namespace cryptonote
}
uint8_t version = m_blockchain_storage.get_current_hard_fork_version();
- return m_mempool.add_tx(tx, tx_hash, blob, tx_weight, tvc, keeped_by_block, relayed, do_not_relay, version);
+ return m_mempool.add_tx(tx, tx_hash, blob, tx_weight, tvc, tx_relay, relayed, version);
}
//-----------------------------------------------------------------------------------------------
bool core::relay_txpool_transactions()
{
// we attempt to relay txes that should be relayed, but were not
- std::vector<std::pair<crypto::hash, cryptonote::blobdata>> txs;
+ std::vector<std::tuple<crypto::hash, cryptonote::blobdata, relay_method>> txs;
if (m_mempool.get_relayable_transactions(txs) && !txs.empty())
{
- cryptonote_connection_context fake_context = AUTO_VAL_INIT(fake_context);
- tx_verification_context tvc = AUTO_VAL_INIT(tvc);
- NOTIFY_NEW_TRANSACTIONS::request r;
- for (auto it = txs.begin(); it != txs.end(); ++it)
+ NOTIFY_NEW_TRANSACTIONS::request public_req{};
+ NOTIFY_NEW_TRANSACTIONS::request private_req{};
+ for (auto& tx : txs)
{
- r.txs.push_back(it->second);
+ switch (std::get<2>(tx))
+ {
+ default:
+ case relay_method::none:
+ break;
+ case relay_method::local:
+ private_req.txs.push_back(std::move(std::get<1>(tx)));
+ break;
+ case relay_method::block:
+ case relay_method::flood:
+ public_req.txs.push_back(std::move(std::get<1>(tx)));
+ break;
+ }
}
- get_protocol()->relay_transactions(r, fake_context);
- m_mempool.set_relayed(txs);
+
+ /* All txes are sent on randomized timers per connection in
+ `src/cryptonote_protocol/levin_notify.cpp.` They are either sent with
+ "white noise" delays or via diffusion (Dandelion++ fluff). So
+ re-relaying public and private _should_ be acceptable here. */
+ const boost::uuids::uuid source = boost::uuids::nil_uuid();
+ if (!public_req.txs.empty())
+ get_protocol()->relay_transactions(public_req, source, epee::net_utils::zone::public_);
+ if (!private_req.txs.empty())
+ get_protocol()->relay_transactions(private_req, source, epee::net_utils::zone::invalid);
}
return true;
}
//-----------------------------------------------------------------------------------------------
- void core::on_transaction_relayed(const cryptonote::blobdata& tx_blob)
+ void core::on_transactions_relayed(const epee::span<const cryptonote::blobdata> tx_blobs, const relay_method tx_relay)
{
- std::vector<std::pair<crypto::hash, cryptonote::blobdata>> txs;
- cryptonote::transaction tx;
- crypto::hash tx_hash;
- if (!parse_and_validate_tx_from_blob(tx_blob, tx, tx_hash))
+ std::vector<crypto::hash> tx_hashes{};
+ tx_hashes.resize(tx_blobs.size());
+
+ cryptonote::transaction tx{};
+ for (std::size_t i = 0; i < tx_blobs.size(); ++i)
{
- LOG_ERROR("Failed to parse relayed transaction");
- return;
+ if (!parse_and_validate_tx_from_blob(tx_blobs[i], tx, tx_hashes[i]))
+ {
+ LOG_ERROR("Failed to parse relayed transaction");
+ return;
+ }
}
- txs.push_back(std::make_pair(tx_hash, std::move(tx_blob)));
- m_mempool.set_relayed(txs);
+ m_mempool.set_relayed(epee::to_span(tx_hashes), tx_relay);
}
//-----------------------------------------------------------------------------------------------
bool core::get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce)
@@ -1369,7 +1389,7 @@ namespace cryptonote
for (const auto &tx_hash: b.tx_hashes)
{
cryptonote::blobdata txblob;
- CHECK_AND_ASSERT_THROW_MES(pool.get_transaction(tx_hash, txblob), "Transaction not found in pool");
+ CHECK_AND_ASSERT_THROW_MES(pool.get_transaction(tx_hash, txblob, relay_category::all), "Transaction not found in pool");
bce.txs.push_back({txblob, crypto::null_hash});
}
return bce;
@@ -1573,14 +1593,14 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
- bool core::get_pool_transaction(const crypto::hash &id, cryptonote::blobdata& tx) const
+ bool core::get_pool_transaction(const crypto::hash &id, cryptonote::blobdata& tx, relay_category tx_category) const
{
- return m_mempool.get_transaction(id, tx);
+ return m_mempool.get_transaction(id, tx, tx_category);
}
//-----------------------------------------------------------------------------------------------
bool core::pool_has_tx(const crypto::hash &id) const
{
- return m_mempool.have_tx(id);
+ return m_mempool.have_tx(id, relay_category::legacy);
}
//-----------------------------------------------------------------------------------------------
bool core::get_pool_transactions_and_spent_keys_info(std::vector<tx_info>& tx_infos, std::vector<spent_key_image_info>& key_image_infos, bool include_sensitive_data) const