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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 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