Skip to content

Commit 27db6ba

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 68ca74f commit 27db6ba

File tree

2 files changed

+47
-36
lines changed

2 files changed

+47
-36
lines changed

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
@@ -2645,7 +2645,8 @@ void wallet2::process_new_scanned_transaction(
26452645
continue;
26462646
const cryptonote::txin_to_key &in_to_key = boost::get<cryptonote::txin_to_key>(in);
26472647
auto it = m_key_images.find(in_to_key.k_image);
2648-
if(it != m_key_images.end())
2648+
const bool key_image_known = it != m_key_images.end();
2649+
if(key_image_known)
26492650
{
26502651
transfer_details& td = m_transfers[it->second];
26512652
uint64_t amount = in_to_key.amount;
@@ -2682,7 +2683,9 @@ void wallet2::process_new_scanned_transaction(
26822683
}
26832684
}
26842685

2685-
if (!pool && (m_track_uses || (m_background_syncing && it == m_key_images.end())))
2686+
const bool check_if_possibly_spent = !pool && (m_track_uses ||
2687+
(!key_image_known && (m_background_syncing || m_multisig)));
2688+
if (check_if_possibly_spent)
26862689
{
26872690
const uint64_t amount = in_to_key.amount;
26882691
std::vector<uint64_t> offsets = cryptonote::relative_output_offsets_to_absolute(in_to_key.key_offsets);
@@ -2708,12 +2711,12 @@ void wallet2::process_new_scanned_transaction(
27082711
const bool possibly_involved_with_tx = received_an_output || recognized_owned_possibly_spent_enote;
27092712
const bool should_cache_bg_tx = possibly_involved_with_tx
27102713
&& !pool
2711-
&& m_background_syncing
2714+
&& (m_background_syncing || m_multisig)
27122715
&& !m_background_sync_data.txs.count(txid);
27132716
if (should_cache_bg_tx)
27142717
{
2715-
// we're going to re-process this receive when background sync is disabled
2716-
if (m_background_syncing && m_background_sync_data.txs.find(txid) == m_background_sync_data.txs.end())
2718+
// we're going to re-process this tx when we can generate the key images for receives
2719+
if (m_background_sync_data.txs.find(txid) == m_background_sync_data.txs.end())
27172720
{
27182721
size_t bgs_idx = m_background_sync_data.txs.size();
27192722
background_synced_tx_t bgs_tx = {
@@ -2724,7 +2727,7 @@ void wallet2::process_new_scanned_transaction(
27242727
.block_timestamp = ts,
27252728
.double_spend_seen = double_spend_seen
27262729
};
2727-
LOG_PRINT_L2("Adding received tx " << txid << " to background sync data (idx=" << bgs_idx << ")");
2730+
LOG_PRINT_L2("Adding tx " << txid << " to background sync data (idx=" << bgs_idx << ")");
27282731
m_background_sync_data.txs.insert({txid, std::move(bgs_tx)});
27292732
}
27302733
}
@@ -4546,7 +4549,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
45464549
}
45474550

45484551
m_first_refresh_done = true;
4549-
if (m_background_syncing || m_is_background_wallet)
4552+
if (m_background_syncing || m_is_background_wallet || m_multisig)
45504553
m_background_sync_data.first_refresh_done = true;
45514554

45524555
m_multisig_rescan_info = std::vector<std::vector<tools::wallet2::multisig_info>>{};
@@ -5939,6 +5942,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
59395942

59405943
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
59415944
setup_new_blockchain();
5945+
reset_background_sync_data(m_background_sync_data);
59425946

59435947
if (!wallet_.empty())
59445948
store();
@@ -6271,6 +6275,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
62716275
this->create_keys_file(m_wallet_file, false, password, boost::filesystem::exists(m_wallet_file + ".address.txt"));
62726276

62736277
this->setup_new_blockchain();
6278+
this->reset_background_sync_data(m_background_sync_data);
62746279

62756280
if (!m_wallet_file.empty())
62766281
this->store();
@@ -6500,7 +6505,7 @@ void wallet2::rewrite(const std::string& wallet_name, const epee::wipeable_strin
65006505
store_background_keys(m_custom_background_key.get());
65016506
store_background_cache(m_custom_background_key.get(), true/*do_reset_background_sync_data*/);
65026507
}
6503-
else if (m_background_sync_type == BackgroundSyncReusePassword)
6508+
else if (m_background_sync_type == BackgroundSyncReusePassword || m_multisig)
65046509
{
65056510
reset_background_sync_data(m_background_sync_data);
65066511
}
@@ -6842,8 +6847,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
68426847

68436848
try
68446849
{
6845-
if (use_fs)
6846-
process_background_cache_on_open();
6850+
process_background_cache_on_open();
68476851
}
68486852
catch (const std::exception &e)
68496853
{
@@ -6974,6 +6978,12 @@ void wallet2::load_wallet_cache(const bool use_fs, const std::string& cache_buf)
69746978
//----------------------------------------------------------------------------------------------------
69756979
void wallet2::process_background_cache_on_open()
69766980
{
6981+
if (m_multisig)
6982+
{
6983+
if (!m_background_sync_data.first_refresh_done)
6984+
reset_background_sync_data(m_background_sync_data);
6985+
return;
6986+
}
69776987
if (m_wallet_file.empty())
69786988
return;
69796989
if (m_background_syncing || m_is_background_wallet)
@@ -8435,13 +8445,11 @@ bool wallet2::parse_multisig_tx_from_str(std::string multisig_tx_st, multisig_tx
84358445
// sanity checks
84368446
for (const auto &ptx: exported_txs.m_ptx)
84378447
{
8438-
CHECK_AND_ASSERT_MES(ptx.selected_transfers.size() == ptx.tx.vin.size(), false, "Mismatched selected_transfers/vin sizes");
8439-
for (size_t idx: ptx.selected_transfers)
8440-
CHECK_AND_ASSERT_MES(idx < m_transfers.size(), false, "Transfer index out of range");
8441-
CHECK_AND_ASSERT_MES(get_construction_data(ptx).selected_transfers.size() == ptx.tx.vin.size(), false, "Mismatched cd selected_transfers/vin sizes");
8442-
for (size_t idx: get_construction_data(ptx).selected_transfers)
8448+
const tools::wallet2::tx_construction_data &sd = get_construction_data(ptx);
8449+
CHECK_AND_ASSERT_MES(sd.selected_transfers.size() == ptx.tx.vin.size(), false, "Mismatched cd selected_transfers/vin sizes");
8450+
for (size_t idx: sd.selected_transfers)
84438451
CHECK_AND_ASSERT_MES(idx < m_transfers.size(), false, "Transfer index out of range");
8444-
CHECK_AND_ASSERT_MES(get_construction_data(ptx).sources.size() == ptx.tx.vin.size(), false, "Mismatched sources/vin sizes");
8452+
CHECK_AND_ASSERT_MES(sd.sources.size() == ptx.tx.vin.size(), false, "Mismatched sources/vin sizes");
84458453
}
84468454

84478455
return true;
@@ -13983,7 +13991,7 @@ void wallet2::process_background_cache(const background_sync_data_t &background_
1398313991
m_processing_background_cache = false;
1398413992
});
1398513993

13986-
if (m_background_syncing || m_multisig || m_watch_only || key_on_device())
13994+
if (m_background_syncing || m_watch_only || key_on_device())
1398713995
return;
1398813996

1398913997
if (!background_sync_data.first_refresh_done)
@@ -15032,32 +15040,35 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs)
1503215040
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; });
1503315041
}
1503415042

15035-
// first pass to determine where to detach the blockchain
15036-
for (size_t n = 0; n < n_outputs; ++n)
15043+
for (size_t n = 0; n < n_outputs && n < m_transfers.size(); ++n)
1503715044
{
15038-
const transfer_details &td = m_transfers[n];
15039-
if (!td.m_key_image_partial)
15045+
update_multisig_rescan_info(m_multisig_rescan_k, m_multisig_rescan_info, n);
15046+
}
15047+
15048+
// The background cache should have all txs saved which need to be rescanned, including potential spends. We process
15049+
// the background cache with multisig info loaded.
15050+
const background_sync_data_t background_sync_data = m_background_sync_data;
15051+
const hashchain blockchain = m_blockchain;
15052+
const TreeCacheV1 tree_cache = m_tree_cache;
15053+
process_background_cache(background_sync_data, blockchain, m_last_block_reward, tree_cache);
15054+
15055+
// Once all key images are known and we've processed the background cache, any txs present in the background
15056+
// cache are no longer useful to us. They've been processed, we can remove them.
15057+
bool all_kis_known = true;
15058+
for (const auto &td : m_transfers)
15059+
{
15060+
if (td.m_key_image_known)
1504015061
continue;
15041-
// FIXME: if we need to pop more blocks from the tree cache than the reorg depth, and the wallet has received
15042-
// outputs from before the detach height, then the wallet won't be able to correct those prior output paths.
15043-
// Some solutions:
15044-
// A) restart sync from the wallet's first received output height.
15045-
// B) re-request output paths from the daemon.
15046-
// C) multisig wallet should stop syncing upon identifying a receive.
15047-
MINFO("Multisig info importing from block height " << td.m_block_height);
15048-
auto output_tracker_cache = create_output_tracker_cache();
15049-
handle_reorg(td.m_block_height, output_tracker_cache);
15062+
all_kis_known = false;
1505015063
break;
1505115064
}
1505215065

15053-
for (size_t n = 0; n < n_outputs && n < m_transfers.size(); ++n)
15066+
if (all_kis_known)
1505415067
{
15055-
update_multisig_rescan_info(m_multisig_rescan_k, m_multisig_rescan_info, n);
15068+
MDEBUG("All key images are known, clearing background sync data since we don't need it anymore");
15069+
reset_background_sync_data(m_background_sync_data);
1505615070
}
1505715071

15058-
15059-
refresh(false);
15060-
1506115072
return n_outputs;
1506215073
}
1506315074
//----------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)