diff --git a/node/node.go b/node/node.go index 3a85943f2d..5bbd0fcb72 100644 --- a/node/node.go +++ b/node/node.go @@ -733,7 +733,7 @@ func createSwitch(config *cfg.Config, func createAddrBookAndSetOnSwitch(config *cfg.Config, sw *p2p.Switch, p2pLogger log.Logger, nodeKey *p2p.NodeKey, ) (pex.AddrBook, error) { - addrBook := pex.NewAddrBook(config.P2P.AddrBookFile(), config.P2P.AddrBookStrict) + addrBook := pex.NewAddrBook(config.P2P.AddrBookFile(), config.P2P.AddrBookStrict, config.P2P.SameRegion) addrBook.SetLogger(p2pLogger.With("book", config.P2P.AddrBookFile())) // Add ourselves to addrbook to prevent dialing ourselves diff --git a/p2p/pex/addrbook.go b/p2p/pex/addrbook.go index 857a6a063f..4204413cb5 100644 --- a/p2p/pex/addrbook.go +++ b/p2p/pex/addrbook.go @@ -7,13 +7,17 @@ package pex import ( crand "crypto/rand" "encoding/binary" + "encoding/json" "fmt" + "io" "math" "math/rand" "net" + "net/http" "sync" "time" + "github.com/biter777/countries" "github.com/minio/highwayhash" "github.com/cometbft/cometbft/crypto" @@ -46,6 +50,7 @@ type AddrBook interface { // Add and remove an address AddAddress(addr *p2p.NetAddress, src *p2p.NetAddress) error + PickAddressNotInRegion(biasTowardsNewAddrs int, region string) *p2p.NetAddress RemoveAddress(*p2p.NetAddress) // Check if the address is in the book @@ -59,6 +64,7 @@ type AddrBook interface { // Pick an address to dial PickAddress(biasTowardsNewAddrs int) *p2p.NetAddress + PickAddressWithRegion(biasTowardsNewAddrs int, region string) *p2p.NetAddress // Mark address MarkGood(p2p.ID) @@ -107,6 +113,8 @@ type addrBook struct { hashKey []byte wg sync.WaitGroup + + isRegionTracking bool } func newHashKey() []byte { @@ -117,7 +125,7 @@ func newHashKey() []byte { // NewAddrBook creates a new address book. // Use Start to begin processing asynchronous address updates. -func NewAddrBook(filePath string, routabilityStrict bool) AddrBook { +func NewAddrBook(filePath string, routabilityStrict, isRegionTracking bool) AddrBook { am := &addrBook{ rand: cmtrand.NewRand(), ourAddrs: make(map[string]struct{}), @@ -127,6 +135,7 @@ func NewAddrBook(filePath string, routabilityStrict bool) AddrBook { filePath: filePath, routabilityStrict: routabilityStrict, hashKey: newHashKey(), + isRegionTracking: isRegionTracking, } am.init() am.BaseService = *service.NewBaseService(nil, "AddrBook", am) @@ -214,7 +223,17 @@ func (a *addrBook) AddAddress(addr *p2p.NetAddress, src *p2p.NetAddress) error { a.mtx.Lock() defer a.mtx.Unlock() - return a.addAddress(addr, src) + if a.isRegionTracking { + region, err := getRegionFromIP(addr.IP.String()) + if err != nil { + a.Logger.Error("Failed to get region from IP", "err", err) + return err + } + + return a.addAddressWithRegion(addr, src, region) + } else { + return a.addAddress(addr, src) + } } // RemoveAddress implements AddrBook - removes the address from the book. @@ -263,6 +282,128 @@ func (a *addrBook) Empty() bool { return a.Size() == 0 } +func (a *addrBook) PickAddressWithRegion(biasTowardsNewAddrs int, region string) *p2p.NetAddress { + a.mtx.Lock() + defer a.mtx.Unlock() + + bookSize := a.size() + if bookSize <= 0 { + if bookSize < 0 { + panic(fmt.Sprintf("Addrbook size %d (new: %d + old: %d) is less than 0", a.nNew+a.nOld, a.nNew, a.nOld)) + } + return nil + } + if biasTowardsNewAddrs > 100 { + biasTowardsNewAddrs = 100 + } + if biasTowardsNewAddrs < 0 { + biasTowardsNewAddrs = 0 + } + + // Bias between new and old addresses. + oldCorrelation := math.Sqrt(float64(a.nOld)) * (100.0 - float64(biasTowardsNewAddrs)) + newCorrelation := math.Sqrt(float64(a.nNew)) * float64(biasTowardsNewAddrs) + + // pick a random peer from a random bucket + var bucket map[string]*knownAddress + pickFromOldBucket := (newCorrelation+oldCorrelation)*a.rand.Float64() < oldCorrelation + if (pickFromOldBucket && a.nOld == 0) || + (!pickFromOldBucket && a.nNew == 0) { + return nil + } + // loop until we pick a random non-empty bucket + for len(bucket) == 0 { + if pickFromOldBucket { + bucket = a.bucketsOld[a.rand.Intn(len(a.bucketsOld))] + } else { + bucket = a.bucketsNew[a.rand.Intn(len(a.bucketsNew))] + } + } + + // Filter the bucket by region + filteredBucket := make(map[string]*knownAddress) + for addrStr, ka := range bucket { + if ka.Region == region { + filteredBucket[addrStr] = ka + } + } + + if len(filteredBucket) == 0 { + return nil + } + + // pick a random index and loop over the map to return that index + randIndex := a.rand.Intn(len(filteredBucket)) + for _, ka := range filteredBucket { + if randIndex == 0 { + return ka.Addr + } + randIndex-- + } + return nil +} + +func (a *addrBook) PickAddressNotInRegion(biasTowardsNewAddrs int, region string) *p2p.NetAddress { + a.mtx.Lock() + defer a.mtx.Unlock() + + bookSize := a.size() + if bookSize <= 0 { + if bookSize < 0 { + panic(fmt.Sprintf("Addrbook size %d (new: %d + old: %d) is less than 0", a.nNew+a.nOld, a.nNew, a.nOld)) + } + return nil + } + if biasTowardsNewAddrs > 100 { + biasTowardsNewAddrs = 100 + } + if biasTowardsNewAddrs < 0 { + biasTowardsNewAddrs = 0 + } + + // Bias between new and old addresses. + oldCorrelation := math.Sqrt(float64(a.nOld)) * (100.0 - float64(biasTowardsNewAddrs)) + newCorrelation := math.Sqrt(float64(a.nNew)) * float64(biasTowardsNewAddrs) + + // pick a random peer from a random bucket + var bucket map[string]*knownAddress + pickFromOldBucket := (newCorrelation+oldCorrelation)*a.rand.Float64() < oldCorrelation + if (pickFromOldBucket && a.nOld == 0) || + (!pickFromOldBucket && a.nNew == 0) { + return nil + } + // loop until we pick a random non-empty bucket + for len(bucket) == 0 { + if pickFromOldBucket { + bucket = a.bucketsOld[a.rand.Intn(len(a.bucketsOld))] + } else { + bucket = a.bucketsNew[a.rand.Intn(len(a.bucketsNew))] + } + } + + // Filter the bucket to exclude the specified region + filteredBucket := make(map[string]*knownAddress) + for addrStr, ka := range bucket { + if ka.Region != region { + filteredBucket[addrStr] = ka + } + } + + if len(filteredBucket) == 0 { + return nil + } + + // pick a random index and loop over the map to return that index + randIndex := a.rand.Intn(len(filteredBucket)) + for _, ka := range filteredBucket { + if randIndex == 0 { + return ka.Addr + } + randIndex-- + } + return nil +} + // PickAddress implements AddrBook. It picks an address to connect to. // The address is picked randomly from an old or new bucket according // to the biasTowardsNewAddrs argument, which must be between [0, 100] (or else is truncated to that range) @@ -636,6 +777,65 @@ func (a *addrBook) pickOldest(bucketType byte, bucketIdx int) *knownAddress { return oldest } +func (a *addrBook) addAddressWithRegion(addr, src *p2p.NetAddress, region string) error { + if addr == nil || src == nil { + return ErrAddrBookNilAddr{addr, src} + } + + if err := addr.Valid(); err != nil { + return ErrAddrBookInvalidAddr{Addr: addr, AddrErr: err} + } + + if _, ok := a.badPeers[addr.ID]; ok { + return ErrAddressBanned{addr} + } + + if _, ok := a.privateIDs[addr.ID]; ok { + return ErrAddrBookPrivate{addr} + } + + if _, ok := a.privateIDs[src.ID]; ok { + return ErrAddrBookPrivateSrc{src} + } + + // TODO: we should track ourAddrs by ID and by IP:PORT and refuse both. + if _, ok := a.ourAddrs[addr.String()]; ok { + return ErrAddrBookSelf{addr} + } + + if a.routabilityStrict && !addr.Routable() { + return ErrAddrBookNonRoutable{addr} + } + + ka := a.addrLookup[addr.ID] + if ka != nil { + // If its already old and the address ID's are the same, ignore it. + // Thereby avoiding issues with a node on the network attempting to change + // the IP of a known node ID. (Which could yield an eclipse attack on the node) + if ka.isOld() && ka.Addr.ID == addr.ID { + return nil + } + // Already in max new buckets. + if len(ka.Buckets) == maxNewBucketsPerAddress { + return nil + } + // The more entries we have, the less likely we are to add more. + factor := int32(2 * len(ka.Buckets)) + if a.rand.Int31n(factor) != 0 { + return nil + } + } else { + ka = newKnownAddress(addr, src) + } + ka.Region = region + + bucket, err := a.calcNewBucket(addr, src) + if err != nil { + return err + } + return a.addToNewBucket(ka, bucket) +} + // adds the address to a "new" bucket. if its already in one, // it only adds it probabilistically func (a *addrBook) addAddress(addr, src *p2p.NetAddress) error { @@ -945,3 +1145,36 @@ func (a *addrBook) hash(b []byte) ([]byte, error) { hasher.Write(b) return hasher.Sum(nil), nil } + +type ipInfo struct { + Status string + Country string +} + +func getRegionFromIP(ip string) (string, error) { + req, err := http.Get(fmt.Sprintf("http://ip-api.com/json/%s?fields=status,country", ip)) + if err != nil { + return "", err + } + defer req.Body.Close() + + body, err := io.ReadAll(req.Body) + if err != nil { + return "", err + } + + var ipInfo ipInfo + json.Unmarshal(body, &ipInfo) + fmt.Println("ipInfoPeer", ipInfo) + + if ipInfo.Status != "success" { + return "", fmt.Errorf("failed to get country from IP %s", ip) + } + + country := countries.ByName(ipInfo.Country) + if country == countries.Unknown { + return "", fmt.Errorf("could not find country: %s", ipInfo.Country) + } + + return country.Info().Region.String(), nil +} diff --git a/p2p/pex/addrbook_test.go b/p2p/pex/addrbook_test.go index c34ee412db..2309cd9761 100644 --- a/p2p/pex/addrbook_test.go +++ b/p2p/pex/addrbook_test.go @@ -25,7 +25,7 @@ func TestAddrBookPickAddress(t *testing.T) { defer deleteTempFile(fname) // 0 addresses - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) assert.Zero(t, book.Size()) @@ -62,11 +62,11 @@ func TestAddrBookSaveLoad(t *testing.T) { defer deleteTempFile(fname) // 0 addresses - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) book.Save() - book = NewAddrBook(fname, true) + book = NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) err := book.Start() require.NoError(t, err) @@ -84,7 +84,7 @@ func TestAddrBookSaveLoad(t *testing.T) { assert.Equal(t, 100, book.Size()) book.Save() - book = NewAddrBook(fname, true) + book = NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) err = book.Start() require.NoError(t, err) @@ -98,7 +98,7 @@ func TestAddrBookLookup(t *testing.T) { randAddrs := randNetAddressPairs(t, 100) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) for _, addrSrc := range randAddrs { addr := addrSrc.addr @@ -117,7 +117,7 @@ func TestAddrBookPromoteToOld(t *testing.T) { randAddrs := randNetAddressPairs(t, 100) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) for _, addrSrc := range randAddrs { err := book.AddAddress(addrSrc.addr, addrSrc.src) @@ -159,7 +159,7 @@ func TestAddrBookHandlesDuplicates(t *testing.T) { fname := createTempFileName("addrbook_test") defer deleteTempFile(fname) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) randAddrs := randNetAddressPairs(t, 100) @@ -213,7 +213,7 @@ func TestAddrBookRemoveAddress(t *testing.T) { fname := createTempFileName("addrbook_test") defer deleteTempFile(fname) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) addr := randIPv4Address(t) @@ -261,7 +261,7 @@ func TestAddrBookGetSelection(t *testing.T) { fname := createTempFileName("addrbook_test") defer deleteTempFile(fname) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) // 1) empty book @@ -303,7 +303,7 @@ func TestAddrBookGetSelectionWithBias(t *testing.T) { fname := createTempFileName("addrbook_test") defer deleteTempFile(fname) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) // 1) empty book @@ -386,7 +386,7 @@ func TestAddrBookHasAddress(t *testing.T) { fname := createTempFileName("addrbook_test") defer deleteTempFile(fname) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) addr := randIPv4Address(t) err := book.AddAddress(addr, addr) @@ -416,7 +416,7 @@ func TestBanBadPeers(t *testing.T) { fname := createTempFileName("addrbook_test") defer deleteTempFile(fname) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) addr := randIPv4Address(t) @@ -443,7 +443,7 @@ func TestAddrBookEmpty(t *testing.T) { fname := createTempFileName("addrbook_test") defer deleteTempFile(fname) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) // Check that empty book is empty require.True(t, book.Empty()) @@ -465,7 +465,7 @@ func TestPrivatePeers(t *testing.T) { fname := createTempFileName("addrbook_test") defer deleteTempFile(fname) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) addrs, private := testCreatePrivateAddrs(t, 10) @@ -614,7 +614,7 @@ func TestAddrBookAddDoesNotOverwriteOldIP(t *testing.T) { src, err := p2p.NewNetAddressString(SrcAddr) require.Nil(t, err) - book := NewAddrBook(fname, true) + book := NewAddrBook(fname, true, false) book.SetLogger(log.TestingLogger()) err = book.AddAddress(peerRealAddr, src) require.Nil(t, err) @@ -739,7 +739,7 @@ func deleteTempFile(fname string) { func createAddrBookWithMOldAndNNewAddrs(t *testing.T, nOld, nNew int) (book *addrBook, fname string) { fname = createTempFileName("addrbook_test") - book = NewAddrBook(fname, true).(*addrBook) + book = NewAddrBook(fname, true, false).(*addrBook) book.SetLogger(log.TestingLogger()) assert.Zero(t, book.Size()) diff --git a/p2p/pex/known_address.go b/p2p/pex/known_address.go index a46e682d88..8be56a8aab 100644 --- a/p2p/pex/known_address.go +++ b/p2p/pex/known_address.go @@ -17,6 +17,7 @@ type knownAddress struct { LastAttempt time.Time `json:"last_attempt"` LastSuccess time.Time `json:"last_success"` LastBanTime time.Time `json:"last_ban_time"` + Region string `json:"region"` } func newKnownAddress(addr *p2p.NetAddress, src *p2p.NetAddress) *knownAddress { diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go index fdb66cda11..ef013976ec 100644 --- a/p2p/pex/pex_reactor.go +++ b/p2p/pex/pex_reactor.go @@ -430,14 +430,23 @@ func (r *Reactor) ensurePeersRoutine() { // fire once immediately. // ensures we dial the seeds right away if the book is empty - r.ensurePeers() + swConfig := r.Switch.GetConfig() + if swConfig.SameRegion { + r.ensurePeersRegion() + } else { + r.ensurePeers() + } // fire periodically ticker := time.NewTicker(r.ensurePeersPeriod) for { select { case <-ticker.C: - r.ensurePeers() + if swConfig.SameRegion { + r.ensurePeersRegion() + } else { + r.ensurePeers() + } case <-r.Quit(): ticker.Stop() return @@ -450,6 +459,124 @@ func (r *Reactor) ensurePeersRoutine() { // heuristic that we haven't perfected yet, or, perhaps is manually edited by // the node operator. It should not be used to compute what addresses are // already connected or not. +func (r *Reactor) ensurePeersRegion() { + var ( + out, in, dial = r.Switch.NumPeers() + numToDial = r.Switch.MaxNumOutboundPeers() - (out + dial) + ) + r.Logger.Info( + "Ensure peers", + "numOutPeers", out, + "numInPeers", in, + "numDialing", dial, + "numToDial", numToDial, + ) + + if numToDial <= 0 { + return + } + + // bias to prefer more vetted peers when we have fewer connections. + // not perfect, but somewhat ensures that we prioritize connecting to more-vetted + // NOTE: range here is [10, 90]. Too high ? + newBias := cmtmath.MinInt(out, 8)*10 + 10 + + toDialInRegion := make(map[p2p.ID]*p2p.NetAddress) + toDialOutOfRegion := make(map[p2p.ID]*p2p.NetAddress) + // Try maxAttempts times to pick numToDial addresses to dial + maxAttempts := numToDial * 3 + + // Determine how many in region and how many out of region peers we need to dial + swConfig := r.Switch.GetConfig() + currentOutboundInOtherRegion := swConfig.CurrentNumOutboundPeersInOtherRegion + maxOutboundPeersInOtherRegion := swConfig.MaxNumOutboundPeers - int(swConfig.MaxPercentPeersInSameRegion*float64(swConfig.MaxNumOutboundPeers)) + + numToDialInOtherRegion := maxOutboundPeersInOtherRegion - currentOutboundInOtherRegion + numToDialInSameRegion := numToDial - numToDialInOtherRegion + + fmt.Println("numToDialInSameRegion", numToDialInSameRegion) + fmt.Println("numToDialInOtherRegion", numToDialInOtherRegion) + + // First iteration: Dial peers in the same region + for i := 0; i < maxAttempts && len(toDialInRegion) < numToDialInSameRegion; i++ { + try := r.book.PickAddressWithRegion(newBias, swConfig.MyRegion) + if try == nil { + continue + } + if _, selected := toDialInRegion[try.ID]; selected { + continue + } + if r.Switch.IsDialingOrExistingAddress(try) { + continue + } + toDialInRegion[try.ID] = try + } + + // Second iteration: Dial peers in other regions + for i := 0; i < maxAttempts && len(toDialOutOfRegion) < numToDialInOtherRegion; i++ { + try := r.book.PickAddressNotInRegion(newBias, swConfig.MyRegion) + if try == nil { + continue + } + if _, selected := toDialOutOfRegion[try.ID]; selected { + continue + } + if r.Switch.IsDialingOrExistingAddress(try) { + continue + } + toDialOutOfRegion[try.ID] = try + } + + // Combine the two maps + toDial := make(map[p2p.ID]*p2p.NetAddress) + for id, addr := range toDialInRegion { + toDial[id] = addr + } + for id, addr := range toDialOutOfRegion { + toDial[id] = addr + } + + // Dial picked addresses + for _, addr := range toDial { + go func(addr *p2p.NetAddress) { + err := r.dialPeer(addr) + if err != nil { + switch err.(type) { + case errMaxAttemptsToDial, errTooEarlyToDial: + r.Logger.Debug(err.Error(), "addr", addr) + default: + r.Logger.Debug(err.Error(), "addr", addr) + } + } + }(addr) + } + + if r.book.NeedMoreAddrs() { + // Check if banned nodes can be reinstated + r.book.ReinstateBadPeers() + } + + if r.book.NeedMoreAddrs() { + + // 1) Pick a random peer and ask for more. + peers := r.Switch.Peers().List() + peersCount := len(peers) + if peersCount > 0 { + peer := peers[cmtrand.Int()%peersCount] + r.Logger.Info("We need more addresses. Sending pexRequest to random peer", "peer", peer) + r.RequestAddrs(peer) + } + + // 2) Dial seeds if we are not dialing anyone. + // This is done in addition to asking a peer for addresses to work-around + // peers not participating in PEX. + if len(toDial) == 0 { + r.Logger.Info("No addresses to dial. Falling back to seeds") + r.dialSeeds() + } + } +} + func (r *Reactor) ensurePeers() { var ( out, in, dial = r.Switch.NumPeers() @@ -468,7 +595,7 @@ func (r *Reactor) ensurePeers() { } // bias to prefer more vetted peers when we have fewer connections. - // not perfect, but somewhate ensures that we prioritize connecting to more-vetted + // not perfect, but somewhat ensures that we prioritize connecting to more-vetted // NOTE: range here is [10, 90]. Too high ? newBias := cmtmath.MinInt(out, 8)*10 + 10 diff --git a/p2p/pex/pex_reactor_test.go b/p2p/pex/pex_reactor_test.go index a485974efe..a642f92fea 100644 --- a/p2p/pex/pex_reactor_test.go +++ b/p2p/pex/pex_reactor_test.go @@ -82,7 +82,7 @@ func TestPEXReactorRunning(t *testing.T) { // create switches for i := 0; i < N; i++ { switches[i] = p2p.MakeSwitch(cfg, i, "testing", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch { - books[i] = NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", i)), false) + books[i] = NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", i)), false, false) books[i].SetLogger(logger.With("pex", i)) sw.SetAddrBook(books[i]) @@ -416,7 +416,7 @@ func TestPEXReactorSeedModeFlushStop(t *testing.T) { // create switches for i := 0; i < N; i++ { switches[i] = p2p.MakeSwitch(cfg, i, "testing", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch { - books[i] = NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", i)), false) + books[i] = NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", i)), false, false) books[i].SetLogger(logger.With("pex", i)) sw.SetAddrBook(books[i]) @@ -585,7 +585,7 @@ func testCreatePeerWithConfig(dir string, id int, config *ReactorConfig) *p2p.Sw "127.0.0.1", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch { - book := NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", id)), false) + book := NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", id)), false, false) book.SetLogger(log.TestingLogger()) sw.SetAddrBook(book) @@ -617,7 +617,7 @@ func testCreateSeed(dir string, id int, knownAddrs, srcAddrs []*p2p.NetAddress) "127.0.0.1", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch { - book := NewAddrBook(filepath.Join(dir, "addrbookSeed.json"), false) + book := NewAddrBook(filepath.Join(dir, "addrbookSeed.json"), false, false) book.SetLogger(log.TestingLogger()) for j := 0; j < len(knownAddrs); j++ { book.AddAddress(knownAddrs[j], srcAddrs[j]) //nolint:errcheck // ignore for tests @@ -651,7 +651,7 @@ func createReactor(conf *ReactorConfig) (r *Reactor, book AddrBook) { if err != nil { panic(err) } - book = NewAddrBook(filepath.Join(dir, "addrbook.json"), true) + book = NewAddrBook(filepath.Join(dir, "addrbook.json"), true, false) book.SetLogger(log.TestingLogger()) r = NewReactor(book, conf) diff --git a/p2p/switch.go b/p2p/switch.go index b470b3ca2d..09450c6f26 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -809,28 +809,28 @@ func (sw *Switch) addOutboundPeerWithConfig( return fmt.Errorf("dial err (peerConfig.DialFail == true)") } - // Check if adding this peer would exceed the percentage of in/outbound peers in the same region - if sw.config.SameRegion { - // Note if the new peer is in the same region as us - peerRegion, err := getRegionFromIP(addr.IP.String()) - if err != nil { - sw.Logger.Error("Failed to get region from IP", "err", err) - return err - } - fmt.Println("peerRegion", peerRegion) - isSameRegion := peerRegion == sw.config.MyRegion - - if !isSameRegion { - // If this peer is not in our same region and we have no room to dial peers outside of our region, return error - // TODO check this formula - fmt.Println("peer is outbound from addOutboundPeerWithConfig") - maxOutboundPeersInOtherRegion := sw.config.MaxNumOutboundPeers - int(sw.config.MaxPercentPeersInSameRegion*float64(sw.config.MaxNumOutboundPeers)) - if sw.config.CurrentNumOutboundPeersInOtherRegion+1 > maxOutboundPeersInOtherRegion { - return ErrRejected{id: ID(addr.ID), err: fmt.Errorf("exceeds max percent peers in same region")} - // return ErrRejected{id: p.ID(), err: fmt.Errorf("exceeds max percent peers in same region")} - } - } - } + // // Check if adding this peer would exceed the percentage of in/outbound peers in the same region + // if sw.config.SameRegion { + // // Note if the new peer is in the same region as us + // peerRegion, err := getRegionFromIP(addr.IP.String()) + // if err != nil { + // sw.Logger.Error("Failed to get region from IP", "err", err) + // return err + // } + // fmt.Println("peerRegion", peerRegion) + // isSameRegion := peerRegion == sw.config.MyRegion + + // if !isSameRegion { + // // If this peer is not in our same region and we have no room to dial peers outside of our region, return error + // // TODO check this formula + // fmt.Println("peer is outbound from addOutboundPeerWithConfig") + // maxOutboundPeersInOtherRegion := sw.config.MaxNumOutboundPeers - int(sw.config.MaxPercentPeersInSameRegion*float64(sw.config.MaxNumOutboundPeers)) + // if sw.config.CurrentNumOutboundPeersInOtherRegion+1 > maxOutboundPeersInOtherRegion { + // return ErrRejected{id: ID(addr.ID), err: fmt.Errorf("exceeds max percent peers in same region")} + // // return ErrRejected{id: p.ID(), err: fmt.Errorf("exceeds max percent peers in same region")} + // } + // } + // } p, err := sw.transport.Dial(*addr, peerConfig{ chDescs: sw.chDescs, @@ -997,3 +997,7 @@ func (sw *Switch) addPeer(p Peer) error { return nil } + +func (sw *Switch) GetConfig() *config.P2PConfig { + return sw.config +} diff --git a/test/fuzz/p2p/addrbook/fuzz.go b/test/fuzz/p2p/addrbook/fuzz.go index 4499950315..9353f231cc 100644 --- a/test/fuzz/p2p/addrbook/fuzz.go +++ b/test/fuzz/p2p/addrbook/fuzz.go @@ -9,7 +9,7 @@ import ( "github.com/cometbft/cometbft/p2p/pex" ) -var addrBook = pex.NewAddrBook("./testdata/addrbook.json", true) +var addrBook = pex.NewAddrBook("./testdata/addrbook.json", true, false) func Fuzz(data []byte) int { addr := new(p2p.NetAddress) diff --git a/test/fuzz/p2p/pex/reactor_receive.go b/test/fuzz/p2p/pex/reactor_receive.go index 0856e6a717..9c4a3e6dfa 100644 --- a/test/fuzz/p2p/pex/reactor_receive.go +++ b/test/fuzz/p2p/pex/reactor_receive.go @@ -19,7 +19,7 @@ var ( ) func init() { - addrB := pex.NewAddrBook("./testdata/addrbook1", false) + addrB := pex.NewAddrBook("./testdata/addrbook1", false, false) pexR := pex.NewReactor(addrB, &pex.ReactorConfig{SeedMode: false}) if pexR == nil { panic("NewReactor returned nil")