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

lightningnetwork / lnd / 13536249039

26 Feb 2025 03:42AM UTC coverage: 57.462% (-1.4%) from 58.835%
13536249039

Pull #8453

github

Roasbeef
peer: update chooseDeliveryScript to gen script if needed

In this commit, we update `chooseDeliveryScript` to generate a new
script if needed. This allows us to fold in a few other lines that
always followed this function into this expanded function.

The tests have been updated accordingly.
Pull Request #8453: [4/4] - multi: integrate new rbf coop close FSM into the existing peer flow

275 of 1318 new or added lines in 22 files covered. (20.86%)

19521 existing lines in 257 files now uncovered.

103858 of 180741 relevant lines covered (57.46%)

24750.23 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