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

#1244 without "5 slots is a Slot" #1251

Merged
merged 16 commits into from
Jul 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion configs/constant_presets/mainnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ EFFECTIVE_BALANCE_INCREMENT: 1000000000
GENESIS_FORK_VERSION: 0x00000000
# 0, GENESIS_EPOCH is derived from this constant
GENESIS_SLOT: 0
BLS_WITHDRAWAL_PREFIX: 0
BLS_WITHDRAWAL_PREFIX: 0x00


# Time parameters
Expand Down
2 changes: 1 addition & 1 deletion configs/constant_presets/minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ EFFECTIVE_BALANCE_INCREMENT: 1000000000
GENESIS_FORK_VERSION: 0x00000000
# 0, GENESIS_EPOCH is derived from this constant
GENESIS_SLOT: 0
BLS_WITHDRAWAL_PREFIX: 0
BLS_WITHDRAWAL_PREFIX: 0x00


# Time parameters
Expand Down
6 changes: 3 additions & 3 deletions scripts/build_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
)
from eth2spec.utils.ssz.ssz_typing import (
bit, boolean, Container, List, Vector, uint64,
Bytes4, Bytes8, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
Bytes1, Bytes4, Bytes8, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
)
from eth2spec.utils.bls import (
bls_aggregate_pubkeys,
Expand Down Expand Up @@ -53,7 +53,7 @@
)
from eth2spec.utils.ssz.ssz_typing import (
bit, boolean, Container, List, Vector, Bytes, uint64,
Bytes4, Bytes8, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
Bytes1, Bytes4, Bytes8, Bytes32, Bytes48, Bytes96, Bitlist, Bitvector,
)
from eth2spec.utils.bls import (
bls_aggregate_pubkeys,
Expand Down Expand Up @@ -185,7 +185,7 @@ def combine_constants(old_constants: Dict[str, str], new_constants: Dict[str, st

ignored_dependencies = [
'bit', 'boolean', 'Vector', 'List', 'Container', 'Hash', 'BLSPubkey', 'BLSSignature', 'Bytes', 'BytesN'
'Bytes4', 'Bytes32', 'Bytes48', 'Bytes96', 'Bitlist', 'Bitvector',
'Bytes1', 'Bytes4', 'Bytes32', 'Bytes48', 'Bytes96', 'Bitlist', 'Bitvector',
'uint8', 'uint16', 'uint32', 'uint64', 'uint128', 'uint256',
'bytes' # to be removed after updating spec doc
]
Expand Down
19 changes: 9 additions & 10 deletions scripts/function_puller.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,14 @@ def get_spec(file_name: str) -> SpecObject:
row[i] = row[i].strip().strip('`')
if '`' in row[i]:
row[i] = row[i][:row[i].find('`')]
if row[1].startswith('uint') or row[1].startswith('Bytes'):
is_constant_def = True
if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_':
is_constant_def = False
for c in row[0]:
if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':
is_constant_def = False
if is_constant_def:
constants[row[0]] = row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')
elif row[1].startswith('uint') or row[1].startswith('Bytes'):
custom_types[row[0]] = row[1]
else:
eligible = True
if row[0][0] not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_':
eligible = False
for c in row[0]:
if c not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789':
eligible = False
if eligible:
constants[row[0]] = row[1].replace('**TBD**', '0x1234567890123456789012345678901234567890')
return functions, custom_types, constants, ssz_objects, inserts
38 changes: 16 additions & 22 deletions specs/core/0_beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
- [State list lengths](#state-list-lengths)
- [Rewards and penalties](#rewards-and-penalties)
- [Max operations per block](#max-operations-per-block)
- [Signature domains](#signature-domains)
- [Signature domain types](#signature-domain-types)
- [Containers](#containers)
- [Misc dependencies](#misc-dependencies)
- [`Fork`](#fork)
Expand Down Expand Up @@ -164,6 +164,8 @@ The following values are (non-configurable) constants used throughout the specif
| `BASE_REWARDS_PER_EPOCH` | `5` |
| `DEPOSIT_CONTRACT_TREE_DEPTH` | `2**5` (= 32) |
| `SECONDS_PER_DAY` | `86400` |
| `JUSTIFICATION_BITS_LENGTH` | `4` |
| `ENDIANNESS` | `'little'` |

## Configuration

Expand All @@ -181,8 +183,6 @@ The following values are (non-configurable) constants used throughout the specif
| `SHUFFLE_ROUND_COUNT` | `90` |
| `MIN_GENESIS_ACTIVE_VALIDATOR_COUNT` | `2**16` (= 65,536) |
| `MIN_GENESIS_TIME` | `1578009600` (Jan 3, 2020) |
| `JUSTIFICATION_BITS_LENGTH` | `4` |
| `ENDIANNESS` | `'little'` |

- 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.)

Expand All @@ -201,7 +201,7 @@ The following values are (non-configurable) constants used throughout the specif
| - | - |
| `GENESIS_SLOT` | `Slot(0)` |
| `GENESIS_EPOCH` | `Epoch(0)` |
| `BLS_WITHDRAWAL_PREFIX` | `0` |
| `BLS_WITHDRAWAL_PREFIX` | `Bytes1(b'\x00')` |

### Time parameters

Expand All @@ -214,20 +214,18 @@ The following values are (non-configurable) constants used throughout the specif
| `SLOTS_PER_ETH1_VOTING_PERIOD` | `2**10` (= 1,024) | slots | ~1.7 hours |
| `SLOTS_PER_HISTORICAL_ROOT` | `2**13` (= 8,192) | slots | ~13 hours |
| `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `2**8` (= 256) | epochs | ~27 hours |
| `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days |
| `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days |
| `MAX_EPOCHS_PER_CROSSLINK` | `2**6` (= 64) | epochs | ~7 hours |
| `MIN_EPOCHS_TO_INACTIVITY_PENALTY` | `2**2` (= 4) | epochs | 25.6 minutes |

- `MAX_EPOCHS_PER_CROSSLINK` should be a small constant times `SHARD_COUNT // SLOTS_PER_EPOCH`.

### State list lengths

| Name | Value | Unit | Duration |
| - | - | :-: | :-: |
| `EPOCHS_PER_HISTORICAL_VECTOR` | `2**16` (= 65,536) | epochs | ~0.8 years |
| `EPOCHS_PER_SLASHINGS_VECTOR` | `2**13` (= 8,192) | epochs | ~36 days |
| `HISTORICAL_ROOTS_LIMIT` | `2**24` (= 16,777,216) | historical roots | ~26,131 years |
| `VALIDATOR_REGISTRY_LIMIT` | `2**40` (= 1,099,511,627,776) | validator spots | |
| `VALIDATOR_REGISTRY_LIMIT` | `2**40` (= 1,099,511,627,776) | validator spots |

### Rewards and penalties

Expand Down Expand Up @@ -547,7 +545,7 @@ class BeaconState(Container):
#### `integer_squareroot`

```python
def integer_squareroot(n: uint64) -> int:
def integer_squareroot(n: uint64) -> uint64:
"""
Return the largest integer ``x`` such that ``x**2 <= n``.
"""
Expand All @@ -570,17 +568,17 @@ def xor(bytes1: Bytes32, bytes2: Bytes32) -> Bytes32:
```

```python
def int_to_bytes(integer: uint64, length: uint64) -> bytes:
def int_to_bytes(n: uint64, length: uint64) -> bytes:
"""
Return the ``length``-byte serialization of ``integer``.
Return the ``length``-byte serialization of ``n``.
"""
return integer.to_bytes(length, ENDIANNESS)
return n.to_bytes(length, ENDIANNESS)
```

#### `bytes_to_int`

```python
def bytes_to_int(data: bytes) -> int:
def bytes_to_int(data: bytes) -> uint64:
"""
Return the integer deserialization of ``data``.
"""
Expand Down Expand Up @@ -715,7 +713,6 @@ def compute_shuffled_index(index: ValidatorIndex, index_count: uint64, seed: Has
Return the shuffled validator index corresponding to ``seed`` (and ``index_count``).
"""
assert index < index_count
assert index_count <= 2**40

# Swap or not (https://link.springer.com/content/pdf/10.1007%2F978-3-642-32009-5_1.pdf)
# See the 'generalized domain' algorithm on page 3
Expand Down Expand Up @@ -853,7 +850,7 @@ def get_active_validator_indices(state: BeaconState, epoch: Epoch) -> Sequence[V
#### `get_validator_churn_limit`

```python
def get_validator_churn_limit(state: BeaconState) -> int:
def get_validator_churn_limit(state: BeaconState) -> uint64:
"""
Return the validator churn limit for the current epoch.
"""
Expand All @@ -876,7 +873,7 @@ def get_seed(state: BeaconState, epoch: Epoch) -> Hash:
#### `get_committee_count`

```python
def get_committee_count(state: BeaconState, epoch: Epoch) -> int:
def get_committee_count(state: BeaconState, epoch: Epoch) -> uint64:
"""
Return the number of committees at ``epoch``.
"""
Expand Down Expand Up @@ -921,7 +918,7 @@ def get_start_shard(state: BeaconState, epoch: Epoch) -> Shard:
#### `get_shard_delta`

```python
def get_shard_delta(state: BeaconState, epoch: Epoch) -> int:
def get_shard_delta(state: BeaconState, epoch: Epoch) -> uint64:
"""
Return the number of shards to increment ``state.start_shard`` at ``epoch``.
"""
Expand Down Expand Up @@ -1699,7 +1696,7 @@ 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, thus the deposit domain is retrieved directly from `compute_domain`
# 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
Expand Down Expand Up @@ -1759,10 +1756,7 @@ def process_transfer(state: BeaconState, transfer: Transfer) -> None:
state.balances[transfer.sender] >= transfer.amount + transfer.fee + MAX_EFFECTIVE_BALANCE
)
# Verify that the pubkey is valid
assert (
state.validators[transfer.sender].withdrawal_credentials ==
int_to_bytes(BLS_WITHDRAWAL_PREFIX, length=1) + hash(transfer.pubkey)[1:]
)
assert state.validators[transfer.sender].withdrawal_credentials == BLS_WITHDRAWAL_PREFIX + hash(transfer.pubkey)[1:]
# Verify that the signature is valid
assert bls_verify(transfer.pubkey, signing_root(transfer), transfer.signature, get_domain(state, DOMAIN_TRANSFER))
# Process the transfer
Expand Down
4 changes: 2 additions & 2 deletions specs/core/0_deposit-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ The amount of ETH (rounded down to the closest Gwei) sent to the deposit contrac

One of the `DepositData` fields is `withdrawal_credentials`. It is a commitment to credentials for withdrawing validator balance (e.g. to another validator, or to shards). The first byte of `withdrawal_credentials` is a version number. As of now, the only expected format is as follows:

- `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX_BYTE`
- `withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:]` where `withdrawal_pubkey` is a BLS pubkey
* `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`
* `withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:]` where `withdrawal_pubkey` is a BLS pubkey

The private key corresponding to `withdrawal_pubkey` will be required to initiate a withdrawal. It can be stored separately until a withdrawal is required, e.g. in cold storage.

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 @@ -87,8 +87,8 @@ A secondary withdrawal private key, `withdrawal_privkey`, must also be securely

The validator constructs their `withdrawal_credentials` via the following:

- Set `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX_BYTE`.
- Set `withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:]`.
* Set `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`.
* Set `withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:]`.

### Submit deposit

Expand Down
4 changes: 2 additions & 2 deletions test_libs/pyspec/eth2spec/test/helpers/deposits.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def prepare_genesis_deposits(spec, genesis_validator_count, amount, signed=False
pubkey = pubkeys[validator_index]
privkey = privkeys[validator_index]
# insecurely use pubkey as withdrawal key if no credentials provided
withdrawal_credentials = spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(pubkey)[1:]
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
deposit, root, deposit_data_list = build_deposit(
spec,
None,
Expand All @@ -89,7 +89,7 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c

# insecurely use pubkey as withdrawal key if no credentials provided
if withdrawal_credentials is None:
withdrawal_credentials = spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(pubkey)[1:]
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]

deposit, root, deposit_data_list = build_deposit(
spec,
Expand Down
2 changes: 1 addition & 1 deletion test_libs/pyspec/eth2spec/test/helpers/genesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
def build_mock_validator(spec, i: int, balance: int):
pubkey = pubkeys[i]
# insecurely use pubkey as withdrawal key as well
withdrawal_credentials = spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(pubkey)[1:]
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkey)[1:]
return spec.Validator(
pubkey=pubkeys[i],
withdrawal_credentials=withdrawal_credentials,
Expand Down
2 changes: 1 addition & 1 deletion test_libs/pyspec/eth2spec/test/helpers/transfers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def get_valid_transfer(spec, state, slot=None, sender_index=None,

# ensure withdrawal_credentials reproducible
state.validators[transfer.sender].withdrawal_credentials = (
spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(transfer.pubkey)[1:]
spec.BLS_WITHDRAWAL_PREFIX + spec.hash(transfer.pubkey)[1:]
)

return transfer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def test_invalid_sig_top_up(spec, state):
def test_invalid_withdrawal_credentials_top_up(spec, state):
validator_index = 0
amount = spec.MAX_EFFECTIVE_BALANCE // 4
withdrawal_credentials = spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(b"junk")[1:]
withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + spec.hash(b"junk")[1:]
deposit = prepare_state_and_deposit(
spec,
state,
Expand Down
3 changes: 2 additions & 1 deletion test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,8 @@ def is_fixed_size(cls):
return True


# Helpers for common BytesN types.
# Helpers for common BytesN types
Bytes1: BytesType = BytesN[1]
Bytes4: BytesType = BytesN[4]
Bytes8: BytesType = BytesN[8]
Bytes32: BytesType = BytesN[32]
Expand Down