Files
databisnisid/config.py
T
proitlab 69704fa23d failover pool Hyperion utk semua pembacaan /v2/* (V60)
verify_txid (distribute) ⊖ lagi single-host single-shot — blip Hyperion
sesaat dulu menahan payout (V59 hold) / gagal ukur reward klaim / kosongkan
SALDO LIQUID dashboard.

config.py: HYPERION_NODES (CSV VEX_HYPERION_NODES, default HYPERION_API +
API_NODES dedup, utama di depan — kedua host mainnet terverifikasi layani
/v2, probe 2026-08-13) ; distribute._get_json GET mirror _post_json V58
(3 putaran, 2s, coba semua host per putaran, semua gagal → None) dipakai
verify_txid — None kini berarti SEMUA host Hyperion gagal, hold V59 jarang
palsu ; claim.reward_from_tx via dist._get_json (tiap attempt settle V55
pool-robust) ; dashboard._get_liquid_vex loop HYPERION_NODES lokal (web ⊖
impor distribute, V31), SALDO LIQUID tetap live saat host mati

oracle: test_distribute V60 failover verify_txid + semua-mati None ;
test_claim V60 reward_from_tx failover ; test_dashboard V60 saldo cadangan +
config default HYPERION_NODES ; docs SPEC §V/V60 + §I + T53 + AGENTS +
.env.example

image web + dist + claim rebuild + push ; live smoke pool /v2/health
2026-08-13 21:30:31 +07:00

148 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Konfigurasi proyek dari env / `.env`.
Bacaan tipe via `os.getenv`; nilai default = konstanta lama. Muat `.env` sekali
di sini supaya semua modul (get_voters, dashboard) berbagi sumber yang sama.
"""
import os
from decimal import Decimal
from dotenv import load_dotenv
load_dotenv()
# BP target
TARGET_BP = os.getenv('VEX_TARGET_BP', 'databisnisid')
# Node RPC publik Vexanium
API_NODE = os.getenv('VEX_API_NODE', 'https://v2.vexascan.com:2096')
# Node pool RPC (V58): CSV `VEX_API_NODES` — node utama + cadangan utk failover
# distribusi (fetch saldo, ABI/TAPOS, broadcast). Default = `API_NODE` +
# `https://api.databisnis.id` (node mainnet Vexanium terverifikasi, host sama
# dgn HYPERION_API tapi melayani juga /v1/chain). Dipakai `distribute.py`;
# scan/klaim tetap memakai `API_NODE` tunggal.
API_NODES = [
n.strip() for n in os.getenv(
'VEX_API_NODES', f'{API_NODE},https://api.databisnis.id').split(',')
if n.strip()
]
# Lokasi basis data SQLite (dipakai fetcher & dashboard)
DB_PATH = os.getenv('VEX_DB_PATH', 'voters.db')
# Backend basis data: 'sqlite' (default) atau 'mysql' (MariaDB/MySQL via PyMySQL)
DB_BACKEND = os.getenv('VEX_DB_BACKEND', 'sqlite')
# Koneksi MariaDB/MySQL (dipakai saat DB_BACKEND='mysql')
DB_HOST = os.getenv('VEX_DB_HOST', '127.0.0.1')
DB_PORT = int(os.getenv('VEX_DB_PORT', '3306'))
DB_USER = os.getenv('VEX_DB_USER', '')
DB_PASS = os.getenv('VEX_DB_PASS', '')
DB_NAME = os.getenv('VEX_DB_NAME', '')
# Syarat minimum stake (dalam VEX) untuk disimpan
MIN_STAKED_VEX = float(os.getenv('VEX_MIN_STAKED_VEX', '1000'))
# Dashboard: ukuran halaman list
PAGE_SIZE = int(os.getenv('DASH_PAGE_SIZE', '50'))
# Dashboard: host & port server Flask
DASH_HOST = os.getenv('DASH_HOST', '127.0.0.1')
DASH_PORT = int(os.getenv('DASH_PORT', '5000'))
# Dashboard: jumlah worker gunicorn (produksi)
DASH_WORKERS = int(os.getenv('DASH_WORKERS', '2'))
# Ambang batas vote "basi" (hari tanpa revote). Sejak V40 pemilih lewat batas
# ini TETAP disimpan di scan (basi dibuang hanya saat tampil/bayar): band
# kadaluarsa 28..31 hari tetap tampil (sorot VOTE ULANG), >31 hari disembunyikan.
VEX_STALE_DAYS = int(os.getenv('VEX_STALE_DAYS', '28'))
# Masa matang (hari): pemilih baru (revote < VEX_MATURITY_DAYS lalu) BELUM
# berhak reward (⊥ dibayar distribusi) hingga votenya berumur ≥ ambang ini.
VEX_MATURITY_DAYS = int(os.getenv('VEX_MATURITY_DAYS', '3'))
# Jendela "kadaluarsa" (hari SETELAH VEX_STALE_DAYS) yang masih tampil di
# dashboard (band sorot VOTE ULANG). Lewat 28+3 = 31 hari → disembunyikan.
VEX_EXPIRED_DAYS = int(os.getenv('VEX_EXPIRED_DAYS', '3'))
# Tag REVOTE (mint) bertahan (hari) sejak revote terakhir: hanya pemilih lama
# yang revote dalam `VEX_REVOTE_TAG_DAYS` terakhir diberi tag; setelah itu
# tampil sbg VALID biasa (tetap dibayar langsung — V42, ⊥ tunggu matang).
VEX_REVOTE_TAG_DAYS = int(os.getenv('VEX_REVOTE_TAG_DAYS', '1'))
# Jendela peringatan (hari SEBELUM VEX_STALE_DAYS): pemilih VALID yang
# `now − STALE < last_vote ≤ now − (STALE − WARN)` diberi badge `VOTE ULANG
# SEGERA` (segera kadaluarsa, masih dibayar).
VEX_WARN_DAYS = int(os.getenv('VEX_WARN_DAYS', '3'))
# Hyperion API untuk saldo liquid akun + verifikasi txid (balance BP,
# disajikan dashboard; verifikasi distribusi/klaim). `HYPERION_API` nama baru
# (V-rename); `DATABISNIS_API` masih dibaca utk backward-compat deploy lama.
HYPERION_API = (os.getenv('HYPERION_API')
or os.getenv('DATABISNIS_API')
or 'https://api.databisnis.id')
# Node pool Hyperion (V60): CSV `VEX_HYPERION_NODES` — host yang melayani
# `/v2/*` utk failover GET Hyperion (verifikasi txid, reward klaim, saldo
# liquid dashboard). Default = `HYPERION_API` (utama) + semua `API_NODES`
# (keduanya mainnet terverifikasi layani /v2, probe 2026-08-13), dedup,
# utama di depan. Dipakai `distribute._get_json` + dashboard `_get_liquid_vex`.
HYPERION_NODES = [
n.strip() for n in os.getenv(
'VEX_HYPERION_NODES',
','.join([HYPERION_API] + [n for n in API_NODES if n != HYPERION_API]),
).split(',') if n.strip()
]
# Dashboard: TTL cache (detik) untuk saldo liquid — gagal fetch juga di-cooldown
DASH_LIQUID_TTL = int(os.getenv('DASH_LIQUID_TTL', '60'))
# ————————————————— Distribusi profit-share (V19..V27) —————————————————
# Jam (lokal, TZ) run harian distribusi; key aktif BP via swarm secret/env.
# ⊥ env-able: konstanta chain Vexanium (token + chain_id untuk signing).
BP_PRIVATE_KEY = os.getenv('VEX_BP_PRIVATE_KEY', '')
DISTRIBUTE_HOUR = int(os.getenv('DISTRIBUTE_HOUR', '10'))
DISTRIBUTE_MAX_ATTEMPTS = int(os.getenv('DISTRIBUTE_MAX_ATTEMPTS', '3'))
# Kill-switch distribusi (V35): default OFF — payout hanya jalan saat diset
# `true`. `--dry-run` tetap boleh jalan (read-only, ⊥ tanda tangan/tulis).
DISTRIBUTE_ENABLED = os.getenv(
'DISTRIBUTE_ENABLED', 'false').lower() in ('1', 'true', 'yes')
# Jadwal distribusi (V37/V44): hari `DISTRIBUTE_WEEKDAY` — satu nama (`sat`) atau
# CSV beberapa hari (`wed,sat`), jam `DISTRIBUTE_HOUR`; plus satu one-off
# `DISTRIBUTE_FIRST_RUN` (`YYYY-MM-DD`). Dipakai distribute_loop (via config,
# konsisten dgn dashboard V38). Default baked = launch pertama 2026-08-17
# (Senin) 10:00 lalu tiap Rabu & Sabtu; env tetap override. Setelah tanggal
# lewat → otomatis hanya mingguan (batas skip event masa lalu).
DISTRIBUTE_WEEKDAY = os.getenv('DISTRIBUTE_WEEKDAY', 'wed,sat')
DISTRIBUTE_FIRST_RUN = os.getenv('DISTRIBUTE_FIRST_RUN', '2026-08-17')
# ————————————————— Notifikasi Telegram (V30/V36) —————————————————
# Bot token tunggal; dua daftar chat id (CSV): KOMUNITAS (`..._COMMUNITY_...`)
# hanya brief mulai/selesai distribusi, INTERNAL (`..._INTERNAL_...`) detail
# distribusi + semua kegagalan + klaim reward (⊥ komunitas). Kosong → kanal
# itu senyap.
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN', '')
TELEGRAM_COMMUNITY_CHAT_IDS = [
c.strip() for c in os.getenv('TELEGRAM_COMMUNITY_CHAT_IDS', '').split(',')
if c.strip()
]
TELEGRAM_INTERNAL_CHAT_IDS = [
c.strip() for c in os.getenv('TELEGRAM_INTERNAL_CHAT_IDS', '').split(',')
if c.strip()
]
# ————————————————— Klaim reward BP (V32..V34) —————————————————
# Poll interval (detik) saat mendekati jendela klaim; fee wallet + persentase
# 10% dari reward yang baru diklaim (floor 4 desimal).
CLAIM_RETRY_SECONDS = int(os.getenv('CLAIM_RETRY_SECONDS', '60'))
BP_FEE_WALLET = os.getenv('VEX_BP_FEE_WALLET', 'bpdbsjasprod')
BP_FEE_PERCENT = Decimal(os.getenv('VEX_BP_FEE_PERCENT', '0.10'))
# Kontrak token VEX = vex.token (⊥ eosio.token — tak ada di chain)
TOKEN_CONTRACT = 'vex.token'
VEX_SYMBOL = 'VEX'
VEX_PRECISION = 4
VEX_CHAIN_ID = 'f9f432b1851b5c179d2091a96f593aaed50ec7466b74f89301f957a83e56ce1f'