def unpack_and_mint(self, msg): """unpacks the request retreiving the number of coins packed and the total value desired. Verification: values must be positive! """ self.number, msg = Basic.read_short(msg) value, msg = Basic.read_int(msg) log_msg('REQUEST:: %s %s'%(self.number, self.hexId), 0) if not BankUtil.is_positive_integer(self.number): raise ValueError('number of coins must be greater than 0!') if value != ACOIN_VALUE or not BankUtil.is_positive_integer(value): raise ValueError('coins must have a positive, integer value') self.bill = 0 self.signatures = "" for i in range(0, self.number): #TODO: move to a worker pool or something sig = Globals.ACOIN_KEY.decrypt(msg[:Globals.ACOIN_KEY_BYTES], False) self.signatures += struct.pack('!%ss'%(Globals.ACOIN_KEY_BYTES), sig) msg = msg[Globals.ACOIN_KEY_BYTES:] self.bill += value #TODO: move this constraint to postgres to get rid of any potential race conditions sql = "SELECT balance FROM Accounts WHERE Username = %s" inj = (self.user,) d = db.read(sql, inj) return d
def unpack_and_mint(self, msg): """unpacks the request retreiving the number of coins packed and the total value desired. Verification: values must be positive! """ self.number, msg = Basic.read_short(msg) value, msg = Basic.read_int(msg) log_msg('REQUEST:: %s %s' % (self.number, self.hexId), 0) if not BankUtil.is_positive_integer(self.number): raise ValueError('number of coins must be greater than 0!') if value != ACOIN_VALUE or not BankUtil.is_positive_integer(value): raise ValueError('coins must have a positive, integer value') self.bill = 0 self.signatures = "" for i in range(0, self.number): #TODO: move to a worker pool or something sig = Globals.ACOIN_KEY.decrypt(msg[:Globals.ACOIN_KEY_BYTES], False) self.signatures += struct.pack('!%ss' % (Globals.ACOIN_KEY_BYTES), sig) msg = msg[Globals.ACOIN_KEY_BYTES:] self.bill += value #TODO: move this constraint to postgres to get rid of any potential race conditions sql = "SELECT balance FROM Accounts WHERE Username = %s" inj = (self.user, ) d = db.read(sql, inj) return d
def main(): """Entrance""" global crtPassword crtPassword = getpass.getpass('enter private key password: '******'Login Reactor Started- Fail is near!', 2) BankUtil.update_local_acoin_interval(start_listening) Globals.reactor = reactor reactor.run()
def generate_reply(self, returned=None, optional=None): """This function is a bit crazy as it is entered from several points as both a callback or called directly :( returns either the successful msg, containing the symmertric key, balance, bank ip address, and login token OR the timeout until the client can log in again @param optional: text to return to the client with a code @type optional: [int, str] @return: None""" PROTOCOL = 1 if self.successful: log_msg('Login was successful.', 3) EventLogging.save_event(BankLogin(username=self.username)) #address of the bank server address = addressBook[0] curExp, nextExp = BankUtil.get_interval_time_deltas() format = '!BBIIII4sI' reply = struct.pack(format, PROTOCOL, 1, self.balance, Globals.CURRENT_ACOIN_INTERVAL[0], \ curExp, nextExp, inet_aton(address.host), address.port) reply += self.authBlob else: reply = struct.pack('!BBI', PROTOCOL, 0, self.timeout) #currently, 1 will replace the txt for a failure displayed client side, while 1 adds to it- thats all for now optional = [0, 'hello'] if optional: code = struct.pack('!B', optional[0]) reply += code + optional[1] #shove off the reply self.reply(reply)
def initialize(): """initialize coins and locks""" log_msg('Initializing cache.', 3) previous, current = BankUtil.get_intervals() Globals.Acoins = {previous: [], current: []} for i in range(Globals.numberOfSets+1): Globals.Acoins[previous].append(set()) Globals.Acoins[current].append(set())
def initialize(): """initialize coins and locks""" log_msg('Initializing cache.', 3) previous, current = BankUtil.get_intervals() Globals.Acoins = {previous: [], current: []} for i in range(Globals.numberOfSets + 1): Globals.Acoins[previous].append(set()) Globals.Acoins[current].append(set())
def reply(self, msg): balance = msg[0][0] curExp, nextExp = BankUtil.get_interval_time_deltas() reply = struct.pack('!IIII%ss'%(self.number), balance, Globals.CURRENT_ACOIN_INTERVAL[0], curExp, nextExp, self.returnSlip) self.encrypted_reply(reply) #log the event if anything was actually deposited: if self.amountEarned: eventLogger.aggregate_event("DEPOSITS", self.user, self.amountEarned)
def reply(self, msg): balance = msg[0][0] curExp, nextExp = BankUtil.get_interval_time_deltas() reply = struct.pack('!IIII%ss' % (self.number), balance, Globals.CURRENT_ACOIN_INTERVAL[0], curExp, nextExp, self.returnSlip) self.encrypted_reply(reply) #log the event if anything was actually deposited: if self.amountEarned: eventLogger.aggregate_event("DEPOSITS", self.user, self.amountEarned)
def main(): """Launches the Serverfactoryprotocolthing """ #run as a daemon Globals.logger = Logger.Logger(options.debug) Globals.logger.start_logs(["BANK", "errors"], "BANK", ".") Twisted.install_exception_handlers() BankUtil.update_local_acoin_interval(start_listening, on_new_interval) Globals.reactor = reactor log_msg('Server started: fail is imminent (not an error)!', 0) if Globals.DEBUG: def start_profiler(): Globals.PROFILER.clear() Globals.PROFILER.enable() def stop_profiler(): Globals.PROFILER.disable() Globals.PROFILER.dump_stats("temp.stats") reactor.callLater(15.0, start_profiler) reactor.callLater(75.0, stop_profiler) reactor.run() ACoinMessages.eventLogger.on_shutdown() log_msg("Shutdown cleanly", 2)
def on_new_interval(): """removes expired acoins and locks from the cache and makes new ones""" previous, current = BankUtil.get_intervals() log_msg('New interval learned: %s!'%current, 3) if Globals.isInitialize: Globals.Acoins[current] = [] for repo in range(Globals.numberOfSets+1): #create new ones Globals.Acoins[current].append(set()) del(Globals.Acoins[previous-1]) else: initialize() Globals.isInitialize = True
def on_new_interval(): """removes expired acoins and locks from the cache and makes new ones""" previous, current = BankUtil.get_intervals() log_msg('New interval learned: %s!' % current, 3) if Globals.isInitialize: Globals.Acoins[current] = [] for repo in range(Globals.numberOfSets + 1): #create new ones Globals.Acoins[current].append(set()) del (Globals.Acoins[previous - 1]) else: initialize() Globals.isInitialize = True
def unpack_and_verify(self, blob): """verifies that... 1. the coin is valid 2. isn't expired 3. hasn't been deposited before returns one of 4 statements""" self.number, blob = Basic.read_short(blob) log_msg('DEPOSIT:: %s %s'%(self.number, self.hexId), 0) total = 0 self.returnSlip = "" if BankUtil.is_positive_integer(self.number): #we don't want the interval to roll over half way through a request current = Globals.CURRENT_ACOIN_INTERVAL[0] for i in range(self.number): result, coin, blob = deposit_acoin(blob, current) self.returnSlip += result if result == '0': total += ACoin.VALUE self.amountEarned = total return total
def unpack_and_verify(self, blob): """verifies that... 1. the coin is valid 2. isn't expired 3. hasn't been deposited before returns one of 4 statements""" self.number, blob = Basic.read_short(blob) log_msg('DEPOSIT:: %s %s' % (self.number, self.hexId), 0) total = 0 self.returnSlip = "" if BankUtil.is_positive_integer(self.number): #we don't want the interval to roll over half way through a request current = Globals.CURRENT_ACOIN_INTERVAL[0] for i in range(self.number): result, coin, blob = deposit_acoin(blob, current) self.returnSlip += result if result == '0': total += ACoin.VALUE self.amountEarned = total return total
def get_cur_interval(): sql, inj = BankUtil.get_current_acoin_interval_sql() cur.execute(sql, inj) tup = cur.fetchall() return tup