diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index ffebcd59..c2ccf3db 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1758,7 +1758,7 @@ bool Blockchain::get_random_rct_outs(const COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS::r return true; } //------------------------------------------------------------------ -bool Blockchain::get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res) const +bool Blockchain::get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index eb7a050b..f9ae9d8a 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -452,7 +452,7 @@ namespace cryptonote * * @return true */ - bool get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res) const; + bool get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res) const; /** * @brief gets random ringct outputs to mix with diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 9deb8863..84a41cfb 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -758,7 +758,7 @@ namespace cryptonote return m_blockchain_storage.get_random_outs_for_amounts(req, res); } //----------------------------------------------------------------------------------------------- - bool core::get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res) const + bool core::get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res) const { return m_blockchain_storage.get_outs(req, res); } diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 5ddab4ed..21f84cdd 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -471,7 +471,7 @@ namespace cryptonote * * @note see Blockchain::get_outs */ - bool get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res) const; + bool get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res) const; /** * diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index a02a2375..5bf50073 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -246,7 +246,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res) + bool core_rpc_server::on_get_outs_bin(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res) { CHECK_CORE_BUSY(); res.status = "Failed"; @@ -269,6 +269,42 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res) + { + CHECK_CORE_BUSY(); + res.status = "Failed"; + + if (m_restricted) + { + if (req.outputs.size() > MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT) + { + res.status = "Too many outs requested"; + return true; + } + } + + cryptonote::COMMAND_RPC_GET_OUTPUTS_BIN::request req_bin; + req_bin.outputs = req.outputs; + cryptonote::COMMAND_RPC_GET_OUTPUTS_BIN::response res_bin; + if(!m_core.get_outs(req_bin, res_bin)) + { + return true; + } + + // convert to text + for (const auto &i: res_bin.outs) + { + res.outs.push_back(cryptonote::COMMAND_RPC_GET_OUTPUTS::outkey()); + cryptonote::COMMAND_RPC_GET_OUTPUTS::outkey &outkey = res.outs.back(); + outkey.key = epee::string_tools::pod_to_hex(i.key); + outkey.mask = epee::string_tools::pod_to_hex(i.mask); + outkey.unlocked = i.unlocked; + } + + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_get_random_rct_outs(const COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS::request& req, COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS::response& res) { CHECK_CORE_BUSY(); @@ -388,6 +424,17 @@ namespace cryptonote res.txs_as_hex.push_back(e.as_hex); if (req.decode_as_json) res.txs_as_json.push_back(e.as_json); + + // output indices too if not in pool + if (pool_tx_hashes.find(tx_hash) == pool_tx_hashes.end()) + { + bool r = m_core.get_tx_outputs_gindexs(tx_hash, e.output_indices); + if (!r) + { + res.status = "Failed"; + return false; + } + } } BOOST_FOREACH(const auto& miss_tx, missed_txs) diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 2fdb790a..b7f6cdd6 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -79,7 +79,7 @@ namespace cryptonote MAP_URI_AUTO_BIN2("/gethashes.bin", on_get_hashes, COMMAND_RPC_GET_HASHES_FAST) MAP_URI_AUTO_BIN2("/get_o_indexes.bin", on_get_indexes, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES) MAP_URI_AUTO_BIN2("/getrandom_outs.bin", on_get_random_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS) - MAP_URI_AUTO_BIN2("/get_outs.bin", on_get_outs, COMMAND_RPC_GET_OUTPUTS) + MAP_URI_AUTO_BIN2("/get_outs.bin", on_get_outs_bin, COMMAND_RPC_GET_OUTPUTS_BIN) MAP_URI_AUTO_BIN2("/getrandom_rctouts.bin", on_get_random_rct_outs, COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS) MAP_URI_AUTO_JON2("/gettransactions", on_get_transactions, COMMAND_RPC_GET_TRANSACTIONS) MAP_URI_AUTO_JON2("/is_key_image_spent", on_is_key_image_spent, COMMAND_RPC_IS_KEY_IMAGE_SPENT) @@ -97,6 +97,7 @@ namespace cryptonote MAP_URI_AUTO_JON2_IF("/out_peers", on_out_peers, COMMAND_RPC_OUT_PEERS, !m_restricted) MAP_URI_AUTO_JON2_IF("/start_save_graph", on_start_save_graph, COMMAND_RPC_START_SAVE_GRAPH, !m_restricted) 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) BEGIN_JSON_RPC_MAP("/json_rpc") MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) @@ -131,6 +132,7 @@ namespace cryptonote bool on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res); bool on_mining_status(const COMMAND_RPC_MINING_STATUS::request& req, COMMAND_RPC_MINING_STATUS::response& res); bool on_get_random_outs(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res); + bool on_get_outs_bin(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res); bool on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res); bool on_get_random_rct_outs(const COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS::request& req, COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS::response& res); bool on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 6d452f59..e19238c4 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -41,7 +41,7 @@ namespace cryptonote #define CORE_RPC_STATUS_BUSY "BUSY" #define CORE_RPC_STATUS_NOT_MINING "NOT MINING" -#define CORE_RPC_VERSION 4 +#define CORE_RPC_VERSION 5 struct COMMAND_RPC_GET_HEIGHT { @@ -162,6 +162,7 @@ namespace cryptonote std::string as_json; bool in_pool; uint64_t block_height; + std::vector output_indices; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(tx_hash) @@ -169,6 +170,7 @@ namespace cryptonote KV_SERIALIZE(as_json) KV_SERIALIZE(in_pool) KV_SERIALIZE(block_height) + KV_SERIALIZE(output_indices) END_KV_SERIALIZE_MAP() }; @@ -291,22 +293,22 @@ namespace cryptonote }; }; //----------------------------------------------- - struct COMMAND_RPC_GET_OUTPUTS + struct get_outputs_out { - struct out - { - uint64_t amount; - uint64_t index; + uint64_t amount; + uint64_t index; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(index) - END_KV_SERIALIZE_MAP() - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount) + KV_SERIALIZE(index) + END_KV_SERIALIZE_MAP() + }; + struct COMMAND_RPC_GET_OUTPUTS_BIN + { struct request { - std::vector outputs; + std::vector outputs; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(outputs) @@ -337,6 +339,42 @@ namespace cryptonote END_KV_SERIALIZE_MAP() }; }; + //----------------------------------------------- + struct COMMAND_RPC_GET_OUTPUTS + { + struct request + { + std::vector outputs; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(outputs) + END_KV_SERIALIZE_MAP() + }; + + struct outkey + { + std::string key; + std::string mask; + bool unlocked; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key) + KV_SERIALIZE(mask) + KV_SERIALIZE(unlocked) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::vector outs; + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(outs) + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; struct COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index e02f3965..42deb337 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3361,8 +3361,8 @@ void wallet2::get_outs(std::vector> &outs, const std::list> &outs, const std::list