Compare commits

...

3 Commits

Author SHA1 Message Date
Amine Khaldi 45650fa5de
Linting addendum. 2023-06-30 14:17:28 +01:00
Amine Khaldi 1b520478a3
Merge commit 'f90ddf42ad5ff047533ba979b96c4d7f3b21f916' into checkpoint/main_from_release_1.8.2_f90ddf42ad5ff047533ba979b96c4d7f3b21f916 2023-06-30 14:09:04 +01:00
Arvid Norberg f90ddf42ad
Eos challenge optimization (#15642)
* fix cache miss (#107)

* Increase vdf client timeout (#103)

* Increase vdf client timeout.

* Reset only on new peak.

* Increase next_iters_count to 10 (#118)

* new end of slot ses validation (#99)

* eos validate infused challenge chain hash in all locations, validate deficit

* lint

* add iterations/diff check

* check all cases of ses

* remove asserts log and return none

* remove asserts log and return none

* typo

* fix store tests

* fix store tests

* lint

* remove logs

---------

Co-authored-by: Almog De Paz <almogdepaz@gmail.com>
Co-authored-by: Florin Chirica <fchirica96@gmail.com>
Co-authored-by: Earle Lowe <30607889+emlowe@users.noreply.github.com>
2023-06-27 15:34:31 -05:00
7 changed files with 292 additions and 42 deletions

View File

@ -95,6 +95,8 @@ def get_block_challenge(
if curr.first_in_sub_slot:
assert curr.finished_challenge_slot_hashes is not None
reversed_challenge_hashes += reversed(curr.finished_challenge_slot_hashes)
if len(reversed_challenge_hashes) >= challenges_to_look_for:
break
if curr.height == 0:
assert curr.finished_challenge_slot_hashes is not None
assert len(curr.finished_challenge_slot_hashes) > 0

View File

@ -1427,6 +1427,8 @@ class FullNode:
sub_slots[1],
fork_block,
self.blockchain,
sub_slot_iters,
difficulty,
)
if fns_peak_result.new_signage_points is not None and peer is not None:
@ -2110,6 +2112,8 @@ class FullNode:
end_of_slot_bundle,
self.blockchain,
peak,
next_sub_slot_iters,
next_difficulty,
await self.blockchain.get_full_peak(),
)
# It may be an empty list, even if it's not None. Not None means added successfully

View File

@ -10,7 +10,7 @@ from chia.consensus.block_record import BlockRecord
from chia.consensus.blockchain_interface import BlockchainInterface
from chia.consensus.constants import ConsensusConstants
from chia.consensus.difficulty_adjustment import can_finish_sub_and_full_epoch
from chia.consensus.make_sub_epoch_summary import next_sub_epoch_summary
from chia.consensus.make_sub_epoch_summary import make_sub_epoch_summary
from chia.consensus.multiprocess_validation import PreValidationResult
from chia.consensus.pot_iterations import calculate_sp_interval_iters
from chia.full_node.signage_point import SignagePoint
@ -18,7 +18,6 @@ from chia.protocols import timelord_protocol
from chia.server.outbound_message import Message
from chia.types.blockchain_format.classgroup import ClassgroupElement
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
from chia.types.blockchain_format.vdf import VDFInfo
from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
from chia.types.full_block import FullBlock
@ -256,6 +255,8 @@ class FullNodeStore:
eos: EndOfSubSlotBundle,
blocks: BlockchainInterface,
peak: Optional[BlockRecord],
next_sub_slot_iters: uint64,
next_difficulty: uint64,
peak_full_block: Optional[FullBlock],
) -> Optional[List[timelord_protocol.NewInfusionPointVDF]]:
"""
@ -284,6 +285,11 @@ class FullNodeStore:
if eos.challenge_chain.challenge_chain_end_of_slot_vdf.challenge != cc_challenge:
# This slot does not append to our next slot
# This prevent other peers from appending fake VDFs to our cache
log.error(
f"bad cc_challenge in new_finished_sub_slot, "
f"got {eos.challenge_chain.challenge_chain_end_of_slot_vdf.challenge}"
f"expected {cc_challenge}"
)
return None
if peak is None:
@ -301,6 +307,7 @@ class FullNodeStore:
# the finished subslot, and the peak is not fully added yet, so it looks like we still need the subslot.
# In that case, we will exit here and let the new_peak code add the subslot.
if total_iters < peak.total_iters:
log.debug("dont add slot, total_iters < peak.total_iters")
return None
rc_challenge = eos.reward_chain.end_of_slot_vdf.challenge
@ -315,6 +322,17 @@ class FullNodeStore:
log.info(f"Don't have challenge hash {rc_challenge}, caching EOS")
return None
if peak.deficit == 0:
if eos.reward_chain.deficit != self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
log.error(
f"eos reward_chain deficit got {eos.reward_chain.deficit} "
f"expected {self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK}"
)
return None
elif eos.reward_chain.deficit != peak.deficit:
log.error(f"wrong eos reward_chain deficit got {eos.reward_chain.deficit} expected {peak.deficit}")
return None
if peak.deficit == self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
icc_start_element = None
elif peak.deficit == self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1:
@ -335,27 +353,67 @@ class FullNodeStore:
icc_iters = sub_slot_iters
assert icc_challenge is not None
if can_finish_sub_and_full_epoch(
finish_se, finish_epoch = can_finish_sub_and_full_epoch(
self.constants,
blocks,
peak.height,
peak.prev_hash,
peak.deficit,
peak.sub_epoch_summary_included is not None,
)[0]:
assert peak_full_block is not None
ses: Optional[SubEpochSummary] = next_sub_epoch_summary(
self.constants, blocks, peak.required_iters, peak_full_block, True
)
if finish_se:
# this is the first slot in a new sub epoch, should include SES
expected_sub_epoch_summary = make_sub_epoch_summary(
self.constants,
blocks,
peak.height,
blocks.block_record(blocks.block_record(peak.prev_hash).prev_hash),
next_difficulty if finish_epoch else None,
next_sub_slot_iters if finish_epoch else None,
)
if ses is not None:
if eos.challenge_chain.subepoch_summary_hash != ses.get_hash():
log.warning(f"SES not correct {ses.get_hash(), eos.challenge_chain}")
if eos.challenge_chain.subepoch_summary_hash is None:
log.warning("SES should not be None")
return None
if eos.challenge_chain.subepoch_summary_hash != expected_sub_epoch_summary.get_hash():
log.warning(
f"Bad SES, expected {expected_sub_epoch_summary} "
f"expected hash {expected_sub_epoch_summary.get_hash()}, got {eos.challenge_chain}"
)
return None
if finish_epoch:
# this is the first slot in a new epoch check diff and iterations
if (
eos.challenge_chain.new_sub_slot_iters is None
or eos.challenge_chain.new_sub_slot_iters != next_sub_slot_iters
):
log.error("wrong new iterations at end of slot bundle")
return None
if (
eos.challenge_chain.new_difficulty is None
or eos.challenge_chain.new_difficulty != next_difficulty
):
log.info("wrong new difficulty at end of slot bundle")
return None
else:
if eos.challenge_chain.subepoch_summary_hash is not None:
log.warning("SES not correct, should be None")
if eos.challenge_chain.new_sub_slot_iters is not None:
log.error("got new iterations at end of slot bundle when it should be None")
return None
if eos.challenge_chain.new_difficulty is not None:
log.info("got new difficulty at end of slot bundle when it should be None")
return None
else:
# empty slots dont have sub_epoch_summary
if eos.challenge_chain.subepoch_summary_hash is not None:
log.warning("SES not correct, should be None in an empty slot")
return None
# This is on an empty slot
cc_start_element = ClassgroupElement.get_default_element()
icc_start_element = ClassgroupElement.get_default_element()
@ -417,6 +475,14 @@ class FullNodeStore:
assert eos.infused_challenge_chain is not None
assert eos.infused_challenge_chain is not None
assert eos.proofs.infused_challenge_chain_slot_proof is not None
if eos.reward_chain.deficit == self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
# only at the end of a challenge slot
if eos.infused_challenge_chain.get_hash() != eos.challenge_chain.infused_challenge_chain_sub_slot_hash:
log.error("infused_challenge_chain mismatch in challenge_chain")
return None
else:
assert eos.challenge_chain.infused_challenge_chain_sub_slot_hash is None
assert eos.infused_challenge_chain.get_hash() == eos.reward_chain.infused_challenge_chain_sub_slot_hash
partial_icc_vdf_info = VDFInfo(
icc_challenge,
@ -449,6 +515,10 @@ class FullNodeStore:
# This is the first sub slot and it's empty, therefore there is no ICC
if eos.infused_challenge_chain is not None or eos.proofs.infused_challenge_chain_slot_proof is not None:
return None
if eos.challenge_chain.infused_challenge_chain_sub_slot_hash is not None:
return None
if eos.reward_chain.infused_challenge_chain_sub_slot_hash is not None:
return None
self.finished_sub_slots.append((eos, [None] * self.constants.NUM_SPS_SUB_SLOT, total_iters))
@ -671,6 +741,8 @@ class FullNodeStore:
ip_sub_slot: Optional[EndOfSubSlotBundle], # None if in first slot
fork_block: Optional[BlockRecord],
blocks: BlockchainInterface,
next_sub_slot_iters: uint64,
next_difficulty: uint64,
) -> FullNodeStorePeakResult:
"""
If the peak is an overflow block, must provide two sub-slots: one for the current sub-slot and one for
@ -737,7 +809,10 @@ class FullNodeStore:
future_eos: List[EndOfSubSlotBundle] = self.future_eos_cache.get(peak.reward_infusion_new_challenge, []).copy()
for eos in future_eos:
if self.new_finished_sub_slot(eos, blocks, peak, peak_full_block) is not None:
if (
self.new_finished_sub_slot(eos, blocks, peak, next_sub_slot_iters, next_difficulty, peak_full_block)
is not None
):
new_eos = eos
break

View File

@ -136,6 +136,7 @@ class Timelord:
self.bluebox_mode = self.config.get("sanitizer_mode", False)
self.pending_bluebox_info: List[Tuple[float, timelord_protocol.RequestCompactProofOfTime]] = []
self.last_active_time = time.time()
self.max_allowed_inactivity_time = 60
self.bluebox_pool: Optional[ProcessPoolExecutor] = None
async def _start(self) -> None:
@ -498,7 +499,7 @@ class Timelord:
self.iters_to_submit[chain].append(next_sp)
self.iteration_to_proof_type[next_sp] = IterationType.SIGNAGE_POINT
next_iters_count += 1
if next_iters_count == 3:
if next_iters_count == 10:
break
# Break so we alternate between checking SP and IP
@ -854,9 +855,10 @@ class Timelord:
else:
# If there were no failures recently trigger a reset after 60 seconds of no activity.
# Signage points should be every 9 seconds
active_time_threshold = 60
active_time_threshold = self.max_allowed_inactivity_time
if time.time() - self.last_active_time > active_time_threshold:
log.error(f"Not active for {active_time_threshold} seconds, restarting all chains")
self.max_allowed_inactivity_time = min(self.max_allowed_inactivity_time * 2, 1800)
await self._reset_chains()
async def _manage_chains(self) -> None:

View File

@ -36,6 +36,7 @@ class TimelordAPI:
async with self.timelord.lock:
if self.timelord.bluebox_mode:
return None
self.timelord.max_allowed_inactivity_time = 60
if new_peak.reward_chain_block.weight > self.timelord.last_state.get_weight():
log.info("Not skipping peak, don't have. Maybe we are not the fastest timelord")
log.info(

View File

@ -9,6 +9,7 @@ import pytest_asyncio
from chia.consensus.blockchain import AddBlockResult, Blockchain
from chia.consensus.constants import ConsensusConstants
from chia.consensus.difficulty_adjustment import get_next_sub_slot_iters_and_difficulty
from chia.consensus.find_fork_point import find_fork_point_in_chain
from chia.consensus.multiprocess_validation import PreValidationResult
from chia.consensus.pot_iterations import is_overflow_block
@ -155,18 +156,35 @@ class TestFullNodeStore:
assert store.get_sub_slot(empty_blockchain.constants.GENESIS_CHALLENGE) is None
assert store.get_sub_slot(sub_slots[0].challenge_chain.get_hash()) is None
assert store.get_sub_slot(sub_slots[1].challenge_chain.get_hash()) is None
assert store.new_finished_sub_slot(sub_slots[1], blockchain, None, None) is None
assert store.new_finished_sub_slot(sub_slots[2], blockchain, None, None) is None
next_sub_slot_iters = custom_block_tools.constants.SUB_SLOT_ITERS_STARTING
next_difficulty = custom_block_tools.constants.DIFFICULTY_STARTING
assert (
store.new_finished_sub_slot(sub_slots[1], blockchain, None, next_sub_slot_iters, next_difficulty, None)
is None
)
assert (
store.new_finished_sub_slot(sub_slots[2], blockchain, None, next_sub_slot_iters, next_difficulty, None)
is None
)
# Test adding sub-slots after genesis
assert store.new_finished_sub_slot(sub_slots[0], blockchain, None, None) is not None
assert (
store.new_finished_sub_slot(sub_slots[0], blockchain, None, next_sub_slot_iters, next_difficulty, None)
is not None
)
sub_slot = store.get_sub_slot(sub_slots[0].challenge_chain.get_hash())
assert sub_slot is not None
assert sub_slot[0] == sub_slots[0]
assert store.get_sub_slot(sub_slots[1].challenge_chain.get_hash()) is None
assert store.new_finished_sub_slot(sub_slots[1], blockchain, None, None) is not None
assert (
store.new_finished_sub_slot(sub_slots[1], blockchain, None, next_sub_slot_iters, next_difficulty, None)
is not None
)
for i in range(len(sub_slots)):
assert store.new_finished_sub_slot(sub_slots[i], blockchain, None, None) is not None
assert (
store.new_finished_sub_slot(sub_slots[i], blockchain, None, next_sub_slot_iters, next_difficulty, None)
is not None
)
slot_i = store.get_sub_slot(sub_slots[i].challenge_chain.get_hash())
assert slot_i is not None
assert slot_i[0] == sub_slots[i]
@ -185,10 +203,25 @@ class TestFullNodeStore:
assert peak is not None
peak_full_block = await blockchain.get_full_peak()
assert peak_full_block is not None
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, peak, blockchain
)
if peak.overflow:
store.new_peak(peak, peak_full_block, sub_slots[-2], sub_slots[-1], None, blockchain)
store.new_peak(
peak,
peak_full_block,
sub_slots[-2],
sub_slots[-1],
None,
blockchain,
next_sub_slot_iters,
next_difficulty,
)
else:
store.new_peak(peak, peak_full_block, None, sub_slots[-1], None, blockchain)
store.new_peak(
peak, peak_full_block, None, sub_slots[-1], None, blockchain, next_sub_slot_iters, next_difficulty
)
assert store.get_sub_slot(sub_slots[0].challenge_chain.get_hash()) is None
assert store.get_sub_slot(sub_slots[1].challenge_chain.get_hash()) is None
@ -230,13 +263,19 @@ class TestFullNodeStore:
normalized_to_identity_cc_ip=normalized_to_identity,
normalized_to_identity_cc_sp=normalized_to_identity,
)
for block in blocks:
await _validate_and_add_block_no_error(blockchain, block)
sb = blockchain.block_record(block.header_hash)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, sb, blockchain
)
result = await blockchain.get_sp_and_ip_sub_slots(block.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
res = store.new_peak(sb, block, sp_sub_slot, ip_sub_slot, None, blockchain)
res = store.new_peak(
sb, block, sp_sub_slot, ip_sub_slot, None, blockchain, next_sub_slot_iters, next_difficulty
)
assert res.added_eos is None
# Add reorg blocks
@ -265,7 +304,12 @@ class TestFullNodeStore:
result = await blockchain.get_sp_and_ip_sub_slots(block.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
res = store.new_peak(sb, block, sp_sub_slot, ip_sub_slot, fork_block, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, sb, blockchain
)
res = store.new_peak(
sb, block, sp_sub_slot, ip_sub_slot, fork_block, blockchain, next_sub_slot_iters, next_difficulty
)
assert res.added_eos is None
# Add slots to the end
@ -278,8 +322,20 @@ class TestFullNodeStore:
normalized_to_identity_cc_ip=normalized_to_identity,
normalized_to_identity_cc_sp=normalized_to_identity,
)
peak = blockchain.get_peak()
for slot in blocks_2[-1].finished_sub_slots:
store.new_finished_sub_slot(slot, blockchain, blockchain.get_peak(), await blockchain.get_full_peak())
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, True, peak, blockchain
)
store.new_finished_sub_slot(
slot,
blockchain,
blockchain.get_peak(),
next_sub_slot_iters,
next_difficulty,
await blockchain.get_full_peak(),
)
assert store.get_sub_slot(sub_slots[3].challenge_chain.get_hash()) is None
assert store.get_sub_slot(sub_slots[4].challenge_chain.get_hash()) is None
@ -326,7 +382,19 @@ class TestFullNodeStore:
assert result is not None
sp_sub_slot, ip_sub_slot = result
res = store.new_peak(sb, blocks[-1], sp_sub_slot, ip_sub_slot, fork_block, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, sb, blockchain
)
res = store.new_peak(
sb,
blocks[-1],
sp_sub_slot,
ip_sub_slot,
fork_block,
blockchain,
next_sub_slot_iters,
next_difficulty,
)
assert res.added_eos is None
if sb.overflow and sp_sub_slot is not None:
assert sp_sub_slot != ip_sub_slot
@ -349,7 +417,18 @@ class TestFullNodeStore:
normalized_to_identity_cc_sp=normalized_to_identity,
)
for slot in blocks_2[-1].finished_sub_slots[:-1]:
store.new_finished_sub_slot(slot, blockchain, blockchain.get_peak(), await blockchain.get_full_peak())
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, True, peak, blockchain
)
store.new_finished_sub_slot(
slot,
blockchain,
blockchain.get_peak(),
next_sub_slot_iters,
next_difficulty,
await blockchain.get_full_peak(),
)
finished_sub_slots = blocks_2[-1].finished_sub_slots
assert len(store.finished_sub_slots) == 4
@ -489,8 +568,14 @@ class TestFullNodeStore:
normalized_to_identity_cc_ip=normalized_to_identity,
normalized_to_identity_cc_sp=normalized_to_identity,
)
peak = blockchain.get_peak()
assert peak is not None
for slot in blocks_3[-1].finished_sub_slots:
store.new_finished_sub_slot(slot, blockchain, None, None)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, True, peak, blockchain
)
store.new_finished_sub_slot(slot, blockchain, None, next_sub_slot_iters, next_difficulty, None)
assert len(store.finished_sub_slots) == 3
finished_sub_slots = blocks_3[-1].finished_sub_slots
@ -536,7 +621,11 @@ class TestFullNodeStore:
await _validate_and_add_block(blockchain, blocks_4[-1], expected_result=AddBlockResult.ADDED_AS_ORPHAN)
sb = blockchain.block_record(blocks_4[-1].header_hash)
store.new_peak(sb, blocks_4[-1], None, None, None, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, sb, blockchain
)
store.new_peak(sb, blocks_4[-1], None, None, None, blockchain, next_sub_slot_iters, next_difficulty)
for i in range(
sb.signage_point_index + custom_block_tools.constants.NUM_SP_INTERVALS_EXTRA,
custom_block_tools.constants.NUM_SPS_SUB_SLOT,
@ -592,16 +681,37 @@ class TestFullNodeStore:
sp_sub_slot, ip_sub_slot = result
peak = sb
peak_full_block = block
res = store.new_peak(sb, block, sp_sub_slot, ip_sub_slot, None, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, peak, blockchain
)
res = store.new_peak(
sb, block, sp_sub_slot, ip_sub_slot, None, blockchain, next_sub_slot_iters, next_difficulty
)
assert res.added_eos is None
assert store.new_finished_sub_slot(dependant_sub_slots[0], blockchain, peak, peak_full_block) is None
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, True, peak, blockchain
)
assert (
store.new_finished_sub_slot(
dependant_sub_slots[0], blockchain, peak, next_sub_slot_iters, next_difficulty, peak_full_block
)
is None
)
block = blocks[-2]
sb = blockchain.block_record(block.header_hash)
result = await blockchain.get_sp_and_ip_sub_slots(block.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
res = store.new_peak(sb, block, sp_sub_slot, ip_sub_slot, None, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, sb, blockchain
)
res = store.new_peak(
sb, block, sp_sub_slot, ip_sub_slot, None, blockchain, next_sub_slot_iters, next_difficulty
)
assert res.added_eos == dependant_sub_slots[0]
assert res.new_signage_points == []
assert res.new_infusion_points == []
@ -622,7 +732,13 @@ class TestFullNodeStore:
result = await blockchain.get_sp_and_ip_sub_slots(block.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
res = store.new_peak(sb, block, sp_sub_slot, ip_sub_slot, None, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, sb, blockchain
)
res = store.new_peak(
sb, block, sp_sub_slot, ip_sub_slot, None, blockchain, next_sub_slot_iters, next_difficulty
)
assert res.added_eos is None
case_0, case_1 = False, False
@ -645,7 +761,13 @@ class TestFullNodeStore:
assert result is not None
sp_sub_slot, ip_sub_slot = result
sb = blockchain.block_record(prev_block.header_hash)
res = store.new_peak(sb, prev_block, sp_sub_slot, ip_sub_slot, None, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, sb, blockchain
)
res = store.new_peak(
sb, prev_block, sp_sub_slot, ip_sub_slot, None, blockchain, next_sub_slot_iters, next_difficulty
)
if len(block.finished_sub_slots) == 0:
case_0 = True
assert res.new_infusion_points == [new_ip]
@ -653,8 +775,16 @@ class TestFullNodeStore:
case_1 = True
assert res.new_infusion_points == []
found_ips: List[timelord_protocol.NewInfusionPointVDF] = []
peak = blockchain.get_peak()
for ss in block.finished_sub_slots:
ipvdf = store.new_finished_sub_slot(ss, blockchain, sb, prev_block)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, True, peak, blockchain
)
ipvdf = store.new_finished_sub_slot(
ss, blockchain, sb, next_sub_slot_iters, next_difficulty, prev_block
)
assert ipvdf is not None
found_ips += ipvdf
assert found_ips == [new_ip]
@ -680,7 +810,13 @@ class TestFullNodeStore:
result = await blockchain.get_sp_and_ip_sub_slots(peak.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
store.new_peak(peak, blocks[-1], sp_sub_slot, ip_sub_slot, None, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, peak, blockchain
)
store.new_peak(
peak, blocks[-1], sub_slots[0], sub_slots[1], None, blockchain, next_sub_slot_iters, next_difficulty
)
blocks = custom_block_tools.get_consecutive_blocks(
2, block_list_input=blocks, guarantee_transaction_block=True
@ -729,7 +865,13 @@ class TestFullNodeStore:
result = await blockchain.get_sp_and_ip_sub_slots(peak.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
store.new_peak(peak, blocks[-2], sp_sub_slot, ip_sub_slot, None, blockchain)
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, peak, blockchain
)
store.new_peak(
peak, blocks[-2], sp_sub_slot, ip_sub_slot, None, blockchain, next_sub_slot_iters, next_difficulty
)
assert_sp_none(i2, False)
assert_sp_none(i2 + 1, False)
@ -769,6 +911,9 @@ class TestFullNodeStore:
result = await blockchain.get_sp_and_ip_sub_slots(peak.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, False, peak, blockchain
)
# Do a reorg, which should remove everything after B2
store.new_peak(
@ -778,6 +923,8 @@ class TestFullNodeStore:
ip_sub_slot,
(await blockchain.get_block_records_at([blocks[-2].height]))[0],
blockchain,
next_sub_slot_iters,
next_difficulty,
)
assert_sp_none(i2, False)
@ -804,8 +951,17 @@ class TestFullNodeStore:
peak = None
peak_full_block = None
for block in default_1000_blocks:
next_sub_slot_iters, next_difficulty = get_next_sub_slot_iters_and_difficulty(
blockchain.constants, True, peak, blockchain
)
for sub_slot in block.finished_sub_slots:
assert store.new_finished_sub_slot(sub_slot, blockchain, peak, peak_full_block) is not None
assert (
store.new_finished_sub_slot(
sub_slot, blockchain, peak, next_sub_slot_iters, next_difficulty, peak_full_block
)
is not None
)
await _validate_and_add_block(blockchain, block)
peak = blockchain.get_peak()
assert peak is not None
@ -814,4 +970,6 @@ class TestFullNodeStore:
result = await blockchain.get_sp_and_ip_sub_slots(peak.header_hash)
assert result is not None
sp_sub_slot, ip_sub_slot = result
store.new_peak(peak, peak_full_block, sp_sub_slot, ip_sub_slot, None, blockchain)
store.new_peak(
peak, peak_full_block, sp_sub_slot, ip_sub_slot, None, blockchain, next_sub_slot_iters, next_difficulty
)

View File

@ -1496,7 +1496,15 @@ class TestFullNodeProtocol:
# Submit the sub slot, but not the last block
blocks = bt.get_consecutive_blocks(1, block_list_input=blocks, skip_slots=1, force_overflow=True)
for ss in blocks[-1].finished_sub_slots:
await full_node_1.respond_end_of_sub_slot(fnp.RespondEndOfSubSlot(ss), peer)
challenge_chain = dataclasses.replace(
ss.challenge_chain,
new_difficulty=20,
)
slot2 = dataclasses.replace(
ss,
challenge_chain=challenge_chain,
)
await full_node_1.respond_end_of_sub_slot(fnp.RespondEndOfSubSlot(slot2), peer)
second_blockchain = empty_blockchain
for block in blocks:
@ -1513,7 +1521,6 @@ class TestFullNodeProtocol:
[],
peak_2.sub_slot_iters,
)
# Submits the signage point, cannot add because don't have block
await full_node_1.respond_signage_point(
fnp.RespondSignagePoint(4, sp.cc_vdf, sp.cc_proof, sp.rc_vdf, sp.rc_proof), peer
@ -1529,7 +1536,8 @@ class TestFullNodeProtocol:
await full_node_1.full_node.add_block(blocks[-1], peer)
# Now signage point should be added
assert full_node_1.full_node.full_node_store.get_signage_point(sp.cc_vdf.output.get_hash()) is not None
sp = full_node_1.full_node.full_node_store.get_signage_point(sp.cc_vdf.output.get_hash())
assert sp is not None
@pytest.mark.asyncio
async def test_slot_catch_up_genesis(self, setup_two_nodes_fixture, self_hostname):