docs: update Proof of Potato model to v0.2
This commit is contained in:
1 parent
e2d0be22fd
commit
7397045a54
19 files changed
+588
-813
No files matched your search
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Illustrative, non-consensus PoP fee/fairness research. All numeric values hypothetical."""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import random
|
||||
|
||||
|
||||
def progressive_example(rewards_90d: float) -> float:
|
||||
"""Example marginal brackets. NEVER use floating-point for on-chain fees."""
|
||||
if rewards_90d < 0:
|
||||
raise ValueError('Rewards must be nonnegative')
|
||||
return (min(rewards_90d, 10) * 0.00005
|
||||
+ min(max(rewards_90d - 10, 0), 90) * 0.0002
|
||||
+ max(rewards_90d - 100, 0) * 0.0005)
|
||||
|
||||
|
||||
def fee_example(window: int, rewards_90d: float) -> float:
|
||||
if window == 1:
|
||||
return 0.0
|
||||
p = progressive_example(rewards_90d)
|
||||
if window == 2:
|
||||
return 0.001 + p
|
||||
if window == 3:
|
||||
return 0.003 + 2 * p
|
||||
raise ValueError('Window must be 1, 2 or 3')
|
||||
|
||||
|
||||
def qualify(rng: random.Random, windows: int, probability: float,
|
||||
rewards_90d: float) -> tuple[bool, float]:
|
||||
"""One ticket at most, fees charged only after the previous window fails."""
|
||||
if not 1 <= windows <= 3 or not 0 <= probability <= 1:
|
||||
raise ValueError('Invalid windows/probability')
|
||||
fee = 0.0
|
||||
for window in range(1, windows + 1):
|
||||
if window > 1:
|
||||
fee += fee_example(window, rewards_90d)
|
||||
if rng.random() < probability:
|
||||
return True, fee
|
||||
return False, fee
|
||||
|
||||
|
||||
def simulate(miners: int, runs: int, seed: int, probability: float,
|
||||
windows: int, rewards_90d: float, reward: float = 1.0) -> dict[str, float]:
|
||||
"""One chosen miner vs N-1 miners always attempting window one."""
|
||||
if miners < 1 or runs < 1 or reward < 0:
|
||||
raise ValueError('Invalid simulation scenario')
|
||||
rng = random.Random(seed)
|
||||
got_ticket = wins = 0
|
||||
spent = 0.0
|
||||
for _ in range(runs):
|
||||
qualified, fee = qualify(rng, windows, probability, rewards_90d)
|
||||
spent += fee
|
||||
if qualified:
|
||||
got_ticket += 1
|
||||
others = sum(rng.random() < probability for _ in range(miners - 1))
|
||||
if qualified and rng.randrange(others + 1) == 0:
|
||||
wins += 1
|
||||
return {
|
||||
'ticket_probability': got_ticket / runs,
|
||||
'win_probability': wins / runs,
|
||||
'avg_fee': spent / runs,
|
||||
'max_fee': sum(fee_example(w, rewards_90d) for w in range(2, windows + 1)),
|
||||
'net_expected_ptm': (wins / runs) * reward - spent / runs,
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--runs', type=int, default=25000)
|
||||
parser.add_argument('--seed', type=int, default=20261025)
|
||||
parser.add_argument('--p', type=float, default=0.70, help='Example success per full window')
|
||||
parser.add_argument('--reward', type=float, default=1.0, help='Illustrative PTM per won lottery')
|
||||
args = parser.parse_args()
|
||||
print('FORSCHUNGSMODELL, KEINE PROTOKOLLREGEL. Float nur für Simulation, niemals On-chain.')
|
||||
print(f'Parameter: runs={args.runs}, seed={args.seed}, p={args.p}, reward={args.reward} PTM')
|
||||
print('Alle anderen Miner nutzen nur das kostenlose Fenster 1.')
|
||||
print('N 90d-Ertrag Fenster Ticket% Gewinn% Ø Gebühr max Gebühr Netto-PTM/Runde')
|
||||
for n in (5, 10, 20, 50):
|
||||
for mined_90d in (0, 10, 100, 1000):
|
||||
for windows in (1, 2, 3):
|
||||
res = simulate(n, args.runs, args.seed + n + int(mined_90d),
|
||||
args.p, windows, float(mined_90d), args.reward)
|
||||
print(f'{n:<3} {mined_90d:>10} {windows:>7} '
|
||||
f'{100*res["ticket_probability"]:>7.2f} '
|
||||
f'{100*res["win_probability"]:>8.2f} '
|
||||
f'{res["avg_fee"]:>9.6f} '
|
||||
f'{res["max_fee"]:>11.6f} '
|
||||
f'{res["net_expected_ptm"]:>15.6f}')
|
||||
print('\nACHTUNG: Modell ohne Sybil-Effekt, Gebührenbudget, Validator-Zensur, reale Hashzeiten,')
|
||||
print('endogene Teilnahmeentscheidung oder Unsicherheit der PoP-Belohnung; keine')
|
||||
print('Garantie für faire Chancen oder wirtschaftlich sinnvolle Tarifwahl.')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user