T14: penanda vote basi (last_vote dari rasio bobot/stake, filter ?stale=1, VEX_STALE_DAYS)
This commit is contained in:
1 parent
2b95be3091
commit
b0b3ba8ab3
10 files changed
+236
-52
No files matched your search
+33
-5
@@ -3,10 +3,11 @@
|
||||
Berjalan imparsial (repeatable) dan siap dijadwalkan (cron). Memakai requests.
|
||||
"""
|
||||
|
||||
import math
|
||||
import sqlite3
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import requests
|
||||
|
||||
@@ -23,6 +24,30 @@ LIMIT = 500
|
||||
# Ambang-batas nama akun "0" (kodifikasi uint64 0) pada tabel voters
|
||||
ZERO_OWNER = '...........q'
|
||||
|
||||
# Skala stake (×10000) dan epoch bobot suara Vexanium (1 Jan 2000)
|
||||
VEX_SCALE = 10000
|
||||
WEIGHT_EPOCH = datetime(2000, 1, 1)
|
||||
|
||||
|
||||
def derive_last_vote(weight, staked_vex):
|
||||
"""V13: perkiraan waktu revote terakhir dari rasio bobot/stake.
|
||||
|
||||
Vexanium: last_vote_weight = staked_raw × 2^(tahun sejak 2000).
|
||||
Maka t = log2(last_vote_weight / staked_raw) → tanggal revote.
|
||||
Kembalikan None bila tak bisa dihitung (bobot/stake nol atau tak valid).
|
||||
"""
|
||||
staked_raw = staked_vex * VEX_SCALE
|
||||
if staked_raw <= 0:
|
||||
return None
|
||||
try:
|
||||
ratio = float(weight) / staked_raw
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
if ratio <= 0:
|
||||
return None
|
||||
t_years = math.log(ratio) / math.log(2)
|
||||
return (WEIGHT_EPOCH + timedelta(days=t_years * 365.25)).isoformat(timespec='seconds')
|
||||
|
||||
|
||||
def fetch_with_retry(payload, max_retries=3, timeout=30):
|
||||
"""POST ke RPC dengan retry (node publik sering timeout).
|
||||
@@ -93,6 +118,7 @@ def normalize(row):
|
||||
'owner': owner,
|
||||
'weight': row.get('last_vote_weight', ''), # V6: bobot verbatim (string)
|
||||
'staked': staked_vex,
|
||||
'last_vote': derive_last_vote(row.get('last_vote_weight', ''), staked_vex),
|
||||
}
|
||||
|
||||
|
||||
@@ -112,12 +138,14 @@ def persist(rows):
|
||||
'owner TEXT PRIMARY KEY, '
|
||||
'weight TEXT NOT NULL, '
|
||||
'staked REAL NOT NULL, '
|
||||
'scanned_at TEXT NOT NULL)'
|
||||
'scanned_at TEXT NOT NULL, '
|
||||
'last_vote TEXT)'
|
||||
)
|
||||
conn.executemany(
|
||||
'INSERT INTO voters (owner, weight, staked, scanned_at) '
|
||||
'VALUES (?, ?, ?, ?)',
|
||||
[(r['owner'], r['weight'], r['staked'], scanned_at) for r in rows],
|
||||
'INSERT INTO voters (owner, weight, staked, scanned_at, last_vote) '
|
||||
'VALUES (?, ?, ?, ?, ?)',
|
||||
[(r['owner'], r['weight'], r['staked'], scanned_at, r.get('last_vote'))
|
||||
for r in rows],
|
||||
)
|
||||
conn.commit()
|
||||
finally:
|
||||
|
||||
Reference in new issue
Block a user