1
0
Fork 0
forked from lthn/blockchain

Merge branch 'recent_history' into cryptoassets

This commit is contained in:
cryptozoidberg 2023-06-21 22:46:29 +02:00
commit 937dfe042e
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
25 changed files with 956 additions and 653 deletions

View file

@ -6,6 +6,17 @@
#define BEGIN_BOOST_SERIALIZATION() template <class t_archive> inline void serialize(t_archive &_arch, const unsigned int ver) {
template<size_t A, size_t B> struct TAssertEquality {
static_assert(A == B, "Serialization map is not updated, sizeof() missmatch");
static constexpr bool _cResult = (A == B);
};
//experemental feature: self-validated serialization map, needed to not forget add new members to serialization maps
#define BEGIN_BOOST_SERIALIZATION_SV(sz) BEGIN_BOOST_SERIALIZATION() \
static constexpr bool _cIsEqual = TAssertEquality<sz, sizeof(*this)>::_cResult;
#define BOOST_SERIALIZE(x) _arch & x;
#define END_BOOST_SERIALIZATION() }

View file

@ -236,9 +236,11 @@
#define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin"
#ifndef TESTNET
#define WALLET_FILE_SERIALIZATION_VERSION 154
#define WALLET_FILE_SERIALIZATION_VERSION 160
#define WALLET_FILE_LAST_SUPPORTED_VERSION 160
#else
#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+70)
#define WALLET_FILE_LAST_SUPPORTED_VERSION (CURRENCY_FORMATION_VERSION+73)
#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+73)
#endif
#define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31)

View file

@ -1664,10 +1664,10 @@ namespace currency
txin_htlc htlc_in = AUTO_VAL_INIT(htlc_in);
x.tx_type = get_tx_type_ex(x.tx, htlc_out, htlc_in);
if(x.tx_type == GUI_TX_TYPE_HTLC_DEPOSIT && x.is_income == true)
if(x.tx_type == GUI_TX_TYPE_HTLC_DEPOSIT && !x.has_outgoing_entries())
{
//need to override amount
x.amount = htlc_out.amount;
x.get_native_income_amount() = htlc_out.amount;
}
}
@ -2892,12 +2892,12 @@ namespace currency
return true;
}
//---------------------------------------------------------------
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<wallet_out_info>& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation)
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<wallet_out_info>& outs, crypto::key_derivation& derivation)
{
crypto::public_key tx_pub_key = get_tx_pub_key_from_extra(tx);
if (null_pkey == tx_pub_key)
return false;
return lookup_acc_outs(acc, tx, get_tx_pub_key_from_extra(tx), outs, sum_of_native_outs, derivation);
return lookup_acc_outs(acc, tx, get_tx_pub_key_from_extra(tx), outs, derivation);
}
//---------------------------------------------------------------
bool check_tx_derivation_hint(const transaction& tx, const crypto::key_derivation& derivation)
@ -2925,7 +2925,7 @@ namespace currency
return false;
}
//---------------------------------------------------------------
bool lookup_acc_outs_genesis(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, uint64_t& money_transfered, crypto::key_derivation& derivation)
bool lookup_acc_outs_genesis(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, crypto::key_derivation& derivation)
{
uint64_t offset = 0;
bool r = get_account_genesis_offset_by_address(get_account_address_as_str(acc.account_address), offset);
@ -2941,27 +2941,25 @@ namespace currency
if (is_out_to_acc(acc.account_address, boost::get<txout_to_key>(o.target), derivation, offset))
{
outs.emplace_back(offset, o.amount);
money_transfered += o.amount;
}
return true;
}
//---------------------------------------------------------------
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation)
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, crypto::key_derivation& derivation)
{
std::list<htlc_info> htlc_info_list;
return lookup_acc_outs(acc, tx, tx_pub_key, outs, sum_of_native_outs, derivation, htlc_info_list);
return lookup_acc_outs(acc, tx, tx_pub_key, outs, derivation, htlc_info_list);
}
//---------------------------------------------------------------
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation, std::list<htlc_info>& htlc_info_list)
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, crypto::key_derivation& derivation, std::list<htlc_info>& htlc_info_list)
{
sum_of_native_outs = 0;
bool r = generate_key_derivation(tx_pub_key, acc.view_secret_key, derivation);
CHECK_AND_ASSERT_MES(r, false, "unable to generate derivation from tx_pub = " << tx_pub_key << " * view_sec, invalid tx_pub?");
if (is_coinbase(tx) && get_block_height(tx) == 0 && tx_pub_key == ggenesis_tx_pub_key)
{
//genesis coinbase
return lookup_acc_outs_genesis(acc, tx, tx_pub_key, outs, sum_of_native_outs, derivation);
return lookup_acc_outs_genesis(acc, tx, tx_pub_key, outs, derivation);
}
if (!check_tx_derivation_hint(tx, derivation))
@ -2978,7 +2976,6 @@ namespace currency
if (is_out_to_acc(acc.account_address, t, derivation, output_index))
{
outs.emplace_back(output_index, o.amount);
sum_of_native_outs += o.amount;
}
VARIANT_CASE_CONST(txout_multisig, t)
if (is_out_to_acc(acc.account_address, t, derivation, output_index))
@ -3019,8 +3016,6 @@ namespace currency
crypto::point_t asset_id_pt = crypto::point_t(zo.blinded_asset_id).modify_mul8() - asset_id_blinding_mask * crypto::c_point_X;
crypto::public_key asset_id = asset_id_pt.to_public_key();
outs.emplace_back(output_index, amount, amount_blinding_mask, asset_id_blinding_mask, asset_id);
if (asset_id == currency::native_coin_asset_id)
sum_of_native_outs += amount;
}
}
VARIANT_SWITCH_END();

View file

@ -334,9 +334,9 @@ namespace currency
bool is_out_to_acc(const account_public_address& addr, const txout_to_key& out_key, const crypto::key_derivation& derivation, size_t output_index);
bool is_out_to_acc(const account_public_address& addr, const txout_multisig& out_multisig, const crypto::key_derivation& derivation, size_t output_index);
bool is_out_to_acc(const account_public_address& addr, const tx_out_zarcanum& zo, const crypto::key_derivation& derivation, size_t output_index, uint64_t& decoded_amount, crypto::public_key& decoded_asset_id, crypto::scalar_t& amount_blinding_mask, crypto::scalar_t& asset_id_blinding_mask);
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation);
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation, std::list<htlc_info>& htlc_info_list);
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<wallet_out_info>& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation);
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, crypto::key_derivation& derivation);
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, const crypto::public_key& tx_pub_key, std::vector<wallet_out_info>& outs, crypto::key_derivation& derivation, std::list<htlc_info>& htlc_info_list);
bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector<wallet_out_info>& outs, crypto::key_derivation& derivation);
bool get_tx_fee(const transaction& tx, uint64_t & fee);
uint64_t get_tx_fee(const transaction& tx);
bool derive_ephemeral_key_helper(const account_keys& ack, const crypto::public_key& tx_public_key, size_t real_output_index, keypair& in_ephemeral);
@ -577,9 +577,9 @@ namespace currency
}
//---------------------------------------------------------------
template<typename t_number>
std::string print_money(t_number amount)
std::string print_money(t_number amount, uint64_t decimals = CURRENCY_DISPLAY_DECIMAL_POINT)
{
return print_fixed_decimal_point(amount, CURRENCY_DISPLAY_DECIMAL_POINT);
return print_fixed_decimal_point(amount, decimals);
}
//---------------------------------------------------------------

View file

@ -25,6 +25,8 @@ namespace currency
//------------------------------------------------------------------
bool is_tx_expired(const transaction& tx, uint64_t expiration_ts_median)
{
if (expiration_ts_median == 0)
return false;
/// tx expiration condition (tx is ok if the following is true)
/// tx_expiration_time - TX_EXPIRATION_MEDIAN_SHIFT > get_last_n_blocks_timestamps_median(TX_EXPIRATION_TIMESTAMP_CHECK_WINDOW)
uint64_t expiration_time = get_tx_expiration_time(tx);

View file

@ -1059,9 +1059,9 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei)
if (!m_tray_icon)
return true;
if (!tei.ti.is_income)
if (tei.ti.has_outgoing_entries())
return true;
if (!tei.ti.amount)
if (!tei.ti.get_native_amount())
return true;
// if (tei.ti.is_mining && m_wallet_states->operator [](tei.wallet_id) != view::wallet_status_info::wallet_state_ready)
// return true;
@ -1075,9 +1075,9 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei)
return true;
}
auto amount_str = currency::print_money_brief(tei.ti.amount);
auto amount_str = currency::print_money_brief(tei.ti.get_native_amount()); //@#@ add handling of assets
std::string title, msg;
if (tei.ti.height == 0) // unconfirmed trx
if (tei.ti.height == 0) // unconfirmed tx
{
msg = amount_str + " " + CURRENCY_NAME_ABR + " " + m_localization[localization_id_is_received];
title = m_localization[localization_id_income_transfer_unconfirmed];

@ -1 +1 @@
Subproject commit 1471e71f4ff685dd080e6551773cf129f1d02c43
Subproject commit e1aea269ee057ccb5b68bce83b8beeb4866e560d

View file

@ -715,7 +715,7 @@ void simple_wallet::on_new_block(uint64_t height, const currency::block& block)
m_refresh_progress_reporter.update(height, false);
}
//----------------------------------------------------------------------------------------------------
std::string print_money_trailing_zeros_replaced_with_spaces(uint64_t amount)
std::string print_money_trailing_zeros_replaced_with_spaces(uint64_t amount, size_t decimal_point = CURRENCY_DISPLAY_DECIMAL_POINT)
{
std::string s = print_money(amount);
size_t p = s.find_last_not_of('0');
@ -729,13 +729,64 @@ std::string print_money_trailing_zeros_replaced_with_spaces(uint64_t amount)
return s;
}
//----------------------------------------------------------------------------------------------------
std::string simple_wallet::get_tocken_info_string(const crypto::public_key& asset_id, uint64_t& decimal_points)
{
std::string token_info = "ZANO";
decimal_points = CURRENCY_DISPLAY_DECIMAL_POINT;
if (asset_id != currency::native_coin_asset_id)
{
currency::asset_descriptor_base adb = AUTO_VAL_INIT(adb);
bool whitelisted = false;
if (!m_wallet->get_asset_id_info(asset_id, adb, whitelisted))
{
token_info = "!UNKNOWN!";
}
else {
decimal_points = adb.decimal_point;
token_info = adb.ticker;
if (whitelisted)
{
token_info += "[*]";
}
else
{
token_info += std::string("[") + epee::string_tools::pod_to_hex(asset_id) + "]";
}
}
}
return token_info;
}
//----------------------------------------------------------------------------------------------------
void simple_wallet::on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined)
{
epee::log_space::console_colors color = wti.is_income ? epee::log_space::console_color_green : epee::log_space::console_color_magenta;
message_writer(color, false) <<
"height " << wti.height <<
", tx " << wti.tx_hash <<
" " << std::right << std::setw(18) << print_money_trailing_zeros_replaced_with_spaces(wti.amount) << (wti.is_income ? " received," : " spent");
if (wti.subtransfers.size() == 1)
{
epee::log_space::console_colors color = !wti.has_outgoing_entries() ? epee::log_space::console_color_green : epee::log_space::console_color_magenta;
uint64_t decimal_points = CURRENCY_DISPLAY_DECIMAL_POINT;
std::string token_info = get_tocken_info_string(wti.subtransfers[0].asset_id, decimal_points);
message_writer(color, false) <<
"height " << wti.height <<
", tx " << wti.tx_hash <<
" " << std::right << std::setw(18) << print_money_trailing_zeros_replaced_with_spaces(wti.subtransfers[0].amount, decimal_points) << (wti.subtransfers[0].is_income ? " received," : " spent") << " " << token_info;
}
else
{
message_writer(epee::log_space::console_color_cyan, false) <<
"height " << wti.height <<
", tx " << wti.tx_hash;
for (const auto& st : wti.subtransfers)
{
epee::log_space::console_colors color = st.is_income ? epee::log_space::console_color_green : epee::log_space::console_color_magenta;
uint64_t decimal_points = CURRENCY_DISPLAY_DECIMAL_POINT;
std::string token_info = get_tocken_info_string(st.asset_id, decimal_points);
message_writer(epee::log_space::console_color_cyan, false) << " "
<< std::right << std::setw(18) << print_money_trailing_zeros_replaced_with_spaces(st.amount, decimal_points) << (st.is_income ? " received," : " spent") << " " << token_info;
}
}
m_refresh_progress_reporter.update(wti.height, true);
}
//----------------------------------------------------------------------------------------------------
@ -861,10 +912,10 @@ bool simple_wallet::show_balance(const std::vector<std::string>& args/* = std::v
return true;
}
//----------------------------------------------------------------------------------------------------
bool print_wti(const tools::wallet_public::wallet_transfer_info& wti)
bool simple_wallet::print_wti(const tools::wallet_public::wallet_transfer_info& wti)
{
epee::log_space::console_colors cl;
if (wti.is_income)
if (!wti.has_outgoing_entries())
cl = epee::log_space::console_color_green;
else
cl = epee::log_space::console_color_magenta;
@ -886,11 +937,30 @@ bool print_wti(const tools::wallet_public::wallet_transfer_info& wti)
remote_side += remote_side.empty() ? it : (separator + it);
}
success_msg_writer(cl) << "[" << wti.transfer_internal_index << "]" << epee::misc_utils::get_time_str_v2(wti.timestamp) << " "
<< (wti.is_income ? "Received " : "Sent ")
<< print_money(wti.amount) << "(fee:" << print_money(wti.fee) << ") "
<< remote_side
<< " " << wti.tx_hash << payment_id_placeholder;
if (wti.subtransfers.size() == 1)
{
success_msg_writer(cl) << "[" << wti.transfer_internal_index << "]" << epee::misc_utils::get_time_str_v2(wti.timestamp) << " "
<< (wti.subtransfers[0].is_income ? "Received " : "Sent ")
<< print_money(wti.subtransfers[0].amount) << "(fee:" << print_money(wti.fee) << ") "
<< remote_side
<< " " << wti.tx_hash << payment_id_placeholder;
}else
{
success_msg_writer(cl) << "[" << wti.transfer_internal_index << "]" << epee::misc_utils::get_time_str_v2(wti.timestamp) << " (fee:" << print_money(wti.fee) << ") "
<< remote_side
<< " " << wti.tx_hash << payment_id_placeholder;
for (auto& st: wti.subtransfers)
{
epee::log_space::console_colors cl = st.is_income ? epee::log_space::console_color_green: epee::log_space::console_color_magenta;
uint64_t decimal_points = CURRENCY_DISPLAY_DECIMAL_POINT;
std::string token_info = get_tocken_info_string(st.asset_id, decimal_points);
success_msg_writer(cl)
<< (st.is_income ? "Received " : "Sent ")
<< print_money(st.amount, decimal_points) << token_info;
}
}
return true;
}
//----------------------------------------------------------------------------------------------------

View file

@ -104,6 +104,8 @@ namespace currency
uint64_t get_daemon_blockchain_height(std::string& err);
bool try_connect_to_daemon();
std::string get_tocken_info_string(const crypto::public_key& asset_id, uint64_t& decimal_point);
bool simple_wallet::print_wti(const tools::wallet_public::wallet_transfer_info& wti);
//----------------- i_wallet2_callback ---------------------
virtual void on_new_block(uint64_t height, const currency::block& block) override;

File diff suppressed because it is too large Load diff

View file

@ -103,12 +103,6 @@ namespace tools
#pragma pack (pop)
struct money_transfer2_details
{
std::vector<size_t> receive_indices;
std::vector<size_t> spent_indices;
};
class i_wallet2_callback
{
@ -118,7 +112,6 @@ namespace tools
virtual ~i_wallet2_callback() = default;
virtual void on_new_block(uint64_t /*height*/, const currency::block& /*block*/) {}
virtual void on_transfer2(const wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) {} // this one is left for compatibility, one day we need to get rid of it
virtual void on_transfer2(const wallet_public::wallet_transfer_info& wti, const std::list<wallet_public::asset_balance_entry>& balances, uint64_t total_mined) {}
virtual void on_pos_block_found(const currency::block& /*block*/) {}
virtual void on_sync_progress(const uint64_t& /*percents*/) {}
@ -390,6 +383,13 @@ namespace tools
bool is_zc() const { return m_zc_info_ptr.get(); }
const crypto::public_key& get_asset_id() const { if (m_zc_info_ptr.get()) { return m_zc_info_ptr->asset_id; } else { return currency::native_coin_asset_id; } }
bool is_native_coin() const { return m_zc_info_ptr.get() ? (m_zc_info_ptr->asset_id == currency::native_coin_asset_id) : true; }
bool is_htlc() const {
if (m_ptx_wallet_info->m_tx.vout[m_internal_output_index].type() == typeid(currency::tx_out_bare) &&
boost::get<currency::tx_out_bare>(m_ptx_wallet_info->m_tx.vout[m_internal_output_index]).target.type() == typeid(currency::txout_htlc))
return true;
return false;
}
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_CUSTOM(m_ptx_wallet_info, const transaction_wallet_info&, tools::wallet2::transform_ptr_to_value, tools::wallet2::transform_value_to_ptr)
@ -436,12 +436,32 @@ namespace tools
};
struct payment_details_subtransfer
{
crypto::public_key asset_id = currency::null_pkey;
uint64_t amount = 0;
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(asset_id)
BOOST_SERIALIZE(amount)
END_BOOST_SERIALIZATION()
};
struct payment_details
{
crypto::hash m_tx_hash = currency::null_hash;
uint64_t m_amount = 0;
uint64_t m_amount = 0; // native coins amount
uint64_t m_block_height = 0;
uint64_t m_unlock_time = 0;
std::vector<payment_details_subtransfer> subtransfers; //subtransfers added for confidential asset only, native amount should be stored in m_amount (for space saving)
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(m_tx_hash)
BOOST_SERIALIZE(m_amount)
BOOST_SERIALIZE(m_block_height)
BOOST_SERIALIZE(m_unlock_time)
BOOST_SERIALIZE(subtransfers)
END_BOOST_SERIALIZATION()
};
struct mining_context : public currency::pos_mining_context
@ -464,9 +484,16 @@ namespace tools
struct expiration_entry_info
{
std::vector<uint64_t> selected_transfers;
uint64_t change_amount = 0;
uint64_t expiration_time = 0;
crypto::hash related_tx_id = currency::null_hash; // tx id which caused money lock, if any (ex: escrow proposal transport tx)
std::vector<payment_details_subtransfer> receved;
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(selected_transfers)
BOOST_SERIALIZE(expiration_time)
BOOST_SERIALIZE(related_tx_id)
BOOST_SERIALIZE(receved)
END_BOOST_SERIALIZATION()
};
/*
@ -529,11 +556,15 @@ namespace tools
END_SERIALIZE()
};
typedef std::unordered_map<crypto::hash, std::pair<currency::transaction, wallet_public::employed_tx_entries>> multisig_entries_map;
struct process_transaction_context
{
uint64_t sum_of_own_native_inputs = 0; // old-fashioned bare inputs or ZC inputs referring to native coin asset_id
process_transaction_context(const currency::transaction& t) : tx(t) {}
const currency::transaction& tx;
bool spent_own_native_inputs = false;
// check all outputs for spending (compare key images)
money_transfer2_details mtd;
wallet_public::employed_tx_entries employed_entries;
bool is_pos_coinbase = false;
bool coin_base_tx = false;
//PoW block don't have change, so all outs supposed to be marked as "mined"
@ -541,6 +572,23 @@ namespace tools
size_t i = 0;
size_t sub_i = 0;
uint64_t height = 0;
uint64_t timestamp = 0;
std::unordered_map<crypto::public_key, boost::multiprecision::int128_t> total_balance_change;
std::vector<std::string> recipients;
std::vector<std::string> remote_aliases;
multisig_entries_map* pmultisig_entries = nullptr;
uint64_t tx_expiration_ts_median = 0;
const crypto::hash& tx_hash() const
{
if (tx_hash_ == currency::null_hash)
{
tx_hash_ = get_transaction_hash(tx);
}
return tx_hash_;
}
private:
mutable crypto::hash tx_hash_ = currency::null_hash;
};
@ -589,6 +637,7 @@ namespace tools
void set_do_rise_transfer(bool do_rise) { m_do_rise_transfer = do_rise; }
bool has_related_alias_entry_unconfirmed(const currency::transaction& tx);
void handle_unconfirmed_tx(process_transaction_context& ptc);
void scan_tx_pool(bool& has_related_alias_in_unconfirmed);
void refresh();
void refresh(size_t & blocks_fetched);
@ -619,7 +668,7 @@ namespace tools
uint64_t balance(uint64_t& unloked) const;
uint64_t unlocked_balance() const;
bool get_asset_id_info(const crypto::public_key& asset_id, currency::asset_descriptor_base& asset_info, bool& whitelist_) const;
void transfer(uint64_t amount, const currency::account_public_address& acc, const crypto::public_key& asset_id = currency::native_coin_asset_id);
void transfer(uint64_t amount, size_t fake_outs_count, const currency::account_public_address& acc, uint64_t fee = TX_DEFAULT_FEE, const crypto::public_key& asset_id = currency::native_coin_asset_id);
void transfer(uint64_t amount, const currency::account_public_address& acc, currency::transaction& result_tx, const crypto::public_key& asset_id = currency::native_coin_asset_id);
@ -788,10 +837,9 @@ namespace tools
WLT_LOG_MAGENTA("Wallet file truncated due to WALLET_FILE_SERIALIZATION_VERSION is more then curren build", LOG_LEVEL_0);
return;
}
if (ver < 149)
if(ver < WALLET_FILE_LAST_SUPPORTED_VERSION)
{
WLT_LOG_MAGENTA("Wallet file truncated due to old version. ver: " << ver << ", WALLET_FILE_SERIALIZATION_VERSION=" << WALLET_FILE_SERIALIZATION_VERSION, LOG_LEVEL_0);
WLT_LOG_MAGENTA("Wallet file truncated due to ver(" << ver << ") is less then WALLET_FILE_LAST_SUPPORTED_VERSION", LOG_LEVEL_0);
return;
}
@ -811,29 +859,9 @@ namespace tools
}
}
//convert from old version
if (ver < 150)
{
WLT_LOG_MAGENTA("Converting blockchain into a short form...", LOG_LEVEL_0);
std::vector<crypto::hash> old_blockchain;
a & old_blockchain;
uint64_t count = 0;
for (auto& h : old_blockchain)
{
m_chain.push_new_block_id(h, count);
count++;
}
WLT_LOG_MAGENTA("Converting done", LOG_LEVEL_0);
}
else
{
a & m_chain;
a & m_minimum_height;
}
// v151: m_amount_gindex_to_transfer_id added
if (ver >= 151)
a & m_amount_gindex_to_transfer_id;
a & m_chain;
a & m_minimum_height;
a & m_amount_gindex_to_transfer_id;
a & m_transfers;
a & m_multisig_transfers;
a & m_key_images;
@ -847,28 +875,13 @@ namespace tools
a & m_pending_key_images;
a & m_tx_keys;
a & m_last_pow_block_h;
//after processing
if (ver < 152)
{
wipeout_extra_if_needed(m_transfer_history);
}
if (ver < 153)
return;
a & m_htlcs;
a & m_active_htlcs;
a & m_active_htlcs_txid;
if (ver < 154)
return;
a & m_own_asset_descriptors;
a & m_custom_assets;
}
void wipeout_extra_if_needed(std::vector<wallet_public::wallet_transfer_info>& transfer_history);
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);
@ -938,7 +951,7 @@ namespace tools
void finalize_transaction(const currency::finalize_tx_param& ftp, currency::finalized_tx& result, bool broadcast_tx, bool store_tx_secret_key = true );
std::string get_log_prefix() const { return m_log_prefix; }
static uint64_t get_max_unlock_time_from_receive_indices(const currency::transaction& tx, const money_transfer2_details& td);
static uint64_t get_max_unlock_time_from_receive_indices(const currency::transaction& tx, const wallet_public::employed_tx_entries& td);
bool get_utxo_distribution(std::map<uint64_t, uint64_t>& distribution);
uint64_t get_sync_progress();
uint64_t get_wallet_file_size()const;
@ -987,7 +1000,7 @@ private:
// -------- t_transport_state_notifier ------------------------------------------------
virtual void notify_state_change(const std::string& state_code, const std::string& details = std::string());
// ------------------------------------------------------------------------------------
void add_transfers_to_expiration_list(const std::vector<uint64_t>& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id);
void add_transfers_to_expiration_list(const std::vector<uint64_t>& selected_transfers, const std::vector<payment_details_subtransfer>& received, uint64_t expiration, const crypto::hash& related_tx_id);
void remove_transfer_from_expiration_list(uint64_t transfer_index);
void load_keys(const std::string& keys_file_name, const std::string& password, uint64_t file_signature, keys_file_data& kf_data);
void process_new_transaction(const currency::transaction& tx, uint64_t height, const currency::block& b, const std::vector<uint64_t>* pglobal_indexes);
@ -1014,18 +1027,11 @@ private:
const std::vector<currency::tx_destination_entry>& splitted_dsts);
void update_current_tx_limit();
void prepare_wti(wallet_public::wallet_transfer_info& wti, uint64_t height, uint64_t timestamp, const currency::transaction& tx, uint64_t amount, const money_transfer2_details& td);
void prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_info& wti, const std::vector<currency::payload_items_v>& decrypted_att);
void handle_money_received2(const currency::block& b,
const currency::transaction& tx,
uint64_t amount,
const money_transfer2_details& td);
void handle_money_spent2(const currency::block& b,
const currency::transaction& in_tx,
uint64_t amount,
const money_transfer2_details& td,
const std::vector<std::string>& recipients,
const std::vector<std::string>& recipients_aliases);
void prepare_wti(wallet_public::wallet_transfer_info& wti, const process_transaction_context& tx_process_context);
void prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_info& wti, const std::vector<currency::payload_items_v>& decrypted_att);
void handle_money(const currency::block& b, const process_transaction_context& tx_process_context);
void load_wti_from_process_transaction_context(wallet_public::wallet_transfer_info& wti, const process_transaction_context& tx_process_context);
void handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop,
currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& blocks);
std::string get_alias_for_address(const std::string& addr);
@ -1091,8 +1097,6 @@ private:
const std::vector<currency::payload_items_v>& decrypted_items, crypto::hash& ms_id, bc_services::contract_private_details& cpd,
const currency::transaction& proposal_template_tx);
void fill_transfer_details(const currency::transaction& tx, const tools::money_transfer2_details& td, tools::wallet_public::wallet_transfer_info_details& res_td) const;
void print_source_entry(std::stringstream& output, const currency::tx_source_entry& src) const;
@ -1191,7 +1195,7 @@ private:
mutable uint64_t m_current_wallet_file_size;
bool m_use_deffered_global_outputs;
bool m_disable_tor_relay;
bool m_use_assets_whitelisting = false;
bool m_use_assets_whitelisting = true;
mutable current_operation_context m_current_context;
//this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions
@ -1203,7 +1207,7 @@ private:
BOOST_CLASS_VERSION(tools::wallet2, WALLET_FILE_SERIALIZATION_VERSION)
BOOST_CLASS_VERSION(tools::wallet_public::wallet_transfer_info, 11)
BOOST_CLASS_VERSION(tools::wallet_public::wallet_transfer_info, 12)
BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 3)
BOOST_CLASS_VERSION(tools::wallet2::transfer_details_base, 2)
@ -1268,51 +1272,7 @@ namespace boost
a & x.is_wallet_owns_redeem;
a & x.transfer_index;
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet2::payment_details& x, const boost::serialization::version_type ver)
{
a & x.m_tx_hash;
a & x.m_amount;
a & x.m_block_height;
a & x.m_unlock_time;
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet_public::wallet_transfer_info_details& x, const boost::serialization::version_type ver)
{
a & x.rcv;
a & x.spn;
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet_public::wallet_transfer_info& x, const boost::serialization::version_type ver)
{
a & x.amount;
a & x.timestamp;
a & x.tx_hash;
a & x.height;
a & x.tx_blob_size;
a & x.payment_id;
a & x.remote_addresses;
a & x.is_income;
a & x.td;
a & x.tx;
a & x.remote_aliases;
a & x.comment;
a & x.contract;
a & x.selected_indicies;
a & x.marketplace_entries;
a & x.unlock_time;
if (ver < 10)
return;
a & x.service_entries;
if (ver < 11)
return;
a & x.asset_id;
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet_public::escrow_contract_details_basic& x, const boost::serialization::version_type ver)
{
@ -1337,19 +1297,6 @@ namespace boost
a & x.contract_id;
}
template <class Archive>
inline void serialize(Archive& a, tools::wallet2::expiration_entry_info& x, const boost::serialization::version_type ver)
{
a & x.expiration_time;
a & x.change_amount;
a & x.selected_transfers;
a & x.related_tx_id;
}
}
}
@ -1379,8 +1326,11 @@ namespace tools
if (tr_index != UINT64_MAX)
{
transfer_details& td = m_transfers[tr_index];
ptc.total_balance_change[td.get_asset_id()] -= td.amount();
if (td.is_native_coin())
ptc.sum_of_own_native_inputs += td.m_amount;
{
ptc.spent_own_native_inputs = true;
}
uint32_t flags_before = td.m_flags;
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_SPENT;
td.m_spent_height = ptc.height;
@ -1400,7 +1350,7 @@ namespace tools
"; flags: " << flags_before << " -> " << td.m_flags);
}
ptc.mtd.spent_indices.push_back(ptc.i);
ptc.employed_entries.spent.push_back(wallet_public::employed_tx_entry{ ptc.i, td.amount(), td.get_asset_id()});
remove_transfer_from_expiration_list(tr_index);
}
return true;

View file

@ -55,7 +55,7 @@ bool wallet2::validate_escrow_proposal(const wallet_public::wallet_transfer_info
// (2/5) extra
decrypted_items.clear();
bool r = decrypt_payload_items(wti.is_income, prop.tx_template, m_account.get_keys(), decrypted_items);
bool r = decrypt_payload_items(wti.is_income_mode_encryption(), prop.tx_template, m_account.get_keys(), decrypted_items);
LOC_CHK(r, "failed to decrypt payload items in proposal tx");
currency::tx_service_attachment tsa = AUTO_VAL_INIT(tsa);

View file

@ -12,7 +12,7 @@ class i_backend_wallet_callback
{
public:
virtual void on_new_block(size_t wallet_id, uint64_t /*height*/, const currency::block& /*block*/) {}
virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) {}
virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) {}
virtual void on_pos_block_found(size_t wallet_id, const currency::block& /*block*/) {}
virtual void on_sync_progress(size_t wallet_id, const uint64_t& /*percents*/) {}
virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti) {}
@ -32,8 +32,8 @@ struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback
virtual void on_new_block(uint64_t height, const currency::block& block) {
m_pbackend->on_new_block(m_wallet_id, height, block);
}
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) {
m_pbackend->on_transfer2(m_wallet_id, wti, balance, unlocked_balance, total_mined);
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) {
m_pbackend->on_transfer2(m_wallet_id, wti, balances, total_mined);
}
virtual void on_pos_block_found(const currency::block& wti) {
m_pbackend->on_pos_block_found(m_wallet_id, wti);

View file

@ -24,16 +24,39 @@ namespace wallet_public
#define WALLET_RPC_STATUS_BUSY "BUSY"
struct wallet_transfer_info_details
{
std::list<uint64_t> rcv;
std::list<uint64_t> spn;
struct employed_tx_entry {
uint64_t index = 0;
uint64_t amount = 0;
crypto::public_key asset_id = currency::native_coin_asset_id;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(rcv)
KV_SERIALIZE(spn)
KV_SERIALIZE(index)
KV_SERIALIZE(amount)
KV_SERIALIZE_POD_AS_HEX_STRING(asset_id)
END_KV_SERIALIZE_MAP()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(index)
BOOST_SERIALIZE(amount)
BOOST_SERIALIZE(asset_id)
END_BOOST_SERIALIZATION()
};
struct employed_tx_entries
{
std::vector<employed_tx_entry> receive;
std::vector<employed_tx_entry> spent;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(receive)
KV_SERIALIZE(spent)
END_KV_SERIALIZE_MAP()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(receive)
BOOST_SERIALIZE(spent)
END_BOOST_SERIALIZATION()
};
struct escrow_contract_details_basic
@ -89,52 +112,67 @@ namespace wallet_public
#define WALLET_TRANSFER_INFO_FLAGS_HTLC_DEPOSIT static_cast<uint16_t>(1 << 0)
struct wallet_sub_transfer_info
{
uint64_t amount = 0;
bool is_income = false;
crypto::public_key asset_id = currency::native_coin_asset_id; // not blinded, not premultiplied by 1/8
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
KV_SERIALIZE(is_income)
KV_SERIALIZE_POD_AS_HEX_STRING(asset_id)
END_KV_SERIALIZE_MAP()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(amount)
BOOST_SERIALIZE(is_income)
BOOST_SERIALIZE(asset_id)
END_BOOST_SERIALIZATION()
};
struct wallet_transfer_info
{
uint64_t amount;
uint64_t timestamp;
crypto::hash tx_hash;
uint64_t height; //if height == 0 then tx is unconfirmed
uint64_t unlock_time;
uint32_t tx_blob_size;
std::string payment_id;
std::vector<std::string> remote_addresses; //optional
std::vector<std::string> remote_aliases; //optional, describe only if there only one remote address
std::string comment;
bool is_income;
bool is_service;
bool is_mixing;
bool is_mining;
uint64_t tx_type;
wallet_transfer_info_details td;
employed_tx_entries employed_entries;
std::vector<currency::tx_service_attachment> service_entries;
std::vector<std::string> remote_addresses; //optional
std::vector<std::string> remote_aliases; //optional, describe only if there only one remote address
std::vector<wallet_sub_transfer_info> subtransfers;
//not included in streaming serialization
uint64_t fee;
bool show_sender;
std::vector<escrow_contract_details> contract;
uint16_t extra_flags;
uint16_t extra_flags;
uint64_t transfer_internal_index;
crypto::public_key asset_id; // not blinded, not premultiplied by 1/8
//not included in kv serialization map
currency::transaction tx;
std::vector<uint64_t> selected_indicies;
std::list<bc_services::offers_attachment_t> marketplace_entries;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
KV_SERIALIZE_POD_AS_HEX_STRING(tx_hash)
KV_SERIALIZE(height)
KV_SERIALIZE(unlock_time)
KV_SERIALIZE(tx_blob_size)
KV_SERIALIZE_BLOB_AS_HEX_STRING(payment_id)
KV_SERIALIZE(remote_addresses)
KV_SERIALIZE(remote_aliases)
KV_SERIALIZE(comment)
KV_SERIALIZE(is_income)
KV_SERIALIZE(timestamp)
KV_SERIALIZE(td)
KV_SERIALIZE(employed_entries)
KV_SERIALIZE(fee)
KV_SERIALIZE(is_service)
KV_SERIALIZE(is_mixing)
@ -144,10 +182,96 @@ namespace wallet_public
KV_SERIALIZE(contract)
KV_SERIALIZE(service_entries)
KV_SERIALIZE(transfer_internal_index)
KV_SERIALIZE_POD_AS_HEX_STRING(asset_id)
KV_SERIALIZE(remote_addresses)
KV_SERIALIZE(remote_aliases)
KV_SERIALIZE(subtransfers)
END_KV_SERIALIZE_MAP()
BEGIN_BOOST_SERIALIZATION()
BOOST_SERIALIZE(timestamp)
BOOST_SERIALIZE(tx_hash)
BOOST_SERIALIZE(height)
BOOST_SERIALIZE(tx_blob_size)
BOOST_SERIALIZE(payment_id)
BOOST_SERIALIZE(remote_addresses)
BOOST_SERIALIZE(employed_entries)
BOOST_SERIALIZE(tx)
BOOST_SERIALIZE(remote_aliases)
BOOST_SERIALIZE(comment)
BOOST_SERIALIZE(contract)
BOOST_SERIALIZE(selected_indicies)
BOOST_SERIALIZE(marketplace_entries)
BOOST_SERIALIZE(unlock_time)
BOOST_SERIALIZE(service_entries)
BOOST_SERIALIZE(subtransfers)
END_BOOST_SERIALIZATION()
bool is_income_mode_encryption() const
{
for (const auto& st : subtransfers)
{
if (st.asset_id == currency::native_coin_asset_id)
return st.is_income;
}
return true;
}
bool has_outgoing_entries() const
{
for (const auto& st : subtransfers)
{
if (!st.is_income)
return true;
}
return false;
}
uint64_t get_native_income_amount() const
{
for (const auto& st : subtransfers)
{
if (st.asset_id == currency::native_coin_asset_id && st.is_income)
return st.amount;
}
return 0;
}
uint64_t get_native_amount() const
{
for (const auto& st : subtransfers)
{
if (st.asset_id == currency::native_coin_asset_id )
return st.amount;
}
return 0;
}
bool get_native_is_income() const
{
for (const auto& st : subtransfers)
{
if (st.asset_id == currency::native_coin_asset_id)
return st.is_income;
}
return false;
}
uint64_t& get_native_income_amount()
{
for (auto& st : subtransfers)
{
if (st.asset_id == currency::native_coin_asset_id)
if (st.is_income)
{
return st.amount;
}
else
{
throw std::runtime_error("Unexpected wallet_transfer_info: native is not income type");
}
}
subtransfers.push_back(wallet_sub_transfer_info());
subtransfers.back().is_income = true;
return subtransfers.back().amount;
}
};
struct asset_balance_entry_base
{
uint64_t total = 0;
@ -437,9 +561,11 @@ namespace wallet_public
{
uint64_t amount;
std::string address;
crypto::public_key asset_id;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
KV_SERIALIZE(address)
KV_SERIALIZE_POD_AS_HEX_STRING(asset_id)
END_KV_SERIALIZE_MAP()
};

View file

@ -366,6 +366,7 @@ namespace tools
payment_id = embedded_payment_id;
}
de.amount = it->amount;
de.asset_id = (it->asset_id == currency::null_pkey ? currency::native_coin_asset_id : it->asset_id);
dsts.push_back(de);
}
@ -688,10 +689,11 @@ namespace tools
}
}
if (wti.is_income && req.in)
bool has_outgoing = wti.has_outgoing_entries();
if (!has_outgoing && req.in)
res.in.push_back(wti);
if (!wti.is_income && req.out)
if (has_outgoing && req.out)
res.out.push_back(wti);
return true; // continue
@ -701,7 +703,7 @@ namespace tools
if (req.pool)
{
w.get_wallet()->enumerate_unconfirmed_transfers([&](const wallet_public::wallet_transfer_info& wti) -> bool {
if ((wti.is_income && req.in) || (!wti.is_income && req.out))
if ((!wti.has_outgoing_entries() && req.in) || (wti.has_outgoing_entries() && req.out))
res.pool.push_back(wti);
return true; // continue
});

View file

@ -24,7 +24,7 @@ using namespace currency;
struct wallet_tests_callback_handler : public tools::i_wallet2_callback
{
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined)
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined)
{
all_wtis.push_back(wti);
}

View file

@ -2071,7 +2071,7 @@ bool make_tx_multisig_to_key(const currency::transaction& source_tx,
return true;
}
bool estimate_wallet_balance_blocked_for_escrow(const tools::wallet2& w, uint64_t& result, bool substruct_change_from_result /* = true */, uint64_t* p_change /* = nullptr */)
bool estimate_wallet_balance_blocked_for_escrow(const tools::wallet2& w, uint64_t& result, bool substruct_change_from_result /* = true */)
{
std::deque<tools::wallet2::transfer_details> transfers;
w.get_transfers(transfers);
@ -2082,18 +2082,24 @@ bool estimate_wallet_balance_blocked_for_escrow(const tools::wallet2& w, uint64_
if (td.m_flags == (WALLET_TRANSFER_DETAIL_FLAG_BLOCKED | WALLET_TRANSFER_DETAIL_FLAG_ESCROW_PROPOSAL_RESERVATION))
result += td.amount();
}
if (substruct_change_from_result || p_change != nullptr)
if (substruct_change_from_result)
{
const std::list<tools::wallet2::expiration_entry_info>& ee = w.get_expiration_entries();
for (auto &e : ee)
{
CHECK_AND_ASSERT_MES(result >= e.change_amount, false, "wrong transfers: result: " << print_money(result) << " is expected to be NOT LESS than change_amount: " << print_money(e.change_amount));
if (substruct_change_from_result)
result -= e.change_amount;
if (p_change != nullptr)
*p_change += e.change_amount;
uint64_t change_amount_native = 0;
for (const auto rd : e.receved)
{
if (rd.asset_id == currency::native_coin_asset_id)
change_amount_native += rd.amount;
}
CHECK_AND_ASSERT_MES(result >= change_amount_native, false, "wrong transfers: result: " << print_money(result) << " is expected to be NOT LESS than change_amount: " << print_money(change_amount_native));
result -= change_amount_native;
}
}
return true;
}

View file

@ -725,7 +725,7 @@ bool make_tx_multisig_to_key(const currency::transaction& source_tx,
const std::vector<currency::attachment_v>& attachments = empty_attachment,
const std::vector<currency::extra_v>& extra = empty_extra);
bool estimate_wallet_balance_blocked_for_escrow(const tools::wallet2& w, uint64_t& result, bool substruct_change_from_result = true, uint64_t* p_change = nullptr);
bool estimate_wallet_balance_blocked_for_escrow(const tools::wallet2& w, uint64_t& result, bool substruct_change_from_result = true);
bool check_wallet_balance_blocked_for_escrow(const tools::wallet2& w, const char* wallet_name, uint64_t expected_amount);
bool refresh_wallet_and_check_balance(const char* intro_log_message, const char* wallet_name, std::shared_ptr<tools::wallet2> wallet, uint64_t expected_total,
bool print_transfers = false,

View file

@ -316,3 +316,40 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf,
return true;
}
//---------------------------------------------------------------
namespace currency
{
//this lookup_acc_outs overload is mostly for backward compatibility for tests, ineffective from performance perspective, should not be used in wallet
inline bool lookup_acc_outs(const currency::account_keys& acc, const currency::transaction& tx, std::vector<currency::wallet_out_info>& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation)
{
outs.clear();
sum_of_native_outs = 0;
bool res = currency::lookup_acc_outs(acc, tx, outs, derivation);
for (const auto& o : outs)
{
if (o.asset_id == currency::native_coin_asset_id)
{
sum_of_native_outs += o.amount;
}
}
return res;
}
//this lookup_acc_outs overload is mostly for backward compatibility for tests, ineffective from performance perspective, should not be used in wallet
inline bool lookup_acc_outs(const currency::account_keys& acc, const currency::transaction& tx, const crypto::public_key& /*tx_onetime_pubkey*/, std::vector<currency::wallet_out_info>& outs, uint64_t& sum_of_native_outs, crypto::key_derivation& derivation)
{
sum_of_native_outs = 0;
bool res = currency::lookup_acc_outs(acc, tx, outs, derivation);
for (const auto& o : outs)
{
if (o.asset_id == currency::native_coin_asset_id)
{
sum_of_native_outs += o.amount;
}
}
return res;
}
}

View file

@ -17,7 +17,7 @@ using namespace currency;
struct wallet_tests_callback_handler : public tools::i_wallet2_callback
{
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined)
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined)
{
all_wtis.push_back(wti);
}
@ -1627,6 +1627,7 @@ bool escrow_custom_test::generate(std::vector<test_event_entry>& events) const
test_details.push_back(cd);
}
for(auto cd : test_details)
{
DO_CALLBACK_PARAMS_STR(events, "check", epee::serialization::store_t_to_json(cd));
@ -1637,7 +1638,7 @@ bool escrow_custom_test::generate(std::vector<test_event_entry>& events) const
prev_block = blk_n;
}
return true;
}
@ -2601,7 +2602,7 @@ bool escrow_cancellation_proposal_expiration::c1(currency::core& c, size_t ev_in
crypto::hash contract_id = contracts.begin()->first;
uint64_t alice_blocked_transfers_sum = 0;
CHECK_AND_ASSERT_MES(estimate_wallet_balance_blocked_for_escrow(*alice_wlt.get(), alice_blocked_transfers_sum, false), false, "");
CHECK_AND_ASSERT_MES(estimate_wallet_balance_blocked_for_escrow(*alice_wlt.get(), alice_blocked_transfers_sum), false, "");
// mine a block, containing escrow proposal tx
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
@ -2622,7 +2623,7 @@ bool escrow_cancellation_proposal_expiration::c1(currency::core& c, size_t ev_in
bob_wlt->accept_proposal(contract_id, TESTS_DEFAULT_FEE);
uint64_t bob_blocked_transfers_sum = 0;
CHECK_AND_ASSERT_MES(estimate_wallet_balance_blocked_for_escrow(*bob_wlt.get(), bob_blocked_transfers_sum, false), false, "");
CHECK_AND_ASSERT_MES(estimate_wallet_balance_blocked_for_escrow(*bob_wlt.get(), bob_blocked_transfers_sum), false, "");
// mine a block containing contract acceptance
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());

View file

@ -140,7 +140,7 @@ bool hard_fork_2_tx_payer_in_wallet::c1(currency::core& c, size_t ev_index, cons
size_t callback_counter = 0;
std::shared_ptr<wlt_lambda_on_transfer2_wrapper> l(new wlt_lambda_on_transfer2_wrapper(
[&](const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -> bool {
[&](const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) -> bool {
CHECK_AND_ASSERT_THROW_MES(wti.show_sender, "show_sender is false");
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.size() == 1, "incorrect wti.remote_addresses.size() = " << wti.remote_addresses.size());
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.front() == m_accounts[MINER_ACC_IDX].get_public_address_str(), "wti.remote_addresses.front is incorrect");
@ -234,8 +234,8 @@ bool hard_fork_2_tx_payer_in_wallet::c1(currency::core& c, size_t ev_index, cons
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
std::shared_ptr<wlt_lambda_on_transfer2_wrapper> l2(new wlt_lambda_on_transfer2_wrapper(
[&](const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -> bool {
CHECK_AND_ASSERT_THROW_MES(wti.amount == MK_TEST_COINS(2), "incorrect wti.amount = " << print_money_brief(wti.amount));
[&](const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) -> bool {
CHECK_AND_ASSERT_THROW_MES(wti.get_native_amount() == MK_TEST_COINS(2), "incorrect wti.amount = " << print_money_brief(wti.get_native_amount()));
CHECK_AND_ASSERT_THROW_MES(wti.show_sender, "show_sender is false");
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.size() == 1, "incorrect wti.remote_addresses.size() = " << wti.remote_addresses.size());
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.front() == m_accounts[MINER_ACC_IDX].get_public_address_str(), "wti.remote_addresses.front is incorrect");
@ -367,8 +367,8 @@ bool hard_fork_2_tx_receiver_in_wallet::c1(currency::core& c, size_t ev_index, c
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
std::shared_ptr<wlt_lambda_on_transfer2_wrapper> l(new wlt_lambda_on_transfer2_wrapper(
[&](const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -> bool {
CHECK_AND_ASSERT_THROW_MES(!wti.is_income, "wti.is_income is " << wti.is_income);
[&](const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) -> bool {
CHECK_AND_ASSERT_THROW_MES(!wti.get_native_is_income(), "wti.is_income is " << wti.get_native_is_income());
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.size() == 2, "incorrect wti.remote_addresses.size() = " << wti.remote_addresses.size());
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.front() == m_accounts[MINER_ACC_IDX].get_public_address_str(), "wti.remote_addresses.front is incorrect");
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.back() == m_accounts[BOB_ACC_IDX].get_public_address_str(), "wti.remote_addresses.back is incorrect");
@ -409,9 +409,9 @@ bool hard_fork_2_tx_receiver_in_wallet::c1(currency::core& c, size_t ev_index, c
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
std::shared_ptr<wlt_lambda_on_transfer2_wrapper> l2(new wlt_lambda_on_transfer2_wrapper(
[&](const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -> bool {
CHECK_AND_ASSERT_THROW_MES(!wti.is_income, "wti.is_income is " << wti.is_income);
CHECK_AND_ASSERT_THROW_MES(wti.amount == MK_TEST_COINS(4), "incorrect wti.amount = " << print_money_brief(wti.amount));
[&](const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) -> bool {
CHECK_AND_ASSERT_THROW_MES(!wti.get_native_is_income(), "wti.is_income is " << wti.get_native_is_income());
CHECK_AND_ASSERT_THROW_MES(wti.get_native_amount() == MK_TEST_COINS(4), "incorrect wti.amount = " << print_money_brief(wti.get_native_amount()));
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.size() == 2, "incorrect wti.remote_addresses.size() = " << wti.remote_addresses.size());
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.front() == m_accounts[MINER_ACC_IDX].get_public_address_str(), "wti.remote_addresses.front is incorrect");
CHECK_AND_ASSERT_THROW_MES(wti.remote_addresses.back() == m_accounts[BOB_ACC_IDX].get_public_address_str(), "wti.remote_addresses.back is incorrect");
@ -1003,7 +1003,7 @@ bool hard_fork_2_awo_wallets_basic_test<before_hf_2>::c1(currency::core& c, size
bool callback_called = false;
std::shared_ptr<wlt_lambda_on_transfer2_wrapper> l(new wlt_lambda_on_transfer2_wrapper(
[&callback_called](const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -> bool {
[&callback_called](const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) -> bool {
callback_called = true;
return true;
}

View file

@ -10,7 +10,7 @@
#include "currency_core/account.h"
#include "currency_core/currency_format_utils.h"
#include "misc_language.h"
#include "chaingen_helpers.h"
using namespace currency;
@ -117,12 +117,12 @@ bool test_transaction_generation_and_ring_signature()
std::vector<wallet_out_info> outs;
uint64_t money = 0;
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
r = lookup_acc_outs(rv_acc.get_keys(), tx_rc1, get_tx_pub_key_from_extra(tx_rc1), outs, money, derivation);
r = lookup_acc_outs(rv_acc.get_keys(), tx_rc1, outs, money, derivation);
CHECK_AND_ASSERT_MES(r, false, "failed to lookup_acc_outs");
CHECK_AND_ASSERT_MES(td.amount == money, false, "wrong money amount in new transaction");
money = 0;
derivation = AUTO_VAL_INIT(derivation);
r = lookup_acc_outs(rv_acc2.get_keys(), tx_rc1, get_tx_pub_key_from_extra(tx_rc1), outs, money, derivation);
r = lookup_acc_outs(rv_acc2.get_keys(), tx_rc1, outs, money, derivation);
CHECK_AND_ASSERT_MES(r, false, "failed to lookup_acc_outs");
CHECK_AND_ASSERT_MES(0 == money, false, "wrong money amount in new transaction");
return true;

View file

@ -1598,7 +1598,7 @@ bool gen_wallet_decrypted_attachments::generate(std::vector<test_event_entry>& e
return true;
}
void gen_wallet_decrypted_attachments::on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined)
void gen_wallet_decrypted_attachments::on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined)
{
m_on_transfer2_called = true;
//try {
@ -1831,9 +1831,9 @@ bool gen_wallet_alias_via_special_wallet_funcs::c1(currency::core& c, size_t ev_
uint64_t biggest_alias_reward = get_alias_coast_from_fee("a", TESTS_DEFAULT_FEE);
std::shared_ptr<wlt_lambda_on_transfer2_wrapper> l(new wlt_lambda_on_transfer2_wrapper(
[biggest_alias_reward](const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -> bool {
[biggest_alias_reward](const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) -> bool {
return std::count(wti.remote_aliases.begin(), wti.remote_aliases.end(), "minerminer") == 1 &&
wti.amount == biggest_alias_reward;
wti.get_native_amount() == biggest_alias_reward + get_tx_fee(wti.tx);
}
));
alice_wlt->callback(l);
@ -3307,8 +3307,12 @@ bool wallet_unconfimed_tx_balance::c1(currency::core& c, size_t ev_index, const
bool callback_is_ok = false;
// this callback will ba called from within wallet2::transfer() below
std::shared_ptr<wlt_lambda_on_transfer2_wrapper> l(new wlt_lambda_on_transfer2_wrapper(
[&callback_is_ok](const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -> bool
[&callback_is_ok](const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) -> bool
{
tools::wallet_public::asset_balance_entry abe = get_native_balance_entry(balances);
uint64_t balance = abe.total;
uint64_t unlocked_balance = abe.unlocked;
CHECK_AND_ASSERT_MES(balance == MK_TEST_COINS(70), false, "invalid balance: " << print_money_brief(balance));
CHECK_AND_ASSERT_MES(unlocked_balance == MK_TEST_COINS(50), false, "invalid unlocked_balance: " << print_money_brief(unlocked_balance));
CHECK_AND_ASSERT_MES(total_mined == 0, false, "invalid total_mined: " << print_money_brief(total_mined));
@ -3510,8 +3514,8 @@ bool wallet_sending_to_integrated_address::c1(currency::core& c, size_t ev_index
bool callback_succeded = false;
std::shared_ptr<wlt_lambda_on_transfer2_wrapper> l(new wlt_lambda_on_transfer2_wrapper(
[&](const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) -> bool {
LOG_PRINT_YELLOW("on_transfer: " << print_money_brief(wti.amount) << " pid len: " << wti.payment_id.size() << " remote addr: " << (wti.remote_addresses.size() > 0 ? wti.remote_addresses[0] : ""), LOG_LEVEL_0);
[&](const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) -> bool {
LOG_PRINT_YELLOW("on_transfer: " << print_money_brief(wti.get_native_amount()) << " pid len: " << wti.payment_id.size() << " remote addr: " << (wti.remote_addresses.size() > 0 ? wti.remote_addresses[0] : ""), LOG_LEVEL_0);
if (wti.payment_id.empty())
return true; // skip another outputs
CHECK_AND_ASSERT_MES(wti.payment_id == payment_id, false, "incorrect payment id");
@ -3722,7 +3726,7 @@ bool wallet_spend_form_auditable_and_track::c1(currency::core& c, size_t ev_inde
r = false;
bool r_comment = false;
bob_wlt->enumerate_transfers_history([&](const tools::wallet_public::wallet_transfer_info& wti) {
if (wti.amount == MK_TEST_COINS(5))
if (wti.get_native_amount() == MK_TEST_COINS(5))
{
r_comment = (wti.comment == m_comment);
if (!r_comment)

View file

@ -110,7 +110,7 @@ struct gen_wallet_decrypted_attachments : public wallet_test, virtual public too
bool generate(std::vector<test_event_entry>& events) const;
// intrface tools::i_wallet2_callback
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) override;
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) override;
private:
mutable bool m_on_transfer2_called;

View file

@ -48,6 +48,17 @@ protected:
std::shared_ptr<tools::i_core_proxy> m_core_proxy;
};
inline const tools::wallet_public::asset_balance_entry get_native_balance_entry(const std::list<tools::wallet_public::asset_balance_entry>& balances)
{
for (const auto& b : balances)
{
if (b.asset_info.asset_id == currency::native_coin_asset_id)
return b;
}
return tools::wallet_public::asset_balance_entry();
}
// wallet callback helper to check balance in wallet callbacks
// see escrow_balance test for usage example
struct wallet_callback_balance_checker : public tools::i_wallet2_callback
@ -62,8 +73,12 @@ struct wallet_callback_balance_checker : public tools::i_wallet2_callback
m_called = false;
}
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) override
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) override
{
tools::wallet_public::asset_balance_entry native_balance = get_native_balance_entry(balances);
uint64_t balance = native_balance.total;
uint64_t unlocked_balance = native_balance.unlocked;
m_called = true;
m_result = false;
CHECK_AND_ASSERT_MES(m_balance == UINT64_MAX || balance == m_balance, (void)(0), m_label << " balance is incorrect: " << currency::print_money_brief(balance) << ", expected: " << currency::print_money_brief(m_balance));
@ -94,11 +109,11 @@ struct wallet_callback_balance_checker : public tools::i_wallet2_callback
struct wlt_lambda_on_transfer2_wrapper : public tools::i_wallet2_callback
{
typedef std::function<bool(const tools::wallet_public::wallet_transfer_info&, uint64_t, uint64_t, uint64_t)> Func;
typedef std::function<bool(const tools::wallet_public::wallet_transfer_info&, const std::list<tools::wallet_public::asset_balance_entry>&, uint64_t)> Func;
wlt_lambda_on_transfer2_wrapper(Func callback) : m_result(false), m_callback(callback) {}
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) override
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, const std::list<tools::wallet_public::asset_balance_entry>& balances, uint64_t total_mined) override
{
m_result = m_callback(wti, balance, unlocked_balance, total_mined);
m_result = m_callback(wti, balances, total_mined);
}
bool m_result;
Func m_callback;