aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/CMakeLists.txt3
-rw-r--r--src/rpc/core_rpc_server.cpp81
-rw-r--r--src/rpc/core_rpc_server.h5
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h68
-rw-r--r--src/rpc/daemon_handler.cpp2
-rw-r--r--src/rpc/message_data_structs.h1
-rw-r--r--src/rpc/zmq_server.cpp1
7 files changed, 139 insertions, 22 deletions
diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt
index 8fc42b7e3..d2c4a33cb 100644
--- a/src/rpc/CMakeLists.txt
+++ b/src/rpc/CMakeLists.txt
@@ -112,6 +112,7 @@ target_link_libraries(rpc
common
cryptonote_core
cryptonote_protocol
+ version
${Boost_REGEX_LIBRARY}
${Boost_THREAD_LIBRARY}
PRIVATE
@@ -121,6 +122,7 @@ target_link_libraries(daemon_messages
LINK_PRIVATE
cryptonote_core
cryptonote_protocol
+ version
serialization
${EXTRA_LIBRARIES})
@@ -129,6 +131,7 @@ target_link_libraries(daemon_rpc_server
rpc
cryptonote_core
cryptonote_protocol
+ version
daemon_messages
serialization
${Boost_CHRONO_LIBRARY}
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index d7968731a..13157f3d4 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -91,12 +91,10 @@ namespace cryptonote
bool core_rpc_server::init(
const boost::program_options::variables_map& vm
, const bool restricted
- , const network_type nettype
, const std::string& port
)
{
m_restricted = restricted;
- m_nettype = nettype;
m_net_server.set_threads_prefix("RPC");
auto rpc_config = cryptonote::rpc_args::process(vm);
@@ -191,10 +189,13 @@ namespace cryptonote
res.rpc_connections_count = get_connections_count();
res.white_peerlist_size = m_p2p.get_peerlist_manager().get_white_peers_count();
res.grey_peerlist_size = m_p2p.get_peerlist_manager().get_gray_peers_count();
- res.mainnet = m_nettype == MAINNET;
- res.testnet = m_nettype == TESTNET;
- res.stagenet = m_nettype == STAGENET;
- res.nettype = m_nettype == MAINNET ? "mainnet" : m_nettype == TESTNET ? "testnet" : m_nettype == STAGENET ? "stagenet" : "fakechain";
+
+ cryptonote::network_type net_type = nettype();
+ res.mainnet = net_type == MAINNET;
+ res.testnet = net_type == TESTNET;
+ res.stagenet = net_type == STAGENET;
+ res.nettype = net_type == MAINNET ? "mainnet" : net_type == TESTNET ? "testnet" : net_type == STAGENET ? "stagenet" : "fakechain";
+
res.cumulative_difficulty = m_core.get_blockchain_storage().get_db().get_block_cumulative_difficulty(res.height - 1);
res.block_size_limit = res.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit();
res.block_size_median = res.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median();
@@ -210,6 +211,7 @@ namespace cryptonote
}
res.database_size = m_core.get_blockchain_storage().get_db().get_database_size();
res.update_available = m_core.is_update_available();
+ res.version = m_restricted ? "" : MONERO_VERSION;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
@@ -750,7 +752,7 @@ namespace cryptonote
PERF_TIMER(on_start_mining);
CHECK_CORE_READY();
cryptonote::address_parse_info info;
- if(!get_account_address_from_str(info, m_nettype, req.miner_address))
+ if(!get_account_address_from_str(info, nettype(), req.miner_address))
{
res.status = "Failed, wrong address";
LOG_PRINT_L0(res.status);
@@ -831,7 +833,7 @@ namespace cryptonote
res.speed = lMiner.get_speed();
res.threads_count = lMiner.get_threads_count();
const account_public_address& lMiningAdr = lMiner.get_mining_address();
- res.address = get_account_address_as_str(m_nettype, false, lMiningAdr);
+ res.address = get_account_address_as_str(nettype(), false, lMiningAdr);
}
res.status = CORE_RPC_STATUS_OK;
@@ -1064,7 +1066,7 @@ namespace cryptonote
cryptonote::address_parse_info info;
- if(!req.wallet_address.size() || !cryptonote::get_account_address_from_str(info, m_nettype, req.wallet_address))
+ if(!req.wallet_address.size() || !cryptonote::get_account_address_from_str(info, nettype(), req.wallet_address))
{
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_WALLET_ADDRESS;
error_resp.message = "Failed to parse wallet address";
@@ -1077,7 +1079,7 @@ namespace cryptonote
return false;
}
- block b = AUTO_VAL_INIT(b);
+ block b;
cryptonote::blobdata blob_reserve;
blob_reserve.resize(req.reserve_size, 0);
if(!m_core.get_block_template(b, info.address, res.difficulty, res.height, res.expected_reward, blob_reserve))
@@ -1148,7 +1150,7 @@ namespace cryptonote
// Fixing of high orphan issue for most pools
// Thanks Boolberry!
- block b = AUTO_VAL_INIT(b);
+ block b;
if(!parse_and_validate_block_from_blob(blockblob, b))
{
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB;
@@ -1216,7 +1218,7 @@ namespace cryptonote
error_resp.message = "Wrong block blob";
return false;
}
- block b = AUTO_VAL_INIT(b);
+ block b;
if(!parse_and_validate_block_from_blob(blockblob, b))
{
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB;
@@ -1590,10 +1592,13 @@ namespace cryptonote
res.rpc_connections_count = get_connections_count();
res.white_peerlist_size = m_p2p.get_peerlist_manager().get_white_peers_count();
res.grey_peerlist_size = m_p2p.get_peerlist_manager().get_gray_peers_count();
- res.mainnet = m_nettype == MAINNET;
- res.testnet = m_nettype == TESTNET;
- res.stagenet = m_nettype == STAGENET;
- res.nettype = m_nettype == MAINNET ? "mainnet" : m_nettype == TESTNET ? "testnet" : m_nettype == STAGENET ? "stagenet" : "fakechain";
+
+ cryptonote::network_type net_type = nettype();
+ res.mainnet = net_type == MAINNET;
+ res.testnet = net_type == TESTNET;
+ res.stagenet = net_type == STAGENET;
+ res.nettype = net_type == MAINNET ? "mainnet" : net_type == TESTNET ? "testnet" : net_type == STAGENET ? "stagenet" : "fakechain";
+
res.cumulative_difficulty = m_core.get_blockchain_storage().get_db().get_block_cumulative_difficulty(res.height - 1);
res.block_size_limit = res.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit();
res.block_size_median = res.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median();
@@ -1609,6 +1614,7 @@ namespace cryptonote
}
res.database_size = m_core.get_blockchain_storage().get_db().get_database_size();
res.update_available = m_core.is_update_available();
+ res.version = m_restricted ? "" : MONERO_VERSION;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
@@ -2133,7 +2139,7 @@ namespace cryptonote
return false;
}
- res.distributions.push_back({std::move(*data), amount, req.binary});
+ res.distributions.push_back({std::move(*data), amount, "", req.binary, req.compress});
}
}
catch (const std::exception &e)
@@ -2147,6 +2153,47 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool core_rpc_server::on_get_output_distribution_bin(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res)
+ {
+ PERF_TIMER(on_get_output_distribution_bin);
+
+ bool r;
+ if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::BIN, "/get_output_distribution.bin", req, res, r))
+ return r;
+
+ res.status = "Failed";
+
+ if (!req.binary)
+ {
+ res.status = "Binary only call";
+ return false;
+ }
+ try
+ {
+ // 0 is placeholder for the whole chain
+ const uint64_t req_to_height = req.to_height ? req.to_height : (m_core.get_current_blockchain_height() - 1);
+ for (uint64_t amount: req.amounts)
+ {
+ auto data = rpc::RpcHandler::get_output_distribution([this](uint64_t amount, uint64_t from, uint64_t to, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) { return m_core.get_output_distribution(amount, from, to, start_height, distribution, base); }, amount, req.from_height, req_to_height, req.cumulative);
+ if (!data)
+ {
+ res.status = "Failed to get output distribution";
+ return false;
+ }
+
+ res.distributions.push_back({std::move(*data), amount, "", req.binary, req.compress});
+ }
+ }
+ catch (const std::exception &e)
+ {
+ res.status = "Failed to get output distribution";
+ return false;
+ }
+
+ res.status = CORE_RPC_STATUS_OK;
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
const command_line::arg_descriptor<std::string, false, true, 2> core_rpc_server::arg_rpc_bind_port = {
diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h
index 3ba882b23..6a616e2e0 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -70,10 +70,9 @@ namespace cryptonote
bool init(
const boost::program_options::variables_map& vm,
const bool restricted,
- const network_type nettype,
const std::string& port
);
- network_type nettype() const { return m_nettype; }
+ network_type nettype() const { return m_core.get_nettype(); }
CHAIN_HTTP_TO_MAP2(connection_context); //forward http requests to uri map
@@ -117,6 +116,7 @@ namespace cryptonote
MAP_URI_AUTO_JON2_IF("/stop_save_graph", on_stop_save_graph, COMMAND_RPC_STOP_SAVE_GRAPH, !m_restricted)
MAP_URI_AUTO_JON2("/get_outs", on_get_outs, COMMAND_RPC_GET_OUTPUTS)
MAP_URI_AUTO_JON2_IF("/update", on_update, COMMAND_RPC_UPDATE, !m_restricted)
+ MAP_URI_AUTO_BIN2("/get_output_distribution.bin", on_get_output_distribution_bin, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION)
BEGIN_JSON_RPC_MAP("/json_rpc")
MAP_JON_RPC("get_block_count", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT)
MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT)
@@ -187,6 +187,7 @@ namespace cryptonote
bool on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res);
bool on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res);
bool on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res);
+ bool on_get_output_distribution_bin(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res);
//json_rpc
bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res);
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 8e8df7a52..d54bfbf8d 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -34,6 +34,40 @@
#include "cryptonote_basic/difficulty.h"
#include "crypto/hash.h"
#include "rpc/rpc_handler.h"
+#include "common/varint.h"
+#include "common/perf_timer.h"
+
+namespace
+{
+ template<typename T>
+ std::string compress_integer_array(const std::vector<T> &v)
+ {
+ std::string s;
+ s.resize(v.size() * (sizeof(T) * 8 / 7 + 1));
+ char *ptr = (char*)s.data();
+ for (const T &t: v)
+ tools::write_varint(ptr, t);
+ s.resize(ptr - s.data());
+ return s;
+ }
+
+ template<typename T>
+ std::vector<T> decompress_integer_array(const std::string &s)
+ {
+ std::vector<T> v;
+ v.reserve(s.size());
+ int read = 0;
+ const std::string::const_iterator end = s.end();
+ for (std::string::const_iterator i = s.begin(); i != end; std::advance(i, read))
+ {
+ T t;
+ read = tools::read_varint(std::string::const_iterator(i), s.end(), t);
+ CHECK_AND_ASSERT_THROW_MES(read > 0 && read <= 256, "Error decompressing data");
+ v.push_back(t);
+ }
+ return v;
+ }
+}
namespace cryptonote
{
@@ -50,7 +84,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 2
-#define CORE_RPC_VERSION_MINOR 1
+#define CORE_RPC_VERSION_MINOR 2
#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)
@@ -697,9 +731,11 @@ namespace cryptonote
struct request
{
std::vector<get_outputs_out> outputs;
+ bool get_txid;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(outputs)
+ KV_SERIALIZE_OPT(get_txid, true)
END_KV_SERIALIZE_MAP()
};
@@ -892,6 +928,7 @@ namespace cryptonote
bool was_bootstrap_ever_used;
uint64_t database_size;
bool update_available;
+ std::string version;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
@@ -926,6 +963,7 @@ namespace cryptonote
KV_SERIALIZE(was_bootstrap_ever_used)
KV_SERIALIZE(database_size)
KV_SERIALIZE(update_available)
+ KV_SERIALIZE(version)
END_KV_SERIALIZE_MAP()
};
};
@@ -2222,6 +2260,7 @@ namespace cryptonote
uint64_t to_height;
bool cumulative;
bool binary;
+ bool compress;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amounts)
@@ -2229,6 +2268,7 @@ namespace cryptonote
KV_SERIALIZE_OPT(to_height, (uint64_t)0)
KV_SERIALIZE_OPT(cumulative, false)
KV_SERIALIZE_OPT(binary, true)
+ KV_SERIALIZE_OPT(compress, false)
END_KV_SERIALIZE_MAP()
};
@@ -2236,14 +2276,38 @@ namespace cryptonote
{
rpc::output_distribution_data data;
uint64_t amount;
+ std::string compressed_data;
bool binary;
+ bool compress;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
KV_SERIALIZE_N(data.start_height, "start_height")
KV_SERIALIZE(binary)
+ KV_SERIALIZE(compress)
if (this_ref.binary)
- KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(data.distribution, "distribution")
+ {
+ if (is_store)
+ {
+ if (this_ref.compress)
+ {
+ const_cast<std::string&>(this_ref.compressed_data) = compress_integer_array(this_ref.data.distribution);
+ KV_SERIALIZE(compressed_data)
+ }
+ else
+ KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(data.distribution, "distribution")
+ }
+ else
+ {
+ if (this_ref.compress)
+ {
+ KV_SERIALIZE(compressed_data)
+ const_cast<std::vector<uint64_t>&>(this_ref.data.distribution) = decompress_integer_array<uint64_t>(this_ref.compressed_data);
+ }
+ else
+ KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(data.distribution, "distribution")
+ }
+ }
else
KV_SERIALIZE_N(data.distribution, "distribution")
KV_SERIALIZE_N(data.base, "base")
diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp
index 64a5cc858..e2885dbb5 100644
--- a/src/rpc/daemon_handler.cpp
+++ b/src/rpc/daemon_handler.cpp
@@ -34,6 +34,7 @@
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/blobdatatype.h"
#include "ringct/rctSigs.h"
+#include "version.h"
namespace cryptonote
{
@@ -437,6 +438,7 @@ namespace rpc
res.info.block_size_limit = res.info.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit();
res.info.block_size_median = res.info.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median();
res.info.start_time = (uint64_t)m_core.get_start_time();
+ res.info.version = MONERO_VERSION;
res.status = Message::STATUS_OK;
res.error_details = "";
diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h
index 3b56aff15..e09b6749e 100644
--- a/src/rpc/message_data_structs.h
+++ b/src/rpc/message_data_structs.h
@@ -191,6 +191,7 @@ namespace rpc
uint64_t block_size_median;
uint64_t block_weight_median;
uint64_t start_time;
+ std::string version;
};
struct output_distribution
diff --git a/src/rpc/zmq_server.cpp b/src/rpc/zmq_server.cpp
index edd3e6669..a2ff76668 100644
--- a/src/rpc/zmq_server.cpp
+++ b/src/rpc/zmq_server.cpp
@@ -27,7 +27,6 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "zmq_server.h"
-#include <boost/chrono/chrono.hpp>
namespace cryptonote
{