-
Notifications
You must be signed in to change notification settings - Fork 770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Voting as separate table #368
Comments
I'm not sure we need a hash chain of votes. Building that would be just as problematic as building the hash chain of blocks (a problem we solved by letting each node declare its own view of which block is the previous block, in its vote). If we don't need a hash chain of votes, then we also don't need a "genesis vote." Each vote already includes pointers (hash/id) to the block-being-voted-on and the previous-block (from the voting node's point of view). That's what builds the "block chain." You can think of the votes as the chain links. Votes are signed, so we can tell if one has been tampered-with (by someone other than the node which wrote it). I'm not sure of the best way to build the vote |
So every vote should be allowed then? Because any node could write a vote with the correct primary key. Of course the signature will reveal it's false, but when should it happen? During voting? This will become voting on votes... During query? The first correct valid votes? How do we prevent a node from from jamming incorrect ids in and preventing legitimate votes? Maybe we shouldn't key the votes this way, then we only need the first valid votes from a node...? |
Ok, talked to @ttmc here is the flow we propose for changes to the vote table: CreateThere are only two possiblities:
UpdateThere are four possibilities:
Deletevalid ↦ nothing: create (triggers changefeed)? Any change except adding a new valid vote should trigger a warning to the federation of possible Byzantine behavior |
I was thinking about this some more... We really don't want to allow a valid vote to be changed (e.g. from "this block is valid" to "this block is invalid"), because that could cause the validity of the block to change (e.g. from valid to invalid), which could make decisions that had been made, based on the validity of that block, to become invalid... a snowball effect. My original thought was to have the votes table be "append-only," i.e. where the only thing that can happen is insertion of votes (i.e. the database itself only allows Create to happen, not Update or Delete). Unfortunately, RethinkDB does allow Update and Delete... We could:
Before we explore option 3 (the most pragmatic one), there's another issue: even if we can revert changes somehow, there will be a brief period where the vote is changed and that can cause the above-mentioned snowball effect. In other words, allowing any kind of change, even briefly, is a recipe for misery. Proposal: Assume that we will go with option 1. or 2. Pretend that the votes table is append-only. Allow both valid and invalid votes to be written to it. Ignore the invalid votes at query time. If a node ever notices an Update or Delete on the votes table, it should raise an exception / alarm. |
Suggested by @r-marques and Bruce: Maybe another option would be: 4. create a modified version of RethinkDB in which user tables don't allow Update or Delete, and use that for the (The |
I'm not sure if I should be amused or concerned... I was reading about append-only databases and stumbled across an interesting fact: RethinkDB started out as an append-only database! Apparently there were problems... http://www.xaprb.com/blog/2013/12/28/immutability-mvcc-and-garbage-collection/ If you read that and became pessimistic about append-only databases, here's a 2015 article that's more optimistic (and which even responds to the above blog post): "The rise of immutable data stores" |
Problem
Per the white paper § 4.7.3, votes are appended directly to the blocks. While the votes are signed, and can thus be validated, there is no notion of when a vote is written or if its value has been changed. This makes it impossible to revert Byzantine changes to the block table as long as changes are handled by reacting to a changefeed -- a changed vote could be changed back, but that would trigger a change and so on. This was recognized while trying to resolve #195 and #194.
Solution
@ttmc proposed the following solution: write votes to a table separate from blocks. This has a few advantages (see initial discussion on #195):
Tasks:
block_id + voting_node_id
-- this is unique, and another insert with this id will be rejected.The text was updated successfully, but these errors were encountered: