lottery.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import matplotlib.pyplot as plt
  2. from tqdm import tqdm
  3. import time
  4. from datetime import timedelta
  5. from core.darkie import *
  6. from pid.cascade import *
  7. from tqdm import tqdm
  8. class DarkfiTable:
  9. def __init__(self, airdrop, running_time, controller_type=CONTROLLER_TYPE_DISCRETE, kp=0, ki=0, kd=0, dt=1, kc=0, ti=0, td=0, ts=0, debug=False, r_kp=0, r_ki=0, r_kd=0):
  10. self.Sigma=airdrop
  11. self.darkies = []
  12. self.running_time=running_time
  13. self.start_time=None
  14. self.end_time=None
  15. self.secondary_pid = SecondaryDiscretePID(kp=kp, ki=ki, kd=kd) if controller_type==CONTROLLER_TYPE_DISCRETE else SecondaryTakahashiPID(kc=kc, ti=ti, td=td, ts=ts)
  16. print('secondary min/max : {}/{}'.format(self.secondary_pid.clip_min, self.secondary_pid.clip_max))
  17. self.primary_pid = PrimaryDiscretePID(kp=r_kp, ki=r_ki, kd=r_kd) if controller_type==CONTROLLER_TYPE_DISCRETE else PrimaryTakahashiPID(kc=kc, ti=ti, td=td, ts=ts)
  18. print('primary min/max : {}/{}'.format(self.primary_pid.clip_min, self.primary_pid.clip_max))
  19. self.debug=debug
  20. self.rewards = []
  21. self.winners = []
  22. def add_darkie(self, darkie):
  23. self.darkies+=[darkie]
  24. def background(self, rand_running_time=True, debug=False, hp=True):
  25. self.debug=debug
  26. self.start_time=time.time()
  27. feedback=0 # number leads in previous slot
  28. # random running time
  29. rand_running_time = random.randint(1,self.running_time) if rand_running_time else self.running_time
  30. self.running_time = rand_running_time
  31. #if rand_running_time and debug:
  32. #print("random running time: {}".format(self.running_time))
  33. #print('running time: {}'.format(self.running_time))
  34. rt_range = tqdm(np.arange(0,self.running_time, 1))
  35. for count in rt_range:
  36. #while count < self.running_time:
  37. winners=0
  38. f = self.secondary_pid.pid_clipped(float(feedback), debug)
  39. if count%EPOCH_LENGTH == 0:
  40. acc = self.secondary_pid.acc()
  41. #staked_ratio = self.avg_stake_ratio()
  42. reward = self.primary_pid.pid_clipped(acc, debug)
  43. self.rewards += [reward]
  44. rt_range.set_description('issuance {} DRK, acc: {}'.format(round(sum(self.rewards),2), round(acc,2)))
  45. #note! thread overhead is 10X slower than sequential node execution!
  46. for i in range(len(self.darkies)):
  47. self.darkies[i].set_sigma_feedback(self.Sigma, feedback, f, count, hp)
  48. self.darkies[i].update_vesting()
  49. self.darkies[i].run(hp)
  50. #print('reward: {}'.format(rewards[-1]))
  51. for i in range(len(self.darkies)):
  52. winners += self.darkies[i].won_hist[-1]
  53. ###
  54. self.winners +=[winners]
  55. feedback = winners
  56. if self.winners[-1]==1:
  57. for i in range(len(self.darkies)):
  58. if self.darkies[i].won_hist[-1]:
  59. self.darkies[i].update_stake(self.rewards[-1])
  60. break
  61. # resolve finalization
  62. if count >= ERC20DRK:
  63. self.Sigma += 1
  64. # resync nodes
  65. merge_length = 0
  66. for i in reversed(self.winners[:-1]):
  67. if i !=1:
  68. merge_length+=1
  69. else:
  70. break
  71. for i in range(merge_length):
  72. resync_slot_id = count-(i+1)
  73. resync_reward_id = int((resync_slot_id)/EPOCH_LENGTH)
  74. resync_reward = self.rewards[resync_reward_id]
  75. # resyncing depends on the random branch chosen,
  76. # it's simulated by choosing first wining node
  77. darkie_winning_idx = 0
  78. random.shuffle(self.darkies)
  79. for darkie_idx in range(len(self.darkies)):
  80. if self.darkies[darkie_idx].won_hist[resync_slot_id]:
  81. darkie_winning_idx = darkie_idx
  82. break
  83. self.darkies[darkie_winning_idx].resync_stake(resync_reward)
  84. count+=1
  85. self.end_time=time.time()
  86. avg_reward = sum(self.rewards)/len(self.rewards)
  87. stake_ratio = self.avg_stake_ratio()
  88. avg_apy = self.avg_apy()
  89. avg_apr = self.avg_apr()
  90. #print('apy: {}, staked_ratio: {}'.format(avg_apy, stake_ratio))
  91. return self.secondary_pid.acc_percentage(), avg_apy, avg_reward, stake_ratio, avg_apr
  92. def avg_apy(self):
  93. return Num(sum([darkie.apy_scaled_to_runningtime(self.rewards) for darkie in self.darkies])/len(self.darkies))
  94. def avg_apr(self):
  95. return Num(sum([darkie.apr_scaled_to_runningtime() for darkie in self.darkies])/len(self.darkies))
  96. def avg_stake_ratio(self):
  97. return sum([darkie.staked_tokens_ratio() for darkie in self.darkies])/len(self.darkies)
  98. def write(self):
  99. elapsed=self.end_time-self.start_time
  100. for id, darkie in enumerate(self.darkies):
  101. darkie.write(id)
  102. if self.debug:
  103. print("total time: {}, slot time: {}".format(str(timedelta(seconds=elapsed)), str(timedelta(seconds=elapsed/self.running_time))))
  104. self.secondary_pid.write()
  105. with open('log/rewards.log', 'w+') as f:
  106. buff = ','.join([str(i) for i in self.rewards])
  107. f.write(buff)