mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-04 09:48:19 +01:00
lnwallet: add new modified HTLC index to the updateLog
In this commit, we add a new index to the HTLC log. This new index is meant to ensure that we don't attempt to modify and HTLC twice. An HTLC modification is either a fail or a settle. This is the first in a series of commits to fix an existing bug in the state machine that can cause a panic if a remote node attempts to settle an HTLC twice.
This commit is contained in:
parent
19e826cada
commit
56ebd6de8d
1 changed files with 29 additions and 8 deletions
|
@ -825,7 +825,7 @@ func (lc *LightningChannel) extractPayDescs(commitHeight uint64,
|
|||
return incomingHtlcs, outgoingHtlcs, nil
|
||||
}
|
||||
|
||||
// diskCommitToMemCommit converts tthe on-disk commitment format to our
|
||||
// diskCommitToMemCommit converts the on-disk commitment format to our
|
||||
// in-memory commitment format which is needed in order to properly resume
|
||||
// channel operations after a restart.
|
||||
func (lc *LightningChannel) diskCommitToMemCommit(isLocal, isPendingCommit bool,
|
||||
|
@ -1090,16 +1090,22 @@ type updateLog struct {
|
|||
// offerIndex is an index that maps the counter for offered HTLC's to
|
||||
// their list element within the main list.List.
|
||||
htlcIndex map[uint64]*list.Element
|
||||
|
||||
// modifiedHtlcs is a set that keeps track of all the current modified
|
||||
// htlcs. A modified HTLC is one that's present in the log, and has as
|
||||
// a pending fail or settle that's attempting to consume it.
|
||||
modifiedHtlcs map[uint64]struct{}
|
||||
}
|
||||
|
||||
// newUpdateLog creates a new updateLog instance.
|
||||
func newUpdateLog(logIndex, htlcCounter uint64) *updateLog {
|
||||
return &updateLog{
|
||||
List: list.New(),
|
||||
updateIndex: make(map[uint64]*list.Element),
|
||||
htlcIndex: make(map[uint64]*list.Element),
|
||||
logIndex: logIndex,
|
||||
htlcCounter: htlcCounter,
|
||||
List: list.New(),
|
||||
updateIndex: make(map[uint64]*list.Element),
|
||||
htlcIndex: make(map[uint64]*list.Element),
|
||||
logIndex: logIndex,
|
||||
htlcCounter: htlcCounter,
|
||||
modifiedHtlcs: make(map[uint64]struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1158,6 +1164,19 @@ func (u *updateLog) removeHtlc(i uint64) {
|
|||
entry := u.htlcIndex[i]
|
||||
u.Remove(entry)
|
||||
delete(u.htlcIndex, i)
|
||||
|
||||
// htlcHasModification returns true if the HTLC identified by the passed index
|
||||
// has a pending modification within the log.
|
||||
func (u *updateLog) htlcHasModification(i uint64) bool {
|
||||
_, o := u.modifiedHtlcs[i]
|
||||
return o
|
||||
}
|
||||
|
||||
// markHtlcModified marks an HTLC as modified based on its HTLC index. After a
|
||||
// call to this method, htlcHasModification will return true until the HTLC is
|
||||
// removed.
|
||||
func (u *updateLog) markHtlcModified(i uint64) {
|
||||
u.modifiedHtlcs[i] = struct{}{}
|
||||
}
|
||||
|
||||
// compactLogs performs garbage collection within the log removing HTLCs which
|
||||
|
@ -1509,10 +1528,12 @@ func (lc *LightningChannel) logUpdateToPayDesc(logUpdate *channeldb.LogUpdate,
|
|||
if !isDustRemote {
|
||||
theirP2WSH, theirWitnessScript, err := genHtlcScript(
|
||||
false, false, wireMsg.Expiry, wireMsg.PaymentHash,
|
||||
remoteCommitKeys)
|
||||
remoteCommitKeys,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pd.theirPkScript = theirP2WSH
|
||||
pd.theirWitnessScript = theirWitnessScript
|
||||
}
|
||||
|
@ -1571,7 +1592,7 @@ func (lc *LightningChannel) logUpdateToPayDesc(logUpdate *channeldb.LogUpdate,
|
|||
}
|
||||
|
||||
// restoreCommitState will restore the local commitment chain and updateLog
|
||||
// state to a consistent in-memory representation of the passed dis commitment.
|
||||
// state to a consistent in-memory representation of the passed disk commitment.
|
||||
// This method is to be used upon reconnection to our channel counter party.
|
||||
// Once the connection has been established, we'll prepare our in memory state
|
||||
// to re-sync states with the remote party, and also verify/extend new proposed
|
||||
|
|
Loading…
Add table
Reference in a new issue