@@ -1772,6 +1772,79 @@ func distinctIds(ids ...*server.Id) []server.Id {
17721772 return distinct
17731773}
17741774
1775+ // The share of destinations a provider must reach to count as healthy: 90%,
1776+ // as 9/10. Compared exactly as `10*ok >= 9*total` rather than through a float
1777+ // division, so the boundary is the same for every denominator.
1778+ //
1779+ // Package scope, not function scope: both UpdateClientScores and
1780+ // UpdateClientLocations gate on this now, and two copies could drift.
1781+ const minEgressHealthOKNumerator = 9
1782+ const minEgressHealthOKDenominator = 10
1783+
1784+ // providerCountFilter answers one question: does this provider count as real,
1785+ // reachable supply?
1786+ //
1787+ // It exists so the advertised provider_count (UpdateClientLocations) and the
1788+ // gated membership (UpdateClientScores) apply an IDENTICAL predicate. They ran
1789+ // different rules before: membership was gated on egress health while the count
1790+ // was not, so a location could survive the gate and still advertise providers
1791+ // that no probe had ever reached.
1792+ //
1793+ // Both maps are loaded once per pass. These loops run over the entire provider
1794+ // population, so a per-provider query here is one round trip per provider.
1795+ type providerCountFilter struct {
1796+ healthCounts map [server.Id ]ProviderEgressHealthCounts
1797+ countryCodes map [server.Id ]string
1798+ }
1799+
1800+ func newProviderCountFilter (ctx context.Context ) providerCountFilter {
1801+ return providerCountFilter {
1802+ healthCounts : GetAllProviderEgressHealthCounts (ctx ),
1803+ countryCodes : GetAllProviderEgressCountryCodes (ctx ),
1804+ }
1805+ }
1806+
1807+ // passesHealth reports whether a probe has MEASURED this provider healthy.
1808+ // Fail closed: no record at all (never probed) does not pass, and neither does
1809+ // a record with no destinations in it, which is not a measurement of anything.
1810+ // Guarding total also keeps the ratio well defined.
1811+ //
1812+ // Compared exactly as 10*ok >= 9*total rather than through a float, so the 90%
1813+ // boundary cannot drift with rounding.
1814+ func (f providerCountFilter ) passesHealth (clientId server.Id ) bool {
1815+ counts , ok := f .healthCounts [clientId ]
1816+ if ! ok {
1817+ return false
1818+ }
1819+ if counts .Total <= 0 {
1820+ return false
1821+ }
1822+ return minEgressHealthOKDenominator * counts .OKCount >= minEgressHealthOKNumerator * counts .Total
1823+ }
1824+
1825+ // countsTowardCountry reports whether this provider counts as supply for
1826+ // countryCode. It must both be measured healthy and have been OBSERVED
1827+ // egressing from that country.
1828+ //
1829+ // The two locations are different claims. network_client_location is where the
1830+ // provider says it is, derived from its own connection. provider_egress_location
1831+ // is where a probe actually watched its traffic leave. Counting on the claim
1832+ // alone advertises providers in countries they do not egress from -- measured
1833+ // on beta at 3 of 152 healthy providers claiming `at` while egressing from `gb`
1834+ // -- which is what an adversarial provider would exploit at scale.
1835+ //
1836+ // A provider with no observed location is not counted, matching the health rule.
1837+ func (f providerCountFilter ) countsTowardCountry (clientId server.Id , countryCode string ) bool {
1838+ if ! f .passesHealth (clientId ) {
1839+ return false
1840+ }
1841+ observed , ok := f .countryCodes [clientId ]
1842+ if ! ok {
1843+ return false
1844+ }
1845+ return observed == strings .ToLower (countryCode )
1846+ }
1847+
17751848func UpdateClientLocations (ctx context.Context , ttl time.Duration ) (returnErr error ) {
17761849 topCitiesPerRegion := 20
17771850 topCitiesPerCountry := 10
@@ -3060,20 +3133,6 @@ func UpdateClientScores(ctx context.Context, ttl time.Duration, parallel int) (r
30603133 minScoreScale := 0.1
30613134 maxScoreScale := 1.0
30623135
3063- // the measured egress health a provider must reach to be offered to users
3064- // at all, as a fraction of the destinations its last probe run sampled.
3065- //
3066- // 90% because it cleanly separates working from broken on the real
3067- // population: the healthy fleet measures 129-131 of 131 destinations, while
3068- // a dead proxy measures 0 of 131. Nothing observed sits near the line, so
3069- // the exact figure is not load bearing -- it only has to be far above 0 and
3070- // below the ~98% a genuinely working provider always clears.
3071- //
3072- // Compared exactly as `10*ok >= 9*total` rather than through a float
3073- // division, so the boundary is the same for every denominator.
3074- const minEgressHealthOKNumerator = 9
3075- const minEgressHealthOKDenominator = 10
3076-
30773136 // health is loaded once for the whole pass rather than per client: this
30783137 // walks every provider, and the table is one row per ever-probed provider.
30793138 //
@@ -3095,21 +3154,11 @@ func UpdateClientScores(ctx context.Context, ttl time.Duration, parallel int) (r
30953154 // still handed to the prober and still graduates the moment it measures
30963155 // healthy. If that queue ever starts consulting these scores, an excluded
30973156 // provider can never be re-measured and is stuck out permanently.
3098- egressHealthCounts := GetAllProviderEgressHealthCounts (ctx )
3099- // passesEgressHealth reports whether a probe has MEASURED this provider
3100- // healthy. Fail closed: no record at all (never probed) does not pass, and
3101- // neither does a record with no destinations in it, which is also not a
3102- // measurement of anything. Guarding total keeps the ratio well defined.
3103- passesEgressHealth := func (clientId server.Id ) bool {
3104- counts , ok := egressHealthCounts [clientId ]
3105- if ! ok {
3106- return false
3107- }
3108- if counts .Total <= 0 {
3109- return false
3110- }
3111- return minEgressHealthOKDenominator * counts .OKCount >= minEgressHealthOKNumerator * counts .Total
3112- }
3157+ // Shared with UpdateClientLocations so the gated membership and the
3158+ // advertised count can never disagree about what "healthy" means.
3159+ // UpdateClientScores uses passesHealth ONLY: its candidate pool is not
3160+ // country-scoped, so the observed-country check does not apply here.
3161+ countFilter := newProviderCountFilter (ctx )
31133162
31143163 // migration: set each client score to the lowest lookback index index
31153164 migrateClientScore := func (clientScore * ClientScore ) {
@@ -3136,7 +3185,7 @@ func UpdateClientScores(ctx context.Context, ttl time.Duration, parallel int) (r
31363185 // nothing else: it can only take a provider out of the pool, and the
31373186 // scaled-weight arithmetic below is untouched, so every provider that
31383187 // still qualifies keeps exactly the weight and ordering it has today.
3139- passesHealth := passesEgressHealth (clientScore .ClientId )
3188+ passesHealth := countFilter . passesHealth (clientScore .ClientId )
31403189
31413190 for _ , rankMode := range slices .Collect (maps .Keys (clientScore .Scores )) {
31423191 passesMinimum := passesHealth
0 commit comments