aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/core_rpc_server.cpp87
-rw-r--r--src/rpc/core_rpc_server.h2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h47
-rw-r--r--src/rpc/message_data_structs.h1
4 files changed, 118 insertions, 19 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index d20000a53..08674a06e 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -485,8 +485,8 @@ namespace cryptonote
vh.push_back(*reinterpret_cast<const crypto::hash*>(b.data()));
}
std::vector<crypto::hash> missed_txs;
- std::vector<transaction> txs;
- bool r = m_core.get_transactions(vh, txs, missed_txs);
+ std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>> txs;
+ bool r = m_core.get_split_transactions_blobs(vh, txs, missed_txs);
if(!r)
{
res.status = "Failed";
@@ -506,7 +506,7 @@ namespace cryptonote
if(r)
{
// sort to match original request
- std::vector<transaction> sorted_txs;
+ std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>> sorted_txs;
std::vector<tx_info>::const_iterator i;
unsigned txs_processed = 0;
for (const crypto::hash &h: vh)
@@ -519,7 +519,7 @@ namespace cryptonote
return true;
}
// core returns the ones it finds in the right order
- if (get_transaction_hash(txs[txs_processed]) != h)
+ if (std::get<0>(txs[txs_processed]) != h)
{
res.status = "Failed: tx hash mismatch";
return true;
@@ -535,7 +535,16 @@ namespace cryptonote
res.status = "Failed to parse and validate tx from blob";
return true;
}
- sorted_txs.push_back(tx);
+ std::stringstream ss;
+ binary_archive<true> ba(ss);
+ bool r = const_cast<cryptonote::transaction&>(tx).serialize_base(ba);
+ if (!r)
+ {
+ res.status = "Failed to serialize transaction base";
+ return true;
+ }
+ const cryptonote::blobdata pruned = ss.str();
+ sorted_txs.push_back(std::make_tuple(h, pruned, get_transaction_prunable_hash(tx), std::string(i->tx_blob, pruned.size())));
missed_txs.erase(std::find(missed_txs.begin(), missed_txs.end(), h));
pool_tx_hashes.insert(h);
const std::string hash_string = epee::string_tools::pod_to_hex(h);
@@ -564,11 +573,36 @@ namespace cryptonote
crypto::hash tx_hash = *vhi++;
e.tx_hash = *txhi++;
- pruned_transaction pruned_tx{tx};
- blobdata blob = req.prune ? t_serializable_object_to_blob(pruned_tx) : t_serializable_object_to_blob(tx);
- e.as_hex = string_tools::buff_to_hex_nodelimer(blob);
- if (req.decode_as_json)
- e.as_json = req.prune ? obj_to_json_str(pruned_tx) : obj_to_json_str(tx);
+ e.prunable_hash = epee::string_tools::pod_to_hex(std::get<2>(tx));
+ if (req.split || req.prune || std::get<3>(tx).empty())
+ {
+ e.pruned_as_hex = string_tools::buff_to_hex_nodelimer(std::get<1>(tx));
+ if (!req.prune)
+ e.prunable_as_hex = string_tools::buff_to_hex_nodelimer(std::get<3>(tx));
+ }
+ else
+ {
+ cryptonote::blobdata tx_data;
+ if (req.prune)
+ tx_data = std::get<1>(tx);
+ else
+ tx_data = std::get<1>(tx) + std::get<3>(tx);
+ e.as_hex = string_tools::buff_to_hex_nodelimer(tx_data);
+ if (req.decode_as_json && !tx_data.empty())
+ {
+ cryptonote::transaction t;
+ if (cryptonote::parse_and_validate_tx_from_blob(tx_data, t))
+ {
+ if (req.prune)
+ {
+ pruned_transaction pruned_tx{t};
+ e.as_json = obj_to_json_str(pruned_tx);
+ }
+ else
+ e.as_json = obj_to_json_str(t);
+ }
+ }
+ }
e.in_pool = pool_tx_hashes.find(tx_hash) != pool_tx_hashes.end();
if (e.in_pool)
{
@@ -869,9 +903,9 @@ namespace cryptonote
{
if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID)
res.white_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv4_network_address>().ip(),
- entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen);
+ entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen, entry.pruning_seed);
else
- res.white_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen);
+ res.white_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen, entry.pruning_seed);
}
res.gray_list.reserve(gray_list.size());
@@ -879,9 +913,9 @@ namespace cryptonote
{
if (entry.adr.get_type_id() == epee::net_utils::ipv4_network_address::ID)
res.gray_list.emplace_back(entry.id, entry.adr.as<epee::net_utils::ipv4_network_address>().ip(),
- entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen);
+ entry.adr.as<epee::net_utils::ipv4_network_address>().port(), entry.last_seen, entry.pruning_seed);
else
- res.gray_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen);
+ res.gray_list.emplace_back(entry.id, entry.adr.str(), entry.last_seen, entry.pruning_seed);
}
res.status = CORE_RPC_STATUS_OK;
@@ -2102,6 +2136,7 @@ namespace cryptonote
m_core.get_blockchain_top(res.height, top_hash);
++res.height; // turn top block height into blockchain height
res.target_height = m_core.get_target_blockchain_height();
+ res.next_needed_pruning_seed = m_p2p.get_payload_object().get_next_needed_pruning_stripe().second;
for (const auto &c: m_p2p.get_payload_object().get_connections())
res.peers.push_back({c});
@@ -2116,6 +2151,7 @@ namespace cryptonote
res.spans.push_back({span.start_block_height, span.nblocks, span_connection_id, (uint32_t)(span.rate + 0.5f), speed, span.size, address});
return true;
});
+ res.overview = block_queue.get_overview(res.height);
res.status = CORE_RPC_STATUS_OK;
return true;
@@ -2215,6 +2251,29 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool core_rpc_server::on_prune_blockchain(const COMMAND_RPC_PRUNE_BLOCKCHAIN::request& req, COMMAND_RPC_PRUNE_BLOCKCHAIN::response& res, epee::json_rpc::error& error_resp)
+ {
+ try
+ {
+ if (!(req.check ? m_core.check_blockchain_pruning() : m_core.prune_blockchain()))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
+ error_resp.message = req.check ? "Failed to check blockchain pruning" : "Failed to prune blockchain";
+ return false;
+ }
+ res.pruning_seed = m_core.get_blockchain_pruning_seed();
+ }
+ catch (const std::exception &e)
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
+ error_resp.message = "Failed to prune blockchain";
+ 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 081ccc25d..83a7cfe27 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -153,6 +153,7 @@ namespace cryptonote
MAP_JON_RPC_WE_IF("sync_info", on_sync_info, COMMAND_RPC_SYNC_INFO, !m_restricted)
MAP_JON_RPC_WE("get_txpool_backlog", on_get_txpool_backlog, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG)
MAP_JON_RPC_WE("get_output_distribution", on_get_output_distribution, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION)
+ MAP_JON_RPC_WE_IF("prune_blockchain", on_prune_blockchain, COMMAND_RPC_PRUNE_BLOCKCHAIN, !m_restricted)
END_JSON_RPC_MAP()
END_URI_MAP2()
@@ -217,6 +218,7 @@ namespace cryptonote
bool on_sync_info(const COMMAND_RPC_SYNC_INFO::request& req, COMMAND_RPC_SYNC_INFO::response& res, epee::json_rpc::error& error_resp);
bool on_get_txpool_backlog(const COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response& res, epee::json_rpc::error& error_resp);
bool on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp);
+ bool on_prune_blockchain(const COMMAND_RPC_PRUNE_BLOCKCHAIN::request& req, COMMAND_RPC_PRUNE_BLOCKCHAIN::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 0a07930ec..dfad5d6a7 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -84,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 2
+#define CORE_RPC_VERSION_MINOR 3
#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)
@@ -601,11 +601,13 @@ namespace cryptonote
std::vector<std::string> txs_hashes;
bool decode_as_json;
bool prune;
+ bool split;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txs_hashes)
KV_SERIALIZE(decode_as_json)
KV_SERIALIZE_OPT(prune, false)
+ KV_SERIALIZE_OPT(split, false)
END_KV_SERIALIZE_MAP()
};
@@ -613,6 +615,9 @@ namespace cryptonote
{
std::string tx_hash;
std::string as_hex;
+ std::string pruned_as_hex;
+ std::string prunable_as_hex;
+ std::string prunable_hash;
std::string as_json;
bool in_pool;
bool double_spend_seen;
@@ -623,6 +628,9 @@ namespace cryptonote
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash)
KV_SERIALIZE(as_hex)
+ KV_SERIALIZE(pruned_as_hex)
+ KV_SERIALIZE(prunable_as_hex)
+ KV_SERIALIZE(prunable_hash)
KV_SERIALIZE(as_json)
KV_SERIALIZE(in_pool)
KV_SERIALIZE(double_spend_seen)
@@ -1311,14 +1319,15 @@ namespace cryptonote
uint32_t ip;
uint16_t port;
uint64_t last_seen;
+ uint32_t pruning_seed;
peer() = default;
- peer(uint64_t id, const std::string &host, uint64_t last_seen)
- : id(id), host(host), ip(0), port(0), last_seen(last_seen)
+ peer(uint64_t id, const std::string &host, uint64_t last_seen, uint32_t pruning_seed)
+ : id(id), host(host), ip(0), port(0), last_seen(last_seen), pruning_seed(pruning_seed)
{}
- peer(uint64_t id, uint32_t ip, uint16_t port, uint64_t last_seen)
- : id(id), host(std::to_string(ip)), ip(ip), port(port), last_seen(last_seen)
+ peer(uint64_t id, uint32_t ip, uint16_t port, uint64_t last_seen, uint32_t pruning_seed)
+ : id(id), host(std::to_string(ip)), ip(ip), port(port), last_seen(last_seen), pruning_seed(pruning_seed)
{}
BEGIN_KV_SERIALIZE_MAP()
@@ -1327,6 +1336,7 @@ namespace cryptonote
KV_SERIALIZE(ip)
KV_SERIALIZE(port)
KV_SERIALIZE(last_seen)
+ KV_SERIALIZE_OPT(pruning_seed, (uint32_t)0)
END_KV_SERIALIZE_MAP()
};
@@ -2238,15 +2248,19 @@ namespace cryptonote
std::string status;
uint64_t height;
uint64_t target_height;
+ uint32_t next_needed_pruning_seed;
std::list<peer> peers;
std::list<span> spans;
+ std::string overview;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
KV_SERIALIZE(height)
KV_SERIALIZE(target_height)
+ KV_SERIALIZE(next_needed_pruning_seed)
KV_SERIALIZE(peers)
KV_SERIALIZE(spans)
+ KV_SERIALIZE(overview)
END_KV_SERIALIZE_MAP()
};
};
@@ -2351,4 +2365,27 @@ namespace cryptonote
};
};
+ struct COMMAND_RPC_PRUNE_BLOCKCHAIN
+ {
+ struct request
+ {
+ bool check;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE_OPT(check, false)
+ END_KV_SERIALIZE_MAP()
+ };
+
+ struct response
+ {
+ uint32_t pruning_seed;
+ std::string status;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(status)
+ KV_SERIALIZE(pruning_seed)
+ END_KV_SERIALIZE_MAP()
+ };
+ };
+
}
diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h
index e09b6749e..73cf28cec 100644
--- a/src/rpc/message_data_structs.h
+++ b/src/rpc/message_data_structs.h
@@ -79,6 +79,7 @@ namespace rpc
uint32_t ip;
uint16_t port;
uint64_t last_seen;
+ uint32_t pruning_seed;
};
struct tx_in_pool