eth2.0-specs/test_libs/pyspec/eth2spec/test/helpers/block.py

74 lines
2.6 KiB
Python
Raw Normal View History

2019-05-15 16:36:32 +00:00
from copy import deepcopy
from eth2spec.test.helpers.keys import privkeys
from eth2spec.utils.bls import bls_sign, only_with_bls
2019-05-31 23:51:09 +00:00
from eth2spec.utils.ssz.ssz_impl import signing_root, hash_tree_root
2019-05-15 16:36:32 +00:00
# Fully ignore the function if BLS is off, beacon-proposer index calculation is slow.
@only_with_bls()
2019-05-30 20:57:18 +00:00
def sign_block(spec, state, block, proposer_index=None):
assert state.slot <= block.slot
if proposer_index is None:
if block.slot == state.slot:
2019-06-30 09:56:14 +00:00
proposer_index = spec.get_proposer_index(state)
else:
2019-05-30 20:57:18 +00:00
if spec.slot_to_epoch(state.slot) + 1 > spec.slot_to_epoch(block.slot):
print("warning: block slot far away, and no proposer index manually given."
" Signing block is slow due to transition for proposer index calculation.")
# use stub state to get proposer index of future slot
stub_state = deepcopy(state)
2019-05-30 20:57:18 +00:00
spec.process_slots(stub_state, block.slot)
2019-06-30 09:56:14 +00:00
proposer_index = spec.get_proposer_index(stub_state)
2019-05-15 16:36:32 +00:00
privkey = privkeys[proposer_index]
block.body.randao_reveal = bls_sign(
2019-05-15 16:36:32 +00:00
privkey=privkey,
2019-05-30 20:57:18 +00:00
message_hash=hash_tree_root(spec.slot_to_epoch(block.slot)),
domain=spec.get_domain(
2019-05-15 16:36:32 +00:00
state,
2019-05-30 20:57:18 +00:00
message_epoch=spec.slot_to_epoch(block.slot),
2019-05-15 16:36:32 +00:00
domain_type=spec.DOMAIN_RANDAO,
)
)
block.signature = bls_sign(
2019-05-15 16:36:32 +00:00
message_hash=signing_root(block),
privkey=privkey,
2019-05-30 20:57:18 +00:00
domain=spec.get_domain(
2019-05-15 16:36:32 +00:00
state,
spec.DOMAIN_BEACON_PROPOSER,
2019-05-30 20:57:18 +00:00
spec.slot_to_epoch(block.slot)))
2019-05-15 16:36:32 +00:00
2019-05-30 20:57:18 +00:00
def apply_empty_block(spec, state):
"""
Transition via an empty block (on current slot, assuming no block has been applied yet).
:return: the empty block that triggered the transition.
"""
2019-05-30 20:57:18 +00:00
block = build_empty_block(spec, state, signed=True)
spec.state_transition(state, block)
return block
2019-05-30 20:57:18 +00:00
def build_empty_block(spec, state, slot=None, signed=False):
2019-05-15 16:36:32 +00:00
if slot is None:
slot = state.slot
2019-05-30 20:57:18 +00:00
empty_block = spec.BeaconBlock()
2019-05-15 16:36:32 +00:00
empty_block.slot = slot
2019-06-09 19:41:21 +00:00
empty_block.body.eth1_data.deposit_count = state.eth1_deposit_index
2019-06-15 14:09:50 +00:00
previous_block_header = deepcopy(state.latest_block_header)
2019-06-30 15:10:22 +00:00
if previous_block_header.state_root == spec.Hash():
2019-05-15 16:36:32 +00:00
previous_block_header.state_root = state.hash_tree_root()
2019-05-27 17:09:52 +00:00
empty_block.parent_root = signing_root(previous_block_header)
2019-05-15 16:36:32 +00:00
if signed:
2019-05-30 20:57:18 +00:00
sign_block(spec, state, empty_block)
2019-05-15 16:36:32 +00:00
return empty_block
2019-05-30 20:57:18 +00:00
def build_empty_block_for_next_slot(spec, state, signed=False):
return build_empty_block(spec, state, state.slot + 1, signed=signed)