Builds on and supersedes paritytech/substrate#14520.
The original scope was to support slashing validators equivocating by virtue of a gossiped vote which votes on a fork that has not been finalized.
This PR's aim differs in the following ways:
we do not slash for voting on unfinalized payloads, but rather for payloads that differ from the payload known to the runtime. As such, we do not check GRANDPA finalization.
while slashing equivocations detected in votes is also supported, the scope is extended to (and the focus placed on) equivocations detected in a SignedCommitment
Rationale for 1.
Since GRANDPA finalization proof is not checked, which leads to slashing on
forks that may not be finalized. This is fine since honest validators will not be slashed on the chain finalized by GRANDPA, which is the only chain that ultimately matters. The only material difference not checking GRANDPA proofs makes is that validators are not slashed for signing BEEFY commitments prior to the blocks committed to being finalized by GRANDPA. This is fine too, since the slashing risk of committing to an incorrect block implies validators will only sign blocks they know will be finalized by GRANDPA.
Rationale for 2.
While dishonest might gossip their equivocating votes via the standard gossip protocol, this hurts the prospect of their attack, and opens the door for the colluders to get slashed even if they don't ultimately carry out the attack on, for instance, the Ethereum bridge. Instead, we should face the reality that we will likely only detect the attack once it is carried out, that is: an equivocating payload of a submitInitial/submitInitialWithHandover call is detected in Ethereum's mempool / a block.
Proposed Solution
Runtime
two new extrinsic submission calls in pallet_beefy: submit_unsigned_vote_equivocation_report (previously report_equivocation) for vote equivocations (VoteEquivocationProof), and submit_unsigned_fork_equivocation_report for fork equivocations (ForkEquivocationProof), the latter whether detected in votes, SignedCommitment, or VersionedFinalityProof
verify commitment's mmr_root != on-chain mmr_root
report offense to staking so offending vote author / SignedCommitment signatories get slashed
Client-side
adds "fisherman" capabilities to voter gossip - on detecting votes for historical forks, it builds the required proof of misbehavior and submits report.
Closes paritytech/polkadot-sdk#1120
TODOs
[ ] Polkadot companion
[ ] Fish for equivocations on Ethereum (not scope of this PR - [best home is probably Snowfork's relayer])
[ ] More robust mechanism than <frame_system::Pallet<System>>::block_hash for verifying header included in ForkEquivocationProof
Description
Builds on and supersedes paritytech/substrate#14520. The original scope was to support slashing validators equivocating by virtue of a gossiped vote which votes on a fork that has not been finalized.
This PR's aim differs in the following ways:
SignedCommitment
Rationale for 1.
Since GRANDPA finalization proof is not checked, which leads to slashing on forks that may not be finalized. This is fine since honest validators will not be slashed on the chain finalized by GRANDPA, which is the only chain that ultimately matters. The only material difference not checking GRANDPA proofs makes is that validators are not slashed for signing BEEFY commitments prior to the blocks committed to being finalized by GRANDPA. This is fine too, since the slashing risk of committing to an incorrect block implies validators will only sign blocks they know will be finalized by GRANDPA.
Rationale for 2.
While dishonest might gossip their equivocating votes via the standard gossip protocol, this hurts the prospect of their attack, and opens the door for the colluders to get slashed even if they don't ultimately carry out the attack on, for instance, the Ethereum bridge. Instead, we should face the reality that we will likely only detect the attack once it is carried out, that is: an equivocating payload of a
submitInitial
/submitInitialWithHandover
call is detected in Ethereum's mempool / a block.Proposed Solution
Runtime
pallet_beefy
:submit_unsigned_vote_equivocation_report
(previouslyreport_equivocation
) for vote equivocations (VoteEquivocationProof
), andsubmit_unsigned_fork_equivocation_report
for fork equivocations (ForkEquivocationProof
), the latter whether detected in votes,SignedCommitment
, orVersionedFinalityProof
mmr_root
!= on-chainmmr_root
SignedCommitment
signatories get slashedClient-side
Closes paritytech/polkadot-sdk#1120
TODOs
<frame_system::Pallet<System>>::block_hash
for verifying header included inForkEquivocationProof