I have been reading about single-decree Paxos (primarily looking at Paxos Made Simple) yet am confused about if a consensus among Acceptors is guaranteed to not change after being reached.
According to James Aspnes's notes,
So now we suppose that some value
v
is eventually accepted by a majorityT
with numbern
. Then we can show by induction on proposal number that all proposals issued with higher numbers have the same value (even if they were issued earlier).
However, I am confused since I believe I have a counterexample, shown below. Feel free to jump to step 12 since that is where simple steps can illustrate the problem. I have included steps 1-12 in case it is not possible to reach the state in step 12.
Consider the following behavior. Borrowing notation from Contradiction in Lamport's Paxos made simple paper.
That is, X(n:v, m)
, means Acceptor X
has largest accepted proposal n:v
, where n
is proposal number and v
is value, and m
is the largest numbered prepare response to which Acceptor X
has responded.
Say we have 3 Acceptors A, B, C. Let Px be a proposer, or even multiple proposers, who keeps sending proposals since they don't find out about any consensus being reached.
Px
broadcastsprepare(1)
A
andB
respond with promise, state isA(:, 1)
,B(:, 1)
Px
receives promises fromA
andB
, confirms majority and broadcastsaccept(1:'foo')
- Only
A
receives this accept, state is nowA(1:'foo', 1)
,B(:, 1)
,C(:,)
Py
broadcastsprepare(2)
B
,C
respond with promises, state is nowA(1:'foo', 1)
,B(:, 2)
,C(:,2)
Py
receives promises fromB
andC
, confirms majority and broadcastsaccept(2:'bar')
- Only
B
receives this accept, state isA(1:'foo', 1)
,B(2:'bar', 2)
,C(:,2)
Pz
broadcastsprepare(3)
A
andC
response with promise, state isA(1:'foo', 3)
,B(2:'bar', 2)
,C(:,3)
Pz
receives promises fromA
andC
, confirms majority, notes that1:'foo'
is the largest numbered accepted value, and broadcasts accept3:'foo'
- Only
C
receives this accept, state isA(1:'foo', 3)
,B(2:'bar', 2)
,C(3:'foo', 3)
-- A consensus has been reached! 'foo' is the value decided upon -- Pn
doesn't know about this, broadcastsprepare(4)
A
andB
response with promise, state isA(1:'foo', 4)
,B(2:'bar', 4)
,C(3:'foo', 3)
Pn
receives promises fromA
andB
, confirms majority, notes that2:'bar'
is the largest numbered accepted value, and broadcasts accept4:'bar'
A
receives this broadcast, state isA(4:'bar', 4)
,B(4:'bar', 4)
,C(3:'foo', 3)
. -- A consensus has been reached! 'bar' is the value decided upon --
To be clear, steps 4, 8, 12, don't necessarily mean that the other nodes "failed", but I think it can just the proposer in question is taking a really long time to deliver the messages. Thus this shouldn't be a case where more than N acceptors crash in out of 2N + 1.
The top-voted answer in Contradiction in Lamport's Paxos made simple paper suggests that Proposers only sent accept messages to Acceptors who promised them and an acceptor accepting a value means updating the maxBal. Both of these are satisfied in the above example, yet it shows how consensus can flip-flop between two different values. Am I missing something here?