forked from lthn/blockchain
Merge branch 'cryptoassets' into multiassets
This commit is contained in:
commit
4aa58d1202
10 changed files with 104 additions and 54 deletions
|
|
@ -3857,17 +3857,12 @@ i_core_event_handler* blockchain_storage::get_event_handler() const
|
|||
//------------------------------------------------------------------
|
||||
uint64_t blockchain_storage::validate_alias_reward(const transaction& tx, const std::string& alias) const
|
||||
{
|
||||
|
||||
//validate alias coast
|
||||
uint64_t fee_for_alias = get_alias_coast(alias);
|
||||
|
||||
//validate the price had been paid
|
||||
uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx);
|
||||
|
||||
CHECK_AND_ASSERT_MES(found_alias_reward >= fee_for_alias, false, "registration of alias '"
|
||||
<< alias << "' goes with a reward of " << print_money(found_alias_reward) << " which is less than expected: " << print_money(fee_for_alias)
|
||||
<<"(fee median: " << get_tx_fee_median() << ")"
|
||||
<< ", tx: " << get_transaction_hash(tx));
|
||||
uint64_t burnt_amount = 0;
|
||||
CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, fee_for_alias, &burnt_amount), false,
|
||||
"registration of alias '" << alias << "' failed due to incorrect reward; expected reward: " << print_money_brief(fee_for_alias)
|
||||
<< "; burnt amount: " << (tx.version <= TRANSACTION_VERSION_PRE_HF4 ? print_money_brief(burnt_amount) : std::string("hidden"))
|
||||
<< "; tx: " << get_transaction_hash(tx));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -4332,12 +4327,12 @@ bool blockchain_storage::validate_all_aliases_for_new_median_mode()
|
|||
uint64_t fee_for_alias = get_alias_coast_from_fee(tei.m_alias.m_alias, median_fee);
|
||||
|
||||
//validate the price had been paid
|
||||
uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx_ptr->tx);
|
||||
if (found_alias_reward < fee_for_alias)
|
||||
uint64_t burnt_amount = 0;
|
||||
if (!check_native_coins_amount_burnt_in_outs(tx_ptr->tx, fee_for_alias, &burnt_amount))
|
||||
{
|
||||
LOG_PRINT_RED_L0("[" << i << "]Found collision on alias: " << tei.m_alias.m_alias
|
||||
<< ", expected fee: " << print_money(fee_for_alias) << "(median:" << print_money(median_fee) << ")"
|
||||
<<" found reward: " << print_money(found_alias_reward) <<". tx_id: " << tx_id);
|
||||
LOG_PRINT_RED_L0("[" << i << "]Detected collision on alias: " << tei.m_alias.m_alias
|
||||
<< ", expected fee: " << print_money_brief(fee_for_alias) << " (median: " << print_money_brief(median_fee) << ")"
|
||||
<< " found reward: " << (tx_ptr->tx.version <= TRANSACTION_VERSION_PRE_HF4 ? print_money_brief(burnt_amount) : std::string("hidden")) << "; tx_id: " << tx_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3490,6 +3490,42 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool check_native_coins_amount_burnt_in_outs(const transaction& tx, const uint64_t amount, uint64_t* p_amount_burnt /* = nullptr */)
|
||||
{
|
||||
if (tx.version <= TRANSACTION_VERSION_PRE_HF4)
|
||||
{
|
||||
uint64_t sum_of_bare_outs_burnt = 0;
|
||||
for (const auto& out : tx.vout)
|
||||
{
|
||||
VARIANT_SWITCH_BEGIN(out);
|
||||
VARIANT_CASE_CONST(tx_out_bare, out)
|
||||
if (out.target.type() != typeid(txout_to_key))
|
||||
continue;
|
||||
const txout_to_key& o = boost::get<txout_to_key>(out.target);
|
||||
if (o.key == null_pkey)
|
||||
sum_of_bare_outs_burnt += out.amount;
|
||||
VARIANT_SWITCH_END();
|
||||
}
|
||||
if (p_amount_burnt)
|
||||
*p_amount_burnt = sum_of_bare_outs_burnt;
|
||||
return sum_of_bare_outs_burnt == amount;
|
||||
}
|
||||
|
||||
// post HF-4 txs
|
||||
// assuming: zero out pubkey, explicit asset_id, zero amount blinding mask
|
||||
crypto::point_t sum_of_amount_commitments = crypto::c_point_0;
|
||||
for (const auto& out : tx.vout)
|
||||
{
|
||||
VARIANT_SWITCH_BEGIN(out);
|
||||
VARIANT_CASE_CONST(tx_out_zarcanum, out_zc)
|
||||
if (out_zc.stealth_address == null_pkey && out_zc.blinded_asset_id == native_coin_asset_id_1div8)
|
||||
sum_of_amount_commitments += crypto::point_t(out_zc.amount_commitment).modify_mul8();
|
||||
VARIANT_SWITCH_END();
|
||||
}
|
||||
return sum_of_amount_commitments == amount * native_coin_asset_id_pt;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// DEPRECATED, don't use -- sowle
|
||||
uint64_t get_amount_for_zero_pubkeys(const transaction& tx)
|
||||
{
|
||||
uint64_t found_alias_reward = 0;
|
||||
|
|
|
|||
|
|
@ -399,7 +399,8 @@ namespace currency
|
|||
bool is_service_tx(const transaction& tx);
|
||||
bool does_tx_have_only_mixin_inputs(const transaction& tx);
|
||||
bool is_showing_sender_addres(const transaction& tx);
|
||||
uint64_t get_amount_for_zero_pubkeys(const transaction& tx);
|
||||
bool check_native_coins_amount_burnt_in_outs(const transaction& tx, const uint64_t amount, uint64_t* p_amount_burnt = nullptr);
|
||||
[[deprecated("Use check_native_coins_amount_burnt_in_outs instead")]] uint64_t get_amount_for_zero_pubkeys(const transaction& tx);
|
||||
//std::string get_comment_from_tx(const transaction& tx);
|
||||
std::string print_stake_kernel_info(const stake_kernel& sk);
|
||||
std::string dump_ring_sig_data(const crypto::hash& hash_for_sig, const crypto::key_image& k_image, const std::vector<const crypto::public_key*>& output_keys_ptrs, const std::vector<crypto::signature>& sig);
|
||||
|
|
|
|||
|
|
@ -2109,13 +2109,13 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed)
|
|||
|
||||
// read extra
|
||||
std::vector<wallet_out_info> outs;
|
||||
uint64_t tx_money_got_in_outs = 0;
|
||||
uint64_t sum_of_received_native_outs = 0;
|
||||
crypto::public_key tx_pub_key = null_pkey;
|
||||
r = parse_and_validate_tx_extra(tx, tx_pub_key);
|
||||
THROW_IF_TRUE_WALLET_EX(!r, error::tx_extra_parse_error, tx);
|
||||
//check if we have money
|
||||
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
|
||||
r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs, derivation);
|
||||
r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, sum_of_received_native_outs, derivation);
|
||||
THROW_IF_TRUE_WALLET_EX(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||
|
||||
//collect incomes
|
||||
|
|
@ -2124,7 +2124,7 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed)
|
|||
|
||||
bool new_multisig_spend_detected = false;
|
||||
//check if we have spendings
|
||||
uint64_t tx_money_spent_in_ins = 0;
|
||||
uint64_t sum_of_spent_native_coin = 0;
|
||||
std::list<size_t> spend_transfers;
|
||||
// check all outputs for spending (compare key images)
|
||||
for (size_t i = 0; i != tx.vin.size(); i++)
|
||||
|
|
@ -2152,7 +2152,33 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed)
|
|||
if (tid != UINT64_MAX)
|
||||
{
|
||||
// own output is being spent by this input
|
||||
tx_money_spent_in_ins += intk.amount;
|
||||
sum_of_spent_native_coin += intk.amount;
|
||||
td.spent_indices.push_back(i);
|
||||
spend_transfers.push_back(tid);
|
||||
}
|
||||
}
|
||||
else if (in.type() == typeid(currency::txin_zc_input))
|
||||
{
|
||||
// bad design -- remove redundancy like using wallet2::process_input_t()
|
||||
const currency::txin_zc_input& zc = boost::get<currency::txin_zc_input>(in);
|
||||
uint64_t tid = UINT64_MAX;
|
||||
if (is_auditable() && is_watch_only())
|
||||
{
|
||||
// tracking wallet, assuming all outputs are spent directly because of mix_attr = 1
|
||||
tid = get_directly_spent_transfer_index_by_input_in_tracking_wallet(zc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// wallet with spend secret key -- we can calculate own key images and then search among them
|
||||
auto it = m_key_images.find(zc.k_image);
|
||||
if (it != m_key_images.end())
|
||||
{
|
||||
tid = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (tid != UINT64_MAX)
|
||||
{
|
||||
td.spent_indices.push_back(i);
|
||||
spend_transfers.push_back(tid);
|
||||
}
|
||||
|
|
@ -2184,7 +2210,7 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed)
|
|||
}
|
||||
|
||||
|
||||
if (((!tx_money_spent_in_ins && tx_money_got_in_outs) || (currency::is_derivation_used_to_encrypt(tx, derivation) && !tx_money_spent_in_ins)) && !is_tx_expired(tx, tx_expiration_ts_median))
|
||||
if (((!sum_of_spent_native_coin && sum_of_received_native_outs) || (currency::is_derivation_used_to_encrypt(tx, derivation) && !sum_of_spent_native_coin)) && !is_tx_expired(tx, tx_expiration_ts_median))
|
||||
{
|
||||
m_unconfirmed_in_transfers[tx_hash] = tx;
|
||||
if (m_unconfirmed_txs.count(tx_hash))
|
||||
|
|
@ -2192,22 +2218,22 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed)
|
|||
|
||||
//prepare notification about pending transaction
|
||||
wallet_public::wallet_transfer_info& unconfirmed_wti = misc_utils::get_or_insert_value_initialized(m_unconfirmed_txs, tx_hash);
|
||||
|
||||
unconfirmed_wti.asset_id = native_coin_asset_id; // <-- TODO @#@#
|
||||
unconfirmed_wti.is_income = true;
|
||||
prepare_wti(unconfirmed_wti, 0, m_core_runtime_config.get_core_time(), tx, tx_money_got_in_outs, td);
|
||||
prepare_wti(unconfirmed_wti, 0, m_core_runtime_config.get_core_time(), tx, sum_of_received_native_outs, td);
|
||||
rise_on_transfer2(unconfirmed_wti);
|
||||
}
|
||||
else if (tx_money_spent_in_ins || new_multisig_spend_detected)
|
||||
else if (sum_of_spent_native_coin || new_multisig_spend_detected)
|
||||
{
|
||||
m_unconfirmed_in_transfers[tx_hash] = tx;
|
||||
if (m_unconfirmed_txs.count(tx_hash))
|
||||
continue;
|
||||
//outgoing tx that was sent somehow not from this application instance
|
||||
uint64_t amount = 0;
|
||||
/*if (!new_multisig_spend_detected && tx_money_spent_in_ins < tx_money_got_in_outs+get_tx_fee(tx))
|
||||
/*if (!new_multisig_spend_detected && tx_money_spent_in_ins < sum_of_received_native_outs+get_tx_fee(tx))
|
||||
{
|
||||
WLT_LOG_ERROR("Transaction that get more then send: tx_money_spent_in_ins=" << tx_money_spent_in_ins
|
||||
<< ", tx_money_got_in_outs=" << tx_money_got_in_outs << ", tx_id=" << tx_hash);
|
||||
<< ", sum_of_received_native_outs=" << sum_of_received_native_outs << ", tx_id=" << tx_hash);
|
||||
}
|
||||
else*/ if (new_multisig_spend_detected)
|
||||
{
|
||||
|
|
@ -2215,12 +2241,12 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed)
|
|||
}
|
||||
else
|
||||
{
|
||||
amount = tx_money_spent_in_ins - (tx_money_got_in_outs + get_tx_fee(tx));
|
||||
amount = sum_of_spent_native_coin - (sum_of_received_native_outs + get_tx_fee(tx));
|
||||
}
|
||||
|
||||
//prepare notification about pending transaction
|
||||
wallet_public::wallet_transfer_info& unconfirmed_wti = misc_utils::get_or_insert_value_initialized(m_unconfirmed_txs, tx_hash);
|
||||
|
||||
unconfirmed_wti.asset_id = native_coin_asset_id; // <-- TODO @#@#
|
||||
unconfirmed_wti.is_income = false;
|
||||
prepare_wti(unconfirmed_wti, 0, m_core_runtime_config.get_core_time(), tx, amount, td);
|
||||
//mark transfers as spend to get correct balance
|
||||
|
|
|
|||
|
|
@ -397,7 +397,6 @@ namespace tools
|
|||
KV_SERIALIZE(m_spent_height)
|
||||
KV_SERIALIZE(m_flags)
|
||||
KV_SERIALIZE(m_amount)
|
||||
//KV_SERIALIZE_N(m_opt_blinding_mask, "blinding_mask")
|
||||
KV_SERIALIZE_N(m_zc_info_ptr, "zc_out_info")
|
||||
KV_SERIALIZE_EPHEMERAL_N(uint64_t, tools::wallet2::transfer_details_base_to_amount, "amount")
|
||||
KV_SERIALIZE_EPHEMERAL_N(std::string, tools::wallet2::transfer_details_base_to_tx_hash, "tx_id")
|
||||
|
|
|
|||
|
|
@ -1842,7 +1842,7 @@ bool check_balance_via_wallet(const tools::wallet2& w, const char* account_name,
|
|||
|
||||
bool r = true;
|
||||
|
||||
#define _CHECK_BAL(v) if (!(expected_##v == INVALID_BALANCE_VAL || v == expected_##v)) { r = false; LOG_PRINT_RED_L0("invalid " #v " balance, expected: " << print_money(expected_##v)); }
|
||||
#define _CHECK_BAL(v) if (!(expected_##v == INVALID_BALANCE_VAL || v == expected_##v)) { r = false; LOG_PRINT_RED_L0("invalid " #v " balance, expected: " << print_money_brief(expected_##v)); }
|
||||
_CHECK_BAL(unlocked)
|
||||
_CHECK_BAL(awaiting_in)
|
||||
_CHECK_BAL(awaiting_out)
|
||||
|
|
|
|||
|
|
@ -288,14 +288,17 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf,
|
|||
currency::account_keys& ak = const_cast<currency::account_keys&>(reward_acc.get_keys());
|
||||
currency::get_aliases_reward_account(ak.account_address, ak.view_secret_key);
|
||||
|
||||
uint64_t fee_median = generator.get_last_n_blocks_fee_median(get_block_hash(head_block));
|
||||
uint64_t reward = currency::get_alias_coast_from_fee(ae.m_alias, fee_median);
|
||||
uint64_t alias_reward = 0;
|
||||
if (get_block_height(head_block) < ALIAS_MEDIAN_RECALC_INTERWAL)
|
||||
alias_reward = get_alias_coast_from_fee(ae.m_alias, ALIAS_VERY_INITAL_COAST); // don't ask why
|
||||
else
|
||||
LOCAL_ASSERT(false); // not implemented yet, see also all the mess around blockchain_storage::get_tx_fee_median(), get_tx_fee_median_effective_index() etc.
|
||||
|
||||
MAKE_TX_MIX_LIST_EXTRA_MIX_ATTR(events,
|
||||
tx_set,
|
||||
miner_acc,
|
||||
reward_acc,
|
||||
reward,
|
||||
alias_reward,
|
||||
0,
|
||||
head_block,
|
||||
CURRENCY_TO_KEY_OUT_RELAXED,
|
||||
|
|
@ -303,12 +306,11 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf,
|
|||
std::vector<currency::attachment_v>());
|
||||
|
||||
|
||||
uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx_set.back());
|
||||
if (found_alias_reward != reward)
|
||||
uint64_t burnt_amount = 0;
|
||||
if (!check_native_coins_amount_burnt_in_outs(tx_set.back(), alias_reward, &burnt_amount))
|
||||
{
|
||||
LOCAL_ASSERT(false);
|
||||
CHECK_AND_ASSERT_MES(false, false, "wrong transaction constructed, first input value not match alias amount or account");
|
||||
return false;
|
||||
CHECK_AND_ASSERT_MES(false, false, "alias reward was not found, expected: " << print_money_brief(alias_reward)
|
||||
<< "; burnt: " << (tx_set.back().version <= TRANSACTION_VERSION_PRE_HF4 ? print_money_brief(burnt_amount) : "hidden") << "; tx: " << get_transaction_hash(tx_set.back()));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ hard_fork_2_base_test::hard_fork_2_base_test(size_t hardfork_01_height, size_t h
|
|||
, m_hardfork_02_height(hardfork_02_height)
|
||||
, m_hardfork_03_height(CURRENCY_MAX_BLOCK_NUMBER)
|
||||
{
|
||||
|
||||
m_hardforks.clear();
|
||||
m_hardforks.set_hardfork_height(1, m_hardfork_01_height);
|
||||
m_hardforks.set_hardfork_height(2, m_hardfork_02_height);
|
||||
m_hardforks.set_hardfork_height(3, m_hardfork_03_height);
|
||||
REGISTER_CALLBACK_METHOD(hard_fork_2_base_test, configure_core);
|
||||
}
|
||||
|
||||
|
|
@ -29,19 +32,11 @@ bool hard_fork_2_base_test::configure_core(currency::core& c, size_t ev_index, c
|
|||
currency::core_runtime_config pc = c.get_blockchain_storage().get_core_runtime_config();
|
||||
pc.min_coinstake_age = TESTS_POS_CONFIG_MIN_COINSTAKE_AGE;
|
||||
pc.pos_minimum_heigh = TESTS_POS_CONFIG_POS_MINIMUM_HEIGH;
|
||||
pc.hard_forks.set_hardfork_height(1, m_hardfork_01_height);
|
||||
pc.hard_forks.set_hardfork_height(2, m_hardfork_02_height);
|
||||
pc.hard_forks.set_hardfork_height(3, m_hardfork_03_height);
|
||||
pc.hard_forks = m_hardforks;
|
||||
c.get_blockchain_storage().set_core_runtime_config(pc);
|
||||
return true;
|
||||
}
|
||||
|
||||
void hard_fork_2_base_test::set_hard_fork_heights_to_generator(test_generator& generator) const
|
||||
{
|
||||
generator.set_hardfork_height(1, m_hardfork_01_height);
|
||||
generator.set_hardfork_height(2, m_hardfork_02_height);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
hard_fork_2_tx_payer_in_wallet::hard_fork_2_tx_payer_in_wallet()
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ struct hard_fork_2_base_test : virtual public test_chain_unit_enchanced
|
|||
hard_fork_2_base_test(size_t hardfork_01_height, size_t hardfork_02_height);
|
||||
bool configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
void set_hard_fork_heights_to_generator(test_generator& generator) const;
|
||||
|
||||
size_t m_hardfork_01_height;
|
||||
size_t m_hardfork_02_height;
|
||||
size_t m_hardfork_03_height;
|
||||
|
|
|
|||
|
|
@ -1670,8 +1670,7 @@ bool gen_wallet_alias_and_unconfirmed_txs::c1(currency::core& c, size_t ev_index
|
|||
std::vector<test_event_entry> stub_events_vec;
|
||||
MAKE_TEST_WALLET_TX_EXTRA(stub_events_vec, tx, bob_wlt, alias_reward, null_account, std::vector<currency::extra_v>({ ai }));
|
||||
|
||||
uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx);
|
||||
CHECK_AND_ASSERT_MES(found_alias_reward == alias_reward, false, "Generated tx has invalid alias reward");
|
||||
CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, alias_reward), false, "Generated tx has invalid alias reward");
|
||||
|
||||
bool has_relates_alias_in_unconfirmed = false;
|
||||
bob_wlt->scan_tx_pool(has_relates_alias_in_unconfirmed);
|
||||
|
|
@ -1707,8 +1706,7 @@ bool gen_wallet_alias_and_unconfirmed_txs::c2(currency::core& c, size_t ev_index
|
|||
std::vector<test_event_entry> stub_events_vec;
|
||||
MAKE_TEST_WALLET_TX_EXTRA(stub_events_vec, tx, bob_wlt, alias_reward, null_account, std::vector<currency::extra_v>({ ai }));
|
||||
|
||||
uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx);
|
||||
CHECK_AND_ASSERT_MES(found_alias_reward == alias_reward, false, "Generated tx has invalid alias reward");
|
||||
CHECK_AND_ASSERT_MES(check_native_coins_amount_burnt_in_outs(tx, alias_reward), false, "Generated tx has invalid alias reward");
|
||||
|
||||
bool has_relates_alias_in_unconfirmed = false;
|
||||
bob_wlt->scan_tx_pool(has_relates_alias_in_unconfirmed);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue