diff --git a/README.md b/README.md index a8bc9c8..6229fce 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Salvium Zero v0.5.4-rc1 +# Salvium Zero v0.5.4-rc3 Copyright (c) 2023-2024, Salvium Portions Copyright (c) 2014-2023, The Monero Project @@ -251,7 +251,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch ( ```bash git clone https://github.com/salvium/salvium cd salvium - git checkout v0.5.4-rc1 + git checkout v0.5.4-rc3 ``` * Build: @@ -370,10 +370,10 @@ application. cd salvium ``` -* If you would like a specific [version/tag](https://github.com/salvium/salvium/tags), do a git checkout for that version. eg. 'v0.5.4-rc1'. If you don't care about the version and just want binaries from master, skip this step: +* If you would like a specific [version/tag](https://github.com/salvium/salvium/tags), do a git checkout for that version. eg. 'v0.5.4-rc3'. If you don't care about the version and just want binaries from master, skip this step: ```bash - git checkout v0.5.4-rc1 + git checkout v0.5.4-rc3 ``` * If you are on a 64-bit system, run: diff --git a/src/multisig/multisig_tx_builder_ringct.cpp b/src/multisig/multisig_tx_builder_ringct.cpp index c0d62f7..5debd33 100644 --- a/src/multisig/multisig_tx_builder_ringct.cpp +++ b/src/multisig/multisig_tx_builder_ringct.cpp @@ -705,7 +705,8 @@ static bool try_reconstruct_range_proofs(const int bp_version, return false; } //---------------------------------------------------------------------------------------------------------------------- -static bool set_tx_return_address_information(const cryptonote::account_keys& account_keys, +static bool set_tx_return_address_information(const uint8_t hf_version, + const cryptonote::account_keys& account_keys, size_t change_index, crypto::public_key& txkey_pub, cryptonote::transaction& unsigned_tx @@ -715,10 +716,15 @@ static bool set_tx_return_address_information(const cryptonote::account_keys& ac // Get the output public key for the change output crypto::public_key P_change = crypto::null_pkey; - if (unsigned_tx.type == cryptonote::transaction_type::TRANSFER) - CHECK_AND_ASSERT_MES(unsigned_tx.vout.size() == 2, false, "Internal error - incorrect number of outputs (!=2) for TRANSFER tx"); - else if (unsigned_tx.type == cryptonote::transaction_type::STAKE) - CHECK_AND_ASSERT_MES(unsigned_tx.vout.size() == 1, false, "Internal error - incorrect number of outputs (!=1) for YIELD tx"); + if (unsigned_tx.type == cryptonote::transaction_type::TRANSFER) { + if (hf_version >= HF_VERSION_ENABLE_N_OUTS) { + CHECK_AND_ASSERT_MES(unsigned_tx.vout.size() >= 2, false, "Internal error - incorrect number of outputs (<2) for TRANSFER tx"); + } else { + CHECK_AND_ASSERT_MES(unsigned_tx.vout.size() == 2, false, "Internal error - incorrect number of outputs (!=2) for TRANSFER tx"); + } + } else if (unsigned_tx.type == cryptonote::transaction_type::STAKE) { + CHECK_AND_ASSERT_MES(unsigned_tx.vout.size() == 1, false, "Internal error - incorrect number of outputs (!=1) for STAKE tx"); + } CHECK_AND_ASSERT_MES(change_index < unsigned_tx.vout.size(), false, "Internal error - invalid change_index"); CHECK_AND_ASSERT_MES(cryptonote::get_output_public_key(unsigned_tx.vout[change_index], P_change), false, "Internal error - failed to get TX change output public key"); CHECK_AND_ASSERT_MES(P_change != crypto::null_pkey, false, "Internal error - not found TX change output for TRANSFER tx"); @@ -750,10 +756,12 @@ static bool set_tx_return_address_information(const cryptonote::account_keys& ac if (unsigned_tx.type == cryptonote::transaction_type::TRANSFER) { // Store the F point - we do not need to generate a full return address in this instance - unsigned_tx.return_address = rct::rct2pk(key_F); + if (not reconstruction) + unsigned_tx.return_address = rct::rct2pk(key_F); // Clear the pubkey, because it isn't used - unsigned_tx.return_pubkey = crypto::null_pkey; + if (not reconstruction) + unsigned_tx.return_pubkey = crypto::null_pkey; } else if (unsigned_tx.type == cryptonote::transaction_type::STAKE) { @@ -766,7 +774,8 @@ static bool set_tx_return_address_information(const cryptonote::account_keys& ac // Next, calculate the corresponding TX public key (= sP_change) // This has to be done using smK() call because of g_k_d() performing a torsion clear - unsigned_tx.return_pubkey = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(P_change), rct::sk2rct(s))); + if (not reconstruction) + unsigned_tx.return_pubkey = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(P_change), rct::sk2rct(s))); // Next, calculate a derivation using the TX public key and our secret view key crypto::key_derivation derivation = AUTO_VAL_INIT(derivation); @@ -785,7 +794,8 @@ static bool set_tx_return_address_information(const cryptonote::account_keys& ac CHECK_AND_ASSERT_MES(P_change == P_change_verify, false, "in get_return_address(): failed sanity check (keys do not match)"); // All is well - copy the return address - unsigned_tx.return_address = out_eph_public_key; + if (not reconstruction) + unsigned_tx.return_address = out_eph_public_key; } else { @@ -1038,6 +1048,7 @@ bool tx_builder_ringct_t::init( const cryptonote::account_keys& account_keys, const std::vector& extra, const cryptonote::transaction_type& tx_type, + const std::uint8_t hf_version, const std::uint64_t unlock_time, const std::uint32_t subaddr_account, const std::set& subaddr_minor_indices, @@ -1070,8 +1081,13 @@ bool tx_builder_ringct_t::init( // decide if view tags are needed const bool use_view_tags{view_tag_required(rct_config.bp_version)}; + // Configure the correct TX version for the current HF + TX type + if (hf_version >= HF_VERSION_ENABLE_N_OUTS && tx_type == cryptonote::transaction_type::TRANSFER) { + unsigned_tx.version = TRANSACTION_VERSION_N_OUTS; + } else { + unsigned_tx.version = 2; + } // misc. fields - unsigned_tx.version = 2; //rct = 2 unsigned_tx.unlock_time = unlock_time; unsigned_tx.type = (tx_type == cryptonote::transaction_type::RETURN) ? cryptonote::TRANSFER : tx_type; unsigned_tx.source_asset_type = "SAL"; @@ -1161,13 +1177,68 @@ bool tx_builder_ringct_t::init( if (not set_tx_outputs_result) return false; - if (unsigned_tx.type == cryptonote::transaction_type::TRANSFER || unsigned_tx.type == cryptonote::transaction_type::STAKE) { + if (hf_version >= HF_VERSION_ENABLE_N_OUTS && unsigned_tx.type == cryptonote::transaction_type::TRANSFER) { + + // Get the output public key for the change output + crypto::public_key P_change = crypto::null_pkey; + CHECK_AND_ASSERT_MES(unsigned_tx.vout.size() >= 2, false, "Internal error - too few outputs for multisig TRANSFER tx"); + CHECK_AND_ASSERT_MES(cryptonote::get_output_public_key(unsigned_tx.vout[change_index], P_change), false, "Internal error - failed to get multisig TX change output public key"); + CHECK_AND_ASSERT_MES(P_change != crypto::null_pkey, false, "Internal error - not found TX change output for multisig TRANSFER tx"); + + // Calculate the F points and change mask for every destination + for (size_t op_index=0; op_index& extra, const cryptonote::transaction_type& type, + const std::uint8_t hf_version, const std::uint64_t unlock_time, const std::uint32_t subaddr_account, const std::set& subaddr_minor_indices, diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp index 2d1df92..bef0906 100644 --- a/src/serialization/json_object.cpp +++ b/src/serialization/json_object.cpp @@ -273,8 +273,13 @@ void toJsonValue(rapidjson::Writer& dest, const cryptonote::t if (tx.type != cryptonote::transaction_type::PROTOCOL) { INSERT_INTO_JSON_OBJECT(dest, amount_burnt, tx.amount_burnt); if (tx.type != cryptonote::transaction_type::MINER) { - INSERT_INTO_JSON_OBJECT(dest, return_address, tx.return_address); - INSERT_INTO_JSON_OBJECT(dest, return_pubkey, tx.return_pubkey); + if (tx.type == cryptonote::transaction_type::TRANSFER && tx.version >= TRANSACTION_VERSION_N_OUTS) { + INSERT_INTO_JSON_OBJECT(dest, return_address_list, tx.return_address_list); + INSERT_INTO_JSON_OBJECT(dest, return_address_change_mask, tx.return_address_change_mask); + } else { + INSERT_INTO_JSON_OBJECT(dest, return_address, tx.return_address); + INSERT_INTO_JSON_OBJECT(dest, return_pubkey, tx.return_pubkey); + } INSERT_INTO_JSON_OBJECT(dest, source_asset_type, tx.source_asset_type); INSERT_INTO_JSON_OBJECT(dest, destination_asset_type, tx.destination_asset_type); INSERT_INTO_JSON_OBJECT(dest, amount_slippage_limit, tx.amount_slippage_limit); @@ -308,8 +313,13 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::transaction& tx) if (tx.type != cryptonote::transaction_type::PROTOCOL) { GET_FROM_JSON_OBJECT(val, tx.amount_burnt, amount_burnt); if (tx.type != cryptonote::transaction_type::MINER) { - GET_FROM_JSON_OBJECT(val, tx.return_address, return_address); - GET_FROM_JSON_OBJECT(val, tx.return_pubkey, return_pubkey); + if (tx.type == cryptonote::transaction_type::TRANSFER && tx.version >= TRANSACTION_VERSION_N_OUTS) { + GET_FROM_JSON_OBJECT(val, tx.return_address_list, return_address_list); + GET_FROM_JSON_OBJECT(val, tx.return_address_change_mask, return_address_change_mask); + } else { + GET_FROM_JSON_OBJECT(val, tx.return_address, return_address); + GET_FROM_JSON_OBJECT(val, tx.return_pubkey, return_pubkey); + } GET_FROM_JSON_OBJECT(val, tx.source_asset_type, source_asset_type); GET_FROM_JSON_OBJECT(val, tx.destination_asset_type, destination_asset_type); GET_FROM_JSON_OBJECT(val, tx.amount_slippage_limit, amount_slippage_limit); diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index d5298de..d5d2310 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -8313,11 +8313,13 @@ bool simple_wallet::stake(const std::vector &args_) return true; } + /* if(m_wallet->multisig()) { fail_msg_writer() << tr("This is a multisig wallet, staking is not currently supported"); return true; } + */ std::vector local_args; local_args.push_back(m_wallet->get_subaddress_as_str({m_current_subaddress_account,0})); diff --git a/src/version.cpp.in b/src/version.cpp.in index 431c6a7..91ee065 100644 --- a/src/version.cpp.in +++ b/src/version.cpp.in @@ -1,5 +1,5 @@ #define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@" -#define DEF_SALVIUM_VERSION "0.5.4-rc1" +#define DEF_SALVIUM_VERSION "0.5.4-rc3" #define DEF_MONERO_VERSION_TAG "release" #define DEF_MONERO_VERSION "0.18.3.3" #define DEF_MONERO_RELEASE_NAME "Zero" diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5927156..337732a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -8290,6 +8290,7 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector subaddr_minor_indices; @@ -10106,6 +10108,7 @@ void wallet2::transfer_selected_rct(std::vector> circ_amounts; THROW_WALLET_EXCEPTION_IF(!get_circulating_supply(circ_amounts), error::wallet_internal_error, "Failed to get circulating supply");