Usage¶
In this section we will guide you through deploying an application on top of Babble. Babble comes with the Dummy application which is used in this demonstration. It is a simple chat application where participants write messages on a channel and Babble guarantees that everyone sees the same messages in the same order.
Docker¶
We have provided a series of scripts to bootstrap a demo. Let us first use the easy method to view the demo and then we will take a closer look at what is happening behind the scenes.
Make sure you have Docker installed.
The demo will pull Docker images from our official public Docker registry
[...]/babble$ cd demo
[...]/babble/demo$ make
Once the testnet is started, a script is automatically launched to monitor consensus figures:
consensus_events:180 consensus_transactions:40 events_per_second:0.00 id:1 last_block_index:3 last_consensus_round:17 num_peers:3 round_events:7 rounds_per_second:0.00 state:Babbling sync_rate:1.00 transaction_pool:0 undetermined_events:18
consensus_events:180 consensus_transactions:40 events_per_second:0.00 id:3 last_block_index:3 last_consensus_round:17 num_peers:3 round_events:7 rounds_per_second:0.00 state:Babbling sync_rate:1.00 transaction_pool:0 undetermined_events:20
consensus_events:180 consensus_transactions:40 events_per_second:0.00 id:2 last_block_index:3 last_consensus_round:17 num_peers:3 round_events:7 rounds_per_second:0.00 state:Babbling sync_rate:1.00 transaction_pool:0 undetermined_events:21
consensus_events:180 consensus_transactions:40 events_per_second:0.00 id:0 last_block_index:3 last_consensus_round:17 num_peers:3 round_events:7 rounds_per_second:0.00 state:Babbling sync_rate:1.00 transaction_pool:0 undetermined_events:20
Running docker ps -a
will show you that 9 docker containers have been launched:
[...]/babble/demo$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba80ef275f22 mosaicnetworks/watcher "/watch.sh" 48 seconds ago Up 7 seconds watcher
4620ed62a67d mosaicnetworks/dummy "dummy '--name=client" 49 seconds ago Up 48 seconds 1339/tcp client4
847ea77bd7fc mosaicnetworks/babble "babble run --cache_s" 50 seconds ago Up 49 seconds 80/tcp, 1337-1338/tcp node4
11df03bf9690 mosaicnetworks/dummy "dummy '--name=client" 51 seconds ago Up 50 seconds 1339/tcp client3
00af002747ca mosaicnetworks/babble "babble run --cache_s" 52 seconds ago Up 50 seconds 80/tcp, 1337-1338/tcp node3
b2011d3d65bb mosaicnetworks/dummy "dummy '--name=client" 53 seconds ago Up 51 seconds 1339/tcp client2
e953b50bc1db mosaicnetworks/babble "babble run --cache_s" 53 seconds ago Up 52 seconds 80/tcp, 1337-1338/tcp node2
0c9dd65de193 mosaicnetworks/dummy "dummy '--name=client" 54 seconds ago Up 53 seconds 1339/tcp client1
d1f4e5008d4d mosaicnetworks/babble "babble run --cache_s" 55 seconds ago Up 54 seconds 80/tcp, 1337-1338/tcp node1
Indeed, each node is comprised of an App and a Babble node (cf Design section).
The watcher
container monitors consensus figures.
Run the demo
script to play with the Dummy App
which is a simple chat application
powered by the Babble consensus platform:
[...]/babble/demo$ make demo

Finally, stop the testnet:
[...]/babble/demo$ make stop
Manual Setup¶
The above scripts hide a lot of the complications involved in setting up a Babble network. They generate the configuration files automatically, copy them to the right places and launch the nodes in Docker containers. We recommend looking at these scripts closely to understand how the demo works. Here, we will attempt to explain the individual steps that take place behind the scenes.
Configuration¶
Babble reads configuration from the directory specified by the datadir
flag
which defaults to ~/.babble
on linux/osx. This directory must contain two
files:
peers.json
: Lists all the participants in the network.priv_key.pem
: Contains the private key of the validator runnning the node.
Every participant has a cryptographic key-pair that is used to encrypt, sign and verify messages. The private key is secret but the public key is used by other nodes to verify messages signed with the private key. The encryption scheme used by Babble is ECDSA with the P256 curve.
To run a Babble network, it is necessary to predefine who the participants are going to be. Each participant will generate a key-pair and decide which network address it is going to be using for the Babble protocol. Someone, or some process, then needs to aggregate the public keys and network addresses of all participants into a single file - the peers.json file. Every participant uses a copy of the same peers.json file. Babble will read that file to identify the participants in the network, communicate with them and verify their cryptographic signatures.
To generate key-pairs in a format usable by Babble, we have created the
keygen
command. It is left to the user to derive a scheme to produce the
configuration files but the docker demo scripts are a good place to start.
So let us say I want to participate in a Babble network. I am going to start by
running babble keygen
to create a key-pair:
babble keygen
Your private key has been saved to: /home/martin/.babble/priv_key.pem
Your public key has been saved to: /home/martin/.babble/key.pub
The private key looks something like this:
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJ3orqofiSXu07mD+f46gZFK3EKSTqhXsbLVmA/aLmyqoAoGCCqGSM49
AwEHoUQDQgAEXgNNc8hJdWrntlFcpg2WpakRsTpNi0W8DgsC7bRQCd9szAdO6298
Z5V0D5k2ZO3ulw+KcXyJNE+EN/QSvfDRfA==
-----END EC PRIVATE KEY-----
and the corresponding public key looks like this:
0x045E034D73C849756AE7B6515CA60D96A5A911B13A4D8B45BC0E0B02EDB45009DF6CCC074EEB6F7C6795740F993664EDEE970F8A717C89344F8437F412BDF0D17C
DO NOT REUSE THESE KEYS
Next, I am going to copy the public key (key.pub) and communicate it to whoever is responsible for producing the peers.json file. At the same time, I will tell them that I am going to be listening on 172.77.5.2:1337.
Suppose three other people do the same thing. The resulting peers.json file could look something like this:
[
{
"NetAddr":"172.77.5.1:1337",
"PubKeyHex":"0x0471AEE3CAE4E8442D37C9F5481FB32C4531511988652DF923B79ED4ED992021183D31E0F6FBFE96D89B6D03D7250292DFECD4FC414D83A5C38FA3FAD0D8572864"
},
{
"NetAddr":"172.77.5.2:1337",
"PubKeyHex":"0x045E034D73C849756AE7B6515CA60D96A5A911B13A4D8B45BC0E0B02EDB45009DF6CCC074EEB6F7C6795740F993664EDEE970F8A717C89344F8437F412BDF0D17C"
},
{
"NetAddr":"172.77.5.3:1337",
"PubKeyHex":"0x047CCCD40D90B331C64CE27911D3A31AF7DC16C1EA6D570FDC2120920663E0A678D7B5D0C19B6A77FEA829F8198F4F487B68206B93B7AD17D7C49CA7E0164D0033"
},
{
"NetAddr":"172.77.5.4:1337",
"PubKeyHex":"0x0406CB5043E7337700E3B154993C872B1C61A84B1A739528C4A10135A3D64939C094B4A999BD21C3D5E9E9ECF15B202414F073795C9483B2F51ADA7EE59EB5EAC4"
}
]
Now everyone is going to take a copy of this peers.json file and put it in a folder together with the priv_key.pem file they generated in the previous step. That is the folder that they need to specify as the datadir when they run Babble.
Babble Executable¶
Let us take a look at the help provided by the Babble CLI:
Run node
Usage:
babble run [flags]
Flags:
--cache-size int Number of items in LRU caches (default 500)
-c, --client-connect string IP:Port to connect to client (default "127.0.0.1:1339")
--datadir string Top-level directory for configuration and data (default "/home/martin/.babble")
--heartbeat duration Time between gossips (default 1s)
-h, --help help for run
-l, --listen string Listen IP:Port for babble node (default ":1337")
--log string debug, info, warn, error, fatal, panic
--max-pool int Connection pool size max (default 2)
-p, --proxy-listen string Listen IP:Port for babble proxy (default "127.0.0.1:1338")
-s, --service-listen string Listen IP:Port for HTTP service
--standalone Do not create a proxy
--store Use badgerDB instead of in-mem DB
--sync-limit int Max number of events for sync (default 100)
-t, --timeout duration TCP Timeout (default 1s)
So we have just seen what the datadir
flag does. The listen
flag
corresponds to the NetAddr in the peers.json file; that is the endpoint that
Babble uses to communicate with other Babble nodes.
As we explained in the architecture section, each Babble node works in conjunction with an application for which it orders transactions. When Babble and the application are connected by a TCP interface, we specify two other endpoints:
proxy-listen
: where Babble listens for transactions from the Appclient-connect
: where the App listens for transactions from Babble
We can also specify where Babble exposes its HTTP API providing information on
the Hashgraph and Blockchain data store. This is controlled by the optional
service-listen
flag.
Finally, we can choose to run Babble with a database backend or only with an
in-memory cache. With the store
flag set, Babble will look for a database
file in datadir
/babdger_db. If the file exists, the node will load the
database and bootstrap itself to a state consistent with the database and it
will be able to proceed with the consensus algorithm from there. If the file
does not exist yet, it will be created and the node will start from a clean
state.
Here is how the Docker demo starts Babble nodes together wth the Dummy application:
for i in $(seq 1 $N)
do
docker run -d --name=client$i --net=babblenet --ip=172.77.5.$(($N+$i)) -it mosaicnetworks/dummy:0.4.0 \
--name="client $i" \
--client-listen="172.77.5.$(($N+$i)):1339" \
--proxy-connect="172.77.5.$i:1338" \
--discard \
--log="debug"
done
for i in $(seq 1 $N)
do
docker create --name=node$i --net=babblenet --ip=172.77.5.$i mosaicnetworks/babble:0.4.0 run \
--cache-size=50000 \
--timeout=200ms \
--heartbeat=10ms \
--listen="172.77.5.$i:1337" \
--proxy-listen="172.77.5.$i:1338" \
--client-connect="172.77.5.$(($N+$i)):1339" \
--service-listen="172.77.5.$i:80" \
--sync-limit=1000 \
--store \
--log="debug"
docker cp $MPWD/conf/node$i node$i:/.babble
docker start node$i
done
Stats, blocks and Logs¶
Once a node is up and running, we can call the stats
endpoint exposed by the
HTTP service:
curl -s http://172.77.5.1:80/stats
or request to see a specific block:
curl -s http://172.77.5.1:80/block/1
Or we can look at the logs produced by Babble:
docker logs node1