klaim baseline saldo stabil (V56/B18) + endpoint cek akun payout-eligible /api/voter (V57)
V56/B18: pre-claim liquid balance dibaca SEKALI per window (poll_claim) dan dibawa ke tiap _try_claim_once — klaim yang mendarat di attempt 1 membuat before attempt 2 (ditolak already-claimed) sudah termasuk reward → delta 0 → alert palsu KLAIM MENDARAT · REWARD TAK TERUKUR (kasus 10 Agt: bfa9ab02 reward 1679.3365 vs tx ditolak b0a8b2f9) ; oracle B18 attempt-1-mendarat → claimed + reward asli terukur
V57: db.py single source eligible_voters(owner=None) — SQL jendela payout V40/V52 (last_vote > now−STALE AND first_seen_at IS NOT NULL AND first_seen_at ≤ now−MATURITY, cutoff UTC-naive) dipakai BAIK distribute.py run_distribution (refactor, hapus _eligible_cutoffs) MAUPUN endpoint baru GET /api/voter/<owner> → 200 {owner, is_valid_voter} (DB-snapshot, selalu 200, ⊖ format-validation); BARU/kadaluarsa/hidden/asing → false ; docs §I/§V/V57 + T50 + AGENTS ; oracle test_dashboard (V57 true/false + drift endpoint==db pool + pool distribusi==db) + test_distribute (mock eligible_voters utk no-op, distribusi luas)
This commit is contained in:
1 parent
ee4682da00
commit
8e80653df9
9 files changed
+172
-40
No files matched your search
@@ -8,7 +8,7 @@ skema `voters` yang sama; query berbagi sintaks ditulis dengan placeholder
|
||||
import sqlite3
|
||||
|
||||
from config import (DB_BACKEND, DB_HOST, DB_NAME, DB_PASS, DB_PORT, DB_PATH,
|
||||
DB_USER)
|
||||
DB_USER, VEX_MATURITY_DAYS, VEX_STALE_DAYS)
|
||||
|
||||
# Skema voters — sama untuk kedua backend (I.db)
|
||||
_COLS = (
|
||||
@@ -388,6 +388,33 @@ def record_first_seen(rows, scanned_at):
|
||||
conn.close()
|
||||
|
||||
|
||||
def eligible_voters(owner=None):
|
||||
"""V57: pemilih yang memenuhi syarat reward (single source, dipakai
|
||||
`distribute.py` + endpoint `/api/voter/<owner>`).
|
||||
|
||||
Jendela reward V40/V52 = `last_vote > now−STALE` (⊥ basi) DAN akun MATANG
|
||||
(`first_seen_at IS NOT NULL` DAN `first_seen_at ≤ now−MATURITY`). Maturity
|
||||
diukur dari `first_seen_at` (presisi detik; B15). Tanpa `owner` → semua
|
||||
baris `(owner, staked)` utk distribusi; dengan `owner` → baris akun itu
|
||||
(`[]` bila tak memenuhi syarat) utk cek endpoint.
|
||||
"""
|
||||
from datetime import datetime, timedelta, timezone
|
||||
now = datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
stale_cutoff = (now - timedelta(days=VEX_STALE_DAYS)).isoformat(timespec='seconds')
|
||||
mature_cutoff = (now - timedelta(days=VEX_MATURITY_DAYS)).isoformat(timespec='seconds')
|
||||
sql = ('SELECT v.owner, v.staked FROM voters v '
|
||||
'LEFT JOIN voter_first_seen fs ON fs.owner = v.owner '
|
||||
'WHERE v.last_vote > %s '
|
||||
' AND fs.first_seen_at IS NOT NULL '
|
||||
' AND fs.first_seen_at <= %s')
|
||||
params = [stale_cutoff, mature_cutoff]
|
||||
if owner is not None:
|
||||
sql += ' AND v.owner = %s'
|
||||
params.append(owner)
|
||||
ensure_first_seen_schema()
|
||||
return query(sql, params)
|
||||
|
||||
|
||||
def pending_claim_fee():
|
||||
"""Klaim terbaru dengan fee belum terkirim (fee_amount > 0) → baris | None.
|
||||
|
||||
|
||||
Reference in new issue
Block a user