Merge branch 'dev' into shardblobs

This commit is contained in:
protolambda 2021-04-06 19:49:48 +02:00
commit cb29a7ed91
No known key found for this signature in database
GPG Key ID: EC89FDBB2B4C7623
9 changed files with 51 additions and 40 deletions

View File

@ -277,6 +277,12 @@ ALTAIR_HARDCODED_SSZ_DEP_CONSTANTS = {
}
ALTAIR_INVAIANT_CHECKS = '''
assert (
TIMELY_HEAD_WEIGHT + TIMELY_SOURCE_WEIGHT + TIMELY_TARGET_WEIGHT + SYNC_REWARD_WEIGHT + PROPOSER_WEIGHT
) == WEIGHT_DENOMINATOR'''
def is_phase0(fork):
return fork == PHASE0
@ -331,6 +337,7 @@ def objects_to_spec(spec_object: SpecObject, imports: str, fork: str, ordered_cl
if is_altair(fork):
altair_ssz_dep_constants_verification = '\n'.join(map(lambda x: 'assert %s == %s' % (x, spec_object.ssz_dep_constants[x]), ALTAIR_HARDCODED_SSZ_DEP_CONSTANTS))
spec += '\n\n\n' + altair_ssz_dep_constants_verification
spec += '\n' + ALTAIR_INVAIANT_CHECKS
spec += '\n'
return spec

View File

@ -88,9 +88,10 @@ Altair is the first beacon chain hard fork. Its main features are:
| `TIMELY_SOURCE_WEIGHT` | `uint64(12)` |
| `TIMELY_TARGET_WEIGHT` | `uint64(24)` |
| `SYNC_REWARD_WEIGHT` | `uint64(8)` |
| `PROPOSER_WEIGHT` | `uint64(8)` |
| `WEIGHT_DENOMINATOR` | `uint64(64)` |
*Note*: The sum of the weight fractions (7/8) plus the proposer inclusion fraction (1/8) equals 1.
*Note*: The sum of the weights equal `WEIGHT_DENOMINATOR`.
### Misc
@ -412,7 +413,7 @@ def slash_validator(state: BeaconState,
if whistleblower_index is None:
whistleblower_index = proposer_index
whistleblower_reward = Gwei(validator.effective_balance // WHISTLEBLOWER_REWARD_QUOTIENT)
proposer_reward = Gwei(whistleblower_reward // PROPOSER_REWARD_QUOTIENT)
proposer_reward = Gwei(whistleblower_reward * PROPOSER_WEIGHT // WEIGHT_DENOMINATOR)
increase_balance(state, proposer_index, proposer_reward)
increase_balance(state, whistleblower_index, Gwei(whistleblower_reward - proposer_reward))
```
@ -477,7 +478,8 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
proposer_reward_numerator += get_base_reward(state, index) * weight
# Reward proposer
proposer_reward = Gwei(proposer_reward_numerator // (WEIGHT_DENOMINATOR * PROPOSER_REWARD_QUOTIENT))
proposer_reward_denominator = (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT) * WEIGHT_DENOMINATOR // PROPOSER_WEIGHT
proposer_reward = Gwei(proposer_reward_numerator // proposer_reward_denominator)
increase_balance(state, get_beacon_proposer_index(state), proposer_reward)
```
@ -529,29 +531,26 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
```python
def process_sync_committee(state: BeaconState, aggregate: SyncAggregate) -> None:
# Verify sync committee aggregate signature signing over the previous slot block root
previous_slot = Slot(max(int(state.slot), 1) - 1)
committee_indices = get_sync_committee_indices(state, get_current_epoch(state))
included_indices = [index for index, bit in zip(committee_indices, aggregate.sync_committee_bits) if bit]
committee_pubkeys = state.current_sync_committee.pubkeys
included_pubkeys = [pubkey for pubkey, bit in zip(committee_pubkeys, aggregate.sync_committee_bits) if bit]
participant_pubkeys = [pubkey for pubkey, bit in zip(committee_pubkeys, aggregate.sync_committee_bits) if bit]
previous_slot = max(state.slot, Slot(1)) - Slot(1)
domain = get_domain(state, DOMAIN_SYNC_COMMITTEE, compute_epoch_at_slot(previous_slot))
signing_root = compute_signing_root(get_block_root_at_slot(state, previous_slot), domain)
assert eth2_fast_aggregate_verify(included_pubkeys, signing_root, aggregate.sync_committee_signature)
assert eth2_fast_aggregate_verify(participant_pubkeys, signing_root, aggregate.sync_committee_signature)
# Compute the maximum sync rewards for the slot
# Compute participant and proposer rewards
total_active_increments = get_total_active_balance(state) // EFFECTIVE_BALANCE_INCREMENT
total_base_rewards = Gwei(get_base_reward_per_increment(state) * total_active_increments)
max_epoch_rewards = Gwei(total_base_rewards * SYNC_REWARD_WEIGHT // WEIGHT_DENOMINATOR)
max_slot_rewards = Gwei(max_epoch_rewards * len(included_indices) // len(committee_indices) // SLOTS_PER_EPOCH)
max_participant_rewards = Gwei(total_base_rewards * SYNC_REWARD_WEIGHT // WEIGHT_DENOMINATOR // SLOTS_PER_EPOCH)
participant_reward = Gwei(max_participant_rewards // SYNC_COMMITTEE_SIZE)
proposer_reward = Gwei(participant_reward * PROPOSER_WEIGHT // (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT))
# Compute the participant and proposer sync rewards
committee_effective_balance = get_total_balance(state, set(included_indices))
for included_index in included_indices:
effective_balance = state.validators[included_index].effective_balance
inclusion_reward = Gwei(max_slot_rewards * effective_balance // committee_effective_balance)
proposer_reward = Gwei(inclusion_reward // PROPOSER_REWARD_QUOTIENT)
# Apply participant and proposer rewards
committee_indices = get_sync_committee_indices(state, get_current_epoch(state))
participant_indices = [index for index, bit in zip(committee_indices, aggregate.sync_committee_bits) if bit]
for participant_index in participant_indices:
increase_balance(state, participant_index, participant_reward)
increase_balance(state, get_beacon_proposer_index(state), proposer_reward)
increase_balance(state, included_index, inclusion_reward - proposer_reward)
```
### Epoch processing

View File

@ -92,7 +92,7 @@ The following validations MUST pass before forwarding the `signed_contribution_a
- _[REJECT]_ `contribution_and_proof.selection_proof` selects the validator as an aggregator for the slot -- i.e. `is_sync_committee_aggregator(state, contribution.slot, contribution_and_proof.selection_proof)` returns `True`.
- _[REJECT]_ The aggregator's validator index is within the current sync committee --
i.e. `state.validators[contribution_and_proof.aggregator_index].pubkey in state.current_sync_committee.pubkeys`.
- _[REJECT]_ The `contribution_and_proof.selection_proof` is a valid signature of the `contribution.slot` by the validator with index `contribution_and_proof.aggregator_index`.
- _[REJECT]_ The `contribution_and_proof.selection_proof` is a valid signature of the `SyncCommitteeSigningData` derived from the `contribution` by the validator with index `contribution_and_proof.aggregator_index`.
- _[REJECT]_ The aggregator signature, `signed_contribution_and_proof.signature`, is valid.
- _[REJECT]_ The aggregate signature is valid for the message `beacon_block_root` and aggregate pubkey derived from the participation info in `aggregation_bits` for the subcommittee specified by the `subcommittee_index`.
@ -183,6 +183,7 @@ Request and Response remain unchanged. A `ForkDigest`-context is used to select
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
| `fork_version` | Chunk SSZ type |
| ------------------------ | -------------------------- |
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |
@ -195,6 +196,7 @@ Request and Response remain unchanged. A `ForkDigest`-context is used to select
Per `context = compute_fork_digest(fork_version, genesis_validators_root)`:
| `fork_version` | Chunk SSZ type |
| ------------------------ | -------------------------- |
| `GENESIS_FORK_VERSION` | `phase0.SignedBeaconBlock` |
| `ALTAIR_FORK_VERSION` | `altair.SignedBeaconBlock` |

View File

@ -220,8 +220,7 @@ Given a collection of the best seen `contributions` (with no repeating `subcommi
the proposer processes them as follows:
```python
def process_sync_committee_contributions(state: BeaconState,
block: BeaconBlock,
def process_sync_committee_contributions(block: BeaconBlock,
contributions: Set[SyncCommitteeContribution]) -> None:
sync_aggregate = SyncAggregate()
signatures = []
@ -310,11 +309,11 @@ Each slot some sync committee members in each subcommittee are selected to aggre
##### Aggregation selection
A validator is selected to aggregate based on the computation in `is_sync_committee_aggregator` where `state` is a `BeaconState` as supplied to `get_sync_committee_slot_signature` and `signature` is the BLS signature returned by `get_sync_committee_slot_signature`.
A validator is selected to aggregate based on the computation in `is_sync_committee_aggregator` where `signature` is the BLS signature returned by `get_sync_committee_selection_proof`.
The signature function takes a `BeaconState` with the relevant sync committees for the queried `slot` (i.e. `state.slot` is within the span covered by the current or next sync committee period), the `subcommittee_index` equal to the `subnet_id`, and the `privkey` is the BLS private key associated with the validator.
```python
def get_sync_committee_slot_signature(state: BeaconState, slot: Slot,
def get_sync_committee_selection_proof(state: BeaconState, slot: Slot,
subcommittee_index: uint64, privkey: int) -> BLSSignature:
domain = get_domain(state, DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF, compute_epoch_at_slot(slot))
signing_data = SyncCommitteeSigningData(
@ -326,7 +325,7 @@ def get_sync_committee_slot_signature(state: BeaconState, slot: Slot,
```
```python
def is_sync_committee_aggregator(state: BeaconState, signature: BLSSignature) -> bool:
def is_sync_committee_aggregator(signature: BLSSignature) -> bool:
modulo = max(1, SYNC_COMMITTEE_SIZE // SYNC_COMMITTEE_SUBNET_COUNT // TARGET_AGGREGATORS_PER_SYNC_SUBCOMMITTEE)
return bytes_to_uint64(hash(signature)[0:8]) % modulo == 0
```
@ -378,7 +377,7 @@ def get_contribution_and_proof(state: BeaconState,
aggregator_index: ValidatorIndex,
contribution: SyncCommitteeContribution,
privkey: int) -> ContributionAndProof:
selection_proof = get_sync_committee_slot_signature(
selection_proof = get_sync_committee_selection_proof(
state,
contribution.slot,
contribution.subcommittee_index,
@ -391,7 +390,7 @@ def get_contribution_and_proof(state: BeaconState,
)
```
Then `signed_contribution_and_proof = SignedContributionAndProof(message=contribution_and_proof, signature=signature)` is constructed and broadast. Where `signature` is obtained from:
Then `signed_contribution_and_proof = SignedContributionAndProof(message=contribution_and_proof, signature=signature)` is constructed and broadcast. Where `signature` is obtained from:
```python
def get_contribution_and_proof_signature(state: BeaconState,

View File

@ -12,7 +12,7 @@
- [Configuration](#configuration)
- [Misc](#misc)
- [New containers](#new-containers)
- [DASSample](#dassample)
- [`DASSample`](#dassample)
- [Helper functions](#helper-functions)
- [Reverse bit ordering](#reverse-bit-ordering)
- [`reverse_bit_order`](#reverse_bit_order)
@ -45,7 +45,7 @@ We define the following Python custom types for type hinting and readability:
## New containers
### DASSample
### `DASSample`
```python
class DASSample(Container):

View File

@ -589,7 +589,7 @@ def get_aggregate_and_proof(state: BeaconState,
)
```
Then `signed_aggregate_and_proof = SignedAggregateAndProof(message=aggregate_and_proof, signature=signature)` is constructed and broadast. Where `signature` is obtained from:
Then `signed_aggregate_and_proof = SignedAggregateAndProof(message=aggregate_and_proof, signature=signature)` is constructed and broadcast. Where `signature` is obtained from:
```python
def get_aggregate_and_proof_signature(state: BeaconState,

View File

@ -75,7 +75,7 @@ We define the following Python custom types for type hinting and readability:
| Name | SSZ equivalent | Description |
| - | - | - |
| `Shard` | `uint64` | A shard number |
| `BLSCommitment` | `bytes48` | A G1 curve point |
| `BLSCommitment` | `Bytes48` | A G1 curve point |
| `BLSPoint` | `uint256` | A number `x` in the range `0 <= x < MODULUS` |
## Constants
@ -114,7 +114,7 @@ The following values are (non-configurable) constants used throughout the specif
| - | - |
| `G1_SETUP` | Type `List[G1]`. The G1-side trusted setup `[G, G*s, G*s**2....]`; note that the first point is the generator. |
| `G2_SETUP` | Type `List[G2]`. The G2-side trusted setup `[G, G*s, G*s**2....]` |
| `ROOT_OF_UNITY` | `pow(PRIMITIVE_ROOT_OF_UNITY, (MODULUS - 1) // (MAX_SAMPLES_PER_BLOCK * POINTS_PER_SAMPLE, MODULUS)` |
| `ROOT_OF_UNITY` | `pow(PRIMITIVE_ROOT_OF_UNITY, (MODULUS - 1) // (MAX_SAMPLES_PER_BLOCK * POINTS_PER_SAMPLE), MODULUS)` |
### Gwei values
@ -241,7 +241,7 @@ class PendingShardHeader(Container):
# Who voted for the header
votes: Bitlist[MAX_VALIDATORS_PER_COMMITTEE]
# Has this header been confirmed?
confirmed: bool
confirmed: boolean
```
### `ShardBlobReference`
@ -572,7 +572,7 @@ def process_shard_header(state: BeaconState,
assert body_summary.degree_proof == G1_SETUP[0]
assert (
bls.Pairing(body_summary.degree_proof, G2_SETUP[0])
== bls.Pairing(body_summary.commitment.point, G2_SETUP[-body_summary.commitment.length]))
== bls.Pairing(body_summary.commitment.point, G2_SETUP[-body_summary.commitment.length])
)
# Get the correct pending header list
@ -704,7 +704,7 @@ def process_pending_headers(state: BeaconState) -> None:
for slot_index in range(SLOTS_PER_EPOCH):
for shard in range(SHARD_COUNT):
state.grandparent_epoch_confirmed_commitments[shard][slot_index] = DataCommitment()
confirmed_headers = [candidate in state.previous_epoch_pending_shard_headers if candidate.confirmed]
confirmed_headers = [candidate for candidate in state.previous_epoch_pending_shard_headers if candidate.confirmed]
for header in confirmed_headers:
state.grandparent_epoch_confirmed_commitments[c.shard][c.slot % SLOTS_PER_EPOCH] = c.commitment
```
@ -752,7 +752,7 @@ def reset_pending_headers(state: BeaconState) -> None:
next_epoch = get_current_epoch(state) + 1
next_epoch_start_slot = compute_start_slot_at_epoch(next_epoch)
for slot in range(next_epoch_start_slot, next_epoch_start_slot + SLOTS_IN_EPOCH):
for index in range(get_committee_count_per_slot(next_epoch):
for index in range(get_committee_count_per_slot(next_epoch)):
shard = compute_shard_from_committee_index(state, slot, index)
committee_length = len(get_beacon_committee(state, slot, shard))
state.current_epoch_pending_shard_headers.append(PendingShardHeader(

View File

@ -1 +1 @@
1.1.0-alpha.1
1.1.0-alpha.3

View File

@ -126,8 +126,7 @@ def compute_sync_committee_participant_reward(spec, state, participant_index, co
inclusion_reward = compute_sync_committee_inclusion_reward(
spec, state, participant_index, committee, committee_bits,
)
proposer_reward = spec.Gwei(inclusion_reward // spec.PROPOSER_REWARD_QUOTIENT)
return spec.Gwei((inclusion_reward - proposer_reward) * multiplicities[participant_index])
return spec.Gwei(inclusion_reward * multiplicities[participant_index])
def compute_sync_committee_proposer_reward(spec, state, committee, committee_bits):
@ -138,7 +137,12 @@ def compute_sync_committee_proposer_reward(spec, state, committee, committee_bit
inclusion_reward = compute_sync_committee_inclusion_reward(
spec, state, index, committee, committee_bits,
)
proposer_reward += spec.Gwei(inclusion_reward // spec.PROPOSER_REWARD_QUOTIENT)
proposer_reward_denominator = (
(spec.WEIGHT_DENOMINATOR - spec.PROPOSER_WEIGHT)
* spec.WEIGHT_DENOMINATOR
// spec.PROPOSER_WEIGHT
)
proposer_reward += spec.Gwei((inclusion_reward * spec.WEIGHT_DENOMINATOR) // proposer_reward_denominator)
return proposer_reward