Sane SSZ object default values (#963)

This commit is contained in:
Justin 2019-04-19 18:26:54 +10:00 committed by GitHub
parent 23fffe6490
commit 39d0822602
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 14 additions and 108 deletions

View File

@ -51,7 +51,6 @@
- [`hash`](#hash) - [`hash`](#hash)
- [`hash_tree_root`](#hash_tree_root) - [`hash_tree_root`](#hash_tree_root)
- [`signing_root`](#signing_root) - [`signing_root`](#signing_root)
- [`get_temporary_block_header`](#get_temporary_block_header)
- [`slot_to_epoch`](#slot_to_epoch) - [`slot_to_epoch`](#slot_to_epoch)
- [`get_previous_epoch`](#get_previous_epoch) - [`get_previous_epoch`](#get_previous_epoch)
- [`get_current_epoch`](#get_current_epoch) - [`get_current_epoch`](#get_current_epoch)
@ -201,13 +200,10 @@ These configurations are updated for releases, but may be out of sync during `de
| Name | Value | | Name | Value |
| - | - | | - | - |
| `GENESIS_FORK_VERSION` | `int_to_bytes4(0)` |
| `GENESIS_SLOT` | `0` | | `GENESIS_SLOT` | `0` |
| `GENESIS_EPOCH` | `0` | | `GENESIS_EPOCH` | `0` |
| `GENESIS_START_SHARD` | `0` |
| `FAR_FUTURE_EPOCH` | `2**64 - 1` | | `FAR_FUTURE_EPOCH` | `2**64 - 1` |
| `ZERO_HASH` | `int_to_bytes32(0)` | | `ZERO_HASH` | `int_to_bytes32(0)` |
| `EMPTY_SIGNATURE` | `int_to_bytes96(0)` |
| `BLS_WITHDRAWAL_PREFIX_BYTE` | `int_to_bytes1(0)` | | `BLS_WITHDRAWAL_PREFIX_BYTE` | `int_to_bytes1(0)` |
### Time parameters ### Time parameters
@ -640,23 +636,6 @@ Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future Ethere
`def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](../simple-serialize.md#self-signed-containers) to compute signing messages. `def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](../simple-serialize.md#self-signed-containers) to compute signing messages.
### `get_temporary_block_header`
```python
def get_temporary_block_header(block: BeaconBlock) -> BeaconBlockHeader:
"""
Return the block header corresponding to a block with ``state_root`` set to ``ZERO_HASH``.
"""
return BeaconBlockHeader(
slot=block.slot,
previous_block_root=block.previous_block_root,
state_root=ZERO_HASH,
block_body_root=hash_tree_root(block.body),
# signing_root(block) is used for block id purposes so signature is a stub
signature=EMPTY_SIGNATURE,
)
```
### `slot_to_epoch` ### `slot_to_epoch`
```python ```python
@ -1345,35 +1324,7 @@ When enough full deposits have been made to the deposit contract, an `Eth2Genesi
* `genesis_eth1_data.deposit_count` is the `deposit_count` contained in the `Eth2Genesis` log. * `genesis_eth1_data.deposit_count` is the `deposit_count` contained in the `Eth2Genesis` log.
* `genesis_eth1_data.block_hash` is the hash of the Ethereum 1.0 block that emitted the `Eth2Genesis` log. * `genesis_eth1_data.block_hash` is the hash of the Ethereum 1.0 block that emitted the `Eth2Genesis` log.
* Let `genesis_state = get_genesis_beacon_state(genesis_validator_deposits, genesis_time, genesis_eth1_data)`. * Let `genesis_state = get_genesis_beacon_state(genesis_validator_deposits, genesis_time, genesis_eth1_data)`.
* Let `genesis_block = get_empty_block()`. * Let `genesis_block = BeaconBlock(state_root=hash_tree_root(genesis_state))`.
* Set `genesis_block.state_root = hash_tree_root(genesis_state)`.
```python
def get_empty_block() -> BeaconBlock:
"""
Get an empty ``BeaconBlock``.
"""
return BeaconBlock(
slot=GENESIS_SLOT,
previous_block_root=ZERO_HASH,
state_root=ZERO_HASH,
body=BeaconBlockBody(
randao_reveal=EMPTY_SIGNATURE,
eth1_data=Eth1Data(
deposit_root=ZERO_HASH,
deposit_count=0,
block_hash=ZERO_HASH,
),
proposer_slashings=[],
attester_slashings=[],
attestations=[],
deposits=[],
voluntary_exits=[],
transfers=[],
),
signature=EMPTY_SIGNATURE,
)
```
```python ```python
def get_genesis_beacon_state(genesis_validator_deposits: List[Deposit], def get_genesis_beacon_state(genesis_validator_deposits: List[Deposit],
@ -1382,50 +1333,7 @@ def get_genesis_beacon_state(genesis_validator_deposits: List[Deposit],
""" """
Get the genesis ``BeaconState``. Get the genesis ``BeaconState``.
""" """
state = BeaconState( state = BeaconState(genesis_time=genesis_time, latest_eth1_data=genesis_eth1_data)
# Misc
slot=GENESIS_SLOT,
genesis_time=genesis_time,
fork=Fork(
previous_version=GENESIS_FORK_VERSION,
current_version=GENESIS_FORK_VERSION,
epoch=GENESIS_EPOCH,
),
# Validator registry
validator_registry=[],
balances=[],
# Randomness and committees
latest_randao_mixes=Vector([ZERO_HASH for _ in range(LATEST_RANDAO_MIXES_LENGTH)]),
latest_start_shard=GENESIS_START_SHARD,
# Finality
previous_epoch_attestations=[],
current_epoch_attestations=[],
previous_justified_epoch=GENESIS_EPOCH,
current_justified_epoch=GENESIS_EPOCH,
previous_justified_root=ZERO_HASH,
current_justified_root=ZERO_HASH,
justification_bitfield=0,
finalized_epoch=GENESIS_EPOCH,
finalized_root=ZERO_HASH,
# Recent state
current_crosslinks=Vector([Crosslink(epoch=GENESIS_EPOCH, previous_crosslink_root=ZERO_HASH, crosslink_data_root=ZERO_HASH) for _ in range(SHARD_COUNT)]),
previous_crosslinks=Vector([Crosslink(epoch=GENESIS_EPOCH, previous_crosslink_root=ZERO_HASH, crosslink_data_root=ZERO_HASH) for _ in range(SHARD_COUNT)]),
latest_block_roots=Vector([ZERO_HASH for _ in range(SLOTS_PER_HISTORICAL_ROOT)]),
latest_state_roots=Vector([ZERO_HASH for _ in range(SLOTS_PER_HISTORICAL_ROOT)]),
latest_active_index_roots=Vector([ZERO_HASH for _ in range(LATEST_ACTIVE_INDEX_ROOTS_LENGTH)]),
latest_slashed_balances=Vector([0 for _ in range(LATEST_SLASHED_EXIT_LENGTH)]),
latest_block_header=get_temporary_block_header(get_empty_block()),
historical_roots=[],
# Ethereum 1.0 chain data
latest_eth1_data=genesis_eth1_data,
eth1_data_votes=[],
deposit_index=0,
)
# Process genesis deposits # Process genesis deposits
for deposit in genesis_validator_deposits: for deposit in genesis_validator_deposits:
@ -1929,7 +1837,11 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
# Verify that the parent matches # Verify that the parent matches
assert block.previous_block_root == signing_root(state.latest_block_header) assert block.previous_block_root == signing_root(state.latest_block_header)
# Save current block as the new latest block # Save current block as the new latest block
state.latest_block_header = get_temporary_block_header(block) state.latest_block_header = BeaconBlockHeader(
slot=block.slot,
previous_block_root=block.previous_block_root,
block_body_root=hash_tree_root(block.body),
)
# Verify proposer is not slashed # Verify proposer is not slashed
proposer = state.validator_registry[get_beacon_proposer_index(state)] proposer = state.validator_registry[get_beacon_proposer_index(state)]
assert not proposer.slashed assert not proposer.slashed
@ -2132,8 +2044,6 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
activation_epoch=FAR_FUTURE_EPOCH, activation_epoch=FAR_FUTURE_EPOCH,
exit_epoch=FAR_FUTURE_EPOCH, exit_epoch=FAR_FUTURE_EPOCH,
withdrawable_epoch=FAR_FUTURE_EPOCH, withdrawable_epoch=FAR_FUTURE_EPOCH,
slashed=False,
high_balance=0
) )
# Note: In phase 2 registry indices that have been withdrawn for a long time will be recycled. # Note: In phase 2 registry indices that have been withdrawn for a long time will be recycled.

View File

@ -9,6 +9,7 @@ This is a **work in progress** describing typing, serialization and Merkleizatio
- [Basic types](#basic-types) - [Basic types](#basic-types)
- [Composite types](#composite-types) - [Composite types](#composite-types)
- [Aliases](#aliases) - [Aliases](#aliases)
- [Default values](#default-values)
- [Serialization](#serialization) - [Serialization](#serialization)
- [`"uintN"`](#uintn) - [`"uintN"`](#uintn)
- [`"bool"`](#bool) - [`"bool"`](#bool)
@ -50,6 +51,10 @@ For convenience we alias:
* `"bytes"` to `["byte"]` (this is *not* a basic type) * `"bytes"` to `["byte"]` (this is *not* a basic type)
* `"bytesN"` to `["byte", N]` (this is *not* a basic type) * `"bytesN"` to `["byte", N]` (this is *not* a basic type)
### Default values
The default value of a type upon initialization is recursively defined using `0` for `"uintN"`, `False` for `"bool"`, and `[]` for lists.
## Serialization ## Serialization
We recursively define the `serialize` function which consumes an object `value` (of the type specified) and returns a bytestring of type `"bytes"`. We recursively define the `serialize` function which consumes an object `value` (of the type specified) and returns a bytestring of type `"bytes"`.

View File

@ -24,7 +24,6 @@ def build_deposit_data(state,
pubkey=pubkey, pubkey=pubkey,
withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + withdrawal_cred[1:], withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + withdrawal_cred[1:],
amount=amount, amount=amount,
proof_of_possession=spec.EMPTY_SIGNATURE,
) )
deposit_data.proof_of_possession = bls.sign( deposit_data.proof_of_possession = bls.sign(
message_hash=signing_root(deposit_data), message_hash=signing_root(deposit_data),

View File

@ -9,13 +9,13 @@ import eth2spec.phase0.spec as spec
from eth2spec.utils.minimal_ssz import signing_root from eth2spec.utils.minimal_ssz import signing_root
from eth2spec.phase0.spec import ( from eth2spec.phase0.spec import (
# constants # constants
EMPTY_SIGNATURE,
ZERO_HASH, ZERO_HASH,
# SSZ # SSZ
Attestation, Attestation,
AttestationData, AttestationData,
AttestationDataAndCustodyBit, AttestationDataAndCustodyBit,
AttesterSlashing, AttesterSlashing,
BeaconBlock,
BeaconBlockHeader, BeaconBlockHeader,
Deposit, Deposit,
DepositData, DepositData,
@ -30,7 +30,6 @@ from eth2spec.phase0.spec import (
get_crosslink_committees_at_slot, get_crosslink_committees_at_slot,
get_current_epoch, get_current_epoch,
get_domain, get_domain,
get_empty_block,
get_epoch_start_slot, get_epoch_start_slot,
get_genesis_beacon_state, get_genesis_beacon_state,
get_previous_epoch, get_previous_epoch,
@ -115,7 +114,7 @@ def create_genesis_state(num_validators, deposit_data_leaves=None):
def build_empty_block_for_next_slot(state): def build_empty_block_for_next_slot(state):
empty_block = get_empty_block() empty_block = BeaconBlock()
empty_block.slot = state.slot + 1 empty_block.slot = state.slot + 1
previous_block_header = deepcopy(state.latest_block_header) previous_block_header = deepcopy(state.latest_block_header)
if previous_block_header.state_root == spec.ZERO_HASH: if previous_block_header.state_root == spec.ZERO_HASH:
@ -130,7 +129,6 @@ def build_deposit_data(state, pubkey, privkey, amount):
# insecurely use pubkey as withdrawal key as well # insecurely use pubkey as withdrawal key as well
withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:], withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(pubkey)[1:],
amount=amount, amount=amount,
signature=EMPTY_SIGNATURE,
) )
signature = bls.sign( signature = bls.sign(
message_hash=signing_root(deposit_data), message_hash=signing_root(deposit_data),
@ -185,7 +183,6 @@ def build_voluntary_exit(state, epoch, validator_index, privkey):
voluntary_exit = VoluntaryExit( voluntary_exit = VoluntaryExit(
epoch=epoch, epoch=epoch,
validator_index=validator_index, validator_index=validator_index,
signature=EMPTY_SIGNATURE,
) )
voluntary_exit.signature = bls.sign( voluntary_exit.signature = bls.sign(
message_hash=signing_root(voluntary_exit), message_hash=signing_root(voluntary_exit),
@ -235,7 +232,6 @@ def get_valid_proposer_slashing(state):
previous_block_root=ZERO_HASH, previous_block_root=ZERO_HASH,
state_root=ZERO_HASH, state_root=ZERO_HASH,
block_body_root=ZERO_HASH, block_body_root=ZERO_HASH,
signature=EMPTY_SIGNATURE,
) )
header_2 = deepcopy(header_1) header_2 = deepcopy(header_1)
header_2.previous_block_root = b'\x02' * 32 header_2.previous_block_root = b'\x02' * 32
@ -304,7 +300,6 @@ def get_valid_attestation(state, slot=None):
aggregation_bitfield=aggregation_bitfield, aggregation_bitfield=aggregation_bitfield,
data=attestation_data, data=attestation_data,
custody_bitfield=custody_bitfield, custody_bitfield=custody_bitfield,
aggregate_signature=EMPTY_SIGNATURE,
) )
participants = get_attesting_indices( participants = get_attesting_indices(
state, state,

View File

@ -8,7 +8,6 @@ import eth2spec.phase0.spec as spec
from eth2spec.utils.minimal_ssz import signing_root from eth2spec.utils.minimal_ssz import signing_root
from eth2spec.phase0.spec import ( from eth2spec.phase0.spec import (
# constants # constants
EMPTY_SIGNATURE,
ZERO_HASH, ZERO_HASH,
# SSZ # SSZ
Deposit, Deposit,
@ -350,7 +349,6 @@ def test_voluntary_exit(state):
voluntary_exit = VoluntaryExit( voluntary_exit = VoluntaryExit(
epoch=get_current_epoch(pre_state), epoch=get_current_epoch(pre_state),
validator_index=validator_index, validator_index=validator_index,
signature=EMPTY_SIGNATURE,
) )
voluntary_exit.signature = bls.sign( voluntary_exit.signature = bls.sign(
message_hash=signing_root(voluntary_exit), message_hash=signing_root(voluntary_exit),
@ -398,7 +396,6 @@ def test_transfer(state):
fee=0, fee=0,
slot=pre_state.slot + 1, slot=pre_state.slot + 1,
pubkey=transfer_pubkey, pubkey=transfer_pubkey,
signature=EMPTY_SIGNATURE,
) )
transfer.signature = bls.sign( transfer.signature = bls.sign(
message_hash=signing_root(transfer), message_hash=signing_root(transfer),