forked from lthn/blockchain
added double spend protection in htlc(great that i've thought about it now), wallet loading optimization
This commit is contained in:
parent
52c5c1250f
commit
82d0e335e6
6 changed files with 78 additions and 20 deletions
|
|
@ -744,8 +744,7 @@ bool blockchain_storage::purge_transaction_keyimages_from_blockchain(const trans
|
|||
}
|
||||
bool operator()(const txin_htlc& inp) const
|
||||
{
|
||||
//HTLC TODO
|
||||
return true;
|
||||
return this->operator()(static_cast<const txin_to_key&>(inp));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -3845,8 +3844,7 @@ namespace currency
|
|||
}
|
||||
bool operator()(const txin_htlc& in) const
|
||||
{
|
||||
//HTLC TODO
|
||||
return true;
|
||||
return this->operator()(static_cast<const txin_to_key&>(in));
|
||||
}
|
||||
bool operator()(const txin_gen& in) const { return true; }
|
||||
bool operator()(const txin_multisig& in) const
|
||||
|
|
|
|||
|
|
@ -779,6 +779,11 @@ namespace currency
|
|||
}
|
||||
else if (tx_ptr->tx.vout[n].target.type() == typeid(txout_htlc))
|
||||
{
|
||||
//check for spend flags
|
||||
CHECK_AND_ASSERT_MES(tx_ptr->m_spent_flags.size() > n, false,
|
||||
"Internal error: tx_ptr->m_spent_flags.size(){" << tx_ptr->m_spent_flags.size() << "} > n{" << n << "}");
|
||||
CHECK_AND_ASSERT_MES(tx_ptr->m_spent_flags[n] == false, false, "HTLC out already spent, double spent attempt detected");
|
||||
|
||||
const txout_htlc& htlc_out = boost::get<txout_htlc>(tx_ptr->tx.vout[n].target);
|
||||
if (htlc_out.expiration > get_current_blockchain_size() - tx_ptr->m_keeper_block_height)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -997,7 +997,7 @@ namespace currency
|
|||
void load_wallet_transfer_info_flags(tools::wallet_public::wallet_transfer_info& x)
|
||||
{
|
||||
x.is_service = currency::is_service_tx(x.tx);
|
||||
x.is_mixing = currency::is_mixin_tx(x.tx);
|
||||
x.is_mixing = currency::does_tx_have_only_mixin_inputs(x.tx);
|
||||
x.is_mining = currency::is_coinbase(x.tx);
|
||||
if (!x.is_mining)
|
||||
x.fee = currency::get_tx_fee(x.tx);
|
||||
|
|
@ -1010,7 +1010,7 @@ namespace currency
|
|||
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)
|
||||
{
|
||||
//need to correct amount
|
||||
//need to override amount
|
||||
x.amount = htlc_out.amount;
|
||||
}
|
||||
}
|
||||
|
|
@ -2366,7 +2366,7 @@ namespace currency
|
|||
return have_type_in_variant_container<tx_payer>(tx.attachment) || have_type_in_variant_container<tx_payer_old>(tx.attachment);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool is_mixin_tx(const transaction& tx)
|
||||
bool does_tx_have_only_mixin_inputs(const transaction& tx)
|
||||
{
|
||||
for (const auto& e : tx.vin)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ namespace currency
|
|||
bool set_payment_id_to_tx(std::vector<attachment_v>& att, const std::string& payment_id);
|
||||
bool add_padding_to_tx(transaction& tx, size_t count);
|
||||
bool is_service_tx(const transaction& tx);
|
||||
bool is_mixin_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);
|
||||
//std::string get_comment_from_tx(const transaction& tx);
|
||||
|
|
|
|||
|
|
@ -2245,8 +2245,6 @@ void wallet2::detach_blockchain(uint64_t including_height)
|
|||
// skip coinbase txs as they are not expected to go into the pool
|
||||
if (is_coinbase(it->tx))
|
||||
{
|
||||
if (!it->is_mining)
|
||||
WLT_LOG_ERROR("is_mining flag is not consistent for tx " << it ->tx_hash);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -3086,7 +3084,7 @@ void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_tra
|
|||
{
|
||||
if (exclude_mining_txs)
|
||||
{
|
||||
if(is_mixin_tx(it->tx))
|
||||
if(currency::is_coinbase(it->tx))
|
||||
continue;
|
||||
}
|
||||
trs.push_back(*it);
|
||||
|
|
@ -3424,7 +3422,7 @@ void wallet2::get_unconfirmed_transfers(std::vector<wallet_public::wallet_transf
|
|||
{
|
||||
for (auto& u : m_unconfirmed_txs)
|
||||
{
|
||||
if (exclude_mining_txs && u.second.is_mining)
|
||||
if (exclude_mining_txs && currency::is_coinbase(u.second.tx))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -4013,7 +4011,7 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details&
|
|||
print_tx_sent_message(tx, "(from multisig)", fee);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::create_htlc_proposal(uint64_t amount, const currency::account_public_address& addr, uint64_t lock_blocks_count, currency::transaction &tx, std::string &origin)
|
||||
void wallet2::create_htlc_proposal(uint64_t amount, const currency::account_public_address& addr, uint64_t lock_blocks_count, currency::transaction &tx, const crypto::hash& htlc_hash, std::string &origin)
|
||||
{
|
||||
construct_tx_param ctp = get_default_construct_tx_param();
|
||||
ctp.fee = TX_DEFAULT_FEE;
|
||||
|
|
@ -4021,8 +4019,8 @@ void wallet2::create_htlc_proposal(uint64_t amount, const currency::account_publ
|
|||
ctp.dsts.back().addr.push_back(addr);
|
||||
ctp.dsts.back().amount = amount;
|
||||
destination_option_htlc_out& htlc_option = ctp.dsts.back().htlc_options;
|
||||
htlc_option.expiration = 740; //about 12 hours
|
||||
htlc_option.htlc_hash = null_hash;
|
||||
htlc_option.expiration = lock_blocks_count; //about 12 hours
|
||||
htlc_option.htlc_hash = htlc_hash;
|
||||
|
||||
finalized_tx ft = AUTO_VAL_INIT(ft);
|
||||
this->transfer(ctp, ft, true, nullptr);
|
||||
|
|
|
|||
|
|
@ -99,8 +99,8 @@ bool atomic_simple_test::c1(currency::core& c, size_t ev_index, const std::vecto
|
|||
miner_wlt->transfer(transfer_amount, accunt_alice_blockchain_a.get_public_address());
|
||||
LOG_PRINT_MAGENTA("Transaction sent to Alice A: " << transfer_amount, LOG_LEVEL_0);
|
||||
|
||||
miner_wlt->transfer(transfer_amount, accunt_bob_blockchain_a.get_public_address());
|
||||
LOG_PRINT_MAGENTA("Transaction sent to Bob A: " << transfer_amount, LOG_LEVEL_0);
|
||||
miner_wlt->transfer(transfer_amount, accunt_bob_blockchain_b.get_public_address());
|
||||
LOG_PRINT_MAGENTA("Transaction sent to Bob B: " << transfer_amount, LOG_LEVEL_0);
|
||||
|
||||
bool r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
||||
|
|
@ -116,19 +116,76 @@ bool atomic_simple_test::c1(currency::core& c, size_t ev_index, const std::vecto
|
|||
alice_a_wlt_instance->refresh();
|
||||
alice_b_wlt_instance->refresh();
|
||||
bob_a_wlt_instance->refresh();
|
||||
bob_a_wlt_instance->refresh();
|
||||
bob_b_wlt_instance->refresh();
|
||||
|
||||
CHECK_AND_FORCE_ASSERT_MES(alice_a_wlt_instance->balance() == transfer_amount, false, "Incorrect balance");
|
||||
CHECK_AND_FORCE_ASSERT_MES(bob_a_wlt_instance->balance() == transfer_amount, false, "Incorrect balance");
|
||||
CHECK_AND_FORCE_ASSERT_MES(bob_b_wlt_instance->balance() == transfer_amount, false, "Incorrect balance");
|
||||
|
||||
|
||||
std::string alice_origin; //will be deterministically generated by Alice's A wallet
|
||||
currency::transaction res_tx = AUTO_VAL_INIT(res_tx);
|
||||
alice_a_wlt_instance->create_htlc_proposal(transfer_amount - TESTS_DEFAULT_FEE, bob_a_wlt_instance->get_account().get_public_address(), 20, res_tx, alice_origin);
|
||||
alice_a_wlt_instance->create_htlc_proposal(transfer_amount - TESTS_DEFAULT_FEE, bob_a_wlt_instance->get_account().get_public_address(), 20, res_tx, currency::null_hash, alice_origin);
|
||||
r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
||||
alice_a_wlt_instance->refresh();
|
||||
alice_b_wlt_instance->refresh();
|
||||
bob_a_wlt_instance->refresh();
|
||||
bob_b_wlt_instance->refresh();
|
||||
|
||||
std::list<wallet_public::htlc_entry_info> htlcs_alice_a;
|
||||
alice_a_wlt_instance->get_list_of_active_htlc(htlcs_alice_a, false);
|
||||
CHECK_AND_ASSERT_MES(htlcs_alice_a.size() == 1, false, "htlcs_alice.size() == 1 failed");
|
||||
|
||||
std::list<wallet_public::htlc_entry_info> htlcs_bob_a;
|
||||
bob_a_wlt_instance->get_list_of_active_htlc(htlcs_bob_a, false);
|
||||
CHECK_AND_ASSERT_MES(htlcs_bob_a.size() == 1, false, "htlcs_bob.size() == 1 failed");
|
||||
|
||||
const wallet_public::htlc_entry_info& hei_bob = *htlcs_bob_a.begin();
|
||||
CHECK_AND_ASSERT_MES(hei_bob.is_redeem == true, false, "hei_bob.is_redeem == true failed");
|
||||
|
||||
|
||||
const wallet_public::htlc_entry_info& hei_alice = *htlcs_alice_a.begin();
|
||||
CHECK_AND_ASSERT_MES(hei_alice.is_redeem == false, false, "hei_alice.is_redeem == false failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES(hei_alice.amount == hei_bob.amount
|
||||
&& hei_alice.sha256_hash == hei_bob.sha256_hash
|
||||
&& hei_alice.tx_id == hei_bob.tx_id, false, "hei_alice !=hei_bob ");
|
||||
|
||||
|
||||
//std::string bob_origin;
|
||||
currency::transaction res_bob_tx = AUTO_VAL_INIT(res_tx);
|
||||
std::string dummy_origin;
|
||||
bob_b_wlt_instance->create_htlc_proposal(transfer_amount - TESTS_DEFAULT_FEE,
|
||||
alice_b_wlt_instance->get_account().get_public_address(),
|
||||
20,
|
||||
res_tx, hei_bob.sha256_hash, dummy_origin);
|
||||
|
||||
r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
|
||||
alice_a_wlt_instance->refresh();
|
||||
alice_b_wlt_instance->refresh();
|
||||
bob_a_wlt_instance->refresh();
|
||||
bob_b_wlt_instance->refresh();
|
||||
|
||||
|
||||
std::list<wallet_public::htlc_entry_info> htlcs_alice_b;
|
||||
alice_b_wlt_instance->get_list_of_active_htlc(htlcs_alice_b, false);
|
||||
CHECK_AND_ASSERT_MES(htlcs_alice_b.size() == 1, false, "htlcs_alice_b.size() == 1 failed");
|
||||
|
||||
std::list<wallet_public::htlc_entry_info> htlcs_bob_b;
|
||||
bob_a_wlt_instance->get_list_of_active_htlc(htlcs_bob_b, false);
|
||||
CHECK_AND_ASSERT_MES(htlcs_bob_b.size() == 1, false, "htlcs_bob_b.size() == 1 failed");
|
||||
|
||||
const wallet_public::htlc_entry_info& hei_bob_b = *htlcs_bob_b.begin();
|
||||
CHECK_AND_ASSERT_MES(hei_bob_b.is_redeem == true, false, "hei_bob.is_redeem == true failed");
|
||||
|
||||
|
||||
const wallet_public::htlc_entry_info& hei_alice_b = *htlcs_alice_b.begin();
|
||||
CHECK_AND_ASSERT_MES(hei_alice_b.is_redeem == false, false, "hei_alice.is_redeem == false failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES(hei_alice_b.amount == hei_bob_b.amount
|
||||
&& hei_alice_b.sha256_hash == hei_bob_b.sha256_hash
|
||||
&& hei_alice_b.tx_id == hei_bob_b.tx_id, false, "hei_alice !=hei_bob ");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue