Add proposer slashing tests (#431)
* Add proposer slashing tests * typo in import
This commit is contained in:
parent
f4a3e47a61
commit
8676bbf388
|
@ -140,37 +140,41 @@ func is_slashable_validator(validator: Validator, epoch: Epoch): bool =
|
|||
(epoch < validator.withdrawable_epoch)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.3/specs/core/0_beacon-chain.md#proposer-slashings
|
||||
proc process_proposer_slashing(
|
||||
proc process_proposer_slashing*(
|
||||
state: var BeaconState, proposer_slashing: ProposerSlashing,
|
||||
flags: UpdateFlags, stateCache: var StateCache): bool =
|
||||
if proposer_slashing.proposer_index.int >= state.validators.len:
|
||||
notice "Proposer slashing: invalid proposer index"
|
||||
return false
|
||||
|
||||
let proposer = state.validators[proposer_slashing.proposer_index.int]
|
||||
|
||||
# Verify that the epoch is the same
|
||||
if not (compute_epoch_of_slot(proposer_slashing.header_1.slot) ==
|
||||
compute_epoch_of_slot(proposer_slashing.header_2.slot)):
|
||||
notice "PropSlash: epoch mismatch"
|
||||
notice "Proposer slashing: epoch mismatch"
|
||||
return false
|
||||
|
||||
# But the headers are different
|
||||
if not (proposer_slashing.header_1 != proposer_slashing.header_2):
|
||||
notice "PropSlash: headers not different"
|
||||
notice "Proposer slashing: headers not different"
|
||||
return false
|
||||
|
||||
# Check proposer is slashable
|
||||
if not is_slashable_validator(proposer, get_current_epoch(state)):
|
||||
notice "PropSlash: slashed proposer"
|
||||
notice "Proposer slashing: slashed proposer"
|
||||
return false
|
||||
|
||||
# Signatures are valid
|
||||
if skipValidation notin flags:
|
||||
for i, header in @[proposer_slashing.header_1, proposer_slashing.header_2]:
|
||||
for i, header in [proposer_slashing.header_1, proposer_slashing.header_2]:
|
||||
if not bls_verify(
|
||||
proposer.pubkey,
|
||||
signing_root(header).data,
|
||||
header.signature,
|
||||
get_domain(
|
||||
state, DOMAIN_BEACON_PROPOSER, compute_epoch_of_slot(header.slot))):
|
||||
notice "PropSlash: invalid signature",
|
||||
notice "Proposer slashing: invalid signature",
|
||||
signature_index = i
|
||||
return false
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import
|
|||
./test_fixture_sanity_blocks,
|
||||
./test_fixture_state_transition_epoch,
|
||||
./test_fixture_operations_attestations,
|
||||
./test_fixture_operations_attester_slashings,
|
||||
./test_fixture_operations_block_header,
|
||||
./test_fixture_operations_voluntary_exit,
|
||||
./test_fixture_operations_attester_slashings
|
||||
./test_fixture_operations_proposer_slashings,
|
||||
./test_fixture_operations_voluntary_exit
|
|
@ -0,0 +1,76 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2018-Present Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
# Standard library
|
||||
os, unittest, strutils,
|
||||
# Beacon chain internals
|
||||
../../beacon_chain/spec/[datatypes, state_transition_block, validator],
|
||||
../../beacon_chain/[ssz, extras],
|
||||
# Test utilities
|
||||
../testutil,
|
||||
./fixtures_utils,
|
||||
../helpers/debug_state
|
||||
|
||||
const OpProposerSlashingDir = SszTestsDir/const_preset/"phase0"/"operations"/"proposer_slashing"/"pyspec_tests"
|
||||
|
||||
template runTest(identifier: untyped) =
|
||||
# We wrap the tests in a proc to avoid running out of globals
|
||||
# in the future: Nim supports up to 3500 globals
|
||||
# but unittest with the macro/templates put everything as globals
|
||||
# https://github.com/nim-lang/Nim/issues/12084#issue-486866402
|
||||
|
||||
const testDir = OpProposerSlashingDir / astToStr(identifier)
|
||||
|
||||
proc `testImpl_proposer_slashing _ identifier`() =
|
||||
|
||||
var flags: UpdateFlags
|
||||
var prefix: string
|
||||
if not existsFile(testDir/"meta.yaml"):
|
||||
flags.incl skipValidation
|
||||
if existsFile(testDir/"post.ssz"):
|
||||
prefix = "[Valid] "
|
||||
else:
|
||||
prefix = "[Invalid] "
|
||||
|
||||
test prefix & astToStr(identifier):
|
||||
var stateRef, postRef: ref BeaconState
|
||||
var proposerSlashing: ref ProposerSlashing
|
||||
new proposerSlashing
|
||||
new stateRef
|
||||
|
||||
proposerSlashing[] = parseTest(testDir/"proposer_slashing.ssz", SSZ, ProposerSlashing)
|
||||
stateRef[] = parseTest(testDir/"pre.ssz", SSZ, BeaconState)
|
||||
|
||||
if existsFile(testDir/"post.ssz"):
|
||||
new postRef
|
||||
postRef[] = parseTest(testDir/"post.ssz", SSZ, BeaconState)
|
||||
|
||||
var cache = get_empty_per_epoch_cache()
|
||||
|
||||
if postRef.isNil:
|
||||
let done = process_proposer_slashing(stateRef[], proposerSlashing[], flags, cache)
|
||||
doAssert done == false, "We didn't expect this invalid proposer slashing to be processed."
|
||||
else:
|
||||
let done = process_proposer_slashing(stateRef[], proposerSlashing[], flags, cache)
|
||||
doAssert done, "Valid proposer slashing not processed"
|
||||
check: stateRef.hash_tree_root() == postRef.hash_tree_root()
|
||||
reportDiff(stateRef, postRef)
|
||||
|
||||
`testImpl_proposer_slashing _ identifier`()
|
||||
|
||||
suite "Official - Operations - Proposer slashing " & preset():
|
||||
runTest(success)
|
||||
runTest(invalid_sig_1)
|
||||
runTest(invalid_sig_2)
|
||||
runTest(invalid_sig_1_and_2)
|
||||
runTest(invalid_proposer_index)
|
||||
runTest(epochs_are_different)
|
||||
runTest(headers_are_same)
|
||||
runTest(proposer_is_not_activated)
|
||||
runTest(proposer_is_slashed)
|
||||
runTest(proposer_is_withdrawn)
|
Loading…
Reference in New Issue