Skip to content

Commit

Permalink
CHIA-1565 Pass a ValidationState to validate_finished_header_block (#…
Browse files Browse the repository at this point in the history
…18712)

Pass a ValidationState to validate_finished_header_block.
  • Loading branch information
AmineKhaldi authored Oct 22, 2024
1 parent 45b08d6 commit 4f00f63
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 70 deletions.
76 changes: 22 additions & 54 deletions chia/_tests/blockchain/test_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,9 @@ async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_block
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad,
False,
expected_difficulty,
expected_sub_slot_iters,
empty_blockchain.constants, empty_blockchain, header_block_bad, False, vs
)
assert error is not None
assert error.code == Err.INVALID_NEW_SUB_SLOT_ITERS
Expand All @@ -199,13 +195,9 @@ async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_block
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad_2,
False,
expected_difficulty,
expected_sub_slot_iters,
empty_blockchain.constants, empty_blockchain, header_block_bad_2, False, vs
)
assert error is not None
assert error.code == Err.INVALID_NEW_DIFFICULTY
Expand Down Expand Up @@ -233,13 +225,9 @@ async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_block
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad_3,
False,
expected_difficulty,
expected_sub_slot_iters,
empty_blockchain.constants, empty_blockchain, header_block_bad_3, False, vs
)
assert error is not None
assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY
Expand All @@ -266,13 +254,9 @@ async def test_long_chain(self, empty_blockchain: Blockchain, default_1000_block
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad_4,
False,
expected_difficulty,
expected_sub_slot_iters,
empty_blockchain.constants, empty_blockchain, header_block_bad_4, False, vs
)
assert error is not None
assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY
Expand Down Expand Up @@ -523,13 +507,11 @@ async def test_invalid_sub_slot_challenge_hash_genesis(self, empty_blockchain: B
)

header_block_bad = get_block_header(block_0_bad, [], [])
vs = ValidationState(
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING, empty_blockchain.constants.DIFFICULTY_STARTING, None
)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad,
False,
empty_blockchain.constants.DIFFICULTY_STARTING,
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING,
empty_blockchain.constants, empty_blockchain, header_block_bad, False, vs
)

assert error is not None
Expand Down Expand Up @@ -557,13 +539,9 @@ async def test_invalid_sub_slot_challenge_hash_non_genesis(
# TODO: Inspect these block values as they are currently None
expected_difficulty = blocks[1].finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = blocks[1].finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad,
False,
expected_difficulty,
expected_sub_slot_iters,
empty_blockchain.constants, empty_blockchain, header_block_bad, False, vs
)
assert error is not None
assert error.code == Err.INVALID_PREV_CHALLENGE_SLOT_HASH
Expand All @@ -588,13 +566,9 @@ async def test_invalid_sub_slot_challenge_hash_empty_ss(self, empty_blockchain:
# TODO: Inspect these block values as they are currently None
expected_difficulty = blocks[1].finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = blocks[1].finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad,
False,
expected_difficulty,
expected_sub_slot_iters,
empty_blockchain.constants, empty_blockchain, header_block_bad, False, vs
)
assert error is not None
assert error.code == Err.INVALID_PREV_CHALLENGE_SLOT_HASH
Expand Down Expand Up @@ -747,13 +721,9 @@ async def test_invalid_icc_into_cc(self, empty_blockchain: Blockchain, bt: Block
# TODO: Inspect these block values as they are currently None
expected_difficulty = block.finished_sub_slots[0].challenge_chain.new_difficulty or uint64(0)
expected_sub_slot_iters = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters or uint64(0)
vs = ValidationState(expected_sub_slot_iters, expected_difficulty, None)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad,
False,
expected_difficulty,
expected_sub_slot_iters,
empty_blockchain.constants, empty_blockchain, header_block_bad, False, vs
)
assert error is not None
assert error.code == Err.INVALID_ICC_HASH_CC
Expand Down Expand Up @@ -819,13 +789,11 @@ async def test_empty_slot_no_ses(self, empty_blockchain: Blockchain, bt: BlockTo
)

header_block_bad = get_block_header(block_bad, [], [])
vs = ValidationState(
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING, empty_blockchain.constants.DIFFICULTY_STARTING, None
)
_, error = validate_finished_header_block(
empty_blockchain.constants,
empty_blockchain,
header_block_bad,
False,
empty_blockchain.constants.DIFFICULTY_STARTING,
empty_blockchain.constants.SUB_SLOT_ITERS_STARTING,
empty_blockchain.constants, empty_blockchain, header_block_bad, False, vs
)
assert error is not None
assert error.code == Err.INVALID_SUB_EPOCH_SUMMARY_HASH
Expand Down
17 changes: 8 additions & 9 deletions chia/consensus/block_header_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
from chia.types.header_block import HeaderBlock
from chia.types.unfinished_header_block import UnfinishedHeaderBlock
from chia.types.validation_state import ValidationState
from chia.util.errors import Err, ValidationError
from chia.util.hash import std_hash
from chia.util.ints import uint8, uint32, uint64, uint128
Expand Down Expand Up @@ -834,10 +835,8 @@ def validate_finished_header_block(
blocks: BlockRecordsProtocol,
header_block: HeaderBlock,
check_filter: bool,
expected_difficulty: uint64,
expected_sub_slot_iters: uint64,
vs: ValidationState,
check_sub_epoch_summary: bool = True,
prev_ses_block: Optional[BlockRecord] = None,
) -> tuple[Optional[uint64], Optional[ValidationError]]:
"""
Fully validates the header of a block. A header block is the same as a full block, but
Expand All @@ -858,11 +857,11 @@ def validate_finished_header_block(
blocks,
unfinished_header_block,
check_filter,
expected_difficulty,
expected_sub_slot_iters,
vs.current_difficulty,
vs.current_ssi,
False,
check_sub_epoch_summary=check_sub_epoch_summary,
prev_ses_block=prev_ses_block,
prev_ses_block=vs.prev_ses_block,
)

genesis_block = False
Expand All @@ -880,7 +879,7 @@ def validate_finished_header_block(

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 @@ -891,8 +890,8 @@ def validate_finished_header_block(
return None, ValidationError(Err.INVALID_HEIGHT)

# 28. Check weight
if header_block.weight != prev_b.weight + expected_difficulty:
log.error(f"INVALID WEIGHT: {header_block} {prev_b} {expected_difficulty}")
if header_block.weight != prev_b.weight + vs.current_difficulty:
log.error(f"INVALID WEIGHT: {header_block} {prev_b} {vs.current_difficulty}")
return None, ValidationError(Err.INVALID_WEIGHT)
else:
# 27b. Check genesis block height, weight, and prev block hash
Expand Down
4 changes: 1 addition & 3 deletions chia/consensus/multiprocess_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ def pre_validate_block(
blockchain,
header_block,
True, # check_filter
vs.current_difficulty,
vs.current_ssi,
prev_ses_block=vs.prev_ses_block,
vs,
)
error_int: Optional[uint16] = None
if error is not None:
Expand Down
4 changes: 3 additions & 1 deletion chia/full_node/weight_proof.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from chia.types.blockchain_format.vdf import VDFInfo, VDFProof, validate_vdf
from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
from chia.types.header_block import HeaderBlock
from chia.types.validation_state import ValidationState
from chia.types.weight_proof import (
RecentChainData,
SubEpochChallengeSegment,
Expand Down Expand Up @@ -1253,8 +1254,9 @@ def validate_recent_blocks(
adjusted = True
deficit = get_deficit(constants, deficit, prev_block_record, overflow, len(block.finished_sub_slots))
if sub_slots > 2 and transaction_blocks > 11 and (tip_height - block.height < last_blocks_to_validate):
vs = ValidationState(ssi, diff, None)
caluclated_required_iters, error = validate_finished_header_block(
constants, sub_blocks, block, False, diff, ssi, ses_blocks > 2
constants, sub_blocks, block, False, vs, ses_blocks > 2
)
if error is not None:
log.error(f"block {block.header_hash} failed validation {error}")
Expand Down
6 changes: 3 additions & 3 deletions chia/wallet/wallet_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from chia.consensus.full_block_to_block_record import block_to_block_record
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.header_block import HeaderBlock
from chia.types.validation_state import ValidationState
from chia.types.weight_proof import WeightProof
from chia.util.errors import Err
from chia.util.ints import uint32, uint64
Expand Down Expand Up @@ -110,9 +111,8 @@ async def add_block(self, block: HeaderBlock) -> tuple[AddBlockResult, Optional[
difficulty = self._difficulty

# Validation requires a block cache (self) that goes back to a subepoch barrier
required_iters, error = validate_finished_header_block(
self.constants, self, block, False, difficulty, sub_slot_iters, False
)
vs = ValidationState(sub_slot_iters, difficulty, None)
required_iters, error = validate_finished_header_block(self.constants, self, block, False, vs, False)
if error is not None:
return AddBlockResult.INVALID_BLOCK, error.code
if required_iters is None:
Expand Down

0 comments on commit 4f00f63

Please sign in to comment.