chainqueue

Blockchain transaction queue control
Info | Log | Files | Refs | LICENSE

state.py (4815B)


      1 # standard imports
      2 import logging
      3 
      4 # external imports
      5 import shep.persist
      6 
      7 logg = logging.getLogger(__name__)
      8 
      9 
     10 class Verify:
     11 
     12     def verify(self, state_store, key, from_state, to_state):
     13         to_state_name = state_store.name(to_state)
     14         m = None
     15         try:  
     16             m = getattr(self, to_state_name)
     17         except AttributeError:
     18             return None
     19 
     20         r = m(state_store, from_state)
     21         if r != None:
     22             from_state_name = state_store.name(from_state)
     23             r = '{} -> {}: {}'.format(from_state_name, to_state_name, r)
     24 
     25         return r
     26 
     27 
     28     def INSUFFICIENT_FUNDS(self, state_store, from_state):
     29         if from_state & state_store.FINAL:
     30             return 'already finalized'
     31         if from_state & state_store.IN_NETWORK:
     32             return 'already in network'
     33 
     34 
     35     def UNKNOWN_ERROR(self, state_store, from_state):
     36         if from_state & state_store.FINAL:
     37             return 'already finalized'
     38         if from_state & state_store.RESERVED:
     39             return 'not reserved'
     40         if from_state & state_store.mask_error:
     41             return 'already in error state'
     42 
     43 
     44     def NODE_ERROR(self, state_store, from_state):
     45         if from_state & state_store.FINAL:
     46             return 'already finalized'
     47         if from_state & state_store.IN_NETWORK:
     48             return 'already in network'
     49         if not from_state & state_store.RESERVED:
     50             return 'not reserved'
     51         if from_state & state_store.mask_error:
     52             return 'already in error state'
     53 
     54 
     55     def NETWORK_ERROR(self, state_store, from_state):
     56         if from_state & state_store.FINAL:
     57             return 'already finalized'
     58         if from_state & state_store.IN_NETWORK:
     59             return 'already in network'
     60 
     61 
     62     def OBSOLETE(self, state_store, from_state):
     63         if from_state & state_store.FINAL:
     64             return 'already finalized'
     65         if from_state & state_store.IN_NETWORK:
     66             return 'already in network'
     67         if from_state & state_store.OBSOLETE:
     68             return 'already obsolete'
     69 
     70     
     71     def MANUAL(self, state_store, from_state):
     72         if from_state & state_store.FINAL:
     73             return 'already finalized'
     74 
     75 
     76     def QUEUED(self, state_store, from_state):
     77         if from_state & state_store.FINAL:
     78             return 'already finalized'
     79         if from_state & state_store.IN_NETWORK:
     80             if not from_state & state_store.mask_error:
     81                 return 'not in error state'
     82         elif from_state & state_store.mask_error:
     83             return 'no first send on error state'
     84           
     85 
     86     def SENDFAIL(self, state_store, from_state):
     87         return self.NODE_ERROR(state_store, from_state)
     88 
     89 
     90     def FINAL(self, state_store, from_state):
     91         if from_state & state_store.FINAL:
     92             return 'already finalized'
     93 
     94 
     95     def _MINEFAIL(self, state_store, from_state):
     96         return self.NETWORK_ERROR(state_store, from_state)
     97 
     98 
     99     def _CANCEL(self, state_store, from_state):
    100         if from_state:
    101             if from_state & state_store.FINAL:
    102                 return 'already finalized'
    103             if not from_state & (state_store.OBSOLETE | state_store.IN_NETWORK):
    104                 return 'can only cancel state having OBSOLETE and/or IN_NETWORK'
    105 
    106 
    107 class Status(shep.persist.PersistedState):
    108 
    109     bits = 12
    110    
    111     def __init__(self, store_factory, allow_invalid=False, event_callback=None):
    112         verify = Verify().verify
    113         self.set_default_state('PENDING')
    114         super(Status, self).__init__(store_factory, self.bits, verifier=verify, check_alias=not allow_invalid, event_callback=event_callback)
    115         self.add('QUEUED')
    116         self.add('RESERVED')
    117         self.add('IN_NETWORK')
    118         self.add('DEFERRED')
    119         self.add('INSUFFICIENT_FUNDS')
    120         self.add('LOCAL_ERROR')
    121         self.add('NODE_ERROR')
    122         self.add('NETWORK_ERROR')
    123         self.add('UNKNOWN_ERROR')
    124         self.add('FINAL')
    125         self.add('OBSOLETE')
    126         self.add('MANUAL')
    127 
    128         self.alias('SENDFAIL', self.DEFERRED | self.LOCAL_ERROR)
    129         self.alias('RETRY', self.DEFERRED | self.QUEUED)
    130         self.alias('OBSOLETED', self.OBSOLETE | self.IN_NETWORK)
    131         self.alias('FUBAR', self.FINAL | self.UNKNOWN_ERROR)
    132         self.alias('CANCELLED', self.IN_NETWORK | self.FINAL | self.OBSOLETE)
    133         self.alias('OVERRIDDEN', self.FINAL | self.OBSOLETE | self.MANUAL)
    134         self.alias('REJECTED', self.NODE_ERROR | self.FINAL)
    135         self.alias('REVERTED', self.IN_NETWORK | self.FINAL | self.NETWORK_ERROR)
    136         self.alias('SUCCESS', self.IN_NETWORK | self.FINAL)
    137         self.alias('_MINEFAIL', self.FINAL | self.NETWORK_ERROR)
    138         self.alias('_CANCEL', self.FINAL | self.OBSOLETE)
    139 
    140         self.mask_error = self.LOCAL_ERROR | self.NODE_ERROR | self.NETWORK_ERROR | self.UNKNOWN_ERROR