-
Notifications
You must be signed in to change notification settings - Fork 267
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
Deterministic channel keypath #1026
Conversation
3d60a90
to
b041d94
Compare
(version match { | ||
case CommitmentV0 => ("channelPath" | keyPathCodec.xmap[Either[KeyPath, KeyPathFundee]](Left(_), { | ||
case Left(kp) => kp | ||
case Right(_) => throw new IllegalArgumentException(s"Found unexpected value for version=$version") |
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.
This will not work for "fundee" channels, but it should be possible to use the V0 key path we read from the database
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.
Yes, this has been fixed in 847eb06
@@ -588,7 +588,7 @@ object Peer { | |||
def makeChannelParams(nodeParams: NodeParams, defaultFinalScriptPubKey: ByteVector, isFunder: Boolean, fundingSatoshis: Long, channelKeyPath: DeterministicWallet.KeyPath): LocalParams = { |
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.
If unused it should be removed ?
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.
Done in 5ded959
} | ||
} | ||
|
||
|
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 is possible to infer the counter value from the data we read from the database (check all channels fro a given peer, then get their block heights from the short channel 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.
The alternative is to have an atomic counter stored in volatile memory, however while this is a more elegant solution it opens up to new attacker scenarios.
def deterministicCommitmentSecret(localParams: LocalParams, index: Long): Crypto.Scalar | ||
|
||
def deterministicCommitmentPoint(localParams: LocalParams, index: Long): Crypto.Point | ||
|
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.
Can we keep the old names instead ?
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.
Yes these changes have been reverted
# Conflicts: # eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala
# Conflicts: # eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala # eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala # eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala # eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala # eclair-core/src/main/scala/fr/acinq/eclair/crypto/LocalKeyManager.scala # eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala # eclair-core/src/test/scala/fr/acinq/eclair/TestConstants.scala # eclair-core/src/test/scala/fr/acinq/eclair/crypto/LocalKeyManagerSpec.scala
…date test vectors
…k while wait_for_funding_signed_internal
5183bc9
to
922072f
Compare
…FIRMED -> WAIT_FOR_FUNDING_LOCKED in funder scenario
…KED -> NORMAL in funder scenario
# Conflicts: # eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala # eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala # eclair-core/src/test/scala/fr/acinq/eclair/channel/states/c/WaitForFundingConfirmedStateSpec.scala
c12c706
to
bdcd0ab
Compare
Codecov Report
@@ Coverage Diff @@
## master #1026 +/- ##
=========================================
+ Coverage 82.47% 82.58% +0.1%
=========================================
Files 99 99
Lines 7594 7682 +88
Branches 293 292 -1
=========================================
+ Hits 6263 6344 +81
- Misses 1331 1338 +7
|
Summary of the changesKey path generationEclair uses BIP32 key paths to derive all the various keys needed for channel operation, instead of generating a new random keypath when negotiating a channel we now use an external source of entropy to feed randomness in the path construction. The entropy is taken from the funding input's outpoint and in the case we're fundee we use a combination of block height and an incrementing counter to ensure we never reuse keys, the full construction is highlighted below: Funder scenario:
Fundee scenario:
Channel creation changesFunder scenario : in order to send an Reference: funder construction and fundee construction Codecs and Commitments upgradesThe usage of 2 different kinds of keypaths (one for funder scenario, two for fundee) forced to upgrade the Database layer upgradesThere is no db migration needed here but we add a new table to channel db, TestingThe PR has been manual tested against eclair master, there are also new codec tests and backward compatibility test for fundee scenario in DATA_NORMAL: here. To ensure previous version with yet-to-open channels can safely upgrade there are some test where we assert we can do FSM transition like "WAIT_FOR_FUNDING_CONFIRMED -> WAIT_FOR_FUNDING_LOCKED", test here and here. |
# Conflicts: # eclair-core/src/main/scala/fr/acinq/eclair/wire/ChannelCodecs.scala # eclair-core/src/test/scala/fr/acinq/eclair/db/ChannelStateSpec.scala # eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala
# Conflicts: # eclair-core/src/main/scala/fr/acinq/eclair/channel/ChannelTypes.scala # eclair-core/src/test/scala/fr/acinq/eclair/wire/ChannelCodecsSpec.scala
Replaced by #1086 |
This PR introduces deterministic keypath construction for the derivation of the keys used in the channel operations, the construction is made in such a way that we guarantee we never reuse the same keypath in order to prevent reusing keys across channels.The schema can be summarized as follow:
Funder scenario:
Fundee scenario:
The fundee scenario involves using 2 different keypaths, one to derive the funding pubkey and another to derive all the other points required to construct
accept_channel
message. The usage of 2 different keypaths is required to compute the scriptPubkey of the funding transaction which is later used to construct the second keypath which is then used to derive all the other points for the channel.As side effect of this PR all the static channel data, as in the data derived from the channel points exchanged in the open/accept messages, can now be derived only from the seed.
Credits: @armelinw