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

Revamp balances and incentivisation #949

Merged
merged 31 commits into from
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6f56c37
Simplify get_justification_and_finalization_deltas
JustinDrake Apr 17, 2019
cc92ee9
Update 0_beacon-chain.md
JustinDrake Apr 17, 2019
0f8b1c5
Update 0_beacon-chain.md
JustinDrake Apr 18, 2019
3f9a65f
Update 0_beacon-chain.md
JustinDrake Apr 18, 2019
91921d8
Update 0_beacon-chain.md
JustinDrake Apr 18, 2019
fb641bc
Merge branch 'dev' into JustinDrake-patch-14
JustinDrake Apr 18, 2019
7a435d2
Merge branch 'dev' into JustinDrake-patch-14
hwwhww Apr 19, 2019
f908c8d
Revamped balances and incentivisation
JustinDrake Apr 20, 2019
d067a9f
Merge branch 'dev' into JustinDrake-patch-14
JustinDrake Apr 20, 2019
4d26ae2
Bug fix
JustinDrake Apr 20, 2019
356ef15
Merge branch 'JustinDrake-patch-14' of github.com:ethereum/eth2.0-spe…
JustinDrake Apr 20, 2019
f07b94e
Fixes
JustinDrake Apr 20, 2019
d700ea4
Fixes
JustinDrake Apr 20, 2019
06f475a
Fixes
JustinDrake Apr 20, 2019
e184f0b
Fix
JustinDrake Apr 20, 2019
7642abf
Fix|
JustinDrake Apr 20, 2019
d6644ed
Fix test
JustinDrake Apr 20, 2019
c123fb1
Single effective balance per review by Vitalik—significant simplifica…
JustinDrake Apr 22, 2019
6903f2e
Update 0_beacon-chain.md
JustinDrake Apr 22, 2019
81ee59b
Update 0_beacon-chain.md
JustinDrake Apr 22, 2019
f2d885f
Address Danny's comments
JustinDrake Apr 24, 2019
5587c44
Update test_libs/pyspec/tests/test_sanity.py
djrtwo Apr 24, 2019
de01ffd
Merge branch 'dev' into JustinDrake-patch-14
JustinDrake Apr 24, 2019
df64eee
Start fixing tests
JustinDrake Apr 24, 2019
55f042a
More fixes
JustinDrake Apr 24, 2019
c37789d
Tests fixed
JustinDrake Apr 24, 2019
b361fdb
bug
JustinDrake Apr 24, 2019
4734b22
simplify
JustinDrake Apr 24, 2019
9c2fa02
Update test_libs/pyspec/tests/test_sanity.py
hwwhww Apr 24, 2019
b1e1510
Update 0_beacon-chain.md
JustinDrake Apr 24, 2019
20d65e0
pr feedback
djrtwo Apr 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
389 changes: 160 additions & 229 deletions specs/core/0_beacon-chain.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions specs/light_client/sync_protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ def verify_block_validity_proof(proof: BlockValidityProof, validator_memory: Val
assert proof.shard_parent_block.beacon_chain_root == hash_tree_root(proof.header)
committee = compute_committee(proof.header, validator_memory)
# Verify that we have >=50% support
support_balance = sum([v.high_balance for i, v in enumerate(committee) if get_bitfield_bit(proof.shard_bitfield, i) is True])
total_balance = sum([v.high_balance for i, v in enumerate(committee)])
support_balance = sum([v.effective_balance for i, v in enumerate(committee) if get_bitfield_bit(proof.shard_bitfield, i) is True])
total_balance = sum([v.effective_balance for i, v in enumerate(committee)])
assert support_balance * 2 > total_balance
# Verify shard attestations
group_public_key = bls_aggregate_pubkeys([
Expand Down
4 changes: 2 additions & 2 deletions specs/validator/0_beacon-chain-validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ A validator has two primary responsibilities to the beacon chain -- [proposing b

### Block proposal

A validator is expected to propose a [`BeaconBlock`](../core/0_beacon-chain.md#beaconblock) at the beginning of any slot during which `get_beacon_proposer_index(state, slot)` returns the validator's `validator_index`. To propose, the validator selects the `BeaconBlock`, `parent`, that in their view of the fork choice is the head of the chain during `slot - 1`. The validator is to create, sign, and broadcast a `block` that is a child of `parent` and that executes a valid [beacon chain state transition](../core/0_beacon-chain.md#beacon-chain-state-transition-function).
A validator is expected to propose a [`BeaconBlock`](../core/0_beacon-chain.md#beaconblock) at the beginning of any slot during which `get_beacon_proposer_index(state)` returns the validator's `validator_index`. To propose, the validator selects the `BeaconBlock`, `parent`, that in their view of the fork choice is the head of the chain during `slot - 1`. The validator is to create, sign, and broadcast a `block` that is a child of `parent` and that executes a valid [beacon chain state transition](../core/0_beacon-chain.md#beacon-chain-state-transition-function).

There is one proposer per slot, so if there are N active validators any individual validator will on average be assigned to propose once per N slots (e.g. at 312500 validators = 10 million ETH, that's once per ~3 weeks).

Expand Down Expand Up @@ -368,7 +368,7 @@ def get_committee_assignment(
return assignment
```

A validator can use the following function to see if they are supposed to propose during their assigned committee slot. This function can only be run during the slot in question and can not reliably be used to predict in advance.
A validator can use the following function to see if they are supposed to propose during their assigned committee slot. This function can only be run during the slot in question. Proposer selection is only stable within the context of the current epoch.

```python
def is_proposer_at_slot(state: BeaconState,
Expand Down
2 changes: 0 additions & 2 deletions test_libs/pyspec/eth2spec/phase0/state_transition.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
BeaconState,
BeaconBlock,
Slot,
process_proposer_attestation_rewards,
)


Expand Down Expand Up @@ -52,7 +51,6 @@ def process_operations(state: BeaconState, block: BeaconBlock) -> None:
spec.MAX_ATTESTATIONS,
spec.process_attestation,
)
process_proposer_attestation_rewards(state)

assert len(block.body.deposits) == expected_deposit_count(state)
process_operation_type(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

import eth2spec.phase0.spec as spec
from eth2spec.phase0.spec import (
get_balance,
get_beacon_proposer_index,
process_attester_slashing,
)
from tests.helpers import (
get_balance,
get_valid_attester_slashing,
next_epoch,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import eth2spec.phase0.spec as spec

from eth2spec.phase0.spec import (
get_balance,
ZERO_HASH,
process_deposit,
)
from tests.helpers import (
get_balance,
build_deposit,
privkeys,
pubkeys,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

import eth2spec.phase0.spec as spec
from eth2spec.phase0.spec import (
get_balance,
get_current_epoch,
process_proposer_slashing,
)
from tests.helpers import (
get_balance,
get_valid_proposer_slashing,
)

Expand Down
10 changes: 4 additions & 6 deletions test_libs/pyspec/tests/block_processing/test_process_transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@

from eth2spec.phase0.spec import (
get_active_validator_indices,
get_balance,
get_beacon_proposer_index,
get_current_epoch,
process_transfer,
set_balance,
)
from tests.helpers import (
get_valid_transfer,
Expand Down Expand Up @@ -75,7 +73,7 @@ def test_success_withdrawable(state):
def test_success_active_above_max_effective(state):
sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
amount = spec.MAX_EFFECTIVE_BALANCE // 32
set_balance(state, sender_index, spec.MAX_EFFECTIVE_BALANCE + amount)
state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + amount
transfer = get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0)

pre_state, post_state = run_transfer_processing(state, transfer)
Expand All @@ -86,7 +84,7 @@ def test_success_active_above_max_effective(state):
def test_active_but_transfer_past_effective_balance(state):
sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
amount = spec.MAX_EFFECTIVE_BALANCE // 32
set_balance(state, sender_index, spec.MAX_EFFECTIVE_BALANCE)
state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE
transfer = get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0)

pre_state, post_state = run_transfer_processing(state, transfer, False)
Expand All @@ -107,7 +105,7 @@ def test_incorrect_slot(state):
def test_insufficient_balance(state):
sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
amount = spec.MAX_EFFECTIVE_BALANCE
set_balance(state, sender_index, spec.MAX_EFFECTIVE_BALANCE)
state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE
transfer = get_valid_transfer(state, sender_index=sender_index, amount=amount + 1, fee=0)

# un-activate so validator can transfer
Expand Down Expand Up @@ -140,4 +138,4 @@ def test_invalid_pubkey(state):

pre_state, post_state = run_transfer_processing(state, transfer, False)

return pre_state, transfer, post_state
return pre_state, transfer, post_state
12 changes: 8 additions & 4 deletions test_libs/pyspec/tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
# functions
convert_to_indexed,
get_active_validator_indices,
get_balance,
get_attesting_indices,
get_block_root,
get_block_root_at_slot,
get_crosslink_committees_at_slot,
get_current_epoch,
get_domain,
Expand All @@ -53,6 +53,10 @@
pubkey_to_privkey = {pubkey: privkey for privkey, pubkey in zip(privkeys, pubkeys)}


def get_balance(state, index):
return state.balances[index]


def set_bitfield_bit(bitfield, i):
"""
Set the bit in ``bitfield`` at position ``i`` to ``1``.
Expand Down Expand Up @@ -150,16 +154,16 @@ def build_attestation_data(state, slot, shard):
if slot == state.slot:
block_root = build_empty_block_for_next_slot(state).previous_block_root
else:
block_root = get_block_root(state, slot)
block_root = get_block_root_at_slot(state, slot)

current_epoch_start_slot = get_epoch_start_slot(get_current_epoch(state))
if slot < current_epoch_start_slot:
print(slot)
epoch_boundary_root = get_block_root(state, get_epoch_start_slot(get_previous_epoch(state)))
epoch_boundary_root = get_block_root(state, get_previous_epoch(state))
elif slot == current_epoch_start_slot:
epoch_boundary_root = block_root
else:
epoch_boundary_root = get_block_root(state, current_epoch_start_slot)
epoch_boundary_root = get_block_root(state, get_current_epoch(state))

if slot < current_epoch_start_slot:
justified_epoch = state.previous_justified_epoch
Expand Down
20 changes: 8 additions & 12 deletions test_libs/pyspec/tests/test_sanity.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@
VoluntaryExit,
# functions
get_active_validator_indices,
get_balance,
get_beacon_proposer_index,
get_block_root,
get_block_root_at_slot,
get_state_root,
get_current_epoch,
get_domain,
get_state_root,
advance_slot,
cache_state,
set_balance,
slot_to_epoch,
verify_merkle_branch,
hash,
)
Expand All @@ -37,6 +34,7 @@
get_merkle_root,
)
from .helpers import (
get_balance,
build_deposit_data,
build_empty_block_for_next_slot,
fill_aggregate_attestation,
Expand All @@ -52,7 +50,6 @@
# mark entire file as 'sanity'
pytestmark = pytest.mark.sanity


def check_finality(state,
prev_state,
current_justified_changed,
Expand Down Expand Up @@ -96,7 +93,7 @@ def test_empty_block_transition(state):
state_transition(test_state, block)

assert len(test_state.eth1_data_votes) == len(state.eth1_data_votes) + 1
assert get_block_root(test_state, state.slot) == block.previous_block_root
assert get_block_root_at_slot(test_state, state.slot) == block.previous_block_root

return state, [block], test_state

Expand All @@ -110,7 +107,7 @@ def test_skipped_slots(state):

assert test_state.slot == block.slot
for slot in range(state.slot, test_state.slot):
assert get_block_root(test_state, slot) == block.previous_block_root
assert get_block_root_at_slot(test_state, slot) == block.previous_block_root

return state, [block], test_state

Expand All @@ -124,7 +121,7 @@ def test_empty_epoch_transition(state):

assert test_state.slot == block.slot
for slot in range(state.slot, test_state.slot):
assert get_block_root(test_state, slot) == block.previous_block_root
assert get_block_root_at_slot(test_state, slot) == block.previous_block_root

return state, [block], test_state

Expand Down Expand Up @@ -303,6 +300,7 @@ def test_deposit_top_up(state):


def test_attestation(state):
state.slot = spec.SLOTS_PER_EPOCH
test_state = deepcopy(state)
attestation = get_valid_attestation(state)

Expand All @@ -316,8 +314,6 @@ def test_attestation(state):

assert len(test_state.current_epoch_attestations) == len(state.current_epoch_attestations) + 1

proposer_index = get_beacon_proposer_index(test_state)
assert test_state.balances[proposer_index] > state.balances[proposer_index]

#
# Epoch transition should move to previous_epoch_attestations
Expand Down Expand Up @@ -441,7 +437,7 @@ def test_balance_driven_status_transitions(state):
assert pre_state.validator_registry[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH

# set validator balance to below ejection threshold
set_balance(pre_state, validator_index, spec.EJECTION_BALANCE - 1)
pre_state.validator_registry[validator_index].effective_balance = spec.EJECTION_BALANCE

post_state = deepcopy(pre_state)
#
Expand Down
3 changes: 2 additions & 1 deletion tests/phase0/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
VoluntaryExit,
# functions
get_block_root,
get_block_root_at_slot,
get_current_epoch,
get_domain,
get_empty_block,
Expand Down Expand Up @@ -141,7 +142,7 @@ def build_attestation_data(state, slot, shard):
if epoch_start_slot == slot:
epoch_boundary_root = block_root
else:
get_block_root(state, epoch_start_slot)
epoch_boundary_root = get_block_root(state, get_current_epoch(state))

if slot < epoch_start_slot:
justified_block_root = state.previous_justified_root
Expand Down