FARGOS Logo

Distributed StarShip

User's Guide

Powered By FARGOS/VISTA

Distributed StarShip User's Guide

FARGOS Development, LLC

http://www.fargos.net

mailto:support@fargos.net

Copyright © 2002 - 2020 FARGOS Development, LLC

Notice Of Rights

All rights reserved. This document may be rendered into whatever form is useful for the user, including electronic transmission or printing, so long as the content is not altered.

Trademarks

FARGOS/VISTA™, FARGOS/SolidState™ and FARGOS/SolidConnection™ are trademarks of FARGOS Development, LLC.

Abbreviations

FARGOS Development, LLC is a Limited Liability Company registered with the State of New York. It is required to identify itself as such in its name, hence the “, LLC” suffix. For purposes of readability in this document, the “, LLC” suffix is sometimes dropped. The phrase “FARGOS Development” always denotes “FARGOS Development, LLC” and is not intended to suggest any alternate form of organization.

Notice of Liability

Information in this document is distributed on an “As Is” basis, without warranty. While every precaution has been taken in the preparation of this document, FARGOS Development, LLC shall not have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the instructions contained within this document or by the computer software or hardware products described in it.

Distributed StarShip

Introduction

Distributed StarShip is a sample FARGOS/VISTA application that implements a space warfare simulator. The capital "S" in Ship is an affectation inherited from the original game's logo; "StarShip" had a more balanced appearance on the terminal than "Starship". The game is intended to demonstrate the power and flexibility of the FARGOS/VISTA Object Management Environment while being entertaining at the same time. Distributed StarShip can be played simultaneously by zero, one, or more human players. If the simulation is left unattended, it is not uncommon for it to end up pushing entire fleets of starships from one side of the galaxy to the other responding to distress messages. To keep things from getting out of hand, there is an explicit upper bound on the number of starships enforced in the game. While the entire game can be processed by a single host, Distributed StarShip is designed to be able to dynamically split the computational workload among an arbitrary pool of heterogeneous hosts, whose membership can grow and shrink at will. In certain configurations, it can provide fault-tolerant operation.

History

The original version of StarShip was written in 1987 by Bryan Beecher and Geoff Carpenter while they were at the University of Michigan. At the time, there was a perceived need for a game that was more realistic than the then-current genre in which a single human-controlled ship took on fleets of weak and unintelligent ships. StarShip addressed these issues by providing a simulator that supported multiple users and a rigid enforcement of game rules to ensure that human-controlled ships had no inherent advantages over those controlled by the computer. To further enhance the realism, ships were assigned missions, such as deliver supplies to a planet or rendezvous with a ship. Completion of a mission awarded points to a ship, which could be cashed in for upgraded capabilities. In this fashion, a ship’s strength increased much like hit points in a conventional role-playing game. A persistent copy of the user’s ship data was maintained, thus as long as a ship survived its battles, it could be used in subsequent games.

In 1994, Distributed StarShip was written as a demonstration of IBM Research’s DRAGONS technology suite. While useful in a standalone environment, the most dramatic demonstrations were possible on a trade show floor. The original StarShip C source code was used as a template for a new, dynamically distributed application that was written in Object-Oriented G (OOG). Distributed StarShip was a completely new game based on many, but not all, of the concepts found in the original StarShip—some details were dropped and new features such as a real-time graphical user interface and the ability to split the simulation across multiple hosts were added. A decade later, it was converted from OOG to Object Implementation Language 2 (OIL2) to run as a FARGOS/VISTA -based application that utilizes modern web browsers and either the then-new-in-2001 Scalable Vector Graphics XML-based application or the now obsoleted Macromedia’s Shockwave Flash as the graphic user interface. There is some loss of functionality due to the use of client/server-oriented web browsers vs. the peer-to-peer, event-driven architecture of a DRAGONS Display Manager, but the result is quite close.

Multiplayer Synchronization

Any multiplayer game faces a significant issue related to the synchronization of the activities of the players. Many games (e.g., checkers, chess, Mille Bornes, Chutes & Ladders) have explicit rules that enforce synchronization. For example, arguably the most common rule is that only one player at a time can issue commands (e.g., make a move)—such games are classified as turn-based.

StarShip was intended to operate continuously in real-time with both humans and the computer operating starships. It should be obvious that it is impossible to force all human players to enter their commands at the exact same moment in time. Likewise, computers have long been capable of performing work faster than humans, so a real-time game that accepted player input as fast as it could be provided would give a computer-controlled player a significant advantage. The StarShip simulator addressed the synchronization issue by implementing the game as an on-going series of state transitions. Inputs would be collected from both human players and the decisions that were made on behalf of the computer-controlled starships. The collected inputs would be applied to the various objects being processed by the simulation (e.g., starships, starbases, and planets) to yield a new state for the simulation. The issue of the disparity of computational speed between human and computer was handled by imposing a delay of several seconds between each state transition: this created a window of opportunity for human players to enter commands. The disparity of processing capabilities between different humans was addressed by imposing an upper bound on the number of inputs that would be permitted by any player between state transitions (for example, a player might be limited to a maximum of three commands). These concepts were carried over into the implementation of Distributed StarShip:

Installing the Game

An on-going Distributed StarShip game is maintained on publicly-accessible www.fargos.net servers, so the quickest way to play is to just access the www.fargos.net/starship.html site. It is, however, a public server and individuals may wish to setup their own private games. The FARGOS/VISTA Software Development Kit includes the OIL2 Architecture Neutral Format object code files that implement all of the StarShip-specific application classes and some FARGOS/VISTA Object Management Environment rc files. A minimum of one server must be deployed for each Distributed StarShip game, which is referred to as the primary instance. Additional servers may participate in the simulation and they are referred to as secondary instances. The discussion of exploiting multiple hosts is deferred until later (see the section " Using Multiple Servers"). Readers, who have no desire to operate their own games or contribute a secondary processor to the public game during their participation, can skip ahead to the section titled " Joining a Distributed StarShip Game.

The graphical user interface is provided via a World Wide Web browser, so an HTTPdaemon and affiliated objects must be configured. The FARGOS/VISTA HTTP Server Programmer’s Guide covers this topic in full in and definitively, but a prototype configuration is illustrated below in Figure 1:

PeerRegistry
AnnounceServices
HTTPcommonLogFormat /tmp/http.log www.domain.com
HTTPdaemon http.profile tcp:0.0.0.0:4321
HTTPpurgeCache 30 www.domain.com
Figure 1

Note: administrators may find that the creation of an AnnounceServices object is not performed in the rc file of many existing HTTPdaemons. An AnnounceServices object is required to enable the distribution of the simulation across multiple hosts. If no use of this capability will be made, then the AnnounceServices object can be omitted; however, since AnnounceServices consumes no CPU cycles unless inter-FARGOS/VISTA Object Management Environment connections are established, there is little incentive to not enable this service.

Security Note: the presence of an AnnounceServices object does not enable incoming FARGOS/VISTA peer connections, so the presence of this object does not introduce a security concern. The class that is of concern is AcceptPeerConnections. The rc file shown below in Figure 2 illustrates the objects that must be created to configure the primary server for a Distributed StarShip game. The various LoadOIL2File objects load the OIL2 Architecture Neutral Format (OIL2 ANF) object code files. As an alternative, an AutomaticClassLoader object can be used, which will automatically load any needed classes on demand. Once the OIL2 ANF files are loaded, the initial objects needed to setup the game may be created. The StarshipHTTPsetup object takes one mandatory argument, which is the logical name of the URLdirectory corresponding to the HTTP server to which the game’s graphic user interface providers should attach. In both Figure 1 and Figure 2, this has been denoted as www.domain.com. The appropriate name must be substituted when creating a local rc file. It can also be provided an optional Boolean flag which indicates whether or not Shockwave Flash should be used as a rendering engine rather than Scalable Vector Graphics (SVG). The last object created in Figure 2 is StarshipPrimary. For a given Distributed StarShip game, there is only one primary server, which is the server upon which the StarshipPrimary object was created. There can be an arbitrary number of additional servers participating in simulation, each of which is viewed as a secondary server. The secondary servers are configured identically to the primary server with one exception: rather than create a StarshipPrimary object, a StarshipSecondary object is created instead.

LoadOIL2File "file:clStarShipPrimary.o2o"
LoadOIL2File "file:clStarShipShipNames.o2o"
LoadOIL2File "file:clStarShipMissions.o2o"
LoadOIL2File "file:clStarShipHTTP.o2o"
LoadOIL2File "file:clStarShipHTTPsvg.o2o"
# Setup HTTP services
StarshipHTTPsetup www.domain.com
# create StarshipPrimary only on main machine
StarshipPrimary
# StarshipSecondary is automatically created by StarshipPrimary
Figure 2

There are three additional template files that must be deployed:

Table 1
File Notes
starshipLogin.html A server-side-include-processed (see HTTP_SSIprocessor) template file that must be installed in a file system directory that is exported as part of the logical root of the HTML page tree.
starshipGUI.html A template for dynamically generated pages that display each starship’s status.
starshipGUIswf.html An equivalent template used when Shockwave Flash is the rendering engine rather than SVG. Note: support for Shockwave Flash was withdrawn in 2020.
animAlert.svg A template for a Scalable Vector Graphics file that implements the animated alert status graphic. This file is read by the StarshipHTTPsetup object.
anim[Red|Green|Yellow]Alert.swf Shockwave Flash animations for the red/green/yellow alert status graphic. Note: support for Shockwave Flash was withdrawn in 2020.

Playing Distributed StarShip

Joining a Distributed StarShip Game

The user interface for the FARGOS/VISTA-based version of Distributed StarShip game is provided through a World Wide Web browser. A player's web browser must support the rendering engine chosen by the administrator, which is either Scalable Vector Graphics or Macromedia’s Shockwave Flash format. Note: support for Shockwave Flash was withdrawn in 2020.

To join a game, a user must first browse the starshipLogin.html page provided by either the primary server or any one of the secondary hosts that are providing the HTTP‑based user interface services. If only one server is hosting the game, the choice of web host is trivial. However, in the more interesting case in which the computational workload of the simulation is shared among multiple servers, a user should attempt to connect to the server that is closest to his machine. The optimal case is when the closest StarshipSecondary object is actually resident on the user's own computer since this means she has contributed the CPU resources of her machine to assist in the processing of the game. The use of multiple servers is discussed later in the section entitled "Using Multiple Servers".

Create A New Starship

Initial StarShip Web Page
Figure 3
As illustrated in the image of Figure 3, the starshipLogin.html page provides three options:

Players will normally utilize the first option, Create a New Starship, to create a new starship of their very own. A user may provide a desired name for the starship or let the game choose an appropriate one automatically. If a player provides a name, it should not have spaces. A player may also choose the side to join by selecting the desired race.

Visitors can monitor the status of both player ships and computer-controlled craft by utilizing the second option, Scan a Starship. The list of known starships is automatically generated using a server-side-include directive; if the data is obsolete, a simple refresh of the page will yield a current list.

If a player has already created a starship, but left the game and wishes to resume playing, the third option, Take Command of an Existing Starship, is available. The game will not permit a user to take command of a starship that already has a currently active captain.

Regardless of the option taken, a successful request will yield a display similar to the display of Figure 4 below. The fundamental difference between a read-only view and a controlling display is the presence of additional form fields, which permit the alteration of various parameters, such as a ship's destination and speed. The layout of the displays and the operation of the controls are discussed in the next section.

View Screen Image
Figure 4

Explanation of the Display

The bridge displays provide information about:

A sample display appears above in Figure 4 and below in Figure 5. As enhancements may have been made to the game since the point in time when this documentation was generated, the actual appearance may be slightly different with respect to some cosmetic details.

Alert Condition

The current alert condition (green, yellow or red) is displayed using an active graphic in the upper left-hand corner. In Figure 4, the starship is under attack, so its alert condition is set to red.

Shield Stengths

In the upper left hand corner of the display, immediately below the Alert Condition graphic, is the current shield status. Shields can be raised or lowered by pressing the Raise Shields or Lower Shields button, respectively. The icon of the ship is surrounded by an image indicating shield strength: the thicker the line, the greater the shield strength. Shield strength is also indicated by color: green, yellow and red indicate decreasing shield strengths.

Strategy note: the shield facing an enemy will take the brunt of an attack. Rotating the ship to present a stronger shield will provide more protection.

Status Window

Miscellaneous statistics such as power usages, a list of attacking ships, etc. will appear in the status window immediately below the Shield Status display. Certain parameters will be colored yellow or red to warn of impending problems.

Short Range Scan

The short-range scan is located in the upper center of the screen and takes up approximately 50% of the available screen real estate. The short-range scan shows ships, planets, and starbases in the immediate area. The long-range scan is used to view the location of all objects. Friendly ships will be colored in green, potential enemies are in yellow and starships actively attacking your ship will be in red. Borders between quadrants will be displayed as dashed gray lines.

All of the displayed objects are selectable by the mouse. If any displayed object is clicked upon, it will be set as the current target. Information about the selected target will be made available in the Target Display. The current target is used by all of the Weapons Controls to lock weapons and it serves as a default destination for making a course change request using the Navigation Controls.

Target Display

The target display is immediately below the Short-Range Scan. Information pertaining to the target’s distance from your ship, speed and heading will be displayed. The current target is used by all of the Weapons Controls to lock weapons and it serves as a default destination for making a course change request using the Navigation Controls.

Distress Button

The distress button is located below the Target Display, which is found just below the Short-Range Scan. If a starship is under attack, a player can press the button to send a distress message and friendly nearby ships may come to assist the embattled starship.

Navigation Controls

The navigation controls are on the upper-right hand side of the display. The ship’s current course and speed are displayed in yellow at the top and the ship's desired course or destination is displayed at the bottom in green. A compass rose is displayed in the middle. The current course is drawn as a dashed yellow line and the desired course is drawn as a solid green line. Controls to set the ship’s course, speed and destination are made available below the information display. Course and destination are mutually exclusive. If a destination is selected, the autopilot will compute the required course automatically, even if the destination object moves. Destinations are specified as the short name of the object (e.g., Vulcan< vs. Federation Planet Vulcan). The field will automatically be filled in with the name of the last target selected from either the Short-Range Scan or Long-Range Scan dsplays.

Strategy Notes: It takes a while for a starship to speed up or slow down. The faster a starship goes, the slower its rate of turn, thus one must slow down to make sharp turns. Distance traveled is a quadratic function based on speed.

Long Range Scan

The long-range scan shows the galaxy of objects and their relative positions. It is displayed below the Navigation Controls on the right hand side of the screen. It provides functionality very similar to that of the Short-Range Scan, but it shows a much larger view. Friendly objects are in green, enemy objects are in red, and the starship associated with the display will be in white. Users can also select targets by clicking on icons in the long-range scan.

Weapons Controls And Mission
Figure 5

Weapons Controls

The weapons controls span the display from left to right just above the Messages Window and the information about the Current Mission. These controls indicate the operational status of each weapon and they permit the weapon to be locked and fired. A weapon can be fired no more than once per turn; once fired, the corresponding fire button will be disabled until the weapon recycles. A weapon’s target lock is taken from the target selection window. A weapon will remain locked on a target until the target is destroyed or a new target lock is requested. It is permitted to have each weapon locked on a different target.

Current Mission

The current mission is displayed in the bottom right-hand side of the screen below the Weapons Controls. If no messages are available, the mission display may extend across the entire bottom of the screen.

Messages Window

Status messages will be displayed in the very bottom left hand side of the screen. Distress messages from other ships, messages from command, reports on an attack, warnings about having passed into enemy space, etc. will be appear here.

Update Interval

A starship's status display is normally automatically updated every 30 seconds; however, this can be set to a user-specified rate by entering the desired rate in seconds and pressing the Change Automatic Update Interval button, which is found at the very bottom of the page.

Using Multiple Servers

Implementation of the Original Starship

The original 1987 version of StarShip was implemented using two separate applications (called starsim and startty) that executed on computers running Unix System III or a subsequent variant (e.g., 4.3BSD, SunOS, Unicos, etc.). The single starsim main process implemented the simulation. A distinct startty user interface process was started on each player’s terminal (which were typically attached via RS‑232C cables). Each startty task accepted input typed by a player and displayed any requested information. Communication between the starsim simulation process and the various startty player interface processes took place over named pipes or sockets. This organization is graphically illustrated below in Figure 6.

Host and TTYs
Figure 6

While the communications links illustrated in Figure 6 were usually physical RS‑232C cables associated with dumb VT‑100 terminals, the terminals could be logically realized as pseudo-ttys and displayed across a network using the xterm application of X10 (or the X11 Window System of today). Regardless of how a player’s terminal was realized, all of the processes associated with the original StarShip game had to run on the same physical host.

Distribution of the Simulation

As noted above, the original version of StarShip was very host-centric. Although the user interface component was broken out as a separate process from the very start, the use of named pipes created a requirement to have all processes reside on the same host. The most natural next step in distributing the workload among multiple machines was to remove the individual user interface tasks from the simulation server and place them on separate machines. This was easily achieved by altering the code to use the socket API introduced in BSD Unix, thus yielding the capability to use TCP connections (or the equivalent). Distribution of the user interface tasks could help slightly with the scalability of the simulation; however, the original dumb TTY interface provided by the startty application was neither CPU nor resource intensive, thus the quantity of work that could be offloaded was not significant.

In 1994, many of the core StarShip concepts were used in the implementation of a completely distributed, load-balanced, fault-tolerant simulator with event-driven graphic user interfaces. The current version of Distributed StarShip is quite similar to the 1994 implementation, with the significant exception that it uses modern web browsers to provide a user interface rather than a DRAGONS Display Manager. While the use of a web browser to implement a real-time display was less than optimal, it is adequate for the purposes of the game.

Since the simulator essentially performs a series of computations against each starship, starbase and planet, one obvious approach to exploit multiple physical machines would be to use a job distribution facility, such as the class JobController.

Another obvious distribution point is the web browser that displays each player’s user interface: since a web browser does not have to run on the same host as a web server, it is clear that the graphics processing needed to render a page can be offloaded to the user’s machine. The next obvious item of processing that could be offloaded is the creation of the dynamically generated HTML pages and imagery for each user’s display; however, in order to generate such dynamic content, the responsible application code needs access to all of the state information maintained by the simulator (such as a starship's speed and course, deflector shield status, etc). The short- and long-range scan displays are particularly expensive since they make a request of every single object processed by the simulator. While the transparently distributed nature of the FARGOS/VISTA Object Management Environment would permit the processing to be handled by another host, the overhead of sending messages between physical machines would overwhelm the benefit gained by offloading computations onto other machines. Consequently, a traditional approach that uses a job scheduling application, such as JobController, would not be an effective means to separate the per-user graphic user interface processing from the main simulation.

Adding a Secondary Server

Distributed StarShip handles both problems by exploiting some of the more novel capabilities of the underlying FARGOS/VISTA Object Management Environment. When a new secondary server registers itself with the primary Distributed StarShip server, a copy of each of the simulation objects is transferred to the newly-attached secondary. This is achieved by sending each object an encodeObject request. The encoded instance is then transferred into the secondary system by sending the ObjectCreator object on the secondary host an importObject request. As a result, all the participating systems use identical object Ids to identify information about a particular starship, but utilize their local copy whenever an application needs to retrieve information. Whenever a new starship object is created during the course of the simulation, it is propagated to each of the currently registered secondary servers using the same mechanism.

This organization yields several benefits. The most obvious is that it eliminates the storm of inter-host messages that would be sent by a conventional design that had everything either maintained by the primary system or partitioned the objects across the processor pool of participating secondary servers. When the simulation needs to process a game play step, the primary instructs the secondary servers to perform the needed calculations on a given set of objects. Once a secondary server is informed about the objects it needs to process, it begins the necessary computations. All of the secondary servers should be performing work in parallel, although there will be some variances. Some of the factors that influence processing time are:

Whenever a secondary server updates a simulation object, it sends a copy of the changes that it made to the primary server. The primary will in turn distribute the updates to the other secondary servers. By sending only the changes, two obvious benefits are obtained:

  1. The amount of data sent is minimized.
  2. It is possible for parallel work to be performed on an object as long as distinct attributes are modified. For example, the course and speed of a starship can be computed at the same time firing of a weapon is processed.

Note: if the transmission of the updates could be sent using multicast, it would be more optimal if the secondary could forward the updates directly to all of its peers in a single operation. Unfortunately, in practice, this is not feasible, so standard inter-FARGOS/VISTA Object Management Environment connectivity is used, which allows secondaries to be operational in far-off locations. Sending the updates to the primary might appear to introduce additional overhead: a hop to the primary and then onto a secondary peer. It does not. The secondary originating the update would have to send the update message to the primary regardless. Since the responsibility for transmitting the updates to all of the remaining secondary peers resides at that point with the primary and the originating secondary sends no further messages, no additional overhead is incurred.

Loss of a Secondary Server

While the design of an application that can tolerate the loss of distributed computations in progress is not an oft-practiced art, it was a guiding principle behind the design of the Distributed StarShip classes. The 1994 version of Distributed StarShip was intended for use at technically oriented trade shows (such as InterOp) where all of the demonstration machines were networked together. Pre-configured copies of the secondary server were made available for downloading from an ftp server running in the demonstration booth. Individuals working for their respective companies could install the secondary software on a machine running in their booth. Once started, it would connect back to the primary machine and participate in sharing the workload. The graphical user interface component, implemented in 1994 using a DRAGONS Display Manager, was supposed to be run on a user’s local machine and be connected to their local secondary process, thus keeping all of the computations associated with their display off of the primary server. It was possible, however, that they connected directly to the primary server. The wide variety of connection options are still present in today's FARGOS/VISTA-based implementation.

One fact was known to an absolute certainty: no other company would have shipped their equipment to a trade show just to play Distributed StarShip. Instead, their staff and computers would have been sent in order to demonstrate their own products. Thus, any secondary system that was added to the processor pool could be expect to be yanked out of service at any moment when its owner decided to return it to the purpose for which the machine was brought.

Because of this operational constraint, Distributed StarShip was designed to tolerate both the unexpected appearance and loss of any (or all) of the secondary servers. Recall that all of the servers are provided with a complete duplicate of the current state of the simulation when they first register with the primary. This means that the primary server can accept new registrations at anytime: it does not matter how many hours the simulation has been underway; whenever a new secondary is registered, it is provided a snapshot of the current state of the simulation. At the beginning of every step in the simulation, the primary spreads the computational workload amongst the currently registered secondary servers. Since a processing step takes place every few seconds, a new secondary system can be utilized in short order.

When a secondary is lost during the idle period between simulation steps, it is merely deleted from the processing pool and the work to be done during the next step is spread amongst the remaining ( N – 1) secondaries. The only interesting case comes when a secondary server is lost during a simulation step. Since the secondary sends back updates to the primary as they are computed, the effect on the simulation ranges from none (all of the updates were computed and sent prior to failure of the secondary server) to a complete loss of every result expected from the secondary server for that processing step.

There are several approaches that can be taken to recover the lost transactions. One option is to delegate the work that was not completed to another secondary server before moving onto the next simulation step. A more pragmatic approach is to just ignore the failure and have the work processed on the next round. It is crucial to recall that the simulation is implemented as a series of state transitions. Although the secondary server was lost, the original state of the objects and the corresponding inputs that were to be applied against them were not lost—they are duplicated in all of the peer systems. Thus, the unexpected failure of a secondary system does not mean that a user's request to fire a photon torpedo is dropped; instead, it means that the launch of the torpedo was delayed by one turn. Although the design of Distributed StarShip permits the system to be resilient, the approach to recovery described above is not without effect: in the meantime, starships that were processed by the surviving secondary systems were able to move, thus they might now be closer or further away, their shields might have had time to strengthen, etc.

Applying the Concepts to other Applications

Unlike most business applications, computer games usually have significant real-time performance constraints. For example, a game that attempts to provide a frame rate of 30 frames a second will be unplayable if the frame rate drops to 4 frames a second. Even an occasional stutter will still be quite noticeable to the player. Due to its use of a web browser to support a graphical user interface, this version of Distributed StarShip does not attempt to provide high frame rates. It does, however, demonstrate several techniques for scalability, fault-tolerance and some unique capabilities of FARGOS/VISTA that are directly applicable to more utilitarian applications. If one substitutes the word “starship” for “independent transaction” then many of the implementation details remain useful. Rather than plot courses, fire weapons and send out distress messages, an independent transaction could be controlling an automated tool on a factory floor, monitoring the performance of a network or system, supporting a distributed whiteboard for an online meeting, simulating a chemical process, etc. The level of fault-tolerance supported by the current Distributed StarShip is useful for many environments, but the primary server remains the one susceptible potential point of failure. That failure point can be removed by introducing a fault-tolerant transaction monitor, such as FARGOS/SolidState (which provides Byzantine fault-tolerance). Such a resulting hybrid system yields the best of both worlds: near linear scalability with the survivability of a Byzantine fault-tolerant system.