8
8
"math/big"
9
9
"strconv"
10
10
"strings"
11
+ "sync"
11
12
12
13
"github.com/lightninglabs/lightning-terminal/session"
13
14
"go.etcd.io/bbolt"
@@ -78,6 +79,10 @@ type PrivacyMapTx interface {
78
79
// RealToPseudo returns the pseudo value associated with the given real
79
80
// value. If no such pair is found, then ErrNoSuchKeyFound is returned.
80
81
RealToPseudo (real string ) (string , error )
82
+
83
+ // FetchAllPairs loads and returns the real-to-pseudo pairs in the form
84
+ // of a PrivacyMapPairs struct.
85
+ FetchAllPairs () (* PrivacyMapPairs , error )
81
86
}
82
87
83
88
// privacyMapDB is an implementation of PrivacyMapDB.
@@ -169,6 +174,8 @@ type privacyMapTx struct {
169
174
}
170
175
171
176
// NewPair inserts a new real-pseudo pair into the db.
177
+ //
178
+ // NOTE: this is part of the PrivacyMapTx interface.
172
179
func (p * privacyMapTx ) NewPair (real , pseudo string ) error {
173
180
privacyBucket , err := getBucket (p .boltTx , privacyBucketKey )
174
181
if err != nil {
@@ -214,6 +221,8 @@ func (p *privacyMapTx) NewPair(real, pseudo string) error {
214
221
215
222
// PseudoToReal will check the db to see if the given pseudo key exists. If
216
223
// it does then the real value is returned, else an error is returned.
224
+ //
225
+ // NOTE: this is part of the PrivacyMapTx interface.
217
226
func (p * privacyMapTx ) PseudoToReal (pseudo string ) (string , error ) {
218
227
privacyBucket , err := getBucket (p .boltTx , privacyBucketKey )
219
228
if err != nil {
@@ -240,6 +249,8 @@ func (p *privacyMapTx) PseudoToReal(pseudo string) (string, error) {
240
249
241
250
// RealToPseudo will check the db to see if the given real key exists. If
242
251
// it does then the pseudo value is returned, else an error is returned.
252
+ //
253
+ // NOTE: this is part of the PrivacyMapTx interface.
243
254
func (p * privacyMapTx ) RealToPseudo (real string ) (string , error ) {
244
255
privacyBucket , err := getBucket (p .boltTx , privacyBucketKey )
245
256
if err != nil {
@@ -264,6 +275,38 @@ func (p *privacyMapTx) RealToPseudo(real string) (string, error) {
264
275
return string (pseudo ), nil
265
276
}
266
277
278
+ // FetchAllPairs loads and returns the real-to-pseudo pairs.
279
+ //
280
+ // NOTE: this is part of the PrivacyMapTx interface.
281
+ func (p * privacyMapTx ) FetchAllPairs () (* PrivacyMapPairs , error ) {
282
+ privacyBucket , err := getBucket (p .boltTx , privacyBucketKey )
283
+ if err != nil {
284
+ return nil , err
285
+ }
286
+
287
+ sessBucket := privacyBucket .Bucket (p .groupID [:])
288
+ if sessBucket == nil {
289
+ return nil , ErrNoSuchKeyFound
290
+ }
291
+
292
+ realToPseudoBucket := sessBucket .Bucket (realToPseudoKey )
293
+ if realToPseudoBucket == nil {
294
+ return nil , ErrNoSuchKeyFound
295
+ }
296
+
297
+ pairs := make (map [string ]string )
298
+ err = realToPseudoBucket .ForEach (func (r , p []byte ) error {
299
+ pairs [string (r )] = string (p )
300
+
301
+ return nil
302
+ })
303
+ if err != nil {
304
+ return nil , err
305
+ }
306
+
307
+ return NewPrivacyMapPairs (pairs ), nil
308
+ }
309
+
267
310
func HideString (tx PrivacyMapTx , real string ) (string , error ) {
268
311
pseudo , err := tx .RealToPseudo (real )
269
312
if err != nil && err != ErrNoSuchKeyFound {
@@ -470,3 +513,73 @@ func decodeChannelPoint(cp string) (string, uint32, error) {
470
513
471
514
return parts [0 ], uint32 (index ), nil
472
515
}
516
+
517
+ // PrivacyMapReader is an interface that gives read access to a privacy map
518
+ // DB.
519
+ type PrivacyMapReader interface {
520
+ // GetPseudo returns the associated pseudo value for a given real value.
521
+ // If no such real value exists in the DB, then false is returned.
522
+ GetPseudo (real string ) (string , bool )
523
+ }
524
+
525
+ // PrivacyMapPairs is an in memory implementation of the PrivacyMapReader.
526
+ type PrivacyMapPairs struct {
527
+ // pairs is a map from real to psuedo strings.
528
+ pairs map [string ]string
529
+
530
+ mu sync.Mutex
531
+ }
532
+
533
+ // NewPrivacyMapPairs constructs a new PrivacyMapPairs struct. It may be
534
+ // initialised with either a nil map or a pre-defined real-to-pseudo strings
535
+ // map.
536
+ func NewPrivacyMapPairs (m map [string ]string ) * PrivacyMapPairs {
537
+ if m != nil {
538
+ return & PrivacyMapPairs {
539
+ pairs : m ,
540
+ }
541
+ }
542
+
543
+ return & PrivacyMapPairs {
544
+ pairs : make (map [string ]string ),
545
+ }
546
+ }
547
+
548
+ // GetPseudo returns the associated pseudo value for a given real value. If no
549
+ // such real value exists in the DB, then false is returned.
550
+ //
551
+ // NOTE: this is part of the PrivacyMapReader interface.
552
+ func (p * PrivacyMapPairs ) GetPseudo (real string ) (string , bool ) {
553
+ p .mu .Lock ()
554
+ defer p .mu .Unlock ()
555
+
556
+ pseudo , ok := p .pairs [real ]
557
+
558
+ return pseudo , ok
559
+ }
560
+
561
+ // Add adds the passed set of real-to-pseudo pairs to the PrivacyMapPairs
562
+ // structure. It will throw an error if the new pairs conflict with any of the
563
+ // existing pairs.
564
+ func (p * PrivacyMapPairs ) Add (pairs map [string ]string ) error {
565
+ p .mu .Lock ()
566
+ defer p .mu .Unlock ()
567
+
568
+ // Do a first pass to ensure that none of the new entries conflict with
569
+ // the existing entries. We do this so that we don't mutate the set of
570
+ // pairs before we know that the new set is valid.
571
+ for realStr , pseudoStr := range pairs {
572
+ ps , ok := p .pairs [realStr ]
573
+ if ok && ps != pseudoStr {
574
+ return fmt .Errorf ("cannot replace existing pseudo " +
575
+ "entry for real value: %s" , realStr )
576
+ }
577
+ }
578
+
579
+ // In our second pass, we can add the new pairs to our set.
580
+ for realStr , pseudoStr := range pairs {
581
+ p .pairs [realStr ] = pseudoStr
582
+ }
583
+
584
+ return nil
585
+ }
0 commit comments