Skip to content

Commit

Permalink
Merge pull request #1241 from ethereum/rename_misc
Browse files Browse the repository at this point in the history
Renaming of functions in the `Misc` section
  • Loading branch information
djrtwo authored Jul 1, 2019
2 parents c79f93f + b08d1d8 commit 155158f
Show file tree
Hide file tree
Showing 16 changed files with 118 additions and 108 deletions.
2 changes: 1 addition & 1 deletion scripts/build_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def apply_constants_preset(preset: Dict[str, Any]) -> None:
global_vars[k] = v
# Deal with derived constants
global_vars['GENESIS_EPOCH'] = slot_to_epoch(GENESIS_SLOT)
global_vars['GENESIS_EPOCH'] = compute_epoch_of_slot(GENESIS_SLOT)
# Initialize SSZ types again, to account for changed lengths
init_SSZ_types()
Expand Down
126 changes: 67 additions & 59 deletions specs/core/0_beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@
- [`is_active_validator`](#is_active_validator)
- [`is_slashable_validator`](#is_slashable_validator)
- [`is_slashable_attestation_data`](#is_slashable_attestation_data)
- [`is_valid_indexed_attestation`](#is_valid_indexed_attestation)
- [`is_valid_merkle_branch`](#is_valid_merkle_branch)
- [Misc](#misc-1)
- [`shuffle_index`](#shuffle_index)
- [`compute_shuffled_index`](#compute_shuffled_index)
- [`compute_committee`](#compute_committee)
- [`validate_indexed_attestation`](#validate_indexed_attestation)
- [`slot_to_epoch`](#slot_to_epoch)
- [`epoch_start_slot`](#epoch_start_slot)
- [`compute_epoch_of_slot`](#compute_epoch_of_slot)
- [`compute_start_slot_of_epoch`](#compute_start_slot_of_epoch)
- [`compute_activation_exit_epoch`](#compute_activation_exit_epoch)
- [`bls_domain`](#bls_domain)
- [`compute_domain`](#compute_domain)
- [Beacon state accessors](#beacon-state-accessors)
- [`get_current_epoch`](#get_current_epoch)
- [`get_previous_epoch`](#get_previous_epoch)
Expand Down Expand Up @@ -645,6 +645,45 @@ def is_slashable_attestation_data(data_1: AttestationData, data_2: AttestationDa
)
```

#### `is_valid_indexed_attestation`

```python
def is_valid_indexed_attestation(state: BeaconState, indexed_attestation: IndexedAttestation) -> bool:
"""
Verify validity of ``indexed_attestation``.
"""
bit_0_indices = indexed_attestation.custody_bit_0_indices
bit_1_indices = indexed_attestation.custody_bit_1_indices

# Verify no index has custody bit equal to 1 [to be removed in phase 1]
if not len(bit_1_indices) == 0:
return False
# Verify max number of indices
if not len(bit_0_indices) + len(bit_1_indices) <= MAX_VALIDATORS_PER_COMMITTEE:
return False
# Verify index sets are disjoint
if not len(set(bit_0_indices).intersection(bit_1_indices)) == 0:
return False
# Verify indices are sorted
if not (bit_0_indices == sorted(bit_0_indices) and bit_1_indices == sorted(bit_1_indices)):
return False
# Verify aggregate signature
if not bls_verify_multiple(
pubkeys=[
bls_aggregate_pubkeys([state.validators[i].pubkey for i in bit_0_indices]),
bls_aggregate_pubkeys([state.validators[i].pubkey for i in bit_1_indices]),
],
message_hashes=[
hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b0)),
hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b1)),
],
signature=indexed_attestation.signature,
domain=get_domain(state, DOMAIN_ATTESTATION, indexed_attestation.data.target.epoch),
):
return False
return True
```

#### `is_valid_merkle_branch`

```python
Expand All @@ -663,10 +702,10 @@ def is_valid_merkle_branch(leaf: Hash, branch: Sequence[Hash], depth: uint64, in

### Misc

#### `shuffle_index`
#### `compute_shuffled_index`

```python
def shuffle_index(index: ValidatorIndex, index_count: uint64, seed: Hash) -> ValidatorIndex:
def compute_shuffled_index(index: ValidatorIndex, index_count: uint64, seed: Hash) -> ValidatorIndex:
"""
Return the shuffled validator index corresponding to ``seed`` (and ``index_count``).
"""
Expand Down Expand Up @@ -699,56 +738,23 @@ def compute_committee(indices: Sequence[ValidatorIndex],
"""
start = (len(indices) * index) // count
end = (len(indices) * (index + 1)) // count
return [indices[shuffle_index(ValidatorIndex(i), len(indices), seed)] for i in range(start, end)]
```

#### `validate_indexed_attestation`

```python
def validate_indexed_attestation(state: BeaconState, indexed_attestation: IndexedAttestation) -> None:
"""
Verify validity of ``indexed_attestation``.
"""
bit_0_indices = indexed_attestation.custody_bit_0_indices
bit_1_indices = indexed_attestation.custody_bit_1_indices

# Verify no index has custody bit equal to 1 [to be removed in phase 1]
assert len(bit_1_indices) == 0
# Verify max number of indices
assert len(bit_0_indices) + len(bit_1_indices) <= MAX_VALIDATORS_PER_COMMITTEE
# Verify index sets are disjoint
assert len(set(bit_0_indices).intersection(bit_1_indices)) == 0
# Verify indices are sorted
assert bit_0_indices == sorted(bit_0_indices) and bit_1_indices == sorted(bit_1_indices)
# Verify aggregate signature
assert bls_verify_multiple(
pubkeys=[
bls_aggregate_pubkeys([state.validators[i].pubkey for i in bit_0_indices]),
bls_aggregate_pubkeys([state.validators[i].pubkey for i in bit_1_indices]),
],
message_hashes=[
hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b0)),
hash_tree_root(AttestationDataAndCustodyBit(data=indexed_attestation.data, custody_bit=0b1)),
],
signature=indexed_attestation.signature,
domain=get_domain(state, DOMAIN_ATTESTATION, indexed_attestation.data.target.epoch),
)
return [indices[compute_shuffled_index(ValidatorIndex(i), len(indices), seed)] for i in range(start, end)]
```

#### `slot_to_epoch`
#### `compute_epoch_of_slot`

```python
def slot_to_epoch(slot: Slot) -> Epoch:
def compute_epoch_of_slot(slot: Slot) -> Epoch:
"""
Return the epoch number of ``slot``.
"""
return Epoch(slot // SLOTS_PER_EPOCH)
```

#### `epoch_start_slot`
#### `compute_start_slot_of_epoch`

```python
def epoch_start_slot(epoch: Epoch) -> Slot:
def compute_start_slot_of_epoch(epoch: Epoch) -> Slot:
"""
Return the start slot of ``epoch``.
"""
Expand All @@ -765,12 +771,12 @@ def compute_activation_exit_epoch(epoch: Epoch) -> Epoch:
return Epoch(epoch + 1 + ACTIVATION_EXIT_DELAY)
```

#### `bls_domain`
#### `compute_domain`

```python
def bls_domain(domain_type: uint64, fork_version: bytes=b'\x00' * 4) -> int:
def compute_domain(domain_type: uint64, fork_version: bytes=b'\x00' * 4) -> int:
"""
Return the BLS domain for the ``domain_type`` and ``fork_version``.
Return the domain for the ``domain_type`` and ``fork_version``.
"""
return bytes_to_int(int_to_bytes(domain_type, length=4) + fork_version)
```
Expand All @@ -784,7 +790,7 @@ def get_current_epoch(state: BeaconState) -> Epoch:
"""
Return the current epoch.
"""
return slot_to_epoch(state.slot)
return compute_epoch_of_slot(state.slot)
```

#### `get_previous_epoch`
Expand All @@ -805,7 +811,7 @@ def get_block_root(state: BeaconState, epoch: Epoch) -> Hash:
"""
Return the block root at the start of a recent ``epoch``.
"""
return get_block_root_at_slot(state, epoch_start_slot(epoch))
return get_block_root_at_slot(state, compute_start_slot_of_epoch(epoch))
```

#### `get_block_root_at_slot`
Expand Down Expand Up @@ -951,7 +957,7 @@ def get_attestation_data_slot(state: BeaconState, data: AttestationData) -> Slot
"""
committee_count = get_committee_count(state, data.target.epoch)
offset = (data.crosslink.shard + SHARD_COUNT - get_start_shard(state, data.target.epoch)) % SHARD_COUNT
return Slot(epoch_start_slot(data.target.epoch) + offset // (committee_count // SLOTS_PER_EPOCH))
return Slot(compute_start_slot_of_epoch(data.target.epoch) + offset // (committee_count // SLOTS_PER_EPOCH))
```

#### `get_compact_committees_root`
Expand Down Expand Up @@ -1004,7 +1010,7 @@ def get_domain(state: BeaconState, domain_type: uint64, message_epoch: Epoch=Non
"""
epoch = get_current_epoch(state) if message_epoch is None else message_epoch
fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version
return bls_domain(domain_type, fork_version)
return compute_domain(domain_type, fork_version)
```

#### `get_indexed_attestation`
Expand Down Expand Up @@ -1588,14 +1594,15 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None:
def process_proposer_slashing(state: BeaconState, proposer_slashing: ProposerSlashing) -> None:
proposer = state.validators[proposer_slashing.proposer_index]
# Verify that the epoch is the same
assert slot_to_epoch(proposer_slashing.header_1.slot) == slot_to_epoch(proposer_slashing.header_2.slot)
assert (compute_epoch_of_slot(proposer_slashing.header_1.slot)
== compute_epoch_of_slot(proposer_slashing.header_2.slot))
# But the headers are different
assert proposer_slashing.header_1 != proposer_slashing.header_2
# Check proposer is slashable
assert is_slashable_validator(proposer, get_current_epoch(state))
# Signatures are valid
for header in (proposer_slashing.header_1, proposer_slashing.header_2):
domain = get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(header.slot))
domain = get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_of_slot(header.slot))
assert bls_verify(proposer.pubkey, signing_root(header), header.signature, domain)

slash_validator(state, proposer_slashing.proposer_index)
Expand All @@ -1608,8 +1615,8 @@ def process_attester_slashing(state: BeaconState, attester_slashing: AttesterSla
attestation_1 = attester_slashing.attestation_1
attestation_2 = attester_slashing.attestation_2
assert is_slashable_attestation_data(attestation_1.data, attestation_2.data)
validate_indexed_attestation(state, attestation_1)
validate_indexed_attestation(state, attestation_2)
assert is_valid_indexed_attestation(state, attestation_1)
assert is_valid_indexed_attestation(state, attestation_2)

slashed_any = False
attesting_indices_1 = attestation_1.custody_bit_0_indices + attestation_1.custody_bit_1_indices
Expand Down Expand Up @@ -1655,7 +1662,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
assert data.crosslink.data_root == Hash() # [to be removed in phase 1]

# Check signature
validate_indexed_attestation(state, get_indexed_attestation(state, attestation))
assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
```

##### Deposits
Expand All @@ -1680,8 +1687,9 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
if pubkey not in validator_pubkeys:
# Verify the deposit signature (proof of possession) for new validators.
# Note: The deposit contract does not check signatures.
# Note: Deposits are valid across forks, hence the deposit domain is retrieved directly from `bls_domain`
if not bls_verify(pubkey, signing_root(deposit.data), deposit.data.signature, bls_domain(DOMAIN_DEPOSIT)):
# Note: Deposits are valid across forks, thus the deposit domain is retrieved directly from `compute_domain`
domain = compute_domain(DOMAIN_DEPOSIT)
if not bls_verify(pubkey, signing_root(deposit.data), deposit.data.signature, domain):
return

# Add validator and balance entries
Expand Down
10 changes: 5 additions & 5 deletions specs/core/0_fork-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def get_latest_attesting_balance(store: Store, root: Hash) -> Gwei:
def get_head(store: Store) -> Hash:
# Execute the LMD-GHOST fork choice
head = store.justified_checkpoint.root
justified_slot = epoch_start_slot(store.justified_checkpoint.epoch)
justified_slot = compute_start_slot_of_epoch(store.justified_checkpoint.epoch)
while True:
children = [
root for root in store.blocks.keys()
Expand Down Expand Up @@ -162,7 +162,7 @@ def on_block(store: Store, block: BeaconBlock) -> None:
store.finalized_checkpoint.root
)
# Check that block is later than the finalized epoch slot
assert block.slot > epoch_start_slot(store.finalized_checkpoint.epoch)
assert block.slot > compute_start_slot_of_epoch(store.finalized_checkpoint.epoch)
# Check the block is valid and compute the post-state
state = state_transition(pre_state, block)
# Add new state for this block to the store
Expand Down Expand Up @@ -190,11 +190,11 @@ def on_attestation(store: Store, attestation: Attestation) -> None:

# Attestations cannot be from future epochs. If they are, delay consideration until the epoch arrives
base_state = store.block_states[target.root].copy()
assert store.time >= base_state.genesis_time + epoch_start_slot(target.epoch) * SECONDS_PER_SLOT
assert store.time >= base_state.genesis_time + compute_start_slot_of_epoch(target.epoch) * SECONDS_PER_SLOT

# Store target checkpoint state if not yet seen
if target not in store.checkpoint_states:
process_slots(base_state, epoch_start_slot(target.epoch))
process_slots(base_state, compute_start_slot_of_epoch(target.epoch))
store.checkpoint_states[target] = base_state
target_state = store.checkpoint_states[target]

Expand All @@ -205,7 +205,7 @@ def on_attestation(store: Store, attestation: Attestation) -> None:

# Get state at the `target` to validate attestation and calculate the committees
indexed_attestation = get_indexed_attestation(target_state, attestation)
validate_indexed_attestation(target_state, indexed_attestation)
assert is_valid_indexed_attestation(target_state, indexed_attestation)

# Update latest messages
for i in indexed_attestation.custody_bit_0_indices + indexed_attestation.custody_bit_1_indices:
Expand Down
9 changes: 5 additions & 4 deletions specs/core/1_custody-game.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,9 +474,10 @@ For each `challenge` in `block.body.custody_chunk_challenges`, run the following
```python
def process_chunk_challenge(state: BeaconState, challenge: CustodyChunkChallenge) -> None:
# Verify the attestation
validate_indexed_attestation(state, get_indexed_attestation(state, challenge.attestation))
assert is_valid_indexed_attestation(state, get_indexed_attestation(state, challenge.attestation))
# Verify it is not too late to challenge
assert slot_to_epoch(challenge.attestation.data.slot) >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY
assert (compute_epoch_of_slot(challenge.attestation.data.slot)
>= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY)
responder = state.validators[challenge.responder_index]
assert responder.exit_epoch >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY
# Verify the responder participated in the attestation
Expand Down Expand Up @@ -517,7 +518,7 @@ For each `challenge` in `block.body.custody_bit_challenges`, run the following f
```python
def process_bit_challenge(state: BeaconState, challenge: CustodyBitChallenge) -> None:
attestation = challenge.attestation
epoch = slot_to_epoch(attestation.data.slot)
epoch = compute_epoch_of_slot(attestation.data.slot)
shard = attestation.data.crosslink.shard

# Verify challenge signature
Expand All @@ -527,7 +528,7 @@ def process_bit_challenge(state: BeaconState, challenge: CustodyBitChallenge) ->
# Verify challenger is slashable
assert is_slashable_validator(challenger, get_current_epoch(state))
# Verify attestation
validate_indexed_attestation(state, get_indexed_attestation(state, attestation))
assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
# Verify attestation is eligible for challenging
responder = state.validators[challenge.responder_index]
assert epoch + responder.max_reveal_lateness <= get_reveal_period(state, challenge.responder_index)
Expand Down
11 changes: 6 additions & 5 deletions specs/core/1_shard-data-chains.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def get_persistent_committee(state: BeaconState,
"""
Return the persistent committee for the given ``shard`` at the given ``slot``.
"""
epoch = slot_to_epoch(slot)
epoch = compute_epoch_of_slot(slot)
earlier_start_epoch = Epoch(epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD * 2)
later_start_epoch = Epoch(epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD)

Expand Down Expand Up @@ -241,7 +241,7 @@ def verify_shard_attestation_signature(state: BeaconState,
pubkey=bls_aggregate_pubkeys(pubkeys),
message_hash=data.shard_block_root,
signature=attestation.aggregate_signature,
domain=get_domain(state, DOMAIN_SHARD_ATTESTER, slot_to_epoch(data.slot))
domain=get_domain(state, DOMAIN_SHARD_ATTESTER, compute_epoch_of_slot(data.slot))
)
```

Expand Down Expand Up @@ -340,7 +340,7 @@ def is_valid_shard_block(beacon_blocks: Sequence[BeaconBlock],
pubkey=beacon_state.validators[proposer_index].pubkey,
message_hash=signing_root(candidate),
signature=candidate.signature,
domain=get_domain(beacon_state, DOMAIN_SHARD_PROPOSER, slot_to_epoch(candidate.slot)),
domain=get_domain(beacon_state, DOMAIN_SHARD_PROPOSER, compute_epoch_of_slot(candidate.slot)),
)

return True
Expand Down Expand Up @@ -404,11 +404,12 @@ def is_valid_beacon_attestation(shard: Shard,
None,
)
assert previous_attestation is not None
assert candidate.data.previous_attestation.epoch < slot_to_epoch(candidate.data.slot)
assert candidate.data.previous_attestation.epoch < compute_epoch_of_slot(candidate.data.slot)

# Check crosslink data root
start_epoch = beacon_state.crosslinks[shard].epoch
end_epoch = min(slot_to_epoch(candidate.data.slot) - CROSSLINK_LOOKBACK, start_epoch + MAX_EPOCHS_PER_CROSSLINK)
end_epoch = min(compute_epoch_of_slot(candidate.data.slot) - CROSSLINK_LOOKBACK,
start_epoch + MAX_EPOCHS_PER_CROSSLINK)
blocks = []
for slot in range(start_epoch * SLOTS_PER_EPOCH, end_epoch * SLOTS_PER_EPOCH):
blocks.append(shard_blocks[slot])
Expand Down
4 changes: 2 additions & 2 deletions specs/light_client/sync_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def compute_committee(header: BeaconBlockHeader,
maximal_later_committee = validator_memory.later_period_data.committee
earlier_start_epoch = get_earlier_start_epoch(header.slot)
later_start_epoch = get_later_start_epoch(header.slot)
epoch = slot_to_epoch(header.slot)
epoch = compute_epoch_of_slot(header.slot)

committee_count = max(
earlier_validator_count // (SHARD_COUNT * TARGET_COMMITTEE_SIZE),
Expand Down Expand Up @@ -192,7 +192,7 @@ def verify_block_validity_proof(proof: BlockValidityProof, validator_memory: Val
pubkey=group_public_key,
message_hash=hash_tree_root(shard_parent_block),
signature=proof.shard_aggregate_signature,
domain=get_domain(state, slot_to_epoch(shard_block.slot), DOMAIN_SHARD_ATTESTER),
domain=get_domain(state, compute_epoch_of_slot(shard_block.slot), DOMAIN_SHARD_ATTESTER),
)
```

Expand Down
4 changes: 2 additions & 2 deletions specs/test_formats/bls/msg_hash_g2_compressed.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ A BLS compressed-hash to G2.
## Test case format

```yaml
input:
input:
message: bytes32,
domain: uint64 -- the BLS domain
domain: uint64 -- the domain
output: List[bytes48] -- length of two
```
Expand Down
Loading

0 comments on commit 155158f

Please sign in to comment.