# Blacklisting Slashable Keys ## Goal To define a strategy for safely blacklisting slashable public keys as found during importing an EIP-3076, JSON slashing protection history in Prysm ## Background The Ethereum Magicians post on [EIP-3076 slashing protection](https://ethereum-magicians.org/t/eip-3076-validator-client-interchange-format-slashing-protection/4883/2) details the following recommendation: **Importing Slashable Data** It’s possible for an interchange file to contain blocks and attestations that are mutually slashable, i.e. the interchange file contains evidence that the validator has already committed a slashable offence. It’s also possible for an interchange to contain messages that are slashable with respect to ones already in the database. Our options: - ACCEPT: require implementations to import files even if they contain slashable data - ACCEPT_PARTIAL: require implementations to import all validators that are not slashable, and reject all that are slashable - REJECT: require implementations to reject any imported file if it contains slashable data - ABSTAIN: allow implementations to choose a semantics that works for them After discussion with client teams, the EIP now recommends to go with **ACCEPT_PARTIAL**. This means that we should check for slashable public keys in the JSON file appropriately and **reject** importing the data for keys that are slashable. There is a big caveat with the requirement above in Prysm, however. ## The Problem Our slashing interchange import and export functions have no knowledge of the user's wallet. The only information they have are the validator database itself. For example: ```go func ImportSlashingInterchangeJSON(validatorDB db.Database, r io.Reader) error ``` and ```go func ExportSlashingInterchangeJSON(validatorDB db.Database) (*EIPStandardFormat, error) ``` During the import process, if we find **slashable public keys** within the JSON file, we reject importing those entries into our DB. However, we also need to **prevent** the validator client from validating with those keys next time it launches. We have no way to do this today in Prysm. ## Possible Solutions ### Store Blacklisted Keys in the DB Upon importing a JSON file, detect which public keys are slashable with respect to entries within the file and save them in a bucket in boltDB using a function `SaveBlacklistedPublicKeys`. Then, at runtime, we prevent performing duties if those keys are blacklisted in the DB by loading them at runtime in the validator client. Pros: - Easy to implement these functions in the DB - Easy to integrate with the current implementation of slashing interchange import/export Cons: - Requires changes to how the validator client's logic works, requiring us to do a DB read to prevent proposing/attesting/aggregating if a public key is in the blacklisted keys in the database. Implementation risk touching a critical code path ### Store the Blacklisted Keys in the Wallet Instead of storing in the DB, we can store a list of blacklisted public keys as an entry in Prysm wallets' all-accounts.keystore.json files. This means the slashing interchange import/export functions would need to knwo about the wallet _and_ the validator DB. Pros: - No changes required to the validator client runtime, instead, when we call `keymanager.FetchValidatingPublicKeys()`, we only return those which are not blacklisted, and the validator can function as usual with those blacklisted keys not performing duties - We already have similar logic for enabled/disabled public keys in the keymanager implementation, we could also add an entry for blacklisted keys Cons: - The import/export functions will also need access to the user's wallet, which can get complex from a CLI standpoint - The logic is no longer all self-contained to the validator DB - Depends on keymanager implementation - Harder to write integration tests for this