Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Piper/remove multi trie support #617

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/api.state.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ configured.
- ``block_class``: The `~evm.rlp.blocks.Block` class for blocks in this VM ruleset.
- ``computation_class``: The `~evm.vm.computation.BaseComputation` class for vm
execution.
- ``trie_class``: The class that is used to house the state trie.
- ``transaction_context_class``: The
`~evm.vm.transaction_context.TransactionContext` class for vm execution.

Expand Down
3 changes: 2 additions & 1 deletion evm/chains/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
check_pow,
)
from evm.constants import (
BLANK_ROOT_HASH,
MAX_UNCLE_DEPTH,
)
from evm.db.chain import AsyncChainDB
Expand Down Expand Up @@ -436,7 +437,7 @@ def from_genesis(cls,
"""
Initializes the Chain from a genesis state.
"""
state_db = chaindb.get_state_db(chaindb.empty_root_hash, read_only=False)
state_db = chaindb.get_state_db(BLANK_ROOT_HASH, read_only=False)

if genesis_state is None:
genesis_state = {}
Expand Down
40 changes: 7 additions & 33 deletions evm/db/chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@
Tuple,
Type,
TYPE_CHECKING,
Union
)

import rlp

from trie import (
BinaryTrie,
HexaryTrie,
)

Expand All @@ -31,8 +29,6 @@

from evm.constants import (
GENESIS_PARENT_HASH,
BLANK_ROOT_HASH,
EMPTY_SHA3,
)
from evm.exceptions import (
BlockNotFound,
Expand Down Expand Up @@ -88,36 +84,14 @@ class TransactionKey(rlp.Serializable):


class BaseChainDB(metaclass=ABCMeta):
trie_class = None
empty_root_hash = None

#
# Trie
#
def set_trie(self, trie_class: Union[Type[HexaryTrie], Type[BinaryTrie]]) -> None:
"""
Sets trie_class and root_hash.
"""
if trie_class is HexaryTrie:
empty_root_hash = BLANK_ROOT_HASH
elif trie_class is BinaryTrie:
empty_root_hash = EMPTY_SHA3
else:
raise NotImplementedError(
"trie_class {} is not supported.".format(trie_class)
)
self.trie_class = trie_class
self.empty_root_hash = empty_root_hash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The root hash code feels like unnecessary inspection on the trie class details, so I'm happy to see that go. Maybe we can push the blank root hash responsibility into the trie class. IIRC, the class already keeps track of what a blank hash is anyway.

Anyway, I guess that's only relevant when we bring back configurable trie classes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this stuff is implemented in the wrong place so....

the cost of keeping the configurable tries around might be higher than the cost of adding them back in later

I think this is accurate.


def __init__(self,
db: BaseDB,
account_state_class: Type[BaseAccountDB] = AccountDB,
trie_class: Type[HexaryTrie] = HexaryTrie) -> None:
db: BaseDB) -> None:

self.db = db
self.journal_db = JournalDB(db)
self.account_state_class = account_state_class
self.set_trie(trie_class)

#
# Canonical chain API
Expand Down Expand Up @@ -454,7 +428,7 @@ def get_block_uncles(self, uncles_hash: bytes) -> List[BlockHeader]:
#
@to_list
def get_receipts(self, header: BlockHeader, receipt_class: Type[Receipt]) -> Iterable[Receipt]:
receipt_db = self.trie_class(db=self.db, root_hash=header.receipt_root)
receipt_db = HexaryTrie(db=self.db, root_hash=header.receipt_root)
for receipt_idx in itertools.count():
receipt_key = rlp.encode(receipt_idx)
if receipt_key in receipt_db:
Expand All @@ -467,7 +441,7 @@ def _get_block_transaction_data(self, transaction_root: bytes) -> Iterable[bytes
'''
:returns: iterable of encoded transactions for the given block header
'''
transaction_db = self.trie_class(self.db, root_hash=transaction_root)
transaction_db = HexaryTrie(self.db, root_hash=transaction_root)
for transaction_idx in itertools.count():
transaction_key = rlp.encode(transaction_idx)
if transaction_key in transaction_db:
Expand Down Expand Up @@ -504,7 +478,7 @@ def get_transaction_by_index(
block_header = self.get_canonical_block_header_by_number(block_number)
except KeyError:
raise TransactionNotFound("Block {} is not in the canonical chain".format(block_number))
transaction_db = self.trie_class(self.db, root_hash=block_header.transaction_root)
transaction_db = HexaryTrie(self.db, root_hash=block_header.transaction_root)
encoded_index = rlp.encode(transaction_index)
if encoded_index in transaction_db:
encoded_transaction = transaction_db[encoded_index]
Expand Down Expand Up @@ -547,12 +521,12 @@ def add_transaction(self,
block_header: BlockHeader,
index_key: int,
transaction: 'BaseTransaction') -> bytes:
transaction_db = self.trie_class(self.db, root_hash=block_header.transaction_root)
transaction_db = HexaryTrie(self.db, root_hash=block_header.transaction_root)
transaction_db[index_key] = rlp.encode(transaction)
return transaction_db.root_hash

def add_receipt(self, block_header: BlockHeader, index_key: int, receipt: Receipt) -> bytes:
receipt_db = self.trie_class(db=self.db, root_hash=block_header.receipt_root)
receipt_db = HexaryTrie(db=self.db, root_hash=block_header.receipt_root)
receipt_db[index_key] = rlp.encode(receipt)
return receipt_db.root_hash

Expand All @@ -575,7 +549,7 @@ def persist_trie_data_dict(self, trie_data_dict: Dict[bytes, bytes]) -> None:
def get_state_db(self,
state_root: bytes,
read_only: bool) -> BaseAccountDB:
return self.account_state_class(
return AccountDB(
db=self.journal_db,
root_hash=state_root,
read_only=read_only,
Expand Down
27 changes: 0 additions & 27 deletions evm/utils/db.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
from trie import (
BinaryTrie,
HexaryTrie,
)

from evm.constants import (
BLANK_ROOT_HASH,
EMPTY_SHA3,
)

from evm.rlp.headers import BlockHeader

from typing import TYPE_CHECKING
Expand Down Expand Up @@ -43,23 +33,6 @@ def get_block_header_by_hash(block_hash: BlockHeader, db: 'BaseChainDB') -> Bloc
return db.get_block_header_by_hash(block_hash)


def get_empty_root_hash(db: 'BaseChainDB') -> bytes:
root_hash = None
if db.trie_class is HexaryTrie:
root_hash = BLANK_ROOT_HASH
elif db.trie_class is BinaryTrie:
root_hash = EMPTY_SHA3
elif db.trie_class is None:
raise AttributeError(
"BaseChainDB must declare a trie_class."
)
else:
raise NotImplementedError(
"db.trie_class {} is not supported.".format(db.trie_class)
)
return root_hash


def apply_state_dict(account_db, state_dict):
for account, account_data in state_dict.items():
account_db.set_balance(account, account_data["balance"])
Expand Down
5 changes: 0 additions & 5 deletions evm/vm/forks/frontier/state.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
from __future__ import absolute_import
from typing import Type # noqa: F401

from trie import (
HexaryTrie,
)

from eth_hash.auto import keccak

from evm import constants
Expand Down Expand Up @@ -215,7 +211,6 @@ def _make_frontier_receipt(state, transaction, computation):
class FrontierState(BaseState, FrontierTransactionExecutor):
block_class = FrontierBlock
computation_class = FrontierComputation
trie_class = HexaryTrie
transaction_context_class = FrontierTransactionContext # type: Type[BaseTransactionContext]

def make_receipt(self, transaction, computation):
Expand Down
1 change: 0 additions & 1 deletion evm/vm/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class BaseState(Configurable, metaclass=ABCMeta):

block_class = None # type: Type[BaseBlock]
computation_class = None # type: Type[BaseComputation]
trie_class = None
transaction_context_class = None # type: Type[BaseTransactionContext]

def __init__(self, chaindb, execution_context, state_root, gas_used):
Expand Down
30 changes: 8 additions & 22 deletions tests/database/test_chaindb.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@
)

import rlp
from trie import (
BinaryTrie,
HexaryTrie,
)

from eth_hash.auto import keccak

from evm.constants import (
BLANK_ROOT_HASH,
)
from evm.db import (
get_db_backend,
)
from evm.db.chain import (
ChainDB,
)
from evm.db.account import (
AccountDB,
)
from evm.exceptions import (
BlockNotFound,
ParentNotFound,
Expand All @@ -33,7 +29,6 @@
assert_rlp_equal,
)
from evm.utils.db import (
get_empty_root_hash,
make_block_hash_to_score_lookup_key,
make_block_number_to_hash_lookup_key,
)
Expand All @@ -50,25 +45,16 @@


def set_empty_root(chaindb, header):
root_hash = get_empty_root_hash(chaindb)
return header.copy(
transaction_root=root_hash,
receipt_root=root_hash,
state_root=root_hash,
transaction_root=BLANK_ROOT_HASH,
receipt_root=BLANK_ROOT_HASH,
state_root=BLANK_ROOT_HASH,
)


@pytest.fixture(params=[AccountDB])
@pytest.fixture
def chaindb(request):
if request.param is AccountDB:
trie_class = HexaryTrie
else:
trie_class = BinaryTrie
return ChainDB(
get_db_backend(),
account_state_class=request.param,
trie_class=trie_class,
)
return ChainDB(get_db_backend())


@pytest.fixture(params=[0, 10, 999])
Expand Down
15 changes: 1 addition & 14 deletions tests/json-fixtures/test_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@

from eth_keys import keys

from trie import (
HexaryTrie,
)

from evm.db import (
get_db_backend,
)
Expand All @@ -20,9 +16,6 @@
from eth_hash.auto import keccak

from evm.db.chain import ChainDB
from evm.db.account import (
AccountDB,
)
from evm.exceptions import (
ValidationError,
)
Expand Down Expand Up @@ -266,8 +259,6 @@ def fixture_vm_class(fixture_data):


def test_state_fixtures(fixture, fixture_vm_class):
account_state_class = AccountDB
trie_class = HexaryTrie
header = BlockHeader(
coinbase=fixture['env']['currentCoinbase'],
difficulty=fixture['env']['currentDifficulty'],
Expand All @@ -277,11 +268,7 @@ def test_state_fixtures(fixture, fixture_vm_class):
parent_hash=fixture['env']['previousHash'],
)

chaindb = ChainDB(
get_db_backend(),
account_state_class=account_state_class,
trie_class=trie_class
)
chaindb = ChainDB(get_db_backend())
vm = fixture_vm_class(header=header, chaindb=chaindb)

state = vm.state
Expand Down