def addNewClient(role, looper, creatorClient: Client, creatorWallet: Wallet, name: str): wallet = Wallet(name) wallet.addIdentifier() idr = wallet.defaultId op = { TXN_TYPE: NYM, ROLE: role, TARGET_NYM: idr, ALIAS: name, VERKEY: wallet.getVerkey(idr) } req = creatorWallet.signOp(op) creatorClient.submitReqs(req) nodeCount = len(creatorClient.nodeReg) looper.run( eventually(checkSufficientRepliesRecvd, creatorClient.inBox, req.reqId, 1, retryWait=1, timeout=3 * nodeCount)) return wallet
def testMerkleProofForNonFirstLeaf(looper, nodeSet, client1: Client, replied1): req2 = sendRandomRequest(client1) f = nodeSet.f looper.run( eventually(checkSufficientRepliesRecvd, client1.inBox, req2.reqId, f, retryWait=1, timeout=15)) replies = client1.getRepliesFromAllNodes(req2.reqId).values() assert Client.verifyMerkleProof(*replies)
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 TemporaryDirectory() 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(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 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 testMerkleProofForNonFirstLeaf(looper, nodeSet, wallet1, client1, replied1): req2 = sendRandomRequest(wallet1, client1) f = nodeSet.f looper.run(eventually(checkSufficientRepliesRecvd, client1.inBox, req2.reqId , f, retryWait=1, timeout=15)) replies = client1.getRepliesFromAllNodes(*req2.key).values() assert Client.verifyMerkleProof(*replies)
def load(): port = genHa()[1] ha = HA('0.0.0.0', port) name = "hello" wallet = Wallet(name) wallet.addIdentifier(signer=SimpleSigner( seed=b'000000000000000000000000Steward1')) client = Client(name, ha=ha) with Looper(debug=getConfig().LOOPER_DEBUG) as looper: looper.add(client) print('Will send {} reqs in all'.format(numReqs)) requests = sendRandomRequests(wallet, client, numReqs) start = perf_counter() for i in range(0, numReqs, numReqs // splits): print('Will wait for {} now'.format(numReqs // splits)) s = perf_counter() reqs = requests[i:i + numReqs // splits + 1] waitForSufficientRepliesForRequests(looper, client, requests=reqs, fVal=2, customTimeoutPerReq=3) print('>>> Got replies for {} requests << in {}'.format( numReqs // splits, perf_counter() - s)) end = perf_counter() print('>>>{}<<<'.format(end - start)) exit(0)
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 _, randomClientPort = genHa() client = Client(stewardName, ha=('0.0.0.0', randomClientPort), config=config) looper.add(client) timeout = waits.expectedClientToPoolConnectionTimeout(4) looper.run(eventually(__checkClientConnected, client, retryWait=1, timeout=timeout)) nodeVerKey = SimpleSigner(seed=nodeSeed).verkey # send request req = submitNodeIpChange(client, stewardWallet, nodeName, nodeVerKey, newNodeHA, newClientHA) return client, req
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 addNewClient(role, looper, creatorClient: Client, creatorWallet: Wallet, name: str): wallet = Wallet(name) wallet.addIdentifier() idr = wallet.defaultId op = { TXN_TYPE: NYM, ROLE: role, TARGET_NYM: idr, ALIAS: name, VERKEY: wallet.getVerkey(idr) } req = creatorWallet.signOp(op) creatorClient.submitReqs(req) nodeCount = len(creatorClient.nodeReg) looper.run(eventually(checkSufficientRepliesRecvd, creatorClient.inBox, req.reqId, 1, retryWait=1, timeout=3 * nodeCount)) return wallet
def inner(client: Client) -> Client: if nodeName: skipIds = [client.nodestack.getRemote(nn).uid for nn in nodeName] ovrdRids = [rid for rid in client.nodestack.remotes.keys() if rid not in skipIds] else: ovrdRids = client.nodestack.remotes.keys()[skipCount:] def evilSend(self, msg, *rids, signer=None) -> None: logger.debug("EVIL: sending to less nodes {}, ignoring passed " "rids {} and sending to {} instead.". format(msg, rids, ovrdRids)) for r in ovrdRids: self._enqueue(msg, r, signer) client.send = types.MethodType(evilSend, client) return client
def check_sufficient_replies_received(client: Client, identifier, request_id): reply, _ = client.getReply(identifier, request_id) full_request_id = "({}:{})".format(identifier, request_id) if reply is not None: logger.debug("got confirmed reply for {}: {}".format( full_request_id, reply)) return reply all_replies = getRepliesFromClientInbox(client.inBox, request_id) logger.debug("there are {} replies for request {}, " "but expected at-least {}, " "or one with valid proof: ".format(len(all_replies), full_request_id, client.quorums.reply.value, all_replies)) raise AssertionError( "There is no proved reply and no " "quorum achieved for request {}".format(full_request_id))
def inner(client: Client) -> Client: if nodeName: skipIds = [client.nodestack.getRemote(nn).uid for nn in nodeName] ovrdRids = [ rid for rid in client.nodestack.remotes.keys() if rid not in skipIds ] else: ovrdRids = list(client.nodestack.remotes.keys())[skipCount:] def evilSend(self, msg, *rids, signer=None) -> None: logger.debug("EVIL: sending to less nodes {}, ignoring passed " "rids {} and sending to {} instead.".format( msg, rids, ovrdRids)) return self.nodestack.send(msg, *ovrdRids, signer=signer) client.send = types.MethodType(evilSend, client) return client
def repeatsRequest(client: Client, count: int) -> Client: """ Client sends count number of requests for each operation. Different requestIds will be generated for the same operation. :param client: the client to make faulty :param count: the number of requests to send for each operation. :return: the faulty client """ def evilSubmit(self, *operations: Mapping) -> List[Request]: requests = [] logger.debug( "EVIL: client creates {} requests for each operation".format(count)) for op in operations: for _ in range(count): request = self.createRequest(op) self.send(request) requests.append(request) return requests client.submit = types.MethodType(evilSubmit, client) return client
def repeatsRequest(client: Client, count: int) -> Client: """ Client sends count number of requests for each operation. Different requestIds will be generated for the same operation. :param client: the client to make faulty :param count: the number of requests to send for each operation. :return: the faulty client """ def evilSubmit(self, *operations: Mapping) -> List[Request]: requests = [] logger.debug( "EVIL: client creates {} requests for each operation".format( count)) for op in operations: for _ in range(count): request = self.createRequest(op) self.nodestack.send(request) requests.append(request) return requests client.submit_DEPRECATED = types.MethodType(evilSubmit, client) return client
def sendRandomRequest(client: Client): return client.submit(randomOperation())[0]
def send_signed_requests(client: Client, signed_reqs: Sequence): return client.submitReqs(*signed_reqs)[0]
def testMerkleProofForFirstLeaf(client1: TestClient, replied1): replies = client1.getRepliesFromAllNodes(*replied1.key).values() assert Client.verifyMerkleProof(*replies)
wallet = Wallet("my_wallet") """ Now the wallet needs to have one keypair, so lets add it. """ wallet.addIdentifier() """ A bi-directional connection is made from the client. This is the ip address and port for the client's interfact to the nodes. """ client_addr = ("127.0.0.1", 8000) """ Create a client. """ clientName = "my_client_id" client = Client(name=clientName, ha=client_addr, nodeReg=cliNodeReg, basedirpath=tmpdir) looper.add(client) """ A client signs its requests. By default, a simple yet secure signing mechanism is created for a client. """ idAndKey = wallet.defaultId, wallet.getVerkey() """ A client's signature verification key must be bootstrapped out of band into the consensus pool. For demonstration, we'll add it directly to each node. """ for node in alpha, beta, gamma, delta: node.clientAuthNr.addIdr(*idAndKey) """
def testMerkleProofForNonFirstLeaf(looper, nodeSet, wallet1, client1, replied1): req2 = sendRandomRequest(wallet1, client1) waitForSufficientRepliesForRequests(looper, client1, requests=[req2]) replies = client1.getRepliesFromAllNodes(*req2.key).values() assert Client.verifyMerkleProof(*replies)
def sendRandomRequests(wallet: Wallet, client: Client, count: int): reqs = [wallet.signOp(randomOperation()) for _ in range(count)] return client.submitReqs(*reqs)
'BetaC': ('127.0.0.1', 7563), 'GammaC': ('127.0.0.1', 7565), 'DeltaC': ('127.0.0.1', 7567)} """ A bi-directional connection is made from the client. This is the ip address and port for the client's interfact to the nodes. """ client_addr = ("127.0.0.1", 8000) """ Create a client. """ clientName = "my_client_id" client = Client(name=clientName, ha=client_addr, nodeReg=cliNodeReg, basedirpath=tmpdir) looper.add(client) """ A client signs its requests. By default, a simple yet secure signing mechanism is created for a client. """ idAndKey = client.getSigner().identifier, client.getSigner().verkey """ A client's signature verification key must be bootstrapped out of band into the consensus pool. For demonstration, we'll add it directly to each node. """ for node in alpha, beta, gamma, delta:
def sendRandomRequests(client: Client, count: int): ops = [randomOperation() for _ in range(count)] return client.submit(*ops)
def sendRandomRequests(wallet: Wallet, client: Client, count: int): logger.debug('{} random requests will be sent'.format(count)) reqs = [wallet.signOp(randomOperation()) for _ in range(count)] return client.submitReqs(*reqs)
Now the wallet needs to have one keypair, so lets add it. """ wallet.addIdentifier() """ A bi-directional connection is made from the client. This is the ip address and port for the client's interfact to the nodes. """ client_addr = ("127.0.0.1", 8000) """ Create a client. """ clientName = "my_client_id" client = Client(name=clientName, ha=client_addr, nodeReg=cliNodeReg, basedirpath=tmpdir) looper.add(client) """ A client signs its requests. By default, a simple yet secure signing mechanism is created for a client. """ idAndKey = wallet.defaultId, wallet.getVerkey() """ A client's signature verification key must be bootstrapped out of band into the consensus pool. For demonstration, we'll add it directly to each node. """ for node in alpha, beta, gamma, delta: