Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary of the changes
Key path generation
Eclair 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 changes
Funder scenario : in order to send an
open_channel
we need to compute the basepoints for the channel operation and indeed we need the key path to do so. This means that before starting the negotiation of the channel opening we must ask the wallet to provide an input for the channel funding, we will use the input outpoint to construct the channel key path. Such particular flow modified theChannel
FSM to have some new intermediate states, namely where we ask the wallet to create a funding transaction WAIT_FOR_FUNDING_INTERNAL_CREATED and where we ask the wallet to sign it WAIT_FOR_FUNDING_SIGNED_INTERNAL. Note that after we ask the wallet to make a funding transaction we strip the signatures from it and we later query the wallet again to add new signatures, the wallet will sign the updated transaction with the script containing the funding pubkey from the remote peer (we have the remote funding pubkey only after we receiveaccept_channel
).Fundee scenario: this scenario uses 2 different keypaths to operate the channel, one for the funding pubkey and one for all the other points. This is necessary because we want to use the scriptPubkey from the funding transaction to construct the keypath but to do so we need to derive out funding pubkey first, in order to do that we use a combination of block height and a counter. This scenario doesn't alter the channel opening flow.
Reference: funder construction and fundee construction
Codecs and Commitments upgrades
The usage of 2 different kinds of keypaths (one for funder scenario, two for fundee) forced to upgrade the
LocalParams
class to store anEither[KeyPath, KeyPathFundee]
, we also need to upgrade the codecs to store these new objects and we must do it in a backward compatible manner.The codec has been modified to support commitment versioning and depending on the version we'll fetch the correct key paths.
Database layer upgrades
There is no db migration needed here but we add a new table to channel db,
block_key_counter
table. This is used to emulate an atomic auto incrementing counter used for the fundee key path construction, the alternative implementation using theAtomicLong
has been ditched because of security concerns.Testing
The 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.