aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2017-04-11 00:32:30 +0200
committerRiccardo Spagni <ric@spagni.net>2017-04-11 00:32:30 +0200
commit878c4ee913eb9f3ba7f56e939988b4a34b3c30a0 (patch)
treedfa82e81aa79559181aba2b94fad70d89bb32af7
parentMerge pull request #1951 (diff)
parentdaemon: new relay_tx command and RPC (diff)
downloadmonero-878c4ee913eb9f3ba7f56e939988b4a34b3c30a0.tar.xz
Merge pull request #1952
548075b1 daemon: new relay_tx command and RPC (moneromooo-monero)
-rw-r--r--src/daemon/command_parser_executor.cpp15
-rw-r--r--src/daemon/command_parser_executor.h2
-rw-r--r--src/daemon/command_server.cpp5
-rw-r--r--src/daemon/rpc_command_executor.cpp28
-rw-r--r--src/daemon/rpc_command_executor.h2
-rw-r--r--src/rpc/core_rpc_server.cpp46
-rw-r--r--src/rpc/core_rpc_server.h2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h23
8 files changed, 122 insertions, 1 deletions
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index 4e6e83eb5..a7caeeffc 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -563,4 +563,19 @@ bool t_command_parser_executor::update(const std::vector<std::string>& args)
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
diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h
index 0a5ca8dd9..a453553f1 100644
--- a/src/daemon/command_parser_executor.h
+++ b/src/daemon/command_parser_executor.h
@@ -132,6 +132,8 @@ public:
bool print_blockchain_dynamic_stats(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
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 0081e00dc..21f550a85 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -248,6 +248,11 @@ t_command_server::t_command_server(
, 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)"
);
+ 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)
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index c5b17268d..249007436 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -1646,4 +1646,32 @@ bool t_rpc_command_executor::update(const std::string &command)
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
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index a015c83ea..3f551bd14 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -153,6 +153,8 @@ public:
bool print_blockchain_dynamic_stats(uint64_t nblocks);
bool update(const std::string &command);
+
+ bool relay_tx(const std::string &txid);
};
} // namespace daemonize
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index a800dbb35..7cce0bf04 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -1588,6 +1588,52 @@ namespace cryptonote
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 = {
"rpc-bind-port"
diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h
index f8eff5f8c..0aa222c87 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -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_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("relay_tx", on_relay_tx, COMMAND_RPC_RELAY_TX, !m_restricted)
END_JSON_RPC_MAP()
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_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_relay_tx(const COMMAND_RPC_RELAY_TX::request& req, COMMAND_RPC_RELAY_TX::response& res, epee::json_rpc::error& error_resp);
//-----------------------
private:
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 6f60093ac..3991fc27b 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -49,7 +49,7 @@ namespace cryptonote
// advance which version they will stop working with
// Don't go over 32767 for any of these
#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 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()
};
};
+
+ 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()
+ };
+ };
}