mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-09-11 10:56:14 +03:00
use rust types for slots, SubEpochSummary and SubEpochData (#17298)
* use rust types for slots, SubEpochSummary and SubEpochData * use rust type for EndOfSubSlotBundle * use rust types for SubEpochChallengeSegment, SubEpochSegments and SubSlotData
This commit is contained in:
parent
f483328276
commit
c6d5f7fa1e
@ -62,8 +62,8 @@ def block_to_block_record(
|
|||||||
blocks,
|
blocks,
|
||||||
block.height,
|
block.height,
|
||||||
blocks.block_record(prev_b.prev_hash),
|
blocks.block_record(prev_b.prev_hash),
|
||||||
block.finished_sub_slots[0].challenge_chain.new_difficulty,
|
uint64.construct_optional(block.finished_sub_slots[0].challenge_chain.new_difficulty),
|
||||||
block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters,
|
uint64.construct_optional(block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters),
|
||||||
)
|
)
|
||||||
if ses.get_hash() != found_ses_hash:
|
if ses.get_hash() != found_ses_hash:
|
||||||
raise ValueError(Err.INVALID_SUB_EPOCH_SUMMARY)
|
raise ValueError(Err.INVALID_SUB_EPOCH_SUMMARY)
|
||||||
|
@ -2233,9 +2233,9 @@ class FullNode:
|
|||||||
if new_infusions is not None:
|
if new_infusions is not None:
|
||||||
self.log.info(
|
self.log.info(
|
||||||
f"⏲️ Finished sub slot, SP {self.constants.NUM_SPS_SUB_SLOT}/{self.constants.NUM_SPS_SUB_SLOT}, "
|
f"⏲️ Finished sub slot, SP {self.constants.NUM_SPS_SUB_SLOT}/{self.constants.NUM_SPS_SUB_SLOT}, "
|
||||||
f"{end_of_slot_bundle.challenge_chain.get_hash()}, "
|
f"{end_of_slot_bundle.challenge_chain.get_hash().hex()}, "
|
||||||
f"number of sub-slots: {len(self.full_node_store.finished_sub_slots)}, "
|
f"number of sub-slots: {len(self.full_node_store.finished_sub_slots)}, "
|
||||||
f"RC hash: {end_of_slot_bundle.reward_chain.get_hash()}, "
|
f"RC hash: {end_of_slot_bundle.reward_chain.get_hash().hex()}, "
|
||||||
f"Deficit {end_of_slot_bundle.reward_chain.deficit}"
|
f"Deficit {end_of_slot_bundle.reward_chain.deficit}"
|
||||||
)
|
)
|
||||||
# Reset farmer response timer for sub slot (SP 0)
|
# Reset farmer response timer for sub slot (SP 0)
|
||||||
@ -2448,8 +2448,8 @@ class FullNode:
|
|||||||
if field_vdf == CompressibleVDFField.CC_EOS_VDF:
|
if field_vdf == CompressibleVDFField.CC_EOS_VDF:
|
||||||
for index, sub_slot in enumerate(block.finished_sub_slots):
|
for index, sub_slot in enumerate(block.finished_sub_slots):
|
||||||
if sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf == vdf_info:
|
if sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf == vdf_info:
|
||||||
new_proofs = dataclasses.replace(sub_slot.proofs, challenge_chain_slot_proof=vdf_proof)
|
new_proofs = sub_slot.proofs.replace(challenge_chain_slot_proof=vdf_proof)
|
||||||
new_subslot = dataclasses.replace(sub_slot, proofs=new_proofs)
|
new_subslot = sub_slot.replace(proofs=new_proofs)
|
||||||
new_finished_subslots = block.finished_sub_slots
|
new_finished_subslots = block.finished_sub_slots
|
||||||
new_finished_subslots[index] = new_subslot
|
new_finished_subslots[index] = new_subslot
|
||||||
new_block = dataclasses.replace(block, finished_sub_slots=new_finished_subslots)
|
new_block = dataclasses.replace(block, finished_sub_slots=new_finished_subslots)
|
||||||
@ -2460,8 +2460,8 @@ class FullNode:
|
|||||||
sub_slot.infused_challenge_chain is not None
|
sub_slot.infused_challenge_chain is not None
|
||||||
and sub_slot.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf == vdf_info
|
and sub_slot.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf == vdf_info
|
||||||
):
|
):
|
||||||
new_proofs = dataclasses.replace(sub_slot.proofs, infused_challenge_chain_slot_proof=vdf_proof)
|
new_proofs = sub_slot.proofs.replace(infused_challenge_chain_slot_proof=vdf_proof)
|
||||||
new_subslot = dataclasses.replace(sub_slot, proofs=new_proofs)
|
new_subslot = sub_slot.replace(proofs=new_proofs)
|
||||||
new_finished_subslots = block.finished_sub_slots
|
new_finished_subslots = block.finished_sub_slots
|
||||||
new_finished_subslots[index] = new_subslot
|
new_finished_subslots[index] = new_subslot
|
||||||
new_block = dataclasses.replace(block, finished_sub_slots=new_finished_subslots)
|
new_block = dataclasses.replace(block, finished_sub_slots=new_finished_subslots)
|
||||||
|
@ -880,9 +880,9 @@ class FullNodeAPI:
|
|||||||
sub_slot_iters = peak.sub_slot_iters
|
sub_slot_iters = peak.sub_slot_iters
|
||||||
for sub_slot in finished_sub_slots:
|
for sub_slot in finished_sub_slots:
|
||||||
if sub_slot.challenge_chain.new_difficulty is not None:
|
if sub_slot.challenge_chain.new_difficulty is not None:
|
||||||
difficulty = sub_slot.challenge_chain.new_difficulty
|
difficulty = uint64(sub_slot.challenge_chain.new_difficulty)
|
||||||
if sub_slot.challenge_chain.new_sub_slot_iters is not None:
|
if sub_slot.challenge_chain.new_sub_slot_iters is not None:
|
||||||
sub_slot_iters = sub_slot.challenge_chain.new_sub_slot_iters
|
sub_slot_iters = uint64(sub_slot.challenge_chain.new_sub_slot_iters)
|
||||||
|
|
||||||
required_iters: uint64 = calculate_iterations_quality(
|
required_iters: uint64 = calculate_iterations_quality(
|
||||||
self.full_node.constants.DIFFICULTY_CONSTANT_FACTOR,
|
self.full_node.constants.DIFFICULTY_CONSTANT_FACTOR,
|
||||||
|
@ -707,10 +707,10 @@ def _create_sub_epoch_data(
|
|||||||
) -> SubEpochData:
|
) -> SubEpochData:
|
||||||
reward_chain_hash: bytes32 = sub_epoch_summary.reward_chain_hash
|
reward_chain_hash: bytes32 = sub_epoch_summary.reward_chain_hash
|
||||||
# Number of subblocks overflow in previous slot
|
# Number of subblocks overflow in previous slot
|
||||||
previous_sub_epoch_overflows: uint8 = sub_epoch_summary.num_blocks_overflow # total in sub epoch - expected
|
previous_sub_epoch_overflows = uint8(sub_epoch_summary.num_blocks_overflow) # total in sub epoch - expected
|
||||||
# New work difficulty and iterations per sub-slot
|
# New work difficulty and iterations per sub-slot
|
||||||
sub_slot_iters: Optional[uint64] = sub_epoch_summary.new_sub_slot_iters
|
sub_slot_iters: Optional[int] = sub_epoch_summary.new_sub_slot_iters
|
||||||
new_difficulty: Optional[uint64] = sub_epoch_summary.new_difficulty
|
new_difficulty: Optional[int] = sub_epoch_summary.new_difficulty
|
||||||
return SubEpochData(reward_chain_hash, previous_sub_epoch_overflows, sub_slot_iters, new_difficulty)
|
return SubEpochData(reward_chain_hash, previous_sub_epoch_overflows, sub_slot_iters, new_difficulty)
|
||||||
|
|
||||||
|
|
||||||
@ -886,7 +886,7 @@ def _map_sub_epoch_summaries(
|
|||||||
|
|
||||||
# if new epoch update diff and iters
|
# if new epoch update diff and iters
|
||||||
if data.new_difficulty is not None:
|
if data.new_difficulty is not None:
|
||||||
curr_difficulty = data.new_difficulty
|
curr_difficulty = uint64(data.new_difficulty)
|
||||||
|
|
||||||
# add to dict
|
# add to dict
|
||||||
summaries.append(ses)
|
summaries.append(ses)
|
||||||
@ -998,7 +998,7 @@ def _validate_segment(
|
|||||||
return False, uint64(0), uint64(0), uint64(0), []
|
return False, uint64(0), uint64(0), uint64(0), []
|
||||||
assert sub_slot_data.signage_point_index is not None
|
assert sub_slot_data.signage_point_index is not None
|
||||||
ip_iters = ip_iters + calculate_ip_iters(
|
ip_iters = ip_iters + calculate_ip_iters(
|
||||||
constants, curr_ssi, sub_slot_data.signage_point_index, required_iters
|
constants, curr_ssi, uint8(sub_slot_data.signage_point_index), required_iters
|
||||||
)
|
)
|
||||||
vdf_list = _get_challenge_block_vdfs(constants, idx, segment.sub_slots, curr_ssi)
|
vdf_list = _get_challenge_block_vdfs(constants, idx, segment.sub_slots, curr_ssi)
|
||||||
to_validate.extend(vdf_list)
|
to_validate.extend(vdf_list)
|
||||||
@ -1025,7 +1025,7 @@ def _get_challenge_block_vdfs(
|
|||||||
assert sub_slot_data.signage_point_index
|
assert sub_slot_data.signage_point_index
|
||||||
sp_input = ClassgroupElement.get_default_element()
|
sp_input = ClassgroupElement.get_default_element()
|
||||||
if not sub_slot_data.cc_signage_point.normalized_to_identity and sub_slot_idx >= 1:
|
if not sub_slot_data.cc_signage_point.normalized_to_identity and sub_slot_idx >= 1:
|
||||||
is_overflow = is_overflow_block(constants, sub_slot_data.signage_point_index)
|
is_overflow = is_overflow_block(constants, uint8(sub_slot_data.signage_point_index))
|
||||||
prev_ssd = sub_slots[sub_slot_idx - 1]
|
prev_ssd = sub_slots[sub_slot_idx - 1]
|
||||||
sp_input = sub_slot_data_vdf_input(
|
sp_input = sub_slot_data_vdf_input(
|
||||||
constants, sub_slot_data, sub_slot_idx, sub_slots, is_overflow, prev_ssd.is_end_of_slot(), ssi
|
constants, sub_slot_data, sub_slot_idx, sub_slots, is_overflow, prev_ssd.is_end_of_slot(), ssi
|
||||||
@ -1103,7 +1103,7 @@ def _validate_sub_slot_data(
|
|||||||
assert sub_slot_data.cc_sp_vdf_info
|
assert sub_slot_data.cc_sp_vdf_info
|
||||||
input = ClassgroupElement.get_default_element()
|
input = ClassgroupElement.get_default_element()
|
||||||
if not sub_slot_data.cc_signage_point.normalized_to_identity:
|
if not sub_slot_data.cc_signage_point.normalized_to_identity:
|
||||||
is_overflow = is_overflow_block(constants, sub_slot_data.signage_point_index)
|
is_overflow = is_overflow_block(constants, uint8(sub_slot_data.signage_point_index))
|
||||||
input = sub_slot_data_vdf_input(
|
input = sub_slot_data_vdf_input(
|
||||||
constants, sub_slot_data, sub_slot_idx, sub_slots, is_overflow, prev_ssd.is_end_of_slot(), ssi
|
constants, sub_slot_data, sub_slot_idx, sub_slots, is_overflow, prev_ssd.is_end_of_slot(), ssi
|
||||||
)
|
)
|
||||||
@ -1208,9 +1208,9 @@ def validate_recent_blocks(
|
|||||||
last_blocks_to_validate = 100 # todo remove cap after benchmarks
|
last_blocks_to_validate = 100 # todo remove cap after benchmarks
|
||||||
for summary in summaries[:ses_idx]:
|
for summary in summaries[:ses_idx]:
|
||||||
if summary.new_sub_slot_iters is not None:
|
if summary.new_sub_slot_iters is not None:
|
||||||
ssi = summary.new_sub_slot_iters
|
ssi = uint64(summary.new_sub_slot_iters)
|
||||||
if summary.new_difficulty is not None:
|
if summary.new_difficulty is not None:
|
||||||
diff = summary.new_difficulty
|
diff = uint64(summary.new_difficulty)
|
||||||
|
|
||||||
ses_blocks, sub_slots, transaction_blocks = 0, 0, 0
|
ses_blocks, sub_slots, transaction_blocks = 0, 0, 0
|
||||||
challenge, prev_challenge = recent_chain.recent_chain_data[0].reward_chain_block.pos_ss_cc_challenge_hash, None
|
challenge, prev_challenge = recent_chain.recent_chain_data[0].reward_chain_block.pos_ss_cc_challenge_hash, None
|
||||||
@ -1226,15 +1226,15 @@ def validate_recent_blocks(
|
|||||||
for sub_slot in block.finished_sub_slots:
|
for sub_slot in block.finished_sub_slots:
|
||||||
prev_challenge = sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf.challenge
|
prev_challenge = sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf.challenge
|
||||||
challenge = sub_slot.challenge_chain.get_hash()
|
challenge = sub_slot.challenge_chain.get_hash()
|
||||||
deficit = sub_slot.reward_chain.deficit
|
deficit = uint8(sub_slot.reward_chain.deficit)
|
||||||
if sub_slot.challenge_chain.subepoch_summary_hash is not None:
|
if sub_slot.challenge_chain.subepoch_summary_hash is not None:
|
||||||
ses = True
|
ses = True
|
||||||
assert summaries[ses_idx].get_hash() == sub_slot.challenge_chain.subepoch_summary_hash
|
assert summaries[ses_idx].get_hash() == sub_slot.challenge_chain.subepoch_summary_hash
|
||||||
ses_idx += 1
|
ses_idx += 1
|
||||||
if sub_slot.challenge_chain.new_sub_slot_iters is not None:
|
if sub_slot.challenge_chain.new_sub_slot_iters is not None:
|
||||||
ssi = sub_slot.challenge_chain.new_sub_slot_iters
|
ssi = uint64(sub_slot.challenge_chain.new_sub_slot_iters)
|
||||||
if sub_slot.challenge_chain.new_difficulty is not None:
|
if sub_slot.challenge_chain.new_difficulty is not None:
|
||||||
diff = sub_slot.challenge_chain.new_difficulty
|
diff = uint64(sub_slot.challenge_chain.new_difficulty)
|
||||||
|
|
||||||
if (challenge is not None) and (prev_challenge is not None):
|
if (challenge is not None) and (prev_challenge is not None):
|
||||||
overflow = is_overflow_block(constants, uint8(block.reward_chain_block.signage_point_index))
|
overflow = is_overflow_block(constants, uint8(block.reward_chain_block.signage_point_index))
|
||||||
@ -1334,7 +1334,7 @@ def __validate_pospace(
|
|||||||
|
|
||||||
sub_slot_data: SubSlotData = segment.sub_slots[idx]
|
sub_slot_data: SubSlotData = segment.sub_slots[idx]
|
||||||
|
|
||||||
if sub_slot_data.signage_point_index and is_overflow_block(constants, sub_slot_data.signage_point_index):
|
if sub_slot_data.signage_point_index and is_overflow_block(constants, uint8(sub_slot_data.signage_point_index)):
|
||||||
curr_slot = segment.sub_slots[idx - 1]
|
curr_slot = segment.sub_slots[idx - 1]
|
||||||
assert curr_slot.cc_slot_end_info
|
assert curr_slot.cc_slot_end_info
|
||||||
challenge = curr_slot.cc_slot_end_info.challenge
|
challenge = curr_slot.cc_slot_end_info.challenge
|
||||||
@ -1391,14 +1391,14 @@ def __get_rc_sub_slot(
|
|||||||
slots_n = 1
|
slots_n = 1
|
||||||
assert first
|
assert first
|
||||||
assert first.signage_point_index is not None
|
assert first.signage_point_index is not None
|
||||||
if is_overflow_block(constants, first.signage_point_index):
|
if is_overflow_block(constants, uint8(first.signage_point_index)):
|
||||||
if idx >= 2 and slots[idx - 2].cc_slot_end is None:
|
if idx >= 2 and slots[idx - 2].cc_slot_end is None:
|
||||||
slots_n = 2
|
slots_n = 2
|
||||||
|
|
||||||
new_diff = None if ses is None else ses.new_difficulty
|
new_diff = None if ses is None else ses.new_difficulty
|
||||||
new_ssi = None if ses is None else ses.new_sub_slot_iters
|
new_ssi = None if ses is None else ses.new_sub_slot_iters
|
||||||
ses_hash: Optional[bytes32] = None if ses is None else ses.get_hash()
|
ses_hash: Optional[bytes32] = None if ses is None else ses.get_hash()
|
||||||
overflow = is_overflow_block(constants, first.signage_point_index)
|
overflow = is_overflow_block(constants, uint8(first.signage_point_index))
|
||||||
if overflow:
|
if overflow:
|
||||||
if idx >= 2 and slots[idx - 2].cc_slot_end is not None and slots[idx - 1].cc_slot_end is not None:
|
if idx >= 2 and slots[idx - 2].cc_slot_end is not None and slots[idx - 1].cc_slot_end is not None:
|
||||||
ses_hash = None
|
ses_hash = None
|
||||||
@ -1483,9 +1483,9 @@ def _get_curr_diff_ssi(
|
|||||||
curr_ssi = constants.SUB_SLOT_ITERS_STARTING
|
curr_ssi = constants.SUB_SLOT_ITERS_STARTING
|
||||||
for ses in reversed(summaries[0:idx]):
|
for ses in reversed(summaries[0:idx]):
|
||||||
if ses.new_sub_slot_iters is not None:
|
if ses.new_sub_slot_iters is not None:
|
||||||
curr_ssi = ses.new_sub_slot_iters
|
curr_ssi = uint64(ses.new_sub_slot_iters)
|
||||||
assert ses.new_difficulty is not None
|
assert ses.new_difficulty is not None
|
||||||
curr_difficulty = ses.new_difficulty
|
curr_difficulty = uint64(ses.new_difficulty)
|
||||||
break
|
break
|
||||||
|
|
||||||
return curr_difficulty, curr_ssi
|
return curr_difficulty, curr_ssi
|
||||||
@ -1558,7 +1558,7 @@ def get_sp_total_iters(
|
|||||||
assert sub_slot_data.cc_ip_vdf_info is not None
|
assert sub_slot_data.cc_ip_vdf_info is not None
|
||||||
assert sub_slot_data.total_iters is not None
|
assert sub_slot_data.total_iters is not None
|
||||||
assert sub_slot_data.signage_point_index is not None
|
assert sub_slot_data.signage_point_index is not None
|
||||||
sp_iters: uint64 = calculate_sp_iters(constants, ssi, sub_slot_data.signage_point_index)
|
sp_iters: uint64 = calculate_sp_iters(constants, ssi, uint8(sub_slot_data.signage_point_index))
|
||||||
ip_iters: uint64 = uint64(sub_slot_data.cc_ip_vdf_info.number_of_iterations)
|
ip_iters: uint64 = uint64(sub_slot_data.cc_ip_vdf_info.number_of_iterations)
|
||||||
sp_sub_slot_total_iters = uint128(sub_slot_data.total_iters - ip_iters)
|
sp_sub_slot_total_iters = uint128(sub_slot_data.total_iters - ip_iters)
|
||||||
if is_overflow:
|
if is_overflow:
|
||||||
|
@ -981,8 +981,8 @@ class BlockTools:
|
|||||||
pending_ses = True
|
pending_ses = True
|
||||||
ses_hash: Optional[bytes32] = sub_epoch_summary.get_hash()
|
ses_hash: Optional[bytes32] = sub_epoch_summary.get_hash()
|
||||||
# if the last block is the last block of the epoch, we set the new sub-slot iters and difficulty
|
# if the last block is the last block of the epoch, we set the new sub-slot iters and difficulty
|
||||||
new_sub_slot_iters: Optional[uint64] = sub_epoch_summary.new_sub_slot_iters
|
new_sub_slot_iters: Optional[uint64] = uint64.construct_optional(sub_epoch_summary.new_sub_slot_iters)
|
||||||
new_difficulty: Optional[uint64] = sub_epoch_summary.new_difficulty
|
new_difficulty: Optional[uint64] = uint64.construct_optional(sub_epoch_summary.new_difficulty)
|
||||||
|
|
||||||
self.log.info(f"Sub epoch summary: {sub_epoch_summary} for block {latest_block.height+1}")
|
self.log.info(f"Sub epoch summary: {sub_epoch_summary} for block {latest_block.height+1}")
|
||||||
else: # the previous block is not the last block of the sub-epoch or epoch
|
else: # the previous block is not the last block of the sub-epoch or epoch
|
||||||
@ -1252,8 +1252,8 @@ class BlockTools:
|
|||||||
num_empty_slots_added += 1
|
num_empty_slots_added += 1
|
||||||
|
|
||||||
if new_sub_slot_iters is not None and new_difficulty is not None: # new epoch
|
if new_sub_slot_iters is not None and new_difficulty is not None: # new epoch
|
||||||
sub_slot_iters = new_sub_slot_iters
|
sub_slot_iters = uint64(new_sub_slot_iters)
|
||||||
difficulty = new_difficulty
|
difficulty = uint64(new_difficulty)
|
||||||
|
|
||||||
def create_genesis_block(
|
def create_genesis_block(
|
||||||
self,
|
self,
|
||||||
@ -1750,7 +1750,7 @@ def get_icc(
|
|||||||
if len(finished_sub_slots) == 0:
|
if len(finished_sub_slots) == 0:
|
||||||
prev_deficit = latest_block.deficit
|
prev_deficit = latest_block.deficit
|
||||||
else:
|
else:
|
||||||
prev_deficit = finished_sub_slots[-1].reward_chain.deficit
|
prev_deficit = uint8(finished_sub_slots[-1].reward_chain.deficit)
|
||||||
|
|
||||||
if deficit == prev_deficit == constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
|
if deficit == prev_deficit == constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
|
||||||
# new slot / overflow sb to new slot / overflow sb
|
# new slot / overflow sb to new slot / overflow sb
|
||||||
|
@ -87,11 +87,11 @@ class LastState:
|
|||||||
self.peak = None
|
self.peak = None
|
||||||
self.subslot_end = state
|
self.subslot_end = state
|
||||||
self.last_ip = uint64(0)
|
self.last_ip = uint64(0)
|
||||||
self.deficit = state.reward_chain.deficit
|
self.deficit = uint8(state.reward_chain.deficit)
|
||||||
if state.challenge_chain.new_difficulty is not None:
|
if state.challenge_chain.new_difficulty is not None:
|
||||||
assert state.challenge_chain.new_sub_slot_iters is not None
|
assert state.challenge_chain.new_sub_slot_iters is not None
|
||||||
self.difficulty = state.challenge_chain.new_difficulty
|
self.difficulty = uint64(state.challenge_chain.new_difficulty)
|
||||||
self.sub_slot_iters = state.challenge_chain.new_sub_slot_iters
|
self.sub_slot_iters = uint64(state.challenge_chain.new_sub_slot_iters)
|
||||||
self.new_epoch = True
|
self.new_epoch = True
|
||||||
else:
|
else:
|
||||||
self.new_epoch = False
|
self.new_epoch = False
|
||||||
|
@ -1,54 +1,9 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
import chia_rs
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from chia_rs import G2Element
|
ChallengeBlockInfo = chia_rs.ChallengeBlockInfo
|
||||||
|
ChallengeChainSubSlot = chia_rs.ChallengeChainSubSlot
|
||||||
from chia.types.blockchain_format.proof_of_space import ProofOfSpace
|
InfusedChallengeChainSubSlot = chia_rs.InfusedChallengeChainSubSlot
|
||||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
RewardChainSubSlot = chia_rs.RewardChainSubSlot
|
||||||
from chia.types.blockchain_format.vdf import VDFInfo, VDFProof
|
SubSlotProofs = chia_rs.SubSlotProofs
|
||||||
from chia.util.ints import uint8, uint64
|
|
||||||
from chia.util.streamable import Streamable, streamable
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class ChallengeBlockInfo(Streamable): # The hash of this is used as the challenge_hash for the ICC VDF
|
|
||||||
proof_of_space: ProofOfSpace
|
|
||||||
challenge_chain_sp_vdf: Optional[VDFInfo] # Only present if not the first sp
|
|
||||||
challenge_chain_sp_signature: G2Element
|
|
||||||
challenge_chain_ip_vdf: VDFInfo
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class ChallengeChainSubSlot(Streamable):
|
|
||||||
challenge_chain_end_of_slot_vdf: VDFInfo
|
|
||||||
infused_challenge_chain_sub_slot_hash: Optional[bytes32] # Only at the end of a slot
|
|
||||||
subepoch_summary_hash: Optional[bytes32] # Only once per sub-epoch, and one sub-epoch delayed
|
|
||||||
new_sub_slot_iters: Optional[uint64] # Only at the end of epoch, sub-epoch, and slot
|
|
||||||
new_difficulty: Optional[uint64] # Only at the end of epoch, sub-epoch, and slot
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class InfusedChallengeChainSubSlot(Streamable):
|
|
||||||
infused_challenge_chain_end_of_slot_vdf: VDFInfo
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class RewardChainSubSlot(Streamable):
|
|
||||||
end_of_slot_vdf: VDFInfo
|
|
||||||
challenge_chain_sub_slot_hash: bytes32
|
|
||||||
infused_challenge_chain_sub_slot_hash: Optional[bytes32]
|
|
||||||
deficit: uint8 # 16 or less. usually zero
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class SubSlotProofs(Streamable):
|
|
||||||
challenge_chain_slot_proof: VDFProof
|
|
||||||
infused_challenge_chain_slot_proof: Optional[VDFProof]
|
|
||||||
reward_chain_slot_proof: VDFProof
|
|
||||||
|
@ -1,18 +1,5 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
import chia_rs
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
SubEpochSummary = chia_rs.SubEpochSummary
|
||||||
from chia.util.ints import uint8, uint64
|
|
||||||
from chia.util.streamable import Streamable, streamable
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class SubEpochSummary(Streamable):
|
|
||||||
prev_subepoch_summary_hash: bytes32
|
|
||||||
reward_chain_hash: bytes32 # hash of reward chain at end of last segment
|
|
||||||
num_blocks_overflow: uint8 # How many more blocks than 384*(N-1)
|
|
||||||
new_difficulty: Optional[uint64] # Only once per epoch (diff adjustment)
|
|
||||||
new_sub_slot_iters: Optional[uint64] # Only once per epoch (diff adjustment)
|
|
||||||
|
@ -1,21 +1,5 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
import chia_rs
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from chia.types.blockchain_format.slots import (
|
EndOfSubSlotBundle = chia_rs.EndOfSubSlotBundle
|
||||||
ChallengeChainSubSlot,
|
|
||||||
InfusedChallengeChainSubSlot,
|
|
||||||
RewardChainSubSlot,
|
|
||||||
SubSlotProofs,
|
|
||||||
)
|
|
||||||
from chia.util.streamable import Streamable, streamable
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class EndOfSubSlotBundle(Streamable):
|
|
||||||
challenge_chain: ChallengeChainSubSlot
|
|
||||||
infused_challenge_chain: Optional[InfusedChallengeChainSubSlot]
|
|
||||||
reward_chain: RewardChainSubSlot
|
|
||||||
proofs: SubSlotProofs
|
|
||||||
|
@ -1,26 +1,16 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import List, Optional
|
from typing import List
|
||||||
|
|
||||||
|
import chia_rs
|
||||||
|
|
||||||
from chia.types.blockchain_format.proof_of_space import ProofOfSpace
|
|
||||||
from chia.types.blockchain_format.reward_chain_block import RewardChainBlock
|
from chia.types.blockchain_format.reward_chain_block import RewardChainBlock
|
||||||
from chia.types.blockchain_format.sized_bytes import bytes32
|
|
||||||
from chia.types.blockchain_format.vdf import VDFInfo, VDFProof
|
|
||||||
from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
|
from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
|
||||||
from chia.types.header_block import HeaderBlock
|
from chia.types.header_block import HeaderBlock
|
||||||
from chia.util.ints import uint8, uint32, uint64, uint128
|
|
||||||
from chia.util.streamable import Streamable, streamable
|
from chia.util.streamable import Streamable, streamable
|
||||||
|
|
||||||
|
SubEpochData = chia_rs.SubEpochData
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class SubEpochData(Streamable):
|
|
||||||
reward_chain_hash: bytes32
|
|
||||||
num_blocks_overflow: uint8
|
|
||||||
new_sub_slot_iters: Optional[uint64]
|
|
||||||
new_difficulty: Optional[uint64]
|
|
||||||
|
|
||||||
|
|
||||||
# number of challenge blocks
|
# number of challenge blocks
|
||||||
# Average iters for challenge blocks
|
# Average iters for challenge blocks
|
||||||
@ -33,53 +23,9 @@ class SubEpochData(Streamable):
|
|||||||
# total number of challenge blocks == total number of reward chain blocks
|
# total number of challenge blocks == total number of reward chain blocks
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
SubEpochChallengeSegment = chia_rs.SubEpochChallengeSegment
|
||||||
@dataclass(frozen=True)
|
SubEpochSegments = chia_rs.SubEpochSegments
|
||||||
class SubSlotData(Streamable):
|
SubSlotData = chia_rs.SubSlotData
|
||||||
# if infused
|
|
||||||
proof_of_space: Optional[ProofOfSpace]
|
|
||||||
# VDF to signage point
|
|
||||||
cc_signage_point: Optional[VDFProof]
|
|
||||||
# VDF from signage to infusion point
|
|
||||||
cc_infusion_point: Optional[VDFProof]
|
|
||||||
icc_infusion_point: Optional[VDFProof]
|
|
||||||
cc_sp_vdf_info: Optional[VDFInfo]
|
|
||||||
signage_point_index: Optional[uint8]
|
|
||||||
# VDF from beginning to end of slot if not infused
|
|
||||||
# from ip to end if infused
|
|
||||||
cc_slot_end: Optional[VDFProof]
|
|
||||||
icc_slot_end: Optional[VDFProof]
|
|
||||||
# info from finished slots
|
|
||||||
cc_slot_end_info: Optional[VDFInfo]
|
|
||||||
icc_slot_end_info: Optional[VDFInfo]
|
|
||||||
cc_ip_vdf_info: Optional[VDFInfo]
|
|
||||||
icc_ip_vdf_info: Optional[VDFInfo]
|
|
||||||
total_iters: Optional[uint128]
|
|
||||||
|
|
||||||
def is_challenge(self) -> bool:
|
|
||||||
if self.proof_of_space is not None:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def is_end_of_slot(self) -> bool:
|
|
||||||
if self.cc_slot_end_info is not None:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class SubEpochChallengeSegment(Streamable):
|
|
||||||
sub_epoch_n: uint32
|
|
||||||
sub_slots: List[SubSlotData]
|
|
||||||
rc_slot_end_info: Optional[VDFInfo] # in first segment of each sub_epoch
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
# this is used only for serialization to database
|
|
||||||
class SubEpochSegments(Streamable):
|
|
||||||
challenge_segments: List[SubEpochChallengeSegment]
|
|
||||||
|
|
||||||
|
|
||||||
@streamable
|
@streamable
|
||||||
|
@ -99,8 +99,8 @@ class WalletBlockchain(BlockchainInterface):
|
|||||||
and block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters is not None
|
and block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters is not None
|
||||||
):
|
):
|
||||||
assert block.finished_sub_slots[0].challenge_chain.new_difficulty is not None # They both change together
|
assert block.finished_sub_slots[0].challenge_chain.new_difficulty is not None # They both change together
|
||||||
sub_slot_iters: uint64 = block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters
|
sub_slot_iters = uint64(block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters)
|
||||||
difficulty: uint64 = block.finished_sub_slots[0].challenge_chain.new_difficulty
|
difficulty = uint64(block.finished_sub_slots[0].challenge_chain.new_difficulty)
|
||||||
else:
|
else:
|
||||||
sub_slot_iters = self._sub_slot_iters
|
sub_slot_iters = self._sub_slot_iters
|
||||||
difficulty = self._difficulty
|
difficulty = self._difficulty
|
||||||
|
@ -657,8 +657,7 @@ class TestBlockHeaderValidation:
|
|||||||
new_finished_ss = recursive_replace(
|
new_finished_ss = recursive_replace(
|
||||||
block.finished_sub_slots[-1],
|
block.finished_sub_slots[-1],
|
||||||
"challenge_chain",
|
"challenge_chain",
|
||||||
replace(
|
block.finished_sub_slots[-1].challenge_chain.replace(
|
||||||
block.finished_sub_slots[-1].challenge_chain,
|
|
||||||
infused_challenge_chain_sub_slot_hash=bytes([1] * 32),
|
infused_challenge_chain_sub_slot_hash=bytes([1] * 32),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -668,8 +667,7 @@ class TestBlockHeaderValidation:
|
|||||||
new_finished_ss = recursive_replace(
|
new_finished_ss = recursive_replace(
|
||||||
block.finished_sub_slots[-1],
|
block.finished_sub_slots[-1],
|
||||||
"challenge_chain",
|
"challenge_chain",
|
||||||
replace(
|
block.finished_sub_slots[-1].challenge_chain.replace(
|
||||||
block.finished_sub_slots[-1].challenge_chain,
|
|
||||||
infused_challenge_chain_sub_slot_hash=block.finished_sub_slots[
|
infused_challenge_chain_sub_slot_hash=block.finished_sub_slots[
|
||||||
-1
|
-1
|
||||||
].infused_challenge_chain.get_hash(),
|
].infused_challenge_chain.get_hash(),
|
||||||
@ -695,7 +693,7 @@ class TestBlockHeaderValidation:
|
|||||||
new_finished_ss_bad_rc = recursive_replace(
|
new_finished_ss_bad_rc = recursive_replace(
|
||||||
block.finished_sub_slots[-1],
|
block.finished_sub_slots[-1],
|
||||||
"reward_chain",
|
"reward_chain",
|
||||||
replace(block.finished_sub_slots[-1].reward_chain, infused_challenge_chain_sub_slot_hash=None),
|
block.finished_sub_slots[-1].reward_chain.replace(infused_challenge_chain_sub_slot_hash=None),
|
||||||
)
|
)
|
||||||
block_bad = recursive_replace(
|
block_bad = recursive_replace(
|
||||||
block, "finished_sub_slots", block.finished_sub_slots[:-1] + [new_finished_ss_bad_rc]
|
block, "finished_sub_slots", block.finished_sub_slots[:-1] + [new_finished_ss_bad_rc]
|
||||||
@ -743,7 +741,7 @@ class TestBlockHeaderValidation:
|
|||||||
new_finished_ss = recursive_replace(
|
new_finished_ss = recursive_replace(
|
||||||
blocks[-1].finished_sub_slots[-1],
|
blocks[-1].finished_sub_slots[-1],
|
||||||
"challenge_chain",
|
"challenge_chain",
|
||||||
replace(blocks[-1].finished_sub_slots[-1].challenge_chain, subepoch_summary_hash=std_hash(b"0")),
|
blocks[-1].finished_sub_slots[-1].challenge_chain.replace(subepoch_summary_hash=std_hash(b"0")),
|
||||||
)
|
)
|
||||||
block_bad = recursive_replace(
|
block_bad = recursive_replace(
|
||||||
blocks[-1], "finished_sub_slots", blocks[-1].finished_sub_slots[:-1] + [new_finished_ss]
|
blocks[-1], "finished_sub_slots", blocks[-1].finished_sub_slots[:-1] + [new_finished_ss]
|
||||||
@ -791,7 +789,7 @@ class TestBlockHeaderValidation:
|
|||||||
new_finished_ss = recursive_replace(
|
new_finished_ss = recursive_replace(
|
||||||
blocks[-1].finished_sub_slots[-1],
|
blocks[-1].finished_sub_slots[-1],
|
||||||
"reward_chain",
|
"reward_chain",
|
||||||
replace(blocks[-1].finished_sub_slots[-1].reward_chain, challenge_chain_sub_slot_hash=bytes([3] * 32)),
|
blocks[-1].finished_sub_slots[-1].reward_chain.replace(challenge_chain_sub_slot_hash=bytes([3] * 32)),
|
||||||
)
|
)
|
||||||
block_1_bad = recursive_replace(
|
block_1_bad = recursive_replace(
|
||||||
blocks[-1], "finished_sub_slots", blocks[-1].finished_sub_slots[:-1] + [new_finished_ss]
|
blocks[-1], "finished_sub_slots", blocks[-1].finished_sub_slots[:-1] + [new_finished_ss]
|
||||||
@ -1037,8 +1035,8 @@ class TestBlockHeaderValidation:
|
|||||||
new_finished_ss = recursive_replace(
|
new_finished_ss = recursive_replace(
|
||||||
new_finished_ss,
|
new_finished_ss,
|
||||||
"reward_chain",
|
"reward_chain",
|
||||||
replace(
|
new_finished_ss.reward_chain.replace(
|
||||||
new_finished_ss.reward_chain, challenge_chain_sub_slot_hash=new_finished_ss.challenge_chain.get_hash()
|
challenge_chain_sub_slot_hash=new_finished_ss.challenge_chain.get_hash()
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
block_bad = recursive_replace(block, "finished_sub_slots", [new_finished_ss] + block.finished_sub_slots[1:])
|
block_bad = recursive_replace(block, "finished_sub_slots", [new_finished_ss] + block.finished_sub_slots[1:])
|
||||||
@ -1072,8 +1070,7 @@ class TestBlockHeaderValidation:
|
|||||||
new_finished_ss = recursive_replace(
|
new_finished_ss = recursive_replace(
|
||||||
new_finished_ss,
|
new_finished_ss,
|
||||||
"reward_chain",
|
"reward_chain",
|
||||||
replace(
|
new_finished_ss.reward_chain.replace(
|
||||||
new_finished_ss.reward_chain,
|
|
||||||
challenge_chain_sub_slot_hash=new_finished_ss.challenge_chain.get_hash(),
|
challenge_chain_sub_slot_hash=new_finished_ss.challenge_chain.get_hash(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1586,12 +1586,10 @@ class TestFullNodeProtocol:
|
|||||||
# Submit the sub slot, but not the last block
|
# 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)
|
blocks = bt.get_consecutive_blocks(1, block_list_input=blocks, skip_slots=1, force_overflow=True)
|
||||||
for ss in blocks[-1].finished_sub_slots:
|
for ss in blocks[-1].finished_sub_slots:
|
||||||
challenge_chain = dataclasses.replace(
|
challenge_chain = ss.challenge_chain.replace(
|
||||||
ss.challenge_chain,
|
|
||||||
new_difficulty=20,
|
new_difficulty=20,
|
||||||
)
|
)
|
||||||
slot2 = dataclasses.replace(
|
slot2 = ss.replace(
|
||||||
ss,
|
|
||||||
challenge_chain=challenge_chain,
|
challenge_chain=challenge_chain,
|
||||||
)
|
)
|
||||||
await full_node_1.respond_end_of_sub_slot(fnp.RespondEndOfSubSlot(slot2), peer)
|
await full_node_1.respond_end_of_sub_slot(fnp.RespondEndOfSubSlot(slot2), peer)
|
||||||
|
@ -555,7 +555,7 @@ def test_recursive_types() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_ambiguous_deserialization_optionals() -> None:
|
def test_ambiguous_deserialization_optionals() -> None:
|
||||||
with pytest.raises(AssertionError):
|
with pytest.raises(ValueError, match="unexpected end of buffer"):
|
||||||
SubEpochChallengeSegment.from_bytes(b"\x00\x00\x00\x03\xff\xff\xff\xff")
|
SubEpochChallengeSegment.from_bytes(b"\x00\x00\x00\x03\xff\xff\xff\xff")
|
||||||
|
|
||||||
@streamable
|
@streamable
|
||||||
|
Loading…
Reference in New Issue
Block a user