Skip to content

Commit 97e2a23

Browse files
committed
lnd: Include a Kvdb impl for peer.PeerDataStore
Signed-off-by: Ononiwu <[email protected]>
1 parent 1b61176 commit 97e2a23

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed

peerstorage.go

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package lnd
2+
3+
import (
4+
"github.com/btcsuite/btcd/btcec/v2"
5+
"github.com/lightningnetwork/lnd/chainntnfs"
6+
"github.com/lightningnetwork/lnd/kvdb"
7+
"github.com/prometheus/common/log"
8+
"sync"
9+
)
10+
11+
const (
12+
maxWipeWindow = 2016
13+
)
14+
15+
var (
16+
peerStorage = []byte("peer-storage")
17+
)
18+
19+
type blockViewer interface {
20+
BestHeight() int32
21+
}
22+
23+
type kvdbPeerStorage struct {
24+
*chainntnfs.BlockEpochEvent
25+
db kvdb.Backend
26+
awaitingDelete map[int32]*btcec.PublicKey
27+
mapMtx sync.RWMutex
28+
quit chan interface{}
29+
blockViewer chainntnfs.BestBlockView
30+
wg sync.WaitGroup
31+
}
32+
33+
type peerStorageConfig struct {
34+
chainNotifier chainntnfs.ChainNotifier
35+
db kvdb.Backend
36+
blockViewer chainntnfs.BestBlockView
37+
}
38+
39+
func newKvdbPeerStorage(c *peerStorageConfig) (*kvdbPeerStorage, error) {
40+
epochEvent, err := c.chainNotifier.RegisterBlockEpochNtfn(nil)
41+
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
return &kvdbPeerStorage{
47+
db: c.db,
48+
BlockEpochEvent: epochEvent,
49+
blockViewer: c.blockViewer,
50+
}, nil
51+
}
52+
53+
func (k *kvdbPeerStorage) start() {
54+
errChan := make(chan error)
55+
56+
k.wg.Add(1)
57+
go func() {
58+
defer k.wg.Done()
59+
err := k.garbageCollector()
60+
select {
61+
case errChan <- err:
62+
case <-k.quit:
63+
}
64+
65+
}()
66+
67+
k.wg.Add(1)
68+
go func() {
69+
defer k.wg.Done()
70+
select {
71+
case err := <-errChan:
72+
if err != nil {
73+
log.Errorf("kvdbPeerStorage experienced "+
74+
"error during operation %v", err)
75+
}
76+
case <-k.quit:
77+
}
78+
}()
79+
}
80+
81+
func (k *kvdbPeerStorage) stop() {
82+
close(k.quit)
83+
k.wg.Wait()
84+
85+
return
86+
}
87+
88+
func (k *kvdbPeerStorage) StorePeerData(data []byte,
89+
peerPub *btcec.PublicKey) error {
90+
// Check if to delete
91+
92+
return kvdb.Update(k.db, func(tx kvdb.RwTx) error {
93+
bucket, err := tx.CreateTopLevelBucket(peerStorage)
94+
if err != nil {
95+
return err
96+
}
97+
98+
peerPubBytes := peerPub.SerializeCompressed()
99+
100+
return bucket.Put(peerPubBytes, data)
101+
}, func() {})
102+
}
103+
104+
func (k *kvdbPeerStorage) RetrievePeerData(peerPub *btcec.PublicKey) ([]byte,
105+
error) {
106+
107+
var data []byte
108+
err := kvdb.View(k.db, func(tx kvdb.RTx) error {
109+
bucket := tx.ReadBucket(peerStorage)
110+
111+
peerPubBytes := peerPub.SerializeCompressed()
112+
113+
data = bucket.Get(peerPubBytes)
114+
return nil
115+
}, func() {})
116+
117+
if err != nil {
118+
return nil, err
119+
}
120+
121+
return data, nil
122+
}
123+
124+
func (k *kvdbPeerStorage) MarkForDelete(peerPub *btcec.PublicKey) error {
125+
k.mapMtx.Lock()
126+
defer k.mapMtx.Unlock()
127+
128+
height, err := k.blockViewer.BestHeight()
129+
if err != nil {
130+
return err
131+
}
132+
133+
k.awaitingDelete[int32(height+maxWipeWindow)] = peerPub
134+
135+
return nil
136+
}
137+
138+
func (k *kvdbPeerStorage) garbageCollector() error {
139+
140+
for {
141+
select {
142+
case e := <-k.Epochs:
143+
k.mapMtx.RLock()
144+
peerPub, ok := k.awaitingDelete[e.Height]
145+
k.mapMtx.RUnlock()
146+
147+
if ok {
148+
err := kvdb.Update(k.db, func(tx kvdb.RwTx) error {
149+
bucket, err := tx.CreateTopLevelBucket(
150+
peerStorage)
151+
if err != nil {
152+
return err
153+
}
154+
155+
peerPubBytes := peerPub.
156+
SerializeCompressed()
157+
158+
return bucket.Delete(peerPubBytes)
159+
}, func() {})
160+
161+
if err != nil {
162+
return err
163+
}
164+
165+
}
166+
case <-k.quit:
167+
k.Cancel()
168+
return nil
169+
}
170+
}
171+
}

0 commit comments

Comments
 (0)