-
Notifications
You must be signed in to change notification settings - Fork 412
Add pruning of preimages no longer needed + tests #32
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
Add pruning of preimages no longer needed + tests #32
Conversation
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.
Awesome! Thanks so much for going after this TODO!a
src/ln/channelmonitor.rs
Outdated
pruned_payment_preimages.insert(k, v); | ||
} | ||
} | ||
for (_tx, htlcs) in &self.remote_claimable_outpoints { |
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.
This seems like its gonna be a pretty large chunk of runtime, but also overkill. Can we effeciently skip remote outpoints that are already revoked somehow, cause we shouldn't need those preimages either, we can use the revocation key.
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.
Outpoint is considered as revoked when we get its per_commitment_secret. At pruning, we need to check that its commitment number is superior at get_min_secret(), but how do we get this commitment number without input sequence and lock_time of the given outpoint, it's only place where it's stored.
Will inquiry more tomorrow to find a map between txid:commitment number, correct me if I'm wrong.
src/ln/channelmonitor.rs
Outdated
// that non-revoked remote commitment tx(n) do not need it, and our latest local commitment | ||
// tx does not need it. | ||
|
||
let mut pruned_payment_preimages = HashMap::with_capacity(self.payment_preimages.capacity()); |
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.
Can you use self.payment_preimages.retain instead of creating a new map and drain()ing the old one? Should be a bit less overhead to doing it that way.
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.
Should be fine
src/ln/channelmonitor.rs
Outdated
Ok(()) | ||
} | ||
|
||
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.
Note you have some trailing whitespace in a few places.
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.
Yes, configured my vim extension accordingly
src/ln/channelmonitor.rs
Outdated
|
||
let mut pruned_payment_preimages = HashMap::with_capacity(self.payment_preimages.capacity()); | ||
for (k, v) in self.payment_preimages.drain() { | ||
for (htlc, _s1, _s2) in &self.current_local_signed_commitment_tx.as_ref().expect("Channel need at least an initial commitment tx !").htlc_outputs { |
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.
This needs to be for &(ref htlc... to make it compile on older rustcs. See travis failure on 1.22.
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.
Compiled with 1.22, got it
e76bcd2
to
6e307c6
Compare
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.
Looks good, thanks, though didn't review the tests in detail (a comment or two describing whats going on would be nice).
src/ln/channelmonitor.rs
Outdated
} | ||
for (_tx, htlcs) in remote_claimable_outpoints { | ||
for htlc in htlcs { | ||
if k == htlc.payment_hash { |
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.
Still kinda worried about the potential performance issue here, especially for watchtowers.
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.
I'd think the way to go here would be some kind of simple caching of the set of unrevoked remote outpoints. I think technically there should only ever be one, but I think channel resumption may break that so lets not assume it. Still, that means having a Vec of the txids and their commitment number (which we know when we call provide_latest_remote_commitment_tx_info, either by calculating it or just making channel pass it in, which may be simpler) should be really cheap.
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.
Yes, I wrote that but not so simple, for a given outpoint (txid, commitment number) you have a set of hash. But how do you map hash to the outpoint without browsing its HTLCs ? You need to cache the binding somewhere, so I was thinking more to a hashmap <payment_hash,commitment number> still generate at provide_latest_remote_commitment_tx_info. That's a dup of data into ChannelMonitor, but will improve performance because you scan htlcs once. Will write that.
src/ln/channelmonitor.rs
Outdated
let local_signed_commitment_tx = &self.current_local_signed_commitment_tx; | ||
let remote_claimable_outpoints = &self.remote_claimable_outpoints; | ||
self.payment_preimages.retain(|&k, _| { | ||
for &(ref htlc, _s1, _s2) in &local_signed_commitment_tx.as_ref().expect("Channel needs at least an initial commitment tx !").htlc_outputs { |
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.
Can you document this precondition in the function's documentation?
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.
Done, also comments for tests
src/ln/channelmonitor.rs
Outdated
} | ||
for (_tx, htlcs) in remote_claimable_outpoints { | ||
for htlc in htlcs { | ||
if k == htlc.payment_hash { |
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.
I'd think the way to go here would be some kind of simple caching of the set of unrevoked remote outpoints. I think technically there should only ever be one, but I think channel resumption may break that so lets not assume it. Still, that means having a Vec of the txids and their commitment number (which we know when we call provide_latest_remote_commitment_tx_info, either by calculating it or just making channel pass it in, which may be simpler) should be really cheap.
6e307c6
to
ef16642
Compare
Change the logic for handling of remote_outpoints, with caching of hash:commitment number at provide_latest_remote_commitment_tx_info. At pruning, if hash belongs to tx non-revoked, keep it, else skip it. Should be more efficient at price of hodling more data. |
Merging, but I've got a few changes I'll make afterwards myself. |
…ip-change-check Drop unused change output calculation
No description provided.