diff --git a/eth2/_utils/merkle/sparse.py b/eth2/_utils/merkle/sparse.py index f8b3e85d94..e4b75d2984 100644 --- a/eth2/_utils/merkle/sparse.py +++ b/eth2/_utils/merkle/sparse.py @@ -11,7 +11,8 @@ TYPE_CHECKING, ) -from cytoolz import ( +from eth_utils.toolz import ( + cons, iterate, take, ) @@ -86,7 +87,7 @@ def calc_merkle_tree_from_leaves(leaves: Sequence[Hash32]) -> MerkleTree: 0, tuple(tree[0]) + (EmptyNodeHashes[i],), ) - tree = (_hash_layer(tree[0]),) + tree + tree = tuple(cons(_hash_layer(tree[0]), tree)) return MerkleTree(tree) diff --git a/eth2/beacon/_utils/random.py b/eth2/beacon/_utils/random.py index 3a2022bfa4..b2258ef3ac 100644 --- a/eth2/beacon/_utils/random.py +++ b/eth2/beacon/_utils/random.py @@ -10,7 +10,6 @@ Hash32, ) from eth_utils import ( - to_tuple, ValidationError, ) @@ -66,10 +65,17 @@ def get_permuted_index(index: int, return new_index -@to_tuple def shuffle(values: Sequence[TItem], seed: Hash32, - shuffle_round_count: int) -> Iterable[TItem]: + shuffle_round_count: int) -> Tuple[TItem, ...]: + # This uses this *sub-function* to get around this `eth-utils` bug + # https://github.com/ethereum/eth-utils/issues/152 + return tuple(_shuffle(values, seed, shuffle_round_count)) + + +def _shuffle(values: Sequence[TItem], + seed: Hash32, + shuffle_round_count: int) -> Iterable[TItem]: """ Return shuffled indices in a pseudorandom permutation `0...list_size-1` with ``seed`` as entropy. @@ -114,7 +120,7 @@ def shuffle(values: Sequence[TItem], yield values[i] -def split(values: Sequence[TItem], split_count: int) -> Tuple[Iterable[TItem], ...]: +def split(values: Sequence[TItem], split_count: int) -> Tuple[Sequence[TItem], ...]: """ Return the split ``values`` in ``split_count`` pieces in protocol. Spec: https://github.com/ethereum/eth2.0-specs/blob/70cef14a08de70e7bd0455d75cf380eb69694bfb/specs/core/0_beacon-chain.md#helper-functions # noqa: E501 diff --git a/eth2/beacon/committee_helpers.py b/eth2/beacon/committee_helpers.py index 2e2430d945..19433cb133 100644 --- a/eth2/beacon/committee_helpers.py +++ b/eth2/beacon/committee_helpers.py @@ -74,7 +74,7 @@ def get_shuffling(*, seed: Hash32, validators: Sequence['ValidatorRecord'], epoch: Epoch, - committee_config: CommitteeConfig) -> Tuple[Iterable[ValidatorIndex], ...]: + committee_config: CommitteeConfig) -> Tuple[Sequence[ValidatorIndex], ...]: """ Shuffle ``validators`` into crosslink committees seeded by ``seed`` and ``epoch``. Return a list of ``committee_per_epoch`` committees where each @@ -285,7 +285,7 @@ def get_crosslink_committees_at_slot( state: 'BeaconState', slot: Slot, committee_config: CommitteeConfig, - registry_change: bool=False) -> Iterable[Tuple[Iterable[ValidatorIndex], Shard]]: + registry_change: bool=False) -> Iterable[Tuple[Sequence[ValidatorIndex], Shard]]: """ Return the list of ``(committee, shard)`` tuples for the ``slot``. """ diff --git a/eth2/beacon/epoch_processing_helpers.py b/eth2/beacon/epoch_processing_helpers.py index 3f934b0a31..71bf254ff3 100644 --- a/eth2/beacon/epoch_processing_helpers.py +++ b/eth2/beacon/epoch_processing_helpers.py @@ -164,7 +164,7 @@ def get_attesting_indices(state: 'BeaconState', def _get_epoch_boundary_attesting_indices(state: 'BeaconState', attestations: Sequence[PendingAttestationRecord], epoch: Epoch, - config: Eth2Config) -> Tuple[ValidatorIndex]: + config: Eth2Config) -> Tuple[ValidatorIndex, ...]: target_root = get_block_root( state, get_epoch_start_slot( @@ -198,7 +198,7 @@ def get_epoch_boundary_attesting_balance(state: 'BeaconState', def get_total_balance_from_effective_balances( effective_balances: Dict[ValidatorIndex, Gwei], - validator_indices: Set[ValidatorIndex]) -> Gwei: + validator_indices: Sequence[ValidatorIndex]) -> Gwei: return Gwei( sum( effective_balances[index] diff --git a/eth2/beacon/state_machines/forks/serenity/epoch_processing.py b/eth2/beacon/state_machines/forks/serenity/epoch_processing.py index 8322f5e9b0..b2c62ec69d 100644 --- a/eth2/beacon/state_machines/forks/serenity/epoch_processing.py +++ b/eth2/beacon/state_machines/forks/serenity/epoch_processing.py @@ -4,7 +4,6 @@ Dict, Iterable, Sequence, - Set, Tuple, ) @@ -350,11 +349,11 @@ def _update_rewards_or_penalies( def _compute_normal_justification_and_finalization_deltas( state: BeaconState, config: Eth2Config, - previous_epoch_active_validator_indices: Set[ValidatorIndex], + previous_epoch_active_validator_indices: Sequence[ValidatorIndex], previous_total_balance: Gwei, - previous_epoch_attester_indices: Set[ValidatorIndex], - previous_epoch_boundary_attester_indices: Set[ValidatorIndex], - previous_epoch_head_attester_indices: Set[ValidatorIndex], + previous_epoch_attester_indices: Sequence[ValidatorIndex], + previous_epoch_boundary_attester_indices: Sequence[ValidatorIndex], + previous_epoch_head_attester_indices: Sequence[ValidatorIndex], inclusion_infos: Dict[ValidatorIndex, InclusionInfo], effective_balances: Dict[ValidatorIndex, Gwei], base_rewards: Dict[ValidatorIndex, Gwei]) -> Tuple[Dict[ValidatorIndex, Gwei], Dict[ValidatorIndex, Gwei]]: # noqa: E501 @@ -448,10 +447,10 @@ def _compute_normal_justification_and_finalization_deltas( def _compute_inactivity_leak_deltas( state: BeaconState, config: Eth2Config, - previous_epoch_active_validator_indices: Set[ValidatorIndex], - previous_epoch_attester_indices: Set[ValidatorIndex], - previous_epoch_boundary_attester_indices: Set[ValidatorIndex], - previous_epoch_head_attester_indices: Set[ValidatorIndex], + previous_epoch_active_validator_indices: Sequence[ValidatorIndex], + previous_epoch_attester_indices: Sequence[ValidatorIndex], + previous_epoch_boundary_attester_indices: Sequence[ValidatorIndex], + previous_epoch_head_attester_indices: Sequence[ValidatorIndex], inclusion_infos: Dict[ValidatorIndex, InclusionInfo], effective_balances: Dict[ValidatorIndex, Gwei], base_rewards: Dict[ValidatorIndex, Gwei], @@ -527,10 +526,10 @@ def _compute_inactivity_leak_deltas( def _process_rewards_and_penalties_for_finality( state: BeaconState, config: Eth2Config, - previous_epoch_active_validator_indices: Set[ValidatorIndex], + previous_epoch_active_validator_indices: Sequence[ValidatorIndex], previous_total_balance: Gwei, previous_epoch_attestations: Sequence[Attestation], - previous_epoch_attester_indices: Set[ValidatorIndex], + previous_epoch_attester_indices: Sequence[ValidatorIndex], inclusion_infos: Dict[ValidatorIndex, InclusionInfo], effective_balances: Dict[ValidatorIndex, Gwei], base_rewards: Dict[ValidatorIndex, Gwei]) -> Tuple[Dict[ValidatorIndex, Gwei], Dict[ValidatorIndex, Gwei]]: # noqa: E501 diff --git a/eth2/beacon/tools/builder/validator.py b/eth2/beacon/tools/builder/validator.py index 89e2623602..f81259ad4e 100644 --- a/eth2/beacon/tools/builder/validator.py +++ b/eth2/beacon/tools/builder/validator.py @@ -668,6 +668,6 @@ def get_committee_assignment( registry_change=registry_change, ) - return CommitteeAssignment(validators, shard, Slot(slot), is_proposer) + return CommitteeAssignment(tuple(validators), shard, Slot(slot), is_proposer) raise NoCommitteeAssignment diff --git a/p2p/discovery.py b/p2p/discovery.py index 0d35f140c9..9c7ffef23e 100644 --- a/p2p/discovery.py +++ b/p2p/discovery.py @@ -1198,7 +1198,7 @@ def __repr__(self) -> str: @to_list def _extract_nodes_from_payload( sender: kademlia.Address, - payload: List[Tuple[str, str, str, bytes]], + payload: List[Tuple[str, bytes, bytes, bytes]], logger: ExtendedDebugLogger) -> Iterator[kademlia.Node]: for item in payload: ip, udp_port, tcp_port, node_id = item diff --git a/p2p/kademlia.py b/p2p/kademlia.py index bd9b36be73..7f92a351bf 100644 --- a/p2p/kademlia.py +++ b/p2p/kademlia.py @@ -90,7 +90,7 @@ def to_endpoint(self) -> List[bytes]: return [self._ip.packed, enc_port(self.udp_port), enc_port(self.tcp_port)] @classmethod - def from_endpoint(cls, ip: str, udp_port: str, tcp_port: str = '\x00\x00') -> 'Address': + def from_endpoint(cls, ip: str, udp_port: bytes, tcp_port: bytes = b'\x00\x00') -> 'Address': return cls(ip, big_endian_to_int(udp_port), big_endian_to_int(tcp_port)) diff --git a/setup.py b/setup.py index a8d6519f44..2674fb6daf 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ "bloom-filter==1.3", "cachetools>=2.1.0,<3.0.0", "coincurve>=10.0.0,<11.0.0", - "eth-utils>=1.3.0,<2", + "eth-utils>=1.5.1,<2", "ipython>=6.2.1,<7.0.0", "plyvel==1.0.5", "py-evm==0.2.0a42", diff --git a/trinity/_utils/chains.py b/trinity/_utils/chains.py index 9e937ffa4a..c1e6285de8 100644 --- a/trinity/_utils/chains.py +++ b/trinity/_utils/chains.py @@ -2,20 +2,28 @@ import os from pathlib import Path from typing import ( + cast, + Any, + Dict, Iterable, + Optional, Tuple, Union, ) +from mypy_extensions import ( + TypedDict, +) + from eth_utils import ( decode_hex, - to_dict, ) from eth_keys import keys from eth_keys.datatypes import PrivateKey from p2p.constants import DEFAULT_MAX_PEERS +from p2p.kademlia import Node as KademliaNode from trinity.constants import ( MAINNET_NETWORK_ID, @@ -109,9 +117,33 @@ def load_nodekey(nodekey_path: Path) -> PrivateKey: return nodekey -@to_dict +class TrinityConfigParams(TypedDict): + network_id: int + use_discv5: bool + + trinity_root_dir: Optional[str] + + genesis_config: Optional[Dict[str, Any]] + + data_dir: Optional[str] + + nodekey_path: Optional[str] + nodekey: Optional[PrivateKey] + + max_peers: Optional[int] + + port: Optional[int] + + preferred_nodes: Optional[Tuple[KademliaNode, ...]] + + def construct_trinity_config_params( - args: argparse.Namespace) -> Iterable[Tuple[str, Union[int, str, Tuple[str, ...]]]]: + args: argparse.Namespace) -> TrinityConfigParams: + return cast(TrinityConfigParams, dict(_construct_trinity_config_params(args))) + + +def _construct_trinity_config_params( + args: argparse.Namespace) -> Iterable[Tuple[str, Union[int, str, bytes, Tuple[str, ...]]]]: """ Helper function for constructing the kwargs to initialize a TrinityConfig object. """ diff --git a/trinity/_utils/eip1085.py b/trinity/_utils/eip1085.py index 68c399a3d2..28f154c6c8 100644 --- a/trinity/_utils/eip1085.py +++ b/trinity/_utils/eip1085.py @@ -213,9 +213,9 @@ def extract_genesis_params(genesis_config: RawEIP1085Dict) -> GenesisParams: return GenesisParams( nonce=decode_hex(raw_params['nonce']), difficulty=to_int(hexstr=raw_params['difficulty']), - extra_data=decode_hex(raw_params['extraData']), + extra_data=Hash32(decode_hex(raw_params['extraData'])), gas_limit=to_int(hexstr=raw_params['gasLimit']), - coinbase=decode_hex(raw_params['author']), + coinbase=Address(decode_hex(raw_params['author'])), timestamp=to_int(hexstr=raw_params['timestamp']), ) diff --git a/trinity/plugins/builtin/json_rpc/plugin.py b/trinity/plugins/builtin/json_rpc/plugin.py index 56fcc7663d..47ea7ae195 100644 --- a/trinity/plugins/builtin/json_rpc/plugin.py +++ b/trinity/plugins/builtin/json_rpc/plugin.py @@ -30,10 +30,9 @@ RPCServer, ) from trinity.rpc.modules import ( - BeaconChainRPCModule, + BaseRPCModule, initialize_beacon_modules, initialize_eth1_modules, - Eth1ChainRPCModule, ) from trinity.rpc.ipc import ( IPCServer, @@ -60,7 +59,7 @@ def configure_parser(self, arg_parser: ArgumentParser, subparser: _SubParsersAct help="Disables the JSON-RPC Server", ) - def setup_eth1_modules(self, trinity_config: TrinityConfig) -> Tuple[Eth1ChainRPCModule, ...]: + def setup_eth1_modules(self, trinity_config: TrinityConfig) -> Tuple[BaseRPCModule, ...]: db_manager = create_db_consumer_manager(trinity_config.database_ipc_path) eth1_app_config = trinity_config.get_app_config(Eth1AppConfig) @@ -80,7 +79,7 @@ def setup_eth1_modules(self, trinity_config: TrinityConfig) -> Tuple[Eth1ChainRP return initialize_eth1_modules(chain, self.event_bus) - def setup_beacon_modules(self) -> Tuple[BeaconChainRPCModule, ...]: + def setup_beacon_modules(self) -> Tuple[BaseRPCModule, ...]: return initialize_beacon_modules(None, self.event_bus) diff --git a/trinity/protocol/bcc/validators.py b/trinity/protocol/bcc/validators.py index cad3d7a13b..63b08bacb9 100644 --- a/trinity/protocol/bcc/validators.py +++ b/trinity/protocol/bcc/validators.py @@ -1,4 +1,5 @@ from typing import ( + cast, Tuple, Union, ) @@ -58,8 +59,9 @@ def _validate_first_block(self, blocks: Tuple[BaseBeaconBlock, ...]) -> None: ) else: if first_block.signed_root != self.block_slot_or_hash: + block_hash = cast(Hash32, self.block_slot_or_hash) raise ValidationError( - f"Requested blocks starting with hash {encode_hex(self.block_slot_or_hash)} " + f"Requested blocks starting with hash {encode_hex(block_hash)} " f"but first returned block has hash {encode_hex(first_block.signed_root)}" ) diff --git a/trinity/protocol/common/validators.py b/trinity/protocol/common/validators.py index 7fb021795e..074e1a8be4 100644 --- a/trinity/protocol/common/validators.py +++ b/trinity/protocol/common/validators.py @@ -9,6 +9,7 @@ from eth.rlp.headers import BlockHeader from eth_typing import ( + Hash32, BlockIdentifier, BlockNumber, ) @@ -61,12 +62,13 @@ def validate_result(self, response: Tuple[BlockHeader, ...]) -> None: # An empty response is always valid return elif not self._is_numbered: + block_hash = cast(Hash32, self.block_number_or_hash) first_header = response[0] - if first_header.hash != self.block_number_or_hash: + if first_header.hash != block_hash: raise ValidationError( "Returned headers cannot be matched to header request. " "Expected first header to have hash of " - f"{encode_hex(self.block_number_or_hash)} but instead got " + f"{encode_hex(block_hash)} but instead got " f"{encode_hex(first_header.hash)}." )