Merge branch 'dev' into proto-merge-test-gen
This commit is contained in:
commit
3f61780260
|
@ -17,7 +17,7 @@ Core specifications for eth2.0 client validation can be found in [specs/core](sp
|
||||||
Accompanying documents can be found in [specs](specs) and include
|
Accompanying documents can be found in [specs](specs) and include
|
||||||
* [SimpleSerialize (SSZ) spec](specs/simple-serialize.md)
|
* [SimpleSerialize (SSZ) spec](specs/simple-serialize.md)
|
||||||
* [BLS signature verification](specs/bls_signature.md)
|
* [BLS signature verification](specs/bls_signature.md)
|
||||||
* [General test format](specs/test-format.md)
|
* [General test format](specs/test_formats/README.md)
|
||||||
* [Honest validator implementation doc](specs/validator/0_beacon-chain-validator.md)
|
* [Honest validator implementation doc](specs/validator/0_beacon-chain-validator.md)
|
||||||
* [Merkle proof formats](specs/light_client/merkle_proofs.md)
|
* [Merkle proof formats](specs/light_client/merkle_proofs.md)
|
||||||
* [Light client syncing protocol](specs/light_client/sync_protocol.md)
|
* [Light client syncing protocol](specs/light_client/sync_protocol.md)
|
||||||
|
|
|
@ -3,7 +3,7 @@ from copy import deepcopy
|
||||||
from py_ecc import bls
|
from py_ecc import bls
|
||||||
|
|
||||||
import eth2spec.phase0.spec as spec
|
import eth2spec.phase0.spec as spec
|
||||||
from eth2spec.utils.minimal_ssz import signed_root
|
from eth2spec.utils.minimal_ssz import signing_root
|
||||||
from eth2spec.phase0.spec import (
|
from eth2spec.phase0.spec import (
|
||||||
# constants
|
# constants
|
||||||
EMPTY_SIGNATURE,
|
EMPTY_SIGNATURE,
|
||||||
|
@ -110,7 +110,7 @@ def build_empty_block_for_next_slot(state):
|
||||||
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:
|
||||||
previous_block_header.state_root = state.hash_tree_root()
|
previous_block_header.state_root = state.hash_tree_root()
|
||||||
empty_block.previous_block_root = signed_root(previous_block_header)
|
empty_block.previous_block_root = signing_root(previous_block_header)
|
||||||
return empty_block
|
return empty_block
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ def build_deposit_data(state, pubkey, privkey, amount):
|
||||||
proof_of_possession=EMPTY_SIGNATURE,
|
proof_of_possession=EMPTY_SIGNATURE,
|
||||||
)
|
)
|
||||||
proof_of_possession = bls.sign(
|
proof_of_possession = bls.sign(
|
||||||
message_hash=signed_root(deposit_data),
|
message_hash=signing_root(deposit_data),
|
||||||
privkey=privkey,
|
privkey=privkey,
|
||||||
domain=get_domain(
|
domain=get_domain(
|
||||||
state.fork,
|
state.fork,
|
||||||
|
@ -170,7 +170,7 @@ def build_voluntary_exit(state, epoch, validator_index, privkey):
|
||||||
signature=EMPTY_SIGNATURE,
|
signature=EMPTY_SIGNATURE,
|
||||||
)
|
)
|
||||||
voluntary_exit.signature = bls.sign(
|
voluntary_exit.signature = bls.sign(
|
||||||
message_hash=signed_root(voluntary_exit),
|
message_hash=signing_root(voluntary_exit),
|
||||||
privkey=privkey,
|
privkey=privkey,
|
||||||
domain=get_domain(
|
domain=get_domain(
|
||||||
fork=state.fork,
|
fork=state.fork,
|
||||||
|
@ -229,12 +229,12 @@ def get_valid_proposer_slashing(state):
|
||||||
domain_type=spec.DOMAIN_BEACON_BLOCK,
|
domain_type=spec.DOMAIN_BEACON_BLOCK,
|
||||||
)
|
)
|
||||||
header_1.signature = bls.sign(
|
header_1.signature = bls.sign(
|
||||||
message_hash=signed_root(header_1),
|
message_hash=signing_root(header_1),
|
||||||
privkey=privkey,
|
privkey=privkey,
|
||||||
domain=domain,
|
domain=domain,
|
||||||
)
|
)
|
||||||
header_2.signature = bls.sign(
|
header_2.signature = bls.sign(
|
||||||
message_hash=signed_root(header_2),
|
message_hash=signing_root(header_2),
|
||||||
privkey=privkey,
|
privkey=privkey,
|
||||||
domain=domain,
|
domain=domain,
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import pytest
|
||||||
from py_ecc import bls
|
from py_ecc import bls
|
||||||
import eth2spec.phase0.spec as spec
|
import eth2spec.phase0.spec as spec
|
||||||
|
|
||||||
from eth2spec.utils.minimal_ssz import signed_root
|
from eth2spec.utils.minimal_ssz import signing_root
|
||||||
from eth2spec.phase0.spec import (
|
from eth2spec.phase0.spec import (
|
||||||
# constants
|
# constants
|
||||||
EMPTY_SIGNATURE,
|
EMPTY_SIGNATURE,
|
||||||
|
@ -300,7 +300,7 @@ def test_voluntary_exit(state):
|
||||||
signature=EMPTY_SIGNATURE,
|
signature=EMPTY_SIGNATURE,
|
||||||
)
|
)
|
||||||
voluntary_exit.signature = bls.sign(
|
voluntary_exit.signature = bls.sign(
|
||||||
message_hash=signed_root(voluntary_exit),
|
message_hash=signing_root(voluntary_exit),
|
||||||
privkey=privkeys[validator_index],
|
privkey=privkeys[validator_index],
|
||||||
domain=get_domain(
|
domain=get_domain(
|
||||||
fork=pre_state.fork,
|
fork=pre_state.fork,
|
||||||
|
@ -387,7 +387,7 @@ def test_transfer(state):
|
||||||
signature=EMPTY_SIGNATURE,
|
signature=EMPTY_SIGNATURE,
|
||||||
)
|
)
|
||||||
transfer.signature = bls.sign(
|
transfer.signature = bls.sign(
|
||||||
message_hash=signed_root(transfer),
|
message_hash=signing_root(transfer),
|
||||||
privkey=transfer_privkey,
|
privkey=transfer_privkey,
|
||||||
domain=get_domain(
|
domain=get_domain(
|
||||||
fork=pre_state.fork,
|
fork=pre_state.fork,
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
- [`xor`](#xor)
|
- [`xor`](#xor)
|
||||||
- [`hash`](#hash)
|
- [`hash`](#hash)
|
||||||
- [`hash_tree_root`](#hash_tree_root)
|
- [`hash_tree_root`](#hash_tree_root)
|
||||||
- [`signed_root`](#signed_root)
|
- [`signing_root`](#signing_root)
|
||||||
- [`get_temporary_block_header`](#get_temporary_block_header)
|
- [`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)
|
||||||
|
@ -664,9 +664,9 @@ Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future Ethere
|
||||||
|
|
||||||
`def hash_tree_root(object: SSZSerializable) -> Bytes32` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash).
|
`def hash_tree_root(object: SSZSerializable) -> Bytes32` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash).
|
||||||
|
|
||||||
### `signed_root`
|
### `signing_root`
|
||||||
|
|
||||||
`def signed_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#signed-roots) to compute signed messages.
|
`def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/simple-serialize.md#self-signed-containers) to compute signing messages.
|
||||||
|
|
||||||
### `get_temporary_block_header`
|
### `get_temporary_block_header`
|
||||||
|
|
||||||
|
@ -680,7 +680,7 @@ def get_temporary_block_header(block: BeaconBlock) -> BeaconBlockHeader:
|
||||||
previous_block_root=block.previous_block_root,
|
previous_block_root=block.previous_block_root,
|
||||||
state_root=ZERO_HASH,
|
state_root=ZERO_HASH,
|
||||||
block_body_root=hash_tree_root(block.body),
|
block_body_root=hash_tree_root(block.body),
|
||||||
# signed_root(block) is used for block id purposes so signature is a stub
|
# signing_root(block) is used for block id purposes so signature is a stub
|
||||||
signature=EMPTY_SIGNATURE,
|
signature=EMPTY_SIGNATURE,
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
@ -1327,7 +1327,7 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
|
||||||
# Verify the proof of possession
|
# Verify the proof of possession
|
||||||
proof_is_valid = bls_verify(
|
proof_is_valid = bls_verify(
|
||||||
pubkey=pubkey,
|
pubkey=pubkey,
|
||||||
message_hash=signed_root(deposit.data),
|
message_hash=signing_root(deposit.data),
|
||||||
signature=deposit.data.proof_of_possession,
|
signature=deposit.data.proof_of_possession,
|
||||||
domain=get_domain(
|
domain=get_domain(
|
||||||
state.fork,
|
state.fork,
|
||||||
|
@ -1707,7 +1707,7 @@ def cache_state(state: BeaconState) -> None:
|
||||||
state.latest_block_header.state_root = previous_slot_state_root
|
state.latest_block_header.state_root = previous_slot_state_root
|
||||||
|
|
||||||
# store latest known block for previous slot
|
# store latest known block for previous slot
|
||||||
state.latest_block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = signed_root(state.latest_block_header)
|
state.latest_block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = signing_root(state.latest_block_header)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Per-epoch processing
|
### Per-epoch processing
|
||||||
|
@ -2197,7 +2197,7 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
|
||||||
# Verify that the slots match
|
# Verify that the slots match
|
||||||
assert block.slot == state.slot
|
assert block.slot == state.slot
|
||||||
# Verify that the parent matches
|
# Verify that the parent matches
|
||||||
assert block.previous_block_root == signed_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 = get_temporary_block_header(block)
|
||||||
# Verify proposer is not slashed
|
# Verify proposer is not slashed
|
||||||
|
@ -2206,7 +2206,7 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None:
|
||||||
# Verify proposer signature
|
# Verify proposer signature
|
||||||
assert bls_verify(
|
assert bls_verify(
|
||||||
pubkey=proposer.pubkey,
|
pubkey=proposer.pubkey,
|
||||||
message_hash=signed_root(block),
|
message_hash=signing_root(block),
|
||||||
signature=block.signature,
|
signature=block.signature,
|
||||||
domain=get_domain(state.fork, get_current_epoch(state), DOMAIN_BEACON_BLOCK)
|
domain=get_domain(state.fork, get_current_epoch(state), DOMAIN_BEACON_BLOCK)
|
||||||
)
|
)
|
||||||
|
@ -2270,7 +2270,7 @@ def process_proposer_slashing(state: BeaconState,
|
||||||
for header in (proposer_slashing.header_1, proposer_slashing.header_2):
|
for header in (proposer_slashing.header_1, proposer_slashing.header_2):
|
||||||
assert bls_verify(
|
assert bls_verify(
|
||||||
pubkey=proposer.pubkey,
|
pubkey=proposer.pubkey,
|
||||||
message_hash=signed_root(header),
|
message_hash=signing_root(header),
|
||||||
signature=header.signature,
|
signature=header.signature,
|
||||||
domain=get_domain(state.fork, slot_to_epoch(header.slot), DOMAIN_BEACON_BLOCK)
|
domain=get_domain(state.fork, slot_to_epoch(header.slot), DOMAIN_BEACON_BLOCK)
|
||||||
)
|
)
|
||||||
|
@ -2396,7 +2396,7 @@ def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None:
|
||||||
# Verify signature
|
# Verify signature
|
||||||
assert bls_verify(
|
assert bls_verify(
|
||||||
pubkey=validator.pubkey,
|
pubkey=validator.pubkey,
|
||||||
message_hash=signed_root(exit),
|
message_hash=signing_root(exit),
|
||||||
signature=exit.signature,
|
signature=exit.signature,
|
||||||
domain=get_domain(state.fork, exit.epoch, DOMAIN_VOLUNTARY_EXIT)
|
domain=get_domain(state.fork, exit.epoch, DOMAIN_VOLUNTARY_EXIT)
|
||||||
)
|
)
|
||||||
|
@ -2441,7 +2441,7 @@ def process_transfer(state: BeaconState, transfer: Transfer) -> None:
|
||||||
# Verify that the signature is valid
|
# Verify that the signature is valid
|
||||||
assert bls_verify(
|
assert bls_verify(
|
||||||
pubkey=transfer.pubkey,
|
pubkey=transfer.pubkey,
|
||||||
message_hash=signed_root(transfer),
|
message_hash=signing_root(transfer),
|
||||||
signature=transfer.signature,
|
signature=transfer.signature,
|
||||||
domain=get_domain(state.fork, slot_to_epoch(transfer.slot), DOMAIN_TRANSFER)
|
domain=get_domain(state.fork, slot_to_epoch(transfer.slot), DOMAIN_TRANSFER)
|
||||||
)
|
)
|
||||||
|
|
|
@ -348,7 +348,7 @@ def process_bit_challenge(state: BeaconState,
|
||||||
challenger = state.validator_registry[challenge.challenger_index]
|
challenger = state.validator_registry[challenge.challenger_index]
|
||||||
assert bls_verify(
|
assert bls_verify(
|
||||||
pubkey=challenger.pubkey,
|
pubkey=challenger.pubkey,
|
||||||
message_hash=signed_root(challenge),
|
message_hash=signing_root(challenge),
|
||||||
signature=challenge.signature,
|
signature=challenge.signature,
|
||||||
domain=get_domain(state, get_current_epoch(state), DOMAIN_CUSTODY_BIT_CHALLENGE),
|
domain=get_domain(state, get_current_epoch(state), DOMAIN_CUSTODY_BIT_CHALLENGE),
|
||||||
)
|
)
|
||||||
|
|
|
@ -287,7 +287,7 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock],
|
||||||
|
|
||||||
# Check beacon block
|
# Check beacon block
|
||||||
beacon_block = beacon_blocks[block.slot]
|
beacon_block = beacon_blocks[block.slot]
|
||||||
assert block.beacon_block_root == signed_root(beacon_block)
|
assert block.beacon_block_root == signing_root(beacon_block)
|
||||||
assert beacon_block.slot <= block.slot:
|
assert beacon_block.slot <= block.slot:
|
||||||
|
|
||||||
# Check state root
|
# Check state root
|
||||||
|
@ -299,12 +299,12 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock],
|
||||||
else:
|
else:
|
||||||
parent_block = next(
|
parent_block = next(
|
||||||
block for block in valid_shard_blocks if
|
block for block in valid_shard_blocks if
|
||||||
signed_root(block) == candidate.previous_block_root
|
signing_root(block) == candidate.previous_block_root
|
||||||
, None)
|
, None)
|
||||||
assert parent_block != None
|
assert parent_block != None
|
||||||
assert parent_block.shard == block.shard
|
assert parent_block.shard == block.shard
|
||||||
assert parent_block.slot < block.slot
|
assert parent_block.slot < block.slot
|
||||||
assert signed_root(beacon_blocks[parent_block.slot]) == parent_block.beacon_chain_root
|
assert signing_root(beacon_blocks[parent_block.slot]) == parent_block.beacon_chain_root
|
||||||
|
|
||||||
# Check attestations
|
# Check attestations
|
||||||
assert len(block.attestations) <= MAX_SHARD_ATTESTIONS
|
assert len(block.attestations) <= MAX_SHARD_ATTESTIONS
|
||||||
|
@ -319,7 +319,7 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock],
|
||||||
assert proposer_index is not None
|
assert proposer_index is not None
|
||||||
assert bls_verify(
|
assert bls_verify(
|
||||||
pubkey=validators[proposer_index].pubkey,
|
pubkey=validators[proposer_index].pubkey,
|
||||||
message_hash=signed_root(block),
|
message_hash=signing_root(block),
|
||||||
signature=block.signature,
|
signature=block.signature,
|
||||||
domain=get_domain(beacon_state, slot_to_epoch(block.slot), DOMAIN_SHARD_PROPOSER)
|
domain=get_domain(beacon_state, slot_to_epoch(block.slot), DOMAIN_SHARD_PROPOSER)
|
||||||
)
|
)
|
||||||
|
@ -342,7 +342,7 @@ def is_valid_shard_attestation(valid_shard_blocks: List[ShardBlock],
|
||||||
# Check shard block
|
# Check shard block
|
||||||
shard_block = next(
|
shard_block = next(
|
||||||
block for block in valid_shard_blocks if
|
block for block in valid_shard_blocks if
|
||||||
signed_root(block) == candidate.attestation.data.shard_block_root
|
signing_root(block) == candidate.attestation.data.shard_block_root
|
||||||
, None)
|
, None)
|
||||||
assert shard_block != None
|
assert shard_block != None
|
||||||
assert shard_block.slot == attestation.data.slot
|
assert shard_block.slot == attestation.data.slot
|
||||||
|
|
|
@ -54,7 +54,7 @@ For convenience we alias:
|
||||||
|
|
||||||
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"`.
|
||||||
|
|
||||||
*Note*: In the function definitions below (`serialize`, `hash_tree_root`, `signed_root`, etc.) objects implicitly carry their type.
|
*Note*: In the function definitions below (`serialize`, `hash_tree_root`, `signing_root`, etc.) objects implicitly carry their type.
|
||||||
|
|
||||||
### `"uintN"`
|
### `"uintN"`
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ We now define Merkleization `hash_tree_root(value)` of an object `value` recursi
|
||||||
|
|
||||||
## Self-signed containers
|
## Self-signed containers
|
||||||
|
|
||||||
Let `value` be a self-signed container object. The convention is that the signature (e.g. a `"bytes96"` BLS12-381 signature) be the last field of `value`. Further, the signed message for `value` is `signed_root(value) = hash_tree_root(truncate_last(value))` where `truncate_last` truncates the last element of `value`.
|
Let `value` be a self-signed container object. The convention is that the signature (e.g. a `"bytes96"` BLS12-381 signature) be the last field of `value`. Further, the signed message for `value` is `signing_root(value) = hash_tree_root(truncate_last(value))` where `truncate_last` truncates the last element of `value`.
|
||||||
|
|
||||||
## Implementations
|
## Implementations
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ In phase 0, all incoming validator deposits originate from the Ethereum 1.0 PoW
|
||||||
To submit a deposit:
|
To submit a deposit:
|
||||||
|
|
||||||
* Pack the validator's [initialization parameters](#initialization) into `deposit_input`, a [`DepositInput`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#depositinput) SSZ object.
|
* Pack the validator's [initialization parameters](#initialization) into `deposit_input`, a [`DepositInput`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#depositinput) SSZ object.
|
||||||
* Let `proof_of_possession` be the result of `bls_sign` of the `signed_root(deposit_input)` with `domain=DOMAIN_DEPOSIT`.
|
* Let `proof_of_possession` be the result of `bls_sign` of the `signing_root(deposit_input)` with `domain=DOMAIN_DEPOSIT`.
|
||||||
* Set `deposit_input.proof_of_possession = proof_of_possession`.
|
* Set `deposit_input.proof_of_possession = proof_of_possession`.
|
||||||
* Let `amount` be the amount in Gwei to be deposited by the validator where `MIN_DEPOSIT_AMOUNT <= amount <= MAX_DEPOSIT_AMOUNT`.
|
* Let `amount` be the amount in Gwei to be deposited by the validator where `MIN_DEPOSIT_AMOUNT <= amount <= MAX_DEPOSIT_AMOUNT`.
|
||||||
* Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `deposit` along with `serialize(deposit_input)` as the singular `bytes` input along with a deposit `amount` in Gwei.
|
* Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `deposit` along with `serialize(deposit_input)` as the singular `bytes` input along with a deposit `amount` in Gwei.
|
||||||
|
@ -152,7 +152,7 @@ _Note:_ there might be "skipped" slots between the `parent` and `block`. These s
|
||||||
|
|
||||||
##### Parent root
|
##### Parent root
|
||||||
|
|
||||||
Set `block.previous_block_root = signed_root(parent)`.
|
Set `block.previous_block_root = signing_root(parent)`.
|
||||||
|
|
||||||
##### State root
|
##### State root
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ Set `block.signature = block_signature` where `block_signature` is defined as:
|
||||||
```python
|
```python
|
||||||
block_signature = bls_sign(
|
block_signature = bls_sign(
|
||||||
privkey=validator.privkey, # privkey store locally, not in state
|
privkey=validator.privkey, # privkey store locally, not in state
|
||||||
message_hash=signed_root(block),
|
message_hash=signing_root(block),
|
||||||
domain=get_domain(
|
domain=get_domain(
|
||||||
fork=fork, # `fork` is the fork object at the slot `block.slot`
|
fork=fork, # `fork` is the fork object at the slot `block.slot`
|
||||||
epoch=slot_to_epoch(block.slot),
|
epoch=slot_to_epoch(block.slot),
|
||||||
|
@ -255,11 +255,11 @@ Set `attestation_data.shard = shard` where `shard` is the shard associated with
|
||||||
|
|
||||||
##### Beacon block root
|
##### Beacon block root
|
||||||
|
|
||||||
Set `attestation_data.beacon_block_root = signed_root(head_block)`.
|
Set `attestation_data.beacon_block_root = signing_root(head_block)`.
|
||||||
|
|
||||||
##### Target root
|
##### Target root
|
||||||
|
|
||||||
Set `attestation_data.target_root = signed_root(epoch_boundary)` where `epoch_boundary` is the block at the most recent epoch boundary.
|
Set `attestation_data.target_root = signing_root(epoch_boundary)` where `epoch_boundary` is the block at the most recent epoch boundary.
|
||||||
|
|
||||||
_Note:_ This can be looked up in the state using:
|
_Note:_ This can be looked up in the state using:
|
||||||
* Let `epoch_start_slot = get_epoch_start_slot(get_current_epoch(head_state))`.
|
* Let `epoch_start_slot = get_epoch_start_slot(get_current_epoch(head_state))`.
|
||||||
|
|
|
@ -205,7 +205,7 @@ def truncate(container):
|
||||||
return truncated_class(**kwargs)
|
return truncated_class(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
def signed_root(container):
|
def signing_root(container):
|
||||||
return hash_tree_root(truncate(container))
|
return hash_tree_root(truncate(container))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue