-
Notifications
You must be signed in to change notification settings - Fork 385
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
Re-derive signers instead of persisting them #1867
Re-derive signers instead of persisting them #1867
Conversation
Codecov ReportBase: 90.69% // Head: 90.54% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #1867 +/- ##
==========================================
- Coverage 90.69% 90.54% -0.15%
==========================================
Files 91 91
Lines 48408 48401 -7
Branches 48408 48401 -7
==========================================
- Hits 43902 43825 -77
- Misses 4506 4576 +70
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
f139370
to
5defb92
Compare
Pushed a new update that allows downgrading and replaces |
Hmmmmm, now that I think about it we really need to pass the |
Hm, yeah, I can see how that can be helpful, though imo that's only necessary prior to a channel_keys_id existing to identify the channel. Perhaps the derive method should take an enum of either a user_channel_id or a channel_keys_id? |
Right, if we want a single derive method we'd probably want to do that, but that also makes me thinking we dont want to merge the methods. |
I disagree. I feel very strongly wr shouldn't have both get and derive. However, I think I have a better idea. Stay tuned lol |
Why not? They do two fundamentally different things - one loads an instance from disk, one constructs a new instance (and presumably writes it to disk). |
Because the entire point of this exercise is a) to obviate this distinction and b) to start phasing out disk I/O altogether. |
5defb92
to
224dbd3
Compare
lightning/src/ln/channel.rs
Outdated
@@ -909,7 +909,8 @@ impl<Signer: Sign> Channel<Signer> { | |||
let opt_anchors = false; // TODO - should be based on features | |||
|
|||
let holder_selected_contest_delay = config.channel_handshake_config.our_to_self_delay; | |||
let holder_signer = keys_provider.get_channel_signer(false, channel_value_satoshis); | |||
let channel_keys_id = keys_provider.generate_channel_keys_id(user_id); |
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.
completely unrelated to this PR, but that variable really shouldn't be called user_id
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.
obviously, user_provided_channel_id
is a bit verbose, but at least it's accurate
No? We cannot remove the I/O for a signer - an enforcing signer absolutely must do IO for every action. What doesn't make sense is the I/O being done "for" a user - they have to do it inline during the signing operations themselves. |
Sorry, I meant I/O done by us. |
Right, I don't see how that's relevant to whether we combine the new-signer and the derive-preexisting-signer methods? |
224dbd3
to
cda514c
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.
Okay, I think we're basically on the same page, one note about further code we can remove but otherwise looks good.
cda514c
to
8e2a89f
Compare
8e2a89f
to
a079946
Compare
a079946
to
1141cbb
Compare
Had to rebase on latest to address a conflict. |
840cf90
to
0572c77
Compare
Needs #1867 (comment) addressed. |
0572c77
to
4501bff
Compare
4501bff
to
9acf5f0
Compare
`get_channel_signer` previously had two different responsibilites: generating unique `channel_keys_id` and using said ID to derive channel keys. We decide to split it into two methods `generate_channel_keys_id` and `derive_channel_signer`, such that we can use the latter to fulfill our goal of re-deriving signers instead of persisting them. There's no point in storing data that can be easily re-derived.
Now that ready_channel is also called on startup upon deserializing channels, we opt to rename it to a more indicative name. We also derive `PartialEq` on ChannelTransactionParameters to allow implementations to determine whether `provide_channel_parameters` calls are idempotent after the channel parameters have already been provided.
To do so, we introduce a new serialization version that doesn't store a channel's signer, and instead stores its signer's `channel_keys_id`. This is a unique identifier that can be provided to our `KeysInterface` to re-derive all private key material for said channel. We choose to not upgrade the minimum compatible serialization version until a later time, which will also remove any signer serialization logic on implementations of `KeysInterface` and `Sign`.
Similar to the previous commit, we introduce a new serialization version that doesn't store a monitor's signer. Since the monitor already knows of a channel's `channel_keys_id`, there's no need to store any new data to re-derive all private key material for said channel.
Since `ChannelMonitor`s will now re-derive signers rather than persisting them, we can no longer use the OnlyReadsKeysInterface concrete implementation.
Now that we opt to always re-derive channel secrets whenever required, we can drop the Clone requirement from Sign.
Now that to_be_bytes is available under our current MSRV of 1.41, we can use it instead of our own version.
9acf5f0
to
444fce7
Compare
Would like an ACK from @devrandom |
@@ -263,6 +263,7 @@ struct KeyProvider { | |||
node_secret: SecretKey, | |||
inbound_payment_key: KeyMaterial, | |||
counter: AtomicU64, | |||
signer_state: RefCell<HashMap<u8, (bool, Arc<Mutex<EnforcementState>>)>> |
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 know it's internal only, but a comment here would be extremely helpful. I think a comment above counter would be helpful, too. What are we counting, 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.
It's ready.
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 open a followup.
/// they MUST NOT be allowed to change to different values once set. | ||
/// counterparty_selected/holder_selected_contest_delay and funding outpoint. Since these are | ||
/// static channel data, they MUST NOT be allowed to change to different values once set, as LDK | ||
/// may call this method more than once. |
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.
Huh? LDK will absolutely not call this method more than once (for a given instance).
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.
well, for a disk-backed signer that returns a shared reference to derive_*
(which is how VLS works internally), it effectively does that. the instances are indexed by the channel keys ID.
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.
or another way to look at it - an enforcing signer must return a shared reference so that it can keep track of a unique signer state
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, my point is that for a given instance of the trait we won't call it more than once. From the perspective of something that exists as multiple instances of the trait its different. Anyway, we can continue this discussion on #1903
Fixes #1209.