-
Notifications
You must be signed in to change notification settings - Fork 412
Handle sizeable push msat (fix #195) + handle two first per_commitment_point + keys interface tests #230
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
Handle sizeable push msat (fix #195) + handle two first per_commitment_point + keys interface tests #230
Conversation
fb533c2
to
01c9168
Compare
Rebased, add solution for #228 and new test which covered both the latter and also one of spendable_output event generation cases. |
src/ln/channel.rs
Outdated
secp_call!(self.secp_ctx.verify(&local_sighash, &sig, &self.their_funding_pubkey.unwrap()), "Invalid funding_created signature from peer", self.channel_id()); | ||
|
||
// ...and we sign it, allowing us ot broadcast the tx if we wish |
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.
nit: s/ot/to
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.
Fixed, and also some others nits
d3ed15d
to
92090bd
Compare
Rebased, implemented the generation of SpendableOutput event for to_remote_output on remote commitment tx, in both branches of check_spend_remote_transaction. I modified witness_script of DynamicOutput as Option, because in this case Script isn't a P2WSH but the secret key is still generate based on per_commitment_point. Still some tests lacking before to consider the PR complete. |
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.
Please limit your commits to having a short (no more than 80ish chars) title, followed by an empty line, then text that is also line-broken to 80ish chars.
@@ -1496,6 +1498,7 @@ impl Channel { | |||
return Err(ChannelError::Close("Peer sent a funding_locked at a strange time")); | |||
} | |||
|
|||
self.channel_monitor.provide_their_next_revocation_point(Some((INITIAL_COMMITMENT_NUMBER - 1 , msg.next_per_commitment_point))); |
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.
Hmm, I think this split may be simpler by just moving the their_next_revocation_point tracking into provide_latest_remote_commitment_tx_info. We only ever use the revocation point in case we have remote_tx_info available corresponding to it, so it should be way simpler to just move it there.
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.
Not sure for this one... firstly we get per_commitment_point from remote at time we don't/didn't have generate remote commitment tx (accept_channel/new_from_req/funding_locked) and secondly we may use revocation point to generate pubkeys without per_commitment_option (htlcs_outputs) in case of sizeable push_msat?
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.
Hmm? You mean you intend to add some use for their_cur_revocation_points beyond what its used for now, right now its only ever used in conjunction with remote_claimable_outpoints data.
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 exactly, see deacb3f, in case of to_remote ouput you don't need remote_claimable_outpoints but you still need per_commitment_point to derive your remoteprivatekey. If I get derivation scheme right, but please review it thoroughly, that's easy to mess this part
(side-note reviewing shutdown let me thought that maybe I should add a check_shutdown_tx in block_connected to generate spendable output for shutdown pubkey) |
92090bd
to
deacb3f
Compare
Rebased with corrections at deacb3f, noted for commits formatting. |
Added new tests, still more coming, for code hygiene will prune redundant test branches with macro and some others nits. |
9bebe2b
to
0ebdc9d
Compare
PR good to a second review, tests should cover almost all keys interface spendable events ! |
self.key_storage = other.key_storage; | ||
} | ||
} | ||
} | ||
// TODO: We should use current_remote_commitment_number and the commitment number out of |
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.
What is the right merge strategy on this one ? If current_remote_commitment_number < our_commitment_number, we keep other data parts right ?
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 looks really good, sorry for the review delay!
src/ln/channelmanager.rs
Outdated
@@ -7490,4 +7495,413 @@ mod tests { | |||
assert_eq!(msg.channel_id, channel_id); | |||
} else { panic!("Unexpected result"); } | |||
} | |||
|
|||
macro_rules! check_dynamic_output { | |||
($event: expr, $event_idx: expr, $output_idx: expr, $value: expr) => { |
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 like $event_idx is always 0 and $event always just has a vec of one or two of the same event. May be cleaner (and more restrictive on behavior) if you just pass in the Node and it can check that the only event(s) are identical SpendableOutputs events (would also simplify the callsites).
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 at 892690b
src/ln/channelmanager.rs
Outdated
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; | ||
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, 0); | ||
let events = nodes[1].chan_monitor.simple_monitor.get_and_clear_pending_events(); | ||
let spend_tx = check_dynamic_output!(events, 0, 0, node_txn[0].output[1].value); |
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.
Oops, SpendableOutputDescriptor needs the value so that you can sign for it without the TxOut.
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 arrived at the same conclusion, my bad, currently rebasing for it
/// back two descriptors, so even a false positive one for remote output to avoid watchtower mode | ||
/// learning channel balance. | ||
fn check_spend_closing_transaction(&self, tx: &Transaction, _height: u32) -> Vec<SpendableOutputDescriptor> { | ||
if tx.input[0].sequence == 0xFFFFFFFF && tx.input[0].witness.last().unwrap().len() == 71 { |
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.
Hmm, wont this match, like, everything? I think we should just say get_shutdown_pubkey() and get_destination_script()-returned scripts won't be provided out as SpendableOutputDescriptors.
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 think it's great to relieve users from any chain watching of LN kind of txs ? If not seems to me they have to implement some LN stuff to know it and it lessens keys interface out-of-box value. The other kind of tx which can spend the funding outpoint is commitment tx and the nSequence of their first input is set to an obfuscated commitment number so can't match I would say, but yes I can add heuristic rules by security.
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 mean they should already have logic for watching an output to a script they generated, the only reason to tell them about outputs is when there is other data mixed in.
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.
Aha yes make sense well if so I believe we can get ride of StaticOutputDescriptor (and its tests) ?
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.
Hmmmmm...that may be the case. Indeed, I guess if we can't provide all of them we might as well provide none of them and at least for this case providing an event for it seems...dubious? I suppose we could generate them completely by comparing this output to addresses we've seen, obviously so that only non-watchtowers can see them.
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.
In fact, checking against bolt, matching is sure (closing tx is the only spending_tx from funding with nSequence set to 0xFFFFFFFF). Don't know if you see my IRC comment but I think my point on offline wallet was irrelevant, detecting this case of output it's still a job handable by ChainWatchInterface if it got destination_script (and if user-provided one want to use a different format descriptor than our, we shouldn't force it to handle our crafted StaticOutputDescriptor). So yes I think that StaticOutputDescriptor can go, the only to reason to keep it could be a performance one (maybe easier to us to filter it, but you know better than me).
For privacy, a rogue watchtower still have the funding_txo and can spot when it spent no ?
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.
Ahh, there's the confusion. So I forgot about the funding input check in block_connected. You should only call check_spend_closing_transaction when the funding_txo is set, though. Still, false-positives in output events really sucks, maybe we can generate these events in Channel in closing_signed handling instead?
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.
So on the idea you're ok to keep StaticOutputDescriptor ?
So implemented with closing_signed as of 6fc8391, should avoid to false-positives due to non-definitive closing_signed message exchanged.
81a1c03
to
892690b
Compare
src/chain/keysinterface.rs
Outdated
/// localkey = payment_basepoint_secret + SHA256(per_commitment_point || payment_basepoint | ||
key: SecretKey, | ||
/// witness redeemScript encumbering output. If None script is a P2WPKH to build from key. | ||
witness_script: Option<Script>, |
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.
At the risk of piling on late in review, I think I'd kinda prefer if this were just a new enum entry? Its already an enum so its not like we're making handling that much more complicated on the user end, and it rather drastically changes the way you have to sign the transaction. What do you think?
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.
Will do, an enum should let us handle other type of script_pubkey latter.
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.
Ohoh, I meant a new top-level enum entry in SpendableOutputDescriptor. Also to_self_delay only needs to be in the P2WSH/RevokeableOutput entry.
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.
Updated
892690b
to
6fc8391
Compare
Goal to claim sizeable push_msat and in event of local commitment tx being broadcast without htlcs
Aims to cover both claiming of sizeable_push_msat and spendable output generation for to_local output
We needed it to be able to track remote_per_commitment_point after channel opening and funds locking
6fc8391
to
1485a85
Compare
Rebased, added AddressType to describe DynamicOutput as comment suggested. |
1485a85
to
1092e95
Compare
Aims to covered both keysinterace preimage tx case and detection of second remote commitment tx Split DynamicDescriptor between *P2WSH and *P2WKH
Aims to send back closing output descriptor to user wallet
Contrary to sizeable push_msat on local commitment tx, the output go to a P2WPKH
Cover both HTLC-Timeout/Success cases
Based on commitment_number
Cover both local HTLC-Timeout/Success case
1092e95
to
3a7b40e
Compare
Gonna merge this cause its waited long enough, but I have one bugfix and one cleanup to add on top that I'll PR in a sec. |
Thanks to have pointed to me #195, I think I spotted a case which wasn't covered by SpendableOuput event generation, to_local output on local commitment tx in broadcast_by_state.
Should fix #195, at funding_created, we sign local_commitment_tx and give it to both channel_manager and channel_monitor.