Skip to content
This repository has been archived by the owner on Jul 1, 2021. It is now read-only.

Commit

Permalink
Use hashable datastructures
Browse files Browse the repository at this point in the history
  • Loading branch information
jannikluhn committed Dec 16, 2019
1 parent 5b99e33 commit 4c9231b
Show file tree
Hide file tree
Showing 81 changed files with 1,045 additions and 999 deletions.
2 changes: 1 addition & 1 deletion eth2/beacon/attestation_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def validate_indexed_attestation(
f" but have {len(attesting_indices)} validators."
)

if attesting_indices != tuple(sorted(attesting_indices)):
if list(attesting_indices) != sorted(attesting_indices):
raise ValidationError(
f"Indices should be sorted; the attesting indices are not: {attesting_indices}."
)
Expand Down
10 changes: 6 additions & 4 deletions eth2/beacon/deposit_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def process_deposit(
# needs to be done here because while the deposit contract will never
# create an invalid Merkle branch, it may admit an invalid deposit
# object, and we need to be able to skip over it
state = state.copy(eth1_deposit_index=state.eth1_deposit_index + 1)
state = state.set("eth1_deposit_index", state.eth1_deposit_index + 1)

pubkey = deposit.data.pubkey
amount = deposit.data.amount
Expand All @@ -72,9 +72,11 @@ def process_deposit(
pubkey, withdrawal_credentials, amount, config
)

return state.copy(
validators=state.validators + (validator,),
balances=state.balances + (amount,),
return state.mset(
"validators",
state.validators.append(validator),
"balances",
state.balances.append(amount),
)
else:
index = ValidatorIndex(validator_pubkeys.index(pubkey))
Expand Down
20 changes: 6 additions & 14 deletions eth2/beacon/epoch_processing_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from eth2._utils.bitfield import Bitfield, has_voted
from eth2._utils.numeric import integer_squareroot
from eth2._utils.tuple import update_tuple_item_with_fn
from eth2.beacon.committee_helpers import get_beacon_committee
from eth2.beacon.constants import BASE_REWARDS_PER_EPOCH
from eth2.beacon.exceptions import InvalidEpochError
Expand All @@ -25,22 +24,15 @@
def increase_balance(
state: BeaconState, index: ValidatorIndex, delta: Gwei
) -> BeaconState:
return state.copy(
balances=update_tuple_item_with_fn(
state.balances, index, lambda balance, *_: Gwei(balance + delta)
)
)
return state.transform(("balances", index), lambda balance: Gwei(balance + delta))


def decrease_balance(
state: BeaconState, index: ValidatorIndex, delta: Gwei
) -> BeaconState:
return state.copy(
balances=update_tuple_item_with_fn(
state.balances,
index,
lambda balance, *_: Gwei(0) if delta > balance else Gwei(balance - delta),
)
return state.transform(
("balances", index),
lambda balance: Gwei(0) if delta > balance else Gwei(balance - delta),
)


Expand All @@ -51,7 +43,7 @@ def get_attesting_indices(
config: CommitteeConfig,
) -> Set[ValidatorIndex]:
"""
Return the sorted attesting indices corresponding to ``attestation_data`` and ``bitfield``.
Return the attesting indices corresponding to ``attestation_data`` and ``bitfield``.
"""
committee = get_beacon_committee(
state, attestation_data.slot, attestation_data.index, config
Expand All @@ -66,7 +58,7 @@ def get_indexed_attestation(
state, attestation.data, attestation.aggregation_bits, config
)

return IndexedAttestation(
return IndexedAttestation.create(
attesting_indices=sorted(attesting_indices),
data=attestation.data,
signature=attestation.signature,
Expand Down
47 changes: 28 additions & 19 deletions eth2/beacon/genesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
from eth_typing import Hash32
import ssz

from eth2.beacon.constants import DEPOSIT_CONTRACT_TREE_DEPTH, SECONDS_PER_DAY
from eth2.beacon.constants import (
DEPOSIT_CONTRACT_TREE_DEPTH,
SECONDS_PER_DAY,
ZERO_HASH32,
ZERO_SIGNING_ROOT,
)
from eth2.beacon.deposit_helpers import process_deposit
from eth2.beacon.helpers import get_active_validator_indices
from eth2.beacon.types.block_headers import BeaconBlockHeader
Expand All @@ -13,15 +18,15 @@
from eth2.beacon.types.eth1_data import Eth1Data
from eth2.beacon.types.states import BeaconState
from eth2.beacon.types.validators import calculate_effective_balance
from eth2.beacon.typing import Timestamp, ValidatorIndex
from eth2.beacon.typing import Gwei, Timestamp, ValidatorIndex
from eth2.beacon.validator_status_helpers import activate_validator
from eth2.configs import Eth2Config


def is_genesis_trigger(
deposits: Sequence[Deposit], timestamp: int, config: Eth2Config
) -> bool:
state = BeaconState(config=config)
state = BeaconState.create(config=config)

for deposit in deposits:
state = process_deposit(state, deposit, config)
Expand All @@ -47,27 +52,28 @@ def initialize_beacon_state_from_eth1(
deposits: Sequence[Deposit],
config: Eth2Config
) -> BeaconState:
state = BeaconState(
state = BeaconState.create(
genesis_time=_genesis_time_from_eth1_timestamp(eth1_timestamp),
eth1_data=Eth1Data(block_hash=eth1_block_hash, deposit_count=len(deposits)),
latest_block_header=BeaconBlockHeader(
body_root=BeaconBlockBody().hash_tree_root
eth1_data=Eth1Data.create(
block_hash=eth1_block_hash, deposit_count=len(deposits)
),
latest_block_header=BeaconBlockHeader.create(
body_root=BeaconBlockBody.create().hash_tree_root
),
block_roots=(ZERO_SIGNING_ROOT,) * config.SLOTS_PER_HISTORICAL_ROOT,
state_roots=(ZERO_HASH32,) * config.SLOTS_PER_HISTORICAL_ROOT,
randao_mixes=(eth1_block_hash,) * config.EPOCHS_PER_HISTORICAL_VECTOR,
slashings=(Gwei(0),) * config.EPOCHS_PER_SLASHINGS_VECTOR,
config=config,
)

# Process genesis deposits
for index, deposit in enumerate(deposits):
deposit_data_list = tuple(deposit.data for deposit in deposits[: index + 1])
state = state.copy(
eth1_data=state.eth1_data.copy(
deposit_root=ssz.get_hash_tree_root(
deposit_data_list,
ssz.List(DepositData, 2 ** DEPOSIT_CONTRACT_TREE_DEPTH),
)
)
deposit_root = ssz.get_hash_tree_root(
deposit_data_list, ssz.List(DepositData, 2 ** DEPOSIT_CONTRACT_TREE_DEPTH)
)
state = state.transform(("eth1_data", "deposit_root"), deposit_root)
state = process_deposit(state=state, deposit=deposit, config=config)

# Process genesis activations
Expand All @@ -76,13 +82,16 @@ def initialize_beacon_state_from_eth1(
balance = state.balances[validator_index]
effective_balance = calculate_effective_balance(balance, config)

state = state.update_validator_with_fn(
validator_index, lambda v, *_: v.copy(effective_balance=effective_balance)
state = state.transform(
("validators", validator_index, "effective_balance"), effective_balance
)

if effective_balance == config.MAX_EFFECTIVE_BALANCE:
state = state.update_validator_with_fn(
validator_index, activate_validator, config.GENESIS_EPOCH
activated_validator = activate_validator(
state.validators[validator_index], config.GENESIS_EPOCH
)
state = state.transform(
("validators", validator_index), activated_validator
)

return state
Expand All @@ -104,4 +113,4 @@ def is_valid_genesis_state(state: BeaconState, config: Eth2Config) -> bool:
def get_genesis_block(
genesis_state_root: Hash32, block_class: Type[BaseBeaconBlock]
) -> BaseBeaconBlock:
return block_class(state_root=genesis_state_root)
return block_class.create(state_root=genesis_state_root)
2 changes: 1 addition & 1 deletion eth2/beacon/state_machines/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,6 @@ def import_block(
state, block=block, check_proposer_signature=check_proposer_signature
)

block = block.copy(state_root=state.hash_tree_root)
block = block.set("state_root", state.hash_tree_root)

return state, block
20 changes: 9 additions & 11 deletions eth2/beacon/state_machines/forks/serenity/block_processing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from eth2._utils.hash import hash_eth2
from eth2._utils.numeric import bitwise_xor
from eth2._utils.tuple import update_tuple_item
from eth2.beacon.committee_helpers import get_beacon_proposer_index
from eth2.beacon.helpers import get_randao_mix
from eth2.beacon.state_machines.forks.serenity.block_validation import (
Expand Down Expand Up @@ -35,14 +34,15 @@ def process_block_header(
state, block, committee_config=CommitteeConfig(config)
)

return state.copy(
latest_block_header=BeaconBlockHeader(
return state.set(
"latest_block_header",
BeaconBlockHeader.create(
slot=block.slot,
parent_root=block.parent_root,
# `state_root` is zeroed and overwritten in the next `process_slot` call
body_root=block.body.hash_tree_root,
# `signature` is zeroed
)
),
)


Expand Down Expand Up @@ -73,19 +73,15 @@ def process_randao(
hash_eth2(block.body.randao_reveal),
)

return state.copy(
randao_mixes=update_tuple_item(
state.randao_mixes, randao_mix_index, new_randao_mix
)
)
return state.transform(("randao_mixes", randao_mix_index), new_randao_mix)


def process_eth1_data(
state: BeaconState, block: BaseBeaconBlock, config: Eth2Config
) -> BeaconState:
body = block.body

new_eth1_data_votes = state.eth1_data_votes + (body.eth1_data,)
new_eth1_data_votes = state.eth1_data_votes.append(body.eth1_data)

new_eth1_data = state.eth1_data
if (
Expand All @@ -94,7 +90,9 @@ def process_eth1_data(
):
new_eth1_data = body.eth1_data

return state.copy(eth1_data=new_eth1_data, eth1_data_votes=new_eth1_data_votes)
return state.mset(
"eth1_data", new_eth1_data, "eth1_data_votes", new_eth1_data_votes
)


def process_block(
Expand Down
Loading

0 comments on commit 4c9231b

Please sign in to comment.