Implementation of causal broadcast inspired by the CBCAST protocol from Lightweight Causal and Atomic Group Multicast [doi:10.1145/128738.128742, pdf]. Verification of causal delivery with Liquid Haskell, described in our paper Verified Causal Broadcast with Liquid Haskell [arXiv:2206.14767, pdf].
The implementation is suitable for inclusion in real world projects, except for the known caveats of the algorithm, namely that the set of processes (view) cannot change during runtime. There is a client library module, CBCAST for clients that don't use Liquid Haskell, and an example key value server. Both have extensive docstring comments. If your project uses Liquid Haskell, you could probably import the internal modules CBCAST.{Core,Transitions}. Finally, the deploy directory readme has NixOps scripts for deployment on AWS.
To follow the proof that applying operations to processes in an execution preserves causal delivery (CD), we suggest:
-
The top level theorem and proof are in CBCAST/Verification/Global/CDpresXStep.hs: The theorem
trcCDpresstates that for all CD-observing executions, applying an arbitrary list of operations to processes in the execution obtains a CD-observing execution.-
The definition of CD is in CBCAST/Verification/Global/Core.hs: The definition
CausalDelivery r N Xstates that for some number of processesNand some executionX, for all process identifiersp_idinX, and messagesm₁andm₂delivered atX p_idwithm₁happens-beforem₂,X p_iddeliversm₁beforem₂. -
The definition of CD-preservation is in CBCAST/Verification/Global/CDpresXStep.hs: The definition
CDpreservation r N Fstates that for some number of processesNand functionF, for all CD-observing executionsx, the executionF xis CD-observing. -
An execution (
Xsized r N) is a function (or mapping), for some number of processesN, from a process identifier on[0,N)to a process with that identifier in CBCAST/Verification/Global/Core.hs. -
Happens before (
→) is an uninterpreted predicate on two events in an execution. We provide the axiompreserveHBwhich sayse → e' ⇒ VC(e) < VC(e')andreflectHBwhich saysVC(e) < VC(e') ⇒ e → e'in CBCAST/Verification/Global/Core.hs.
-
This relies on our work showing that applying operations to a single process preserves process-local causal delivery (PLCD).
-
The top level theorem and proof are in CBCAST/Verification/PLCDpresStep.hs: The theorem
trcPLCDpresstates that for all PLCD-observing processes, applying an arbitrary list of operations to the process obtains a PLCD-observing process.-
The definition of PLCD is in CBCAST/Verification/PLCD.hs: The definition
PLCD r N PROCstates that for some number of processesNand some processPROC, for all messagesm₁andm₂delivered atPROCwith sent-VC ofm₁less-than sent-VC ofm₂,PROCdeliversm₁beforem₂. -
The definition of PLCD-preservation is in CBCAST/Verification/PLCDpres.hs: The definition
PLCDpreservation r N Fstates that for some number of processesNand some functionF, for all PLCD-observing processesp, the processF pis PLCD-observing.
-
Here's a diagram of the important components of the proof. Purple theorems are concerned with global properties of an execution, blue theorems assist with translating between process-local and global-execution properties, and yellow theorems are concerned with process local properties. Dashed arrows indicate inclusion via lemmas.
Compiling the project will run the Liquid Haskell verification as a GHC plugin.
It normally takes about 4 minutes (on a 2015 MacBookPro).
To skip the verification and just build the code, you can turn off the Liquid Haskell plugin in package.yaml.
- For most systems,
stack buildshould do the trick.
- Use
nix-shellto enter a development environment or usenix-buildto build the project. - Flake commands work too.
