process.py (3076B)
1 # standard imports 2 import logging 3 4 # external imports 5 from chaind.error import TxSourceError 6 from chainlib.eth.address import ( 7 is_checksum_address, 8 to_checksum_address, 9 ) 10 from chainlib.eth.tx import unpack 11 from chainlib.eth.gas import Gas 12 from hexathon import ( 13 add_0x, 14 strip_0x, 15 ) 16 from funga.eth.transaction import EIP155Transaction 17 18 logg = logging.getLogger(__name__) 19 20 21 class Processor: 22 23 def __init__(self, resolver, source, use_checksum=True): 24 self.resolver = resolver 25 self.source = source 26 self.processor = [] 27 self.safe = use_checksum 28 self.conn = None 29 30 31 def add_processor(self, processor): 32 self.processor.append(processor) 33 34 35 def load(self, conn, process=True): 36 self.conn = conn 37 for processor in self.processor: 38 self.content = processor.load(self.source) 39 if self.content != None: 40 if process: 41 try: 42 self.process() 43 except Exception as e: 44 raise TxSourceError('invalid source contents: {}'.format(str(e))) 45 return self.content 46 raise TxSourceError('unparseable source') 47 48 49 # 0: recipient 50 # 1: amount 51 # 2: token identifier (optional, when not specified network gas token will be used) 52 # 3: gas amount (optional) 53 def process(self): 54 txs = [] 55 for i, r in enumerate(self.content): 56 logg.debug('processing {}'.format(r)) 57 address = r[0] 58 if self.safe: 59 if not is_checksum_address(address): 60 raise ValueError('invalid checksum address {} in record {}'.format(address, i)) 61 else: 62 address = to_checksum_address(address) 63 64 self.content[i][0] = add_0x(address) 65 try: 66 self.content[i][1] = int(r[1]) 67 except ValueError: 68 self.content[i][1] = int(strip_0x(r[1]), 16) 69 native_token_value = 0 70 71 if len(self.content[i]) == 3: 72 self.content[i].append(native_token_value) 73 74 75 def __iter__(self): 76 self.resolver.reset() 77 self.cursor = 0 78 return self 79 80 81 def __next__(self): 82 if self.cursor == len(self.content): 83 raise StopIteration() 84 85 r = self.content[self.cursor] 86 87 value = r[1] 88 gas_value = 0 89 try: 90 gas_value = r[3] 91 except IndexError: 92 pass 93 logg.debug('gasvalue {}'.format(gas_value)) 94 data = '0x' 95 96 executable_address = None 97 try: 98 executable_address = r[2] 99 except IndexError: 100 pass 101 102 tx = self.resolver.create(self.conn, r[0], gas_value, data=data, token_value=value, executable_address=executable_address) 103 v = self.resolver.sign(tx) 104 105 self.cursor += 1 106 107 return v 108 109 110 def __str__(self): 111 names = [] 112 for s in self.processor: 113 names.append(str(s)) 114 return ','.join(names)