mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-20 05:14:35 +00:00
Optional slashing protection for remote keys (#4981)
* Optional slashing protection for remote keys * Merge remote-tracking branch 'origin/unstable' into disable-slashing-protection-web3signer * Start writing tests * Merge remote-tracking branch 'origin/unstable' into disable-slashing-protection-web3signer * Merge remote-tracking branch 'michael/disable-slashing-protection-web3signer' into disable-slashing-protection-web3signer * Make half-written tests compile * Make tests work * Update help text * Update book CLI text * Merge remote-tracking branch 'origin/unstable' into disable-slashing-protection-web3signer * More logging & CLI tests * CLI tweaks
This commit is contained in:
@@ -367,6 +367,17 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
||||
constructed by builders, regardless of payload value.")
|
||||
.takes_value(false),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("disable-slashing-protection-web3signer")
|
||||
.long("disable-slashing-protection-web3signer")
|
||||
.help("Disable Lighthouse's slashing protection for all web3signer keys. This can \
|
||||
reduce the I/O burden on the VC but is only safe if slashing protection \
|
||||
is enabled on the remote signer and is implemented correctly. DO NOT ENABLE \
|
||||
THIS FLAG UNLESS YOU ARE CERTAIN THAT SLASHING PROTECTION IS ENABLED ON \
|
||||
THE REMOTE SIGNER. YOU WILL GET SLASHED IF YOU USE THIS FLAG WITHOUT \
|
||||
ENABLING WEB3SIGNER'S SLASHING PROTECTION.")
|
||||
.takes_value(false)
|
||||
)
|
||||
/*
|
||||
* Experimental/development options.
|
||||
*/
|
||||
|
||||
@@ -76,6 +76,8 @@ pub struct Config {
|
||||
pub enable_latency_measurement_service: bool,
|
||||
/// Defines the number of validators per `validator/register_validator` request sent to the BN.
|
||||
pub validator_registration_batch_size: usize,
|
||||
/// Enable slashing protection even while using web3signer keys.
|
||||
pub enable_web3signer_slashing_protection: bool,
|
||||
/// Enables block production via the block v3 endpoint. This configuration option can be removed post deneb.
|
||||
pub produce_block_v3: bool,
|
||||
/// Specifies the boost factor, a percentage multiplier to apply to the builder's payload value.
|
||||
@@ -124,6 +126,7 @@ impl Default for Config {
|
||||
broadcast_topics: vec![ApiTopic::Subscriptions],
|
||||
enable_latency_measurement_service: true,
|
||||
validator_registration_batch_size: 500,
|
||||
enable_web3signer_slashing_protection: true,
|
||||
produce_block_v3: false,
|
||||
builder_boost_factor: None,
|
||||
prefer_builder_proposals: false,
|
||||
@@ -407,6 +410,19 @@ impl Config {
|
||||
return Err("validator-registration-batch-size cannot be 0".to_string());
|
||||
}
|
||||
|
||||
config.enable_web3signer_slashing_protection =
|
||||
if cli_args.is_present("disable-slashing-protection-web3signer") {
|
||||
warn!(
|
||||
log,
|
||||
"Slashing protection for remote keys disabled";
|
||||
"info" => "ensure slashing protection on web3signer is enabled or you WILL \
|
||||
get slashed"
|
||||
);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,20 @@ impl SigningContext {
|
||||
}
|
||||
|
||||
impl SigningMethod {
|
||||
/// Return whether this signing method requires local slashing protection.
|
||||
pub fn requires_local_slashing_protection(
|
||||
&self,
|
||||
enable_web3signer_slashing_protection: bool,
|
||||
) -> bool {
|
||||
match self {
|
||||
// Slashing protection is ALWAYS required for local keys. DO NOT TURN THIS OFF.
|
||||
SigningMethod::LocalKeystore { .. } => true,
|
||||
// Slashing protection is only required for remote signer keys when the configuration
|
||||
// dictates that it is desired.
|
||||
SigningMethod::Web3Signer { .. } => enable_web3signer_slashing_protection,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the signature of `signable_message`, with respect to the `signing_context`.
|
||||
pub async fn get_signature<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
&self,
|
||||
|
||||
@@ -97,6 +97,7 @@ pub struct ValidatorStore<T, E: EthSpec> {
|
||||
fee_recipient_process: Option<Address>,
|
||||
gas_limit: Option<u64>,
|
||||
builder_proposals: bool,
|
||||
enable_web3signer_slashing_protection: bool,
|
||||
produce_block_v3: bool,
|
||||
prefer_builder_proposals: bool,
|
||||
builder_boost_factor: Option<u64>,
|
||||
@@ -131,6 +132,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
fee_recipient_process: config.fee_recipient,
|
||||
gas_limit: config.gas_limit,
|
||||
builder_proposals: config.builder_proposals,
|
||||
enable_web3signer_slashing_protection: config.enable_web3signer_slashing_protection,
|
||||
produce_block_v3: config.produce_block_v3,
|
||||
prefer_builder_proposals: config.prefer_builder_proposals,
|
||||
builder_boost_factor: config.builder_boost_factor,
|
||||
@@ -604,19 +606,26 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
let signing_context = self.signing_context(Domain::BeaconProposer, signing_epoch);
|
||||
let domain_hash = signing_context.domain_hash(&self.spec);
|
||||
|
||||
let signing_method = self.doppelganger_checked_signing_method(validator_pubkey)?;
|
||||
|
||||
// Check for slashing conditions.
|
||||
let slashing_status = self.slashing_protection.check_and_insert_block_proposal(
|
||||
&validator_pubkey,
|
||||
&block.block_header(),
|
||||
domain_hash,
|
||||
);
|
||||
let slashing_status = if signing_method
|
||||
.requires_local_slashing_protection(self.enable_web3signer_slashing_protection)
|
||||
{
|
||||
self.slashing_protection.check_and_insert_block_proposal(
|
||||
&validator_pubkey,
|
||||
&block.block_header(),
|
||||
domain_hash,
|
||||
)
|
||||
} else {
|
||||
Ok(Safe::Valid)
|
||||
};
|
||||
|
||||
match slashing_status {
|
||||
// We can safely sign this block without slashing.
|
||||
Ok(Safe::Valid) => {
|
||||
metrics::inc_counter_vec(&metrics::SIGNED_BLOCKS_TOTAL, &[metrics::SUCCESS]);
|
||||
|
||||
let signing_method = self.doppelganger_checked_signing_method(validator_pubkey)?;
|
||||
let signature = signing_method
|
||||
.get_signature::<E, Payload>(
|
||||
SignableMessage::BeaconBlock(&block),
|
||||
@@ -672,20 +681,28 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
});
|
||||
}
|
||||
|
||||
// Get the signing method and check doppelganger protection.
|
||||
let signing_method = self.doppelganger_checked_signing_method(validator_pubkey)?;
|
||||
|
||||
// Checking for slashing conditions.
|
||||
let signing_epoch = attestation.data.target.epoch;
|
||||
let signing_context = self.signing_context(Domain::BeaconAttester, signing_epoch);
|
||||
let domain_hash = signing_context.domain_hash(&self.spec);
|
||||
let slashing_status = self.slashing_protection.check_and_insert_attestation(
|
||||
&validator_pubkey,
|
||||
&attestation.data,
|
||||
domain_hash,
|
||||
);
|
||||
let slashing_status = if signing_method
|
||||
.requires_local_slashing_protection(self.enable_web3signer_slashing_protection)
|
||||
{
|
||||
self.slashing_protection.check_and_insert_attestation(
|
||||
&validator_pubkey,
|
||||
&attestation.data,
|
||||
domain_hash,
|
||||
)
|
||||
} else {
|
||||
Ok(Safe::Valid)
|
||||
};
|
||||
|
||||
match slashing_status {
|
||||
// We can safely sign this attestation.
|
||||
Ok(Safe::Valid) => {
|
||||
let signing_method = self.doppelganger_checked_signing_method(validator_pubkey)?;
|
||||
let signature = signing_method
|
||||
.get_signature::<E, BlindedPayload<E>>(
|
||||
SignableMessage::AttestationData(&attestation.data),
|
||||
|
||||
Reference in New Issue
Block a user