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
- Run on multiple nodes [Default 2]
- Have multiple voters/node [Default 4]
- Have any number of faulty nodes [Default 2]
- Connect to any PostgreQL DB with right user/password
- 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();
}
}
|