Merge pull request #3536
c77d2bfaAdd the possibility to export private view key for fast scan. (cslashm)100b7bc1Change mutex lock model to avoid dead lock and ensure locks are always released. (cslashm)641dfc99Automatic height setup when creating/restoring hw device. (cslashm)
This commit is contained in:
+44
-11
@@ -1007,13 +1007,16 @@ void wallet2::set_unspent(size_t idx)
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info) const
|
||||
{
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
std::unique_lock<hw::device> hwdev_lock (hwdev);
|
||||
hwdev.set_mode(hw::device::TRANSACTION_PARSE);
|
||||
if (o.target.type() != typeid(txout_to_key))
|
||||
{
|
||||
tx_scan_info.error = true;
|
||||
LOG_ERROR("wrong type id in transaction out");
|
||||
return;
|
||||
}
|
||||
tx_scan_info.received = is_out_to_acc_precomp(m_subaddresses, boost::get<txout_to_key>(o.target).key, derivation, additional_derivations, i, m_account.get_device());
|
||||
tx_scan_info.received = is_out_to_acc_precomp(m_subaddresses, boost::get<txout_to_key>(o.target).key, derivation, additional_derivations, i, hwdev);
|
||||
if(tx_scan_info.received)
|
||||
{
|
||||
tx_scan_info.money_transfered = o.amount; // may be 0 for ringct outputs
|
||||
@@ -1080,9 +1083,15 @@ void wallet2::scan_output(const cryptonote::transaction &tx, const crypto::publi
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector<uint64_t> &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen)
|
||||
{
|
||||
// In this function, tx (probably) only contains the base information
|
||||
// (that is, the prunable stuff may or may not be included)
|
||||
//ensure device is let in NONE mode in any case
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
|
||||
std::unique_lock<hw::device> hwdev_lock (hwdev);
|
||||
hw::reset_mode rst(hwdev);
|
||||
hwdev_lock.unlock();
|
||||
|
||||
// In this function, tx (probably) only contains the base information
|
||||
// (that is, the prunable stuff may or may not be included)
|
||||
if (!miner_tx && !pool)
|
||||
process_unconfirmed(txid, tx, height);
|
||||
std::vector<size_t> outs;
|
||||
@@ -1119,8 +1128,10 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
tools::threadpool& tpool = tools::threadpool::getInstance();
|
||||
tools::threadpool::waiter waiter;
|
||||
const cryptonote::account_keys& keys = m_account.get_keys();
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
crypto::key_derivation derivation;
|
||||
|
||||
hwdev_lock.lock();
|
||||
hwdev.set_mode(hw::device::TRANSACTION_PARSE);
|
||||
if (!hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation))
|
||||
{
|
||||
MWARNING("Failed to generate key derivation from tx pubkey, skipping");
|
||||
@@ -1140,6 +1151,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
additional_derivations.pop_back();
|
||||
}
|
||||
}
|
||||
hwdev_lock.unlock();
|
||||
|
||||
if (miner_tx && m_refresh_type == RefreshNoCoinbase)
|
||||
{
|
||||
@@ -1161,16 +1173,19 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
std::ref(tx_scan_info[i])));
|
||||
}
|
||||
waiter.wait();
|
||||
|
||||
// then scan all outputs from 0
|
||||
hwdev_lock.lock();
|
||||
hwdev.set_mode(hw::device::NONE);
|
||||
for (size_t i = 0; i < tx.vout.size(); ++i)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||
if (tx_scan_info[i].received)
|
||||
{
|
||||
hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation);
|
||||
scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs);
|
||||
}
|
||||
}
|
||||
hwdev_lock.unlock();
|
||||
}
|
||||
}
|
||||
else if (tx.vout.size() > 1 && tools::threadpool::getInstance().get_max_concurrency() > 1)
|
||||
@@ -1181,14 +1196,19 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
std::ref(tx_scan_info[i])));
|
||||
}
|
||||
waiter.wait();
|
||||
|
||||
hwdev_lock.lock();
|
||||
hwdev.set_mode(hw::device::NONE);
|
||||
for (size_t i = 0; i < tx.vout.size(); ++i)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||
if (tx_scan_info[i].received)
|
||||
{
|
||||
hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation);
|
||||
scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs);
|
||||
}
|
||||
}
|
||||
hwdev_lock.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1198,7 +1218,11 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||
if (tx_scan_info[i].received)
|
||||
{
|
||||
hwdev_lock.lock();
|
||||
hwdev.set_mode(hw::device::NONE);
|
||||
hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation);
|
||||
scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs);
|
||||
hwdev_lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7259,6 +7283,11 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image,
|
||||
// usable balance.
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, bool trusted_daemon)
|
||||
{
|
||||
//ensure device is let in NONE mode in any case
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
std::unique_lock<hw::device> hwdev_lock (hwdev);
|
||||
hw::reset_mode rst(hwdev);
|
||||
|
||||
if(m_light_wallet) {
|
||||
// Populate m_transfers
|
||||
light_wallet_get_unspent_outs();
|
||||
@@ -7476,8 +7505,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
unsigned int original_output_index = 0;
|
||||
std::vector<size_t>* unused_transfers_indices = &unused_transfers_indices_per_subaddr[0].second;
|
||||
std::vector<size_t>* unused_dust_indices = &unused_dust_indices_per_subaddr[0].second;
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
hwdev.set_signature_mode(hw::device::SIGNATURE_FAKE);
|
||||
|
||||
hwdev.set_mode(hw::device::TRANSACTION_CREATE_FAKE);
|
||||
while ((!dsts.empty() && dsts[0].amount > 0) || adding_fee || !preferred_inputs.empty() || should_pick_a_second_output(use_rct, txes.back().selected_transfers.size(), *unused_transfers_indices, *unused_dust_indices)) {
|
||||
TX &tx = txes.back();
|
||||
|
||||
@@ -7706,7 +7735,7 @@ skip_tx:
|
||||
LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) <<
|
||||
" total fee, " << print_money(accumulated_change) << " total change");
|
||||
|
||||
hwdev.set_signature_mode(hw::device::SIGNATURE_REAL);
|
||||
hwdev.set_mode(hw::device::TRANSACTION_CREATE_REAL);
|
||||
for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i)
|
||||
{
|
||||
TX &tx = *i;
|
||||
@@ -7837,6 +7866,11 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt
|
||||
|
||||
std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, bool trusted_daemon)
|
||||
{
|
||||
//ensure device is let in NONE mode in any case
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
std::unique_lock<hw::device> hwdev_lock (hwdev);
|
||||
hw::reset_mode rst(hwdev);
|
||||
|
||||
uint64_t accumulated_fee, accumulated_outputs, accumulated_change;
|
||||
struct TX {
|
||||
std::vector<size_t> selected_transfers;
|
||||
@@ -7869,8 +7903,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
||||
needed_fee = 0;
|
||||
|
||||
// while we have something to send
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
hwdev.set_signature_mode(hw::device::SIGNATURE_FAKE);
|
||||
hwdev.set_mode(hw::device::TRANSACTION_CREATE_FAKE);
|
||||
while (!unused_dust_indices.empty() || !unused_transfers_indices.empty()) {
|
||||
TX &tx = txes.back();
|
||||
|
||||
@@ -7956,7 +7989,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
|
||||
LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) <<
|
||||
" total fee, " << print_money(accumulated_change) << " total change");
|
||||
|
||||
hwdev.set_signature_mode(hw::device::SIGNATURE_REAL);
|
||||
hwdev.set_mode(hw::device::TRANSACTION_CREATE_REAL);
|
||||
for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i)
|
||||
{
|
||||
TX &tx = *i;
|
||||
|
||||
Reference in New Issue
Block a user