diff --git a/network/p2p/p2p.go b/network/p2p/p2p.go index 3f6737928a..8d5f3e4f38 100644 --- a/network/p2p/p2p.go +++ b/network/p2p/p2p.go @@ -243,7 +243,7 @@ func (s *serviceImpl) IDSigner() *PeerIDChallengeSigner { // DialPeersUntilTargetCount attempts to establish connections to the provided phonebook addresses func (s *serviceImpl) DialPeersUntilTargetCount(targetConnCount int) { ps := s.host.Peerstore().(*pstore.PeerStore) - addrInfos := ps.GetAddresses(targetConnCount, phonebook.PhoneBookEntryRelayRole) + addrInfos := ps.GetAddresses(targetConnCount, phonebook.RelayRole) conns := s.host.Network().Conns() var numOutgoingConns int for _, conn := range conns { diff --git a/network/p2p/peerstore/peerstore.go b/network/p2p/peerstore/peerstore.go index 5516db6250..479b07da5a 100644 --- a/network/p2p/peerstore/peerstore.go +++ b/network/p2p/peerstore/peerstore.go @@ -57,11 +57,8 @@ type addressData struct { networkNames map[string]bool mu *deadlock.RWMutex - // role is the role that this address serves. - role phonebook.PhoneBookEntryRoles - - // persistent is set true for peers whose record should not be removed for the peer list - persistent bool + // roles is the roles that this address serves. + roles phonebook.RoleSet } // peerStoreCAB combines the libp2p Peerstore and CertifiedAddrBook interfaces. @@ -78,7 +75,7 @@ func NewPeerStore(addrInfo []*peer.AddrInfo, network string) (*PeerStore, error) } pstore := &PeerStore{peerStoreCAB: ps} - pstore.AddPersistentPeers(addrInfo, network, phonebook.PhoneBookEntryRelayRole) + pstore.AddPersistentPeers(addrInfo, network, phonebook.RelayRole) return pstore, nil } @@ -97,7 +94,7 @@ func MakePhonebook(connectionsRateLimitingCount uint, } // GetAddresses returns up to N addresses, but may return fewer -func (ps *PeerStore) GetAddresses(n int, role phonebook.PhoneBookEntryRoles) []*peer.AddrInfo { +func (ps *PeerStore) GetAddresses(n int, role phonebook.Role) []*peer.AddrInfo { return shuffleSelect(ps.filterRetryTime(time.Now(), role), n) } @@ -205,7 +202,10 @@ func (ps *PeerStore) UpdateConnectionTime(addrOrPeerID string, provisionalTime t } // ReplacePeerList replaces the peer list for the given networkName and role. -func (ps *PeerStore) ReplacePeerList(addressesThey []*peer.AddrInfo, networkName string, role phonebook.PhoneBookEntryRoles) { +// new entries in addressesThey are being added +// existing items that aren't included in addressesThey are being removed +// matching entries roles gets updated as needed and persistent peers are not touched +func (ps *PeerStore) ReplacePeerList(addressesThey []*peer.AddrInfo, networkName string, role phonebook.Role) { // prepare a map of items we'd like to remove. removeItems := make(map[peer.ID]bool, 0) peerIDs := ps.Peers() @@ -213,23 +213,35 @@ func (ps *PeerStore) ReplacePeerList(addressesThey []*peer.AddrInfo, networkName data, _ := ps.Get(pid, addressDataKey) if data != nil { ad := data.(addressData) + updated := false ad.mu.RLock() - if ad.networkNames[networkName] && ad.role == role && !ad.persistent { - removeItems[pid] = true + if ad.networkNames[networkName] && !ad.roles.IsPersistent(role) { + if ad.roles.Is(role) { + removeItems[pid] = true + } else if ad.roles.Has(role) { + ad.roles.Remove(role) + updated = true + } } ad.mu.RUnlock() + + if updated { + _ = ps.Put(pid, addressDataKey, ad) + } } } for _, info := range addressesThey { data, _ := ps.Get(info.ID, addressDataKey) if data != nil { - // we already have this. - // Update the networkName + // we already have this + // update the networkName and role ad := data.(addressData) ad.mu.Lock() ad.networkNames[networkName] = true + ad.roles.Add(role) ad.mu.Unlock() + _ = ps.Put(info.ID, addressDataKey, ad) // do not remove this entry delete(removeItems, info.ID) @@ -248,15 +260,16 @@ func (ps *PeerStore) ReplacePeerList(addressesThey []*peer.AddrInfo, networkName } // AddPersistentPeers stores addresses of peers which are persistent. -// i.e. they won't be replaced by ReplacePeerList calls -func (ps *PeerStore) AddPersistentPeers(addrInfo []*peer.AddrInfo, networkName string, role phonebook.PhoneBookEntryRoles) { +// i.e. they won't be replaced by ReplacePeerList calls. +// If a peer is already in the peerstore, its role will be updated. +func (ps *PeerStore) AddPersistentPeers(addrInfo []*peer.AddrInfo, networkName string, role phonebook.Role) { for _, info := range addrInfo { data, _ := ps.Get(info.ID, addressDataKey) if data != nil { // we already have this. - // Make sure the persistence field is set to true + // Make sure the persistence field is set to true and overwrite the role ad := data.(addressData) - ad.persistent = true + ad.roles.AddPersistent(role) _ = ps.Put(info.ID, addressDataKey, ad) } else { // we don't have this item. add it. @@ -273,13 +286,12 @@ func (ps *PeerStore) Length() int { } // makePhonebookEntryData creates a new address entry for provided network name and role. -func makePhonebookEntryData(networkName string, role phonebook.PhoneBookEntryRoles, persistent bool) addressData { +func makePhonebookEntryData(networkName string, role phonebook.Role, persistent bool) addressData { pbData := addressData{ networkNames: make(map[string]bool), mu: &deadlock.RWMutex{}, recentConnectionTimes: make([]time.Time, 0), - role: role, - persistent: persistent, + roles: phonebook.MakeRoleSet(role, persistent), } pbData.networkNames[networkName] = true return pbData @@ -320,13 +332,13 @@ func (ps *PeerStore) popNElements(n int, peerID peer.ID) { _ = ps.Put(peerID, addressDataKey, ad) } -func (ps *PeerStore) filterRetryTime(t time.Time, role phonebook.PhoneBookEntryRoles) []*peer.AddrInfo { +func (ps *PeerStore) filterRetryTime(t time.Time, role phonebook.Role) []*peer.AddrInfo { o := make([]*peer.AddrInfo, 0, len(ps.Peers())) for _, peerID := range ps.Peers() { data, _ := ps.Get(peerID, addressDataKey) if data != nil { ad := data.(addressData) - if t.After(ad.retryAfter) && role == ad.role { + if t.After(ad.retryAfter) && ad.roles.Has(role) { mas := ps.Addrs(peerID) info := peer.AddrInfo{ID: peerID, Addrs: mas} o = append(o, &info) diff --git a/network/p2p/peerstore/peerstore_test.go b/network/p2p/peerstore/peerstore_test.go index 91152d4cd0..ddf5e70fe9 100644 --- a/network/p2p/peerstore/peerstore_test.go +++ b/network/p2p/peerstore/peerstore_test.go @@ -32,13 +32,6 @@ import ( "github.com/algorand/go-algorand/test/partitiontest" ) -// PhoneBookEntryRelayRole used for all the relays that are provided either via the algobootstrap SRV record -// or via a configuration file. -const PhoneBookEntryRelayRole = 1 - -// PhoneBookEntryArchiverRole used for all the archivers that are provided via the archive SRV record. -const PhoneBookEntryArchiverRole = 2 - func TestPeerstore(t *testing.T) { partitiontest.PartitionTest(t) t.Parallel() @@ -90,7 +83,7 @@ func TestPeerstore(t *testing.T) { } func testPhonebookAll(t *testing.T, set []*peer.AddrInfo, ph *PeerStore) { - actual := ph.GetAddresses(len(set), PhoneBookEntryRelayRole) + actual := ph.GetAddresses(len(set), phonebook.RelayRole) for _, info := range actual { ok := false for _, known := range set { @@ -125,7 +118,7 @@ func testPhonebookUniform(t *testing.T, set []*peer.AddrInfo, ph *PeerStore, get counts[set[i].ID.String()] = 0 } for i := 0; i < uniformityTestLength; i++ { - actual := ph.GetAddresses(getsize, PhoneBookEntryRelayRole) + actual := ph.GetAddresses(getsize, phonebook.RelayRole) for _, info := range actual { if _, ok := counts[info.ID.String()]; ok { counts[info.ID.String()]++ @@ -161,7 +154,7 @@ func TestArrayPhonebookAll(t *testing.T) { ph, err := MakePhonebook(1, 1*time.Millisecond) require.NoError(t, err) for _, addr := range set { - entry := makePhonebookEntryData("", PhoneBookEntryRelayRole, false) + entry := makePhonebookEntryData("", phonebook.RelayRole, false) info, _ := peerInfoFromDomainPort(addr) ph.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL) ph.Put(info.ID, addressDataKey, entry) @@ -183,7 +176,7 @@ func TestArrayPhonebookUniform1(t *testing.T) { ph, err := MakePhonebook(1, 1*time.Millisecond) require.NoError(t, err) for _, addr := range set { - entry := makePhonebookEntryData("", PhoneBookEntryRelayRole, false) + entry := makePhonebookEntryData("", phonebook.RelayRole, false) info, _ := peerInfoFromDomainPort(addr) ph.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL) ph.Put(info.ID, addressDataKey, entry) @@ -205,7 +198,7 @@ func TestArrayPhonebookUniform3(t *testing.T) { ph, err := MakePhonebook(1, 1*time.Millisecond) require.NoError(t, err) for _, addr := range set { - entry := makePhonebookEntryData("", PhoneBookEntryRelayRole, false) + entry := makePhonebookEntryData("", phonebook.RelayRole, false) info, _ := peerInfoFromDomainPort(addr) ph.AddAddrs(info.ID, info.Addrs, libp2p.AddressTTL) ph.Put(info.ID, addressDataKey, entry) @@ -223,19 +216,12 @@ func TestMultiPhonebook(t *testing.T) { require.NoError(t, err) infoSet = append(infoSet, info) } - pha := make([]*peer.AddrInfo, 0) - for _, e := range infoSet[:5] { - pha = append(pha, e) - } - phb := make([]*peer.AddrInfo, 0) - for _, e := range infoSet[5:] { - phb = append(phb, e) - } - + pha := append([]*peer.AddrInfo{}, infoSet[:5]...) + phb := append([]*peer.AddrInfo{}, infoSet[5:]...) ph, err := MakePhonebook(1, 1*time.Millisecond) require.NoError(t, err) - ph.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole) - ph.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole) + ph.ReplacePeerList(pha, "pha", phonebook.RelayRole) + ph.ReplacePeerList(phb, "phb", phonebook.RelayRole) testPhonebookAll(t, infoSet, ph) testPhonebookUniform(t, infoSet, ph, 1) @@ -258,23 +244,17 @@ func TestMultiPhonebookPersistentPeers(t *testing.T) { infoSet = append(infoSet, info) } - pha := make([]*peer.AddrInfo, 0) - for _, e := range infoSet[:5] { - pha = append(pha, e) - } - phb := make([]*peer.AddrInfo, 0) - for _, e := range infoSet[5:] { - phb = append(phb, e) - } + pha := append([]*peer.AddrInfo{}, infoSet[:5]...) + phb := append([]*peer.AddrInfo{}, infoSet[5:]...) ph, err := MakePhonebook(1, 1*time.Millisecond) require.NoError(t, err) - ph.AddPersistentPeers(persistentPeers, "pha", PhoneBookEntryRelayRole) - ph.AddPersistentPeers(persistentPeers, "phb", PhoneBookEntryRelayRole) - ph.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole) - ph.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole) + ph.AddPersistentPeers(persistentPeers, "pha", phonebook.RelayRole) + ph.AddPersistentPeers(persistentPeers, "phb", phonebook.RelayRole) + ph.ReplacePeerList(pha, "pha", phonebook.RelayRole) + ph.ReplacePeerList(phb, "phb", phonebook.RelayRole) testPhonebookAll(t, append(infoSet, info), ph) - allAddresses := ph.GetAddresses(len(set)+len(persistentPeers), PhoneBookEntryRelayRole) + allAddresses := ph.GetAddresses(len(set)+len(persistentPeers), phonebook.RelayRole) for _, pp := range persistentPeers { found := false for _, addr := range allAddresses { @@ -285,6 +265,29 @@ func TestMultiPhonebookPersistentPeers(t *testing.T) { } require.True(t, found, fmt.Sprintf("%s not found in %v", string(pp.ID), allAddresses)) } + + // check that role of persistent peer gets updated with AddPersistentPeers + ph2, err := MakePhonebook(1, 1*time.Millisecond) + require.NoError(t, err) + ph2.AddPersistentPeers(persistentPeers, "phc", phonebook.RelayRole) + ph2.AddPersistentPeers(persistentPeers, "phc", phonebook.ArchivalRole) + allAddresses = ph2.GetAddresses(len(set)+len(persistentPeers), phonebook.RelayRole) + require.Len(t, allAddresses, 1) + allAddresses = ph2.GetAddresses(len(set)+len(persistentPeers), phonebook.ArchivalRole) + require.Len(t, allAddresses, 1) + + // check that role of persistent peer survives + ph3, err := MakePhonebook(1, 1*time.Millisecond) + ph3.AddPersistentPeers(persistentPeers, "phc", phonebook.ArchivalRole) + require.NoError(t, err) + phc := []*peer.AddrInfo{info} + ph3.ReplacePeerList(phc, "phc", phonebook.RelayRole) + + allAddresses = ph3.GetAddresses(len(set)+len(persistentPeers), phonebook.RelayRole) + require.Len(t, allAddresses, 1) + allAddresses = ph3.GetAddresses(len(set)+len(persistentPeers), phonebook.ArchivalRole) + require.Len(t, allAddresses, 1) + } func TestMultiPhonebookDuplicateFiltering(t *testing.T) { @@ -298,18 +301,12 @@ func TestMultiPhonebookDuplicateFiltering(t *testing.T) { infoSet = append(infoSet, info) } - pha := make([]*peer.AddrInfo, 0) - for _, e := range infoSet[:7] { - pha = append(pha, e) - } - phb := make([]*peer.AddrInfo, 0) - for _, e := range infoSet[3:] { - phb = append(phb, e) - } + pha := append([]*peer.AddrInfo{}, infoSet[:7]...) + phb := append([]*peer.AddrInfo{}, infoSet[3:]...) ph, err := MakePhonebook(1, 1*time.Millisecond) require.NoError(t, err) - ph.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole) - ph.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole) + ph.ReplacePeerList(pha, "pha", phonebook.RelayRole) + ph.ReplacePeerList(phb, "phb", phonebook.RelayRole) testPhonebookAll(t, infoSet, ph) testPhonebookUniform(t, infoSet, ph, 1) @@ -338,7 +335,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { // Test the addresses are populated in the phonebook and a // time can be added to one of them - entries.ReplacePeerList([]*peer.AddrInfo{info1, info2}, "default", PhoneBookEntryRelayRole) + entries.ReplacePeerList([]*peer.AddrInfo{info1, info2}, "default", phonebook.RelayRole) addrInPhonebook, waitTime, provisionalTime := entries.GetConnectionWaitTime(string(info1.ID)) require.Equal(t, true, addrInPhonebook) require.Equal(t, time.Duration(0), waitTime) @@ -355,7 +352,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { } // add another value to addr - addrInPhonebook, waitTime, provisionalTime = entries.GetConnectionWaitTime(string(info1.ID)) + _, waitTime, provisionalTime = entries.GetConnectionWaitTime(string(info1.ID)) require.Equal(t, time.Duration(0), waitTime) require.Equal(t, true, entries.UpdateConnectionTime(string(info1.ID), provisionalTime)) data, _ = entries.Get(info1.ID, addressDataKey) @@ -370,7 +367,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { // the first time should be removed and a new one added // there should not be any wait - addrInPhonebook, waitTime, provisionalTime = entries.GetConnectionWaitTime(string(info1.ID)) + _, waitTime, provisionalTime = entries.GetConnectionWaitTime(string(info1.ID)) require.Equal(t, time.Duration(0), waitTime) require.Equal(t, true, entries.UpdateConnectionTime(string(info1.ID), provisionalTime)) data, _ = entries.Get(info1.ID, addressDataKey) @@ -416,7 +413,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { require.Equal(t, 3, len(phBookData)) // add another element to trigger wait - _, waitTime, provisionalTime = entries.GetConnectionWaitTime(string(info2.ID)) + _, waitTime, _ = entries.GetConnectionWaitTime(string(info2.ID)) require.Greater(t, int64(waitTime), int64(0)) // no element should be removed data2, _ = entries.Get(info2.ID, addressDataKey) @@ -469,20 +466,20 @@ func TestPhonebookRoles(t *testing.T) { ph, err := MakePhonebook(1, 1) require.NoError(t, err) - ph.ReplacePeerList(infoRelaySet, "default", PhoneBookEntryRelayRole) - ph.ReplacePeerList(infoArchiverSet, "default", PhoneBookEntryArchiverRole) + ph.ReplacePeerList(infoRelaySet, "default", phonebook.RelayRole) + ph.ReplacePeerList(infoArchiverSet, "default", phonebook.ArchivalRole) require.Equal(t, len(relaysSet)+len(archiverSet), len(ph.Peers())) require.Equal(t, len(relaysSet)+len(archiverSet), ph.Length()) - for _, role := range []phonebook.PhoneBookEntryRoles{PhoneBookEntryRelayRole, PhoneBookEntryArchiverRole} { + for _, role := range []phonebook.Role{phonebook.RelayRole, phonebook.ArchivalRole} { for k := 0; k < 100; k++ { for l := 0; l < 3; l++ { entries := ph.GetAddresses(l, role) - if role == PhoneBookEntryRelayRole { + if role == phonebook.RelayRole { for _, entry := range entries { require.Contains(t, string(entry.ID), "relay") } - } else if role == PhoneBookEntryArchiverRole { + } else if role == phonebook.ArchivalRole { for _, entry := range entries { require.Contains(t, string(entry.ID), "archiver") } @@ -491,3 +488,125 @@ func TestPhonebookRoles(t *testing.T) { } } } + +// TestPhonebookRolesMulti makes sure the same host might have multiple roles +func TestPhonebookRolesMulti(t *testing.T) { + partitiontest.PartitionTest(t) + + relaysSet := []string{"relay1:4040", "relay2:4041"} + archiverSet := []string{"relay1:4040", "archiver1:1111"} + const numUnique = 3 + + infoRelaySet := make([]*peer.AddrInfo, 0) + for _, addr := range relaysSet { + info, err := peerInfoFromDomainPort(addr) + require.NoError(t, err) + infoRelaySet = append(infoRelaySet, info) + } + + infoArchiverSet := make([]*peer.AddrInfo, 0) + for _, addr := range archiverSet { + info, err := peerInfoFromDomainPort(addr) + require.NoError(t, err) + infoArchiverSet = append(infoArchiverSet, info) + } + + ph, err := MakePhonebook(1, 1) + require.NoError(t, err) + ph.ReplacePeerList(infoRelaySet, "default", phonebook.RelayRole) + ph.ReplacePeerList(infoArchiverSet, "default", phonebook.ArchivalRole) + require.Equal(t, numUnique, len(ph.Peers())) + require.Equal(t, numUnique, ph.Length()) + + const maxPeers = 5 + entries := ph.GetAddresses(maxPeers, phonebook.RelayRole) + require.Equal(t, len(relaysSet), len(entries)) + entries = ph.GetAddresses(maxPeers, phonebook.ArchivalRole) + require.Equal(t, len(archiverSet), len(entries)) +} + +func TestReplacePeerList(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + relaysSet := []string{"a:1", "b:2"} + archiverSet := []string{"c:3"} + comboSet := []string{"b:2", "c:3"} // b is in both sets + + infoRelaySet := make([]*peer.AddrInfo, 0) + for _, addr := range relaysSet { + info, err := peerInfoFromDomainPort(addr) + require.NoError(t, err) + infoRelaySet = append(infoRelaySet, info) + } + + infoArchiverSet := make([]*peer.AddrInfo, 0) + for _, addr := range archiverSet { + info, err := peerInfoFromDomainPort(addr) + require.NoError(t, err) + infoArchiverSet = append(infoArchiverSet, info) + } + + infoComboArchiverSet := make([]*peer.AddrInfo, 0) + for _, addr := range comboSet { + info, err := peerInfoFromDomainPort(addr) + require.NoError(t, err) + infoComboArchiverSet = append(infoComboArchiverSet, info) + } + + ph, err := MakePhonebook(1, 1) + require.NoError(t, err) + + ph.ReplacePeerList(infoRelaySet, "default", phonebook.RelayRole) + res := ph.GetAddresses(4, phonebook.RelayRole) + require.Equal(t, 2, len(res)) + for _, info := range infoRelaySet { + require.Contains(t, res, info) + } + + ph.ReplacePeerList(infoArchiverSet, "default", phonebook.ArchivalRole) + res = ph.GetAddresses(4, phonebook.ArchivalRole) + require.Equal(t, 1, len(res)) + for _, info := range infoArchiverSet { + require.Contains(t, res, info) + } + + // make b archival in addition to relay + ph.ReplacePeerList(infoComboArchiverSet, "default", phonebook.ArchivalRole) + res = ph.GetAddresses(4, phonebook.RelayRole) + require.Equal(t, 2, len(res)) + for _, info := range infoRelaySet { + require.Contains(t, res, info) + } + res = ph.GetAddresses(4, phonebook.ArchivalRole) + require.Equal(t, 2, len(res)) + for _, info := range infoComboArchiverSet { + require.Contains(t, res, info) + } + + // update relays + ph.ReplacePeerList(infoRelaySet, "default", phonebook.RelayRole) + res = ph.GetAddresses(4, phonebook.RelayRole) + require.Equal(t, 2, len(res)) + for _, info := range infoRelaySet { + require.Contains(t, res, info) + } + res = ph.GetAddresses(4, phonebook.ArchivalRole) + require.Equal(t, 2, len(res)) + for _, info := range infoComboArchiverSet { + require.Contains(t, res, info) + } + + // exclude b from archival + ph.ReplacePeerList(infoArchiverSet, "default", phonebook.ArchivalRole) + res = ph.GetAddresses(4, phonebook.RelayRole) + require.Equal(t, 2, len(res)) + for _, info := range infoRelaySet { + require.Contains(t, res, info) + } + res = ph.GetAddresses(4, phonebook.ArchivalRole) + require.Equal(t, 1, len(res)) + for _, info := range infoArchiverSet { + require.Contains(t, res, info) + } +} diff --git a/network/p2pNetwork.go b/network/p2pNetwork.go index 43a59eb0d6..d30d332c52 100644 --- a/network/p2pNetwork.go +++ b/network/p2pNetwork.go @@ -45,6 +45,9 @@ import ( manet "github.com/multiformats/go-multiaddr/net" ) +// some arbitrary number TODO: figure out a better value based on peerSelector/fetcher algorithm +const numArchivalPeersToFind = 4 + // P2PNetwork implements the GossipNode interface type P2PNetwork struct { service p2p.Service @@ -434,15 +437,31 @@ func (n *P2PNetwork) meshThreadInner() int { n.log.Warnf("Error getting relay nodes from capabilities discovery: %v", err) } n.log.Debugf("Discovered %d gossip peers from DHT", len(dhtPeers)) + + // also discover archival nodes + var dhtArchivalPeers []peer.AddrInfo + dhtArchivalPeers, err = n.capabilitiesDiscovery.PeersForCapability(p2p.Archival, numArchivalPeersToFind) + if err != nil { + n.log.Warnf("Error getting archival nodes from capabilities discovery: %v", err) + } + n.log.Debugf("Discovered %d archival peers from DHT", len(dhtArchivalPeers)) + + if len(dhtArchivalPeers) > 0 { + replace := make([]*peer.AddrInfo, len(dhtArchivalPeers)) + for i := range dhtArchivalPeers { + replace[i] = &dhtArchivalPeers[i] + } + n.pstore.ReplacePeerList(replace, string(n.networkID), phonebook.ArchivalRole) + } } peers := mergeP2PAddrInfoResolvedAddresses(dnsPeers, dhtPeers) - replace := make([]*peer.AddrInfo, 0, len(peers)) + replace := make([]*peer.AddrInfo, len(peers)) for i := range peers { - replace = append(replace, &peers[i]) + replace[i] = &peers[i] } if len(peers) > 0 { - n.pstore.ReplacePeerList(replace, string(n.networkID), phonebook.PhoneBookEntryRelayRole) + n.pstore.ReplacePeerList(replace, string(n.networkID), phonebook.RelayRole) } return len(peers) } @@ -640,7 +659,7 @@ func (n *P2PNetwork) GetPeers(options ...PeerOption) []Peer { n.wsPeersLock.RUnlock() case PeersPhonebookRelays: const maxNodes = 100 - addrInfos := n.pstore.GetAddresses(maxNodes, phonebook.PhoneBookEntryRelayRole) + addrInfos := n.pstore.GetAddresses(maxNodes, phonebook.RelayRole) for _, peerInfo := range addrInfos { if peerInfo.ID == n.service.ID() { continue @@ -657,30 +676,22 @@ func (n *P2PNetwork) GetPeers(options ...PeerOption) []Peer { n.log.Debugf("Relay node(s) from peerstore: %v", addrs) } case PeersPhonebookArchivalNodes: - // query known archival nodes from DHT if enabled - if n.config.EnableDHTProviders { - const nodesToFind = 5 - infos, err := n.capabilitiesDiscovery.PeersForCapability(p2p.Archival, nodesToFind) - if err != nil { - n.log.Warnf("Error getting archival nodes from capabilities discovery: %v", err) - return peers + // query known archival nodes that came from from DHT if enabled (or DNS if configured) + addrInfos := n.pstore.GetAddresses(numArchivalPeersToFind, phonebook.ArchivalRole) + for _, peerInfo := range addrInfos { + if peerInfo.ID == n.service.ID() { + continue } - n.log.Debugf("Got %d archival node(s) from DHT", len(infos)) - for _, addrInfo := range infos { - if addrInfo.ID == n.service.ID() { - continue - } - if peerCore, ok := addrInfoToWsPeerCore(n, &addrInfo); ok { - peers = append(peers, &peerCore) - } + if peerCore, ok := addrInfoToWsPeerCore(n, peerInfo); ok { + peers = append(peers, &peerCore) } - if n.log.GetLevel() >= logging.Debug && len(peers) > 0 { - addrs := make([]string, 0, len(peers)) - for _, peer := range peers { - addrs = append(addrs, peer.(*wsPeerCore).GetAddress()) - } - n.log.Debugf("Archival node(s) from DHT: %v", addrs) + } + if n.log.GetLevel() >= logging.Debug && len(peers) > 0 { + addrs := make([]string, 0, len(peers)) + for _, peer := range peers { + addrs = append(addrs, peer.(*wsPeerCore).GetAddress()) } + n.log.Debugf("Archival node(s) from peerstore: %v", addrs) } case PeersConnectedIn: n.wsPeersLock.RLock() diff --git a/network/p2pNetwork_test.go b/network/p2pNetwork_test.go index 079bbbab03..a7b15fad4f 100644 --- a/network/p2pNetwork_test.go +++ b/network/p2pNetwork_test.go @@ -598,7 +598,7 @@ func TestP2PNetworkDHTCapabilities(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - netA, err := NewP2PNetwork(log, cfg, "", nil, genesisID, config.Devtestnet, test.nis[0], nil) + netA, err := NewP2PNetwork(log.With("name", "netA"), cfg, "", nil, genesisID, config.Devtestnet, test.nis[0], nil) require.NoError(t, err) err = netA.Start() @@ -612,13 +612,13 @@ func TestP2PNetworkDHTCapabilities(t *testing.T) { multiAddrStr := addrsA[0].String() phoneBookAddresses := []string{multiAddrStr} - netB, err := NewP2PNetwork(log, cfg, "", phoneBookAddresses, genesisID, config.Devtestnet, test.nis[1], nil) + netB, err := NewP2PNetwork(log.With("name", "netB"), cfg, "", phoneBookAddresses, genesisID, config.Devtestnet, test.nis[1], nil) require.NoError(t, err) err = netB.Start() require.NoError(t, err) defer netB.Stop() - netC, err := NewP2PNetwork(log, cfg, "", phoneBookAddresses, genesisID, config.Devtestnet, test.nis[2], nil) + netC, err := NewP2PNetwork(log.With("name", "netC"), cfg, "", phoneBookAddresses, genesisID, config.Devtestnet, test.nis[2], nil) require.NoError(t, err) err = netC.Start() require.NoError(t, err) @@ -680,9 +680,10 @@ func TestP2PNetworkDHTCapabilities(t *testing.T) { fmt.Sprintf("Not all expected %s cap peers were found", cap), ) // ensure GetPeers gets PeersPhonebookArchivalNodes peers - // it appears there are artifical peers because of listening on localhost and on a real network interface + // it appears there are artificial peers because of listening on localhost and on a real network interface // so filter out and save only unique peers by their IDs net := nets[idx] + net.meshThreadInner() // update peerstore with DHT peers peers := net.GetPeers(PeersPhonebookArchivalNodes) uniquePeerIDs := make(map[peer.ID]struct{}) for _, p := range peers { @@ -790,7 +791,7 @@ func TestP2PHTTPHandler(t *testing.T) { require.NoError(t, err) pstore, err := peerstore.MakePhonebook(0, 10*time.Second) require.NoError(t, err) - pstore.AddPersistentPeers([]*peer.AddrInfo{&peerInfoA}, "net", phonebook.PhoneBookEntryRelayRole) + pstore.AddPersistentPeers([]*peer.AddrInfo{&peerInfoA}, "net", phonebook.RelayRole) httpClient, err = netB.service.GetHTTPClient(&peerInfoA, pstore, 1*time.Second) require.NoError(t, err) _, err = httpClient.Get("/test") @@ -1427,7 +1428,7 @@ func TestGetPeersFiltersSelf(t *testing.T) { ID: selfID, Addrs: []multiaddr.Multiaddr{selfAddr}, } - net.pstore.AddPersistentPeers([]*peer.AddrInfo{selfInfo}, "test-network", phonebook.PhoneBookEntryRelayRole) + net.pstore.AddPersistentPeers([]*peer.AddrInfo{selfInfo}, "test-network", phonebook.RelayRole) // Create and add another peer otherID, err := peer.Decode("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") @@ -1438,7 +1439,7 @@ func TestGetPeersFiltersSelf(t *testing.T) { ID: otherID, Addrs: []multiaddr.Multiaddr{addr}, } - net.pstore.AddPersistentPeers([]*peer.AddrInfo{otherInfo}, "test-network", phonebook.PhoneBookEntryRelayRole) + net.pstore.AddPersistentPeers([]*peer.AddrInfo{otherInfo}, "test-network", phonebook.RelayRole) peers := net.GetPeers(PeersPhonebookRelays) diff --git a/network/phonebook/phonebook.go b/network/phonebook/phonebook.go index 8e8dacc1f0..58d3774cc1 100644 --- a/network/phonebook/phonebook.go +++ b/network/phonebook/phonebook.go @@ -29,23 +29,84 @@ import ( // of how many addresses the phonebook actually has. ( with the retry-after logic applied ) const getAllAddresses = math.MaxInt32 -// PhoneBookEntryRoles defines the roles that a single entry on the phonebook can take. -// currently, we have two roles : relay role and archival role, which are mutually exclusive. +// RoleSet defines the roles that a single entry on the phonebook can take. +// currently, we have two roles : relay role and archival role. // -//msgp:ignore PhoneBookEntryRoles -type PhoneBookEntryRoles int +//msgp:ignore Roles +type RoleSet struct { + roles Role // roles is a bitfield of the roles that this entry has + persistence persistence // persistence is a bitfield of the roles that are persistent + _ func() // func is not comparable so that Roles. This is to prevent roles misuse and direct comparison. +} + +// Role is a single role that a phonebook entry can have. +type Role uint8 +type persistence uint8 -// PhoneBookEntryRelayRole used for all the relays that are provided either via the algobootstrap SRV record -// or via a configuration file. -const PhoneBookEntryRelayRole = 1 +// enforceUint8 is a generic type that only compiles for types whose underlying type is uint8. +type enforceUint8[T ~uint8] struct{} -// PhoneBookEntryArchivalRole used for all the archival nodes that are provided via the archive SRV record. -const PhoneBookEntryArchivalRole = 2 +// enforce the underlying type of Role and persistence to be the same uint8 +var _ enforceUint8[Role] +var _ enforceUint8[persistence] + +const ( + // RelayRole used for all the relays that are provided either via the algobootstrap SRV record + // or via a configuration file. + RelayRole Role = 1 << iota + // ArchivalRole used for all the archival nodes that are provided via the archive SRV record. + ArchivalRole +) + +// MakeRoleSet creates a new RoleSet with the passed role +func MakeRoleSet(role Role, persistent bool) RoleSet { + r := RoleSet{roles: role} + if persistent { + r.persistence = persistence(role) + } + return r +} + +// Has checks if the role in this role set has the other role +func (r RoleSet) Has(other Role) bool { + return r.roles&other != 0 +} + +// Is checks if this set of roles is exactly the same as the other roles +func (r RoleSet) Is(other Role) bool { + return r.roles == other +} + +// Add adds the other roles to this set of roles +func (r *RoleSet) Add(other Role) { + r.roles |= other +} + +// Remove removes the other role from this set of roles +func (r *RoleSet) Remove(other Role) { + r.roles &= ^other +} + +// AddPersistent adds a role and marks it as persistent +func (r *RoleSet) AddPersistent(role Role) { + r.roles |= role + r.persistence |= persistence(role) +} + +// IsPersistent checks if the given role is marked as persistent +func (r RoleSet) IsPersistent(role Role) bool { + return r.persistence&persistence(role) != 0 +} + +// hasPersistentRoles checks if there are any persistent roles in the set +func (r RoleSet) hasPersistentRoles() bool { + return r.persistence != 0 +} // Phonebook stores or looks up addresses of nodes we might contact type Phonebook interface { // GetAddresses(N) returns up to N addresses, but may return fewer - GetAddresses(n int, role PhoneBookEntryRoles) []string + GetAddresses(n int, role Role) []string // UpdateRetryAfter updates the retry-after field for the entries matching the given address UpdateRetryAfter(addr string, retryAfter time.Time) @@ -65,12 +126,13 @@ type Phonebook interface { // ReplacePeerList merges a set of addresses with that passed in for networkName // new entries in dnsAddresses are being added // existing items that aren't included in dnsAddresses are being removed - // matching entries don't change - ReplacePeerList(dnsAddresses []string, networkName string, role PhoneBookEntryRoles) + // matching entries roles gets updated as needed and persistent peers are not touched + ReplacePeerList(dnsAddresses []string, networkName string, role Role) // AddPersistentPeers stores addresses of peers which are persistent. - // i.e. they won't be replaced by ReplacePeerList calls - AddPersistentPeers(dnsAddresses []string, networkName string, role PhoneBookEntryRoles) + // i.e. they won't be replaced by ReplacePeerList calls. + // If a peer is already in the peerstore, its role will be updated. + AddPersistentPeers(dnsAddresses []string, networkName string, role Role) } // addressData: holds the information associated with each phonebook address. @@ -85,20 +147,16 @@ type addressData struct { // networkNames: lists the networks to which the given address belongs. networkNames map[string]bool - // role is the role that this address serves. - role PhoneBookEntryRoles - - // persistent is set true for peers whose record should not be removed for the peer list - persistent bool + // roles is the roles that this address serves. + roles RoleSet } // makePhonebookEntryData creates a new addressData entry for provided network name and role. -func makePhonebookEntryData(networkName string, role PhoneBookEntryRoles, persistent bool) addressData { +func makePhonebookEntryData(networkName string, role Role, persistent bool) addressData { pbData := addressData{ networkNames: make(map[string]bool), recentConnectionTimes: make([]time.Time, 0), - role: role, - persistent: persistent, + roles: MakeRoleSet(role, persistent), } pbData.networkNames[networkName] = true return pbData @@ -127,7 +185,7 @@ func MakePhonebook(connectionsRateLimitingCount uint, func (e *phonebookImpl) deletePhonebookEntry(entryName, networkName string) { pbEntry := e.data[entryName] delete(pbEntry.networkNames, networkName) - if 0 == len(pbEntry.networkNames) { + if len(pbEntry.networkNames) == 0 { delete(e.data, entryName) } } @@ -149,10 +207,10 @@ func (e *phonebookImpl) appendTime(addr string, t time.Time) { e.data[addr] = entry } -func (e *phonebookImpl) filterRetryTime(t time.Time, role PhoneBookEntryRoles) []string { +func (e *phonebookImpl) filterRetryTime(t time.Time, role Role) []string { o := make([]string, 0, len(e.data)) for addr, entry := range e.data { - if t.After(entry.retryAfter) && role == entry.role { + if t.After(entry.retryAfter) && entry.roles.Has(role) { o = append(o, addr) } } @@ -162,24 +220,31 @@ func (e *phonebookImpl) filterRetryTime(t time.Time, role PhoneBookEntryRoles) [ // ReplacePeerList merges a set of addresses with that passed in. // new entries in addressesThey are being added // existing items that aren't included in addressesThey are being removed -// matching entries don't change -func (e *phonebookImpl) ReplacePeerList(addressesThey []string, networkName string, role PhoneBookEntryRoles) { +// matching entries roles gets updated as needed and persistent peers are not touched +func (e *phonebookImpl) ReplacePeerList(addressesThey []string, networkName string, role Role) { e.lock.Lock() defer e.lock.Unlock() // prepare a map of items we'd like to remove. removeItems := make(map[string]bool, 0) for k, pbd := range e.data { - if pbd.networkNames[networkName] && pbd.role == role && !pbd.persistent { - removeItems[k] = true + if pbd.networkNames[networkName] && !pbd.roles.IsPersistent(role) { + if pbd.roles.Is(role) { + removeItems[k] = true + } else if pbd.roles.Has(role) { + pbd.roles.Remove(role) + e.data[k] = pbd + } } } for _, addr := range addressesThey { if pbData, has := e.data[addr]; has { - // we already have this. - // Update the networkName + // we already have this + // update the networkName and role pbData.networkNames[networkName] = true + pbData.roles.Add(role) + e.data[addr] = pbData // do not remove this entry delete(removeItems, addr) @@ -195,15 +260,18 @@ func (e *phonebookImpl) ReplacePeerList(addressesThey []string, networkName stri } } -func (e *phonebookImpl) AddPersistentPeers(dnsAddresses []string, networkName string, role PhoneBookEntryRoles) { +// AddPersistentPeers stores addresses of peers which are persistent. +// i.e. they won't be replaced by ReplacePeerList calls. +// If a peer is already in the peerstore, its role will be updated. +func (e *phonebookImpl) AddPersistentPeers(dnsAddresses []string, networkName string, role Role) { e.lock.Lock() defer e.lock.Unlock() for _, addr := range dnsAddresses { if pbData, has := e.data[addr]; has { // we already have this. - // Make sure the persistence field is set to true - pbData.persistent = true + // Make sure the persistence field is set to true and overwrite the role + pbData.roles.AddPersistent(role) e.data[addr] = pbData } else { // we don't have this item. add it. @@ -335,7 +403,7 @@ func shuffleSelect(set []string, n int) []string { } // GetAddresses returns up to N shuffled address -func (e *phonebookImpl) GetAddresses(n int, role PhoneBookEntryRoles) []string { +func (e *phonebookImpl) GetAddresses(n int, role Role) []string { e.lock.RLock() defer e.lock.RUnlock() return shuffleSelect(e.filterRetryTime(time.Now(), role), n) diff --git a/network/phonebook/phonebook_test.go b/network/phonebook/phonebook_test.go index 7fdf022153..b0805582d0 100644 --- a/network/phonebook/phonebook_test.go +++ b/network/phonebook/phonebook_test.go @@ -25,7 +25,7 @@ import ( ) func testPhonebookAll(t *testing.T, set []string, ph Phonebook) { - actual := ph.GetAddresses(len(set), PhoneBookEntryRelayRole) + actual := ph.GetAddresses(len(set), RelayRole) for _, got := range actual { ok := false for _, known := range set { @@ -57,7 +57,7 @@ func testPhonebookUniform(t *testing.T, set []string, ph Phonebook, getsize int) expected := (uniformityTestLength * getsize) / len(set) counts := make([]int, len(set)) for i := 0; i < uniformityTestLength; i++ { - actual := ph.GetAddresses(getsize, PhoneBookEntryRelayRole) + actual := ph.GetAddresses(getsize, RelayRole) for i, known := range set { for _, xa := range actual { if known == xa { @@ -88,7 +88,7 @@ func TestArrayPhonebookAll(t *testing.T) { set := []string{"a", "b", "c", "d", "e"} ph := MakePhonebook(1, 1).(*phonebookImpl) for _, e := range set { - ph.data[e] = makePhonebookEntryData("", PhoneBookEntryRelayRole, false) + ph.data[e] = makePhonebookEntryData("", RelayRole, false) } testPhonebookAll(t, set, ph) } @@ -99,7 +99,7 @@ func TestArrayPhonebookUniform1(t *testing.T) { set := []string{"a", "b", "c", "d", "e"} ph := MakePhonebook(1, 1).(*phonebookImpl) for _, e := range set { - ph.data[e] = makePhonebookEntryData("", PhoneBookEntryRelayRole, false) + ph.data[e] = makePhonebookEntryData("", RelayRole, false) } testPhonebookUniform(t, set, ph, 1) } @@ -110,7 +110,7 @@ func TestArrayPhonebookUniform3(t *testing.T) { set := []string{"a", "b", "c", "d", "e"} ph := MakePhonebook(1, 1).(*phonebookImpl) for _, e := range set { - ph.data[e] = makePhonebookEntryData("", PhoneBookEntryRelayRole, false) + ph.data[e] = makePhonebookEntryData("", RelayRole, false) } testPhonebookUniform(t, set, ph, 3) } @@ -119,17 +119,11 @@ func TestMultiPhonebook(t *testing.T) { partitiontest.PartitionTest(t) set := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"} - pha := make([]string, 0) - for _, e := range set[:5] { - pha = append(pha, e) - } - phb := make([]string, 0) - for _, e := range set[5:] { - phb = append(phb, e) - } + pha := append([]string{}, set[:5]...) + phb := append([]string{}, set[5:]...) mp := MakePhonebook(1, 1*time.Millisecond) - mp.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole) - mp.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole) + mp.ReplacePeerList(pha, "pha", RelayRole) + mp.ReplacePeerList(phb, "phb", RelayRole) testPhonebookAll(t, set, mp) testPhonebookUniform(t, set, mp, 1) @@ -143,42 +137,50 @@ func TestMultiPhonebookPersistentPeers(t *testing.T) { persistentPeers := []string{"a"} set := []string{"b", "c", "d", "e", "f", "g", "h", "i", "j", "k"} - pha := make([]string, 0) - for _, e := range set[:5] { - pha = append(pha, e) - } - phb := make([]string, 0) - for _, e := range set[5:] { - phb = append(phb, e) - } + pha := append([]string{}, set[:5]...) + phb := append([]string{}, set[5:]...) mp := MakePhonebook(1, 1*time.Millisecond) - mp.AddPersistentPeers(persistentPeers, "pha", PhoneBookEntryRelayRole) - mp.AddPersistentPeers(persistentPeers, "phb", PhoneBookEntryRelayRole) - mp.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole) - mp.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole) + mp.AddPersistentPeers(persistentPeers, "pha", RelayRole) + mp.AddPersistentPeers(persistentPeers, "phb", RelayRole) + mp.ReplacePeerList(pha, "pha", RelayRole) + mp.ReplacePeerList(phb, "phb", RelayRole) testPhonebookAll(t, append(set, persistentPeers...), mp) - allAddresses := mp.GetAddresses(len(set)+len(persistentPeers), PhoneBookEntryRelayRole) + allAddresses := mp.GetAddresses(len(set)+len(persistentPeers), RelayRole) for _, pp := range persistentPeers { require.Contains(t, allAddresses, pp) } + + // check that role of persistent peer gets updated with AddPersistentPeers + mp2 := MakePhonebook(1, 1*time.Millisecond) + mp2.AddPersistentPeers(persistentPeers, "phc", RelayRole) + mp2.AddPersistentPeers(persistentPeers, "phc", ArchivalRole) + allAddresses = mp2.GetAddresses(len(set)+len(persistentPeers), RelayRole) + require.Len(t, allAddresses, 1) + allAddresses = mp2.GetAddresses(len(set)+len(persistentPeers), ArchivalRole) + require.Len(t, allAddresses, 1) + + // check that role of persistent peer survives + mp3 := MakePhonebook(1, 1*time.Millisecond) + mp3.AddPersistentPeers(persistentPeers, "phc", ArchivalRole) + phc := []string{"a"} + mp3.ReplacePeerList(phc, "phc", RelayRole) + + allAddresses = mp3.GetAddresses(len(set)+len(persistentPeers), RelayRole) + require.Len(t, allAddresses, 1) + allAddresses = mp3.GetAddresses(len(set)+len(persistentPeers), ArchivalRole) + require.Len(t, allAddresses, 1) } func TestMultiPhonebookDuplicateFiltering(t *testing.T) { partitiontest.PartitionTest(t) set := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"} - pha := make([]string, 0) - for _, e := range set[:7] { - pha = append(pha, e) - } - phb := make([]string, 0) - for _, e := range set[3:] { - phb = append(phb, e) - } + pha := append([]string{}, set[:7]...) + phb := append([]string{}, set[3:]...) mp := MakePhonebook(1, 1*time.Millisecond) - mp.ReplacePeerList(pha, "pha", PhoneBookEntryRelayRole) - mp.ReplacePeerList(phb, "phb", PhoneBookEntryRelayRole) + mp.ReplacePeerList(pha, "pha", RelayRole) + mp.ReplacePeerList(phb, "phb", RelayRole) testPhonebookAll(t, set, mp) testPhonebookUniform(t, set, mp, 1) @@ -204,7 +206,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { // Test the addresses are populated in the phonebook and a // time can be added to one of them - entries.ReplacePeerList([]string{addr1, addr2}, "default", PhoneBookEntryRelayRole) + entries.ReplacePeerList([]string{addr1, addr2}, "default", RelayRole) addrInPhonebook, waitTime, provisionalTime := entries.GetConnectionWaitTime(addr1) require.Equal(t, true, addrInPhonebook) require.Equal(t, time.Duration(0), waitTime) @@ -218,7 +220,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { } // add another value to addr - addrInPhonebook, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr1) + _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr1) require.Equal(t, time.Duration(0), waitTime) require.Equal(t, true, entries.UpdateConnectionTime(addr1, provisionalTime)) phBookData = entries.data[addr1].recentConnectionTimes @@ -232,7 +234,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { // the first time should be removed and a new one added // there should not be any wait - addrInPhonebook, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr1) + _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr1) require.Equal(t, time.Duration(0), waitTime) require.Equal(t, true, entries.UpdateConnectionTime(addr1, provisionalTime)) phBookData2 := entries.data[addr1].recentConnectionTimes @@ -259,7 +261,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { } // value 2 - addrInPhonebook, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr2) + _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr2) require.Equal(t, time.Duration(0), waitTime) require.Equal(t, true, entries.UpdateConnectionTime(addr2, provisionalTime)) // value 3 @@ -272,7 +274,7 @@ func TestWaitAndAddConnectionTimeLongtWindow(t *testing.T) { require.Equal(t, 3, len(phBookData)) // add another element to trigger wait - _, waitTime, provisionalTime = entries.GetConnectionWaitTime(addr2) + _, waitTime, _ = entries.GetConnectionWaitTime(addr2) require.Greater(t, int64(waitTime), int64(0)) // no element should be removed phBookData2 = entries.data[addr2].recentConnectionTimes @@ -306,7 +308,7 @@ func TestWaitAndAddConnectionTimeShortWindow(t *testing.T) { addr1 := "addrABC" // Init the data structures - entries.ReplacePeerList([]string{addr1}, "default", PhoneBookEntryRelayRole) + entries.ReplacePeerList([]string{addr1}, "default", RelayRole) // add 3 values. should not wait // value 1 @@ -345,20 +347,20 @@ func TestPhonebookRoles(t *testing.T) { archiverSet := []string{"archiver1", "archiver2", "archiver3"} ph := MakePhonebook(1, 1).(*phonebookImpl) - ph.ReplacePeerList(relaysSet, "default", PhoneBookEntryRelayRole) - ph.ReplacePeerList(archiverSet, "default", PhoneBookEntryArchivalRole) + ph.ReplacePeerList(relaysSet, "default", RelayRole) + ph.ReplacePeerList(archiverSet, "default", ArchivalRole) require.Equal(t, len(relaysSet)+len(archiverSet), len(ph.data)) require.Equal(t, len(relaysSet)+len(archiverSet), ph.Length()) - for _, role := range []PhoneBookEntryRoles{PhoneBookEntryRelayRole, PhoneBookEntryArchivalRole} { + for _, role := range []Role{RelayRole, ArchivalRole} { for k := 0; k < 100; k++ { for l := 0; l < 3; l++ { entries := ph.GetAddresses(l, role) - if role == PhoneBookEntryRelayRole { + if role == RelayRole { for _, entry := range entries { require.Contains(t, entry, "relay") } - } else if role == PhoneBookEntryArchivalRole { + } else if role == ArchivalRole { for _, entry := range entries { require.Contains(t, entry, "archiver") } @@ -367,3 +369,124 @@ func TestPhonebookRoles(t *testing.T) { } } } + +func TestRolesOperations(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + var tests = []struct { + role Role + otherRoles Role + }{ + {RelayRole, ArchivalRole}, + {ArchivalRole, RelayRole}, + } + + for _, test := range tests { + combo := RoleSet{roles: test.role} + combo.Add(test.otherRoles) + require.Equal(t, test.role|test.otherRoles, combo.roles) + require.True(t, combo.Has(test.role)) + require.False(t, combo.Is(test.role)) + require.True(t, combo.Has(test.otherRoles)) + require.False(t, combo.Is(test.otherRoles)) + + combo.Remove(test.otherRoles) + require.Equal(t, test.role, combo.roles) + require.True(t, combo.Has(test.role)) + require.True(t, combo.Is(test.role)) + require.False(t, combo.Has(test.otherRoles)) + require.False(t, combo.Is(test.otherRoles)) + } +} + +func TestReplacePeerList(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + pb := MakePhonebook(1, 1) + pb.ReplacePeerList([]string{"a", "b"}, "default", RelayRole) + res := pb.GetAddresses(4, RelayRole) + require.ElementsMatch(t, []string{"a", "b"}, res) + + pb.ReplacePeerList([]string{"c"}, "default", ArchivalRole) + res = pb.GetAddresses(4, ArchivalRole) + require.ElementsMatch(t, []string{"c"}, res) + + // make b archival in addition to relay + pb.ReplacePeerList([]string{"b", "c"}, "default", ArchivalRole) + res = pb.GetAddresses(4, RelayRole) + require.ElementsMatch(t, []string{"a", "b"}, res) + res = pb.GetAddresses(4, ArchivalRole) + require.ElementsMatch(t, []string{"b", "c"}, res) + + // update relays + pb.ReplacePeerList([]string{"a", "b"}, "default", RelayRole) + res = pb.GetAddresses(4, RelayRole) + require.ElementsMatch(t, []string{"a", "b"}, res) + res = pb.GetAddresses(4, ArchivalRole) + require.ElementsMatch(t, []string{"b", "c"}, res) + + // exclude b from archival + pb.ReplacePeerList([]string{"c"}, "default", ArchivalRole) + res = pb.GetAddresses(4, RelayRole) + require.ElementsMatch(t, []string{"a", "b"}, res) + res = pb.GetAddresses(4, ArchivalRole) + require.ElementsMatch(t, []string{"c"}, res) +} + +func TestRoleSetPersistence(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + tests := []struct { + name string + fn func(*testing.T) + }{ + { + name: "MakeRoleSet with persistence", + fn: func(t *testing.T) { + rs := MakeRoleSet(RelayRole, true) + require.True(t, rs.IsPersistent(RelayRole), "Expected RelayRole to be persistent") + require.True(t, rs.hasPersistentRoles(), "Expected HasPersistentRoles to return true") + }, + }, + { + name: "MakeRoleSet without persistence", + fn: func(t *testing.T) { + rs := MakeRoleSet(RelayRole, false) + require.False(t, rs.IsPersistent(RelayRole), "Expected RelayRole to not be persistent") + require.False(t, rs.hasPersistentRoles(), "Expected HasPersistentRoles to return false") + }, + }, + { + name: "AddPersistent", + fn: func(t *testing.T) { + rs := MakeRoleSet(RelayRole, false) + rs.AddPersistent(ArchivalRole) + + require.True(t, rs.IsPersistent(ArchivalRole), "Expected ArchivalRole to be persistent") + require.False(t, rs.IsPersistent(RelayRole), "Expected RelayRole to not be persistent") + require.True(t, rs.Has(ArchivalRole), "Expected to have ArchivalRole") + require.True(t, rs.Has(RelayRole), "Expected to have RelayRole") + require.True(t, rs.hasPersistentRoles(), "Expected HasPersistentRoles to return true") + }, + }, + { + name: "Multiple roles with different persistence", + fn: func(t *testing.T) { + rs := MakeRoleSet(RelayRole, true) + rs.Add(ArchivalRole) + + require.True(t, rs.IsPersistent(RelayRole), "Expected RelayRole to be persistent") + require.False(t, rs.IsPersistent(ArchivalRole), "Expected ArchivalRole to not be persistent") + require.True(t, rs.Has(RelayRole), "Expected to have RelayRole") + require.True(t, rs.Has(ArchivalRole), "Expected to have ArchivalRole") + }, + }, + } + + for _, test := range tests { + t.Run(test.name, test.fn) + } +} diff --git a/network/requestLogger_test.go b/network/requestLogger_test.go index 4da7ea08b3..c5f3967197 100644 --- a/network/requestLogger_test.go +++ b/network/requestLogger_test.go @@ -71,7 +71,7 @@ func TestRequestLogger(t *testing.T) { require.True(t, postListen) t.Log(addrA) netB.phonebook = phonebook.MakePhonebook(1, 1*time.Millisecond) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer func() { t.Log("stopping B"); netB.Stop(); t.Log("B done") }() diff --git a/network/requestTracker_test.go b/network/requestTracker_test.go index d359ae15a4..a73646ae45 100644 --- a/network/requestTracker_test.go +++ b/network/requestTracker_test.go @@ -124,9 +124,9 @@ func TestRateLimiting(t *testing.T) { networks[i].config.GossipFanout = 1 phonebooks[i] = phonebook.MakePhonebook(networks[i].config.ConnectionsRateLimitingCount, time.Duration(networks[i].config.ConnectionsRateLimitingWindowSeconds)*time.Second) - phonebooks[i].ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + phonebooks[i].ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) networks[i].phonebook = phonebook.MakePhonebook(1, 1*time.Millisecond) - networks[i].phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + networks[i].phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) defer func(net *WebsocketNetwork, i int) { t.Logf("stopping network %d", i) net.Stop() @@ -156,7 +156,7 @@ func TestRateLimiting(t *testing.T) { case <-readyCh: // it's closed, so this client got connected. connectedClients++ - phonebookLen := len(phonebooks[i].GetAddresses(1, phonebook.PhoneBookEntryRelayRole)) + phonebookLen := len(phonebooks[i].GetAddresses(1, phonebook.RelayRole)) // if this channel is ready, than we should have an address, since it didn't get blocked. require.Equal(t, 1, phonebookLen) default: diff --git a/network/wsNetwork.go b/network/wsNetwork.go index b13c499667..2d72f5d2ff 100644 --- a/network/wsNetwork.go +++ b/network/wsNetwork.go @@ -530,7 +530,7 @@ func (wn *WebsocketNetwork) GetPeers(options ...PeerOption) []Peer { case PeersPhonebookRelays: // return copy of phonebook, which probably also contains peers we're connected to, but if it doesn't maybe we shouldn't be making new connections to those peers (because they disappeared from the directory) var addrs []string - addrs = wn.phonebook.GetAddresses(1000, phonebook.PhoneBookEntryRelayRole) + addrs = wn.phonebook.GetAddresses(1000, phonebook.RelayRole) for _, addr := range addrs { client, _ := wn.GetHTTPClient(addr) peerCore := makePeerCore(wn.ctx, wn, wn.log, wn.handler.readBuffer, addr, client, "" /*origin address*/) @@ -538,7 +538,7 @@ func (wn *WebsocketNetwork) GetPeers(options ...PeerOption) []Peer { } case PeersPhonebookArchivalNodes: var addrs []string - addrs = wn.phonebook.GetAddresses(1000, phonebook.PhoneBookEntryArchivalRole) + addrs = wn.phonebook.GetAddresses(1000, phonebook.ArchivalRole) for _, addr := range addrs { client, _ := wn.GetHTTPClient(addr) peerCore := makePeerCore(wn.ctx, wn, wn.log, wn.handler.readBuffer, addr, client, "" /*origin address*/) @@ -1558,12 +1558,12 @@ func (wn *WebsocketNetwork) refreshRelayArchivePhonebookAddresses() { func (wn *WebsocketNetwork) updatePhonebookAddresses(relayAddrs []string, archiveAddrs []string) { if len(relayAddrs) > 0 { wn.log.Debugf("got %d relay dns addrs, %#v", len(relayAddrs), relayAddrs[:min(5, len(relayAddrs))]) - wn.phonebook.ReplacePeerList(relayAddrs, string(wn.NetworkID), phonebook.PhoneBookEntryRelayRole) + wn.phonebook.ReplacePeerList(relayAddrs, string(wn.NetworkID), phonebook.RelayRole) } else { wn.log.Infof("got no relay DNS addrs for network %s", wn.NetworkID) } if len(archiveAddrs) > 0 { - wn.phonebook.ReplacePeerList(archiveAddrs, string(wn.NetworkID), phonebook.PhoneBookEntryArchivalRole) + wn.phonebook.ReplacePeerList(archiveAddrs, string(wn.NetworkID), phonebook.ArchivalRole) } else { wn.log.Infof("got no archive DNS addrs for network %s", wn.NetworkID) } @@ -1582,7 +1582,7 @@ func (wn *WebsocketNetwork) checkNewConnectionsNeeded() bool { return false } // get more than we need so that we can ignore duplicates - newAddrs := wn.phonebook.GetAddresses(desired+numOutgoingTotal, phonebook.PhoneBookEntryRelayRole) + newAddrs := wn.phonebook.GetAddresses(desired+numOutgoingTotal, phonebook.RelayRole) for _, na := range newAddrs { if na == wn.config.PublicAddress { // filter out self-public address, so we won't try to connect to ourselves. @@ -2233,7 +2233,7 @@ func NewWebsocketNetwork(log logging.Logger, config config.Local, phonebookAddre addresses = append(addresses, a) } } - pb.AddPersistentPeers(addresses, string(networkID), phonebook.PhoneBookEntryRelayRole) + pb.AddPersistentPeers(addresses, string(networkID), phonebook.RelayRole) wn = &WebsocketNetwork{ log: log, config: config, diff --git a/network/wsNetwork_test.go b/network/wsNetwork_test.go index ad8dff913a..9496e650f0 100644 --- a/network/wsNetwork_test.go +++ b/network/wsNetwork_test.go @@ -325,7 +325,7 @@ func setupWebsocketNetworkABwithLogger(t *testing.T, countTarget int, log loggin addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer func() { if !success { @@ -458,7 +458,7 @@ func TestWebsocketProposalPayloadCompression(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") messages := [][]byte{ @@ -637,7 +637,7 @@ func TestWebsocketNetworkNoAddress(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") @@ -702,7 +702,7 @@ func lineNetwork(t *testing.T, numNodes int) (nodes []*WebsocketNetwork, counter if i > 0 { addrPrev, postListen := nodes[i-1].Address() require.True(t, postListen) - nodes[i].phonebook.ReplacePeerList([]string{addrPrev}, "default", phonebook.PhoneBookEntryRelayRole) + nodes[i].phonebook.ReplacePeerList([]string{addrPrev}, "default", phonebook.RelayRole) nodes[i].RegisterHandlers([]TaggedMessageHandler{{Tag: protocol.TxnTag, MessageHandler: &counters[i]}}) } nodes[i].Start() @@ -1080,7 +1080,7 @@ func TestDupFilter(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") counter := &messageCounterHandler{t: t, limit: 1, done: make(chan struct{})} @@ -1093,7 +1093,7 @@ func TestDupFilter(t *testing.T) { require.True(t, postListen) netC := makeTestFilterWebsocketNode(t, "c") netC.config.GossipFanout = 1 - netC.phonebook.ReplacePeerList([]string{addrB}, "default", phonebook.PhoneBookEntryRelayRole) + netC.phonebook.ReplacePeerList([]string{addrB}, "default", phonebook.RelayRole) netC.Start() defer netC.Stop() @@ -1172,7 +1172,7 @@ func TestGetPeers(t *testing.T) { require.True(t, postListen) t.Log(addrA) phbMulti := phonebook.MakePhonebook(1, 1*time.Millisecond) - phbMulti.ReplacePeerList([]string{addrA}, "phba", phonebook.PhoneBookEntryRelayRole) + phbMulti.ReplacePeerList([]string{addrA}, "phba", phonebook.RelayRole) netB.phonebook = phbMulti netB.Start() defer netB.Stop() @@ -1183,10 +1183,10 @@ func TestGetPeers(t *testing.T) { waitReady(t, netB, readyTimeout.C) t.Log("b ready") - phbMulti.ReplacePeerList([]string{"a", "b", "c"}, "ph", phonebook.PhoneBookEntryRelayRole) + phbMulti.ReplacePeerList([]string{"a", "b", "c"}, "ph", phonebook.RelayRole) // A few for archival node roles - phbMulti.ReplacePeerList([]string{"d", "e", "f"}, "ph", phonebook.PhoneBookEntryArchivalRole) + phbMulti.ReplacePeerList([]string{"d", "e", "f"}, "ph", phonebook.ArchivalRole) //addrB, _ := netB.Address() @@ -2182,7 +2182,7 @@ func BenchmarkWebsocketNetworkBasic(t *testing.B) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") returns := make(chan uint64, 100) @@ -2264,7 +2264,7 @@ func TestWebsocketNetworkPrio(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") @@ -2311,7 +2311,7 @@ func TestWebsocketNetworkPrioLimit(t *testing.T) { netB.SetPrioScheme(&prioB) netB.config.GossipFanout = 1 netB.config.NetAddress = "" - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.RegisterHandlers([]TaggedMessageHandler{{Tag: protocol.TxnTag, MessageHandler: counterB}}) netB.Start() defer netStop(t, netB, "B") @@ -2325,7 +2325,7 @@ func TestWebsocketNetworkPrioLimit(t *testing.T) { netC.SetPrioScheme(&prioC) netC.config.GossipFanout = 1 netC.config.NetAddress = "" - netC.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netC.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netC.RegisterHandlers([]TaggedMessageHandler{{Tag: protocol.TxnTag, MessageHandler: counterC}}) netC.Start() defer func() { t.Log("stopping C"); netC.Stop(); t.Log("C done") }() @@ -2410,7 +2410,7 @@ func TestWebsocketNetworkManyIdle(t *testing.T) { for i := 0; i < numClients; i++ { client := makeTestWebsocketNodeWithConfig(t, clientConf) client.config.GossipFanout = 1 - client.phonebook.ReplacePeerList([]string{relayAddr}, "default", phonebook.PhoneBookEntryRelayRole) + client.phonebook.ReplacePeerList([]string{relayAddr}, "default", phonebook.RelayRole) client.Start() defer client.Stop() @@ -2535,7 +2535,7 @@ func TestDelayedMessageDrop(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") counter := newMessageCounter(t, 5) @@ -2590,7 +2590,7 @@ func TestSlowPeerDisconnection(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") @@ -2669,14 +2669,14 @@ func TestForceMessageRelaying(t *testing.T) { noAddressConfig.NetAddress = "" netB := makeTestWebsocketNodeWithConfig(t, noAddressConfig) netB.config.GossipFanout = 1 - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") noAddressConfig.ForceRelayMessages = true netC := makeTestWebsocketNodeWithConfig(t, noAddressConfig) netC.config.GossipFanout = 1 - netC.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netC.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netC.Start() defer func() { t.Log("stopping C"); netC.Stop(); t.Log("C done") }() @@ -2822,7 +2822,7 @@ func TestWebsocketNetworkTopicRoundtrip(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") @@ -2922,7 +2922,7 @@ func TestWebsocketNetworkMessageOfInterest(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Logf("netA %s", addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) // have netB asking netA to send it ft2. // Max MOI size is calculated by encoding all of the valid tags, since we are using a custom tag here we must deregister one in the default set. @@ -3047,7 +3047,7 @@ func TestWebsocketNetworkTXMessageOfInterestRelay(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") @@ -3131,7 +3131,7 @@ func TestWebsocketNetworkTXMessageOfInterestForceTx(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") @@ -3213,7 +3213,7 @@ func TestWebsocketNetworkTXMessageOfInterestNPN(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") require.False(t, netB.relayMessages) @@ -3319,7 +3319,7 @@ func TestWebsocketNetworkTXMessageOfInterestPN(t *testing.T) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") require.False(t, netB.relayMessages) @@ -3441,7 +3441,7 @@ func testWebsocketDisconnection(t *testing.T, disconnectFunc func(wn *WebsocketN addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer netStop(t, netB, "B") @@ -3636,7 +3636,7 @@ func BenchmarkVariableTransactionMessageBlockSizes(t *testing.B) { addrA, postListen := netA.Address() require.True(t, postListen) t.Log(addrA) - netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.PhoneBookEntryRelayRole) + netB.phonebook.ReplacePeerList([]string{addrA}, "default", phonebook.RelayRole) netB.Start() defer func() { netB.Stop() }() @@ -4545,7 +4545,7 @@ func TestWsNetworkPhonebookMix(t *testing.T) { nil, ) require.NoError(t, err) - addrs := net.phonebook.GetAddresses(10, phonebook.PhoneBookEntryRelayRole) + addrs := net.phonebook.GetAddresses(10, phonebook.RelayRole) require.Len(t, addrs, 1) }