mirror of
https://codeberg.org/anoncontributorxmr/monero.git
synced 2024-11-26 09:24:47 +00:00
replace most boost serialization with existing monero serialization
This reduces the attack surface for data that can come from malicious sources (exported output and key images, multisig transactions...) since the monero serialization is already exposed to the outside, and the boost lib we were using had a few known crashers. For interoperability, a new load-deprecated-formats wallet setting is added (off by default). This allows loading boost format data if there is no alternative. It will likely go at some point, along with the ability to load those. Notably, the peer lists file still uses the boost serialization code, as the data it stores is define in epee, while the new serialization code is in monero, and migrating it was fairly hairy. Since this file is local and not obtained from anyone else, the marginal risk is minimal, but it could be migrated later if needed. Some tests and tools also do, this will stay as is for now.
This commit is contained in:
parent
43a4fd9e16
commit
7175dcb107
34 changed files with 837 additions and 392 deletions
|
@ -28,8 +28,6 @@
|
||||||
|
|
||||||
#include <boost/range/adaptor/transformed.hpp>
|
#include <boost/range/adaptor/transformed.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
|
||||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
|
||||||
#include "common/unordered_containers_boost_serialization.h"
|
#include "common/unordered_containers_boost_serialization.h"
|
||||||
#include "common/command_line.h"
|
#include "common/command_line.h"
|
||||||
#include "common/varint.h"
|
#include "common/varint.h"
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include "serialization/variant.h"
|
#include "serialization/variant.h"
|
||||||
#include "serialization/vector.h"
|
#include "serialization/containers.h"
|
||||||
#include "serialization/binary_archive.h"
|
#include "serialization/binary_archive.h"
|
||||||
#include "serialization/json_archive.h"
|
#include "serialization/json_archive.h"
|
||||||
#include "serialization/debug_archive.h"
|
#include "serialization/debug_archive.h"
|
||||||
|
|
|
@ -34,7 +34,6 @@ using namespace epee;
|
||||||
#include "cryptonote_basic_impl.h"
|
#include "cryptonote_basic_impl.h"
|
||||||
#include "string_tools.h"
|
#include "string_tools.h"
|
||||||
#include "serialization/binary_utils.h"
|
#include "serialization/binary_utils.h"
|
||||||
#include "serialization/container.h"
|
|
||||||
#include "cryptonote_format_utils.h"
|
#include "cryptonote_format_utils.h"
|
||||||
#include "cryptonote_config.h"
|
#include "cryptonote_config.h"
|
||||||
#include "misc_language.h"
|
#include "misc_language.h"
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
#include <boost/serialization/set.hpp>
|
#include <boost/serialization/set.hpp>
|
||||||
#include <boost/serialization/map.hpp>
|
#include <boost/serialization/map.hpp>
|
||||||
#include <boost/serialization/is_bitwise_serializable.hpp>
|
#include <boost/serialization/is_bitwise_serializable.hpp>
|
||||||
#include <boost/archive/binary_iarchive.hpp>
|
|
||||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||||
#include "cryptonote_basic.h"
|
#include "cryptonote_basic.h"
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "misc_language.h"
|
#include "misc_language.h"
|
||||||
#include "string_tools.h"
|
#include "string_tools.h"
|
||||||
#include "time_helper.h"
|
#include "time_helper.h"
|
||||||
|
#include "serialization/serialization.h"
|
||||||
#include "cryptonote_config.h"
|
#include "cryptonote_config.h"
|
||||||
|
|
||||||
namespace nodetool
|
namespace nodetool
|
||||||
|
@ -84,6 +85,15 @@ namespace nodetool
|
||||||
KV_SERIALIZE_OPT(rpc_port, (uint16_t)0)
|
KV_SERIALIZE_OPT(rpc_port, (uint16_t)0)
|
||||||
KV_SERIALIZE_OPT(rpc_credits_per_hash, (uint32_t)0)
|
KV_SERIALIZE_OPT(rpc_credits_per_hash, (uint32_t)0)
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE()
|
||||||
|
FIELD(adr)
|
||||||
|
FIELD(id)
|
||||||
|
VARINT_FIELD(last_seen)
|
||||||
|
VARINT_FIELD(pruning_seed)
|
||||||
|
VARINT_FIELD(rpc_port)
|
||||||
|
VARINT_FIELD(rpc_credits_per_hash)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
typedef peerlist_entry_base<epee::net_utils::network_address> peerlist_entry;
|
typedef peerlist_entry_base<epee::net_utils::network_address> peerlist_entry;
|
||||||
|
|
||||||
|
@ -99,6 +109,12 @@ namespace nodetool
|
||||||
KV_SERIALIZE(id)
|
KV_SERIALIZE(id)
|
||||||
KV_SERIALIZE(first_seen)
|
KV_SERIALIZE(first_seen)
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE()
|
||||||
|
FIELD(adr)
|
||||||
|
FIELD(id)
|
||||||
|
VARINT_FIELD(first_seen)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
typedef anchor_peerlist_entry_base<epee::net_utils::network_address> anchor_peerlist_entry;
|
typedef anchor_peerlist_entry_base<epee::net_utils::network_address> anchor_peerlist_entry;
|
||||||
|
|
||||||
|
@ -114,6 +130,12 @@ namespace nodetool
|
||||||
KV_SERIALIZE(id)
|
KV_SERIALIZE(id)
|
||||||
KV_SERIALIZE(is_income)
|
KV_SERIALIZE(is_income)
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE()
|
||||||
|
FIELD(adr)
|
||||||
|
FIELD(id)
|
||||||
|
FIELD(is_income)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
typedef connection_entry_base<epee::net_utils::network_address> connection_entry;
|
typedef connection_entry_base<epee::net_utils::network_address> connection_entry;
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ extern "C" {
|
||||||
#include "hex.h"
|
#include "hex.h"
|
||||||
#include "span.h"
|
#include "span.h"
|
||||||
#include "memwipe.h"
|
#include "memwipe.h"
|
||||||
#include "serialization/vector.h"
|
#include "serialization/containers.h"
|
||||||
#include "serialization/debug_archive.h"
|
#include "serialization/debug_archive.h"
|
||||||
#include "serialization/binary_archive.h"
|
#include "serialization/binary_archive.h"
|
||||||
#include "serialization/json_archive.h"
|
#include "serialization/json_archive.h"
|
||||||
|
@ -239,6 +239,12 @@ namespace rct {
|
||||||
struct RCTConfig {
|
struct RCTConfig {
|
||||||
RangeProofType range_proof_type;
|
RangeProofType range_proof_type;
|
||||||
int bp_version;
|
int bp_version;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
VARINT_FIELD(range_proof_type)
|
||||||
|
VARINT_FIELD(bp_version)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
struct rctSigBase {
|
struct rctSigBase {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
@ -317,6 +323,16 @@ namespace rct {
|
||||||
ar.end_array();
|
ar.end_array();
|
||||||
return ar.stream().good();
|
return ar.stream().good();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
FIELD(type)
|
||||||
|
FIELD(message)
|
||||||
|
FIELD(mixRing)
|
||||||
|
FIELD(pseudoOuts)
|
||||||
|
FIELD(ecdhInfo)
|
||||||
|
FIELD(outPk)
|
||||||
|
VARINT_FIELD(txnFee)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
struct rctSigPrunable {
|
struct rctSigPrunable {
|
||||||
std::vector<rangeSig> rangeSigs;
|
std::vector<rangeSig> rangeSigs;
|
||||||
|
@ -436,6 +452,12 @@ namespace rct {
|
||||||
return ar.stream().good();
|
return ar.stream().good();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
FIELD(rangeSigs)
|
||||||
|
FIELD(bulletproofs)
|
||||||
|
FIELD(MGs)
|
||||||
|
FIELD(pseudoOuts)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
struct rctSig: public rctSigBase {
|
struct rctSig: public rctSigBase {
|
||||||
rctSigPrunable p;
|
rctSigPrunable p;
|
||||||
|
@ -449,6 +471,11 @@ namespace rct {
|
||||||
{
|
{
|
||||||
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 ? p.pseudoOuts : pseudoOuts;
|
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 ? p.pseudoOuts : pseudoOuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
FIELDS((rctSigBase&)*this)
|
||||||
|
FIELD(p)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
//other basepoint H = toPoint(cn_fast_hash(G)), G the basepoint
|
//other basepoint H = toPoint(cn_fast_hash(G)), G the basepoint
|
||||||
|
|
|
@ -27,14 +27,12 @@
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
|
||||||
#include "cryptonote_config.h"
|
#include "cryptonote_config.h"
|
||||||
#include "include_base_utils.h"
|
#include "include_base_utils.h"
|
||||||
#include "string_tools.h"
|
#include "string_tools.h"
|
||||||
#include "file_io_utils.h"
|
#include "file_io_utils.h"
|
||||||
#include "int-util.h"
|
#include "int-util.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
#include "serialization/crypto.h"
|
|
||||||
#include "common/unordered_containers_boost_serialization.h"
|
#include "common/unordered_containers_boost_serialization.h"
|
||||||
#include "cryptonote_basic/cryptonote_boost_serialization.h"
|
#include "cryptonote_basic/cryptonote_boost_serialization.h"
|
||||||
#include "cryptonote_basic/cryptonote_format_utils.h"
|
#include "cryptonote_basic/cryptonote_format_utils.h"
|
||||||
|
@ -295,15 +293,29 @@ namespace cryptonote
|
||||||
std::ifstream data;
|
std::ifstream data;
|
||||||
data.open(state_file_path, std::ios_base::binary | std::ios_base::in);
|
data.open(state_file_path, std::ios_base::binary | std::ios_base::in);
|
||||||
if (!data.fail())
|
if (!data.fail())
|
||||||
|
{
|
||||||
|
bool loaded = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
binary_archive<false> ar(data);
|
||||||
|
if (::serialization::serialize(ar, *this))
|
||||||
|
if (::serialization::check_stream_state(ar))
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
if (!loaded)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
boost::archive::portable_binary_iarchive a(data);
|
boost::archive::portable_binary_iarchive a(data);
|
||||||
a >> *this;
|
a >> *this;
|
||||||
|
loaded = true;
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (...) {}
|
||||||
|
}
|
||||||
|
if (!loaded)
|
||||||
{
|
{
|
||||||
MERROR("Failed to load RPC payments file: " << e.what());
|
MERROR("Failed to load RPC payments file");
|
||||||
m_client_info.clear();
|
m_client_info.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,8 +356,9 @@ namespace cryptonote
|
||||||
MWARNING("Failed to save RPC payments to file " << state_file_path);
|
MWARNING("Failed to save RPC payments to file " << state_file_path);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
boost::archive::portable_binary_oarchive a(data);
|
binary_archive<true> ar(data);
|
||||||
a << *this;
|
if (!::serialization::serialize(ar, *const_cast<rpc_payment*>(this)))
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
CATCH_ENTRY_L0("rpc_payment::store", false);
|
CATCH_ENTRY_L0("rpc_payment::store", false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,17 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <map>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <boost/serialization/version.hpp>
|
#include <boost/serialization/version.hpp>
|
||||||
#include "cryptonote_basic/blobdatatype.h"
|
#include "cryptonote_basic/blobdatatype.h"
|
||||||
#include "cryptonote_basic/cryptonote_basic.h"
|
#include "cryptonote_basic/cryptonote_basic.h"
|
||||||
|
#include <boost/serialization/list.hpp>
|
||||||
|
#include <boost/serialization/vector.hpp>
|
||||||
|
#include "serialization/crypto.h"
|
||||||
|
#include "serialization/string.h"
|
||||||
|
#include "serialization/pair.h"
|
||||||
|
#include "serialization/containers.h"
|
||||||
|
|
||||||
namespace cryptonote
|
namespace cryptonote
|
||||||
{
|
{
|
||||||
|
@ -96,6 +103,33 @@ namespace cryptonote
|
||||||
a & nonces_bad;
|
a & nonces_bad;
|
||||||
a & nonces_dupe;
|
a & nonces_dupe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(block)
|
||||||
|
FIELD(previous_block)
|
||||||
|
FIELD(hashing_blob)
|
||||||
|
FIELD(previous_hashing_blob)
|
||||||
|
VARINT_FIELD(seed_height)
|
||||||
|
VARINT_FIELD(previous_seed_height)
|
||||||
|
FIELD(seed_hash)
|
||||||
|
FIELD(previous_seed_hash)
|
||||||
|
VARINT_FIELD(cookie)
|
||||||
|
FIELD(top)
|
||||||
|
FIELD(previous_top)
|
||||||
|
VARINT_FIELD(credits)
|
||||||
|
FIELD(payments)
|
||||||
|
FIELD(previous_payments)
|
||||||
|
FIELD(update_time)
|
||||||
|
FIELD(last_request_timestamp)
|
||||||
|
FIELD(block_template_update_time)
|
||||||
|
VARINT_FIELD(credits_total)
|
||||||
|
VARINT_FIELD(credits_used)
|
||||||
|
VARINT_FIELD(nonces_good)
|
||||||
|
VARINT_FIELD(nonces_stale)
|
||||||
|
VARINT_FIELD(nonces_bad)
|
||||||
|
VARINT_FIELD(nonces_dupe)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -114,8 +148,8 @@ namespace cryptonote
|
||||||
template <class t_archive>
|
template <class t_archive>
|
||||||
inline void serialize(t_archive &a, const unsigned int ver)
|
inline void serialize(t_archive &a, const unsigned int ver)
|
||||||
{
|
{
|
||||||
a & m_client_info;
|
a & m_client_info.parent();
|
||||||
a & m_hashrate;
|
a & m_hashrate.parent();
|
||||||
a & m_credits_total;
|
a & m_credits_total;
|
||||||
a & m_credits_used;
|
a & m_credits_used;
|
||||||
a & m_nonces_good;
|
a & m_nonces_good;
|
||||||
|
@ -124,6 +158,18 @@ namespace cryptonote
|
||||||
a & m_nonces_dupe;
|
a & m_nonces_dupe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(m_client_info)
|
||||||
|
FIELD(m_hashrate)
|
||||||
|
VARINT_FIELD(m_credits_total)
|
||||||
|
VARINT_FIELD(m_credits_used)
|
||||||
|
VARINT_FIELD(m_nonces_good)
|
||||||
|
VARINT_FIELD(m_nonces_stale)
|
||||||
|
VARINT_FIELD(m_nonces_bad)
|
||||||
|
VARINT_FIELD(m_nonces_dupe)
|
||||||
|
END_SERIALIZE()
|
||||||
|
|
||||||
bool load(std::string directory);
|
bool load(std::string directory);
|
||||||
bool store(const std::string &directory = std::string()) const;
|
bool store(const std::string &directory = std::string()) const;
|
||||||
|
|
||||||
|
@ -131,9 +177,9 @@ namespace cryptonote
|
||||||
cryptonote::account_public_address m_address;
|
cryptonote::account_public_address m_address;
|
||||||
uint64_t m_diff;
|
uint64_t m_diff;
|
||||||
uint64_t m_credits_per_hash_found;
|
uint64_t m_credits_per_hash_found;
|
||||||
std::unordered_map<crypto::public_key, client_info> m_client_info;
|
serializable_unordered_map<crypto::public_key, client_info> m_client_info;
|
||||||
std::string m_directory;
|
std::string m_directory;
|
||||||
std::map<uint64_t, uint64_t> m_hashrate;
|
serializable_map<uint64_t, uint64_t> m_hashrate;
|
||||||
uint64_t m_credits_total;
|
uint64_t m_credits_total;
|
||||||
uint64_t m_credits_used;
|
uint64_t m_credits_used;
|
||||||
uint64_t m_nonces_good;
|
uint64_t m_nonces_good;
|
||||||
|
@ -143,6 +189,3 @@ namespace cryptonote
|
||||||
mutable boost::mutex mutex;
|
mutable boost::mutex mutex;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CLASS_VERSION(cryptonote::rpc_payment, 0);
|
|
||||||
BOOST_CLASS_VERSION(cryptonote::rpc_payment::client_info, 0);
|
|
||||||
|
|
|
@ -28,10 +28,6 @@
|
||||||
//
|
//
|
||||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "serialization.h"
|
|
||||||
|
|
||||||
namespace serialization
|
namespace serialization
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
|
@ -103,7 +99,7 @@ bool do_serialize_container(Archive<true> &ar, C &v)
|
||||||
return false;
|
return false;
|
||||||
if (i != v.begin())
|
if (i != v.begin())
|
||||||
ar.delimit_array();
|
ar.delimit_array();
|
||||||
if(!::serialization::detail::serialize_container_element(ar, const_cast<typename C::value_type&>(*i)))
|
if(!::serialization::detail::serialize_container_element(ar, (typename C::value_type&)*i))
|
||||||
return false;
|
return false;
|
||||||
if (!ar.stream().good())
|
if (!ar.stream().good())
|
||||||
return false;
|
return false;
|
||||||
|
|
128
src/serialization/containers.h
Normal file
128
src/serialization/containers.h
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <set>
|
||||||
|
#include "serialization.h"
|
||||||
|
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::vector<T> &v);
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::vector<T> &v);
|
||||||
|
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::deque<T> &v);
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::deque<T> &v);
|
||||||
|
|
||||||
|
template<typename K, typename V>
|
||||||
|
class serializable_unordered_map: public std::unordered_map<K, V>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename std::pair<K, V> value_type;
|
||||||
|
typename std::unordered_map<K, V> &parent() { return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_unordered_map<K, V> &v);
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_unordered_map<K, V> &v);
|
||||||
|
|
||||||
|
template<typename K, typename V>
|
||||||
|
class serializable_map: public std::map<K, V>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename std::pair<K, V> value_type;
|
||||||
|
typename std::map<K, V> &parent() { return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_map<K, V> &v);
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_map<K, V> &v);
|
||||||
|
|
||||||
|
template<typename K, typename V>
|
||||||
|
class serializable_unordered_multimap: public std::unordered_multimap<K, V>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename std::pair<K, V> value_type;
|
||||||
|
typename std::unordered_multimap<K, V> &parent() { return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_unordered_multimap<K, V> &v);
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_unordered_multimap<K, V> &v);
|
||||||
|
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::unordered_set<T> &v);
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::unordered_set<T> &v);
|
||||||
|
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::set<T> &v);
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::set<T> &v);
|
||||||
|
|
||||||
|
namespace serialization
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename T> void do_reserve(std::vector<T> &c, size_t N) { c.reserve(N); }
|
||||||
|
template <typename T> void do_add(std::vector<T> &c, T &&e) { c.emplace_back(std::forward<T>(e)); }
|
||||||
|
|
||||||
|
template <typename T> void do_add(std::deque<T> &c, T &&e) { c.emplace_back(std::forward<T>(e)); }
|
||||||
|
|
||||||
|
template <typename K, typename V> void do_add(serializable_unordered_map<K, V> &c, std::pair<K, V> &&e) { c.insert(std::forward<std::pair<K, V>>(e)); }
|
||||||
|
|
||||||
|
template <typename K, typename V> void do_add(serializable_map<K, V> &c, std::pair<K, V> &&e) { c.insert(std::forward<std::pair<K, V>>(e)); }
|
||||||
|
|
||||||
|
template <typename K, typename V> void do_add(serializable_unordered_multimap<K, V> &c, std::pair<K, V> &&e) { c.insert(std::forward<std::pair<K, V>>(e)); }
|
||||||
|
|
||||||
|
template <typename T> void do_add(std::unordered_set<T> &c, T &&e) { c.insert(std::forward<T>(e)); }
|
||||||
|
|
||||||
|
template <typename T> void do_add(std::set<T> &c, T &&e) { c.insert(std::forward<T>(e)); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "container.h"
|
||||||
|
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::vector<T> &v) { return do_serialize_container(ar, v); }
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::vector<T> &v) { return do_serialize_container(ar, v); }
|
||||||
|
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::deque<T> &v) { return do_serialize_container(ar, v); }
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::deque<T> &v) { return do_serialize_container(ar, v); }
|
||||||
|
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_unordered_map<K, V> &v) { return do_serialize_container(ar, v); }
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_unordered_map<K, V> &v) { return do_serialize_container(ar, v); }
|
||||||
|
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_map<K, V> &v) { return do_serialize_container(ar, v); }
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_map<K, V> &v) { return do_serialize_container(ar, v); }
|
||||||
|
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<false> &ar, serializable_unordered_multimap<K, V> &v) { return do_serialize_container(ar, v); }
|
||||||
|
template <template <bool> class Archive, typename K, typename V> bool do_serialize(Archive<true> &ar, serializable_unordered_multimap<K, V> &v) { return do_serialize_container(ar, v); }
|
||||||
|
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::unordered_set<T> &v) { return do_serialize_container(ar, v); }
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::unordered_set<T> &v) { return do_serialize_container(ar, v); }
|
||||||
|
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<false> &ar, std::set<T> &v) { return do_serialize_container(ar, v); }
|
||||||
|
template <template <bool> class Archive, class T> bool do_serialize(Archive<true> &ar, std::set<T> &v) { return do_serialize_container(ar, v); }
|
|
@ -1,64 +0,0 @@
|
||||||
// Copyright (c) 2014-2020, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<false> &ar, std::deque<T> &v);
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<true> &ar, std::deque<T> &v);
|
|
||||||
|
|
||||||
namespace serialization
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
void do_reserve(std::deque<T> &c, size_t N)
|
|
||||||
{
|
|
||||||
c.reserve(N);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void do_add(std::deque<T> &c, T &&e)
|
|
||||||
{
|
|
||||||
c.emplace_back(std::move(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "serialization.h"
|
|
||||||
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<false> &ar, std::deque<T> &v) { return do_serialize_container(ar, v); }
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<true> &ar, std::deque<T> &v) { return do_serialize_container(ar, v); }
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace serialization
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void do_add(std::list<T> &c, T &&e)
|
void do_add(std::list<T> &c, T &&e)
|
||||||
{
|
{
|
||||||
c.emplace_back(std::move(e));
|
c.emplace_back(std::forward<T>(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/type_traits/is_integral.hpp>
|
#include <boost/type_traits/is_integral.hpp>
|
||||||
#include <boost/type_traits/integral_constant.hpp>
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
|
#include <boost/mpl/bool.hpp>
|
||||||
|
|
||||||
/*! \struct is_blob_type
|
/*! \struct is_blob_type
|
||||||
*
|
*
|
||||||
|
@ -278,6 +279,27 @@ inline bool do_serialize(Archive &ar, bool &v)
|
||||||
if (!ar.stream().good()) return false; \
|
if (!ar.stream().good()) return false; \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
|
/*! \macro MAGIC_FIELD(m)
|
||||||
|
*/
|
||||||
|
#define MAGIC_FIELD(m) \
|
||||||
|
std::string magic = m; \
|
||||||
|
do { \
|
||||||
|
ar.tag("magic"); \
|
||||||
|
ar.serialize_blob((void*)magic.data(), magic.size()); \
|
||||||
|
if (!ar.stream().good()) return false; \
|
||||||
|
if (magic != m) return false; \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
/*! \macro VERSION_FIELD(v)
|
||||||
|
*/
|
||||||
|
#define VERSION_FIELD(v) \
|
||||||
|
uint32_t version = v; \
|
||||||
|
do { \
|
||||||
|
ar.tag("version"); \
|
||||||
|
ar.serialize_varint(version); \
|
||||||
|
if (!ar.stream().good()) return false; \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
|
||||||
namespace serialization {
|
namespace serialization {
|
||||||
/*! \namespace detail
|
/*! \namespace detail
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
// Copyright (c) 2014-2020, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<false> &ar, std::set<T> &v);
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<true> &ar, std::set<T> &v);
|
|
||||||
|
|
||||||
namespace serialization
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
void do_add(std::set<T> &c, T &&e)
|
|
||||||
{
|
|
||||||
c.insert(std::move(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "serialization.h"
|
|
||||||
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<false> &ar, std::set<T> &v) { return do_serialize_container(ar, v); }
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<true> &ar, std::set<T> &v) { return do_serialize_container(ar, v); }
|
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
// Copyright (c) 2014-2020, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<false> &ar, std::unordered_set<T> &v);
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<true> &ar, std::unordered_set<T> &v);
|
|
||||||
|
|
||||||
namespace serialization
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
void do_add(std::unordered_set<T> &c, T &&e)
|
|
||||||
{
|
|
||||||
c.insert(std::move(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "serialization.h"
|
|
||||||
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<false> &ar, std::unordered_set<T> &v) { return do_serialize_container(ar, v); }
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<true> &ar, std::unordered_set<T> &v) { return do_serialize_container(ar, v); }
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
// Copyright (c) 2014-2020, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "serialization.h"
|
|
||||||
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<false> &ar, std::vector<T> &v);
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<true> &ar, std::vector<T> &v);
|
|
||||||
|
|
||||||
namespace serialization
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
void do_reserve(std::vector<T> &c, size_t N)
|
|
||||||
{
|
|
||||||
c.reserve(N);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void do_add(std::vector<T> &c, T &&e)
|
|
||||||
{
|
|
||||||
c.emplace_back(std::move(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "container.h"
|
|
||||||
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<false> &ar, std::vector<T> &v) { return do_serialize_container(ar, v); }
|
|
||||||
template <template <bool> class Archive, class T>
|
|
||||||
bool do_serialize(Archive<true> &ar, std::vector<T> &v) { return do_serialize_container(ar, v); }
|
|
||||||
|
|
|
@ -3100,6 +3100,28 @@ bool simple_wallet::set_export_format(const std::vector<std::string> &args/* = s
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool simple_wallet::set_load_deprecated_formats(const std::vector<std::string> &args/* = std::vector<std::string()*/)
|
||||||
|
{
|
||||||
|
if (args.size() < 2)
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("Value not specified");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto pwd_container = get_and_verify_password();
|
||||||
|
if (pwd_container)
|
||||||
|
{
|
||||||
|
parse_bool_and_use(args[1], [&](bool r) {
|
||||||
|
m_wallet->load_deprecated_formats(r);
|
||||||
|
m_wallet->rewrite(m_wallet_file, pwd_container->password());
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
message_writer() << tr("Warning: deprecated formats use boost serialization, which has buffer overflows and crashers. Only load deprecated formats from sources you trust.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||||
{
|
{
|
||||||
if(args.empty())
|
if(args.empty())
|
||||||
|
@ -3789,6 +3811,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||||
success_msg_writer() << "persistent-rpc-client-id = " << m_wallet->persistent_rpc_client_id();
|
success_msg_writer() << "persistent-rpc-client-id = " << m_wallet->persistent_rpc_client_id();
|
||||||
success_msg_writer() << "auto-mine-for-rpc-payment-threshold = " << m_wallet->auto_mine_for_rpc_payment_threshold();
|
success_msg_writer() << "auto-mine-for-rpc-payment-threshold = " << m_wallet->auto_mine_for_rpc_payment_threshold();
|
||||||
success_msg_writer() << "credits-target = " << m_wallet->credits_target();
|
success_msg_writer() << "credits-target = " << m_wallet->credits_target();
|
||||||
|
success_msg_writer() << "load-deprecated-formats = " << m_wallet->load_deprecated_formats();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3850,6 +3873,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||||
CHECK_SIMPLE_VARIABLE("setup-background-mining", set_setup_background_mining, tr("1/yes or 0/no"));
|
CHECK_SIMPLE_VARIABLE("setup-background-mining", set_setup_background_mining, tr("1/yes or 0/no"));
|
||||||
CHECK_SIMPLE_VARIABLE("device-name", set_device_name, tr("<device_name[:device_spec]>"));
|
CHECK_SIMPLE_VARIABLE("device-name", set_device_name, tr("<device_name[:device_spec]>"));
|
||||||
CHECK_SIMPLE_VARIABLE("export-format", set_export_format, tr("\"binary\" or \"ascii\""));
|
CHECK_SIMPLE_VARIABLE("export-format", set_export_format, tr("\"binary\" or \"ascii\""));
|
||||||
|
CHECK_SIMPLE_VARIABLE("load-deprecated-formats", set_load_deprecated_formats, tr("0 or 1"));
|
||||||
CHECK_SIMPLE_VARIABLE("persistent-rpc-client-id", set_persistent_rpc_client_id, tr("0 or 1"));
|
CHECK_SIMPLE_VARIABLE("persistent-rpc-client-id", set_persistent_rpc_client_id, tr("0 or 1"));
|
||||||
CHECK_SIMPLE_VARIABLE("auto-mine-for-rpc-payment-threshold", set_auto_mine_for_rpc_payment_threshold, tr("floating point >= 0"));
|
CHECK_SIMPLE_VARIABLE("auto-mine-for-rpc-payment-threshold", set_auto_mine_for_rpc_payment_threshold, tr("floating point >= 0"));
|
||||||
CHECK_SIMPLE_VARIABLE("credits-target", set_credits_target, tr("unsigned integer"));
|
CHECK_SIMPLE_VARIABLE("credits-target", set_credits_target, tr("unsigned integer"));
|
||||||
|
|
|
@ -151,6 +151,7 @@ namespace cryptonote
|
||||||
bool set_setup_background_mining(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_setup_background_mining(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_device_name(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_device_name(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_export_format(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_export_format(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
|
bool set_load_deprecated_formats(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_persistent_rpc_client_id(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_persistent_rpc_client_id(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_auto_mine_for_rpc_payment_threshold(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_auto_mine_for_rpc_payment_threshold(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_credits_target(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_credits_target(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "message_store.h"
|
#include "message_store.h"
|
||||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
|
||||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
@ -182,8 +181,8 @@ bool message_store::signer_labels_complete() const
|
||||||
void message_store::get_signer_config(std::string &signer_config)
|
void message_store::get_signer_config(std::string &signer_config)
|
||||||
{
|
{
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
ar << m_signers;
|
THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(ar, m_signers), tools::error::wallet_internal_error, "Failed to serialize signer config");
|
||||||
signer_config = oss.str();
|
signer_config = oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,8 +193,8 @@ void message_store::unpack_signer_config(const multisig_wallet_state &state, con
|
||||||
{
|
{
|
||||||
std::stringstream iss;
|
std::stringstream iss;
|
||||||
iss << signer_config;
|
iss << signer_config;
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
binary_archive<false> ar(iss);
|
||||||
ar >> signers;
|
THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(ar, signers), tools::error::wallet_internal_error, "Failed to serialize signer config");
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -364,8 +363,8 @@ size_t message_store::add_auto_config_data_message(const multisig_wallet_state &
|
||||||
data.monero_address = me.monero_address;
|
data.monero_address = me.monero_address;
|
||||||
|
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
ar << data;
|
THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(ar, data), tools::error::wallet_internal_error, "Failed to serialize auto config data");
|
||||||
|
|
||||||
return add_message(state, 0, message_type::auto_config_data, message_direction::out, oss.str());
|
return add_message(state, 0, message_type::auto_config_data, message_direction::out, oss.str());
|
||||||
}
|
}
|
||||||
|
@ -384,8 +383,8 @@ void message_store::process_auto_config_data_message(uint32_t id)
|
||||||
{
|
{
|
||||||
std::stringstream iss;
|
std::stringstream iss;
|
||||||
iss << m.content;
|
iss << m.content;
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
binary_archive<false> ar(iss);
|
||||||
ar >> data;
|
THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(ar, data), tools::error::wallet_internal_error, "Failed to serialize auto config data");
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -745,8 +744,8 @@ std::string message_store::get_sanitized_text(const std::string &text, size_t ma
|
||||||
void message_store::write_to_file(const multisig_wallet_state &state, const std::string &filename)
|
void message_store::write_to_file(const multisig_wallet_state &state, const std::string &filename)
|
||||||
{
|
{
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
ar << *this;
|
THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(ar, *this), tools::error::wallet_internal_error, "Failed to serialize MMS state");
|
||||||
std::string buf = oss.str();
|
std::string buf = oss.str();
|
||||||
|
|
||||||
crypto::chacha_key key;
|
crypto::chacha_key key;
|
||||||
|
@ -762,14 +761,14 @@ void message_store::write_to_file(const multisig_wallet_state &state, const std:
|
||||||
write_file_data.encrypted_data = encrypted_data;
|
write_file_data.encrypted_data = encrypted_data;
|
||||||
|
|
||||||
std::stringstream file_oss;
|
std::stringstream file_oss;
|
||||||
boost::archive::portable_binary_oarchive file_ar(file_oss);
|
binary_archive<true> file_ar(file_oss);
|
||||||
file_ar << write_file_data;
|
THROW_WALLET_EXCEPTION_IF(!::serialization::serialize(file_ar, write_file_data), tools::error::wallet_internal_error, "Failed to serialize MMS state");
|
||||||
|
|
||||||
bool success = epee::file_io_utils::save_string_to_file(filename, file_oss.str());
|
bool success = epee::file_io_utils::save_string_to_file(filename, file_oss.str());
|
||||||
THROW_WALLET_EXCEPTION_IF(!success, tools::error::file_save_error, filename);
|
THROW_WALLET_EXCEPTION_IF(!success, tools::error::file_save_error, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void message_store::read_from_file(const multisig_wallet_state &state, const std::string &filename)
|
void message_store::read_from_file(const multisig_wallet_state &state, const std::string &filename, bool load_deprecated_formats)
|
||||||
{
|
{
|
||||||
boost::system::error_code ignored_ec;
|
boost::system::error_code ignored_ec;
|
||||||
bool file_exists = boost::filesystem::exists(filename, ignored_ec);
|
bool file_exists = boost::filesystem::exists(filename, ignored_ec);
|
||||||
|
@ -785,19 +784,39 @@ void message_store::read_from_file(const multisig_wallet_state &state, const std
|
||||||
bool success = epee::file_io_utils::load_file_to_string(filename, buf);
|
bool success = epee::file_io_utils::load_file_to_string(filename, buf);
|
||||||
THROW_WALLET_EXCEPTION_IF(!success, tools::error::file_read_error, filename);
|
THROW_WALLET_EXCEPTION_IF(!success, tools::error::file_read_error, filename);
|
||||||
|
|
||||||
|
bool loaded = false;
|
||||||
file_data read_file_data;
|
file_data read_file_data;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::stringstream iss;
|
||||||
|
iss << buf;
|
||||||
|
binary_archive<false> ar(iss);
|
||||||
|
if (::serialization::serialize(ar, read_file_data))
|
||||||
|
if (::serialization::check_stream_state(ar))
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
if (!loaded && load_deprecated_formats)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::stringstream iss;
|
std::stringstream iss;
|
||||||
iss << buf;
|
iss << buf;
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
ar >> read_file_data;
|
ar >> read_file_data;
|
||||||
|
loaded = true;
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
MERROR("MMS file " << filename << " has bad structure <iv,encrypted_data>: " << e.what());
|
MERROR("MMS file " << filename << " has bad structure <iv,encrypted_data>: " << e.what());
|
||||||
THROW_WALLET_EXCEPTION_IF(true, tools::error::file_read_error, filename);
|
THROW_WALLET_EXCEPTION_IF(true, tools::error::file_read_error, filename);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!loaded)
|
||||||
|
{
|
||||||
|
MERROR("MMS file " << filename << " has bad structure <iv,encrypted_data>");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(true, tools::error::file_read_error, filename);
|
||||||
|
}
|
||||||
|
|
||||||
crypto::chacha_key key;
|
crypto::chacha_key key;
|
||||||
crypto::generate_chacha_key(&state.view_secret_key, sizeof(crypto::secret_key), key, 1);
|
crypto::generate_chacha_key(&state.view_secret_key, sizeof(crypto::secret_key), key, 1);
|
||||||
|
@ -805,18 +824,38 @@ void message_store::read_from_file(const multisig_wallet_state &state, const std
|
||||||
decrypted_data.resize(read_file_data.encrypted_data.size());
|
decrypted_data.resize(read_file_data.encrypted_data.size());
|
||||||
crypto::chacha20(read_file_data.encrypted_data.data(), read_file_data.encrypted_data.size(), key, read_file_data.iv, &decrypted_data[0]);
|
crypto::chacha20(read_file_data.encrypted_data.data(), read_file_data.encrypted_data.size(), key, read_file_data.iv, &decrypted_data[0]);
|
||||||
|
|
||||||
|
loaded = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::stringstream iss;
|
||||||
|
iss << decrypted_data;
|
||||||
|
binary_archive<false> ar(iss);
|
||||||
|
if (::serialization::serialize(ar, *this))
|
||||||
|
if (::serialization::check_stream_state(ar))
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
catch(...) {}
|
||||||
|
if (!loaded && load_deprecated_formats)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::stringstream iss;
|
std::stringstream iss;
|
||||||
iss << decrypted_data;
|
iss << decrypted_data;
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
ar >> *this;
|
ar >> *this;
|
||||||
|
loaded = true;
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
MERROR("MMS file " << filename << " has bad structure: " << e.what());
|
MERROR("MMS file " << filename << " has bad structure: " << e.what());
|
||||||
THROW_WALLET_EXCEPTION_IF(true, tools::error::file_read_error, filename);
|
THROW_WALLET_EXCEPTION_IF(true, tools::error::file_read_error, filename);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!loaded)
|
||||||
|
{
|
||||||
|
MERROR("MMS file " << filename << " has bad structure");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(true, tools::error::file_read_error, filename);
|
||||||
|
}
|
||||||
|
|
||||||
m_filename = filename;
|
m_filename = filename;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
#include "common/command_line.h"
|
#include "common/command_line.h"
|
||||||
#include "wipeable_string.h"
|
#include "wipeable_string.h"
|
||||||
#include "net/abstract_http_client.h"
|
#include "net/abstract_http_client.h"
|
||||||
|
#include "serialization/crypto.h"
|
||||||
|
#include "serialization/string.h"
|
||||||
|
#include "serialization/containers.h"
|
||||||
#include "message_transporter.h"
|
#include "message_transporter.h"
|
||||||
|
|
||||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||||
|
@ -112,6 +115,24 @@ namespace mms
|
||||||
uint32_t round;
|
uint32_t round;
|
||||||
uint32_t signature_count;
|
uint32_t signature_count;
|
||||||
std::string transport_id;
|
std::string transport_id;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
VARINT_FIELD(id)
|
||||||
|
VARINT_FIELD(type)
|
||||||
|
VARINT_FIELD(direction)
|
||||||
|
FIELD(content)
|
||||||
|
VARINT_FIELD(created)
|
||||||
|
VARINT_FIELD(modified)
|
||||||
|
VARINT_FIELD(sent)
|
||||||
|
VARINT_FIELD(signer_index)
|
||||||
|
FIELD(hash)
|
||||||
|
VARINT_FIELD(state)
|
||||||
|
VARINT_FIELD(wallet_height)
|
||||||
|
VARINT_FIELD(round)
|
||||||
|
VARINT_FIELD(signature_count)
|
||||||
|
FIELD(transport_id)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
// "wallet_height" (for lack of a short name that would describe what it is about)
|
// "wallet_height" (for lack of a short name that would describe what it is about)
|
||||||
// is the number of transfers present in the wallet at the time of message
|
// is the number of transfers present in the wallet at the time of message
|
||||||
|
@ -132,6 +153,21 @@ namespace mms
|
||||||
std::string auto_config_transport_address;
|
std::string auto_config_transport_address;
|
||||||
bool auto_config_running;
|
bool auto_config_running;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(label)
|
||||||
|
FIELD(transport_address)
|
||||||
|
FIELD(monero_address_known)
|
||||||
|
FIELD(monero_address)
|
||||||
|
FIELD(me)
|
||||||
|
VARINT_FIELD(index)
|
||||||
|
FIELD(auto_config_token)
|
||||||
|
FIELD(auto_config_public_key)
|
||||||
|
FIELD(auto_config_secret_key)
|
||||||
|
FIELD(auto_config_transport_address)
|
||||||
|
FIELD(auto_config_running)
|
||||||
|
END_SERIALIZE()
|
||||||
|
|
||||||
authorized_signer()
|
authorized_signer()
|
||||||
{
|
{
|
||||||
monero_address_known = false;
|
monero_address_known = false;
|
||||||
|
@ -164,6 +200,13 @@ namespace mms
|
||||||
std::string label;
|
std::string label;
|
||||||
std::string transport_address;
|
std::string transport_address;
|
||||||
cryptonote::account_public_address monero_address;
|
cryptonote::account_public_address monero_address;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(label)
|
||||||
|
FIELD(transport_address)
|
||||||
|
FIELD(monero_address)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Overal .mms file structure, with the "message_store" object serialized to and
|
// Overal .mms file structure, with the "message_store" object serialized to and
|
||||||
|
@ -174,6 +217,13 @@ namespace mms
|
||||||
uint32_t file_version;
|
uint32_t file_version;
|
||||||
crypto::chacha_iv iv;
|
crypto::chacha_iv iv;
|
||||||
std::string encrypted_data;
|
std::string encrypted_data;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
FIELD(magic_string)
|
||||||
|
FIELD(file_version)
|
||||||
|
FIELD(iv)
|
||||||
|
FIELD(encrypted_data)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following struct provides info about the current state of a "wallet2" object
|
// The following struct provides info about the current state of a "wallet2" object
|
||||||
|
@ -198,6 +248,19 @@ namespace mms
|
||||||
uint32_t multisig_rounds_passed;
|
uint32_t multisig_rounds_passed;
|
||||||
size_t num_transfer_details;
|
size_t num_transfer_details;
|
||||||
std::string mms_file;
|
std::string mms_file;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(address)
|
||||||
|
VARINT_FIELD(nettype)
|
||||||
|
FIELD(view_secret_key)
|
||||||
|
FIELD(multisig)
|
||||||
|
FIELD(multisig_is_ready)
|
||||||
|
FIELD(has_multisig_partial_key_images)
|
||||||
|
VARINT_FIELD(multisig_rounds_passed)
|
||||||
|
VARINT_FIELD(num_transfer_details)
|
||||||
|
FIELD(mms_file)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
class message_store
|
class message_store
|
||||||
|
@ -283,7 +346,7 @@ namespace mms
|
||||||
void stop() { m_run.store(false, std::memory_order_relaxed); m_transporter.stop(); }
|
void stop() { m_run.store(false, std::memory_order_relaxed); m_transporter.stop(); }
|
||||||
|
|
||||||
void write_to_file(const multisig_wallet_state &state, const std::string &filename);
|
void write_to_file(const multisig_wallet_state &state, const std::string &filename);
|
||||||
void read_from_file(const multisig_wallet_state &state, const std::string &filename);
|
void read_from_file(const multisig_wallet_state &state, const std::string &filename, bool load_deprecated_formats = false);
|
||||||
|
|
||||||
template <class t_archive>
|
template <class t_archive>
|
||||||
inline void serialize(t_archive &a, const unsigned int ver)
|
inline void serialize(t_archive &a, const unsigned int ver)
|
||||||
|
@ -298,6 +361,18 @@ namespace mms
|
||||||
a & m_auto_send;
|
a & m_auto_send;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(m_active)
|
||||||
|
VARINT_FIELD(m_num_authorized_signers)
|
||||||
|
VARINT_FIELD(m_nettype)
|
||||||
|
VARINT_FIELD(m_num_required_signers)
|
||||||
|
FIELD(m_signers)
|
||||||
|
FIELD(m_messages)
|
||||||
|
VARINT_FIELD(m_next_message_id)
|
||||||
|
FIELD(m_auto_send)
|
||||||
|
END_SERIALIZE()
|
||||||
|
|
||||||
static const char* message_type_to_string(message_type type);
|
static const char* message_type_to_string(message_type type);
|
||||||
static const char* message_direction_to_string(message_direction direction);
|
static const char* message_direction_to_string(message_direction direction);
|
||||||
static const char* message_state_to_string(message_state state);
|
static const char* message_state_to_string(message_state state);
|
||||||
|
|
|
@ -103,8 +103,8 @@ using namespace cryptonote;
|
||||||
// used to target a given block weight (additional outputs may be added on top to build fee)
|
// 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 TX_WEIGHT_TARGET(bytes) (bytes*2/3)
|
||||||
|
|
||||||
#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\004"
|
#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\005"
|
||||||
#define SIGNED_TX_PREFIX "Monero signed tx set\004"
|
#define SIGNED_TX_PREFIX "Monero signed tx set\005"
|
||||||
#define MULTISIG_UNSIGNED_TX_PREFIX "Monero multisig unsigned tx set\001"
|
#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
|
#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_offline(false),
|
||||||
m_rpc_version(0),
|
m_rpc_version(0),
|
||||||
m_export_format(ExportFormat::Binary),
|
m_export_format(ExportFormat::Binary),
|
||||||
|
m_load_deprecated_formats(false),
|
||||||
m_credits_target(0)
|
m_credits_target(0)
|
||||||
{
|
{
|
||||||
set_rpc_client_secret_key(rct::rct2sk(rct::skGen()));
|
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);
|
value2.SetInt(m_export_format);
|
||||||
json.AddMember("export_format", value2, json.GetAllocator());
|
json.AddMember("export_format", value2, json.GetAllocator());
|
||||||
|
|
||||||
|
value2.SetInt(m_load_deprecated_formats);
|
||||||
|
json.AddMember("load_deprecated_formats", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetUint(1);
|
value2.SetUint(1);
|
||||||
json.AddMember("encrypted_secret_keys", value2, json.GetAllocator());
|
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_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
|
||||||
m_original_keys_available = false;
|
m_original_keys_available = false;
|
||||||
m_export_format = ExportFormat::Binary;
|
m_export_format = ExportFormat::Binary;
|
||||||
|
m_load_deprecated_formats = false;
|
||||||
m_device_name = "";
|
m_device_name = "";
|
||||||
m_device_derivation_path = "";
|
m_device_derivation_path = "";
|
||||||
m_key_device_type = hw::device::device_type::SOFTWARE;
|
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);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, export_format, ExportFormat, Int, false, Binary);
|
||||||
m_export_format = field_export_format;
|
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());
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, device_name, std::string, String, false, std::string());
|
||||||
if (m_device_name.empty())
|
if (m_device_name.empty())
|
||||||
{
|
{
|
||||||
|
@ -5617,11 +5625,27 @@ 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]);
|
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 {
|
try {
|
||||||
|
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;
|
std::stringstream iss;
|
||||||
iss << cache_data;
|
iss << cache_data;
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
ar >> *this;
|
ar >> *this;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
// try with previous scheme: direct from keys
|
// try with previous scheme: direct from keys
|
||||||
|
@ -5717,7 +5741,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (use_fs)
|
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)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
|
@ -5907,8 +5931,9 @@ boost::optional<wallet2::cache_file_data> wallet2::get_cache_file_data(const epe
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
ar << *this;
|
if (!::serialization::serialize(ar, *this))
|
||||||
|
return boost::none;
|
||||||
|
|
||||||
boost::optional<wallet2::cache_file_data> cache_file_data = (wallet2::cache_file_data) {};
|
boost::optional<wallet2::cache_file_data> cache_file_data = (wallet2::cache_file_data) {};
|
||||||
cache_file_data.get().cache_data = oss.str();
|
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();
|
txs.transfers = export_outputs();
|
||||||
// save as binary
|
// save as binary
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ar << txs;
|
if (!::serialization::serialize(ar, txs))
|
||||||
|
return std::string();
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -6617,6 +6643,11 @@ bool wallet2::parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsi
|
||||||
s = s.substr(1);
|
s = s.substr(1);
|
||||||
if (version == '\003')
|
if (version == '\003')
|
||||||
{
|
{
|
||||||
|
if (!m_load_deprecated_formats)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Not loading deprecated format");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::istringstream iss(s);
|
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')
|
else if (version == '\004')
|
||||||
{
|
{
|
||||||
|
if (!m_load_deprecated_formats)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Not loading deprecated format");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
s = decrypt_with_view_secret_key(s);
|
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;
|
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
|
else
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Unsupported version in unsigned tx");
|
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
|
// save as binary
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ar << signed_txes;
|
if (!::serialization::serialize(ar, signed_txes))
|
||||||
|
return std::string();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -6901,6 +6958,11 @@ bool wallet2::parse_tx_from_str(const std::string &signed_tx_st, std::vector<too
|
||||||
s = s.substr(1);
|
s = s.substr(1);
|
||||||
if (version == '\003')
|
if (version == '\003')
|
||||||
{
|
{
|
||||||
|
if (!m_load_deprecated_formats)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Not loading deprecated format");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::istringstream iss(s);
|
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')
|
else if (version == '\004')
|
||||||
{
|
{
|
||||||
|
if (!m_load_deprecated_formats)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("Not loading deprecated format");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
s = decrypt_with_view_secret_key(s);
|
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;
|
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
|
else
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Unsupported version in signed transaction");
|
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
|
// save as binary
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ar << txs;
|
if (!::serialization::serialize(ar, txs))
|
||||||
|
return std::string();
|
||||||
}
|
}
|
||||||
catch (...)
|
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());
|
LOG_PRINT_L0("Failed to decrypt multisig tx data: " << e.what());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool loaded = false;
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
std::istringstream iss(multisig_tx_st);
|
||||||
|
binary_archive<false> ar(iss);
|
||||||
|
if (::serialization::serialize(ar, exported_txs))
|
||||||
|
if (::serialization::check_stream_state(ar))
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!loaded && m_load_deprecated_formats)
|
||||||
{
|
{
|
||||||
std::istringstream iss(multisig_tx_st);
|
std::istringstream iss(multisig_tx_st);
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
ar >> exported_txs;
|
ar >> exported_txs;
|
||||||
|
loaded = true;
|
||||||
}
|
}
|
||||||
catch (...)
|
}
|
||||||
|
catch(...) {}
|
||||||
|
|
||||||
|
if (!loaded)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Failed to parse multisig tx data");
|
LOG_PRINT_L0("Failed to parse multisig tx data");
|
||||||
return false;
|
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)
|
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
|
// Lookup key image from cache
|
||||||
std::map<uint64_t, crypto::key_image> index_keyimage_map;
|
serializable_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_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()) {
|
if(found_pub_key != m_key_image_cache.end()) {
|
||||||
// pub key found. key image for index cached?
|
// pub key found. key image for index cached?
|
||||||
index_keyimage_map = found_pub_key->second;
|
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
|
// 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)
|
for (const cryptonote::subaddress_index &index : subaddr_indices)
|
||||||
{
|
{
|
||||||
crypto::secret_key subaddr_spend_skey = m_account.get_keys().m_spend_secret_key;
|
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
|
// serialize & encode
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
ar << proofs << subaddr_spendkeys;
|
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());
|
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,
|
THROW_WALLET_EXCEPTION_IF(!tools::base58::decode(sig_str.substr(std::strlen(header_v1)), sig_decoded), error::wallet_internal_error,
|
||||||
"Signature decoding error");
|
"Signature decoding error");
|
||||||
|
|
||||||
|
bool loaded = false;
|
||||||
|
std::vector<reserve_proof_entry> proofs;
|
||||||
|
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);
|
std::istringstream iss(sig_decoded);
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
std::vector<reserve_proof_entry> proofs;
|
ar >> proofs >> subaddr_spendkeys.parent();
|
||||||
std::unordered_map<crypto::public_key, crypto::signature> subaddr_spendkeys;
|
}
|
||||||
ar >> proofs >> subaddr_spendkeys;
|
|
||||||
|
|
||||||
THROW_WALLET_EXCEPTION_IF(subaddr_spendkeys.count(address.m_spend_public_key) == 0, error::wallet_internal_error,
|
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");
|
"The given address isn't found in the proof");
|
||||||
|
@ -12021,7 +12140,7 @@ std::string wallet2::get_description() const
|
||||||
return "";
|
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
|
// ensure consistency
|
||||||
if (m_account_tags.second.size() != get_num_subaddress_accounts())
|
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);
|
PERF_TIMER(export_outputs_to_str);
|
||||||
|
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
const auto& outputs = export_outputs(all);
|
auto outputs = export_outputs(all);
|
||||||
ar << outputs;
|
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));
|
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;
|
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;
|
size_t imported_outputs = 0;
|
||||||
|
bool loaded = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::string body(data, headerlen);
|
std::string body(data, headerlen);
|
||||||
std::stringstream iss;
|
|
||||||
iss << body;
|
|
||||||
std::pair<size_t, std::vector<tools::wallet2::transfer_details>> outputs;
|
std::pair<size_t, std::vector<tools::wallet2::transfer_details>> outputs;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
std::stringstream iss;
|
||||||
|
iss << body;
|
||||||
|
binary_archive<false> ar(iss);
|
||||||
|
if (::serialization::serialize(ar, outputs))
|
||||||
|
if (::serialization::check_stream_state(ar))
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
|
||||||
|
if (!loaded && m_load_deprecated_formats)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::stringstream iss;
|
||||||
|
iss << body;
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
ar >> outputs;
|
ar >> outputs;
|
||||||
|
loaded = true;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loaded)
|
||||||
{
|
{
|
||||||
iss.str("");
|
outputs.first = 0;
|
||||||
iss << body;
|
outputs.second = {};
|
||||||
boost::archive::binary_iarchive ar(iss);
|
|
||||||
ar >> outputs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imported_outputs = import_outputs(outputs);
|
imported_outputs = import_outputs(outputs);
|
||||||
|
@ -13027,8 +13162,8 @@ cryptonote::blobdata wallet2::export_multisig()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
ar << info;
|
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;
|
const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address;
|
||||||
std::string header;
|
std::string header;
|
||||||
|
@ -13098,10 +13233,26 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs)
|
||||||
seen.insert(signer);
|
seen.insert(signer);
|
||||||
|
|
||||||
std::string body(data, headerlen);
|
std::string body(data, headerlen);
|
||||||
std::istringstream iss(body);
|
|
||||||
std::vector<tools::wallet2::multisig_info> i;
|
std::vector<tools::wallet2::multisig_info> 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);
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
ar >> i;
|
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()));
|
MINFO(boost::format("%u outputs found") % boost::lexical_cast<std::string>(i.size()));
|
||||||
info.push_back(std::move(i));
|
info.push_back(std::move(i));
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,10 @@
|
||||||
#include "ringct/rctTypes.h"
|
#include "ringct/rctTypes.h"
|
||||||
#include "ringct/rctOps.h"
|
#include "ringct/rctOps.h"
|
||||||
#include "checkpoints/checkpoints.h"
|
#include "checkpoints/checkpoints.h"
|
||||||
|
#include "serialization/crypto.h"
|
||||||
|
#include "serialization/string.h"
|
||||||
#include "serialization/pair.h"
|
#include "serialization/pair.h"
|
||||||
|
#include "serialization/containers.h"
|
||||||
|
|
||||||
#include "wallet_errors.h"
|
#include "wallet_errors.h"
|
||||||
#include "common/password.h"
|
#include "common/password.h"
|
||||||
|
@ -205,6 +208,13 @@ private:
|
||||||
a & m_blockchain;
|
a & m_blockchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
VARINT_FIELD(m_offset)
|
||||||
|
FIELD(m_genesis)
|
||||||
|
FIELD(m_blockchain)
|
||||||
|
END_SERIALIZE()
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t m_offset;
|
size_t m_offset;
|
||||||
crypto::hash m_genesis;
|
crypto::hash m_genesis;
|
||||||
|
@ -381,6 +391,19 @@ private:
|
||||||
uint64_t m_timestamp;
|
uint64_t m_timestamp;
|
||||||
bool m_coinbase;
|
bool m_coinbase;
|
||||||
cryptonote::subaddress_index m_subaddr_index;
|
cryptonote::subaddress_index m_subaddr_index;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(m_tx_hash)
|
||||||
|
VARINT_FIELD(m_amount)
|
||||||
|
FIELD(m_amounts)
|
||||||
|
VARINT_FIELD(m_fee)
|
||||||
|
VARINT_FIELD(m_block_height)
|
||||||
|
VARINT_FIELD(m_unlock_time)
|
||||||
|
VARINT_FIELD(m_timestamp)
|
||||||
|
FIELD(m_coinbase)
|
||||||
|
FIELD(m_subaddr_index)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct address_tx : payment_details
|
struct address_tx : payment_details
|
||||||
|
@ -393,6 +416,12 @@ private:
|
||||||
{
|
{
|
||||||
payment_details m_pd;
|
payment_details m_pd;
|
||||||
bool m_double_spend_seen;
|
bool m_double_spend_seen;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(m_pd)
|
||||||
|
FIELD(m_double_spend_seen)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct unconfirmed_transfer_details
|
struct unconfirmed_transfer_details
|
||||||
|
@ -409,6 +438,21 @@ private:
|
||||||
uint32_t m_subaddr_account; // subaddress account of your wallet to be used in this transfer
|
uint32_t m_subaddr_account; // subaddress account of your wallet to be used in this transfer
|
||||||
std::set<uint32_t> m_subaddr_indices; // set of address indices used as inputs in this transfer
|
std::set<uint32_t> m_subaddr_indices; // set of address indices used as inputs in this transfer
|
||||||
std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> m_rings; // relative
|
std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> m_rings; // relative
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(m_tx)
|
||||||
|
VARINT_FIELD(m_amount_in)
|
||||||
|
VARINT_FIELD(m_amount_out)
|
||||||
|
VARINT_FIELD(m_change)
|
||||||
|
VARINT_FIELD(m_sent_time)
|
||||||
|
FIELD(m_dests)
|
||||||
|
FIELD(m_payment_id)
|
||||||
|
VARINT_FIELD(m_timestamp)
|
||||||
|
VARINT_FIELD(m_subaddr_account)
|
||||||
|
FIELD(m_subaddr_indices)
|
||||||
|
FIELD(m_rings)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct confirmed_transfer_details
|
struct confirmed_transfer_details
|
||||||
|
@ -428,6 +472,21 @@ private:
|
||||||
confirmed_transfer_details(): m_amount_in(0), m_amount_out(0), m_change((uint64_t)-1), m_block_height(0), m_payment_id(crypto::null_hash), m_timestamp(0), m_unlock_time(0), m_subaddr_account((uint32_t)-1) {}
|
confirmed_transfer_details(): m_amount_in(0), m_amount_out(0), m_change((uint64_t)-1), m_block_height(0), m_payment_id(crypto::null_hash), m_timestamp(0), m_unlock_time(0), m_subaddr_account((uint32_t)-1) {}
|
||||||
confirmed_transfer_details(const unconfirmed_transfer_details &utd, uint64_t height):
|
confirmed_transfer_details(const unconfirmed_transfer_details &utd, uint64_t height):
|
||||||
m_amount_in(utd.m_amount_in), m_amount_out(utd.m_amount_out), m_change(utd.m_change), m_block_height(height), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id), m_timestamp(utd.m_timestamp), m_unlock_time(utd.m_tx.unlock_time), m_subaddr_account(utd.m_subaddr_account), m_subaddr_indices(utd.m_subaddr_indices), m_rings(utd.m_rings) {}
|
m_amount_in(utd.m_amount_in), m_amount_out(utd.m_amount_out), m_change(utd.m_change), m_block_height(height), m_dests(utd.m_dests), m_payment_id(utd.m_payment_id), m_timestamp(utd.m_timestamp), m_unlock_time(utd.m_tx.unlock_time), m_subaddr_account(utd.m_subaddr_account), m_subaddr_indices(utd.m_subaddr_indices), m_rings(utd.m_rings) {}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
VARINT_FIELD(m_amount_in)
|
||||||
|
VARINT_FIELD(m_amount_out)
|
||||||
|
VARINT_FIELD(m_change)
|
||||||
|
VARINT_FIELD(m_block_height)
|
||||||
|
FIELD(m_dests)
|
||||||
|
FIELD(m_payment_id)
|
||||||
|
VARINT_FIELD(m_timestamp)
|
||||||
|
VARINT_FIELD(m_unlock_time)
|
||||||
|
VARINT_FIELD(m_subaddr_account)
|
||||||
|
FIELD(m_subaddr_indices)
|
||||||
|
FIELD(m_rings)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tx_construction_data
|
struct tx_construction_data
|
||||||
|
@ -460,7 +519,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<transfer_details> transfer_container;
|
typedef std::vector<transfer_details> transfer_container;
|
||||||
typedef std::unordered_multimap<crypto::hash, payment_details> payment_container;
|
typedef serializable_unordered_multimap<crypto::hash, payment_details> payment_container;
|
||||||
|
|
||||||
struct multisig_sig
|
struct multisig_sig
|
||||||
{
|
{
|
||||||
|
@ -469,6 +528,15 @@ private:
|
||||||
std::unordered_set<rct::key> used_L;
|
std::unordered_set<rct::key> used_L;
|
||||||
std::unordered_set<crypto::public_key> signing_keys;
|
std::unordered_set<crypto::public_key> signing_keys;
|
||||||
rct::multisig_out msout;
|
rct::multisig_out msout;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(sigs)
|
||||||
|
FIELD(ignore)
|
||||||
|
FIELD(used_L)
|
||||||
|
FIELD(signing_keys)
|
||||||
|
FIELD(msout)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
// The convention for destinations is:
|
// The convention for destinations is:
|
||||||
|
@ -511,13 +579,26 @@ private:
|
||||||
{
|
{
|
||||||
std::vector<tx_construction_data> txes;
|
std::vector<tx_construction_data> txes;
|
||||||
std::pair<size_t, wallet2::transfer_container> transfers;
|
std::pair<size_t, wallet2::transfer_container> transfers;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(txes)
|
||||||
|
FIELD(transfers)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct signed_tx_set
|
struct signed_tx_set
|
||||||
{
|
{
|
||||||
std::vector<pending_tx> ptx;
|
std::vector<pending_tx> ptx;
|
||||||
std::vector<crypto::key_image> key_images;
|
std::vector<crypto::key_image> key_images;
|
||||||
std::unordered_map<crypto::public_key, crypto::key_image> tx_key_images;
|
serializable_unordered_map<crypto::public_key, crypto::key_image> tx_key_images;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(ptx)
|
||||||
|
FIELD(key_images)
|
||||||
|
FIELD(tx_key_images)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct multisig_tx_set
|
struct multisig_tx_set
|
||||||
|
@ -561,6 +642,15 @@ private:
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
bool m_is_subaddress;
|
bool m_is_subaddress;
|
||||||
bool m_has_payment_id;
|
bool m_has_payment_id;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(m_address)
|
||||||
|
FIELD(m_payment_id)
|
||||||
|
FIELD(m_description)
|
||||||
|
FIELD(m_is_subaddress)
|
||||||
|
FIELD(m_has_payment_id)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
struct reserve_proof_entry
|
struct reserve_proof_entry
|
||||||
|
@ -571,6 +661,16 @@ private:
|
||||||
crypto::key_image key_image;
|
crypto::key_image key_image;
|
||||||
crypto::signature shared_secret_sig;
|
crypto::signature shared_secret_sig;
|
||||||
crypto::signature key_image_sig;
|
crypto::signature key_image_sig;
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(txid)
|
||||||
|
VARINT_FIELD(index_in_tx)
|
||||||
|
FIELD(shared_secret)
|
||||||
|
FIELD(key_image)
|
||||||
|
FIELD(shared_secret_sig)
|
||||||
|
FIELD(key_image_sig)
|
||||||
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::tuple<uint64_t, crypto::public_key, rct::key> get_outs_entry;
|
typedef std::tuple<uint64_t, crypto::public_key, rct::key> get_outs_entry;
|
||||||
|
@ -927,6 +1027,7 @@ private:
|
||||||
{
|
{
|
||||||
std::vector<crypto::hash> blockchain;
|
std::vector<crypto::hash> blockchain;
|
||||||
a & blockchain;
|
a & blockchain;
|
||||||
|
m_blockchain.clear();
|
||||||
for (const auto &b: blockchain)
|
for (const auto &b: blockchain)
|
||||||
{
|
{
|
||||||
m_blockchain.push_back(b);
|
m_blockchain.push_back(b);
|
||||||
|
@ -938,25 +1039,25 @@ private:
|
||||||
}
|
}
|
||||||
a & m_transfers;
|
a & m_transfers;
|
||||||
a & m_account_public_address;
|
a & m_account_public_address;
|
||||||
a & m_key_images;
|
a & m_key_images.parent();
|
||||||
if(ver < 6)
|
if(ver < 6)
|
||||||
return;
|
return;
|
||||||
a & m_unconfirmed_txs;
|
a & m_unconfirmed_txs.parent();
|
||||||
if(ver < 7)
|
if(ver < 7)
|
||||||
return;
|
return;
|
||||||
a & m_payments;
|
a & m_payments.parent();
|
||||||
if(ver < 8)
|
if(ver < 8)
|
||||||
return;
|
return;
|
||||||
a & m_tx_keys;
|
a & m_tx_keys.parent();
|
||||||
if(ver < 9)
|
if(ver < 9)
|
||||||
return;
|
return;
|
||||||
a & m_confirmed_txs;
|
a & m_confirmed_txs.parent();
|
||||||
if(ver < 11)
|
if(ver < 11)
|
||||||
return;
|
return;
|
||||||
a & dummy_refresh_height;
|
a & dummy_refresh_height;
|
||||||
if(ver < 12)
|
if(ver < 12)
|
||||||
return;
|
return;
|
||||||
a & m_tx_notes;
|
a & m_tx_notes.parent();
|
||||||
if(ver < 13)
|
if(ver < 13)
|
||||||
return;
|
return;
|
||||||
if (ver < 17)
|
if (ver < 17)
|
||||||
|
@ -964,6 +1065,7 @@ private:
|
||||||
// we're loading an old version, where m_unconfirmed_payments was a std::map
|
// we're loading an old version, where m_unconfirmed_payments was a std::map
|
||||||
std::unordered_map<crypto::hash, payment_details> m;
|
std::unordered_map<crypto::hash, payment_details> m;
|
||||||
a & m;
|
a & m;
|
||||||
|
m_unconfirmed_payments.clear();
|
||||||
for (std::unordered_map<crypto::hash, payment_details>::const_iterator i = m.begin(); i != m.end(); ++i)
|
for (std::unordered_map<crypto::hash, payment_details>::const_iterator i = m.begin(); i != m.end(); ++i)
|
||||||
m_unconfirmed_payments.insert(std::make_pair(i->first, pool_payment_details{i->second, false}));
|
m_unconfirmed_payments.insert(std::make_pair(i->first, pool_payment_details{i->second, false}));
|
||||||
}
|
}
|
||||||
|
@ -972,6 +1074,7 @@ private:
|
||||||
if(ver < 15)
|
if(ver < 15)
|
||||||
{
|
{
|
||||||
// we're loading an older wallet without a pubkey map, rebuild it
|
// we're loading an older wallet without a pubkey map, rebuild it
|
||||||
|
m_pub_keys.clear();
|
||||||
for (size_t i = 0; i < m_transfers.size(); ++i)
|
for (size_t i = 0; i < m_transfers.size(); ++i)
|
||||||
{
|
{
|
||||||
const transfer_details &td = m_transfers[i];
|
const transfer_details &td = m_transfers[i];
|
||||||
|
@ -981,7 +1084,7 @@ private:
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
a & m_pub_keys;
|
a & m_pub_keys.parent();
|
||||||
if(ver < 16)
|
if(ver < 16)
|
||||||
return;
|
return;
|
||||||
a & m_address_book;
|
a & m_address_book;
|
||||||
|
@ -992,6 +1095,7 @@ private:
|
||||||
// we're loading an old version, where m_unconfirmed_payments payload was payment_details
|
// we're loading an old version, where m_unconfirmed_payments payload was payment_details
|
||||||
std::unordered_multimap<crypto::hash, payment_details> m;
|
std::unordered_multimap<crypto::hash, payment_details> m;
|
||||||
a & m;
|
a & m;
|
||||||
|
m_unconfirmed_payments.clear();
|
||||||
for (const auto &i: m)
|
for (const auto &i: m)
|
||||||
m_unconfirmed_payments.insert(std::make_pair(i.first, pool_payment_details{i.second, false}));
|
m_unconfirmed_payments.insert(std::make_pair(i.first, pool_payment_details{i.second, false}));
|
||||||
}
|
}
|
||||||
|
@ -1001,20 +1105,20 @@ private:
|
||||||
a & m_scanned_pool_txs[1];
|
a & m_scanned_pool_txs[1];
|
||||||
if (ver < 20)
|
if (ver < 20)
|
||||||
return;
|
return;
|
||||||
a & m_subaddresses;
|
a & m_subaddresses.parent();
|
||||||
std::unordered_map<cryptonote::subaddress_index, crypto::public_key> dummy_subaddresses_inv;
|
std::unordered_map<cryptonote::subaddress_index, crypto::public_key> dummy_subaddresses_inv;
|
||||||
a & dummy_subaddresses_inv;
|
a & dummy_subaddresses_inv;
|
||||||
a & m_subaddress_labels;
|
a & m_subaddress_labels;
|
||||||
a & m_additional_tx_keys;
|
a & m_additional_tx_keys.parent();
|
||||||
if(ver < 21)
|
if(ver < 21)
|
||||||
return;
|
return;
|
||||||
a & m_attributes;
|
a & m_attributes.parent();
|
||||||
if(ver < 22)
|
if(ver < 22)
|
||||||
return;
|
return;
|
||||||
a & m_unconfirmed_payments;
|
a & m_unconfirmed_payments.parent();
|
||||||
if(ver < 23)
|
if(ver < 23)
|
||||||
return;
|
return;
|
||||||
a & m_account_tags;
|
a & (std::pair<std::map<std::string, std::string>, std::vector<std::string>>&)m_account_tags;
|
||||||
if(ver < 24)
|
if(ver < 24)
|
||||||
return;
|
return;
|
||||||
a & m_ring_history_saved;
|
a & m_ring_history_saved;
|
||||||
|
@ -1023,18 +1127,48 @@ private:
|
||||||
a & m_last_block_reward;
|
a & m_last_block_reward;
|
||||||
if(ver < 26)
|
if(ver < 26)
|
||||||
return;
|
return;
|
||||||
a & m_tx_device;
|
a & m_tx_device.parent();
|
||||||
if(ver < 27)
|
if(ver < 27)
|
||||||
return;
|
return;
|
||||||
a & m_device_last_key_image_sync;
|
a & m_device_last_key_image_sync;
|
||||||
if(ver < 28)
|
if(ver < 28)
|
||||||
return;
|
return;
|
||||||
a & m_cold_key_images;
|
a & m_cold_key_images.parent();
|
||||||
if(ver < 29)
|
if(ver < 29)
|
||||||
return;
|
return;
|
||||||
a & m_rpc_client_secret_key;
|
a & m_rpc_client_secret_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
MAGIC_FIELD("monero wallet cache")
|
||||||
|
VERSION_FIELD(0)
|
||||||
|
FIELD(m_blockchain)
|
||||||
|
FIELD(m_transfers)
|
||||||
|
FIELD(m_account_public_address)
|
||||||
|
FIELD(m_key_images)
|
||||||
|
FIELD(m_unconfirmed_txs)
|
||||||
|
FIELD(m_payments)
|
||||||
|
FIELD(m_tx_keys)
|
||||||
|
FIELD(m_confirmed_txs)
|
||||||
|
FIELD(m_tx_notes)
|
||||||
|
FIELD(m_unconfirmed_payments)
|
||||||
|
FIELD(m_pub_keys)
|
||||||
|
FIELD(m_address_book)
|
||||||
|
FIELD(m_scanned_pool_txs[0])
|
||||||
|
FIELD(m_scanned_pool_txs[1])
|
||||||
|
FIELD(m_subaddresses)
|
||||||
|
FIELD(m_subaddress_labels)
|
||||||
|
FIELD(m_additional_tx_keys)
|
||||||
|
FIELD(m_attributes)
|
||||||
|
FIELD(m_account_tags)
|
||||||
|
FIELD(m_ring_history_saved)
|
||||||
|
FIELD(m_last_block_reward)
|
||||||
|
FIELD(m_tx_device)
|
||||||
|
FIELD(m_device_last_key_image_sync)
|
||||||
|
FIELD(m_cold_key_images)
|
||||||
|
FIELD(m_rpc_client_secret_key)
|
||||||
|
END_SERIALIZE()
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Check if wallet keys and bin files exist
|
* \brief Check if wallet keys and bin files exist
|
||||||
* \param file_path Wallet file path
|
* \param file_path Wallet file path
|
||||||
|
@ -1106,6 +1240,8 @@ private:
|
||||||
void device_derivation_path(const std::string &device_derivation_path) { m_device_derivation_path = device_derivation_path; }
|
void device_derivation_path(const std::string &device_derivation_path) { m_device_derivation_path = device_derivation_path; }
|
||||||
const ExportFormat & export_format() const { return m_export_format; }
|
const ExportFormat & export_format() const { return m_export_format; }
|
||||||
inline void set_export_format(const ExportFormat& export_format) { m_export_format = export_format; }
|
inline void set_export_format(const ExportFormat& export_format) { m_export_format = export_format; }
|
||||||
|
bool load_deprecated_formats() const { return m_load_deprecated_formats; }
|
||||||
|
void load_deprecated_formats(bool load) { m_load_deprecated_formats = load; }
|
||||||
bool persistent_rpc_client_id() const { return m_persistent_rpc_client_id; }
|
bool persistent_rpc_client_id() const { return m_persistent_rpc_client_id; }
|
||||||
void persistent_rpc_client_id(bool persistent) { m_persistent_rpc_client_id = persistent; }
|
void persistent_rpc_client_id(bool persistent) { m_persistent_rpc_client_id = persistent; }
|
||||||
void auto_mine_for_rpc_payment_threshold(float threshold) { m_auto_mine_for_rpc_payment_threshold = threshold; }
|
void auto_mine_for_rpc_payment_threshold(float threshold) { m_auto_mine_for_rpc_payment_threshold = threshold; }
|
||||||
|
@ -1197,7 +1333,7 @@ private:
|
||||||
* \brief Get the list of registered account tags.
|
* \brief Get the list of registered account tags.
|
||||||
* \return first.Key=(tag's name), first.Value=(tag's label), second[i]=(i-th account's tag)
|
* \return first.Key=(tag's name), first.Value=(tag's label), second[i]=(i-th account's tag)
|
||||||
*/
|
*/
|
||||||
const std::pair<std::map<std::string, std::string>, std::vector<std::string>>& get_account_tags();
|
const std::pair<serializable_map<std::string, std::string>, std::vector<std::string>>& get_account_tags();
|
||||||
/*!
|
/*!
|
||||||
* \brief Set a tag to the given accounts.
|
* \brief Set a tag to the given accounts.
|
||||||
* \param account_indices Indices of accounts.
|
* \param account_indices Indices of accounts.
|
||||||
|
@ -1539,28 +1675,28 @@ private:
|
||||||
std::string m_mms_file;
|
std::string m_mms_file;
|
||||||
const std::unique_ptr<epee::net_utils::http::abstract_http_client> m_http_client;
|
const std::unique_ptr<epee::net_utils::http::abstract_http_client> m_http_client;
|
||||||
hashchain m_blockchain;
|
hashchain m_blockchain;
|
||||||
std::unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs;
|
serializable_unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs;
|
||||||
std::unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs;
|
serializable_unordered_map<crypto::hash, confirmed_transfer_details> m_confirmed_txs;
|
||||||
std::unordered_multimap<crypto::hash, pool_payment_details> m_unconfirmed_payments;
|
serializable_unordered_multimap<crypto::hash, pool_payment_details> m_unconfirmed_payments;
|
||||||
std::unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
|
serializable_unordered_map<crypto::hash, crypto::secret_key> m_tx_keys;
|
||||||
cryptonote::checkpoints m_checkpoints;
|
cryptonote::checkpoints m_checkpoints;
|
||||||
std::unordered_map<crypto::hash, std::vector<crypto::secret_key>> m_additional_tx_keys;
|
serializable_unordered_map<crypto::hash, std::vector<crypto::secret_key>> m_additional_tx_keys;
|
||||||
|
|
||||||
transfer_container m_transfers;
|
transfer_container m_transfers;
|
||||||
payment_container m_payments;
|
payment_container m_payments;
|
||||||
std::unordered_map<crypto::key_image, size_t> m_key_images;
|
serializable_unordered_map<crypto::key_image, size_t> m_key_images;
|
||||||
std::unordered_map<crypto::public_key, size_t> m_pub_keys;
|
serializable_unordered_map<crypto::public_key, size_t> m_pub_keys;
|
||||||
cryptonote::account_public_address m_account_public_address;
|
cryptonote::account_public_address m_account_public_address;
|
||||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> m_subaddresses;
|
serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index> m_subaddresses;
|
||||||
std::vector<std::vector<std::string>> m_subaddress_labels;
|
std::vector<std::vector<std::string>> m_subaddress_labels;
|
||||||
std::unordered_map<crypto::hash, std::string> m_tx_notes;
|
serializable_unordered_map<crypto::hash, std::string> m_tx_notes;
|
||||||
std::unordered_map<std::string, std::string> m_attributes;
|
serializable_unordered_map<std::string, std::string> m_attributes;
|
||||||
std::vector<tools::wallet2::address_book_row> m_address_book;
|
std::vector<tools::wallet2::address_book_row> m_address_book;
|
||||||
std::pair<std::map<std::string, std::string>, std::vector<std::string>> m_account_tags;
|
std::pair<serializable_map<std::string, std::string>, std::vector<std::string>> m_account_tags;
|
||||||
uint64_t m_upper_transaction_weight_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value
|
uint64_t m_upper_transaction_weight_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value
|
||||||
const std::vector<std::vector<tools::wallet2::multisig_info>> *m_multisig_rescan_info;
|
const std::vector<std::vector<tools::wallet2::multisig_info>> *m_multisig_rescan_info;
|
||||||
const std::vector<std::vector<rct::key>> *m_multisig_rescan_k;
|
const std::vector<std::vector<rct::key>> *m_multisig_rescan_k;
|
||||||
std::unordered_map<crypto::public_key, crypto::key_image> m_cold_key_images;
|
serializable_unordered_map<crypto::public_key, crypto::key_image> m_cold_key_images;
|
||||||
|
|
||||||
std::atomic<bool> m_run;
|
std::atomic<bool> m_run;
|
||||||
|
|
||||||
|
@ -1627,7 +1763,7 @@ private:
|
||||||
uint64_t m_credits_target;
|
uint64_t m_credits_target;
|
||||||
|
|
||||||
// Aux transaction data from device
|
// Aux transaction data from device
|
||||||
std::unordered_map<crypto::hash, std::string> m_tx_device;
|
serializable_unordered_map<crypto::hash, std::string> m_tx_device;
|
||||||
|
|
||||||
// Light wallet
|
// Light wallet
|
||||||
bool m_light_wallet; /* sends view key to daemon for scanning */
|
bool m_light_wallet; /* sends view key to daemon for scanning */
|
||||||
|
@ -1641,7 +1777,7 @@ private:
|
||||||
// We save the info from the first call in m_light_wallet_address_txs for easier lookup.
|
// We save the info from the first call in m_light_wallet_address_txs for easier lookup.
|
||||||
std::unordered_map<crypto::hash, address_tx> m_light_wallet_address_txs;
|
std::unordered_map<crypto::hash, address_tx> m_light_wallet_address_txs;
|
||||||
// store calculated key image for faster lookup
|
// store calculated key image for faster lookup
|
||||||
std::unordered_map<crypto::public_key, std::map<uint64_t, crypto::key_image> > m_key_image_cache;
|
serializable_unordered_map<crypto::public_key, serializable_map<uint64_t, crypto::key_image> > m_key_image_cache;
|
||||||
|
|
||||||
std::string m_ring_database;
|
std::string m_ring_database;
|
||||||
bool m_ring_history_saved;
|
bool m_ring_history_saved;
|
||||||
|
@ -1668,6 +1804,7 @@ private:
|
||||||
std::unique_ptr<wallet_device_callback> m_device_callback;
|
std::unique_ptr<wallet_device_callback> m_device_callback;
|
||||||
|
|
||||||
ExportFormat m_export_format;
|
ExportFormat m_export_format;
|
||||||
|
bool m_load_deprecated_formats;
|
||||||
|
|
||||||
static boost::mutex default_daemon_address_lock;
|
static boost::mutex default_daemon_address_lock;
|
||||||
static std::string default_daemon_address;
|
static std::string default_daemon_address;
|
||||||
|
@ -2064,7 +2201,7 @@ namespace boost
|
||||||
a & x.key_images;
|
a & x.key_images;
|
||||||
if (ver < 1)
|
if (ver < 1)
|
||||||
return;
|
return;
|
||||||
a & x.tx_key_images;
|
a & x.tx_key_images.parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
|
|
|
@ -838,10 +838,11 @@ namespace tools
|
||||||
static std::string ptx_to_string(const tools::wallet2::pending_tx &ptx)
|
static std::string ptx_to_string(const tools::wallet2::pending_tx &ptx)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
boost::archive::portable_binary_oarchive ar(oss);
|
binary_archive<true> ar(oss);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ar << ptx;
|
if (!::serialization::serialize(ar, const_cast<tools::wallet2::pending_tx&>(ptx)))
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -1550,14 +1551,31 @@ namespace tools
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool loaded = false;
|
||||||
tools::wallet2::pending_tx ptx;
|
tools::wallet2::pending_tx ptx;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::istringstream iss(blob);
|
||||||
|
binary_archive<false> ar(iss);
|
||||||
|
if (::serialization::serialize(ar, ptx))
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
catch(...) {}
|
||||||
|
|
||||||
|
if (!loaded && !m_restricted)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::istringstream iss(blob);
|
std::istringstream iss(blob);
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
ar >> ptx;
|
ar >> ptx;
|
||||||
|
loaded = true;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loaded)
|
||||||
{
|
{
|
||||||
er.code = WALLET_RPC_ERROR_CODE_BAD_TX_METADATA;
|
er.code = WALLET_RPC_ERROR_CODE_BAD_TX_METADATA;
|
||||||
er.message = "Failed to parse tx metadata.";
|
er.message = "Failed to parse tx metadata.";
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
// advance which version they will stop working with
|
// advance which version they will stop working with
|
||||||
// Don't go over 32767 for any of these
|
// Don't go over 32767 for any of these
|
||||||
#define WALLET_RPC_VERSION_MAJOR 1
|
#define WALLET_RPC_VERSION_MAJOR 1
|
||||||
#define WALLET_RPC_VERSION_MINOR 18
|
#define WALLET_RPC_VERSION_MINOR 19
|
||||||
#define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
#define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
||||||
#define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR)
|
#define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR)
|
||||||
namespace tools
|
namespace tools
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <boost/archive/binary_oarchive.hpp>
|
|
||||||
#include <boost/archive/binary_iarchive.hpp>
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/serialization/vector.hpp>
|
#include <boost/serialization/vector.hpp>
|
||||||
|
|
Binary file not shown.
Binary file not shown.
BIN
tests/data/fuzz/cold-outputs/out-all-6
Normal file
BIN
tests/data/fuzz/cold-outputs/out-all-6
Normal file
Binary file not shown.
BIN
tests/data/fuzz/cold-outputs/out-none-6
Normal file
BIN
tests/data/fuzz/cold-outputs/out-none-6
Normal file
Binary file not shown.
Binary file not shown.
|
@ -40,7 +40,7 @@ BEGIN_INIT_SIMPLE_FUZZER()
|
||||||
static tools::wallet2 local_wallet;
|
static tools::wallet2 local_wallet;
|
||||||
wallet = &local_wallet;
|
wallet = &local_wallet;
|
||||||
|
|
||||||
static const char * const spendkey_hex = "0b4f47697ec99c3de6579304e5f25c68b07afbe55b71d99620bf6cbf4e45a80f";
|
static const char * const spendkey_hex = "f285d4ac9e66271256fc7cde0d3d6b36f66efff6ccd766706c408e86f4997a0d";
|
||||||
crypto::secret_key spendkey;
|
crypto::secret_key spendkey;
|
||||||
epee::string_tools::hex_to_pod(spendkey_hex, spendkey);
|
epee::string_tools::hex_to_pod(spendkey_hex, spendkey);
|
||||||
|
|
||||||
|
@ -50,12 +50,12 @@ BEGIN_INIT_SIMPLE_FUZZER()
|
||||||
END_INIT_SIMPLE_FUZZER()
|
END_INIT_SIMPLE_FUZZER()
|
||||||
|
|
||||||
BEGIN_SIMPLE_FUZZER()
|
BEGIN_SIMPLE_FUZZER()
|
||||||
std::string s = std::string("\x01\x16serialization::archive") + std::string((const char*)buf, len);
|
std::string s((const char*)buf, len);
|
||||||
std::pair<size_t, std::vector<tools::wallet2::transfer_details>> outputs;
|
std::pair<size_t, std::vector<tools::wallet2::transfer_details>> outputs;
|
||||||
std::stringstream iss;
|
std::stringstream iss;
|
||||||
iss << s;
|
iss << s;
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
binary_archive<false> ar(iss);
|
||||||
ar >> outputs;
|
::serialization::serialize(ar, outputs);
|
||||||
size_t n_outputs = wallet->import_outputs(outputs);
|
size_t n_outputs = wallet->import_outputs(outputs);
|
||||||
std::cout << boost::lexical_cast<std::string>(n_outputs) << " outputs imported" << std::endl;
|
std::cout << boost::lexical_cast<std::string>(n_outputs) << " outputs imported" << std::endl;
|
||||||
END_SIMPLE_FUZZER()
|
END_SIMPLE_FUZZER()
|
||||||
|
|
|
@ -40,7 +40,7 @@ BEGIN_INIT_SIMPLE_FUZZER()
|
||||||
static tools::wallet2 local_wallet;
|
static tools::wallet2 local_wallet;
|
||||||
wallet = &local_wallet;
|
wallet = &local_wallet;
|
||||||
|
|
||||||
static const char * const spendkey_hex = "0b4f47697ec99c3de6579304e5f25c68b07afbe55b71d99620bf6cbf4e45a80f";
|
static const char * const spendkey_hex = "f285d4ac9e66271256fc7cde0d3d6b36f66efff6ccd766706c408e86f4997a0d";
|
||||||
crypto::secret_key spendkey;
|
crypto::secret_key spendkey;
|
||||||
epee::string_tools::hex_to_pod(spendkey_hex, spendkey);
|
epee::string_tools::hex_to_pod(spendkey_hex, spendkey);
|
||||||
|
|
||||||
|
@ -50,12 +50,12 @@ BEGIN_INIT_SIMPLE_FUZZER()
|
||||||
END_INIT_SIMPLE_FUZZER()
|
END_INIT_SIMPLE_FUZZER()
|
||||||
|
|
||||||
BEGIN_SIMPLE_FUZZER()
|
BEGIN_SIMPLE_FUZZER()
|
||||||
std::string s = std::string("\x01\x16serialization::archive") + std::string((const char*)buf, len);
|
std::string s((const char*)buf, len);
|
||||||
tools::wallet2::unsigned_tx_set exported_txs;
|
tools::wallet2::unsigned_tx_set exported_txs;
|
||||||
std::stringstream iss;
|
std::stringstream iss;
|
||||||
iss << s;
|
iss << s;
|
||||||
boost::archive::portable_binary_iarchive ar(iss);
|
binary_archive<false> ar(iss);
|
||||||
ar >> exported_txs;
|
::serialization::serialize(ar, exported_txs);
|
||||||
std::vector<tools::wallet2::pending_tx> ptx;
|
std::vector<tools::wallet2::pending_tx> ptx;
|
||||||
bool success = wallet->sign_tx(exported_txs, "/tmp/cold-transaction-test-signed", ptx);
|
bool success = wallet->sign_tx(exported_txs, "/tmp/cold-transaction-test-signed", ptx);
|
||||||
std::cout << (success ? "signed" : "error") << std::endl;
|
std::cout << (success ? "signed" : "error") << std::endl;
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#include "serialization/json_archive.h"
|
#include "serialization/json_archive.h"
|
||||||
#include "serialization/debug_archive.h"
|
#include "serialization/debug_archive.h"
|
||||||
#include "serialization/variant.h"
|
#include "serialization/variant.h"
|
||||||
#include "serialization/vector.h"
|
#include "serialization/containers.h"
|
||||||
#include "serialization/binary_utils.h"
|
#include "serialization/binary_utils.h"
|
||||||
#include "wallet/wallet2.h"
|
#include "wallet/wallet2.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include "serialization/json_archive.h"
|
#include "serialization/json_archive.h"
|
||||||
#include "serialization/debug_archive.h"
|
#include "serialization/debug_archive.h"
|
||||||
#include "serialization/variant.h"
|
#include "serialization/variant.h"
|
||||||
#include "serialization/vector.h"
|
#include "serialization/containers.h"
|
||||||
#include "serialization/binary_utils.h"
|
#include "serialization/binary_utils.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
Loading…
Reference in a new issue