evm-booking

EVM smart contract for ERC20 backed time slot booking
Info | Log | Files | Refs | README

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