def send_res_proof_to_clients():
		output("Olympus:      Res proofs for clients")
		for client_id in client_res_shuttle:
			if (not check_client_ready(client_id)):
				continue
			output("Olympus:      Checking res proofs for client", client_id)
			res_stats = client_res_shuttle[client_id]
			result_hash_list=[]
			result_digest=""
			result=""
			result_proof={}
			for tup in res_stats:	
				slot_id=tup[1]
				orig_stat=verify_signed_msg(rep_pub_keys[tup[2]], tup[0])
				if (orig_stat):
					result = orig_stat['result']
					res_op = orig_stat['op']
					res_slot = orig_stat['slot_id']
					result_digest = create_hash_and_encode_msg(result).digest
					result_hash_list.append(orig_stat['digest'])
					output("Olympus:      Client: ",client_id,"Got result ",result,"from rep",tup[2], "at slot" , tup[1])
					output("Olympus:      Client: ",client_id,"Orig_res_stat: result ",result,"from rep",tup[2], "at slot" , res_slot, "and op", res_op)
			if (len(result_hash_list) == (int(nreplicas/2) + 1) and (len(set(result_hash_list)) == 1) and (result_digest == result_hash_list[0])):
				output("Olympus:      Res proof Validated and Sending res proofs to client",client_id)
				result_proof['result_statements'] = result_hash_list
				send(('olymp_res_proof', result_proof, result, longest_slot_len + slot_id), to=client_config[client_id])
			else:
				output("Olympus:      Did not find a quorum of result proof for client", client_id)
 def validate_result_proof(result_proof):
     output("Replica", myreplica_id, " :Trying to validate result proof")
     result_statements = result_proof['result_statements']
     result = result_proof['result']
     result_hash = create_hash_and_encode_msg(result).digest
     op_list = []
     for index, rstat in enumerate(result_statements):
         #output (">>",index)
         sender_public_key_hex = rep_pub_keys[index]
         orig_stat = verify_signed_msg(sender_public_key_hex, rstat)
         if (orig_stat):
             #output ("Replica", myreplica_id, " :Verified signature of replica ", index)
             op_list.append(orig_stat['op'])
             if ((result == orig_stat['result'])
                     and (result_hash == orig_stat['digest'])):
                 continue
             else:
                 output(
                     "Replica", myreplica_id,
                     " :result proof error, validation mismatch for sender ",
                     index)
                 return None
         else:
             output(
                 "Replica", myreplica_id,
                 " :result proof error, vCould not verify id of sender ",
                 index)
             return None
     if (len(set(op_list)) != 1):
         output("Replica", myreplica_id,
                " :Invald operation in result proof")
         return None
     else:
         return 1
	def validate_order_proof(order_proof, next_slot_id, sender_id):
		output("Olympus:      Trying to validate order proof for rep", sender_id, "at slot ", next_slot_id)
		order_statements = order_proof['order_statements']
		if (len(order_statements) != (sender_id+1)):
			output ("Olympus      :Length of order proof not correct")
			return None	
		operation = order_proof['op']
		slot_id = order_proof['slot_id']
		if (slot_id != next_slot_id):
			output("Olympus:      Unexpected slot id in history from replica", sender_id)
			return None
		#output("slot_id", slot_id, "op:", operation)
		for index, ostat in enumerate(order_statements):
			#output (">>",index, ostat)
			sender_public_key_hex = rep_pub_keys[index]
			orig_stat=verify_signed_msg(sender_public_key_hex, ostat)
			if(orig_stat):
				#output ("Olympus:     Verified signature of replica ", index)
				#output("validated order proof, type orig_stat", type(orig_stat), "sid", orig_stat['slot_id'], "op",orig_stat['op'])
				if ((slot_id == orig_stat['slot_id']) and (operation == orig_stat['op'])):
					continue
				else:
					output ("Olympus:      Order Proof validation mismatch for replica ", index, "from sender", sender_id)
					return None
			else:
				output ("Olympus:      Order Proof validation Could not verify id of replica ", index, "from sender", sender_id)
				return None

		return (slot_id, operation)
Exemple #4
0
 def receive(msg=('wedge_req', signed_wedge_msg)):
     output("\n\n")
     output("Replica", myreplica_id, " :Got wedge req from Olympus")
     wedge_req_msg_num += 1
     failure = super().check_for_failures(-1, 'wedge_req',
                                          wedge_req_msg_num,
                                          rep_fail_triggers)
     if failure and any(
             x in failure for x in
         ["sleep", "crash", "extra_op", "drop", "increment_slot"]):
         pending_fail = apply_immediate_failure(mydict, failure, False)
         if (pending_fail == "drop"):
             return
     elif (failure):
         output("Replica", myreplica_id, " :Found failure", failure,
                "for wedge_req  at msg num ", wedge_req_msg_num)
         super().update_relevant_failure(failure, "wedge_req", -1,
                                         wedge_req_msg_num,
                                         pending_failures)
     orig_msg = verify_signed_msg(olymp_config['pub_keys'],
                                  signed_wedge_msg)
     if orig_msg:
         send_hist = copy.deepcopy(history)
         mode = 2
         if (len(pending_failures['wedge_msg']) != 0):
             next_failure = pending_failures['wedge_msg'].pop(0)
             output("Replica", myreplica_id, "next_fail", next_failure)
             if ("truncate_history" in next_failure[0]):
                 p1 = re.search("(?<=\().*(?=\))", next_failure[0])
                 pair = p1.group()
                 tr_len = int(pair.strip())
                 output("Replica", myreplica_id,
                        " :Found failure truncate hist with len", tr_len)
                 if (tr_len <= len(send_hist)):
                     for i in range(0, tr_len):
                         send_hist.pop()
         output("Replica", myreplica_id, " :Sending history with hist_len",
                len(send_hist))
         send(('wedge_resp', myreplica_id, send_hist),
              to=olymp_config['config'])
     else:
         output("Replica", myreplica_id,
                " :Could not verify Olympus identity")
Exemple #5
0
 def receive(msg=('client_result_pkg', result, replica_id,
                  signed_result_client, client_req_id, slot_id)):
     output("Client: ", myclient_id, " :Got result proof pkg from replica",
            replica_id)
     sender_public_key_hex = rep_pub_keys[
         replica_id]  # this cannot be a fn call, this is stored somewhere.
     orig_res_client = verify_signed_msg(sender_public_key_hex,
                                         signed_result_client)
     if not (orig_res_client):
         output("Client: ", myclient_id,
                " :Could NOT verify the identity of replica", replica_id)
     else:
         output("Client: ", myclient_id, " :verified sign of replica",
                replica_id)
         result_proof = orig_res_client['result_proof']
         #maybe use slot_id and replica_id too?
         num_valid_replicas = validate_result_proof(result_proof, result)
         if not (num_valid_replicas):
             output("Client: ", myclient_id,
                    " :Could NOT validate result proof for req_id",
                    client_req_id)
             output("Client: ", myclient_id, "Notifying Olympus")
             #what to do now?
         else:
             #handle multiple responses for same req
             output("Client: ", myclient_id,
                    " :Validated result proof from replica,", replica_id,
                    "for req_id", client_req_id, "at slot_id", slot_id,
                    "result", result)
             if ((client_req_id in valid_result_proofs)
                     and (not valid_result_proofs[client_req_id])):
                 output("Client: ", myclient_id,
                        " :Accepted Res proof from replica,", replica_id,
                        " for req_id", client_req_id, "with result", result,
                        "and slot", slot_id, "for op", pending_op)
                 valid_result_proofs[client_req_id] = True
                 rep_res[slot_id] = result
                 exp_res[client_req_id]['slot'] = slot_id
             else:
                 output("Client: ", myclient_id,
                        "already got result proof for req_id",
                        client_req_id)
                 return
Exemple #6
0
 def validate_result_proof(result_proof, result):
     output("Client: ", myclient_id, ":trying to validate result proof")
     result_statements = result_proof['result_statements']
     #result = result_proof['result']
     result_hash = create_hash_and_encode_msg(result).digest
     valid_reps = 0
     op_list = []
     shift = 0
     if len((result_statements)) < nreplicas:
         output("Client: ", myclient_id, "Truncated res_proof of size ",
                len((result_statements)))
         shit = 1
     for index, rstat in enumerate(result_statements):
         #output (">>",index)
         sender_public_key_hex = rep_pub_keys[index + shift]
         orig_stat = verify_signed_msg(sender_public_key_hex, rstat)
         if (orig_stat):
             #output ("Client", myclient_id, " :Verified signature of replica ", index)
             op_list.append(orig_stat['op'])
             if ((result_hash == orig_stat['digest'])):
                 valid_reps += 1
                 continue
             else:
                 output("Client: ", myclient_id,
                        "Result proof error: mismatch for sender ", index)
                 continue
         else:
             output("Client: ", myclient_id,
                    "Result proof error: Could not verify id of sender ",
                    index)
             continue
     if (len(set(op_list)) != 1):
         output("Client: ", myclient_id,
                "Invalid operation in result proof")
         is_op_invalid = True
     if (valid_reps >= (int(nreplicas / 2) + 1)):
         output("Client: ", myclient_id, "Got ", valid_reps,
                "valid results")
         return valid_reps
     else:
         return 0
 def validate_order_proof(order_proof, next_slot_id, operation):
     output("Replica", myreplica_id, " :Trying to validate order proof")
     order_statements = order_proof['order_statements']
     if (len(order_statements) != (myreplica_id)):
         output("Replica", myreplica_id,
                " :Length of order proof not correct")
         return (None, next_slot_id)
     expected_slot = next_slot_id
     slot_id = order_proof['slot_id']
     if (slot_id != expected_slot):
         output("Replica", myreplica_id,
                " :OP validation did not expect this slot_id; exp:",
                expected_slot, "got ", slot_id)
         return (None, next_slot_id)
     for index, ostat in enumerate(order_statements):
         #output (">>",index, ostat)
         sender_public_key_hex = rep_pub_keys[index]
         orig_stat = verify_signed_msg(sender_public_key_hex, ostat)
         if (orig_stat):
             #output ("Replica", myreplica_id, " :Verified signature of replica ", index)
             #output("validated order proof, type orig_stat", type(orig_stat), "sid", orig_stat['slot_id'], "op",orig_stat['op'])
             if ((slot_id == orig_stat['slot_id'])
                     and (operation == orig_stat['op'])):
                 continue
             else:
                 output("Replica: ", myreplica_id,
                        "Order Proof validation mismatch for sender ",
                        index)
                 return (None, next_slot_id)
         else:
             output(
                 "Replica: ", myreplica_id,
                 "Order Proof validation Could not verify id of sender ",
                 index)
             return (None, next_slot_id)
     next_slot_id += 1
     return (1, next_slot_id)
 def inject_failure(order_proof, result_proof, next_failure):
     output("Checking pending faiures for replica", myreplica_id)
     nreplicas = len(rep_config)
     trigger = next_failure[1]
     if "change_result" in next_failure[0]:
         output(
             "Replica", myreplica_id, " : { Trigger  :", trigger,
             " : failure <change_result> } injected in result_shuttle_pkg")
         result_msg_hash = create_hash_and_encode_msg("OK")
         sender_public_key_hex = rep_pub_keys[myreplica_id]
         myindex = myreplica_id
         if (len(result_proof['result_statements']) < nreplicas):
             output(
                 "Replica", myreplica_id,
                 " : Changing result and btw, someone already dropped Head's result statement"
             )
             myindex = myreplica_id - 1
         orig_rstat = verify_signed_msg(
             sender_public_key_hex,
             result_proof['result_statements'][myindex])
         if (orig_rstat):
             orig_rstat['digest'] = result_msg_hash.digest
             signed_result_stat = generate_signed_msg(
                 orig_rstat, my_priv_key)
             result_proof['result_statements'][myindex] = signed_result_stat
         else:
             output("FAILED TO INJECT FAILURE : COuld not verify sign of ",
                    myindex)
     elif "drop_result_stmt" in next_failure[0]:
         #is nullifying better than omitting
         output(
             "Replica", myreplica_id, " : { Trigger", trigger,
             " : failure <drop_result_stmt> } injected in result_shuttle_pkg"
         )
         if (len(result_proof['result_statements']) < nreplicas):
             output(
                 "Replica", myreplica_id,
                 " : Someone already dropped Head's result statement, ignoring"
             )
         else:
             output("Replica", myreplica_id,
                    " : Dropping head res statement")
             del (result_proof['result_statements'][0])
     elif "change_operation" in next_failure[0]:
         output(
             "Replica", myreplica_id, " : { Trigger", trigger,
             " : failure <change_operation> } injected in fwd_shuttle_pkg")
         sender_public_key_hex = rep_pub_keys[myreplica_id]
         orig_ostat = verify_signed_msg(
             sender_public_key_hex,
             order_proof['order_statements'][myreplica_id])
         orig_rstat = verify_signed_msg(
             sender_public_key_hex,
             result_proof['result_statements'][myreplica_id])
         if (orig_ostat and orig_rstat):
             orig_ostat['op'] = "get(x)"
             orig_rstat['op'] = "get(x)"
             signed_order_stat = generate_signed_msg(
                 orig_ostat, my_priv_key)
             signed_result_stat = generate_signed_msg(
                 orig_rstat, my_priv_key)
             order_proof['order_statements'][
                 myreplica_id] = signed_order_stat
             result_proof['result_statements'][
                 myreplica_id] = signed_result_stat
         else:
             output("Replica", myreplica_id,
                    " : Invalid sign on order or rstat; order stat",
                    orig_ostat, "result_stat", orig_rstat)
     elif "invalid_order_sig" in next_failure[0]:
         orig_ostat = order_proof['order_statements'][myreplica_id]
         invalid_ostat = gen_invalid_sign_msg(orig_ostat)
         order_proof['order_statements'][myreplica_id] = invalid_ostat
         output(
             "Replica", myreplica_id, " : { Trigger", trigger,
             " : failure <invalid_order_sig> } injected in fwd_shuttle_pkg")
     elif "invalid_result_sig" in next_failure[0]:
         myindex = myreplica_id
         if ((len(result_proof['result_statements']) < nreplicas)
                 and am_I_tail):
             output(
                 "Replica", myreplica_id,
                 " : Invalidating result stat and btw, someone already dropped Head's result statement"
             )
             myindex = myreplica_id - 1
         orig_rstat = result_proof['result_statements'][myindex]
         invalid_rstat = gen_invalid_sign_msg(orig_rstat)
         result_proof['result_statements'][myindex] = invalid_rstat
         output(
             "Replica", myreplica_id, " : { Trigger", trigger,
             " : failure <invalid_result_sig> } injected in res_shuttle_pkg"
         )
Exemple #9
0
    def receive(msg=('client_op_req', signed_client_msg, client_id,
                     client_req_id)):
        output("\n\n")
        if (mode == 2):
            output("Replica", myreplica_id,
                   " :Client req in immutable mode, ignored")
            return

        TIMEOUT = mytimeout
        output("Replica", myreplica_id, " :Client_op request from client",
               client_id, "with req_id", client_req_id, "potential slot_id",
               next_slot_id)
        client_msg[client_id]['num_client_req'] += 1
        failure = super().check_for_failures(
            client_id, 'client_req', client_msg[client_id]['num_client_req'],
            rep_fail_triggers)
        if failure and any(
                x in failure for x in
            ["sleep", "crash", "extra_op", "drop", "increment_slot"]):
            pending_fail = apply_immediate_failure(mydict, failure, False)
            if (pending_fail == "drop"):
                return
        elif (failure):
            output("Replica", myreplica_id, " :Found failure", failure,
                   "for client", client_id, "at msg_num ",
                   client_msg[client_id]['num_client_req'])
            super().update_relevant_failure(
                failure, 'client_request', client_id,
                client_msg[client_id]['num_client_req'], pending_failures)
        sender_public_key_hex = client_pub_keys[client_id]  #0 is the client
        orig_client_msg = verify_signed_msg(sender_public_key_hex,
                                            signed_client_msg)
        if not (orig_client_msg):
            output("Replica", myreplica_id,
                   " :Could NOT verify the identity of msg from client")
            return
        else:
            output("Replica", myreplica_id, " :Verified sign of client",
                   client_id)
            is_retransmit = orig_client_msg['is_retransmit']
            operation = orig_client_msg['operation']
            if (is_retransmit):
                output("Replica", myreplica_id,
                       " :This is a retransmitted request client-id",
                       client_id, "with req", client_req_id)
                #do I have this result cached?
                key = (client_id, client_req_id)
                key = str(key)
                if (key in res_proof_cache):
                    output("Replica", myreplica_id,
                           " :Found cached result for", client_id,
                           "with req id", client_req_id)
                    result_proof = res_proof_cache[key]['cached_result_proof']
                    result = res_proof_cache[key]['cached_result']
                    order_proof = {}
                    if (len(pending_failures['res_shuttle']) != 0):
                        next_failure = pending_failures['res_shuttle'].pop(0)
                        super().inject_failure(order_proof, result_proof,
                                               next_failure)
                    send_shuttle = {'result_proof': result_proof}
                    signed_send_shuttle = generate_signed_msg(
                        send_shuttle, my_priv_key)
                    send(('client_result_pkg', result, myreplica_id,
                          signed_send_shuttle, client_req_id,
                          longest_slot_len + req_slot_map[key]),
                         to=client_config[client_id])
                elif (not am_I_head):
                    output("Replica", myreplica_id, " :Cache lookup for req",
                           client_req_id, "from", client_id,
                           "failed, Sending fwd req to head")
                    send(('rep_fwd_req', operation, myreplica_id, client_id,
                          client_req_id, signed_client_msg),
                         to=rep_config[0])
                    exp_val = client_msg[client_id]['num_valid_res_shutl'] + 1
                    #wait for timer to expire or a res_shuttle to arrive, is the check correct
                    #would it be good to check for specific req id
                    output("Replica", myreplica_id,
                           "  :Starting timer waiting for (", client_req_id,
                           client_id, ") to arrive")
                    if (await (client_msg[client_id]['num_valid_res_shutl'] ==
                               exp_val)):
                        result_proof = res_proof_cache[key][
                            'cached_result_proof']
                        result = res_proof_cache[key]['cached_result']
                        order_proof = {}
                        if (len(pending_failures['res_shuttle']) != 0):
                            next_failure = pending_failures['res_shuttle'].pop(
                                0)
                            super().inject_failure(order_proof, result_proof,
                                                   next_failure)
                        send_shuttle = {'result_proof': result_proof}
                        signed_send_shuttle = generate_signed_msg(
                            send_shuttle, my_priv_key)
                        output("Replica", myreplica_id,
                               "  :Res proof arrived and sending to client ",
                               client_id)
                        if (not am_I_tail):  #tail must have sent anyway
                            send(('client_result_pkg', result, myreplica_id,
                                  signed_send_shuttle, client_req_id,
                                  longest_slot_len + req_slot_map[key]),
                                 to=client_config[client_id])
                    elif timeout(TIMEOUT):
                        output(
                            "Replica", myreplica_id,
                            "  :Timed out and Complaining to Olympus for req-id",
                            client_req_id, "from client", client_id)
                        send(('reconfig_req', myreplica_id, True),
                             to=olymp_config['config'])
                elif (am_I_head):
                    #head has ordered this operation
                    output("Replica", myreplica_id,
                           "  or HEAD could not find (", client_id,
                           client_req_id, ") in cache")
                    handle_retransmitted_req(key, operation, myreplica_id,
                                             client_id, client_req_id,
                                             signed_client_msg)

            else:
                output("Replica", myreplica_id, " :Client_req got operation",
                       operation)
                if (pending_slot_failure and am_I_head):
                    output("Replica", myreplica_id, " :slot failure injected")
                    next_slot_id += 1
                    pending_slot_failure = False
                is_result = 0
                order_proof = {}
                key = (client_id, client_req_id)
                slot_key = str(key)
                #have an if check here?
                order_proof['slot_id'] = next_slot_id
                req_slot_map[slot_key] = next_slot_id
                next_slot_id += 1
                order_proof['op'] = operation
                result_proof = {}
                result = apply_operation(mydict, operation)
                order_proof['order_statements'] = []
                result_proof['result_statements'] = []
                #result_proof['slot_id'] = []

                send_shuttle = super().create_new_shuttle(
                    order_proof, result_proof, myreplica_id, is_result, result,
                    my_priv_key, operation)
                history.append(copy.deepcopy(order_proof))
                recent_client_req_map.appendleft(client_id)
                signed_res_stat_map[client_id] = (copy.deepcopy(
                    result_proof['result_statements'][-1]),
                                                  copy.deepcopy(
                                                      order_proof['slot_id']),
                                                  myreplica_id)
                '''
				if (am_I_head):
					if (dummy_msg_num == 4):
						return
					else:
						dummy_msg_num +=1
				'''

                if (len(pending_failures['fwd_shuttle']) != 0):
                    next_failure = pending_failures['fwd_shuttle'].pop(0)
                    super().inject_failure(order_proof, result_proof,
                                           next_failure)
                signed_new_fwd_shuttle = generate_signed_msg(
                    send_shuttle, my_priv_key)
                send_to_correct_replica(rep_config, myreplica_id,
                                        signed_new_fwd_shuttle, result,
                                        is_result, client_id, client_req_id,
                                        send_shuttle, signed_client_msg)
Exemple #10
0
 def receive(msg=('signed_result_shuttle_pkg', replica_id,
                  signed_res_shuttle, client_id, client_req_id)):
     output("\n\n")
     if (mode == 2):
         output("Replica", myreplica_id,
                " :Client req in immutable mode, ignored")
         return
     output("Replica", myreplica_id, " :Res_shuttle_pkg from replica",
            replica_id, "for client", client_id, "and req", client_req_id)
     sender_public_key_hex = rep_pub_keys[replica_id]
     client_msg[client_id]['num_res_shutl'] += 1
     failure = super().check_for_failures(
         client_id, 'res_shutl', client_msg[client_id]['num_res_shutl'],
         rep_fail_triggers)
     if failure and any(
             x in failure for x in
         ["sleep", "crash", "extra_op", "drop", "increment_slot"]):
         pending_fail = apply_immediate_failure(mydict, failure, False)
         if (pending_fail == "drop"):
             return
     elif (failure):
         output("Replica", myreplica_id, " :Found failure", failure,
                "for client", client_id, "at msg_num ",
                client_msg[client_id]['num_res_shutl'])
         super().update_relevant_failure(
             failure, "result_shuttle", client_id,
             client_msg[client_id]['num_res_shutl'], pending_failures)
     orig_res_shuttle = verify_signed_msg(sender_public_key_hex,
                                          signed_res_shuttle)
     if not (orig_res_shuttle):
         output("Replica", myreplica_id,
                " :Could NOT verify the identity of ", replica_id)
     else:
         output("Replica", myreplica_id, " :Validated identity of ",
                replica_id)
         result_proof = orig_res_shuttle['result_proof']
         order_proof = orig_res_shuttle['order_proof']
         is_result = orig_res_shuttle['is_result']
         if not (super().validate_result_proof(result_proof)):
             output("Replica", myreplica_id,
                    " :Could NOT validate result proof")
             output("Replica", myreplica_id, " :Complaining to olympus")
             #what to do here
         else:
             client_msg[client_id]['num_valid_res_shutl'] += 1
             cache_result_shuttle(result_proof, client_id, client_req_id)
             output("Replica", myreplica_id, " :Validated result proof")
             if (not am_I_head
                     and (len(pending_failures['res_shuttle']) != 0)):
                 next_failure = pending_failures['res_shuttle'].pop(0)
                 super().inject_failure(order_proof, result_proof,
                                        next_failure)
             send_shuttle = {
                 'is_result': is_result,
                 'order_proof': order_proof,
                 'result_proof': result_proof
             }
             signed_new_res_shuttle = generate_signed_msg(
                 send_shuttle, my_priv_key)
             result = result_proof['result']
             if (signed_new_res_shuttle):
                 send_to_correct_replica(rep_config, myreplica_id,
                                         signed_new_res_shuttle, result,
                                         is_result, client_id,
                                         client_req_id, send_shuttle, "")
             else:
                 output("Replica", myreplica_id, " :Error in res shuttle")
Exemple #11
0
 def receive(msg=('signed_fwd_shuttle_pkg', replica_id, signed_fwd_shuttle,
                  client_id, client_req_id, signed_client_msg)):
     if (mode == 2):
         output("Replica", myreplica_id,
                " :Client req in immutable mode, ignored")
         return
     output("\n\n")
     output("Replica", myreplica_id, " :Fwd_shuttle_pkg from replica",
            replica_id, "for client", client_id, "and req-id",
            client_req_id, "potential slot", next_slot_id)
     sender_public_key_hex = rep_pub_keys[replica_id]
     orig_fwd_shuttle = verify_signed_msg(sender_public_key_hex,
                                          signed_fwd_shuttle)
     client_public_key_hex = client_pub_keys[client_id]
     orig_client_msg = verify_signed_msg(client_public_key_hex,
                                         signed_client_msg)
     client_msg[client_id]['num_fwd_shutl'] += 1
     failure = super().check_for_failures(
         client_id, 'fwd_shutl', client_msg[client_id]['num_fwd_shutl'],
         rep_fail_triggers)
     if failure and any(
             x in failure for x in
         ["sleep", "crash", "extra_op", "drop", "increment_slot"]):
         pending_fail = apply_immediate_failure(mydict, failure, False)
         if (pending_fail == "drop"):
             return
     elif (failure):
         output("Replica", myreplica_id, " :Found fwd_shutl failure",
                failure, "for client", client_id, "at msg num ",
                client_msg[client_id]['num_fwd_shutl'])
         super().update_relevant_failure(
             failure, "shuttle", client_id,
             client_msg[client_id]['num_fwd_shutl'], pending_failures)
     if (not orig_client_msg):
         output("Replica", myreplica_id,
                " :Could not verify signed client msg")
         return
     else:
         operation = orig_client_msg['operation']
     if not (orig_fwd_shuttle):
         output("Replica", myreplica_id,
                " :fwd_pkg Could NOT verify the identity of msg from ",
                replica_id)
         return
     else:
         #orig_fwd_shuttle is of type Shuttle
         output("Replica", myreplica_id, " :verified sign of replica",
                replica_id)
         is_result = orig_fwd_shuttle['is_result']
         order_proof = orig_fwd_shuttle['order_proof']
         result_proof = orig_fwd_shuttle['result_proof']
         #maybe use slot_id and replica_id too?
         (is_op_valid, next_slot_id) = super().validate_order_proof(
             order_proof, next_slot_id, operation)
         if not (is_op_valid):
             output("Replica", myreplica_id,
                    " :Could NOT validate order proof")
             output("Replica", myreplica_id, " :Complaining to olympus")
             #what to do now?
         else:
             output("Replica", myreplica_id, " :validated order proof")
             output("Replica", myreplica_id, " : Slot_id",
                    order_proof['slot_id'], "operation", operation)
             key = (client_id, client_req_id)
             key = str(key)
             req_slot_map[key] = order_proof['slot_id']
             if (operation == "get(x)"):
                 output("something went very wrong")
                 #fail_var=-1
             result = apply_operation(mydict, operation)
             if (am_I_tail):
                 is_result = 1
             else:
                 is_result = 0
             send_shuttle = super().create_new_shuttle(
                 order_proof, result_proof, myreplica_id, is_result, result,
                 my_priv_key, operation)
             if (am_I_tail):
                 client_msg[client_id]['num_valid_res_shutl'] += 1
                 cache_result_shuttle(result_proof, client_id,
                                      client_req_id)
             history.append(copy.deepcopy(order_proof))
             recent_client_req_map.appendleft(client_id)
             signed_res_stat_map[client_id] = (
                 copy.deepcopy(result_proof['result_statements'][-1]),
                 copy.deepcopy(order_proof['slot_id']),
                 myreplica_id,
             )
             if (not am_I_tail
                     and (len(pending_failures['fwd_shuttle']) != 0)):
                 next_failure = pending_failures['fwd_shuttle'].pop(0)
                 super().inject_failure(order_proof, result_proof,
                                        next_failure)
             if (am_I_tail and (len(pending_failures['res_shuttle']) != 0)):
                 next_failure = pending_failures['res_shuttle'].pop(0)
                 super().inject_failure(order_proof, result_proof,
                                        next_failure)
             signed_new_fwd_shuttle = generate_signed_msg(
                 send_shuttle, my_priv_key)
             if (signed_new_fwd_shuttle):
                 send_to_correct_replica(rep_config, myreplica_id,
                                         signed_new_fwd_shuttle, result,
                                         is_result, client_id,
                                         client_req_id, send_shuttle,
                                         signed_client_msg)
             else:
                 output("Fwd: replica", myreplica_id,
                        " :Error in fwd shuttle")