def create_community(self, cls, *args, **kwargs): temp_dir = unicode(mkdtemp(suffix="_dispersy_test_session")) dispersy = Dispersy(StandaloneEndpoint(0), temp_dir, database_filename=u':memory:') dispersy.start(autoload_discovery=False) my_member = dispersy.get_new_member(u'curve25519') if self.communities: head_community = self.communities[0] master_member = dispersy.get_member(mid=head_community._master_member.mid) community = cls.init_community(dispersy, master_member, my_member, *args, **kwargs) community.candidates.clear() community.add_discovered_candidate(Candidate(head_community.dispersy.lan_address, False)) else: community = cls.create_community(dispersy, my_member, *args, **kwargs) community.candidates.clear() self.attach_hooks(community) self.communities.append(community) return community
class DispersyManager(object): def __init__(self, port, state_dir, keypair_fn): self.logger = logging.getLogger(self.__class__.__name__) self.port = port self.state_dir = state_dir self.keypair_fn = keypair_fn or os.path.join(self.state_dir, 'market.pem') self.session = None self.dispersy = None self.community = None def start_dispersy(self): self.logger.info('Starting Dispersy on port %d with state dir %s', self.port, self.state_dir) endpoint = StandaloneEndpoint(self.port) self.dispersy = Dispersy(endpoint, self.state_dir) return self.dispersy.start(autoload_discovery=True) def start_market(self, *args, **kwargs): if os.path.exists(self.keypair_fn): self.logger.info('Using existing keypair') with open(self.keypair_fn, 'rb') as keypair_fp: keypair_bin = keypair_fp.read() keypair = LibNaCLSK(binarykey=keypair_bin) else: self.logger.info('Creating new keypair') keypair = LibNaCLSK() with open(self.keypair_fn, 'wb') as keypair_fp: keypair_fp.write(keypair.key.sk) keypair_fp.write(keypair.key.seed) self.logger.debug('Public key %s', urlsafe_b64encode(keypair.pub().key_to_bin())) member = self.dispersy.get_member(private_key=keypair.key_to_bin()) database = InternetOfMoneyDB(self.state_dir) manager = BankManager(database, cache_dir=self.state_dir) money_community = self.dispersy.define_auto_load(MoneyCommunity, member, load=True)[0] money_community.bank_managers = {manager.get_bank_id(): manager} self.logger.info('Starting MarketCommunity') kwargs['money_community'] = money_community self.community = self.dispersy.define_auto_load(MarketCommunity, member, load=True, args=args, kargs=kwargs)[0] def stop_dispersy(self): self.logger.info('Stopping Dispersy') return self.dispersy.stop()
def run(): crypto = ECCrypto() dispersy = Dispersy( StandaloneEndpoint(options["port"], options["ip"]), options["statedir"], u'dispersy.db', crypto) if not dispersy.start(): raise RuntimeError("Unable to start Dispersy") master_member = MarketCommunity.get_master_members(dispersy)[0] my_member = dispersy.get_member(private_key=crypto.key_to_bin( crypto.generate_key(u"curve25519"))) MarketCommunity.init_community(dispersy, master_member, my_member) self._stopping = False def signal_handler(sig, frame): logger.info("Received signal '%s' in %s (shutting down)" % (sig, frame)) if not self._stopping: self._stopping = True dispersy.stop() reactor.stop() signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler)
class Session(object): """ This class represents an Internet-of-Money session. It contains methods to start, close and manage the session. """ def __init__(self, options): self.options = options self.managers = {} self.money_community = None self.line_receiver = None self.database = None self.dispersy = None self.is_switch = False self.cache_dir = self.options['cache'] self.api_manager = None self.input_deferreds = {} self.is_locked = True self.file_handler = None self.stream_handler = None # Make sure to use our own root certificates file dir_path = os.path.dirname(os.path.realpath(__file__)) os.environ['SSL_CERT_FILE'] = os.path.join(dir_path, 'data', 'root_certs.pem') def start(self): if not os.path.exists(self.cache_dir): os.mkdir(self.cache_dir) # Setup the database self.database = InternetOfMoneyDB(self.cache_dir) self.init_logging() if self.options["switch"]: self.enable_switch() self.initialize_managers() # Start the HTTP API self.api_manager = RESTManager(self) self.api_manager.start(self.options['apiport']) for manager in self.managers.itervalues(): manager.input_handler = self.input_handler @inlineCallbacks def stop(self): yield self.api_manager.stop() self.database.close() logging.getLogger().removeHandler(self.file_handler) logging.getLogger().removeHandler(self.stream_handler) if self.dispersy: yield self.dispersy.stop() yield succeed(None) def unlock(self, password): """ Unlock the wallet using the provided password. """ if not self.is_locked: return # Already unlocked if not os.path.exists(os.path.join(self.cache_dir, 'pwhash')): raise RuntimeError("No password set!") with open(os.path.join(self.cache_dir, 'pwhash'), 'r') as hash_file: file_hash = hash_file.read() hex_hash = hashlib.sha1(bytes(password)).hexdigest() if file_hash != hex_hash: raise WrongPasswordException() for manager in self.managers.itervalues(): manager.load_storage(password) self.is_locked = False def set_password(self, password): """ Set the password for this wallet. """ if os.path.exists(os.path.join(self.cache_dir, 'pwhash')): raise PasswordAlreadySetException() with open(os.path.join(self.cache_dir, 'pwhash'), 'w') as hash_file: hex_hash = hashlib.sha1(bytes(password)).hexdigest() hash_file.write(hex_hash) for manager in self.managers.itervalues(): manager.load_storage(password) def input_handler(self, required_input): input_deferred = Deferred() self.input_deferreds[required_input.name] = input_deferred self.api_manager.root_endpoint.events_endpoint.send_input_request(required_input) return input_deferred def on_input(self, name, user_input): """ This method is invoked when there is user input available. :param name: the name of the input, should match the name passed to iom_input_handler :type name: str :param user_input: a dictionary with the given user input. :type user_input: dict """ if name not in self.input_deferreds: raise RuntimeError("Received input that we didn't expect!") self.input_deferreds[name].callback(user_input) del self.input_deferreds[name] def init_logging(self): # Initialize logging log.startLogging(sys.stdout) root = logging.getLogger() root.setLevel(logging.DEBUG) # Log critical messages to stderr self.stream_handler = logging.StreamHandler(sys.stderr) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') self.stream_handler.setFormatter(formatter) self.stream_handler.setLevel(logging.CRITICAL) root.addHandler(self.stream_handler) self.file_handler = logging.handlers.WatchedFileHandler( os.environ.get("LOGFILE", os.path.join(self.cache_dir, "iom.log"))) self.file_handler.setFormatter(formatter) self.file_handler.setLevel(logging.DEBUG) root.addHandler(self.file_handler) def initialize_managers(self): paypal_manager = PayPalManager(self.database, cache_dir=self.cache_dir) rabo_manager = RaboManager(self.database, cache_dir=self.cache_dir) abn_manager = ABNManager(self.database, cache_dir=self.cache_dir) ing_manager = INGManager(self.database, cache_dir=self.cache_dir) self.managers = { paypal_manager.get_bank_id(): paypal_manager, rabo_manager.get_bank_id(): rabo_manager, abn_manager.get_bank_id(): abn_manager, ing_manager.get_bank_id(): ing_manager, } if self.options['dummy']: dummy1_manager = Dummy1Manager(self.database, cache_dir=self.cache_dir) dummy2_manager = Dummy2Manager(self.database, cache_dir=self.cache_dir) dummy3_manager = Dummy3Manager(self.database, cache_dir=self.cache_dir) self.managers[dummy1_manager.get_bank_id()] = dummy1_manager self.managers[dummy2_manager.get_bank_id()] = dummy2_manager self.managers[dummy3_manager.get_bank_id()] = dummy3_manager def load_money_community(self): keypair_path = os.path.join(self.cache_dir, 'ec.pem') if os.path.exists(keypair_path): keypair = permid.read_keypair(keypair_path) else: keypair = permid.generate_keypair() permid.save_keypair(keypair, keypair_path) master_member = self.dispersy.get_member(private_key=keypair.key_to_bin()) chain_community = self.dispersy.define_auto_load(MoneyChainCommunity, master_member, load=True, kargs={})[0] kwargs = { 'database': self.database, 'money_chain_community': chain_community, 'tx_fee': self.options['txfee'] } self.money_community = self.dispersy.define_auto_load(MoneyCommunity, master_member, load=True, kargs=kwargs)[0] self.money_community.bank_managers = self.managers def enable_switch(self): self.is_switch = True # Start Dispersy. First, fix the bootstrap server pointer os.environ[BOOTSTRAP_FILE_ENVNAME] = 'bootstrap.txt' self.dispersy = Dispersy(StandaloneEndpoint(self.options['port'], '0.0.0.0'), os.path.join(self.cache_dir, u'dispersy'), u'dispersy.db') self.dispersy.statistics.enable_debug_statistics(True) self.dispersy.start(autoload_discovery=True) self.load_money_community()
class MarketApplication(QApplication): """ This class represents the main Market application. """ bank_status = {} port = 1236 database_prefix = 'market' def __init__(self, *argv): QApplication.__init__(self, *argv) def initialize(self): self.initialize_api() # Load banks from market import Global from market.models.user import User for bank_name in Global.BANKS: bank = self.api._get_user(Global.BANKS[bank_name]) or User( public_key=Global.BANKS[bank_name], time_added=0) bank.post_or_put(self.api.db) self.api.create_profile(bank, {'role': 3}) # self.private_key = None self.user = None self.community = None self.identify() # signal.signal(signal.SIGINT, self.close) signal.signal(signal.SIGQUIT, self.close) self.aboutToQuit.connect(self.close) def run(self): #print reactor # reactor.callWhenRunning(self.start_dispersy) # reactor.run() pass def close(self, *_): from twisted.internet import reactor self.dispersy.stop() reactor.stop() time.sleep(2) os._exit(1) def initialize_api(self): from market.api.api import MarketAPI from market.database.backends import PersistentBackend, MemoryBackend from market.database.database import MarketDatabase self._api = MarketAPI( MarketDatabase(PersistentBackend('.', u'sqlite/market.db'))) def identify(self): """ Identify the user to the system. If it already exists in the screen go on, if not create a user. """ try: self.private_key = self.api.db.backend.get_option('user_key_priv') self.user = self.api.login_user(self.private_key.encode("HEX")) print "Using an existing user" except (KeyError, IndexError): user, _, priv = self.api.create_user() self.user = user self.private_key = priv print "Using a new user" def start_dispersy(self): from dispersy.dispersy import Dispersy from dispersy.endpoint import StandaloneEndpoint from market import Global from market.community.community import MortgageMarketCommunity from twisted.internet.task import LoopingCall self.dispersy = Dispersy(StandaloneEndpoint(self.port, '0.0.0.0'), unicode('.'), u'dispersy-%s.db' % self.database_prefix) self.dispersy.statistics.enable_debug_statistics(True) self.dispersy.start(autoload_discovery=True) my_member = self.dispersy.get_member( private_key=self.private_key.decode("HEX")) master_member = self.dispersy.get_member(public_key=Global.MASTER_KEY) self.community = MortgageMarketCommunity.init_community( self.dispersy, master_member, my_member) self.community.api = self.api self.community.user = self.user self.api.community = self.community # Run the scenario every 3 seconds LoopingCall(self._scenario).start(3.0) # Send messages from the queue every 3 seconds LoopingCall(self.api.outgoing_queue.process).start(3.0) LoopingCall(self.api.incoming_queue.process).start(3.0) def _scenario(self): for bank_id in Global.BANKS: user = self.api._get_user(Global.BANKS[bank_id]) if user.id in self.api.user_candidate and self.bank_status[ bank_id] == False: print bank_id, " is ONLINE" self.bank_status[bank_id] = True self.profile = True else: if not bank_id in self.bank_status: self.bank_status[bank_id] = False print bank_id, " is OFFLINE" # pass @property def api(self): return self._api