lnwallet: keep commitments cold at all times, store sig instead

This commit changes prior behavior which stored a “hot” commitment
transaction, meaning one which all the sigScript fully assembled and
able to be broadcast.

Instead, we now store the current signature for our commitment
transaction as a separate field within the database and within memory.
As a result, this eliminates a class of bugs which would erroneously
broadcast a fully loaded commitment transaction, either leading to a
loss of funds, or suspending availability to funds for a period of
time.
This commit is contained in:
Olaoluwa Osuntokun 2016-07-05 16:53:55 -07:00
parent f03122e697
commit 8775107454
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
1 changed files with 12 additions and 4 deletions

View File

@ -853,7 +853,6 @@ func (l *LightningWallet) handleContributionMsg(req *addContributionMsg) {
pendingReservation.partialState.ChanID = fundingOutpoint
pendingReservation.partialState.TheirCommitKey = theirCommitKey
pendingReservation.partialState.TheirMultiSigKey = theirContribution.MultiSigKey
pendingReservation.partialState.TheirCommitTx = theirCommitTx
pendingReservation.partialState.OurCommitTx = ourCommitTx
pendingReservation.ourContribution.RevocationKey = ourRevokeKey
@ -1050,7 +1049,6 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
// Finally, create an instance of a Script VM, and ensure that the
// Script executes succesfully.
// TODO(roasbeef): remove afterwards, should *never* be hot...
commitTx.TxIn[0].Witness = witness
vm, err := txscript.NewEngine(p2wsh,
commitTx, 0, txscript.StandardVerifyFlags, nil,
@ -1064,6 +1062,11 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
return
}
// Strip and store the signature to ensure that our commitment
// transaction doesn't stay hot.
commitTx.TxIn[0].Witness = nil
pendingReservation.partialState.OurCommitSig = theirCommitSig
// Funding complete, this entry can be removed from limbo.
l.limboMtx.Lock()
delete(l.fundingLimbo, pendingReservation.reservationID)
@ -1147,7 +1150,6 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
txsort.InPlaceSort(ourCommitTx)
pendingReservation.partialState.OurCommitTx = ourCommitTx
txsort.InPlaceSort(theirCommitTx)
pendingReservation.partialState.TheirCommitTx = theirCommitTx
// Verify that their signature of valid for our current commitment
// transaction. Re-generate both the redeemScript and p2sh output. We
@ -1184,7 +1186,8 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
// Finally, create an instance of a Script VM, and ensure that the
// Script executes succesfully.
ourCommitTx.TxIn[0].Witness = witness // TODO(roasbeef): don't stay hot!!
ourCommitTx.TxIn[0].Witness = witness
// TODO(roasbeef): replace engine with plain sighash check
vm, err := txscript.NewEngine(p2wsh,
ourCommitTx, 0, txscript.StandardVerifyFlags, nil,
nil, channelValue)
@ -1197,6 +1200,11 @@ func (l *LightningWallet) handleSingleFunderSigs(req *addSingleFunderSigsMsg) {
return
}
// Strip and store the signature to ensure that our commitment
// transaction doesn't stay hot.
ourCommitTx.TxIn[0].Witness = nil
pendingReservation.partialState.OurCommitSig = req.theirCommitmentSig
// With their signature for our version of the commitment transactions
// verified, we can now generate a signature for their version,
// allowing the funding transaction to be safely broadcast.