Skip to content
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

Handle updates on the bigchain table #195

Closed
r-marques opened this issue Apr 20, 2016 · 11 comments
Closed

Handle updates on the bigchain table #195

r-marques opened this issue Apr 20, 2016 · 11 comments
Assignees

Comments

@r-marques
Copy link
Contributor

We need to check for updates on the bigchain table. The only updates allowed are the appending of new votes. Any other update needs to be reverted

@ttmc
Copy link
Contributor

ttmc commented May 25, 2016

Note: It's not enough to check if an update to the bigchain table is a vote. It must be a valid vote:

  • Is it a "second vote" from a node, on a block where it already voted? Invalid.
  • Is it an attempt to change a vote? Invalid. (Even if the signature is valid.)

@rhsimplex
Copy link
Contributor

I don't think this is possible in the current architecture. Reverting a change will itself trigger a change and so on. How is the Election process (which handles updates to bigchain) to know the difference between a reverted change, legitimate change, and illegitimate change?

@ttmc
Copy link
Contributor

ttmc commented May 31, 2016

@rhsimplex and I discussed an idea: make a hash chain of votes (appended to each block) so that we can tell if a previous vote was changed or deleted. (Right now, we can't tell if a vote is being changed by a bad node or by a revert process.)

To do that, we could add a new hash to the vote data model.

The first vote's hash would be just the hash of the block (the block id). The second vote's hash would be a hash of the block id and the first vote (serialized). And so on. Block validation would include checking all the vote hashes.

The last-received vote could be changed (but only by the node who created it), but maybe that's okay: it's just one vote.

@r-marques @diminator @vrde Do you think this would work?

@diminator
Copy link
Contributor

How would you append?

block: {
...
   votes {
       block_id <- vote1 <- vote2 ...
   }
}

@ttmc
Copy link
Contributor

ttmc commented May 31, 2016

The block model already has votes, which is a list of votes. There would be no change to the block model, just the vote model.

@diminator
Copy link
Contributor

oh, ok

so we're actually updating that record and not appending?

@ttmc
Copy link
Contributor

ttmc commented May 31, 2016

The list of votes starts out empty and the normal thing is to just append new votes onto the end of that list. The question is what to do when a node changes or deletes previous votes. (It's just a list with no particular order or expected length.) We want to revert bad changes, but how can another node tell a bad change from a revert change? A hash chain would make it possible to tell.

@diminator
Copy link
Contributor

but couldnt a node always remove all votes and restart from the block id?

@ttmc
Copy link
Contributor

ttmc commented May 31, 2016

Yes, but I guess that would be easy to detect from the changefeed: a block would go from having lots of votes (with a valid vote hash chain) to none (also valid, so this is a corner case). The revert change would also be easy to verify: a bunch of votes suddenly appearing where there were none before, and they would have a valid hash chain (and there's no way one node could build such a thing).

@diminator
Copy link
Contributor

ok, taking into account old_val from the changefeed would indeed solve it

@ttmc
Copy link
Contributor

ttmc commented Jun 3, 2016

As discussed in the planning meeting today, @rhsimplex and I thought of an alternative solution: create a new, third table for votes. Then the bigchain table becomes append-only, the votes table would be append-only, and the logic for detecting "bad" changes in the changefeed becomes really simple.

This idea was discussed and we decided to go ahead with it.

Note: The id of the vote document (i.e. the database primary key) could be the hash of the tuple (block being voted on, public key of node voting) so that if a node tried to write a new vote that is a second vote on the same block, RethinkDB wouldn't let it, because a vote with that id would already be in the votes table.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants