beacon.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. from ouroboros.clock import SynchedNTPClock
  2. from ouroboros.vrf import VRF
  3. from ouroboros.logger import Logger
  4. import threading
  5. import time
  6. '''
  7. \class TrustedBeacon
  8. the trusted beacon is decentralized, such that at the onset of the Epoch,
  9. the leader of the first slot generated the signed seed, and release the signature,
  10. proof, and base to the genesis block.
  11. #TODO implement trustedbeacon as a node
  12. '''
  13. class TrustedBeacon(SynchedNTPClock, threading.Thread):
  14. def __init__(self, node, vrf, epoch_length, genesis_time):
  15. self.epoch_length=epoch_length # how many slots in a a block
  16. SynchedNTPClock.__init__(self)
  17. threading.Thread.__init__(self)
  18. self.daemon=True
  19. self.node = node #stakeholder
  20. self.vrf = vrf
  21. self.current_slot = self.slot
  22. self.log = Logger(self, genesis_time)
  23. self.log.info(f"constructed for node {str(node)}")
  24. def __repr__(self):
  25. return f"trustedbeacon"
  26. def run(self):
  27. self.log.highlight("thread [start]")
  28. self.__background()
  29. self.log.info("thread [end]")
  30. def __background(self):
  31. current_epoch = self.slot
  32. self.log.info('background waiting for the onset of next synched epoch...')
  33. while True:
  34. if self.slot != current_epoch:
  35. current_epoch = self.slot
  36. self.__callback()
  37. def __callback(self):
  38. self.current_slot = self.slot
  39. if self.current_slot%self.epoch_length!=0:
  40. self.log.info(f"callback: new slot of idx: {self.current_slot}")
  41. y, pi = self.vrf.sign(self.current_slot)
  42. self.log.info(f"callback: signature calculated for {str(self.node)}")
  43. self.node.new_slot(self.current_slot, y, pi)
  44. else:
  45. sigmas = []
  46. proofs = []
  47. for i in range(self.epoch_length):
  48. self.log.info(f"callback: new slot of idx: {self.current_slot}, epoch slot {i}")
  49. y, pi = self.vrf.sign(self.current_slot)
  50. self.log.info(f"callback: signature calculated for {str(self.node)}")
  51. sigmas.append(y)
  52. proofs.append(pi)
  53. self.node.new_epoch(self.current_slot, sigmas, proofs)
  54. def verify(self, y, pi, pk_raw, g):
  55. return VRF.verify(self.current_slot, y, pi, pk_raw, g)