forked from lthn/blockchain
Merge branch 'multiassets' into zarcanum
This commit is contained in:
commit
e70efc898c
9 changed files with 208 additions and 134 deletions
|
|
@ -206,8 +206,22 @@ namespace currency
|
|||
uint32_t n_extras;
|
||||
};
|
||||
|
||||
//!!!!this is temporary struct!!!
|
||||
//needed only to hold asset_id of input/output while zarcanum extension being developed
|
||||
struct open_asset_id
|
||||
{
|
||||
crypto::hash asset_id;
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(asset_id) // referring_input
|
||||
END_SERIALIZE()
|
||||
|
||||
typedef boost::variant<signed_parts, extra_attachment_info> txin_etc_details_v;
|
||||
BEGIN_BOOST_SERIALIZATION()
|
||||
BOOST_SERIALIZE(asset_id)
|
||||
END_BOOST_SERIALIZATION()
|
||||
};
|
||||
|
||||
|
||||
typedef boost::variant<signed_parts, extra_attachment_info, open_asset_id> txin_etc_details_v;
|
||||
|
||||
|
||||
struct referring_input
|
||||
|
|
@ -372,6 +386,7 @@ namespace currency
|
|||
END_BOOST_SERIALIZATION()
|
||||
};
|
||||
|
||||
typedef boost::variant<open_asset_id> txout_etc_details_v;
|
||||
|
||||
struct tx_out_zarcanum
|
||||
{
|
||||
|
|
@ -386,6 +401,7 @@ namespace currency
|
|||
crypto::public_key amount_commitment; // premultiplied by 1/8
|
||||
uint64_t encrypted_amount;
|
||||
uint8_t mix_attr;
|
||||
std::vector<txout_etc_details_v> etc_details;
|
||||
//crypto::public_key token_masked_generator;
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
|
|
@ -1063,7 +1079,7 @@ SET_VARIANT_TAGS(currency::void_sig, 44, "void_sig");
|
|||
SET_VARIANT_TAGS(currency::zarcanum_outs_range_proof, 45, "zarcanum_outs_range_proof");
|
||||
SET_VARIANT_TAGS(currency::zc_balance_proof, 46, "zc_balance_proof");
|
||||
|
||||
|
||||
SET_VARIANT_TAGS(currency::open_asset_id, 47, "asset_id");
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -882,6 +882,14 @@ namespace currency
|
|||
// TODO @#@# implement multisig support
|
||||
|
||||
tx_out_zarcanum out = AUTO_VAL_INIT(out);
|
||||
//@#@
|
||||
//TODO: TEMPORARY
|
||||
if (de.asset_id != currency::null_hash)
|
||||
{
|
||||
out.etc_details.push_back(open_asset_id{ de.asset_id });
|
||||
}
|
||||
//@#@
|
||||
|
||||
const account_public_address& apa = de.addr.front();
|
||||
if (apa.spend_public_key == null_pkey && apa.view_public_key == null_pkey)
|
||||
{
|
||||
|
|
@ -1881,8 +1889,13 @@ namespace currency
|
|||
txin_zc_input zc_in = AUTO_VAL_INIT(zc_in);
|
||||
zc_in.k_image = img;
|
||||
zc_in.key_offsets = std::move(key_offsets);
|
||||
//TEMPORARY
|
||||
if (src_entr.asset_id != currency::null_hash)
|
||||
{
|
||||
zc_in.etc_details.push_back(open_asset_id{ src_entr.asset_id });
|
||||
}
|
||||
tx.vin.push_back(zc_in);
|
||||
//zc_sources.push_back(&src_entr);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1906,6 +1919,9 @@ namespace currency
|
|||
if (shuffle)
|
||||
std::sort(shuffled_dsts.begin(), shuffled_dsts.end(), [](const tx_destination_entry& de1, const tx_destination_entry& de2) { return de1.amount < de2.amount; });
|
||||
|
||||
|
||||
// TODO: consider "Shuffle" inputs
|
||||
|
||||
uint64_t summary_outs_money = 0;
|
||||
//fill outputs
|
||||
size_t output_index = tx.vout.size(); // in case of append mode we need to start output indexing from the last one + 1
|
||||
|
|
@ -2578,6 +2594,11 @@ namespace currency
|
|||
if (is_out_to_acc(acc, zo, derivation, output_index, amount, blinding_mask))
|
||||
{
|
||||
outs.emplace_back(output_index, amount, blinding_mask);
|
||||
open_asset_id v = AUTO_VAL_INIT(v);
|
||||
if (get_type_in_variant_container(zo.etc_details, v))
|
||||
{
|
||||
outs.back().asset_id = v.asset_id;
|
||||
}
|
||||
money_transfered += amount;
|
||||
}
|
||||
VARIANT_SWITCH_END();
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ namespace currency
|
|||
size_t index = SIZE_MAX;
|
||||
uint64_t amount = 0;
|
||||
crypto::scalar_t blinding_mask = 0;
|
||||
crypto::hash asset_id = currency::null_hash;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,17 +41,18 @@ namespace currency
|
|||
//typedef serializable_pair<txout_ref_v, crypto::public_key> output_entry; // txout_ref_v is either global output index or ref_by_id; public_key - is output's stealth address
|
||||
|
||||
std::vector<output_entry> outputs;
|
||||
uint64_t real_output; //index in outputs vector of real output_entry
|
||||
crypto::public_key real_out_tx_key; //real output's transaction's public key
|
||||
crypto::scalar_t real_out_amount_blinding_mask; //blinding mask of real out's amount committment (only for zarcanum inputs, otherwise must be 0)
|
||||
size_t real_output_in_tx_index; //index in transaction outputs vector
|
||||
uint64_t amount; //money
|
||||
uint64_t transfer_index; //money
|
||||
crypto::hash multisig_id; //if txin_multisig: multisig output id
|
||||
size_t ms_sigs_count; //if txin_multisig: must be equal to output's minimum_sigs
|
||||
size_t ms_keys_count; //if txin_multisig: must be equal to size of output's keys container
|
||||
bool separately_signed_tx_complete; //for separately signed tx only: denotes the last source entry in complete tx to explicitly mark the final step of tx creation
|
||||
std::string htlc_origin; //for htlc, specify origin
|
||||
uint64_t real_output = 0; //index in outputs vector of real output_entry
|
||||
crypto::public_key real_out_tx_key = currency::null_pkey; //real output's transaction's public key
|
||||
crypto::scalar_t real_out_amount_blinding_mask; //blinding mask of real out's amount committment (only for zarcanum inputs, otherwise must be 0)
|
||||
size_t real_output_in_tx_index = 0; //index in transaction outputs vector
|
||||
uint64_t amount = 0; //money
|
||||
uint64_t transfer_index = 0; //index in m_transfers
|
||||
crypto::hash multisig_id = currency::null_hash; //if txin_multisig: multisig output id
|
||||
size_t ms_sigs_count = 0; //if txin_multisig: must be equal to output's minimum_sigs
|
||||
size_t ms_keys_count = 0; //if txin_multisig: must be equal to size of output's keys container
|
||||
bool separately_signed_tx_complete = false; //for separately signed tx only: denotes the last source entry in complete tx to explicitly mark the final step of tx creation
|
||||
std::string htlc_origin; //for htlc, specify origin
|
||||
crypto::hash asset_id = currency::null_hash; //asset id
|
||||
|
||||
bool is_multisig() const { return ms_sigs_count > 0; }
|
||||
bool is_zarcanum() const { return !real_out_amount_blinding_mask.is_zero(); }
|
||||
|
|
@ -76,8 +77,8 @@ namespace currency
|
|||
//if this struct is present, then creating htlc out, expiration -> number of blocks that htlc proposal is active
|
||||
struct destination_option_htlc_out
|
||||
{
|
||||
uint64_t expiration;
|
||||
crypto::hash htlc_hash;
|
||||
uint64_t expiration = 0;
|
||||
crypto::hash htlc_hash = currency::null_hash;
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(expiration)
|
||||
|
|
@ -90,16 +91,17 @@ namespace currency
|
|||
{
|
||||
uint64_t amount; //money
|
||||
std::list<account_public_address> addr; //destination address, in case of 1 address - txout_to_key, in case of more - txout_multisig
|
||||
size_t minimum_sigs; //if txout_multisig: minimum signatures that are required to spend this output (minimum_sigs <= addr.size()) IF txout_to_key - not used
|
||||
uint64_t amount_to_provide; //amount money that provided by initial creator of tx, used with partially created transactions
|
||||
uint64_t unlock_time;
|
||||
destination_option_htlc_out htlc_options; //htlc options
|
||||
size_t minimum_sigs = 0; //if txout_multisig: minimum signatures that are required to spend this output (minimum_sigs <= addr.size()) IF txout_to_key - not used
|
||||
uint64_t amount_to_provide = 0; //amount money that provided by initial creator of tx, used with partially created transactions
|
||||
uint64_t unlock_time = 0;
|
||||
destination_option_htlc_out htlc_options; //htlc options
|
||||
crypto::hash asset_id = currency::null_hash;
|
||||
|
||||
|
||||
tx_destination_entry() : amount(0), minimum_sigs(0), amount_to_provide(0), unlock_time(0), htlc_options(destination_option_htlc_out()){}
|
||||
tx_destination_entry(uint64_t a, const account_public_address& ad) : amount(a), addr(1, ad), minimum_sigs(0), amount_to_provide(0), unlock_time(0), htlc_options(destination_option_htlc_out()) {}
|
||||
tx_destination_entry(uint64_t a, const account_public_address& ad, uint64_t ut) : amount(a), addr(1, ad), minimum_sigs(0), amount_to_provide(0), unlock_time(ut), htlc_options(destination_option_htlc_out()) {}
|
||||
tx_destination_entry(uint64_t a, const std::list<account_public_address>& addr) : amount(a), addr(addr), minimum_sigs(addr.size()), amount_to_provide(0), unlock_time(0), htlc_options(destination_option_htlc_out()) {}
|
||||
tx_destination_entry() = default;
|
||||
tx_destination_entry(uint64_t a, const account_public_address& ad) : amount(a), addr(1, ad) {}
|
||||
tx_destination_entry(uint64_t a, const account_public_address& ad, uint64_t ut) : amount(a), addr(1, ad), unlock_time(ut) {}
|
||||
tx_destination_entry(uint64_t a, const std::list<account_public_address>& addr) : amount(a), addr(addr), minimum_sigs(addr.size()) {}
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(amount)
|
||||
|
|
|
|||
|
|
@ -2184,6 +2184,7 @@ QString MainWindow::toggle_autostart(const QString& param)
|
|||
return MAKE_RESPONSE(default_ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
/*
|
||||
QString MainWindow::check_available_sources(const QString& param)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
|
@ -2192,6 +2193,7 @@ QString MainWindow::check_available_sources(const QString& param)
|
|||
return m_backend.check_available_sources(sources.wallet_id, sources.req_data).c_str();
|
||||
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
|
||||
}
|
||||
*/
|
||||
|
||||
QString MainWindow::open_url_in_browser(const QString& param)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ public:
|
|||
bool set_is_disabled_notifications(const bool& param);
|
||||
QString export_wallet_history(const QString& param);
|
||||
QString get_log_file();
|
||||
QString check_available_sources(const QString& param);
|
||||
//QString check_available_sources(const QString& param);
|
||||
QString open_url_in_browser(const QString& param);
|
||||
|
||||
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
|
|
|
|||
|
|
@ -626,6 +626,10 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
td.m_ptx_wallet_info = pwallet_info;
|
||||
td.m_internal_output_index = o;
|
||||
td.m_key_image = ki;
|
||||
if (outs[i_in_outs].asset_id != currency::null_hash)
|
||||
{
|
||||
td.m_asset_id.reset(new crypto::hash(outs[i_in_outs].asset_id));
|
||||
}
|
||||
td.m_amount = outs[i_in_outs].amount;
|
||||
if (m_use_deffered_global_outputs)
|
||||
{
|
||||
|
|
@ -695,7 +699,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
if (td.m_key_image != currency::null_ki)
|
||||
m_key_images[td.m_key_image] = transfer_index;
|
||||
|
||||
add_transfer_to_transfers_cache(td.m_amount, transfer_index);
|
||||
add_transfer_to_transfers_cache(td.m_amount, transfer_index, td.get_asset_id());
|
||||
|
||||
if (is_watch_only() && is_auditable())
|
||||
{
|
||||
|
|
@ -865,7 +869,7 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept
|
|||
construct_param.crypt_address = m_account.get_public_address();
|
||||
construct_param.flags = TX_FLAG_SIGNATURE_MODE_SEPARATE;
|
||||
construct_param.mark_tx_as_complete = true;
|
||||
construct_param.split_strategy_id = detail::ssi_digit;
|
||||
construct_param.split_strategy_id = get_current_split_strategy();
|
||||
|
||||
//little hack for now, we add multisig_entry before transaction actually get to blockchain
|
||||
//to let prepare_transaction (which is called from build_escrow_release_templates) work correct
|
||||
|
|
@ -876,7 +880,7 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept
|
|||
transfer_details_base& tdb = m_multisig_transfers[contract_id];
|
||||
//create once instance of tx for all entries
|
||||
std::shared_ptr<transaction_wallet_info> pwallet_info(new transaction_wallet_info());
|
||||
pwallet_info->m_tx = tx;;
|
||||
pwallet_info->m_tx = tx;
|
||||
pwallet_info->m_block_height = 0;
|
||||
pwallet_info->m_block_timestamp = 0;
|
||||
tdb.m_ptx_wallet_info = pwallet_info;
|
||||
|
|
@ -1050,7 +1054,7 @@ void wallet2::request_cancel_contract(const crypto::hash& contract_id, uint64_t
|
|||
tsa.flags |= TX_SERVICE_ATTACHMENT_ENCRYPT_BODY;
|
||||
construct_param.extra.push_back(tsa);
|
||||
construct_param.crypt_address = contr_it->second.private_detailes.b_addr;
|
||||
construct_param.split_strategy_id = detail::ssi_digit;
|
||||
construct_param.split_strategy_id = get_current_split_strategy();
|
||||
|
||||
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
|
||||
ftp.tx_version = this->get_current_tx_version();
|
||||
|
|
@ -1822,6 +1826,14 @@ void wallet2::refresh(std::atomic<bool>& stop)
|
|||
refresh(n, f, stop);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
detail::split_strategy_id_t wallet2::get_current_split_strategy()
|
||||
{
|
||||
if (is_need_to_split_outputs())
|
||||
return tools::detail::ssi_digit;
|
||||
else
|
||||
return tools::detail::ssi_void;
|
||||
}
|
||||
//
|
||||
void wallet2::transfer(uint64_t amount, const currency::account_public_address& acc, currency::transaction& result_tx)
|
||||
{
|
||||
std::vector<currency::extra_v> extra;
|
||||
|
|
@ -1831,7 +1843,7 @@ void wallet2::transfer(uint64_t amount, const currency::account_public_address&
|
|||
dst.resize(1);
|
||||
dst.back().addr.push_back(acc);
|
||||
dst.back().amount = amount;
|
||||
this->transfer(dst, 0, 0, TX_DEFAULT_FEE, extra, attachments, tools::detail::ssi_digit, tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), result_tx);
|
||||
this->transfer(dst, 0, 0, TX_DEFAULT_FEE, extra, attachments, get_current_split_strategy(), tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD), result_tx);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::transfer(uint64_t amount, const currency::account_public_address& acc)
|
||||
|
|
@ -3074,8 +3086,8 @@ void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) con
|
|||
bool wallet2::generate_packing_transaction_if_needed(currency::transaction& tx, uint64_t fake_outputs_number)
|
||||
{
|
||||
prepare_free_transfers_cache(0);
|
||||
auto it = m_found_free_amounts.find(CURRENCY_BLOCK_REWARD);
|
||||
if (it == m_found_free_amounts.end() || it->second.size() <= m_pos_mint_packing_size)
|
||||
auto it = m_found_free_amounts[currency::null_hash].find(CURRENCY_BLOCK_REWARD);
|
||||
if (it == m_found_free_amounts[currency::null_hash].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
|
||||
|
|
@ -3227,12 +3239,16 @@ void wallet2::sign_transfer_files(const std::string& tx_sources_file, const std:
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::get_utxo_distribution(std::map<uint64_t, uint64_t>& distribution)
|
||||
{
|
||||
//TODO@#@
|
||||
/*
|
||||
prepare_free_transfers_cache(0);
|
||||
for (auto ent : m_found_free_amounts)
|
||||
{
|
||||
distribution[ent.first] = ent.second.size();
|
||||
}
|
||||
return true;
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::submit_transfer(const std::string& signed_tx_blob, currency::transaction& tx)
|
||||
|
|
@ -3968,7 +3984,7 @@ void wallet2::push_offer(const bc_services::offer_details_ex& od, currency::tran
|
|||
bc_services::put_offer_into_attachment(static_cast<bc_services::offer_details>(od), attachments);
|
||||
|
||||
destinations.push_back(tx_dest);
|
||||
transfer(destinations, 0, 0, od.fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx);
|
||||
transfer(destinations, 0, 0, od.fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
const transaction& wallet2::get_transaction_by_id(const crypto::hash& tx_hash)
|
||||
|
|
@ -3998,7 +4014,7 @@ void wallet2::cancel_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, uin
|
|||
crypto::generate_signature(crypto::cn_fast_hash(sig_blob.data(), sig_blob.size()), ephemeral.pub, ephemeral.sec, co.sig);
|
||||
bc_services::put_offer_into_attachment(co, attachments);
|
||||
|
||||
transfer(std::vector<currency::tx_destination_entry>(), 0, 0, fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx);
|
||||
transfer(std::vector<currency::tx_destination_entry>(), 0, 0, fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::update_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, const bc_services::offer_details_ex& od, currency::transaction& res_tx)
|
||||
|
|
@ -4024,7 +4040,7 @@ void wallet2::update_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, con
|
|||
bc_services::put_offer_into_attachment(uo, attachments);
|
||||
|
||||
destinations.push_back(tx_dest);
|
||||
transfer(destinations, 0, 0, od.fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx);
|
||||
transfer(destinations, 0, 0, od.fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector<currency::extra_v>& extra)
|
||||
|
|
@ -4104,7 +4120,7 @@ void wallet2::request_alias_registration(currency::extra_alias_entry& ai, curren
|
|||
tx_dest_alias_reward.amount = reward;
|
||||
destinations.push_back(tx_dest_alias_reward);
|
||||
|
||||
transfer(destinations, 0, 0, fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx, CURRENCY_TO_KEY_OUT_RELAXED, false);
|
||||
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);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::request_alias_update(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward)
|
||||
|
|
@ -4129,11 +4145,12 @@ void wallet2::request_alias_update(currency::extra_alias_entry& ai, currency::tr
|
|||
|
||||
push_alias_info_to_extra_according_to_hf_status(ai, extra);
|
||||
|
||||
transfer(destinations, 0, 0, fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), res_tx, CURRENCY_TO_KEY_OUT_RELAXED, false);
|
||||
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);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::check_available_sources(std::list<uint64_t>& amounts)
|
||||
{
|
||||
/*
|
||||
std::list<std::vector<uint64_t> > holds;
|
||||
amounts.sort();
|
||||
bool res = true;
|
||||
|
|
@ -4159,6 +4176,8 @@ bool wallet2::check_available_sources(std::list<uint64_t>& amounts)
|
|||
|
||||
WLT_LOG_MAGENTA("[CHECK_AVAILABLE_SOURCES]: " << amounts << " res: " << res << ENDL <<" holds: " << holds, LOG_LEVEL_0);
|
||||
return res;
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
std::string get_random_rext(size_t len)
|
||||
|
|
@ -4246,7 +4265,7 @@ void wallet2::build_escrow_release_templates(crypto::hash multisig_id,
|
|||
construct_tx_param construct_params = AUTO_VAL_INIT(construct_params);
|
||||
construct_params.fee = fee;
|
||||
construct_params.multisig_id = multisig_id;
|
||||
construct_params.split_strategy_id = detail::ssi_digit;
|
||||
construct_params.split_strategy_id = get_current_split_strategy();
|
||||
construct_params.dsts.resize(2);
|
||||
//0 - addr_a
|
||||
//1 - addr_b
|
||||
|
|
@ -4310,7 +4329,7 @@ void wallet2::build_escrow_cancel_template(crypto::hash multisig_id,
|
|||
ftp.tx_version = this->get_current_tx_version();
|
||||
construct_params.fee = it->second.amount() - (ecrow_details.amount_a_pledge + ecrow_details.amount_to_pay + ecrow_details.amount_b_pledge);
|
||||
construct_params.multisig_id = multisig_id;
|
||||
construct_params.split_strategy_id = detail::ssi_digit;
|
||||
construct_params.split_strategy_id = get_current_split_strategy();
|
||||
construct_params.dsts.resize(2);
|
||||
//0 - addr_a
|
||||
//1 - addr_b
|
||||
|
|
@ -4360,7 +4379,7 @@ void wallet2::build_escrow_template(const bc_services::contract_private_details&
|
|||
ctp.mark_tx_as_complete = false;
|
||||
ctp.multisig_id = currency::null_hash;
|
||||
ctp.shuffle = true;
|
||||
ctp.split_strategy_id = detail::ssi_digit;
|
||||
ctp.split_strategy_id = get_current_split_strategy();
|
||||
ctp.tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED;
|
||||
ctp.unlock_time = unlock_time;
|
||||
|
||||
|
|
@ -4518,7 +4537,7 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details&
|
|||
ctp.fake_outputs_count = fake_outputs_count;
|
||||
ctp.fee = fee;
|
||||
ctp.shuffle = true;
|
||||
ctp.split_strategy_id = detail::ssi_digit;
|
||||
ctp.split_strategy_id = get_current_split_strategy();
|
||||
ctp.tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED;
|
||||
ctp.unlock_time = unlock_time;
|
||||
|
||||
|
|
@ -4646,8 +4665,8 @@ bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& o
|
|||
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)
|
||||
{
|
||||
prepare_free_transfers_cache(fake_outputs_count);
|
||||
auto it = m_found_free_amounts.find(CURRENCY_BLOCK_REWARD);
|
||||
if (it == m_found_free_amounts.end() || it->second.size() < m_pos_mint_packing_size)
|
||||
auto it = m_found_free_amounts[currency::null_hash].find(CURRENCY_BLOCK_REWARD);
|
||||
if (it == m_found_free_amounts[currency::null_hash].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; )
|
||||
|
|
@ -4664,19 +4683,20 @@ bool wallet2::prepare_tx_sources_for_packing(uint64_t items_to_pack, size_t fake
|
|||
set_it++;
|
||||
}
|
||||
if (!it->second.size())
|
||||
m_found_free_amounts.erase(it);
|
||||
m_found_free_amounts[currency::null_hash].erase(it);
|
||||
|
||||
return prepare_tx_sources(fake_outputs_count, sources, selected_indicies, found_money);
|
||||
return prepare_tx_sources(fake_outputs_count, sources, selected_indicies);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_tx_sources(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust_threshold, std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies, uint64_t& found_money)
|
||||
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)
|
||||
{
|
||||
found_money = select_transfers(needed_money, fake_outputs_count, dust_threshold, selected_indicies);
|
||||
WLT_THROW_IF_FALSE_WALLET_EX_MES(found_money >= needed_money, error::not_enough_money, "", found_money, needed_money, 0);
|
||||
return prepare_tx_sources(fake_outputs_count, sources, selected_indicies, found_money);
|
||||
bool r = select_transfers(needed_money_map, fake_outputs_count, dust_threshold, selected_indicies);
|
||||
if (!r)
|
||||
return r;
|
||||
return prepare_tx_sources(fake_outputs_count, sources, selected_indicies);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::prefetch_global_indicies_if_needed(std::vector<uint64_t>& selected_indicies)
|
||||
void wallet2::prefetch_global_indicies_if_needed(const std::vector<uint64_t>& selected_indicies)
|
||||
{
|
||||
std::list<std::reference_wrapper<const currency::transaction>> txs;
|
||||
std::list<uint64_t> indices_that_requested_global_indicies;
|
||||
|
|
@ -4702,7 +4722,7 @@ void wallet2::prefetch_global_indicies_if_needed(std::vector<uint64_t>& selected
|
|||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_tx_sources(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(size_t fake_outputs_count, std::vector<currency::tx_source_entry>& sources, const std::vector<uint64_t>& selected_indicies)
|
||||
{
|
||||
typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry;
|
||||
typedef currency::tx_source_entry::output_entry tx_output_entry;
|
||||
|
|
@ -4754,6 +4774,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
|
|||
transfer_details& td = *it;
|
||||
src.transfer_index = it - m_transfers.begin();
|
||||
src.amount = td.amount();
|
||||
src.asset_id = td.get_asset_id();
|
||||
//paste mixin transaction
|
||||
if (daemon_resp.outs.size())
|
||||
{
|
||||
|
|
@ -4894,9 +4915,10 @@ bool wallet2::prepare_tx_sources_htlc(crypto::hash htlc_tx_id, const std::string
|
|||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
uint64_t wallet2::get_needed_money(uint64_t fee, const std::vector<currency::tx_destination_entry>& dsts)
|
||||
assets_selection_context wallet2::get_needed_money(uint64_t fee, const std::vector<currency::tx_destination_entry>& dsts)
|
||||
{
|
||||
uint64_t needed_money = fee;
|
||||
assets_selection_context amounts_map;
|
||||
amounts_map[currency::null_hash].needed_amount = fee;
|
||||
BOOST_FOREACH(auto& dt, dsts)
|
||||
{
|
||||
THROW_IF_TRUE_WALLET_EX(0 == dt.amount, error::zero_destination);
|
||||
|
|
@ -4904,10 +4926,10 @@ uint64_t wallet2::get_needed_money(uint64_t fee, const std::vector<currency::tx_
|
|||
if (dt.amount_to_provide)
|
||||
money_to_add = dt.amount_to_provide;
|
||||
|
||||
needed_money += money_to_add;
|
||||
THROW_IF_TRUE_WALLET_EX(needed_money < money_to_add, error::tx_sum_overflow, dsts, fee);
|
||||
amounts_map[dt.asset_id].needed_amount += money_to_add;
|
||||
THROW_IF_TRUE_WALLET_EX(amounts_map[dt.asset_id].needed_amount < money_to_add, error::tx_sum_overflow, dsts, fee);
|
||||
}
|
||||
return needed_money;
|
||||
return std::move(amounts_map);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
void wallet2::set_disable_tor_relay(bool disable)
|
||||
|
|
@ -5184,6 +5206,20 @@ bool wallet2::get_actual_offers(std::list<bc_services::offer_details_ex>& offers
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::select_indices_for_transfer(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector<uint64_t>& selected_indexes)
|
||||
{
|
||||
bool res = true;
|
||||
//
|
||||
for (auto& item : needed_money_map)
|
||||
{
|
||||
auto asset_cashe_it = m_found_free_amounts.find(item.first);
|
||||
WLT_THROW_IF_FALSE_WALLET_EX_MES(asset_cashe_it != m_found_free_amounts.end(), error::not_enough_money, "", item.second.found_amount, item.second.needed_amount, 0, item.first);
|
||||
item.second.found_amount = select_indices_for_transfer(selected_indexes, asset_cashe_it->second, item.second.needed_amount, fake_outputs_count);
|
||||
WLT_THROW_IF_FALSE_WALLET_EX_MES(item.second.found_amount >= item.second.needed_amount, error::not_enough_money, "", item.second.found_amount, item.second.needed_amount, 0, item.first);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
uint64_t wallet2::select_indices_for_transfer(std::vector<uint64_t>& selected_indexes, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count)
|
||||
{
|
||||
WLT_LOG_GREEN("Selecting indices for transfer of " << print_money_brief(needed_money) << " with " << fake_outputs_count << " fake outs, found_free_amounts.size()=" << found_free_amounts.size() << "...", LOG_LEVEL_0);
|
||||
|
|
@ -5276,7 +5312,7 @@ bool wallet2::prepare_free_transfers_cache(uint64_t fake_outputs_count)
|
|||
if (is_transfer_able_to_go(td, fake_outputs_count))
|
||||
{
|
||||
//@#@
|
||||
m_found_free_amounts[td.amount()].insert(i);
|
||||
m_found_free_amounts[td.get_asset_id()][td.amount()].insert(i);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
|
@ -5291,18 +5327,18 @@ void wallet2::add_transfers_to_transfers_cache(const std::vector<uint64_t>& inde
|
|||
{
|
||||
//@#@
|
||||
for (auto i : indexs)
|
||||
add_transfer_to_transfers_cache(boost::get<tx_out_bare>(m_transfers[i].m_ptx_wallet_info->m_tx.vout[m_transfers[i].m_internal_output_index]).amount , i);
|
||||
add_transfer_to_transfers_cache(m_transfers[i].amount(), i, m_transfers[i].get_asset_id());
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::add_transfer_to_transfers_cache(uint64_t amount, uint64_t index)
|
||||
void wallet2::add_transfer_to_transfers_cache(uint64_t amount, uint64_t index, const crypto::hash& asset_id)
|
||||
{
|
||||
m_found_free_amounts[amount].insert(index);
|
||||
m_found_free_amounts[asset_id][amount].insert(index);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
uint64_t wallet2::select_transfers(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust, std::vector<uint64_t>& selected_indicies)
|
||||
bool wallet2::select_transfers(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust, std::vector<uint64_t>& selected_indicies)
|
||||
{
|
||||
prepare_free_transfers_cache(fake_outputs_count);
|
||||
return select_indices_for_transfer(selected_indicies, m_found_free_amounts, needed_money, fake_outputs_count);
|
||||
return select_indices_for_transfer(needed_money_map, fake_outputs_count, selected_indicies);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::read_money_transfer2_details_from_tx(const transaction& tx, const std::vector<currency::tx_destination_entry>& splitted_dsts,
|
||||
|
|
@ -5399,7 +5435,7 @@ void wallet2::transfer(const std::vector<currency::tx_destination_entry>& dsts,
|
|||
const std::vector<currency::attachment_v>& attachments,
|
||||
currency::transaction& tx)
|
||||
{
|
||||
transfer(dsts, fake_outputs_count, unlock_time, fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx);
|
||||
transfer(dsts, fake_outputs_count, unlock_time, fee, extra, attachments, get_current_split_strategy(), tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::transfer(const std::vector<currency::tx_destination_entry>& dsts, size_t fake_outputs_count,
|
||||
|
|
@ -5498,21 +5534,43 @@ bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) c
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::is_need_to_split_outputs()
|
||||
{
|
||||
if (this->m_core_runtime_config.hard_forks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, this->get_blockchain_current_size()))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::prepare_tx_destinations(const assets_selection_context& needed_money_map,
|
||||
detail::split_strategy_id_t destination_split_strategy_id,
|
||||
const tx_dust_policy& dust_policy,
|
||||
const std::vector<currency::tx_destination_entry>& dsts,
|
||||
std::vector<currency::tx_destination_entry>& final_detinations)
|
||||
{
|
||||
for (auto& el: needed_money_map)
|
||||
{
|
||||
prepare_tx_destinations(el.second.needed_amount, el.second.found_amount, destination_split_strategy_id, dust_policy, dsts, final_detinations, el.first);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::prepare_tx_destinations(uint64_t needed_money,
|
||||
uint64_t found_money,
|
||||
detail::split_strategy_id_t destination_split_strategy_id,
|
||||
const tx_dust_policy& dust_policy,
|
||||
const std::vector<currency::tx_destination_entry>& dsts,
|
||||
std::vector<currency::tx_destination_entry>& final_detinations)
|
||||
std::vector<currency::tx_destination_entry>& final_detinations, const crypto::hash& asset_id)
|
||||
{
|
||||
currency::tx_destination_entry change_dts = AUTO_VAL_INIT(change_dts);
|
||||
if (needed_money < found_money)
|
||||
{
|
||||
change_dts.addr.push_back(m_account.get_keys().account_address);
|
||||
change_dts.amount = found_money - needed_money;
|
||||
change_dts.asset_id = asset_id;
|
||||
}
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "needed_money==" << needed_money << " < found_money==" << found_money);
|
||||
|
||||
|
||||
uint64_t dust = 0;
|
||||
bool r = detail::apply_split_strategy_by_id(destination_split_strategy_id, dsts, change_dts, dust_policy.dust_threshold, final_detinations, dust, WALLET_MAX_ALLOWED_OUTPUT_AMOUNT);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "invalid split strategy id: " << destination_split_strategy_id);
|
||||
|
|
@ -5530,55 +5588,60 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money,
|
|||
if (0 != dust && !dust_policy.add_to_fee)
|
||||
{
|
||||
final_detinations.push_back(currency::tx_destination_entry(dust, dust_policy.addr_for_dust));
|
||||
final_detinations.back().asset_id = asset_id;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx_param& ftp, const currency::transaction& tx_for_mode_separate /* = currency::transaction() */)
|
||||
{
|
||||
TIME_MEASURE_START_MS(get_needed_money_time);
|
||||
uint64_t needed_money = get_needed_money(ctp.fee, ctp.dsts);
|
||||
if (ctp.flags & TX_FLAG_SIGNATURE_MODE_SEPARATE && tx_for_mode_separate.vout.size())
|
||||
|
||||
assets_selection_context needed_money_map = get_needed_money(ctp.fee, ctp.dsts);
|
||||
//@#@ need to do refactoring over this part to support hidden amounts and asset_id
|
||||
if (ctp.flags & TX_FLAG_SIGNATURE_MODE_SEPARATE && tx_for_mode_separate.vout.size() )
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(get_tx_flags(tx_for_mode_separate) & TX_FLAG_SIGNATURE_MODE_SEPARATE, "tx_param.flags differs from tx.flags");
|
||||
needed_money += (currency::get_outs_money_amount(tx_for_mode_separate) - get_inputs_money_amount(tx_for_mode_separate));
|
||||
needed_money_map[currency::null_hash].needed_amount += (currency::get_outs_money_amount(tx_for_mode_separate) - get_inputs_money_amount(tx_for_mode_separate));
|
||||
}
|
||||
TIME_MEASURE_FINISH_MS(get_needed_money_time);
|
||||
|
||||
uint64_t found_money = 0;
|
||||
//uint64_t found_money = 0;
|
||||
|
||||
TIME_MEASURE_START_MS(prepare_tx_sources_time);
|
||||
if (ctp.perform_packing)
|
||||
{
|
||||
prepare_tx_sources_for_packing(WALLET_DEFAULT_POS_MINT_PACKING_SIZE, 0, ftp.sources, ftp.selected_transfers, found_money);
|
||||
prepare_tx_sources_for_packing(WALLET_DEFAULT_POS_MINT_PACKING_SIZE, 0, ftp.sources, ftp.selected_transfers, needed_money_map[currency::null_hash].found_amount);
|
||||
}
|
||||
else if (ctp.htlc_tx_id != currency::null_hash)
|
||||
{
|
||||
//htlc
|
||||
prepare_tx_sources_htlc(ctp.htlc_tx_id, ctp.htlc_origin, ftp.sources, found_money);
|
||||
//@#@ need to do refactoring over this part to support hidden amounts and asset_id
|
||||
prepare_tx_sources_htlc(ctp.htlc_tx_id, ctp.htlc_origin, ftp.sources, needed_money_map[currency::null_hash].found_amount);
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(ctp.dsts.size() == 1,
|
||||
"htlc: unexpected ctp.dsts.size() =" << ctp.dsts.size(), API_RETURN_CODE_INTERNAL_ERROR);
|
||||
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(found_money > ctp.fee,
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(needed_money_map[currency::null_hash].found_amount > ctp.fee,
|
||||
"htlc: found money less then fee", API_RETURN_CODE_INTERNAL_ERROR);
|
||||
|
||||
//fill amount
|
||||
ctp.dsts.begin()->amount = found_money - ctp.fee;
|
||||
ctp.dsts.begin()->amount = needed_money_map[currency::null_hash].found_amount - ctp.fee;
|
||||
|
||||
}
|
||||
else if (ctp.multisig_id != currency::null_hash)
|
||||
{
|
||||
//multisig
|
||||
prepare_tx_sources(ctp.multisig_id, ftp.sources, found_money);
|
||||
//@#@ need to do refactoring over this part to support hidden amounts and asset_id
|
||||
prepare_tx_sources(ctp.multisig_id, ftp.sources, needed_money_map[currency::null_hash].found_amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
//regular tx
|
||||
prepare_tx_sources(needed_money, ctp.fake_outputs_count, ctp.dust_policy.dust_threshold, ftp.sources, ftp.selected_transfers, found_money);
|
||||
prepare_tx_sources(needed_money_map, ctp.fake_outputs_count, ctp.dust_policy.dust_threshold, ftp.sources, ftp.selected_transfers);
|
||||
}
|
||||
TIME_MEASURE_FINISH_MS(prepare_tx_sources_time);
|
||||
|
||||
TIME_MEASURE_START_MS(prepare_tx_destinations_time);
|
||||
prepare_tx_destinations(needed_money, found_money, static_cast<detail::split_strategy_id_t>(ctp.split_strategy_id), ctp.dust_policy, ctp.dsts, ftp.prepared_destinations);
|
||||
prepare_tx_destinations(needed_money_map, static_cast<detail::split_strategy_id_t>(ctp.split_strategy_id), ctp.dust_policy, ctp.dsts, ftp.prepared_destinations);
|
||||
TIME_MEASURE_FINISH_MS(prepare_tx_destinations_time);
|
||||
|
||||
if (ctp.mark_tx_as_complete && !ftp.sources.empty())
|
||||
|
|
@ -5716,7 +5779,7 @@ construct_tx_param wallet2::get_default_construct_tx_param_inital()
|
|||
|
||||
ctp.fee = m_core_runtime_config.tx_default_fee;
|
||||
ctp.dust_policy = tools::tx_dust_policy(DEFAULT_DUST_THRESHOLD);
|
||||
ctp.split_strategy_id = tools::detail::ssi_digit;
|
||||
ctp.split_strategy_id = get_current_split_strategy();
|
||||
ctp.tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED;
|
||||
ctp.shuffle = 0;
|
||||
return ctp;
|
||||
|
|
@ -5999,7 +6062,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public
|
|||
|
||||
// try to construct a transaction
|
||||
std::vector<currency::tx_destination_entry> dsts({ tx_destination_entry(amount_swept - fee, destination_addr) });
|
||||
prepare_tx_destinations(0, 0, detail::ssi_digit, tools::tx_dust_policy(), dsts, ftp.prepared_destinations);
|
||||
prepare_tx_destinations(0, 0, get_current_split_strategy(), tools::tx_dust_policy(), dsts, ftp.prepared_destinations, currency::null_hash);
|
||||
|
||||
currency::transaction tx = AUTO_VAL_INIT(tx);
|
||||
crypto::secret_key tx_key = AUTO_VAL_INIT(tx_key);
|
||||
|
|
|
|||
|
|
@ -295,53 +295,14 @@ namespace tools
|
|||
bool perform_packing = false;
|
||||
};
|
||||
|
||||
// struct currency::finalize_tx_param
|
||||
// {
|
||||
// uint64_t unlock_time;
|
||||
// std::vector<currency::extra_v> extra;
|
||||
// std::vector<currency::attachment_v> attachments;
|
||||
// currency::account_public_address crypt_address;
|
||||
// uint8_t tx_outs_attr;
|
||||
// bool shuffle;
|
||||
// uint8_t flags;
|
||||
// crypto::hash multisig_id;
|
||||
// std::vector<currency::tx_source_entry> sources;
|
||||
// std::vector<uint64_t> selected_transfers;
|
||||
// std::vector<currency::tx_destination_entry> prepared_destinations;
|
||||
//
|
||||
// crypto::public_key spend_pub_key; // only for validations
|
||||
//
|
||||
// BEGIN_SERIALIZE_OBJECT()
|
||||
// FIELD(unlock_time)
|
||||
// FIELD(extra)
|
||||
// FIELD(attachments)
|
||||
// FIELD(crypt_address)
|
||||
// FIELD(tx_outs_attr)
|
||||
// FIELD(shuffle)
|
||||
// FIELD(flags)
|
||||
// FIELD(multisig_id)
|
||||
// FIELD(sources)
|
||||
// FIELD(selected_transfers)
|
||||
// FIELD(prepared_destinations)
|
||||
// FIELD(spend_pub_key)
|
||||
// END_SERIALIZE()
|
||||
// };
|
||||
//
|
||||
// struct currency::finalized_tx
|
||||
// {
|
||||
// currency::transaction tx;
|
||||
// crypto::secret_key one_time_key;
|
||||
// currency::finalize_tx_param ftp;
|
||||
// std::vector<serializable_pair<uint64_t, crypto::key_image>> outs_key_images; // pairs (out_index, key_image) for each change output
|
||||
//
|
||||
// BEGIN_SERIALIZE_OBJECT()
|
||||
// FIELD(tx)
|
||||
// FIELD(one_time_key)
|
||||
// FIELD(ftp)
|
||||
// FIELD(outs_key_images)
|
||||
// END_SERIALIZE()
|
||||
// };
|
||||
|
||||
struct selection_for_amount
|
||||
{
|
||||
uint64_t needed_amount = 0;
|
||||
uint64_t found_amount = 0;
|
||||
//std::vector<uint64_t> selected_indicies;
|
||||
};
|
||||
typedef std::unordered_map<crypto::hash, selection_for_amount> assets_selection_context;
|
||||
|
||||
class wallet2: public tools::tor::t_transport_state_notifier
|
||||
{
|
||||
|
|
@ -493,6 +454,7 @@ namespace tools
|
|||
typedef std::unordered_map<crypto::hash, transfer_details_base> multisig_transfer_container;
|
||||
typedef std::unordered_map<crypto::hash, tools::wallet_public::escrow_contract_details_basic> escrow_contracts_container;
|
||||
typedef std::map<uint64_t, std::set<size_t> > free_amounts_cache_type;
|
||||
typedef std::unordered_map<crypto::hash, free_amounts_cache_type> free_assets_amounts_cache_type;
|
||||
typedef std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t> amount_gindex_to_transfer_id_container; // maps [amount; gindex] -> tid
|
||||
|
||||
|
||||
|
|
@ -847,6 +809,7 @@ namespace tools
|
|||
bool is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_outputs_count);
|
||||
bool is_transfer_able_to_go(const transfer_details& td, uint64_t fake_outputs_count);
|
||||
uint64_t select_indices_for_transfer(std::vector<uint64_t>& ind, free_amounts_cache_type& found_free_amounts, uint64_t needed_money, uint64_t fake_outputs_count);
|
||||
bool select_indices_for_transfer(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector<uint64_t>& selected_indexes);
|
||||
|
||||
//PoS
|
||||
//synchronous version of function
|
||||
|
|
@ -959,9 +922,9 @@ private:
|
|||
currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& unserialized);
|
||||
void pull_blocks(size_t& blocks_added, std::atomic<bool>& stop);
|
||||
bool prepare_free_transfers_cache(uint64_t fake_outputs_count);
|
||||
uint64_t select_transfers(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust, std::vector<uint64_t>& selected_indicies);
|
||||
bool select_transfers(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust, std::vector<uint64_t>& selected_indicies);
|
||||
void add_transfers_to_transfers_cache(const std::vector<uint64_t>& indexs);
|
||||
void add_transfer_to_transfers_cache(uint64_t amount, uint64_t index);
|
||||
void add_transfer_to_transfers_cache(uint64_t amount, uint64_t index, const crypto::hash& asset_id = currency::null_hash);
|
||||
bool prepare_file_names(const std::wstring& file_path);
|
||||
void process_unconfirmed(const currency::transaction& tx, std::vector<std::string>& recipients, std::vector<std::string>& recipients_aliases);
|
||||
void add_sent_unconfirmed_tx(const currency::transaction& tx,
|
||||
|
|
@ -996,19 +959,24 @@ private:
|
|||
void rise_on_transfer2(const wallet_public::wallet_transfer_info& wti);
|
||||
void process_genesis_if_needed(const currency::block& genesis);
|
||||
bool build_escrow_proposal(bc_services::contract_private_details& ecrow_details, uint64_t fee, uint64_t unlock_time, currency::tx_service_attachment& att, std::vector<uint64_t>& selected_indicies);
|
||||
bool prepare_tx_sources(uint64_t needed_money, size_t fake_outputs_count, uint64_t dust_threshold, std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies, uint64_t& found_money);
|
||||
bool prepare_tx_sources(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(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);
|
||||
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);
|
||||
void prefetch_global_indicies_if_needed(std::vector<uint64_t>& selected_indicies);
|
||||
uint64_t get_needed_money(uint64_t fee, const std::vector<currency::tx_destination_entry>& dsts);
|
||||
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,
|
||||
detail::split_strategy_id_t destination_split_strategy_id,
|
||||
const tx_dust_policy& dust_policy,
|
||||
const std::vector<currency::tx_destination_entry>& dsts,
|
||||
std::vector<currency::tx_destination_entry>& final_detinations);
|
||||
void prepare_tx_destinations(uint64_t needed_money,
|
||||
uint64_t found_money,
|
||||
detail::split_strategy_id_t destination_split_strategy_id,
|
||||
const tx_dust_policy& dust_policy,
|
||||
const std::vector<currency::tx_destination_entry>& dsts,
|
||||
std::vector<currency::tx_destination_entry>& final_detinations);
|
||||
std::vector<currency::tx_destination_entry>& final_detinations, const crypto::hash& assed_id);
|
||||
bool handle_contract(wallet_public::wallet_transfer_info& wti, const bc_services::contract_private_details& cntr, const std::vector<currency::payload_items_v>& decrypted_attach);
|
||||
bool handle_release_contract(wallet_public::wallet_transfer_info& wti, const std::string& release_instruction);
|
||||
bool handle_cancel_proposal(wallet_public::wallet_transfer_info& wti, const bc_services::escrow_cancel_templates_body& ectb, const std::vector<currency::payload_items_v>& decrypted_attach);
|
||||
|
|
@ -1017,7 +985,7 @@ private:
|
|||
uint64_t get_current_tx_version();
|
||||
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const wallet_public::wallet_transfer_info& wti) const;
|
||||
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const std::string& reason = "internal intention") const;
|
||||
|
||||
bool is_need_to_split_outputs();
|
||||
template<typename input_t>
|
||||
bool process_input_t(const input_t& in_t, wallet2::process_transaction_context& ptc, const currency::transaction& tx);
|
||||
|
||||
|
|
@ -1082,6 +1050,7 @@ private:
|
|||
void push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector<currency::extra_v>& extra);
|
||||
void remove_transfer_from_amount_gindex_map(uint64_t tid);
|
||||
uint64_t get_alias_cost(const std::string& alias);
|
||||
detail::split_strategy_id_t get_current_split_strategy();
|
||||
|
||||
static void wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
|
||||
static void wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
|
||||
|
|
@ -1130,7 +1099,7 @@ private:
|
|||
std::list<expiration_entry_info> m_money_expirations;
|
||||
//optimization for big wallets and batch tx
|
||||
|
||||
free_amounts_cache_type m_found_free_amounts;
|
||||
free_assets_amounts_cache_type m_found_free_amounts;
|
||||
uint64_t m_fake_outputs_count;
|
||||
std::string m_miner_text_info;
|
||||
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ namespace tools
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
struct not_enough_money : public transfer_error
|
||||
{
|
||||
not_enough_money(std::string&& loc, uint64_t availbable, uint64_t tx_amount, uint64_t fee)
|
||||
not_enough_money(std::string&& loc, uint64_t availbable, uint64_t tx_amount, uint64_t fee, const crypto::hash& assset_id)
|
||||
: transfer_error(std::move(loc), "NOT_ENOUGH_MONEY")
|
||||
, m_available(availbable)
|
||||
, m_tx_amount(tx_amount)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue