Skip to content

Slasher HTTP API to import attestations from blocks #7110

Open
@michaelsproul

Description

@michaelsproul

In light of the recent Holesky incident, it may be useful to be able to manually import blocks and attestations to the slasher.

On Holesky, many slashers were shutdown during the non-finality period, meaning they missed the detection of many surround votes made by validators. One way we could get some of these slashings would be to manually feed blocks from the invalid chain to the slasher, so it can ingest the invalid attestations contained in those blocks and detect slashings.

The complication is, attestations in blocks require their BeaconState/committee to be converted into indexed attestations. And the slasher needs indexed attestations (it needs to know which validators are attesting to the bad chain).

So I think we probably need a few new endpoints:

Import attestations

  • Path: /lighthouse/slasher/import_attestations
  • Method: POST
  • Request body: Vec<IndexedAttestation>
  • Response: status code only

This endpoint is more important. It would import all of the indexed attestations to the slasher:

/// If a slasher is configured, provide the attestations from the block.
fn import_block_update_slasher(
&self,
block: BeaconBlockRef<T::EthSpec>,
state: &BeaconState<T::EthSpec>,
ctxt: &mut ConsensusContext<T::EthSpec>,
) {
if let Some(slasher) = self.slasher.as_ref() {
for attestation in block.body().attestations() {
let indexed_attestation = match ctxt.get_indexed_attestation(state, attestation) {
Ok(indexed) => indexed,
Err(e) => {
debug!(
self.log,
"Failed to get indexed attestation";
"purpose" => "slasher",
"attestation_slot" => attestation.data().slot,
"error" => ?e,
);
continue;
}
};
slasher.accept_attestation(indexed_attestation.clone_as_indexed_attestation());
}
}
}

Export indexed attestations

  • Path: /lighthouse/indexed_attestations
  • Method: POST
  • Request body: SignedBeaconBlock (or SignedBlindedBeaconBlock)
  • Response: Vec<IndexedAttestation>

This would need to be run on a node with the dodgy chain import (possibly imported via lcli http-sync). It would convert all of the attestations in the block into indexed attestations using the committees from the parent BeaconState.

These indexed attestations could then be saved to disk and plumbed into the /lighthouse/slasher/import_attestations endpoint.

Import block

  • Path: /lighthouse/slasher/import_block
  • Method: POST
  • Request body: SignedBeaconBlock (or SignedBlindedBeaconBlock?)
  • Response: status code only

This method is not as useful as I originally hoped, it would just be able to import the block header to the slasher due to the shuffling issue described above.

The implementation should pass the block itself to the slasher, probably using accept_block_header like in block verification:

slasher.accept_block_header(verified_header);

Metadata

Metadata

Assignees

No one assigned

    Labels

    HTTP-APIenhancementNew feature or requestnon-finalityBugs and optimisations related to networks that are not finalizingslasher

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions