Official implementation of ISAAC protocol based on the consensus model of mFBA
This is not a repository for running a node. This is only a proof of concept for BOSCoin's ISAAC consensus protocol. Feel free to test.
To install and deploy the source, you need to install these packages,
- python: 3.6 or higher
- pip
Once the dependencies are installed, clone this repository and run.
$ python setup.py develop
$ run-blockchain.py -h
usage: run-blockchain.py [-h] [-verbose]
[-log-level {critical,fatal,error,warn,warning,info,debug}]
[-log-output LOG_OUTPUT]
[-log-output-metric LOG_OUTPUT_METRIC]
[-log-show-line] [-log-no-color]
conf
positional arguments:
conf ini config file for server node
optional arguments:
-h, --help show this help message and exit
-verbose verbose log (default: False)
-log-level {critical,fatal,error,warn,warning,info,debug}
set log level (default: debug)
-log-output LOG_OUTPUT
set log output file (default: None)
-log-output-metric LOG_OUTPUT_METRIC
set metric output file (default: None)
-log-show-line show seperate lines in log (default: False)
-log-no-color disable colorized log message by level (default:
False)
Set the config file.
$ run-blockchain.py examples/node5001.ini
2017-12-06 15:21:48,459 - __main__ - DEBUG - Node ID: 5001
2017-12-06 15:21:48,459 - __main__ - DEBUG - Node PORT: 5001
2017-12-06 15:21:48,459 - __main__ - DEBUG - Validators: ['localhost:5002', 'localhost:5003']
Run the other nodes like this.
$ run-blockchain.py examples/node5002.ini
$ run-blockchain.py examples/node5003.ini
$ run-client.py -h
usage: run-client.py [-h] [-verbose]
[-log-level {critical,fatal,error,warn,warning,info,debug}]
[-log-output LOG_OUTPUT]
[-log-output-metric LOG_OUTPUT_METRIC] [-log-show-line]
[-log-no-color] [-m MESSAGE] [-i IP] [-p PORT]
optional arguments:
-h, --help show this help message and exit
-verbose verbose log (default: False)
-log-level {critical,fatal,error,warn,warning,info,debug}
set log level (default: debug)
-log-output LOG_OUTPUT
set log output file (default: None)
-log-output-metric LOG_OUTPUT_METRIC
set metric output file (default: None)
-log-show-line show seperate lines in log (default: False)
-log-no-color disable colorized log message by level (default:
False)
-m MESSAGE, --message MESSAGE
Messages you want to send to the server (default:
Quaerat)
-i IP, --ip IP Server IP you want to send the message to (default:
localhost)
-p PORT, --port PORT Server port you want to send the message to (default:
5001)
After checking node state in the cmd line, run the run-client.py to send a message to node '5001' as below.
$ run-client.py --ip "localhost" --port 5001 --message "message"
Send five messages at a time every 4 seconds to node 5001
$ for i in $(seq 5)
do
run-client.py \
--ip localhost \
--port 5001 \
--message "message-$i"
sleep 4
done
Send five messages at a time every 4 seconds to node 5001
and 5002
,
$ for port in 5001 5002
do
for i in $(seq 5)
do
run-client.py \
--ip localhost \
--port $port \
--message "message-$i"
sleep 4
done
done
Send five messages at a time every 4 seconds to 5000
-5003
randomly three times
$ for _ in $(seq 3)
do
p=$(expr $RANDOM % 4)
for i in $(seq 5)
do
run-client.py \
--ip localhost \
--port "500$p" \
--message "message-$i"
sleep 4
done
done
$ pytest
$ flake8
See the examples.
Before running this script, please run
python setup.py develop
.
$ send-message.py -h
usage: send-message.py [-h] [-verbose]
[-log-level {critical,fatal,error,warn,warning,info,debug}]
[-log-output LOG_OUTPUT]
[-log-output-metric LOG_OUTPUT_METRIC] [-log-show-line]
[-log-no-color]
endpoints [endpoints ...] [message]
positional arguments:
endpoints endpoints and it's number of messages, you want to
send; ex) http://localhost:80?m=5
http://localhost:80?m=10
message Messages you want to send to the server (default:
None)
optional arguments:
-h, --help show this help message and exit
-verbose verbose log (default: False)
-log-level {critical,fatal,error,warn,warning,info,debug}
set log level (default: debug)
-log-output LOG_OUTPUT
set log output file (default: None)
-log-output-metric LOG_OUTPUT_METRIC
set metric output file (default: None)
-log-show-line show seperate lines in log (default: False)
-log-no-color disable colorized log message by level (default:
False)
This script will try to send messages to multiple nodes simultaneously.
This will send one random message to http://localhost:54320.
$ send-message.py http://localhost:54320
This will send one random message to http://localhost:54320 and http://localhost:54321 at the same time.
$ send-message.py http://localhost:54320 http://localhost:54321
You can set the number of messages for each node. For example, this will send 9 random messages to http://localhost:54320 and 10 random messages to http://localhost:54321.
$ send-message.py http://localhost:54320?m=9 http://localhost:54321?m=10
This simple script will try to analyze the metric messages from node. Mainly this will handle below issues,
- node activity
- fault tolerance for nodes
- safety between quorum(2 nodes)
liveness between quorum(2 nodes)
The terminology of these terms are described in the BOSCoin official homepage. The interesting thing is that to check the health of quorum, this script will create a superset in all the validators and compose the quorum with each 2 nodes.
Before running the metric-analyzer.py
, the 'metric' messages from running nodes should be stored in an output file.
For example, metric logs can be generated in /tmp/metric.json
by the following scripts
$ run-blockchain.py examples/node5001.ini -log-output-metric /tmp/metric.json
$ run-blockchain.py examples/node5002.ini -log-output-metric /tmp/metric.json
$ run-blockchain.py examples/node5003.ini -log-output-metric /tmp/metric.json
$ run-blockchain.py examples/node5004.ini -log-output-metric /tmp/metric.json
Then send messages to nodes.
$ for port in 5001 5002 5003 5004
do
for i in $(seq 5)
do
python scripts/run-client.py \
--ip localhost \
--port $port \
--message "message-$i"
sleep 2
done
done
$ metric-analyzer.py -h
usage: metric-analyzer.py [-h] [-verbose]
[-log-level {critical,fatal,error,warn,warning,info,debug}]
[-log-output LOG_OUTPUT]
[-log-output-metric LOG_OUTPUT_METRIC]
[-log-show-line] [-log-no-color] [-type TYPE]
[-nodes NODES] [-node NODE]
[metric]
positional arguments:
metric metric file (default: None)
optional arguments:
-h, --help show this help message and exit
-verbose verbose log (default: False)
-log-level {critical,fatal,error,warn,warning,info,debug}
set log level (default: debug)
-log-output LOG_OUTPUT
set log output file (default: None)
-log-output-metric LOG_OUTPUT_METRIC
set metric output file (default: None)
-log-show-line show seperate lines in log (default: False)
-log-no-color disable colorized log message by level (default:
False)
-type TYPE set the analyzer type to be shown
(dict_keys(['history', 'safety', 'fault-tolerance']))
(default: None)
-nodes NODES set the nodes to be shown (default: None)
If you have /tmp/metric.json
,
$ metric-analyzer.py /tmp/metric.json
You can filter multiple types as you want. For example the following script will only show the results for safety and fault tolerance of node 5001
.
$ metric-analyzer.py -type safety,fault-tolerance -nodes 5001 /tmp/metric.json