• 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

77.78
/channeldb/witness_cache.go
1
package channeldb
2

3
import (
4
        "fmt"
5

6
        "github.com/lightningnetwork/lnd/kvdb"
7
        "github.com/lightningnetwork/lnd/lntypes"
8
)
9

10
var (
11
        // ErrNoWitnesses is an error that's returned when no new witnesses have
12
        // been added to the WitnessCache.
13
        ErrNoWitnesses = fmt.Errorf("no witnesses")
14

15
        // ErrUnknownWitnessType is returned if a caller attempts to
16
        ErrUnknownWitnessType = fmt.Errorf("unknown witness type")
17
)
18

19
// WitnessType is enum that denotes what "type" of witness is being
20
// stored/retrieved. As the WitnessCache itself is agnostic and doesn't enforce
21
// any structure on added witnesses, we use this type to partition the
22
// witnesses on disk, and also to know how to map a witness to its look up key.
23
type WitnessType uint8
24

25
var (
26
        // Sha256HashWitness is a witness that is simply the pre image to a
27
        // hash image. In order to map to its key, we'll use sha256.
28
        Sha256HashWitness WitnessType = 1
29
)
30

31
// toDBKey is a helper method that maps a witness type to the key that we'll
32
// use to store it within the database.
33
func (w WitnessType) toDBKey() ([]byte, error) {
17✔
34
        switch w {
17✔
35

36
        case Sha256HashWitness:
17✔
37
                return []byte{byte(w)}, nil
17✔
38

39
        default:
×
40
                return nil, ErrUnknownWitnessType
×
41
        }
42
}
43

44
var (
45
        // witnessBucketKey is the name of the bucket that we use to store all
46
        // witnesses encountered. Within this bucket, we'll create a sub-bucket for
47
        // each witness type.
48
        witnessBucketKey = []byte("byte")
49
)
50

51
// WitnessCache is a persistent cache of all witnesses we've encountered on the
52
// network. In the case of multi-hop, multi-step contracts, a cache of all
53
// witnesses can be useful in the case of partial contract resolution. If
54
// negotiations break down, we may be forced to locate the witness for a
55
// portion of the contract on-chain. In this case, we'll then add that witness
56
// to the cache so the incoming contract can fully resolve witness.
57
// Additionally, as one MUST always use a unique witness on the network, we may
58
// use this cache to detect duplicate witnesses.
59
//
60
// TODO(roasbeef): need expiry policy?
61
//   - encrypt?
62
type WitnessCache struct {
63
        db *DB
64
}
65

66
// NewWitnessCache returns a new instance of the witness cache.
67
func (d *DB) NewWitnessCache() *WitnessCache {
4✔
68
        return &WitnessCache{
4✔
69
                db: d,
4✔
70
        }
4✔
71
}
4✔
72

73
// witnessEntry is a key-value struct that holds each key -> witness pair, used
74
// when inserting records into the cache.
75
type witnessEntry struct {
76
        key     []byte
77
        witness []byte
78
}
79

80
// AddSha256Witnesses adds a batch of new sha256 preimages into the witness
81
// cache. This is an alias for AddWitnesses that uses Sha256HashWitness as the
82
// preimages' witness type.
83
func (w *WitnessCache) AddSha256Witnesses(preimages ...lntypes.Preimage) error {
4✔
84
        // Optimistically compute the preimages' hashes before attempting to
4✔
85
        // start the db transaction.
4✔
86
        entries := make([]witnessEntry, 0, len(preimages))
4✔
87
        for i := range preimages {
10✔
88
                hash := preimages[i].Hash()
6✔
89
                entries = append(entries, witnessEntry{
6✔
90
                        key:     hash[:],
6✔
91
                        witness: preimages[i][:],
6✔
92
                })
6✔
93
        }
6✔
94

95
        return w.addWitnessEntries(Sha256HashWitness, entries)
4✔
96
}
97

98
// addWitnessEntries inserts the witnessEntry key-value pairs into the cache,
99
// using the appropriate witness type to segment the namespace of possible
100
// witness types.
101
func (w *WitnessCache) addWitnessEntries(wType WitnessType,
102
        entries []witnessEntry) error {
5✔
103

5✔
104
        // Exit early if there are no witnesses to add.
5✔
105
        if len(entries) == 0 {
5✔
106
                return nil
×
107
        }
×
108

109
        return kvdb.Batch(w.db.Backend, func(tx kvdb.RwTx) error {
10✔
110
                witnessBucket, err := tx.CreateTopLevelBucket(witnessBucketKey)
5✔
111
                if err != nil {
5✔
112
                        return err
×
113
                }
×
114

115
                witnessTypeBucketKey, err := wType.toDBKey()
5✔
116
                if err != nil {
5✔
117
                        return err
×
118
                }
×
119
                witnessTypeBucket, err := witnessBucket.CreateBucketIfNotExists(
5✔
120
                        witnessTypeBucketKey,
5✔
121
                )
5✔
122
                if err != nil {
5✔
123
                        return err
×
124
                }
×
125

126
                for _, entry := range entries {
13✔
127
                        err = witnessTypeBucket.Put(entry.key, entry.witness)
8✔
128
                        if err != nil {
8✔
129
                                return err
×
130
                        }
×
131
                }
132

133
                return nil
5✔
134
        })
135
}
136

137
// LookupSha256Witness attempts to lookup the preimage for a sha256 hash. If
138
// the witness isn't found, ErrNoWitnesses will be returned.
139
func (w *WitnessCache) LookupSha256Witness(hash lntypes.Hash) (lntypes.Preimage, error) {
8✔
140
        witness, err := w.lookupWitness(Sha256HashWitness, hash[:])
8✔
141
        if err != nil {
10✔
142
                return lntypes.Preimage{}, err
2✔
143
        }
2✔
144

145
        return lntypes.MakePreimage(witness)
6✔
146
}
147

148
// lookupWitness attempts to lookup a witness according to its type and also
149
// its witness key. In the case that the witness isn't found, ErrNoWitnesses
150
// will be returned.
151
func (w *WitnessCache) lookupWitness(wType WitnessType, witnessKey []byte) ([]byte, error) {
8✔
152
        var witness []byte
8✔
153
        err := kvdb.View(w.db, func(tx kvdb.RTx) error {
16✔
154
                witnessBucket := tx.ReadBucket(witnessBucketKey)
8✔
155
                if witnessBucket == nil {
8✔
UNCOV
156
                        return ErrNoWitnesses
×
UNCOV
157
                }
×
158

159
                witnessTypeBucketKey, err := wType.toDBKey()
8✔
160
                if err != nil {
8✔
161
                        return err
×
162
                }
×
163
                witnessTypeBucket := witnessBucket.NestedReadBucket(witnessTypeBucketKey)
8✔
164
                if witnessTypeBucket == nil {
9✔
165
                        return ErrNoWitnesses
1✔
166
                }
1✔
167

168
                dbWitness := witnessTypeBucket.Get(witnessKey)
7✔
169
                if dbWitness == nil {
8✔
170
                        return ErrNoWitnesses
1✔
171
                }
1✔
172

173
                witness = make([]byte, len(dbWitness))
6✔
174
                copy(witness[:], dbWitness)
6✔
175

6✔
176
                return nil
6✔
177
        }, func() {
8✔
178
                witness = nil
8✔
179
        })
8✔
180
        if err != nil {
10✔
181
                return nil, err
2✔
182
        }
2✔
183

184
        return witness, nil
6✔
185
}
186

187
// DeleteSha256Witness attempts to delete a sha256 preimage identified by hash.
188
func (w *WitnessCache) DeleteSha256Witness(hash lntypes.Hash) error {
3✔
189
        return w.deleteWitness(Sha256HashWitness, hash[:])
3✔
190
}
3✔
191

192
// deleteWitness attempts to delete a particular witness from the database.
193
func (w *WitnessCache) deleteWitness(wType WitnessType, witnessKey []byte) error {
3✔
194
        return kvdb.Batch(w.db.Backend, func(tx kvdb.RwTx) error {
6✔
195
                witnessBucket, err := tx.CreateTopLevelBucket(witnessBucketKey)
3✔
196
                if err != nil {
3✔
197
                        return err
×
198
                }
×
199

200
                witnessTypeBucketKey, err := wType.toDBKey()
3✔
201
                if err != nil {
3✔
202
                        return err
×
203
                }
×
204
                witnessTypeBucket, err := witnessBucket.CreateBucketIfNotExists(
3✔
205
                        witnessTypeBucketKey,
3✔
206
                )
3✔
207
                if err != nil {
3✔
208
                        return err
×
209
                }
×
210

211
                return witnessTypeBucket.Delete(witnessKey)
3✔
212
        })
213
}
214

215
// DeleteWitnessClass attempts to delete an *entire* class of witnesses. After
216
// this function return with a non-nil error,
217
func (w *WitnessCache) DeleteWitnessClass(wType WitnessType) error {
1✔
218
        return kvdb.Batch(w.db.Backend, func(tx kvdb.RwTx) error {
2✔
219
                witnessBucket, err := tx.CreateTopLevelBucket(witnessBucketKey)
1✔
220
                if err != nil {
1✔
221
                        return err
×
222
                }
×
223

224
                witnessTypeBucketKey, err := wType.toDBKey()
1✔
225
                if err != nil {
1✔
226
                        return err
×
227
                }
×
228

229
                return witnessBucket.DeleteNestedBucket(witnessTypeBucketKey)
1✔
230
        })
231
}
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