From dd47d03cf2b5b3dc59cd99aca247d1025679f83a Mon Sep 17 00:00:00 2001 From: jeffro256 Date: Sat, 3 Feb 2024 21:59:58 -0600 Subject: [PATCH] Enforce Tx unlock_time is Zero by Relay Rule [RELEASE] Related to https://github.com/monero-project/research-lab/issues/78 Added a relay rule that enforces the `unlock_time` field is equal to 0 for non-coinbase transactions. UIs changed: * Removed `locked_transfer` and `locked_sweep_all` commands from `monero-wallet-cli` APIs changed: * Removed `unlock_time` parameters from `wallet2` transfer methods * Wallet RPC transfer endpoints send error codes when requested unlock time is not 0 * Removed `unlock_time` parameters from `construct_tx*` cryptonote core functions @tobtoht: undo rebase changes tx.dsts -> tx_dsts --- src/cryptonote_basic/verification_context.h | 1 + src/cryptonote_core/cryptonote_tx_utils.cpp | 12 +- src/cryptonote_core/cryptonote_tx_utils.h | 6 +- src/cryptonote_core/tx_pool.cpp | 9 ++ src/multisig/multisig_tx_builder_ringct.cpp | 3 +- src/multisig/multisig_tx_builder_ringct.h | 1 - src/rpc/core_rpc_server.cpp | 2 + src/rpc/core_rpc_server_commands_defs.h | 4 +- src/rpc/daemon_handler.cpp | 10 ++ src/simplewallet/simplewallet.cpp | 141 ++---------------- src/simplewallet/simplewallet.h | 6 +- src/wallet/api/wallet.cpp | 4 +- src/wallet/wallet2.cpp | 59 ++++---- src/wallet/wallet2.h | 12 +- src/wallet/wallet_errors.h | 15 +- src/wallet/wallet_rpc_server.cpp | 32 +++- src/wallet/wallet_rpc_server_error_codes.h | 2 + tests/core_tests/block_validation.cpp | 4 +- tests/core_tests/bulletproof_plus.cpp | 2 +- tests/core_tests/bulletproofs.cpp | 2 +- tests/core_tests/chaingen.cpp | 12 +- tests/core_tests/chaingen.h | 2 +- tests/core_tests/double_spend.inl | 2 +- tests/core_tests/integer_overflow.cpp | 4 +- tests/core_tests/multisig.cpp | 4 +- tests/core_tests/rct.cpp | 4 +- tests/core_tests/rct2.cpp | 2 +- tests/core_tests/transaction_tests.cpp | 2 +- tests/core_tests/tx_validation.cpp | 29 +++- tests/core_tests/v2_tests.cpp | 2 +- tests/core_tests/wallet_tools.cpp | 8 +- tests/core_tests/wallet_tools.h | 2 +- .../transactions_flow_test.cpp | 2 +- tests/performance_tests/check_tx_signature.h | 6 +- tests/performance_tests/construct_tx.h | 2 +- .../performance_tests/ge_frombytes_vartime.h | 2 +- tests/performance_tests/ge_tobytes.h | 2 +- tests/unit_tests/json_serialization.cpp | 2 +- 38 files changed, 186 insertions(+), 230 deletions(-) diff --git a/src/cryptonote_basic/verification_context.h b/src/cryptonote_basic/verification_context.h index 10a16a8c1..9b496f0d8 100644 --- a/src/cryptonote_basic/verification_context.h +++ b/src/cryptonote_basic/verification_context.h @@ -59,6 +59,7 @@ namespace cryptonote bool m_fee_too_low; bool m_too_few_outputs; bool m_tx_extra_too_big; + bool m_nonzero_unlock_time; }; struct block_verification_context diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 5058b89a9..dc9d6612f 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -203,7 +203,7 @@ namespace cryptonote return addr.m_view_public_key; } //--------------------------------------------------------------- - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool shuffle_outs, bool use_view_tags) + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool shuffle_outs, bool use_view_tags) { hw::device &hwdev = sender_account_keys.get_device(); @@ -218,7 +218,7 @@ namespace cryptonote amount_keys.clear(); tx.version = rct ? 2 : 1; - tx.unlock_time = unlock_time; + tx.unlock_time = 0; tx.extra = extra; crypto::public_key txkey_pub; @@ -606,7 +606,7 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags) + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags) { hw::device &hwdev = sender_account_keys.get_device(); hwdev.open_tx(tx_key); @@ -627,7 +627,7 @@ namespace cryptonote } bool shuffle_outs = true; - bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags); + bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags); hwdev.close_tx(); return r; } catch(...) { @@ -636,14 +636,14 @@ namespace cryptonote } } //--------------------------------------------------------------- - bool construct_tx(const account_keys& sender_account_keys, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time) + bool construct_tx(const account_keys& sender_account_keys, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx) { std::unordered_map subaddresses; subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0,0}; crypto::secret_key tx_key; std::vector additional_tx_keys; std::vector destinations_copy = destinations; - return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}); + return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}); } //--------------------------------------------------------------- bool generate_genesis_block( diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index 5f301bb89..072ddf75d 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -118,9 +118,9 @@ namespace cryptonote //--------------------------------------------------------------- crypto::public_key get_destination_view_key_pub(const std::vector &destinations, const boost::optional& change_addr); - bool construct_tx(const account_keys& sender_account_keys, std::vector &sources, const std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time); - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false); - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false); + bool construct_tx(const account_keys& sender_account_keys, std::vector &sources, const std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx); + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false); + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map& subaddresses, std::vector& sources, std::vector& destinations, const boost::optional& change_addr, const std::vector &extra, transaction& tx, crypto::secret_key &tx_key, std::vector &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false); bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, const cryptonote::tx_destination_entry &dst_entr, const boost::optional &change_addr, const size_t output_index, const bool &need_additional_txkeys, const std::vector &additional_tx_keys, diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 2a3b7a5d5..0af6cab85 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -236,6 +236,15 @@ namespace cryptonote return false; } + if (!kept_by_block && tx.unlock_time) + { + LOG_PRINT_L1("transaction unlock time is not zero: " << tx.unlock_time); + tvc.m_verifivation_failed = true; + tvc.m_nonzero_unlock_time = true; + tvc.m_no_drop_offense = true; + return false; + } + // if the transaction came from a block popped from the chain, // don't check if we have its key images as spent. // TODO: Investigate why not? diff --git a/src/multisig/multisig_tx_builder_ringct.cpp b/src/multisig/multisig_tx_builder_ringct.cpp index e5c9ac483..33c0396dc 100644 --- a/src/multisig/multisig_tx_builder_ringct.cpp +++ b/src/multisig/multisig_tx_builder_ringct.cpp @@ -820,7 +820,6 @@ tx_builder_ringct_t::~tx_builder_ringct_t() bool tx_builder_ringct_t::init( const cryptonote::account_keys& account_keys, const std::vector& extra, - const std::uint64_t unlock_time, const std::uint32_t subaddr_account, const std::set& subaddr_minor_indices, std::vector& sources, @@ -854,7 +853,7 @@ bool tx_builder_ringct_t::init( // misc. fields unsigned_tx.version = 2; //rct = 2 - unsigned_tx.unlock_time = unlock_time; + unsigned_tx.unlock_time = 0; // sort inputs sort_sources(sources); diff --git a/src/multisig/multisig_tx_builder_ringct.h b/src/multisig/multisig_tx_builder_ringct.h index 853934659..92be95be0 100644 --- a/src/multisig/multisig_tx_builder_ringct.h +++ b/src/multisig/multisig_tx_builder_ringct.h @@ -71,7 +71,6 @@ public: bool init( const cryptonote::account_keys& account_keys, const std::vector& extra, - const std::uint64_t unlock_time, const std::uint32_t subaddr_account, const std::set& subaddr_minor_indices, std::vector& sources, diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 826cb63fa..0ad80f41e 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1340,6 +1340,8 @@ namespace cryptonote add_reason(reason, "too few outputs"); if ((res.tx_extra_too_big = tvc.m_tx_extra_too_big)) add_reason(reason, "tx-extra too big"); + if ((res.nonzero_unlock_time = tvc.m_nonzero_unlock_time)) + add_reason(reason, "tx unlock time is not zero"); const std::string punctuation = reason.empty() ? "" : ": "; if (tvc.m_verifivation_failed) { diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 9b3d0f001..5b328b055 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -88,7 +88,7 @@ namespace cryptonote // advance which version they will stop working with // Don't go over 32767 for any of these #define CORE_RPC_VERSION_MAJOR 3 -#define CORE_RPC_VERSION_MINOR 13 +#define CORE_RPC_VERSION_MINOR 14 #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR) @@ -640,6 +640,7 @@ namespace cryptonote bool too_few_outputs; bool sanity_check_failed; bool tx_extra_too_big; + bool nonzero_unlock_time; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE_PARENT(rpc_access_response_base) @@ -655,6 +656,7 @@ namespace cryptonote KV_SERIALIZE(too_few_outputs) KV_SERIALIZE(sanity_check_failed) KV_SERIALIZE(tx_extra_too_big) + KV_SERIALIZE(nonzero_unlock_time) END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init response; diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index 0466c92c2..11ab80666 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -422,6 +422,16 @@ namespace rpc if (!res.error_details.empty()) res.error_details += " and "; res.error_details += "too few outputs"; } + if (tvc.m_tx_extra_too_big) + { + if (!res.error_details.empty()) res.error_details += " and "; + res.error_details += "tx_extra too long"; + } + if (tvc.m_nonzero_unlock_time) + { + if (!res.error_details.empty()) res.error_details += " and "; + res.error_details += "non-zero unlock time"; + } if (res.error_details.empty()) { res.error_details = "an unknown issue was found with the transaction"; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index f2eaf6b13..b9e30f9d9 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -155,11 +155,6 @@ typedef cryptonote::simple_wallet sw; } \ } while(0) -enum TransferType { - Transfer, - TransferLocked, -}; - static std::string get_human_readable_timespan(std::chrono::seconds seconds); static std::string get_human_readable_timespan(uint64_t seconds); @@ -197,8 +192,6 @@ namespace const char* USAGE_PAYMENTS("payments [ ... ]"); const char* USAGE_PAYMENT_ID("payment_id"); const char* USAGE_TRANSFER("transfer [index=[,,...]] [] [] ( |
) [subtractfeefrom=[,,all,...]] []"); - const char* USAGE_LOCKED_TRANSFER("locked_transfer [index=[,,...]] [] [] ( | ) []"); - const char* USAGE_LOCKED_SWEEP_ALL("locked_sweep_all [index=[,,...] | index=all] [] []
[]"); const char* USAGE_SWEEP_ALL("sweep_all [index=[,,...] | index=all] [] [] [outputs=]
[]"); const char* USAGE_SWEEP_ACCOUNT("sweep_account [index=[,,...] | index=all] [] [] [outputs=]
[]"); const char* USAGE_SWEEP_BELOW("sweep_below [index=[,,...]] [] []
[]"); @@ -3336,14 +3329,6 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::on_command, this, &simple_wallet::transfer, _1), tr(USAGE_TRANSFER), tr("Transfer to
. If the parameter \"index=[,,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or etcetera (before the payment ID, if it's included). The \"subtractfeefrom=\" list allows you to choose which destinations to fund the tx fee from instead of the change output. The fee will be split across the chosen destinations proportionally equally. For example, to make 3 transfers where the fee is taken from the first and third destinations, one could do: \"transfer 3 0.5 1 subtractfeefrom=0,2\". Let's say the tx fee is 0.1. The balance would drop by exactly 4.5 XMR including fees, and addr1 & addr3 would receive 2.925 & 0.975 XMR, respectively. Use \"subtractfeefrom=all\" to spread the fee across all destinations.")); - m_cmd_binder.set_handler("locked_transfer", - boost::bind(&simple_wallet::on_command, this, &simple_wallet::locked_transfer,_1), - tr(USAGE_LOCKED_TRANSFER), - tr("Transfer to
and lock it for (max. 1000000). If the parameter \"index=[,,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. is the number of inputs to include for untraceability. Multiple payments can be made at once by adding URI_2 or etcetera (before the payment ID, if it's included)")); - m_cmd_binder.set_handler("locked_sweep_all", - boost::bind(&simple_wallet::on_command, this, &simple_wallet::locked_sweep_all,_1), - tr(USAGE_LOCKED_SWEEP_ALL), - tr("Send all unlocked balance to an address and lock it for (max. 1000000). If the parameter \"index=[,,...]\" or \"index=all\" is specified, the wallet sweeps outputs received by those or all address indices, respectively. If omitted, the wallet randomly chooses an address index to be used. is the priority of the sweep. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. is the number of inputs to include for untraceability.")); m_cmd_binder.set_handler("sweep_unmixable", boost::bind(&simple_wallet::on_command, this, &simple_wallet::sweep_unmixable, _1), tr("Send all unmixable outputs to yourself with ring_size 1")); @@ -6588,7 +6573,7 @@ bool simple_wallet::on_command(bool (simple_wallet::*cmd)(const std::vector*cmd)(args); } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::transfer_main(int transfer_type, const std::vector &args_, bool called_by_mms) +bool simple_wallet::transfer_main(const std::vector &args_, bool called_by_mms) { // "transfer [index=[,,...]] [] []
[]" if (!try_connect_to_daemon()) @@ -6640,7 +6625,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector(local_args.back()); - } - catch (const std::exception &e) - { - fail_msg_writer() << tr("bad locked_blocks parameter:") << " " << local_args.back(); - return false; - } - if (locked_blocks > 1000000) - { - fail_msg_writer() << tr("Locked blocks too high, max 1000000 (˜4 yrs)"); - return false; - } - local_args.pop_back(); - } - // Parse subtractfeefrom destination list tools::wallet2::unique_index_container subtract_fee_from_outputs; bool subtract_fee_from_all = false; @@ -6814,28 +6779,8 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector ptx_vector; - uint64_t bc_height, unlock_block = 0; - std::string err; - switch (transfer_type) - { - case TransferLocked: - bc_height = get_daemon_blockchain_height(err); - if (!err.empty()) - { - fail_msg_writer() << tr("failed to get blockchain height: ") << err; - return false; - } - unlock_block = bc_height + locked_blocks; - ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); - break; - default: - LOG_ERROR("Unknown transfer method, using default"); - /* FALLTHRU */ - case Transfer: - ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); - break; - } + auto ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, priority, extra, + m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs); if (ptx_vector.empty()) { @@ -6945,11 +6890,6 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vectorprint_ring_members())) return false; bool default_ring_size = true; @@ -7069,29 +7009,7 @@ bool simple_wallet::transfer(const std::vector &args_) PRINT_USAGE(USAGE_TRANSFER); return true; } - transfer_main(Transfer, args_, false); - return true; -} -//---------------------------------------------------------------------------------------------------- -bool simple_wallet::locked_transfer(const std::vector &args_) -{ - if (args_.size() < 1) - { - PRINT_USAGE(USAGE_LOCKED_TRANSFER); - return true; - } - transfer_main(TransferLocked, args_, false); - return true; -} -//---------------------------------------------------------------------------------------------------- -bool simple_wallet::locked_sweep_all(const std::vector &args_) -{ - if (args_.size() < 1) - { - PRINT_USAGE(USAGE_LOCKED_SWEEP_ALL); - return true; - } - sweep_main(m_current_subaddress_account, 0, true, args_); + transfer_main(args_, false); return true; } //---------------------------------------------------------------------------------------------------- @@ -7203,7 +7121,7 @@ bool simple_wallet::sweep_unmixable(const std::vector &args_) return true; } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, const std::vector &args_) +bool simple_wallet::sweep_main(uint32_t account, uint64_t below, const std::vector &args_) { auto print_usage = [this, account, below]() { @@ -7283,41 +7201,6 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co return true; } - uint64_t unlock_block = 0; - if (locked) { - uint64_t locked_blocks = 0; - - if (local_args.size() < 2) { - fail_msg_writer() << tr("missing lockedblocks parameter"); - return true; - } - - try - { - locked_blocks = boost::lexical_cast(local_args[1]); - } - catch (const std::exception &e) - { - fail_msg_writer() << tr("bad locked_blocks parameter"); - return true; - } - if (locked_blocks > 1000000) - { - fail_msg_writer() << tr("Locked blocks too high, max 1000000 (˜4 yrs)"); - return true; - } - std::string err; - uint64_t bc_height = get_daemon_blockchain_height(err); - if (!err.empty()) - { - fail_msg_writer() << tr("failed to get blockchain height: ") << err; - return true; - } - unlock_block = bc_height + locked_blocks; - - local_args.erase(local_args.begin() + 1); - } - size_t outputs = 1; if (local_args.size() > 0 && local_args[0].substr(0, 8) == "outputs=") { @@ -7392,7 +7275,7 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co try { // figure out what tx will be necessary - auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, outputs, fake_outs_count, unlock_block /* unlock_time */, priority, extra, account, subaddr_indices); + auto ptx_vector = m_wallet->create_transactions_all(below, info.address, info.is_subaddress, outputs, fake_outs_count, priority, extra, account, subaddr_indices); if (ptx_vector.empty()) { @@ -7649,7 +7532,7 @@ bool simple_wallet::sweep_single(const std::vector &args_) try { // figure out what tx will be necessary - auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, outputs, fake_outs_count, 0 /* unlock_time */, priority, extra); + auto ptx_vector = m_wallet->create_transactions_single(ki, info.address, info.is_subaddress, outputs, fake_outs_count, priority, extra); if (ptx_vector.empty()) { @@ -7759,7 +7642,7 @@ bool simple_wallet::sweep_single(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::sweep_all(const std::vector &args_) { - sweep_main(m_current_subaddress_account, 0, false, args_); + sweep_main(m_current_subaddress_account, 0, args_); return true; } //---------------------------------------------------------------------------------------------------- @@ -7779,7 +7662,7 @@ bool simple_wallet::sweep_account(const std::vector &args_) } local_args.erase(local_args.begin()); - sweep_main(account, 0, false, local_args); + sweep_main(account, 0, local_args); return true; } //---------------------------------------------------------------------------------------------------- @@ -7797,7 +7680,7 @@ bool simple_wallet::sweep_below(const std::vector &args_) fail_msg_writer() << tr("invalid amount threshold"); return true; } - sweep_main(m_current_subaddress_account, below, false, std::vector(++args_.begin(), args_.end())); + sweep_main(m_current_subaddress_account, below, std::vector(++args_.begin(), args_.end())); return true; } //---------------------------------------------------------------------------------------------------- @@ -11399,7 +11282,7 @@ void simple_wallet::mms_sync(const std::vector &args) void simple_wallet::mms_transfer(const std::vector &args) { // It's too complicated to check any arguments here, just let 'transfer_main' do the whole job - transfer_main(Transfer, args, true); + transfer_main(args, true); } void simple_wallet::mms_delete(const std::vector &args) diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 7c45d45e8..652708f5a 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -170,11 +170,9 @@ namespace cryptonote bool show_incoming_transfers(const std::vector &args); bool show_payments(const std::vector &args); bool show_blockchain_height(const std::vector &args); - bool transfer_main(int transfer_type, const std::vector &args, bool called_by_mms); + bool transfer_main(const std::vector &args, bool called_by_mms); bool transfer(const std::vector &args); - bool locked_transfer(const std::vector &args); - bool locked_sweep_all(const std::vector &args); - bool sweep_main(uint32_t account, uint64_t below, bool locked, const std::vector &args); + bool sweep_main(uint32_t account, uint64_t below, const std::vector &args); bool sweep_all(const std::vector &args); bool sweep_account(const std::vector &args); bool sweep_below(const std::vector &args); diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 8d7364cba..fc4f89128 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1588,11 +1588,11 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vectoradjust_mixin(mixin_count); if (amount) { - transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, + transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count, adjusted_priority, extra, subaddr_account, subaddr_indices); } else { - transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, 1, fake_outs_count, 0 /* unlock_time */, + transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, 1, fake_outs_count, adjusted_priority, extra, subaddr_account, subaddr_indices); } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index f34b10988..2321151f3 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -7333,14 +7333,15 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector additional_tx_keys; - bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, sd.unlock_time, tx_key, additional_tx_keys, sd.use_rct, rct_config, sd.use_view_tags); - THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, sd.unlock_time, m_nettype); + bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sd.sources, sd.splitted_dsts, sd.change_dts.addr, sd.extra, ptx.tx, tx_key, additional_tx_keys, sd.use_rct, rct_config, sd.use_view_tags); + THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sd.sources, sd.splitted_dsts, m_nettype); // we don't test tx size, because we don't know the current limit, due to not having a blockchain, // and it's a bit pointless to fail there anyway, since it'd be a (good) guess only. We sign anyway, // and if we really go over limit, the daemon will reject when it gets submitted. Chances are it's @@ -7870,7 +7871,6 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector> template void wallet2::transfer_selected(const std::vector& dsts, const std::vector& selected_transfers, size_t fake_outputs_count, std::vector> &outs, std::unordered_set &valid_public_keys_cache, - uint64_t unlock_time, uint64_t fee, const std::vector& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, + uint64_t fee, const std::vector& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, bool use_view_tags) { using namespace cryptonote; @@ -9533,9 +9533,9 @@ void wallet2::transfer_selected(const std::vector additional_tx_keys; LOG_PRINT_L2("constructing tx"); - bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, {}, use_view_tags); + bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, change_dts.addr, extra, tx, tx_key, additional_tx_keys, false, {}, use_view_tags); LOG_PRINT_L2("constructed tx, r="< dsts, const std::vector& selected_transfers, size_t fake_outputs_count, std::vector> &outs, std::unordered_set &valid_public_keys_cache, - uint64_t unlock_time, uint64_t fee, const std::vector& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, bool use_view_tags) + uint64_t fee, const std::vector& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, bool use_view_tags) { using namespace cryptonote; // throw if attempting a transaction with no destinations @@ -9779,7 +9779,6 @@ void wallet2::transfer_selected_rct(std::vector wallet2::create_transactions_2(std::vector> &outs, */ valid_public_keys_cache, - unlock_time, /* CONST uint64_t unlock_time, */ tx.needed_fee, /* CONST uint64_t fee, */ extra, /* const std::vector& extra, */ test_tx, /* OUT cryptonote::transaction& tx, */ @@ -11213,7 +11211,6 @@ skip_tx: fake_outs_count, tx.outs, valid_public_keys_cache, - unlock_time, tx.needed_fee, extra, detail::digit_split_strategy, @@ -11327,7 +11324,7 @@ bool wallet2::sanity_check(const std::vector &ptx_vector, c return true; } -std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices) +std::vector wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices) { std::vector unused_transfers_indices; std::vector unused_dust_indices; @@ -11397,10 +11394,10 @@ std::vector wallet2::create_transactions_all(uint64_t below } } - return create_transactions_from(address, is_subaddress, outputs, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra); + return create_transactions_from(address, is_subaddress, outputs, unused_transfers_indices, unused_dust_indices, fake_outs_count, priority, extra); } -std::vector wallet2::create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra) +std::vector wallet2::create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra) { std::vector unused_transfers_indices; std::vector unused_dust_indices; @@ -11418,10 +11415,10 @@ std::vector wallet2::create_transactions_single(const crypt break; } } - return create_transactions_from(address, is_subaddress, outputs, unused_transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra); + return create_transactions_from(address, is_subaddress, outputs, unused_transfers_indices, unused_dust_indices, fake_outs_count, priority, extra); } -std::vector wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector unused_transfers_indices, std::vector unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra) +std::vector wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector unused_transfers_indices, std::vector unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector& extra) { //ensure device is let in NONE mode in any case hw::device &hwdev = m_account.get_device(); @@ -11530,10 +11527,10 @@ std::vector wallet2::create_transactions_from(const crypton LOG_PRINT_L2("Trying to create a tx now, with " << tx.dsts.size() << " destinations and " << tx.selected_transfers.size() << " outputs"); if (use_rct) - transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra, + transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra, test_tx, test_ptx, rct_config, use_view_tags); else - transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra, + transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags); auto txBlob = t_serializable_object_to_blob(test_ptx.tx); needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask); @@ -11567,10 +11564,10 @@ std::vector wallet2::create_transactions_from(const crypton dt.amount = dt_amount + dt_residue; } if (use_rct) - transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra, + transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra, test_tx, test_ptx, rct_config, use_view_tags); else - transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, unlock_time, needed_fee, extra, + transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, valid_public_keys_cache, needed_fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags); txBlob = t_serializable_object_to_blob(test_ptx.tx); needed_fee = calculate_fee(use_per_byte_fee, test_ptx.tx, txBlob.size(), base_fee, fee_quantization_mask); @@ -11606,10 +11603,10 @@ std::vector wallet2::create_transactions_from(const crypton cryptonote::transaction test_tx; pending_tx test_ptx; if (use_rct) { - transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, valid_public_keys_cache, unlock_time, tx.needed_fee, extra, + transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, valid_public_keys_cache, tx.needed_fee, extra, test_tx, test_ptx, rct_config, use_view_tags); } else { - transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, valid_public_keys_cache, unlock_time, tx.needed_fee, extra, + transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, valid_public_keys_cache, tx.needed_fee, extra, detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx, use_view_tags); } auto txBlob = t_serializable_object_to_blob(test_ptx.tx); @@ -11921,7 +11918,7 @@ std::vector wallet2::create_unmixable_sweep_transactions() unmixable_transfer_outputs.push_back(n); } - return create_transactions_from(m_account_public_address, false, 1, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 0 /* unlock_time */, 1 /*priority */, std::vector()); + return create_transactions_from(m_account_public_address, false, 1, unmixable_transfer_outputs, unmixable_dust_outputs, 0 /*fake_outs_count */, 1 /*priority */, std::vector()); } //---------------------------------------------------------------------------------------------------- void wallet2::discard_unmixable_outputs() diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 3144a8fd3..c38d77675 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1088,10 +1088,10 @@ private: template void transfer_selected(const std::vector& dsts, const std::vector& selected_transfers, size_t fake_outputs_count, std::vector> &outs, std::unordered_set &valid_public_keys_cache, - uint64_t unlock_time, uint64_t fee, const std::vector& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, const bool use_view_tags); + uint64_t fee, const std::vector& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx, const bool use_view_tags); void transfer_selected_rct(std::vector dsts, const std::vector& selected_transfers, size_t fake_outputs_count, std::vector> &outs, std::unordered_set &valid_public_keys_cache, - uint64_t unlock_time, uint64_t fee, const std::vector& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, const bool use_view_tags); + uint64_t fee, const std::vector& extra, cryptonote::transaction& tx, pending_tx &ptx, const rct::RCTConfig &rct_config, const bool use_view_tags); void commit_tx(pending_tx& ptx_vector); void commit_tx(std::vector& ptx_vector); @@ -1113,10 +1113,10 @@ private: bool parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsigned_tx_set &exported_txs) const; bool load_tx(const std::string &signed_filename, std::vector &ptx, std::function accept_func = NULL); bool parse_tx_from_str(const std::string &signed_tx_st, std::vector &ptx, std::function accept_func); - std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose - std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices); - std::vector create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra); - std::vector create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector unused_transfers_indices, std::vector unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra); + std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose + std::vector create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra, uint32_t subaddr_account, std::set subaddr_indices); + std::vector create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector& extra); + std::vector create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector unused_transfers_indices, std::vector unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector& extra); bool sanity_check(const std::vector &ptx_vector, const std::vector& dsts, const unique_index_container& subtract_fee_from_outputs = {}) const; void cold_tx_aux_import(const std::vector& ptx, const std::vector& tx_device_aux); void cold_sign_tx(const std::vector& ptx_vector, signed_tx_set &exported_txs, std::vector &dsts_info, std::vector & tx_device_aux); diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 1f7e1c75d..c077313d4 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -86,6 +86,7 @@ namespace tools // zero_amount // zero_destination // subtract_fee_from_bad_index + // nonzero_unlock_time // wallet_rpc_error * // daemon_busy // no_connection_to_daemon @@ -592,20 +593,17 @@ namespace tools std::string && loc , sources_t const & sources , destinations_t const & destinations - , uint64_t unlock_time , cryptonote::network_type nettype ) : transfer_error(std::move(loc), "transaction was not constructed") , m_sources(sources) , m_destinations(destinations) - , m_unlock_time(unlock_time) , m_nettype(nettype) { } const sources_t& sources() const { return m_sources; } const destinations_t& destinations() const { return m_destinations; } - uint64_t unlock_time() const { return m_unlock_time; } std::string to_string() const { @@ -637,15 +635,12 @@ namespace tools cryptonote::print_money(dst.amount); } - ss << "\nunlock_time: " << m_unlock_time; - return ss.str(); } private: sources_t m_sources; destinations_t m_destinations; - uint64_t m_unlock_time; cryptonote::network_type m_nettype; }; //---------------------------------------------------------------------------------------------------- @@ -789,6 +784,14 @@ namespace tools } }; //---------------------------------------------------------------------------------------------------- + struct nonzero_unlock_time : public transfer_error + { + explicit nonzero_unlock_time(std::string&& loc) + : transfer_error(std::move(loc), "transaction cannot have non-zero unlock time") + { + } + }; + //---------------------------------------------------------------------------------------------------- struct wallet_rpc_error : public wallet_logic_error { const std::string& request() const { return m_request; } diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 4e42d64cd..58c9c5af6 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -1080,6 +1080,12 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } + else if (req.unlock_time) + { + er.code = WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME; + er.message = "Transaction cannot have non-zero unlock time"; + return false; + } CHECK_MULTISIG_ENABLED(); @@ -1093,7 +1099,7 @@ namespace tools { uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0); uint32_t priority = m_wallet->adjust_priority(req.priority); - std::vector ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs); + std::vector ptx_vector = m_wallet->create_transactions_2(dsts, mixin, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs); if (ptx_vector.empty()) { @@ -1134,6 +1140,12 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } + else if (req.unlock_time) + { + er.code = WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME; + er.message = "Transaction cannot have non-zero unlock time"; + return false; + } CHECK_MULTISIG_ENABLED(); @@ -1148,7 +1160,7 @@ namespace tools uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0); uint32_t priority = m_wallet->adjust_priority(req.priority); LOG_PRINT_L2("on_transfer_split calling create_transactions_2"); - std::vector ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices); + std::vector ptx_vector = m_wallet->create_transactions_2(dsts, mixin, priority, extra, req.account_index, req.subaddr_indices); LOG_PRINT_L2("on_transfer_split called create_transactions_2"); if (ptx_vector.empty()) @@ -1570,6 +1582,12 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } + else if (req.unlock_time) + { + er.code = WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME; + er.message = "Transaction cannot have non-zero unlock time"; + return false; + } CHECK_MULTISIG_ENABLED(); @@ -1605,7 +1623,7 @@ namespace tools { uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0); uint32_t priority = m_wallet->adjust_priority(req.priority); - std::vector ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, req.unlock_time, priority, extra, req.account_index, subaddr_indices); + std::vector ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, priority, extra, req.account_index, subaddr_indices); return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.amounts_by_dest_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay, res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er); @@ -1630,6 +1648,12 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } + else if (req.unlock_time) + { + er.code = WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME; + er.message = "Transaction cannot have non-zero unlock time"; + return false; + } if (req.outputs < 1) { @@ -1662,7 +1686,7 @@ namespace tools { uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0); uint32_t priority = m_wallet->adjust_priority(req.priority); - std::vector ptx_vector = m_wallet->create_transactions_single(ki, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, req.unlock_time, priority, extra); + std::vector ptx_vector = m_wallet->create_transactions_single(ki, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, priority, extra); if (ptx_vector.empty()) { diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h index 734229380..541d29f86 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h @@ -79,3 +79,5 @@ #define WALLET_RPC_ERROR_CODE_ZERO_AMOUNT -46 #define WALLET_RPC_ERROR_CODE_INVALID_SIGNATURE_TYPE -47 #define WALLET_RPC_ERROR_CODE_DISABLED -48 +#define WALLET_RPC_ERROR_CODE_PROXY_ALREADY_DEFINED -49 +#define WALLET_RPC_ERROR_CODE_NONZERO_UNLOCK_TIME -50 diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index 711f67b41..2fe0e46e2 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -350,7 +350,7 @@ bool gen_block_miner_tx_has_2_in::generate(std::vector& events destinations.push_back(de); transaction tmp_tx; - if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector(), tmp_tx, 0)) + if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector(), tmp_tx)) return false; MAKE_MINER_TX_MANUALLY(miner_tx, blk_0); @@ -393,7 +393,7 @@ bool gen_block_miner_tx_with_txin_to_key::generate(std::vector destinations.push_back(de); transaction tmp_tx; - if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector(), tmp_tx, 0)) + if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector(), tmp_tx)) return false; MAKE_MINER_TX_MANUALLY(miner_tx, blk_1); diff --git a/tests/core_tests/bulletproof_plus.cpp b/tests/core_tests/bulletproof_plus.cpp index f758ac0fb..d32f9b689 100644 --- a/tests/core_tests/bulletproof_plus.cpp +++ b/tests/core_tests/bulletproof_plus.cpp @@ -136,7 +136,7 @@ bool gen_bpp_tx_validation_base::generate_with(std::vector& ev std::unordered_map subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct_txes.resize(rct_txes.size() + 1); - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx && !post_tx(rct_txes.back(), n)) diff --git a/tests/core_tests/bulletproofs.cpp b/tests/core_tests/bulletproofs.cpp index 2f0f33cd6..ee747ab99 100644 --- a/tests/core_tests/bulletproofs.cpp +++ b/tests/core_tests/bulletproofs.cpp @@ -136,7 +136,7 @@ bool gen_bp_tx_validation_base::generate_with(std::vector& eve std::unordered_map subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct_txes.resize(rct_txes.size() + 1); - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx && !post_tx(rct_txes.back(), n)) diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 9bcae19d0..7e89ab140 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -1028,7 +1028,7 @@ bool construct_tx_to_key(const std::vector& events, cryptonote vector destinations; fill_tx_sources_and_destinations(events, blk_head, from, get_address(to), amount, fee, nmix, sources, destinations); - return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector(), tx, rct, range_proof_type, bp_version); } bool construct_tx_to_key(const std::vector& events, cryptonote::transaction& tx, const cryptonote::block& blk_head, @@ -1044,7 +1044,7 @@ bool construct_tx_to_key(const std::vector& events, cryptonote fill_tx_destinations(from, destinations, fee, sources, destinations_all, false); - return construct_tx_rct(from.get_keys(), sources, destinations_all, get_address(from), std::vector(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(from.get_keys(), sources, destinations_all, get_address(from), std::vector(), tx, rct, range_proof_type, bp_version); } bool construct_tx_to_key(cryptonote::transaction& tx, @@ -1054,7 +1054,7 @@ bool construct_tx_to_key(cryptonote::transaction& tx, { vector destinations; fill_tx_destinations(from, get_address(to), amount, fee, sources, destinations, rct); - return construct_tx_rct(from.get_keys(), sources, destinations, get_address(from), std::vector(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(from.get_keys(), sources, destinations, get_address(from), std::vector(), tx, rct, range_proof_type, bp_version); } bool construct_tx_to_key(cryptonote::transaction& tx, @@ -1065,10 +1065,10 @@ bool construct_tx_to_key(cryptonote::transaction& tx, { vector all_destinations; fill_tx_destinations(from, destinations, fee, sources, all_destinations, rct); - return construct_tx_rct(from.get_keys(), sources, all_destinations, get_address(from), std::vector(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(from.get_keys(), sources, all_destinations, get_address(from), std::vector(), tx, rct, range_proof_type, bp_version); } -bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, cryptonote::transaction& tx, uint64_t unlock_time, bool rct, rct::RangeProofType range_proof_type, int bp_version) +bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, cryptonote::transaction& tx, bool rct, rct::RangeProofType range_proof_type, int bp_version) { std::unordered_map subaddresses; subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0, 0}; @@ -1076,7 +1076,7 @@ bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std:: std::vector additional_tx_keys; std::vector destinations_copy = destinations; rct::RCTConfig rct_config = {range_proof_type, bp_version}; - return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config); + return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config); } transaction construct_tx_with_fee(std::vector& events, const block& blk_head, diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index d5c9edc55..2c3c45a44 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -450,7 +450,7 @@ bool construct_tx_rct(const cryptonote::account_keys& sender_account_keys, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, - std::vector extra, cryptonote::transaction& tx, uint64_t unlock_time, + std::vector extra, cryptonote::transaction& tx, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0); diff --git a/tests/core_tests/double_spend.inl b/tests/core_tests/double_spend.inl index 59460e674..ff6acc502 100644 --- a/tests/core_tests/double_spend.inl +++ b/tests/core_tests/double_spend.inl @@ -144,7 +144,7 @@ bool gen_double_spend_in_tx::generate(std::vector(), tx_1, 0)) + if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector(), tx_1)) return false; SET_EVENT_VISITOR_SETT(events, txs_keeped_by_block ? event_visitor_settings::set_txs_keeped_by_block : 0); diff --git a/tests/core_tests/integer_overflow.cpp b/tests/core_tests/integer_overflow.cpp index 31853ca24..c808ec17e 100644 --- a/tests/core_tests/integer_overflow.cpp +++ b/tests/core_tests/integer_overflow.cpp @@ -174,7 +174,7 @@ bool gen_uint_overflow_2::generate(std::vector& events) const destinations.push_back(tx_destination_entry(sources.front().amount - MONEY_SUPPLY - MONEY_SUPPLY + 1 - TESTS_DEFAULT_FEE, bob_addr, false)); cryptonote::transaction tx_1; - if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector(), tx_1, 0)) + if (!construct_tx(miner_account.get_keys(), sources, destinations, boost::none, std::vector(), tx_1)) return false; events.push_back(tx_1); @@ -200,7 +200,7 @@ bool gen_uint_overflow_2::generate(std::vector& events) const destinations.push_back(de); cryptonote::transaction tx_2; - if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector(), tx_2, 0)) + if (!construct_tx(bob_account.get_keys(), sources, destinations, boost::none, std::vector(), tx_2)) return false; events.push_back(tx_2); diff --git a/tests/core_tests/multisig.cpp b/tests/core_tests/multisig.cpp index 28b44d293..966c76116 100644 --- a/tests/core_tests/multisig.cpp +++ b/tests/core_tests/multisig.cpp @@ -310,7 +310,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector ins_order; @@ -399,7 +399,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector additional_tx_keys; std::unordered_map subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), rct_txes[n], 0, tx_key, additional_tx_keys, true); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), rct_txes[n], tx_key, additional_tx_keys, true); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); events.push_back(rct_txes[n]); starting_rct_tx_hashes.push_back(get_transaction_hash(rct_txes[n])); @@ -229,7 +229,7 @@ bool gen_rct_tx_validation_base::generate_with_full(std::vector additional_tx_keys; std::unordered_map subaddresses; subaddresses[miner_accounts[0].get_keys().m_account_address.m_spend_public_key] = {0,0}; - bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), tx, 0, tx_key, additional_tx_keys, true, rct_config, use_view_tags); + bool r = construct_tx_and_get_tx_key(miner_accounts[0].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), tx, tx_key, additional_tx_keys, true, rct_config, use_view_tags); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx) diff --git a/tests/core_tests/rct2.cpp b/tests/core_tests/rct2.cpp index d98cbd453..971f321a5 100644 --- a/tests/core_tests/rct2.cpp +++ b/tests/core_tests/rct2.cpp @@ -136,7 +136,7 @@ bool gen_rct2_tx_validation_base::generate_with(std::vector& e std::unordered_map subaddresses; subaddresses[miner_accounts[n].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct_txes.resize(rct_txes.size() + 1); - bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), rct_txes.back(), 0, tx_key, additional_tx_keys, true, rct_config[n]); + bool r = construct_tx_and_get_tx_key(miner_accounts[n].get_keys(), subaddresses, sources, destinations, cryptonote::account_public_address{}, std::vector(), rct_txes.back(), tx_key, additional_tx_keys, true, rct_config[n]); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (post_tx && !post_tx(rct_txes.back(), n)) diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index 0f8df5030..3bc34956e 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -102,7 +102,7 @@ bool test_transaction_generation_and_ring_signature() destinations.push_back(td); transaction tx_rc1; - bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, boost::none, std::vector(), tx_rc1, 0); + bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, boost::none, std::vector(), tx_rc1); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); crypto::hash pref_hash = get_transaction_prefix_hash(tx_rc1); diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index b2b742b93..207a1d9da 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -212,7 +212,7 @@ bool gen_tx_unlock_time::generate(std::vector& events) const GENERATE_ACCOUNT(miner_account); MAKE_GENESIS_BLOCK(events, blk_0, miner_account, ts_start); - REWIND_BLOCKS_N(events, blk_1, blk_0, miner_account, 10); + REWIND_BLOCKS_N(events, blk_1, blk_0, miner_account, 20); REWIND_BLOCKS(events, blk_1r, blk_1, miner_account); auto make_tx_with_unlock_time = [&](uint64_t unlock_time) -> transaction @@ -222,9 +222,34 @@ bool gen_tx_unlock_time::generate(std::vector& events) const std::list txs_0; + // Let's make sure that non-zero unlock times fail with a normal relay method + SET_EVENT_VISITOR_SETT(events, 0); // set relay_method::fluff + txs_0.push_back(make_tx_with_unlock_time(0)); events.push_back(txs_0.back()); + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) - 1)); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r))); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) + 1)); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) + 2)); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(ts_start - 1)); + + DO_CALLBACK(events, "mark_invalid_tx"); + events.push_back(make_tx_with_unlock_time(time(0) + 60 * 60)); + + // We want to try adding these transactions with non-zero unlock times to the pool, but relay + // rules enforce otherwise, so we set the relay method to block + SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_keeped_by_block); // set relay_method::block + txs_0.push_back(make_tx_with_unlock_time(get_block_height(blk_1r) - 1)); events.push_back(txs_0.back()); @@ -596,6 +621,7 @@ bool gen_tx_check_input_unlock_time::generate(std::vector& eve events.push_back(txs_0.back()); }; + SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_keeped_by_block); // set relay_method::block uint64_t blk_3_height = get_block_height(blk_1r) + 2; make_tx_to_acc(0, 0); make_tx_to_acc(1, blk_3_height - 1); @@ -604,6 +630,7 @@ bool gen_tx_check_input_unlock_time::generate(std::vector& eve make_tx_to_acc(4, time(0) - 1); make_tx_to_acc(5, time(0) + 60 * 60); MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0); + SET_EVENT_VISITOR_SETT(events, 0); // set relay_method::fluff std::list txs_1; auto make_tx_from_acc = [&](size_t acc_idx, bool invalid) diff --git a/tests/core_tests/v2_tests.cpp b/tests/core_tests/v2_tests.cpp index 68db46f51..a8bbf4b98 100644 --- a/tests/core_tests/v2_tests.cpp +++ b/tests/core_tests/v2_tests.cpp @@ -107,7 +107,7 @@ bool gen_v2_tx_validation_base::generate_with(std::vector& eve destinations.push_back(td); transaction tx; - bool r = construct_tx(miner_accounts[0].get_keys(), sources, destinations, boost::none, std::vector(), tx, 0); + bool r = construct_tx(miner_accounts[0].get_keys(), sources, destinations, boost::none, std::vector(), tx); CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction"); if (!valid) DO_CALLBACK(events, "mark_invalid_tx"); diff --git a/tests/core_tests/wallet_tools.cpp b/tests/core_tests/wallet_tools.cpp index a3b66e835..b5155ea7b 100644 --- a/tests/core_tests/wallet_tools.cpp +++ b/tests/core_tests/wallet_tools.cpp @@ -259,7 +259,7 @@ bool construct_tx_to_key(cryptonote::transaction& tx, { vector destinations; fill_tx_destinations(sender_wallet->get_account(), get_address(to), amount, fee, sources, destinations, rct); - return construct_tx_rct(sender_wallet, sources, destinations, get_address(sender_wallet), std::vector(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(sender_wallet, sources, destinations, get_address(sender_wallet), std::vector(), tx, rct, range_proof_type, bp_version); } bool construct_tx_to_key(cryptonote::transaction& tx, @@ -270,15 +270,15 @@ bool construct_tx_to_key(cryptonote::transaction& tx, { vector all_destinations; fill_tx_destinations(sender_wallet->get_account(), destinations, fee, sources, all_destinations, rct); - return construct_tx_rct(sender_wallet, sources, all_destinations, get_address(sender_wallet), std::vector(), tx, 0, rct, range_proof_type, bp_version); + return construct_tx_rct(sender_wallet, sources, all_destinations, get_address(sender_wallet), std::vector(), tx, rct, range_proof_type, bp_version); } -bool construct_tx_rct(tools::wallet2 * sender_wallet, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, cryptonote::transaction& tx, uint64_t unlock_time, bool rct, rct::RangeProofType range_proof_type, int bp_version) +bool construct_tx_rct(tools::wallet2 * sender_wallet, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, std::vector extra, cryptonote::transaction& tx, bool rct, rct::RangeProofType range_proof_type, int bp_version) { subaddresses_t & subaddresses = wallet_accessor_test::get_subaddresses(sender_wallet); crypto::secret_key tx_key; std::vector additional_tx_keys; std::vector destinations_copy = destinations; rct::RCTConfig rct_config = {range_proof_type, bp_version}; - return construct_tx_and_get_tx_key(sender_wallet->get_account().get_keys(), subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config); + return construct_tx_and_get_tx_key(sender_wallet->get_account().get_keys(), subaddresses, sources, destinations_copy, change_addr, extra, tx, tx_key, additional_tx_keys, rct, rct_config); } diff --git a/tests/core_tests/wallet_tools.h b/tests/core_tests/wallet_tools.h index 982862d45..4039d9343 100644 --- a/tests/core_tests/wallet_tools.h +++ b/tests/core_tests/wallet_tools.h @@ -82,5 +82,5 @@ bool construct_tx_rct(tools::wallet2 * sender_wallet, std::vector& sources, const std::vector& destinations, const boost::optional& change_addr, - std::vector extra, cryptonote::transaction& tx, uint64_t unlock_time, + std::vector extra, cryptonote::transaction& tx, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0); diff --git a/tests/functional_tests/transactions_flow_test.cpp b/tests/functional_tests/transactions_flow_test.cpp index 41cf1bea5..8e3e30d49 100644 --- a/tests/functional_tests/transactions_flow_test.cpp +++ b/tests/functional_tests/transactions_flow_test.cpp @@ -85,7 +85,7 @@ bool do_send_money(tools::wallet2& w1, tools::wallet2& w2, size_t mix_in_factor, try { std::vector ptx; - ptx = w1.create_transactions_2(dsts, mix_in_factor, 0, 0, std::vector(), 0, {}); + ptx = w1.create_transactions_2(dsts, mix_in_factor, 0, std::vector(), 0, {}); for (auto &p: ptx) w1.commit_tx(p); return true; diff --git a/tests/performance_tests/check_tx_signature.h b/tests/performance_tests/check_tx_signature.h index b542f91b1..3578a513a 100644 --- a/tests/performance_tests/check_tx_signature.h +++ b/tests/performance_tests/check_tx_signature.h @@ -72,7 +72,7 @@ public: std::unordered_map subaddresses; subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct::RCTConfig rct_config{range_proof_type, bp_version}; - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config)) + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector(), m_tx, tx_key, additional_tx_keys, rct, rct_config)) return false; get_transaction_prefix_hash(m_tx, m_tx_prefix_hash); @@ -136,7 +136,7 @@ public: m_txes.resize(a_num_txes + (extra_outs > 0 ? 1 : 0)); for (size_t n = 0; n < a_num_txes; ++n) { - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector(), m_txes[n], 0, tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2})) + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector(), m_txes[n], tx_key, additional_tx_keys, true, {rct::RangeProofPaddedBulletproof, 2})) return false; } @@ -147,7 +147,7 @@ public: for (size_t n = 1; n < extra_outs; ++n) destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); - if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector(), m_txes.back(), 0, tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2})) + if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector(), m_txes.back(), tx_key, additional_tx_keys, true, {rct::RangeProofMultiOutputBulletproof, 2})) return false; } diff --git a/tests/performance_tests/construct_tx.h b/tests/performance_tests/construct_tx.h index 00bd75b40..96da25306 100644 --- a/tests/performance_tests/construct_tx.h +++ b/tests/performance_tests/construct_tx.h @@ -74,7 +74,7 @@ public: std::unordered_map subaddresses; subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0}; rct::RCTConfig rct_config{range_proof_type, bp_version}; - return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector(), m_tx, 0, tx_key, additional_tx_keys, rct, rct_config); + return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector(), m_tx, tx_key, additional_tx_keys, rct, rct_config); } private: diff --git a/tests/performance_tests/ge_frombytes_vartime.h b/tests/performance_tests/ge_frombytes_vartime.h index 912961b50..6b85fb39c 100644 --- a/tests/performance_tests/ge_frombytes_vartime.h +++ b/tests/performance_tests/ge_frombytes_vartime.h @@ -57,7 +57,7 @@ public: std::vector destinations; destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); - if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector(), m_tx, 0)) + if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector(), m_tx)) return false; const cryptonote::txin_to_key& txin = boost::get(m_tx.vin[0]); diff --git a/tests/performance_tests/ge_tobytes.h b/tests/performance_tests/ge_tobytes.h index a0566b081..26346a413 100644 --- a/tests/performance_tests/ge_tobytes.h +++ b/tests/performance_tests/ge_tobytes.h @@ -57,7 +57,7 @@ public: std::vector destinations; destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false)); - if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector(), m_tx, 0)) + if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, boost::none, std::vector(), m_tx)) return false; const cryptonote::txin_to_key& txin = boost::get(m_tx.vin[0]); diff --git a/tests/unit_tests/json_serialization.cpp b/tests/unit_tests/json_serialization.cpp index aa46b68dc..9525d23ea 100644 --- a/tests/unit_tests/json_serialization.cpp +++ b/tests/unit_tests/json_serialization.cpp @@ -78,7 +78,7 @@ namespace test std::unordered_map subaddresses; subaddresses[from.m_account_address.m_spend_public_key] = {0,0}; - if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, 0, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 })) + if (!cryptonote::construct_tx_and_get_tx_key(from, subaddresses, actual_sources, to, boost::none, {}, tx, tx_key, extra_keys, rct, { bulletproof ? rct::RangeProofBulletproof : rct::RangeProofBorromean, bulletproof ? 2 : 0 })) throw std::runtime_error{"transaction construction error"}; return tx;