Skip to content

Commit 3846f17

Browse files
committed
add this to be a method on peerstore
1 parent 4fb69b6 commit 3846f17

File tree

6 files changed

+92
-83
lines changed

6 files changed

+92
-83
lines changed

core/peerstore/peerstore.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ type Peerstore interface {
7070
// RemovePeer removes all the peer related information except its addresses. To remove the
7171
// addresses use `AddrBook.ClearAddrs` or set the address ttls to 0.
7272
RemovePeer(peer.ID)
73+
74+
// UpdateHostAddrs updates the addresses of the host in the peerstore. It also adds the signed
75+
// peer record for the host if there's a private key available for the host in the KeyBook.
76+
// This method should only be used to update the addresses of the Host that owns the peerstore.
77+
UpdateHostAddrs(hostID peer.ID, currentAddrs, removedAddrs, peerRecordAddrs []ma.Multiaddr) error
7378
}
7479

7580
// PeerMetadata can handle values of any type. Serializing values is

p2p/host/basic/addrs_manager.go

Lines changed: 14 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"sync/atomic"
1212
"time"
1313

14-
"github.com/libp2p/go-libp2p/core/crypto"
1514
"github.com/libp2p/go-libp2p/core/event"
1615
"github.com/libp2p/go-libp2p/core/network"
1716
"github.com/libp2p/go-libp2p/core/peer"
@@ -74,10 +73,8 @@ type addrsManager struct {
7473
addrsMx sync.RWMutex
7574
currentAddrs hostAddrs
7675

77-
signKey crypto.PrivKey
78-
addrStore addrStore
79-
signedRecordStore peerstore.CertifiedAddrBook
80-
hostID peer.ID
76+
peerstore peerstore.Peerstore
77+
hostID peer.ID
8178

8279
wg sync.WaitGroup
8380
ctx context.Context
@@ -94,9 +91,7 @@ func newAddrsManager(
9491
client autonatv2Client,
9592
enableMetrics bool,
9693
registerer prometheus.Registerer,
97-
disableSignedPeerRecord bool,
98-
signKey crypto.PrivKey,
99-
addrStore addrStore,
94+
pstore peerstore.Peerstore,
10095
hostID peer.ID,
10196
) (*addrsManager, error) {
10297
ctx, cancel := context.WithCancel(context.Background())
@@ -110,23 +105,14 @@ func newAddrsManager(
110105
triggerAddrsUpdateChan: make(chan chan struct{}, 1),
111106
triggerReachabilityUpdate: make(chan struct{}, 1),
112107
interfaceAddrs: &interfaceAddrsCache{},
113-
signKey: signKey,
114-
addrStore: addrStore,
108+
peerstore: pstore,
115109
hostID: hostID,
116110
ctx: ctx,
117111
ctxCancel: cancel,
118112
}
119113
unknownReachability := network.ReachabilityUnknown
120114
as.hostReachability.Store(&unknownReachability)
121115

122-
if !disableSignedPeerRecord {
123-
var ok bool
124-
as.signedRecordStore, ok = as.addrStore.(peerstore.CertifiedAddrBook)
125-
if !ok {
126-
return nil, errors.New("peerstore doesn't implement CertifiedAddrBook interface")
127-
}
128-
}
129-
130116
if client != nil {
131117
var metricsTracker MetricsTracker
132118
if enableMetrics {
@@ -347,26 +333,10 @@ func (a *addrsManager) updateAddrs(prevHostAddrs hostAddrs, relayAddrs []ma.Mult
347333

348334
// updatePeerStore updates the peer store for the host
349335
func (a *addrsManager) updatePeerStore(currentAddrs []ma.Multiaddr, removedAddrs []ma.Multiaddr) {
350-
// update host addresses in the peer store
351-
a.addrStore.SetAddrs(a.hostID, currentAddrs, peerstore.PermanentAddrTTL)
352-
a.addrStore.SetAddrs(a.hostID, removedAddrs, 0)
353-
354-
var sr *record.Envelope
355-
// Our addresses have changed.
356-
// store the signed peer record in the peer store.
357-
if a.signedRecordStore != nil {
358-
var err error
359-
// add signed peer record to the event
360-
// in case of an error drop this event.
361-
sr, err = a.makeSignedPeerRecord(currentAddrs)
362-
if err != nil {
363-
log.Error("error creating a signed peer record from the set of current addresses", "err", err)
364-
return
365-
}
366-
if _, err := a.signedRecordStore.ConsumePeerRecord(sr, peerstore.PermanentAddrTTL); err != nil {
367-
log.Error("failed to persist signed peer record in peer store", "err", err)
368-
return
369-
}
336+
peerRecordAddrs := trimHostAddrList(currentAddrs, maxPeerRecordSize-1024) // 1024 B of buffer for things other than addrs in peerstore
337+
err := a.peerstore.UpdateHostAddrs(a.hostID, currentAddrs, removedAddrs, peerRecordAddrs)
338+
if err != nil {
339+
log.Error("error updating peer store", "err", err)
370340
}
371341
}
372342

@@ -378,7 +348,7 @@ func (a *addrsManager) notifyAddrsUpdated(emitter event.Emitter, localAddrsEmitt
378348
}
379349
}
380350
if areAddrsDifferent(previous.addrs, current.addrs) {
381-
log.Debug("host addresses updated", "addrs", current.localAddrs)
351+
log.Debug("host addresses updated", "addrs", current.addrs)
382352
a.emitLocalAddrsUpdated(localAddrsEmitter, current.addrs, previous.addrs)
383353
}
384354

@@ -562,30 +532,6 @@ func (a *addrsManager) appendObservedAddrs(dst []ma.Multiaddr, listenAddrs, ifac
562532
return dst
563533
}
564534

565-
// makeSignedPeerRecord creates a signed peer record for the given addresses
566-
func (a *addrsManager) makeSignedPeerRecord(addrs []ma.Multiaddr) (*record.Envelope, error) {
567-
if a.signKey == nil {
568-
return nil, errors.New("signKey is nil")
569-
}
570-
// Limit the length of currentAddrs to ensure that our signed peer records aren't rejected
571-
peerRecordSize := 64 // HostID
572-
k, err := a.signKey.Raw()
573-
var nk int
574-
if err == nil {
575-
nk = len(k)
576-
} else {
577-
nk = 1024 // In case of error, use a large enough value.
578-
}
579-
peerRecordSize += 2 * nk // 1 for signature, 1 for public key
580-
// we want the final address list to be small for keeping the signed peer record in size
581-
addrs = trimHostAddrList(addrs, maxPeerRecordSize-peerRecordSize-256) // 256 B of buffer
582-
rec := peer.PeerRecordFromAddrInfo(peer.AddrInfo{
583-
ID: a.hostID,
584-
Addrs: addrs,
585-
})
586-
return record.Seal(rec, a.signKey)
587-
}
588-
589535
// emitLocalAddrsUpdated emits an EvtLocalAddressesUpdated event and updates the addresses in the peerstore.
590536
func (a *addrsManager) emitLocalAddrsUpdated(emitter event.Emitter, currentAddrs []ma.Multiaddr, lastAddrs []ma.Multiaddr) {
591537
added, maintained, removed := diffAddrs(lastAddrs, currentAddrs)
@@ -594,8 +540,11 @@ func (a *addrsManager) emitLocalAddrsUpdated(emitter event.Emitter, currentAddrs
594540
}
595541

596542
var sr *record.Envelope
597-
if a.signedRecordStore != nil {
598-
sr = a.signedRecordStore.GetPeerRecord(a.hostID)
543+
if a.peerstore != nil {
544+
ca, ok := a.peerstore.(peerstore.CertifiedAddrBook)
545+
if ok {
546+
sr = ca.GetPeerRecord(a.hostID)
547+
}
599548
}
600549

601550
evt := &event.EvtLocalAddressesUpdated{

p2p/host/basic/addrs_manager_test.go

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,10 @@ func (m *mockObservedAddrs) AddrsFor(local ma.Multiaddr) []ma.Multiaddr { return
5757

5858
var _ ObservedAddrsManager = &mockObservedAddrs{}
5959

60-
type addrStoreArgs struct {
61-
AddrStore addrStore
62-
SignKey crypto.PrivKey
63-
HostID peer.ID
64-
DisableSignedPeerRecord bool
60+
type peerstoreArgs struct {
61+
Peerstore peerstore.Peerstore
62+
HostID peer.ID
63+
SignKey crypto.PrivKey
6564
}
6665

6766
type addrsManagerArgs struct {
@@ -72,7 +71,7 @@ type addrsManagerArgs struct {
7271
AddCertHashes func([]ma.Multiaddr) []ma.Multiaddr
7372
AutoNATClient autonatv2Client
7473
Bus event.Bus
75-
AddrStoreArgs addrStoreArgs
74+
PeerstoreArgs peerstoreArgs
7675
}
7776

7877
type addrsManagerTestCase struct {
@@ -96,14 +95,14 @@ func newAddrsManagerTestCase(tb testing.TB, args addrsManagerArgs) addrsManagerT
9695
if args.AddCertHashes != nil {
9796
addCertHashes = args.AddCertHashes
9897
}
99-
signKey := args.AddrStoreArgs.SignKey
100-
addrStore := args.AddrStoreArgs.AddrStore
101-
pid := args.AddrStoreArgs.HostID
102-
if args.AddrStoreArgs == (addrStoreArgs{}) {
98+
peerstore := args.PeerstoreArgs.Peerstore
99+
pid := args.PeerstoreArgs.HostID
100+
signKey := args.PeerstoreArgs.SignKey
101+
if peerstore == nil {
103102
var err error
104103
signKey, _, err = crypto.GenerateEd25519Key(rand.Reader)
105104
require.NoError(tb, err)
106-
addrStore, err = pstoremem.NewPeerstore()
105+
peerstore, err = pstoremem.NewPeerstore()
107106
require.NoError(tb, err)
108107
pid, err = peer.IDFromPrivateKey(signKey)
109108
require.NoError(tb, err)
@@ -118,9 +117,7 @@ func newAddrsManagerTestCase(tb testing.TB, args addrsManagerArgs) addrsManagerT
118117
args.AutoNATClient,
119118
true,
120119
prometheus.DefaultRegisterer,
121-
false,
122-
signKey,
123-
addrStore,
120+
peerstore,
124121
pid,
125122
)
126123
require.NoError(tb, err)
@@ -456,6 +453,7 @@ func TestAddrsManagerPeerstoreUpdated(t *testing.T) {
456453
require.NoError(t, err)
457454
pid, err := peer.IDFromPrivateKey(signKey)
458455
require.NoError(t, err)
456+
require.NoError(t, pstore.AddPrivKey(pid, signKey))
459457

460458
var update atomic.Bool
461459
am := newAddrsManagerTestCase(t, addrsManagerArgs{
@@ -466,15 +464,16 @@ func TestAddrsManagerPeerstoreUpdated(t *testing.T) {
466464
}
467465
return []ma.Multiaddr{quic2}
468466
},
469-
AddrStoreArgs: addrStoreArgs{
470-
AddrStore: pstore,
467+
PeerstoreArgs: peerstoreArgs{
468+
Peerstore: pstore,
471469
HostID: pid,
472470
SignKey: signKey,
473471
},
474472
})
475473
defer am.Close()
476474
matest.AssertEqualMultiaddrs(t, []ma.Multiaddr{quic1}, pstore.Addrs(pid))
477475
ev := cab.GetPeerRecord(pid)
476+
require.NotNil(t, ev)
478477
pr := peerRecordFromEnvelope(t, ev)
479478
require.Equal(t, pr.Addrs, []ma.Multiaddr{quic1})
480479
update.Store(true)

p2p/host/basic/basic_host.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,6 @@ func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) {
237237
autonatv2Client,
238238
opts.EnableMetrics,
239239
opts.PrometheusRegisterer,
240-
opts.DisableSignedPeerRecord,
241-
h.Peerstore().PrivKey(h.ID()),
242240
h.Peerstore(),
243241
h.ID(),
244242
)

p2p/host/peerstore/pstoreds/peerstore.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import (
88

99
"github.com/libp2p/go-libp2p/core/peer"
1010
"github.com/libp2p/go-libp2p/core/peerstore"
11+
"github.com/libp2p/go-libp2p/core/record"
1112
pstore "github.com/libp2p/go-libp2p/p2p/host/peerstore"
1213

1314
ds "github.com/ipfs/go-datastore"
1415
"github.com/ipfs/go-datastore/query"
1516
"github.com/multiformats/go-base32"
17+
ma "github.com/multiformats/go-multiaddr"
1618
)
1719

1820
// Configuration object for the peerstore.
@@ -177,6 +179,33 @@ func (ps *pstoreds) PeerInfo(p peer.ID) peer.AddrInfo {
177179
}
178180
}
179181

182+
func (ps *pstoreds) UpdateHostAddrs(hostID peer.ID, currentAddrs, removedAddrs, peerRecordAddrs []ma.Multiaddr) error {
183+
// update host addresses in the peer store
184+
ps.dsAddrBook.SetAddrs(hostID, currentAddrs, peerstore.PermanentAddrTTL)
185+
ps.dsAddrBook.SetAddrs(hostID, removedAddrs, 0)
186+
187+
signKey := ps.dsKeyBook.PrivKey(hostID)
188+
if signKey == nil {
189+
log.Debug("no sign key found for host", "host", hostID)
190+
// don't return an error here. It's fine to not have a signed peer record.
191+
return nil
192+
}
193+
194+
pr := peer.PeerRecordFromAddrInfo(peer.AddrInfo{
195+
ID: hostID,
196+
Addrs: peerRecordAddrs,
197+
})
198+
rec, err := record.Seal(pr, signKey)
199+
if err != nil {
200+
return fmt.Errorf("error sealing peer record: %s", err)
201+
}
202+
_, err = ps.dsAddrBook.ConsumePeerRecord(rec, peerstore.PermanentAddrTTL)
203+
if err != nil {
204+
return fmt.Errorf("error consuming peer record: %s", err)
205+
}
206+
return nil
207+
}
208+
180209
// RemovePeer removes entries associated with a peer from:
181210
// * the KeyBook
182211
// * the ProtoBook

p2p/host/peerstore/pstoremem/peerstore.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66

77
"github.com/libp2p/go-libp2p/core/peer"
88
"github.com/libp2p/go-libp2p/core/peerstore"
9+
"github.com/libp2p/go-libp2p/core/record"
910
pstore "github.com/libp2p/go-libp2p/p2p/host/peerstore"
11+
ma "github.com/multiformats/go-multiaddr"
1012
)
1113

1214
type pstoremem struct {
@@ -98,6 +100,33 @@ func (ps *pstoremem) PeerInfo(p peer.ID) peer.AddrInfo {
98100
}
99101
}
100102

103+
func (ps *pstoremem) UpdateHostAddrs(hostID peer.ID, currentAddrs, removedAddrs, peerRecordAddrs []ma.Multiaddr) error {
104+
// update host addresses in the peer store
105+
ps.memoryAddrBook.SetAddrs(hostID, currentAddrs, peerstore.PermanentAddrTTL)
106+
ps.memoryAddrBook.SetAddrs(hostID, removedAddrs, 0)
107+
108+
signKey := ps.memoryKeyBook.PrivKey(hostID)
109+
if signKey == nil {
110+
log.Debug("no sign key found for host", "host", hostID)
111+
// don't return an error here. It's fine to not have a signed peer record.
112+
return nil
113+
}
114+
115+
pr := peer.PeerRecordFromAddrInfo(peer.AddrInfo{
116+
ID: hostID,
117+
Addrs: peerRecordAddrs,
118+
})
119+
rec, err := record.Seal(pr, signKey)
120+
if err != nil {
121+
return fmt.Errorf("error sealing peer record: %s", err)
122+
}
123+
_, err = ps.memoryAddrBook.ConsumePeerRecord(rec, peerstore.PermanentAddrTTL)
124+
if err != nil {
125+
return fmt.Errorf("error consuming peer record: %s", err)
126+
}
127+
return nil
128+
}
129+
101130
// RemovePeer removes entries associated with a peer from:
102131
// * the KeyBook
103132
// * the ProtoBook

0 commit comments

Comments
 (0)