def testPromiscuousConnection(tdir, keysAndNames): # Simulating node to client connection alphaSighex, alphaPrikey, alphaVerhex, alphaPubkey, alphaName, betaSighex, \ betaPrikey, betaVerhex, betaPubkey, betaName = keysAndNames alpha = RoadStack(name=alphaName, ha=genHa(), sigkey=alphaSighex, prikey=hexlify(alphaPrikey), auto=AutoMode.always, basedirpath=tdir) beta = RoadStack(name=betaName, ha=genHa(), main=True, sigkey=betaSighex, prikey=hexlify(betaPrikey), auto=AutoMode.always, basedirpath=tdir) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.join(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def poolTxnData(nodeAndClientInfoFilePath): data = json.loads(open(nodeAndClientInfoFilePath).read().strip()) for txn in data["txns"]: if txn[TXN_TYPE] == NODE: txn[DATA][NODE_PORT] = genHa()[1] txn[DATA][CLIENT_PORT] = genHa()[1] return data
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 testRaetPreSharedKeysPromiscous(tdir): alphaSigner = SimpleSigner() betaSigner = SimpleSigner() logger.debug("Alpha's verkey {}".format(alphaSigner.naclSigner.verhex)) logger.debug("Beta's verkey {}".format(betaSigner.naclSigner.verhex)) alpha = RoadStack(name='alpha', ha=genHa(), sigkey=alphaSigner.naclSigner.keyhex, auto=AutoMode.always, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.naclSigner.keyhex, main=True, auto=AutoMode.always, basedirpath=tdir) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha, verkey=betaSigner.naclSigner.verhex) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def getPoolTxnData(nodeAndClientInfoFilePath, poolId, newPoolTxnNodeNames): data={} data["seeds"]={} data["txns"]=[] for index, n in enumerate(newPoolTxnNodeNames, start=1): newStewardAlias = poolId + "Steward" + str(index) stewardSeed = (newStewardAlias + "0" * (32 - len(newStewardAlias))).encode() data["seeds"][newStewardAlias] = stewardSeed stewardSigner = SimpleSigner(seed=stewardSeed) data["txns"].append({ TARGET_NYM: stewardSigner.verkey, ROLE: STEWARD, TXN_TYPE: NYM, ALIAS: poolId + "Steward" + str(index), TXN_ID: sha256("{}".format(stewardSigner.verkey).encode()).hexdigest() }) newNodeAlias = n nodeSeed = (newNodeAlias + "0" * (32 - len(newNodeAlias))).encode() data["seeds"][newNodeAlias] = nodeSeed nodeSigner = SimpleSigner(seed=nodeSeed) data["txns"].append({ TARGET_NYM: nodeSigner.verkey, TXN_TYPE: NODE, f.IDENTIFIER.nm: stewardSigner.verkey, DATA: { CLIENT_IP: "127.0.0.1", ALIAS: newNodeAlias, NODE_IP: "127.0.0.1", NODE_PORT: genHa()[1], CLIENT_PORT: genHa()[1], SERVICES: [VALIDATOR], }, TXN_ID: sha256("{}".format(nodeSigner.verkey).encode()).hexdigest() }) return data
def createAgent(agentClass, name, wallet=None, basedirpath=None, port=None, loop=None, clientClass=Client): config = getConfig() if not wallet: wallet = Wallet(name) if not basedirpath: basedirpath = config.baseDir if not port: _, port = genHa() _, clientPort = genHa() client = clientClass(randomString(6), ha=("0.0.0.0", clientPort), basedirpath=basedirpath) return agentClass(basedirpath=basedirpath, client=client, wallet=wallet, port=port, loop=loop)
def poolTxnData(dirName): filePath = os.path.join(dirName(__file__), "node_and_client_info.py") data = json.loads(open(filePath).read().strip()) for txn in data["txns"]: if txn[TXN_TYPE] == NEW_NODE: txn[DATA][NODE_PORT] = genHa()[1] txn[DATA][CLIENT_PORT] = genHa()[1] return data
def testConsecutiveAddSameNodeWithNonAliasChange(be, do, newStewardCli, newNodeAdded): be(newStewardCli) nodeIp, nodePort = genHa() clientIp, clientPort = genHa() vals['newNodeData'][NODE_IP] = nodeIp vals['newNodeData'][NODE_PORT] = nodePort vals['newNodeData'][CLIENT_IP] = nodeIp vals['newNodeData'][CLIENT_PORT] = clientPort sendNodeCmd(do, newNodeData=vals) exitFromCli(do)
def testRaetPreSharedKeysNonPromiscous(tdir): alphaSigner = SimpleSigner() betaSigner = SimpleSigner() alphaPrivateer = Privateer() betaPrivateer = Privateer() logger.debug("Alpha's verkey {}".format(alphaSigner.naclSigner.verhex)) logger.debug("Beta's verkey {}".format(betaSigner.naclSigner.verhex)) alpha = RoadStack(name='alpha', ha=genHa(), sigkey=alphaSigner.naclSigner.keyhex, prikey=alphaPrivateer.keyhex, auto=AutoMode.never, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.naclSigner.keyhex, prikey=betaPrivateer.keyhex, main=True, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": betaSigner.naclSigner.verhex, "pubhex": betaPrivateer.pubhex }, "beta") beta.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": alphaSigner.naclSigner.verhex, "pubhex": alphaPrivateer.pubhex }, "alpha") try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def nodeReg(): return { 'Alpha': NodeDetail(genHa(1), "AlphaC", genHa(1)), 'Beta': NodeDetail(genHa(1), "BetaC", genHa(1)), 'Gamma': NodeDetail(genHa(1), "GammaC", genHa(1)), 'Delta': NodeDetail(genHa(1), "DeltaC", genHa(1)) }
def testRaetPreSharedKeysNonPromiscous(tdir): alphaSigner = SimpleSigner() betaSigner = SimpleSigner() alphaPrivateer = Privateer() betaPrivateer = Privateer() logger.debug("Alpha's verkey {}".format(alphaSigner.naclSigner.verhex)) logger.debug("Beta's verkey {}".format(betaSigner.naclSigner.verhex)) alpha = RoadStack(name='alpha', ha=genHa(), sigkey=alphaSigner.naclSigner.keyhex, prikey=alphaPrivateer.keyhex, auto=AutoMode.never, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.naclSigner.keyhex, prikey=betaPrivateer.keyhex, main=True, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": betaSigner.naclSigner.verhex, "pubhex": betaPrivateer.pubhex }, "beta") beta.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": alphaSigner.naclSigner.verhex, "pubhex": alphaPrivateer.pubhex }, "alpha") try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def _(wallet, basedir=None): basedir = basedir or tdirWithPoolTxns _, port = genHa() _, clientPort = genHa() client = TestClient(randomString(6), ha=("0.0.0.0", clientPort), basedirpath=basedir) agent = TestWalletedAgent(name=wallet.name, basedirpath=basedir, client=client, wallet=wallet, port=port) return agent
def testNodePortChanged(looper, txnPoolNodeSet, tdirWithPoolTxns, tconf, steward1, stewardWallet, nodeThetaAdded): """ An running node's port is changed """ newSteward, newStewardWallet, newNode = nodeThetaAdded nodeNewHa, clientNewHa = genHa(2) logger.debug("{} changing HAs to {} {}".format(newNode, nodeNewHa, clientNewHa)) changeNodeHa(looper, newSteward, newStewardWallet, newNode, nodeHa=nodeNewHa, clientHa=clientNewHa) newNode.stop() looper.removeProdable(name=newNode.name) logger.debug("{} starting with HAs {} {}".format(newNode, nodeNewHa, clientNewHa)) node = TestNode(newNode.name, basedirpath=tdirWithPoolTxns, config=tconf, ha=nodeNewHa, cliha=clientNewHa) looper.add(node) # The last element of `txnPoolNodeSet` is the node Theta that was just # stopped txnPoolNodeSet[-1] = node looper.run(checkNodesConnected(txnPoolNodeSet)) looper.run(eventually(checkNodeLedgersForEquality, node, *txnPoolNodeSet[:-1], retryWait=1, timeout=10)) ensureClientConnectedToNodesAndPoolLedgerSame(looper, steward1, *txnPoolNodeSet) ensureClientConnectedToNodesAndPoolLedgerSame(looper, newSteward, *txnPoolNodeSet)
def testClientReconnectUsingDifferentHa(looper, txnPoolNodeSet, tdirWithPoolTxns, poolTxnClientData): """ Client should not be able to connect to nodes even after it has changed its HA. Since running on a local environment, only checking change of port. Dont know how to change IP. :return: """ # TODO: Check for change of IP too client, wallet = buildPoolClientAndWallet(poolTxnClientData, tdirWithPoolTxns) looper.add(client) ensureClientConnectedToNodesAndPoolLedgerSame(looper, client, *txnPoolNodeSet) basedirpath = client.basedirpath looper.removeProdable(client) # Removing RAET keep directory otherwise the client will use the same port # since it will a directory of its name in the keep shutil.rmtree(os.path.join(basedirpath, client.name), ignore_errors=True) ha = genHa() client, _ = genTestClient(txnPoolNodeSet, identifier=wallet.defaultId, ha=ha, tmpdir=tdirWithPoolTxns, usePoolLedger=True, name=client.name) looper.add(client) ensureClientConnectedToNodesAndPoolLedgerSame(looper, client, *txnPoolNodeSet)
def testClientReconnectUsingDifferentHa(looper, txnPoolNodeSet, tdirWithPoolTxns, poolTxnClientData): """ Client should not be able to connect to nodes even after it has changed its HA. Since running on a local environment, only checking change of port. Dont know how to change IP. :return: """ # TODO: Check for change of IP too # name, seed = poolTxnClientData # signer = SimpleSigner(seed=seed) # name = "testClient96541" # ha = genHa() # client = genTestClient(txnPoolNodeSet, signer=signer, ha=ha, # tmpdir=tdirWithPoolTxns, usePoolLedger=True, # name=name) client, wallet = buildPoolClientAndWallet(poolTxnClientData, tdirWithPoolTxns) looper.add(client) ensureClientConnectedToNodesAndPoolLedgerSame(looper, client, *txnPoolNodeSet) basedirpath = client.basedirpath looper.removeProdable(client) # Removing RAET keep directory otherwise the client will use the same port # since it will a directory of its name in the keep shutil.rmtree(os.path.join(basedirpath, client.name), ignore_errors=True) ha = genHa() client, _ = genTestClient(txnPoolNodeSet, identifier=wallet.defaultId, ha=ha, tmpdir=tdirWithPoolTxns, usePoolLedger=True, name=client.name) looper.add(client) ensureClientConnectedToNodesAndPoolLedgerSame(looper, client, *txnPoolNodeSet)
def nodeRegsForCLI(nodeNames): nodeNames = ['Alpha', 'Beta', 'Gamma', 'Delta'] has = [genHa(2) for _ in nodeNames] nodeNamesC = [n + 'C' for n in nodeNames] nodeReg = OrderedDict((n, has[i][0]) for i, n in enumerate(nodeNames)) cliNodeReg = OrderedDict((n, has[i][1]) for i, n in enumerate(nodeNamesC)) return adict(nodeReg=nodeReg, cliNodeReg=cliNodeReg)
def addNewStewardAndNode(looper, creatorClient, creatorWallet, stewardName, newNodeName, tdir, tconf, allPluginsPath=None, autoStart=True, nodeClass=TestNode, clientClass=TestClient): newStewardWallet = addNewClient(STEWARD, looper, creatorClient, creatorWallet, stewardName) newSteward = clientClass(name=stewardName, nodeReg=None, ha=genHa(), basedirpath=tdir) looper.add(newSteward) looper.run(newSteward.ensureConnectedToNodes()) newNode = addNewNode(looper, newSteward, newStewardWallet, newNodeName, tdir, tconf, allPluginsPath, autoStart=autoStart, nodeClass=nodeClass) return newSteward, newStewardWallet, newNode
def addNewNode(looper, stewardClient, stewardWallet, newNodeName, tdir, tconf, allPluginsPath=None, autoStart=True): sigseed = randomString(32).encode() nodeSigner = SimpleSigner(seed=sigseed) (nodeIp, nodePort), (clientIp, clientPort) = genHa(2) op = { TXN_TYPE: NEW_NODE, TARGET_NYM: nodeSigner.identifier, DATA: { NODE_IP: nodeIp, NODE_PORT: nodePort, CLIENT_IP: clientIp, CLIENT_PORT: clientPort, ALIAS: newNodeName } } req = stewardWallet.signOp(op) stewardClient.submitReqs(req) nodeCount = len(stewardClient.nodeReg) looper.run(eventually(checkSufficientRepliesRecvd, stewardClient.inBox, req.reqId, 1, retryWait=1, timeout=3 * nodeCount)) initLocalKeep(newNodeName, tdir, sigseed, override=True) node = TestNode(newNodeName, basedirpath=tdir, config=tconf, ha=(nodeIp, nodePort), cliha=(clientIp, clientPort), pluginPaths=allPluginsPath) if autoStart: looper.add(node) return node
def changeHA(looper, config, nodeName, nodeSeed, newNodeHA, stewardName, stewardsSeed, newClientHA=None): if not newClientHA: newClientHA = HA(newNodeHA.host, newNodeHA.port + 1) # prepare steward wallet stewardSigner = SimpleSigner(seed=stewardsSeed) stewardWallet = Wallet(stewardName) stewardWallet.addIdentifier(signer=stewardSigner) # prepare client to submit change ha request to sovrin _, randomClientPort = genHa() client = Client(stewardName, ha=('0.0.0.0', randomClientPort), config=config) looper.add(client) looper.run( eventually(__checkClientConnected, client, retryWait=1, timeout=5)) nodeVerKey = SimpleSigner(seed=nodeSeed).verkey # send request req = submitNodeIpChange(client, stewardWallet, nodeName, nodeVerKey, newNodeHA, newClientHA) return client, req
def testNonPromiscousConnectionWithOneKey(tdir, keysAndNames): # Simulating node to node connection alphaSighex, alphaPrikey, alphaVerhex, alphaPubkey, alphaName, betaSighex,\ betaPrikey, betaVerhex, betaPubkey, betaName = keysAndNames alpha = RoadStack(name=alphaName, ha=genHa(), sigkey=alphaSighex, prikey=hexlify(alphaPrikey), auto=AutoMode.never, basedirpath=tdir) beta = RoadStack(name=betaName, ha=genHa(), sigkey=betaSighex, prikey=hexlify(betaPrikey), main=True, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": betaVerhex, "pubhex": hexlify(betaPubkey) }, betaName) beta.keep.dumpRemoteRoleData( { "acceptance": Acceptance.accepted.value, "verhex": alphaVerhex, "pubhex": hexlify(alphaPubkey) }, alphaName) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def testChangeHaPersistsPostNodesRestart(looper, txnPoolNodeSet, tdirWithPoolTxns, tconf, steward1, stewardWallet, nodeThetaAdded, poolTxnClientData): newSteward, newStewardWallet, newNode = nodeThetaAdded nodeNewHa, clientNewHa = genHa(2) logger.debug("{} changing HAs to {} {}".format(newNode, nodeNewHa, clientNewHa)) # Making the change HA txn an confirming its succeeded changeNodeHa(looper, newSteward, newStewardWallet, newNode, nodeHa=nodeNewHa, clientHa=clientNewHa) # Stopping existing nodes for node in txnPoolNodeSet: node.stop() looper.removeProdable(node) # Starting nodes again by creating `Node` objects since that simulates # what happens when starting the node with script restartedNodes = [] for node in txnPoolNodeSet[:-1]: restartedNode = TestNode(node.name, basedirpath=tdirWithPoolTxns, config=tconf, ha=node.nodestack.ha, cliha=node.clientstack.ha) looper.add(restartedNode) restartedNodes.append(restartedNode) # Starting the node whose HA was changed node = TestNode(newNode.name, basedirpath=tdirWithPoolTxns, config=tconf, ha=nodeNewHa, cliha=clientNewHa) looper.add(node) restartedNodes.append(node) looper.run(checkNodesConnected(restartedNodes)) looper.run( eventually(checkNodeLedgersForEquality, node, *restartedNodes[:-1], retryWait=1, timeout=10)) # Building a new client that reads from the genesis txn file # but is able to connect to all nodes client, wallet = buildPoolClientAndWallet(poolTxnClientData, tdirWithPoolTxns) looper.add(client) ensureClientConnectedToNodesAndPoolLedgerSame(looper, client, *restartedNodes)
def genNodeReg(count=None, names=None) -> Dict[str, NodeDetail]: """ :param count: number of nodes, mutually exclusive with names :param names: iterable with names of nodes, mutually exclusive with count :return: dictionary of name: (node stack HA, client stack name, client stack HA) """ if names is None: names = genNodeNames(count) nodeReg = OrderedDict( (n, NodeDetail(genHa(), n + CLIENT_STACK_SUFFIX, genHa())) for n in names) def extractCliNodeReg(self): return OrderedDict((n.cliname, n.cliha) for n in self.values()) nodeReg.extractCliNodeReg = types.MethodType(extractCliNodeReg, nodeReg) return nodeReg
def testNonPromiscousConnectionWithOneKey(tdir, keysAndNames): # Simulating node to node connection alphaSighex, alphaPrikey, alphaVerhex, alphaPubkey, alphaName, betaSighex,\ betaPrikey, betaVerhex, betaPubkey, betaName = keysAndNames alpha = RoadStack(name=alphaName, ha=genHa(), sigkey=alphaSighex, prikey=hexlify(alphaPrikey), auto=AutoMode.never, basedirpath=tdir) beta = RoadStack(name=betaName, ha=genHa(), sigkey=betaSighex, prikey=hexlify(betaPrikey), main=True, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": betaVerhex, "pubhex": hexlify(betaPubkey) }, betaName) beta.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": alphaVerhex, "pubhex": hexlify(alphaPubkey) }, alphaName) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.allow(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def changeNodeHa(looper, txnPoolNodeSet, tdirWithPoolTxns, poolTxnData, poolTxnStewardNames, tconf, shouldBePrimary): # prepare new ha for node and client stack subjectedNode = None stewardName = None stewardsSeed = None for nodeIndex, n in enumerate(txnPoolNodeSet): if (shouldBePrimary and n.primaryReplicaNo == 0) or \ (not shouldBePrimary and n.primaryReplicaNo != 0): subjectedNode = n stewardName = poolTxnStewardNames[nodeIndex] stewardsSeed = poolTxnData["seeds"][stewardName].encode() break nodeStackNewHA, clientStackNewHA = genHa(2) logger.debug("change HA for node: {} to {}". format(subjectedNode.name, (nodeStackNewHA, clientStackNewHA))) nodeSeed = poolTxnData["seeds"][subjectedNode.name].encode() # change HA stewardClient, req = changeHA(looper, tconf, subjectedNode.name, nodeSeed, nodeStackNewHA, stewardName, stewardsSeed) f = getMaxFailures(len(stewardClient.nodeReg)) looper.run(eventually(checkSufficientRepliesRecvd, stewardClient.inBox, req.reqId, f, retryWait=1, timeout=20)) # stop node for which HA will be changed subjectedNode.stop() looper.removeProdable(subjectedNode) # start node with new HA restartedNode = TestNode(subjectedNode.name, basedirpath=tdirWithPoolTxns, config=tconf, ha=nodeStackNewHA, cliha=clientStackNewHA) looper.add(restartedNode) txnPoolNodeSet[nodeIndex] = restartedNode looper.run(checkNodesConnected(txnPoolNodeSet, overrideTimeout=70)) ensureElectionsDone(looper, txnPoolNodeSet, retryWait=1, timeout=10) # start client and check the node HA anotherClient, _ = genTestClient(tmpdir=tdirWithPoolTxns, usePoolLedger=True) looper.add(anotherClient) looper.run(eventually(anotherClient.ensureConnectedToNodes)) stewardWallet = Wallet(stewardName) stewardWallet.addIdentifier(signer=SimpleSigner(seed=stewardsSeed)) sendReqsToNodesAndVerifySuffReplies(looper, stewardWallet, stewardClient, 8) looper.run(eventually(checkIfGenesisPoolTxnFileUpdated, *txnPoolNodeSet, stewardClient, anotherClient, retryWait=1, timeout=10)) looper.removeProdable(stewardClient)
def changeNodeHa(looper, txnPoolNodeSet, tdirWithPoolTxns, poolTxnData, poolTxnStewardNames, tconf, shouldBePrimary): # prepare new ha for node and client stack subjectedNode = None stewardName = None stewardsSeed = None for nodeIndex, n in enumerate(txnPoolNodeSet): if (shouldBePrimary and n.primaryReplicaNo == 0) or \ (not shouldBePrimary and n.primaryReplicaNo != 0): subjectedNode = n stewardName = poolTxnStewardNames[nodeIndex] stewardsSeed = poolTxnData["seeds"][stewardName].encode() break nodeStackNewHA, clientStackNewHA = genHa(2) logger.debug("change HA for node: {} to {}". format(subjectedNode.name, (nodeStackNewHA, clientStackNewHA))) nodeSeed = poolTxnData["seeds"][subjectedNode.name].encode() # change HA stewardClient, req = changeHA(looper, tconf, subjectedNode.name, nodeSeed, nodeStackNewHA, stewardName, stewardsSeed) f = getMaxFailures(len(stewardClient.nodeReg)) looper.run(eventually(checkSufficientRepliesRecvd, stewardClient.inBox, req.reqId, f, retryWait=1, timeout=20)) # stop node for which HA will be changed subjectedNode.stop() looper.removeProdable(subjectedNode) # start node with new HA restartedNode = TestNode(subjectedNode.name, basedirpath=tdirWithPoolTxns, config=tconf, ha=nodeStackNewHA, cliha=clientStackNewHA) looper.add(restartedNode) txnPoolNodeSet[nodeIndex] = restartedNode looper.run(checkNodesConnected(txnPoolNodeSet, overrideTimeout=70)) ensureElectionsDone(looper, txnPoolNodeSet, retryWait=1, timeout=10) # start client and check the node HA anotherClient, _ = genTestClient(tmpdir=tdirWithPoolTxns, usePoolLedger=True) looper.add(anotherClient) looper.run(eventually(anotherClient.ensureConnectedToNodes)) stewardWallet = Wallet(stewardName) stewardWallet.addIdentifier(signer=SimpleSigner(seed=stewardsSeed)) sendReqsToNodesAndVerifySuffReplies(looper, stewardWallet, stewardClient, 8) looper.run(eventually(checkIfGenesisPoolTxnFileUpdated, *txnPoolNodeSet, stewardClient, anotherClient, retryWait=1, timeout=10))
def testConsecutiveAddSameNodeWithNodeAndClientPortSame( be, do, newStewardCli, newNodeAdded): be(newStewardCli) nodeIp, nodePort = genHa() vals['newNodeData'][NODE_IP] = nodeIp vals['newNodeData'][NODE_PORT] = nodePort vals['newNodeData'][CLIENT_IP] = nodeIp vals['newNodeData'][CLIENT_PORT] = nodePort sendNodeCmd(do, newNodeData=vals, expMsgs=["node and client ha can't be same"]) exitFromCli(do)
def getNewNodeData(): newStewardSeed = randomSeed() newNodeSeed = randomSeed() nodeIp, nodePort = genHa() clientIp, clientPort = genHa() newNodeData = { NODE_IP: nodeIp, NODE_PORT: nodePort, CLIENT_IP: clientIp, CLIENT_PORT: clientPort, ALIAS: randomString(6) } return { 'newStewardSeed': newStewardSeed, 'newStewardIdr': SimpleSigner(seed=newStewardSeed).identifier, 'newNodeSeed': newNodeSeed, 'newNodeIdr': SimpleSigner(seed=newNodeSeed).identifier, 'newNodeData': newNodeData }
def nodeThetaAdded(looper, nodeSet, tdirWithPoolTxns, tconf, steward, stewardWallet, allPluginsPath, testNodeClass, testClientClass, tdir): newStewardName = "testClientSteward" + randomString(3) newNodeName = "Theta" newSteward, newStewardWallet = getClientAddedWithRole( nodeSet, tdir, looper, steward, stewardWallet, newStewardName, STEWARD) sigseed = randomString(32).encode() nodeSigner = SimpleSigner(seed=sigseed) (nodeIp, nodePort), (clientIp, clientPort) = genHa(2) data = { NODE_IP: nodeIp, NODE_PORT: nodePort, CLIENT_IP: clientIp, CLIENT_PORT: clientPort, ALIAS: newNodeName, SERVICES: [ VALIDATOR, ] } node = Node(nodeSigner.identifier, data, newStewardWallet.defaultId) newStewardWallet.addNode(node) reqs = newStewardWallet.preparePending() req, = newSteward.submitReqs(*reqs) checkSufficientRepliesForRequests(looper, newSteward, [ req, ]) def chk(): assert newStewardWallet.getNode(node.id).seqNo is not None looper.run(eventually(chk, retryWait=1, timeout=10)) initLocalKeep(newNodeName, tdirWithPoolTxns, sigseed, override=True) newNode = testNodeClass(newNodeName, basedirpath=tdir, config=tconf, ha=(nodeIp, nodePort), cliha=(clientIp, clientPort), pluginPaths=allPluginsPath) nodeSet.append(newNode) looper.add(newNode) looper.run(checkNodesConnected(nodeSet)) ensureClientConnectedToNodesAndPoolLedgerSame(looper, steward, *nodeSet) ensureClientConnectedToNodesAndPoolLedgerSame(looper, newSteward, *nodeSet) return newSteward, newStewardWallet, newNode
def testPromiscuousConnection(tdir): alpha = RoadStack(name='alpha', ha=genHa(), auto=AutoMode.always, basedirpath=tdir) beta = RoadStack(name='beta', ha=genHa(), main=True, auto=AutoMode.always, basedirpath=tdir) try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.join(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) finally: cleanup(alpha, beta)
def addNewNode(looper, stewardClient, stewardWallet, newNodeName, tdir, tconf, allPluginsPath=None, autoStart=True, nodeClass=TestNode): sigseed = randomString(32).encode() nodeSigner = SimpleSigner(seed=sigseed) (nodeIp, nodePort), (clientIp, clientPort) = genHa(2) op = { TXN_TYPE: NODE, TARGET_NYM: nodeSigner.identifier, DATA: { NODE_IP: nodeIp, NODE_PORT: nodePort, CLIENT_IP: clientIp, CLIENT_PORT: clientPort, ALIAS: newNodeName, SERVICES: [ VALIDATOR, ] } } req = stewardWallet.signOp(op) stewardClient.submitReqs(req) nodeCount = len(stewardClient.nodeReg) looper.run( eventually(checkSufficientRepliesRecvd, stewardClient.inBox, req.reqId, 1, retryWait=1, timeout=5 * nodeCount)) initLocalKeep(newNodeName, tdir, sigseed, override=True) node = nodeClass(newNodeName, basedirpath=tdir, config=tconf, ha=(nodeIp, nodePort), cliha=(clientIp, clientPort), pluginPaths=allPluginsPath) if autoStart: looper.add(node) return node
def testNodePortCannotBeChangedByAnotherSteward(looper, txnPoolNodeSet, tdirWithPoolTxns, tconf, steward1, stewardWallet, nodeThetaAdded): _, _, newNode = nodeThetaAdded nodeNewHa, clientNewHa = genHa(2) logger.debug('{} changing HAs to {} {}'.format(newNode, nodeNewHa, clientNewHa)) with pytest.raises(AssertionError): changeNodeHa(looper, steward1, stewardWallet, newNode, nodeHa=nodeNewHa, clientHa=clientNewHa) for node in txnPoolNodeSet: checkReqNackWithReason(steward1, 'is not a steward of node', node.clientstack.name)
def addNewStewardAndNode(looper, creatorClient, creatorWallet, stewardName, newNodeName, tdir, tconf, allPluginsPath=None, autoStart=True): newStewardWallet = addNewClient(STEWARD, looper, creatorClient, creatorWallet, stewardName) newSteward = TestClient(name=stewardName, nodeReg=None, ha=genHa(), # DEPR # signer=newStewardSigner, basedirpath=tdir) looper.add(newSteward) looper.run(newSteward.ensureConnectedToNodes()) newNode = addNewNode(looper, newSteward, newStewardWallet, newNodeName, tdir, tconf, allPluginsPath, autoStart=autoStart) return newSteward, newStewardWallet, newNode
def testChangeHaPersistsPostNodesRestart(looper, txnPoolNodeSet, tdirWithPoolTxns, tconf, steward1, stewardWallet, nodeThetaAdded, poolTxnClientData): newSteward, newStewardWallet, newNode = nodeThetaAdded nodeNewHa, clientNewHa = genHa(2) logger.debug("{} changing HAs to {} {}".format(newNode, nodeNewHa, clientNewHa)) # Making the change HA txn an confirming its succeeded changeNodeHa(looper, newSteward, newStewardWallet, newNode, nodeHa=nodeNewHa, clientHa=clientNewHa) # Stopping existing nodes for node in txnPoolNodeSet: node.stop() looper.removeProdable(node) # Starting nodes again by creating `Node` objects since that simulates # what happens when starting the node with script restartedNodes = [] for node in txnPoolNodeSet[:-1]: restartedNode = TestNode(node.name, basedirpath=tdirWithPoolTxns, config=tconf, ha=node.nodestack.ha, cliha=node.clientstack.ha) looper.add(restartedNode) restartedNodes.append(restartedNode) # Starting the node whose HA was changed node = TestNode(newNode.name, basedirpath=tdirWithPoolTxns, config=tconf, ha=nodeNewHa, cliha=clientNewHa) looper.add(node) restartedNodes.append(node) looper.run(checkNodesConnected(restartedNodes)) looper.run(eventually(checkNodeLedgersForEquality, node, *restartedNodes[:-1], retryWait=1, timeout=10)) # Building a new client that reads from the genesis txn file # but is able to connect to all nodes client, wallet = buildPoolClientAndWallet(poolTxnClientData, tdirWithPoolTxns) looper.add(client) ensureClientConnectedToNodesAndPoolLedgerSame(looper, client, *restartedNodes)
def genTestClient(nodes=None, nodeReg=None, tmpdir=None, testClientClass=TestClient, identifier: Identifier = None, verkey: str = None, bootstrapKeys=True, ha=None, usePoolLedger=False, name=None, sighex=None) -> (TestClient, Wallet): if not usePoolLedger: nReg = nodeReg if nodeReg: assert isinstance(nodeReg, dict) elif hasattr(nodes, "nodeReg"): nReg = nodes.nodeReg.extractCliNodeReg() else: error("need access to nodeReg") for k, v in nReg.items(): assert type(k) == str assert (type(v) == HA or type(v[0]) == HA) else: logger.debug("TestClient using pool ledger") nReg = None ha = genHa() if not ha else ha name = name or "testClient{}".format(ha.port) tc = testClientClass(name, nodeReg=nReg, ha=ha, basedirpath=tmpdir, sighex=sighex) w = None # type: Wallet if bootstrapKeys and nodes: if not identifier or not verkey: # no identifier or verkey were provided, so creating a wallet w = Wallet("test") w.addIdentifier() identifier = w.defaultId verkey = w.getVerkey() bootstrapClientKeys(identifier, verkey, nodes) return tc, w
def testNodePortChanged(looper, txnPoolNodeSet, tdirWithPoolTxns, tconf, steward1, stewardWallet, nodeThetaAdded): """ An running node's port is changed """ newSteward, newStewardWallet, newNode = nodeThetaAdded nodeNewHa, clientNewHa = genHa(2) logger.debug("{} changing HAs to {} {}".format(newNode, nodeNewHa, clientNewHa)) changeNodeHa(looper, newSteward, newStewardWallet, newNode, nodeHa=nodeNewHa, clientHa=clientNewHa) newNode.stop() looper.removeProdable(name=newNode.name) logger.debug("{} starting with HAs {} {}".format(newNode, nodeNewHa, clientNewHa)) node = TestNode(newNode.name, basedirpath=tdirWithPoolTxns, config=tconf, ha=nodeNewHa, cliha=clientNewHa) looper.add(node) # The last element of `txnPoolNodeSet` is the node Theta that was just # stopped txnPoolNodeSet[-1] = node looper.run(checkNodesConnected(txnPoolNodeSet)) looper.run( eventually(checkNodeLedgersForEquality, node, *txnPoolNodeSet[:-1], retryWait=1, timeout=10)) ensureClientConnectedToNodesAndPoolLedgerSame(looper, steward1, *txnPoolNodeSet) ensureClientConnectedToNodesAndPoolLedgerSame(looper, newSteward, *txnPoolNodeSet)
def thriftAgentPort(): return genHa()[1]
from plenum.common.eventually import eventually from plenum.common.log import getlogger from plenum.common.looper import Looper from plenum.common.port_dispenser import genHa from plenum.common.temp_file_util import SafeTemporaryDirectory from plenum.common.types import NodeDetail from plenum.test.test_node import TestNode, checkNodesConnected, \ checkProtocolInstanceSetup logger = getlogger() whitelist = ['discarding message', 'found legacy entry'] nodeReg = { 'Alpha': NodeDetail(genHa(1), "AlphaC", genHa(1)), 'Beta': NodeDetail(genHa(1), "BetaC", genHa(1)), 'Gamma': NodeDetail(genHa(1), "GammaC", genHa(1)), 'Delta': NodeDetail(genHa(1), "DeltaC", genHa(1)) } # Its a function fixture, deliberately @pytest.yield_fixture() def tdirAndLooper(): with SafeTemporaryDirectory() as td: logger.debug("temporary directory: {}".format(td)) with Looper() as looper: yield td, looper
def testUsedPortDetection(tdir, client1): port = client1.nodestack.ha[1] assert isPortUsed(tdir, port) newPort = genHa()[1] assert not isPortUsed(tdir, newPort)
def testConnectionWithHaChanged(tdir): console = getConsole() console.reinit(verbosity=console.Wordage.verbose) alphaSigner = SimpleSigner() betaSigner = SimpleSigner() alphaPrivateer = Privateer() betaPrivateer = Privateer() logger.debug("Alpha's verkey {}".format(alphaSigner.naclSigner.verhex)) logger.debug("Beta's verkey {}".format(betaSigner.naclSigner.verhex)) alpha = None def setupAlpha(ha): nonlocal alpha alpha = RoadStack(name='alpha', ha=ha, sigkey=alphaSigner.naclSigner.keyhex, prikey=alphaPrivateer.keyhex, auto=AutoMode.never, basedirpath=tdir) alpha.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": betaSigner.naclSigner.verhex, "pubhex": betaPrivateer.pubhex }, "beta") oldHa = genHa() setupAlpha(oldHa) beta = RoadStack(name='beta', ha=genHa(), sigkey=betaSigner.naclSigner.keyhex, prikey=betaPrivateer.keyhex, main=True, auto=AutoMode.never, basedirpath=tdir, mutable=True) beta.keep.dumpRemoteRoleData({ "acceptance": Acceptance.accepted.value, "verhex": alphaSigner.naclSigner.verhex, "pubhex": alphaPrivateer.pubhex }, "alpha") try: betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.join(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) logger.debug("beta knows alpha as {}". format(getRemote(beta, "alpha").ha)) cleanup(alpha) newHa = genHa() logger.debug("alpha changing ha to {}".format(newHa)) setupAlpha(newHa) betaRemote = RemoteEstate(stack=alpha, ha=beta.ha) alpha.addRemote(betaRemote) alpha.join(uid=betaRemote.uid, cascade=True) handshake(alpha, beta) sendMsgs(alpha, beta, betaRemote) logger.debug("beta knows alpha as {}". format(getRemote(beta, "alpha").ha)) finally: cleanup(alpha, beta)
import pytest from copy import copy from plenum.common.eventually import eventually from plenum.common.port_dispenser import genHa from plenum.common.signer_simple import SimpleSigner from plenum.common.txn import NODE_IP, CLIENT_IP, CLIENT_PORT, NODE_PORT, ALIAS from plenum.common.types import CLIENT_STACK_SUFFIX from plenum.common.util import randomSeed, randomString from sovrin.test.cli.test_tutorial import poolNodesStarted, philCli newStewardSeed = randomSeed() newNodeSeed = randomSeed() nodeIp, nodePort = genHa() clientIp, clientPort = genHa() newNodeData = { NODE_IP: nodeIp, NODE_PORT: nodePort, CLIENT_IP: clientIp, CLIENT_PORT: clientPort, ALIAS: randomString(6) } vals = { 'newStewardSeed': newStewardSeed, 'newStewardIdr': SimpleSigner(seed=newStewardSeed).identifier, 'newNodeSeed': newNodeSeed, 'newNodeIdr': SimpleSigner(seed=newNodeSeed).identifier, 'newNodeData': newNodeData }