Sane SSZ object default values (#963)
This commit is contained in:
parent
23fffe6490
commit
39d0822602
|
@ -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.
|
||||||
|
|
|
@ -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"`.
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in New Issue