commit 18384d95b35b66f064306f8075048b7acfb79bd8
parent 8e3490c4d35014cfbfa5dd153bd60c20a68bb744
Author: lash <dev@holbrook.no>
Date: Sun, 16 Jun 2024 23:04:52 +0100
Factor out test setup, implement lmdb class
Diffstat:
7 files changed, 178 insertions(+), 45 deletions(-)
diff --git a/eth_cache/store/lmdb.py b/eth_cache/store/lmdb.py
@@ -0,0 +1,66 @@
+# standard imports
+import os
+import json
+import logging
+
+# external imports
+import lmdb
+from hexathon import strip_0x
+from chainlib.eth.tx import (
+ Tx,
+ pack,
+ )
+
+
+logg = logging.getLogger(__name__)
+
+default_base_dir = '/var/lib'
+
+
+def chain_dir_for(chain_spec, base_dir=default_base_dir):
+ chain_dir = os.path.join(base_dir, str(chain_spec).replace(':', '/'))
+ return os.path.join(chain_dir, 'eth_cache')
+
+
+class LmdbStore:
+
+ def __init__(self, chain_spec, cache_root=default_base_dir, address_rules=None):
+ # TODO: perhaps common for all
+ self.chain_spec = chain_spec
+ self.address_rules = address_rules
+ # TODO: perhaps common for all fs
+ self.chain_dir = chain_dir_for(chain_spec, cache_root)
+ self.cache_dir = self.chain_dir
+ os.makedirs(self.cache_dir, exist_ok=True)
+ self.block_src_path = os.path.join(self.cache_dir, 'block', 'src')
+ self.block_num_path = os.path.join(self.cache_dir, 'block', 'num')
+ self.block_hash_path = os.path.join(self.cache_dir, 'block', 'hash')
+ self.tx_path = os.path.join(self.cache_dir, 'tx', 'src')
+ self.tx_raw_path = os.path.join(self.cache_dir, 'tx', 'raw')
+ self.rcpt_path = os.path.join(self.cache_dir, 'rcpt', 'src')
+ self.rcpt_raw_path = os.path.join(self.cache_dir, 'rcpt', 'raw')
+ self.address_path = os.path.join(self.cache_dir, 'address')
+ self.db = lmdb.open(self.cache_dir, create=True)
+
+
+ def __to_path_key(self, path, k):
+ if path[len(path)-1] != '/':
+ path += '/'
+ return path.encode('utf-8') + k
+
+
+ def put_tx(self, tx, include_data=False):
+ raw = pack(tx.src, self.chain_spec)
+ tx_hash_dirnormal = strip_0x(tx.hash).upper()
+ tx_hash_bytes = bytes.fromhex(tx_hash_dirnormal)
+ k = self.__to_path_key('tx_raw', tx_hash_bytes)
+ with self.db.begin(write=True) as tx:
+ tx.put(k, raw)
+
+
+ def get_tx(self, tx_hash):
+ self.__to_path_key(self, path, key)
+
+
+ def __str__(self):
+ return 'RockDbStore: root {}'.format(self.cache_dir)
diff --git a/requirements.txt b/requirements.txt
@@ -1,4 +1,4 @@
hexathon~=0.1.7
jsonrpc-std~=0.1.0
leveldir~=0.3.0
-chainlib-eth~=0.6.0
+chainlib-eth~=0.6.3
diff --git a/setup.py b/setup.py
@@ -1,5 +1,5 @@
from setuptools import setup
-import configparser
+#import configparser
import os
diff --git a/test_requirements.txt b/test_requirements.txt
@@ -1,5 +1,6 @@
-eth_tester==0.5.0b3
-py-evm==0.3.0a20
-rlp==2.0.1
-pytest==6.0.1
+eth_tester==0.10.0b4
+py-evm==0.10.0b4
+rlp==3.0.0
+#pytest==6.0.1
coverage==5.5
+#setuptools==70.0.0
diff --git a/tests/test_basic.py b/tests/test_basic.py
@@ -6,64 +6,38 @@ import logging
import json
# external imports
-from chainlib.chain import ChainSpec
+from chainlib.eth.address import is_same_address
+from hexathon import strip_0x
+from chainlib.eth.nonce import RPCNonceOracle
from chainlib.eth.gas import (
Gas,
OverrideGasOracle,
)
-from chainlib.eth.nonce import RPCNonceOracle
-from chainlib.eth.unittest.ethtester import EthTesterCase
-from chainlib.eth.tx import (
- transaction,
- receipt,
- TxFormat,
- Tx,
- )
from chainlib.eth.block import (
block_by_hash,
block_by_number,
Block,
)
-from chainlib.eth.address import is_same_address
-from hexathon import strip_0x
-
+from chainlib.eth.tx import (
+ transaction,
+ Tx,
+ )
+
# local imports
from eth_cache.store.file import FileStore
from eth_cache.rpc import CacheRPC
+from tests.util import TestCache
+
logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
-class TestCache(EthTesterCase):
+class TestCacheBasic(TestCache):
def setUp(self):
- super(TestCache, self).setUp()
- fp = tempfile.mkdtemp()
- self.cache_dir = fp
-
- class Applier:
- def apply_rules_addresses(self, sender, recipient, address):
- return True
-
- self.store = FileStore(self.chain_spec, cache_root=self.cache_dir, address_rules=Applier())
- nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
- gas_oracle = OverrideGasOracle(price=100000000000, limit=30000)
- c = Gas(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
- (tx_hash, o) = c.create(self.accounts[0], self.accounts[1], 1024)
- r = self.rpc.do(o)
-
- o = transaction(tx_hash)
- tx_src = self.rpc.do(o)
-
- o = receipt(tx_hash)
- rcpt_src = self.rpc.do(o)
-
- o = block_by_hash(tx_src['block_hash'])
- block_src = self.rpc.do(o)
-
- self.block = Block(block_src)
- self.tx = Tx(tx_src, block=self.block, rcpt=rcpt_src)
+ super(TestCacheBasic, self).setUp()
+ self.store = FileStore(self.chain_spec, cache_root=self.cache_dir, address_rules=self.address_rules)
def tearDown(self):
diff --git a/tests/test_lmdb.py b/tests/test_lmdb.py
@@ -0,0 +1,24 @@
+# standard imports
+import unittest
+
+# local imports
+from eth_cache.store.lmdb import LmdbStore
+from tests.util import TestCache
+
+
+class TestCacheBasic(TestCache):
+
+ def setUp(self):
+ super(TestCacheBasic, self).setUp()
+ self.store = LmdbStore(self.chain_spec, cache_root=self.cache_dir, address_rules=self.address_rules)
+
+
+ def test_tx(self):
+ self.store.put_tx(self.tx, include_data=True)
+ #j = self.store.get_tx(self.tx.hash)
+ #tx = json.loads(j)
+ #self.assertTrue(is_same_address(tx['hash'], self.tx.hash))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/util.py b/tests/util.py
@@ -0,0 +1,68 @@
+# standard imports
+import tempfile
+import shutil
+import unittest
+
+# external imports
+from chainlib.chain import ChainSpec
+from chainlib.eth.gas import (
+ Gas,
+ OverrideGasOracle,
+ )
+from chainlib.eth.nonce import RPCNonceOracle
+from chainlib.eth.tx import (
+ transaction,
+ receipt,
+ TxFormat,
+ Tx,
+ )
+from chainlib.eth.block import (
+ block_by_hash,
+ Block,
+ )
+from chainlib.eth.dialect import DialectFilter as EthDialectFilter
+
+from chainlib.eth.unittest.ethtester import EthTesterCase
+
+# TODO: 2024-06-16 suddenly state_root value is binary, which breaks the json serializer. this seems to be a bug in the eth-tester, and this code should probably be moved to chainlib-eth unittest and implemented by default in test cases
+class DialectFilter(EthDialectFilter):
+
+ def apply_src(self, src, dialect_filter=None):
+
+ for k in src.keys():
+ if type(src[k]) == bytes:
+ src[k] = '0x' + src[k].hex()
+
+ return src
+
+
+class TestCache(EthTesterCase):
+
+ def setUp(self):
+ super(TestCache, self).setUp()
+ fp = tempfile.mkdtemp()
+ self.cache_dir = fp
+
+ class Applier:
+ def apply_rules_addresses(self, sender, recipient, address):
+ return True
+
+ self.address_rules = Applier()
+ nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
+ gas_oracle = OverrideGasOracle(price=100000000000, limit=30000)
+ c = Gas(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
+ (tx_hash, o) = c.create(self.accounts[0], self.accounts[1], 1024)
+ r = self.rpc.do(o)
+
+ o = transaction(tx_hash)
+ tx_src = self.rpc.do(o)
+
+ o = receipt(tx_hash)
+ rcpt_src = self.rpc.do(o)
+
+ o = block_by_hash(tx_src['block_hash'])
+ block_src = self.rpc.do(o)
+
+ fltr = DialectFilter()
+ self.block = Block(block_src, dialect_filter=fltr)
+ self.tx = Tx(tx_src, block=self.block, rcpt=rcpt_src, dialect_filter=fltr)