Lecture 1: Logical and Physical Time with some Applications (Part 1)

Lecture 1: Logical, Physical & Causal Time
(Part 1)
Anish Arora
CSE 6333
Logical Clocks
• j, k
:
processes
• ch.j.k
:
channel from j to k – a sequence
• m
:
message
• e, f
:
events
• lc.j
:
logical clock of j – an integer
• lc.e
:
logical time of e – an integer
Logical Clocks program
Process j
{local event e}

lc.j, lc.e := lc.j+1, lc.j+1
{sent event e,

lc.j, lc.e := lc.j+1, lc.j+1
▯
from j to k}
; ch.j.k
:= (ch.j.k oe,lc.e)
▯
{receive event e,

lc.j, lc.e := (lc.j max lc.m)+1,
msg m from k to j}
(lc.j max lc.m)+1
; ch.k.j
:= tail(ch.k.j)
Logical Clocks invariant
Process j
{local event e}

lc.j, lc.e := lc.j+1, lc.j+1
{sent event e,

lc.j, lc.e := lc.j+1, lc.j+1
▯
from j to k}
; ch.j.k
:= (ch.j.k oe,lc.e)
▯
{receive event e,

lc.j, lc.e := (lc.j max lc.m)+1,
msg m from k to j}
(lc.j max lc.m)+1
; ch.j.k
:= tail(ch.k.j)
Invariant
( e,j : e occurs at j : lc.e  lc.j)

( e,f:: e happens before f  lc.e < lc.f)

( m,j,k : m  ch.j.k : (e : e occurs at j: lc.e=lc.m))
Logical Clocks
Theorem : Invariant is closed in program of logical clocks
Proof : We show that for any “new” event, if Invariant holds
before the event occurs, then Invariant holds after it occurs
1) ( e,j : e occurs at j : lc.e  lc.j)
•
If e is an old event, this term is preserved since lc.j cannot decrease
•
If e is a new event, and occurs at j, this term holds since lc.e = lc.j
•
If e is a new event, and occurs at a process other than j, this term
holds trivially
2) ( m,j,k : m  ch.j.k : (e : e occurs at j : lc.e  lc.m))
•
If m is an old message, term is trivially preserved by the same witness
•
If m is a new message, then this term holds since lc.m := lc.e,
where e is the new event
Logical Clocks
3) ( e,f : e happens before f  lc.e < lc.f)
•
If e and f are old events, this term is trivially preserved
•
If e is the new event, there is no event in f such that e happens
before f
•
If e is an old event and f is the new event then,
I.
If e is the event immediately preceding f at the same process j,
then lc.e  lc.f before f occurs and lc.e < lc.f after f occurs and lc.f
:= lc.j. Hence lc.e < lc.f
II. If e is the send event corresponding to the receive event f, then
lc.f > lc.m = lc.e
III. If e is some other event that happens before f, then e happens
before e’ such that I or II apply to e’. From Invariant, lc.e < lc.e’,
and from lc.e’ < lc.f. Hence lc.e < lc.f
Vector Clocks
Correctness requirement:
( e,f :: e happens before f  vc.e < vc.f)
where
• e
:
events
• j, k
:
processes
• vc.j
:
vector clock of j – a vector 1..N of integers
• vc.e
:
vector time of e – a vector 1..N of integers
– 1..N
Vector Clocks
Process j
{local event e}

vc.j.j := vc.j.j+1
; vc.e := vc.j
▯
{sent event e}

vc.j.j := vc.j.j+1
; send msg with vc.e = vc.j
▯
{receive event e, 
message m}
vc.j.j := vc.j.j+1
; (|| k :: vc.j.k := vc.j.k max vc.m.k)
Vector orderings :
vc.e < vc.f

(j :: vc.e.jvc.f.j)  (j :: vc.e.j<vc.f.j)
Proof of Invariance for Vector Clocks
Let i,j,k be processes;
ai,bj be events at processes i and j respectively;
mk be a message sent by process k
R=
( i,j,mi :: vc.i.i  vc.j.i

( ai,bj ::
ai hb bj

 ai hb bj

 vc.i.j  vc.mi.j )
vc.ai < vc.bj
vc.ai.i  vc.bj.i )
Theorem : R is an Invariant
Proof : We show that for any “new” event, if R holds before the
event occurs, then R holds after the event occurs
Vector Clocks
1) vc.i.i  vc.j.i : If the events occurs at a process other than j and
i, this term is obviously preserved
If the event occurs at process i, then vc.i.i is
incremented thereby preserving this term
If the event occurs at process j, j i then vc.j.i either
remains unchanged or is set to the maximum of vc.j.i and vc.mk.i.
However, from R, vc.mk.i  vc.k.i and vc.k.i  vc.i.i, hence the
term is preserved
2) vc.i.j  vc.mi.j : The timestamp of a message never changes, and
vc.i.j is nondecreasing. Hence this term is preserved
Vector Clocks
3) ai hb bj  vc.ai < vc.bj : We consider three cases:
–
If both ai and bj are both not the new events, then this term is
preserved trivially
–
If ai is the new event but bj is not, then (ai hb bj) and this
term is true
–
If bj is the new event and ai is not, then
I. If j=i and ai is the event immediately before bj then
vc.bj.j = vc.ai.j + 1. Hence vc.ai < vc.bj
II. If bj is the receive event caused by the send event ai, then
vc.ai.j < vc.bj.j and vc.ai  vc.bj. Hence vc.ai < vc.bj
III. If subcases I and II do not hold and ai hb bj then ai hb ck
such that for ck I or II apply. From R, vc.ai < vc.ck, and
since vc.ck < vc.bj , vc.ai < vc.bj
Vector Clocks
4) ai hb bj  (vc.ai < vc.bj  vc.ai.i  vc.bj.i)
We prove the contrapositive : (ai hb bj)  (vc.ai<vc.bj)  (vc.ai.i>vc.bj.i)
We consider three cases:
–
If both ai and bj are both not the new events, then this term is
preserved trivially
–
If ai is the new event but bj is not, then vc.ai.i = vc.i.i > vc.j.i  vc.bj.i.
Hence (vc.ai<vc.bj)
–
If ai is an old event and bj is the new event, then (ai hb ck) where ck
is any event such that I and II apply
(ai hb ck)

{from R}
vc.ai.i > vc.ck.i

{ij, else ai hb bj}
vc.ai.i > vc.bj.i

{definition of >}
vc.ai.i > vc.bj.i  (vc.ai < vc.bj)
Restriction
•
Adding (conjoining) extra guards to any of the actions of a
program
•
The addition of these guards restricts the set of states in
which the restricted actions execute
•
Theorem: Every safety property of the program is a safety
property of the restricted program
(Hint: {P} s {Q}  {P  g} s {Q})
Superposition
•
Adding actions to a program that do not modify (write) the
program variables – they modify only the ‘superposed’
variables
•
The addition of the actions may be in
– parallel with program actions
– interleaved with program actions
•
Theorem: Every safety and progress property of the
program is a property of the superposed program
Proof: For progress, assume program actions are executed
fairly
Causal Broadcast (Birman-Schiper-Stepheson)
Causal ordering:
( e,f,j :
send.e happens before send.f

deliveredj.e happens before deliveredj.f )
• i, j, k
:
Processes
• m
:
message
• vc.i
:
vector clock of i
• vc.m
:
vector time of m
Causal Broadcast
Process i
{send message m}

vc.i.i := vc.i.i+1
; vc.m := vc.i
; send.m to all j
▯
{receive message m

(|| k : vc.i.k := vc.i.k
from j }

max
vc.i.j + 1 = vc.m.j

vc.m.k)
(k : kj : vc.i.k  vc.m.k)
; deliver m to i
Causal Broadcast (safety)
Let P = (i,j,k,ai,bj,mi,nj :: vc.i.i  vc.j.i

vc.i  vc.mi

deliveredj.mi  vc.j  vc.mi

deliveredj.mi  vc.j.i  vc.mi.i

ai hb bj
 vc.a  vc.b

ai hb bj
 vc.ai.i  vc.bj.i

CB
)
where
CB = (mi,nj,k::send.mi hb send.nj  deliveredk.nj  deliveredk.mi)
Causal Broadcast (safety)
Theorem:
P is an invariant
Proof:
Every event is either a send or a deliver of a message.
Our obligation is to show that for every “new” event,
if P holds before the event then P holds after the event.
The first six conjuncts are easily verified.
We show that these six conjuncts imply CB




send.mi hb send.nj
{ 5th conjunct
vc.mi  vc.nj
{ transitivity  }
vc.mi  vc.k
{ definition of  for vectors }
vc.mi.i  vc.k.i
{ 4th conjunct }
deliveredk.mi

,

deliveredk.nj
3rd conjunct }
vc.nj  vc.k
Progress proof of Causal Broadcast (sketch)
•
If finitely many messages are sent, eventually all send actions are
disabled
•
In states where no send actions are enabled, eventually all (sent)
messages have been received
•
In states where no send actions are enabled and all messages have
been received, either all messages have been delivered or some
deliver action is enabled
•

This step requires proof: consider all undelivered messages at j, and
further consider only those which did not happen after any other
message in this set.

If the deliver action is disabled for all such messages mk, then:
vc.j.k + 1 = vc.mk.k  (l : vc.j.l < vc.mk.l) which implies from the
invariant P that (ml : vc.mk.l = vc.ml.l :
deliveredj.ml  deliveredk.ml  send.ml hb send.mk) which is false
Therefore eventually all messages will be delivered
Note that this proof does not require any fairness of program execution