Skip to content

Commit

Permalink
feat(network): permanent peer store (#1354)
Browse files Browse the repository at this point in the history
  • Loading branch information
kehiy authored and themantre committed Jun 25, 2024
1 parent 384860e commit c0da4e2
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 19 deletions.
2 changes: 2 additions & 0 deletions network/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Config struct {
DefaultPort int `toml:"-"`
DefaultBootstrapAddrStrings []string `toml:"-"`
IsBootstrapper bool `toml:"-"`
PeerStorePath string `toml:"-"`
}

func DefaultConfig() *Config {
Expand All @@ -48,6 +49,7 @@ func DefaultConfig() *Config {
ForcePrivateNetwork: false,
DefaultPort: 0,
IsBootstrapper: false,
PeerStorePath: "peers.json",
}
}

Expand Down
92 changes: 73 additions & 19 deletions network/peermgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package network

import (
"context"
"encoding/json"
"fmt"
"sync"
"time"

lp2phost "github.com/libp2p/go-libp2p/core/host"
lp2pnet "github.com/libp2p/go-libp2p/core/network"
lp2ppeer "github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multiaddr"
"github.com/pactus-project/pactus/util"
"github.com/pactus-project/pactus/util/logger"
)

Expand All @@ -23,40 +26,49 @@ type peerInfo struct {
type peerMgr struct {
lk sync.RWMutex

ctx context.Context
minConns int
numInbound int
numOutbound int
host lp2phost.Host
peers map[lp2ppeer.ID]*peerInfo
logger *logger.SubLogger
ctx context.Context
minConns int
numInbound int
numOutbound int
host lp2phost.Host
peers map[lp2ppeer.ID]*peerInfo
peerStorePath string
logger *logger.SubLogger
}

// newPeerMgr creates a new Peer Manager instance.
func newPeerMgr(ctx context.Context, h lp2phost.Host,
conf *Config, log *logger.SubLogger,
) *peerMgr {
peers := make(map[lp2ppeer.ID]*peerInfo)
peerStore, err := loadPeerStore(conf.PeerStorePath)
if err != nil {
log.Error("failed to load peer store", "err", err)
}
log.Info("peer store loaded successfully")

peerStore = append(peerStore, conf.BootstrapAddrInfos()...)

for _, ai := range conf.BootstrapAddrInfos() {
peers := make(map[lp2ppeer.ID]*peerInfo)
for _, ai := range peerStore {
peers[ai.ID] = &peerInfo{
MultiAddress: ai.Addrs[0],
Connected: false,
Direction: lp2pnet.DirUnknown,
}
}

b := &peerMgr{
ctx: ctx,
minConns: conf.MinConns(),
peers: peers,
host: h,
logger: log,
pm := &peerMgr{
ctx: ctx,
minConns: conf.MinConns(),
peers: peers,
peerStorePath: conf.PeerStorePath,
host: h,
logger: log,
}

log.Info("peer manager created", "minConns", b.minConns)
log.Info("peer manager created", "minConns", pm.minConns)

return b
return pm
}

// Start starts the Peer Manager.
Expand All @@ -78,7 +90,10 @@ func (mgr *peerMgr) Start() {
}()
}

func (*peerMgr) Stop() {
func (mgr *peerMgr) Stop() {
if err := mgr.savePeerStore(); err != nil {
mgr.logger.Error("can't save peer store", "err", err)
}
}

func (mgr *peerMgr) SetPeerConnected(pid lp2ppeer.ID, ma multiaddr.Multiaddr,
Expand Down Expand Up @@ -148,7 +163,7 @@ func (mgr *peerMgr) setPeerDisconnected(pid lp2ppeer.ID) {
pi.Direction = lp2pnet.DirUnknown
}

// checkConnectivity performs the actual work of maintaining connections.
// CheckConnectivity performs the actual work of maintaining connections.
// It ensures that the number of connections stays within the minimum and maximum thresholds.
func (mgr *peerMgr) CheckConnectivity() {
mgr.lk.Lock()
Expand Down Expand Up @@ -210,3 +225,42 @@ func (mgr *peerMgr) NumOutbound() int {

return mgr.numOutbound
}

func (mgr *peerMgr) savePeerStore() error {
mgr.lk.RLock()
defer mgr.lk.RUnlock()

ps := make([]string, 0)
for id, info := range mgr.peers {
ps = append(ps, fmt.Sprintf("%s/p2p/%s", info.MultiAddress.String(), id.String()))
}

data, err := json.Marshal(ps)
if err != nil {
return err
}

return util.WriteFile(mgr.peerStorePath, data)
}

func loadPeerStore(path string) ([]lp2ppeer.AddrInfo, error) {
peerStore := make([]lp2ppeer.AddrInfo, 0)

data, err := util.ReadFile(path)
if err != nil {
return peerStore, err
}

ps := make([]string, 0)
err = json.Unmarshal(data, &ps)
if err != nil {
return peerStore, err
}

peerStore, err = MakeAddrInfos(ps)
if err != nil {
return []lp2ppeer.AddrInfo{}, err
}

return peerStore, nil
}

0 comments on commit c0da4e2

Please sign in to comment.