lighthouse/validator_client/slashing_protection/src/lib.rs
ethDreamer ba55e140ae Enable Compatibility with Windows (#2333)
## Issue Addressed

Windows incompatibility.

## Proposed Changes

On windows, lighthouse needs to default to STDIN as tty doesn't exist. Also Windows uses ACLs for file permissions. So to mirror chmod 600, we will remove every entry in a file's ACL and add only a single SID that is an alias for the file owner.

Beyond that, there were several changes made to different unit tests because windows has slightly different error messages as well as frustrating nuances around killing a process :/

## Additional Info

Tested on my Windows VM and it appears to work, also compiled & tested on Linux with these changes. Permissions look correct on both platforms now. Just waiting for my validator to activate on Prater so I can test running full validator client on windows.

Co-authored-by: ethDreamer <37123614+ethDreamer@users.noreply.github.com>
Co-authored-by: Michael Sproul <micsproul@gmail.com>
2021-05-19 23:05:16 +00:00

136 lines
3.6 KiB
Rust

mod attestation_tests;
mod block_tests;
pub mod interchange;
pub mod interchange_test;
mod parallel_tests;
mod registration_tests;
mod signed_attestation;
mod signed_block;
mod slashing_database;
pub mod test_utils;
pub use crate::signed_attestation::{InvalidAttestation, SignedAttestation};
pub use crate::signed_block::{InvalidBlock, SignedBlock};
pub use crate::slashing_database::{
InterchangeImportOutcome, SlashingDatabase, SUPPORTED_INTERCHANGE_FORMAT_VERSION,
};
use rusqlite::Error as SQLError;
use std::io::{Error as IOError, ErrorKind};
use std::string::ToString;
use types::{Hash256, PublicKeyBytes};
/// The filename within the `validators` directory that contains the slashing protection DB.
pub const SLASHING_PROTECTION_FILENAME: &str = "slashing_protection.sqlite";
/// The attestation or block is not safe to sign.
///
/// This could be because it's slashable, or because an error occurred.
#[derive(PartialEq, Debug)]
pub enum NotSafe {
UnregisteredValidator(PublicKeyBytes),
InvalidBlock(InvalidBlock),
InvalidAttestation(InvalidAttestation),
PermissionsError,
IOError(ErrorKind),
SQLError(String),
SQLPoolError(String),
}
/// The attestation or block is safe to sign, and will not cause the signer to be slashed.
#[derive(PartialEq, Debug)]
pub enum Safe {
/// Casting the exact same data (block or attestation) twice is never slashable.
SameData,
/// Incoming data is safe from slashing, and is not a duplicate.
Valid,
}
/// A wrapper for `Hash256` that treats `0x0` as a special null value.
///
/// Notably `SigningRoot(0x0) != SigningRoot(0x0)`. It is `PartialEq` but not `Eq`!
#[derive(Debug, Clone, Copy, Default)]
pub struct SigningRoot(Hash256);
impl PartialEq for SigningRoot {
fn eq(&self, other: &Self) -> bool {
!self.0.is_zero() && self.0 == other.0
}
}
impl From<Hash256> for SigningRoot {
fn from(hash: Hash256) -> Self {
SigningRoot(hash)
}
}
impl Into<Hash256> for SigningRoot {
fn into(self) -> Hash256 {
self.0
}
}
impl SigningRoot {
fn to_hash256(self) -> Hash256 {
self.into()
}
}
/// Safely parse a `Hash256` from the given `column` of an SQLite `row`.
fn hash256_from_row(column: usize, row: &rusqlite::Row) -> rusqlite::Result<Hash256> {
use rusqlite::{types::Type, Error};
let bytes: Vec<u8> = row.get(column)?;
if bytes.len() == 32 {
Ok(Hash256::from_slice(&bytes))
} else {
Err(Error::FromSqlConversionFailure(
column,
Type::Blob,
Box::from(format!("Invalid length for Hash256: {}", bytes.len())),
))
}
}
impl From<IOError> for NotSafe {
fn from(error: IOError) -> NotSafe {
NotSafe::IOError(error.kind())
}
}
impl From<SQLError> for NotSafe {
fn from(error: SQLError) -> NotSafe {
NotSafe::SQLError(error.to_string())
}
}
impl From<r2d2::Error> for NotSafe {
fn from(error: r2d2::Error) -> Self {
// Use `Display` impl to print "timed out waiting for connection"
NotSafe::SQLPoolError(format!("{}", error))
}
}
impl ToString for NotSafe {
fn to_string(&self) -> String {
format!("{:?}", self)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
#[allow(clippy::eq_op)]
fn signing_root_partial_eq() {
let h0 = SigningRoot(Hash256::zero());
let h1 = SigningRoot(Hash256::repeat_byte(1));
let h2 = SigningRoot(Hash256::repeat_byte(2));
assert_ne!(h0, h0);
assert_ne!(h0, h1);
assert_ne!(h1, h0);
assert_eq!(h1, h1);
assert_ne!(h1, h2);
}
}