In class, we gave a round-based protocol for consensus in synchronous systems for crash failures. Give a round-based protocol for consensus in synchronous systems for send omission failures. A send omission is a failure in which a process attempts to send a message but the message is instead dropped. Hint: in each round, have processes send messages in a way that each process can determine whether or not it has suffered a send omission. If a process i determines this, then have it crash itself. Assume that no more than t processes can be faulty, where a faulty process can have send omission failures, can crash, or can do both.
Let p1 be the transmitter and v be the value it wishes to broadcast reliably. This value is from the domain V. There are two other values, neither in V: ∅, which a process p sends to q to indicate that p failed to receive an expected message from q in the previous round, and ⊥, which a process p sends to q to indicate that p received a message from q sent in the previous round.
Each process p executes the following protocol.
d = none; It is easy to show that this protocol ensures that if a correct process sets d to val in round i < t + 1 then all processes that are not crashed by the end of round i set d to val in round i + 1. And, if a process sets d to val in round t + 1 then a correct process set d to val in some round i < t + 1. So, all we need to show is that if a send-faulty process sets d to val in some round i < t + 1 and later decides, then all processes that decide have set d to val by round t + 1.
A process x that is send-faulty will crash itself if it learns it has committed a send omission. Thus, if a send-faulty process decides, then it sent all expected messages to all correct processes in each round. Thus, if x sets d to val in some round i < t + 1, then each correct process receives val by round i + 1. And, similar to above, if x sets d to val in round t + 1, then a correct process set d to val in some round i < t + 1.
round 0:
if (p == p1) {
d = v;
send(v) to all;
}
else send(⊥) to all;
round i: 1 ≤ i ≤ t:
if (receive(∅) from any process) crash;
if (receive(val ∈ V) from any process && d == none) {
d = val;
send(d) to all;
}
else for each process (q) {
if (received message from q) send(⊥) to q;
else send(∅) to q;
}
round t+1:
if (receive(∅) from any process && d == none) crash;
if (receive(val ∈ V) from any process) d = val;
if (d == none) decide(0);
else decide(d);
Like the previous problem, come up with a round-based protocol for receive omission failures. A receive omission is a failure in which a process attempts to receive a message that has been sent to it, but the message is instead dropped. Assume that no more than t processes can be faulty, where a faulty process can have receive omission failures, can crash, or can do both.
Let p1 be the transmitter and v be the value it wishes to broadcast reliably. This value is from the domain V.
This problem requires n > 2t. An informal proof is: assume it is solvable with n ≤ 2t. Divide the processes into two sets A and B, each containing t or fewer processes. Let p1 be in A and let v ≠ 0 (where 0 is the default decision value). Consider three runs:
Each process p executes the following protocol. The value ⊥ ∉ V is a heartbeat.
d = ⊥ As with the previous protocol, it is easy to show that this protocol ensures that if any process sets d to val in round i < t + 1 and does not crash in this round, then all correct processes set d to val in round i + 1. And, if a process sets d to val in round t + 1 then some process set d to val in some round i < t + 1 and did not crash in that round. So, we need to show that if a process sets d to val in some round i < t + 1 and does not crash, then a receive-faulty process either sets d to val by round t + 2 or crashes itself before deciding.
Since this protocol runs for t+2 rounds, and all correct processes receive v by round t+1, each correct process will have broadcast v by round v+2. If a receive-faulty process receives none of these messages, then it will detect this fact and crash itself before deciding.
silent[1..n] = [false, ..., false];
round 0:
if (p == p1) {
d = v;
send(v) to all;
}
else send(⊥) to all;
round i: 1 ≤ i ≤ t+1:
for each process q:
if (did not receive message from q) silent[q] = true;
if (more than t elements of silent are true) crash;
if (receive(val ∈ V) from any process && d == none) {
d = val;
send(d) to all;
}
else send(⊥) to all;
round t+2:
for each process q:
if (did not receive message from q) silent[q] = true;
if (more than t elements of silent are true) crash;
if (receive(val ∈ V) from any process) d = val;
if (d == none) decide(0);
else decide(d);
Consider a broadcast service with the following interface:
bc-send(m): A process i presents a message m to be broadcast to all processes in the group (including i).
bc-recv(m): A process i receives a message m that was broadcast to all processes in the group.
Neither of these operations block: the first one does not wait for the message to be received by all processes, and the second one works in an interrupt-like fashion.
We define three different ordering requirements:
FIFO: if a process i executes bc-send(m1) before executing bc-send(m2), then no process executes bc-recv(m2) before executing bc-recv(m1).
Causal: if process i executing bc-send(m1) happens before process jexecuting bc-send(m2), then no process executes bc-recv(m2) before executing bc-recv(m1). In this case, we define "happens before" in terms of local events and bc-send(m), bc-recv(m) events.
Total: For all messages m1 and m2 and all processes i and j, if i executes bc-recv(m1) before executing bc-recv(m2), then process j does not execute bc-recv(m2) before executing bc-recv(m1).
Answer the following two questions about this kind of service.
Give a space-time diagram of that illustrate an execution of a broadcast service that is FIFO and causal but not total.

Here's s simple example. It is trivially FIFO and causal, and is not total. Repeating this pattern of messages is also FIFO, causal and not total.
Prove that if a broadcast service is both FIFO and total, then it is also causal.
Assume i executed bc-send(m1) causally before j executed bc-send(m2). This means that j executed bc-recv(m1) before executing bc-send(m2). By definition, j executed bc-send(m2) before executing bc-recv(m2), and so j executed bc-receive(m1) before executing bc-recv(m2). Since the broadcast is total, i executed bc-recv(m1) before executing bc-recv(m2). Thus, the broadcast primitive is causal.
30 January 2009 by kam