-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wallet: rescan bc with preserving key images #4889
Conversation
Does it have any advantage over f26ce08 ? |
(apart from the height setting) |
IMO this builds on top of that. It is soft (!hard) rescan_bc which on top of that preserves key images (KIs). KIs are sometimes difficult to get, e.g., on watch-only wallets, HW wallets. So after such KI import one needs to determine which were spent. Trusted node is required for this.
|
I mean, this can be useful after wallet restore (e.g. from a device or watch-only wallet). After restore one needs to check the spent status, this helps to avoid trusted node requirement. Its just an idea which might be implemented in somewhat more elegant way. |
Oh, I thought the other one kept key images, but it doesn't. Nevermind. |
I will change the PR a bit. I got an idea it can be the same rescan_bc call bust with different argument. |
actually... was soft reset meant to preserve key images? If yes this PR is not needed then, just a small change to soft reset. |
Doing it that way wlil break if the rescan actually changes m_transfers. |
Good point, if blockchain re-ogranizes then preserving key images would not work well (as mapping So for doing this correctly we maybe need to check if the "new" blockchain contains the last_block_hash at last_block_height? |
f631de3
to
9af64df
Compare
@moneromooo-monero you've sparked an idea of checking the My idea is to hash uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const;
|
Sounds dangerous. I'd rather do three steps:
That is safe and simple, and achieves what you wanted (have good spent state without asking the daemon). |
I am not sure I follow 100% 😕
Would this also work?
Still sounds like large code change. |
You are right, for a view wallet, you'd end up with unknown key images, so you'd have to keep an output-to-key image mapping too if doing it that way (not just txid, you could have several outs with the same txid). You can't hash m_transfers. It's not a POD type. |
True, I've missed that.
I had something reasonable in mind, like: for(const transfer_details & transfer : m_transfers)
keccak_update(&state, (const uint8_t *) transfer.m_txid.data, sizeof(transfer.m_txid.data)); Or |
Yes, but you'd also need other stuff, like output index. But that'd work I think. Just seems more complicated to me. If it's the opposite way for you, then go ahead :) |
afe3e90
to
69dfbe2
Compare
bba1df7
to
bce5ebf
Compare
So I've iterated to the current state:
|
That seems more complicated than necessary, and seems to not help in the case whre m_transfers is changed (which is the useful case). What I had in mind is this (untested): diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c08379514..ccb0333ff 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -5145,6 +5145,8 @@ void wallet2::rescan_spent() //---------------------------------------------------------------------------------------------------- void wallet2::rescan_blockchain(bool hard, bool refresh) { + std::unordered_map key_image_map; + if(hard) { clear(); @@ -5152,6 +5154,11 @@ void wallet2::rescan_blockchain(bool hard, bool refresh) } else { + // remember key images + for (const transfer_details &td: m_transfers) + if (td.m_key_image_known) + key_image_map[td.get_public_key()] = td.m_key_image; + m_blockchain.clear(); m_transfers.clear(); m_key_images.clear(); @@ -5167,6 +5174,19 @@ void wallet2::rescan_blockchain(bool hard, bool refresh) if (refresh) this->refresh(false); + + // restore unknown key images + for (size_t i = 0; i second;; + td.m_key_image_known = true; + m_key_images[it->second] = i; + } + } } //---------------------------------------------------------------------------------------------------- bool wallet2::is_transfer_unlocked(const transfer_details& td) constwhich is much simpler, and |
As I understood it, if IMO If just new transfers are added its still fine with my method (ordering of old ones and KIs stay same). If blockchain reorganizes then the key image import has to be performed again. Problem with I have an impression that "my" mechanism is relatively simple. The main idea is just to keep Where mine and your view deviates? :) Use-case: restore watch-only wallet, import key images, rescan_spent with untrusted node. |
There are more code changes as I've added the restore-height to the rescan_bc in the simplewallet + boilerplate for parameter processing (soft|hard|keep_ki). Besides that the patch is relatively small. |
Hmm I need a minute to think it trough |
bce5ebf
to
6e75b8b
Compare
6e75b8b
to
27343f1
Compare
m_transfers will usually change because of a bug. Reorgs are supposed to be handled without any manual input. |
Are you done ? Last comment says you'll think things through. |
Maybe a few more days? :) |
Sure. Whatever you need, I just wasn't sure if you were done :) |
27343f1
to
732a14a
Compare
Is this ready now ? |
I liked the idea this patch enables users to rescan_spent or import key images using untrusted daemon which may increase security as users just put I think this PR is kind of finished for me now, I could rebase if you guys are fine with the approach and you think the PR won't make wallet more fragile or prone to user errors. |
Well, I don't like the way it goes about it (the hashing), but the overall idea is OK I think :) |
Do you want to rebase it ? |
- enables to perform rescan_spent / ki sync with untrusted daemon. Spent check status involves RPC calls which require trusted daemon status as it leaks information. The new call performs soft reset while preserving key images thus a sequence: refresh, ki sync / import, rescan_bc keep_ki will correctly perform spent checking without need for trusted daemon. - useful to detect spent outputs with untrusted daemon on watch_only / multisig / hw-cold wallets after expensive key image sync. - cli: rescan_bc keep_ki
732a14a
to
f42263e
Compare
rebase finished |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed
f42263e wallet: adds rescan_bc option with preserving key images (Dusan Klinec)
Experimental feature. Prototype implementation (just an idea).
Enables to perform rescan_spent / key image import with an untrusted daemon. Spent check status involves RPC calls which require trusted daemon status as it leaks information (asks for particular key images being spent). The new call
rescan_bc_keep_ki
performs soft reset while preserving key images thus the following sequence of commands will correctly perform spent checking without need for trusted daemon:Useful to detect spent outputs (e.g., after restore) with untrusted daemon on watch_only / multisig / cold / hw-backed wallets after expensive key image sync. Downside: need to download the blockchain since restore height.
Usage:
rescan_bc keep_ki [restore_height]
. Restore height defaults to 0. Ideally you wan't to perform restore from the height your wallet was generated, therefresh-from-block-height
. This variable is printed byset
command.rescan_bc hard [restore_height]
rescan_bc soft [restore_height]