diff --git a/beacon-chain/core/blocks/BUILD.bazel b/beacon-chain/core/blocks/BUILD.bazel index d564be7f1074..7ba2bc10bda5 100644 --- a/beacon-chain/core/blocks/BUILD.bazel +++ b/beacon-chain/core/blocks/BUILD.bazel @@ -60,6 +60,7 @@ go_test( "exit_test.go", "genesis_test.go", "header_test.go", + "proposer_slashing_regression_test.go", "proposer_slashing_test.go", "randao_test.go", ], diff --git a/beacon-chain/core/blocks/proposer_slashing.go b/beacon-chain/core/blocks/proposer_slashing.go index 4af10206b5eb..84caf8c3a325 100644 --- a/beacon-chain/core/blocks/proposer_slashing.go +++ b/beacon-chain/core/blocks/proposer_slashing.go @@ -4,13 +4,14 @@ import ( "context" "fmt" + "github.com/prysmaticlabs/prysm/shared/params" + "github.com/gogo/protobuf/proto" "github.com/pkg/errors" ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators" stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state" - "github.com/prysmaticlabs/prysm/shared/params" ) // ProcessProposerSlashings is one of the operations performed @@ -86,7 +87,7 @@ func VerifyProposerSlashing( if err != nil { return err } - if !helpers.IsSlashableValidatorUsingTrie(proposer, helpers.SlotToEpoch(hSlot)) { + if !helpers.IsSlashableValidatorUsingTrie(proposer, helpers.CurrentEpoch(beaconState)) { return fmt.Errorf("validator with key %#x is not slashable", proposer.PublicKey()) } headers := []*ethpb.SignedBeaconBlockHeader{slashing.Header_1, slashing.Header_2} @@ -96,6 +97,5 @@ func VerifyProposerSlashing( return errors.Wrap(err, "could not verify beacon block header") } } - return nil } diff --git a/beacon-chain/core/blocks/proposer_slashing_regression_test.go b/beacon-chain/core/blocks/proposer_slashing_regression_test.go new file mode 100644 index 000000000000..64a59382b495 --- /dev/null +++ b/beacon-chain/core/blocks/proposer_slashing_regression_test.go @@ -0,0 +1,38 @@ +package blocks_test + +import ( + "io/ioutil" + "testing" + + "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" + + ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" + stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state" + pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" + "github.com/prysmaticlabs/prysm/shared/testutil/require" +) + +// Beaconfuzz discovered an issue where a proposer slashing could be produced which would pass +// validation where we use the slashing's slot instead of the current epoch of our state for validation. +// This would lead to us accepting an invalid slashing by marking the respective validator as 'slashable' +// when it was not in actuality. +// See: https://github.com/sigp/beacon-fuzz/issues/91 +func TestVerifyProposerSlashing_BeaconFuzzIssue91(t *testing.T) { + file, err := ioutil.ReadFile("testdata/beaconfuzz_91_beacon.ssz") + require.NoError(t, err) + rawState := &pb.BeaconState{} + err = rawState.UnmarshalSSZ(file) + require.NoError(t, err) + + st, err := stateTrie.InitializeFromProtoUnsafe(rawState) + require.NoError(t, err) + + file, err = ioutil.ReadFile("testdata/beaconfuzz_91_proposer_slashing.ssz") + require.NoError(t, err) + slashing := ðpb.ProposerSlashing{} + err = slashing.UnmarshalSSZ(file) + require.NoError(t, err) + + err = blocks.VerifyProposerSlashing(st, slashing) + require.ErrorContains(t, "validator with key 0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb is not slashable", err) +} diff --git a/beacon-chain/core/blocks/testdata/beaconfuzz_91_beacon.ssz b/beacon-chain/core/blocks/testdata/beaconfuzz_91_beacon.ssz new file mode 100644 index 000000000000..268ee8f0df38 Binary files /dev/null and b/beacon-chain/core/blocks/testdata/beaconfuzz_91_beacon.ssz differ diff --git a/beacon-chain/core/blocks/testdata/beaconfuzz_91_proposer_slashing.ssz b/beacon-chain/core/blocks/testdata/beaconfuzz_91_proposer_slashing.ssz new file mode 100644 index 000000000000..f7bdaca3ac00 Binary files /dev/null and b/beacon-chain/core/blocks/testdata/beaconfuzz_91_proposer_slashing.ssz differ