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

lightningnetwork / lnd / 13157733617

05 Feb 2025 12:49PM UTC coverage: 57.712% (-1.1%) from 58.82%
13157733617

Pull #9447

github

yyforyongyu
sweep: rename methods for clarity

We now rename "third party" to "unknown" as the inputs can be spent via
an older sweeping tx, a third party (anchor), or a remote party (pin).
In fee bumper we don't have the info to distinguish the above cases, and
leave them to be further handled by the sweeper as it has more context.
Pull Request #9447: sweep: start tracking input spending status in the fee bumper

83 of 87 new or added lines in 2 files covered. (95.4%)

19472 existing lines in 252 files now uncovered.

103634 of 179570 relevant lines covered (57.71%)

24840.31 hits per line

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

77.18
/channeldb/waitingproof.go
1
package channeldb
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "fmt"
7
        "io"
8
        "sync"
9

10
        "github.com/go-errors/errors"
11
        "github.com/lightningnetwork/lnd/kvdb"
12
        "github.com/lightningnetwork/lnd/lnwire"
13
)
14

15
var (
16
        // waitingProofsBucketKey byte string name of the waiting proofs store.
17
        waitingProofsBucketKey = []byte("waitingproofs")
18

19
        // ErrWaitingProofNotFound is returned if waiting proofs haven't been
20
        // found by db.
21
        ErrWaitingProofNotFound = errors.New("waiting proofs haven't been " +
22
                "found")
23

24
        // ErrWaitingProofAlreadyExist is returned if waiting proofs haven't been
25
        // found by db.
26
        ErrWaitingProofAlreadyExist = errors.New("waiting proof with such " +
27
                "key already exist")
28
)
29

30
// WaitingProofStore is the bold db map-like storage for half announcement
31
// signatures. The one responsibility of this storage is to be able to
32
// retrieve waiting proofs after client restart.
33
type WaitingProofStore struct {
34
        // cache is used in order to reduce the number of redundant get
35
        // calls, when object isn't stored in it.
36
        cache map[WaitingProofKey]struct{}
37
        db    kvdb.Backend
38
        mu    sync.RWMutex
39
}
40

41
// NewWaitingProofStore creates new instance of proofs storage.
42
func NewWaitingProofStore(db kvdb.Backend) (*WaitingProofStore, error) {
27✔
43
        s := &WaitingProofStore{
27✔
44
                db: db,
27✔
45
        }
27✔
46

27✔
47
        if err := s.ForAll(func(proof *WaitingProof) error {
27✔
UNCOV
48
                s.cache[proof.Key()] = struct{}{}
×
UNCOV
49
                return nil
×
50
        }, func() {
27✔
51
                s.cache = make(map[WaitingProofKey]struct{})
27✔
52
        }); err != nil && err != ErrWaitingProofNotFound {
27✔
53
                return nil, err
×
54
        }
×
55

56
        return s, nil
27✔
57
}
58

59
// Add adds new waiting proof in the storage.
60
func (s *WaitingProofStore) Add(proof *WaitingProof) error {
11✔
61
        s.mu.Lock()
11✔
62
        defer s.mu.Unlock()
11✔
63

11✔
64
        err := kvdb.Update(s.db, func(tx kvdb.RwTx) error {
22✔
65
                var err error
11✔
66
                var b bytes.Buffer
11✔
67

11✔
68
                // Get or create the bucket.
11✔
69
                bucket, err := tx.CreateTopLevelBucket(waitingProofsBucketKey)
11✔
70
                if err != nil {
11✔
71
                        return err
×
72
                }
×
73

74
                // Encode the objects and place it in the bucket.
75
                if err := proof.Encode(&b); err != nil {
11✔
76
                        return err
×
77
                }
×
78

79
                key := proof.Key()
11✔
80

11✔
81
                return bucket.Put(key[:], b.Bytes())
11✔
82
        }, func() {})
11✔
83
        if err != nil {
11✔
84
                return err
×
85
        }
×
86

87
        // Knowing that the write succeeded, we can now update the in-memory
88
        // cache with the proof's key.
89
        s.cache[proof.Key()] = struct{}{}
11✔
90

11✔
91
        return nil
11✔
92
}
93

94
// Remove removes the proof from storage by its key.
95
func (s *WaitingProofStore) Remove(key WaitingProofKey) error {
11✔
96
        s.mu.Lock()
11✔
97
        defer s.mu.Unlock()
11✔
98

11✔
99
        if _, ok := s.cache[key]; !ok {
11✔
100
                return ErrWaitingProofNotFound
×
101
        }
×
102

103
        err := kvdb.Update(s.db, func(tx kvdb.RwTx) error {
22✔
104
                // Get or create the top bucket.
11✔
105
                bucket := tx.ReadWriteBucket(waitingProofsBucketKey)
11✔
106
                if bucket == nil {
11✔
107
                        return ErrWaitingProofNotFound
×
108
                }
×
109

110
                return bucket.Delete(key[:])
11✔
111
        }, func() {})
11✔
112
        if err != nil {
11✔
113
                return err
×
114
        }
×
115

116
        // Since the proof was successfully deleted from the store, we can now
117
        // remove it from the in-memory cache.
118
        delete(s.cache, key)
11✔
119

11✔
120
        return nil
11✔
121
}
122

123
// ForAll iterates thought all waiting proofs and passing the waiting proof
124
// in the given callback.
125
func (s *WaitingProofStore) ForAll(cb func(*WaitingProof) error,
126
        reset func()) error {
37✔
127

37✔
128
        return kvdb.View(s.db, func(tx kvdb.RTx) error {
74✔
129
                bucket := tx.ReadBucket(waitingProofsBucketKey)
37✔
130
                if bucket == nil {
64✔
131
                        return ErrWaitingProofNotFound
27✔
132
                }
27✔
133

134
                // Iterate over objects buckets.
135
                return bucket.ForEach(func(k, v []byte) error {
14✔
136
                        // Skip buckets fields.
4✔
137
                        if v == nil {
4✔
138
                                return nil
×
139
                        }
×
140

141
                        r := bytes.NewReader(v)
4✔
142
                        proof := &WaitingProof{}
4✔
143
                        if err := proof.Decode(r); err != nil {
4✔
144
                                return err
×
145
                        }
×
146

147
                        return cb(proof)
4✔
148
                })
149
        }, reset)
150
}
151

152
// Get returns the object which corresponds to the given index.
153
func (s *WaitingProofStore) Get(key WaitingProofKey) (*WaitingProof, error) {
21✔
154
        var proof *WaitingProof
21✔
155

21✔
156
        s.mu.RLock()
21✔
157
        defer s.mu.RUnlock()
21✔
158

21✔
159
        if _, ok := s.cache[key]; !ok {
31✔
160
                return nil, ErrWaitingProofNotFound
10✔
161
        }
10✔
162

163
        err := kvdb.View(s.db, func(tx kvdb.RTx) error {
22✔
164
                bucket := tx.ReadBucket(waitingProofsBucketKey)
11✔
165
                if bucket == nil {
11✔
166
                        return ErrWaitingProofNotFound
×
167
                }
×
168

169
                // Iterate over objects buckets.
170
                v := bucket.Get(key[:])
11✔
171
                if v == nil {
11✔
172
                        return ErrWaitingProofNotFound
×
173
                }
×
174

175
                r := bytes.NewReader(v)
11✔
176
                return proof.Decode(r)
11✔
177
        }, func() {
11✔
178
                proof = &WaitingProof{}
11✔
179
        })
11✔
180

181
        return proof, err
11✔
182
}
183

184
// WaitingProofKey is the proof key which uniquely identifies the waiting
185
// proof object. The goal of this key is distinguish the local and remote
186
// proof for the same channel id.
187
type WaitingProofKey [9]byte
188

189
// WaitingProof is the storable object, which encapsulate the half proof and
190
// the information about from which side this proof came. This structure is
191
// needed to make channel proof exchange persistent, so that after client
192
// restart we may receive remote/local half proof and process it.
193
type WaitingProof struct {
194
        *lnwire.AnnounceSignatures1
195
        isRemote bool
196
}
197

198
// NewWaitingProof constructs a new waiting prof instance.
199
func NewWaitingProof(isRemote bool,
200
        proof *lnwire.AnnounceSignatures1) *WaitingProof {
21✔
201

21✔
202
        return &WaitingProof{
21✔
203
                AnnounceSignatures1: proof,
21✔
204
                isRemote:            isRemote,
21✔
205
        }
21✔
206
}
21✔
207

208
// OppositeKey returns the key which uniquely identifies opposite waiting proof.
209
func (p *WaitingProof) OppositeKey() WaitingProofKey {
30✔
210
        var key [9]byte
30✔
211
        binary.BigEndian.PutUint64(key[:8], p.ShortChannelID.ToUint64())
30✔
212

30✔
213
        if !p.isRemote {
41✔
214
                key[8] = 1
11✔
215
        }
11✔
216
        return key
30✔
217
}
218

219
// Key returns the key which uniquely identifies waiting proof.
220
func (p *WaitingProof) Key() WaitingProofKey {
24✔
221
        var key [9]byte
24✔
222
        binary.BigEndian.PutUint64(key[:8], p.ShortChannelID.ToUint64())
24✔
223

24✔
224
        if p.isRemote {
30✔
225
                key[8] = 1
6✔
226
        }
6✔
227
        return key
24✔
228
}
229

230
// Encode writes the internal representation of waiting proof in byte stream.
231
func (p *WaitingProof) Encode(w io.Writer) error {
11✔
232
        if err := binary.Write(w, byteOrder, p.isRemote); err != nil {
11✔
233
                return err
×
234
        }
×
235

236
        // TODO(yy): remove the type assertion when we finished refactoring db
237
        // into using write buffer.
238
        buf, ok := w.(*bytes.Buffer)
11✔
239
        if !ok {
11✔
240
                return fmt.Errorf("expect io.Writer to be *bytes.Buffer")
×
241
        }
×
242

243
        if err := p.AnnounceSignatures1.Encode(buf, 0); err != nil {
11✔
244
                return err
×
245
        }
×
246

247
        return nil
11✔
248
}
249

250
// Decode reads the data from the byte stream and initializes the
251
// waiting proof object with it.
252
func (p *WaitingProof) Decode(r io.Reader) error {
15✔
253
        if err := binary.Read(r, byteOrder, &p.isRemote); err != nil {
15✔
254
                return err
×
255
        }
×
256

257
        msg := &lnwire.AnnounceSignatures1{}
15✔
258
        if err := msg.Decode(r, 0); err != nil {
15✔
259
                return err
×
260
        }
×
261

262
        p.AnnounceSignatures1 = msg
15✔
263

15✔
264
        return nil
15✔
265
}
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