aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/core_rpc_server.cpp80
-rw-r--r--src/rpc/core_rpc_server.h2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h72
3 files changed, 132 insertions, 22 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 03cf20f93..fbca32f80 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -2216,7 +2216,8 @@ namespace cryptonote
// Fixing of high orphan issue for most pools
// Thanks Boolberry!
block b;
- if(!parse_and_validate_block_from_blob(blockblob, b))
+ crypto::hash blk_id;
+ if(!parse_and_validate_block_from_blob(blockblob, b, blk_id))
{
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB;
error_resp.message = "Wrong block blob";
@@ -2239,6 +2240,7 @@ namespace cryptonote
error_resp.message = "Block not accepted";
return false;
}
+ res.block_id = epee::string_tools::pod_to_hex(blk_id);
res.status = CORE_RPC_STATUS_OK;
return true;
}
@@ -3534,6 +3536,82 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool core_rpc_server::on_get_txids_loose(const COMMAND_RPC_GET_TXIDS_LOOSE::request& req, COMMAND_RPC_GET_TXIDS_LOOSE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
+ {
+ RPC_TRACKER(get_txids_loose);
+
+ // Maybe don't use bootstrap since this endpoint is meant to retreive TXIDs w/ k-anonymity,
+ // so shunting this request to a random node seems counterproductive.
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ const uint64_t max_num_txids = RESTRICTED_SPENT_KEY_IMAGES_COUNT * (m_restricted ? 1 : 10);
+
+ // Sanity check parameters
+ if (req.num_matching_bits > 256)
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
+ error_resp.message = "There are only 256 bits in a hash, you gave too many";
+ return false;
+ }
+
+ // Attempt to guess when bit count is too low before fetching, within a certain margin of error
+ const uint64_t num_txs_ever = m_core.get_blockchain_storage().get_db().get_tx_count();
+ const uint64_t num_expected_fetch = (num_txs_ever >> std::min((int) req.num_matching_bits, 63));
+ const uint64_t max_num_txids_with_margin = 2 * max_num_txids;
+ if (num_expected_fetch > max_num_txids_with_margin)
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
+ error_resp.message = "Trying to search with too few matching bits, detected before fetching";
+ return false;
+ }
+
+ // Convert txid template to a crypto::hash
+ crypto::hash search_hash;
+ if (!epee::string_tools::hex_to_pod(req.txid_template, search_hash))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
+ error_resp.message = "Could not decode hex txid";
+ return false;
+ }
+ // Check that txid template is zeroed correctly for number of given matchign bits
+ else if (search_hash != make_hash32_loose_template(req.num_matching_bits, search_hash))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
+ error_resp.message = "Txid template is not zeroed correctly for number of bits. You could be leaking true txid!";
+ return false;
+ }
+
+ try
+ {
+ // Do the DB fetch
+ const auto txids = m_core.get_blockchain_storage().get_db().get_txids_loose(search_hash, req.num_matching_bits, max_num_txids);
+ // Fill out response form
+ for (const auto& txid : txids)
+ res.txids.emplace_back(epee::string_tools::pod_to_hex(txid));
+ }
+ catch (const TX_EXISTS&)
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
+ error_resp.message = "Trying to search with too few matching bits";
+ return false;
+ }
+ catch (const std::exception& e)
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
+ error_resp.message = std::string("Error during get_txids_loose: ") + e.what();
+ return false;
+ }
+
+ res.status = CORE_RPC_STATUS_OK;
+ return true;
+#else // BYTE_ORDER == BIG_ENDIAN
+ // BlockchainLMDB::compare_hash32 has different key ordering (thus different txid templates) on BE systems
+ error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
+ error_resp.message = "Due to implementation details, this feature is not available on big-endian daemons";
+ return false;
+#endif
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_rpc_access_submit_nonce(const COMMAND_RPC_ACCESS_SUBMIT_NONCE::request& req, COMMAND_RPC_ACCESS_SUBMIT_NONCE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
{
RPC_TRACKER(rpc_access_submit_nonce);
diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h
index 790d5eb23..7c31d2539 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -178,6 +178,7 @@ namespace cryptonote
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)
MAP_JON_RPC_WE_IF("flush_cache", on_flush_cache, COMMAND_RPC_FLUSH_CACHE, !m_restricted)
+ MAP_JON_RPC_WE("get_txids_loose", on_get_txids_loose, COMMAND_RPC_GET_TXIDS_LOOSE)
MAP_JON_RPC_WE("rpc_access_info", on_rpc_access_info, COMMAND_RPC_ACCESS_INFO)
MAP_JON_RPC_WE("rpc_access_submit_nonce",on_rpc_access_submit_nonce, COMMAND_RPC_ACCESS_SUBMIT_NONCE)
MAP_JON_RPC_WE("rpc_access_pay", on_rpc_access_pay, COMMAND_RPC_ACCESS_PAY)
@@ -255,6 +256,7 @@ namespace cryptonote
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, const connection_context *ctx = NULL);
bool on_prune_blockchain(const COMMAND_RPC_PRUNE_BLOCKCHAIN::request& req, COMMAND_RPC_PRUNE_BLOCKCHAIN::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_flush_cache(const COMMAND_RPC_FLUSH_CACHE::request& req, COMMAND_RPC_FLUSH_CACHE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
+ bool on_get_txids_loose(const COMMAND_RPC_GET_TXIDS_LOOSE::request& req, COMMAND_RPC_GET_TXIDS_LOOSE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_rpc_access_info(const COMMAND_RPC_ACCESS_INFO::request& req, COMMAND_RPC_ACCESS_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_rpc_access_submit_nonce(const COMMAND_RPC_ACCESS_SUBMIT_NONCE::request& req, COMMAND_RPC_ACCESS_SUBMIT_NONCE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_rpc_access_pay(const COMMAND_RPC_ACCESS_PAY::request& req, COMMAND_RPC_ACCESS_PAY::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 7f1581d0c..c0330eed9 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -88,7 +88,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 3
-#define CORE_RPC_VERSION_MINOR 12
+#define CORE_RPC_VERSION_MINOR 13
#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)
@@ -617,7 +617,7 @@ namespace cryptonote
bool do_sanity_checks;
BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE_PARENT(rpc_access_request_base);
+ KV_SERIALIZE_PARENT(rpc_access_request_base)
KV_SERIALIZE(tx_as_hex)
KV_SERIALIZE_OPT(do_not_relay, false)
KV_SERIALIZE_OPT(do_sanity_checks, true)
@@ -693,7 +693,7 @@ namespace cryptonote
struct request_t: public rpc_access_request_base
{
BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE_PARENT(rpc_access_request_base);
+ KV_SERIALIZE_PARENT(rpc_access_request_base)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@@ -1115,8 +1115,11 @@ namespace cryptonote
struct response_t: public rpc_response_base
{
+ std::string block_id;
+
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_PARENT(rpc_response_base)
+ KV_SERIALIZE(block_id)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
@@ -1214,7 +1217,7 @@ namespace cryptonote
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_PARENT(rpc_access_request_base)
- KV_SERIALIZE_OPT(fill_pow_hash, false);
+ KV_SERIALIZE_OPT(fill_pow_hash, false)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@@ -1244,7 +1247,7 @@ namespace cryptonote
KV_SERIALIZE_PARENT(rpc_access_request_base)
KV_SERIALIZE(hash)
KV_SERIALIZE(hashes)
- KV_SERIALIZE_OPT(fill_pow_hash, false);
+ KV_SERIALIZE_OPT(fill_pow_hash, false)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@@ -1273,7 +1276,7 @@ namespace cryptonote
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_PARENT(rpc_access_request_base)
KV_SERIALIZE(height)
- KV_SERIALIZE_OPT(fill_pow_hash, false);
+ KV_SERIALIZE_OPT(fill_pow_hash, false)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@@ -1302,7 +1305,7 @@ namespace cryptonote
KV_SERIALIZE_PARENT(rpc_access_request_base)
KV_SERIALIZE(hash)
KV_SERIALIZE(height)
- KV_SERIALIZE_OPT(fill_pow_hash, false);
+ KV_SERIALIZE_OPT(fill_pow_hash, false)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@@ -1760,7 +1763,7 @@ namespace cryptonote
KV_SERIALIZE_PARENT(rpc_access_request_base)
KV_SERIALIZE(start_height)
KV_SERIALIZE(end_height)
- KV_SERIALIZE_OPT(fill_pow_hash, false);
+ KV_SERIALIZE_OPT(fill_pow_hash, false)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@@ -2121,12 +2124,12 @@ namespace cryptonote
uint64_t recent_cutoff;
BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE_PARENT(rpc_access_request_base);
- KV_SERIALIZE(amounts);
- KV_SERIALIZE(min_count);
- KV_SERIALIZE(max_count);
- KV_SERIALIZE(unlocked);
- KV_SERIALIZE(recent_cutoff);
+ KV_SERIALIZE_PARENT(rpc_access_request_base)
+ KV_SERIALIZE(amounts)
+ KV_SERIALIZE(min_count)
+ KV_SERIALIZE(max_count)
+ KV_SERIALIZE(unlocked)
+ KV_SERIALIZE(recent_cutoff)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@@ -2139,10 +2142,10 @@ namespace cryptonote
uint64_t recent_instances;
BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE(amount);
- KV_SERIALIZE(total_instances);
- KV_SERIALIZE(unlocked_instances);
- KV_SERIALIZE(recent_instances);
+ KV_SERIALIZE(amount)
+ KV_SERIALIZE(total_instances)
+ KV_SERIALIZE(unlocked_instances)
+ KV_SERIALIZE(recent_instances)
END_KV_SERIALIZE_MAP()
entry(uint64_t amount, uint64_t total_instances, uint64_t unlocked_instances, uint64_t recent_instances):
@@ -2213,9 +2216,9 @@ namespace cryptonote
uint64_t count;
BEGIN_KV_SERIALIZE_MAP()
- KV_SERIALIZE_PARENT(rpc_access_request_base);
- KV_SERIALIZE(height);
- KV_SERIALIZE(count);
+ KV_SERIALIZE_PARENT(rpc_access_request_base)
+ KV_SERIALIZE(height)
+ KV_SERIALIZE(count)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@@ -2790,4 +2793,31 @@ namespace cryptonote
typedef epee::misc_utils::struct_init<response_t> response;
};
+ struct COMMAND_RPC_GET_TXIDS_LOOSE
+ {
+ struct request_t: public rpc_request_base
+ {
+ std::string txid_template;
+ std::uint32_t num_matching_bits;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE_PARENT(rpc_request_base)
+ KV_SERIALIZE(txid_template)
+ KV_SERIALIZE(num_matching_bits)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<request_t> request;
+
+ struct response_t: public rpc_response_base
+ {
+ std::vector<std::string> txids;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE_PARENT(rpc_response_base)
+ KV_SERIALIZE(txids)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<response_t> response;
+ };
+
}