Cleanup naming
This commit is contained in:
parent
2622548ba7
commit
196ac42025
|
@ -190,7 +190,7 @@ The following values are (non-configurable) constants used throughout the specif
|
||||||
| `MIN_PER_EPOCH_CHURN_LIMIT` | `2**2` (= 4) |
|
| `MIN_PER_EPOCH_CHURN_LIMIT` | `2**2` (= 4) |
|
||||||
| `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) |
|
| `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) |
|
||||||
| `SHUFFLE_ROUND_COUNT` | `90` |
|
| `SHUFFLE_ROUND_COUNT` | `90` |
|
||||||
| `JUSTIFICATION_BITVECTOR_LENGTH` | `4` |
|
| `JUSTIFICATION_BITS_LENGTH` | `4` |
|
||||||
|
|
||||||
* For the safety of crosslinks, `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](https://vitalik.ca/files/Ithaca201807_Sharding.pdf); with sufficient active validators (at least `SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE`), the shuffling algorithm ensures committee sizes of at least `TARGET_COMMITTEE_SIZE`. (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.)
|
* For the safety of crosslinks, `TARGET_COMMITTEE_SIZE` exceeds [the recommended minimum committee size of 111](https://vitalik.ca/files/Ithaca201807_Sharding.pdf); with sufficient active validators (at least `SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE`), the shuffling algorithm ensures committee sizes of at least `TARGET_COMMITTEE_SIZE`. (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.)
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ class IndexedAttestation(Container):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class PendingAttestation(Container):
|
class PendingAttestation(Container):
|
||||||
aggregation_bitfield: Bitlist[MAX_INDICES_PER_ATTESTATION]
|
aggregation_bits: Bitlist[MAX_INDICES_PER_ATTESTATION]
|
||||||
data: AttestationData
|
data: AttestationData
|
||||||
inclusion_delay: Slot
|
inclusion_delay: Slot
|
||||||
proposer_index: ValidatorIndex
|
proposer_index: ValidatorIndex
|
||||||
|
@ -427,9 +427,9 @@ class AttesterSlashing(Container):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class Attestation(Container):
|
class Attestation(Container):
|
||||||
aggregation_bitfield: Bitlist[MAX_INDICES_PER_ATTESTATION]
|
aggregation_bits: Bitlist[MAX_INDICES_PER_ATTESTATION]
|
||||||
data: AttestationData
|
data: AttestationData
|
||||||
custody_bitfield: Bitlist[MAX_INDICES_PER_ATTESTATION]
|
custody_bits: Bitlist[MAX_INDICES_PER_ATTESTATION]
|
||||||
signature: BLSSignature
|
signature: BLSSignature
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ class BeaconState(Container):
|
||||||
previous_crosslinks: Vector[Crosslink, SHARD_COUNT] # Previous epoch snapshot
|
previous_crosslinks: Vector[Crosslink, SHARD_COUNT] # Previous epoch snapshot
|
||||||
current_crosslinks: Vector[Crosslink, SHARD_COUNT]
|
current_crosslinks: Vector[Crosslink, SHARD_COUNT]
|
||||||
# Finality
|
# Finality
|
||||||
justification_bitfield: Bitvector[JUSTIFICATION_BITVECTOR_LENGTH] # Bit set for every recent justified epoch
|
justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] # Bit set for every recent justified epoch
|
||||||
previous_justified_checkpoint: Checkpoint # Previous epoch snapshot
|
previous_justified_checkpoint: Checkpoint # Previous epoch snapshot
|
||||||
current_justified_checkpoint: Checkpoint
|
current_justified_checkpoint: Checkpoint
|
||||||
finalized_checkpoint: Checkpoint
|
finalized_checkpoint: Checkpoint
|
||||||
|
@ -867,12 +867,12 @@ def get_crosslink_committee(state: BeaconState, epoch: Epoch, shard: Shard) -> S
|
||||||
```python
|
```python
|
||||||
def get_attesting_indices(state: BeaconState,
|
def get_attesting_indices(state: BeaconState,
|
||||||
data: AttestationData,
|
data: AttestationData,
|
||||||
bitfield: Bitlist[MAX_INDICES_PER_ATTESTATION]) -> Sequence[ValidatorIndex]:
|
bits: Bitlist[MAX_INDICES_PER_ATTESTATION]) -> Sequence[ValidatorIndex]:
|
||||||
"""
|
"""
|
||||||
Return the sorted attesting indices corresponding to ``data`` and ``bitfield``.
|
Return the sorted attesting indices corresponding to ``data`` and ``bits``.
|
||||||
"""
|
"""
|
||||||
committee = get_crosslink_committee(state, data.target.epoch, data.crosslink.shard)
|
committee = get_crosslink_committee(state, data.target.epoch, data.crosslink.shard)
|
||||||
return sorted([index for i, index in enumerate(committee) if bitfield[i]])
|
return sorted([index for i, index in enumerate(committee) if bits[i]])
|
||||||
```
|
```
|
||||||
|
|
||||||
### `int_to_bytes`
|
### `int_to_bytes`
|
||||||
|
@ -920,8 +920,8 @@ def convert_to_indexed(state: BeaconState, attestation: Attestation) -> IndexedA
|
||||||
"""
|
"""
|
||||||
Convert ``attestation`` to (almost) indexed-verifiable form.
|
Convert ``attestation`` to (almost) indexed-verifiable form.
|
||||||
"""
|
"""
|
||||||
attesting_indices = get_attesting_indices(state, attestation.data, attestation.aggregation_bitfield)
|
attesting_indices = get_attesting_indices(state, attestation.data, attestation.aggregation_bits)
|
||||||
custody_bit_1_indices = get_attesting_indices(state, attestation.data, attestation.custody_bitfield)
|
custody_bit_1_indices = get_attesting_indices(state, attestation.data, attestation.custody_bits)
|
||||||
assert set(custody_bit_1_indices).issubset(attesting_indices)
|
assert set(custody_bit_1_indices).issubset(attesting_indices)
|
||||||
custody_bit_0_indices = [index for index in attesting_indices if index not in custody_bit_1_indices]
|
custody_bit_0_indices = [index for index in attesting_indices if index not in custody_bit_1_indices]
|
||||||
|
|
||||||
|
@ -1146,7 +1146,7 @@ def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, eth
|
||||||
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
validator.activation_eligibility_epoch = GENESIS_EPOCH
|
||||||
validator.activation_epoch = GENESIS_EPOCH
|
validator.activation_epoch = GENESIS_EPOCH
|
||||||
|
|
||||||
# Populate active_index_roots
|
# Populate active_index_roots
|
||||||
genesis_active_index_root = hash_tree_root(
|
genesis_active_index_root = hash_tree_root(
|
||||||
List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, GENESIS_EPOCH))
|
List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, GENESIS_EPOCH))
|
||||||
)
|
)
|
||||||
|
@ -1254,7 +1254,7 @@ def get_unslashed_attesting_indices(state: BeaconState,
|
||||||
attestations: Sequence[PendingAttestation]) -> Set[ValidatorIndex]:
|
attestations: Sequence[PendingAttestation]) -> Set[ValidatorIndex]:
|
||||||
output = set() # type: Set[ValidatorIndex]
|
output = set() # type: Set[ValidatorIndex]
|
||||||
for a in attestations:
|
for a in attestations:
|
||||||
output = output.union(get_attesting_indices(state, a.data, a.aggregation_bitfield))
|
output = output.union(get_attesting_indices(state, a.data, a.aggregation_bits))
|
||||||
return set(filter(lambda index: not state.validators[index].slashed, list(output)))
|
return set(filter(lambda index: not state.validators[index].slashed, list(output)))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1294,36 +1294,35 @@ def process_justification_and_finalization(state: BeaconState) -> None:
|
||||||
|
|
||||||
# Process justifications
|
# Process justifications
|
||||||
state.previous_justified_checkpoint = state.current_justified_checkpoint
|
state.previous_justified_checkpoint = state.current_justified_checkpoint
|
||||||
state.justification_bitfield[1:JUSTIFICATION_BITVECTOR_LENGTH] = \
|
state.justification_bits[1:JUSTIFICATION_BITS_LENGTH] = state.justification_bits[0:JUSTIFICATION_BITS_LENGTH - 1]
|
||||||
state.justification_bitfield[0:JUSTIFICATION_BITVECTOR_LENGTH - 1]
|
state.justification_bits[0] = 0b0
|
||||||
state.justification_bitfield[0] = 0b0
|
|
||||||
previous_epoch_matching_target_balance = get_attesting_balance(
|
previous_epoch_matching_target_balance = get_attesting_balance(
|
||||||
state, get_matching_target_attestations(state, previous_epoch)
|
state, get_matching_target_attestations(state, previous_epoch)
|
||||||
)
|
)
|
||||||
if previous_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
|
if previous_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
|
||||||
state.current_justified_checkpoint = Checkpoint(epoch=previous_epoch,
|
state.current_justified_checkpoint = Checkpoint(epoch=previous_epoch,
|
||||||
root=get_block_root(state, previous_epoch))
|
root=get_block_root(state, previous_epoch))
|
||||||
state.justification_bitfield[1] = 0b1
|
state.justification_bits[1] = 0b1
|
||||||
current_epoch_matching_target_balance = get_attesting_balance(
|
current_epoch_matching_target_balance = get_attesting_balance(
|
||||||
state, get_matching_target_attestations(state, current_epoch)
|
state, get_matching_target_attestations(state, current_epoch)
|
||||||
)
|
)
|
||||||
if current_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
|
if current_epoch_matching_target_balance * 3 >= get_total_active_balance(state) * 2:
|
||||||
state.current_justified_checkpoint = Checkpoint(epoch=current_epoch, root=get_block_root(state, current_epoch))
|
state.current_justified_checkpoint = Checkpoint(epoch=current_epoch, root=get_block_root(state, current_epoch))
|
||||||
state.justification_bitfield[0] = 0b1
|
state.justification_bits[0] = 0b1
|
||||||
|
|
||||||
# Process finalizations
|
# Process finalizations
|
||||||
bitfield = state.justification_bitfield
|
bits = state.justification_bits
|
||||||
# The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th as source
|
# The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th as source
|
||||||
if all(bitfield[1:4]) and old_previous_justified_checkpoint.epoch + 3 == current_epoch:
|
if all(bits[1:4]) and old_previous_justified_checkpoint.epoch + 3 == current_epoch:
|
||||||
state.finalized_checkpoint = old_previous_justified_checkpoint
|
state.finalized_checkpoint = old_previous_justified_checkpoint
|
||||||
# The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as source
|
# The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as source
|
||||||
if all(bitfield[1:3]) and old_previous_justified_checkpoint.epoch + 2 == current_epoch:
|
if all(bits[1:3]) and old_previous_justified_checkpoint.epoch + 2 == current_epoch:
|
||||||
state.finalized_checkpoint = old_previous_justified_checkpoint
|
state.finalized_checkpoint = old_previous_justified_checkpoint
|
||||||
# The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as source
|
# The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as source
|
||||||
if all(bitfield[0:3]) and old_current_justified_checkpoint.epoch + 2 == current_epoch:
|
if all(bits[0:3]) and old_current_justified_checkpoint.epoch + 2 == current_epoch:
|
||||||
state.finalized_checkpoint = old_current_justified_checkpoint
|
state.finalized_checkpoint = old_current_justified_checkpoint
|
||||||
# The 1st/2nd most recent epochs are justified, the 1st using the 2nd as source
|
# The 1st/2nd most recent epochs are justified, the 1st using the 2nd as source
|
||||||
if all(bitfield[0:2]) and old_current_justified_checkpoint.epoch + 1 == current_epoch:
|
if all(bits[0:2]) and old_current_justified_checkpoint.epoch + 1 == current_epoch:
|
||||||
state.finalized_checkpoint = old_current_justified_checkpoint
|
state.finalized_checkpoint = old_current_justified_checkpoint
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1379,7 +1378,7 @@ def get_attestation_deltas(state: BeaconState) -> Tuple[Sequence[Gwei], Sequence
|
||||||
index = ValidatorIndex(index)
|
index = ValidatorIndex(index)
|
||||||
attestation = min([
|
attestation = min([
|
||||||
a for a in matching_source_attestations
|
a for a in matching_source_attestations
|
||||||
if index in get_attesting_indices(state, a.data, a.aggregation_bitfield)
|
if index in get_attesting_indices(state, a.data, a.aggregation_bits)
|
||||||
], key=lambda a: a.inclusion_delay)
|
], key=lambda a: a.inclusion_delay)
|
||||||
proposer_reward = Gwei(get_base_reward(state, index) // PROPOSER_REWARD_QUOTIENT)
|
proposer_reward = Gwei(get_base_reward(state, index) // PROPOSER_REWARD_QUOTIENT)
|
||||||
rewards[attestation.proposer_index] += proposer_reward
|
rewards[attestation.proposer_index] += proposer_reward
|
||||||
|
@ -1661,7 +1660,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
||||||
|
|
||||||
pending_attestation = PendingAttestation(
|
pending_attestation = PendingAttestation(
|
||||||
data=data,
|
data=data,
|
||||||
aggregation_bitfield=attestation.aggregation_bitfield,
|
aggregation_bits=attestation.aggregation_bits,
|
||||||
inclusion_delay=state.slot - attestation_slot,
|
inclusion_delay=state.slot - attestation_slot,
|
||||||
proposer_index=get_beacon_proposer_index(state),
|
proposer_index=get_beacon_proposer_index(state),
|
||||||
)
|
)
|
||||||
|
@ -1680,7 +1679,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
|
||||||
assert data.crosslink.start_epoch == parent_crosslink.end_epoch
|
assert data.crosslink.start_epoch == parent_crosslink.end_epoch
|
||||||
assert data.crosslink.end_epoch == min(data.target.epoch, parent_crosslink.end_epoch + MAX_EPOCHS_PER_CROSSLINK)
|
assert data.crosslink.end_epoch == min(data.target.epoch, parent_crosslink.end_epoch + MAX_EPOCHS_PER_CROSSLINK)
|
||||||
assert data.crosslink.data_root == ZERO_HASH # [to be removed in phase 1]
|
assert data.crosslink.data_root == ZERO_HASH # [to be removed in phase 1]
|
||||||
|
|
||||||
# Check signature
|
# Check signature
|
||||||
validate_indexed_attestation(state, convert_to_indexed(state, attestation))
|
validate_indexed_attestation(state, convert_to_indexed(state, attestation))
|
||||||
```
|
```
|
||||||
|
|
|
@ -272,14 +272,14 @@ def get_custody_chunk_count(crosslink: Crosslink) -> int:
|
||||||
return crosslink_length * chunks_per_epoch
|
return crosslink_length * chunks_per_epoch
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_bitfield_bit`
|
### `get_bit`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_bitfield_bit(bitfield: bytes, i: int) -> int:
|
def get_bit(serialization: bytes, i: int) -> int:
|
||||||
"""
|
"""
|
||||||
Extract the bit in ``bitfield`` at position ``i``.
|
Extract the bit in ``serialization`` at position ``i``.
|
||||||
"""
|
"""
|
||||||
return (bitfield[i // 8] >> (i % 8)) % 2
|
return (serialization[i // 8] >> (i % 8)) % 2
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_custody_chunk_bit`
|
### `get_custody_chunk_bit`
|
||||||
|
@ -287,17 +287,17 @@ def get_bitfield_bit(bitfield: bytes, i: int) -> int:
|
||||||
```python
|
```python
|
||||||
def get_custody_chunk_bit(key: BLSSignature, chunk: bytes) -> bool:
|
def get_custody_chunk_bit(key: BLSSignature, chunk: bytes) -> bool:
|
||||||
# TODO: Replace with something MPC-friendly, e.g. the Legendre symbol
|
# TODO: Replace with something MPC-friendly, e.g. the Legendre symbol
|
||||||
return bool(get_bitfield_bit(hash(key + chunk), 0))
|
return bool(get_bit(hash(key + chunk), 0))
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_chunk_bits_root`
|
### `get_chunk_bits_root`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_chunk_bits_root(chunk_bitfield: bytes) -> Bytes32:
|
def get_chunk_bits_root(chunk_bits: bytes) -> Bytes32:
|
||||||
aggregated_bits = bytearray([0] * 32)
|
aggregated_bits = bytearray([0] * 32)
|
||||||
for i in range(0, len(chunk_bitfield), 32):
|
for i in range(0, len(chunk_bits), 32):
|
||||||
for j in range(32):
|
for j in range(32):
|
||||||
aggregated_bits[j] ^= chunk_bitfield[i + j]
|
aggregated_bits[j] ^= chunk_bits[i + j]
|
||||||
return hash(aggregated_bits)
|
return hash(aggregated_bits)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -489,7 +489,7 @@ def process_chunk_challenge(state: BeaconState,
|
||||||
responder = state.validators[challenge.responder_index]
|
responder = state.validators[challenge.responder_index]
|
||||||
assert responder.exit_epoch >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY
|
assert responder.exit_epoch >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY
|
||||||
# Verify the responder participated in the attestation
|
# Verify the responder participated in the attestation
|
||||||
attesters = get_attesting_indices(state, challenge.attestation.data, challenge.attestation.aggregation_bitfield)
|
attesters = get_attesting_indices(state, challenge.attestation.data, challenge.attestation.aggregation_bits)
|
||||||
assert challenge.responder_index in attesters
|
assert challenge.responder_index in attesters
|
||||||
# Verify the challenge is not a duplicate
|
# Verify the challenge is not a duplicate
|
||||||
for record in state.custody_chunk_challenge_records:
|
for record in state.custody_chunk_challenge_records:
|
||||||
|
@ -546,7 +546,7 @@ def process_bit_challenge(state: BeaconState,
|
||||||
get_validators_custody_reveal_period(state, challenge.responder_index))
|
get_validators_custody_reveal_period(state, challenge.responder_index))
|
||||||
|
|
||||||
# Verify the responder participated in the attestation
|
# Verify the responder participated in the attestation
|
||||||
attesters = get_attesting_indices(state, attestation.data, attestation.aggregation_bitfield)
|
attesters = get_attesting_indices(state, attestation.data, attestation.aggregation_bits)
|
||||||
assert challenge.responder_index in attesters
|
assert challenge.responder_index in attesters
|
||||||
|
|
||||||
# A validator can be the challenger for at most one challenge at a time
|
# A validator can be the challenger for at most one challenge at a time
|
||||||
|
@ -575,8 +575,8 @@ def process_bit_challenge(state: BeaconState,
|
||||||
# Verify the chunk count
|
# Verify the chunk count
|
||||||
chunk_count = get_custody_chunk_count(attestation.data.crosslink)
|
chunk_count = get_custody_chunk_count(attestation.data.crosslink)
|
||||||
# Verify the first bit of the hash of the chunk bits does not equal the custody bit
|
# Verify the first bit of the hash of the chunk bits does not equal the custody bit
|
||||||
custody_bit = attestation.custody_bitfield[attesters.index(challenge.responder_index)]
|
custody_bit = attestation.custody_bits[attesters.index(challenge.responder_index)]
|
||||||
assert custody_bit != get_bitfield_bit(get_chunk_bits_root(challenge.chunk_bits), 0)
|
assert custody_bit != get_bit(get_chunk_bits_root(challenge.chunk_bits), 0)
|
||||||
# Add new bit challenge record
|
# Add new bit challenge record
|
||||||
new_record = CustodyBitChallengeRecord(
|
new_record = CustodyBitChallengeRecord(
|
||||||
challenge_index=state.custody_challenge_index,
|
challenge_index=state.custody_challenge_index,
|
||||||
|
@ -670,7 +670,7 @@ def process_bit_challenge_response(state: BeaconState,
|
||||||
)
|
)
|
||||||
# Verify the chunk bit does not match the challenge chunk bit
|
# Verify the chunk bit does not match the challenge chunk bit
|
||||||
assert (get_custody_chunk_bit(challenge.responder_key, response.chunk)
|
assert (get_custody_chunk_bit(challenge.responder_key, response.chunk)
|
||||||
!= get_bitfield_bit(challenge.chunk_bits_leaf, response.chunk_index % 256))
|
!= get_bit(challenge.chunk_bits_leaf, response.chunk_index % 256))
|
||||||
# Clear the challenge
|
# Clear the challenge
|
||||||
records = state.custody_bit_challenge_records
|
records = state.custody_bit_challenge_records
|
||||||
records[records.index(challenge)] = CustodyBitChallengeRecord()
|
records[records.index(challenge)] = CustodyBitChallengeRecord()
|
||||||
|
|
|
@ -92,7 +92,7 @@ class ShardAttestation(Container):
|
||||||
slot: Slot
|
slot: Slot
|
||||||
shard: Shard
|
shard: Shard
|
||||||
shard_block_root: Bytes32
|
shard_block_root: Bytes32
|
||||||
aggregation_bitfield: Bitlist[PLACEHOLDER]
|
aggregation_bits: Bitlist[PLACEHOLDER]
|
||||||
aggregate_signature: BLSSignature
|
aggregate_signature: BLSSignature
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ def verify_shard_attestation_signature(state: BeaconState,
|
||||||
persistent_committee = get_persistent_committee(state, data.shard, data.slot)
|
persistent_committee = get_persistent_committee(state, data.shard, data.slot)
|
||||||
pubkeys = []
|
pubkeys = []
|
||||||
for i, index in enumerate(persistent_committee):
|
for i, index in enumerate(persistent_committee):
|
||||||
if attestation.aggregation_bitfield[i]:
|
if attestation.aggregation_bits[i]:
|
||||||
validator = state.validators[index]
|
validator = state.validators[index]
|
||||||
assert is_active_validator(validator, get_current_epoch(state))
|
assert is_active_validator(validator, get_current_epoch(state))
|
||||||
pubkeys.append(validator.pubkey)
|
pubkeys.append(validator.pubkey)
|
||||||
|
|
|
@ -168,7 +168,7 @@ If a client wants to update its `finalized_header` it asks the network for a `Bl
|
||||||
{
|
{
|
||||||
'header': BeaconBlockHeader,
|
'header': BeaconBlockHeader,
|
||||||
'shard_aggregate_signature': BLSSignature,
|
'shard_aggregate_signature': BLSSignature,
|
||||||
'shard_bitfield': Bitlist[PLACEHOLDER],
|
'shard_bits': Bitlist[PLACEHOLDER],
|
||||||
'shard_parent_block': ShardBlock,
|
'shard_parent_block': ShardBlock,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -180,13 +180,13 @@ def verify_block_validity_proof(proof: BlockValidityProof, validator_memory: Val
|
||||||
assert proof.shard_parent_block.beacon_chain_root == hash_tree_root(proof.header)
|
assert proof.shard_parent_block.beacon_chain_root == hash_tree_root(proof.header)
|
||||||
committee = compute_committee(proof.header, validator_memory)
|
committee = compute_committee(proof.header, validator_memory)
|
||||||
# Verify that we have >=50% support
|
# Verify that we have >=50% support
|
||||||
support_balance = sum([v.effective_balance for i, v in enumerate(committee) if proof.shard_bitfield[i]])
|
support_balance = sum([v.effective_balance for i, v in enumerate(committee) if proof.shard_bits[i]])
|
||||||
total_balance = sum([v.effective_balance for i, v in enumerate(committee)])
|
total_balance = sum([v.effective_balance for i, v in enumerate(committee)])
|
||||||
assert support_balance * 2 > total_balance
|
assert support_balance * 2 > total_balance
|
||||||
# Verify shard attestations
|
# Verify shard attestations
|
||||||
group_public_key = bls_aggregate_pubkeys([
|
group_public_key = bls_aggregate_pubkeys([
|
||||||
v.pubkey for v, index in enumerate(committee)
|
v.pubkey for v, index in enumerate(committee)
|
||||||
if proof.shard_bitfield[index]
|
if proof.shard_bits[index]
|
||||||
])
|
])
|
||||||
assert bls_verify(
|
assert bls_verify(
|
||||||
pubkey=group_public_key,
|
pubkey=group_public_key,
|
||||||
|
@ -196,4 +196,4 @@ def verify_block_validity_proof(proof: BlockValidityProof, validator_memory: Val
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
The size of this proof is only 200 (header) + 96 (signature) + 16 (bitfield) + 352 (shard block) = 664 bytes. It can be reduced further by replacing `ShardBlock` with `MerklePartial(lambda x: x.beacon_chain_root, ShardBlock)`, which would cut off ~220 bytes.
|
The size of this proof is only 200 (header) + 96 (signature) + 16 (bits) + 352 (shard block) = 664 bytes. It can be reduced further by replacing `ShardBlock` with `MerklePartial(lambda x: x.beacon_chain_root, ShardBlock)`, which would cut off ~220 bytes.
|
||||||
|
|
|
@ -44,8 +44,8 @@
|
||||||
- [Crosslink vote](#crosslink-vote)
|
- [Crosslink vote](#crosslink-vote)
|
||||||
- [Construct attestation](#construct-attestation)
|
- [Construct attestation](#construct-attestation)
|
||||||
- [Data](#data)
|
- [Data](#data)
|
||||||
- [Aggregation bitfield](#aggregation-bitfield)
|
- [Aggregation bits](#aggregation-bits)
|
||||||
- [Custody bitfield](#custody-bitfield)
|
- [Custody bits](#custody-bits)
|
||||||
- [Aggregate signature](#aggregate-signature)
|
- [Aggregate signature](#aggregate-signature)
|
||||||
- [How to avoid slashing](#how-to-avoid-slashing)
|
- [How to avoid slashing](#how-to-avoid-slashing)
|
||||||
- [Proposer slashing](#proposer-slashing)
|
- [Proposer slashing](#proposer-slashing)
|
||||||
|
@ -322,19 +322,19 @@ Next, the validator creates `attestation`, an [`Attestation`](../core/0_beacon-c
|
||||||
|
|
||||||
Set `attestation.data = attestation_data` where `attestation_data` is the `AttestationData` object defined in the previous section, [attestation data](#attestation-data).
|
Set `attestation.data = attestation_data` where `attestation_data` is the `AttestationData` object defined in the previous section, [attestation data](#attestation-data).
|
||||||
|
|
||||||
##### Aggregation bitfield
|
##### Aggregation bits
|
||||||
|
|
||||||
* Let `aggregation_bitfield` be a byte array filled with zeros of length `(len(committee) + 7) // 8`.
|
* Let `aggregation_bits` be a byte array filled with zeros of length `(len(committee) + 7) // 8`.
|
||||||
* Let `index_into_committee` be the index into the validator's `committee` at which `validator_index` is located.
|
* Let `index_into_committee` be the index into the validator's `committee` at which `validator_index` is located.
|
||||||
* Set `aggregation_bitfield[index_into_committee // 8] |= 2 ** (index_into_committee % 8)`.
|
* Set `aggregation_bits[index_into_committee // 8] |= 2 ** (index_into_committee % 8)`.
|
||||||
* Set `attestation.aggregation_bitfield = aggregation_bitfield`.
|
* Set `attestation.aggregation_bits = aggregation_bits`.
|
||||||
|
|
||||||
*Note*: Calling `get_attesting_indices(state, attestation.data, attestation.aggregation_bitfield)` should return a list of length equal to 1, containing `validator_index`.
|
*Note*: Calling `get_attesting_indices(state, attestation.data, attestation.aggregation_bits)` should return a list of length equal to 1, containing `validator_index`.
|
||||||
|
|
||||||
##### Custody bitfield
|
##### Custody bits
|
||||||
|
|
||||||
* Let `custody_bitfield` be a byte array filled with zeros of length `(len(committee) + 7) // 8`.
|
* Let `custody_bits` be a byte array filled with zeros of length `(len(committee) + 7) // 8`.
|
||||||
* Set `attestation.custody_bitfield = custody_bitfield`.
|
* Set `attestation.custody_bits = custody_bits`.
|
||||||
|
|
||||||
*Note*: This is a stub for Phase 0.
|
*Note*: This is a stub for Phase 0.
|
||||||
|
|
||||||
|
|
|
@ -415,16 +415,16 @@ components:
|
||||||
type: object
|
type: object
|
||||||
description: "The [`Attestation`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestation) object from the Eth2.0 spec."
|
description: "The [`Attestation`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestation) object from the Eth2.0 spec."
|
||||||
properties:
|
properties:
|
||||||
aggregation_bitfield:
|
aggregation_bits:
|
||||||
type: string
|
type: string
|
||||||
format: byte
|
format: byte
|
||||||
pattern: "^0x[a-fA-F0-9]+$"
|
pattern: "^0x[a-fA-F0-9]+$"
|
||||||
description: "Attester aggregation bitfield."
|
description: "Attester aggregation bits."
|
||||||
custody_bitfield:
|
custody_bits:
|
||||||
type: string
|
type: string
|
||||||
format: byte
|
format: byte
|
||||||
pattern: "^0x[a-fA-F0-9]+$"
|
pattern: "^0x[a-fA-F0-9]+$"
|
||||||
description: "Custody bitfield."
|
description: "Custody bits."
|
||||||
signature:
|
signature:
|
||||||
type: string
|
type: string
|
||||||
format: byte
|
format: byte
|
||||||
|
|
|
@ -9,7 +9,7 @@ def test_decoder():
|
||||||
rng = Random(123)
|
rng = Random(123)
|
||||||
|
|
||||||
# check these types only, Block covers a lot of operation types already.
|
# check these types only, Block covers a lot of operation types already.
|
||||||
# TODO: Once has Bitfields and Bitvectors, add back
|
# TODO: Once has Bitlists and Bitvectors, add back
|
||||||
# spec.BeaconState and spec.BeaconBlock
|
# spec.BeaconState and spec.BeaconBlock
|
||||||
for typ in [spec.IndexedAttestation, spec.AttestationDataAndCustodyBit]:
|
for typ in [spec.IndexedAttestation, spec.AttestationDataAndCustodyBit]:
|
||||||
# create a random pyspec value
|
# create a random pyspec value
|
||||||
|
|
|
@ -118,5 +118,5 @@ def test_on_attestation_invalid_attestation(spec, state):
|
||||||
|
|
||||||
attestation = get_valid_attestation(spec, state, slot=block.slot)
|
attestation = get_valid_attestation(spec, state, slot=block.slot)
|
||||||
# make attestation invalid
|
# make attestation invalid
|
||||||
attestation.custody_bitfield[0:8] = [0, 0, 0, 0, 1, 1, 1, 1]
|
attestation.custody_bits[0:8] = [0, 0, 0, 0, 1, 1, 1, 1]
|
||||||
run_on_attestation(spec, state, store, attestation, False)
|
run_on_attestation(spec, state, store, attestation, False)
|
||||||
|
|
|
@ -67,12 +67,12 @@ def get_valid_attestation(spec, state, slot=None, signed=False):
|
||||||
)
|
)
|
||||||
|
|
||||||
committee_size = len(crosslink_committee)
|
committee_size = len(crosslink_committee)
|
||||||
aggregation_bitfield = Bitlist[spec.MAX_INDICES_PER_ATTESTATION](*([0] * committee_size))
|
aggregation_bits = Bitlist[spec.MAX_INDICES_PER_ATTESTATION](*([0] * committee_size))
|
||||||
custody_bitfield = Bitlist[spec.MAX_INDICES_PER_ATTESTATION](*([0] * committee_size))
|
custody_bits = Bitlist[spec.MAX_INDICES_PER_ATTESTATION](*([0] * committee_size))
|
||||||
attestation = spec.Attestation(
|
attestation = spec.Attestation(
|
||||||
aggregation_bitfield=aggregation_bitfield,
|
aggregation_bits=aggregation_bits,
|
||||||
data=attestation_data,
|
data=attestation_data,
|
||||||
custody_bitfield=custody_bitfield,
|
custody_bits=custody_bits,
|
||||||
)
|
)
|
||||||
fill_aggregate_attestation(spec, state, attestation)
|
fill_aggregate_attestation(spec, state, attestation)
|
||||||
if signed:
|
if signed:
|
||||||
|
@ -105,7 +105,7 @@ def sign_attestation(spec, state, attestation):
|
||||||
participants = spec.get_attesting_indices(
|
participants = spec.get_attesting_indices(
|
||||||
state,
|
state,
|
||||||
attestation.data,
|
attestation.data,
|
||||||
attestation.aggregation_bitfield,
|
attestation.aggregation_bits,
|
||||||
)
|
)
|
||||||
|
|
||||||
attestation.signature = sign_aggregate_attestation(spec, state, attestation.data, participants)
|
attestation.signature = sign_aggregate_attestation(spec, state, attestation.data, participants)
|
||||||
|
@ -135,7 +135,7 @@ def fill_aggregate_attestation(spec, state, attestation):
|
||||||
attestation.data.crosslink.shard,
|
attestation.data.crosslink.shard,
|
||||||
)
|
)
|
||||||
for i in range(len(crosslink_committee)):
|
for i in range(len(crosslink_committee)):
|
||||||
attestation.aggregation_bitfield[i] = True
|
attestation.aggregation_bits[i] = True
|
||||||
|
|
||||||
|
|
||||||
def add_attestation_to_state(spec, state, attestation, slot):
|
def add_attestation_to_state(spec, state, attestation, slot):
|
||||||
|
|
|
@ -275,14 +275,14 @@ def test_bad_crosslink_end_epoch(spec, state):
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_inconsistent_bitfields(spec, state):
|
def test_inconsistent_bits(spec, state):
|
||||||
attestation = get_valid_attestation(spec, state)
|
attestation = get_valid_attestation(spec, state)
|
||||||
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
||||||
|
|
||||||
custody_bitfield = deepcopy(attestation.aggregation_bitfield)
|
custody_bits = deepcopy(attestation.aggregation_bits)
|
||||||
custody_bitfield.append(False)
|
custody_bits.append(False)
|
||||||
|
|
||||||
attestation.custody_bitfield = custody_bitfield
|
attestation.custody_bits = custody_bits
|
||||||
|
|
||||||
sign_attestation(spec, state, attestation)
|
sign_attestation(spec, state, attestation)
|
||||||
|
|
||||||
|
@ -291,11 +291,11 @@ def test_inconsistent_bitfields(spec, state):
|
||||||
|
|
||||||
@with_phases(['phase0'])
|
@with_phases(['phase0'])
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_non_empty_custody_bitfield(spec, state):
|
def test_non_empty_custody_bits(spec, state):
|
||||||
attestation = get_valid_attestation(spec, state)
|
attestation = get_valid_attestation(spec, state)
|
||||||
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
||||||
|
|
||||||
attestation.custody_bitfield = deepcopy(attestation.aggregation_bitfield)
|
attestation.custody_bits = deepcopy(attestation.aggregation_bits)
|
||||||
|
|
||||||
sign_attestation(spec, state, attestation)
|
sign_attestation(spec, state, attestation)
|
||||||
|
|
||||||
|
@ -304,12 +304,12 @@ def test_non_empty_custody_bitfield(spec, state):
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_empty_aggregation_bitfield(spec, state):
|
def test_empty_aggregation_bits(spec, state):
|
||||||
attestation = get_valid_attestation(spec, state)
|
attestation = get_valid_attestation(spec, state)
|
||||||
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
||||||
|
|
||||||
attestation.aggregation_bitfield = Bitlist[spec.MAX_INDICES_PER_ATTESTATION](
|
attestation.aggregation_bits = Bitlist[spec.MAX_INDICES_PER_ATTESTATION](
|
||||||
*([0b0] * len(attestation.aggregation_bitfield)))
|
*([0b0] * len(attestation.aggregation_bits)))
|
||||||
|
|
||||||
sign_attestation(spec, state, attestation)
|
sign_attestation(spec, state, attestation)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from ..merkle_minimal import merkleize_chunks
|
from ..merkle_minimal import merkleize_chunks
|
||||||
from ..hash_function import hash
|
from ..hash_function import hash
|
||||||
from .ssz_typing import (
|
from .ssz_typing import (
|
||||||
SSZValue, SSZType, BasicValue, BasicType, Series, Elements, Bitfield, boolean, Container, List, Bytes,
|
SSZValue, SSZType, BasicValue, BasicType, Series, Elements, Bits, boolean, Container, List, Bytes,
|
||||||
Bitlist, Bitvector, uint,
|
Bitlist, Bitvector, uint,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ def item_length(typ: SSZType) -> int:
|
||||||
def chunk_count(typ: SSZType) -> int:
|
def chunk_count(typ: SSZType) -> int:
|
||||||
if isinstance(typ, BasicType):
|
if isinstance(typ, BasicType):
|
||||||
return 1
|
return 1
|
||||||
elif issubclass(typ, Bitfield):
|
elif issubclass(typ, Bits):
|
||||||
return (typ.length + 255) // 256
|
return (typ.length + 255) // 256
|
||||||
elif issubclass(typ, Elements):
|
elif issubclass(typ, Elements):
|
||||||
return (typ.length * item_length(typ.elem_type) + 31) // 32
|
return (typ.length * item_length(typ.elem_type) + 31) // 32
|
||||||
|
|
|
@ -353,11 +353,11 @@ class BitElementsType(ElementsType):
|
||||||
length: int
|
length: int
|
||||||
|
|
||||||
|
|
||||||
class Bitfield(BaseList, metaclass=BitElementsType):
|
class Bits(BaseList, metaclass=BitElementsType):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Bitlist(Bitfield):
|
class Bitlist(Bits):
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_fixed_size(cls):
|
def is_fixed_size(cls):
|
||||||
return False
|
return False
|
||||||
|
@ -367,7 +367,7 @@ class Bitlist(Bitfield):
|
||||||
return cls()
|
return cls()
|
||||||
|
|
||||||
|
|
||||||
class Bitvector(Bitfield):
|
class Bitvector(Bits):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def extract_args(cls, *args):
|
def extract_args(cls, *args):
|
||||||
|
|
Loading…
Reference in New Issue