aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r--src/wallet/wallet2.cpp241
1 files changed, 196 insertions, 45 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 353f20b51..aeddd773d 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -103,8 +103,8 @@ using namespace cryptonote;
// used to target a given block weight (additional outputs may be added on top to build fee)
#define TX_WEIGHT_TARGET(bytes) (bytes*2/3)
-#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\004"
-#define SIGNED_TX_PREFIX "Monero signed tx set\004"
+#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\005"
+#define SIGNED_TX_PREFIX "Monero signed tx set\005"
#define MULTISIG_UNSIGNED_TX_PREFIX "Monero multisig unsigned tx set\001"
#define RECENT_OUTPUT_RATIO (0.5) // 50% of outputs are from the recent zone
@@ -1183,6 +1183,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
m_offline(false),
m_rpc_version(0),
m_export_format(ExportFormat::Binary),
+ m_load_deprecated_formats(false),
m_credits_target(0)
{
set_rpc_client_secret_key(rct::rct2sk(rct::skGen()));
@@ -3903,6 +3904,9 @@ boost::optional<wallet2::keys_file_data> wallet2::get_keys_file_data(const epee:
value2.SetInt(m_export_format);
json.AddMember("export_format", value2, json.GetAllocator());
+ value2.SetInt(m_load_deprecated_formats);
+ json.AddMember("load_deprecated_formats", value2, json.GetAllocator());
+
value2.SetUint(1);
json.AddMember("encrypted_secret_keys", value2, json.GetAllocator());
@@ -4072,6 +4076,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
m_original_keys_available = false;
m_export_format = ExportFormat::Binary;
+ m_load_deprecated_formats = false;
m_device_name = "";
m_device_derivation_path = "";
m_key_device_type = hw::device::device_type::SOFTWARE;
@@ -4252,6 +4257,9 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, export_format, ExportFormat, Int, false, Binary);
m_export_format = field_export_format;
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, load_deprecated_formats, int, Int, false, false);
+ m_load_deprecated_formats = field_load_deprecated_formats;
+
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, device_name, std::string, String, false, std::string());
if (m_device_name.empty())
{
@@ -5617,10 +5625,26 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
crypto::chacha20(cache_file_data.cache_data.data(), cache_file_data.cache_data.size(), m_cache_key, cache_file_data.iv, &cache_data[0]);
try {
- std::stringstream iss;
- iss << cache_data;
- boost::archive::portable_binary_iarchive ar(iss);
- ar >> *this;
+ bool loaded = false;
+
+ try
+ {
+ std::stringstream iss;
+ iss << cache_data;
+ binary_archive<false> ar(iss);
+ if (::serialization::serialize(ar, *this))
+ if (::serialization::check_stream_state(ar))
+ loaded = true;
+ }
+ catch(...) { }
+
+ if (!loaded)
+ {
+ std::stringstream iss;
+ iss << cache_data;
+ boost::archive::portable_binary_iarchive ar(iss);
+ ar >> *this;
+ }
}
catch(...)
{
@@ -5717,7 +5741,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
try
{
if (use_fs)
- m_message_store.read_from_file(get_multisig_wallet_state(), m_mms_file);
+ m_message_store.read_from_file(get_multisig_wallet_state(), m_mms_file, m_load_deprecated_formats);
}
catch (const std::exception &e)
{
@@ -5907,8 +5931,9 @@ boost::optional<wallet2::cache_file_data> wallet2::get_cache_file_data(const epe
try
{
std::stringstream oss;
- boost::archive::portable_binary_oarchive ar(oss);
- ar << *this;
+ binary_archive<true> ar(oss);
+ if (!::serialization::serialize(ar, *this))
+ return boost::none;
boost::optional<wallet2::cache_file_data> cache_file_data = (wallet2::cache_file_data) {};
cache_file_data.get().cache_data = oss.str();
@@ -6570,10 +6595,11 @@ std::string wallet2::dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) c
txs.transfers = export_outputs();
// save as binary
std::ostringstream oss;
- boost::archive::portable_binary_oarchive ar(oss);
+ binary_archive<true> ar(oss);
try
{
- ar << txs;
+ if (!::serialization::serialize(ar, txs))
+ return std::string();
}
catch (...)
{
@@ -6617,6 +6643,11 @@ bool wallet2::parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsi
s = s.substr(1);
if (version == '\003')
{
+ if (!m_load_deprecated_formats)
+ {
+ LOG_PRINT_L0("Not loading deprecated format");
+ return false;
+ }
try
{
std::istringstream iss(s);
@@ -6631,6 +6662,11 @@ bool wallet2::parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsi
}
else if (version == '\004')
{
+ if (!m_load_deprecated_formats)
+ {
+ LOG_PRINT_L0("Not loading deprecated format");
+ return false;
+ }
try
{
s = decrypt_with_view_secret_key(s);
@@ -6652,6 +6688,26 @@ bool wallet2::parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsi
return false;
}
}
+ else if (version == '\005')
+ {
+ try { s = decrypt_with_view_secret_key(s); }
+ catch(const std::exception &e) { LOG_PRINT_L0("Failed to decrypt unsigned tx: " << e.what()); return false; }
+ try
+ {
+ std::istringstream iss(s);
+ binary_archive<false> ar(iss);
+ if (!::serialization::serialize(ar, exported_txs))
+ {
+ LOG_PRINT_L0("Failed to parse data from unsigned tx");
+ return false;
+ }
+ }
+ catch (...)
+ {
+ LOG_PRINT_L0("Failed to parse data from unsigned tx");
+ return false;
+ }
+ }
else
{
LOG_PRINT_L0("Unsupported version in unsigned tx");
@@ -6849,10 +6905,11 @@ std::string wallet2::sign_tx_dump_to_str(unsigned_tx_set &exported_txs, std::vec
// save as binary
std::ostringstream oss;
- boost::archive::portable_binary_oarchive ar(oss);
+ binary_archive<true> ar(oss);
try
{
- ar << signed_txes;
+ if (!::serialization::serialize(ar, signed_txes))
+ return std::string();
}
catch(...)
{
@@ -6901,6 +6958,11 @@ bool wallet2::parse_tx_from_str(const std::string &signed_tx_st, std::vector<too
s = s.substr(1);
if (version == '\003')
{
+ if (!m_load_deprecated_formats)
+ {
+ LOG_PRINT_L0("Not loading deprecated format");
+ return false;
+ }
try
{
std::istringstream iss(s);
@@ -6915,6 +6977,11 @@ bool wallet2::parse_tx_from_str(const std::string &signed_tx_st, std::vector<too
}
else if (version == '\004')
{
+ if (!m_load_deprecated_formats)
+ {
+ LOG_PRINT_L0("Not loading deprecated format");
+ return false;
+ }
try
{
s = decrypt_with_view_secret_key(s);
@@ -6936,6 +7003,26 @@ bool wallet2::parse_tx_from_str(const std::string &signed_tx_st, std::vector<too
return false;
}
}
+ else if (version == '\005')
+ {
+ try { s = decrypt_with_view_secret_key(s); }
+ catch (const std::exception &e) { LOG_PRINT_L0("Failed to decrypt signed transaction: " << e.what()); return false; }
+ try
+ {
+ std::istringstream iss(s);
+ binary_archive<false> ar(iss);
+ if (!::serialization::serialize(ar, signed_txs))
+ {
+ LOG_PRINT_L0("Failed to deserialize signed transaction");
+ return false;
+ }
+ }
+ catch (const std::exception &e)
+ {
+ LOG_PRINT_L0("Failed to decrypt signed transaction: " << e.what());
+ return false;
+ }
+ }
else
{
LOG_PRINT_L0("Unsupported version in signed transaction");
@@ -6987,10 +7074,11 @@ std::string wallet2::save_multisig_tx(multisig_tx_set txs)
// save as binary
std::ostringstream oss;
- boost::archive::portable_binary_oarchive ar(oss);
+ binary_archive<true> ar(oss);
try
{
- ar << txs;
+ if (!::serialization::serialize(ar, txs))
+ return std::string();
}
catch (...)
{
@@ -7054,13 +7142,29 @@ bool wallet2::parse_multisig_tx_from_str(std::string multisig_tx_st, multisig_tx
LOG_PRINT_L0("Failed to decrypt multisig tx data: " << e.what());
return false;
}
+ bool loaded = false;
try
{
std::istringstream iss(multisig_tx_st);
- boost::archive::portable_binary_iarchive ar(iss);
- ar >> exported_txs;
+ binary_archive<false> ar(iss);
+ if (::serialization::serialize(ar, exported_txs))
+ if (::serialization::check_stream_state(ar))
+ loaded = true;
}
- catch (...)
+ catch (...) {}
+ try
+ {
+ if (!loaded && m_load_deprecated_formats)
+ {
+ std::istringstream iss(multisig_tx_st);
+ boost::archive::portable_binary_iarchive ar(iss);
+ ar >> exported_txs;
+ loaded = true;
+ }
+ }
+ catch(...) {}
+
+ if (!loaded)
{
LOG_PRINT_L0("Failed to parse multisig tx data");
return false;
@@ -9547,8 +9651,8 @@ bool wallet2::light_wallet_parse_rct_str(const std::string& rct_string, const cr
bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image, const crypto::public_key& tx_public_key, uint64_t out_index)
{
// Lookup key image from cache
- std::map<uint64_t, crypto::key_image> index_keyimage_map;
- std::unordered_map<crypto::public_key, std::map<uint64_t, crypto::key_image> >::const_iterator found_pub_key = m_key_image_cache.find(tx_public_key);
+ serializable_map<uint64_t, crypto::key_image> index_keyimage_map;
+ serializable_unordered_map<crypto::public_key, serializable_map<uint64_t, crypto::key_image> >::const_iterator found_pub_key = m_key_image_cache.find(tx_public_key);
if(found_pub_key != m_key_image_cache.end()) {
// pub key found. key image for index cached?
index_keyimage_map = found_pub_key->second;
@@ -11736,7 +11840,7 @@ std::string wallet2::get_reserve_proof(const boost::optional<std::pair<uint32_t,
}
// collect all subaddress spend keys that received those outputs and generate their signatures
- std::unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
+ serializable_unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
for (const cryptonote::subaddress_index &index : subaddr_indices)
{
crypto::secret_key subaddr_spend_skey = m_account.get_keys().m_spend_secret_key;
@@ -11753,8 +11857,9 @@ std::string wallet2::get_reserve_proof(const boost::optional<std::pair<uint32_t,
// serialize & encode
std::ostringstream oss;
- boost::archive::portable_binary_oarchive ar(oss);
- ar << proofs << subaddr_spendkeys;
+ binary_archive<true> ar(oss);
+ THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(ar, proofs), error::wallet_internal_error, "Failed to serialize proof");
+ THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(ar, subaddr_spendkeys), error::wallet_internal_error, "Failed to serialize proof");
return "ReserveProofV2" + tools::base58::encode(oss.str());
}
@@ -11778,11 +11883,25 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
THROW_WALLET_EXCEPTION_IF(!tools::base58::decode(sig_str.substr(std::strlen(header_v1)), sig_decoded), error::wallet_internal_error,
"Signature decoding error");
- std::istringstream iss(sig_decoded);
- boost::archive::portable_binary_iarchive ar(iss);
+ bool loaded = false;
std::vector<reserve_proof_entry> proofs;
- std::unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
- ar >> proofs >> subaddr_spendkeys;
+ serializable_unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
+ try
+ {
+ std::istringstream iss(sig_decoded);
+ binary_archive<false> ar(iss);
+ if (::serialization::serialize_noeof(ar, proofs))
+ if (::serialization::serialize_noeof(ar, subaddr_spendkeys))
+ if (::serialization::check_stream_state(ar))
+ loaded = true;
+ }
+ catch(...) {}
+ if (!loaded && m_load_deprecated_formats)
+ {
+ std::istringstream iss(sig_decoded);
+ boost::archive::portable_binary_iarchive ar(iss);
+ ar >> proofs >> subaddr_spendkeys.parent();
+ }
THROW_WALLET_EXCEPTION_IF(subaddr_spendkeys.count(address.m_spend_public_key) == 0, error::wallet_internal_error,
"The given address isn't found in the proof");
@@ -12021,7 +12140,7 @@ std::string wallet2::get_description() const
return "";
}
-const std::pair<std::map<std::string, std::string>, std::vector<std::string>>& wallet2::get_account_tags()
+const std::pair<serializable_map<std::string, std::string>, std::vector<std::string>>& wallet2::get_account_tags()
{
// ensure consistency
if (m_account_tags.second.size() != get_num_subaddress_accounts())
@@ -12743,9 +12862,9 @@ std::string wallet2::export_outputs_to_str(bool all) const
PERF_TIMER(export_outputs_to_str);
std::stringstream oss;
- boost::archive::portable_binary_oarchive ar(oss);
- const auto& outputs = export_outputs(all);
- ar << outputs;
+ binary_archive<true> ar(oss);
+ auto outputs = export_outputs(all);
+ THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(ar, outputs), error::wallet_internal_error, "Failed to serialize output data");
std::string magic(OUTPUT_EXPORT_FILE_MAGIC, strlen(OUTPUT_EXPORT_FILE_MAGIC));
const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
@@ -12857,23 +12976,39 @@ size_t wallet2::import_outputs_from_str(const std::string &outputs_st)
}
size_t imported_outputs = 0;
+ bool loaded = false;
try
{
std::string body(data, headerlen);
- std::stringstream iss;
- iss << body;
std::pair<size_t, std::vector<tools::wallet2::transfer_details>> outputs;
try
{
- boost::archive::portable_binary_iarchive ar(iss);
- ar >> outputs;
+ std::stringstream iss;
+ iss << body;
+ binary_archive<false> ar(iss);
+ if (::serialization::serialize(ar, outputs))
+ if (::serialization::check_stream_state(ar))
+ loaded = true;
}
- catch (...)
+ catch (...) {}
+
+ if (!loaded && m_load_deprecated_formats)
{
- iss.str("");
- iss << body;
- boost::archive::binary_iarchive ar(iss);
- ar >> outputs;
+ try
+ {
+ std::stringstream iss;
+ iss << body;
+ boost::archive::portable_binary_iarchive ar(iss);
+ ar >> outputs;
+ loaded = true;
+ }
+ catch (...) {}
+ }
+
+ if (!loaded)
+ {
+ outputs.first = 0;
+ outputs.second = {};
}
imported_outputs = import_outputs(outputs);
@@ -13027,8 +13162,8 @@ cryptonote::blobdata wallet2::export_multisig()
}
std::stringstream oss;
- boost::archive::portable_binary_oarchive ar(oss);
- ar << info;
+ binary_archive<true> ar(oss);
+ CHECK_AND_ASSERT_THROW_MES(::serialization::serialize(ar, info), "Failed to serialize multisig data");
const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
std::string header;
@@ -13098,10 +13233,26 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs)
seen.insert(signer);
std::string body(data, headerlen);
- std::istringstream iss(body);
std::vector<tools::wallet2::multisig_info> i;
- boost::archive::portable_binary_iarchive ar(iss);
- ar >> i;
+
+ bool loaded = false;
+ try
+ {
+ std::istringstream iss(body);
+ binary_archive<false> ar(iss);
+ if (::serialization::serialize(ar, i))
+ if (::serialization::check_stream_state(ar))
+ loaded = true;
+ }
+ catch(...) {}
+ if (!loaded && m_load_deprecated_formats)
+ {
+ std::istringstream iss(body);
+ boost::archive::portable_binary_iarchive ar(iss);
+ ar >> i;
+ loaded = true;
+ }
+ CHECK_AND_ASSERT_THROW_MES(loaded, "Failed to load output data");
MINFO(boost::format("%u outputs found") % boost::lexical_cast<std::string>(i.size()));
info.push_back(std::move(i));
}