diff --git a/README.md b/README.md
index 13558e5f..4d5ca173 100644
--- a/README.md
+++ b/README.md
@@ -13,14 +13,14 @@ Be sure to clone the repository properly:\
### Dependencies
| component / version | minimum
(not recommended but may work) | recommended | most recent of what we have ever tested |
|--|--|--|--|
-| gcc (Linux) | 5.4.0 | 7.5.0 | 8.3.0 |
+| gcc (Linux) | 7.5.0 | 7.5.0 | 8.3.0 |
| llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 |
-| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2017 (15.9.0) | 2022 (17.4.2) |
-| [XCode](https://developer.apple.com/downloads/) (macOS) | 9.2 | 12.3 | 12.3 |
-| [CMake](https://cmake.org/download/) | 2.8.6 | 3.15.5 | 3.26.3 |
+| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2017 (15.9.30) | 2017 (15.9.30) | 2022 (17.6.1) |
+| [XCode](https://developer.apple.com/downloads/) (macOS) | 12.3 | 14.3 | 14.3 |
+| [CMake](https://cmake.org/download/) | 3.1.6 | 3.15.5 | 3.26.3 |
| [Boost](https://www.boost.org/users/download/) | 1.70 | 1.70 | 1.76 |
| [OpenSSL](https://www.openssl.org/source/) [(win)](https://slproweb.com/products/Win32OpenSSL.html) | - | 1.1.1n | 1.1.1n |
-| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.15.2 |
+| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.12.12 | 5.15.2 |
Note:\
[*server version*] denotes steps required for building command-line tools (daemon, simplewallet, etc.).\
diff --git a/src/crypto/range_proofs.h b/src/crypto/range_proofs.h
index 95cbbc43..238bc300 100644
--- a/src/crypto/range_proofs.h
+++ b/src/crypto/range_proofs.h
@@ -56,7 +56,7 @@ namespace crypto
};
- template
+ template
struct bpp_crypto_trait_zano : gen_trait_t
{
static constexpr size_t c_bpp_n = N; // the upper bound for the witness's range
@@ -134,7 +134,7 @@ namespace crypto
}; // struct bpp_crypto_trait_zano
- typedef bpp_crypto_trait_zano bpp_crypto_trait_ZC_out;
+ typedef bpp_crypto_trait_zano bpp_crypto_trait_ZC_out;
typedef bpp_crypto_trait_zano bpp_crypto_trait_Zarcanum;
diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp
index 4419e105..9a8298e4 100644
--- a/src/currency_core/blockchain_storage.cpp
+++ b/src/currency_core/blockchain_storage.cpp
@@ -4503,11 +4503,12 @@ bool check_tx_explicit_asset_id_rules(const transaction& tx, bool all_tx_ins_hav
CHECK_AND_ASSERT_MES(r, false, "output #" << j << " has a non-explicit asset id");
}
}
- else // otherwise all outputs must have hidden asset id
+ else // otherwise all outputs must have hidden asset id (unless they burn money by sending them to null pubkey)
{
for(size_t j = 0, k = tx.vout.size(); j < k; ++j)
{
- r = crypto::point_t(boost::get(tx.vout[j]).blinded_asset_id).modify_mul8().to_public_key() != native_coin_asset_id;
+ const tx_out_zarcanum& zo = boost::get(tx.vout[j]);
+ r = zo.stealth_address == null_pkey || crypto::point_t(zo.blinded_asset_id).modify_mul8().to_public_key() != native_coin_asset_id;
CHECK_AND_ASSERT_MES(r, false, "output #" << j << " has an explicit asset id");
}
}
@@ -4705,7 +4706,8 @@ struct outputs_visitor
{
if (!m_bch.is_tx_spendtime_unlocked(source_out_unlock_time))
{
- LOG_PRINT_L0("One of outputs for one of inputs have wrong tx.unlock_time = " << get_tx_unlock_time(source_tx, out_i));
+ uint64_t limit = source_out_unlock_time < CURRENCY_MAX_BLOCK_NUMBER ? m_bch.get_current_blockchain_size() - 1 + CURRENCY_LOCKED_TX_ALLOWED_DELTA_BLOCKS : m_bch.get_core_runtime_config().get_core_time() + CURRENCY_LOCKED_TX_ALLOWED_DELTA_SECONDS;
+ LOG_PRINT_L0("An output has unlock time value of " << get_tx_unlock_time(source_tx, out_i) << " while the current limit is " << limit);
return false;
}
}
diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h
index b9dde3d9..758b9b43 100644
--- a/src/currency_core/blockchain_storage.h
+++ b/src/currency_core/blockchain_storage.h
@@ -829,7 +829,8 @@ namespace currency
if (!vis.handle_output(tx_ptr->tx, validated_tx, o, n))
{
- LOG_PRINT_RED_L0("handle_output failed for output #" << n << " in " << tx_id);
+ size_t verified_input_index = std::find(validated_tx.vin.begin(), validated_tx.vin.end(), verified_input) - validated_tx.vin.begin();
+ LOG_PRINT_RED_L0("handle_output failed for output #" << n << " in " << tx_id << " referenced by input #" << verified_input_index << " in tx " << get_transaction_hash(validated_tx));
return false;
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
@@ -844,7 +845,8 @@ namespace currency
TIME_MEASURE_START_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
if (!vis.handle_output(tx_ptr->tx, validated_tx, out_zc, n))
{
- LOG_PRINT_RED_L0("handle_output failed for output #" << n << " in " << tx_id);
+ size_t verified_input_index = std::find(validated_tx.vin.begin(), validated_tx.vin.end(), verified_input) - validated_tx.vin.begin();
+ LOG_PRINT_RED_L0("handle_output failed for output #" << n << " in " << tx_id << " referenced by input #" << verified_input_index << " in tx " << get_transaction_hash(validated_tx));
return false;
}
TIME_MEASURE_FINISH_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output);
diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h
index 7e2b928f..d5693b67 100644
--- a/src/currency_core/currency_basic.h
+++ b/src/currency_core/currency_basic.h
@@ -1140,6 +1140,13 @@ namespace currency
bool operator ==(const currency::zarcanum_sig& a, const currency::zarcanum_sig& b);
bool operator ==(const currency::ref_by_id& a, const currency::ref_by_id& b);
+ // TODO: REPLACE all of the following operators to "bool operator==(..) const = default" once we moved to C++20 -- sowle
+ bool operator ==(const currency::signed_parts& a, const currency::signed_parts& b);
+ bool operator ==(const currency::txin_gen& a, const currency::txin_gen& b);
+ bool operator ==(const currency::txin_to_key& a, const currency::txin_to_key& b);
+ bool operator ==(const currency::txin_multisig& a, const currency::txin_multisig& b);
+ bool operator ==(const currency::txin_htlc& a, const currency::txin_htlc& b);
+ bool operator ==(const currency::txin_zc_input& a, const currency::txin_zc_input& b);
} // namespace currency
POD_MAKE_HASHABLE(currency, account_public_address);
diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp
index e0edf3a4..2c812068 100644
--- a/src/currency_core/currency_format_utils.cpp
+++ b/src/currency_core/currency_format_utils.cpp
@@ -1162,12 +1162,12 @@ namespace currency
crypto::scalar_t amount_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_AMOUNT_MASK, h);
out.encrypted_amount = de.amount ^ amount_mask.m_u64[0];
- asset_blinding_mask = crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_ASSET_BLINDING_MASK, h); // f = Hs(domain_sep, d, i)
+ CHECK_AND_ASSERT_MES(~de.flags & tx_destination_entry_flags::tdef_explicit_native_asset_id || de.asset_id == currency::native_coin_asset_id, false, "explicit_native_asset_id may be used only with native asset id");
+ asset_blinding_mask = de.flags & tx_destination_entry_flags::tdef_explicit_native_asset_id ? 0 : crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_ASSET_BLINDING_MASK, h); // f = Hs(domain_sep, d, i)
blinded_asset_id = crypto::point_t(de.asset_id) + asset_blinding_mask * crypto::c_point_X;
out.blinded_asset_id = (crypto::c_scalar_1div8 * blinded_asset_id).to_public_key(); // T = 1/8 * (H_asset + s * X)
- CHECK_AND_ASSERT_MES(~de.flags & tx_destination_entry_flags::tdef_explicit_native_asset_id || de.asset_id == currency::native_coin_asset_id, false, "explicit_native_asset_id may be used only with native asset id");
- asset_blinding_mask = de.flags & tx_destination_entry_flags::tdef_explicit_native_asset_id ? 0 : crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_ASSET_BLINDING_MASK, h); // f = Hs(domain_sep, d, i)
+ amount_blinding_mask = de.flags & tx_destination_entry_flags::tdef_zero_amount_blinding_mask ? 0 : crypto::hash_helper_t::hs(CRYPTO_HDS_OUT_AMOUNT_BLINDING_MASK, h); // f = Hs(domain_sep, d, i)
amount_commitment = de.amount * blinded_asset_id + amount_blinding_mask * crypto::c_point_G;
out.amount_commitment = (crypto::c_scalar_1div8 * amount_commitment).to_public_key(); // E = 1/8 * e * T + 1/8 * y * G
@@ -2458,7 +2458,6 @@ namespace currency
if (!append_mode && all_inputs_are_obviously_native_coins && gen_context.ao_asset_id == currency::null_pkey)
dst_entr.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id; // all inputs are obviously native coins -- all outputs must have explicit asset ids (unless there's an asset emission)
- CHECK_AND_ASSERT_MES(dst_entr.amount > 0, false, "Destination with wrong amount: " << dst_entr.amount); // <<-- TODO @#@# consider removing this check
r = construct_tx_out(dst_entr, txkey.sec, output_index, tx, deriv_cache, sender_account_keys,
gen_context.asset_id_blinding_masks[output_index], gen_context.amount_blinding_masks[output_index],
gen_context.blinded_asset_ids[output_index], gen_context.amount_commitments[output_index], result, tx_outs_attr);
@@ -2964,17 +2963,41 @@ namespace currency
return true;
}
//---------------------------------------------------------------
- uint64_t get_outs_money_amount(const transaction& tx)
+ uint64_t get_outs_money_amount(const transaction& tx, const currency::account_keys& keys /* = currency::null_acc_keys */)
{
uint64_t outputs_amount = 0;
- for (const auto& o : tx.vout)
+
+ bool process_hidden_amounts = false;
+ crypto::key_derivation derivation = null_derivation;
+ if (keys.spend_secret_key != null_skey && keys.view_secret_key != null_skey)
{
+ process_hidden_amounts = true;
+ bool r = crypto::generate_key_derivation(get_tx_pub_key_from_extra(tx), keys.view_secret_key, derivation);
+ if (!r)
+ LOG_PRINT_YELLOW("generate_key_derivation failed in get_outs_money_amount", LOG_LEVEL_0);
+ }
+
+ for (size_t output_index = 0; output_index < tx.vout.size(); ++output_index)
+ {
+ const auto& o = tx.vout[output_index];
VARIANT_SWITCH_BEGIN(o);
- VARIANT_CASE_CONST(tx_out_bare, o)
- outputs_amount += o.amount;
- // ignore outputs with hidden amounts
+ VARIANT_CASE_CONST(tx_out_bare, bo)
+ outputs_amount += bo.amount;
+ VARIANT_CASE_CONST(tx_out_zarcanum, zo)
+ if (process_hidden_amounts)
+ {
+ uint64_t decoded_amount = 0;
+ crypto::public_key decoded_asset_id{};
+ crypto::scalar_t amount_blinding_mask{}, asset_id_blinding_mask{};
+ if (is_out_to_acc(keys.account_address, zo, derivation, output_index, decoded_amount, decoded_asset_id, amount_blinding_mask, asset_id_blinding_mask))
+ {
+ if (decoded_asset_id == currency::native_coin_asset_id)
+ outputs_amount += decoded_amount;
+ }
+ }
VARIANT_SWITCH_END();
}
+
return outputs_amount;
}
//---------------------------------------------------------------
@@ -3282,7 +3305,7 @@ namespace currency
}
//---------------------------------------------------------------
// NOTE: this function is obsolete and depricated
- // PoS block real timestamp is set using a service attachment in mining tx extra since 2021-10
+ [[deprecated("PoS block real timestamp is set using a service attachment in mining tx extra since 2021-10")]]
uint64_t get_actual_timestamp(const block& b)
{
uint64_t tes_ts = b.timestamp;
@@ -4320,7 +4343,50 @@ namespace currency
return a.n == b.n && a.tx_id == b.tx_id;
}
//--------------------------------------------------------------------------------
-
+ bool operator ==(const currency::signed_parts& a, const currency::signed_parts& b)
+ {
+ return
+ a.n_extras == b.n_extras &&
+ a.n_outs == b.n_outs;
+ }
+ bool operator ==(const currency::txin_gen& a, const currency::txin_gen& b)
+ {
+ return a.height == b.height;
+ }
+ bool operator ==(const currency::txin_to_key& a, const currency::txin_to_key& b)
+ {
+ return
+ a.amount == b.amount &&
+ a.etc_details == b.etc_details &&
+ a.key_offsets == b.key_offsets &&
+ a.k_image == b.k_image;
+ }
+ bool operator ==(const currency::txin_multisig& a, const currency::txin_multisig& b)
+ {
+ return
+ a.amount == b.amount &&
+ a.etc_details == b.etc_details &&
+ a.multisig_out_id == b.multisig_out_id &&
+ a.sigs_count == b.sigs_count;
+ }
+ bool operator ==(const currency::txin_htlc& a, const currency::txin_htlc& b)
+ {
+ return
+ a.amount == b.amount &&
+ a.etc_details == b.etc_details &&
+ a.hltc_origin == b.hltc_origin &&
+ a.key_offsets == b.key_offsets &&
+ a.k_image == b.k_image;
+ }
+ bool operator ==(const currency::txin_zc_input& a, const currency::txin_zc_input& b)
+ {
+ return
+ a.etc_details == b.etc_details &&
+ a.key_offsets == b.key_offsets &&
+ a.k_image == b.k_image;
+ }
+ //--------------------------------------------------------------------------------
+
boost::multiprecision::uint1024_t get_a_to_b_relative_cumulative_difficulty(const wide_difficulty_type& difficulty_pos_at_split_point,
const wide_difficulty_type& difficulty_pow_at_split_point,
diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h
index 8311428e..412f31d8 100644
--- a/src/currency_core/currency_format_utils.h
+++ b/src/currency_core/currency_format_utils.h
@@ -380,7 +380,7 @@ namespace currency
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
uint64_t get_inputs_money_amount(const transaction& tx);
bool get_inputs_money_amount(const transaction& tx, uint64_t& money);
- uint64_t get_outs_money_amount(const transaction& tx);
+ uint64_t get_outs_money_amount(const transaction& tx, const currency::account_keys& acc_keys_for_hidden_amounts = currency::null_acc_keys);
bool check_inputs_types_supported(const transaction& tx);
bool check_outs_valid(const transaction& tx);
bool parse_amount(uint64_t& amount, const std::string& str_amount);
diff --git a/src/currency_core/currency_format_utils_transactions.h b/src/currency_core/currency_format_utils_transactions.h
index e4f16d1f..c5c9cfb0 100644
--- a/src/currency_core/currency_format_utils_transactions.h
+++ b/src/currency_core/currency_format_utils_transactions.h
@@ -62,6 +62,7 @@ namespace currency
bool is_multisig() const { return ms_sigs_count > 0; }
bool is_zc() const { return !real_out_amount_blinding_mask.is_zero(); }
bool is_native_coin() const { return asset_id == currency::native_coin_asset_id; }
+ uint64_t amount_for_global_output_index() const { return is_zc() ? 0 : amount; } // amount value for global outputs index, it's zero for outputs with hidden amounts
BEGIN_SERIALIZE_OBJECT()
FIELD(outputs)
@@ -96,9 +97,10 @@ namespace currency
enum tx_destination_entry_flags
{
- tdef_none = 0,
- tdef_explicit_native_asset_id = 0x0001,
- tdef_explicit_amount_to_provide = 0x0002
+ tdef_none = 0,
+ tdef_explicit_native_asset_id = 0x0001,
+ tdef_explicit_amount_to_provide = 0x0002,
+ tdef_zero_amount_blinding_mask = 0x0004 // currently it's only used for burning native coins
};
struct tx_destination_entry
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 00646db6..c2194866 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -1208,16 +1208,8 @@ namespace currency
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_alias_reward(const COMMAND_RPC_GET_ALIAS_REWARD::request& req, COMMAND_RPC_GET_ALIAS_REWARD::response& res, epee::json_rpc::error& error_resp, connection_context& cntx)
{
-
- uint64_t default_tx_fee = m_core.get_blockchain_storage().get_core_runtime_config().tx_default_fee;
- uint64_t current_median_fee = m_core.get_blockchain_storage().get_tx_fee_median();
-
- res.reward = get_alias_coast_from_fee(req.alias, std::max(default_tx_fee, current_median_fee));
-
- if (res.reward)
- res.status = API_RETURN_CODE_OK;
- else
- res.status = API_RETURN_CODE_NOT_FOUND;
+ res.reward = m_core.get_blockchain_storage().get_alias_coast(req.alias);
+ res.status = API_RETURN_CODE_OK;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
diff --git a/src/version.h.in b/src/version.h.in
index 5c81f31f..c7e36c70 100644
--- a/src/version.h.in
+++ b/src/version.h.in
@@ -8,6 +8,6 @@
#define PROJECT_REVISION "0"
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
-#define PROJECT_VERSION_BUILD_NO 213
+#define PROJECT_VERSION_BUILD_NO 217
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 3a737704..9bdb27cc 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -4581,7 +4581,7 @@ uint64_t wallet2::get_alias_cost(const std::string& alias)
throw std::runtime_error(std::string("Failed to get alias cost"));
}
- return rsp.reward + rsp.reward / 10; //add 10% of price to be sure;
+ return rsp.reward;
}
//----------------------------------------------------------------------------------------------------
void wallet2::request_alias_registration(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward, const crypto::secret_key& authority_key)
@@ -4631,6 +4631,7 @@ void wallet2::request_alias_registration(currency::extra_alias_entry& ai, curren
tx_dest_alias_reward.addr.resize(1);
get_aliases_reward_account(tx_dest_alias_reward.addr.back());
tx_dest_alias_reward.amount = reward;
+ tx_dest_alias_reward.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
destinations.push_back(tx_dest_alias_reward);
transfer(destinations, 0, 0, fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx, CURRENCY_TO_KEY_OUT_RELAXED, false);
@@ -6480,9 +6481,15 @@ void wallet2::prepare_tx_destinations(const assets_selection_context& needed_mon
if (dst.asset_id == currency::null_pkey)
final_destinations.emplace_back(dst.amount, dst.addr, dst.asset_id);
- // if there's not ehough destinations items (i.e. outputs), split the last one
- if (final_destinations.size() > 0 && final_destinations.size() < CURRENCY_TX_MIN_ALLOWED_OUTS)
+ if (final_destinations.empty())
{
+ // if there's no destinations -- make CURRENCY_TX_MIN_ALLOWED_OUTS empty destinations
+ for(size_t i = 0; i < CURRENCY_TX_MIN_ALLOWED_OUTS; ++i)
+ final_destinations.emplace_back(0, m_account.get_public_address());
+ }
+ else if (final_destinations.size() < CURRENCY_TX_MIN_ALLOWED_OUTS)
+ {
+ // if there's not ehough destinations items (i.e. outputs), split the last one
tx_destination_entry de = final_destinations.back();
final_destinations.pop_back();
size_t items_to_be_added = CURRENCY_TX_MIN_ALLOWED_OUTS - final_destinations.size();
@@ -6509,7 +6516,7 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money,
for(auto& dst : dsts)
{
if (dst.asset_id == asset_id)
- final_destinations.emplace_back(dst.amount, dst.addr, dst.asset_id);
+ final_destinations.emplace_back(dst);
}
if (found_money > needed_money)
final_destinations.emplace_back(found_money - needed_money, m_account.get_public_address(), asset_id); // returning back the change
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 0572e03f..f4170ebc 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -650,7 +650,7 @@ namespace tools
void push_offer(const bc_services::offer_details_ex& od, currency::transaction& res_tx);
void cancel_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, uint64_t fee, currency::transaction& tx);
void update_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, const bc_services::offer_details_ex& od, currency::transaction& res_tx);
- void request_alias_registration(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward, const crypto::secret_key& authority_key = currency::null_skey);
+ void request_alias_registration(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward = 0, const crypto::secret_key& authority_key = currency::null_skey); // if the given reward is 0, then the actual reward value will be requested via RPC
void request_alias_update(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward);
bool check_available_sources(std::list& amounts);
diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp
index ad72a9b4..cf4f3940 100644
--- a/src/wallet/wallets_manager.cpp
+++ b/src/wallet/wallets_manager.cpp
@@ -1394,9 +1394,8 @@ std::string wallets_manager::get_alias_coast(const std::string& a, uint64_t& coa
if (!m_rpc_proxy->call_COMMAND_RPC_GET_ALIAS_REWARD(req, rsp))
return API_RETURN_CODE_BAD_ARG;
- coast = rsp.reward + rsp.reward/10; //add 10% of price to be sure
+ coast = rsp.reward;
return rsp.status;
-
}
std::string wallets_manager::request_alias_registration(const currency::alias_rpc_details& al, uint64_t wallet_id, uint64_t fee, currency::transaction& res_tx, uint64_t reward)
diff --git a/tests/core_tests/alias_tests.cpp b/tests/core_tests/alias_tests.cpp
index bdb68673..290d5875 100644
--- a/tests/core_tests/alias_tests.cpp
+++ b/tests/core_tests/alias_tests.cpp
@@ -100,24 +100,41 @@ gen_alias_tests::gen_alias_tests()
bool gen_alias_tests::generate(std::vector& events) const
{
+ bool r = false;
GENERATE_ACCOUNT(preminer_account);
- GENERATE_ACCOUNT(miner_account); // event index
+ GENERATE_ACCOUNT(miner_account);
m_accounts.push_back(miner_account);
- MAKE_GENESIS_BLOCK(events, blk_0, preminer_account, test_core_time::get_time()); // 0
- DO_CALLBACK(events, "configure_core"); // 1
- MAKE_ACCOUNT(events, first_acc); // 2
- MAKE_ACCOUNT(events, second_acc); // 3
- MAKE_ACCOUNT(events, third_acc); // 4
- REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_account, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); // 2N+4 (N = CURRENCY_MINED_MONEY_UNLOCK_WINDOW)
+ MAKE_GENESIS_BLOCK(events, blk_0, preminer_account, test_core_time::get_time());
size_t small_outs_to_transfer = MAX_ALIAS_PER_BLOCK + 10;
- transaction tx_1 = AUTO_VAL_INIT(tx_1);
- bool r = construct_tx_with_many_outputs(m_hardforks, events, blk_0, preminer_account.get_keys(), miner_account.get_public_address(), small_outs_to_transfer * TESTS_DEFAULT_FEE * 11, small_outs_to_transfer, TESTS_DEFAULT_FEE, tx_1);
- CHECK_AND_ASSERT_MES(r, false, "construct_tx_with_many_outputs failed");
- events.push_back(tx_1); // 2N+5
- MAKE_NEXT_BLOCK_TX1(events, blk_a, blk_0r, miner_account, tx_1); // 2N+6
- REWIND_BLOCKS_N_WITH_TIME(events, blk_ar, blk_a, miner_account, CURRENCY_MINED_MONEY_UNLOCK_WINDOW); // 4N+6
+ // rebuild genesis miner tx
+ std::vector destinations(small_outs_to_transfer, tx_destination_entry(TESTS_DEFAULT_FEE * 11, preminer_account.get_public_address()));
+ CHECK_AND_ASSERT_MES(replace_coinbase_in_genesis_block(destinations, generator, events, blk_0), false, "");
+
+ DO_CALLBACK(events, "configure_core");
+ MAKE_ACCOUNT(events, first_acc);
+ MAKE_ACCOUNT(events, second_acc);
+ MAKE_ACCOUNT(events, third_acc);
+
+ REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, preminer_account, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
+
+ size_t outs_in_a_tx = 32 /* <-- TODO change to some constant, meaning max outputs in post HF4 txs */ - 1;
+ std::vector txs;
+ while(small_outs_to_transfer > 0)
+ {
+ size_t outs_count = std::min(outs_in_a_tx, small_outs_to_transfer);
+ small_outs_to_transfer -= outs_count;
+ txs.push_back(transaction{});
+ r = construct_tx_with_many_outputs(m_hardforks, events, blk_0r, preminer_account.get_keys(), miner_account.get_public_address(), outs_count * TESTS_DEFAULT_FEE * 11, outs_count, TESTS_DEFAULT_FEE, txs.back());
+ CHECK_AND_ASSERT_MES(r, false, "construct_tx_with_many_outputs failed");
+ ADD_CUSTOM_EVENT(events, txs.back());
+ }
+ // split into two blocks because they won't fit into one
+ MAKE_NEXT_BLOCK_TX_LIST(events, blk_a, blk_0r, miner_account, std::list(txs.begin(), txs.begin() + txs.size() / 2));
+ MAKE_NEXT_BLOCK_TX_LIST(events, blk_a2, blk_a, miner_account, std::list(txs.begin() + txs.size() / 2, txs.end()));
+
+ REWIND_BLOCKS_N_WITH_TIME(events, blk_ar, blk_a2, miner_account, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
MAKE_NEXT_BLOCK(events, blk_1, blk_ar, miner_account); // 4N+7
currency::extra_alias_entry ai = AUTO_VAL_INIT(ai);
@@ -926,6 +943,7 @@ gen_alias_too_much_reward::gen_alias_too_much_reward()
bool gen_alias_too_much_reward::generate(std::vector& events) const
{
// pay for alias far too much and see, if it's ok
+ // UPDATE: since HF4 it's not ok, the reward must be precise
uint64_t ts = test_core_time::get_time();
@@ -948,9 +966,32 @@ bool gen_alias_too_much_reward::generate(std::vector& events)
bool r = get_aliases_reward_account(const_cast(reward_acc.get_public_address()));
CHECK_AND_ASSERT_MES(r, false, "get_aliases_reward_account failed");
- MAKE_TX_FEE_MIX_ATTR_EXTRA(events, tx_0, miner_acc, reward_acc, premine, TESTS_DEFAULT_FEE, 0, blk_0r, CURRENCY_TO_KEY_OUT_RELAXED, extra, false);
- MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
- DO_CALLBACK(events, "check_alias");
+ std::vector sources;
+ std::vector destinations;
+ r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc, reward_acc, premine, TESTS_DEFAULT_FEE, 0, sources, destinations);
+ CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
+ for(auto& d : destinations)
+ if (d.addr.back() == null_pub_addr)
+ d.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
+ transaction tx_0{};
+ crypto::secret_key sk{};
+ r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ ai }), empty_attachment, tx_0, get_tx_version_from_events(events), sk, 0);
+ CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
+
+ if (tx_0.version <= TRANSACTION_VERSION_PRE_HF4)
+ {
+ ADD_CUSTOM_EVENT(events, tx_0);
+ MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
+ DO_CALLBACK(events, "check_alias");
+ }
+ else
+ {
+ // post HF4: alias reward must be precise
+ DO_CALLBACK(events, "mark_invalid_tx");
+ ADD_CUSTOM_EVENT(events, tx_0);
+ DO_CALLBACK(events, "mark_invalid_block");
+ MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
+ }
return true;
}
@@ -1039,12 +1080,12 @@ bool gen_alias_too_small_reward::generate(std::vector& events)
std::list txs;
for (size_t i = 0; i < aliases_count; ++i)
{
- uint64_t alias_reward = get_alias_coast_from_fee(aliases[i].name, TESTS_DEFAULT_FEE);
+ uint64_t alias_reward = get_alias_coast_from_fee(aliases[i].name, ALIAS_VERY_INITAL_COAST);
transaction tx = AUTO_VAL_INIT(tx);
- DO_CALLBACK(events, "mark_invalid_tx"); // should be rejected, because it's paid TX_POOL_MINIMUM_FEE / 10
- if (!make_tx_reg_alias(events, generator, blk_1, aliases[i].name, aliases[i].addr, ALIAS_VERY_INITAL_COAST / 10, miner_acc, tx, used_sources))
- return false;
+ DO_CALLBACK(events, "mark_invalid_tx"); // should be rejected, because it's paid ALIAS_VERY_INITAL_COAST / 10
+ r = make_tx_reg_alias(events, generator, blk_1, aliases[i].name, aliases[i].addr, ALIAS_VERY_INITAL_COAST / 10, miner_acc, tx, used_sources);
+ CHECK_AND_ASSERT_MES(r, false, "make_tx_reg_alias failed, i: " << i);
// this block commented due to new fee median rules, TODO: review
// DO_CALLBACK(events, "mark_invalid_tx"); // should be rejected, because it's paid TX_POOL_MINIMUM_FEE / 10 less then required
@@ -1052,8 +1093,15 @@ bool gen_alias_too_small_reward::generate(std::vector& events)
// return false;
// should be accepted
- if (!make_tx_reg_alias(events, generator, blk_1, aliases[i].name, aliases[i].addr, alias_reward, miner_acc, tx, used_sources))
- return false;
+ tx = transaction{};
+ r = make_tx_reg_alias(events, generator, blk_1, aliases[i].name, aliases[i].addr, alias_reward, miner_acc, tx, used_sources);
+ CHECK_AND_ASSERT_MES(r, false, "make_tx_reg_alias failed, i: " << i);
+
+ uint64_t burnt_amount = 0;
+ CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, alias_reward, &burnt_amount), false,
+ "registration of alias '" << aliases[i].name << "' failed due to incorrect reward; expected reward: " << print_money_brief(alias_reward)
+ << "; burnt amount: " << (tx.version <= TRANSACTION_VERSION_PRE_HF4 ? print_money_brief(burnt_amount) : std::string("hidden"))
+ << "; tx: " << get_transaction_hash(tx));
txs.push_back(tx);
}
@@ -1106,11 +1154,13 @@ bool gen_alias_too_small_reward::make_tx_reg_alias(std::vector
std::vector sources;
uint64_t amount = alias_reward + TESTS_DEFAULT_FEE;
- r = fill_tx_sources(sources, events, prev_block, miner_acc.get_keys(), amount, 0, used_sources);
+ r = fill_tx_sources(sources, events, prev_block, miner_acc.get_keys(), amount, 0, used_sources, /* check for spends: */ true, /* check for unlock time: */ true);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed, requested money: " << print_money_brief(amount));
std::vector destinations;
- destinations.push_back(tx_destination_entry(alias_reward, reward_acc.get_public_address()));
+ tx_destination_entry burn_dst(alias_reward, reward_acc.get_public_address());
+ burn_dst.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask; // burning outs need to have this flags to facilitate balance check
+ destinations.push_back(burn_dst);
uint64_t sources_amount = get_sources_total_amount(sources);
if (sources_amount > alias_reward + TESTS_DEFAULT_FEE)
destinations.push_back(tx_destination_entry(sources_amount - (alias_reward + TESTS_DEFAULT_FEE), miner_acc.get_public_address())); // change
@@ -1119,6 +1169,7 @@ bool gen_alias_too_small_reward::make_tx_reg_alias(std::vector
uint64_t tx_version = get_tx_version(get_block_height(prev_block), m_hardforks);
r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx, tx_version, stub, uint64_t(0));
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
+ PRINT_EVENT_N_TEXT(events, "make_tx_reg_alias -> construct_tx()");
events.push_back(tx);
append_vector_by_another_vector(used_sources, sources);
@@ -1217,7 +1268,7 @@ bool gen_alias_switch_and_check_block_template::generate(std::vector& events)
for (auto se : sources)
input_amount += se.amount;
if (input_amount > TESTS_DEFAULT_FEE)
- destinations.push_back(tx_destination_entry(input_amount - TESTS_DEFAULT_FEE, miner_acc.get_public_address()));
+ {
+ uint64_t d = input_amount - TESTS_DEFAULT_FEE;
+ destinations.push_back(tx_destination_entry(d / 2, miner_acc.get_public_address()));
+ d -= d / 2;
+ destinations.push_back(tx_destination_entry(d, miner_acc.get_public_address()));
+ }
- tx_builder tb;
+ transaction tx{};
+ uint64_t tx_version = currency::get_tx_version(get_block_height(blk_0r) + 1, generator.get_hardforks());
+ crypto::secret_key sk{};
+ r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ ai }), empty_attachment, tx, tx_version, sk, 0);
+
+ /*tx_builder tb;
tb.step1_init();
tb.step2_fill_inputs(miner_acc.get_keys(), sources);
tb.step3_fill_outputs(destinations);
tb.m_tx.extra.push_back(ai);
tb.step4_calc_hash();
- tb.step5_sign(sources);
+ tb.step5_sign(sources);*/
- events.push_back(tb.m_tx);
- MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1, miner_acc, tb.m_tx);
+ ADD_CUSTOM_EVENT(events, tx);
+ MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1, miner_acc, tx);
return true;
}
@@ -1466,16 +1529,18 @@ bool gen_alias_in_coinbase::generate(std::vector& events) cons
set_hard_fork_heights_to_generator(generator);
DO_CALLBACK(events, "configure_core");
+ MAKE_NEXT_BLOCK(events, blk_1, blk_0, miner_acc);
+
// reg an alias using coinbase
extra_alias_entry ai = AUTO_VAL_INIT(ai);
ai.m_alias = "emmanuel.goldstein"; // long enough alias to minimize it's cost
ai.m_address = miner_acc.get_public_address();
- block blk_1 = AUTO_VAL_INIT(blk_1);
- bool r = generator.construct_pow_block_with_alias_info_in_coinbase(miner_acc, blk_0, ai, blk_1);
+ block blk_2 = AUTO_VAL_INIT(blk_2);
+ bool r = generator.construct_pow_block_with_alias_info_in_coinbase(miner_acc, blk_1, ai, blk_2);
CHECK_AND_ASSERT_MES(r, false, "construct_block_gentime_with_coinbase_cb failed");
- events.push_back(blk_1);
+ events.push_back(blk_2);
DO_CALLBACK_PARAMS_STR(events, "check", t_serializable_object_to_blob(ai));
@@ -1487,11 +1552,11 @@ bool gen_alias_in_coinbase::generate(std::vector& events) cons
r = sign_extra_alias_entry(ai, miner_acc.get_public_address().spend_public_key, miner_acc.get_keys().spend_secret_key);
CHECK_AND_ASSERT_MES(r, false, "sign_extra_alias_entry failed");
- block blk_2 = AUTO_VAL_INIT(blk_2);
- r = generator.construct_pow_block_with_alias_info_in_coinbase(miner_acc, blk_1, ai, blk_2);
+ block blk_3 = AUTO_VAL_INIT(blk_3);
+ r = generator.construct_pow_block_with_alias_info_in_coinbase(miner_acc, blk_2, ai, blk_3);
CHECK_AND_ASSERT_MES(r, false, "construct_block_gentime_with_coinbase_cb failed");
- events.push_back(blk_2);
+ events.push_back(blk_3);
DO_CALLBACK_PARAMS_STR(events, "check", t_serializable_object_to_blob(ai));
diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp
index df5ef7f1..fdbb1f48 100644
--- a/tests/core_tests/chaingen.cpp
+++ b/tests/core_tests/chaingen.cpp
@@ -1023,18 +1023,90 @@ uint64_t test_generator::get_last_n_blocks_fee_median(const crypto::hash& head_b
bool test_generator::construct_pow_block_with_alias_info_in_coinbase(const account_base& acc, const block& prev_block, const extra_alias_entry& ai, block& b)
{
- return construct_block_gentime_with_coinbase_cb(prev_block, acc, [&acc, &ai](transaction& miner_tx){
+ return construct_block_gentime_with_coinbase_cb(prev_block, acc, [&acc, &ai](transaction& miner_tx, const currency::keypair& tx_key){
+ bool r = false;
miner_tx.extra.push_back(ai);
- if (ai.m_sign.empty())
+
+ uint64_t alias_cost = ai.m_sign.empty() ? get_alias_coast_from_fee(ai.m_alias, ALIAS_VERY_INITAL_COAST) : 0;
+ uint64_t block_reward = get_outs_money_amount(miner_tx, acc.get_keys());
+ CHECK_AND_ASSERT_MES(alias_cost < block_reward, false, "Alias '" << ai.m_alias << "' can't be registered via block coinbase, because it's price: " << print_money(alias_cost) << " is greater than block reward: " << print_money(block_reward));
+ uint64_t new_block_reward = block_reward - alias_cost;
+ if (miner_tx.version > TRANSACTION_VERSION_PRE_HF4)
{
- // if no alias update - reduce block reward by alias cost
- uint64_t alias_cost = get_alias_coast_from_fee(ai.m_alias, TESTS_DEFAULT_FEE);
- uint64_t block_reward = get_outs_money_amount(miner_tx);
- CHECK_AND_ASSERT_MES(alias_cost <= block_reward, false, "Alias '" << ai.m_alias << "' can't be registered via block coinbase, because it's price: " << print_money(alias_cost) << " is greater than block reward: " << print_money(block_reward));
- block_reward -= alias_cost;
+ // ZC outs
miner_tx.vout.clear();
- if (block_reward > 0)
+
+ tx_generation_context tx_gen_context{};
+ tx_gen_context.resize(/* ZC ins: */ 0, /* OUTS: */ alias_cost != 0 ? 3 : 2);
+ std::set deriv_cache;
+ finalized_tx fin_tx_stub{};
+ size_t output_index = 0;
+
+ // outputs 0, 1: block reward splitted into two
+ tx_destination_entry de{new_block_reward / 2, acc.get_public_address()};
+ de.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id;
+ r = construct_tx_out(de, tx_key.sec, output_index, miner_tx, deriv_cache, account_keys(),
+ tx_gen_context.asset_id_blinding_masks[output_index], tx_gen_context.amount_blinding_masks[output_index],
+ tx_gen_context.blinded_asset_ids[output_index], tx_gen_context.amount_commitments[output_index], fin_tx_stub);
+ CHECK_AND_ASSERT_MES(r, false, "construct_tx_out failed for output " << output_index);
+ tx_gen_context.amounts[output_index] = de.amount;
+ tx_gen_context.asset_ids[output_index] = crypto::point_t(de.asset_id);
+ tx_gen_context.asset_id_blinding_mask_x_amount_sum += tx_gen_context.asset_id_blinding_masks[output_index] * de.amount;
+ tx_gen_context.amount_blinding_masks_sum += tx_gen_context.amount_blinding_masks[output_index];
+ tx_gen_context.amount_commitments_sum += tx_gen_context.amount_commitments[output_index];
+
+ ++output_index;
+ de = tx_destination_entry{new_block_reward - new_block_reward / 2, acc.get_public_address()};
+ de.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id;
+ r = construct_tx_out(de, tx_key.sec, output_index, miner_tx, deriv_cache, account_keys(),
+ tx_gen_context.asset_id_blinding_masks[output_index], tx_gen_context.amount_blinding_masks[output_index],
+ tx_gen_context.blinded_asset_ids[output_index], tx_gen_context.amount_commitments[output_index], fin_tx_stub);
+ CHECK_AND_ASSERT_MES(r, false, "construct_tx_out failed for output " << output_index);
+ tx_gen_context.amounts[output_index] = de.amount;
+ tx_gen_context.asset_ids[output_index] = crypto::point_t(de.asset_id);
+ tx_gen_context.asset_id_blinding_mask_x_amount_sum += tx_gen_context.asset_id_blinding_masks[output_index] * de.amount;
+ tx_gen_context.amount_blinding_masks_sum += tx_gen_context.amount_blinding_masks[output_index];
+ tx_gen_context.amount_commitments_sum += tx_gen_context.amount_commitments[output_index];
+
+ if (alias_cost != 0)
{
+ // output 2: alias reward
+ ++output_index;
+ de = tx_destination_entry{alias_cost, null_pub_addr};
+ de.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
+ r = construct_tx_out(de, tx_key.sec, output_index, miner_tx, deriv_cache, account_keys(),
+ tx_gen_context.asset_id_blinding_masks[output_index], tx_gen_context.amount_blinding_masks[output_index],
+ tx_gen_context.blinded_asset_ids[output_index], tx_gen_context.amount_commitments[output_index], fin_tx_stub);
+ CHECK_AND_ASSERT_MES(r, false, "construct_tx_out failed for output " << output_index);
+ tx_gen_context.amounts[output_index] = de.amount;
+ tx_gen_context.asset_ids[output_index] = crypto::point_t(de.asset_id);
+ tx_gen_context.asset_id_blinding_mask_x_amount_sum += tx_gen_context.asset_id_blinding_masks[output_index] * de.amount;
+ tx_gen_context.amount_blinding_masks_sum += tx_gen_context.amount_blinding_masks[output_index];
+ tx_gen_context.amount_commitments_sum += tx_gen_context.amount_commitments[output_index];
+ }
+
+ // reconstruct all proofs
+ crypto::hash tx_id = get_transaction_hash(miner_tx);
+ miner_tx.proofs.clear();
+ // empty asset surjection proof
+ miner_tx.proofs.emplace_back(std::move(currency::zc_asset_surjection_proof{}));
+ // range proofs
+ currency::zc_outs_range_proof range_proofs{};
+ r = generate_zc_outs_range_proof(tx_id, 0, tx_gen_context, miner_tx.vout, range_proofs);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to generate zc_outs_range_proof()");
+ miner_tx.proofs.emplace_back(std::move(range_proofs));
+ // balance proof
+ currency::zc_balance_proof balance_proof{};
+ r = generate_tx_balance_proof(miner_tx, tx_id, tx_gen_context, block_reward, balance_proof);
+ CHECK_AND_ASSERT_MES(r, false, "generate_tx_balance_proof failed");
+ miner_tx.proofs.emplace_back(std::move(balance_proof));
+ }
+ else
+ {
+ // old behaviour, bare non-hidden outs
+ if (ai.m_sign.empty())
+ {
+ miner_tx.vout.clear();
bool null_out_key = false;
auto f = [&acc, &miner_tx, &null_out_key](uint64_t amount){
keypair kp = AUTO_VAL_INIT(kp);
@@ -1043,7 +1115,7 @@ bool test_generator::construct_pow_block_with_alias_info_in_coinbase(const accou
otk.key = null_out_key ? null_pkey : kp.pub;
miner_tx.vout.push_back(tx_out_bare({ amount, otk }));
};
- decompose_amount_into_digits(block_reward, DEFAULT_DUST_THRESHOLD, f, f);
+ decompose_amount_into_digits(new_block_reward, DEFAULT_DUST_THRESHOLD, f, f);
null_out_key = true;
f(alias_cost); // add an output for burning alias cost into ashes
}
@@ -1351,7 +1423,7 @@ bool fill_tx_sources(std::vector& sources, const std:
if (sout.type().hash_code() == typeid(uint64_t).hash_code()) // output by global index
{
uint64_t gindex = boost::get(sout);
- auto& outs_by_amount = outs[s.amount];
+ auto& outs_by_amount = outs[s.amount_for_global_output_index()];
if (gindex >= outs_by_amount.size())
return false;
outs_by_amount[gindex].spent = true;
@@ -1703,7 +1775,7 @@ bool construct_tx_with_many_outputs(const currency::hard_forks_descriptor& hf, s
uint64_t total_amount, size_t outputs_count, uint64_t fee, currency::transaction& tx, bool use_ref_by_id /* = false */)
{
std::vector sources;
- bool r = fill_tx_sources(sources, events, blk_head, keys_from, total_amount + fee, 0, true, false, use_ref_by_id);
+ bool r = fill_tx_sources(sources, events, blk_head, keys_from, total_amount + fee, 0, true, true, use_ref_by_id);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
std::vector destinations;
@@ -2255,6 +2327,53 @@ bool shuffle_source_entries(std::vector& sources)
return true;
}
+bool replace_coinbase_in_genesis_block(const std::vector& destinations, test_generator& generator, std::vector& events, currency::block& genesis_block)
+{
+ bool r = false;
+ generator.remove_block_info(genesis_block);
+ events.pop_back();
+
+ // remember premine amount
+ uint64_t premine_amount = get_outs_money_amount(genesis_block.miner_tx);
+
+ // replace tx key
+ keypair tx_key = keypair::generate();
+ for(auto& el : genesis_block.miner_tx.extra)
+ {
+ if (el.type() == typeid(crypto::public_key))
+ {
+ boost::get(el) = tx_key.pub;
+ break;
+ }
+ }
+ uint64_t total_amount = 0;
+
+ // replace outputs
+ genesis_block.miner_tx.vout.clear();
+
+ for(size_t output_index = 0; output_index < destinations.size() + 1; ++output_index)
+ {
+ uint64_t amount = output_index < destinations.size() ? destinations[output_index].amount : premine_amount - total_amount;
+ const account_public_address& addr = output_index < destinations.size() ? destinations[output_index].addr.back() : destinations.back().addr.back();
+
+ crypto::key_derivation derivation{};
+ bool r = crypto::generate_key_derivation(addr.view_public_key, tx_key.sec, derivation);
+ CHECK_AND_ASSERT_MES(r, false, "generate_key_derivation failed");
+
+ txout_to_key target{};
+ r = crypto::derive_public_key(derivation, output_index, addr.spend_public_key, target.key);
+ CHECK_AND_ASSERT_MES(r, false, "derive_public_key failed");
+ genesis_block.miner_tx.vout.emplace_back(tx_out_bare{amount, target});
+ total_amount += amount;
+ CHECK_AND_ASSERT_MES(total_amount <= premine_amount, false, "total amount is greater than premine amount");
+ }
+
+ events.push_back(genesis_block);
+ std::vector block_sizes;
+ generator.add_block(genesis_block, 0, block_sizes, 0, 0, std::list{}, null_hash);
+ return true;
+}
+
//------------------------------------------------------------------------------
test_chain_unit_base::test_chain_unit_base()
diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h
index b904770a..663593c7 100644
--- a/tests/core_tests/chaingen.h
+++ b/tests/core_tests/chaingen.h
@@ -745,6 +745,9 @@ bool check_mixin_value_for_each_input(size_t mixin, const crypto::hash& tx_id, c
bool shuffle_source_entry(currency::tx_source_entry& se);
bool shuffle_source_entries(std::vector& sources);
+// one output will be created for each destination entry and one additional output to add up to old coinbase total amount
+bool replace_coinbase_in_genesis_block(const std::vector& destinations, test_generator& generator, std::vector& events, currency::block& genesis_block);
+
//--------------------------------------------------------------------------
template
auto do_check_tx_verification_context(const currency::tx_verification_context& tvc, bool tx_added, size_t event_index, const currency::transaction& tx, t_test_class& validator, int)
@@ -954,10 +957,13 @@ bool test_generator::construct_block_gentime_with_coinbase_cb(const currency::bl
uint64_t block_reward_without_fee = 0;
- r = construct_miner_tx(height, epee::misc_utils::median(block_sizes), already_generated_coins, 0 /* current_block_size !HACK! */, 0, acc.get_public_address(), acc.get_public_address(), miner_tx, block_reward_without_fee, get_tx_version(height, m_hardforks), currency::blobdata(), 1);
+ currency::keypair tx_sec_key = currency::keypair::generate();
+ r = construct_miner_tx(height, epee::misc_utils::median(block_sizes), already_generated_coins, 0 /* current_block_size !HACK! */, 0,
+ acc.get_public_address(), acc.get_public_address(), miner_tx, block_reward_without_fee, get_tx_version(height, m_hardforks), currency::blobdata(), /* max outs: */ 1,
+ /* pos: */ false, currency::pos_entry(), /* ogc_ptr: */ nullptr, &tx_sec_key);
CHECK_AND_ASSERT_MES(r, false, "construct_miner_tx failed");
- if (!cb(miner_tx))
+ if (!cb(miner_tx, tx_sec_key))
return false;
currency::wide_difficulty_type diff = get_difficulty_for_next_block(prev_id, true);
diff --git a/tests/core_tests/chaingen_helpers.h b/tests/core_tests/chaingen_helpers.h
index b984fde7..a5e59ab8 100644
--- a/tests/core_tests/chaingen_helpers.h
+++ b/tests/core_tests/chaingen_helpers.h
@@ -283,30 +283,40 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf,
const alias_entry_t& ae,
test_generator& generator)
{
- std::vector ex;
- ex.push_back(ae);
+ std::vector extra;
+ extra.push_back(ae);
currency::account_base reward_acc;
currency::account_keys& ak = const_cast(reward_acc.get_keys());
currency::get_aliases_reward_account(ak.account_address, ak.view_secret_key);
uint64_t alias_reward = 0;
if (get_block_height(head_block) < ALIAS_MEDIAN_RECALC_INTERWAL)
- alias_reward = get_alias_coast_from_fee(ae.m_alias, ALIAS_VERY_INITAL_COAST); // don't ask why
+ {
+ alias_reward = currency::get_alias_coast_from_fee(ae.m_alias, ALIAS_VERY_INITAL_COAST); // don't ask why
+ }
else
+ {
LOCAL_ASSERT(false); // not implemented yet, see also all the mess around blockchain_storage::get_tx_fee_median(), get_tx_fee_median_effective_index() etc.
+ }
- MAKE_TX_MIX_LIST_EXTRA_MIX_ATTR(events,
- tx_set,
- miner_acc,
- reward_acc,
- alias_reward,
- 0,
- head_block,
- CURRENCY_TO_KEY_OUT_RELAXED,
- ex,
- std::vector());
-
+ std::vector sources;
+ std::vector destinations;
+ bool r = fill_tx_sources_and_destinations(events, head_block, miner_acc, reward_acc, alias_reward, TESTS_DEFAULT_FEE, 0, sources, destinations);
+ CHECK_AND_ASSERT_MES(r, false, "alias: fill_tx_sources_and_destinations failed");
+ for(auto& el : destinations)
+ {
+ if (el.addr.front() == reward_acc.get_public_address())
+ el.flags |= currency::tx_destination_entry_flags::tdef_explicit_native_asset_id | currency::tx_destination_entry_flags::tdef_zero_amount_blinding_mask; // all alias-burn outputs must have explicit native asset id and zero amount mask
+ }
+
+ uint64_t tx_version = currency::get_tx_version(get_block_height(head_block) + 1, generator.get_hardforks()); // assuming the tx will be in the next block (head_block + 1)
+ tx_set.emplace_back();
+ r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx_set.back(), tx_version, generator.last_tx_generated_secret_key, 0);
+ PRINT_EVENT_N_TEXT(events, "put_alias_via_tx_to_list()");
+ events.push_back(tx_set.back());
+
+ // make sure the tx's amount commitments balance each other correctly
uint64_t burnt_amount = 0;
if (!check_native_coins_amount_burnt_in_outs(tx_set.back(), alias_reward, &burnt_amount))
{
diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp
index 04e21245..1904ce7b 100644
--- a/tests/core_tests/chaingen_main.cpp
+++ b/tests/core_tests/chaingen_main.cpp
@@ -118,7 +118,7 @@ bool test_parse_hardfork_str_mask()
{
static_assert(ZANO_HARDFORKS_TOTAL >= 5, "this test was made in assumption that this condition holds");
auto v_range = [](size_t a, size_t b) -> std::vector { std::vector r; for(size_t i = a; i <= b; ++i) r.push_back(i); return r; };
- auto v_concat = [](const std::vector& a, const std::vector& b) -> std::vector { std::vector r = a; r.insert(r.end(), b.begin(), b.end()); };
+ auto v_concat = [](const std::vector& a, const std::vector& b) -> std::vector { std::vector r = a; r.insert(r.end(), b.begin(), b.end()); return r; };
const std::vector res_empty;
const std::vector res_all_hf = v_range(0, ZANO_HARDFORKS_TOTAL - 1);
std::string hf_total_num_str_m_1 = epee::string_tools::num_to_string_fast(ZANO_HARDFORKS_TOTAL - 1);
@@ -386,7 +386,7 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
#define GENERATE_AND_PLAY(genclass) \
- if((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test))) \
+ if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test)))) \
{ \
TIME_MEASURE_START_MS(t); \
++tests_count; \
@@ -396,14 +396,14 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
failed_tests.insert(#genclass); \
LOCAL_ASSERT(false); \
if (stop_on_first_fail) \
- return 1; \
+ skip_all_till_the_end = true; \
} \
TIME_MEASURE_FINISH_MS(t); \
tests_running_time.push_back(std::make_pair(#genclass, t)); \
}
#define GENERATE_AND_PLAY_INTERMITTED_BY_BLOCKCHAIN_SAVELOAD(genclass) \
- if(run_single_test.empty() || run_single_test == #genclass) \
+ if (!skip_all_till_the_end && (run_single_test.empty() || run_single_test == #genclass)) \
{ \
const char* testname = #genclass " (BC saveload)"; \
TIME_MEASURE_START_MS(t); \
@@ -414,29 +414,29 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
failed_tests.insert(testname); \
LOCAL_ASSERT(false); \
if (stop_on_first_fail) \
- return 1; \
+ skip_all_till_the_end = true; \
} \
TIME_MEASURE_FINISH_MS(t); \
tests_running_time.push_back(std::make_pair(testname, t)); \
}
#define GENERATE_AND_PLAY_HF(genclass, hardfork_str_mask) \
- if((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test))) \
+ if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test)))) \
{ \
std::vector hardforks = parse_hardfork_str_mask(hardfork_str_mask); \
CHECK_AND_ASSERT_MES(!hardforks.empty(), false, "invalid hardforks mask: " << hardfork_str_mask); \
- for(size_t hfid : hardforks) \
+ for(size_t i = 0; i < hardforks.size() && !skip_all_till_the_end; ++i) \
{ \
- std::string tns = std::string(#genclass) + " @ HF " + epee::string_tools::num_to_string_fast(hfid); \
+ std::string tns = std::string(#genclass) + " @ HF " + epee::string_tools::num_to_string_fast(hardforks[i]); \
const char* testname = tns.c_str(); \
TIME_MEASURE_START_MS(t); \
++tests_count; \
- if (!generate_and_play(testname, hfid)) \
+ if (!generate_and_play(testname, hardforks[i])) \
{ \
failed_tests.insert(testname); \
LOCAL_ASSERT(false); \
if (stop_on_first_fail) \
- return 1; \
+ skip_all_till_the_end = true; \
} \
TIME_MEASURE_FINISH_MS(t); \
tests_running_time.push_back(std::make_pair(testname, t)); \
@@ -889,6 +889,8 @@ int main(int argc, char* argv[])
stop_on_first_fail = command_line::get_arg(g_vm, arg_stop_on_fail);
}
+
+ bool skip_all_till_the_end = false;
size_t tests_count = 0;
size_t unique_tests_count = 0;
size_t serious_failures_count = 0;
@@ -1031,23 +1033,22 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY_HF(gen_no_attchments_in_coinbase, "3");
GENERATE_AND_PLAY(gen_no_attchments_in_coinbase_gentime);
- //GENERATE_AND_PLAY(gen_alias_tests);
- GENERATE_AND_PLAY_HF(gen_alias_tests, "4,1");
- GENERATE_AND_PLAY(gen_alias_strange_data);
- GENERATE_AND_PLAY(gen_alias_concurrency_with_switch);
- GENERATE_AND_PLAY(gen_alias_same_alias_in_tx_pool);
- GENERATE_AND_PLAY(gen_alias_switch_and_tx_pool);
- GENERATE_AND_PLAY(gen_alias_update_after_addr_changed);
- GENERATE_AND_PLAY(gen_alias_blocking_reg_by_invalid_tx);
- GENERATE_AND_PLAY(gen_alias_blocking_update_by_invalid_tx);
+ GENERATE_AND_PLAY_HF(gen_alias_tests, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_strange_data, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_concurrency_with_switch, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_same_alias_in_tx_pool, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_switch_and_tx_pool, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_update_after_addr_changed, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_blocking_reg_by_invalid_tx, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_blocking_update_by_invalid_tx, "3-*");
GENERATE_AND_PLAY_HF(gen_alias_reg_with_locked_money, "*");
- GENERATE_AND_PLAY(gen_alias_too_small_reward);
- GENERATE_AND_PLAY(gen_alias_too_much_reward);
+ GENERATE_AND_PLAY_HF(gen_alias_too_small_reward, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_too_much_reward, "3-*");
GENERATE_AND_PLAY_HF(gen_alias_tx_no_outs, "*");
- GENERATE_AND_PLAY(gen_alias_switch_and_check_block_template);
- GENERATE_AND_PLAY(gen_alias_too_many_regs_in_block_template);
- GENERATE_AND_PLAY(gen_alias_update_for_free);
- GENERATE_AND_PLAY(gen_alias_in_coinbase);
+ GENERATE_AND_PLAY_HF(gen_alias_switch_and_check_block_template, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_too_many_regs_in_block_template, "3"); // disabled in HF4 due to tx outputs count limitation
+ GENERATE_AND_PLAY_HF(gen_alias_update_for_free, "3-*");
+ GENERATE_AND_PLAY_HF(gen_alias_in_coinbase, "3-*");
GENERATE_AND_PLAY(gen_wallet_basic_transfer);
GENERATE_AND_PLAY(gen_wallet_refreshing_on_chain_switch);
@@ -1062,8 +1063,8 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(gen_wallet_transfers_and_outdated_unconfirmed_txs);
GENERATE_AND_PLAY(gen_wallet_transfers_and_chain_switch);
GENERATE_AND_PLAY(gen_wallet_decrypted_attachments);
- GENERATE_AND_PLAY(gen_wallet_alias_and_unconfirmed_txs);
- GENERATE_AND_PLAY(gen_wallet_alias_via_special_wallet_funcs);
+ GENERATE_AND_PLAY_HF(gen_wallet_alias_and_unconfirmed_txs, "3-*");
+ GENERATE_AND_PLAY_HF(gen_wallet_alias_via_special_wallet_funcs, "3-*");
GENERATE_AND_PLAY(gen_wallet_fake_outputs_randomness);
GENERATE_AND_PLAY(gen_wallet_fake_outputs_not_enough);
GENERATE_AND_PLAY(gen_wallet_offers_basic);
@@ -1284,6 +1285,9 @@ int main(int argc, char* argv[])
}
}
+ if (skip_all_till_the_end)
+ std::cout << ENDL << concolor::yellow << "(execution interrupted at the first failure; not all tests were run)" << ENDL;
+
serious_failures_count = failed_tests.size() - failed_postponed_tests_count;
if (!postponed_tests.empty())
diff --git a/tests/core_tests/checkpoints_tests.cpp b/tests/core_tests/checkpoints_tests.cpp
index 49eeafc2..5692734b 100644
--- a/tests/core_tests/checkpoints_tests.cpp
+++ b/tests/core_tests/checkpoints_tests.cpp
@@ -827,7 +827,7 @@ bool gen_no_attchments_in_coinbase_gentime::generate(std::vectortransfer(alice_balance - TESTS_DEFAULT_FEE, m_accounts[MINER_ACC_IDX].get_public_address(), tx_2, native_coin_asset_id);
+ alice_wlt->transfer(alice_balance - TESTS_DEFAULT_FEE, m_accounts[BOB_ACC_IDX].get_public_address(), tx_2, native_coin_asset_id);
CHECK_AND_ASSERT_MES(tx_2.vout.size() == 2, false, "unexpected tx_2.vout.size : " << tx_2.vout.size());
for(auto& out : tx_2.vout)
@@ -325,11 +327,28 @@ bool assets_and_explicit_native_coins_in_outs::c2_alice_deploys_asset(currency::
// finally, get this tx confirmed
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
- r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
+ r = mine_next_pow_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
+ std::shared_ptr bob_wlt = init_playtime_test_wallet(events, c, m_accounts[BOB_ACC_IDX]);
+ bob_wlt->refresh();
+ uint64_t bob_balance = alice_balance - TESTS_DEFAULT_FEE;
+ CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt, "Bob", bob_balance, 0, bob_balance, 0, 0), false, "");
+
+ extra_alias_entry ae{};
+ ae.m_alias = "kris.kelvin";
+ ae.m_address = m_accounts[BOB_ACC_IDX].get_public_address();
+ transaction tx_3{};
+ bob_wlt->request_alias_registration(ae, tx_3, TESTS_DEFAULT_FEE);
+
+ // finally, get this tx confirmed
+ CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
+ r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
+ CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
+ CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count());
+
return true;
}
diff --git a/tests/core_tests/wallet_tests.cpp b/tests/core_tests/wallet_tests.cpp
index e9a2141d..08c113eb 100644
--- a/tests/core_tests/wallet_tests.cpp
+++ b/tests/core_tests/wallet_tests.cpp
@@ -1616,9 +1616,6 @@ void gen_wallet_decrypted_attachments::on_transfer2(const tools::wallet_public::
gen_wallet_alias_and_unconfirmed_txs::gen_wallet_alias_and_unconfirmed_txs()
{
- m_hardforks.set_hardfork_height(1, 0);
- m_hardforks.set_hardfork_height(2, 0);
-
REGISTER_CALLBACK_METHOD(gen_wallet_alias_and_unconfirmed_txs, c1);
REGISTER_CALLBACK_METHOD(gen_wallet_alias_and_unconfirmed_txs, c2);
REGISTER_CALLBACK_METHOD(gen_wallet_alias_and_unconfirmed_txs, c3);
@@ -1636,17 +1633,29 @@ bool gen_wallet_alias_and_unconfirmed_txs::generate(std::vector({ ai }), true);
- uint64_t amount = get_alias_coast_from_fee(std::string(ALIAS_MINIMUM_PUBLIC_SHORT_NAME_ALLOWED, 'a'), TESTS_DEFAULT_FEE);
- MAKE_TX(events, tx_0, miner_acc, alice_acc, amount, blk_0r);
- MAKE_TX(events, tx_1, miner_acc, alice_acc, amount, blk_0r);
- MAKE_TX(events, tx_2, miner_acc, bob_acc, amount, blk_0r);
- MAKE_TX(events, tx_3, miner_acc, bob_acc, amount, blk_0r);
+ std::vector sources;
+ std::vector destinations;
+ bool r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc, null_account, get_alias_coast_from_fee(ai.m_alias, ALIAS_VERY_INITAL_COAST), TESTS_DEFAULT_FEE, 0, sources, destinations);
+ CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
+ for(auto& d : destinations)
+ if (d.addr.back() == null_pub_addr)
+ d.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
+ transaction tx_alice_alias{};
+ crypto::secret_key sk{};
+ r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector({ ai }), empty_attachment, tx_alice_alias, get_tx_version_from_events(events), sk, 0);
+ CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
+ ADD_CUSTOM_EVENT(events, tx_alice_alias);
+
+ uint64_t alias_cost = get_alias_coast_from_fee(std::string(ALIAS_MINIMUM_PUBLIC_SHORT_NAME_ALLOWED, 'a'), ALIAS_VERY_INITAL_COAST);
+ MAKE_TX(events, tx_0, miner_acc, alice_acc, alias_cost, blk_0r);
+ MAKE_TX(events, tx_1, miner_acc, alice_acc, TESTS_DEFAULT_FEE, blk_0r);
+ MAKE_TX(events, tx_2, miner_acc, bob_acc, alias_cost, blk_0r);
+ MAKE_TX(events, tx_3, miner_acc, bob_acc, TESTS_DEFAULT_FEE, blk_0r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_1, blk_0r, miner_acc, std::list({ tx_0, tx_1, tx_2, tx_3, tx_alice_alias }));
REWIND_BLOCKS_N(events, blk_1r, blk_1, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE);
@@ -1675,12 +1684,14 @@ bool gen_wallet_alias_and_unconfirmed_txs::c1(currency::core& c, size_t ev_index
ai.m_address = m_accounts[BOB_ACC_IDX].get_public_address();
ai.m_view_key.push_back(m_accounts[BOB_ACC_IDX].get_keys().view_secret_key);
- uint64_t alias_reward = get_alias_coast_from_fee(ai.m_alias, TESTS_DEFAULT_FEE);
- bool r = check_balance_via_wallet(*bob_wlt.get(), "bob_wlt", alias_reward * 2);
+ uint64_t alias_reward = get_alias_coast_from_fee(ai.m_alias, ALIAS_VERY_INITAL_COAST);
+ bool r = check_balance_via_wallet(*bob_wlt.get(), "bob_wlt", alias_reward + TESTS_DEFAULT_FEE);
CHECK_AND_ASSERT_MES(r, false, "Incorrect wallet balance");
- std::vector stub_events_vec;
- MAKE_TEST_WALLET_TX_EXTRA(stub_events_vec, tx, bob_wlt, alias_reward, null_account, std::vector({ ai }));
+ transaction tx{};
+ std::vector destinations({tx_destination_entry(alias_reward, null_pub_addr)});
+ destinations.back().flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
+ bob_wlt->transfer(destinations, 0, 0, TESTS_DEFAULT_FEE, std::vector({ ai }), empty_attachment, tx);
CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, alias_reward), false, "Generated tx has invalid alias reward");
@@ -1711,12 +1722,14 @@ bool gen_wallet_alias_and_unconfirmed_txs::c2(currency::core& c, size_t ev_index
ai.m_address = someone.get_public_address();
ai.m_view_key.push_back(someone.get_keys().view_secret_key);
- uint64_t alias_reward = get_alias_coast_from_fee(ai.m_alias, TESTS_DEFAULT_FEE);
- bool r = check_balance_via_wallet(*bob_wlt.get(), "bob_wlt", alias_reward * 2);
+ uint64_t alias_reward = get_alias_coast_from_fee(ai.m_alias, ALIAS_VERY_INITAL_COAST);
+ bool r = check_balance_via_wallet(*bob_wlt.get(), "bob_wlt", alias_reward + TESTS_DEFAULT_FEE);
CHECK_AND_ASSERT_MES(r, false, "Incorrect wallet balance");
- std::vector stub_events_vec;
- MAKE_TEST_WALLET_TX_EXTRA(stub_events_vec, tx, bob_wlt, alias_reward, null_account, std::vector({ ai }));
+ transaction tx{};
+ std::vector destinations({tx_destination_entry(alias_reward, null_pub_addr)});
+ destinations.back().flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
+ bob_wlt->transfer(destinations, 0, 0, TESTS_DEFAULT_FEE, std::vector({ ai }), empty_attachment, tx);
CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, alias_reward), false, "Generated tx has invalid alias reward");
@@ -1748,8 +1761,11 @@ bool gen_wallet_alias_and_unconfirmed_txs::c3(currency::core& c, size_t ev_index
bool r = sign_extra_alias_entry(ai, m_accounts[ALICE_ACC_IDX].get_keys().account_address.spend_public_key, m_accounts[ALICE_ACC_IDX].get_keys().spend_secret_key);
CHECK_AND_ASSERT_MES(r, false, "sign_extra_alias_entry failed");
- std::vector stub_events_vec;
- MAKE_TEST_WALLET_TX_EXTRA(stub_events_vec, tx, alice_wlt, 1, null_account, std::vector({ ai }));
+ transaction tx{};
+ std::vector destinations({tx_destination_entry(1, null_pub_addr)});
+ destinations.back().flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
+ alice_wlt->transfer(destinations, 0, 0, TESTS_DEFAULT_FEE, std::vector({ ai }), empty_attachment, tx);
+
bool has_relates_alias_in_unconfirmed = false;
alice_wlt->scan_tx_pool(has_relates_alias_in_unconfirmed);
@@ -1781,24 +1797,26 @@ bool gen_wallet_alias_via_special_wallet_funcs::generate(std::vector({ tx_0, tx_1, tx_2 }));
+ MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner_acc, std::list({ tx_0, tx_1, tx_2 }));
- REWIND_BLOCKS_N(events, blk_1r, blk_1, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE);
+ REWIND_BLOCKS_N(events, blk_3r, blk_3, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE);
DO_CALLBACK(events, "c1");
@@ -1812,14 +1830,13 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_
bool received_money;
std::atomic atomic_false = ATOMIC_VAR_INIT(false);
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
- CHECK_AND_ASSERT_MES(blocks_fetched == 1 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE, false, "Incorrect numbers of blocks fetched");
+ CHECK_AND_ASSERT_MES(blocks_fetched == 2 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE, false, "Incorrect numbers of blocks fetched");
extra_alias_entry ai = AUTO_VAL_INIT(ai);
ai.m_alias = "alicealice";
ai.m_address = m_accounts[ALICE_ACC_IDX].get_public_address();
- uint64_t alias_reward = get_alias_coast_from_fee(ai.m_alias, TESTS_DEFAULT_FEE);
transaction res_tx = AUTO_VAL_INIT(res_tx);
- alice_wlt->request_alias_registration(ai, res_tx, TESTS_DEFAULT_FEE, alias_reward);
+ alice_wlt->request_alias_registration(ai, res_tx, TESTS_DEFAULT_FEE); // use 0 reward for alias so wallet calculate the correct reward by its own
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool");
@@ -1827,9 +1844,9 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool");
- CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == 2 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE + 1, false, "Incorrect blockchain size");
+ CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == 3 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE + 1, false, "Incorrect blockchain size");
- uint64_t biggest_alias_reward = get_alias_coast_from_fee("a", TESTS_DEFAULT_FEE);
+ uint64_t biggest_alias_reward = get_alias_coast_from_fee("a", ALIAS_VERY_INITAL_COAST);
std::shared_ptr l(new wlt_lambda_on_transfer2_wrapper(
[biggest_alias_reward](const tools::wallet_public::wallet_transfer_info& wti, const std::list& balances, uint64_t total_mined) -> bool {
return std::count(wti.remote_aliases.begin(), wti.remote_aliases.end(), "minerminer") == 1 &&
@@ -1847,7 +1864,7 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool");
- CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == 2 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE + 2, false, "Incorrect blockchain size");
+ CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == 3 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE + 2, false, "Incorrect blockchain size");
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
CHECK_AND_ASSERT_MES(blocks_fetched == 2, false, "Incorrect numbers of blocks fetched");
@@ -1860,7 +1877,7 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool");
- CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == 2 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE + 3, false, "Incorrect blockchain size");
+ CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == 3 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE + 3, false, "Incorrect blockchain size");
extra_alias_entry ai2 = AUTO_VAL_INIT(ai2);
r = c.get_blockchain_storage().get_alias_info(ai.m_alias, ai2);