diff --git a/cic_syncer/client/block.py b/cic_syncer/client/block.py new file mode 100644 index 0000000..06cbfb3 --- /dev/null +++ b/cic_syncer/client/block.py @@ -0,0 +1,16 @@ +class Block: + + def __init__(self, hsh, obj): + self.hash = hsh + self.obj = obj + + + def tx(self, idx): + return NotImplementedError + + + def number(self): + return NotImplementedError + + + diff --git a/cic_syncer/client/evm/__pycache__/response.cpython-38.pyc b/cic_syncer/client/evm/__pycache__/response.cpython-38.pyc index 0813207..59f7df3 100644 Binary files a/cic_syncer/client/evm/__pycache__/response.cpython-38.pyc and b/cic_syncer/client/evm/__pycache__/response.cpython-38.pyc differ diff --git a/cic_syncer/client/evm/__pycache__/websocket.cpython-38.pyc b/cic_syncer/client/evm/__pycache__/websocket.cpython-38.pyc index 289ec78..58a6efe 100644 Binary files a/cic_syncer/client/evm/__pycache__/websocket.cpython-38.pyc and b/cic_syncer/client/evm/__pycache__/websocket.cpython-38.pyc differ diff --git a/cic_syncer/client/evm/response.py b/cic_syncer/client/evm/response.py index 0d4e72c..c53933c 100644 --- a/cic_syncer/client/evm/response.py +++ b/cic_syncer/client/evm/response.py @@ -1,11 +1,14 @@ import json from cic_syncer.client import translate +from cic_syncer.client.block import Block +from cic_syncer.client.tx import Tx translations = { 'block_number': translate.hex_to_int, 'get_block': json.dumps, + 'number': translate.hex_to_int, } @@ -22,4 +25,24 @@ class EVMResponse: def get_result(self): - return self.fn(self.response_object.get('result')) + r = self.fn(self.response_object.get('result')) + if r == 'null': + return None + return r + + +class EVMTx(Tx): + + def __init__(self, block, tx_number, obj): + super(EVMTx, self).__init__(block, tx_number, obj) + + +class EVMBlock(Block): + + def tx(self, idx): + o = self.obj['transactions'][idx] + return Tx(self, idx, o) + + + def number(self): + return translate.hex_to_int(self.obj['number']) diff --git a/cic_syncer/client/evm/websocket.py b/cic_syncer/client/evm/websocket.py index 5b81282..8feadde 100644 --- a/cic_syncer/client/evm/websocket.py +++ b/cic_syncer/client/evm/websocket.py @@ -6,6 +6,8 @@ import websocket from .response import EVMResponse from cic_syncer.error import RequestError +from cic_syncer.client.translate import with_0x +from cic_syncer.client.evm.response import EVMBlock logg = logging.getLogger() @@ -55,5 +57,31 @@ class EVMWebsocketClient: if err != None: raise RequestError(err) - return res.get_result() + j = res.get_result() + if j == None: + return None + o = json.loads(j) + return EVMBlock(o['hash'], o) + + def get_block_by_hash(self, hx_in): + req_id = str(uuid.uuid4()) + hx = with_0x(hx_in) + req ={ + 'jsonrpc': '2.0', + 'method': 'eth_getBlockByHash', + 'id': str(req_id), + 'params': [hx, False], + } + self.conn.send(json.dumps(req)) + r = self.conn.recv() + res = EVMResponse('get_block', json.loads(r)) + err = res.get_error() + if err != None: + raise RequestError(err) + + j = res.get_result() + if j == None: + return None + o = json.loads(j) + return EVMBlock(o['hash'], o) diff --git a/cic_syncer/client/translate.py b/cic_syncer/client/translate.py index ad35fb4..4331afd 100644 --- a/cic_syncer/client/translate.py +++ b/cic_syncer/client/translate.py @@ -15,6 +15,12 @@ def strip_0x(hx): return is_hex(hx) +def with_0x(hx): + if len(hx) >= 2 and hx[:2] == '0x': + hx = hx[2:] + return '0x' + is_hex(hx) + + def hex_to_int(hx, endianness='big'): hx = strip_0x(hx) b = bytes.fromhex(hx) diff --git a/cic_syncer/client/tx.py b/cic_syncer/client/tx.py new file mode 100644 index 0000000..594491a --- /dev/null +++ b/cic_syncer/client/tx.py @@ -0,0 +1,6 @@ +class Tx: + + def __init__(self, block, tx_number, obj): + self.block = block + self.tx_number = tx_number + self.obj = obj diff --git a/cic_syncer/driver.py b/cic_syncer/driver.py index 6e5fb88..c2d0460 100644 --- a/cic_syncer/driver.py +++ b/cic_syncer/driver.py @@ -35,7 +35,9 @@ class MinedSyncer(Syncer): def loop(self, interval, getter): while self.running and Syncer.running_global: - e = self.get(getter) + block_hash = self.get(getter) + if block_hash != None: + self.process(getter, block_hash) time.sleep(interval) @@ -45,12 +47,30 @@ class HeadSyncer(MinedSyncer): super(HeadSyncer, self).__init__(backend) + def process(self, getter, block): + logg.debug('process block {}'.format(block)) + block = getter.get_block_by_hash(block.hash) + i = 0 + tx = None + while True: + try: + tx = block.tx(i) + logg.debug('tx {}'.format(tx)) + self.backend.set(block.number(), i) + for f in self.filter: + f(getter, block, tx) + except IndexError as e: + self.backend.set(block.number() + 1, 0) + break + i += 1 + + def get(self, getter): (block_number, tx_number) = self.backend.get() block_hash = [] uu = uuid.uuid4() res = getter.get_block_by_integer(block_number) - logg.debug(res) + logg.debug('get {}'.format(res)) - return block_hash + return res