• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 13566028875

27 Feb 2025 12:09PM UTC coverage: 49.396% (-9.4%) from 58.748%
13566028875

Pull #9555

github

ellemouton
graph/db: populate the graph cache in Start instead of during construction

In this commit, we move the graph cache population logic out of the
ChannelGraph constructor and into its Start method instead.
Pull Request #9555: graph: extract cache from CRUD [6]

34 of 54 new or added lines in 4 files covered. (62.96%)

27464 existing lines in 436 files now uncovered.

101095 of 204664 relevant lines covered (49.4%)

1.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.5
/lnwallet/commit_sort.go
1
package lnwallet
2

3
import (
4
        "bytes"
5
        "sort"
6

7
        "github.com/btcsuite/btcd/chaincfg/chainhash"
8
        "github.com/btcsuite/btcd/wire"
9
)
10

11
// InPlaceCommitSort performs an in-place sort of a commitment transaction,
12
// given an unsorted transaction and a list of CLTV values for the HTLCs.
13
//
14
// The sort applied is a modified BIP69 sort, that uses the CLTV values of HTLCs
15
// as a tie breaker in case two HTLC outputs have an identical amount and
16
// pkscript. The pkscripts can be the same if they share the same payment hash,
17
// but since the CLTV is enforced via the nLockTime of the second-layer
18
// transactions, the script does not directly commit to them. Instead, the CLTVs
19
// must be supplied separately to act as a tie-breaker, otherwise we may produce
20
// invalid HTLC signatures if the receiver produces an alternative ordering
21
// during verification.
22
//
23
// NOTE: Commitment outputs should have a 0 CLTV corresponding to their index on
24
// the unsorted commitment transaction.
25
func InPlaceCommitSort(tx *wire.MsgTx, cltvs []uint32) {
3✔
26
        if len(tx.TxOut) != len(cltvs) {
3✔
27
                panic("output and cltv list size mismatch")
×
28
        }
29

30
        sort.Sort(sortableInputSlice(tx.TxIn))
3✔
31
        sort.Sort(sortableCommitOutputSlice{tx.TxOut, cltvs})
3✔
32
}
33

34
// sortableInputSlice is a slice of transaction inputs that supports sorting via
35
// BIP69.
36
type sortableInputSlice []*wire.TxIn
37

38
// Len returns the length of the sortableInputSlice.
39
//
40
// NOTE: Part of the sort.Interface interface.
41
func (s sortableInputSlice) Len() int { return len(s) }
3✔
42

43
// Swap exchanges the position of inputs i and j.
44
//
45
// NOTE: Part of the sort.Interface interface.
UNCOV
46
func (s sortableInputSlice) Swap(i, j int) {
×
UNCOV
47
        s[i], s[j] = s[j], s[i]
×
UNCOV
48
}
×
49

50
// Less is the BIP69 input comparison function. The sort is first applied on
51
// input hash (reversed / rpc-style), then index. This logic is copied from
52
// btcutil/txsort.
53
//
54
// NOTE: Part of the sort.Interface interface.
UNCOV
55
func (s sortableInputSlice) Less(i, j int) bool {
×
UNCOV
56
        // Input hashes are the same, so compare the index.
×
UNCOV
57
        ihash := s[i].PreviousOutPoint.Hash
×
UNCOV
58
        jhash := s[j].PreviousOutPoint.Hash
×
UNCOV
59
        if ihash == jhash {
×
UNCOV
60
                return s[i].PreviousOutPoint.Index < s[j].PreviousOutPoint.Index
×
UNCOV
61
        }
×
62

63
        // At this point, the hashes are not equal, so reverse them to
64
        // big-endian and return the result of the comparison.
UNCOV
65
        const hashSize = chainhash.HashSize
×
UNCOV
66
        for b := 0; b < hashSize/2; b++ {
×
UNCOV
67
                ihash[b], ihash[hashSize-1-b] = ihash[hashSize-1-b], ihash[b]
×
UNCOV
68
                jhash[b], jhash[hashSize-1-b] = jhash[hashSize-1-b], jhash[b]
×
UNCOV
69
        }
×
UNCOV
70
        return bytes.Compare(ihash[:], jhash[:]) == -1
×
71
}
72

73
// sortableCommitOutputSlice is a slice of transaction outputs on a commitment
74
// transaction and the corresponding CLTV values of any HTLCs. Commitment
75
// outputs should have a CLTV of 0 and the same index in cltvs.
76
type sortableCommitOutputSlice struct {
77
        txouts []*wire.TxOut
78
        cltvs  []uint32
79
}
80

81
// Len returns the length of the sortableCommitOutputSlice.
82
//
83
// NOTE: Part of the sort.Interface interface.
84
func (s sortableCommitOutputSlice) Len() int {
3✔
85
        return len(s.txouts)
3✔
86
}
3✔
87

88
// Swap exchanges the position of outputs i and j, as well as their
89
// corresponding CLTV values.
90
//
91
// NOTE: Part of the sort.Interface interface.
92
func (s sortableCommitOutputSlice) Swap(i, j int) {
3✔
93
        s.txouts[i], s.txouts[j] = s.txouts[j], s.txouts[i]
3✔
94
        s.cltvs[i], s.cltvs[j] = s.cltvs[j], s.cltvs[i]
3✔
95
}
3✔
96

97
// Less is a modified BIP69 output comparison, that sorts based on value, then
98
// pkscript, then CLTV value.
99
//
100
// NOTE: Part of the sort.Interface interface.
101
func (s sortableCommitOutputSlice) Less(i, j int) bool {
3✔
102
        outi, outj := s.txouts[i], s.txouts[j]
3✔
103

3✔
104
        if outi.Value != outj.Value {
6✔
105
                return outi.Value < outj.Value
3✔
106
        }
3✔
107

108
        pkScriptCmp := bytes.Compare(outi.PkScript, outj.PkScript)
3✔
109
        if pkScriptCmp != 0 {
6✔
110
                return pkScriptCmp < 0
3✔
111
        }
3✔
112

113
        return s.cltvs[i] < s.cltvs[j]
3✔
114
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc