Lighthouse: Implement slash protection

Created on 23 Feb 2019  路  12Comments  路  Source: sigp/lighthouse

Description

The validator client does not store the messages it signs and is therefore vulnerable to generating slashable messages

Steps to resolve

  • Determine a suitable database format.
  • Ensure all signed messages are stored in the database.
  • Ensure that newly signed messages are not in conflict with any previously signed messages.

Additional Info

Database formats

We want this database to be validator specific and portable. For example, I want to be able to move my validator from one machine to another, whilst maintaining that validators message history. As such, I suggest each validator has their own database, stored alongside their keys and config info (see #253 for suggestions on directory structure).

We should choose some single-process database that has high resistance to corruption.

val-client

All 12 comments

Hey @paulhauner, this something I could pick up?

Hey, thanks for reaching out.

@AgeManning is about to start a refactor of the validator client (primarily making it more async) so it's perhaps not the best time to start coding on this.

However, there's a bit of research that needs to happen first. Primarily about designing the schema of the database so it's space and time efficient. I'd be happy to work with you if you want to start thinking about data structures?

@paulhauner Yeah, that sounds good. Maybe after I've done a bit of digging on my own we could hop on a call and discuss what makes sense.

Sounds good!

I had a think about this. I think we can make a maximally safe (but not profit maximizing) system given the following rules:

  • Unless it is the validators first attestation, every attestation must have an attestation.data.target.epoch that is greater than it's previous attestation.

  • Unless it is the validators first block proposal, every block.slot must be in a greater epoch than it's previous block proposal.

I'm in favor of using this solution for now, unless we can easily think of a better solution.

To suit this, we only need to store:

struct ValidatorHistory {
  /// The `attestation.data.target.epoch` of the validators most recent attestation.
  previous_attestation_target_epoch: Option<Epoch>,
  /// The `epoch(block.slot)` of the validators most recent block proposal.
  previous_block_proposal_epoch: Option<Epoch>
}

I think we should store these parameters in a very simple file, perhaps just the SSZ representation of the above struct.

The validator client current stores it's keys in ~/.lighthouse-validator, one directory per validator. I think we should put that ValidatorHistory file in there, along with a lockfile. The lockfile should effectively restrict read/write of a validators directory to only one running lighthouse process.

@michaelsproul you might find this interesting :)

Would it be an improvement to only read the file upon initialization of the client and then use a threadsafe ValidatorHistory object stored in memory from then on, only writing to the file when it's updated or upon termination. I would imagine blocking messages on reading and writing to this file could be slow. Looking at the client code tho, I'm not sure where this would be stored.

This sounds like a sensible optimization!

Alright, well, sounds like that's pretty much set :) I'll get to coding this whenever the time is right.

Re: @paulhauner

I had a think about this. I think we can make a maximally safe (but not profit maximizing) system given the following rules:

  • Unless it is the validators first attestation, every attestation must have an attestation.data.target.epoch that is greater than it's previous attestation.

  • Unless it is the validators first block proposal, every block.slot must be in a greater epoch than it's previous block proposal.

I agree with these two maxims, but we need an extra one to guard against surround votes:

  • Every attestation must have an attestation.data.source.epoch that is greater than or equal to its previous attestation.

Otherwise you might sign an attestation which surrounds a previous one. The existing rules only guard against signing a new attestation surrounded by a previous one.

@michaelsproul, agreed. I was wrong.

I think it's safe to invalidate anything I've said here and work off the docs created by @pscott (I linked you to them in chat) :)

No worries, I just necrobumped this issue while trying to remember what the minimal safe algorithm was when reviewing Scott's algo.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wschwab picture wschwab  路  3Comments

paulhauner picture paulhauner  路  5Comments

q9f picture q9f  路  4Comments

plamarque picture plamarque  路  4Comments

michaelsproul picture michaelsproul  路  4Comments