Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lnwallet/aux_resolutions.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ type ResolutionReq struct {
// KeyRing is the key ring for the channel.
KeyRing *CommitmentKeyRing

// InitialKeyRing is the key ring for the initial commitment state at
// height 0. This lets downstream resolvers distinguish "just opened"
// commitment outputs from later states that use the post-channel_ready
// commitment point.
InitialKeyRing *CommitmentKeyRing

// CsvDelay is the CSV delay for the local output for this commitment.
CsvDelay uint32

Expand Down
46 changes: 46 additions & 0 deletions lnwallet/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,44 @@ func (lc *LightningChannel) extractPayDescs(feeRate chainfee.SatPerKWeight,
return incomingHtlcs, outgoingHtlcs, nil
}

// initialCommitmentKeyRing derives the key ring for the initial commitment
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The function comment should start with the function's name (initialCommitmentKeyRingFromState) to adhere to the repository's style guide.

Suggested change
// initialCommitmentKeyRing derives the key ring for the initial commitment
// initialCommitmentKeyRingFromState derives the key ring for the initial commitment
References
  1. Function comments must begin with the function name. (link)

// state at height 0. This is distinct from the live key ring after
// channel_ready, which already moved on to the next per-commitment point.
// If the initial commitment point can't be derived, then nil is returned and
// the caller should fall back to the live key ring.
func initialCommitmentKeyRingFromState(chanState *channeldb.OpenChannel,
whoseCommit lntypes.ChannelParty) *CommitmentKeyRing {

switch {
case whoseCommit.IsLocal():
revocation, err := chanState.RevocationProducer.AtIndex(0)
if err != nil {
return nil
}

commitPoint := input.ComputeCommitmentPoint(revocation[:])

return DeriveCommitmentKeys(
commitPoint, lntypes.Local, chanState.ChanType,
&chanState.LocalChanCfg, &chanState.RemoteChanCfg,
)

case whoseCommit.IsRemote():
if chanState.RemoteCurrentRevocation == nil {
return nil
}

return DeriveCommitmentKeys(
chanState.RemoteCurrentRevocation, lntypes.Remote,
chanState.ChanType, &chanState.LocalChanCfg,
&chanState.RemoteChanCfg,
)

default:
return nil
}
}

// diskCommitToMemCommit converts the on-disk commitment format to our
// in-memory commitment format which is needed in order to properly resume
// channel operations after a restart.
Expand Down Expand Up @@ -8521,6 +8559,13 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel,

// At this point, we'll check to see if we need any extra
// resolution data for this output.
var initialKeyRing *CommitmentKeyRing
if chanState.LocalCommitment.CommitHeight == 0 {
initialKeyRing = initialCommitmentKeyRingFromState(
chanState, lntypes.Local,
)
}

resolveBlob := fn.MapOptionZ(
auxResolver,
func(a AuxContractResolver) fn.Result[tlv.Blob] {
Expand All @@ -8539,6 +8584,7 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel,
ContractPoint: commitResolution.SelfOutPoint,
SignDesc: commitResolution.SelfOutputSignDesc,
KeyRing: keyRing,
InitialKeyRing: initialKeyRing,
CsvDelay: csvTimeout,
CommitFee: chanState.LocalCommitment.CommitFee,
})
Expand Down
Loading