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

Add get_merkle_root #1689

Merged
merged 4 commits into from
Jan 8, 2019
Merged

Add get_merkle_root #1689

merged 4 commits into from
Jan 8, 2019

Conversation

hwwhww
Copy link
Contributor

@hwwhww hwwhww commented Dec 31, 2018

What was wrong?

Replace #1674
Fix #1673
It's #1674 without get_updated_merkle_accumulator

How was it fixed?

  • Refactor eth._utils.merkle APIs
  • Add get_merkle_root

Cute Animal Picture

earless seal

@hwwhww hwwhww added the eth2.0 label Dec 31, 2018
from eth_typing import Hash32
from eth_hash.auto import keccak


def hash_eth2(data: bytes) -> Hash32:
def hash_eth2(data: Hashable) -> Hash32:
Copy link
Contributor

Choose a reason for hiding this comment

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

I might miss some historical discussion. But is Hashable what we want here?
According to typing documentation, Hashable is an alias to collections.abc.Hashable, which checks if an object has the abstract method __hash__. That is in the sense of Python hash rather then if a Serializable object could be hash_eth2-ed or tree-hashed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ohh I changed it to Hashable just for resolving the lint error with merkle utils.
eth_hash.auto.keccak takes Union[bytes, bytearray] as input. Could we just replace Hashable with Union[bytes, bytearray]? Ping @jannikluhn to confirm it. 🙏

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree to Hashable --> Union[bytes, bytearray] (even though bytearray doesn't seem to be used in py-evm much, so just bytes might be fine too).

n_layers,
iterate(_hash_layer, leaves),
)
)[::-1]
Copy link
Member

Choose a reason for hiding this comment

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

IIUC this is reversing the iterable. I think reversed(...) reads a lot more naturally.

@djrtwo
Copy link
Contributor

djrtwo commented Jan 7, 2019

In what context do we expect to use get_merkle_root vs calc_merkle_root?

@hwwhww
Copy link
Contributor Author

hwwhww commented Jan 7, 2019

@djrtwo this module was written for proof of custody a long time ago. calc_merkle_root was the old one, and get_merkle_root is what we need for the beacon chain spec.

  • calc_merkle_root(items):
    • takes "items" - the items before being hashed
    • does a leaves = tuple(hash_eth2(item) for item in items) ( in calc_merkle_tree).
  • get_merkle_root:
    • takes "leaves" - the hashed items
    • merkleizes these leaves. In our case, leaves is latest_block_roots.

Not sure if we will need calc_merkle_root in the future...

@djrtwo
Copy link
Contributor

djrtwo commented Jan 7, 2019

Right. So do we want to leave both in for now?
The naming and functionality are very similar and might cause confusion.

That said, I'm not too opposed to leaving in the old function..


leaves = tuple(keccak(item) for item in items)
tree = cast(MerkleTree, tuple(take(n_layers, iterate(_hash_layer, leaves)))[::-1])
tree = cast(
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't have to use cast here, MerkleTree(tuple(...)) works as well (and mypy can check that the argument has the right type).

MerkleTree,
tuple(
reversed(
tuple(
Copy link
Contributor

Choose a reason for hiding this comment

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

This expression is getting quite long. Can we maybe split it up, e.g.:

reversed_tree = tuple(take(n_layers, iterate(_hash_layer, leaves)))
return MerkleTree(tuple(reversed(reversed_tree)))

@hwwhww
Copy link
Contributor Author

hwwhww commented Jan 8, 2019

@djrtwo
I renamed calc_merkle_root to get_merkle_root_from_items for distingushing. I think it's okay to leave it, for now.

@jannikluhn
Oh, just found that we missed tests/core/test_blob_utils.py in master branch (https://github.com/jannikluhn/py-evm/blob/048f0df597b56ae0af47df661e3572dcd02b1571/tests/core/test_blob_utils.py).

Copy link
Contributor

@djrtwo djrtwo left a comment

Choose a reason for hiding this comment

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

lgtm

@hwwhww hwwhww merged commit ee8f72d into ethereum:master Jan 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add get_merkle_root
5 participants