Merge remote-tracking branch 'origin' into monerogui-otsur
This commit is contained in:
commit
9e42096333
|
@ -120,3 +120,5 @@ nbproject
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
*.log
|
*.log
|
||||||
|
.gitignore
|
||||||
|
/dist/
|
||||||
|
|
|
@ -56,6 +56,8 @@ using namespace epee;
|
||||||
#include "rpc/core_rpc_server_commands_defs.h"
|
#include "rpc/core_rpc_server_commands_defs.h"
|
||||||
#include "daemonizer/daemonizer.h"
|
#include "daemonizer/daemonizer.h"
|
||||||
|
|
||||||
|
#define KEY_IMAGE_EXPORT_FILE_MAGIC "Monero key image export\003"
|
||||||
|
|
||||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||||
#define MONERO_DEFAULT_LOG_CATEGORY "wallet.rpc"
|
#define MONERO_DEFAULT_LOG_CATEGORY "wallet.rpc"
|
||||||
|
|
||||||
|
@ -3104,6 +3106,152 @@ namespace tools
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool wallet_rpc_server::on_export_encrypted_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||||
|
{
|
||||||
|
if (!m_wallet) return not_open(er);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> ski = m_wallet->export_key_images(req.all);
|
||||||
|
res.offset = ski.first;
|
||||||
|
|
||||||
|
std::string data;
|
||||||
|
const cryptonote::account_public_address &keys = m_wallet->get_account().get_keys().m_account_address;
|
||||||
|
|
||||||
|
data.reserve(4 + sizeof(crypto::public_key) * 2 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature)));
|
||||||
|
|
||||||
|
data.resize(4);
|
||||||
|
data[0] = res.offset & 0xff;
|
||||||
|
data[1] = (res.offset >> 8) & 0xff;
|
||||||
|
data[2] = (res.offset >> 16) & 0xff;
|
||||||
|
data[3] = (res.offset >> 24) & 0xff;
|
||||||
|
|
||||||
|
data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key));
|
||||||
|
data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key));
|
||||||
|
|
||||||
|
for (const auto &item : ski.second)
|
||||||
|
{
|
||||||
|
data += std::string((const char *)&item.first, sizeof(crypto::key_image));
|
||||||
|
data += std::string((const char *)&item.second, sizeof(crypto::signature));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ciphertext = m_wallet->encrypt_with_view_secret_key(data);
|
||||||
|
|
||||||
|
std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC));
|
||||||
|
res.encrypted_key_images_blob = epee::string_tools::buff_to_hex_nodelimer(magic + ciphertext);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||||
|
{
|
||||||
|
if (!m_wallet) return not_open(er);
|
||||||
|
if (m_restricted)
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_DENIED;
|
||||||
|
er.message = "Command unavailable in restricted mode.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!m_wallet->is_trusted_daemon())
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||||
|
er.message = "This command requires a trusted daemon.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::string data;
|
||||||
|
if (!epee::string_tools::parse_hexstr_to_binbuff(req.encrypted_key_images_blob, data))
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||||
|
er.message = "Failed to parse encrypted key images blob";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC);
|
||||||
|
if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen))
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||||
|
er.message = "Bad key image export file magic in blob";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
data = m_wallet->decrypt_with_view_secret_key(std::string(data, magiclen));
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||||
|
er.message = "Failed to decrypt blob";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t headerlen = 4 + 2 * sizeof(crypto::public_key);
|
||||||
|
if (data.size() < headerlen)
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||||
|
er.message = "Bad data size from file";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t offset = (uint8_t)data[0] | (((uint8_t)data[1]) << 8) | (((uint8_t)data[2]) << 16) | (((uint8_t)data[3]) << 24);
|
||||||
|
if (offset > m_wallet->get_num_transfer_details())
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||||
|
er.message = "Offset larger than known outputs";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[4];
|
||||||
|
const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[4 + sizeof(crypto::public_key)];
|
||||||
|
const cryptonote::account_public_address &keys = m_wallet->get_account().get_keys().m_account_address;
|
||||||
|
if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key)
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||||
|
er.message = "Key images from different account";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature);
|
||||||
|
if ((data.size() - headerlen) % record_size)
|
||||||
|
{
|
||||||
|
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||||
|
er.message = "Bad data size from file";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t nki = (data.size() - headerlen) / record_size;
|
||||||
|
|
||||||
|
std::vector<std::pair<crypto::key_image, crypto::signature>> ski;
|
||||||
|
ski.reserve(nki);
|
||||||
|
for (size_t n = 0; n < nki; ++n)
|
||||||
|
{
|
||||||
|
crypto::key_image key_image = *reinterpret_cast<const crypto::key_image*>(&data[headerlen + n * record_size]);
|
||||||
|
crypto::signature signature = *reinterpret_cast<const crypto::signature*>(&data[headerlen + n * record_size + sizeof(crypto::key_image)]);
|
||||||
|
|
||||||
|
ski.push_back(std::make_pair(key_image, signature));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t spent = 0, unspent = 0;
|
||||||
|
uint64_t height = m_wallet->import_key_images(ski, offset, spent, unspent);
|
||||||
|
res.height = height;
|
||||||
|
res.spent = spent;
|
||||||
|
res.unspent = unspent;
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -125,6 +125,8 @@ namespace tools
|
||||||
MAP_JON_RPC_WE("import_outputs", on_import_outputs, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS)
|
MAP_JON_RPC_WE("import_outputs", on_import_outputs, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS)
|
||||||
MAP_JON_RPC_WE("export_key_images", on_export_key_images, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES)
|
MAP_JON_RPC_WE("export_key_images", on_export_key_images, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES)
|
||||||
MAP_JON_RPC_WE("import_key_images", on_import_key_images, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES)
|
MAP_JON_RPC_WE("import_key_images", on_import_key_images, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES)
|
||||||
|
MAP_JON_RPC_WE("export_encrypted_key_images", on_export_encrypted_key_images, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES)
|
||||||
|
MAP_JON_RPC_WE("import_encrypted_key_images", on_import_encrypted_key_images, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES)
|
||||||
MAP_JON_RPC_WE("make_uri", on_make_uri, wallet_rpc::COMMAND_RPC_MAKE_URI)
|
MAP_JON_RPC_WE("make_uri", on_make_uri, wallet_rpc::COMMAND_RPC_MAKE_URI)
|
||||||
MAP_JON_RPC_WE("parse_uri", on_parse_uri, wallet_rpc::COMMAND_RPC_PARSE_URI)
|
MAP_JON_RPC_WE("parse_uri", on_parse_uri, wallet_rpc::COMMAND_RPC_PARSE_URI)
|
||||||
MAP_JON_RPC_WE("get_address_book", on_get_address_book, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY)
|
MAP_JON_RPC_WE("get_address_book", on_get_address_book, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY)
|
||||||
|
@ -220,6 +222,8 @@ namespace tools
|
||||||
bool on_import_outputs(const wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
bool on_import_outputs(const wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||||
bool on_export_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
bool on_export_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||||
bool on_import_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
bool on_import_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||||
|
bool on_export_encrypted_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||||
|
bool on_import_encrypted_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||||
bool on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
bool on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||||
bool on_parse_uri(const wallet_rpc::COMMAND_RPC_PARSE_URI::request& req, wallet_rpc::COMMAND_RPC_PARSE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
bool on_parse_uri(const wallet_rpc::COMMAND_RPC_PARSE_URI::request& req, wallet_rpc::COMMAND_RPC_PARSE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||||
bool on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
bool on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||||
|
|
|
@ -1825,6 +1825,60 @@ namespace wallet_rpc
|
||||||
typedef epee::misc_utils::struct_init<response_t> response;
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES
|
||||||
|
{
|
||||||
|
struct request_t
|
||||||
|
{
|
||||||
|
bool all;
|
||||||
|
|
||||||
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
KV_SERIALIZE_OPT(all, false)
|
||||||
|
END_KV_SERIALIZE_MAP()
|
||||||
|
};
|
||||||
|
typedef epee::misc_utils::struct_init<request_t> request;
|
||||||
|
|
||||||
|
struct response_t
|
||||||
|
{
|
||||||
|
uint32_t offset;
|
||||||
|
std::string encrypted_key_images_blob;
|
||||||
|
|
||||||
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
KV_SERIALIZE(offset)
|
||||||
|
KV_SERIALIZE(encrypted_key_images_blob)
|
||||||
|
END_KV_SERIALIZE_MAP()
|
||||||
|
};
|
||||||
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES
|
||||||
|
{
|
||||||
|
struct request_t
|
||||||
|
{
|
||||||
|
uint32_t offset;
|
||||||
|
std::string encrypted_key_images_blob;
|
||||||
|
|
||||||
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
KV_SERIALIZE_OPT(offset, (uint32_t)0)
|
||||||
|
KV_SERIALIZE(encrypted_key_images_blob)
|
||||||
|
END_KV_SERIALIZE_MAP()
|
||||||
|
};
|
||||||
|
typedef epee::misc_utils::struct_init<request_t> request;
|
||||||
|
|
||||||
|
struct response_t
|
||||||
|
{
|
||||||
|
uint64_t height;
|
||||||
|
uint64_t spent;
|
||||||
|
uint64_t unspent;
|
||||||
|
|
||||||
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
KV_SERIALIZE(height)
|
||||||
|
KV_SERIALIZE(spent)
|
||||||
|
KV_SERIALIZE(unspent)
|
||||||
|
END_KV_SERIALIZE_MAP()
|
||||||
|
};
|
||||||
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
|
};
|
||||||
|
|
||||||
struct uri_spec
|
struct uri_spec
|
||||||
{
|
{
|
||||||
std::string address;
|
std::string address;
|
||||||
|
|
Loading…
Reference in New Issue