portable serializer: make signerd/unsigned tx portable, ignore archive version checking
This commit is contained in:
parent
dd580d7bc7
commit
f390a0e2dc
5 changed files with 117 additions and 61 deletions
|
@ -321,6 +321,8 @@ portable_binary_iarchive::init(unsigned int flags){
|
||||||
boost::archive::library_version_type input_library_version;
|
boost::archive::library_version_type input_library_version;
|
||||||
* this >> input_library_version;
|
* this >> input_library_version;
|
||||||
|
|
||||||
|
// ignore archive version checking
|
||||||
|
/*
|
||||||
// extra little .t is to get around borland quirk
|
// extra little .t is to get around borland quirk
|
||||||
if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version)
|
if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version)
|
||||||
boost::serialization::throw_exception(
|
boost::serialization::throw_exception(
|
||||||
|
@ -328,6 +330,7 @@ portable_binary_iarchive::init(unsigned int flags){
|
||||||
boost::archive::archive_exception::unsupported_version
|
boost::archive::archive_exception::unsupported_version
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
|
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
|
||||||
this->set_library_version(input_library_version);
|
this->set_library_version(input_library_version);
|
||||||
|
|
|
@ -277,10 +277,14 @@ portable_binary_oarchive::init(unsigned int flags) {
|
||||||
boost::archive::BOOST_ARCHIVE_SIGNATURE()
|
boost::archive::BOOST_ARCHIVE_SIGNATURE()
|
||||||
);
|
);
|
||||||
* this << file_signature;
|
* this << file_signature;
|
||||||
|
// ignore archive version checking
|
||||||
|
const boost::archive::library_version_type v{};
|
||||||
|
/*
|
||||||
// write library version
|
// write library version
|
||||||
const boost::archive::library_version_type v(
|
const boost::archive::library_version_type v(
|
||||||
boost::archive::BOOST_ARCHIVE_VERSION()
|
boost::archive::BOOST_ARCHIVE_VERSION()
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
* this << v;
|
* this << v;
|
||||||
}
|
}
|
||||||
save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
|
save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
|
||||||
|
|
|
@ -36,7 +36,8 @@
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
#include "crypto/hash.h"
|
#include "crypto/hash.h"
|
||||||
#include "ringct/rctOps.h"
|
#include "ringct/rctOps.h"
|
||||||
|
#include <boost/serialization/vector.hpp>
|
||||||
|
#include <boost/serialization/utility.hpp>
|
||||||
|
|
||||||
namespace cryptonote
|
namespace cryptonote
|
||||||
{
|
{
|
||||||
|
@ -62,16 +63,6 @@ namespace cryptonote
|
||||||
rct::key mask; //ringct amount mask
|
rct::key mask; //ringct amount mask
|
||||||
|
|
||||||
void push_output(uint64_t idx, const crypto::public_key &k, uint64_t amount) { outputs.push_back(std::make_pair(idx, rct::ctkey({rct::pk2rct(k), rct::zeroCommit(amount)}))); }
|
void push_output(uint64_t idx, const crypto::public_key &k, uint64_t amount) { outputs.push_back(std::make_pair(idx, rct::ctkey({rct::pk2rct(k), rct::zeroCommit(amount)}))); }
|
||||||
|
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
|
||||||
FIELD(outputs)
|
|
||||||
VARINT_FIELD(real_output)
|
|
||||||
FIELD(real_out_tx_key)
|
|
||||||
VARINT_FIELD(real_output_in_tx_index)
|
|
||||||
VARINT_FIELD(amount)
|
|
||||||
FIELD(rct)
|
|
||||||
FIELD(mask)
|
|
||||||
END_SERIALIZE()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tx_destination_entry
|
struct tx_destination_entry
|
||||||
|
@ -261,3 +252,23 @@ namespace cryptonote
|
||||||
specific_type& variable_name = boost::get<specific_type>(variant_var);
|
specific_type& variable_name = boost::get<specific_type>(variant_var);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_CLASS_VERSION(cryptonote::tx_source_entry, 0)
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace serialization
|
||||||
|
{
|
||||||
|
template <class Archive>
|
||||||
|
inline void serialize(Archive &a, cryptonote::tx_source_entry &x, const boost::serialization::version_type ver)
|
||||||
|
{
|
||||||
|
a & x.outputs;
|
||||||
|
a & x.real_output;
|
||||||
|
a & x.real_out_tx_key;
|
||||||
|
a & x.real_output_in_tx_index;
|
||||||
|
a & x.amount;
|
||||||
|
a & x.rct;
|
||||||
|
a & x.mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -77,8 +77,8 @@ using namespace cryptonote;
|
||||||
// arbitrary, used to generate different hashes from the same input
|
// arbitrary, used to generate different hashes from the same input
|
||||||
#define CHACHA8_KEY_TAIL 0x8c
|
#define CHACHA8_KEY_TAIL 0x8c
|
||||||
|
|
||||||
#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\002"
|
#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\003"
|
||||||
#define SIGNED_TX_PREFIX "Monero signed tx set\002"
|
#define SIGNED_TX_PREFIX "Monero signed tx set\003"
|
||||||
|
|
||||||
#define RECENT_OUTPUT_RATIO (0.25) // 25% of outputs are from the recent zone
|
#define RECENT_OUTPUT_RATIO (0.25) // 25% of outputs are from the recent zone
|
||||||
#define RECENT_OUTPUT_ZONE (5 * 86400) // last 5 days are the recent zone
|
#define RECENT_OUTPUT_ZONE (5 * 86400) // last 5 days are the recent zone
|
||||||
|
@ -3018,14 +3018,19 @@ bool wallet2::save_tx(const std::vector<pending_tx>& ptx_vector, const std::stri
|
||||||
for (auto &tx: ptx_vector)
|
for (auto &tx: ptx_vector)
|
||||||
txs.txes.push_back(tx.construction_data);
|
txs.txes.push_back(tx.construction_data);
|
||||||
txs.transfers = m_transfers;
|
txs.transfers = m_transfers;
|
||||||
std::string s = obj_to_json_str(txs);
|
// save as binary
|
||||||
if (s.empty())
|
std::ostringstream oss;
|
||||||
|
boost::archive::portable_binary_oarchive ar(oss);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ar << txs;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
LOG_PRINT_L2("Saving unsigned tx data: " << s);
|
}
|
||||||
// save as binary as there's no implementation of loading a json_archive
|
LOG_PRINT_L2("Saving unsigned tx data: " << oss.str());
|
||||||
if (!::serialization::dump_binary(txs, s))
|
return epee::file_io_utils::save_string_to_file(filename, std::string(UNSIGNED_TX_PREFIX) + oss.str());
|
||||||
return false;
|
|
||||||
return epee::file_io_utils::save_string_to_file(filename, std::string(UNSIGNED_TX_PREFIX) + s);
|
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector<wallet2::pending_tx> &txs, std::function<bool(const unsigned_tx_set&)> accept_func)
|
bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector<wallet2::pending_tx> &txs, std::function<bool(const unsigned_tx_set&)> accept_func)
|
||||||
|
@ -3050,7 +3055,14 @@ bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &s
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unsigned_tx_set exported_txs;
|
unsigned_tx_set exported_txs;
|
||||||
if (!::serialization::parse_binary(std::string(s.c_str() + magiclen, s.size() - magiclen), exported_txs))
|
s = s.substr(magiclen);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::istringstream iss(s);
|
||||||
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
|
ar >> exported_txs;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Failed to parse data from " << unsigned_filename);
|
LOG_PRINT_L0("Failed to parse data from " << unsigned_filename);
|
||||||
return false;
|
return false;
|
||||||
|
@ -3123,14 +3135,19 @@ bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &s
|
||||||
signed_txes.key_images[i] = m_transfers[i].m_key_image;
|
signed_txes.key_images[i] = m_transfers[i].m_key_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = obj_to_json_str(signed_txes);
|
// save as binary
|
||||||
if (s.empty())
|
std::ostringstream oss;
|
||||||
|
boost::archive::portable_binary_oarchive ar(oss);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ar << signed_txes;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
LOG_PRINT_L2("Saving signed tx data: " << s);
|
}
|
||||||
// save as binary as there's no implementation of loading a json_archive
|
LOG_PRINT_L2("Saving signed tx data: " << oss.str());
|
||||||
if (!::serialization::dump_binary(signed_txes, s))
|
return epee::file_io_utils::save_string_to_file(signed_filename, std::string(SIGNED_TX_PREFIX) + oss.str());
|
||||||
return false;
|
|
||||||
return epee::file_io_utils::save_string_to_file(signed_filename, std::string(SIGNED_TX_PREFIX) + s);
|
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func)
|
bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func)
|
||||||
|
@ -3156,7 +3173,14 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal
|
||||||
LOG_PRINT_L0("Bad magic from " << signed_filename);
|
LOG_PRINT_L0("Bad magic from " << signed_filename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!::serialization::parse_binary(std::string(s.c_str() + magiclen, s.size() - magiclen), signed_txs))
|
s = s.substr(magiclen);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::istringstream iss(s);
|
||||||
|
boost::archive::portable_binary_iarchive ar(iss);
|
||||||
|
ar >> signed_txs;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Failed to parse data from " << signed_filename);
|
LOG_PRINT_L0("Failed to parse data from " << signed_filename);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -201,17 +201,6 @@ namespace tools
|
||||||
uint64_t unlock_time;
|
uint64_t unlock_time;
|
||||||
bool use_rct;
|
bool use_rct;
|
||||||
std::vector<cryptonote::tx_destination_entry> dests; // original setup, does not include change
|
std::vector<cryptonote::tx_destination_entry> dests; // original setup, does not include change
|
||||||
|
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
|
||||||
FIELD(sources)
|
|
||||||
FIELD(change_dts)
|
|
||||||
FIELD(splitted_dsts)
|
|
||||||
FIELD(selected_transfers)
|
|
||||||
FIELD(extra)
|
|
||||||
VARINT_FIELD(unlock_time)
|
|
||||||
FIELD(use_rct)
|
|
||||||
FIELD(dests)
|
|
||||||
END_SERIALIZE()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<transfer_details> transfer_container;
|
typedef std::vector<transfer_details> transfer_container;
|
||||||
|
@ -232,39 +221,18 @@ namespace tools
|
||||||
std::vector<cryptonote::tx_destination_entry> dests;
|
std::vector<cryptonote::tx_destination_entry> dests;
|
||||||
|
|
||||||
tx_construction_data construction_data;
|
tx_construction_data construction_data;
|
||||||
|
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
|
||||||
FIELD(tx)
|
|
||||||
VARINT_FIELD(dust)
|
|
||||||
VARINT_FIELD(fee)
|
|
||||||
FIELD(dust_added_to_fee)
|
|
||||||
FIELD(change_dts)
|
|
||||||
FIELD(selected_transfers)
|
|
||||||
FIELD(key_images)
|
|
||||||
FIELD(tx_key)
|
|
||||||
FIELD(dests)
|
|
||||||
FIELD(construction_data)
|
|
||||||
END_SERIALIZE()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct unsigned_tx_set
|
struct unsigned_tx_set
|
||||||
{
|
{
|
||||||
std::vector<tx_construction_data> txes;
|
std::vector<tx_construction_data> txes;
|
||||||
wallet2::transfer_container transfers;
|
wallet2::transfer_container transfers;
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
|
||||||
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;
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
|
||||||
FIELD(ptx)
|
|
||||||
FIELD(key_images)
|
|
||||||
END_SERIALIZE()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct keys_file_data
|
struct keys_file_data
|
||||||
|
@ -672,6 +640,10 @@ BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 6)
|
BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 6)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 3)
|
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 3)
|
||||||
BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 16)
|
BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 16)
|
||||||
|
BOOST_CLASS_VERSION(tools::wallet2::unsigned_tx_set, 0)
|
||||||
|
BOOST_CLASS_VERSION(tools::wallet2::signed_tx_set, 0)
|
||||||
|
BOOST_CLASS_VERSION(tools::wallet2::tx_construction_data, 0)
|
||||||
|
BOOST_CLASS_VERSION(tools::wallet2::pending_tx, 0)
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
@ -869,6 +841,48 @@ namespace boost
|
||||||
a & x.m_payment_id;
|
a & x.m_payment_id;
|
||||||
a & x.m_description;
|
a & x.m_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
inline void serialize(Archive &a, tools::wallet2::unsigned_tx_set &x, const boost::serialization::version_type ver)
|
||||||
|
{
|
||||||
|
a & x.txes;
|
||||||
|
a & x.transfers;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
inline void serialize(Archive &a, tools::wallet2::signed_tx_set &x, const boost::serialization::version_type ver)
|
||||||
|
{
|
||||||
|
a & x.ptx;
|
||||||
|
a & x.key_images;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
inline void serialize(Archive &a, tools::wallet2::tx_construction_data &x, const boost::serialization::version_type ver)
|
||||||
|
{
|
||||||
|
a & x.sources;
|
||||||
|
a & x.change_dts;
|
||||||
|
a & x.splitted_dsts;
|
||||||
|
a & x.selected_transfers;
|
||||||
|
a & x.extra;
|
||||||
|
a & x.unlock_time;
|
||||||
|
a & x.use_rct;
|
||||||
|
a & x.dests;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
inline void serialize(Archive &a, tools::wallet2::pending_tx &x, const boost::serialization::version_type ver)
|
||||||
|
{
|
||||||
|
a & x.tx;
|
||||||
|
a & x.dust;
|
||||||
|
a & x.fee;
|
||||||
|
a & x.dust_added_to_fee;
|
||||||
|
a & x.change_dts;
|
||||||
|
a & x.selected_transfers;
|
||||||
|
a & x.key_images;
|
||||||
|
a & x.tx_key;
|
||||||
|
a & x.dests;
|
||||||
|
a & x.construction_data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue