1
0
Fork 0
forked from lthn/blockchain

improved p2p protocol for relaying tx over tor

This commit is contained in:
cryptozoidberg 2022-03-21 16:47:11 +02:00
parent 7f82a13e62
commit 72bfd89717
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
9 changed files with 78 additions and 59 deletions

View file

@ -250,6 +250,8 @@
static_assert(CURRENCY_MINER_TX_MAX_OUTS <= CURRENCY_TX_MAX_ALLOWED_OUTS, "Miner tx must obey normal tx max outs limit");
static_assert(PREMINE_AMOUNT / WALLET_MAX_ALLOWED_OUTPUT_AMOUNT < CURRENCY_MINER_TX_MAX_OUTS, "Premine can't be divided into reasonable number of outs");
#define CURRENCY_RELAY_TXS_MAX_COUNT 5

View file

@ -666,7 +666,7 @@ namespace currency
bool tx_memory_pool::force_relay_pool() const
{
LOG_PRINT_GREEN("Preparing relay message...", LOG_LEVEL_0);
NOTIFY_NEW_TRANSACTIONS::request r = AUTO_VAL_INIT(r);
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request r = AUTO_VAL_INIT(r);
m_db_transactions.enumerate_items([&](uint64_t i, const crypto::hash& k, const tx_details& v)
{

View file

@ -71,7 +71,7 @@ namespace currency
/************************************************************************/
/* */
/************************************************************************/
struct NOTIFY_NEW_TRANSACTIONS
struct NOTIFY_OR_INVOKE_NEW_TRANSACTIONS
{
const static int ID = BC_COMMANDS_POOL_BASE + 2;
@ -83,6 +83,16 @@ namespace currency
KV_SERIALIZE(txs)
END_KV_SERIALIZE_MAP()
};
struct response
{
std::string code;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(code)
END_KV_SERIALIZE_MAP()
};
};
/************************************************************************/
/* */
@ -174,34 +184,6 @@ namespace currency
};
};
/************************************************************************/
/* */
/************************************************************************/
struct INVOKE_NEW_TRANSACTION
{
const static int ID = BC_COMMANDS_POOL_BASE + 8;
struct request
{
blobdata tx;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx)
END_KV_SERIALIZE_MAP()
};
struct response
{
std::string code;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(code)
END_KV_SERIALIZE_MAP()
};
};
}
#include "currency_protocol_defs_print.h"

View file

@ -35,14 +35,15 @@ namespace currency
typedef core_stat_info stat_info;
typedef t_currency_protocol_handler<t_core> currency_protocol_handler;
typedef CORE_SYNC_DATA payload_type;
typedef std::pair<NOTIFY_NEW_TRANSACTIONS::request, currency_connection_context> relay_que_entry;
typedef std::pair<NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request, currency_connection_context> relay_que_entry;
t_currency_protocol_handler(t_core& rcore, nodetool::i_p2p_endpoint<connection_context>* p_net_layout);
~t_currency_protocol_handler();
BEGIN_INVOKE_MAP2(currency_protocol_handler)
HANDLE_NOTIFY_T2(NOTIFY_NEW_BLOCK, &currency_protocol_handler::handle_notify_new_block)
HANDLE_NOTIFY_T2(NOTIFY_NEW_TRANSACTIONS, &currency_protocol_handler::handle_notify_new_transactions)
HANDLE_NOTIFY_T2(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS, &currency_protocol_handler::handle_notify_new_transactions)
HANDLE_INVOKE_T2(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS, &currency_protocol_handler::handle_invoke_new_transaction)
HANDLE_NOTIFY_T2(NOTIFY_REQUEST_GET_OBJECTS, &currency_protocol_handler::handle_request_get_objects)
HANDLE_NOTIFY_T2(NOTIFY_RESPONSE_GET_OBJECTS, &currency_protocol_handler::handle_response_get_objects)
HANDLE_NOTIFY_T2(NOTIFY_REQUEST_CHAIN, &currency_protocol_handler::handle_request_chain)
@ -76,16 +77,18 @@ namespace currency
private:
//----------------- commands handlers ----------------------------------------------
int handle_notify_new_block(int command, NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& context);
int handle_notify_new_transactions(int command, NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& context);
int handle_notify_new_transactions(int command, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& context);
int handle_invoke_new_transaction(int command, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& req, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response& rsp, currency_connection_context& context);
int handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context);
int handle_response_get_objects(int command, NOTIFY_RESPONSE_GET_OBJECTS::request& arg, currency_connection_context& context);
int handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request& arg, currency_connection_context& context);
int handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, currency_connection_context& context);
//----------------- i_bc_protocol_layout ---------------------------------------
virtual bool relay_block(NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& exclude_context);
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context);
virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context);
//----------------------------------------------------------------------------------
//bool get_payload_sync_data(HANDSHAKE_DATA::request& hshd, currency_connection_context& context);
bool request_missing_objects(currency_connection_context& context, bool check_having_blocks);
@ -93,7 +96,7 @@ namespace currency
void relay_que_worker();
void process_current_relay_que(const std::list<relay_que_entry>& que);
bool check_stop_flag_and_drop_cc(currency_connection_context& context);
int handle_new_transaction_from_net(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& req, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response& rsp, currency_connection_context& context, bool is_notify);
t_core& m_core;
nodetool::p2p_endpoint_stub<connection_context> m_p2p_stub;

View file

@ -369,48 +369,79 @@ namespace currency
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
int t_currency_protocol_handler<t_core>::handle_notify_new_transactions(int command, NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& context)
int t_currency_protocol_handler<t_core>::handle_notify_new_transactions(int command, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& context)
{
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response rsp_dummy = AUTO_VAL_INIT(rsp_dummy);
return this->handle_new_transaction_from_net(arg, rsp_dummy, context, true);
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
int t_currency_protocol_handler<t_core>::handle_invoke_new_transaction(int command, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& req, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response& rsp, currency_connection_context& context)
{
return this->handle_new_transaction_from_net(req, rsp, context, false);
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
int t_currency_protocol_handler<t_core>::handle_new_transaction_from_net(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response& rsp, currency_connection_context& context, bool is_notify)
{
//do not process requests if it comes from node wich is debugged
if (m_debug_ip_address != 0 && context.m_remote_ip == m_debug_ip_address)
{
rsp.code = API_RETURN_CODE_ACCESS_DENIED;
return 1;
}
//if(context.m_state != currency_connection_context::state_normal)
// return 1;
if (!this->is_synchronized())
{
rsp.code = API_RETURN_CODE_BUSY;
return 1;
}
uint64_t inital_tx_count = arg.txs.size();
if (inital_tx_count > CURRENCY_RELAY_TXS_MAX_COUNT)
{
LOG_PRINT_L1("NOTIFY_NEW_TRANSACTIONS: To many transactions in NOTIFY_OR_INVOKE_NEW_TRANSACTIONS(" << inital_tx_count << ")");
rsp.code = API_RETURN_CODE_OVERFLOW;
return 1;
}
TIME_MEASURE_START_MS(new_transactions_handle_time);
for(auto tx_blob_it = arg.txs.begin(); tx_blob_it!=arg.txs.end();)
for (auto tx_blob_it = arg.txs.begin(); tx_blob_it != arg.txs.end();)
{
currency::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
m_core.handle_incoming_tx(*tx_blob_it, tvc, false);
if(tvc.m_verification_failed)
if (tvc.m_verification_failed)
{
LOG_PRINT_L0("NOTIFY_NEW_TRANSACTIONS: Tx verification failed, dropping connection");
m_p2p->drop_connection(context);
if(is_notify)
m_p2p->drop_connection(context);
else
rsp.code = API_RETURN_CODE_FAIL;
return 1;
}
if(tvc.m_should_be_relayed)
if (tvc.m_should_be_relayed)
++tx_blob_it;
else
arg.txs.erase(tx_blob_it++);
}
if(arg.txs.size())
if (arg.txs.size())
{
//TODO: add announce usage here
relay_transactions(arg, context);
}
TIME_MEASURE_FINISH_MS(new_transactions_handle_time);
LOG_PRINT_L2("NOTIFY_NEW_TRANSACTIONS: " << new_transactions_handle_time << "ms (inital_tx_count: " << inital_tx_count << ", relayed_tx_count: " << arg.txs.size() << ")");
return true;
LOG_PRINT_L2("NOTIFY_OR_INVOKE_NEW_TRANSACTIONS(is_notify=" << is_notify <<"): " << new_transactions_handle_time << "ms (inital_tx_count: " << inital_tx_count << ", relayed_tx_count: " << arg.txs.size() << ")");
rsp.code = API_RETURN_CODE_OK;
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
int t_currency_protocol_handler<t_core>::handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context)
@ -759,7 +790,7 @@ namespace currency
m_p2p->get_connections(connections);
for (auto& cc : connections)
{
NOTIFY_NEW_TRANSACTIONS::request req = AUTO_VAL_INIT(req);
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request req = AUTO_VAL_INIT(req);
for (auto& qe : que)
{
//exclude relaying to original sender
@ -769,7 +800,7 @@ namespace currency
}
if (req.txs.size())
{
post_notify<NOTIFY_NEW_TRANSACTIONS>(req, cc);
post_notify<NOTIFY_OR_INVOKE_NEW_TRANSACTIONS>(req, cc);
if (debug_ss.tellp())
debug_ss << ", ";
@ -947,7 +978,7 @@ namespace currency
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
bool t_currency_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)
bool t_currency_protocol_handler<t_core>::relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)
{
#ifdef ASYNC_RELAY_MODE
{
@ -959,7 +990,7 @@ namespace currency
//m_relay_que_cv.notify_all();
return true;
#else
return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context);
return relay_post_notify<NOTIFY_OR_INVOKE_NEW_TRANSACTIONS>(arg, exclude_context);
#endif
}
}

View file

@ -17,7 +17,7 @@ namespace currency
struct i_currency_protocol
{
virtual bool relay_block(NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& exclude_context)=0;
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)=0;
virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)=0;
//virtual bool request_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context)=0;
};
@ -30,7 +30,7 @@ namespace currency
{
return false;
}
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& /*arg*/, currency_connection_context& /*exclude_context*/)
virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& /*arg*/, currency_connection_context& /*exclude_context*/)
{
return false;
}

View file

@ -705,7 +705,7 @@ namespace currency
}
NOTIFY_NEW_TRANSACTIONS::request r;
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request r;
r.txs.push_back(tx_blob);
m_core.get_protocol()->relay_transactions(r, fake_context);
//TODO: make sure that tx has reached other nodes here, probably wait to receive reflections from other nodes
@ -716,7 +716,7 @@ namespace currency
bool core_rpc_server::on_force_relaey_raw_txs(const COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& req, COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& res, connection_context& cntx)
{
CHECK_CORE_READY();
NOTIFY_NEW_TRANSACTIONS::request r = AUTO_VAL_INIT(r);
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request r = AUTO_VAL_INIT(r);
for (const auto& t : req.txs_as_hex)
{

View file

@ -4616,14 +4616,15 @@ void wallet2::send_transaction_to_network(const transaction& tx)
{
continue;//THROW_IF_FALSE_WALLET_EX(false, error::no_connection_to_daemon, "Failed to connect to TOR node");
}
currency::NOTIFY_NEW_TRANSACTIONS::request p2p_req = AUTO_VAL_INIT(p2p_req);
currency::NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request p2p_req = AUTO_VAL_INIT(p2p_req);
currency::NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response p2p_rsp = AUTO_VAL_INIT(p2p_rsp);
p2p_req.txs.push_back(t_serializable_object_to_blob(tx));
std::string blob;
epee::serialization::store_t_to_binary(p2p_req, blob);
p2p_client.notify(NOTIFY_NEW_TRANSACTIONS::ID, blob);
p2p_client.invoke(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::ID, blob);
p2p_client.disconnect();
//checking if transaction got relayed
//checking if transaction got relayed to other nodes and
//return;
}
}

View file

@ -51,7 +51,7 @@ public:
//----------------- i_currency_protocol ---------------------------------------
virtual bool relay_block(currency::NOTIFY_NEW_BLOCK::request& /*arg*/, currency::currency_connection_context& /*exclude_context*/) override { return false; }
virtual bool relay_transactions(currency::NOTIFY_NEW_TRANSACTIONS::request& arg, currency::currency_connection_context& /*exclude_context*/) override
virtual bool relay_transactions(currency::NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency::currency_connection_context& /*exclude_context*/) override
{
if (m_core_listener)
{