def test_tx_forward_on_host(self): peers = make_intersecting_committees_on_host(5, 1) value = 999 submit_to = list(peers.keys())[0] target = None for port in peers: if peers[port].committee_id_a() != peers[submit_to].committee_id_a() \ and peers[port].committee_id_a() != peers[submit_to].committee_id_b() \ and peers[port].committee_id_b() != peers[submit_to].committee_id_a() \ and peers[port].committee_id_b() != peers[submit_to].committee_id_b(): target = port break committee_id = peers[target].committee_id_a() tx = Transaction(quorum=committee_id, key="test_{}".format(value), value=str(value)) url = "http://localhost:{port}/submit/".format(port=peers[submit_to].port) result = requests.post(url, json=tx.to_json()) self.assertEqual(ROUTE_EXECUTED_CORRECTLY, get_plain_text(result)) time.sleep(3) # wait for network to confirm # get peers in committee committee_members = {} for port in peers: if peers[port].committee_id_a() == committee_id or peers[port].committee_id_b() == committee_id: committee_members[port] = peers[port] for member in committee_members: tx = Transaction(quorum=committee_id, key="test_{}".format(value), value=str(value)) url = "http://localhost:{port}/get/".format(port=member) result = requests.post(url, json=tx.to_json()) self.assertEqual(str(value), get_plain_text(result))
def get_avg_for(number_of_transactions: int, experiment_duration_secs: int, measurement_interval_secs: int, number_of_intersections: int, experiments: int, committees: int): throughputPerE = {} for e in range(experiments): print("Setting up experiment {}".format(e)) peers = make_intersecting_committees_on_host(committees, number_of_intersections) results = run_experiment(peers, experiment_duration_secs, measurement_interval_secs, number_of_transactions) throughputPerE[e] = results["throughput"] print("Cleaning up experiment {}".format(e)) del peers gc.collect() throughput = {} # For each experiment for e in range(experiments): # If no transactions were confirmed, inputs zero, to prevent dividing by zero if len(throughputPerE[e]) == 0: throughputPerE[e] = 0 # takes the amount of transactions confirmed per experiment and divides them by the runs in each experiment else: for key in throughputPerE[e]: if key in throughput: value = throughput[key] + throughputPerE[e][key] throughput[key] = value else: throughput[key] = throughputPerE[e][key] sortedlist = sorted(throughput.items()) sortedThroughput = dict(sortedlist) return {"throughput": sortedThroughput}
def get_avg_for(number_of_transactions: int, number_of_intersections: int, experiments: int, committees: int): throughputPer5 = {} for e in range(experiments): print("Setting up experiment {}".format(e)) peers = make_intersecting_committees_on_host(committees, number_of_intersections) results = run_experiment(peers, number_of_transactions) throughputPer5[e] = results["throughput"] print("Cleaning up experiment {}".format(e)) os.echo("docker kill $(docker ps -q)") os.echo("docker rm $(docker ps -a -q)") del peers gc.collect() throughput = [] # For each experiment for e in range(experiments): # If no transactions were confirmed, inputs zero, to prevent dividing by zero if len(throughputPer5[e]) == 0: throughputPer5[e] = 0 # takes the amount of transactions confirmed per experiment and divides them by the runs in each experiment else: throughputPer5[e] = sum(throughputPer5[e]) / len(throughputPer5[e]) for e in throughputPer5: throughput.append(throughputPer5[e]) return {"throughput": sum(throughput) / len(throughput)}
def test_intersecting_committees_on_host(self): peers = make_intersecting_committees_on_host(5, 1) for p in peers: pid = peers[p].pid() pros = [] for pro in psutil.process_iter(): pros.append(pro.pid) self.assertIn(pid, pros)
def get_avg_for(number_of_committees: int, number_of_intersections: int, experiments: int, total_tx: int): waiting_time = [] for e in range(experiments): print("Setting up experiment {}".format(e)) peers = make_intersecting_committees_on_host(number_of_committees, number_of_intersections) results = run_experiment(peers, total_tx) waiting_time += results["waitingTime"] print("Cleaning up experiment {}".format(e)) del peers gc.collect() return {"waitingTime": sum(waiting_time) / len(waiting_time)}
def test_cooperative_leave(self): num_committees = 8 # Tracks how many times each individual quorum has lost a peer sawtooth_committees_members = {} for i in range(0, num_committees): sawtooth_committees_members[i] = num_committees - 1 # set up initial network peers = make_intersecting_committees_on_host(num_committees, 1) # pick a random peer to leave random.seed(time.gmtime()) rand_port = random.choice(list(peers.keys())) rand_peer = peers[rand_port] rand_peer_pid = rand_peer.pid() rand_peer_quorums = [ rand_peer.committee_id_a(), rand_peer.committee_id_b() ] # Make sure random peer is a valid process before the leave running_processes_before_leave = [] for p in psutil.process_iter(): running_processes_before_leave.append(p.pid) self.assertIn(rand_peer_pid, running_processes_before_leave) # Ensure peer is in the dict of peers self.assertIn(rand_port, list(peers.keys())) quorum_exists = False # Make sure all neighbors know about the leaving peer before they leave ids_found = 0 for search_committee in rand_peer_quorums: for port in list(peers.keys()): for quorum_id in peers[port].app.api.config[QUORUMS]: for neighbor in peers[port].app.api.config[QUORUMS][ quorum_id]: if neighbor[QUORUM_ID] == search_committee: ids_found += 1 if ids_found == 2: quorum_exists = True break self.assertEqual(True, quorum_exists) # Do not allow peers to leave if they should not be allowed to leave leave_success = rand_peer.leave() if leave_success: id_a = peers[rand_port].app.api.config[ PBFT_INSTANCES].committee_id_a id_b = peers[rand_port].app.api.config[ PBFT_INSTANCES].committee_id_b sawtooth_committees_members[int(id_a)] -= 1 sawtooth_committees_members[int(id_b)] -= 1 del peers[rand_port] # Delay to allow other peers to cat ch up time.sleep(2) else: # Peer failed to cooperatively leave return # Random peer should no longer be running running_processes_after_leave = [] for p in psutil.process_iter(): running_processes_after_leave.append(p.pid) # Leaving API process has been terminated self.assertNotIn(rand_peer_pid, running_processes_after_leave) # Terminated port is no longer present port_found = False peer_found = False for search_committee in rand_peer_quorums: for port in list(peers.keys()): for quorum_id in peers[port].app.api.config[QUORUMS]: for neighbor in peers[port].app.api.config[QUORUMS][ quorum_id]: if neighbor[PORT] == rand_port: port_found = True break neighbor_inter = peers[port].app.api.config[ PBFT_INSTANCES] neighbor_instance_a = neighbor_inter.instance_a neighbor_instance_b = neighbor_inter.instance_b # Leaving API process has been removed from peers dict self.assertEqual(False, port_found) # Continue deleting peers until at breaking point of consensus while True: random.seed(time.gmtime()) rand_port = random.choice(list(peers.keys())) rand_peer = peers[rand_port] rand_inter = rand_peer.app.api.config[PBFT_INSTANCES] id_a = rand_inter.committee_id_a id_b = rand_inter.committee_id_b leave_success = rand_peer.leave() del peers[rand_port] sawtooth_committees_members[int(id_a)] -= 1 sawtooth_committees_members[int(id_b)] -= 1 if sawtooth_committees_members[int( id_a)] >= 4 and sawtooth_committees_members[int( id_b)] >= 4: self.assertEqual(True, leave_success) else: self.assertEqual(False, leave_success) return