-
Notifications
You must be signed in to change notification settings - Fork 378
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
Let ChannelSigner
set and spend LN scriptpubkeys
#3512
base: main
Are you sure you want to change the base?
Conversation
508d577
to
5b57776
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3512 +/- ##
==========================================
+ Coverage 88.42% 88.81% +0.39%
==========================================
Files 149 149
Lines 112959 115657 +2698
Branches 112959 115657 +2698
==========================================
+ Hits 99883 102723 +2840
+ Misses 10605 10497 -108
+ Partials 2471 2437 -34 ☔ View full report in Codecov by Sentry. |
1547436
to
72b317e
Compare
This allows the `to_remote` output to easily be changed according to the features of the channel, or the evolution of the LN specification. `to_remote` could even be set to completely arbitrary scripts if compatibility with the formal LN spec is not required.
This allows the `to_local` output to easily be changed according to the features of the channel, or the evolution of the LN specification. `to_local` could even be set to completely arbitrary scripts if compatibility with the formal LN spec is not required.
This allows the htlc tx output to easily be changed according to the features of the channel, or the evolution of the LN specification. The output could even be set to completely arbitrary scripts if compatibility with the formal LN spec is not required. Builders of htlc transactions now ask a `ChannelSigner` for the appropriate revokeable script pubkey to use, and then pass it to the htlc transaction constructors.
All LN-Penalty channel signers need to be able to punish the counterparty in case they broadcast an old state. In this commit, we ask implementers of `ChannelSigner` to produce the full transaction with the given input finalized to punish the corresponding previous output. Consumers of the `ChannelSigner` trait can now be agnostic to the specific scripts used in revokeable outputs. We leave passing to the `ChannelSigner` all the previous `TxOut`'s needed to produce valid schnorr signatures under BIP 341 spending rules to a later patch.
for the revokeable scripts in the `to_local` and the htlc tx outputs.
All LN-Penalty channel signers need to be able to punish the counterparty in case they broadcast an old state. In this commit, we ask implementers of `ChannelSigner` to produce the full transaction with the given input finalized to punish the corresponding previous output. Consumers of the `ChannelSigner` trait can now be agnostic to the specific scripts used in HTLC outputs of commitment transactions. We leave passing to the `ChannelSigner` all the previous `TxOut`'s needed to produce valid schnorr signatures under BIP 341 spending rules to a later patch.
8000729
to
8a20905
Compare
8a20905
to
5fc079b
Compare
/// | ||
/// If `is_holder_tx` is set, return the `to_remote` script pubkey for the local party's commitment | ||
/// transaction, otherwise, for the remote party's. | ||
fn get_counterparty_payment_script(&self, is_holder_tx: bool) -> ScriptBuf { |
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.
Just returning the scripts for each position in the commitment transaction is cool, but I don't think it would allow someone to have, for example, a dual-normal-DLC channel. Rather, it would be nice if all of build_commitment_transaction
were the interface, tell the "signer" what the HTLCs are and let them build the whole transaction.
It may require a bit more work as we'll need to include additional metadata in the transaction object returned (which output is to_remote
/to_local
/each HTLC), but the ultimate result would be fewer API calls across the trait, a simpler API and more flexibility.
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.
thanks for the review Matt - overall I agree, I'm researching this direction now.
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.
@TheBlueMatt regarding this additional metadata:
- right now we already have additional metadata returned, the
Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>
for each HTLC included in the commit tx built withbuild_commitment_transaction
. - this additional metadata travels to the corresponding
ChannelMonitor
viaChannelMonitorUpdate
s and gets stored incounterparty_claimable_outpoints: HashMap<Txid, Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>>
- When a counterparty commit tx falls onchain, we read that hashmap, and include that metadata in the
PackageTemplate
s built, and thesePackageTemplates
are given to theOnchainTxHandler
.
On the other hand for the to_local
output of commitment transaction
- In this PR, the
ChannelMonitor
does a roundtrip to the signer to ask it for the expectedto_local
script pubkey in that commitment transaction, then iterates over the outputs of the broadcasted transaction to identify theto_local
output. The output is then passed to either aRevokedOutput
PackageTemplate
orDelayedPaymentOutputDescriptor
depending on the case.
Question:
- do we keep a single
build_commitment_transaction
call inchannel
, and then pass the data over to theChannelMonitor
via the updates, like is done now for HTLC outputs? In that case it seems we'd need to extend the updates and the state of theChannelMonitor
to includeto_local
outputs. - or do we call
build_commitment_transaction
again inChannelMonitor
to get the data needed to identify theto_local
output.
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 have a rough draft that implements the first path - send to_local
output metadata via channel updates.
I am not thrilled about storing all the counterparty to_local
outputs in the ChannelMonitor
state. EDIT: we could store a mapping of the txid to the index of the to_local
output in that commitment transaction.
But asking the signer to build the entire commitment transaction again seems repetitive (ie didn't I already give it to you?). Naively, we'd grab the HTLC metadata on the call in channel
, and the to_local
metadata in the second call in ChannelMonitor
. We'd have to find a way to consolidate metadata collection for the ChannelMonitor
in a single spot.
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.
but the ultimate result would be fewer API calls across the trait, a simpler API and more flexibility.
- I was hoping that with the
Provided Methods
we don't actually increase the number of methods most users would have to implement - justget_channel_parameters
andget_channel_value_satoshis
. Then people can override only the methods they require. - If we require additional outputs, with this current approach I was thinking of introducing one more call that returns a collection of these additional
TxOut
s. It would be aProvided Method
that returnsNone
/ empty collection by default. - I still have to figure out how to offer the ability to set the locktime, and sequence fields of various transactions - definitely asking "signers" to build entire transactions would help in that regard.
…script For a given commitment number, all revokeable outputs of HTLC transactions have the same script pubkey. If we know the secret for that commitment number, any outputs with that script pubkey are `RevokedOutput`s. This patch removes any checks on the input at the index of the revoked output, as these are not necessary.
@TheBlueMatt the very last commit here 22c9a5c implements a a provided method - people who want custom stuff override, and people who want to stick to LN spec leave that alone. |
This PR allows the customization of different outputs of the commitment transaction, in preparation for taproot channels and also to allow people to set the outputs to arbitrary scripts if they don't require compatibility with the formal LN spec.
My approach is to ask the channel signers to do more work (but not more than that of most hardware wallets):
EcdsaChannelSigner
would return just the signature.This PR:
SpendableOutputDescriptor::to_psbt_input
andSpendableOutputDescriptor::create_spendable_outputs_psbt
assume scripts from the LN specification are used.I mark it as draft. I understand this is a huge PR. I hope to show the full picture of how the current approach works to get approach ACKs, then happy to break it down into smaller PRs.
Remaining TODOs:
SpendableOutputDescriptor
to accomodate taproot / arbitrary scripts.EcdsaChannelSigner
vsChannelSigner
APIs.ChannelSigner
to return just the witness that finalizes the given input, instead of returning the full transaction with the given input finalized.ChannelSigner
inline with the LN spec. One possible route: have theChannelSigner
trait offer "ProvidedMethods" for implementers who want to stay in-line with the LN specification - people who want to depart from the spec would then override these methods.FundedChannel
will work given a customized commitment transaction.bitcoin::sighash::Prevouts
of the transaction that the input is spending.to_remote
output switching back from P2WSH to P2WPKH in a TRUC world where we drop the 1 block CSV locktime on that output.CommitmentTransaction
vsTrustedCommitmentTransaction
?Supersedes #3454