def run_node(): nodeReg = OrderedDict([ ('Alpha', ('127.0.0.1', 9701)), ('Beta', ('127.0.0.1', 9703)), ('Gamma', ('127.0.0.1', 9705)), ('Delta', ('127.0.0.1', 9707))]) # the first argument should be the node name try: nodeName = sys.argv[1] except IndexError: names = list(nodeReg.keys()) print("Please supply a node name (one of {}) as the first argument.". format(", ".join(names))) print("For example:") print(" {} {}".format(sys.argv[0], names[0])) return with Looper(debug=False) as looper: # Nodes persist keys when bootstrapping to other nodes and reconnecting # using an ephemeral temporary directory when proving a concept is a # nice way to keep things tidy. with TemporaryDirectory() as tmpdir: node = Node(nodeName, nodeReg, basedirpath=tmpdir) # see simple_client.py joe_verkey = b'cffbb88a142be2f62d1b408818e21a2f' \ b'887c4442ae035a260d4cc2ec28ae24d6' node.clientAuthNr.addClient("Joe", joe_verkey) looper.add(node) node.startKeySharing() looper.run()
def __init__(self, nodeCount=None, nodeRegistry=None, nodeSet=None, looper=None, tmpdir=None): super().__init__() self.actor = None # type: Organization if nodeSet is None: self.nodes = self.enter_context( TestNodeSet(count=nodeCount, nodeReg=nodeRegistry, tmpdir=tmpdir)) else: self.nodes = nodeSet self.nodeReg = self.nodes.nodeReg if looper is None: self.looper = self.enter_context(Looper(self.nodes)) else: self.looper = looper self.tmpdir = tmpdir self.ran = [] # history of what has been run self.userId = None self.userNym = None self.sponsor = None self.sponsorNym = None self.agent = None self.agentNym = None
def nodeCreatedAfterSomeTxns(txnPoolNodeSet, tdirWithPoolTxns, poolTxnStewardData, tconf, allPluginsPath, request): with Looper(debug=True) as looper: client, wallet = buildPoolClientAndWallet(poolTxnStewardData, tdirWithPoolTxns, clientClass=TestClient) looper.add(client) looper.run(client.ensureConnectedToNodes()) txnCount = getValueFromModule(request, "txnCount", 5) sendReqsToNodesAndVerifySuffReplies(looper, wallet, client, txnCount, timeoutPerReq=25) newStewardName = randomString() newNodeName = "Epsilon" newStewardClient, newStewardWallet, newNode = addNewStewardAndNode( looper, client, wallet, newStewardName, newNodeName, tdirWithPoolTxns, tconf, allPluginsPath=allPluginsPath, autoStart=True) yield looper, newNode, client, wallet, newStewardClient, \ newStewardWallet
def testNodesComingUpAtDifferentTimes(): console = getConsole() console.reinit(flushy=True, verbosity=console.Wordage.verbose) with TemporaryDirectory() as td: print("temporary directory: {}".format(td)) with Looper() as looper: nodes = [] names = list(nodeReg.keys()) shuffle(names) waits = [randint(1, 10) for _ in names] rwaits = [randint(1, 10) for _ in names] for i, name in enumerate(names): node = TestNode(name, nodeReg, basedirpath=td) looper.add(node) node.startKeySharing() nodes.append(node) looper.runFor(waits[i]) looper.run(checkNodesConnected(nodes, overrideTimeout=10)) print("connects") print("node order: {}".format(names)) print("waits: {}".format(waits)) for n in nodes: n.stop() for i, n in enumerate(nodes): n.start(looper.loop) looper.runFor(rwaits[i]) looper.runFor(3) looper.run(checkNodesConnected(nodes, overrideTimeout=10)) print("reconnects") print("node order: {}".format(names)) print("rwaits: {}".format(rwaits))
def testTestNodeDelay(tdir_for_func): nodeNames = {"testA", "testB"} with TestNodeSet(names=nodeNames, tmpdir=tdir_for_func) as nodes: nodeA = nodes.getNode("testA") nodeB = nodes.getNode("testB") with Looper(nodes) as looper: for n in nodes: n.startKeySharing() logging.debug("connect") looper.run(checkNodesConnected(nodes)) logging.debug("send one message, without delay") msg = randomMsg() looper.run(sendMsgAndCheck(nodes, nodeA, nodeB, msg, 1)) logging.debug("set delay, then send another message and find that " "it doesn't arrive") msg = randomMsg() nodeB.nodeIbStasher.delay(delayerMsgTuple(6, type(msg), nodeA.name)) with pytest.raises(AssertionError): looper.run(sendMsgAndCheck(nodes, nodeA, nodeB, msg, 3)) logging.debug("but then find that it arrives after the delay " "duration has passed") looper.run(sendMsgAndCheck(nodes, nodeA, nodeB, msg, 4)) logging.debug( "reset the delay, and find another message comes quickly") nodeB.nodeIbStasher.resetDelays() msg = randomMsg() looper.run(sendMsgAndCheck(nodes, nodeA, nodeB, msg, 1))
def testNodesConnectsWhenOneNodeIsLate(): with TemporaryDirectory() as td: with Looper() as looper: nodes = [] names = list(nodeReg.keys()) logger.debug("Node names: {}".format(names)) def create(name): node = TestNode(name, nodeReg, basedirpath=td) looper.add(node) node.startKeySharing() nodes.append(node) for name in names[:3]: create(name) looper.run(checkNodesConnected(nodes)) # wait for the election to complete with the first three nodes looper.runFor(10) # create the fourth and see that it learns who the primaries are # from the other nodes create(names[3]) checkProtocolInstanceSetup(looper, nodes, timeout=10)
def testMultipleRequests(tdir_for_func): """ Send multiple requests to the client """ with TestNodeSet(count=7, tmpdir=tdir_for_func) as nodeSet: with Looper(nodeSet) as looper: for n in nodeSet: n.startKeySharing() ss0 = snapshotStats(*nodeSet) client, wal = setupNodesAndClient(looper, nodeSet, tmpdir=tdir_for_func) ss1 = snapshotStats(*nodeSet) def x(): requests = [sendRandomRequest(wal, client) for _ in range(10)] for request in requests: looper.run( eventually(checkSufficientRepliesRecvd, client.inBox, request.reqId, 3, retryWait=1, timeout=3 * len(nodeSet))) ss2 = snapshotStats(*nodeSet) diff = statsDiff(ss2, ss1) pprint(ss2) print("----------------------------------------------") pprint(diff) profile_this(x)
def testReqExecWhenReturnedByMaster(tdir_for_func): with TestNodeSet(count=4, tmpdir=tdir_for_func) as nodeSet: with Looper(nodeSet) as looper: for n in nodeSet: n.startKeySharing() client1, wallet1 = setupNodesAndClient(looper, nodeSet, tmpdir=tdir_for_func) req = sendRandomRequest(wallet1, client1) looper.run( eventually(checkSufficientRepliesRecvd, client1.inBox, req.reqId, 1, retryWait=1, timeout=15)) async def chk(): for node in nodeSet: entries = node.spylog.getAll(node.processOrdered.__name__) for entry in entries: arg = entry.params['ordered'] result = entry.result if arg.instId == node.instances.masterId: assert result else: assert result is None looper.run(eventually(chk, timeout=3))
def runAgent(agentClass, name, wallet=None, basedirpath=None, port=None, startRunning=True, bootstrap=False): config = getConfig() if not wallet: wallet = Wallet(name) if not basedirpath: basedirpath = config.baseDir if not port: _, port = genHa() _, clientPort = genHa() client = Client(randomString(6), ha=("0.0.0.0", clientPort), basedirpath=basedirpath) agent = agentClass(basedirpath=basedirpath, client=client, wallet=wallet, port=port) if startRunning: if bootstrap: agent.bootstrap() with Looper(debug=True) as looper: looper.add(agent) logger.debug("Running {} now (port: {})".format(name, port)) looper.run() else: return agent
def testKeyShareParty(tdir_for_func): """ connections to all nodes should be successfully established when key sharing is enabled. """ nodeReg = genNodeReg(5) logging.debug("-----sharing keys-----") with TestNodeSet(nodeReg=nodeReg, tmpdir=tdir_for_func) as nodeSet: with Looper(nodeSet) as looper: for n in nodeSet: n.startKeySharing() looper.run(checkNodesConnected(nodeSet)) logging.debug("-----key sharing done, connect after key sharing-----") with TestNodeSet(nodeReg=nodeReg, tmpdir=tdir_for_func) as nodeSet: with Looper(nodeSet) as loop: loop.run(checkNodesConnected(nodeSet), msgAll(nodeSet))
def testNodesConnectWhenTheyAllStartAtOnce(): with TemporaryDirectory() as td: with Looper() as looper: nodes = [] for name in nodeReg: node = TestNode(name, nodeReg, basedirpath=td) looper.add(node) node.startKeySharing() nodes.append(node) looper.run(checkNodesConnected(nodes))
def startAgent(name, seed, loop=None): agentWallet = Wallet(name) agentWallet.addIdentifier(signer=SimpleSigner(seed=bytes(seed, 'utf-8'))) agent = createAgent(WalletedAgent, name, wallet=agentWallet, loop=loop) agentPort = agent.endpoint.stackParams['ha'].port with Looper(debug=True) as looper: looper.add(agent) log.debug("Running {} now (port: {})".format(name, agentPort)) return agent
def txnPoolNodeSet(tdirWithPoolTxns, tconf, poolTxnNodeNames, tdirWithNodeKeepInited): with Looper(debug=True) as looper: nodes = [] for nm in poolTxnNodeNames: node = TestNode(nm, basedirpath=tdirWithPoolTxns, config=tconf) looper.add(node) nodes.append(node) looper.run( eventually(checkNodesConnected, nodes, retryWait=1, timeout=5)) yield nodes
def run_node(): ip = '52.37.111.254' cliNodeReg = OrderedDict([ # ('AlphaC', ('127.0.0.1', 8002)), ('AlphaC', (ip, 4002)), ('BetaC', (ip, 4004)), ('GammaC', (ip, 4006)), ('DeltaC', (ip, 4008)) ]) with Looper(debug=False) as looper: # Nodes persist keys when bootstrapping to other nodes and reconnecting # using an ephemeral temporary directory when proving a concept is a # nice way to keep things clean. clientName = 'Joem' # this seed is used by the signer to deterministically generate # a signature verification key that is shared out of band with the # consensus pool seed = b'g034OTmx7qBRtywvCbKhjfALHnsdcJpl' assert len(seed) == 32 signer = SimpleSigner(seed=seed) assert signer.verstr == 'o7z4QmFkNB+mVkFI2BwX0H' \ 'dm1BGhnz8psWnKYIXWTaQ=' client_address = ('0.0.0.0', 8000) tmpdir = os.path.join(tempfile.gettempdir(), "sovrin_clients", clientName) client = Client(clientName, cliNodeReg, ha=client_address, signer=signer, basedirpath=tmpdir) looper.add(client) # give the client time to connect looper.runFor(3) # a simple message msg = {TXN_TYPE: NYM} # submit the request to the pool request, = client.submit(msg) # allow time for the request to be executed looper.runFor(3) reply, status = client.getReply(request.reqId) print('') print('Reply: {}\n'.format(reply)) print('Status: {}\n'.format(status))
def _(subdir, looper=None): def new(): return newCLI(looper, tdir, subDirectory=subdir, conf=tconf, poolDir=tdirWithPoolTxns, domainDir=tdirWithDomainTxns) if looper: yield new() else: with Looper(debug=False) as looper: yield new()
def run(self, coro, nodecount=4): tmpdir = self.fresh_tdir() with self.testNodeSetClass(count=nodecount, tmpdir=tmpdir) as nodeset: with Looper(nodeset) as looper: for n in nodeset: n.startKeySharing() ctx = adict(looper=looper, nodeset=nodeset, tmpdir=tmpdir) looper.run(checkNodesConnected(nodeset)) ensureElectionsDone(looper=looper, nodes=nodeset, retryWait=1, timeout=30) looper.run(coro(ctx))
def runAgent(agent, looper=None, bootstrap=True): def doRun(looper): looper.add(agent) logger.debug("Running {} now (port: {})".format( agent.name, agent.port)) if bootstrap: looper.run(agent.bootstrap()) if looper: doRun(looper) else: with Looper(debug=True, loop=agent.loop) as looper: doRun(looper) looper.run()
def testNodesReceiveClientMsgs(txnPoolNodeSet, tdirWithPoolTxns, poolTxnClientData, txnPoolCliNodeReg): with Looper(debug=True) as looper: name, pkseed, sigseed = poolTxnClientData signer = SimpleSigner(seed=sigseed) client = TestClient(name=name, nodeReg=txnPoolCliNodeReg, ha=genHa(), signer=signer, basedirpath=tdirWithPoolTxns) looper.add(client) looper.run(client.ensureConnectedToNodes()) sendReqsToNodesAndVerifySuffReplies(looper, client, 1)
def txnPoolNodeSet(tdirWithPoolTxns, tdirWithDomainTxns, tconf, poolTxnNodeNames, allPluginsPath, tdirWithNodeKeepInited, testNodeClass): with Looper(debug=True) as looper: nodes = [] for nm in poolTxnNodeNames: node = testNodeClass(nm, basedirpath=tdirWithPoolTxns, config=tconf, pluginPaths=allPluginsPath) looper.add(node) nodes.append(node) looper.run(checkNodesConnected(nodes)) yield nodes
def run_node(): cliNodeReg = OrderedDict([('AlphaC', ('127.0.0.1', 8002)), ('BetaC', ('127.0.0.1', 8004)), ('GammaC', ('127.0.0.1', 8006)), ('DeltaC', ('127.0.0.1', 8008))]) with Looper(debug=False) as looper: # Nodes persist keys when bootstrapping to other nodes and reconnecting # using an ephemeral temporary directory when proving a concept is a # nice way to keep things clean. with SafeTemporaryDirectory() as tmpdir: clientName = 'Joe' # this seed is used by the signer to deterministically generate # a signature verification key that is shared out of band with the # consensus pool seed = b'a 32 byte super secret seed.....' assert len(seed) == 32 signer = SimpleSigner(clientName, seed) assert signer.verkey == b'cffbb88a142be2f62d1b408818e21a2f' \ b'887c4442ae035a260d4cc2ec28ae24d6' client_address = ('127.0.0.1', 8000) client = Client(clientName, cliNodeReg, ha=client_address, signer=signer, basedirpath=tmpdir) looper.add(client) # give the client time to connect looper.runFor(3) # a simple message msg = {'life_answer': 42} # submit the request to the pool request, = client.submit_DEPRECATED(msg) # allow time for the request to be executed looper.runFor(3) reply, status = client.getReply(request.reqId) print('') print('Reply: {}\n'.format(reply)) print('Status: {}\n'.format(status))
def testRequestReturnToNodeWhenPrePrepareNotReceivedByOneNode(tdir_for_func): """Test no T-3""" nodeNames = genNodeNames(7) nodeReg = genNodeReg(names=nodeNames) with TestNodeSet(nodeReg=nodeReg, tmpdir=tdir_for_func) as nodeSet: with Looper(nodeSet) as looper: prepareNodeSet(looper, nodeSet) logger.debug("Add the seven nodes back in") # Every node except A delays self nomination so A can become primary nodeA = addNodeBack(nodeSet, looper, nodeNames[0]) for i in range(1, 7): node = addNodeBack(nodeSet, looper, nodeNames[i]) node.delaySelfNomination(15) nodeB = nodeSet.getNode(nodeNames[1]) # Node B delays PREPREPARE from node A(which would be the primary) # for a long time. nodeB.nodeIbStasher.delay( delayerMsgTuple(120, PrePrepare, nodeA.name)) # Ensure elections are done ensureElectionsDone(looper=looper, nodes=nodeSet, retryWait=1, timeout=30) assert nodeA.hasPrimary instNo = nodeA.primaryReplicaNo client1, wallet1 = setupClient(looper, nodeSet, tmpdir=tdir_for_func) req = sendRandomRequest(wallet1, client1) # All nodes including B should return their ordered requests for node in nodeSet: looper.run( eventually(checkRequestReturnedToNode, node, wallet1.defaultId, req.reqId, req.digest, instNo, retryWait=1, timeout=30)) # Node B should not have received the PRE-PREPARE request yet replica = nodeB.replicas[instNo] # type: Replica assert len(replica.prePrepares) == 0
def runAlice(name=None, wallet=None, basedirpath=None, port=None, startRunning=True): # TODO: Copied code from `runFaber`, need to refactor name = name or 'Alice Jones' wallet = wallet or Wallet(name) config = getConfig() basedirpath = basedirpath or os.path.expanduser(config.baseDir) if not port: _, port = genHa() _, clientPort = genHa() client = Client(randomString(6), ha=("0.0.0.0", clientPort), basedirpath=basedirpath) def listClaims(msg): body, frm = msg """ body = { "type": <some type>, "identifier": <id>, "nonce": <nonce>, "signature" : <sig> } """ # TODO: Need to do nonce verification here data = json.loads(body) print(data) # wallet.knownIds[data['identifier']] = # TODO: Send claims handlers = {AVAIL_CLAIM_LIST: listClaims} alice = AliceAgent(name, basedirpath=basedirpath, client=client, port=port, handlers=handlers) if startRunning: with Looper(debug=True) as looper: looper.add(alice) logger.debug("Running Faber now...") looper.run() else: return alice
def testConnectWithoutKeySharingFails(tdir_for_func): """ attempts at connecting to nodes when key sharing is disabled must fail """ nodeNames = genNodeNames(5) with TestNodeSet(names=nodeNames, tmpdir=tdir_for_func, keyshare=False) as nodes: with Looper(nodes) as looper: try: looper.run( checkNodesConnected(nodes, RemoteState(None, None, None))) except RemoteNotFound: pass except KeyError as ex: assert [n for n in nodeNames if n == ex.args[0]] except Exception: raise
def run_node(): with Looper(debug=False) as looper: # Nodes persist keys when bootstrapping to other nodes and reconnecting # using an ephemeral temporary directory when proving a concept is a # nice way to keep things clean. config = getConfig() basedirpath = config.baseDir cliNodeReg = {k: v[0] for k, v in config.cliNodeReg.items()} clientName = 'Alice' # this seed is used by the signer to deterministically generate # a signature verification key that is shared out of band with the # consensus pool seed = b'22222222222222222222222222222222' assert len(seed) == 32 signer = SimpleSigner(clientName, seed) client_address = ('0.0.0.0', 9700) client = Client(clientName, cliNodeReg, ha=client_address, signer=signer, basedirpath=basedirpath) looper.add(client) # give the client time to connect looper.runFor(3) # a simple message msg = {'life_answer': 42} # submit the request to the pool request, = client.submit_DEPRECATED(msg) # allow time for the request to be executed looper.runFor(3) reply, status = client.getReply(request.reqId) print('') print('Reply: {}\n'.format(reply)) print('Status: {}\n'.format(status))
def testSelfNominationDelay(tdir_for_func): nodeNames = ["testA", "testB", "testC", "testD"] with TestNodeSet(names=nodeNames, tmpdir=tdir_for_func) as nodeSet: with Looper(nodeSet) as looper: prepareNodeSet(looper, nodeSet) delay = 30 # Add node A nodeA = addNodeBack(nodeSet, looper, nodeNames[0]) nodeA.delaySelfNomination(delay) nodesBCD = [] for name in nodeNames[1:]: # nodesBCD.append(nodeSet.addNode(name, i+1, AutoMode.never)) nodesBCD.append(addNodeBack(nodeSet, looper, name)) # Ensuring that NodeA is started before any other node to demonstrate # that it is delaying self nomination looper.run( eventually(lambda: assertExp(nodeA.isReady()), retryWait=1, timeout=5)) # Elections should be done ensureElectionsDone(looper=looper, nodes=nodeSet, retryWait=1, timeout=10) # node A should not have any primary replica looper.run( eventually(lambda: assertExp(not nodeA.hasPrimary), retryWait=1, timeout=10)) # Make sure that after at the most 30 seconds, nodeA's # `startElection` is called looper.run( eventually(lambda: assertExp( len(nodeA.spylog.getAll(Node.decidePrimaries.__name__)) > 0 ), retryWait=1, timeout=30))
def main(logfile: str = None, debug=None, cliClass=None): config = getConfig() nodeReg = config.nodeReg cliNodeReg = config.cliNodeReg basedirpath = config.baseDir if not cliClass: cliClass = Cli with Looper(debug=False) as looper: cli = cliClass(looper=looper, basedirpath=basedirpath, nodeReg=nodeReg, cliNodeReg=cliNodeReg, logFileName=logfile, debug=debug) if not debug: looper.run(cli.shell(*sys.argv[1:])) print('Goodbye.') return cli
def checkStewardAdded(poolTxnStewardData, tdirWithPoolTxns): with Looper(debug=True) as looper: client, wallet = buildPoolClientAndWallet(poolTxnStewardData, tdirWithPoolTxns) looper.add(client) looper.run(client.ensureConnectedToNodes()) sigseed = b'55555555555555555555555555555555' newSigner = SimpleSigner(sigseed) op = { TXN_TYPE: NYM, ROLE: STEWARD, TARGET_NYM: newSigner.verkey, ALIAS: "Robert", } req = wallet.signOp(op) client.submitReqs(req) def chk(): assert client.getReply(req.reqId) == (None, "NOT_FOUND") looper.run(eventually(chk, retryWait=1, timeout=5))
def testNodeConnectionAfterKeysharingRestarted(): console = getConsole() console.reinit(flushy=True, verbosity=console.Wordage.verbose) with TemporaryDirectory() as td: print("temporary directory: {}".format(td)) with Looper() as looper: timeout = 60 names = ["Alpha", "Beta"] print(names) nrg = {n: nodeReg[n] for n in names} A, B = [TestNode(name, nrg, basedirpath=td) for name in names] looper.add(A) A.startKeySharing(timeout=timeout) looper.runFor(timeout + 1) print("done waiting for A's timeout") looper.add(B) B.startKeySharing(timeout=timeout) looper.runFor(timeout + 1) print("done waiting for B's timeout") A.startKeySharing(timeout=timeout) B.startKeySharing(timeout=timeout) looper.run(checkNodesConnected([A, B]))
def testAddNewClient(txnPoolNodeSet, tdirWithPoolTxns, poolTxnStewardData, txnPoolCliNodeReg): with Looper(debug=True) as looper: name, pkseed, sigseed = poolTxnStewardData stewardSigner = SimpleSigner(seed=sigseed) client = TestClient(name=name, nodeReg=txnPoolCliNodeReg, ha=genHa(), signer=stewardSigner, basedirpath=tdirWithPoolTxns) looper.add(client) looper.run(client.ensureConnectedToNodes()) sigseed = b'55555555555555555555555555555555' pkseed = b'66666666666666666666666666666666' newSigner = SimpleSigner(sigseed) priver = Privateer(pkseed) req, = client.submit({ TXN_TYPE: NEW_CLIENT, ORIGIN: client.defaultIdentifier, TARGET_NYM: newSigner.verstr, DATA: { "pubkey": priver.pubhex.decode(), "alias": "Robert" } }) looper.run( eventually(checkSufficientRepliesRecvd, client.inBox, req.reqId, 1, retryWait=1, timeout=5)) def chk(): for node in txnPoolNodeSet: assert newSigner.verstr in node.clientAuthNr.clients looper.run(eventually(chk, retryWait=1, timeout=5))
def testNodeConnection(): console = getConsole() console.reinit(flushy=True, verbosity=console.Wordage.verbose) with TemporaryDirectory() as td: print("temporary directory: {}".format(td)) with Looper() as looper: names = ["Alpha", "Beta"] print(names) nrg = {n: nodeReg[n] for n in names} A, B = [TestNode(name, nrg, basedirpath=td) for name in names] looper.add(A) A.startKeySharing() looper.runFor(4) print("wait done") looper.add(B) B.startKeySharing() looper.runFor(4) looper.run(checkNodesConnected([A, B])) looper.stopall() A.start(looper.loop) looper.runFor(4) B.start(looper.loop) looper.run(checkNodesConnected([A, B]))