From 78a4a15bb4221759fe89176a7f72a3fb7d92bc64 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Thu, 12 Jul 2018 11:02:53 +0200 Subject: [PATCH] lnwallet/channel: check validity of received commitPoint This commit adds a check for the LocalUnrevokedCommitPoint sent to us by the remote during channel reestablishment, ensuring it is the same point as they have previously sent us. --- lnwallet/channel.go | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/lnwallet/channel.go b/lnwallet/channel.go index d929e2d9..8cfd60c5 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -3173,8 +3173,6 @@ func (lc *LightningChannel) ProcessChanSyncMsg( } } - // TODO(roasbeef): check validity of commitment point after the fact - // Take note of our current commit chain heights before we begin adding // more to them. var ( @@ -3395,6 +3393,39 @@ func (lc *LightningChannel) ProcessChanSyncMsg( return nil, nil, nil, ErrCannotSyncCommitChains } + // If we didn't have recovery options, then the final check cannot be + // performed, and we'll return early. + if !hasRecoveryOptions { + return updates, openedCircuits, closedCircuits, nil + } + + // At this point we have determined that either the commit heights are + // in sync, or that we are in a state we can recover from. As a final + // check, we ensure that the commitment point sent to us by the remote + // is valid. + var commitPoint *btcec.PublicKey + switch { + case msg.NextLocalCommitHeight == remoteTailHeight+2: + commitPoint = lc.channelState.RemoteNextRevocation + + case msg.NextLocalCommitHeight == remoteTailHeight+1: + commitPoint = lc.channelState.RemoteCurrentRevocation + } + if commitPoint != nil && + !commitPoint.IsEqual(msg.LocalUnrevokedCommitPoint) { + + walletLog.Errorf("ChannelPoint(%v), sync failed: remote "+ + "sent invalid commit point for height %v!", + lc.channelState.FundingOutpoint, + msg.NextLocalCommitHeight) + + if err := lc.channelState.MarkBorked(); err != nil { + return nil, nil, nil, err + } + // TODO(halseth): force close? + return nil, nil, nil, ErrInvalidLocalUnrevokedCommitPoint + } + return updates, openedCircuits, closedCircuits, nil }