Chris Pollett > Students >
Vishwanath

    ( Print View )

    [Bio]

    [Project Blog]

    [CS297Proposal]

    [DDBMS1 slides-PPT]

    [DDBMS2 slides-PPT]

    [Distributed Algorithms-PPT]

    [Del1]

    [Replication-PPT]

    [Del2]

    [XML Replication]

    [MANET Networks]

    [Del3]

    [CS297 Report-PDF]

    [CS298Proposal]

    [Del 1 CS298]

    [Del 2 CS298]

    [CS298 Presentation-PPT]

    [CS298 Report-PDF]

    [Project Code-ZIP]

                          

























Deliverable 2 : Implementation of Byzantine Algorithm on Distributed Databases

Description:

The program basically involves independent entities (voters) who cast exactly one vote in every round, and notify all their peers about the value of the vote casted. Faulty nodes [since they are malicious] provide different values to each of their peers. A vote is a simple binary value 0/1.

All voters wait until they have received a vote from everyone for this round before they begin the next round. "A" voter reaches a DECISION when 7/8 of his votes carry the same value. In the program, we also bias each individual non-faulty voters to cast with the majority (defined as 5/8) in each succeeding round. This allows our program to converge faster.

A BYZANTINE agreement is reached when 7/8 voters HAVE reached the SAME DECISION.

Introduction :

This program is an implementation of a distributed Byzantine agreement. The program can be configured to

  1. Run on multiple nodes [Default 2]
  2. Have multiple voters/node [Default 4]
  3. Have any number of faulty nodes [Default 2]
  4. Connect to any PostgreQL DB with right user/password
  5. Have any table name as the backing store for intermediate results.

Setup :

This program needs several components to be working properly before running the program. On ALL systems do the following:

(a) Install Fedora 4 core on Linux or greater. http://www.fedorafaq.org/

(b) Sun's Java.

FC4 core DOES ship with an open source implementation of Java. See http://fedoraproject.org/wiki/JavaFAQ for information about this. Unfortunately, on this implementation the rmic compiler is broken, and any client when trying to lookup any RMI service gets a "java.rmi. NotBoundException". Naming.lookup seems to return the name of the RMI service correctly though. You need to install the latest Sun's JDK. A very useful set of instructions are here. "http://www.stanton-finley.net/fedora_core_4_installation_notes.html#Java" are here. In have installed JDK1.5.0_09

(c) Start apache

apachectl start

After doing (a), (b) and (c) any regular non-JDBC RMI program [examples from Sun] would work fine.

(d) Accessing PostgreSQL from inside JDBC is harder. First, you need to prepare PostgreSQL. As root do,

   $ service postgresql stop
   $ In /var/lib/pgsql/data/pg_hba.conf

   Comment out ALL the lines, and add the following at the end
   host    all     all     127.0.0.1       255.255.255.255         trust
   local   all     all     trust

   $ service postgresql start
   

(e) Create a Database and a user [with password] that JDBC programs can access.

   $ su - postgres
   $ createdb testdb
   $ createuser -U postgres -P testuser
      For password enter testuser, testuser
   $ exit
   $ service postgresql restart

Example:


Output observed for one of the instance of our program is as below:
----------------------------------------------------------------------
CLIENT: running the Byzantine Manager....
Created NEW VOTER
Created NEW VOTER
Created NEW VOTER
Created NEW VOTER
Created NEW VOTER
Created NEW VOTER
Created NEW VOTER
Created NEW VOTER
 VOTER: 0 ROUND: 0 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 1 ROUND: 0 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 2 ROUND: 0 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 3 ROUND: 0 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 4 ROUND: 0 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 6 ROUND: 0 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 7 ROUND: 0 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1

 VOTER: 0 ROUND: 0 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 1
 VOTER: 2 ROUND: 0 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 1
 VOTER: 3 ROUND: 0 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 1
 VOTER: 4 ROUND: 0 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 1
 VOTER: 5 ROUND: 0 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 0
 VOTER: 6 ROUND: 0 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 1
 VOTER: 7 ROUND: 0 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 1

 VOTER: 0 ROUND: 0 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 1
 VOTER: 1 ROUND: 0 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 1
 VOTER: 2 ROUND: 0 RxED: 0 FROM: 7 C_HEADS: 1 C_TAILS: 2
 VOTER: 3 ROUND: 0 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 1
 VOTER: 4 ROUND: 0 RxED: 0 FROM: 7 C_HEADS: 1 C_TAILS: 2
 VOTER: 5 ROUND: 0 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 0
 VOTER: 6 ROUND: 0 RxED: 0 FROM: 7 C_HEADS: 1 C_TAILS: 2

 VOTER: 0 ROUND: 0 RxED: 1 FROM: 2 C_HEADS: 3 C_TAILS: 1
 VOTER: 1 ROUND: 0 RxED: 1 FROM: 2 C_HEADS: 2 C_TAILS: 1
 VOTER: 3 ROUND: 0 RxED: 0 FROM: 2 C_HEADS: 2 C_TAILS: 2
 VOTER: 4 ROUND: 0 RxED: 0 FROM: 2 C_HEADS: 1 C_TAILS: 3
 VOTER: 5 ROUND: 0 RxED: 1 FROM: 2 C_HEADS: 3 C_TAILS: 0
 VOTER: 6 ROUND: 0 RxED: 1 FROM: 2 C_HEADS: 2 C_TAILS: 2
 VOTER: 7 ROUND: 0 RxED: 0 FROM: 2 C_HEADS: 1 C_TAILS: 2

 VOTER: 0 ROUND: 0 RxED: 1 FROM: 3 C_HEADS: 4 C_TAILS: 1
 VOTER: 1 ROUND: 0 RxED: 1 FROM: 3 C_HEADS: 3 C_TAILS: 1
 VOTER: 2 ROUND: 0 RxED: 1 FROM: 3 C_HEADS: 2 C_TAILS: 2
 VOTER: 4 ROUND: 0 RxED: 1 FROM: 3 C_HEADS: 2 C_TAILS: 3
 VOTER: 5 ROUND: 0 RxED: 1 FROM: 3 C_HEADS: 4 C_TAILS: 0
 VOTER: 6 ROUND: 0 RxED: 1 FROM: 3 C_HEADS: 3 C_TAILS: 2
 VOTER: 7 ROUND: 0 RxED: 1 FROM: 3 C_HEADS: 2 C_TAILS: 2

 VOTER: 1 ROUND: 0 RxED: 0 FROM: 0 C_HEADS: 3 C_TAILS: 2
 VOTER: 2 ROUND: 0 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 3
 VOTER: 3 ROUND: 0 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 3
 VOTER: 4 ROUND: 0 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 4
 VOTER: 5 ROUND: 0 RxED: 0 FROM: 0 C_HEADS: 4 C_TAILS: 1
 VOTER: 6 ROUND: 0 RxED: 0 FROM: 0 C_HEADS: 3 C_TAILS: 3
 VOTER: 7 ROUND: 0 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 3

 VOTER: 0 ROUND: 0 RxED: 1 FROM: 6 C_HEADS: 5 C_TAILS: 1
 VOTER: 1 ROUND: 0 RxED: 1 FROM: 6 C_HEADS: 4 C_TAILS: 2
 VOTER: 2 ROUND: 0 RxED: 1 FROM: 6 C_HEADS: 3 C_TAILS: 3
 VOTER: 3 ROUND: 0 RxED: 1 FROM: 6 C_HEADS: 3 C_TAILS: 3
 VOTER: 4 ROUND: 0 RxED: 1 FROM: 6 C_HEADS: 3 C_TAILS: 4
 VOTER: 5 ROUND: 0 RxED: 1 FROM: 6 C_HEADS: 5 C_TAILS: 1
 VOTER: 7 ROUND: 0 RxED: 1 FROM: 6 C_HEADS: 3 C_TAILS: 3

 VOTER: 0 ROUND: 0 RxED: 0 FROM: 4 C_HEADS: 5 C_TAILS: 2
 VOTER: 1 ROUND: 0 RxED: 0 FROM: 4 C_HEADS: 4 C_TAILS: 3
 VOTER: 2 ROUND: 0 RxED: 0 FROM: 4 C_HEADS: 3 C_TAILS: 4
 VOTER: 3 ROUND: 0 RxED: 0 FROM: 4 C_HEADS: 3 C_TAILS: 4
 VOTER: 5 ROUND: 0 RxED: 0 FROM: 4 C_HEADS: 5 C_TAILS: 2
 VOTER: 6 ROUND: 0 RxED: 0 FROM: 4 C_HEADS: 3 C_TAILS: 4
 VOTER: 7 ROUND: 0 RxED: 0 FROM: 4 C_HEADS: 3 C_TAILS: 4

 VOTER: 0 ROUND: 1 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 0
 VOTER: 2 ROUND: 1 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 0
 VOTER: 3 ROUND: 1 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 0
 VOTER: 4 ROUND: 1 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 0
 VOTER: 5 ROUND: 1 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 0
 VOTER: 6 ROUND: 1 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 0
 VOTER: 7 ROUND: 1 RxED: 1 FROM: 1 C_HEADS: 1 C_TAILS: 0

VOTER: 1 :ROUND: 0 :VOTES: 7 :HEADS: 5 :TAILS: 3

 VOTER: 0 ROUND: 1 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 0
 VOTER: 1 ROUND: 1 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 0
 VOTER: 2 ROUND: 1 RxED: 0 FROM: 7 C_HEADS: 1 C_TAILS: 1
 VOTER: 3 ROUND: 1 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 0
 VOTER: 4 ROUND: 1 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 0
 VOTER: 5 ROUND: 1 RxED: 0 FROM: 7 C_HEADS: 1 C_TAILS: 1
 VOTER: 6 ROUND: 1 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 0
VOTER: 7 :ROUND: 0 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 0 ROUND: 1 RxED: 0 FROM: 5 C_HEADS: 2 C_TAILS: 1
 VOTER: 1 ROUND: 1 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 1
 VOTER: 2 ROUND: 1 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 2
 VOTER: 3 ROUND: 1 RxED: 0 FROM: 5 C_HEADS: 2 C_TAILS: 1
 VOTER: 4 ROUND: 1 RxED: 0 FROM: 5 C_HEADS: 2 C_TAILS: 1
 VOTER: 6 ROUND: 1 RxED: 0 FROM: 5 C_HEADS: 2 C_TAILS: 1
 VOTER: 7 ROUND: 1 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 1
VOTER: 5 :ROUND: 0 :VOTES: 7 :HEADS: 5 :TAILS: 3
 VOTER: 0 ROUND: 1 RxED: 0 FROM: 2 C_HEADS: 2 C_TAILS: 2
 VOTER: 1 ROUND: 1 RxED: 1 FROM: 2 C_HEADS: 2 C_TAILS: 1
 VOTER: 3 ROUND: 1 RxED: 1 FROM: 2 C_HEADS: 3 C_TAILS: 1
 VOTER: 4 ROUND: 1 RxED: 0 FROM: 2 C_HEADS: 2 C_TAILS: 2
 VOTER: 5 ROUND: 1 RxED: 0 FROM: 2 C_HEADS: 1 C_TAILS: 2
 VOTER: 6 ROUND: 1 RxED: 0 FROM: 2 C_HEADS: 2 C_TAILS: 2
 VOTER: 7 ROUND: 1 RxED: 0 FROM: 2 C_HEADS: 1 C_TAILS: 2
VOTER: 2 :ROUND: 0 :VOTES: 7 :HEADS: 3 :TAILS: 5
 VOTER: 0 ROUND: 1 RxED: 0 FROM: 4 C_HEADS: 2 C_TAILS: 3
 VOTER: 1 ROUND: 1 RxED: 0 FROM: 4 C_HEADS: 2 C_TAILS: 2
 VOTER: 2 ROUND: 1 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 3
 VOTER: 3 ROUND: 1 RxED: 0 FROM: 4 C_HEADS: 3 C_TAILS: 2
 VOTER: 5 ROUND: 1 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 3
 VOTER: 6 ROUND: 1 RxED: 0 FROM: 4 C_HEADS: 2 C_TAILS: 3
 VOTER: 7 ROUND: 1 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 3
VOTER: 4 :ROUND: 0 :VOTES: 7 :HEADS: 3 :TAILS: 5
 VOTER: 0 ROUND: 1 RxED: 1 FROM: 3 C_HEADS: 3 C_TAILS: 3
 VOTER: 1 ROUND: 1 RxED: 1 FROM: 3 C_HEADS: 3 C_TAILS: 2
 VOTER: 2 ROUND: 1 RxED: 1 FROM: 3 C_HEADS: 2 C_TAILS: 3
 VOTER: 4 ROUND: 1 RxED: 1 FROM: 3 C_HEADS: 3 C_TAILS: 2
 VOTER: 5 ROUND: 1 RxED: 1 FROM: 3 C_HEADS: 2 C_TAILS: 3
 VOTER: 6 ROUND: 1 RxED: 1 FROM: 3 C_HEADS: 3 C_TAILS: 3
 VOTER: 7 ROUND: 1 RxED: 1 FROM: 3 C_HEADS: 2 C_TAILS: 3
VOTER: 3 :ROUND: 0 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 1 ROUND: 1 RxED: 0 FROM: 0 C_HEADS: 3 C_TAILS: 3
 VOTER: 2 ROUND: 1 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 4
 VOTER: 3 ROUND: 1 RxED: 0 FROM: 0 C_HEADS: 3 C_TAILS: 3
 VOTER: 4 ROUND: 1 RxED: 0 FROM: 0 C_HEADS: 3 C_TAILS: 3
 VOTER: 5 ROUND: 1 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 4
 VOTER: 6 ROUND: 1 RxED: 0 FROM: 0 C_HEADS: 3 C_TAILS: 4
 VOTER: 7 ROUND: 1 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 4
VOTER: 0 :ROUND: 0 :VOTES: 7 :HEADS: 5 :TAILS: 3
 VOTER: 0 ROUND: 1 RxED: 1 FROM: 6 C_HEADS: 4 C_TAILS: 3
 VOTER: 1 ROUND: 1 RxED: 1 FROM: 6 C_HEADS: 4 C_TAILS: 3
 VOTER: 2 ROUND: 1 RxED: 1 FROM: 6 C_HEADS: 3 C_TAILS: 4
 VOTER: 3 ROUND: 1 RxED: 1 FROM: 6 C_HEADS: 4 C_TAILS: 3
 VOTER: 4 ROUND: 1 RxED: 1 FROM: 6 C_HEADS: 4 C_TAILS: 3
 VOTER: 5 ROUND: 1 RxED: 1 FROM: 6 C_HEADS: 3 C_TAILS: 4
 VOTER: 7 ROUND: 1 RxED: 1 FROM: 6 C_HEADS: 3 C_TAILS: 4
VOTER: 6 :ROUND: 0 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 0 ROUND: 2 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 1
 VOTER: 1 ROUND: 2 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 0
 VOTER: 3 ROUND: 2 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 1
 VOTER: 4 ROUND: 2 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 0
 VOTER: 5 ROUND: 2 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 1
 VOTER: 6 ROUND: 2 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 1
 VOTER: 7 ROUND: 2 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 0
VOTER: 2 :ROUND: 1 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 0 ROUND: 2 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 1 ROUND: 2 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 1
 VOTER: 2 ROUND: 2 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 3 ROUND: 2 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 4 ROUND: 2 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 1
 VOTER: 6 ROUND: 2 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 7 ROUND: 2 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 1
VOTER: 5 :ROUND: 1 :VOTES: 7 :HEADS: 3 :TAILS: 5
 VOTER: 0 ROUND: 2 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 3
 VOTER: 2 ROUND: 2 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
 VOTER: 3 ROUND: 2 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 3
 VOTER: 4 ROUND: 2 RxED: 0 FROM: 1 C_HEADS: 1 C_TAILS: 2
 VOTER: 5 ROUND: 2 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
 VOTER: 6 ROUND: 2 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 3
 VOTER: 7 ROUND: 2 RxED: 0 FROM: 1 C_HEADS: 1 C_TAILS: 2
VOTER: 1 :ROUND: 1 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 0 ROUND: 2 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 3
 VOTER: 1 ROUND: 2 RxED: 0 FROM: 7 C_HEADS: 1 C_TAILS: 2
 VOTER: 2 ROUND: 2 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 2
 VOTER: 3 ROUND: 2 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 4
 VOTER: 4 ROUND: 2 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 2
 VOTER: 5 ROUND: 2 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 2
 VOTER: 6 ROUND: 2 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 3
VOTER: 7 :ROUND: 1 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 0 ROUND: 2 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 4
 VOTER: 1 ROUND: 2 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
 VOTER: 2 ROUND: 2 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
 VOTER: 4 ROUND: 2 RxED: 0 FROM: 3 C_HEADS: 2 C_TAILS: 3
 VOTER: 5 ROUND: 2 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
 VOTER: 6 ROUND: 2 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 4
 VOTER: 7 ROUND: 2 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
VOTER: 3 :ROUND: 1 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 1 ROUND: 2 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 4
 VOTER: 2 ROUND: 2 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 4
 VOTER: 3 ROUND: 2 RxED: 0 FROM: 0 C_HEADS: 0 C_TAILS: 5
 VOTER: 4 ROUND: 2 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 4
 VOTER: 5 ROUND: 2 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 4
 VOTER: 6 ROUND: 2 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 5
 VOTER: 7 ROUND: 2 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 4
VOTER: 0 :ROUND: 1 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 0 ROUND: 2 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
 VOTER: 1 ROUND: 2 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
 VOTER: 2 ROUND: 2 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
 VOTER: 3 ROUND: 2 RxED: 0 FROM: 6 C_HEADS: 0 C_TAILS: 6
 VOTER: 4 ROUND: 2 RxED: 0 FROM: 6 C_HEADS: 2 C_TAILS: 5
 VOTER: 5 ROUND: 2 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
 VOTER: 7 ROUND: 2 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
VOTER: 6 :ROUND: 1 :VOTES: 7 :HEADS: 3 :TAILS: 5
 VOTER: 0 ROUND: 2 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 1 ROUND: 2 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 2 ROUND: 2 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 3 ROUND: 2 RxED: 0 FROM: 4 C_HEADS: 0 C_TAILS: 7
 VOTER: 5 ROUND: 2 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 6 ROUND: 2 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 7 ROUND: 2 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
VOTER: 4 :ROUND: 1 :VOTES: 7 :HEADS: 4 :TAILS: 4
 VOTER: 0 ROUND: 3 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 1 ROUND: 3 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 2 ROUND: 3 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 3 ROUND: 3 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 4 ROUND: 3 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 6 ROUND: 3 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 7 ROUND: 3 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
VOTER: 5 :ROUND: 2 :VOTES: 7 :HEADS: 1 :TAILS: 7
ROUND: 3 VOTER: 5 DECISION: 0
 VOTER: 0 ROUND: 3 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
 VOTER: 2 ROUND: 3 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
 VOTER: 3 ROUND: 3 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
 VOTER: 4 ROUND: 3 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
 VOTER: 5 ROUND: 3 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 1
 VOTER: 6 ROUND: 3 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
 VOTER: 7 ROUND: 3 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
VOTER: 1 :ROUND: 2 :VOTES: 7 :HEADS: 1 :TAILS: 7
ROUND: 3 VOTER: 1 DECISION: 0
 VOTER: 0 ROUND: 3 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 2
 VOTER: 1 ROUND: 3 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 1
 VOTER: 3 ROUND: 3 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 3
 VOTER: 4 ROUND: 3 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 2
 VOTER: 5 ROUND: 3 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 1
 VOTER: 6 ROUND: 3 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 3
 VOTER: 7 ROUND: 3 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 2
VOTER: 2 :ROUND: 2 :VOTES: 7 :HEADS: 2 :TAILS: 6
 VOTER: 0 ROUND: 3 RxED: 0 FROM: 7 C_HEADS: 1 C_TAILS: 3
 VOTER: 1 ROUND: 3 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 1
 VOTER: 2 ROUND: 3 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 3
 VOTER: 3 ROUND: 3 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 4
 VOTER: 4 ROUND: 3 RxED: 1 FROM: 7 C_HEADS: 2 C_TAILS: 2
 VOTER: 5 ROUND: 3 RxED: 0 FROM: 7 C_HEADS: 1 C_TAILS: 2
 VOTER: 6 ROUND: 3 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 4
VOTER: 7 :ROUND: 2 :VOTES: 7 :HEADS: 1 :TAILS: 7
ROUND: 3 VOTER: 7 DECISION: 0
 VOTER: 0 ROUND: 3 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 4
 VOTER: 1 ROUND: 3 RxED: 0 FROM: 3 C_HEADS: 2 C_TAILS: 2
 VOTER: 2 ROUND: 3 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 4
 VOTER: 4 ROUND: 3 RxED: 0 FROM: 3 C_HEADS: 2 C_TAILS: 3
 VOTER: 5 ROUND: 3 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
 VOTER: 6 ROUND: 3 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 5
 VOTER: 7 ROUND: 3 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
VOTER: 3 :ROUND: 2 :VOTES: 7 :HEADS: 0 :TAILS: 8
ROUND: 3 VOTER: 3 DECISION: 0
 VOTER: 1 ROUND: 3 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 3
 VOTER: 2 ROUND: 3 RxED: 0 FROM: 0 C_HEADS: 0 C_TAILS: 5
 VOTER: 3 ROUND: 3 RxED: 0 FROM: 0 C_HEADS: 0 C_TAILS: 5
 VOTER: 4 ROUND: 3 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 4
 VOTER: 5 ROUND: 3 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 4
 VOTER: 6 ROUND: 3 RxED: 0 FROM: 0 C_HEADS: 0 C_TAILS: 6
 VOTER: 7 ROUND: 3 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 4
VOTER: 0 :ROUND: 2 :VOTES: 7 :HEADS: 1 :TAILS: 7
ROUND: 3 VOTER: 0 DECISION: 0
 VOTER: 0 ROUND: 3 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
 VOTER: 1 ROUND: 3 RxED: 0 FROM: 6 C_HEADS: 2 C_TAILS: 4
 VOTER: 2 ROUND: 3 RxED: 0 FROM: 6 C_HEADS: 0 C_TAILS: 6
 VOTER: 3 ROUND: 3 RxED: 0 FROM: 6 C_HEADS: 0 C_TAILS: 6
 VOTER: 4 ROUND: 3 RxED: 0 FROM: 6 C_HEADS: 2 C_TAILS: 5
 VOTER: 5 ROUND: 3 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
 VOTER: 7 ROUND: 3 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
VOTER: 6 :ROUND: 2 :VOTES: 7 :HEADS: 1 :TAILS: 7
ROUND: 3 VOTER: 6 DECISION: 0
 VOTER: 0 ROUND: 3 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 1 ROUND: 3 RxED: 0 FROM: 4 C_HEADS: 2 C_TAILS: 5
 VOTER: 2 ROUND: 3 RxED: 0 FROM: 4 C_HEADS: 0 C_TAILS: 7
 VOTER: 3 ROUND: 3 RxED: 0 FROM: 4 C_HEADS: 0 C_TAILS: 7
 VOTER: 5 ROUND: 3 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 6 ROUND: 3 RxED: 0 FROM: 4 C_HEADS: 0 C_TAILS: 7
 VOTER: 7 ROUND: 3 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
VOTER: 4 :ROUND: 2 :VOTES: 7 :HEADS: 2 :TAILS: 6
 VOTER: 0 ROUND: 4 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 1
 VOTER: 1 ROUND: 4 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 1
 VOTER: 2 ROUND: 4 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 1
 VOTER: 4 ROUND: 4 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 1
 VOTER: 5 ROUND: 4 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 1
 VOTER: 6 ROUND: 4 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 1
 VOTER: 7 ROUND: 4 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 1
VOTER: 3 :ROUND: 3 :VOTES: 7 :HEADS: 0 :TAILS: 8
 VOTER: 0 ROUND: 4 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 1 ROUND: 4 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 2 ROUND: 4 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 3 ROUND: 4 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
 VOTER: 4 ROUND: 4 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 6 ROUND: 4 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 7 ROUND: 4 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
VOTER: 5 :ROUND: 3 :VOTES: 7 :HEADS: 1 :TAILS: 7
 VOTER: 0 ROUND: 4 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 3
 VOTER: 1 ROUND: 4 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 2
 VOTER: 2 ROUND: 4 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 2
 VOTER: 3 ROUND: 4 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 1
 VOTER: 4 ROUND: 4 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 3
 VOTER: 5 ROUND: 4 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 1
 VOTER: 6 ROUND: 4 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 3
VOTER: 7 :ROUND: 3 :VOTES: 7 :HEADS: 1 :TAILS: 7
 VOTER: 0 ROUND: 4 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 4
 VOTER: 2 ROUND: 4 RxED: 0 FROM: 1 C_HEADS: 1 C_TAILS: 3
 VOTER: 3 ROUND: 4 RxED: 0 FROM: 1 C_HEADS: 1 C_TAILS: 2
 VOTER: 4 ROUND: 4 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 4
 VOTER: 5 ROUND: 4 RxED: 0 FROM: 1 C_HEADS: 1 C_TAILS: 2
 VOTER: 6 ROUND: 4 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 4
 VOTER: 7 ROUND: 4 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 3
VOTER: 1 :ROUND: 3 :VOTES: 7 :HEADS: 2 :TAILS: 6
 VOTER: 0 ROUND: 4 RxED: 0 FROM: 6 C_HEADS: 0 C_TAILS: 5
 VOTER: 1 ROUND: 4 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 3
 VOTER: 2 ROUND: 4 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 4
 VOTER: 3 ROUND: 4 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 3
 VOTER: 4 ROUND: 4 RxED: 0 FROM: 6 C_HEADS: 0 C_TAILS: 5
 VOTER: 5 ROUND: 4 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 3
 VOTER: 7 ROUND: 4 RxED: 0 FROM: 6 C_HEADS: 0 C_TAILS: 4
VOTER: 6 :ROUND: 3 :VOTES: 7 :HEADS: 0 :TAILS: 8
 VOTER: 0 ROUND: 4 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 5
 VOTER: 1 ROUND: 4 RxED: 0 FROM: 2 C_HEADS: 1 C_TAILS: 4
 VOTER: 3 ROUND: 4 RxED: 1 FROM: 2 C_HEADS: 2 C_TAILS: 3
 VOTER: 4 ROUND: 4 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 5
 VOTER: 5 ROUND: 4 RxED: 1 FROM: 2 C_HEADS: 2 C_TAILS: 3
 VOTER: 6 ROUND: 4 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 5
 VOTER: 7 ROUND: 4 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 5
VOTER: 2 :ROUND: 3 :VOTES: 7 :HEADS: 0 :TAILS: 8
ROUND: 4 VOTER: 2 DECISION: 0
 VOTER: 1 ROUND: 4 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 5
 VOTER: 2 ROUND: 4 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 5
 VOTER: 3 ROUND: 4 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 4
 VOTER: 4 ROUND: 4 RxED: 0 FROM: 0 C_HEADS: 1 C_TAILS: 6
 VOTER: 5 ROUND: 4 RxED: 0 FROM: 0 C_HEADS: 2 C_TAILS: 4
 VOTER: 6 ROUND: 4 RxED: 0 FROM: 0 C_HEADS: 0 C_TAILS: 6
 VOTER: 7 ROUND: 4 RxED: 0 FROM: 0 C_HEADS: 0 C_TAILS: 6
VOTER: 0 :ROUND: 3 :VOTES: 7 :HEADS: 1 :TAILS: 7
Voter 0  Agreement Reached!! Agreement is 0
 VOTER: 0 ROUND: 4 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 1 ROUND: 4 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 2 ROUND: 4 RxED: 0 FROM: 4 C_HEADS: 1 C_TAILS: 6
 VOTER: 3 ROUND: 4 RxED: 0 FROM: 4 C_HEADS: 2 C_TAILS: 5
 VOTER: 5 ROUND: 4 RxED: 0 FROM: 4 C_HEADS: 2 C_TAILS: 5
 VOTER: 6 ROUND: 4 RxED: 0 FROM: 4 C_HEADS: 0 C_TAILS: 7
 VOTER: 7 ROUND: 4 RxED: 0 FROM: 4 C_HEADS: 0 C_TAILS: 7
VOTER: 4 :ROUND: 3 :VOTES: 7 :HEADS: 2 :TAILS: 6
Voter 4  Agreement Reached!! Agreement is 0
 VOTER: 0 ROUND: 5 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 1
 VOTER: 1 ROUND: 5 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 0
 VOTER: 2 ROUND: 5 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 0
 VOTER: 3 ROUND: 5 RxED: 1 FROM: 7 C_HEADS: 1 C_TAILS: 0
 VOTER: 4 ROUND: 5 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 1
 VOTER: 5 ROUND: 5 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 1
 VOTER: 6 ROUND: 5 RxED: 0 FROM: 7 C_HEADS: 0 C_TAILS: 1
VOTER: 7 :ROUND: 4 :VOTES: 7 :HEADS: 0 :TAILS: 8
Voter 7  Agreement Reached!! Agreement is 0
 VOTER: 0 ROUND: 5 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 1 ROUND: 5 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 1
 VOTER: 2 ROUND: 5 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 1
 VOTER: 3 ROUND: 5 RxED: 0 FROM: 5 C_HEADS: 1 C_TAILS: 1
 VOTER: 4 ROUND: 5 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 6 ROUND: 5 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 2
 VOTER: 7 ROUND: 5 RxED: 0 FROM: 5 C_HEADS: 0 C_TAILS: 1
VOTER: 5 :ROUND: 4 :VOTES: 7 :HEADS: 2 :TAILS: 6
Voter 5  Agreement Reached!! Agreement is 0
 VOTER: 0 ROUND: 5 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 3
 VOTER: 2 ROUND: 5 RxED: 0 FROM: 1 C_HEADS: 1 C_TAILS: 2
 VOTER: 3 ROUND: 5 RxED: 0 FROM: 1 C_HEADS: 1 C_TAILS: 2
 VOTER: 4 ROUND: 5 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 3
 VOTER: 5 ROUND: 5 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
 VOTER: 6 ROUND: 5 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 3
 VOTER: 7 ROUND: 5 RxED: 0 FROM: 1 C_HEADS: 0 C_TAILS: 2
VOTER: 1 :ROUND: 4 :VOTES: 7 :HEADS: 1 :TAILS: 7
Voter 1  Agreement Reached!! Agreement is 0
 VOTER: 0 ROUND: 5 RxED: 0 FROM: 2 C_HEADS: 0 C_TAILS: 4
 VOTER: 1 ROUND: 5 RxED: 1 FROM: 2 C_HEADS: 2 C_TAILS: 1
 VOTER: 3 ROUND: 5 RxED: 1 FROM: 2 C_HEADS: 2 C_TAILS: 2
 VOTER: 4 ROUND: 5 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 3
 VOTER: 5 ROUND: 5 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 2
 VOTER: 6 ROUND: 5 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 3
 VOTER: 7 ROUND: 5 RxED: 1 FROM: 2 C_HEADS: 1 C_TAILS: 2
VOTER: 2 :ROUND: 4 :VOTES: 7 :HEADS: 2 :TAILS: 6
Voter 2  Agreement Reached!! Agreement is 0
 VOTER: 0 ROUND: 5 RxED: 0 FROM: 3 C_HEADS: 0 C_TAILS: 5
 VOTER: 1 ROUND: 5 RxED: 0 FROM: 3 C_HEADS: 2 C_TAILS: 2
 VOTER: 2 ROUND: 5 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
 VOTER: 4 ROUND: 5 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 4
 VOTER: 5 ROUND: 5 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
 VOTER: 6 ROUND: 5 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 4
 VOTER: 7 ROUND: 5 RxED: 0 FROM: 3 C_HEADS: 1 C_TAILS: 3
VOTER: 3 :ROUND: 4 :VOTES: 7 :HEADS: 2 :TAILS: 6
Voter 3  Agreement Reached!! Agreement is 0
 VOTER: 0 ROUND: 5 RxED: 0 FROM: 6 C_HEADS: 0 C_TAILS: 6
 VOTER: 1 ROUND: 5 RxED: 0 FROM: 6 C_HEADS: 2 C_TAILS: 3
 VOTER: 2 ROUND: 5 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 4
 VOTER: 3 ROUND: 5 RxED: 0 FROM: 6 C_HEADS: 2 C_TAILS: 3
 VOTER: 4 ROUND: 5 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 5
 VOTER: 5 ROUND: 5 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 4
 VOTER: 7 ROUND: 5 RxED: 0 FROM: 6 C_HEADS: 1 C_TAILS: 4
VOTER: 6 :ROUND: 4 :VOTES: 7 :HEADS: 0 :TAILS: 8
Voter 6  Agreement Reached!! Agreement is 0
!!! Byzantine Agreeement Reached !!!

Reading the output:

In each round, each voter casts his vote. If 7/8 of his votes agree then he reaches a decision. Once a decision is reached the voter keeps participating in the voting process but this is more of a dummy process, ie once his decision is made he wont change it, he will just keep checking whether 7/8 voters have reached a decision. Once all the voters reach a decision, in the final round they all announce to each other that a Byzantine Agreement has been reached.

For our output this is brief explanation:

Round in which decision is reached by each voter

Voter 0  :  Round : 2   Decision : 0
Voter 1  :  Round : 2   Decision : 0
Voter 2  :  Round : 3   Decision : 0
Voter 3  :  Round : 2   Decision : 0
Voter 4  :
Voter 5  :  Round : 2   Decision : 0
Voter 6  :  Round : 2   Decision : 0
Voter 7  :  Round : 2   DEcision : 0

Since all the voters (or 7/8) have come on a decision by round 3, in round 4 everyone becomes aware of the same and a Byzantine Agreement is reached in the following round.


run_all.sh
------------

#!/bin/sh

# Run this script as root on both machines.
# You need to have all files under the same directory
# structure for both client and server.

MANAGER=192.168.0.107
CLIENT=192.168.0.102
PREFIX=192
C_USER=hlthantr
#NFS_EXPORT=/tmp/nfse
#NFS_IMPORT=/tmp/nfsi

# Derived do not touch
do_mgr=0

function stop_service {
   s_name=$1
   nlines=`ps -eaf | grep $s_name | wc -l`
   pid=`ps -eaf | grep $s_name | grep -v 'grep' | awk '{print $2}'`
   if [ "${nlines}" = "2" ]; then
      echo "STOPPING SERVICE $sname: PID: $pid"
      kill $pid
   elif [ "$pid" != "" ]; then
      kill $pid
   fi


}

function cleanup {

   echo "Cleaning up prior installation.....";
   # Create the HTML directory if didn't exist on the webserver
   if [ ! -d /var/www/html/proj2 ]; then
      mkdir /var/www/html/proj2
   fi
   rm -f /var/www/html/proj2/*.class

   # Check your identity
   ipaddr=`ifconfig | grep $PREFIX | cut -d':' -f2 | cut -d' ' -f1`

   if [ "$ipaddr" = "$CLIENT" ]; then
      peer_ip=192.168.0.107
      do_mgr=0
   else
      peer_ip=192.168.0.102
      do_mgr=1
   fi
   echo "....Done"
   echo "Killing daemon RMI services....."
   stop_service VoterServer
   stop_service rmiregistry
   stop_service Manager
   psql testdb testdb -c 'DROP TABLE tblByzantine'
   echo "....Done"

}
function compile {
   echo "Compiling project...."
   cd /home/$C_USER/proj2

   # First compile all the java classes
   javac *.java

   # Run rmic on all the implementation classes
   rmic VoterManagerImpl
   rmic VoterByzantineImpl

   # Copy all the files into the HTTP server
   cp /home/$C_USER/proj2/*.class /var/www/html/proj2
   echo "...Done"
}
if [ "$USER" != "root" ]; then
   echo "You must be root to execute this script";
   exit
fi

cleanup
compile
rmiregistry &
export CLASSPATH=`pwd`:/var/www/html/proj2:/usr/share/java/postgresql-jdbc3.jar:.

echo "Running VoterServer....";
java -Djava.rmi.server.codebase=http://${ipaddr}/proj2\
 -Djava.rmi.server.hostname=${ipaddr} \
 -Djava.security.policy=rmi.server.policy VoterServer &

sleep 2
echo "....Done";
if test ${do_mgr} = 0; then
   echo "CLIENT: running the Byzantine Manager...."
   sleep 2
   java -Djava.rmi.server.codebase=http://${ipaddr}/proj2\
   -Djava.security.policy=rmi.client.policy Manager
fi




Manager.java
--------------

/**
 * Manager.java: This class is the top level class that
 * instantiates the nodes, and tells them how many voters
 * they have
 */

import java.rmi.*;
import java.util.*;

public class Manager
{
   private static int nVOTERS = 8;
   private static int nREMOTE = 4;
   private static int nFAULTY = 2;
   private static int maxDELAY = 100;
   private static int faulty_nodes[] = {2, 7};

   /*
    * A database of the same name exists
    * on ALL machines participating in the
    * distributed Byzantine agreement
    */

   private static String dbName = "testdb";
   private static String dbUser = "testdb";
   private static String dbPassword = "testuser";

   public Manager() {

   }
   public static void main(String[] args)
   {
      if (System.getSecurityManager() == null) {
         System.setSecurityManager(new RMISecurityManager());
      }

      try {
         /*
          * Obtain the VoterManager Object reference from
          * all the remote/local nodes
          */

         VoterManager v1 = (VoterManager)Naming.lookup("rmi://192.168.0.102/voteMgr");
         VoterManager v2 = (VoterManager)Naming.lookup("rmi://192.168.0.107/voteMgr");


         /*
          * Create and add some number of voters
          */
         ArrayList vList = new ArrayList();
         Random rand = new Random();
         int delay = 0;

         Voter vtr = null;
         boolean isFaulty = false;
         int f_idx = 0;
         String tblName;
         for (int idx = 0; idx < nVOTERS; idx ++) {
            delay = rand.nextInt(maxDELAY) + 1;
            isFaulty = false;
            if ((f_idx < nFAULTY) &&
                 (idx == faulty_nodes[f_idx])) {
               isFaulty = true;
               f_idx ++;
            }

            if (idx < nREMOTE) {
               tblName = (idx == 0)?"tblByzantine":null;

               vtr = v1.createVoter(delay,
                          isFaulty,
                          dbName,
                          dbUser, dbPassword,
                          tblName);
            } else {
               tblName = (idx == nREMOTE)?"tblByzantine":null;
               vtr = v2.createVoter(delay, isFaulty, dbName,
                           dbUser, dbPassword, tblName);
            }
            vList.add(vtr);
         }

         /*
          * Initialize all the voters
          */
         initializeVoters(vList);

         /*
          * start them off
          */
         startVoters(vList);

         /*
          * Poll for agreement
         */

         while (true) {
            if (voterDone(vList)) {
               System.out.println("!!! Byzantine Agreeement Reached !!!");
               break;
            }
         }


      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   public static void initializeVoters(ArrayList vList)
      throws RemoteException, ClassNotFoundException,
      java.sql.SQLException
   {
      for (int idx = 0; idx < vList.size(); idx ++) {
         ((Voter)vList.get(idx)).initialize(vList);
      }

   }
   public static void startVoters(ArrayList vList) throws RemoteException
   {
      for (int idx = 0; idx < vList.size(); idx ++) {
         ((Voter)vList.get(idx)).start();
      }

   }
   public static boolean voterDone(ArrayList vList) throws RemoteException
   {
      boolean isDone = true;
      for (int idx = 0; idx < vList.size(); idx ++) {
         if (!(((Voter)vList.get(idx)).isDone())) {
            isDone = false;
            break;
         }
      }
      return isDone;

   }

}

Voter.java
-------------

import java.util.*;
interface Voter extends java.rmi.Remote
{
   public void initialize(ArrayList list)
      throws java.rmi.RemoteException,
         java.sql.SQLException,
         ClassNotFoundException;
   public void start() throws java.rmi.RemoteException;
   public boolean isDone() throws java.rmi.RemoteException;
   public void receiveVote(int i, Voter v)
      throws java.rmi.RemoteException,
      ClassNotFoundException,
      java.sql.SQLException;
   public int getRoundNumber() throws java.rmi.RemoteException;
   public int  getDecision() throws java.rmi.RemoteException;
}


VoterByzantineImpl.java
------------------------

import java.awt.event.*;
import java.util.*;
import javax.swing.Timer;
import java.sql.*;

/**
   VoterByzantineImpl Class

   Implements a Byzantine agreement Voter.
   Each voter for every round has a single row in a PostgreSQL DB.
   All voters on the same machine share a single table/DB.
   Each voter updates its database tuple that's of the form
   < voter_id, round, vote_cnt, head_cnt, tail_cnt>
   when it receives a vote.
   Voter arrives at its decision when it has 7/8 votes of
   the same type [Heads/Tails].
   Voter, however, continues to vote thereafter as well.
   Byzantine agreement is reached when 7/8 voters have reached
   a decision, and the decisions tally.
   @author Preethi Vishwanath
   @version 1.0
*/

public class VoterByzantineImpl extends Timer
   implements ActionListener, Voter
{

  /**
   Constructor: The VoterManager provides the delay for this voter to sleep
   before casting its own vote, and whether this is a faulty voter or not.
   In addition, details about the backing store where to log the vote
   is also provided

   @param:
      delay: Sleep time before voting
      faultyNotFaulty: Voter can change vote even in a round.
      dbName, user, passwrd, tName: Database connection parameters & table
   @returns None
    */


   VoterByzantineImpl(int delay,
            boolean faultyNotFaulty,
            String dbName, String user,
            String passwd, String tName)
   throws ClassNotFoundException, SQLException
   {
      super(delay, null);
      voterFaulty = faultyNotFaulty;
      this.dbName = dbName;
      this.user = user;
      this.passwd = passwd;
      tblName = tName;
      addActionListener(this);

   }

   /**
   isDone: Query function for the top level manager, basically
   a status check to see if this node is done or NOT

   @param none
   @return boolean
    */

   public boolean isDone() {
   if (isDone) return true;
   return false;

   }

   /**

   actionPerformed: Periodically vote until a Byzantine agreement is reached.
                    To vote in a faulty or not faulty manner is determined
                    in the voteByzantine function.

   @param arg0  ActionEvent is not used

   @return void

   */
public void actionPerformed(ActionEvent arg0) {
   Connection db;
   Statement sql;

   try {
      if (roundNumber == 0) {
         voteByzantine();
            } else {

         Class.forName("org.postgresql.Driver");
         db = DriverManager.getConnection("jdbc:postgresql://localhost/" + dbName,
                       user, passwd);

            sql = db.createStatement();
         int tmp_round = roundNumber - 1;
         sqlText = "SELECT vote_cnt FROM " + tblName + " WHERE voter_id = "
         + voterID +" AND round = " + tmp_round;
         ResultSet rs = sql.executeQuery(sqlText);
         int cnt = 0;
         while (rs.next()) {
            cnt = rs.getInt(1);
         }
         rs.close();
               if (cnt < (numVoters - 1)) {
                   return;
               } else  {
                     if (agreementReached()) {
                         // cast last vote before stopping in case others
                           // haven't verified the agreement yet
               voteByzantine();
               System.out.println("Voter " + voterID + "  Agreement Reached!!"
                                    + " Agreement is " + agreement);
               isDone = true;
               this.stop();
            } else  {
               voteByzantine();
                     }
               }
      }
   } catch (Exception e) { e. printStackTrace(); }
}


   /**

   broadcastRandom: Faulty Voters will call this function to send random
                    votes to each of the other Voters in the electorate.
                    Each round all of the vote values that were sent to
                    the other Voters are output to the console.

   @return void

   */

   public void broadcastRandom()
   throws java.rmi.RemoteException,
   java.sql.SQLException,
   ClassNotFoundException
 {
      Random voteSelector = new Random();

   for(int i = 0; i < numVoters; i++) {
         if (electorate.indexOf(this) != i) {
            currentVote = (voteSelector.nextBoolean()) ? HEADS : TAILS;
            ((Voter)electorate.get(i)).receiveVote(currentVote, this);
         }
      }
   }


   /**

   broadcastNormal: Normal Voters will call this function to send the same
                    vote to all of the other Voters in the electorate.
                    Each round all of the vote value that was sent to
                    the other Voters is output to the console.

   @return void

   */

   public void broadcastNormal()
   throws java.rmi.RemoteException,
   java.sql.SQLException,
   ClassNotFoundException
   {
      for(int i = 0; i < numVoters; i++) {
   if (electorate.indexOf(this) != i) {
            ((Voter)electorate.get(i)).receiveVote(currentVote, this);
   }
      }
   }


   /**

   voteByzantine: Implements the Byzantine election algorithm. Checks
                  for a majority vote and determines if the tally of the
                  majority vote exceeds the threshold or not.  The threshold
                  is determined by a global coin toss.  If the tally exceeds
                  the threshold then the Voter votes the same as the majority,
                  otherwise it votes 0.  When 7/8 of all Voters reach the same
                  decision then that decision becomes permanent for this voter.

   @return void

   */




   public void voteByzantine ()
   throws java.rmi.RemoteException,
   SQLException, ClassNotFoundException
   {
        Connection db;
      Statement sql;

       if (voterFaulty) broadcastRandom();
       else broadcastNormal();


   // Initialize the database
   Class.forName("org.postgresql.Driver");
   db = DriverManager.getConnection("jdbc:postgresql://localhost/" + dbName,
                 user, passwd);

        sql = db.createStatement();

   // We add an Array element to each counter for this round
        // if not already added in receiveVote
         sqlText = "SELECT vote_cnt FROM " + tblName + " WHERE voter_id = " + voterID
         + " AND round = " + roundNumber;
        ResultSet rs = sql.executeQuery(sqlText);
   boolean is_present = false;
   while (rs.next()) {
      is_present = true;
   }
   rs.close();
   if (!is_present) {
      sqlText = "INSERT INTO " + tblName + " VALUES (" + voterID + ","
      + roundNumber + ", 0, 0, 0)";
      sql.executeUpdate(sqlText);
   }

      // Here we check the previous round's majority and tally
      // so we skip it during round 0
      if (roundNumber != 0) {
    int numHeads = 0;
    int numTails = 0;
         //Include this Voter's vote for checking the majority and tally
    int d_rnd = roundNumber - 1;
    sqlText = "SELECT head_cnt, tail_cnt FROM " + tblName + " WHERE voter_id = "
    + voterID + "AND round = " +d_rnd;
    rs = sql.executeQuery(sqlText);
    while (rs.next()) {
      numHeads = rs.getInt(1);
      numTails = rs.getInt(2);
    }
    rs.close();

    System.out.println("VTR[" + voterID + "]:VOTE:[" + currentVote + "]:RND["
    + roundNumber + "]:nH[" + numHeads + "]:nT[" + numTails +"]");
         if (currentVote == HEADS) {numHeads++;}
         else {numTails++;}

         int majority = (numHeads > numTails) ? HEADS : TAILS;
         int tally = (majority == HEADS) ? numHeads : numTails;

         int threshold;

         //Global coin flip determines which threshold to use in this round
         //if (_cfp.flip() == HEADS)
            threshold = (int) (((5.0 / 8.0) * numVoters) + 1);
         //else
         //threshold = (int) (((3.0 / 4.0) * numVoters) + 1);

         currentVote = (tally >= threshold) ? majority : 0;


         if ((tally >= ((7.0 / 8.0) * numVoters)) &&
         (decision == UNDECIDED))
         {
            decision = majority;
            System.out.println( "ROUND: " + roundNumber + " VOTER: "
            + voterID + " DECISION: " + decision);
         }
      }
   sql.close();
   db.close();
      roundNumber++;
   }


   /**

   initialize: sets this Voter's electorate list to the list of Voter's
               passed in.  Sets this Voter's ID. Also stores the number
               of Voters.

   @param list  ArrayList of Voters to initialize

   @return void

   */

   public void initialize (ArrayList list)
   throws SQLException,
      ClassNotFoundException

   {
      Connection db = null;
      Statement sql = null;

      electorate = list;
      voterID = list.indexOf(this);
      numVoters = list.size();

      roundNumber = 0;
      decision = UNDECIDED;
      agreement = UNDECIDED;
      isDone = false;


      // initial vote for a good voter
      currentVote = (new Random().nextBoolean()) ? HEADS : TAILS;

      // Initialize the database
        Class.forName("org.postgresql.Driver");
   db = DriverManager.getConnection("jdbc:postgresql://localhost/" + dbName,
                 user, passwd);


   sql = db.createStatement();
   sqlText = "INSERT INTO " + tblName + " VALUES (" + voterID + ", 0, 0, 0, 0)";
   System.out.println(sqlText);
   sql.executeUpdate(sqlText);
   sql.close();
   db.close();
   }


   /**

   getDecision: gets a Voter's decision

   @return int  HEADS (1) or TAILS (0)

   */

   public int getDecision()
   {
      return decision;
   }


   /**

   getRoundNumber: gets the round number that a Voter is currently in

   @return int  round number

   */

   public int getRoundNumber()
   {
      return roundNumber;
   }


   /**

   receiveVote: Maintains the running count of the votes received from
                all of the other Voters for every round executed

   @param i  What the vote is HEADS (1) or Tails (0)
   @param v  Which Voter cast that vote

   @return void

   */

   public void receiveVote (int i, Voter v)
   throws java.rmi.RemoteException,
   SQLException, ClassNotFoundException

   {


      int round = v.getRoundNumber();
      Statement sql;
      Connection db;

      // Initialize the database
        Class.forName("org.postgresql.Driver");
   db = DriverManager.getConnection("jdbc:postgresql://localhost/" + dbName,
                 user, passwd);

      sql = db.createStatement();

      sqlText = "SELECT vote_cnt FROM " + tblName + " WHERE voter_id = "
      + voterID + "AND round = " + round;
      int cnt = 0;
      ResultSet rs = sql.executeQuery(sqlText);
      boolean is_present = false;
      while (rs.next()) {
         is_present = true;
      }
      rs.close();
      if (!is_present) {
      sqlText = "INSERT INTO " + tblName + " VALUES ( " + voterID + "," + round + ", 0, 0, 0)";
      sql.executeUpdate(sqlText);
      }
      sqlText = "SELECT vote_cnt, head_cnt, tail_cnt FROM " + tblName
      + " WHERE voter_id = " + voterID + " AND round = " + round;
      rs = sql.executeQuery(sqlText);
      int vote_count = 0;
      int head_count = 0;
      int tail_count = 0;
      while (rs.next()) {
      vote_count = rs.getInt(1);
      head_count = rs.getInt(2);
      tail_count = rs.getInt(3);
      }
      rs.close();
      vote_count ++;

      sqlText = "UPDATE " + tblName + " SET vote_cnt = " + vote_count
      + " WHERE voter_id = " + voterID + " AND round = " + round;
   sql.executeUpdate(sqlText);

      if (i == HEADS)  {
        head_count ++;
         sqlText = "UPDATE " + tblName + " SET head_cnt = " + head_count
         + " WHERE voter_id = " + voterID + " AND round = " + round;

      } else {
   tail_count ++;
         sqlText = "UPDATE " + tblName + " SET tail_cnt = " + tail_count
         + " WHERE voter_id = " + voterID + " AND round = " + round;
      }
   sql.executeUpdate(sqlText);
      sql.close();
      db.close();

   }


   /**

   agreementReached: Checks if 7/8 of all the Voters have come to a final
                     decision or not

   @return boolean  1 if agreement has been reached 0 if not

   */

   public boolean agreementReached () throws java.rmi.RemoteException
   {
      int numHeads = 0;
      int numTails = 0;
      boolean result = false;

      for(int i = 0; i < numVoters; i++)
      {
         if (((Voter)electorate.get(i)).getDecision() == HEADS)
            numHeads++;

         if (((Voter)electorate.get(i)).getDecision() == TAILS)
            numTails++;
      }

      if (numHeads >= ((7.0 / 8.0) * numVoters))
      {
         agreement = HEADS;
         result = true;
      }
      else if ( numTails >= ((7.0 / 8.0) * numVoters))
      {
         agreement = TAILS;
         result = true;
      }
      else
      {
         result = false;
      }

      return result;
   }


   private boolean voterFaulty; // faulty or not?
   private boolean isDone; // Am I done or not?
   private int roundNumber; // current round
   private int voterID;
   private int currentVote; // Voter's vote for current round
   private int decision; // final decision for this Voter
   private int agreement; // agreement of at least 7/8 of Voters
   private ArrayList electorate; // List of all Voters
   private int numVoters; // Total number of Voters

   private static final int HEADS = 1;
   private static final int TAILS = 0;
   private static final int UNDECIDED = -1;
   private static final long serialVersionUID = 1L;

   private String dbName;
   private String user;
   private String passwd;
   private String tblName;
   private String sqlText;

}

VoterManager.java
------------------

/*
 * Interface definition for a VoterManager
 * Manages a bunch of voters that can be created
 * from a remote client
 * Responsible for instantiation and termination
 * of the Voters
 */


interface VoterManager extends java.rmi.Remote
{
   public Voter createVoter(int delay, boolean flty, String db,
              String user, String passwd, String tblName)
   throws java.rmi.RemoteException, ClassNotFoundException,
   java.sql.SQLException;

}

VoterManagerImpl.java
----------------------

import java.sql.*;

public class VoterManagerImpl
   extends java.rmi.server.UnicastRemoteObject
   implements VoterManager
{
   private static final long serialVersionUID=1L;
   private String mTbl;

   public VoterManagerImpl() throws java.rmi.RemoteException {

   }
   public Voter createVoter(int delay,
             boolean faulty,
             String dbName,
             String user,
             String passwd,
             String tblName)
      throws java.sql.SQLException, ClassNotFoundException
   {
      // Create the table for all voters on this node
      Connection db;
      Statement sql;
      String sqlText;

      //
      if (tblName != null) {
         mTbl = tblName;
               Class.forName("org.postgresql.Driver");
         db = DriverManager.getConnection("jdbc:postgresql://localhost/" + dbName,
                 user, passwd);


         sql = db.createStatement();
         sqlText = "CREATE TABLE "+ tblName +
         "(voter_id int, round int, vote_cnt int, head_cnt int, tail_cnt int)";
         System.out.println(" DB: EXECUTING: " + sqlText);
         sql.executeUpdate(sqlText);
         sql.close();
         db.close();
      }


      Voter v = new VoterByzantineImpl(delay, faulty,
                   dbName, user, passwd, mTbl);
      System.out.println("Created NEW VOTER");
      return v;
   }


}

VoterServer.java
-----------------

/**
 * VoterServer class
 * Creates a continuously running server that instantiates a
 * VoterManager RMI Object that can then accept incoming
 * RMI request to create a voter, or set properties of the voter
 *
 * @Parameters: None
 * @Returns: None
 */

import java.rmi.*;
public class VoterServer {
   public VoterServer() {
      if (System.getSecurityManager() == null) {
         System.setSecurityManager(new RMISecurityManager());
      }
      try {
         VoterManager vmgr = new VoterManagerImpl();
         Naming.rebind("rmi://localhost/voteMgr", vmgr);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   public static void main(String[] args) {
      new VoterServer();
   }

}