blockchain.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import math
  2. from ouroboros.logger import Logger
  3. '''
  4. Non-forkable Blockchain for simplicity
  5. #TODO implement forkable chain
  6. '''
  7. class Blockchain(object):
  8. def __init__(self, R, genesis_time):
  9. self.blocks = []
  10. self.log = Logger(self, genesis_time)
  11. self.R = R # how many slots in single epoch
  12. self.epochs = []
  13. @property
  14. def epoch_length(self):
  15. return self.R
  16. def __repr__(self):
  17. buff=''
  18. for e in range(len(self.epochs)):
  19. for b in range(len(e)):
  20. buff+=str(b)+'\n'
  21. return buff
  22. '''
  23. @return: epoch reference
  24. '''
  25. def __getitem__(self, i):
  26. e_idx = math.floor(i/self.epoch_length)
  27. e_blk_idx = i%self.epoch_length
  28. return self.epochs[e_idx][e_blk_idx]
  29. '''
  30. @return: number of blocks
  31. '''
  32. def __len__(self):
  33. return len(self.epochs*self.epoch_length)
  34. '''
  35. def __add_block(self, block):
  36. self.blocks.append(block)
  37. def add_epoch(self, epoch):
  38. assert epoch!=None, 'epoch cant be None'
  39. assert len(epoch)>0 , 'epoch cant be zero-sized'
  40. for idx, block in enumerate(epoch):
  41. if not block.empty:
  42. self.__add_block(block)
  43. else:
  44. self.log.warn(f"an empty block at index of index: {block.index},\nrelative slot:{idx}\nabsolute slot: {self.length*idx+block.slot}")
  45. '''
  46. def append(self, epoch):
  47. assert epoch!=None, 'epoch cant be None'
  48. assert len(epoch)>0 , 'epoch cant be zero-sized'
  49. assert len(epoch)==self.epoch_length
  50. self.append(epoch)