syntax = "proto3"; package ethereum.slashing; import "eth/v1alpha1/beacon_block.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; // Slasher service API // // Slasher service provides an interface for validators and beacon chain server to query // and subscribe for slashable events on the network as well as to make sure that the // attestation or proposal they are going to submit to the network are not going to // produce a slashable event. service Slasher { // Gets AttesterSlashing container if the attestation that // was received produces a slashable event. rpc IsSlashableAttestation(ethereum.eth.v1alpha1.IndexedAttestation) returns (AttesterSlashingResponse); // Gets ProposerSlashing container if the block header that // was received produces a slashable event. rpc IsSlashableBlock(ProposerSlashingRequest) returns (ProposerSlashingResponse); // Gets ProposerSlashingResponse container if slashing with the requested status are found in the db. rpc ProposerSlashings(SlashingStatusRequest) returns (ProposerSlashingResponse); // Gets AttesterSlashingResponse container if slashing with the requested status are found in the db. rpc AttesterSlashings(SlashingStatusRequest) returns (AttesterSlashingResponse); } // CompressedIdxAtt is an indexed attestation with the []byte data root // in place of its AttestationData. message CompressedIdxAtt { repeated uint64 indices = 1 ; bytes data_root = 2; // 96 bytes aggregate signature. bytes signature = 3; } // CompressedIdxAttList is a list of CompressedIdxAtts used for // accessing an array from the DB. message CompressedIdxAttList { repeated CompressedIdxAtt list = 1; } message ProposerSlashingRequest { ethereum.eth.v1alpha1.SignedBeaconBlockHeader block_header = 1; uint64 validator_index = 2; } message ProposerSlashingResponse { repeated ethereum.eth.v1alpha1.ProposerSlashing proposer_slashing = 1; } message AttesterSlashingResponse { repeated ethereum.eth.v1alpha1.AttesterSlashing attester_slashing = 1; } // In order to detect surrounded attestation we need to compare // each attestation source to those spans // see https://github.com/protolambda/eth2-surround/blob/master/README.md#min-max-surround // for further details. message MinMaxEpochSpan { uint32 min_epoch_span = 1; uint32 max_epoch_span = 2; } // Every validator will have their own spans map containing min distance from each epoch // to the closest target epoch of another attestation (surrounded) and max distance to // a target attestation (surrounding), in order to detect slashable attestation as quickly // as possible. message EpochSpanMap { // uint64 is for storing the epoch map epoch_span_map = 1; } // ProposalHistory defines the structure for recording a validator's historical proposals. // Using a bitlist to represent the epochs and an uint64 to mark the latest marked // epoch of the bitlist, we can easily store which epochs a validator has proposed // a block for while pruning the older data. message ProposalHistory { bytes epoch_bits = 1 [(gogoproto.casttype) = "github.com/prysmaticlabs/go-bitfield.Bitlist"]; uint64 latest_epoch_written = 2; } // AttestationHistory defines the structure for recording a validator's historical attestation. // Using a map[uint64]uint64 to map its target epoch to its source epoch, in order to detect if a // vote being created is not a double vote and surrounded by, or surrounding any other votes. // Using an uint64 to mark the latest written epoch, we can safely perform a rolling prune whenever // the history is updated. message AttestationHistory { map target_to_source = 1; uint64 latest_epoch_written = 2; } message SlashingStatusRequest { enum SlashingStatus { // Unknown default status in case it is not set Unknown = 0; // Active slashing proof hasn't been included yet. Active = 1; // Included slashing proof that has been included in a block. Included = 2; // Reverted slashing proof that has been reverted and therefore is relevant again. Reverted = 3; } SlashingStatus status = 1; }