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

Renaming of functions in the Misc section #1241

Merged
merged 10 commits into from Jul 1, 2019
2 changes: 1 addition & 1 deletion scripts/build_spec.py
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
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 @@ -1586,14 +1592,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 @@ -1606,8 +1613,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 @@ -1653,7 +1660,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 @@ -1678,8 +1685,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
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
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
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
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
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