Merge pull request #956 from halseth/channel-newlocalforceclosesummary
[refactor] lnwallet/channel: add NewLocalForceCloseSummary
This commit is contained in:
commit
32ad632aa1
@ -196,7 +196,7 @@ func newActiveChannelArbitrator(channel *channeldb.OpenChannel,
|
|||||||
ChanPoint: chanPoint,
|
ChanPoint: chanPoint,
|
||||||
ShortChanID: channel.ShortChanID,
|
ShortChanID: channel.ShortChanID,
|
||||||
BlockEpochs: blockEpoch,
|
BlockEpochs: blockEpoch,
|
||||||
ForceCloseChan: func() (*lnwallet.ForceCloseSummary, error) {
|
ForceCloseChan: func() (*lnwallet.LocalForceCloseSummary, error) {
|
||||||
// With the channels fetched, attempt to locate
|
// With the channels fetched, attempt to locate
|
||||||
// the target channel according to its channel
|
// the target channel according to its channel
|
||||||
// point.
|
// point.
|
||||||
|
@ -89,7 +89,7 @@ type ChannelArbitratorConfig struct {
|
|||||||
// is watching over. We'll use this when we decide that we need to go
|
// is watching over. We'll use this when we decide that we need to go
|
||||||
// to chain. The returned summary contains all items needed to
|
// to chain. The returned summary contains all items needed to
|
||||||
// eventually resolve all outputs on chain.
|
// eventually resolve all outputs on chain.
|
||||||
ForceCloseChan func() (*lnwallet.ForceCloseSummary, error)
|
ForceCloseChan func() (*lnwallet.LocalForceCloseSummary, error)
|
||||||
|
|
||||||
// CloseChannel is a function closure that marks a channel under watch
|
// CloseChannel is a function closure that marks a channel under watch
|
||||||
// as "closing". In this phase, we will no longer accept any updates to
|
// as "closing". In this phase, we will no longer accept any updates to
|
||||||
|
@ -5203,23 +5203,24 @@ func extractHtlcResolutions(feePerKw SatPerKWeight, ourCommit bool,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForceCloseSummary describes the final commitment state before the channel is
|
// LocalForceCloseSummary describes the final commitment state before the
|
||||||
// locked-down to initiate a force closure by broadcasting the latest state
|
// channel is locked-down to initiate a force closure by broadcasting the
|
||||||
// on-chain. The summary includes all the information required to claim all
|
// latest state on-chain. If we intend to broadcast this this state, the
|
||||||
// rightfully owned outputs.
|
// channel should not be used after generating this close summary. The summary
|
||||||
type ForceCloseSummary struct {
|
// includes all the information required to claim all rightfully owned outputs
|
||||||
|
// when the commitment gets confirmed.
|
||||||
|
type LocalForceCloseSummary struct {
|
||||||
// ChanPoint is the outpoint that created the channel which has been
|
// ChanPoint is the outpoint that created the channel which has been
|
||||||
// force closed.
|
// force closed.
|
||||||
ChanPoint wire.OutPoint
|
ChanPoint wire.OutPoint
|
||||||
|
|
||||||
// CloseTx is the transaction which closed the channel on-chain. If we
|
// CloseTx is the transaction which can be used to close the channel
|
||||||
// initiate the force close, then this will be our latest commitment
|
// on-chain. When we initiate a force close, this will be our latest
|
||||||
// state. Otherwise, this will be the state that the remote peer
|
// commitment state.
|
||||||
// broadcasted on-chain.
|
|
||||||
CloseTx *wire.MsgTx
|
CloseTx *wire.MsgTx
|
||||||
|
|
||||||
// CommitResolution contains all the data required to sweep the output
|
// CommitResolution contains all the data required to sweep the output
|
||||||
// to ourselves. If this is our commitment transaction, then we'll need
|
// to ourselves. Since this is our commitment transaction, we'll need
|
||||||
// to wait a time delay before we can sweep the output.
|
// to wait a time delay before we can sweep the output.
|
||||||
//
|
//
|
||||||
// NOTE: If our commitment delivery output is below the dust limit,
|
// NOTE: If our commitment delivery output is below the dust limit,
|
||||||
@ -5227,52 +5228,69 @@ type ForceCloseSummary struct {
|
|||||||
CommitResolution *CommitOutputResolution
|
CommitResolution *CommitOutputResolution
|
||||||
|
|
||||||
// HtlcResolutions contains all the data required to sweep any outgoing
|
// HtlcResolutions contains all the data required to sweep any outgoing
|
||||||
// HTLC's and incoming HTLc's we now the preimage to. For each of these
|
// HTLC's and incoming HTLc's we know the preimage to. For each of these
|
||||||
// HTLC's, we'll need to go to the second level to sweep them fully.
|
// HTLC's, we'll need to go to the second level to sweep them fully.
|
||||||
HtlcResolutions *HtlcResolutions
|
HtlcResolutions *HtlcResolutions
|
||||||
|
|
||||||
// ChanSnapshot is a snapshot of the final state of the channel at the
|
// ChanSnapshot is a snapshot of the final state of the channel at the
|
||||||
// time it was closed.
|
// time the summary was created.
|
||||||
ChanSnapshot channeldb.ChannelSnapshot
|
ChanSnapshot channeldb.ChannelSnapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForceClose executes a unilateral closure of the transaction at the current
|
// ForceClose executes a unilateral closure of the transaction at the current
|
||||||
// lowest commitment height of the channel. Following a force closure, all
|
// lowest commitment height of the channel. Following a force closure, all
|
||||||
// state transitions, or modifications to the state update logs will be
|
// state transitions, or modifications to the state update logs will be
|
||||||
// rejected. Additionally, this function also returns a ForceCloseSummary which
|
// rejected. Additionally, this function also returns a LocalForceCloseSummary
|
||||||
// includes the necessary details required to sweep all the time-locked within
|
// which includes the necessary details required to sweep all the time-locked
|
||||||
// the commitment transaction.
|
// outputs within the commitment transaction.
|
||||||
//
|
//
|
||||||
// TODO(roasbeef): all methods need to abort if in dispute state
|
// TODO(roasbeef): all methods need to abort if in dispute state
|
||||||
// TODO(roasbeef): method to generate CloseSummaries for when the remote peer
|
// TODO(roasbeef): method to generate CloseSummaries for when the remote peer
|
||||||
// does a unilateral close
|
// does a unilateral close
|
||||||
func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
|
func (lc *LightningChannel) ForceClose() (*LocalForceCloseSummary, error) {
|
||||||
lc.Lock()
|
lc.Lock()
|
||||||
defer lc.Unlock()
|
defer lc.Unlock()
|
||||||
|
|
||||||
// Set the channel state to indicate that the channel is now in a
|
|
||||||
// contested state.
|
|
||||||
lc.status = channelDispute
|
|
||||||
|
|
||||||
commitTx, err := lc.getSignedCommitTx()
|
commitTx, err := lc.getSignedCommitTx()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
localCommitment := lc.channelState.LocalCommitment
|
||||||
|
summary, err := NewLocalForceCloseSummary(lc.channelState,
|
||||||
|
lc.signer, lc.pCache, commitTx, localCommitment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the channel state to indicate that the channel is now in a
|
||||||
|
// contested state.
|
||||||
|
lc.status = channelDispute
|
||||||
|
|
||||||
|
return summary, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLocalForceCloseSummary generates a LocalForceCloseSummary from the given
|
||||||
|
// channel state. The passed commitTx must be a fully signed commitment
|
||||||
|
// transaction corresponding to localCommit.
|
||||||
|
func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer Signer,
|
||||||
|
pCache PreimageCache, commitTx *wire.MsgTx,
|
||||||
|
localCommit channeldb.ChannelCommitment) (*LocalForceCloseSummary, error) {
|
||||||
|
|
||||||
// Re-derive the original pkScript for to-self output within the
|
// Re-derive the original pkScript for to-self output within the
|
||||||
// commitment transaction. We'll need this to find the corresponding
|
// commitment transaction. We'll need this to find the corresponding
|
||||||
// output in the commitment transaction and potentially for creating
|
// output in the commitment transaction and potentially for creating
|
||||||
// the sign descriptor.
|
// the sign descriptor.
|
||||||
csvTimeout := uint32(lc.localChanCfg.CsvDelay)
|
csvTimeout := uint32(chanState.LocalChanCfg.CsvDelay)
|
||||||
unusedRevocation, err := lc.channelState.RevocationProducer.AtIndex(
|
revocation, err := chanState.RevocationProducer.AtIndex(
|
||||||
lc.currentHeight,
|
localCommit.CommitHeight,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
commitPoint := ComputeCommitmentPoint(unusedRevocation[:])
|
commitPoint := ComputeCommitmentPoint(revocation[:])
|
||||||
keyRing := deriveCommitmentKeys(commitPoint, true, lc.localChanCfg,
|
keyRing := deriveCommitmentKeys(commitPoint, true, &chanState.LocalChanCfg,
|
||||||
lc.remoteChanCfg)
|
&chanState.RemoteChanCfg)
|
||||||
selfScript, err := commitScriptToSelf(csvTimeout, keyRing.DelayKey,
|
selfScript, err := commitScriptToSelf(csvTimeout, keyRing.DelayKey,
|
||||||
keyRing.RevocationKey)
|
keyRing.RevocationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -5300,8 +5318,6 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
localCommitment := lc.channelState.LocalCommitment
|
|
||||||
|
|
||||||
// With the necessary information gathered above, create a new sign
|
// With the necessary information gathered above, create a new sign
|
||||||
// descriptor which is capable of generating the signature the caller
|
// descriptor which is capable of generating the signature the caller
|
||||||
// needs to sweep this output. The hash cache, and input index are not
|
// needs to sweep this output. The hash cache, and input index are not
|
||||||
@ -5311,16 +5327,16 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
|
|||||||
var commitResolution *CommitOutputResolution
|
var commitResolution *CommitOutputResolution
|
||||||
if len(delayScript) != 0 {
|
if len(delayScript) != 0 {
|
||||||
singleTweak := SingleTweakBytes(
|
singleTweak := SingleTweakBytes(
|
||||||
commitPoint, lc.localChanCfg.DelayBasePoint.PubKey,
|
commitPoint, chanState.LocalChanCfg.DelayBasePoint.PubKey,
|
||||||
)
|
)
|
||||||
localBalance := localCommitment.LocalBalance
|
localBalance := localCommit.LocalBalance
|
||||||
commitResolution = &CommitOutputResolution{
|
commitResolution = &CommitOutputResolution{
|
||||||
SelfOutPoint: wire.OutPoint{
|
SelfOutPoint: wire.OutPoint{
|
||||||
Hash: commitTx.TxHash(),
|
Hash: commitTx.TxHash(),
|
||||||
Index: delayIndex,
|
Index: delayIndex,
|
||||||
},
|
},
|
||||||
SelfOutputSignDesc: SignDescriptor{
|
SelfOutputSignDesc: SignDescriptor{
|
||||||
KeyDesc: lc.localChanCfg.DelayBasePoint,
|
KeyDesc: chanState.LocalChanCfg.DelayBasePoint,
|
||||||
SingleTweak: singleTweak,
|
SingleTweak: singleTweak,
|
||||||
WitnessScript: selfScript,
|
WitnessScript: selfScript,
|
||||||
Output: &wire.TxOut{
|
Output: &wire.TxOut{
|
||||||
@ -5338,19 +5354,19 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
|
|||||||
// outgoing HTLC's that we'll need to claim as well.
|
// outgoing HTLC's that we'll need to claim as well.
|
||||||
txHash := commitTx.TxHash()
|
txHash := commitTx.TxHash()
|
||||||
htlcResolutions, err := extractHtlcResolutions(
|
htlcResolutions, err := extractHtlcResolutions(
|
||||||
SatPerKWeight(localCommitment.FeePerKw), true, lc.signer,
|
SatPerKWeight(localCommit.FeePerKw), true, signer,
|
||||||
localCommitment.Htlcs, keyRing, lc.localChanCfg,
|
localCommit.Htlcs, keyRing, &chanState.LocalChanCfg,
|
||||||
lc.remoteChanCfg, txHash, lc.pCache)
|
&chanState.RemoteChanCfg, txHash, pCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ForceCloseSummary{
|
return &LocalForceCloseSummary{
|
||||||
ChanPoint: lc.channelState.FundingOutpoint,
|
ChanPoint: chanState.FundingOutpoint,
|
||||||
CloseTx: commitTx,
|
CloseTx: commitTx,
|
||||||
CommitResolution: commitResolution,
|
CommitResolution: commitResolution,
|
||||||
HtlcResolutions: htlcResolutions,
|
HtlcResolutions: htlcResolutions,
|
||||||
ChanSnapshot: *lc.channelState.Snapshot(),
|
ChanSnapshot: *chanState.Snapshot(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user