mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-09-19 23:21:46 +03:00
Merge commit 'f90ddf42ad5ff047533ba979b96c4d7f3b21f916' into checkpoint/main_from_release_1.8.2_f90ddf42ad5ff047533ba979b96c4d7f3b21f916
This commit is contained in:
commit
a6713258c6
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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(
|
||||
|
@ -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,13 @@ 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_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 +620,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 +680,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 +731,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 +760,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 +774,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 +809,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], sp_sub_slot, ip_sub_slot, 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 +864,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 +910,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 +922,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 +950,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 +969,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
|
||||
)
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user