Merge pull request #4787

3dba7f25 protocol: option to pad transaction relay to the next kB (moneromooo-monero)
This commit is contained in:
Riccardo Spagni 2018-12-12 11:53:10 +02:00
commit dde1e69723
No known key found for this signature in database
GPG key ID: 55432DF31CCD4FCD
6 changed files with 52 additions and 1 deletions

View file

@ -160,6 +160,11 @@ namespace cryptonote
, "Relay blocks as normal blocks" , "Relay blocks as normal blocks"
, false , false
}; };
static const command_line::arg_descriptor<bool> arg_pad_transactions = {
"pad-transactions"
, "Pad relayed transactions to help defend against traffic volume analysis"
, false
};
static const command_line::arg_descriptor<size_t> arg_max_txpool_weight = { static const command_line::arg_descriptor<size_t> arg_max_txpool_weight = {
"max-txpool-weight" "max-txpool-weight"
, "Set maximum txpool weight in bytes." , "Set maximum txpool weight in bytes."
@ -185,7 +190,8 @@ namespace cryptonote
m_disable_dns_checkpoints(false), m_disable_dns_checkpoints(false),
m_update_download(0), m_update_download(0),
m_nettype(UNDEFINED), m_nettype(UNDEFINED),
m_update_available(false) m_update_available(false),
m_pad_transactions(false)
{ {
m_checkpoints_updating.clear(); m_checkpoints_updating.clear();
set_cryptonote_protocol(pprotocol); set_cryptonote_protocol(pprotocol);
@ -279,6 +285,7 @@ namespace cryptonote
command_line::add_arg(desc, arg_offline); command_line::add_arg(desc, arg_offline);
command_line::add_arg(desc, arg_disable_dns_checkpoints); command_line::add_arg(desc, arg_disable_dns_checkpoints);
command_line::add_arg(desc, arg_max_txpool_weight); command_line::add_arg(desc, arg_max_txpool_weight);
command_line::add_arg(desc, arg_pad_transactions);
command_line::add_arg(desc, arg_block_notify); command_line::add_arg(desc, arg_block_notify);
miner::init_options(desc); miner::init_options(desc);
@ -317,6 +324,7 @@ namespace cryptonote
set_enforce_dns_checkpoints(command_line::get_arg(vm, arg_dns_checkpoints)); set_enforce_dns_checkpoints(command_line::get_arg(vm, arg_dns_checkpoints));
test_drop_download_height(command_line::get_arg(vm, arg_test_drop_download_height)); test_drop_download_height(command_line::get_arg(vm, arg_test_drop_download_height));
m_fluffy_blocks_enabled = !get_arg(vm, arg_no_fluffy_blocks); m_fluffy_blocks_enabled = !get_arg(vm, arg_no_fluffy_blocks);
m_pad_transactions = get_arg(vm, arg_pad_transactions);
m_offline = get_arg(vm, arg_offline); m_offline = get_arg(vm, arg_offline);
m_disable_dns_checkpoints = get_arg(vm, arg_disable_dns_checkpoints); m_disable_dns_checkpoints = get_arg(vm, arg_disable_dns_checkpoints);
if (!command_line::is_arg_defaulted(vm, arg_fluffy_blocks)) if (!command_line::is_arg_defaulted(vm, arg_fluffy_blocks))

View file

@ -754,6 +754,13 @@ namespace cryptonote
*/ */
bool fluffy_blocks_enabled() const { return m_fluffy_blocks_enabled; } bool fluffy_blocks_enabled() const { return m_fluffy_blocks_enabled; }
/**
* @brief get whether transaction relay should be padded
*
* @return whether transaction relay should be padded
*/
bool pad_transactions() const { return m_pad_transactions; }
/** /**
* @brief check a set of hashes against the precompiled hash set * @brief check a set of hashes against the precompiled hash set
* *
@ -1013,6 +1020,7 @@ namespace cryptonote
bool m_fluffy_blocks_enabled; bool m_fluffy_blocks_enabled;
bool m_offline; bool m_offline;
bool m_pad_transactions;
}; };
} }

View file

@ -146,9 +146,11 @@ namespace cryptonote
struct request struct request
{ {
std::vector<blobdata> txs; std::vector<blobdata> txs;
std::string _; // padding
BEGIN_KV_SERIALIZE_MAP() BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txs) KV_SERIALIZE(txs)
KV_SERIALIZE(_)
END_KV_SERIALIZE_MAP() END_KV_SERIALIZE_MAP()
}; };
}; };

View file

@ -1726,8 +1726,39 @@ skip:
bool t_cryptonote_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context) bool t_cryptonote_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context)
{ {
// no check for success, so tell core they're relayed unconditionally // no check for success, so tell core they're relayed unconditionally
const bool pad_transactions = m_core.pad_transactions();
size_t bytes = pad_transactions ? 9 /* header */ + 4 /* 1 + 'txs' */ + tools::get_varint_data(arg.txs.size()).size() : 0;
for(auto tx_blob_it = arg.txs.begin(); tx_blob_it!=arg.txs.end(); ++tx_blob_it) for(auto tx_blob_it = arg.txs.begin(); tx_blob_it!=arg.txs.end(); ++tx_blob_it)
{
m_core.on_transaction_relayed(*tx_blob_it); m_core.on_transaction_relayed(*tx_blob_it);
if (pad_transactions)
bytes += tools::get_varint_data(tx_blob_it->size()).size() + tx_blob_it->size();
}
if (pad_transactions)
{
// stuff some dummy bytes in to stay safe from traffic volume analysis
static constexpr size_t granularity = 1024;
size_t padding = granularity - bytes % granularity;
const size_t overhead = 2 /* 1 + '_' */ + tools::get_varint_data(padding).size();
if (overhead > padding)
padding = 0;
else
padding -= overhead;
arg._ = std::string(padding, ' ');
std::string arg_buff;
epee::serialization::store_t_to_binary(arg, arg_buff);
// we probably lowballed the payload size a bit, so added a but too much. Fix this now.
size_t remove = arg_buff.size() % granularity;
if (remove > arg._.size())
arg._.clear();
else
arg._.resize(arg._.size() - remove);
// if the size of _ moved enough, we might lose byte in size encoding, we don't care
}
return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context); return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context);
} }
//------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------

View file

@ -104,5 +104,6 @@ namespace tests
cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; } cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; }
bool fluffy_blocks_enabled() const { return false; } bool fluffy_blocks_enabled() const { return false; }
uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; } uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; }
bool pad_transactions() const { return false; }
}; };
} }

View file

@ -83,6 +83,7 @@ public:
cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; } cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; }
bool fluffy_blocks_enabled() const { return false; } bool fluffy_blocks_enabled() const { return false; }
uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; } uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; }
bool pad_transactions() { return false; }
void stop() {} void stop() {}
}; };