lnwallet: Refactor commitment key generation code.
Create struct holding all commitment keys to clean up code and avoid deriving keys multiple times.
This commit is contained in:
parent
0994852396
commit
3151a3a596
@ -292,6 +292,41 @@ type commitment struct {
|
|||||||
incomingHTLCIndex map[int32]*PaymentDescriptor
|
incomingHTLCIndex map[int32]*PaymentDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// commitmentKeyRing holds all derived keys needed to construct commitment and
|
||||||
|
// HTLC transactions. The keys are derived differently depending whether the
|
||||||
|
// commitment transaction is ours or the remote peer's. Private keys associated
|
||||||
|
// with each key may belong to the commitment owner or the "other party" which
|
||||||
|
// is referred to in the field comments, regardless of which is local and which
|
||||||
|
// is remote.
|
||||||
|
type commitmentKeyRing struct {
|
||||||
|
// commitPoint is the "per commitment point" used to derive the tweak for
|
||||||
|
// each base point.
|
||||||
|
commitPoint *btcec.PublicKey
|
||||||
|
|
||||||
|
// localKeyTweak is the tweak used to derive the local public key from the
|
||||||
|
// local payment base point or the local private key from the base point
|
||||||
|
// secret. This may be included in a SignDescriptor to generate signatures
|
||||||
|
// for the local payment key.
|
||||||
|
localKeyTweak []byte
|
||||||
|
|
||||||
|
// delayKey is the commitment transaction owner's key which is included in
|
||||||
|
// HTLC success and timeout transaction scripts.
|
||||||
|
delayKey *btcec.PublicKey
|
||||||
|
|
||||||
|
// paymentKey is the other party's payment key in the commitment tx.
|
||||||
|
paymentKey *btcec.PublicKey
|
||||||
|
|
||||||
|
// revocationKey is the key that can be used by the other party to redeem
|
||||||
|
// outputs from a revoked commitment transaction if it were to be published.
|
||||||
|
revocationKey *btcec.PublicKey
|
||||||
|
|
||||||
|
// localKey is this node's payment key in the commitment tx.
|
||||||
|
localKey *btcec.PublicKey
|
||||||
|
|
||||||
|
// remoteKey is the remote node's payment key in the commitment tx.
|
||||||
|
remoteKey *btcec.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
// locateOutputIndex is a small helper function to locate the output index of a
|
// locateOutputIndex is a small helper function to locate the output index of a
|
||||||
// particular HTLC within the current commitment transaction. The duplicate map
|
// particular HTLC within the current commitment transaction. The duplicate map
|
||||||
// massed in is to be retained for each output within the commitment
|
// massed in is to be retained for each output within the commitment
|
||||||
@ -1115,27 +1150,15 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
|||||||
|
|
||||||
// With the commitment point generated, we can now generate the four
|
// With the commitment point generated, we can now generate the four
|
||||||
// keys we'll need to reconstruct the commitment state,
|
// keys we'll need to reconstruct the commitment state,
|
||||||
localKey := TweakPubKey(chanState.LocalChanCfg.PaymentBasePoint,
|
keyRing := deriveCommitmentKeys(commitmentPoint, false,
|
||||||
commitmentPoint)
|
&chanState.LocalChanCfg, &chanState.RemoteChanCfg)
|
||||||
remoteKey := TweakPubKey(chanState.RemoteChanCfg.PaymentBasePoint,
|
|
||||||
commitmentPoint)
|
|
||||||
remoteDelayKey := TweakPubKey(chanState.RemoteChanCfg.DelayBasePoint,
|
|
||||||
commitmentPoint)
|
|
||||||
|
|
||||||
// Once we derive the revocation leaf, we can then re-create the
|
|
||||||
// revocation public key used within this state. This is needed in
|
|
||||||
// order to create the proper script below.
|
|
||||||
revocationKey := DeriveRevocationPubkey(
|
|
||||||
chanState.LocalChanCfg.RevocationBasePoint,
|
|
||||||
commitmentPoint,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Next, reconstruct the scripts as they were present at this state
|
// Next, reconstruct the scripts as they were present at this state
|
||||||
// number so we can have the proper witness script to sign and include
|
// number so we can have the proper witness script to sign and include
|
||||||
// within the final witness.
|
// within the final witness.
|
||||||
remoteDelay := uint32(chanState.RemoteChanCfg.CsvDelay)
|
remoteDelay := uint32(chanState.RemoteChanCfg.CsvDelay)
|
||||||
remotePkScript, err := commitScriptToSelf(remoteDelay, remoteDelayKey,
|
remotePkScript, err := commitScriptToSelf(remoteDelay, keyRing.delayKey,
|
||||||
revocationKey)
|
keyRing.revocationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1143,7 +1166,7 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
localPkScript, err := commitScriptUnencumbered(localKey)
|
localPkScript, err := commitScriptUnencumbered(keyRing.localKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1180,13 +1203,8 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
|||||||
// If the local balance exceeds the remote party's dust limit,
|
// If the local balance exceeds the remote party's dust limit,
|
||||||
// instantiate the local sign descriptor.
|
// instantiate the local sign descriptor.
|
||||||
if localAmt >= chanState.RemoteChanCfg.DustLimit {
|
if localAmt >= chanState.RemoteChanCfg.DustLimit {
|
||||||
// We'll need to reconstruct the single tweak so we can sweep
|
|
||||||
// our non-delayed pay-to-self output self.
|
|
||||||
singleTweak := SingleTweakBytes(commitmentPoint,
|
|
||||||
chanState.LocalChanCfg.PaymentBasePoint)
|
|
||||||
|
|
||||||
localSignDesc = &SignDescriptor{
|
localSignDesc = &SignDescriptor{
|
||||||
SingleTweak: singleTweak,
|
SingleTweak: keyRing.localKeyTweak,
|
||||||
PubKey: chanState.LocalChanCfg.PaymentBasePoint,
|
PubKey: chanState.LocalChanCfg.PaymentBasePoint,
|
||||||
WitnessScript: localPkScript,
|
WitnessScript: localPkScript,
|
||||||
Output: &wire.TxOut{
|
Output: &wire.TxOut{
|
||||||
@ -1226,8 +1244,8 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
|||||||
// the sender of the HTLC (relative to us). So we'll
|
// the sender of the HTLC (relative to us). So we'll
|
||||||
// re-generate the sender HTLC script.
|
// re-generate the sender HTLC script.
|
||||||
if htlc.Incoming {
|
if htlc.Incoming {
|
||||||
htlcScript, err = senderHTLCScript(localKey, remoteKey,
|
htlcScript, err = senderHTLCScript(keyRing.localKey,
|
||||||
revocationKey, htlc.RHash[:])
|
keyRing.remoteKey, keyRing.revocationKey, htlc.RHash[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1237,8 +1255,8 @@ func newBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
|||||||
// receiver of this HTLC.
|
// receiver of this HTLC.
|
||||||
} else {
|
} else {
|
||||||
htlcScript, err = receiverHTLCScript(
|
htlcScript, err = receiverHTLCScript(
|
||||||
htlc.RefundTimeout, localKey, remoteKey,
|
htlc.RefundTimeout, keyRing.localKey, keyRing.remoteKey,
|
||||||
revocationKey, htlc.RHash[:],
|
keyRing.revocationKey, htlc.RHash[:],
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1362,7 +1380,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven
|
|||||||
// necessary.
|
// necessary.
|
||||||
//
|
//
|
||||||
// We'll also handle the case of the remote party broadcasting their
|
// We'll also handle the case of the remote party broadcasting their
|
||||||
// commitment transaction which is one height above ours. This case an
|
// commitment transaction which is one height above ours. This case can
|
||||||
// arise when we initiate a state transition, but the remote party has
|
// arise when we initiate a state transition, but the remote party has
|
||||||
// a fail crash _after_ accepting the new state, but _before_ sending
|
// a fail crash _after_ accepting the new state, but _before_ sending
|
||||||
// their signature to us.
|
// their signature to us.
|
||||||
@ -1394,17 +1412,15 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven
|
|||||||
// revocation point so we can re-construct the HTLC state and
|
// revocation point so we can re-construct the HTLC state and
|
||||||
// also our payment key.
|
// also our payment key.
|
||||||
commitPoint := lc.channelState.RemoteCurrentRevocation
|
commitPoint := lc.channelState.RemoteCurrentRevocation
|
||||||
revokeKey := DeriveRevocationPubkey(
|
keyRing := deriveCommitmentKeys(commitPoint, false,
|
||||||
lc.localChanCfg.RevocationBasePoint,
|
lc.localChanCfg, lc.remoteChanCfg)
|
||||||
commitPoint,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Next, we'll obtain HTLC resolutions for all the outgoing
|
// Next, we'll obtain HTLC resolutions for all the outgoing
|
||||||
// HTLC's we had on their commitment transaction.
|
// HTLC's we had on their commitment transaction.
|
||||||
htlcResolutions, localKey, err := extractHtlcResolutions(
|
htlcResolutions, err := extractHtlcResolutions(
|
||||||
lc.channelState.FeePerKw, false, lc.signer,
|
lc.channelState.FeePerKw, false, lc.signer,
|
||||||
lc.channelState.Htlcs, commitPoint,
|
lc.channelState.Htlcs, keyRing,
|
||||||
revokeKey, lc.localChanCfg, lc.remoteChanCfg,
|
lc.localChanCfg, lc.remoteChanCfg,
|
||||||
*commitSpend.SpenderTxHash)
|
*commitSpend.SpenderTxHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
walletLog.Errorf("unable to create htlc "+
|
walletLog.Errorf("unable to create htlc "+
|
||||||
@ -1415,7 +1431,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven
|
|||||||
// Before we can generate the proper sign descriptor, we'll
|
// Before we can generate the proper sign descriptor, we'll
|
||||||
// need to locate the output index of our non-delayed output on
|
// need to locate the output index of our non-delayed output on
|
||||||
// the commitment transaction.
|
// the commitment transaction.
|
||||||
selfP2WKH, err := commitScriptUnencumbered(localKey)
|
selfP2WKH, err := commitScriptUnencumbered(keyRing.localKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
walletLog.Errorf("unable to create self commit "+
|
walletLog.Errorf("unable to create self commit "+
|
||||||
"script: %v", err)
|
"script: %v", err)
|
||||||
@ -1440,7 +1456,7 @@ func (lc *LightningChannel) closeObserver(channelCloseNtfn *chainntnfs.SpendEven
|
|||||||
localPayBase := lc.localChanCfg.PaymentBasePoint
|
localPayBase := lc.localChanCfg.PaymentBasePoint
|
||||||
selfSignDesc = &SignDescriptor{
|
selfSignDesc = &SignDescriptor{
|
||||||
PubKey: localPayBase,
|
PubKey: localPayBase,
|
||||||
SingleTweak: SingleTweakBytes(commitPoint, localPayBase),
|
SingleTweak: keyRing.localKeyTweak,
|
||||||
WitnessScript: selfP2WKH,
|
WitnessScript: selfP2WKH,
|
||||||
Output: &wire.TxOut{
|
Output: &wire.TxOut{
|
||||||
Value: int64(lc.channelState.LocalBalance.ToSatoshis()),
|
Value: int64(lc.channelState.LocalBalance.ToSatoshis()),
|
||||||
@ -1583,27 +1599,12 @@ func (lc *LightningChannel) restoreStateLogs() error {
|
|||||||
// the point derived from the commitment secret at the remote party's
|
// the point derived from the commitment secret at the remote party's
|
||||||
// revocation based.
|
// revocation based.
|
||||||
localCommitPoint := ComputeCommitmentPoint(ourRevPreImage[:])
|
localCommitPoint := ComputeCommitmentPoint(ourRevPreImage[:])
|
||||||
localRevocation := DeriveRevocationPubkey(
|
localCommitKeys := deriveCommitmentKeys(localCommitPoint, true,
|
||||||
remoteChanCfg.RevocationBasePoint,
|
localChanCfg, remoteChanCfg)
|
||||||
localCommitPoint,
|
|
||||||
)
|
|
||||||
remoteCommitPoint := lc.channelState.RemoteCurrentRevocation
|
remoteCommitPoint := lc.channelState.RemoteCurrentRevocation
|
||||||
remoteRevocation := DeriveRevocationPubkey(
|
remoteCommitKeys := deriveCommitmentKeys(remoteCommitPoint, false,
|
||||||
localChanCfg.RevocationBasePoint,
|
localChanCfg, remoteChanCfg)
|
||||||
remoteCommitPoint,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Additionally, we'll fetch the current payment base points which are
|
|
||||||
// required to fully generate the scripts.
|
|
||||||
localCommitLocalKey := TweakPubKey(localChanCfg.PaymentBasePoint,
|
|
||||||
localCommitPoint)
|
|
||||||
localCommitRemoteKey := TweakPubKey(remoteChanCfg.PaymentBasePoint,
|
|
||||||
localCommitPoint)
|
|
||||||
|
|
||||||
remoteCommitLocalKey := TweakPubKey(localChanCfg.PaymentBasePoint,
|
|
||||||
remoteCommitPoint)
|
|
||||||
remoteCommitRemoteKey := TweakPubKey(remoteChanCfg.PaymentBasePoint,
|
|
||||||
remoteCommitPoint)
|
|
||||||
|
|
||||||
var ourCounter, theirCounter uint64
|
var ourCounter, theirCounter uint64
|
||||||
|
|
||||||
@ -1637,8 +1638,8 @@ func (lc *LightningChannel) restoreStateLogs() error {
|
|||||||
if !isDustLocal {
|
if !isDustLocal {
|
||||||
ourP2WSH, ourWitnessScript, err = lc.genHtlcScript(
|
ourP2WSH, ourWitnessScript, err = lc.genHtlcScript(
|
||||||
htlc.Incoming, true, htlc.RefundTimeout, htlc.RHash,
|
htlc.Incoming, true, htlc.RefundTimeout, htlc.RHash,
|
||||||
localCommitLocalKey, localCommitRemoteKey,
|
localCommitKeys.localKey, localCommitKeys.remoteKey,
|
||||||
localRevocation)
|
localCommitKeys.revocationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1646,8 +1647,8 @@ func (lc *LightningChannel) restoreStateLogs() error {
|
|||||||
if !isDustRemote {
|
if !isDustRemote {
|
||||||
theirP2WSH, theirWitnessScript, err = lc.genHtlcScript(
|
theirP2WSH, theirWitnessScript, err = lc.genHtlcScript(
|
||||||
htlc.Incoming, false, htlc.RefundTimeout, htlc.RHash,
|
htlc.Incoming, false, htlc.RefundTimeout, htlc.RHash,
|
||||||
remoteCommitLocalKey, remoteCommitRemoteKey,
|
remoteCommitKeys.localKey, remoteCommitKeys.remoteKey,
|
||||||
remoteRevocation)
|
remoteCommitKeys.revocationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1735,11 +1736,9 @@ func (lc *LightningChannel) fetchHTLCView(theirLogIndex, ourLogIndex uint64) *ht
|
|||||||
// both local and remote commitment transactions in order to sign or verify new
|
// both local and remote commitment transactions in order to sign or verify new
|
||||||
// commitment updates. A fully populated commitment is returned which reflects
|
// commitment updates. A fully populated commitment is returned which reflects
|
||||||
// the proper balances for both sides at this point in the commitment chain.
|
// the proper balances for both sides at this point in the commitment chain.
|
||||||
//
|
|
||||||
// TODO(roasbeef): update commit to to have all keys?
|
|
||||||
func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
||||||
ourLogIndex, theirLogIndex uint64,
|
ourLogIndex, theirLogIndex uint64,
|
||||||
commitPoint *btcec.PublicKey) (*commitment, error) {
|
keyRing *commitmentKeyRing) (*commitment, error) {
|
||||||
|
|
||||||
commitChain := lc.localCommitChain
|
commitChain := lc.localCommitChain
|
||||||
if remoteChain {
|
if remoteChain {
|
||||||
@ -1853,9 +1852,8 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
delayKey, paymentKey, revocationKey *btcec.PublicKey
|
delay uint32
|
||||||
delay uint32
|
delayBalance, p2wkhBalance btcutil.Amount
|
||||||
delayBalance, p2wkhBalance btcutil.Amount
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// We'll now compute the delay, payment and revocation key based on the
|
// We'll now compute the delay, payment and revocation key based on the
|
||||||
@ -1864,40 +1862,20 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
|||||||
// revocation key, we take the opposite party's revocation base point
|
// revocation key, we take the opposite party's revocation base point
|
||||||
// and combine that with the current commitment point.
|
// and combine that with the current commitment point.
|
||||||
if remoteChain {
|
if remoteChain {
|
||||||
delayKey = TweakPubKey(lc.remoteChanCfg.DelayBasePoint,
|
|
||||||
commitPoint)
|
|
||||||
paymentKey = TweakPubKey(lc.localChanCfg.PaymentBasePoint,
|
|
||||||
commitPoint)
|
|
||||||
revocationKey = DeriveRevocationPubkey(
|
|
||||||
lc.localChanCfg.RevocationBasePoint,
|
|
||||||
commitPoint,
|
|
||||||
)
|
|
||||||
|
|
||||||
delay = uint32(lc.remoteChanCfg.CsvDelay)
|
delay = uint32(lc.remoteChanCfg.CsvDelay)
|
||||||
delayBalance = theirBalance.ToSatoshis()
|
delayBalance = theirBalance.ToSatoshis()
|
||||||
p2wkhBalance = ourBalance.ToSatoshis()
|
p2wkhBalance = ourBalance.ToSatoshis()
|
||||||
} else {
|
} else {
|
||||||
delayKey = TweakPubKey(lc.localChanCfg.DelayBasePoint,
|
|
||||||
commitPoint)
|
|
||||||
paymentKey = TweakPubKey(lc.remoteChanCfg.PaymentBasePoint,
|
|
||||||
commitPoint)
|
|
||||||
revocationKey = DeriveRevocationPubkey(
|
|
||||||
lc.remoteChanCfg.RevocationBasePoint,
|
|
||||||
commitPoint,
|
|
||||||
)
|
|
||||||
|
|
||||||
delay = uint32(lc.localChanCfg.CsvDelay)
|
delay = uint32(lc.localChanCfg.CsvDelay)
|
||||||
delayBalance = ourBalance.ToSatoshis()
|
delayBalance = ourBalance.ToSatoshis()
|
||||||
p2wkhBalance = theirBalance.ToSatoshis()
|
p2wkhBalance = theirBalance.ToSatoshis()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef); create all keys unconditionally within commitment
|
|
||||||
// store in commitment, will need all when doing HTLC's
|
|
||||||
|
|
||||||
// Generate a new commitment transaction with all the latest
|
// Generate a new commitment transaction with all the latest
|
||||||
// unsettled/un-timed out HTLCs.
|
// unsettled/un-timed out HTLCs.
|
||||||
commitTx, err := CreateCommitTx(lc.fundingTxIn, delayKey, paymentKey,
|
commitTx, err := CreateCommitTx(lc.fundingTxIn, keyRing.delayKey,
|
||||||
revocationKey, delay, delayBalance, p2wkhBalance, dustLimit)
|
keyRing.paymentKey, keyRing.revocationKey, delay, delayBalance,
|
||||||
|
p2wkhBalance, dustLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1906,17 +1884,14 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
|||||||
// Each output includes an off-chain 2-of-2 covenant clause, so we'll
|
// Each output includes an off-chain 2-of-2 covenant clause, so we'll
|
||||||
// need the objective local/remote keys for this particular commitment
|
// need the objective local/remote keys for this particular commitment
|
||||||
// as well.
|
// as well.
|
||||||
// TODO(roasbeef): could avoid computing them both here
|
|
||||||
localKey := TweakPubKey(lc.localChanCfg.PaymentBasePoint, commitPoint)
|
|
||||||
remoteKey := TweakPubKey(lc.remoteChanCfg.PaymentBasePoint, commitPoint)
|
|
||||||
for _, htlc := range filteredHTLCView.ourUpdates {
|
for _, htlc := range filteredHTLCView.ourUpdates {
|
||||||
if htlcIsDust(false, !remoteChain, feePerKw,
|
if htlcIsDust(false, !remoteChain, feePerKw,
|
||||||
htlc.Amount.ToSatoshis(), dustLimit) {
|
htlc.Amount.ToSatoshis(), dustLimit) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err := lc.addHTLC(commitTx, ourCommitTx, false, htlc, localKey,
|
err := lc.addHTLC(commitTx, ourCommitTx, false, htlc, keyRing.localKey,
|
||||||
remoteKey, revocationKey)
|
keyRing.remoteKey, keyRing.revocationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1927,8 +1902,8 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err := lc.addHTLC(commitTx, ourCommitTx, true, htlc, localKey,
|
err := lc.addHTLC(commitTx, ourCommitTx, true, htlc, keyRing.localKey,
|
||||||
remoteKey, revocationKey)
|
keyRing.remoteKey, keyRing.revocationKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -2156,26 +2131,10 @@ func processRemoveEntry(htlc *PaymentDescriptor, ourBalance,
|
|||||||
// generating a new commitment for the remote party. The jobs generated by the
|
// generating a new commitment for the remote party. The jobs generated by the
|
||||||
// signature can be submitted to the sigPool to generate all the signatures
|
// signature can be submitted to the sigPool to generate all the signatures
|
||||||
// asynchronously and in parallel.
|
// asynchronously and in parallel.
|
||||||
//
|
func genRemoteHtlcSigJobs(keyRing *commitmentKeyRing,
|
||||||
// TODO(roasbeef): all keys will eventually be generated within the commitment
|
|
||||||
// itself
|
|
||||||
func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey,
|
|
||||||
localChanCfg, remoteChanCfg *channeldb.ChannelConfig,
|
localChanCfg, remoteChanCfg *channeldb.ChannelConfig,
|
||||||
remoteCommitView *commitment) ([]signJob, chan struct{}, error) {
|
remoteCommitView *commitment) ([]signJob, chan struct{}, error) {
|
||||||
|
|
||||||
// First, we'll generate all the keys required to generate the scripts
|
|
||||||
// for each HTLC output and transaction.
|
|
||||||
//
|
|
||||||
// TODO(roabseef): avoid re-calculating, put in commitment struct?
|
|
||||||
commitTweak := SingleTweakBytes(commitPoint,
|
|
||||||
localChanCfg.PaymentBasePoint)
|
|
||||||
revocationKey := DeriveRevocationPubkey(
|
|
||||||
localChanCfg.RevocationBasePoint,
|
|
||||||
commitPoint,
|
|
||||||
)
|
|
||||||
remoteDelayKey := TweakPubKey(remoteChanCfg.DelayBasePoint,
|
|
||||||
commitPoint)
|
|
||||||
|
|
||||||
txHash := remoteCommitView.txn.TxHash()
|
txHash := remoteCommitView.txn.TxHash()
|
||||||
dustLimit := localChanCfg.DustLimit
|
dustLimit := localChanCfg.DustLimit
|
||||||
feePerKw := remoteCommitView.feePerKw
|
feePerKw := remoteCommitView.feePerKw
|
||||||
@ -2221,7 +2180,7 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey,
|
|||||||
}
|
}
|
||||||
sigJob.tx, err = createHtlcTimeoutTx(op, outputAmt,
|
sigJob.tx, err = createHtlcTimeoutTx(op, outputAmt,
|
||||||
htlc.Timeout, uint32(remoteChanCfg.CsvDelay),
|
htlc.Timeout, uint32(remoteChanCfg.CsvDelay),
|
||||||
revocationKey, remoteDelayKey)
|
keyRing.revocationKey, keyRing.delayKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -2231,7 +2190,7 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey,
|
|||||||
// transaction. Note we use the raw HTLC amount.
|
// transaction. Note we use the raw HTLC amount.
|
||||||
sigJob.signDesc = SignDescriptor{
|
sigJob.signDesc = SignDescriptor{
|
||||||
PubKey: localChanCfg.PaymentBasePoint,
|
PubKey: localChanCfg.PaymentBasePoint,
|
||||||
SingleTweak: commitTweak,
|
SingleTweak: keyRing.localKeyTweak,
|
||||||
WitnessScript: htlc.theirWitnessScript,
|
WitnessScript: htlc.theirWitnessScript,
|
||||||
Output: &wire.TxOut{
|
Output: &wire.TxOut{
|
||||||
Value: int64(htlc.Amount.ToSatoshis()),
|
Value: int64(htlc.Amount.ToSatoshis()),
|
||||||
@ -2270,8 +2229,8 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey,
|
|||||||
Index: uint32(htlc.remoteOutputIndex),
|
Index: uint32(htlc.remoteOutputIndex),
|
||||||
}
|
}
|
||||||
sigJob.tx, err = createHtlcSuccessTx(op, outputAmt,
|
sigJob.tx, err = createHtlcSuccessTx(op, outputAmt,
|
||||||
uint32(remoteChanCfg.CsvDelay), revocationKey,
|
uint32(remoteChanCfg.CsvDelay), keyRing.revocationKey,
|
||||||
remoteDelayKey)
|
keyRing.delayKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -2281,7 +2240,7 @@ func genRemoteHtlcSigJobs(commitPoint *btcec.PublicKey,
|
|||||||
// transaction. Note we use the raw HTLC amount.
|
// transaction. Note we use the raw HTLC amount.
|
||||||
sigJob.signDesc = SignDescriptor{
|
sigJob.signDesc = SignDescriptor{
|
||||||
PubKey: localChanCfg.PaymentBasePoint,
|
PubKey: localChanCfg.PaymentBasePoint,
|
||||||
SingleTweak: commitTweak,
|
SingleTweak: keyRing.localKeyTweak,
|
||||||
WitnessScript: htlc.theirWitnessScript,
|
WitnessScript: htlc.theirWitnessScript,
|
||||||
Output: &wire.TxOut{
|
Output: &wire.TxOut{
|
||||||
Value: int64(htlc.Amount.ToSatoshis()),
|
Value: int64(htlc.Amount.ToSatoshis()),
|
||||||
@ -2333,6 +2292,8 @@ func (lc *LightningChannel) SignNextCommitment() (*btcec.Signature, []*btcec.Sig
|
|||||||
// used within fetchCommitmentView to derive all the keys necessary to
|
// used within fetchCommitmentView to derive all the keys necessary to
|
||||||
// construct the commitment state.
|
// construct the commitment state.
|
||||||
commitPoint := lc.channelState.RemoteNextRevocation
|
commitPoint := lc.channelState.RemoteNextRevocation
|
||||||
|
keyRing := deriveCommitmentKeys(commitPoint, false, lc.localChanCfg,
|
||||||
|
lc.remoteChanCfg)
|
||||||
|
|
||||||
// Create a new commitment view which will calculate the evaluated
|
// Create a new commitment view which will calculate the evaluated
|
||||||
// state of the remote node's new commitment including our latest added
|
// state of the remote node's new commitment including our latest added
|
||||||
@ -2342,8 +2303,7 @@ func (lc *LightningChannel) SignNextCommitment() (*btcec.Signature, []*btcec.Sig
|
|||||||
// _all_ of our changes (pending or committed) but only the remote
|
// _all_ of our changes (pending or committed) but only the remote
|
||||||
// node's changes up to the last change we've ACK'd.
|
// node's changes up to the last change we've ACK'd.
|
||||||
newCommitView, err := lc.fetchCommitmentView(true,
|
newCommitView, err := lc.fetchCommitmentView(true,
|
||||||
lc.localUpdateLog.logIndex, lc.remoteUpdateLog.ackedIndex,
|
lc.localUpdateLog.logIndex, lc.remoteUpdateLog.ackedIndex, keyRing)
|
||||||
commitPoint)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -2364,7 +2324,7 @@ func (lc *LightningChannel) SignNextCommitment() (*btcec.Signature, []*btcec.Sig
|
|||||||
// need to generate signatures of each of them for the remote party's
|
// need to generate signatures of each of them for the remote party's
|
||||||
// commitment state. We do so in two phases: first we generate and
|
// commitment state. We do so in two phases: first we generate and
|
||||||
// submit the set of signature jobs to the worker pool.
|
// submit the set of signature jobs to the worker pool.
|
||||||
sigBatch, cancelChan, err := genRemoteHtlcSigJobs(commitPoint,
|
sigBatch, cancelChan, err := genRemoteHtlcSigJobs(keyRing,
|
||||||
lc.localChanCfg, lc.remoteChanCfg, newCommitView,
|
lc.localChanCfg, lc.remoteChanCfg, newCommitView,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2507,7 +2467,7 @@ func (lc *LightningChannel) validateCommitmentSanity(theirLogCounter,
|
|||||||
// commitment state. The jobs generated are fully populated, and can be sent
|
// commitment state. The jobs generated are fully populated, and can be sent
|
||||||
// directly into the pool of workers.
|
// directly into the pool of workers.
|
||||||
func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
||||||
commitPoint *btcec.PublicKey, htlcSigs []*btcec.Signature,
|
keyRing *commitmentKeyRing, htlcSigs []*btcec.Signature,
|
||||||
localChanCfg, remoteChanCfg *channeldb.ChannelConfig) []verifyJob {
|
localChanCfg, remoteChanCfg *channeldb.ChannelConfig) []verifyJob {
|
||||||
|
|
||||||
// If this new commitment state doesn't have any HTLC's that are to be
|
// If this new commitment state doesn't have any HTLC's that are to be
|
||||||
@ -2516,16 +2476,6 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, we'll re-derive the keys necessary to reconstruct the HTLC
|
|
||||||
// output and transaction state.
|
|
||||||
remoteKey := TweakPubKey(remoteChanCfg.PaymentBasePoint, commitPoint)
|
|
||||||
revocationKey := DeriveRevocationPubkey(
|
|
||||||
remoteChanCfg.RevocationBasePoint,
|
|
||||||
commitPoint,
|
|
||||||
)
|
|
||||||
localDelayKey := TweakPubKey(localChanCfg.DelayBasePoint,
|
|
||||||
commitPoint)
|
|
||||||
|
|
||||||
txHash := localCommitmentView.txn.TxHash()
|
txHash := localCommitmentView.txn.TxHash()
|
||||||
feePerKw := localCommitmentView.feePerKw
|
feePerKw := localCommitmentView.feePerKw
|
||||||
|
|
||||||
@ -2565,7 +2515,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
|||||||
|
|
||||||
successTx, err := createHtlcSuccessTx(op,
|
successTx, err := createHtlcSuccessTx(op,
|
||||||
outputAmt, uint32(localChanCfg.CsvDelay),
|
outputAmt, uint32(localChanCfg.CsvDelay),
|
||||||
revocationKey, localDelayKey)
|
keyRing.revocationKey, keyRing.delayKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -2606,7 +2556,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
|||||||
timeoutTx, err := createHtlcTimeoutTx(op,
|
timeoutTx, err := createHtlcTimeoutTx(op,
|
||||||
outputAmt, htlc.Timeout,
|
outputAmt, htlc.Timeout,
|
||||||
uint32(localChanCfg.CsvDelay),
|
uint32(localChanCfg.CsvDelay),
|
||||||
revocationKey, localDelayKey,
|
keyRing.revocationKey, keyRing.delayKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -2635,7 +2585,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
|
|||||||
}
|
}
|
||||||
|
|
||||||
verifyJobs = append(verifyJobs, verifyJob{
|
verifyJobs = append(verifyJobs, verifyJob{
|
||||||
pubKey: remoteKey,
|
pubKey: keyRing.remoteKey,
|
||||||
sig: htlcSigs[i],
|
sig: htlcSigs[i],
|
||||||
sigHash: sigHash,
|
sigHash: sigHash,
|
||||||
})
|
})
|
||||||
@ -2679,13 +2629,14 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSig *btcec.Signature,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
commitPoint := ComputeCommitmentPoint(commitSecret[:])
|
commitPoint := ComputeCommitmentPoint(commitSecret[:])
|
||||||
|
keyRing := deriveCommitmentKeys(commitPoint, true, lc.localChanCfg,
|
||||||
|
lc.remoteChanCfg)
|
||||||
|
|
||||||
// With the current commitment point re-calculated, construct the new
|
// With the current commitment point re-calculated, construct the new
|
||||||
// commitment view which includes all the entries we know of in their
|
// commitment view which includes all the entries we know of in their
|
||||||
// HTLC log, and up to ourLogIndex in our HTLC log.
|
// HTLC log, and up to ourLogIndex in our HTLC log.
|
||||||
localCommitmentView, err := lc.fetchCommitmentView(false,
|
localCommitmentView, err := lc.fetchCommitmentView(false,
|
||||||
lc.localUpdateLog.ackedIndex, lc.remoteUpdateLog.logIndex,
|
lc.localUpdateLog.ackedIndex, lc.remoteUpdateLog.logIndex, keyRing)
|
||||||
commitPoint)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -2719,8 +2670,7 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSig *btcec.Signature,
|
|||||||
// pool to verify each of the HTLc signatures presented. Once
|
// pool to verify each of the HTLc signatures presented. Once
|
||||||
// generated, we'll submit these jobs to the worker pool.
|
// generated, we'll submit these jobs to the worker pool.
|
||||||
verifyJobs := genHtlcSigValidationJobs(localCommitmentView,
|
verifyJobs := genHtlcSigValidationJobs(localCommitmentView,
|
||||||
commitPoint,
|
keyRing, htlcSigs, lc.localChanCfg, lc.remoteChanCfg)
|
||||||
htlcSigs, lc.localChanCfg, lc.remoteChanCfg)
|
|
||||||
cancelChan := make(chan struct{})
|
cancelChan := make(chan struct{})
|
||||||
verifyResps := lc.sigPool.SubmitVerifyBatch(verifyJobs, cancelChan)
|
verifyResps := lc.sigPool.SubmitVerifyBatch(verifyJobs, cancelChan)
|
||||||
|
|
||||||
@ -3413,9 +3363,9 @@ type OutgoingHtlcResolution struct {
|
|||||||
// caller to sweep an outgoing HTLC present on either their, or the remote
|
// caller to sweep an outgoing HTLC present on either their, or the remote
|
||||||
// party's commitment transaction.
|
// party's commitment transaction.
|
||||||
func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig,
|
func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig,
|
||||||
commitHash chainhash.Hash, htlc *channeldb.HTLC, commitPoint,
|
commitHash chainhash.Hash, htlc *channeldb.HTLC, keyRing *commitmentKeyRing,
|
||||||
delayKey, localKey, remoteKey *btcec.PublicKey, revokeKey *btcec.PublicKey,
|
feePewKw, dustLimit btcutil.Amount, csvDelay uint32,
|
||||||
feePewKw, dustLimit btcutil.Amount, csvDelay uint32) (*OutgoingHtlcResolution, error) {
|
) (*OutgoingHtlcResolution, error) {
|
||||||
|
|
||||||
op := wire.OutPoint{
|
op := wire.OutPoint{
|
||||||
Hash: commitHash,
|
Hash: commitHash,
|
||||||
@ -3432,7 +3382,7 @@ func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig,
|
|||||||
// transaction.
|
// transaction.
|
||||||
timeoutTx, err := createHtlcTimeoutTx(
|
timeoutTx, err := createHtlcTimeoutTx(
|
||||||
op, secondLevelOutputAmt, htlc.RefundTimeout, csvDelay,
|
op, secondLevelOutputAmt, htlc.RefundTimeout, csvDelay,
|
||||||
revokeKey, delayKey,
|
keyRing.revocationKey, keyRing.delayKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -3441,16 +3391,14 @@ func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig,
|
|||||||
// With the transaction created, we can generate a sign descriptor
|
// With the transaction created, we can generate a sign descriptor
|
||||||
// that's capable of generating the signature required to spend the
|
// that's capable of generating the signature required to spend the
|
||||||
// HTLC output using the timeout transaction.
|
// HTLC output using the timeout transaction.
|
||||||
htlcCreationScript, err := senderHTLCScript(localKey, remoteKey,
|
htlcCreationScript, err := senderHTLCScript(keyRing.localKey,
|
||||||
revokeKey, htlc.RHash[:])
|
keyRing.remoteKey, keyRing.revocationKey, htlc.RHash[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
timeoutTweak := SingleTweakBytes(commitPoint,
|
|
||||||
localChanCfg.PaymentBasePoint)
|
|
||||||
timeoutSignDesc := SignDescriptor{
|
timeoutSignDesc := SignDescriptor{
|
||||||
PubKey: localChanCfg.PaymentBasePoint,
|
PubKey: localChanCfg.PaymentBasePoint,
|
||||||
SingleTweak: timeoutTweak,
|
SingleTweak: keyRing.localKeyTweak,
|
||||||
WitnessScript: htlcCreationScript,
|
WitnessScript: htlcCreationScript,
|
||||||
Output: &wire.TxOut{
|
Output: &wire.TxOut{
|
||||||
Value: int64(htlc.Amt.ToSatoshis()),
|
Value: int64(htlc.Amt.ToSatoshis()),
|
||||||
@ -3473,7 +3421,7 @@ func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig,
|
|||||||
// transaction creates so we can generate the signDesc required to
|
// transaction creates so we can generate the signDesc required to
|
||||||
// complete the claim process after a delay period.
|
// complete the claim process after a delay period.
|
||||||
htlcSweepScript, err := secondLevelHtlcScript(
|
htlcSweepScript, err := secondLevelHtlcScript(
|
||||||
revokeKey, delayKey, csvDelay,
|
keyRing.revocationKey, keyRing.delayKey, csvDelay,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -3483,14 +3431,15 @@ func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
delayTweak := SingleTweakBytes(commitPoint,
|
// TODO: Signing with the delay key is wrong for remote commitments
|
||||||
|
localDelayTweak := SingleTweakBytes(keyRing.commitPoint,
|
||||||
localChanCfg.DelayBasePoint)
|
localChanCfg.DelayBasePoint)
|
||||||
return &OutgoingHtlcResolution{
|
return &OutgoingHtlcResolution{
|
||||||
Expiry: htlc.RefundTimeout,
|
Expiry: htlc.RefundTimeout,
|
||||||
SignedTimeoutTx: timeoutTx,
|
SignedTimeoutTx: timeoutTx,
|
||||||
SweepSignDesc: SignDescriptor{
|
SweepSignDesc: SignDescriptor{
|
||||||
PubKey: localChanCfg.DelayBasePoint,
|
PubKey: localChanCfg.DelayBasePoint,
|
||||||
SingleTweak: delayTweak,
|
SingleTweak: localDelayTweak,
|
||||||
WitnessScript: htlcSweepScript,
|
WitnessScript: htlcSweepScript,
|
||||||
Output: &wire.TxOut{
|
Output: &wire.TxOut{
|
||||||
PkScript: htlcScriptHash,
|
PkScript: htlcScriptHash,
|
||||||
@ -3505,17 +3454,9 @@ func newHtlcResolution(signer Signer, localChanCfg *channeldb.ChannelConfig,
|
|||||||
// the local key used when generating the HTLC scrips. This function is to be
|
// the local key used when generating the HTLC scrips. This function is to be
|
||||||
// used in two cases: force close, or a unilateral close.
|
// used in two cases: force close, or a unilateral close.
|
||||||
func extractHtlcResolutions(feePerKw btcutil.Amount, ourCommit bool,
|
func extractHtlcResolutions(feePerKw btcutil.Amount, ourCommit bool,
|
||||||
signer Signer, htlcs []*channeldb.HTLC,
|
signer Signer, htlcs []*channeldb.HTLC, keyRing *commitmentKeyRing,
|
||||||
commitPoint, revokeKey *btcec.PublicKey,
|
|
||||||
localChanCfg, remoteChanCfg *channeldb.ChannelConfig,
|
localChanCfg, remoteChanCfg *channeldb.ChannelConfig,
|
||||||
commitHash chainhash.Hash) ([]OutgoingHtlcResolution, *btcec.PublicKey, error) {
|
commitHash chainhash.Hash) ([]OutgoingHtlcResolution, error) {
|
||||||
|
|
||||||
// As uusal, we start by re-generating the key-ring required to
|
|
||||||
// reconstruct the pkScripts used, and sign any transactions or inputs
|
|
||||||
// required to sweep all funds.
|
|
||||||
localKey := TweakPubKey(localChanCfg.PaymentBasePoint, commitPoint)
|
|
||||||
delayKey := TweakPubKey(localChanCfg.DelayBasePoint, commitPoint)
|
|
||||||
remoteKey := TweakPubKey(remoteChanCfg.PaymentBasePoint, commitPoint)
|
|
||||||
|
|
||||||
dustLimit := remoteChanCfg.DustLimit
|
dustLimit := remoteChanCfg.DustLimit
|
||||||
csvDelay := remoteChanCfg.CsvDelay
|
csvDelay := remoteChanCfg.CsvDelay
|
||||||
@ -3542,19 +3483,18 @@ func extractHtlcResolutions(feePerKw btcutil.Amount, ourCommit bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ohr, err := newHtlcResolution(
|
ohr, err := newHtlcResolution(
|
||||||
signer, localChanCfg, commitHash, htlc, commitPoint,
|
signer, localChanCfg, commitHash, htlc, keyRing,
|
||||||
delayKey, localKey, remoteKey, revokeKey, feePerKw,
|
feePerKw, dustLimit, uint32(csvDelay),
|
||||||
dustLimit, uint32(csvDelay),
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): needs to point to proper amount including
|
// TODO(roasbeef): needs to point to proper amount including
|
||||||
htlcResolutions = append(htlcResolutions, *ohr)
|
htlcResolutions = append(htlcResolutions, *ohr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return htlcResolutions, localKey, nil
|
return htlcResolutions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForceCloseSummary describes the final commitment state before the channel is
|
// ForceCloseSummary describes the final commitment state before the channel is
|
||||||
@ -3628,12 +3568,10 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
commitPoint := ComputeCommitmentPoint(unusedRevocation[:])
|
commitPoint := ComputeCommitmentPoint(unusedRevocation[:])
|
||||||
revokeKey := DeriveRevocationPubkey(
|
keyRing := deriveCommitmentKeys(commitPoint, true, lc.localChanCfg,
|
||||||
lc.remoteChanCfg.RevocationBasePoint,
|
lc.remoteChanCfg)
|
||||||
commitPoint,
|
selfScript, err := commitScriptToSelf(csvTimeout, keyRing.delayKey,
|
||||||
)
|
keyRing.revocationKey)
|
||||||
delayKey := TweakPubKey(lc.localChanCfg.DelayBasePoint, commitPoint)
|
|
||||||
selfScript, err := commitScriptToSelf(csvTimeout, delayKey, revokeKey)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -3685,9 +3623,9 @@ func (lc *LightningChannel) ForceClose() (*ForceCloseSummary, error) {
|
|||||||
// need to create a series of sign descriptors for any lingering
|
// need to create a series of sign descriptors for any lingering
|
||||||
// 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(
|
||||||
lc.channelState.FeePerKw, true, lc.signer, lc.channelState.Htlcs,
|
lc.channelState.FeePerKw, true, lc.signer, lc.channelState.Htlcs,
|
||||||
commitPoint, revokeKey, lc.localChanCfg, lc.remoteChanCfg, txHash)
|
keyRing, lc.localChanCfg, lc.remoteChanCfg, txHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -4009,3 +3947,38 @@ func (lc *LightningChannel) RemoteNextRevocation() *btcec.PublicKey {
|
|||||||
|
|
||||||
return lc.channelState.RemoteNextRevocation
|
return lc.channelState.RemoteNextRevocation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deriveCommitmentKey generates a new commitment key set using the base points
|
||||||
|
// and commitment point. The keys are derived differently depending whether the
|
||||||
|
// commitment transaction is ours or the remote peer's.
|
||||||
|
func deriveCommitmentKeys(commitPoint *btcec.PublicKey, isOurCommit bool,
|
||||||
|
localChanCfg, remoteChanCfg *channeldb.ChannelConfig) *commitmentKeyRing {
|
||||||
|
keyRing := new(commitmentKeyRing)
|
||||||
|
|
||||||
|
keyRing.commitPoint = commitPoint
|
||||||
|
keyRing.localKeyTweak = SingleTweakBytes(commitPoint,
|
||||||
|
localChanCfg.PaymentBasePoint)
|
||||||
|
keyRing.localKey = TweakPubKeyWithTweak(localChanCfg.PaymentBasePoint,
|
||||||
|
keyRing.localKeyTweak)
|
||||||
|
keyRing.remoteKey = TweakPubKey(remoteChanCfg.PaymentBasePoint, commitPoint)
|
||||||
|
|
||||||
|
// We'll now compute the delay, payment and revocation key based on the
|
||||||
|
// current commitment point. All keys are tweaked each state in order
|
||||||
|
// to ensure the keys from each state are unlinkable. TO create the
|
||||||
|
// revocation key, we take the opposite party's revocation base point
|
||||||
|
// and combine that with the current commitment point.
|
||||||
|
var delayBasePoint, revocationBasePoint *btcec.PublicKey
|
||||||
|
if isOurCommit {
|
||||||
|
keyRing.paymentKey = keyRing.remoteKey
|
||||||
|
delayBasePoint = localChanCfg.DelayBasePoint
|
||||||
|
revocationBasePoint = remoteChanCfg.RevocationBasePoint
|
||||||
|
} else {
|
||||||
|
keyRing.paymentKey = keyRing.localKey
|
||||||
|
delayBasePoint = remoteChanCfg.DelayBasePoint
|
||||||
|
revocationBasePoint = localChanCfg.RevocationBasePoint
|
||||||
|
}
|
||||||
|
keyRing.delayKey = TweakPubKey(delayBasePoint, commitPoint)
|
||||||
|
keyRing.revocationKey = DeriveRevocationPubkey(revocationBasePoint, commitPoint)
|
||||||
|
|
||||||
|
return keyRing
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user