Handle sizeable push msat (fix #195) + handle two first per_commitment_point + keys interface tests#230
Conversation
|
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
| // They sign the "local" commitment transaction... | ||
| 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 |
|
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. |
TheBlueMatt
left a comment
There was a problem hiding this comment.
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.
| 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.
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.
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.
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.
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) |
|
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. |
|
PR good to a second review, tests should cover almost all keys interface spendable events ! |
| } | ||
| } | ||
| } | ||
| // TODO: We should use current_remote_commitment_number and the commitment number out of |
There was a problem hiding this comment.
What is the right merge strategy on this one ? If current_remote_commitment_number < our_commitment_number, we keep other data parts right ?
TheBlueMatt
left a comment
There was a problem hiding this comment.
This looks really good, sorry for the review delay!
src/ln/channelmanager.rs
Outdated
| } | ||
|
|
||
| macro_rules! check_dynamic_output { | ||
| ($event: expr, $event_idx: expr, $output_idx: expr, $value: expr) => { |
There was a problem hiding this comment.
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).
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.
Oops, SpendableOutputDescriptor needs the value so that you can sign for it without the TxOut.
There was a problem hiding this comment.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Will do, an enum should let us handle other type of script_pubkey latter.
There was a problem hiding this comment.
Ohoh, I meant a new top-level enum entry in SpendableOutputDescriptor. Also to_self_delay only needs to be in the P2WSH/RevokeableOutput entry.
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
|
Rebased, added AddressType to describe DynamicOutput as comment suggested. |
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
|
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.