mirror of
https://github.com/monero-project/monero.git
synced 2025-08-19 00:37:54 -04:00
wallet-rpc: watch-only and cold wallet features added
- unsigned_txset, signed_txset in transfer / submit_transfer / sign_transfer - export_outputs, import_outputs Squashed commits: [f4d9f3d4] wallet-rpc: do_not_relay removed from submit_transfer [5b16a86f] wallet-rpc: review-fix - method signature changes, renaming [b7fbb10a] wallet-rpc: naming fixes (unsigned vs signed), consts renamed [8c7d2727] wallet-rpc: sign_transfer added [481d024a] wallet2: sign_tx splitted to work with strings and structs, more granular [2a474db9] wallet-rpc: wallet2::load_unsigned_tx split to load from str, file [b1e3a018] wallet-rpc: review fix, load_tx_from_str variable rename [1f6373be] wallet-rpc: review fix: save_tx_to_{str,file} [2a08eafc] wallet-rpc: review comments fixes - redundant this removed from wallet2.cpp - load_tx_from_str, load_tx_from_file [43498052] wallet-rpc: submit_transfer added [9c45d1ad] wallet-rpc: watch_only check, return unsigned_txset [62831396] wallet2: added string variants to load_tx, save_tx - analogously to save_multisig_tx - required for monero-wallet-rpc to support watch-only wallet
This commit is contained in:
parent
9bc8f76924
commit
9c2a7b4638
7 changed files with 495 additions and 98 deletions
|
@ -90,8 +90,6 @@ typedef cryptonote::simple_wallet sw;
|
|||
|
||||
#define MIN_RING_SIZE 7 // Used to inform user about min ring size -- does not track actual protocol
|
||||
|
||||
#define OUTPUT_EXPORT_FILE_MAGIC "Monero output export\003"
|
||||
|
||||
#define LOCK_IDLE_SCOPE() \
|
||||
bool auto_refresh_enabled = m_auto_refresh_enabled.load(std::memory_order_relaxed); \
|
||||
m_auto_refresh_enabled.store(false, std::memory_order_relaxed); \
|
||||
|
@ -7182,19 +7180,8 @@ bool simple_wallet::export_outputs(const std::vector<std::string> &args)
|
|||
LOCK_IDLE_SCOPE();
|
||||
try
|
||||
{
|
||||
std::vector<tools::wallet2::transfer_details> outs = m_wallet->export_outputs();
|
||||
|
||||
std::stringstream oss;
|
||||
boost::archive::portable_binary_oarchive ar(oss);
|
||||
ar << outs;
|
||||
|
||||
std::string magic(OUTPUT_EXPORT_FILE_MAGIC, strlen(OUTPUT_EXPORT_FILE_MAGIC));
|
||||
const cryptonote::account_public_address &keys = m_wallet->get_account().get_keys().m_account_address;
|
||||
std::string header;
|
||||
header += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key));
|
||||
header += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key));
|
||||
std::string ciphertext = m_wallet->encrypt_with_view_secret_key(header + oss.str());
|
||||
bool r = epee::file_io_utils::save_string_to_file(filename, magic + ciphertext);
|
||||
std::string data = m_wallet->export_outputs_to_str();
|
||||
bool r = epee::file_io_utils::save_string_to_file(filename, data);
|
||||
if (!r)
|
||||
{
|
||||
fail_msg_writer() << tr("failed to save file ") << filename;
|
||||
|
@ -7233,63 +7220,16 @@ bool simple_wallet::import_outputs(const std::vector<std::string> &args)
|
|||
fail_msg_writer() << tr("failed to read file ") << filename;
|
||||
return true;
|
||||
}
|
||||
const size_t magiclen = strlen(OUTPUT_EXPORT_FILE_MAGIC);
|
||||
if (data.size() < magiclen || memcmp(data.data(), OUTPUT_EXPORT_FILE_MAGIC, magiclen))
|
||||
{
|
||||
fail_msg_writer() << "Bad output export file magic in " << filename;
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
data = m_wallet->decrypt_with_view_secret_key(std::string(data, magiclen));
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
fail_msg_writer() << "Failed to decrypt " << filename << ": " << e.what();
|
||||
return true;
|
||||
}
|
||||
|
||||
const size_t headerlen = 2 * sizeof(crypto::public_key);
|
||||
if (data.size() < headerlen)
|
||||
{
|
||||
fail_msg_writer() << "Bad data size from file " << filename;
|
||||
return true;
|
||||
}
|
||||
const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[0];
|
||||
const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[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)
|
||||
{
|
||||
fail_msg_writer() << "Outputs from " << filename << " are for a different account";
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::string body(data, headerlen);
|
||||
std::stringstream iss;
|
||||
iss << body;
|
||||
std::vector<tools::wallet2::transfer_details> outputs;
|
||||
try
|
||||
{
|
||||
boost::archive::portable_binary_iarchive ar(iss);
|
||||
ar >> outputs;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
iss.str("");
|
||||
iss << body;
|
||||
boost::archive::binary_iarchive ar(iss);
|
||||
ar >> outputs;
|
||||
}
|
||||
LOCK_IDLE_SCOPE();
|
||||
size_t n_outputs = m_wallet->import_outputs(outputs);
|
||||
size_t n_outputs = m_wallet->import_outputs_from_str(data);
|
||||
success_msg_writer() << boost::lexical_cast<std::string>(n_outputs) << " outputs imported";
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
fail_msg_writer() << "Failed to import outputs: " << e.what();
|
||||
fail_msg_writer() << "Failed to import outputs " << filename << ": " << e.what();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue