def start(self): """Do the rest of the setup before turning control over to the reactor""" self._setup_environment() self._load_settings() self._load_data() self._create_applications() #in case this was the first run: self.bbApp.settings.fileName = os.path.join( Globals.USER_DATA_DIR, BitBlinder.BitBlinderSettings.defaultFile) GlobalEvents.throw_event("settings_changed") #must be done after settings are loaded self._start_psyco() #check for updates for the program: Updater.get().start() #start the bank bankStartupDeferred = self.bankApp.start() bankStartupDeferred.addCallback(self._on_bank_ready) bankStartupDeferred.addErrback(log_ex, "Bank failed to start!") #the rest of the startup code needs to run after the reactor has started: Scheduler.schedule_once(0.0, self._on_reactor_started)
def start(self): """Do the rest of the setup before turning control over to the reactor""" self._setup_environment() self._load_settings() self._load_data() self._create_applications() #in case this was the first run: self.bbApp.settings.fileName = os.path.join(Globals.USER_DATA_DIR, BitBlinder.BitBlinderSettings.defaultFile) GlobalEvents.throw_event("settings_changed") #must be done after settings are loaded self._start_psyco() #check for updates for the program: Updater.get().start() #start the bank bankStartupDeferred = self.bankApp.start() bankStartupDeferred.addCallback(self._on_bank_ready) bankStartupDeferred.addErrback(log_ex, "Bank failed to start!") #the rest of the startup code needs to run after the reactor has started: Scheduler.schedule_once(0.0, self._on_reactor_started)
def buildProtocol(self, addr): protocolInstance = protocol.ClientFactory.buildProtocol(self, addr) if self.protocolInstance: raise Exception("Hey, you're only supposed to build one protocol with this factory!") self.protocolInstance = protocolInstance self.protocolInstance.responseReceived = False Scheduler.schedule_once(TIMEOUT, self.on_timeout) return self.protocolInstance
def buildProtocol(self, addr): protocolInstance = protocol.ClientFactory.buildProtocol(self, addr) if self.protocolInstance: raise Exception( "Hey, you're only supposed to build one protocol with this factory!" ) self.protocolInstance = protocolInstance self.protocolInstance.responseReceived = False Scheduler.schedule_once(TIMEOUT, self.on_timeout) return self.protocolInstance
def _check_welcome_dialog(self, triggeringApp): if not self.torApp.is_ready() or not self.bankApp.is_ready(): return if not self.torApp.settings.promptedAboutRelay: self.welcomeDialog = WelcomeDialog.WelcomeDialog(self) self.torApp.settings.promptedAboutRelay = True self.torApp.settings.save() #TODO: remove this hack--need to schedule a _raise later so that the window doesnt get hidden by other stuff that happens when Tor launches def raise_later(): if self.welcomeDialog: self.welcomeDialog.raise_() Scheduler.schedule_once(2.0, raise_later)
def show_msgbox(self, text, title="Notice", cb=None, buttons=None, args=None, width=200, link=None): text = "%s: %s" % (title, text) if buttons != None: text += "\nDefaulted to %s" % (buttons[0]) if link != None: text += "\nLink: %s" % (link) log_msg(text, 2) if cb: if not args: args = [] args.insert(0, 0) args.insert(0, None) Scheduler.schedule_once(0.1, cb, *args)
def _check_welcome_dialog(self, triggeringApp): if not self.torApp.is_ready() or not self.bankApp.is_ready(): return if not self.torApp.settings.promptedAboutRelay: self.welcomeDialog = WelcomeDialog.WelcomeDialog(self) self.torApp.settings.promptedAboutRelay = True self.torApp.settings.save() #TODO: remove this hack--need to schedule a _raise later so that the window doesnt get hidden by other stuff that happens when Tor launches def raise_later(): if self.welcomeDialog: self.welcomeDialog.raise_() Scheduler.schedule_once(2.0, raise_later)
def send_payment_request(self, readTokens, writeTokens): """Called by a Circuit object when it wants to actually make a payment @param readTokens: the number of read tokens to pay for at each hop in the circuit @type readTokens: int @param writeTokens: the number of read tokens to pay for at each hop in the circuit @type writeTokens: int""" assert (readTokens + writeTokens) / Globals.CELLS_PER_PAYMENT, "tried to pay for bad number of cells" #make sure our setup is done: if not self.setupDone: #have we even started? if not self.setupStarted: self.send_setup_message() self.queuedReadTokens += readTokens self.queuedWriteTokens += writeTokens return #dont bother trying to send payments for circuits that are already closed if self.circ.is_done(): return #send the payments deferreds = [] for paymentStream in self.paymentStreams.values(): deferreds.append(paymentStream.send_payment(readTokens, writeTokens)) paymentsDoneDeferred = DeferredList(deferreds) paymentsDoneDeferred.addErrback(self.generic_error_handler) addTokensDeferred = Deferred() self.inflightReadTokens += readTokens self.inflightWriteTokens += writeTokens #timeout in case the payment fails. We will close the circuit in this case. event = Scheduler.schedule_once(PaymentStream.PAR_TIMEOUT, self.all_receipts_received, None, addTokensDeferred, readTokens, writeTokens, None) paymentsDoneDeferred.addCallback(self.all_receipts_received, addTokensDeferred, readTokens, writeTokens, event) addTokensDeferred.addCallback(self._add_tokens_callback, readTokens, writeTokens) addTokensDeferred.addErrback(self.generic_error_handler)
def send_setup_message(self): """Send the setup messages from each PaymentStream""" if not self.setupStarted: log_msg("circ=%d: Sending PAR setup message" % (self.circ.id), 3, "par") self.setupStarted = True self.inflightReadTokens += PaymentMessageHandler.START_READ_TOKENS self.inflightWriteTokens += PaymentMessageHandler.START_WRITE_TOKENS for paymentStream in self.paymentStreams.values(): paymentStream.send_setup() #schedule a timeout so we dont wait forever: def par_setup_timeout(): if not self.setupDone: #END_CIRC_REASON_TIMEOUT if not self.circ.is_done(): self.circ.close(10) Scheduler.schedule_once(PaymentStream.PAR_TIMEOUT, par_setup_timeout)
def send_setup_message(self): """Send the setup messages from each PaymentStream""" if not self.setupStarted: log_msg("circ=%d: Sending PAR setup message" % (self.circ.id), 3, "par") self.setupStarted = True self.inflightReadTokens += PaymentMessageHandler.START_READ_TOKENS self.inflightWriteTokens += PaymentMessageHandler.START_WRITE_TOKENS for paymentStream in self.paymentStreams.values(): paymentStream.send_setup() #schedule a timeout so we dont wait forever: def par_setup_timeout(): if not self.setupDone: #END_CIRC_REASON_TIMEOUT if not self.circ.is_done(): self.circ.close(10) Scheduler.schedule_once(PaymentStream.PAR_TIMEOUT, par_setup_timeout)
def handle_stream(self, stream): """Attach a Stream to an appropriate Circuit. Builds a new Circuit if necessary. @param stream: the stream to attach @type stream: Stream @return: True on success, False otherwise. Will close the stream if False is returned.""" stream.handleAttempts += 1 if stream.handleAttempts > 2: #7 = END_STREAM_REASON_TIMEOUT (failed to connect in a reasonable amount of time) stream.close(7) log_msg("Tried to attach stream too many times, stopping.", 2, "stream") return False host = stream.targetHost port = stream.targetPort #record in our port history: if port not in self.portHistory: self.portHistory[port] = 0 self.portHistory[port] += 1 #find the best circuit, or failing that, build one: best = self.find_or_build_best_circuit(host, port, stream.ignoreCircuits) #if there is no such circuit: if not best: #3 = END_STREAM_REASON_CONNECTREFUSED (we couldnt figure out where to connect) stream.close(3) return False #actually attach the stream to the circuit if not best.attach(stream): #1 -- REASON_MISC (catch-all for unlisted reasons) stream.close(1) log_msg( "Stream=%d failed to attach to Circuit=%d" % (stream.id, best.id), 1, "stream") return False #if the circuit is not yet open, put a 15 second timeout on it: if not best.status in ("LAUNCHED", "PRELAUNCH"): def circuit_timeout(circ): if circ.status in ("LAUNCHED", "PRELAUNCH") and circ.is_open(): circ.close() Scheduler.schedule_once(15.0, circuit_timeout, best) return True
def show_msgbox(self, text, title="Notice", cb=None, buttons=None, args=None, width=200, link=None): text = "%s: %s" % (title, text) if buttons != None: text += "\nDefaulted to %s" % (buttons[0]) if link != None: text += "\nLink: %s" % (link) log_msg(text, 2) if cb: if not args: args = [] args.insert(0, 0) args.insert(0, None) Scheduler.schedule_once(0.1, cb, *args)
def on_new_info(self, balance, interval, expiresCurrent, expiresNext): """Called when we learn about new ACoin interval information @param balance: new bank balance @type balance: int @param interval: current ACoin interval @type interval: int @param expiresCurrent: how many seconds until this interval expires @type expiresCurrent: int @param expiresNext: how many seconds until the next interval also expires @type expiresNext: int""" #if we just learned about a new interval: if interval > self.currentACoinInterval: curTime = time.time() expiresCurrent += curTime expiresNext += curTime log_msg("Learned about new interval: %s" % (interval), 4) #make sure we dont have any expiring ACoins: if self.ACoins.has_key(self.currentACoinInterval - 1): del self.ACoins[self.currentACoinInterval - 1] self.currentACoinInterval = interval self.curIntervalExpiration = expiresCurrent self.nextAcoinIntervalExpiration = expiresNext self.APPROX_INTERVAL_LEN = expiresNext - expiresCurrent self.beginDepositACoinTime = expiresCurrent - ( 0.1 * self.APPROX_INTERVAL_LEN) self.beginDepositACoinTime -= random.random() * ( 0.3 * self.APPROX_INTERVAL_LEN) self.sendOldACoinCutoff = expiresCurrent - ( 0.1 * self.APPROX_INTERVAL_LEN) needNewACoinTime = self.sendOldACoinCutoff - ( random.random() * 0.1 * self.APPROX_INTERVAL_LEN) - curTime if needNewACoinTime > 0: Scheduler.schedule_once(needNewACoinTime, self.check_next_acoins) self.intervalLearningDelay = random.random() * ( 0.25 * self.APPROX_INTERVAL_LEN) log_msg("\nACoin send cutoff: %s\nACoin accept cutoff: %s\nCur interval ends at: %s\nLearning about next interval at: %s" \ % tuple([time.asctime(time.gmtime(t)) for t in (self.sendOldACoinCutoff, self.beginDepositACoinTime, expiresCurrent, expiresCurrent+self.intervalLearningDelay)]), 4) self.on_new_balance_from_bank(balance)
def handle_stream(self, stream): """Attach a Stream to an appropriate Circuit. Builds a new Circuit if necessary. @param stream: the stream to attach @type stream: Stream @return: True on success, False otherwise. Will close the stream if False is returned.""" stream.handleAttempts += 1 if stream.handleAttempts > 2: #7 = END_STREAM_REASON_TIMEOUT (failed to connect in a reasonable amount of time) stream.close(7) log_msg("Tried to attach stream too many times, stopping.", 2, "stream") return False host = stream.targetHost port = stream.targetPort #record in our port history: if port not in self.portHistory: self.portHistory[port] = 0 self.portHistory[port] += 1 #find the best circuit, or failing that, build one: best = self.find_or_build_best_circuit(host, port, stream.ignoreCircuits) #if there is no such circuit: if not best: #3 = END_STREAM_REASON_CONNECTREFUSED (we couldnt figure out where to connect) stream.close(3) return False #actually attach the stream to the circuit if not best.attach(stream): #1 -- REASON_MISC (catch-all for unlisted reasons) stream.close(1) log_msg("Stream=%d failed to attach to Circuit=%d" % (stream.id, best.id), 1, "stream") return False #if the circuit is not yet open, put a 15 second timeout on it: if not best.status in ("LAUNCHED", "PRELAUNCH"): def circuit_timeout(circ): if circ.status in ("LAUNCHED", "PRELAUNCH") and circ.is_open(): circ.close() Scheduler.schedule_once(15.0, circuit_timeout, best) return True
def _subprocess_finished(self, result, p): if result == True: self.remove_process(p) if p == self.polipoProc: self.polipoProc = None self.stop() else: if len(self.processes) == 1 and self.polipoProc: #lets check if any firefoxes start up in the next few seconds, in case this is the reboot: if not self.checkFFEvent: self.checkFFEvent = Scheduler.schedule_once(2.0, self._check_for_firefoxes) if len(self.processes) <= 0: self._all_subprocesses_done() elif result != False: log_ex(result, "Failed while waiting for subprocess")
def stop(self, timeout=10.0): """Dump all ACoins immediately. @param timeout: how long to wait while depositing ACoins @returns: a Deferred to be triggered when done or if the attempt timed out.""" if self.shutdownDeferred: return self.shutdownDeferred #cancel any bank messages in progress self.messageQueue = [] #since we wont be able to send the deposit anyway... if not self.isLoggedIn: if self.is_starting(): #notify anyone waiting on the startup deferred: self.loginInProgress = False d = self.startupDeferred self.startupDeferred = None d.callback(False) return defer.succeed(True) #create the deferred self.shutdownDeferred = defer.Deferred() #schedule the timeout self.shutdownTimeoutEvent = Scheduler.schedule_once( timeout, self._shutdown_timeout) #move all ACoins over to be in deposit progress coinsToDeposit = [] for key, coins in self.ACoins.iteritems(): coinsToDeposit += coins self.ACoins = {} self.depositingACoins += coinsToDeposit if not self.acoinDepositInProgress: coinsToDeposit = self.depositingACoins #save ACoins self.coinsChanged = True self.save_coins() #send the message to the bank bankD = defer.Deferred() self.send_message( ACoinDepositFactory.ACoinDepositFactory(self, coinsToDeposit, bankD)) #on success, trigger the deferred bankD.addCallback(self._shutdown_success) #deal with failure by trying again bankD.addErrback(self._shutdown_failure) self._trigger_event("stopped") return self.shutdownDeferred
def add_task(self, func, delay = 0, id = None): assert float(delay) >= 0 eventId = self.curEventId self.curEventId += 1 if not self.idMapping.has_key(id): self.idMapping[id] = set() self.idMapping[id].add(eventId) def wrapperFunc(func=func, id=id, eventId=eventId): if self.idMapping.has_key(id) and eventId in self.idMapping[id]: self.idMapping[id].remove(eventId) if len(self.idMapping[id]) <= 0: del self.idMapping[id] if self.events.has_key(id) and self.events[id].has_key(eventId): del self.events[id][eventId] if len(self.events[id]) <= 0: del self.events[id] func() if not self.events.has_key(id): self.events[id] = {} self.events[id][eventId] = Scheduler.schedule_once(delay, wrapperFunc)
def send_payment_request(self, readTokens, writeTokens): """Called by a Circuit object when it wants to actually make a payment @param readTokens: the number of read tokens to pay for at each hop in the circuit @type readTokens: int @param writeTokens: the number of read tokens to pay for at each hop in the circuit @type writeTokens: int""" assert ( readTokens + writeTokens ) / Globals.CELLS_PER_PAYMENT, "tried to pay for bad number of cells" #make sure our setup is done: if not self.setupDone: #have we even started? if not self.setupStarted: self.send_setup_message() self.queuedReadTokens += readTokens self.queuedWriteTokens += writeTokens return #dont bother trying to send payments for circuits that are already closed if self.circ.is_done(): return #send the payments deferreds = [] for paymentStream in self.paymentStreams.values(): deferreds.append( paymentStream.send_payment(readTokens, writeTokens)) paymentsDoneDeferred = DeferredList(deferreds) paymentsDoneDeferred.addErrback(self.generic_error_handler) addTokensDeferred = Deferred() self.inflightReadTokens += readTokens self.inflightWriteTokens += writeTokens #timeout in case the payment fails. We will close the circuit in this case. event = Scheduler.schedule_once(PaymentStream.PAR_TIMEOUT, self.all_receipts_received, None, addTokensDeferred, readTokens, writeTokens, None) paymentsDoneDeferred.addCallback(self.all_receipts_received, addTokensDeferred, readTokens, writeTokens, event) addTokensDeferred.addCallback(self._add_tokens_callback, readTokens, writeTokens) addTokensDeferred.addErrback(self.generic_error_handler)
def add_task(self, func, delay=0, id=None): assert float(delay) >= 0 eventId = self.curEventId self.curEventId += 1 if not self.idMapping.has_key(id): self.idMapping[id] = set() self.idMapping[id].add(eventId) def wrapperFunc(func=func, id=id, eventId=eventId): if self.idMapping.has_key(id) and eventId in self.idMapping[id]: self.idMapping[id].remove(eventId) if len(self.idMapping[id]) <= 0: del self.idMapping[id] if self.events.has_key(id) and self.events[id].has_key(eventId): del self.events[id][eventId] if len(self.events[id]) <= 0: del self.events[id] func() if not self.events.has_key(id): self.events[id] = {} self.events[id][eventId] = Scheduler.schedule_once(delay, wrapperFunc)
def _schedule_next_test(self): self.nextScheduledTest = Scheduler.schedule_once( self.SECONDS_BETWEEN_TESTS, self._start_probe)
def _schedule_timeout(self, result=None): Scheduler.schedule_once(self.timeout, self.failure, TimeoutError())
def request_failed(self, error, httpDownloadInstance=None): self.downloadingUpdate = False log_ex(error, "Error while downloading update", [DownloadSizeError]) #lets try the full installer instead then Scheduler.schedule_once(30 * 60, self.check_for_updates)
def hash_failed(self, error): self.downloadingUpdate = False log_ex(error, "Error while verifying update") #lets just try again in half an hour or something Scheduler.schedule_once(30 * 60, self.check_for_updates)
def _schedule_next_test(self): self.nextScheduledTest = Scheduler.schedule_once(self.SECONDS_BETWEEN_TESTS, self._start_probe)
def _schedule_timeout(self, result=None): Scheduler.schedule_once(self.timeout, self.failure, TimeoutError())