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

CHIA-1709 Pass a ValidationState to validate_unfinished_block_header #18818

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
46 changes: 21 additions & 25 deletions chia/consensus/block_header_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,10 @@ def validate_unfinished_header_block(
blocks: BlockRecordsProtocol,
header_block: UnfinishedHeaderBlock,
check_filter: bool,
expected_difficulty: uint64,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a little confusing but the naming is important here, its actually not the current difficulty and sub slot iters but the difficulty and sub slot iters expected to be in the block, idk if maybe we should rename ValidationState params to difficulty and sub_slot_iters and add a comment

expected_sub_slot_iters: uint64,
vs: ValidationState,
skip_overflow_last_ss_validation: bool = False,
skip_vdf_is_valid: bool = False,
check_sub_epoch_summary: bool = True,
prev_ses_block: Optional[BlockRecord] = None,
) -> tuple[Optional[uint64], Optional[ValidationError]]:
"""
Validates an unfinished header block. This is a block without the infusion VDFs (unfinished)
Expand All @@ -70,7 +68,7 @@ def validate_unfinished_header_block(

overflow = is_overflow_block(constants, header_block.reward_chain_block.signage_point_index)
if skip_overflow_last_ss_validation and overflow:
if final_eos_is_already_included(header_block, blocks, expected_sub_slot_iters):
if final_eos_is_already_included(header_block, blocks, vs.current_ssi):
skip_overflow_last_ss_validation = False
finished_sub_slots_since_prev = len(header_block.finished_sub_slots)
else:
Expand All @@ -84,8 +82,8 @@ def validate_unfinished_header_block(
can_finish_epoch: bool = False
if genesis_block:
height: uint32 = uint32(0)
assert expected_difficulty == constants.DIFFICULTY_STARTING
assert expected_sub_slot_iters == constants.SUB_SLOT_ITERS_STARTING
assert vs.current_difficulty == constants.DIFFICULTY_STARTING
assert vs.current_ssi == constants.SUB_SLOT_ITERS_STARTING
else:
assert prev_b is not None
height = uint32(prev_b.height + 1)
Expand All @@ -97,7 +95,7 @@ def validate_unfinished_header_block(
prev_b.prev_hash,
prev_b.deficit,
prev_b.sub_epoch_summary_included is not None,
prev_ses_block=prev_ses_block,
prev_ses_block=vs.prev_ses_block,
)
else:
can_finish_se = False
Expand Down Expand Up @@ -262,9 +260,9 @@ def validate_unfinished_header_block(

if can_finish_epoch and sub_slot.challenge_chain.subepoch_summary_hash is not None:
# 2m. Check new difficulty and ssi
if sub_slot.challenge_chain.new_sub_slot_iters != expected_sub_slot_iters:
if sub_slot.challenge_chain.new_sub_slot_iters != vs.current_ssi:
return None, ValidationError(Err.INVALID_NEW_SUB_SLOT_ITERS)
if sub_slot.challenge_chain.new_difficulty != expected_difficulty:
if sub_slot.challenge_chain.new_difficulty != vs.current_difficulty:
return None, ValidationError(Err.INVALID_NEW_DIFFICULTY)
else:
# 2n. Check new difficulty and ssi are None if we don't finish epoch
Expand All @@ -283,7 +281,7 @@ def validate_unfinished_header_block(
),
)

eos_vdf_iters: uint64 = expected_sub_slot_iters
eos_vdf_iters: uint64 = vs.current_ssi
cc_start_element: ClassgroupElement = ClassgroupElement.get_default_element()
cc_eos_vdf_challenge: bytes32 = challenge_hash
if genesis_block:
Expand Down Expand Up @@ -338,7 +336,7 @@ def validate_unfinished_header_block(
if finished_sub_slot_n == 0:
cc_eos_vdf_info_iters = prev_b.sub_slot_iters
else:
cc_eos_vdf_info_iters = expected_sub_slot_iters
cc_eos_vdf_info_iters = vs.current_ssi
# Check that the modified data is correct
if sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf != partial_cc_vdf_info.replace(
number_of_iterations=cc_eos_vdf_info_iters
Expand Down Expand Up @@ -423,9 +421,9 @@ def validate_unfinished_header_block(
blocks,
height,
blocks.block_record(prev_b.prev_hash),
expected_difficulty if can_finish_epoch else None,
expected_sub_slot_iters if can_finish_epoch else None,
prev_ses_block,
vs.current_difficulty if can_finish_epoch else None,
vs.current_ssi if can_finish_epoch else None,
vs.prev_ses_block,
)
expected_hash = expected_sub_epoch_summary.get_hash()
if expected_hash != ses_hash:
Expand Down Expand Up @@ -505,12 +503,12 @@ def validate_unfinished_header_block(
constants.DIFFICULTY_CONSTANT_FACTOR,
q_str,
header_block.reward_chain_block.proof_of_space.size,
expected_difficulty,
vs.current_difficulty,
cc_sp_hash,
)

# 7. check required iters
if required_iters >= calculate_sp_interval_iters(constants, expected_sub_slot_iters):
if required_iters >= calculate_sp_interval_iters(constants, vs.current_ssi):
return None, ValidationError(Err.INVALID_REQUIRED_ITERS)

# 8a. check signage point index 0 has no cc sp
Expand All @@ -527,13 +525,13 @@ def validate_unfinished_header_block(

sp_iters: uint64 = calculate_sp_iters(
constants,
expected_sub_slot_iters,
vs.current_ssi,
header_block.reward_chain_block.signage_point_index,
)

ip_iters: uint64 = calculate_ip_iters(
constants,
expected_sub_slot_iters,
vs.current_ssi,
header_block.reward_chain_block.signage_point_index,
required_iters,
)
Expand All @@ -549,15 +547,15 @@ def validate_unfinished_header_block(

# 10. Check total iters
if genesis_block:
total_iters: uint128 = uint128(expected_sub_slot_iters * finished_sub_slots_since_prev)
total_iters: uint128 = uint128(vs.current_ssi * finished_sub_slots_since_prev)
else:
assert prev_b is not None
if new_sub_slot:
total_iters = prev_b.total_iters
# Add the rest of the slot of prev_b
total_iters = uint128(total_iters + prev_b.sub_slot_iters - prev_b.ip_iters(constants))
# Add other empty slots
total_iters = uint128(total_iters + (expected_sub_slot_iters * (finished_sub_slots_since_prev - 1)))
total_iters = uint128(total_iters + (vs.current_ssi * (finished_sub_slots_since_prev - 1)))
else:
# Slot iters is guaranteed to be the same for header_block and prev_b
# This takes the beginning of the slot, and adds ip_iters
Expand All @@ -572,7 +570,7 @@ def validate_unfinished_header_block(
),
)

sp_total_iters: uint128 = uint128(total_iters - ip_iters + sp_iters - (expected_sub_slot_iters if overflow else 0))
sp_total_iters: uint128 = uint128(total_iters - ip_iters + sp_iters - (vs.current_ssi if overflow else 0))
if overflow and skip_overflow_last_ss_validation:
dummy_vdf_info = VDFInfo(
bytes32.zeros,
Expand Down Expand Up @@ -703,7 +701,7 @@ def validate_unfinished_header_block(

# The first block to have an sp > the last tx block's infusion iters, is a tx block
if overflow:
our_sp_total_iters: uint128 = uint128(total_iters - ip_iters + sp_iters - expected_sub_slot_iters)
our_sp_total_iters: uint128 = uint128(total_iters - ip_iters + sp_iters - vs.current_ssi)
else:
our_sp_total_iters = uint128(total_iters - ip_iters + sp_iters)
if (our_sp_total_iters > curr.total_iters) != (header_block.foliage.foliage_transaction_block_hash is not None):
Expand Down Expand Up @@ -857,11 +855,9 @@ def validate_finished_header_block(
blocks,
unfinished_header_block,
check_filter,
vs.current_difficulty,
vs.current_ssi,
vs,
False,
check_sub_epoch_summary=check_sub_epoch_summary,
prev_ses_block=vs.prev_ses_block,
)

genesis_block = False
Expand Down
5 changes: 3 additions & 2 deletions chia/consensus/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from chia.types.header_block import HeaderBlock
from chia.types.unfinished_block import UnfinishedBlock
from chia.types.unfinished_header_block import UnfinishedHeaderBlock
from chia.types.validation_state import ValidationState
from chia.types.weight_proof import SubEpochChallengeSegment
from chia.util.cpu import available_logical_cores
from chia.util.errors import Err
Expand Down Expand Up @@ -683,13 +684,13 @@ async def validate_unfinished_block_header(
sub_slot_iters, difficulty = get_next_sub_slot_iters_and_difficulty(
self.constants, len(unfinished_header_block.finished_sub_slots) > 0, prev_b, self
)
vs = ValidationState(sub_slot_iters, difficulty, None)
required_iters, error = validate_unfinished_header_block(
self.constants,
self,
unfinished_header_block,
False,
difficulty,
sub_slot_iters,
vs,
skip_overflow_ss_validation,
)
if error is not None:
Expand Down
Loading