Dr. Annette Bieniusa M.Sc. Peter Zeller M.Sc. Mathias Weber
TU Kaiserslautern
Fachbereich Informatik AG Softwaretechnik
Exercise 3: Programming Distributed Systems (SS 2018)
• To get feedback to your solution: Create a new branch in your git repository (e.g.
git checkout -b ex3). Submit your solution to the programming exercise via your group’s repository to the new branch in a folder named “ex3”. When your solution is ready, create a merge request in Gitlab and assign Peter Zeller to it.
This will allow us to comment on your code and give you feedback.
• Prepare this sheet for the exercise on Thursday, May 17.
1 Atomic broadcast and consensus
In the lecture you have seen, that atomic broadcast can be implemented using consensus (Atomic Broadcast Algorithm, Lecture 4, Slide 19).
a) Show that it is also possible to do the reverse: Describe an algorithm that im- plements consensus by using atomic broadcast. Your algorithm should provide a propose method to clients and trigger a decide -event when a proposed value is de- cided.
b) Assume we change the atomic broadcast algorithm from the lecture and only use best-effort broadcast instead of reliable broadcast. Show that this would make the algorithm incorrect.
c) Consider the following modification to the atomic broadcast algorithm from the lecture. Why does this “optimization” not work correctly?
S t a t e :
kp // c o n s e n s u s n u m b e r
p e n d i n g // m e s s a g e s r e c e i v e d but not a - d e l i v e r e d by p r o c e s s U p o n I n i t do :
kp ← 0;
p e n d i n g ← ∅;
U p o n a - B r o a d c a s t ( m ) do t r i g g e r rb - B r o a d c a s t ( m );
U p o n rb - D e l i v e r ( m ) do p e n d i n g ← p e n d i n g ∪ { m };
U p o n p e n d i n g 6=∅ do kp ← kp + 1;
p r o p o s e (kp, p e n d i n g );
w a i t u n t i l d e c i d e (kp, msgkp)
∀ m in msgkp in d e t e r m i n i s t i c o r d e r do t r i g g e r a - D e l i v e r ( m ) p e n d i n g ← p e n d i n g \ msgkp
2 Optimizing causal broadcast
The causal broadcast algorithm from the lecture, which you implemented for the last exercise sheet, reuses the reliable broadcast algorithm. This is a nice and modular solution, however it has some performance issues:
• Without crashes, the number of messages sent by our reliable broadcast imple- mentation is N
2if N is the number of processes.
• The reliable broadcast algorithm keeps a set, which grows with every delivered message.
Design an optimized algorithm, which does not have these performance issues.
You don’t have to implement your optimized version of the algorithm. However, if you do implement it, be aware that the tests we provided for the last exercise sheet were specific for that algorithm and might not work for algorithms that use a different strategy.
3 Practical exercise: state machine replication
In this exercise you will implement an online gambling service “Repbet”, where users can bet money on the outcome of certain events.
Since gamblers can get pretty angry, when their favorite game is not available, we want to use replication for high availability. We also want high consistency for dealing with money and aggressive gamblers and therefore will use replicated state machines with the Raft algorithm.
The template you can download for this task already contains the basic setup. Check the Readme file for instructions on building the project. The module
repbet_machinecontains the implementation of the replicated state machine and stubs for the functions you need to implement to solve this task. The comments in this file explain how to use and adapt the replicated state machine. We use the library “ra”
1as Raft library.
Implement the following functions:
% % C r e a t e s a new u s e r w i t h the g i v e n Name , Mail , and P a s s w o r d .
% % R e t u r n s 'ok' w h e n the u s e r was c r e a t e d and {error , n a m e _ t a k e n} if the
% % u s e r n a m e is a l r e a d y t a k e n .
c r e a t e _ u s e r ( Node , Name , Mail , P a s s w o r d ) - > ...
% % C h e c k s if t h e r e is a u s e r w i t h the g i v e n n a m e and p a s s w o r d c o m b i n a t i o n
% % R e t u r n s ok if p a s s w o r d m a t c h e s and {error , a u t h e n t i c a t i o n _ f a i l e d} o t h e r w i s e c h e c k _ p a s s w o r d ( Node , U s e r n a m e , P a s s w o r d ) - > ...
% % C r e a t e s a new c h a l l e n g e w i t h the g i v e n d e s c r i p t i o n t h a t u s e r s can bet on .
% % E a c h c h a l l e n g e g e t s a s s i g n e d a new u n i q u e id , w h i c h is r e t u r n e d
% % as {ok , C h a l l e n g e I d}.
c r e a t e _ c h a l l e n g e ( Node , D e s c r i p t i o n ) - > ...
% % M a k e s the g i v e n u s e r bet on a g i v e n c h a l l e n g e .
% % R e s u l t is e i t h e r t r u e or f a l s e ( t r u e if the u s e r bets , t h a t the c h a l l e n g e
% % t u r n s out to be true , f a l s e o t h e r w i s e )
% % M o n e y is the a m o u n t of m o n e y the u s e r b e t s on t h i s c h a l l e n g e .
% % T h i s a m o u n t is d i r e c t l y s u b t r a c t e d f r o m the u s e r s b a l a n c e .
% % R e t u r n s ok if b e t t i n g was s u c c e s s f u l
% % R e t u r n s {error , a m o u n t _ m u s t _ b e _ p o s i t i v e}, if M o n e y is <= 0
% % R e t u r n s {error , i n v a l i d _ u s e r} or {error , i n v a l i d _ c h a l l e n g e} if u s e r
% % of c h a l l e n g e d o e s not e x i s t
% % R e t u r n s {error , i n s u f f i c i e n t _ f u n d s} if the u s e r s a c c o u n t b a l a n c e is
1
Source code is available at
https://github.com/rabbitmq/ra. You can find some documentationat
https://rabbitmq.github.io/ra/. The interesting parts are in the description of the raand
ra_machinemodules.
% % l e s s t h a n the M o n e y he w a n t s to bet
bet ( Node , U s e r n a m e , C h a l l e n g e I d , Result , M o n e y ) - > ...
% % C h a n g e s the b a l a n c e of the g i v e n u s e r by the g i v e n A m o u n t
% % A m o u n t can be p o s i t i v e or n e g a t i v e , but the u s e r a c c o u n t m u s t
% % a l w a y s h a v e p o s i t i v e v a l u e
% % R e t u r n s ok on s u c c e s s and {error , i n s u f f i c i e n t _ f u n d s}, if c h a n g i n g
% % the b a l a n c e w o u l d go b e l o w 0
c h a n g e _ b a l a n c e ( Node , U s e r n a m e , A m o u n t ) - > ...
% % C o m p l e t e s the g i v e n c h a l l e n g e by s e t t i n g a R e s u l t
% % R e s u l t is e i t h e r t r u e or f a l s e
% % All M o n e y bet on t h i s c h a l l e n g e is d i s t r i b u t e d a m o n g the u s e r s
% % t h a t g u e s s e s the r e s u l t c o r r e c t l y ,
% % p r o p o r t i o n a l l y to the a m o u n t t h e y h a v e bet . c o m p l e t e _ c h a l l e n g e ( Node , C h a l l e n g e I d , R e s u l t ) - > ...
% % Get a l i s t of all c h a l l e n g e s , t h a t h a v e not yet b e e n c o m p l e t e d
% % R e t u r n s a l i s t of t u p l e s : {Id , D e s c r i p t i o n , T o t a l M o n e y , Y e s P e r c e n t a g e}
% % Id is the Id of the c h a l l e n g e
% % D e s c r i p t i o n is its d e s c r i p t i o n
% % T o t a l M o n e y is the o v e r a l l a m o u n t i n v e s t e d in t h i s c h a l l e n g e
% % Y e s P e r c e n t a g e is the p e r c e n t a g e of m o n e y t h a t has b e e n set on 'yes' ( t r u e ) l i s t _ a c t i v e _ c h a l l e n g e s ( N o d e ) - > ...
% % Get a l i s t of all c h a l l e n g e s , t h a t the g i v e n u s e r has p a r t i c i p a t e d in
% % R e t u r n s a l i s t of t u p l e s :
% % {Id , D e s c r i p t i o n , Result , U s e r G u e s s , U s e r M o n e y , T o t a l M o n e y , Y e s P e r c e n t a g e}
% % Id is the Id of the c h a l l e n g e
% % D e s c r i p t i o n is its d e s c r i p t i o n
% % R e s u l t is e i t h e r 't r u e' or 'f a l s e' for c o m p l e t e d c h a l l e n g e s
% % or 'n o t _ c o m p l e t e d' o t h e r w i s e
% % T o t a l M o n e y is the o v e r a l l a m o u n t i n v e s t e d in t h i s c h a l l e n g e
% % Y e s P e r c e n t a g e is the p e r c e n t a g e of m o n e y t h a t has b e e n set on 'yes' ( t r u e )
% % U s e r G u e s s is the r e s u l t g u e s s e d by the u s e r in his bet
% % U s e r M o n e y is the a m o u n t of m o n e y i n v e s t e d by the u s e r l i s t _ u s e r _ c h a l l e n g e s ( Node , U s e r n a m e ) - > ...
% % Get the c u r r e n t b a l a n c e of a u s e r
% % R e t u r n s {ok , B a l a n c e} or {error , u s e r _ n o t _ f o u n d} g e t _ b a l a n c e ( Node , U s e r n a m e ) - > ...