clock.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. '''
  2. synchronized NTP clock
  3. '''
  4. import ntplib
  5. import time
  6. import math
  7. class SynchedNTPClock(object):
  8. def __init__(self, epoch_length, slot_length=180, ntp_server='europe.pool.ntp.org'):
  9. #TODO how long should be the slot length
  10. self.epoch_length=epoch_length # how many slots in a a block
  11. self.slot_length=slot_length
  12. self.ntp_server = ntp_server
  13. self.ntp_client = ntplib.NTPClient()
  14. #TODO validate the server
  15. # when was darkfi birthday? as seconds since the epoch
  16. self.darkfi_epoch=time.mktime(time.strptime("2022-01-01", "%Y-%m-%d"))
  17. self.offline_cnt=0
  18. def __repr__(self):
  19. return 'darkfi time: '+ time.ctime(self.darkfi_time) + ', current synched time: ' + ctime(self.synched_time)
  20. def __get_time_stat(self):
  21. response=None
  22. success=False
  23. while not success:
  24. try:
  25. response = self.ntp_client.request(self.ntp_server, version=3)
  26. success=True
  27. #except ntplib.NTPException as e:
  28. except:
  29. pass
  30. #print("connection failed: {}".format(e.what()))
  31. return response
  32. @property
  33. def synched_time(self):
  34. state = self.__get_time_stat()
  35. stime = state.tx_time
  36. return stime
  37. @property
  38. def darkfi_time(self):
  39. return self.synched_time - self.darkfi_epoch
  40. @property
  41. def offline_time(self):
  42. self.offline_cnt+=1
  43. return self.offline_cnt
  44. @property
  45. def slot(self):
  46. return math.floor(self.offline_time/self.slot_length)
  47. @property
  48. def epoch(self):
  49. return math.floor(self.slot/self.epoch_length)
  50. @property
  51. def epoch_slot(self):
  52. return self.slot%self.epoch_length