def __init__(self, name: str, nodeReg: Dict[str, HA] = None, ha: Union[HA, Tuple[str, int]] = None, basedirpath: str = None, genesis_dir: str = None, ledger_dir: str = None, keys_dir: str = None, plugins_dir: str = None, config=None, sighex: str = None): """ Creates a new client. :param name: unique identifier for the client :param nodeReg: names and host addresses of all nodes in the pool :param ha: tuple of host and port """ self.config = config or getConfig() dataDir = self.config.clientDataDir or "data/clients" self.basedirpath = basedirpath or self.config.CLI_BASE_DIR self.basedirpath = os.path.expanduser(self.basedirpath) signer = Signer(sighex) sighex = signer.keyraw verkey = rawToFriendly(signer.verraw) self.stackName = verkey # TODO: Have a way for a client to have a user friendly name. Does it # matter now, it used to matter in some CLI exampples in the past. # self.name = name self.name = self.stackName or 'Client~' + str(id(self)) self.genesis_dir = genesis_dir or self.basedirpath self.ledger_dir = ledger_dir or os.path.join(self.basedirpath, dataDir, self.name) self.plugins_dir = plugins_dir or self.basedirpath _keys_dir = keys_dir or self.basedirpath self.keys_dir = os.path.join(_keys_dir, "keys") cha = None if self.exists(self.stackName, self.keys_dir): cha = self.nodeStackClass.getHaFromLocal( self.stackName, self.keys_dir) if cha: cha = HA(*cha) logger.debug("Client {} ignoring given ha {} and using {}". format(self.name, ha, cha)) if not cha: cha = ha if isinstance(ha, HA) else HA(*ha) self.reqRepStore = self.getReqRepStore() self.txnLog = self.getTxnLogStore() HasFileStorage.__init__(self, self.ledger_dir) # TODO: Find a proper name self.alias = name if not nodeReg: self.mode = None HasPoolManager.__init__(self) self.ledgerManager = LedgerManager(self, ownedByNode=False) self.ledgerManager.addLedger( POOL_LEDGER_ID, self.ledger, preCatchupStartClbk=self.prePoolLedgerCatchup, postCatchupCompleteClbk=self.postPoolLedgerCaughtUp, postTxnAddedToLedgerClbk=self.postTxnFromCatchupAddedToLedger) else: cliNodeReg = OrderedDict() for nm, (ip, port) in nodeReg.items(): cliNodeReg[nm] = HA(ip, port) self.nodeReg = cliNodeReg self.mode = Mode.discovered HasActionQueue.__init__(self) self.setPoolParams() stackargs = dict(name=self.stackName, ha=cha, main=False, # stops incoming vacuous joins auth_mode=AuthMode.ALLOW_ANY.value) stackargs['basedirpath'] = self.keys_dir self.created = time.perf_counter() # noinspection PyCallingNonCallable # TODO I think this is a bug here, sighex is getting passed in the seed # parameter self.nodestack = self.nodeStackClass(stackargs, self.handleOneNodeMsg, self.nodeReg, sighex) self.nodestack.onConnsChanged = self.onConnsChanged if self.nodeReg: logger.info( "Client {} initialized with the following node registry:".format( self.alias)) lengths = [max(x) for x in zip(*[ (len(name), len(host), len(str(port))) for name, (host, port) in self.nodeReg.items()])] fmt = " {{:<{}}} listens at {{:<{}}} on port {{:>{}}}".format( *lengths) for name, (host, port) in self.nodeReg.items(): logger.info(fmt.format(name, host, port)) else: logger.info( "Client {} found an empty node registry:".format(self.alias)) Motor.__init__(self) self.inBox = deque() self.nodestack.connectNicelyUntil = 0 # don't need to connect # nicely as a client # TODO: Need to have couple of tests around `reqsPendingConnection` # where we check with and without pool ledger # Stores the requests that need to be sent to the nodes when the client # has made sufficient connections to the nodes. self.reqsPendingConnection = deque() # Tuple of identifier and reqId as key and value as tuple of set of # nodes which are expected to send REQACK self.expectingAcksFor = {} # Tuple of identifier and reqId as key and value as tuple of set of # nodes which are expected to send REPLY self.expectingRepliesFor = {} self._observers = {} # type Dict[str, Callable] self._observerSet = set() # makes it easier to guard against duplicates plugins_to_load = self.config.PluginsToLoad if hasattr(self.config, "PluginsToLoad") else None tp = loadPlugins(self.plugins_dir, plugins_to_load) logger.debug("total plugins loaded in client: {}".format(tp)) self._multi_sig_verifier = self._create_multi_sig_verifier() self._read_only_requests = set()
def __init__(self, name: str, nodeReg: Dict[str, HA]=None, ha: Union[HA, Tuple[str, int]]=None, basedirpath: str=None, config=None, sighex: str=None): """ Creates a new client. :param name: unique identifier for the client :param nodeReg: names and host addresses of all nodes in the pool :param ha: tuple of host and port """ self.config = config or getConfig() basedirpath = self.config.baseDir if not basedirpath else basedirpath self.basedirpath = basedirpath signer = Signer(sighex) sighex = signer.keyhex verkey = rawToFriendly(signer.verraw) self.name = name self.stackName = verkey cha = None # If client information already exists is RAET then use that if self.exists(self.stackName, basedirpath): cha = getHaFromLocalEstate(self.stackName, basedirpath) if cha: cha = HA(*cha) logger.debug("Client {} ignoring given ha {} and using {}". format(self.name, ha, cha)) if not cha: cha = ha if isinstance(ha, HA) else HA(*ha) self.reqRepStore = self.getReqRepStore() self.txnLog = self.getTxnLogStore() self.dataDir = self.config.clientDataDir or "data/clients" HasFileStorage.__init__(self, self.name, baseDir=self.basedirpath, dataDir=self.dataDir) self._ledger = None if not nodeReg: self.mode = None HasPoolManager.__init__(self) self.ledgerManager = LedgerManager(self, ownedByNode=False) self.ledgerManager.addLedger(0, self.ledger, postCatchupCompleteClbk=self.postPoolLedgerCaughtUp, postTxnAddedToLedgerClbk=self.postTxnFromCatchupAddedToLedger) else: cliNodeReg = OrderedDict() for nm, (ip, port) in nodeReg.items(): cliNodeReg[nm] = HA(ip, port) self.nodeReg = cliNodeReg self.mode = Mode.discovered HasActionQueue.__init__(self) self.setF() stackargs = dict(name=self.stackName, ha=cha, main=False, # stops incoming vacuous joins auto=AutoMode.always) stackargs['basedirpath'] = basedirpath self.created = time.perf_counter() # noinspection PyCallingNonCallable self.nodestack = self.nodeStackClass(stackargs, self.handleOneNodeMsg, self.nodeReg, sighex) self.nodestack.onConnsChanged = self.onConnsChanged if self.nodeReg: logger.info("Client {} initialized with the following node registry:" .format(self.name)) lengths = [max(x) for x in zip(*[ (len(name), len(host), len(str(port))) for name, (host, port) in self.nodeReg.items()])] fmt = " {{:<{}}} listens at {{:<{}}} on port {{:>{}}}".format( *lengths) for name, (host, port) in self.nodeReg.items(): logger.info(fmt.format(name, host, port)) else: logger.info( "Client {} found an empty node registry:".format(self.name)) Motor.__init__(self) self.inBox = deque() self.nodestack.connectNicelyUntil = 0 # don't need to connect # nicely as a client # TODO: Need to have couple of tests around `reqsPendingConnection` # where we check with and without pool ledger # Stores the requests that need to be sent to the nodes when the client # has made sufficient connections to the nodes. self.reqsPendingConnection = deque() # Tuple of identifier and reqId as key and value as tuple of set of # nodes which are expected to send REQACK self.expectingAcksFor = {} # Tuple of identifier and reqId as key and value as tuple of set of # nodes which are expected to send REPLY self.expectingRepliesFor = {} tp = loadPlugins(self.basedirpath) logger.debug("total plugins loaded in client: {}".format(tp))
def __init__(self, name: str, nodeReg: Dict[str, HA] = None, ha: Union[HA, Tuple[str, int]] = None, basedirpath: str = None, config=None): """ Creates a new client. :param name: unique identifier for the client :param nodeReg: names and host addresses of all nodes in the pool :param ha: tuple of host and port :param lastReqId: Request Id of the last request sent by client """ self.config = config or getConfig() basedirpath = self.config.baseDir if not basedirpath else basedirpath self.basedirpath = basedirpath cha = None # If client information already exists is RAET then use that if self.exists(name, basedirpath): logger.debug("Client {} ignoring given ha".format(ha)) cha = getHaFromLocalEstate(name, basedirpath) if cha: cha = HA(*cha) if not cha: cha = ha if isinstance(ha, HA) else HA(*ha) self.name = name self.reqRepStore = self.getReqRepStore() self.txnLog = self.getTxnLogStore() self.dataDir = self.config.clientDataDir or "data/clients" HasFileStorage.__init__(self, self.name, baseDir=self.basedirpath, dataDir=self.dataDir) self._ledger = None if not nodeReg: self.mode = None HasPoolManager.__init__(self) self.ledgerManager = LedgerManager(self, ownedByNode=False) self.ledgerManager.addLedger( 0, self.ledger, postCatchupCompleteClbk=self.postPoolLedgerCaughtUp, postTxnAddedToLedgerClbk=self.postTxnFromCatchupAddedToLedger) else: cliNodeReg = OrderedDict() for nm, (ip, port) in nodeReg.items(): cliNodeReg[nm] = HA(ip, port) self.nodeReg = cliNodeReg self.mode = Mode.discovered self.setF() stackargs = dict( name=name, ha=cha, main=False, # stops incoming vacuous joins auto=AutoMode.always) stackargs['basedirpath'] = basedirpath self.created = time.perf_counter() # noinspection PyCallingNonCallable self.nodestack = self.nodeStackClass(stackargs, self.handleOneNodeMsg, self.nodeReg) self.nodestack.onConnsChanged = self.onConnsChanged logger.info( "Client {} initialized with the following node registry:".format( name)) lengths = [ max(x) for x in zip(*[(len(name), len(host), len(str(port))) for name, (host, port) in self.nodeReg.items()]) ] fmt = " {{:<{}}} listens at {{:<{}}} on port {{:>{}}}".format( *lengths) for name, (host, port) in self.nodeReg.items(): logger.info(fmt.format(name, host, port)) Motor.__init__(self) self.inBox = deque() self.nodestack.connectNicelyUntil = 0 # don't need to connect # nicely as a client # TODO: Need to have couple of tests around `reqsPendingConnection` # where we check with and without pool ledger # Stores the requests that need to be sent to the nodes when the client # has made sufficient connections to the nodes. self.reqsPendingConnection = deque() tp = loadPlugins(self.basedirpath) logger.debug("total plugins loaded in client: {}".format(tp))
def __init__(self, name: str, nodeReg: Dict[str, HA] = None, ha: Union[HA, Tuple[str, int]] = None, basedirpath: str = None, config=None, sighex: str = None): """ Creates a new client. :param name: unique identifier for the client :param nodeReg: names and host addresses of all nodes in the pool :param ha: tuple of host and port """ self.config = config or getConfig() basedirpath = self.config.baseDir if not basedirpath else basedirpath self.basedirpath = basedirpath signer = Signer(sighex) sighex = signer.keyraw verkey = rawToFriendly(signer.verraw) self.stackName = verkey # TODO: Have a way for a client to have a user friendly name. Does it # matter now, it used to matter in some CLI exampples in the past. # self.name = name self.name = self.stackName cha = None # If client information already exists is RAET then use that if self.exists(self.stackName, basedirpath): cha = getHaFromLocalEstate(self.stackName, basedirpath) if cha: cha = HA(*cha) logger.debug( "Client {} ignoring given ha {} and using {}".format( self.name, ha, cha)) if not cha: cha = ha if isinstance(ha, HA) else HA(*ha) self.reqRepStore = self.getReqRepStore() self.txnLog = self.getTxnLogStore() self.dataDir = self.config.clientDataDir or "data/clients" HasFileStorage.__init__(self, self.name, baseDir=self.basedirpath, dataDir=self.dataDir) # TODO: Find a proper name self.alias = name self._ledger = None if not nodeReg: self.mode = None HasPoolManager.__init__(self) self.ledgerManager = LedgerManager(self, ownedByNode=False) self.ledgerManager.addLedger( 0, self.ledger, postCatchupCompleteClbk=self.postPoolLedgerCaughtUp, postTxnAddedToLedgerClbk=self.postTxnFromCatchupAddedToLedger) else: cliNodeReg = OrderedDict() for nm, (ip, port) in nodeReg.items(): cliNodeReg[nm] = HA(ip, port) self.nodeReg = cliNodeReg self.mode = Mode.discovered HasActionQueue.__init__(self) self.setF() stackargs = dict( name=self.stackName, ha=cha, main=False, # stops incoming vacuous joins auto=2) stackargs['basedirpath'] = basedirpath self.created = time.perf_counter() # noinspection PyCallingNonCallable self.nodestack = self.nodeStackClass(stackargs, self.handleOneNodeMsg, self.nodeReg, sighex) self.nodestack.onConnsChanged = self.onConnsChanged if self.nodeReg: logger.info( "Client {} initialized with the following node registry:". format(self.alias)) lengths = [ max(x) for x in zip(*[(len(name), len(host), len(str(port))) for name, (host, port) in self.nodeReg.items()]) ] fmt = " {{:<{}}} listens at {{:<{}}} on port {{:>{}}}".format( *lengths) for name, (host, port) in self.nodeReg.items(): logger.info(fmt.format(name, host, port)) else: logger.info("Client {} found an empty node registry:".format( self.alias)) Motor.__init__(self) self.inBox = deque() self.nodestack.connectNicelyUntil = 0 # don't need to connect # nicely as a client # TODO: Need to have couple of tests around `reqsPendingConnection` # where we check with and without pool ledger # Stores the requests that need to be sent to the nodes when the client # has made sufficient connections to the nodes. self.reqsPendingConnection = deque() # Tuple of identifier and reqId as key and value as tuple of set of # nodes which are expected to send REQACK self.expectingAcksFor = {} # Tuple of identifier and reqId as key and value as tuple of set of # nodes which are expected to send REPLY self.expectingRepliesFor = {} tp = loadPlugins(self.basedirpath) logger.debug("total plugins loaded in client: {}".format(tp))