def cb(timeout): self.requestBlocks_dcall = None # Pick one of the hashes randomly try: bhash = self.req_blocks.peek() except KeyError: return # Build request packet packet = ['bQ'] packet.append(self.main.osm.me.ipp) packet.append(bhash) # Send to bridge ad = Ad().setRawIPPort(self.parent_n.ipp) self.main.ph.sendPacket(''.join(packet), ad.getAddrTuple()) # Too many failures, just give up if timeout > 30.0: self.req_blocks.clear() return # Schedule next request. # This will become immediate if a reply arrives. when = random.uniform(0.9, 1.1) * timeout timeout *= 1.2 self.requestBlocks_dcall = reactor.callLater(when, cb, timeout)
def receivedBlockRequest(self, src_ipp, bhash): try: b = self.cached_blocks[bhash] except KeyError: LOG.warning("Requested block not found") return b.scheduleExpire(self.cached_blocks, bhash) packet = ['bB'] packet.append(self.main.osm.me.ipp) packet.append(struct.pack('!H', len(b.data))) packet.append(b.data) ad = Ad().setRawIPPort(src_ipp) self.main.ph.sendPacket(''.join(packet), ad.getAddrTuple())
def sendSyncReply(self, src_ipp, cont, uncont): # This gets spliced into the SyncRequestRoutingManager ad = Ad().setRawIPPort(src_ipp) osm = self.main.osm # Build Packet packet = ['bY'] # My IP:Port packet.append(osm.me.ipp) # seqnum, expire time, session id, uptime, flags, hashes, pubkey block_hashes, blocks = self.getStateData(packet) # Contacted Nodes packet.append(struct.pack('!B', len(cont))) packet.extend(cont) # Uncontacted Nodes packet.append(struct.pack('!B', len(uncont))) packet.extend(uncont) # Signature self.signPacket(packet, broadcast=False) # Send it self.main.ph.sendPacket(''.join(packet), ad.getAddrTuple()) # Keep track of the data for a while, # so the node can request it. for bhash, data in zip(block_hashes, blocks): try: b = self.cached_blocks[bhash] except KeyError: b = self.cached_blocks[bhash] = self.CachedBlock(data) b.scheduleExpire(self.cached_blocks, bhash)