Subject: Re: [Din] draft-mazieres-dinrg-scp-04 (page 16) Potential improvement to balloting protocol, setting cCounter
From: David Mazieres <[email-masked]>
To: Piers Powlesland <[email-masked]>
Cc: [email-masked]
Date: Sat, 03 Nov 2018 00:22:19 -0700
List-Id: "Discussion of distributed Internet Infrastructure approaches, aspects such as Service Federation, and underlying technologies" <din.irtf.org>

Piers Powlesland <[email-masked]> writes:

> I have a few things I'm not clear on.
>
> I don't see that this statement is correct.
>
>>You mean transition to voting to commit nothing?  (Though still
>>vote-or-confirm (n,x) for 4 <= n <= 8.)
>
> So following the update steps for c, first the c will be set to NULL
> and then the next step will be executed.
>
>> * If "c == NULL" and "hCounter == ballot.counter" (meaning
>>    "ballot" is confirmed prepared), then set "c" to "ballot".
>
> Resulting in the following node state.
>
> ballot = (8,x)
> prepared = (8,x)
> preparedPrime = (4,z)
> cCounter = 8
> hCounter = 8
>
> Which as described in the IETF document would I think means the node
> now is voting to commit(8,x) ?

Oh, yes, sorry.  But importantly you are no longer voting to commit
(5,x) and (6,x).

>> * If "cCounter != 0": "vote commit(<n, ballot.value>)" for every "cCounter <= n <= hCounter"
>
> Also what is "vote-or-confirm" ?

Sorry, another mistake on my part.  I meant vote-or-accept.

> I can imagine the following scenario that seems to be allowable via
> the IETF update rules that would allow a node to illegally vote for a
> range of ballots that the node has never set its ballot equal to.
>
> The node starts with the following state. It is currently voting to
> commit(2,x) among other things.
>
> ballot =(2,x)
> prepared =(2,x)
> preparedPrime =(1,y)
> cCounter =2
> hCounter =2
>
> Now we see blocking threshold for accept prepare(8,x)
>
> ballot =(8,x) // ballot.counter was also updated by the blocking threshold.
> prepared =(8,x)
> preparedPrime =(1,y)
> cCounter =2
> hCounter =8
>
> Now we see quorum threshold for accept prepare(8,x) (we have confirmed
> prepared (8,x) and h.value == b.value so we set hCounter to 8)
>
> ballot =(8,x)
> prepared =(8,x)
> preparedPrime =(1,y)
> cCounter =2
> hCounter =8

Sorry, what's the difference between this and above?  I'm assuming you
meant hCounter=2 above, and hCounter=8 here.

> So now we are voting to commit, 2...8 with value == x but ballot has
> never been set to a ballot with counter  3...7 and value == x. Doesn't
> this make it illegal to vote to commit (3,x)...(7,x)?

No, that's okay.  The thing we actually need to avoid is voting to abort
and commit the same ballot b.  In this case that's fine because you
never voted to abort any of (3,x)...(7,x).  The protocol could of course
keep track of very vote you have ever cast to make sure this is okay.
Instead, to keep the state small, it uses the trick that you reset c to
0 whenever the ballot might contain a new value, and then you have to
set c to the current ballot number, because the (conservative)
assumption is that if c == 0, then you might have voted to abort any
ballot less than the current ballot.

Does that make sense?  Maybe some of this rationale needs to go into the
document...

David