diff --git a/external/boost/archive/portable_binary_iarchive.hpp b/external/boost/archive/portable_binary_iarchive.hpp index 7149cca0..78d615f2 100644 --- a/external/boost/archive/portable_binary_iarchive.hpp +++ b/external/boost/archive/portable_binary_iarchive.hpp @@ -321,6 +321,8 @@ portable_binary_iarchive::init(unsigned int flags){ boost::archive::library_version_type input_library_version; * this >> input_library_version; + // ignore archive version checking + /* // extra little .t is to get around borland quirk if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version) boost::serialization::throw_exception( @@ -328,6 +330,7 @@ portable_binary_iarchive::init(unsigned int flags){ boost::archive::archive_exception::unsupported_version ) ); + */ #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) this->set_library_version(input_library_version); diff --git a/external/boost/archive/portable_binary_oarchive.hpp b/external/boost/archive/portable_binary_oarchive.hpp index 8fd7090a..cdb4caf0 100644 --- a/external/boost/archive/portable_binary_oarchive.hpp +++ b/external/boost/archive/portable_binary_oarchive.hpp @@ -277,10 +277,14 @@ portable_binary_oarchive::init(unsigned int flags) { boost::archive::BOOST_ARCHIVE_SIGNATURE() ); * this << file_signature; + // ignore archive version checking + const boost::archive::library_version_type v{}; + /* // write library version const boost::archive::library_version_type v( boost::archive::BOOST_ARCHIVE_VERSION() ); + */ * this << v; } save(static_cast(m_flags >> CHAR_BIT)); diff --git a/src/cryptonote_core/cryptonote_format_utils.h b/src/cryptonote_core/cryptonote_format_utils.h index 704b8467..a6610e60 100644 --- a/src/cryptonote_core/cryptonote_format_utils.h +++ b/src/cryptonote_core/cryptonote_format_utils.h @@ -36,7 +36,8 @@ #include "crypto/crypto.h" #include "crypto/hash.h" #include "ringct/rctOps.h" - +#include +#include namespace cryptonote { @@ -62,16 +63,6 @@ namespace cryptonote 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)}))); } - - 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 @@ -261,3 +252,23 @@ namespace cryptonote specific_type& variable_name = boost::get(variant_var); } + +BOOST_CLASS_VERSION(cryptonote::tx_source_entry, 0) + +namespace boost +{ + namespace serialization + { + template + 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; + } + } +} diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 221dd8e0..52d9e594 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -77,8 +77,8 @@ using namespace cryptonote; // arbitrary, used to generate different hashes from the same input #define CHACHA8_KEY_TAIL 0x8c -#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\002" -#define SIGNED_TX_PREFIX "Monero signed tx set\002" +#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\003" +#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_ZONE (5 * 86400) // last 5 days are the recent zone @@ -3018,14 +3018,19 @@ bool wallet2::save_tx(const std::vector& ptx_vector, const std::stri for (auto &tx: ptx_vector) txs.txes.push_back(tx.construction_data); txs.transfers = m_transfers; - std::string s = obj_to_json_str(txs); - if (s.empty()) + // save as binary + std::ostringstream oss; + boost::archive::portable_binary_oarchive ar(oss); + try + { + ar << txs; + } + catch (...) + { return false; - LOG_PRINT_L2("Saving unsigned tx data: " << s); - // save as binary as there's no implementation of loading a json_archive - if (!::serialization::dump_binary(txs, s)) - return false; - return epee::file_io_utils::save_string_to_file(filename, std::string(UNSIGNED_TX_PREFIX) + s); + } + LOG_PRINT_L2("Saving unsigned tx data: " << oss.str()); + return epee::file_io_utils::save_string_to_file(filename, std::string(UNSIGNED_TX_PREFIX) + oss.str()); } //---------------------------------------------------------------------------------------------------- bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector &txs, std::function accept_func) @@ -3050,7 +3055,14 @@ bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &s return false; } 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); 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; } - s = obj_to_json_str(signed_txes); - if (s.empty()) + // save as binary + std::ostringstream oss; + boost::archive::portable_binary_oarchive ar(oss); + try + { + ar << signed_txes; + } + catch(...) + { return false; - LOG_PRINT_L2("Saving signed tx data: " << s); - // save as binary as there's no implementation of loading a json_archive - if (!::serialization::dump_binary(signed_txes, s)) - return false; - return epee::file_io_utils::save_string_to_file(signed_filename, std::string(SIGNED_TX_PREFIX) + s); + } + LOG_PRINT_L2("Saving signed tx data: " << oss.str()); + return epee::file_io_utils::save_string_to_file(signed_filename, std::string(SIGNED_TX_PREFIX) + oss.str()); } //---------------------------------------------------------------------------------------------------- bool wallet2::load_tx(const std::string &signed_filename, std::vector &ptx, std::function accept_func) @@ -3156,7 +3173,14 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector> signed_txs; + } + catch (...) { LOG_PRINT_L0("Failed to parse data from " << signed_filename); return false; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 54e26008..e7a6dfad 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -201,17 +201,6 @@ namespace tools uint64_t unlock_time; bool use_rct; std::vector 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_container; @@ -232,39 +221,18 @@ namespace tools std::vector dests; 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 { std::vector txes; wallet2::transfer_container transfers; - BEGIN_SERIALIZE_OBJECT() - FIELD(txes) - FIELD(transfers) - END_SERIALIZE() }; struct signed_tx_set { std::vector ptx; std::vector key_images; - BEGIN_SERIALIZE_OBJECT() - FIELD(ptx) - FIELD(key_images) - END_SERIALIZE() }; 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::confirmed_transfer_details, 3) 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 { @@ -869,6 +841,48 @@ namespace boost a & x.m_payment_id; a & x.m_description; } + + template + inline void serialize(Archive &a, tools::wallet2::unsigned_tx_set &x, const boost::serialization::version_type ver) + { + a & x.txes; + a & x.transfers; + } + + template + 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 + 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 + 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; + } } }