Пример #1
0
    def received_crawl_request(self, peer, dist, payload):
        self.logger.info("Received crawl request from node %s for range %d-%d",
                         hexlify(peer.public_key.key_to_bin())[-8:],
                         payload.start_seq_num, payload.end_seq_num)
        start_seq_num = payload.start_seq_num
        end_seq_num = payload.end_seq_num

        # It could be that our start_seq_num and end_seq_num are negative. If so, convert them to positive numbers,
        # based on the last block of ones chain.
        if start_seq_num < 0:
            last_block = self.persistence.get_latest(payload.public_key)
            start_seq_num = max(GENESIS_SEQ, last_block.sequence_number + start_seq_num + 1) \
                if last_block else GENESIS_SEQ
        if end_seq_num < 0:
            last_block = self.persistence.get_latest(payload.public_key)
            end_seq_num = max(GENESIS_SEQ, last_block.sequence_number + end_seq_num + 1) \
                if last_block else GENESIS_SEQ

        blocks = self.persistence.crawl(payload.public_key,
                                        start_seq_num,
                                        end_seq_num,
                                        limit=self.settings.max_crawl_batch)
        total_count = len(blocks)

        if total_count == 0:
            global_time = self.claim_global_time()
            response_payload = EmptyCrawlResponsePayload(payload.crawl_id)
            dist = GlobalTimeDistributionPayload(global_time)
            packet = self._ez_pack(self._prefix, 7, [dist, response_payload],
                                   False)
            self.endpoint.send(peer.address, packet)
        else:
            self.send_crawl_responses(blocks, peer, payload.crawl_id)
Пример #2
0
    def send_crawl_request(self,
                           peer,
                           public_key,
                           start_seq_num,
                           end_seq_num,
                           for_half_block=None):
        """
        Send a crawl request to a specific peer.
        """
        crawl_id = for_half_block.hash_number if for_half_block else \
            RandomNumberCache.find_unclaimed_identifier(self.request_cache, "crawl")
        crawl_future = Future()
        self.request_cache.add(CrawlRequestCache(self, crawl_id, crawl_future))
        self.logger.info(
            "Requesting crawl of node %s (blocks %d to %d) with id %d",
            hexlify(peer.public_key.key_to_bin())[-8:], start_seq_num,
            end_seq_num, crawl_id)

        global_time = self.claim_global_time()
        auth = BinMemberAuthenticationPayload(
            self.my_peer.public_key.key_to_bin())
        payload = CrawlRequestPayload(public_key, start_seq_num, end_seq_num,
                                      crawl_id)
        dist = GlobalTimeDistributionPayload(global_time)

        packet = self._ez_pack(self._prefix, 2, [auth, dist, payload])
        self.endpoint.send(peer.address, packet)

        return crawl_future
Пример #3
0
    def send_block_pair(self, block1, block2, address=None, ttl=1):
        """
        Send a half block pair to a specific address, or do a broadcast to known peers if no peer is specified.
        """
        global_time = self.claim_global_time()
        dist = GlobalTimeDistributionPayload(global_time)

        if address:
            self.logger.debug(
                "Sending block pair to (%s:%d) (%s and %s)",
                address[0],
                address[1],
                block1,
                block2,
            )
            payload = HalfBlockPairPayload.from_half_blocks(block1, block2)
            packet = self._ez_pack(self._prefix, 4, [dist, payload], False)
            self.endpoint.send(address, packet)
        else:
            self.logger.debug("Broadcasting blocks %s and %s", block1, block2)
            payload = HalfBlockPairBroadcastPayload.from_half_blocks(
                block1, block2, ttl
            )
            packet = self._ez_pack(self._prefix, 6, [dist, payload], False)
            peers = self.get_peers()
            for peer in random.sample(
                peers, min(len(peers), self.settings.broadcast_fanout)
            ):
                self.endpoint.send(peer.address, packet)
            self._add_broadcasted_blockid(block1.block_id)
Пример #4
0
    def send_crawl_response(self, block, crawl_id, index, total_count, peer):
        self.logger.debug("Sending block for crawl request to %s (%s)", peer, block)

        # Don't answer with any invalid blocks.
        validation = self.validate_persist_block(block)
        if validation[0] == ValidationResult.invalid and total_count > 0:
            # We send an empty block to the crawl requester if no blocks should be sent back
            self.logger.error(
                "Not sending crawl response, the block is invalid. Result %s",
                repr(validation),
            )
            self.persistence_integrity_check()
            return

        global_time = self.claim_global_time()
        payload = CrawlResponsePayload.from_crawl(block, crawl_id, index, total_count)
        dist = GlobalTimeDistributionPayload(global_time)

        packet = self._ez_pack(self._prefix, 3, [dist, payload], False)
        self.endpoint.send(peer.address, packet)
Пример #5
0
    def did_trade(self, transaction, block):
        """
        We just performed a trade with a counterparty.
        """
        other_order_id = transaction.partner_order_id
        self.remove_outstanding_requests_with_order_id(other_order_id)
        if other_order_id not in self.matches:
            return

        self.received_responses_ids.add(other_order_id)

        for match_payload in self.matches[other_order_id]:
            self._logger.info("Sending transaction completed (order %s) to matchmaker %s", transaction.order_id,
                              match_payload.matchmaker_trader_id.as_hex())

            linked_block = self.community.trustchain.persistence.get_linked(block) or block
            global_time = self.community.claim_global_time()
            dist = GlobalTimeDistributionPayload(global_time)
            payload = HalfBlockPairPayload.from_half_blocks(block, linked_block)
            packet = self.community._ez_pack(self.community._prefix, MSG_MATCH_DONE, [dist, payload], False)
            self.community.endpoint.send(self.community.lookup_ip(match_payload.matchmaker_trader_id), packet)

        if self.order.status == "open":
            self.process_match()