async def wallet_short_sync_backtrack(self, header_block, peer): top = header_block blocks = [top] # Fetch blocks backwards until we hit the one that we have, # then complete them with additions / removals going forward while not self.wallet_state_manager.blockchain.contains_block(top.prev_header_hash) and top.height > 0: request_prev = wallet_protocol.RequestBlockHeader(top.height - 1) response_prev: Optional[RespondBlockHeader] = await peer.request_block_header(request_prev) if response_prev is None or not isinstance(response_prev, RespondBlockHeader): raise RuntimeError("bad block header response from peer while syncing") prev_head = response_prev.header_block blocks.append(prev_head) top = prev_head blocks.reverse() await self.complete_blocks(blocks, peer) await self.wallet_state_manager.create_more_puzzle_hashes()
async def new_peak_wallet(self, peak: wallet_protocol.NewPeakWallet, peer: WSChiaConnection): if self.wallet_state_manager is None: return None curr_peak = self.wallet_state_manager.blockchain.get_peak() if curr_peak is not None and curr_peak.weight >= peak.weight: return None if self.new_peak_lock is None: self.new_peak_lock = asyncio.Lock() async with self.new_peak_lock: request = wallet_protocol.RequestBlockHeader(peak.height) response: Optional[RespondBlockHeader] = await peer.request_block_header(request) if response is None or not isinstance(response, RespondBlockHeader) or response.header_block is None: return None header_block = response.header_block if (curr_peak is None and header_block.height < self.constants.WEIGHT_PROOF_RECENT_BLOCKS) or ( curr_peak is not None and curr_peak.height > header_block.height - 200 ): top = header_block blocks = [top] # Fetch blocks backwards until we hit the one that we have, # then complete them with additions / removals going forward while not self.wallet_state_manager.blockchain.contains_block(top.prev_header_hash) and top.height > 0: request_prev = wallet_protocol.RequestBlockHeader(top.height - 1) response_prev: Optional[RespondBlockHeader] = await peer.request_block_header(request_prev) if response_prev is None: return None if not isinstance(response_prev, RespondBlockHeader): return None prev_head = response_prev.header_block blocks.append(prev_head) top = prev_head blocks.reverse() await self.complete_blocks(blocks, peer) await self.wallet_state_manager.create_more_puzzle_hashes() elif header_block.height >= self.constants.WEIGHT_PROOF_RECENT_BLOCKS: # Request weight proof # Sync if PoW validates if self.wallet_state_manager.sync_mode: self.last_new_peak_messages.put(peer, peak) return None weight_request = RequestProofOfWeight(header_block.height, header_block.header_hash) weight_proof_response: RespondProofOfWeight = await peer.request_proof_of_weight( weight_request, timeout=360 ) if weight_proof_response is None: return None weight_proof = weight_proof_response.wp if self.wallet_state_manager is None: return None if self.server is not None and self.server.is_trusted_peer(peer, self.config["trusted_peers"]): valid, fork_point = self.wallet_state_manager.weight_proof_handler.get_fork_point_no_validations( weight_proof ) else: valid, fork_point, _ = await self.wallet_state_manager.weight_proof_handler.validate_weight_proof( weight_proof ) if not valid: self.log.error( f"invalid weight proof, num of epochs {len(weight_proof.sub_epochs)}" f" recent blocks num ,{len(weight_proof.recent_chain_data)}" ) self.log.debug(f"{weight_proof}") return None self.log.info(f"Validated, fork point is {fork_point}") self.wallet_state_manager.sync_store.add_potential_fork_point( header_block.header_hash, uint32(fork_point) ) self.wallet_state_manager.sync_store.add_potential_peak(header_block) self.start_sync()
async def new_peak_wallet(self, peak: wallet_protocol.NewPeakWallet, peer: WSChiaConnection): if self.wallet_state_manager is None: return if self.wallet_state_manager.blockchain.contains_block(peak.header_hash): self.log.debug(f"known peak {peak.header_hash}") return if self.wallet_state_manager.sync_mode: self.last_new_peak_messages.put(peer, peak) return async with self.new_peak_lock: curr_peak = self.wallet_state_manager.blockchain.get_peak() if curr_peak is not None and curr_peak.weight >= peak.weight: return request = wallet_protocol.RequestBlockHeader(peak.height) response: Optional[RespondBlockHeader] = await peer.request_block_header(request) if response is None or not isinstance(response, RespondBlockHeader) or response.header_block is None: self.log.warning(f"bad peak response from peer {response}") return header_block = response.header_block curr_peak_height = 0 if curr_peak is None else curr_peak.height if (curr_peak_height == 0 and peak.height < self.constants.WEIGHT_PROOF_RECENT_BLOCKS) or ( curr_peak_height > peak.height - 200 ): if peak.height <= curr_peak_height + self.config["short_sync_blocks_behind_threshold"]: await self.wallet_short_sync_backtrack(header_block, peer) else: await self.batch_sync_to_peak(curr_peak_height, peak) elif peak.height >= self.constants.WEIGHT_PROOF_RECENT_BLOCKS: # Request weight proof # Sync if PoW validates weight_request = RequestProofOfWeight(peak.height, peak.header_hash) weight_proof_response: RespondProofOfWeight = await peer.request_proof_of_weight( weight_request, timeout=360 ) if weight_proof_response is None: return weight_proof = weight_proof_response.wp if self.wallet_state_manager is None: return if self.server is not None and self.server.is_trusted_peer(peer, self.config["trusted_peers"]): valid, fork_point = self.wallet_state_manager.weight_proof_handler.get_fork_point_no_validations( weight_proof ) else: valid, fork_point, _ = await self.wallet_state_manager.weight_proof_handler.validate_weight_proof( weight_proof ) if not valid: self.log.error( f"invalid weight proof, num of epochs {len(weight_proof.sub_epochs)}" f" recent blocks num ,{len(weight_proof.recent_chain_data)}" ) self.log.debug(f"{weight_proof}") return self.log.info(f"Validated, fork point is {fork_point}") self.wallet_state_manager.sync_store.add_potential_fork_point( header_block.header_hash, uint32(fork_point) ) self.wallet_state_manager.sync_store.add_potential_peak(header_block) self.start_sync()
), uint8(30), "None", ) new_peak_wallet = wallet_protocol.NewPeakWallet( bytes32( bytes.fromhex( "ee50e45652cb6a60e3ab0031aa425a6019648fe5344ae860e6fc14af1aa3c2fa") ), uint32(1093428752), uint128(207496292293729126634170184354599452208), uint32(133681371), ) request_block_header = wallet_protocol.RequestBlockHeader(uint32(3562957314), ) respond_header_block = wallet_protocol.RespondBlockHeader(header_block, ) reject_header_request = wallet_protocol.RejectHeaderRequest(uint32(17867635), ) request_removals = wallet_protocol.RequestRemovals( uint32(3500751918), bytes32( bytes.fromhex( "b44bc0e0fce20331a57081107dfd30ef39fc436e6e6ce4f6f0ab8db4f981d114") ), [ bytes32( bytes.fromhex( "ab62cfb2abaf9e1a475b707c3d3de35d6ef4a298b31137802fd9ea47d48ff0d5"