Skip to content

Commit e8c5e7d

Browse files
authored
Merge pull request #9044 from ProofOfKeags/refactor/stfu-prefactor
Refactor/stfu prefactor
2 parents 54eeb0e + 1422729 commit e8c5e7d

File tree

3 files changed

+474
-413
lines changed

3 files changed

+474
-413
lines changed

htlcswitch/link.go

Lines changed: 92 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ func (l *channelLink) resolveFwdPkgs() error {
958958

959959
// If any of our reprocessing steps require an update to the commitment
960960
// txn, we initiate a state transition to capture all relevant changes.
961-
if l.channel.PendingLocalUpdateCount() > 0 {
961+
if l.channel.NumPendingUpdates(lntypes.Local, lntypes.Remote) > 0 {
962962
return l.updateCommitTx()
963963
}
964964

@@ -1086,6 +1086,83 @@ func (l *channelLink) loadAndRemove() error {
10861086
return l.channel.RemoveFwdPkgs(removeHeights...)
10871087
}
10881088

1089+
// handleChanSyncErr performs the error handling logic in the case where we
1090+
// could not successfully syncChanStates with our channel peer.
1091+
func (l *channelLink) handleChanSyncErr(err error) {
1092+
l.log.Warnf("error when syncing channel states: %v", err)
1093+
1094+
var errDataLoss *lnwallet.ErrCommitSyncLocalDataLoss
1095+
1096+
switch {
1097+
case errors.Is(err, ErrLinkShuttingDown):
1098+
l.log.Debugf("unable to sync channel states, link is " +
1099+
"shutting down")
1100+
return
1101+
1102+
// We failed syncing the commit chains, probably because the remote has
1103+
// lost state. We should force close the channel.
1104+
case errors.Is(err, lnwallet.ErrCommitSyncRemoteDataLoss):
1105+
fallthrough
1106+
1107+
// The remote sent us an invalid last commit secret, we should force
1108+
// close the channel.
1109+
// TODO(halseth): and permanently ban the peer?
1110+
case errors.Is(err, lnwallet.ErrInvalidLastCommitSecret):
1111+
fallthrough
1112+
1113+
// The remote sent us a commit point different from what they sent us
1114+
// before.
1115+
// TODO(halseth): ban peer?
1116+
case errors.Is(err, lnwallet.ErrInvalidLocalUnrevokedCommitPoint):
1117+
// We'll fail the link and tell the peer to force close the
1118+
// channel. Note that the database state is not updated here,
1119+
// but will be updated when the close transaction is ready to
1120+
// avoid that we go down before storing the transaction in the
1121+
// db.
1122+
l.failf(
1123+
LinkFailureError{
1124+
code: ErrSyncError,
1125+
FailureAction: LinkFailureForceClose,
1126+
},
1127+
"unable to synchronize channel states: %v", err,
1128+
)
1129+
1130+
// We have lost state and cannot safely force close the channel. Fail
1131+
// the channel and wait for the remote to hopefully force close it. The
1132+
// remote has sent us its latest unrevoked commitment point, and we'll
1133+
// store it in the database, such that we can attempt to recover the
1134+
// funds if the remote force closes the channel.
1135+
case errors.As(err, &errDataLoss):
1136+
err := l.channel.MarkDataLoss(
1137+
errDataLoss.CommitPoint,
1138+
)
1139+
if err != nil {
1140+
l.log.Errorf("unable to mark channel data loss: %v",
1141+
err)
1142+
}
1143+
1144+
// We determined the commit chains were not possible to sync. We
1145+
// cautiously fail the channel, but don't force close.
1146+
// TODO(halseth): can we safely force close in any cases where this
1147+
// error is returned?
1148+
case errors.Is(err, lnwallet.ErrCannotSyncCommitChains):
1149+
if err := l.channel.MarkBorked(); err != nil {
1150+
l.log.Errorf("unable to mark channel borked: %v", err)
1151+
}
1152+
1153+
// Other, unspecified error.
1154+
default:
1155+
}
1156+
1157+
l.failf(
1158+
LinkFailureError{
1159+
code: ErrRecoveryError,
1160+
FailureAction: LinkFailureForceNone,
1161+
},
1162+
"unable to synchronize channel states: %v", err,
1163+
)
1164+
}
1165+
10891166
// htlcManager is the primary goroutine which drives a channel's commitment
10901167
// update state-machine in response to messages received via several channels.
10911168
// This goroutine reads messages from the upstream (remote) peer, and also from
@@ -1121,89 +1198,7 @@ func (l *channelLink) htlcManager() {
11211198
if l.cfg.SyncStates {
11221199
err := l.syncChanStates()
11231200
if err != nil {
1124-
l.log.Warnf("error when syncing channel states: %v", err)
1125-
1126-
errDataLoss, localDataLoss :=
1127-
err.(*lnwallet.ErrCommitSyncLocalDataLoss)
1128-
1129-
switch {
1130-
case err == ErrLinkShuttingDown:
1131-
l.log.Debugf("unable to sync channel states, " +
1132-
"link is shutting down")
1133-
return
1134-
1135-
// We failed syncing the commit chains, probably
1136-
// because the remote has lost state. We should force
1137-
// close the channel.
1138-
case err == lnwallet.ErrCommitSyncRemoteDataLoss:
1139-
fallthrough
1140-
1141-
// The remote sent us an invalid last commit secret, we
1142-
// should force close the channel.
1143-
// TODO(halseth): and permanently ban the peer?
1144-
case err == lnwallet.ErrInvalidLastCommitSecret:
1145-
fallthrough
1146-
1147-
// The remote sent us a commit point different from
1148-
// what they sent us before.
1149-
// TODO(halseth): ban peer?
1150-
case err == lnwallet.ErrInvalidLocalUnrevokedCommitPoint:
1151-
// We'll fail the link and tell the peer to
1152-
// force close the channel. Note that the
1153-
// database state is not updated here, but will
1154-
// be updated when the close transaction is
1155-
// ready to avoid that we go down before
1156-
// storing the transaction in the db.
1157-
l.failf(
1158-
//nolint:lll
1159-
LinkFailureError{
1160-
code: ErrSyncError,
1161-
FailureAction: LinkFailureForceClose,
1162-
},
1163-
"unable to synchronize channel "+
1164-
"states: %v", err,
1165-
)
1166-
return
1167-
1168-
// We have lost state and cannot safely force close the
1169-
// channel. Fail the channel and wait for the remote to
1170-
// hopefully force close it. The remote has sent us its
1171-
// latest unrevoked commitment point, and we'll store
1172-
// it in the database, such that we can attempt to
1173-
// recover the funds if the remote force closes the
1174-
// channel.
1175-
case localDataLoss:
1176-
err := l.channel.MarkDataLoss(
1177-
errDataLoss.CommitPoint,
1178-
)
1179-
if err != nil {
1180-
l.log.Errorf("unable to mark channel "+
1181-
"data loss: %v", err)
1182-
}
1183-
1184-
// We determined the commit chains were not possible to
1185-
// sync. We cautiously fail the channel, but don't
1186-
// force close.
1187-
// TODO(halseth): can we safely force close in any
1188-
// cases where this error is returned?
1189-
case err == lnwallet.ErrCannotSyncCommitChains:
1190-
if err := l.channel.MarkBorked(); err != nil {
1191-
l.log.Errorf("unable to mark channel "+
1192-
"borked: %v", err)
1193-
}
1194-
1195-
// Other, unspecified error.
1196-
default:
1197-
}
1198-
1199-
l.failf(
1200-
LinkFailureError{
1201-
code: ErrRecoveryError,
1202-
FailureAction: LinkFailureForceNone,
1203-
},
1204-
"unable to synchronize channel "+
1205-
"states: %v", err,
1206-
)
1201+
l.handleChanSyncErr(err)
12071202
return
12081203
}
12091204
}
@@ -1291,15 +1286,19 @@ func (l *channelLink) htlcManager() {
12911286
// the batch ticker so that it can be cleared. Otherwise pause
12921287
// the ticker to prevent waking up the htlcManager while the
12931288
// batch is empty.
1294-
if l.channel.PendingLocalUpdateCount() > 0 {
1289+
numUpdates := l.channel.NumPendingUpdates(
1290+
lntypes.Local, lntypes.Remote,
1291+
)
1292+
if numUpdates > 0 {
12951293
l.cfg.BatchTicker.Resume()
12961294
l.log.Tracef("BatchTicker resumed, "+
1297-
"PendingLocalUpdateCount=%d",
1298-
l.channel.PendingLocalUpdateCount())
1295+
"NumPendingUpdates(Local, Remote)=%d",
1296+
numUpdates,
1297+
)
12991298
} else {
13001299
l.cfg.BatchTicker.Pause()
13011300
l.log.Trace("BatchTicker paused due to zero " +
1302-
"PendingLocalUpdateCount")
1301+
"NumPendingUpdates(Local, Remote)")
13031302
}
13041303

13051304
select {
@@ -1657,7 +1656,7 @@ func (l *channelLink) handleDownstreamUpdateAdd(pkt *htlcPacket) error {
16571656
l.log.Tracef("received downstream htlc: payment_hash=%x, "+
16581657
"local_log_index=%v, pend_updates=%v",
16591658
htlc.PaymentHash[:], index,
1660-
l.channel.PendingLocalUpdateCount())
1659+
l.channel.NumPendingUpdates(lntypes.Local, lntypes.Remote))
16611660

16621661
pkt.outgoingChanID = l.ShortChanID()
16631662
pkt.outgoingHTLCID = index
@@ -1863,7 +1862,8 @@ func (l *channelLink) handleDownstreamPkt(pkt *htlcPacket) {
18631862
// tryBatchUpdateCommitTx updates the commitment transaction if the batch is
18641863
// full.
18651864
func (l *channelLink) tryBatchUpdateCommitTx() {
1866-
if l.channel.PendingLocalUpdateCount() < uint64(l.cfg.BatchSize) {
1865+
pending := l.channel.NumPendingUpdates(lntypes.Local, lntypes.Remote)
1866+
if pending < uint64(l.cfg.BatchSize) {
18671867
return
18681868
}
18691869

@@ -1939,7 +1939,6 @@ func (l *channelLink) cleanupSpuriousResponse(pkt *htlcPacket) {
19391939
// direct channel with, updating our respective commitment chains.
19401940
func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
19411941
switch msg := msg.(type) {
1942-
19431942
case *lnwire.UpdateAddHTLC:
19441943
if l.IsFlushing(Incoming) {
19451944
// This is forbidden by the protocol specification.
@@ -2597,9 +2596,9 @@ func (l *channelLink) updateCommitTx() error {
25972596
l.cfg.PendingCommitTicker.Resume()
25982597
l.log.Trace("PendingCommitTicker resumed")
25992598

2599+
n := l.channel.NumPendingUpdates(lntypes.Local, lntypes.Remote)
26002600
l.log.Tracef("revocation window exhausted, unable to send: "+
2601-
"%v, pend_updates=%v, dangling_closes%v",
2602-
l.channel.PendingLocalUpdateCount(),
2601+
"%v, pend_updates=%v, dangling_closes%v", n,
26032602
lnutils.SpewLogClosure(l.openedCircuits),
26042603
lnutils.SpewLogClosure(l.closedCircuits))
26052604

0 commit comments

Comments
 (0)