Author: Not specified Language: python
Description: Not specified Timestamp: 2017-09-22 21:07:48 +0000
View raw paste Reply
class Olympus :
        # Setup class variables
        configuration_size = 100 # Number of replicas in a configuration
        pending_replicas = Replica_List # List of pending replicas
        configuration = generate_new_configuration() # List of replicas in current config
        olympus_keys = (public_key, private_key) # Public key private key tuple
        message_handler = OlympusMessageHandler(olympus_keys)
        history = []
        history_candidate = []
        quorum_size = 20 #

        # Reconfiguration
        def reconfigure() :
                # Send wedge
                for replica in configuration :
                        message_handler.send(receiver = replica, message = wedge_message('Wedge'))
                # Await response from quorum
                q_history = []
                for q in Quorum :
                        q_history.add(await receive_wedged())
                # Rebuild longest history
                maximal_history = select_maximal_history(q_history)
                # Send catch up message and wait for replicas to catch up
                catchup_replicas = []
                for q in Quorum :
                        if len(q.history) < len(maximal_history) :
                                message_handler.send(receiver = q, message = catch_up_message(maximal_history - q.history))

                # Wait for replicas to catch up
                caughtup_running_state_hash = None
                for q in catchup_replicas :
                        # We assume all replicas in this set have the same running state at this point and return the same hash
                        caughtup_running_state_hash = await caught_up()

                # Compute the hash of running state from replicas who caught up
                quorum_running_state = None
                while quorum_running_state == None :
                        # If matches hash (matches the one who caught up) that's the correct running state
                        # Else ask another replica
                        q = Quorum[random] # For random q in Quorum
                        running_state = message_handler.send(receiver = q, message = get_running_state_message())
                        if hash(running_state) == caughtup_running_state_hash :
                                quorum_running_state = running_state
                # Allocate new configuration
                new_config = generate_new_configuration(new_replicas)
                # init_hist
                for replica in new_config :
                        # Send the quorum running state achieved above in the init hist message to new replicas
                        replica.init_hist(quorum_running_state, history)
        # Receive handler for wedged response
        def receive_wedged(message) :
                # Form the maximal history set
                for order_statement in message :
                        if order_statement.slot in history :
                                if order_statement.operation != history[slot] : # We had another operation in this slot, this node is faulty so we ignore all of its history
                        else :
                                if order_statement not in history :
        # Handle message time out
        def message_timeout(message) :
                # Connection from/to olympus should be reliable, but if this case happened try to make the replica immutable
                # If message timed out to a node, try to make it immutable
                message_handler.send(receiver = message.receiver, message = make_immutable_message())

        # On reconfiguration message received
        def receive_reconfiguration_request(message) :
                # We assume the client/replica had a valid reason to request a reconfiguration
                if message.sender in configuration or message.sender is Client : # If node is in current configuration or is client

        # Sends current configuration
        def get_current_configuration(target) :
                message_handler.send(target, configuration)
        # Generates new configuration (initial setup for new nodes)
        def generate_new_configuration() :
                # Allocate new nodes & their keys
                # Select replicas from pending list and remove them from pending list
                new_replicas = pending_replicas[0:100]
                for replica in new_replicas :
                        message_handler.send(receiver = replica, message = set_keys_message(public_key, private_key))
                return new_config

        # Initialize history of new nodes and their running state
        def init_hist(configuration) :
                # Update nodes history and give them a runnning state
                for replica in configuration :
                        message_handler.send(receiver = replica, message = init_hist_message(history, running_state))

        def select_maximal_history(hist_list) :
                # Select maximal history list
                maximal_history = longest(item in hist_list) # Longest history in the list is our maximal history set
                return maximal_history

        # On checkpoint message received, update running state and history if newer than current saved state
        def receive_checkpoint_message(message) :
                if message.slot > history[-1].slot : # If last slot in checkpoint is greater than last slot in history, checkpoint contains newer state
                        history.merge(message.history) # Add new items to history
                        running_state = history.running_state
View raw paste Reply