From d9fc666db8934f7669133807ea0bec96eef27105 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 7 Aug 2022 14:56:59 +0000 Subject: wallet2: fix missing subaddress indices in "light" exported outputs --- src/wallet/wallet2.cpp | 4 +++- src/wallet/wallet2.h | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 195763949..d87aa0e33 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -13241,7 +13241,7 @@ size_t wallet2::import_outputs(const std::pair m_additional_tx_keys; + uint32_t m_subaddr_index_major; + uint32_t m_subaddr_index_minor; BEGIN_SERIALIZE_OBJECT() - VERSION_FIELD(0) + VERSION_FIELD(1) FIELD(m_pubkey) VARINT_FIELD(m_internal_output_index) VARINT_FIELD(m_global_output_index) @@ -411,6 +413,8 @@ private: FIELD(m_flags.flags) VARINT_FIELD(m_amount) FIELD(m_additional_tx_keys) + VARINT_FIELD(m_subaddr_index_major) + VARINT_FIELD(m_subaddr_index_minor) END_SERIALIZE() }; -- cgit v1.2.3 From 67b6d6ae2cfb5fcf97be096d0f6600c4ed90548f Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 7 Aug 2022 15:00:16 +0000 Subject: wallet2: prevent importing outputs in a hot wallet --- src/wallet/wallet2.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d87aa0e33..aba929855 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -13162,6 +13162,8 @@ size_t wallet2::import_outputs(const std::pair m_transfers.size(), error::wallet_internal_error, "Imported outputs omit more outputs that we know of"); -- cgit v1.2.3 From 692f1d4e3d2567fcfd4b3cb2c702fb4ea8e82d79 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 7 Aug 2022 15:19:32 +0000 Subject: wallet2: do not assume imported outputs must be non empty --- src/wallet/wallet2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index aba929855..9caf43cbb 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6606,7 +6606,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector Date: Mon, 15 Aug 2022 19:50:34 -0700 Subject: wallet2: fixes for export/import output flow - only allow offline wallets to import outputs - don't import empty outputs - export subaddress indexes when exporting outputs --- src/wallet/wallet2.cpp | 8 ++++++-- src/wallet/wallet2.h | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9caf43cbb..536460396 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -6606,7 +6606,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector> wall etd.m_flags.m_key_image_partial = td.m_key_image_partial; etd.m_amount = td.m_amount; etd.m_additional_tx_keys = get_additional_tx_pub_keys_from_extra(td.m_tx); + etd.m_subaddr_index_major = td.m_subaddr_index.major; + etd.m_subaddr_index_minor = td.m_subaddr_index.minor; outs.push_back(etd); } @@ -13162,7 +13164,7 @@ size_t wallet2::import_outputs(const std::pair m_transfers.size(), error::wallet_internal_error, "Imported outputs omit more outputs that we know of"); @@ -13230,6 +13232,8 @@ size_t wallet2::import_outputs(const std::pair m_transfers.size(), error::wallet_internal_error, "Imported outputs omit more outputs that we know of. Try using export_outputs all."); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 6598dea10..06d4e636e 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -406,6 +406,8 @@ private: BEGIN_SERIALIZE_OBJECT() VERSION_FIELD(1) + if (version < 1) + return false; FIELD(m_pubkey) VARINT_FIELD(m_internal_output_index) VARINT_FIELD(m_global_output_index) -- cgit v1.2.3 From c5579ac236962ac71cf39bd1928690fe7e1d1899 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 16 Aug 2022 20:20:38 +0000 Subject: allow exporting outputs in chunks this will make it easier huge wallets to do so without hitting random limits (eg, max string size in node). --- src/device_trezor/device_trezor.cpp | 12 +- src/device_trezor/trezor/protocol.hpp | 4 +- src/serialization/tuple.h | 169 +++++++++++++++++++++++++++ src/simplewallet/simplewallet.cpp | 6 +- src/wallet/api/wallet.cpp | 4 +- src/wallet/wallet2.cpp | 94 ++++++++++----- src/wallet/wallet2.h | 64 +++++++--- src/wallet/wallet_rpc_server.cpp | 2 +- src/wallet/wallet_rpc_server_commands_defs.h | 4 + 9 files changed, 303 insertions(+), 56 deletions(-) create mode 100644 src/serialization/tuple.h (limited to 'src') diff --git a/src/device_trezor/device_trezor.cpp b/src/device_trezor/device_trezor.cpp index 6f7ae9a6b..9065cf0bb 100644 --- a/src/device_trezor/device_trezor.cpp +++ b/src/device_trezor/device_trezor.cpp @@ -511,7 +511,7 @@ namespace trezor { tools::wallet2::signed_tx_set & signed_tx, hw::tx_aux_data & aux_data) { - CHECK_AND_ASSERT_THROW_MES(unsigned_tx.transfers.first == 0, "Unsuported non zero offset"); + CHECK_AND_ASSERT_THROW_MES(std::get<0>(unsigned_tx.transfers) == 0, "Unsuported non zero offset"); TREZOR_AUTO_LOCK_CMD(); require_connected(); @@ -522,7 +522,7 @@ namespace trezor { const size_t num_tx = unsigned_tx.txes.size(); m_num_transations_to_sign = num_tx; signed_tx.key_images.clear(); - signed_tx.key_images.resize(unsigned_tx.transfers.second.size()); + signed_tx.key_images.resize(std::get<2>(unsigned_tx.transfers).size()); for(size_t tx_idx = 0; tx_idx < num_tx; ++tx_idx) { std::shared_ptr signer; @@ -566,8 +566,8 @@ namespace trezor { cpend.key_images = key_images; // KI sync - for(size_t cidx=0, trans_max=unsigned_tx.transfers.second.size(); cidx < trans_max; ++cidx){ - signed_tx.key_images[cidx] = unsigned_tx.transfers.second[cidx].m_key_image; + for(size_t cidx=0, trans_max=std::get<2>(unsigned_tx.transfers).size(); cidx < trans_max; ++cidx){ + signed_tx.key_images[cidx] = std::get<2>(unsigned_tx.transfers)[cidx].m_key_image; } size_t num_sources = cdata.tx_data.sources.size(); @@ -579,9 +579,9 @@ namespace trezor { CHECK_AND_ASSERT_THROW_MES(src_idx < cdata.tx.vin.size(), "Invalid idx_mapped"); size_t idx_map_src = cdata.tx_data.selected_transfers[idx_mapped]; - CHECK_AND_ASSERT_THROW_MES(idx_map_src >= unsigned_tx.transfers.first, "Invalid offset"); + CHECK_AND_ASSERT_THROW_MES(idx_map_src >= std::get<0>(unsigned_tx.transfers), "Invalid offset"); - idx_map_src -= unsigned_tx.transfers.first; + idx_map_src -= std::get<0>(unsigned_tx.transfers); CHECK_AND_ASSERT_THROW_MES(idx_map_src < signed_tx.key_images.size(), "Invalid key image index"); const auto vini = boost::get(cdata.tx.vin[src_idx]); diff --git a/src/device_trezor/trezor/protocol.hpp b/src/device_trezor/trezor/protocol.hpp index 858db1520..aa4b3a305 100644 --- a/src/device_trezor/trezor/protocol.hpp +++ b/src/device_trezor/trezor/protocol.hpp @@ -232,8 +232,8 @@ namespace tx { } const tools::wallet2::transfer_details & get_transfer(size_t idx) const { - CHECK_AND_ASSERT_THROW_MES(idx < m_unsigned_tx->transfers.second.size() + m_unsigned_tx->transfers.first && idx >= m_unsigned_tx->transfers.first, "Invalid transfer index"); - return m_unsigned_tx->transfers.second[idx - m_unsigned_tx->transfers.first]; + CHECK_AND_ASSERT_THROW_MES(idx < std::get<2>(m_unsigned_tx->transfers).size() + std::get<0>(m_unsigned_tx->transfers) && idx >= std::get<0>(m_unsigned_tx->transfers), "Invalid transfer index"); + return std::get<2>(m_unsigned_tx->transfers)[idx - std::get<0>(m_unsigned_tx->transfers)]; } const tools::wallet2::transfer_details & get_source_transfer(size_t idx) const { diff --git a/src/serialization/tuple.h b/src/serialization/tuple.h new file mode 100644 index 000000000..6d98e05b0 --- /dev/null +++ b/src/serialization/tuple.h @@ -0,0 +1,169 @@ +// 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 +#include "serialization.h" + +namespace serialization +{ + namespace detail + { + template + bool serialize_tuple_element(Archive& ar, T& e) + { + return ::do_serialize(ar, e); + } + + template + bool serialize_tuple_element(Archive& ar, uint64_t& e) + { + ar.serialize_varint(e); + return true; + } + } +} + +template