Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion network/p2p/peerstore/peerstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,19 @@ func (ps *PeerStore) ReplacePeerList(addressesThey []*peer.AddrInfo, networkName

}
for _, info := range addressesThey {
if len(info.Addrs) == 0 {
// skip entries without addresses
continue
}
data, _ := ps.Get(info.ID, psmdkAddressData)
if data != nil {
// we already have this
// update the networkName and role
// update the networkName and role, and refresh the address TTL
ad := data.(addressData)
ad.networkNames[networkName] = true
ad.roles.Add(role)
_ = ps.Put(info.ID, psmdkAddressData, ad)
ps.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL)

// do not remove this entry
delete(removeItems, info.ID)
Expand All @@ -273,13 +278,19 @@ func (ps *PeerStore) AddPersistentPeers(addrInfo []*peer.AddrInfo, networkName s
defer ps.lock.Unlock()

for _, info := range addrInfo {
if len(info.Addrs) == 0 {
// skip entries without addresses
continue
}
data, _ := ps.Get(info.ID, psmdkAddressData)
if data != nil {
// we already have this.
// Make sure the persistence field is set to true and overwrite the role
ad := data.(addressData)
ad.roles.AddPersistent(role)
_ = ps.Put(info.ID, psmdkAddressData, ad)
// refresh the address TTL
ps.AddAddrs(info.ID, info.Addrs, libp2p.PermanentAddrTTL)
} else {
// we don't have this item. add it.
ps.AddAddrs(info.ID, info.Addrs, libp2p.PermanentAddrTTL)
Expand Down
54 changes: 54 additions & 0 deletions network/p2p/peerstore/peerstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,3 +610,57 @@ func TestReplacePeerList(t *testing.T) {
require.Contains(t, res, info)
}
}

// TestReplacePeerListRefreshesAddresses simulates addresses expiring
// by calling ReplacePeerList + UpdateAddrs(newTTL=0) + ReplacePeerList again
func TestReplacePeerListRefreshesAddresses(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

relaysSet := []string{"relay1:4160", "relay2:4160", "relay3:4160"}
infoRelaySet := make([]*peer.AddrInfo, 0)
for _, addr := range relaysSet {
info, err := peerInfoFromDomainPort(addr)
require.NoError(t, err)
infoRelaySet = append(infoRelaySet, info)
}

ph, err := MakePhonebook(1, time.Millisecond)
require.NoError(t, err)

ph.ReplacePeerList(infoRelaySet, "default", phonebook.RelayRole)

for _, info := range infoRelaySet {
addrs := ph.Addrs(info.ID)
require.NotEmpty(t, addrs)
}

// Simulate addr book GC run by setting zero TTL
for _, info := range infoRelaySet {
ph.UpdateAddrs(info.ID, libp2p.AddressTTL, 0)
}

// Verify metadata still exists but addresses are now empty
for _, info := range infoRelaySet {
addrs := ph.Addrs(info.ID)
require.Empty(t, addrs)
data, err := ph.Get(info.ID, psmdkAddressData)
require.NoError(t, err)
require.NotNil(t, data)
}

// Re-add the peer list, which should refresh the addresses
ph.ReplacePeerList(infoRelaySet, "default", phonebook.RelayRole)

// Verify addresses are restored
for _, info := range infoRelaySet {
addrs := ph.Addrs(info.ID)
require.NotEmpty(t, addrs)
}

result := ph.GetAddresses(len(relaysSet), phonebook.RelayRole)
require.Equal(t, len(relaysSet), len(result))
for _, info := range result {
require.NotEmpty(t, info.Addrs)
}
}
Loading