time.py (2979B)
1 # standard imports 2 import datetime 3 import logging 4 5 # external imports 6 from chainlib.eth.tx import TxFormat 7 8 # local imports 9 from evm_booking import Booking 10 11 logg = logging.getLogger(__name__) 12 13 PERIOD_HALFHOUR = 60*30 14 PERIOD_HOUR = PERIOD_HALFHOUR * 2 15 PERIOD_DAY = PERIOD_HOUR * 24 16 PERIOD_YEAR = PERIOD_DAY * 365 17 PERIOD_LEAPYEAR = PERIOD_YEAR + PERIOD_DAY 18 19 20 class TimeBooking(Booking): 21 22 def __init__(self, chain_spec, period_seconds, resolution_seconds, start_seconds=None, signer=None, gas_oracle=None, nonce_oracle=None): 23 super(TimeBooking, self).__init__(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) 24 if period_seconds % resolution_seconds > 0: 25 raise ValueError("period must be evenly divided in resolution") 26 self.start = None 27 self.end = None 28 duration = period_seconds * resolution_seconds 29 if start_seconds != None: 30 self.start = datetime.datetime.fromtimestamp(start_seconds) 31 self.end = self.start + datetime.timedelta(seconds=duration + 1) 32 self.unit = resolution_seconds 33 self.capacity_units = int(period_seconds / resolution_seconds) 34 35 36 def constructor(self, sender_address, token_address, tx_format=TxFormat.JSONRPC, version=None): 37 return super(TimeBooking, self).constructor(sender_address, token_address, self.capacity_units, self.end, tx_format=tx_format, version=version) 38 39 40 def share_date(self, contract_address, sender_address, start_date, count, ref_date=None, tx_format=TxFormat.JSONRPC, id_generator=None): 41 offset = self.offset_from_date(start_date, count, ref_date=ref_date) 42 return super(TimeBooking, self).share(contract_address, sender_address, offset, count) 43 44 45 def consume_date(self, contract_address, sender_address, start_date, count, ref_date=None, tx_format=TxFormat.JSONRPC, id_generator=None): 46 offset = self.offset_from_date(start_date, count, ref_date=ref_date) 47 return super(TimeBooking, self).consume(contract_address, sender_address, offset, count) 48 49 50 def offset_from_date(self, start_date, count, ref_date=None): 51 if ref_date == None: 52 ref_date = self.start 53 if ref_date == None: 54 raise AttributeError('no reference start date exists') 55 56 duration = datetime.timedelta(seconds=count*self.unit) 57 end_seconds = self.capacity_units * self.unit 58 end_date = ref_date + datetime.timedelta(seconds=end_seconds) 59 target_date = start_date + duration 60 if target_date > end_date: 61 raise ValueError('duration results in {} which is beyond end date {}'.format(target_date, end_date)) 62 63 delta = start_date - ref_date 64 if delta.seconds % self.unit > 0: 65 raise ValueError('start date must be evenly divide into unit of {} seconds'.format(self.unit)) 66 offset = (delta.days * 24*60*60) / self.unit 67 offset += int(delta.seconds / self.unit) 68 return offset