forked from lthn/blockchain
Merge branch 'cryptoassets' of github.com:hyle-team/zano into cryptoassets
This commit is contained in:
commit
7b228f07b4
22 changed files with 390 additions and 138 deletions
|
|
@ -1323,7 +1323,7 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t
|
|||
if (is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM)) // TODO @#@# consider moving to validate_tx_for_hardfork_specific_terms
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment.empty(), false, "coinbase transaction has attachments; attachments are not allowed for coinbase transactions.");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.proofs.size() == 3, false, "coinbase transaction has incorrect number of proofs (" << b.miner_tx.proofs.size() << "), expected 2");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.proofs.size() == 3, false, "coinbase transaction has incorrect number of proofs (" << b.miner_tx.proofs.size() << "), expected 3");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.proofs[0].type() == typeid(zc_asset_surjection_proof), false, "coinbase transaction has incorrect type of proof #0 (expected: zc_asset_surjection_proof)");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.proofs[1].type() == typeid(zc_outs_range_proof), false, "coinbase transaction has incorrect type of proof #1 (expected: zc_outs_range_proof)");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.proofs[2].type() == typeid(zc_balance_proof), false, "coinbase transaction has incorrect type of proof #2 (expected: zc_balance_proof)");
|
||||
|
|
@ -1518,6 +1518,8 @@ bool blockchain_storage::create_block_template(const create_block_template_param
|
|||
if (!block_filled)
|
||||
return false;
|
||||
|
||||
resp.txs_fee = fee;
|
||||
|
||||
/*
|
||||
instead of complicated two-phase template construction and adjustment of cumulative size with block reward we
|
||||
use CURRENCY_COINBASE_BLOB_RESERVED_SIZE as penalty-free coinbase transaction reservation.
|
||||
|
|
@ -1528,6 +1530,7 @@ bool blockchain_storage::create_block_template(const create_block_template_param
|
|||
miner_address,
|
||||
stakeholder_address,
|
||||
b.miner_tx,
|
||||
resp.block_reward_without_fee,
|
||||
get_tx_version(height, m_core_runtime_config.hard_forks),
|
||||
ex_nonce,
|
||||
CURRENCY_MINER_TX_MAX_OUTS,
|
||||
|
|
|
|||
|
|
@ -147,6 +147,8 @@ namespace currency
|
|||
wide_difficulty_type diffic;
|
||||
uint64_t height;
|
||||
tx_generation_context miner_tx_tgc; // bad design, a lot of copying, consider redesign -- sowle
|
||||
uint64_t block_reward_without_fee;
|
||||
uint64_t txs_fee; // sum of transactions' fee if any
|
||||
};
|
||||
|
||||
typedef std::unordered_map<crypto::hash, transaction> transactions_map;
|
||||
|
|
|
|||
|
|
@ -357,24 +357,24 @@ namespace currency
|
|||
const account_public_address &miner_address,
|
||||
const account_public_address &stakeholder_address,
|
||||
transaction& tx,
|
||||
uint64_t& block_reward_without_fee,
|
||||
uint64_t tx_version,
|
||||
const blobdata& extra_nonce /* = blobdata() */,
|
||||
size_t max_outs /* = CURRENCY_MINER_TX_MAX_OUTS */,
|
||||
bool pos /* = false */,
|
||||
const pos_entry& pe /* = pos_entry() */, // only pe.stake_unlock_time and pe.stake_amount are used now, TODO: consider refactoring -- sowle
|
||||
tx_generation_context* ogc_ptr /* = nullptr */,
|
||||
tx_generation_context* ogc_ptr /* = nullptr */,
|
||||
const keypair* tx_one_time_key_to_use /* = nullptr */
|
||||
)
|
||||
{
|
||||
bool r = false;
|
||||
|
||||
uint64_t block_reward = 0;
|
||||
if (!get_block_reward(pos, median_size, current_block_size, already_generated_coins, block_reward, height))
|
||||
if (!get_block_reward(pos, median_size, current_block_size, already_generated_coins, block_reward_without_fee, height))
|
||||
{
|
||||
LOG_ERROR("Block is too big");
|
||||
return false;
|
||||
}
|
||||
block_reward += fee;
|
||||
uint64_t block_reward = block_reward_without_fee + fee;
|
||||
|
||||
//
|
||||
// prepare destinations
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ namespace currency
|
|||
std::string htlc_origin;
|
||||
std::vector<serializable_pair<uint64_t, crypto::key_image>> outs_key_images; // pairs (out_index, key_image) for each change output
|
||||
crypto::key_derivation derivation;
|
||||
bool was_not_prepared = false; // true if tx was not prepared/created for some good reason (e.g. not enough outs for UTXO defragmentation tx). Because we decided not to throw exceptions for non-error cases. -- sowle
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(tx)
|
||||
|
|
@ -198,6 +199,7 @@ namespace currency
|
|||
FIELD(htlc_origin)
|
||||
FIELD(outs_key_images)
|
||||
FIELD(derivation)
|
||||
FIELD(was_not_prepared)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
|
|
@ -255,7 +257,8 @@ namespace currency
|
|||
uint64_t fee,
|
||||
const account_public_address &miner_address,
|
||||
const account_public_address &stakeholder_address,
|
||||
transaction& tx,
|
||||
transaction& tx,
|
||||
uint64_t& block_reward_without_fee,
|
||||
uint64_t tx_version,
|
||||
const blobdata& extra_nonce = blobdata(),
|
||||
size_t max_outs = CURRENCY_MINER_TX_MAX_OUTS,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 2750d12c11f6063e75f6370a4382db7f0784d624
|
||||
Subproject commit 1471e71f4ff685dd080e6551773cf129f1d02c43
|
||||
|
|
@ -912,6 +912,8 @@ namespace currency
|
|||
res.prev_hash = string_tools::pod_to_hex(resp.b.prev_id);
|
||||
res.miner_tx_tgc = resp.miner_tx_tgc;
|
||||
res.height = resp.height;
|
||||
res.block_reward_without_fee = resp.block_reward_without_fee;
|
||||
res.txs_fee = resp.txs_fee;
|
||||
//calculate epoch seed
|
||||
res.seed = currency::ethash_epoch_to_seed(currency::ethash_height_to_epoch(res.height));
|
||||
|
||||
|
|
|
|||
|
|
@ -861,6 +861,8 @@ namespace currency
|
|||
blobdata blocktemplate_blob;
|
||||
std::string prev_hash;
|
||||
tx_generation_context miner_tx_tgc;
|
||||
uint64_t block_reward_without_fee;
|
||||
uint64_t txs_fee;
|
||||
std::string status;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
|
|
@ -870,6 +872,8 @@ namespace currency
|
|||
KV_SERIALIZE(blocktemplate_blob)
|
||||
KV_SERIALIZE(prev_hash)
|
||||
KV_SERIALIZE(miner_tx_tgc)
|
||||
KV_SERIALIZE(block_reward_without_fee)
|
||||
KV_SERIALIZE(txs_fee)
|
||||
KV_SERIALIZE(status)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1808,11 +1808,13 @@ bool simple_wallet::deploy_new_asset(const std::vector<std::string> &args)
|
|||
if (!args.size() || args.size() > 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
return true;
|
||||
}
|
||||
bool r = epee::serialization::load_t_from_json_file(adb, args[0]);
|
||||
if (!r)
|
||||
{
|
||||
fail_msg_writer() << "Failed to load json file with asset specification: " << args[0];
|
||||
return true;
|
||||
}
|
||||
tx_destination_entry td = AUTO_VAL_INIT(td);
|
||||
td.addr.push_back(m_wallet->get_account().get_public_address());
|
||||
|
|
@ -1842,6 +1844,7 @@ bool simple_wallet::add_custom_asset_id(const std::vector<std::string> &args)
|
|||
if (!args.size() || args.size() > 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
return true;
|
||||
}
|
||||
crypto::public_key asset_id = currency::null_pkey;
|
||||
if (!epee::string_tools::parse_tpod_from_hex_string(args[0], asset_id))
|
||||
|
|
@ -1877,6 +1880,7 @@ bool simple_wallet::generate_ionic_swap_proposal(const std::vector<std::string>
|
|||
if (args.size() != 2)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
return true;
|
||||
}
|
||||
|
||||
view::ionic_swap_proposal_info proposal_info = AUTO_VAL_INIT(proposal_info);
|
||||
|
|
@ -1884,6 +1888,7 @@ bool simple_wallet::generate_ionic_swap_proposal(const std::vector<std::string>
|
|||
if (!r)
|
||||
{
|
||||
fail_msg_writer() << "Failed to load json file with asset specification: " << args[0];
|
||||
return true;
|
||||
}
|
||||
currency::account_public_address destination_addr = AUTO_VAL_INIT(destination_addr);
|
||||
currency::payment_id_t integrated_payment_id;
|
||||
|
|
@ -1921,6 +1926,7 @@ bool simple_wallet::get_ionic_swap_proposal_info(const std::vector<std::string>
|
|||
if (args.size() != 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string raw_proposal;
|
||||
|
|
@ -1953,6 +1959,7 @@ bool simple_wallet::accept_ionic_swap_proposal(const std::vector<std::string> &a
|
|||
if (args.size() != 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string raw_proposal;
|
||||
|
|
@ -1983,6 +1990,7 @@ bool simple_wallet::remove_custom_asset_id(const std::vector<std::string> &args)
|
|||
if (!args.size() || args.size() > 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid arguments count: " << args.size() << ", expected 1";
|
||||
return true;
|
||||
}
|
||||
crypto::public_key asset_id = currency::null_pkey;
|
||||
if (!epee::string_tools::parse_tpod_from_hex_string(args[0], asset_id))
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "0"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 206
|
||||
#define PROJECT_VERSION_BUILD_NO 208
|
||||
#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 "]"
|
||||
|
|
|
|||
|
|
@ -51,6 +51,10 @@ using namespace currency;
|
|||
|
||||
#define MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES (100*1024*1024) // 100 MB
|
||||
|
||||
#define WALLET_DEFAULT_DECOYS_COUNT_FOR_DEFRAGMENTATION_TX 10 // TODO @#@# change to default decoy set number
|
||||
#define WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 3 // TODO: @#@# consider descreasing to mimic normal tx
|
||||
#define WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX 10 // TODO: @#@# consider descreasing to mimic normal tx
|
||||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
#define LOG_DEFAULT_CHANNEL "wallet"
|
||||
ENABLE_CHANNEL_BY_DEFAULT("wallet")
|
||||
|
|
@ -69,7 +73,9 @@ namespace tools
|
|||
, m_watch_only(false)
|
||||
, m_last_pow_block_h(0)
|
||||
, m_minimum_height(WALLET_MINIMUM_HEIGHT_UNSET_CONST)
|
||||
, m_pos_mint_packing_size(WALLET_DEFAULT_POS_MINT_PACKING_SIZE)
|
||||
, m_min_utxo_count_for_defragmentation_tx(WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
, m_max_utxo_count_for_defragmentation_tx(WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
, m_decoys_count_for_defragmentation_tx(WALLET_DEFAULT_DECOYS_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
, m_current_wallet_file_size(0)
|
||||
, m_use_deffered_global_outputs(false)
|
||||
#ifdef DISABLE_TOR
|
||||
|
|
@ -203,9 +209,15 @@ bool wallet2::set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy)
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::set_pos_mint_packing_size(uint64_t new_size)
|
||||
void wallet2::set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs)
|
||||
{
|
||||
m_pos_mint_packing_size = new_size;
|
||||
m_min_utxo_count_for_defragmentation_tx = min_outs;
|
||||
m_max_utxo_count_for_defragmentation_tx = max_outs;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count)
|
||||
{
|
||||
m_decoys_count_for_defragmentation_tx = decoys_count;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::shared_ptr<i_core_proxy> wallet2::get_core_proxy()
|
||||
|
|
@ -3363,33 +3375,18 @@ void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) con
|
|||
incoming_transfers = m_transfers;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::generate_packing_transaction_if_needed(currency::transaction& tx, uint64_t fake_outputs_number)
|
||||
bool wallet2::generate_utxo_defragmentation_transaction_if_needed(currency::transaction& tx)
|
||||
{
|
||||
prepare_free_transfers_cache(0);
|
||||
auto it = m_found_free_amounts[currency::native_coin_asset_id].find(CURRENCY_BLOCK_REWARD);
|
||||
if (it == m_found_free_amounts[currency::native_coin_asset_id].end() || it->second.size() <= m_pos_mint_packing_size)
|
||||
return false;
|
||||
|
||||
//let's check if we have at least WALLET_POS_MINT_PACKING_SIZE transactions which is ready to go
|
||||
size_t count = 0;
|
||||
for (auto it_ind = it->second.begin(); it_ind != it->second.end() && count <= m_pos_mint_packing_size; it_ind++)
|
||||
{
|
||||
if (is_transfer_ready_to_go(m_transfers[*it_ind], fake_outputs_number))
|
||||
++count;
|
||||
}
|
||||
if (count <= m_pos_mint_packing_size)
|
||||
return false;
|
||||
construct_tx_param ctp = get_default_construct_tx_param();
|
||||
currency::tx_destination_entry de = AUTO_VAL_INIT(de);
|
||||
de.addr.push_back(m_account.get_public_address());
|
||||
de.amount = m_pos_mint_packing_size*CURRENCY_BLOCK_REWARD;
|
||||
ctp.dsts.push_back(de);
|
||||
ctp.perform_packing = true;
|
||||
|
||||
TRY_ENTRY();
|
||||
transfer(ctp, tx, false, nullptr);
|
||||
CATCH_ENTRY2(false);
|
||||
ctp.create_utxo_defragmentation_tx = true;
|
||||
finalized_tx ftp{};
|
||||
|
||||
transfer(ctp, ftp, false, nullptr);
|
||||
|
||||
if (ftp.was_not_prepared)
|
||||
return false; // no such UTXO were found, not an error
|
||||
|
||||
tx = ftp.tx;
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -3682,7 +3679,7 @@ bool enum_container(iterator_t it_begin, iterator_t it_end, callback_t cb)
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::is_consolidating_transaction(const wallet_public::wallet_transfer_info& wti)
|
||||
bool wallet2::is_defragmentation_transaction(const wallet_public::wallet_transfer_info& wti)
|
||||
{
|
||||
if (!wti.is_income)
|
||||
{
|
||||
|
|
@ -3705,7 +3702,7 @@ void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_tra
|
|||
|
||||
if (exclude_mining_txs)
|
||||
{
|
||||
if (currency::is_coinbase(wti.tx) || is_consolidating_transaction(wti))
|
||||
if (currency::is_coinbase(wti.tx) || is_defragmentation_transaction(wti))
|
||||
return true;
|
||||
}
|
||||
trs.push_back(wti);
|
||||
|
|
@ -3912,7 +3909,7 @@ bool wallet2::is_in_hardfork_zone(uint64_t hardfork_index) const
|
|||
return m_core_runtime_config.is_hardfork_active_for_height(hardfork_index, get_blockchain_current_size());
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::block& b, const pos_entry& pe, currency::tx_generation_context& miner_tx_tgc) const
|
||||
bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, uint64_t full_block_reward, const currency::pos_entry& pe, currency::tx_generation_context& miner_tx_tgc, currency::block& b) const
|
||||
{
|
||||
bool r = false;
|
||||
WLT_CHECK_AND_ASSERT_MES(pe.wallet_index < m_transfers.size(), false, "invalid pe.wallet_index: " << pe.wallet_index);
|
||||
|
|
@ -4096,9 +4093,8 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::bl
|
|||
b.miner_tx.proofs.emplace_back(std::move(range_proofs));
|
||||
|
||||
// balance proof
|
||||
uint64_t block_reward = COIN; // TODO @#@# move it somewhere -- sowle
|
||||
currency::zc_balance_proof balance_proof{};
|
||||
r = generate_tx_balance_proof(b.miner_tx, miner_tx_id, miner_tx_tgc, block_reward, balance_proof);
|
||||
r = generate_tx_balance_proof(b.miner_tx, miner_tx_id, miner_tx_tgc, full_block_reward, balance_proof);
|
||||
WLT_CHECK_AND_ASSERT_MES(r, false, "generate_tx_balance_proof failed");
|
||||
b.miner_tx.proofs.emplace_back(std::move(balance_proof));
|
||||
|
||||
|
|
@ -4228,12 +4224,21 @@ bool wallet2::build_minted_block(const mining_context& cxt, const currency::acco
|
|||
tmpl_req.pe.tx_out_index = td.m_internal_output_index;
|
||||
tmpl_req.pe.wallet_index = cxt.index;
|
||||
|
||||
//generate packing tx
|
||||
transaction pack_tx = AUTO_VAL_INIT(pack_tx);
|
||||
if (generate_packing_transaction_if_needed(pack_tx, 0))
|
||||
// mark stake source as spent and make sure it will be restored in case of error
|
||||
const std::vector<uint64_t> stake_transfer_idx_vec{ cxt.index };
|
||||
mark_transfers_as_spent(stake_transfer_idx_vec, "stake source");
|
||||
bool gracefull_leaving = false;
|
||||
auto stake_transfer_spent_flag_restorer = epee::misc_utils::create_scope_leave_handler([&](){
|
||||
if (!gracefull_leaving)
|
||||
clear_transfers_from_flag(stake_transfer_idx_vec, WALLET_TRANSFER_DETAIL_FLAG_SPENT, "stake source");
|
||||
});
|
||||
|
||||
// generate UTXO Defragmentation Transaction - to reduce the UTXO set size
|
||||
transaction udtx{};
|
||||
if (generate_utxo_defragmentation_transaction_if_needed(udtx))
|
||||
{
|
||||
tx_to_blob(pack_tx, tmpl_req.explicit_transaction);
|
||||
WLT_LOG_GREEN("Packing inputs: " << pack_tx.vin.size() << " inputs consolidated in tx " << get_transaction_hash(pack_tx), LOG_LEVEL_0);
|
||||
tx_to_blob(udtx, tmpl_req.explicit_transaction);
|
||||
WLT_LOG_GREEN("Note: " << udtx.vin.size() << " inputs were aggregated into UTXO defragmentation tx " << get_transaction_hash(udtx), LOG_LEVEL_0);
|
||||
}
|
||||
m_core_proxy->call_COMMAND_RPC_GETBLOCKTEMPLATE(tmpl_req, tmpl_rsp);
|
||||
WLT_CHECK_AND_ASSERT_MES(tmpl_rsp.status == API_RETURN_CODE_OK, false, "Failed to create block template after kernel hash found!");
|
||||
|
|
@ -4257,11 +4262,12 @@ bool wallet2::build_minted_block(const mining_context& cxt, const currency::acco
|
|||
set_block_datetime(current_timestamp, b);
|
||||
WLT_LOG_MAGENTA("Applying actual timestamp: " << current_timestamp, LOG_LEVEL_0);
|
||||
|
||||
res = prepare_and_sign_pos_block(cxt, b, tmpl_req.pe, tmpl_rsp.miner_tx_tgc);
|
||||
uint64_t full_block_reward = tmpl_rsp.block_reward_without_fee + tmpl_rsp.txs_fee;
|
||||
res = prepare_and_sign_pos_block(cxt, full_block_reward, tmpl_req.pe, tmpl_rsp.miner_tx_tgc, b);
|
||||
WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to prepare_and_sign_pos_block");
|
||||
|
||||
crypto::hash block_hash = get_block_hash(b);
|
||||
WLT_LOG_GREEN("Block " << print16(block_hash) << " has been constructed, sending to core...", LOG_LEVEL_0);
|
||||
WLT_LOG_GREEN("Block " << print16(block_hash) << " @ " << get_block_height(b) << " has been constructed, sending to core...", LOG_LEVEL_0);
|
||||
|
||||
currency::COMMAND_RPC_SUBMITBLOCK2::request subm_req = AUTO_VAL_INIT(subm_req);
|
||||
currency::COMMAND_RPC_SUBMITBLOCK2::response subm_rsp = AUTO_VAL_INIT(subm_rsp);
|
||||
|
|
@ -4278,6 +4284,7 @@ bool wallet2::build_minted_block(const mining_context& cxt, const currency::acco
|
|||
WLT_LOG_GREEN("PoS block " << print16(block_hash) << " generated and accepted, congrats!", LOG_LEVEL_0);
|
||||
m_wcallback->on_pos_block_found(b);
|
||||
|
||||
gracefull_leaving = true; // to prevent source transfer flags be cleared in scope leave handler
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -4492,6 +4499,7 @@ void wallet2::deploy_new_asset(const currency::asset_descriptor_base& asset_info
|
|||
construct_tx_param ctp = get_default_construct_tx_param();
|
||||
ctp.dsts = destinations;
|
||||
ctp.extra.push_back(asset_reg_info);
|
||||
ctp.need_at_least_1_zc = true;
|
||||
|
||||
finalized_tx ft = AUTO_VAL_INIT(ft);
|
||||
this->transfer(ctp, ft, true, nullptr);
|
||||
|
|
@ -5376,33 +5384,40 @@ bool wallet2::decrypt_buffer(const std::string& buff, std::string& res_buff)
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake_outputs_count, std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies, uint64_t& found_money)
|
||||
bool wallet2::prepare_tx_sources_for_defragmentation_tx(std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies, uint64_t& found_money)
|
||||
{
|
||||
prepare_free_transfers_cache(fake_outputs_count);
|
||||
//prepare_free_transfers_cache(fake_outputs_count);
|
||||
//free_amounts_cache_type& free_amounts_for_native_coin = m_found_free_amounts[currency::native_coin_asset_id];
|
||||
|
||||
free_amounts_cache_type& free_amounts_for_native_coin = m_found_free_amounts[currency::native_coin_asset_id];
|
||||
|
||||
auto it = free_amounts_for_native_coin.find(CURRENCY_BLOCK_REWARD);
|
||||
if (it == free_amounts_for_native_coin.end() || it->second.size() < m_pos_mint_packing_size)
|
||||
return false;
|
||||
|
||||
for (auto set_it = it->second.begin(); set_it != it->second.end() && selected_indicies.size() <= m_pos_mint_packing_size; )
|
||||
std::stringstream ss;
|
||||
if (epee::log_space::log_singletone::get_log_detalisation_level() >= LOG_LEVEL_2)
|
||||
ss << "preparing sources for utxo defragmentation tx:";
|
||||
for (size_t i = 0, size = m_transfers.size(); i < size && selected_indicies.size() < m_max_utxo_count_for_defragmentation_tx; ++i)
|
||||
{
|
||||
if (is_transfer_ready_to_go(m_transfers[*set_it], fake_outputs_count))
|
||||
{
|
||||
found_money += it->first;
|
||||
selected_indicies.push_back(*set_it);
|
||||
WLT_LOG_L2("Selected index: " << *set_it << ", transfer_details: " << ENDL << epee::serialization::store_t_to_json(m_transfers[*set_it]));
|
||||
|
||||
it->second.erase(set_it++);
|
||||
}
|
||||
else
|
||||
set_it++;
|
||||
}
|
||||
if (!it->second.size())
|
||||
free_amounts_for_native_coin.erase(it);
|
||||
const auto& td = m_transfers[i];
|
||||
if (!td.is_native_coin() || td.m_amount > CURRENCY_BLOCK_REWARD)
|
||||
continue;
|
||||
|
||||
return prepare_tx_sources(fake_outputs_count, sources, selected_indicies);
|
||||
if (is_transfer_ready_to_go(td, m_decoys_count_for_defragmentation_tx))
|
||||
{
|
||||
found_money += td.m_amount;
|
||||
selected_indicies.push_back(i);
|
||||
if (epee::log_space::log_singletone::get_log_detalisation_level() >= LOG_LEVEL_2)
|
||||
ss << " selected transfer #" << i << ", amount: " << print_money_brief(td.m_amount) << ", height: " << td.m_ptx_wallet_info->m_block_height << ", " << (td.is_zc() ? "ZC" : " ");
|
||||
}
|
||||
}
|
||||
|
||||
if (selected_indicies.size() < m_min_utxo_count_for_defragmentation_tx)
|
||||
{
|
||||
// too few outputs were found, hence don't create a defragmentation tx
|
||||
selected_indicies.clear();
|
||||
found_money = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
WLT_LOG(ss.str(), LOG_LEVEL_2);
|
||||
|
||||
return prepare_tx_sources(m_decoys_count_for_defragmentation_tx, sources, selected_indicies);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies)
|
||||
|
|
@ -6416,7 +6431,7 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money,
|
|||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& msc)
|
||||
bool wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& msc)
|
||||
{
|
||||
|
||||
SET_CONTEXT_OBJ_FOR_SCOPE(pconstruct_tx_param, ctp);
|
||||
|
|
@ -6448,9 +6463,14 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx
|
|||
//uint64_t found_money = 0;
|
||||
|
||||
TIME_MEASURE_START_MS(prepare_tx_sources_time);
|
||||
if (ctp.perform_packing)
|
||||
if (ctp.create_utxo_defragmentation_tx)
|
||||
{
|
||||
prepare_tx_sources_for_packing(WALLET_DEFAULT_POS_MINT_PACKING_SIZE, 0, ftp.sources, ftp.selected_transfers, needed_money_map[currency::native_coin_asset_id].found_amount);
|
||||
try
|
||||
{
|
||||
if (!prepare_tx_sources_for_defragmentation_tx(ftp.sources, ftp.selected_transfers, needed_money_map[currency::native_coin_asset_id].found_amount))
|
||||
return false;
|
||||
}
|
||||
catch(const error::not_enough_outs_to_mix&) { return false; } // if there's not enough decoys, return false to indicate minor non-fatal error
|
||||
}
|
||||
else if (ctp.htlc_tx_id != currency::null_hash)
|
||||
{
|
||||
|
|
@ -6506,6 +6526,7 @@ void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx
|
|||
<< ", construct_tx_time: " << construct_tx_time << " ms"
|
||||
<< ", sign_ms_input_time: " << sign_ms_input_time << " ms",
|
||||
LOG_LEVEL_0);*/
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::finalize_transaction(const currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key /* = true */)
|
||||
|
|
@ -6706,6 +6727,10 @@ void wallet2::transfer(construct_tx_param& ctp,
|
|||
|
||||
check_and_throw_if_self_directed_tx_with_payment_id_requested(ctp);
|
||||
|
||||
bool asset_operation_requested = count_type_in_variant_container<asset_descriptor_operation>(ctp.extra) != 0;
|
||||
bool dont_have_zero_asset_ids_in_destinations = std::count_if(ctp.dsts.begin(), ctp.dsts.end(), [](const tx_destination_entry& de) { return de.asset_id == null_pkey; }) == 0;
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(asset_operation_requested || dont_have_zero_asset_ids_in_destinations, "zero asset id is used errounesly (no asset operation was requested)");
|
||||
|
||||
if (ctp.crypt_address.spend_public_key == currency::null_pkey)
|
||||
{
|
||||
ctp.crypt_address = currency::get_crypt_address_from_destinations(m_account.get_keys(), ctp.dsts);
|
||||
|
|
@ -6714,7 +6739,11 @@ void wallet2::transfer(construct_tx_param& ctp,
|
|||
TIME_MEASURE_START(prepare_transaction_time);
|
||||
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
|
||||
ftp.tx_version = this->get_current_tx_version();
|
||||
prepare_transaction(ctp, ftp);
|
||||
if (!prepare_transaction(ctp, ftp))
|
||||
{
|
||||
result.was_not_prepared = true;
|
||||
return;
|
||||
}
|
||||
TIME_MEASURE_FINISH(prepare_transaction_time);
|
||||
|
||||
if (m_watch_only)
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@
|
|||
#define WALLET_DEFAULT_TX_SPENDABLE_AGE 10
|
||||
#define WALLET_POS_MINT_CHECK_HEIGHT_INTERVAL 1
|
||||
|
||||
#define WALLET_DEFAULT_POS_MINT_PACKING_SIZE 100
|
||||
|
||||
#define WALLET_TRANSFER_DETAIL_FLAG_SPENT uint32_t(1 << 0)
|
||||
#define WALLET_TRANSFER_DETAIL_FLAG_BLOCKED uint32_t(1 << 1)
|
||||
#define WALLET_TRANSFER_DETAIL_FLAG_ESCROW_PROPOSAL_RESERVATION uint32_t(1 << 2)
|
||||
|
|
@ -299,7 +297,7 @@ namespace tools
|
|||
currency::account_public_address crypt_address;
|
||||
uint8_t tx_outs_attr = 0;
|
||||
bool shuffle = false;
|
||||
bool perform_packing = false;
|
||||
bool create_utxo_defragmentation_tx = false;
|
||||
bool need_at_least_1_zc = false;
|
||||
};
|
||||
|
||||
|
|
@ -574,7 +572,7 @@ namespace tools
|
|||
const currency::account_base& get_account() const { return m_account; }
|
||||
|
||||
void get_recent_transfers_history(std::vector<wallet_public::wallet_transfer_info>& trs, size_t offset, size_t count, uint64_t& total, uint64_t& last_item_index, bool exclude_mining_txs = false, bool start_from_end = true);
|
||||
bool is_consolidating_transaction(const wallet_public::wallet_transfer_info& wti);
|
||||
bool is_defragmentation_transaction(const wallet_public::wallet_transfer_info& wti);
|
||||
uint64_t get_recent_transfers_total_count();
|
||||
uint64_t get_transfer_entries_count();
|
||||
void get_unconfirmed_transfers(std::vector<wallet_public::wallet_transfer_info>& trs, bool exclude_mining_txs = false);
|
||||
|
|
@ -609,7 +607,8 @@ namespace tools
|
|||
void deploy_new_asset(const currency::asset_descriptor_base& asset_info, const std::vector<currency::tx_destination_entry>& destinations, currency::transaction& result_tx, crypto::public_key& new_asset_id);
|
||||
|
||||
bool set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy);
|
||||
void set_pos_mint_packing_size(uint64_t new_size);
|
||||
void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs
|
||||
void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count);
|
||||
void set_minimum_height(uint64_t h);
|
||||
std::shared_ptr<i_core_proxy> get_core_proxy();
|
||||
uint64_t balance() const;
|
||||
|
|
@ -885,7 +884,7 @@ namespace tools
|
|||
//next functions in public area only becausce of test_generator
|
||||
//TODO: Need refactoring - remove it back to private zone
|
||||
void set_genesis(const crypto::hash& genesis_hash);
|
||||
bool prepare_and_sign_pos_block(const mining_context& cxt, currency::block& b, const currency::pos_entry& pe, currency::tx_generation_context& miner_tx_tgc) const;
|
||||
bool prepare_and_sign_pos_block(const mining_context& cxt, uint64_t full_block_reward, const currency::pos_entry& pe, currency::tx_generation_context& miner_tx_tgc, currency::block& b) const;
|
||||
void process_new_blockchain_entry(const currency::block& b,
|
||||
const currency::block_direct_data_entry& bche,
|
||||
const crypto::hash& bl_id,
|
||||
|
|
@ -933,7 +932,7 @@ namespace tools
|
|||
const std::list<expiration_entry_info>& get_expiration_entries() const { return m_money_expirations; };
|
||||
bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) const;
|
||||
|
||||
void prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& emode_separate = mode_separate_context());
|
||||
bool prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const mode_separate_context& emode_separate = mode_separate_context());
|
||||
|
||||
void finalize_transaction(const currency::finalize_tx_param& ftp, currency::transaction& tx, crypto::secret_key& tx_key, bool broadcast_tx, bool store_tx_secret_key = true);
|
||||
void finalize_transaction(const currency::finalize_tx_param& ftp, currency::finalized_tx& result, bool broadcast_tx, bool store_tx_secret_key = true );
|
||||
|
|
@ -1042,7 +1041,7 @@ private:
|
|||
bool prepare_tx_sources(size_t fake_outputs_count, std::vector<currency::tx_source_entry>& sources, const std::vector<uint64_t>& selected_indicies);
|
||||
bool prepare_tx_sources(crypto::hash multisig_id, std::vector<currency::tx_source_entry>& sources, uint64_t& found_money);
|
||||
bool prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string& origin, std::vector<currency::tx_source_entry>& sources, uint64_t& found_money);
|
||||
bool prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake_outputs_count, std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies, uint64_t& found_money);
|
||||
bool prepare_tx_sources_for_defragmentation_tx(std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies, uint64_t& found_money);
|
||||
void prefetch_global_indicies_if_needed(const std::vector<uint64_t>& selected_indicies);
|
||||
assets_selection_context get_needed_money(uint64_t fee, const std::vector<currency::tx_destination_entry>& dsts);
|
||||
void prepare_tx_destinations(const assets_selection_context& needed_money_map,
|
||||
|
|
@ -1110,7 +1109,7 @@ private:
|
|||
void exception_handler();
|
||||
void exception_handler() const;
|
||||
uint64_t get_minimum_allowed_fee_for_contract(const crypto::hash& ms_id);
|
||||
bool generate_packing_transaction_if_needed(currency::transaction& tx, uint64_t fake_outputs_number);
|
||||
bool generate_utxo_defragmentation_transaction_if_needed(currency::transaction& tx);
|
||||
bool store_unsigned_tx_to_file_and_reserve_transfers(const currency::finalize_tx_param& ftp, const std::string& filename, std::string* p_unsigned_tx_blob_str = nullptr);
|
||||
void check_and_throw_if_self_directed_tx_with_payment_id_requested(const construct_tx_param& ctp);
|
||||
void push_new_block_id(const crypto::hash& id, uint64_t height);
|
||||
|
|
@ -1146,7 +1145,9 @@ private:
|
|||
|
||||
std::atomic<uint64_t> m_last_bc_timestamp;
|
||||
bool m_do_rise_transfer;
|
||||
uint64_t m_pos_mint_packing_size;
|
||||
uint64_t m_min_utxo_count_for_defragmentation_tx;
|
||||
uint64_t m_max_utxo_count_for_defragmentation_tx;
|
||||
size_t m_decoys_count_for_defragmentation_tx;
|
||||
|
||||
transfer_container m_transfers;
|
||||
multisig_transfer_container m_multisig_transfers;
|
||||
|
|
|
|||
|
|
@ -299,6 +299,7 @@ bool test_generator::construct_block(currency::block& blk,
|
|||
blk.miner_tx = AUTO_VAL_INIT(blk.miner_tx);
|
||||
size_t target_block_size = txs_size + 0; // zero means no cost for ordinary coinbase
|
||||
tx_generation_context miner_tx_tgc{};
|
||||
uint64_t block_reward_without_fee = 0;
|
||||
while (true)
|
||||
{
|
||||
r = construct_miner_tx(height, misc_utils::median(block_sizes),
|
||||
|
|
@ -308,6 +309,7 @@ bool test_generator::construct_block(currency::block& blk,
|
|||
miner_acc.get_keys().account_address,
|
||||
miner_acc.get_keys().account_address,
|
||||
blk.miner_tx,
|
||||
block_reward_without_fee,
|
||||
get_tx_version(height, m_hardforks),
|
||||
blobdata(),
|
||||
test_generator::get_test_gentime_settings().miner_tx_max_outs,
|
||||
|
|
@ -354,7 +356,7 @@ bool test_generator::construct_block(currency::block& blk,
|
|||
else
|
||||
{
|
||||
//need to build pos block
|
||||
r = sign_block(wallets[won_walled_index].mining_context, pe, *wallets[won_walled_index].wallet, miner_tx_tgc, blk);
|
||||
r = sign_block(wallets[won_walled_index].mining_context, pe, block_reward_without_fee + total_fee, *wallets[won_walled_index].wallet, miner_tx_tgc, blk);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to find_kernel_and_sign()");
|
||||
}
|
||||
|
||||
|
|
@ -373,11 +375,12 @@ bool test_generator::construct_block(currency::block& blk,
|
|||
|
||||
bool test_generator::sign_block(const tools::wallet2::mining_context& mining_context,
|
||||
const pos_entry& pe,
|
||||
uint64_t full_block_reward,
|
||||
const tools::wallet2& w,
|
||||
tx_generation_context& miner_tx_tgc,
|
||||
currency::block& b)
|
||||
{
|
||||
bool r = w.prepare_and_sign_pos_block(mining_context, b, pe, miner_tx_tgc);
|
||||
bool r = w.prepare_and_sign_pos_block(mining_context, full_block_reward, pe, miner_tx_tgc, b);
|
||||
CHECK_AND_ASSERT_MES(r, false, "prepare_and_sign_pos_block failed");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -933,9 +936,10 @@ bool test_generator::construct_block(int64_t manual_timestamp_adjustment,
|
|||
}
|
||||
else
|
||||
{
|
||||
uint64_t base_block_reward = 0;
|
||||
size_t current_block_size = txs_sizes + get_object_blobsize(blk.miner_tx);
|
||||
// TODO: This will work, until size of constructed block is less then CURRENCY_BLOCK_GRANTED_FULL_REWARD_ZONE
|
||||
if (!construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, current_block_size, 0, miner_acc.get_public_address(), miner_acc.get_public_address(), blk.miner_tx, get_tx_version(height, m_hardforks), blobdata(), 1))
|
||||
if (!construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, current_block_size, 0, miner_acc.get_public_address(), miner_acc.get_public_address(), blk.miner_tx, base_block_reward, get_tx_version(height, m_hardforks), blobdata(), 1))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -488,6 +488,7 @@ public:
|
|||
|
||||
bool sign_block(const tools::wallet2::mining_context& mining_context,
|
||||
const currency::pos_entry& pe,
|
||||
uint64_t full_block_reward,
|
||||
const tools::wallet2& w,
|
||||
currency::tx_generation_context& miner_tx_tgc,
|
||||
currency::block& b);
|
||||
|
|
@ -951,7 +952,9 @@ bool test_generator::construct_block_gentime_with_coinbase_cb(const currency::bl
|
|||
size_t height = get_block_height(prev_block) + 1;
|
||||
//size_t current_block_size = get_object_blobsize(miner_tx);
|
||||
|
||||
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, get_tx_version(height, m_hardforks), currency::blobdata(), 1);
|
||||
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);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_miner_tx failed");
|
||||
|
||||
if (!cb(miner_tx))
|
||||
|
|
|
|||
|
|
@ -1076,7 +1076,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(wallet_outputs_with_same_key_image);
|
||||
GENERATE_AND_PLAY(wallet_unconfirmed_tx_expiration);
|
||||
GENERATE_AND_PLAY(wallet_unconfimed_tx_balance);
|
||||
GENERATE_AND_PLAY_HF(packing_outputs_on_pos_minting_wallet, "3");
|
||||
GENERATE_AND_PLAY_HF(packing_outputs_on_pos_minting_wallet, "3-*");
|
||||
GENERATE_AND_PLAY(wallet_watch_only_and_chain_switch);
|
||||
|
||||
GENERATE_AND_PLAY(wallet_rpc_integrated_address);
|
||||
|
|
@ -1256,6 +1256,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(zarcanum_in_alt_chain);
|
||||
GENERATE_AND_PLAY(assets_and_explicit_native_coins_in_outs);
|
||||
GENERATE_AND_PLAY(zarcanum_block_with_txs);
|
||||
GENERATE_AND_PLAY(asset_depoyment_and_few_zc_utxos);
|
||||
|
||||
|
||||
// GENERATE_AND_PLAY(gen_block_reward);
|
||||
|
|
|
|||
|
|
@ -332,3 +332,129 @@ bool assets_and_explicit_native_coins_in_outs::c2_alice_deploys_asset(currency::
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
asset_depoyment_and_few_zc_utxos::asset_depoyment_and_few_zc_utxos()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(asset_depoyment_and_few_zc_utxos, c1);
|
||||
|
||||
m_hardforks.clear();
|
||||
m_hardforks.set_hardfork_height(ZANO_HARDFORK_04_ZARCANUM, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1);
|
||||
}
|
||||
|
||||
bool asset_depoyment_and_few_zc_utxos::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
bool r = false;
|
||||
|
||||
uint64_t ts = test_core_time::get_time();
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts);
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts);
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
|
||||
DO_CALLBACK(events, "configure_core"); // necessary to set m_hardforks
|
||||
|
||||
// HF4 requires tests_random_split_strategy (for 2 outputs minimum)
|
||||
test_gentime_settings tgts = generator.get_test_gentime_settings();
|
||||
tgts.split_strategy = tests_random_split_strategy;
|
||||
generator.set_test_gentime_settings(tgts);
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
DO_CALLBACK_PARAMS(events, "check_hardfork_inactive", static_cast<size_t>(ZANO_HARDFORK_04_ZARCANUM));
|
||||
|
||||
// tx_0: miner -> Alice
|
||||
// make tx_0 before HF4, so Alice will have only bare outs
|
||||
transaction tx_0{};
|
||||
std::vector<tx_source_entry> sources;
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
for(size_t i = 0; i < 100; ++i)
|
||||
destinations.emplace_back(TESTS_DEFAULT_FEE, m_accounts[ALICE_ACC_IDX].get_public_address());
|
||||
m_alice_initial_balance = TESTS_DEFAULT_FEE * 100;
|
||||
r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), m_alice_initial_balance + TESTS_DEFAULT_FEE, 0);
|
||||
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
|
||||
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
|
||||
|
||||
ADD_CUSTOM_EVENT(events, tx_0);
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
|
||||
|
||||
// make sure HF4 has been activated
|
||||
DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast<size_t>(ZANO_HARDFORK_04_ZARCANUM));
|
||||
|
||||
// tx_1: miner -> Alice
|
||||
// send less than min fee. This output will be the only ZC UTXO in Alice's wallet
|
||||
//destinations.clear();
|
||||
|
||||
MAKE_TX(events, tx_1, miner_acc, alice_acc, TESTS_DEFAULT_FEE * 0.5, blk_1);
|
||||
m_alice_initial_balance += TESTS_DEFAULT_FEE * 0.5;
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1, miner_acc, tx_1);
|
||||
|
||||
// rewind blocks
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_2r, blk_2, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
// check Alice's balance and make sure she can deploy an asset
|
||||
DO_CALLBACK(events, "c1");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asset_depoyment_and_few_zc_utxos::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false;
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, m_accounts[ALICE_ACC_IDX]);
|
||||
alice_wlt->refresh();
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", m_alice_initial_balance, 0, m_alice_initial_balance, 0, 0), false, "");
|
||||
|
||||
// make sure Alice has correct UTXO wallet structure
|
||||
tools::wallet2::transfer_container transfers{};
|
||||
alice_wlt->get_transfers(transfers);
|
||||
size_t zc_unspent_outs = 0, unspent_outs = 0;
|
||||
for(auto& td : transfers)
|
||||
{
|
||||
if (!td.is_spent())
|
||||
{
|
||||
++unspent_outs;
|
||||
if (td.is_zc())
|
||||
++zc_unspent_outs;
|
||||
}
|
||||
}
|
||||
CHECK_AND_ASSERT_MES(unspent_outs == 101 && zc_unspent_outs == 1, false, "incorrect UTXO structure: " << unspent_outs << ", " << zc_unspent_outs);
|
||||
|
||||
asset_descriptor_base adb{};
|
||||
adb.total_max_supply = 100 * 1000000000000;
|
||||
adb.full_name = "very confidential asset";
|
||||
adb.ticker = "VCA";
|
||||
adb.decimal_point = 12;
|
||||
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.emplace_back(adb.total_max_supply, m_accounts[MINER_ACC_IDX].get_public_address(), null_pkey);
|
||||
destinations.emplace_back(adb.total_max_supply / 2, m_accounts[MINER_ACC_IDX].get_public_address(), null_pkey);
|
||||
|
||||
transaction asset_emission_tx{};
|
||||
crypto::public_key asset_id = null_pkey;
|
||||
|
||||
alice_wlt->deploy_new_asset(adb, destinations, asset_emission_tx, asset_id);
|
||||
|
||||
// make sure the emission tx is correct
|
||||
CHECK_AND_ASSERT_MES(asset_emission_tx.vout.size() > 2, false, "Unexpected vout size: " << asset_emission_tx.vout.size());
|
||||
for(auto& out : asset_emission_tx.vout)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(out.type() == typeid(tx_out_zarcanum), false, "invalid out type");
|
||||
const tx_out_zarcanum& out_zc = boost::get<tx_out_zarcanum>(out);
|
||||
// as soon as this is the asset emmiting transaction, no output has an obvious asset id
|
||||
// make sure it is so
|
||||
CHECK_AND_ASSERT_MES(out_zc.blinded_asset_id != native_coin_asset_id_1div8, false, "One of outputs has explicit native asset id, which is unexpected");
|
||||
}
|
||||
|
||||
// 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_blocks_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,3 +26,12 @@ struct assets_and_explicit_native_coins_in_outs : public wallet_test
|
|||
mutable uint64_t m_alice_initial_balance = 0;
|
||||
};
|
||||
|
||||
struct asset_depoyment_and_few_zc_utxos : public wallet_test
|
||||
{
|
||||
asset_depoyment_and_few_zc_utxos();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable uint64_t m_alice_initial_balance = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -166,9 +166,10 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
|||
pe.amount = m_context.stake_amount;
|
||||
|
||||
// generate miner tx using incorrect current_block_size only for size estimation
|
||||
uint64_t block_reward_without_fee = 0;
|
||||
size_t estimated_block_size = m_txs_total_size;
|
||||
bool r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee,
|
||||
reward_receiver_address, stakeholder_address, m_block.miner_tx, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use);
|
||||
reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "construct_miner_tx failed");
|
||||
|
||||
estimated_block_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx);
|
||||
|
|
@ -176,7 +177,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
|
|||
for (size_t try_count = 0; try_count != 10; ++try_count)
|
||||
{
|
||||
r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee,
|
||||
reward_receiver_address, stakeholder_address, m_block.miner_tx, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use);
|
||||
reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed");
|
||||
|
||||
cumulative_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx);
|
||||
|
|
|
|||
|
|
@ -1085,7 +1085,7 @@ bool pos_minting_tx_packing::c1(currency::core& c, size_t ev_index, const std::v
|
|||
m_alice_start_amount + CURRENCY_BLOCK_REWARD * m_pos_mint_packing_size // unlocked
|
||||
), false, "");
|
||||
|
||||
alice_wlt->set_pos_mint_packing_size(m_pos_mint_packing_size);
|
||||
alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(m_pos_mint_packing_size + 1, m_pos_mint_packing_size + 1); // +1 because previous implementation () had an error with this limit
|
||||
|
||||
// no coinbase tx outputs should be packed
|
||||
r = alice_wlt->try_mint_pos();
|
||||
|
|
|
|||
|
|
@ -34,23 +34,24 @@ bool test_transaction_generation_and_ring_signature()
|
|||
|
||||
std::string add_str = miner_acc3.get_public_address_str();
|
||||
|
||||
uint64_t block_reward_without_fee = 0;
|
||||
|
||||
account_base rv_acc;
|
||||
rv_acc.generate();
|
||||
account_base rv_acc2;
|
||||
rv_acc2.generate();
|
||||
transaction tx_mine_1;
|
||||
construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().account_address, miner_acc1.get_keys().account_address, tx_mine_1, TRANSACTION_VERSION_PRE_HF4);
|
||||
construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().account_address, miner_acc1.get_keys().account_address, tx_mine_1, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4);
|
||||
transaction tx_mine_2;
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc2.get_keys().account_address, miner_acc2.get_keys().account_address, tx_mine_2, TRANSACTION_VERSION_PRE_HF4);
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc2.get_keys().account_address, miner_acc2.get_keys().account_address, tx_mine_2, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4);
|
||||
transaction tx_mine_3;
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc3.get_keys().account_address, miner_acc3.get_keys().account_address, tx_mine_3, TRANSACTION_VERSION_PRE_HF4);
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc3.get_keys().account_address, miner_acc3.get_keys().account_address, tx_mine_3, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4);
|
||||
transaction tx_mine_4;
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc4.get_keys().account_address, miner_acc4.get_keys().account_address, tx_mine_4, TRANSACTION_VERSION_PRE_HF4);
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc4.get_keys().account_address, miner_acc4.get_keys().account_address, tx_mine_4, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4);
|
||||
transaction tx_mine_5;
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc5.get_keys().account_address, miner_acc5.get_keys().account_address, tx_mine_5, TRANSACTION_VERSION_PRE_HF4);
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc5.get_keys().account_address, miner_acc5.get_keys().account_address, tx_mine_5, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4);
|
||||
transaction tx_mine_6;
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().account_address, miner_acc6.get_keys().account_address, tx_mine_6, TRANSACTION_VERSION_PRE_HF4);
|
||||
construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().account_address, miner_acc6.get_keys().account_address, tx_mine_6, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4);
|
||||
|
||||
//fill inputs entry
|
||||
typedef tx_source_entry::output_entry tx_output_entry;
|
||||
|
|
@ -134,8 +135,9 @@ bool test_block_creation()
|
|||
account_public_address adr;
|
||||
bool r = get_account_address_from_str(adr, "ZxDLGBGXbjo5w51tJkvxEPHFRr7Xft4hf33N8EkJPndoGCqocQF1mzpZqYwXByx5gMbfQuPAAB9vj79EFR6Jwkgu1o3aMQPwJ");
|
||||
CHECK_AND_ASSERT_MES(r, false, "failed to import");
|
||||
uint64_t block_reward_without_fee = 0;
|
||||
block b;
|
||||
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, TRANSACTION_VERSION_PRE_HF4);
|
||||
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3355,15 +3355,15 @@ packing_outputs_on_pos_minting_wallet::packing_outputs_on_pos_minting_wallet()
|
|||
|
||||
bool packing_outputs_on_pos_minting_wallet::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
// Test ideas:
|
||||
// 1) UTXO defragmentation tx cannot select stake output by accident;
|
||||
// 2) if UTXO defragmentation tx cannot be constructed because of too few decoy outputs, PoS can still be created;
|
||||
// 3) UTXO defragmentation tx limits works as expected.
|
||||
|
||||
// 0 10 11 21 22 <- blockchain height (assuming CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10)
|
||||
// (0 )... (0r)- (1 )... (1r)- <- main chain
|
||||
// tx_0 <- txs
|
||||
|
||||
GENERATE_ACCOUNT(miner_acc);
|
||||
m_accounts.push_back(miner_acc);
|
||||
//GENERATE_ACCOUNT(alice_acc);
|
||||
//m_accounts.push_back(alice_acc);
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate();
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate();
|
||||
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate();
|
||||
|
||||
// don't use MAKE_GENESIS_BLOCK here because it will mask 'generator'
|
||||
currency::block blk_0 = AUTO_VAL_INIT(blk_0);
|
||||
|
|
@ -3372,21 +3372,32 @@ bool packing_outputs_on_pos_minting_wallet::generate(std::vector<test_event_entr
|
|||
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
|
||||
CREATE_TEST_WALLET(miner_wlt, miner_acc, blk_0);
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, miner_wlt, blk_0, 0);
|
||||
uint64_t unlocked, awaiting_in, awaiting_out, mined;
|
||||
m_premine_amount = miner_wlt->balance(unlocked, awaiting_in, awaiting_out, mined);
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
size_t n_blocks = CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5;
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, n_blocks);
|
||||
m_mined_amount = n_blocks * COIN;
|
||||
m_single_amount = TESTS_DEFAULT_FEE * 5;
|
||||
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, miner_wlt, blk_0r, n_blocks);
|
||||
CHECK_TEST_WALLET_BALANCE_AT_GEN_TIME(miner_wlt, m_premine_amount + m_mined_amount);
|
||||
MAKE_TX(events, tx_0, miner_acc, alice_acc, m_single_amount, blk_0r);
|
||||
MAKE_TX(events, tx_1, miner_acc, alice_acc, m_single_amount, blk_0r);
|
||||
MAKE_TX(events, tx_2, miner_acc, alice_acc, m_single_amount, blk_0r);
|
||||
MAKE_TX(events, tx_3, miner_acc, alice_acc, m_single_amount, blk_0r);
|
||||
MAKE_TX(events, tx_4, miner_acc, alice_acc, m_single_amount, blk_0r);
|
||||
MAKE_TX(events, tx_5, miner_acc, bob_acc, m_single_amount, blk_0r);
|
||||
MAKE_TX(events, tx_6, miner_acc, bob_acc, m_single_amount, blk_0r);
|
||||
|
||||
//MAKE_TX_FEE(events, tx_0, miner_acc, alice_acc, MK_TEST_COINS(2000), TESTS_DEFAULT_FEE, blk_0r);
|
||||
//MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
|
||||
//REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE);
|
||||
m_alice_initial_balance = m_single_amount * 5;
|
||||
m_bob_initial_balance = m_single_amount * 2;
|
||||
|
||||
MAKE_NEXT_BLOCK_TX_LIST(events, blk_1, blk_0r, miner_acc, std::list<transaction>({tx_0, tx_1, tx_2, tx_3, tx_4, tx_5, tx_6}));
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
CREATE_TEST_WALLET(alice_wlt, alice_acc, blk_0);
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, alice_wlt, blk_1r, CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 1);
|
||||
CHECK_TEST_WALLET_BALANCE_AT_GEN_TIME(alice_wlt, m_alice_initial_balance);
|
||||
|
||||
CREATE_TEST_WALLET(bob_wlt, bob_acc, blk_0);
|
||||
REFRESH_TEST_WALLET_AT_GEN_TIME(events, bob_wlt, blk_1r, CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 1);
|
||||
CHECK_TEST_WALLET_BALANCE_AT_GEN_TIME(bob_wlt, m_bob_initial_balance);
|
||||
|
||||
DO_CALLBACK(events, "c1");
|
||||
|
||||
|
|
@ -3395,30 +3406,72 @@ bool packing_outputs_on_pos_minting_wallet::generate(std::vector<test_event_entr
|
|||
|
||||
bool packing_outputs_on_pos_minting_wallet::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX);
|
||||
size_t blocks_fetched = 0;
|
||||
bool received_money;
|
||||
std::atomic<bool> atomic_false = ATOMIC_VAR_INIT(false);
|
||||
miner_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5, false, "Incorrect numbers of blocks fetched");
|
||||
|
||||
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 1, false, "Incorrect numbers of blocks fetched: " << blocks_fetched);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", m_alice_initial_balance, 0, m_alice_initial_balance, 0, 0), false, "");
|
||||
|
||||
bob_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 1, false, "Incorrect numbers of blocks fetched: " << blocks_fetched);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "bob_wlt", m_bob_initial_balance, 0, m_bob_initial_balance, 0, 0), false, "");
|
||||
|
||||
// 1. Try to defragment the same UTXO that is used for staking
|
||||
// (Bob has two: one UTXO is for staking, other is being defragmented)
|
||||
bob_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 10);
|
||||
bob_wlt->set_pos_decoys_count_for_defragmentation_tx(0);
|
||||
bob_wlt->try_mint_pos();
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 3, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());
|
||||
bob_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect numbers of blocks fetched: " << blocks_fetched);
|
||||
|
||||
// (also make sure that unlocked balance is zero)
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt.get(), "bob_wlt", m_bob_initial_balance + CURRENCY_BLOCK_REWARD, CURRENCY_BLOCK_REWARD + TESTS_DEFAULT_FEE, 0), false, "");
|
||||
|
||||
|
||||
miner_wlt->set_pos_mint_packing_size(4);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*miner_wlt.get(), "miner_wlt", m_premine_amount + m_mined_amount, uint64_max, uint64_max, 0, 0), false, "");
|
||||
// 2. Try to mine a PoS block and defragment some of UTXO
|
||||
alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(2, 2);
|
||||
alice_wlt->set_pos_decoys_count_for_defragmentation_tx(0);
|
||||
alice_wlt->try_mint_pos();
|
||||
|
||||
miner_wlt->try_mint_pos();
|
||||
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 4, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());
|
||||
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == 2, false, "Incorrect numbers of blocks fetched: " << blocks_fetched);
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 7, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());
|
||||
miner_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect numbers of blocks fetched");
|
||||
// (also make sure that only two UTXOs is unlocked)
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", m_alice_initial_balance + CURRENCY_BLOCK_REWARD, CURRENCY_BLOCK_REWARD + TESTS_DEFAULT_FEE, m_single_amount * 2), false, "");
|
||||
|
||||
block top_block = AUTO_VAL_INIT(top_block);
|
||||
bool r = c.get_blockchain_storage().get_top_block(top_block);
|
||||
CHECK_AND_ASSERT_MES(r && is_pos_block(top_block), false, "get_top_block failed or smth goes wrong");
|
||||
uint64_t top_block_reward = get_outs_money_amount(top_block.miner_tx);
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*miner_wlt.get(), "miner_wlt", m_premine_amount + m_mined_amount + COIN), false, "");
|
||||
|
||||
miner_wlt->reset_password(g_wallet_password);
|
||||
miner_wlt->store(g_wallet_filename);
|
||||
// 3. Try to mine a PoS block and defragment with huge decoy set. Make sure block is mined successfully without a defragmentation tx
|
||||
// Alice has one UTXO
|
||||
alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 1);
|
||||
alice_wlt->set_pos_decoys_count_for_defragmentation_tx(80);
|
||||
alice_wlt->try_mint_pos();
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 5, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());
|
||||
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect numbers of blocks fetched: " << blocks_fetched);
|
||||
|
||||
// Alice's unlocked balance should consist only of one UTXO
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", m_alice_initial_balance + CURRENCY_BLOCK_REWARD * 2, CURRENCY_BLOCK_REWARD * 2 + TESTS_DEFAULT_FEE, m_single_amount), false, "");
|
||||
|
||||
|
||||
// 4. Finally mine a PoS and defragment the last one unlocked UTXO
|
||||
alice_wlt->set_pos_utxo_count_limits_for_defragmentation_tx(1, 1);
|
||||
alice_wlt->set_pos_decoys_count_for_defragmentation_tx(0);
|
||||
alice_wlt->try_mint_pos();
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_current_blockchain_size() == CURRENCY_MINED_MONEY_UNLOCK_WINDOW * 2 + 6, false, "Incorrect blockchain height:" << c.get_current_blockchain_size());
|
||||
alice_wlt->refresh(blocks_fetched, received_money, atomic_false);
|
||||
CHECK_AND_ASSERT_MES(blocks_fetched == 1, false, "Incorrect numbers of blocks fetched: " << blocks_fetched);
|
||||
|
||||
// Alice's unlocked balance should be zero
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", m_alice_initial_balance + CURRENCY_BLOCK_REWARD * 3, CURRENCY_BLOCK_REWARD * 3 + TESTS_DEFAULT_FEE, 0), false, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -257,8 +257,9 @@ struct packing_outputs_on_pos_minting_wallet : public wallet_test
|
|||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable uint64_t m_premine_amount = 0;
|
||||
mutable uint64_t m_mined_amount = 0;
|
||||
mutable uint64_t m_single_amount = 0;
|
||||
mutable uint64_t m_alice_initial_balance = 0;
|
||||
mutable uint64_t m_bob_initial_balance = 0;
|
||||
};
|
||||
|
||||
struct wallet_sending_to_integrated_address : public wallet_test
|
||||
|
|
|
|||
|
|
@ -807,7 +807,7 @@ bool zarcanum_block_with_txs::generate(std::vector<test_event_entry>& events) co
|
|||
|
||||
// make sure Alice received both block reward and the fee
|
||||
uint64_t mined_amount_2 = COIN + fee;
|
||||
DO_CALLBACK_PARAMS(events, "check_balance", params_check_balance(ALICE_ACC_IDX, m_alice_balance + mined_amount_2, 0, mined_amount + mined_amount_2, 0, 0));
|
||||
DO_CALLBACK_PARAMS(events, "check_balance", params_check_balance(ALICE_ACC_IDX, m_alice_balance + mined_amount_2, UINT64_MAX, mined_amount + mined_amount_2, 0, 0));
|
||||
m_alice_balance += mined_amount_2;
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue