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 = DidSigner(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)[0][0] waitForSufficientRepliesForRequests(looper, newSteward, requests=[req]) def chk(): assert newStewardWallet.getNode(node.id).seqNo is not None timeout = waits.expectedTransactionExecutionTime(len(nodeSet)) looper.run(eventually(chk, retryWait=1, timeout=timeout)) initLocalKeys(newNodeName, tdirWithPoolTxns, sigseed, override=True) newNode = testNodeClass(newNodeName, basedirpath=tdir, base_data_dir=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 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) waitForSufficientRepliesForRequests(looper, newSteward, requests=[req]) def chk(): assert newStewardWallet.getNode(node.id).seqNo is not None timeout = waits.expectedTransactionExecutionTime(len(nodeSet)) looper.run(eventually(chk, retryWait=1, timeout=timeout)) initLocalKeys(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
console.reinit(verbosity=console.Wordage.terse) """ 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 SafeTemporaryDirectory() as tmpdir: """ Looper runs an asynchronous message loop that services the nodes and client. It's also a context manager, so it cleans up after itself. """ with Looper(debug=False) as looper: """ The nodes need to have the their keys initialized """ initLocalKeys('Alpha', tmpdir, randomString(32), override=True) initLocalKeys('AlphaC', tmpdir, randomString(32), override=True) initLocalKeys('Beta', tmpdir, randomString(32), override=True) initLocalKeys('BetaC', tmpdir, randomString(32), override=True) initLocalKeys('Gamma', tmpdir, randomString(32), override=True) initLocalKeys('GammaC', tmpdir, randomString(32), override=True) initLocalKeys('Delta', tmpdir, randomString(32), override=True) initLocalKeys('DeltaC', tmpdir, randomString(32), override=True) """ A node registry is a dictionary of Node names and their IP addresses and port numbers. """ nodeReg = { 'Alpha': NodeDetail(HA('127.0.0.1', 7560), "AlphaC", HA('127.0.0.1', 7561)), 'Beta':
def bootstrapTestNodesCore(cls, config, envName, appendToLedgers, domainTxnFieldOrder, trustee_def, steward_defs, node_defs, client_defs, localNodes, nodeParamsFileName): if not localNodes: localNodes = {} try: if isinstance(localNodes, int): _localNodes = {localNodes} else: _localNodes = {int(_) for _ in localNodes} except BaseException as exc: raise RuntimeError( 'nodeNum must be an int or set of ints') from exc baseDir = cls.setup_base_dir(config) poolLedger = cls.init_pool_ledger(appendToLedgers, baseDir, config, envName) domainLedger = cls.init_domain_ledger(appendToLedgers, baseDir, config, envName, domainTxnFieldOrder) trustee_txn = Member.nym_txn(trustee_def.nym, trustee_def.name, role=TRUSTEE) domainLedger.add(trustee_txn) for sd in steward_defs: nym_txn = Member.nym_txn(sd.nym, sd.name, role=STEWARD, creator=trustee_def.nym) domainLedger.add(nym_txn) for nd in node_defs: if nd.idx in _localNodes: _, verkey = initLocalKeys(nd.name, baseDir, nd.sigseed, True, config=config) _, verkey = initLocalKeys(nd.name + CLIENT_STACK_SUFFIX, baseDir, nd.sigseed, True, config=config) verkey = verkey.encode() assert verkey == nd.verkey if nd.ip != '127.0.0.1': paramsFilePath = os.path.join(baseDir, nodeParamsFileName) print('Nodes will not run locally, so writing ' '{}'.format(paramsFilePath)) TestNetworkSetup.writeNodeParamsFile( paramsFilePath, nd.name, nd.port, nd.client_port) print("This node with name {} will use ports {} and {} for " "nodestack and clientstack respectively".format( nd.name, nd.port, nd.client_port)) else: verkey = nd.verkey node_nym = cls.getNymFromVerkey(verkey) node_txn = Steward.node_txn(nd.steward_nym, nd.name, node_nym, nd.ip, nd.port, nd.client_port) poolLedger.add(node_txn) for cd in client_defs: txn = Member.nym_txn(cd.nym, cd.name, creator=trustee_def.nym) domainLedger.add(txn) poolLedger.stop() domainLedger.stop()
def bootstrapTestNodesCore(config, envName, appendToLedgers, domainTxnFieldOrder, ips, nodeCount, clientCount, nodeNum, startingPort, nodeParamsFileName): baseDir = config.baseDir if not os.path.exists(baseDir): os.makedirs(baseDir, exist_ok=True) localNodes = not ips if localNodes: ips = ['127.0.0.1'] * nodeCount else: ips = ips.split(",") if len(ips) != nodeCount: if len(ips) > nodeCount: ips = ips[:nodeCount] else: ips += ['127.0.0.1'] * (nodeCount - len(ips)) if hasattr(config, "ENVS") and envName: poolTxnFile = config.ENVS[envName].poolLedger domainTxnFile = config.ENVS[envName].domainLedger else: poolTxnFile = config.poolTransactionsFile domainTxnFile = config.domainTransactionsFile poolLedger = Ledger(CompactMerkleTree(), dataDir=baseDir, fileName=poolTxnFile) domainLedger = Ledger( CompactMerkleTree(), serializer=CompactSerializer(fields=domainTxnFieldOrder), dataDir=baseDir, fileName=domainTxnFile) if not appendToLedgers: poolLedger.reset() domainLedger.reset() trusteeName = "Trustee1" sigseed = TestNetworkSetup.getSigningSeed(trusteeName) verkey = Signer(sigseed).verhex trusteeNym = TestNetworkSetup.getNymFromVerkey(verkey) txn = { TARGET_NYM: trusteeNym, TXN_TYPE: NYM, # TODO: Trustees dont exist in Plenum, but only in Sovrin. # This should be moved to Sovrin ROLE: TRUSTEE, ALIAS: trusteeName, TXN_ID: sha256(trusteeName.encode()).hexdigest() } domainLedger.add(txn) steward1Nym = None for num in range(1, nodeCount + 1): stewardName = "Steward" + str(num) sigseed = TestNetworkSetup.getSigningSeed(stewardName) verkey = Signer(sigseed).verhex stewardNym = TestNetworkSetup.getNymFromVerkey(verkey) txn = { TARGET_NYM: stewardNym, TXN_TYPE: NYM, ROLE: STEWARD, ALIAS: stewardName, TXN_ID: sha256(stewardName.encode()).hexdigest() } if num == 1: steward1Nym = stewardNym else: # The first steward adds every steward txn[f.IDENTIFIER.nm] = steward1Nym domainLedger.add(txn) nodeName = "Node" + str(num) nodePort, clientPort = startingPort + (num * 2 - 1), startingPort \ + (num * 2) ip = ips[num - 1] sigseed = TestNetworkSetup.getSigningSeed(nodeName) if nodeNum == num: _, verkey = initLocalKeys(nodeName, baseDir, sigseed, True, config=config) _, verkey = initLocalKeys(nodeName + CLIENT_STACK_SUFFIX, baseDir, sigseed, True, config=config) verkey = verkey.encode() print("This node with name {} will use ports {} and {} for " "nodestack and clientstack respectively".format( nodeName, nodePort, clientPort)) if not localNodes: paramsFilePath = os.path.join(baseDir, nodeParamsFileName) print('Nodes will not run locally, so writing ' '{}'.format(paramsFilePath)) TestNetworkSetup.writeNodeParamsFile( paramsFilePath, nodeName, nodePort, clientPort) else: verkey = Signer(sigseed).verhex txn = { TARGET_NYM: TestNetworkSetup.getNymFromVerkey(verkey), TXN_TYPE: NODE, f.IDENTIFIER.nm: stewardNym, DATA: { CLIENT_IP: ip, ALIAS: nodeName, CLIENT_PORT: clientPort, NODE_IP: ip, NODE_PORT: nodePort, SERVICES: [VALIDATOR] }, TXN_ID: sha256(nodeName.encode()).hexdigest() } poolLedger.add(txn) for num in range(1, clientCount + 1): clientName = "Client" + str(num) sigseed = TestNetworkSetup.getSigningSeed(clientName) verkey = Signer(sigseed).verhex txn = { f.IDENTIFIER.nm: steward1Nym, TARGET_NYM: TestNetworkSetup.getNymFromVerkey(verkey), TXN_TYPE: NYM, ALIAS: clientName, TXN_ID: sha256(clientName.encode()).hexdigest() } domainLedger.add(txn) poolLedger.stop() domainLedger.stop()