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

lightningnetwork / lnd / 13236757158

10 Feb 2025 08:39AM UTC coverage: 57.649% (-1.2%) from 58.815%
13236757158

Pull #9493

github

ziggie1984
lncli: for some cmds we don't replace the data of the response.

For some cmds it is not very practical to replace the json output
because we might pipe it into other commands. For example when
creating the route we want to pipe it into sendtoRoute.
Pull Request #9493: For some lncli cmds we should not replace the content with other data

0 of 9 new or added lines in 2 files covered. (0.0%)

19535 existing lines in 252 files now uncovered.

103517 of 179563 relevant lines covered (57.65%)

24878.49 hits per line

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

0.0
/htlcswitch/sequencer.go
1
package htlcswitch
2

3
import (
4
        "sync"
5

6
        "github.com/go-errors/errors"
7
        "github.com/lightningnetwork/lnd/channeldb"
8
        "github.com/lightningnetwork/lnd/kvdb"
9
)
10

11
// defaultSequenceBatchSize specifies the window of sequence numbers that are
12
// allocated for each write to disk made by the sequencer.
13
const defaultSequenceBatchSize = 1000
14

15
// Sequencer emits sequence numbers for locally initiated HTLCs. These are
16
// only used internally for tracking pending payments, however they must be
17
// unique in order to avoid circuit key collision in the circuit map.
18
type Sequencer interface {
19
        // NextID returns a unique sequence number for each invocation.
20
        NextID() (uint64, error)
21
}
22

23
var (
24
        // nextPaymentIDKey identifies the bucket that will keep track of the
25
        // persistent sequence numbers for payments.
26
        nextPaymentIDKey = []byte("next-payment-id-key")
27

28
        // ErrSequencerCorrupted signals that the persistence engine was not
29
        // initialized, or has been corrupted since startup.
30
        ErrSequencerCorrupted = errors.New(
31
                "sequencer database has been corrupted")
32
)
33

34
// persistentSequencer is a concrete implementation of IDGenerator, that uses
35
// channeldb to allocate sequence numbers.
36
type persistentSequencer struct {
37
        db *channeldb.DB
38

39
        mu sync.Mutex
40

41
        nextID    uint64
42
        horizonID uint64
43
}
44

45
// NewPersistentSequencer initializes a new sequencer using a channeldb backend.
UNCOV
46
func NewPersistentSequencer(db *channeldb.DB) (Sequencer, error) {
×
UNCOV
47
        g := &persistentSequencer{
×
UNCOV
48
                db: db,
×
UNCOV
49
        }
×
UNCOV
50

×
UNCOV
51
        // Ensure the database bucket is created before any updates are
×
UNCOV
52
        // performed.
×
UNCOV
53
        if err := g.initDB(); err != nil {
×
54
                return nil, err
×
55
        }
×
56

UNCOV
57
        return g, nil
×
58
}
59

60
// NextID returns a unique sequence number for every invocation, persisting the
61
// assignment to avoid reuse.
UNCOV
62
func (s *persistentSequencer) NextID() (uint64, error) {
×
UNCOV
63

×
UNCOV
64
        // nextID will be the unique sequence number returned if no errors are
×
UNCOV
65
        // encountered.
×
UNCOV
66
        var nextID uint64
×
UNCOV
67

×
UNCOV
68
        // If our sequence batch has not been exhausted, we can allocate the
×
UNCOV
69
        // next identifier in the range.
×
UNCOV
70
        s.mu.Lock()
×
UNCOV
71
        defer s.mu.Unlock()
×
UNCOV
72

×
UNCOV
73
        if s.nextID < s.horizonID {
×
UNCOV
74
                nextID = s.nextID
×
UNCOV
75
                s.nextID++
×
UNCOV
76

×
UNCOV
77
                return nextID, nil
×
UNCOV
78
        }
×
79

80
        // Otherwise, our sequence batch has been exhausted. We use the last
81
        // known sequence number on disk to mark the beginning of the next
82
        // sequence batch, and allocate defaultSequenceBatchSize (1000) at a
83
        // time.
84
        //
85
        // NOTE: This also will happen on the first invocation after startup,
86
        // i.e. when nextID and horizonID are both 0. The next sequence batch to be
87
        // allocated will start from the last known tip on disk, which is fine
88
        // as we only require uniqueness of the allocated numbers.
UNCOV
89
        var nextHorizonID uint64
×
UNCOV
90
        if err := kvdb.Update(s.db, func(tx kvdb.RwTx) error {
×
UNCOV
91
                nextIDBkt := tx.ReadWriteBucket(nextPaymentIDKey)
×
UNCOV
92
                if nextIDBkt == nil {
×
93
                        return ErrSequencerCorrupted
×
94
                }
×
95

UNCOV
96
                nextID = nextIDBkt.Sequence()
×
UNCOV
97
                nextHorizonID = nextID + defaultSequenceBatchSize
×
UNCOV
98

×
UNCOV
99
                // Cannot fail when used in Update.
×
UNCOV
100
                nextIDBkt.SetSequence(nextHorizonID)
×
UNCOV
101

×
UNCOV
102
                return nil
×
UNCOV
103
        }, func() {
×
UNCOV
104
                nextHorizonID = 0
×
UNCOV
105
        }); err != nil {
×
106
                return 0, err
×
107
        }
×
108

109
        // Never assign index zero, to avoid collisions with the EmptyKeystone.
UNCOV
110
        if nextID == 0 {
×
UNCOV
111
                nextID++
×
UNCOV
112
        }
×
113

114
        // If our batch sequence allocation succeed, update our in-memory values
115
        // so we can continue to allocate sequence numbers without hitting disk.
116
        // The nextID is incremented by one in memory so the in can be used
117
        // issued directly on the next invocation.
UNCOV
118
        s.nextID = nextID + 1
×
UNCOV
119
        s.horizonID = nextHorizonID
×
UNCOV
120

×
UNCOV
121
        return nextID, nil
×
122
}
123

124
// initDB populates the bucket used to generate payment sequence numbers.
UNCOV
125
func (s *persistentSequencer) initDB() error {
×
UNCOV
126
        return kvdb.Update(s.db, func(tx kvdb.RwTx) error {
×
UNCOV
127
                _, err := tx.CreateTopLevelBucket(nextPaymentIDKey)
×
UNCOV
128
                return err
×
UNCOV
129
        }, func() {})
×
130
}
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

© 2025 Coveralls, Inc