Conversation
Roll-up of #588 with some conflicts resolved
* Require slot uniqueness for blocks (rather than epochs) * Native DB support for Slot and Epoch * Simplify surrounding/surrounded-by queries
A single SQL database saves on open file descriptors.
|
Hey, not sure it's worth it but locking validators into a Sorry bit of a brain dump message, just didn't want to forget. |
61477b1 to
3ddda95
Compare
a82ff3c to
f62e428
Compare
|
This is finally ready for review! Here's a quick overview:
|
There was a problem hiding this comment.
Beautifully clean and elegant, as always :) I really like how simple this becomes with SQL and the concurrency properties we get from SQLite.
There's a few comments, but nothing structural. I also wanted to raise two things for consideration:
Using domain for uniqueness
I can see that a conflicting vote across different domains is prevented here, whilst not being slashable on-chain. I support this decision, it makes things much simpler and I really doubt we're ever going to support staking on two chains with the same VC instance.
I noticed that some of the tests were using the different domain to simulate "difference" instead of mutating some other field like beacon_block_root. Whilst I completely believe it's functionally equivalent, it did occur to me that the tests are using "same message different domain" to test that something is NoteSafe when technically that is Safe on the chain. Perhaps throwing in a couple of quick tests that mutate at least one of the AttestationData fields might be nice, as a token gesture if nothing else.
Verification of data read from the database
As noted in comments, we can hit panics/unintended behaviour if the Slot, Epoch or Hash256 values stored in the database are not properly formed. You can definitely make the argument that we're already relying upon (a) our input to the database to be consistent and (b) SQLite to maintain that consistency, so double-checking is a waste of time. But, unless it's messy, perhaps we should just double check? Perhaps you already have thought about this; I did notice theToSql/FromSql error types were kinda funky.
eth2/types/src/sqlite.rs
Outdated
|
|
||
| impl ToSql for Slot { | ||
| fn to_sql(&self) -> Result<ToSqlOutput, Error> { | ||
| Ok(ToSqlOutput::from(self.as_u64() as i64)) |
There was a problem hiding this comment.
As mentioned in the main comment, we could use TryFrom<u64> for i64, seeing as we're in a Result context.
There was a problem hiding this comment.
Casting u64 <-> i64 is safe and lossless, but I refactored this to use an error type anyway
| let signing_bytes: Vec<u8> = row.get(1)?; | ||
| Ok(SignedBlock { | ||
| slot, | ||
| signing_root: Hash256::from_slice(&signing_bytes), |
There was a problem hiding this comment.
As above regarding Hash256::from_slice
There was a problem hiding this comment.
Fixed, good catch!
660c667 to
75be431
Compare
|
All review comments have been addressed I think, just waiting on CI to pass. Regarding the domain, you're right. Unless we stored a mapping from I added a test ( |
paulhauner
left a comment
There was a problem hiding this comment.
But some false positives, if they simplify the design, seem tolerable.
I agree.
Looks great! This is has my approval. I'm going to flag it as blocked until we cut a v0.1.2 release, then we can include this in the v0.2.0 release :)
Issue Addressed
Closes #254
Replaces #588
Obsoletes #623
Proposed Changes
Builds upon @pscott's previous PR, updating his work for the latest changes in
master, and moving to a single slashing protection database to solve an issue with file descriptor limits (one DB per validator broke down at around 100 validators per machine under default Linux limits of 1024 FDs per process).Additional Info
Completed TODOs:
FIXMEs,printlns, etcFuzz or property test the concurrency safety as well