daemon: new relay_tx command and RPC

This commit is contained in:
moneromooo-monero 2017-04-02 12:17:35 +01:00
parent c9063c0b8f
commit 548075b1f5
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3
8 changed files with 122 additions and 1 deletions

View File

@ -563,4 +563,19 @@ bool t_command_parser_executor::update(const std::vector<std::string>& args)
return m_executor.update(args.front()); return m_executor.update(args.front());
} }
bool t_command_parser_executor::relay_tx(const std::vector<std::string>& args)
{
if (args.size() != 1) return false;
std::string txid;
crypto::hash hash;
if (!parse_hash256(args[0], hash))
{
std::cout << "failed to parse tx id" << std::endl;
return true;
}
txid = args[0];
return m_executor.relay_tx(txid);
}
} // namespace daemonize } // namespace daemonize

View File

@ -132,6 +132,8 @@ public:
bool print_blockchain_dynamic_stats(const std::vector<std::string>& args); bool print_blockchain_dynamic_stats(const std::vector<std::string>& args);
bool update(const std::vector<std::string>& args); bool update(const std::vector<std::string>& args);
bool relay_tx(const std::vector<std::string>& args);
}; };
} // namespace daemonize } // namespace daemonize

View File

@ -248,6 +248,11 @@ t_command_server::t_command_server(
, std::bind(&t_command_parser_executor::update, &m_parser, p::_1) , std::bind(&t_command_parser_executor::update, &m_parser, p::_1)
, "subcommands: check (check if an update is available), download (download it is there is), update (not implemented)" , "subcommands: check (check if an update is available), download (download it is there is), update (not implemented)"
); );
m_command_lookup.set_handler(
"relay_tx"
, std::bind(&t_command_parser_executor::relay_tx, &m_parser, p::_1)
, "Relay a given transaction by its txid"
);
} }
bool t_command_server::process_command_str(const std::string& cmd) bool t_command_server::process_command_str(const std::string& cmd)

View File

@ -1646,4 +1646,32 @@ bool t_rpc_command_executor::update(const std::string &command)
return true; return true;
} }
bool t_rpc_command_executor::relay_tx(const std::string &txid)
{
cryptonote::COMMAND_RPC_RELAY_TX::request req;
cryptonote::COMMAND_RPC_RELAY_TX::response res;
std::string fail_message = "Unsuccessful";
epee::json_rpc::error error_resp;
req.txids.push_back(txid);
if (m_is_rpc)
{
if (!m_rpc_client->json_rpc_request(req, res, "relay_tx", fail_message.c_str()))
{
return true;
}
}
else
{
if (!m_rpc_server->on_relay_tx(req, res, error_resp) || res.status != CORE_RPC_STATUS_OK)
{
tools::fail_msg_writer() << make_error(fail_message, res.status);
return true;
}
}
return true;
}
}// namespace daemonize }// namespace daemonize

View File

@ -153,6 +153,8 @@ public:
bool print_blockchain_dynamic_stats(uint64_t nblocks); bool print_blockchain_dynamic_stats(uint64_t nblocks);
bool update(const std::string &command); bool update(const std::string &command);
bool relay_tx(const std::string &txid);
}; };
} // namespace daemonize } // namespace daemonize

View File

@ -1588,6 +1588,52 @@ namespace cryptonote
return true; return true;
} }
//------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp)
{
if(!check_core_busy())
{
error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY;
error_resp.message = "Core is busy.";
return false;
}
bool failed = false;
for (const auto &str: req.txids)
{
cryptonote::blobdata txid_data;
if(!epee::string_tools::parse_hexstr_to_binbuff(str, txid_data))
{
res.status = std::string("Invalid transaction id: ") + str;
failed = true;
}
crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
cryptonote::transaction tx;
bool r = m_core.get_pool_transaction(txid, tx);
if (r)
{
cryptonote_connection_context fake_context = AUTO_VAL_INIT(fake_context);
NOTIFY_NEW_TRANSACTIONS::request r;
r.txs.push_back(cryptonote::tx_to_blob(tx));
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
}
else
{
res.status = std::string("Transaction not found in pool: ") + str;
failed = true;
}
}
if (failed)
{
return false;
}
res.status = CORE_RPC_STATUS_OK;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_bind_port = { const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_bind_port = {
"rpc-bind-port" "rpc-bind-port"

View File

@ -121,6 +121,7 @@ namespace cryptonote
MAP_JON_RPC_WE("get_coinbase_tx_sum", on_get_coinbase_tx_sum, COMMAND_RPC_GET_COINBASE_TX_SUM) MAP_JON_RPC_WE("get_coinbase_tx_sum", on_get_coinbase_tx_sum, COMMAND_RPC_GET_COINBASE_TX_SUM)
MAP_JON_RPC_WE("get_fee_estimate", on_get_per_kb_fee_estimate, COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE) MAP_JON_RPC_WE("get_fee_estimate", on_get_per_kb_fee_estimate, COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE)
MAP_JON_RPC_WE_IF("get_alternate_chains",on_get_alternate_chains, COMMAND_RPC_GET_ALTERNATE_CHAINS, !m_restricted) MAP_JON_RPC_WE_IF("get_alternate_chains",on_get_alternate_chains, COMMAND_RPC_GET_ALTERNATE_CHAINS, !m_restricted)
MAP_JON_RPC_WE_IF("relay_tx", on_relay_tx, COMMAND_RPC_RELAY_TX, !m_restricted)
END_JSON_RPC_MAP() END_JSON_RPC_MAP()
END_URI_MAP2() END_URI_MAP2()
@ -174,6 +175,7 @@ namespace cryptonote
bool on_get_coinbase_tx_sum(const COMMAND_RPC_GET_COINBASE_TX_SUM::request& req, COMMAND_RPC_GET_COINBASE_TX_SUM::response& res, epee::json_rpc::error& error_resp); bool on_get_coinbase_tx_sum(const COMMAND_RPC_GET_COINBASE_TX_SUM::request& req, COMMAND_RPC_GET_COINBASE_TX_SUM::response& res, epee::json_rpc::error& error_resp);
bool on_get_per_kb_fee_estimate(const COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp); bool on_get_per_kb_fee_estimate(const COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp);
bool on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp); bool on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp);
bool on_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp);
//----------------------- //-----------------------
private: private:

View File

@ -49,7 +49,7 @@ namespace cryptonote
// advance which version they will stop working with // advance which version they will stop working with
// Don't go over 32767 for any of these // Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 1 #define CORE_RPC_VERSION_MAJOR 1
#define CORE_RPC_VERSION_MINOR 8 #define CORE_RPC_VERSION_MINOR 9
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR) #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
@ -1495,4 +1495,25 @@ namespace cryptonote
END_KV_SERIALIZE_MAP() END_KV_SERIALIZE_MAP()
}; };
}; };
struct COMMAND_RPC_RELAY_TX
{
struct request
{
std::list<std::string> txids;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txids)
END_KV_SERIALIZE_MAP()
};
struct response
{
std::string status;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};
};
} }