FlareWatch gán cho mỗi nhà cung cấp dữ liệu FTSO một điểm tổng hợp từ 0–100 trên 12 chiều được tính điểm. Phép toán là xác định, các đầu vào là dữ liệu công khai trên chuỗi và hệ sinh thái Flare[Flaremetrics] [FSE] [Flare Explorer], và cùng một thuật toán áp dụng cho mỗi provider — bao gồm FTSO provider của FlareWatch, được tính điểm bằng chính xác hàm này mà không có xử lý đặc biệt. Trang này ghi lại mỗi thứ nguyên và ngưỡng để delegator và nhà khai thác có thể thấy chính xác cách tính điểm số và tại sao mỗi giá trị được chọn. Mỗi khiếu nại ở đây liên kết trở lại với nguồn ngữp hạng chính của nó — xem Nguồn & tham khảo ở dưới cùng.
chế độ ủy quyền trên trang các trình xác thực (ủy quyền WFLR cho các nhà cung cấp dữ liệu FTSO để chia sẻ lạm phát FTSO). Điểm số trình xác thực được hiển thị trong chế độ staking (ủy quyền FLR cho trình xác thực P-Chain để nhận phần thưởng VRM + MIRROR) sử dụng một thuật toán 9 chiều riêng biệt tập trung vào hoạt động của trình xác thực — thời gian hoạt động, phí, độ tin cậy, v.v. Đây là các vai trò riêng biệt trên chuỗi với phần thưởng riêng biệt, được chấm điểm riêng. Xem Phương pháp luận Điểm số Trình xác thực cho phía staking.| 90+ | Tầng hàng đầu — top ~10–20% các nhà cung cấp FTSO. Hồ sơ điển hình: tỷ lệ phần thưởng cao hơn mức trung bình, độ chính xác cao, tham gia đầy đủ giao thức V2 (FTSO Scaling + Fast Updates + FDC), phí thấp/bằng không, cơ sở ủy quyền lớn, nút trình xác thực thanh toán MIRROR, thương hiệu được đặt tên. Không yêu cầu chiều độ duy nhất — các nhà cung cấp đạt tầng hàng đầu bằng cách tích tụ sức mạnh trên hầu hết các danh mục. |
| 80–89 | Mạnh — đáp ứng hầu hết các điểm chuẩn chính; thiếu một hoặc hai chiều so với tầng hàng đầu. |
| 70–79 | Tốt — đáp ứng tất cả các tiêu chí cơ sở; không có khoảng trống lớn. |
| 60–69 | Chấp nhận được — có thể sử dụng nhưng không có sự khác biệt. |
| <60 | Dưới mức trung bình — khoảng trống đáng kể trong một hoặc nhiều chiều. Sự kiện toán học, không phải đánh giá chất lượng. |
if (rate <= 0 || medianRate <= 0): score = 0 else: ratio = rate / medianRate score = min(25, round(ratio * 12.5 * 10) / 10) // 1 decimal place // Anomaly detection: providers > 3× the median are capped at // median × 3 for scoring purposes (prevents data outliers from // distorting the linear curve).
if (fseAccuracySecondary > 0): pct = fseAccuracySecondary / 100 if (pct >= 97) score = 25 elif (pct >= 95) score = 18 + (pct - 95) * 3.5 // 95 → 18, 97 → 25 elif (pct >= 93) score = 16 + (pct - 93) * 1 // 93 → 16, 95 → 18 elif (pct >= 90) score = 13 + (pct - 90) * 1 // 90 → 13, 93 → 16 elif (pct >= 85) score = 10 + (pct - 85) * 0.6 // 85 → 10, 90 → 13 elif (pct >= 80) score = 6 + (pct - 80) * 0.8 // 80 → 6, 85 → 10 else score = max(0, 2 + (pct - 70) * 0.4) elif (fseAccuracyPrimary > 0): // Primary fallback: similar piecewise linear curve. else: score = WEIGHT_ACCURACY / 2 // Neutral — no FSE data
earned = last 12 epochs where rewardRate > 0, keyed by epochId pairs = [earned[i-1], earned[i]] where epochId[i] - epochId[i-1] == 1 if (pairs.length < 3) return 10 // Neutral — too few consecutive pairs // DOWNSIDE volatility only: rises never hurt, so a stable or RISING // rate scores near full and a recovery lifts the score. Only drops // between CONSECUTIVE epochs count, in proportion to depth (RMS), // weighted toward recent pairs so an active recovery pulls the score up. drops[i] = max(0, (prev - cur) / prev) // rise -> 0 w[i] = 0.8 ^ (age of pair) // newest pair = highest cv = sqrt( sum(w[i] * drops[i]^2) / sum(w[i]) ) score = max(0, round((1 - min(1, cv * 6)) * 20 * 10) / 10)
if (!isActive) score = 0 // see "Active" below
else:
score = 3 // active baseline
if (hasSubmitAddress AND hasSigningPolicyAddress AND voterRegistered):
score += 4 // V1 registered
if (fseFtsoScaling) score += 8/3 // ~2.67 each
if (fseFastUpdates) score += 8/3
if (fseFdc) score += 8/3
score = min(15, round(score * 10) / 10)anchor = max(lowest active fee observed, protocol fee floor) // FIP-16 sets a 20% minimum entity fee. All 98 providers charge // exactly 20%, so the anchor is 20% and nobody is docked for // charging the only fee the protocol permits. Same curve and // same anchor the validator page's Fee dimension uses. if (!isActive) score = 0 d = fee - anchor // distance ABOVE the best real offer if (d <= 0) score = 15 // at or below the anchor → full marks elif (d <= 5) score = 15 - d * 0.43 elif (d <= 10) score = 12.9 - (d - 5) * 0.64 elif (d <= 15) score = 9.6 - (d - 10) * 0.86 elif (d <= 20) score = 5.4 - (d - 15) * 1.07 else: score = 0 // extractive
if (no fseNodeIDs) score = 0 if (mirrorStatsMap empty) score = 12 / 2 = 6 // Neutral seed before data lands activeCount = nodes_with_status_active fraction = activeCount / fseNodeIDs.length base = 12 * fraction // Overperformance bonus per node, applied only when ALL gates pass: // - >= 30 days observed since first reading (firstObservedAtMs) // - >= 3 paid stake observations // - finite medianOverpaymentRatio // Bayesian shrinkage with prior k=5 toward 1.0 (neutral): // shrunken = (observedRatio * N + 1.0 * 5) / (N + 5) // Bucketed bonus from shrunken: // < 1.05 → 0 < 1.15 → 1 < 1.30 → 2 >= 1.30 → 3 avgBonus = sum_per_node(bonus) / fseNodeIDs.length score = round((base + avgBonus) * 10) / 10
if (count <= 5) score = 0 elif (count >= 500) score = 12 else: ratio = log(count / 5) / log(100) // maps [5, 500] → [0, 1] score = round(min(12, max(0, ratio * 12)) * 10) / 10
if (fseActive) score = 10 elif (rewardRate > 0) score = 7 else score = 0
change = abs(votePowerDailyChangePct * 100) if (change < 1) score = 10 elif (change < 3) score = 10 - (change - 1) * 1.5 // 1 → 10, 3 → 7 elif (change < 5) score = 7 - (change - 3) * 1.5 // 3 → 7, 5 → 4 elif (change < 10) score = 4 - (change - 5) * 0.4 // 5 → 4, 10 → 2 else score = max(0, 2 - (change - 10) * 0.1)
if (no fspData OR totalEpochs <= 0) score = 5 // active window = epochs from the provider's first paid epoch to now missed = (active-window epochs) - (epochs the provider was paid) score = max(0, 10 - missed * 3)
if (no name) score = 0 elif (name starts with 0x or matches hex regex) score = 0 elif (name.length < 4) score = 4 else score = 8
ownBond = operator's own P-Chain node bond (FLR) total = ownBond + delegated WFLR vote power alignment = piecewise-linear ratio curve (0% → 0 … ≥10% → 7) absolute = min(7, ownBond / 5,000,000 * 7) // saturates at 5M FLR score = max(alignment, absolute)
fspRewardRate, delegationFeePercentage, wNatWeight, và votePowerDailyChangePct của bạn.providersuccessrate.secondary để tính độ chính xác, cộng với các cờ entityminimalconditionslatest.ftso_scaling / ftso_fast_updates / fdc cho trạng thái V2.RewardClaimed với claimType=3 tham chiếu đến nodeID của bạn. Nếu không có sự kiện gần đây nào cho bất kỳ nút nào của bạn, bạn sẽ hiển thị là MIRROR-không hoạt động trên điểm số.// Step 1 — Raw composite (sum of 12 dimensions, max 172)
raw = rewardRate + accuracy + consistency + v2 + fee + mirror
+ delegators + participation + stability + compliance
+ identity + selfBond
// An UNMEASURED reward rate is not a FAILED one. When a provider is
// demonstrably distributing but we hold no rate figure for it, the
// Reward Rate weight leaves the DENOMINATOR rather than scoring 0
// against it — we score what we measured, over what we could measure.
maxRaw = (rewardRate figure missing AND isActive) ? 172 - 25 : 172
normalized = round((raw / maxRaw) * 100)
// (The separate vote-power dilution penalty was REMOVED in v4.9. It
// double-counted: an over-cap provider already earns a below-median
// realized reward rate, so the median-anchored Reward Rate dimension
// docks it for dilution once. Cap proximity is now a neutral DISPLAY
// signal on every provider, not a second deduction in the score.)
// Step 2 — Dynamic weight redistribution
// Across the active provider set, dimensions where everyone clusters
// (stddev < 1.0) become non-discriminating. Their weight gets
// redistributed evenly across dimensions where the spread is wider
// (stddev >= 1.0). The redistribution recomputes the score:
//
// for each dim d:
// multiplier[d] = 1.0 if stddev[d] < 1.0
// = (weight[d] + bonus) / weight[d] otherwise
// bonus = sum(weights of low-stddev dims) / count(high-stddev dims)
//
// adjusted_raw = sum(breakdown[d] * multiplier[d])
// adjusted_max = sum(weight[d] * multiplier[d])
// final = round((adjusted_raw / adjusted_max) * 100)
// Step 3 — Final score (capped at 100)
score = min(100, final)services/ftso/scoring.ts trong codebase FlareWatch. Các toán tử hoặc nhà nghiên cứu muốn kiểm tra triển khai trực tiếp (thay vì đọc các công thức văn bản + ở trên) — hoặc muốn fork nó cho riêng họ — có thể gửi email đến [email protected] để yêu cầu truy cập. Chúng tôi sẽ xuất bản tệp dưới dạng gói mã nguồn mở độc lập nếu có nhu cầu thực sự./api/cron/refresh-validators, điều này tính toán lại điểm của mỗi nhà cung cấp hoạt động mỗi 5 phút (cùng một lần chạy tính toán lại điểm của các trình xác thực P-Chain). Các đầu vào (Flaremetrics, FSE, FSP rewards, V2 RewardManager events) được tìm nạp mới trên mỗi lần chạy.