Babble
Distributed Consensus Middleware
Install / Use
/learn @mosaicnetworks/BabbleREADME
BABBLE

Babble is a distributed consensus engine designed to easily plug into any application. It uses peer-to-peer networking and a consensus algorithm to guarantee that a group of connected computers process the same commands in the same order.
Table of Contents
Features
-
Asynchronous: Participants have the freedom to process commands at different times.
-
Leaderless: No participant plays a special role.
-
Byzantine Fault-Tolerant: Supports one third of faulty nodes, including malicious behavior.
-
Finality: Babble’s output can be used immediately, no need for block confirmations.
-
Dynamic Membership: Members can join or leave a Babble network without undermining security.
-
Fast Sync: Joining nodes can sync directly to the current state of a network.
-
Accountability: Auditable history of the consensus algorithm’s output.
-
Language Agnostic: Integrate with applications written in any programming language.
-
Mobile: Bindings for Android and iOS.
-
WebRTC: Supports WebRTC connections for practical p2p connections.
Consensus
We use an adaptation of the Hashgraph consensus algorithm, invented by Leemon Baird, to which we added important features. Hashgraph is best described in the white-paper and its accompanying document. The original Hashgraph algorithm is protected by patents in the USA, so anyone intending to use this software in the USA should take this into consideration. For a high level overview of the concepts behind Babble, please refer to this document.
Babble's major departure from the original Hashgraph algorithm is the introduction of blocks, which represent self-contained sections of the Hashgraph, and which are instrumental in the implementation of two important new features that were alluded to in Baird's paper, but not specified:
-
A dynamic membership protocol, which enables peers to join or leave a group on demand.
-
A fast-sync protocol which enables joining nodes to fast-forward directly to a point in the hashgraph without downloading the entire history.
API

Babble communicates with the App through an AppProxy interface, which has two
implementations:
-
InmemProxy: An InmemProxy uses native callback handlers to integrate Babble as a regular Go dependency. -
SocketProxy: A SocketProxy connects to an App via TCP sockets. It enables the application to run in a separate process or machine, and to be written in any programming language.
Refer to the dummy package for an example that implements both proxies.
// Start from default Babble configuration.
babbleConfig := config.NewDefaultConfig()
// Create dummy InmemProxy
dummy := NewInmemDummyClient(babbleConfig.Logger())
// Set the proxy in the Babble configuration.
babbleConfig.Proxy = dummy
// Instantiate Babble.
babble := babble.NewBabble(babbleConfig)
// Read in the configuration and initialise the node accordingly.
if err := babble.Init(); err != nil {
babbleConfig.Logger().Error("Cannot initialize babble:", err)
os.Exit(1)
}
// The application can submit transactions to Babble using the proxy's
// SubmitTx. Babble will broadcast the transactions to other nodes, run them
// through the consensus algorithm, and eventually call the callback methods
// implemented in the handler.
go func() {
dummy.SubmitTx([]byte("the test transaction"))
}()
// Run the node aynchronously.
babble.Run()
// Babble reacts to SIGINT (Ctrl + c) and SIGTERM by calling the leave
// method to politely leave a Babble network, but it can also be called
// manually.
defer babble.Node.Leave()
Configuration
Babble configuration is defined in the config package.
Data Directory
Babble reads configuration files from its data directory which defaults to
~/.babble on Linux. It can be overwritten with DataDir in the Config object
or --datadir from the CLI.
Key
Every Babble validator requires a cryptographic key-pair 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 secp256k1 curve (like Bitcoin and Ethereum).
To pass a private key to Babble, either set it directly in the Config object,
or dump it to a priv_key file in the data directory. Babble's keygen command
may be used to generate key-pairs in the appropriate format.
Peers
Babble needs to know the other peers in the network. This is specified by adding two JSON files in the data directory.
-
genesis.peers.jsoncorresponds to the initial validator-set; the one that the hashgraph was started with. Ifgenesis.peers.jsonis not provided, Babble will usepeers.jsonas the genesis validator-set. -
peers.jsoncorresponds to the set of peers that the node should attempt to connect to upon starting.
peers.json and gensesis.peers.json are not necessarily equal because
the dynamic membership
protocol enables new nodes to join or leave a live Babble network dynamically.
It is important for a joining node to know the initial validator-set in order to
replay and verify the hashgraph up to the point where it joins.
It is possible to start a Babble network with just a single node, or with a
predefined validator-set composed of multiple nodes. In the latter case,
someone, or some process, needs to aggregate the public keys and network
addresses of all participants into a single file (peers.genesis.json), and
ensure that everyone has a copy of this file. 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.
To join an existing network, a peer must first obtain the JSON peers files from
an existing node and place them in the data directory. One way to obtain the
peers files is to query the /peers and /genesispeers functions exposed by
the HTTP API service. Please refer to the
join script in the demo for an example.
for an example.
Transport
Implementations of the Transport interface determine how nodes communicate with one-another.
TCP
The TCP transport is suitable when nodes are in the same local network, or when users are able to configure their connections appropriately to avoid NAT issues.
To use a TCP transport, set the following configuration properties:
-
BinAdddror--listen: the IP:PORT of the TCP socket that Babble binds to. By defaultBindAddris127.0.0.1:1337, meaning that Babble will bind to the loopback address on the local machine. -
AdvertiseAddror--advertise: (optional) The address that is advertised to other nodes. IfBindAddris a local address not reachable by other peers, it is necessary to setAdvertiseAddrto something else. IfAdvertiseAddris not set, it defaults to theBindAddr.
For example, when running a node from a local network behind a NAT, the
BindAddr might be 192.168.1.10 which is not reachable from outside the local
network. So it is necessary to set AdvertiseAddr to the public IP of the
router, and to setup port-forwarding in the NAT.
Note that the advertise address (which defaults to bind address if not set) must
match the address of the peer in the peers.genesis.json or peers.json files.
WebRTC
Because Babble is a peer-to-peer application, it can run into issues with NATs and firewalls. The WebRTC transport addresses the NAT traversal issue, but it requires centralised servers for peers to exchange connection information and to provide STUN/TURN services.
To use a WebRTC transport, use the following configuration properties:
-
WebRTCor--webrtc: tells Babble to use a WebRTC transport. -
SignalAddror--signal-addr: address of the WebRTC signaling server. -
`S
