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
vis eventually accepted by a majorityTwith 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.
Pxbroadcastsprepare(1)AandBrespond with promise, state isA(:, 1),B(:, 1)Pxreceives promises fromAandB, confirms majority and broadcastsaccept(1:'foo')- Only
Areceives this accept, state is nowA(1:'foo', 1),B(:, 1),C(:,) Pybroadcastsprepare(2)B,Crespond with promises, state is nowA(1:'foo', 1),B(:, 2),C(:,2)Pyreceives promises fromBandC, confirms majority and broadcastsaccept(2:'bar')- Only
Breceives this accept, state isA(1:'foo', 1),B(2:'bar', 2),C(:,2) Pzbroadcastsprepare(3)AandCresponse with promise, state isA(1:'foo', 3),B(2:'bar', 2),C(:,3)Pzreceives promises fromAandC, confirms majority, notes that1:'foo'is the largest numbered accepted value, and broadcasts accept3:'foo'- Only
Creceives 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 -- Pndoesn't know about this, broadcastsprepare(4)AandBresponse with promise, state isA(1:'foo', 4),B(2:'bar', 4),C(3:'foo', 3)Pnreceives promises fromAandB, confirms majority, notes that2:'bar'is the largest numbered accepted value, and broadcasts accept4:'bar'Areceives 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?