-
Notifications
You must be signed in to change notification settings - Fork 411
Add util fn for creating a Transaction from spendable outputs #789
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 util fn for creating a Transaction from spendable outputs #789
Conversation
Codecov Report
@@ Coverage Diff @@
## main #789 +/- ##
==========================================
+ Coverage 90.75% 90.77% +0.01%
==========================================
Files 44 44
Lines 24075 24282 +207
==========================================
+ Hits 21849 22041 +192
- Misses 2226 2241 +15
Continue to review full report at Codecov.
|
lightning/src/chain/keysinterface.rs
Outdated
/// Information about a spendable output to a P2WSH script. See | ||
/// SpendableOutputDescriptor::DynamicOutputP2WSH for more details on how to spend this. | ||
#[derive(Clone, Debug, PartialEq)] | ||
pub struct DynamicP2WSHOutputDescriptor { |
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.
Probably not for this PR, but maybe this can be DelayedPaymentFromHolderOutput
and the one below can be StaticPaymentFromCounterpartyOutput
?
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.
Right, there are a few things in keysinterface that could use renaming, so maybe we can do it as a follow up - I'd like to rename ChanKeys
to ChannelSigner
(and a bunch of things downstream that use similar naming) as well.
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.
Went ahead and did this since Val had a further naming comment.
lightning/src/chain/keysinterface.rs
Outdated
/// script_pubkey as it appears in the output. | ||
/// An output to a script which was provided via KeysInterface directly, either from | ||
/// `get_destination_script()` or `get_shutdown_pubkey()`, thus you should already know how to | ||
/// spend it. No secret keys are provided as rust-lightning was never given any key. | ||
/// These may include outputs from a transaction punishing our counterparty or claiming an HTLC | ||
/// on-chain using the payment preimage or after it has timed out. | ||
StaticOutput { |
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.
it would be good to have the derivation path here (and maybe channel ID - see comment nearby), even if it's not used, just so that the user / KeysManager
implementation can keep track of which channel is being swept
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 this is really in #786. It would feel awkward to tie the scripts to a channel without moving the functions to get them to the ChannelSigner
? I dont really want to do that, though, as the current setup is great in that the KeysInterface
implementation is trivial and gives you direct control over all the entropy used and keys used directly (that aren't fixed by the lightning protocol), and the ChannelSigner
implementation is all about the lightning protocol details.
I guess we could maybe pass the channel information to the functions in KeysInterface
to get the fields as a middle ground, but ultimately a user probably would just want some kind of integer id to figure out what HD derivation path they used, not channel information, and I'm not really sure how to capture that easily.
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.
Oh, this wasn't about the scripts at all. It's about this struct (StaticOutput
), which is constructed in ChannelMonitor
when sweeping a payment to us. I'm just saying it would be good for the KeysManager
to know which channel is being swept for housekeeping / policy controls. ChannelMonitor
has the derivation ID handy, so it's easy to populate such a field in this struct.
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.
Right, it just felt awkward that we pass an id referencing the derivation id when the script/output itself isn't in any way related to a given derivation, the KeysManager
returns them directly. Best would be to pass in the derivation info to the keysmanager when we get those scripts, I think, but we don't have it yet at that point, afair.
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.
OK, there's no rush to get into this in this PR.
5adddfe
to
29d6c13
Compare
bfbcd4e
to
84bec9b
Compare
/// The output which is referenced by the given outpoint | ||
pub output: TxOut, | ||
/// The revocation_pubkey used to derive witnessScript | ||
pub revocation_pubkey: PublicKey, |
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.
isn't this available from ChannelKeys
, so doesn't need to be replicated here?
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.
No, this is the revocation point for the broadcast commitment transaction. I'll clarify the docs.
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.
Ah, we can't re-derive the revocation_pubkey
, because that would require the counterparty's revocation base, which we don't have because we rederived ChannelKeys
from scratch and therefore it doesn't have the counterparty's pubkeys.
However, we could still make it work if we looked up the populated ChannelKeys
instead of re-deriving them.
So this brings up the question - why are we using derive_channel_keys
instead of looking up the existing ChannelKeys
in some index?
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.
Right. Depending on the specific KeysInterface implementation we could look up a globally-cached remote public keys object. However we should try to be as implementation-agnostic as possible, so in this case I'm not sure it's ideal. We could provide the raw data to re-derive in the event, but I'm not sure what that protects against - if they even is bogus no funds loss can occur, the client may just create an invalid transaction.
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.
It's pretty minor, just felt a bit more "normalized" to provide just the minimum set of fields.
We previously counted 35 bytes for a length + public key, but in reality they are never larger than 34 bytes - 33 for the key and 1 for the push length.
Both SpendableOutputDescriptor::DynamicOutputP2WSH and SpendableOutputDescriptor::StaticOutputCounterpartyPayment are relevant only in the context of a given channel, making them candidates for being passed into helper functions in `InMemoryChannelKeys`. This moves them into their own structs so that they can later be used standalone.
e16b8dc
to
25a17d9
Compare
Rebased and squashed after dependent-PR merge with no other changes. |
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.
Super useful utility! Seems like a big win for users.
lightning/src/chain/keysinterface.rs
Outdated
/// Information about a spendable output to a P2WSH script. See | ||
/// SpendableOutputDescriptor::DynamicOutputP2WSH for more details on how to spend this. | ||
#[derive(Clone, Debug, PartialEq)] | ||
pub struct DynamicP2WSHOutputDescriptor { |
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: this could be renamed to be uniform to DynamicOutputP2WSH
: i.e., rename to DynamicOutputP2WSHDescriptor
(or vice versa)
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.
Did something more akin to devrandom's suggestion above #789 (comment)
KeyManager::new() took a bitcoin::Network parameter which needs to be passed to the BIP 32 Extended Key constructor, but because we never write out the BIP 32 serialization, it isn't used. Instead, we just pass a dummy value into `ExtendedPrivKey`, dropping the unused argument to KeysManager::new().
Previously, test_dynamic_spendable_outputs_local_htlc_success_tx called connect_block with two identical transactions, which resulted in duplicate SpendableOutputs Events back-to-back. This is a test issue as such a block_connected call represents an invalid block.
This adds a utility method, `KeysManager::spend_spendable_outputs`, which constructs a Transaction from a given set of `SpendableOutputDescriptor`s, deriving relevant keys as needed. It also adds methods which can sign individual inputs where channel-specific key derivation is required to `InMemoryChannelKeys`, making it easy to sign transaction inputs when a custom `KeysInterface` is used with `InMemoryChannelKeys`.
25a17d9
to
8dbadd1
Compare
Both Miron and Val suggested naming tweaks in their reviews, so clarifying things some would be good.
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.
New naming + typo fixes LGTM
Based on #786, This adds a utility method,
KeysManager::spend_spendable_outputs
,which constructs a Transaction from a given set of
SpendableOutputDescriptor
s, deriving relevant keys as needed.It also adds methods which can sign individual inputs where
channel-specific key derivation is required to
InMemoryChannelKeys
, making it easy to sign transaction inputswhen a custom
KeysInterface
is used withInMemoryChannelKeys
.