From ab9ee667cb23f6574758f15912016d50949636a4 Mon Sep 17 00:00:00 2001 From: Mariano Sorgente Date: Thu, 3 Dec 2020 14:10:51 +0900 Subject: [PATCH] Recursive fetching of sub slots --- src/consensus/default_constants.py | 4 +-- src/full_node/full_node_api.py | 19 +++++++++++-- src/timelord.py | 43 +++++++++++++++++------------- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/consensus/default_constants.py b/src/consensus/default_constants.py index c963a81c2e..3db6515036 100644 --- a/src/consensus/default_constants.py +++ b/src/consensus/default_constants.py @@ -6,8 +6,8 @@ testnet_kwargs = { "SLOT_SUB_BLOCKS_TARGET": 32, "MIN_SUB_BLOCKS_PER_CHALLENGE_BLOCK": 16, "MAX_SUB_SLOT_SUB_BLOCKS": 128, - "NUM_SPS_SUB_SLOT": 16, - "SUB_SLOT_ITERS_STARTING": 2 ** 24, + "NUM_SPS_SUB_SLOT": 64, + "SUB_SLOT_ITERS_STARTING": 2 ** 26, # DIFFICULTY_STARTING is the starting difficulty for the first epoch, which is then further # multiplied by another factor of 2^25, to be used in the VDF iter calculation formula. "DIFFICULTY_STARTING": 2 ** 20, diff --git a/src/full_node/full_node_api.py b/src/full_node/full_node_api.py index 97d61c1ef5..286a207e26 100644 --- a/src/full_node/full_node_api.py +++ b/src/full_node/full_node_api.py @@ -389,7 +389,23 @@ class FullNodeAPI: @api_request async def respond_end_of_sub_slot( self, request: full_node_protocol.RespondEndOfSubSlot, peer: ws.WSChiaConnection - ) -> None: + ) -> Optional[Message]: + if ( + self.full_node.full_node_store.get_sub_slot( + request.end_of_slot_bundle.challenge_chain.challenge_chain_end_of_slot_vdf.challenge + ) + is None + and request.end_of_slot_bundle.challenge_chain.challenge_chain_end_of_slot_vdf.challenge + != self.full_node.constants.FIRST_CC_CHALLENGE + ): + # If we don't have the prev, request the prev instead + full_node_request = full_node_protocol.RequestSignagePointOrEndOfSubSlot( + request.end_of_slot_bundle.challenge_chain.challenge_chain_end_of_slot_vdf.challenge, + uint8(0), + bytes([0] * 32), + ) + return Message("request_signage_point_or_end_of_sub_slot", full_node_request) + peak = self.full_node.blockchain.get_peak() if peak is not None and peak.height > 2: next_sub_slot_iters = self.full_node.blockchain.get_next_slot_iters(peak.header_hash, True) @@ -402,7 +418,6 @@ class FullNodeAPI: new_infusions = self.full_node.full_node_store.new_finished_sub_slot( request.end_of_slot_bundle, self.full_node.blockchain.sub_blocks, self.full_node.blockchain.get_peak() ) - # It may be an empty list, even if it's not None. Not None means added successfully if new_infusions is not None: self.log.info( diff --git a/src/timelord.py b/src/timelord.py index 07b9248c34..f991d34d5c 100644 --- a/src/timelord.py +++ b/src/timelord.py @@ -2,6 +2,7 @@ import asyncio import io import logging import time +import traceback from asyncio import StreamReader, StreamWriter from enum import Enum from typing import Dict, List, Optional, Tuple, Union @@ -607,25 +608,29 @@ class Timelord: await asyncio.sleep(5) await self._reset_chains() while not self._shut_down: - await asyncio.sleep(0.1) - # Didn't get any useful data, continue. - # Map free vdf_clients to unspawned chains. - await self._map_chains_with_vdf_clients() - async with self.lock: - # We've got a new peak, process it. - if self.new_peak is not None: - await self._handle_new_peak() - # A subslot ended, process it. - if self.new_subslot_end is not None: - await self._handle_subslot_end() - # Submit pending iterations. - await self._submit_iterations() - # Check for new signage point and broadcast it if present. - await self._check_for_new_sp() - # Check for new infusion point and broadcast it if present. - await self._check_for_new_ip() - # Check for end of subslot, respawn chains and build EndOfSubslotBundle. - await self._check_for_end_of_subslot() + try: + await asyncio.sleep(0.1) + # Didn't get any useful data, continue. + # Map free vdf_clients to unspawned chains. + await self._map_chains_with_vdf_clients() + async with self.lock: + # We've got a new peak, process it. + if self.new_peak is not None: + await self._handle_new_peak() + # A subslot ended, process it. + if self.new_subslot_end is not None: + await self._handle_subslot_end() + # Submit pending iterations. + await self._submit_iterations() + # Check for new signage point and broadcast it if present. + await self._check_for_new_sp() + # Check for new infusion point and broadcast it if present. + await self._check_for_new_ip() + # Check for end of subslot, respawn chains and build EndOfSubslotBundle. + await self._check_for_end_of_subslot() + except Exception as e: + tb = traceback.format_exc() + log.error(f"Error while handling message: {tb}") async def _do_process_communication( self,