Store node info timestamp to cache file

Last update isn't updated often for many nodes which makes cache
useless. Instead, we now save the last info retrieval timestamp with
it. The existing cache will be invalidated due to the structure change.
pull/18/head
rkfg 2 years ago
parent f15046dd19
commit be60dd99c8

@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/gofrs/flock" "github.com/gofrs/flock"
"github.com/lightningnetwork/lnd/lnrpc"
) )
func lock() *flock.Flock { func lock() *flock.Flock {
@ -20,6 +19,14 @@ func (r *regolancer) loadNodeCache(filename string, exp int, doLock bool) error
if filename == "" { if filename == "" {
return nil return nil
} }
defer func() {
err := recover()
if err == nil {
return
}
log.Printf("Loading failed, cache format might be outdated: %s", err)
r.nodeCache = map[string]cachedNodeInfo{}
}()
if doLock { if doLock {
log.Printf("Loading node cache from %s", filename) log.Printf("Loading node cache from %s", filename)
l := lock() l := lock()
@ -34,10 +41,13 @@ func (r *regolancer) loadNodeCache(filename string, exp int, doLock bool) error
return nil return nil
} }
defer f.Close() defer f.Close()
gob.NewDecoder(f).Decode(&r.nodeCache) err = gob.NewDecoder(f).Decode(&r.nodeCache)
if err != nil {
return err
}
for k, v := range r.nodeCache { for k, v := range r.nodeCache {
if time.Since(time.Unix(int64(v.Node.LastUpdate), 0)) > since := time.Since(v.Timestamp)
time.Minute*time.Duration(exp) { if since > time.Minute*time.Duration(exp) {
delete(r.nodeCache, k) delete(r.nodeCache, k)
} }
} }
@ -54,7 +64,7 @@ func (r *regolancer) saveNodeCache(filename string, exp int) error {
l.Lock() l.Lock()
defer l.Unlock() defer l.Unlock()
old := regolancer{nodeCache: map[string]*lnrpc.NodeInfo{}} old := regolancer{nodeCache: map[string]cachedNodeInfo{}}
err := old.loadNodeCache(filename, exp, false) err := old.loadNodeCache(filename, exp, false)
if err != nil { if err != nil {
@ -62,7 +72,7 @@ func (r *regolancer) saveNodeCache(filename string, exp int) error {
} }
for k, v := range old.nodeCache { for k, v := range old.nodeCache {
if n, ok := r.nodeCache[k]; !ok || if n, ok := r.nodeCache[k]; !ok ||
n.Node.LastUpdate < v.Node.LastUpdate { n.Timestamp.Before(v.Timestamp) {
r.nodeCache[k] = v r.nodeCache[k] = v
} }
} }
@ -72,6 +82,6 @@ func (r *regolancer) saveNodeCache(filename string, exp int) error {
return fmt.Errorf("error creating node cache file: %s", err) return fmt.Errorf("error creating node cache file: %s", err)
} }
defer f.Close() defer f.Close()
gob.NewEncoder(f).Encode(r.nodeCache) err = gob.NewEncoder(f).Encode(r.nodeCache)
return nil return err
} }

@ -57,6 +57,11 @@ type failedRoute struct {
expiration *time.Time expiration *time.Time
} }
type cachedNodeInfo struct {
*lnrpc.NodeInfo
Timestamp time.Time
}
type regolancer struct { type regolancer struct {
lnClient lnrpc.LightningClient lnClient lnrpc.LightningClient
routerClient routerrpc.RouterClient routerClient routerrpc.RouterClient
@ -67,7 +72,7 @@ type regolancer struct {
toChannels []*lnrpc.Channel toChannels []*lnrpc.Channel
toChannelId map[uint64]struct{} toChannelId map[uint64]struct{}
channelPairs map[string][2]*lnrpc.Channel channelPairs map[string][2]*lnrpc.Channel
nodeCache map[string]*lnrpc.NodeInfo nodeCache map[string]cachedNodeInfo
chanCache map[uint64]*lnrpc.ChannelEdge chanCache map[uint64]*lnrpc.ChannelEdge
failureCache map[string]failedRoute failureCache map[string]failedRoute
excludeIn map[uint64]struct{} excludeIn map[uint64]struct{}
@ -237,7 +242,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
r := regolancer{ r := regolancer{
nodeCache: map[string]*lnrpc.NodeInfo{}, nodeCache: map[string]cachedNodeInfo{},
chanCache: map[uint64]*lnrpc.ChannelEdge{}, chanCache: map[uint64]*lnrpc.ChannelEdge{},
channelPairs: map[string][2]*lnrpc.Channel{}, channelPairs: map[string][2]*lnrpc.Channel{},
failureCache: map[string]failedRoute{}, failureCache: map[string]failedRoute{},

@ -118,11 +118,14 @@ func (r *regolancer) getRoutes(ctx context.Context, from, to uint64, amtMsat int
func (r *regolancer) getNodeInfo(ctx context.Context, pk string) (*lnrpc.NodeInfo, error) { func (r *regolancer) getNodeInfo(ctx context.Context, pk string) (*lnrpc.NodeInfo, error) {
if nodeInfo, ok := r.nodeCache[pk]; ok { if nodeInfo, ok := r.nodeCache[pk]; ok {
return nodeInfo, nil return nodeInfo.NodeInfo, nil
} }
nodeInfo, err := r.lnClient.GetNodeInfo(ctx, &lnrpc.NodeInfoRequest{PubKey: pk}) nodeInfo, err := r.lnClient.GetNodeInfo(ctx, &lnrpc.NodeInfoRequest{PubKey: pk})
if err == nil { if err == nil {
r.nodeCache[pk] = nodeInfo r.nodeCache[pk] = cachedNodeInfo{
NodeInfo: nodeInfo,
Timestamp: time.Now(),
}
} }
return nodeInfo, err return nodeInfo, err
} }

Loading…
Cancel
Save