diff --git a/boa/util/leveldb.py b/boa/util/leveldb.py new file mode 100644 index 00000000..0e744cbe --- /dev/null +++ b/boa/util/leveldb.py @@ -0,0 +1,32 @@ +# copy py-evm LevelDB implementation, removed in +# https://github.com/ethereum/py-evm/commit/c2ca44a1212a287 +import plyvel +from eth.db.backends.base import BaseDB + + +class LevelDB(BaseDB): + # Creates db as a class variable to avoid level db lock error + def __init__(self, db_path, max_open_files: int = None) -> None: + self.db = plyvel.DB( + db_path, + create_if_missing=True, + error_if_exists=False, + max_open_files=max_open_files, + ) + + def __getitem__(self, key: bytes) -> bytes: + v = self.db.get(key) + if v is None: + raise KeyError(key) + return v + + def __setitem__(self, key: bytes, value: bytes) -> None: + self.db.put(key, value) + + def _exists(self, key: bytes) -> bool: + return self.db.get(key) is not None + + def __delitem__(self, key: bytes) -> None: + if self.db.get(key) is None: + raise KeyError(key) + self.db.delete(key) diff --git a/boa/vm/fork.py b/boa/vm/fork.py index 3da9e15c..51b59c0e 100644 --- a/boa/vm/fork.py +++ b/boa/vm/fork.py @@ -9,6 +9,7 @@ import rlp from eth.db.account import AccountDB, keccak from eth.db.backends.memory import MemoryDB +from eth.db.cache import CacheDB from eth.rlp.accounts import Account from eth.vm.interrupt import MissingBytecode from eth_utils import int_to_big_endian, to_checksum_address @@ -33,9 +34,7 @@ def __init__(self, url: str, cache_file: str = DEFAULT_CACHE_DIR): self._init_mem_db() if cache_file is not None: try: - # LevelDB has been removed from py-evm 0.8.1 onwards - from eth.db.backends.level import LevelDB - from eth.db.cache import CacheDB + from boa.util.leveldb import LevelDB cache_file = os.path.expanduser(cache_file) # use CacheDB as an additional layer over disk