Skip to content
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

Merged

Conversation

wpaulino
Copy link
Contributor

Fixes #1209.

@wpaulino wpaulino marked this pull request as ready for review November 21, 2022 21:37
lightning/src/chain/keysinterface.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/chain/onchaintx.rs Show resolved Hide resolved
@codecov-commenter
Copy link

codecov-commenter commented Nov 22, 2022

Codecov Report

Base: 90.69% // Head: 90.54% // Decreases project coverage by -0.14% ⚠️

Coverage data is based on head (444fce7) compared to base (52edb35).
Patch coverage: 89.55% of modified lines in pull request are covered.

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     
Impacted Files Coverage Δ
lightning/src/chain/package.rs 92.84% <ø> (ø)
lightning/src/util/byte_utils.rs 100.00% <ø> (ø)
lightning/src/util/test_utils.rs 73.50% <71.42%> (-3.56%) ⬇️
lightning/src/ln/channelmanager.rs 86.30% <80.00%> (+0.01%) ⬆️
lightning/src/ln/channel.rs 88.70% <80.43%> (-0.14%) ⬇️
lightning/src/chain/channelmonitor.rs 90.88% <92.85%> (+0.14%) ⬆️
lightning/src/chain/keysinterface.rs 83.14% <100.00%> (-7.82%) ⬇️
lightning/src/chain/onchaintx.rs 95.13% <100.00%> (-0.17%) ⬇️
lightning/src/ln/chan_utils.rs 93.62% <100.00%> (+<0.01%) ⬆️
lightning/src/ln/chanmon_update_fail_tests.rs 97.59% <100.00%> (ø)
... and 14 more

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.
📢 Do you have feedback about the report comment? Let us know in this issue.

@wpaulino
Copy link
Contributor Author

Pushed a new update that allows downgrading and replaces get_channel_signer with derive_channel_signer.

@TheBlueMatt
Copy link
Collaborator

Hmmmmm, now that I think about it we really need to pass the user_channel_id through to the new-signer function. We could do that by passing an enum that either has a keys_id or a user_id to the method, but given the two methods are likely to do very different things (read state vs persist new state) I'm very unconvinced that they need to be merged.

@arik-so
Copy link
Contributor

arik-so commented Nov 22, 2022

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?

@TheBlueMatt
Copy link
Collaborator

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.

@arik-so
Copy link
Contributor

arik-so commented Nov 22, 2022

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

@TheBlueMatt
Copy link
Collaborator

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).

@arik-so
Copy link
Contributor

arik-so commented Nov 22, 2022

Because the entire point of this exercise is a) to obviate this distinction and b) to start phasing out disk I/O altogether.

lightning/src/chain/keysinterface.rs Outdated Show resolved Hide resolved
lightning/src/chain/keysinterface.rs Outdated Show resolved Hide resolved
@@ -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);
Copy link
Contributor

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

Copy link
Contributor

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

lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/util/byte_utils.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
@TheBlueMatt
Copy link
Collaborator

Because the entire point of this exercise is a) to obviate this distinction and b) to start phasing out disk I/O altogether.

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.

@arik-so
Copy link
Contributor

arik-so commented Nov 23, 2022

Sorry, I meant I/O done by us.

@TheBlueMatt
Copy link
Collaborator

Right, I don't see how that's relevant to whether we combine the new-signer and the derive-preexisting-signer methods?

lightning/src/chain/keysinterface.rs Outdated Show resolved Hide resolved
lightning/src/chain/onchaintx.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a 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.

lightning/src/chain/keysinterface.rs Outdated Show resolved Hide resolved
lightning/src/chain/keysinterface.rs Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/util/byte_utils.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
lightning/src/chain/onchaintx.rs Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/util/byte_utils.rs Outdated Show resolved Hide resolved
lightning/src/chain/keysinterface.rs Outdated Show resolved Hide resolved
lightning/src/chain/keysinterface.rs Show resolved Hide resolved
lightning/src/chain/onchaintx.rs Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
@wpaulino
Copy link
Contributor Author

wpaulino commented Dec 1, 2022

Had to rebase on latest to address a conflict.

lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/chain/keysinterface.rs Show resolved Hide resolved
TheBlueMatt
TheBlueMatt previously approved these changes Dec 2, 2022
@TheBlueMatt
Copy link
Collaborator

Needs #1867 (comment) addressed.

arik-so
arik-so previously approved these changes Dec 2, 2022
`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.
@TheBlueMatt
Copy link
Collaborator

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>>)>>
Copy link
Contributor

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?

Copy link
Contributor

@arik-so arik-so left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ready.

Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a 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.
Copy link
Collaborator

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).

Copy link
Member

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.

Copy link
Member

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

Copy link
Collaborator

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

@TheBlueMatt TheBlueMatt merged commit 5588eeb into lightningdevkit:main Dec 6, 2022
@wpaulino wpaulino deleted the remove-signer-persistence branch December 6, 2022 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Do not default to storing InMemoryChannelKeys keys on disk
6 participants