chaind-eth

Queue server for ethereum
Log | Files | Refs | README | LICENSE

commit 1929050e97631b09382ffbf5d3334d8a3f93375e
parent 1b82cb31187069e0ea0930de28ab5858a55f1cd2
Author: nolash <dev@holbrook.no>
Date:   Fri, 16 Jul 2021 20:03:51 +0200

add missing files, make adapter test rely on chaintool alembic

Diffstat:
M.gitignore | 1+
Achaind_eth/chain.py | 18++++++++++++++++++
Mchaind_eth/runnable/server.py | 14+++++++++-----
Mchaind_eth/runnable/syncer.py | 12++++++------
Mchainqueue/adapters/eth.py | 16+++-------------
Mrequirements.txt | 1+
Atests/chaind_eth_base.py | 22++++++++++++++++++++++
Atests/test_adapter.py | 45+++++++++++++++++++++++++++++++++++++++++++++
Atests/test_helo.py | 15+++++++++++++++
9 files changed, 120 insertions(+), 24 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -4,3 +4,4 @@ gmon.out dist/ build/ *.egg-info +*.sqlite diff --git a/chaind_eth/chain.py b/chaind_eth/chain.py @@ -0,0 +1,18 @@ +# external imports +from chainlib.interface import ChainInterface +from chainlib.eth.block import ( + block_by_number, + Block, + ) +from chainlib.eth.tx import ( + receipt, + Tx, + ) + +class EthChainInterface(ChainInterface): + + def __init__(self): + self._block_by_number = block_by_number + self._block_from_src = Block.from_src + self._tx_receipt = receipt + self._src_normalize = Tx.src_normalize diff --git a/chaind_eth/runnable/server.py b/chaind_eth/runnable/server.py @@ -16,6 +16,7 @@ from hexathon import strip_0x from chainlib.chain import ChainSpec from chainlib.eth.connection import EthHTTPConnection from chainqueue.sql.backend import SQLBackend +from chainlib.error import JSONRPCException from chainqueue.db import dsn_from_config # local imports @@ -167,12 +168,15 @@ def main(): logg.debug('recv {} bytes'.format(len(data))) session = backend.create_session() - r = adapter.add(chain_spec, data, session) try: - r = srvs.send(r.to_bytes(4, byteorder='big')) - logg.debug('{} bytes sent'.format(r)) - except BrokenPipeError: - logg.debug('they just hung up. how rude.') + r = adapter.add(data, chain_spec, session=session) + try: + r = srvs.send(r.to_bytes(4, byteorder='big')) + logg.debug('{} bytes sent'.format(r)) + except BrokenPipeError: + logg.debug('they just hung up. how rude.') + except ValueError as e: + logg.error('invalid input: {}'.format(e)) session.close() srvs.close() diff --git a/chaind_eth/runnable/syncer.py b/chaind_eth/runnable/syncer.py @@ -16,10 +16,8 @@ from hexathon import strip_0x from chainlib.chain import ChainSpec from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.block import block_latest -from chainsyncer.driver import ( - HeadSyncer, - HistorySyncer, - ) +from chainsyncer.driver.head import HeadSyncer +from chainsyncer.driver.history import HistorySyncer from chainsyncer.db import dsn_from_config from chainsyncer.db.models.base import SessionBase from chainsyncer.backend.sql import SQLBackend @@ -27,6 +25,7 @@ from chainsyncer.error import SyncDone # local imports from chaind_eth.filter import StateFilter +from chaind_eth.chain import EthChainInterface logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() @@ -113,11 +112,12 @@ def main(): for syncer_backend in syncer_backends: logg.info('resuming sync session {}'.format(syncer_backend)) + chain_interface = EthChainInterface() for syncer_backend in syncer_backends: - syncers.append(HistorySyncer(syncer_backend)) + syncers.append(HistorySyncer(syncer_backend, chain_interface)) syncer_backend = SQLBackend.live(chain_spec, block_offset+1) - syncers.append(HeadSyncer(syncer_backend)) + syncers.append(HeadSyncer(syncer_backend, chain_interface)) state_filter = StateFilter(chain_spec) filters = [ diff --git a/chainqueue/adapters/eth.py b/chainqueue/adapters/eth.py @@ -11,12 +11,11 @@ from hexathon import ( # local imports from chainqueue.adapters.base import Adapter -from chainqueue.enum import StatusBits class EthAdapter(Adapter): - def translate(self, bytecode, chain_spec): + def translate(self, chain_spec, bytecode): tx = unpack(bytecode, chain_spec) tx['source_token'] = ZERO_ADDRESS tx['destination_token'] = ZERO_ADDRESS @@ -25,8 +24,8 @@ class EthAdapter(Adapter): return tx - def add(self, chain_spec, bytecode, session): - tx = self.translate(bytecode, chain_spec) + def add(self, chain_spec, bytecode, session=None): + tx = self.translate(chain_spec, bytecode) r = self.backend.create(chain_spec, tx['nonce'], tx['from'], tx['hash'], add_0x(bytecode.hex()), session=session) if r: session.rollback() @@ -42,12 +41,3 @@ class EthAdapter(Adapter): # r = self.backend.create(chain_spec, tx['nonce'], tx['from'], tx['hash'], add_0x(bytecode.hex()), session=session) # session.close() - - def upcoming(self, chain_spec, session): - return self.backend.get(chain_spec, StatusBits.QUEUED, unpack) # possible maldesign, up-stack should use our session? - - - def dispatch(self, chain_spec, rpc, tx_hash, signed_tx, session): - o = raw(signed_tx) - r = self.backend.dispatch(chain_spec, rpc, tx_hash, o) - return r diff --git a/requirements.txt b/requirements.txt @@ -1,2 +1,3 @@ chaind<=0.0.1,>=0.0.1a3 hexathon~=0.0.1a7 +chainlib-eth<=0.0.5,>0.0.4 diff --git a/tests/chaind_eth_base.py b/tests/chaind_eth_base.py @@ -0,0 +1,22 @@ +# standard imports +import unittest + +# external imports +from chainsyncer.unittest.db import ChainSyncerDb +from chainqueue.unittest.db import ChainQueueDb + + +class TestBase(unittest.TestCase): + + def setUp(self): + self.db_chainsyncer = ChainSyncerDb() + self.session_chainsyncer = self.db_chainsyncer.bind_session() + + self.db_chainqueue = ChainQueueDb() + self.session_chainqueue = self.db_chainqueue.bind_session() + + def tearDown(self): + self.session_chainsyncer.commit() + self.db_chainsyncer.release_session(self.session_chainsyncer) + self.session_chainqueue.commit() + self.db_chainqueue.release_session(self.session_chainqueue) diff --git a/tests/test_adapter.py b/tests/test_adapter.py @@ -0,0 +1,45 @@ +# stanndard imports +import logging +import unittest +import os + +# external imports +from chainqueue.sql.backend import SQLBackend +from chainlib.chain import ChainSpec +from chainqueue.unittest.db import ( + db_config, + dsn_from_config, + ) + +# local imports +from chainqueue.adapters.eth import EthAdapter + +# test imports +from tests.chaind_eth_base import TestBase + +logging.basicConfig(level=logging.DEBUG) + + +class TestAdapter(TestBase): + + example_tx = bytes.fromhex('f8640183989680825208948311ad69b3429400ab795d45af85d204f73329ae8204d38026a097a7fd66548e4c116270b547ac7ed8cb531b0b97f80d49b45986144e47dbe44da07cc4345741dc0fabf65a473c0d3a1536cd501961f7e01b07dd8e107ff87d1556') + dsn = dsn_from_config(db_config) + + def setUp(self): + super(TestAdapter, self).setUp() + self.chain_spec = ChainSpec.from_chain_str('foo:bar:1:baz') + self.backend = SQLBackend(self.dsn, debug=bool(os.environ.get('DATABASE_DEBUG'))) + self.adapter = EthAdapter(self.backend) + + + def test_eth_adapter_translate(self): + self.adapter.translate(self.chain_spec, self.example_tx) + # succesful decode means translate is working, no further checks needed + + + def test_eth_adapter_add(self): + self.adapter.add(self.chain_spec, self.example_tx, session=self.session_chainqueue) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_helo.py b/tests/test_helo.py @@ -0,0 +1,15 @@ +# standard imports +import unittest + +# test imports +from tests.chaind_eth_base import TestBase + + +class TestHelo(TestBase): + + def test_helo(self): + pass + + +if __name__ == '__main__': + unittest.main()