sol mainnet payouts tasks
This commit is contained in:
@@ -12,7 +12,12 @@ import urllib.request
|
||||
import pytest
|
||||
|
||||
from meshnet_contracts import LocalSolanaContracts
|
||||
from meshnet_tracker.billing import BillingLedger
|
||||
from meshnet_tracker.billing import (
|
||||
BillingLedger,
|
||||
DEFAULT_PAYOUT_DUST_FLOOR,
|
||||
DEFAULT_PAYOUT_THRESHOLD,
|
||||
DEFAULT_SETTLE_PERIOD,
|
||||
)
|
||||
from meshnet_tracker.server import TrackerServer
|
||||
|
||||
MODEL = "stub-model"
|
||||
@@ -172,3 +177,115 @@ def test_non_leader_never_signs():
|
||||
assert ledger.get_node_pending("wallet-a") > 0
|
||||
finally:
|
||||
tracker.stop()
|
||||
|
||||
|
||||
# Production defaults — sourced from billing.py (cli.py uses the same constants)
|
||||
PROD_SETTLE_PERIOD = DEFAULT_SETTLE_PERIOD
|
||||
PROD_PAYOUT_THRESHOLD = DEFAULT_PAYOUT_THRESHOLD
|
||||
PROD_DUST_FLOOR = DEFAULT_PAYOUT_DUST_FLOOR
|
||||
|
||||
|
||||
def _set_pending_since(ledger: BillingLedger, wallet: str, ts: float) -> None:
|
||||
with ledger._lock:
|
||||
ledger._pending_since[wallet] = ts
|
||||
|
||||
|
||||
def test_prod_settlement_constants():
|
||||
"Production settlement policy is 24 h period, 5 USDT threshold, 0.01 dust floor.\n\nTags: billing, settlement"
|
||||
assert DEFAULT_SETTLE_PERIOD == 86400.0
|
||||
assert DEFAULT_PAYOUT_THRESHOLD == 5.0
|
||||
assert DEFAULT_PAYOUT_DUST_FLOOR == 0.01
|
||||
|
||||
|
||||
def test_payables_24h_period_not_due_before_elapsed():
|
||||
"Sub-threshold pending is not payable until the 24 h period elapses.\n\nTags: billing, settlement"
|
||||
ledger = BillingLedger(starting_credit=100.0, default_price_per_1k=0.02)
|
||||
ledger.charge_request("client", MODEL, 1000, [("node-wallet", 12)])
|
||||
assert ledger.get_node_pending("node-wallet") == pytest.approx(0.018)
|
||||
|
||||
t0 = 1_700_000_000.0
|
||||
_set_pending_since(ledger, "node-wallet", t0)
|
||||
due_early = ledger.payables(
|
||||
threshold=PROD_PAYOUT_THRESHOLD,
|
||||
max_period=PROD_SETTLE_PERIOD,
|
||||
dust_floor=PROD_DUST_FLOOR,
|
||||
now=t0 + PROD_SETTLE_PERIOD - 1.0,
|
||||
)
|
||||
assert due_early == []
|
||||
|
||||
|
||||
def test_payables_24h_period_triggers_at_boundary():
|
||||
"Sub-threshold pending becomes payable exactly after the 24 h period.\n\nTags: billing, settlement"
|
||||
ledger = BillingLedger(starting_credit=100.0, default_price_per_1k=0.02)
|
||||
ledger.charge_request("client", MODEL, 1000, [("node-wallet", 12)])
|
||||
pending = ledger.get_node_pending("node-wallet")
|
||||
|
||||
t0 = 1_700_000_000.0
|
||||
_set_pending_since(ledger, "node-wallet", t0)
|
||||
due = ledger.payables(
|
||||
threshold=PROD_PAYOUT_THRESHOLD,
|
||||
max_period=PROD_SETTLE_PERIOD,
|
||||
dust_floor=PROD_DUST_FLOOR,
|
||||
now=t0 + PROD_SETTLE_PERIOD,
|
||||
)
|
||||
assert due == [("node-wallet", pytest.approx(pending))]
|
||||
|
||||
|
||||
def test_payables_threshold_triggers_before_24h_period():
|
||||
"Pending ≥ 5 USDT pays immediately without waiting the 24 h period.\n\nTags: billing, settlement"
|
||||
ledger = BillingLedger(starting_credit=1000.0, default_price_per_1k=0.02)
|
||||
# cost = 300k * 0.02 / 1k = 6.0 USDT → node share 5.4 USDT
|
||||
ledger.charge_request("client", MODEL, 300_000, [("node-wallet", 12)])
|
||||
assert ledger.get_node_pending("node-wallet") >= PROD_PAYOUT_THRESHOLD
|
||||
|
||||
due = ledger.payables(
|
||||
threshold=PROD_PAYOUT_THRESHOLD,
|
||||
max_period=PROD_SETTLE_PERIOD,
|
||||
dust_floor=PROD_DUST_FLOOR,
|
||||
now=time.time(),
|
||||
)
|
||||
assert len(due) == 1
|
||||
assert due[0][0] == "node-wallet"
|
||||
|
||||
|
||||
def test_prod_defaults_hold_sub_threshold_pending():
|
||||
"Tracker with prod 24 h / 5 USDT settings does not pay tiny balances early.\n\nTags: billing, settlement"
|
||||
ledger = BillingLedger(starting_credit=100.0, default_price_per_1k=0.02)
|
||||
ledger.charge_request("client", MODEL, 1000, [("node-wallet", 12)])
|
||||
treasury = _FakePayoutTreasury()
|
||||
tracker = _make_tracker(
|
||||
ledger,
|
||||
treasury,
|
||||
threshold=PROD_PAYOUT_THRESHOLD,
|
||||
period=PROD_SETTLE_PERIOD,
|
||||
dust=PROD_DUST_FLOOR,
|
||||
)
|
||||
tracker.start()
|
||||
try:
|
||||
time.sleep(0.5)
|
||||
assert treasury.batches == []
|
||||
assert ledger.get_node_pending("node-wallet") > 0
|
||||
finally:
|
||||
tracker.stop()
|
||||
|
||||
|
||||
def test_prod_threshold_triggers_immediate_payout():
|
||||
"Tracker with prod 24 h period still pays when pending ≥ 5 USDT.\n\nTags: billing, settlement"
|
||||
ledger = BillingLedger(starting_credit=1000.0, default_price_per_1k=0.02)
|
||||
ledger.charge_request("client", MODEL, 300_000, [("node-wallet", 12)])
|
||||
treasury = _FakePayoutTreasury()
|
||||
tracker = _make_tracker(
|
||||
ledger,
|
||||
treasury,
|
||||
threshold=PROD_PAYOUT_THRESHOLD,
|
||||
period=PROD_SETTLE_PERIOD,
|
||||
dust=PROD_DUST_FLOOR,
|
||||
)
|
||||
tracker.start()
|
||||
try:
|
||||
assert _wait_for(lambda: treasury.batches)
|
||||
assert ledger.get_node_pending("node-wallet") == pytest.approx(0.0)
|
||||
assert treasury.batches[0][0][0] == "node-wallet"
|
||||
assert treasury.batches[0][0][1] >= PROD_PAYOUT_THRESHOLD
|
||||
finally:
|
||||
tracker.stop()
|
||||
|
||||
Reference in New Issue
Block a user