Skip to content

Commit 2e6520d

Browse files
committed
Get multisig working pre-FCMP++/Carrot fork
Reuse the background sync cache for multisig sync, so that upon importing multisig info, the wallet doesn't need to rescan the chain and instead can just process the background cache.
1 parent aaac8a6 commit 2e6520d

2 files changed

Lines changed: 47 additions & 36 deletions

File tree

src/fcmp_pp/tree_cache.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ template<typename C1, typename C2>
739739
bool TreeCache<C1, C2>::register_output(const OutputPair &output)
740740
{
741741
auto output_ref_hash = get_output_ref_hash(output);
742-
CHECK_AND_ASSERT_MES(m_registered_outputs.find(output_ref_hash) == m_registered_outputs.end(), false,
742+
CHECK_AND_NO_ASSERT_MES_L1(m_registered_outputs.find(output_ref_hash) == m_registered_outputs.end(), false,
743743
"output is already registered");
744744

745745
// Add to registered outputs container

src/wallet/wallet2.cpp

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,7 +2646,8 @@ void wallet2::process_new_scanned_transaction(
26462646
continue;
26472647
const cryptonote::txin_to_key &in_to_key = boost::get<cryptonote::txin_to_key>(in);
26482648
auto it = m_key_images.find(in_to_key.k_image);
2649-
if(it != m_key_images.end())
2649+
const bool key_image_known = it != m_key_images.end();
2650+
if(key_image_known)
26502651
{
26512652
transfer_details& td = m_transfers[it->second];
26522653
uint64_t amount = in_to_key.amount;
@@ -2683,7 +2684,9 @@ void wallet2::process_new_scanned_transaction(
26832684
}
26842685
}
26852686

2686-
if (!pool && (m_track_uses || (m_background_syncing && it == m_key_images.end())))
2687+
const bool check_if_possibly_spent = !pool && (m_track_uses ||
2688+
(!key_image_known && (m_background_syncing || m_multisig)));
2689+
if (check_if_possibly_spent)
26872690
{
26882691
const uint64_t amount = in_to_key.amount;
26892692
std::vector<uint64_t> offsets = cryptonote::relative_output_offsets_to_absolute(in_to_key.key_offsets);
@@ -2709,12 +2712,12 @@ void wallet2::process_new_scanned_transaction(
27092712
const bool possibly_involved_with_tx = received_an_output || recognized_owned_possibly_spent_enote;
27102713
const bool should_cache_bg_tx = possibly_involved_with_tx
27112714
&& !pool
2712-
&& m_background_syncing
2715+
&& (m_background_syncing || m_multisig)
27132716
&& !m_background_sync_data.txs.count(txid);
27142717
if (should_cache_bg_tx)
27152718
{
2716-
// we're going to re-process this receive when background sync is disabled
2717-
if (m_background_syncing && m_background_sync_data.txs.find(txid) == m_background_sync_data.txs.end())
2719+
// we're going to re-process this tx when we can generate the key images for receives
2720+
if (m_background_sync_data.txs.find(txid) == m_background_sync_data.txs.end())
27182721
{
27192722
size_t bgs_idx = m_background_sync_data.txs.size();
27202723
background_synced_tx_t bgs_tx = {
@@ -2725,7 +2728,7 @@ void wallet2::process_new_scanned_transaction(
27252728
.block_timestamp = ts,
27262729
.double_spend_seen = double_spend_seen
27272730
};
2728-
LOG_PRINT_L2("Adding received tx " << txid << " to background sync data (idx=" << bgs_idx << ")");
2731+
LOG_PRINT_L2("Adding tx " << txid << " to background sync data (idx=" << bgs_idx << ")");
27292732
m_background_sync_data.txs.insert({txid, std::move(bgs_tx)});
27302733
}
27312734
}
@@ -4564,7 +4567,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
45644567
}
45654568

45664569
m_first_refresh_done = true;
4567-
if (m_background_syncing || m_is_background_wallet)
4570+
if (m_background_syncing || m_is_background_wallet || m_multisig)
45684571
m_background_sync_data.first_refresh_done = true;
45694572

45704573
m_multisig_rescan_info = std::vector<std::vector<tools::wallet2::multisig_info>>{};
@@ -5957,6 +5960,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
59575960

59585961
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
59595962
setup_new_blockchain();
5963+
reset_background_sync_data(m_background_sync_data);
59605964

59615965
if (!wallet_.empty())
59625966
store();
@@ -6289,6 +6293,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
62896293
this->create_keys_file(m_wallet_file, false, password, boost::filesystem::exists(m_wallet_file + ".address.txt"));
62906294

62916295
this->setup_new_blockchain();
6296+
this->reset_background_sync_data(m_background_sync_data);
62926297

62936298
if (!m_wallet_file.empty())
62946299
this->store();
@@ -6518,7 +6523,7 @@ void wallet2::rewrite(const std::string& wallet_name, const epee::wipeable_strin
65186523
store_background_keys(m_custom_background_key.get());
65196524
store_background_cache(m_custom_background_key.get(), true/*do_reset_background_sync_data*/);
65206525
}
6521-
else if (m_background_sync_type == BackgroundSyncReusePassword)
6526+
else if (m_background_sync_type == BackgroundSyncReusePassword || m_multisig)
65226527
{
65236528
reset_background_sync_data(m_background_sync_data);
65246529
}
@@ -6860,8 +6865,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
68606865

68616866
try
68626867
{
6863-
if (use_fs)
6864-
process_background_cache_on_open();
6868+
process_background_cache_on_open();
68656869
}
68666870
catch (const std::exception &e)
68676871
{
@@ -6992,6 +6996,12 @@ void wallet2::load_wallet_cache(const bool use_fs, const std::string& cache_buf)
69926996
//----------------------------------------------------------------------------------------------------
69936997
void wallet2::process_background_cache_on_open()
69946998
{
6999+
if (m_multisig)
7000+
{
7001+
if (!m_background_sync_data.first_refresh_done)
7002+
reset_background_sync_data(m_background_sync_data);
7003+
return;
7004+
}
69957005
if (m_wallet_file.empty())
69967006
return;
69977007
if (m_background_syncing || m_is_background_wallet)
@@ -8453,13 +8463,11 @@ bool wallet2::parse_multisig_tx_from_str(std::string multisig_tx_st, multisig_tx
84538463
// sanity checks
84548464
for (const auto &ptx: exported_txs.m_ptx)
84558465
{
8456-
CHECK_AND_ASSERT_MES(ptx.selected_transfers.size() == ptx.tx.vin.size(), false, "Mismatched selected_transfers/vin sizes");
8457-
for (size_t idx: ptx.selected_transfers)
8458-
CHECK_AND_ASSERT_MES(idx < m_transfers.size(), false, "Transfer index out of range");
8459-
CHECK_AND_ASSERT_MES(get_construction_data(ptx).selected_transfers.size() == ptx.tx.vin.size(), false, "Mismatched cd selected_transfers/vin sizes");
8460-
for (size_t idx: get_construction_data(ptx).selected_transfers)
8466+
const tools::wallet2::tx_construction_data &sd = get_construction_data(ptx);
8467+
CHECK_AND_ASSERT_MES(sd.selected_transfers.size() == ptx.tx.vin.size(), false, "Mismatched cd selected_transfers/vin sizes");
8468+
for (size_t idx: sd.selected_transfers)
84618469
CHECK_AND_ASSERT_MES(idx < m_transfers.size(), false, "Transfer index out of range");
8462-
CHECK_AND_ASSERT_MES(get_construction_data(ptx).sources.size() == ptx.tx.vin.size(), false, "Mismatched sources/vin sizes");
8470+
CHECK_AND_ASSERT_MES(sd.sources.size() == ptx.tx.vin.size(), false, "Mismatched sources/vin sizes");
84638471
}
84648472

84658473
return true;
@@ -14017,7 +14025,7 @@ void wallet2::process_background_cache(const background_sync_data_t &background_
1401714025
m_processing_background_cache = false;
1401814026
});
1401914027

14020-
if (m_background_syncing || m_multisig || m_watch_only || key_on_device())
14028+
if (m_background_syncing || m_watch_only || key_on_device())
1402114029
return;
1402214030

1402314031
if (!background_sync_data.first_refresh_done)
@@ -15066,32 +15074,35 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs)
1506615074
std::sort(m_multisig_rescan_info.begin(), m_multisig_rescan_info.end(), [](const std::vector<tools::wallet2::multisig_info> &i0, const std::vector<tools::wallet2::multisig_info> &i1){ return memcmp(&i0[0].m_signer, &i1[0].m_signer, sizeof(i0[0].m_signer)) < 0; });
1506715075
}
1506815076

15069-
// first pass to determine where to detach the blockchain
15070-
for (size_t n = 0; n < n_outputs; ++n)
15077+
for (size_t n = 0; n < n_outputs && n < m_transfers.size(); ++n)
1507115078
{
15072-
const transfer_details &td = m_transfers[n];
15073-
if (!td.m_key_image_partial)
15079+
update_multisig_rescan_info(m_multisig_rescan_k, m_multisig_rescan_info, n);
15080+
}
15081+
15082+
// The background cache should have all txs saved which need to be rescanned, including potential spends. We process
15083+
// the background cache with multisig info loaded.
15084+
const background_sync_data_t background_sync_data = m_background_sync_data;
15085+
const hashchain blockchain = m_blockchain;
15086+
const TreeCacheV1 tree_cache = m_tree_cache;
15087+
process_background_cache(background_sync_data, blockchain, m_last_block_reward, tree_cache);
15088+
15089+
// Once all key images are known and we've processed the background cache, any txs present in the background
15090+
// cache are no longer useful to us. They've been processed, we can remove them.
15091+
bool all_kis_known = true;
15092+
for (const auto &td : m_transfers)
15093+
{
15094+
if (td.m_key_image_known)
1507415095
continue;
15075-
// FIXME: if we need to pop more blocks from the tree cache than the reorg depth, and the wallet has received
15076-
// outputs from before the detach height, then the wallet won't be able to correct those prior output paths.
15077-
// Some solutions:
15078-
// A) restart sync from the wallet's first received output height.
15079-
// B) re-request output paths from the daemon.
15080-
// C) multisig wallet should stop syncing upon identifying a receive.
15081-
MINFO("Multisig info importing from block height " << td.m_block_height);
15082-
auto output_tracker_cache = create_output_tracker_cache();
15083-
handle_reorg(td.m_block_height, output_tracker_cache);
15096+
all_kis_known = false;
1508415097
break;
1508515098
}
1508615099

15087-
for (size_t n = 0; n < n_outputs && n < m_transfers.size(); ++n)
15100+
if (all_kis_known)
1508815101
{
15089-
update_multisig_rescan_info(m_multisig_rescan_k, m_multisig_rescan_info, n);
15102+
MDEBUG("All key images are known, clearing background sync data since we don't need it anymore");
15103+
reset_background_sync_data(m_background_sync_data);
1509015104
}
1509115105

15092-
15093-
refresh(false);
15094-
1509515106
return n_outputs;
1509615107
}
1509715108
//----------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)