From 0cbf5571d3ccd07c81d33b05dd23b2ac9c777c3b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 16 Aug 2022 20:20:38 +0000 Subject: [PATCH] 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 + tests/data/fuzz/cold-outputs/out-all-6 | Bin 2607 -> 394 bytes tests/functional_tests/cold_signing.py | 54 ++++-- tests/fuzz/cold-outputs.cpp | 2 +- utils/python-rpc/framework/wallet.py | 5 +- 13 files changed, 348 insertions(+), 72 deletions(-) create mode 100644 src/serialization/tuple.h diff --git a/src/device_trezor/device_trezor.cpp b/src/device_trezor/device_trezor.cpp index 58c36f2c9..3f7b10be4 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 fa8355200..7ffadd9aa 100644 --- a/src/device_trezor/trezor/protocol.hpp +++ b/src/device_trezor/trezor/protocol.hpp @@ -230,8 +230,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