Skip to content

Commit

Permalink
TestingKeyManager: Slashing by Slot (#449)
Browse files Browse the repository at this point in the history
* Use slots instead of data root to do slashing check

* Adjust ValCheck SpecTest to use slashable slots

* Adjust test cases

* Add test case for a valid BeaconVote with a slot that is different than the slashable slot
  • Loading branch information
MatheusFranco99 authored Jul 4, 2024
1 parent 8f8c8d7 commit b072467
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 81 deletions.
1 change: 1 addition & 0 deletions ssv/spectest/all_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ var AllTests = []tests.TestF{
valcheckattestations.Valid,
valcheckattestations.MinoritySlashable,
valcheckattestations.MajoritySlashable,
valcheckattestations.ValidNonSlashableSlot,

valcheckproposer.BlindedBlock,

Expand Down
Binary file modified ssv/spectest/generate/tests.json.gz
Binary file not shown.
4 changes: 2 additions & 2 deletions ssv/spectest/tests/msg_processing_spectest.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ func (test *MsgProcessingSpecTest) runPreTesting() (*ssv.Validator, *ssv.Committ
}
if test.DecidedSlashable && IsQBFTProposalMessage(msg) {
for _, validatorShare := range test.Runner.GetBaseRunner().Share {
test.Runner.GetSigner().(*testingutils.TestingKeyManager).AddSlashableDataRoot(validatorShare.
SharePubKey, testingutils.TestingAttestationDataRoot[:])
test.Runner.GetSigner().(*testingutils.TestingKeyManager).AddSlashableSlot(validatorShare.
SharePubKey, testingutils.TestingAttestationData.Slot)
}
}
}
Expand Down
24 changes: 13 additions & 11 deletions ssv/spectest/tests/valcheck/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package valcheck
import (
"testing"

"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/ssvlabs/ssv-spec/qbft"
"github.com/ssvlabs/ssv-spec/ssv"
"github.com/ssvlabs/ssv-spec/types"
Expand All @@ -11,14 +12,15 @@ import (
)

type SpecTest struct {
Name string
Network types.BeaconNetwork
RunnerRole types.RunnerRole
Input []byte
SlashableDataRoots map[string][][]byte // map share pk to a list of slashable data roots
ShareValidatorsPK []types.ShareValidatorPK `json:"omitempty"` // Optional. Specify validators shares for beacon vote value check
ExpectedError string
AnyError bool
Name string
Network types.BeaconNetwork
RunnerRole types.RunnerRole
DutySlot phase0.Slot // DutySlot is used only for the RoleCommittee since the BeaconVoteValueCheckF requires the duty's slot
Input []byte
SlashableSlots map[string][]phase0.Slot // map share pk to a list of slashable slots
ShareValidatorsPK []types.ShareValidatorPK `json:"omitempty"` // Optional. Specify validators shares for beacon vote value check
ExpectedError string
AnyError bool
}

func (test *SpecTest) TestName() string {
Expand All @@ -27,8 +29,8 @@ func (test *SpecTest) TestName() string {

func (test *SpecTest) Run(t *testing.T) {
signer := testingutils.NewTestingKeyManager()
if len(test.SlashableDataRoots) > 0 {
signer = testingutils.NewTestingKeyManagerWithSlashableRoots(test.SlashableDataRoots)
if len(test.SlashableSlots) > 0 {
signer = testingutils.NewTestingKeyManagerWithSlashableSlots(test.SlashableSlots)
}

check := test.valCheckF(signer)
Expand Down Expand Up @@ -58,7 +60,7 @@ func (test *SpecTest) valCheckF(signer types.BeaconSigner) qbft.ProposedValueChe
}
switch test.RunnerRole {
case types.RoleCommittee:
return ssv.BeaconVoteValueCheckF(signer, testingutils.TestingDutySlot, shareValidatorsPK,
return ssv.BeaconVoteValueCheckF(signer, test.DutySlot, shareValidatorsPK,
testingutils.TestingDutyEpoch)
case types.RoleProposer:
return ssv.ProposerValueCheckF(signer, test.Network, pubKeyBytes, testingutils.TestingValidatorIndex, nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests/valcheck"
"github.com/ssvlabs/ssv-spec/types"
"github.com/ssvlabs/ssv-spec/types/testingutils"
)

// BeaconVoteDataNil tests consensus data != nil
Expand All @@ -18,6 +19,7 @@ func BeaconVoteDataNil() tests.SpecTest {
Name: "consensus data value check nil",
Network: types.PraterNetwork,
RunnerRole: types.RoleCommittee,
DutySlot: testingutils.TestingDutySlot,
Input: input,
ExpectedError: "attestation data source >= target",
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests/valcheck"
"github.com/ssvlabs/ssv-spec/types"
"github.com/ssvlabs/ssv-spec/types/testingutils"
)

// FarFutureTarget tests AttestationData.Target.Epoch higher than expected
Expand All @@ -27,6 +28,7 @@ func FarFutureTarget() tests.SpecTest {
Name: "attestation value check far future target",
Network: types.BeaconTestNetwork,
RunnerRole: types.RoleCommittee,
DutySlot: testingutils.TestingDutySlot,
Input: input,
ExpectedError: "attestation data target epoch is into far future",
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package valcheckattestations

import (
"encoding/hex"
"math"

"github.com/attestantio/go-eth2-client/spec/phase0"
spec "github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests/valcheck"
Expand All @@ -25,16 +25,6 @@ func MajoritySlashable() tests.SpecTest {
},
}

attestationData := &spec.AttestationData{
Slot: testingutils.TestingDutySlot,
Index: math.MaxUint64,
BeaconBlockRoot: data.BlockRoot,
Source: data.Source,
Target: data.Target,
}

r, _ := attestationData.HashTreeRoot()

input, _ := data.Encode()

// Get shares
Expand All @@ -48,18 +38,19 @@ func MajoritySlashable() tests.SpecTest {
}

// Make slashable map with majority
slashableMap := make(map[string][][]byte)
slashableMap := make(map[string][]phase0.Slot)
for i := 0; i < int(keySet.Threshold); i++ {
slashableMap[sharesPKString[i]] = [][]byte{r[:]}
slashableMap[sharesPKString[i]] = []phase0.Slot{testingutils.TestingDutySlot}
}

return &valcheck.SpecTest{
Name: "attestation value check with slashable majority",
Network: types.BeaconTestNetwork,
RunnerRole: types.RoleCommittee,
Input: input,
ExpectedError: "slashable attestation",
SlashableDataRoots: slashableMap,
ShareValidatorsPK: sharesPKBytes,
Name: "attestation value check with slashable majority",
Network: types.BeaconTestNetwork,
RunnerRole: types.RoleCommittee,
DutySlot: testingutils.TestingDutySlot,
Input: input,
ExpectedError: "slashable attestation",
SlashableSlots: slashableMap,
ShareValidatorsPK: sharesPKBytes,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package valcheckattestations

import (
"encoding/hex"
"math"

"github.com/attestantio/go-eth2-client/spec/phase0"
spec "github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests/valcheck"
Expand All @@ -25,16 +25,6 @@ func MinoritySlashable() tests.SpecTest {
},
}

attestationData := &spec.AttestationData{
Slot: testingutils.TestingDutySlot,
Index: math.MaxUint64,
BeaconBlockRoot: data.BlockRoot,
Source: data.Source,
Target: data.Target,
}

r, _ := attestationData.HashTreeRoot()

input, _ := data.Encode()

// Get shares
Expand All @@ -48,19 +38,20 @@ func MinoritySlashable() tests.SpecTest {
}

// Make slashable map with minority
slashableMap := map[string][][]byte{
slashableMap := map[string][]phase0.Slot{
sharesPKString[0]: {
r[:],
testingutils.TestingDutySlot,
},
}

return &valcheck.SpecTest{
Name: "attestation value check with slashable minority",
Network: types.BeaconTestNetwork,
RunnerRole: types.RoleCommittee,
Input: input,
ExpectedError: "slashable attestation",
SlashableDataRoots: slashableMap,
ShareValidatorsPK: sharesPKBytes,
Name: "attestation value check with slashable minority",
Network: types.BeaconTestNetwork,
RunnerRole: types.RoleCommittee,
DutySlot: testingutils.TestingDutySlot,
Input: input,
ExpectedError: "slashable attestation",
SlashableSlots: slashableMap,
ShareValidatorsPK: sharesPKBytes,
}
}
17 changes: 4 additions & 13 deletions ssv/spectest/tests/valcheck/valcheckattestations/slashable.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package valcheckattestations

import (
"encoding/hex"
"math"

"github.com/attestantio/go-eth2-client/spec/phase0"
spec "github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests/valcheck"
Expand All @@ -25,16 +25,6 @@ func Slashable() tests.SpecTest {
},
}

attestationData := &spec.AttestationData{
Slot: testingutils.TestingDutySlot,
Index: math.MaxUint64,
BeaconBlockRoot: data.BlockRoot,
Source: data.Source,
Target: data.Target,
}

r, _ := attestationData.HashTreeRoot()

input, _ := data.Encode()

keySet := testingutils.Testing4SharesSet()
Expand All @@ -45,11 +35,12 @@ func Slashable() tests.SpecTest {
Name: "attestation value check slashable",
Network: types.BeaconTestNetwork,
RunnerRole: types.RoleCommittee,
DutySlot: testingutils.TestingDutySlot,
Input: input,
ExpectedError: "slashable attestation",
SlashableDataRoots: map[string][][]byte{
SlashableSlots: map[string][]phase0.Slot{
shareString: {
r[:],
testingutils.TestingDutySlot,
},
},
ShareValidatorsPK: []types.ShareValidatorPK{sharePKBytes},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests/valcheck"
"github.com/ssvlabs/ssv-spec/types"
"github.com/ssvlabs/ssv-spec/types/testingutils"
)

// SourceHigherThanTarget tests AttestationData.Source.Epoch higher than target
Expand All @@ -27,6 +28,7 @@ func SourceHigherThanTarget() tests.SpecTest {
Name: "attestation value check source higher than target",
Network: types.BeaconTestNetwork,
RunnerRole: types.RoleCommittee,
DutySlot: testingutils.TestingDutySlot,
Input: input,
ExpectedError: "attestation data source >= target",
}
Expand Down
1 change: 1 addition & 0 deletions ssv/spectest/tests/valcheck/valcheckattestations/valid.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func Valid() tests.SpecTest {
Name: "attestation value check valid",
Network: types.PraterNetwork,
RunnerRole: types.RoleCommittee,
DutySlot: testingutils.TestingDutySlot,
Input: testingutils.TestBeaconVoteByts,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package valcheckattestations

import (
"encoding/hex"

"github.com/attestantio/go-eth2-client/spec/phase0"
spec "github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests"
"github.com/ssvlabs/ssv-spec/ssv/spectest/tests/valcheck"
"github.com/ssvlabs/ssv-spec/types"
"github.com/ssvlabs/ssv-spec/types/testingutils"
)

// ValidNonSlashableSlot tests a valid AttestationData with a slot that is not slashable
func ValidNonSlashableSlot() tests.SpecTest {
data := &types.BeaconVote{
BlockRoot: spec.Root{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2},
Source: &spec.Checkpoint{
Epoch: 0,
Root: spec.Root{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2},
},
Target: &spec.Checkpoint{
Epoch: 1,
Root: spec.Root{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2},
},
}

input, _ := data.Encode()

keySet := testingutils.Testing4SharesSet()
sharePKBytes := keySet.Shares[1].Serialize()
shareString := hex.EncodeToString(sharePKBytes)

return &valcheck.SpecTest{
Name: "attestation valid with non slashable slot",
Network: types.BeaconTestNetwork,
RunnerRole: types.RoleCommittee,
DutySlot: testingutils.TestingDutySlot + 1,
Input: input,
SlashableSlots: map[string][]phase0.Slot{
shareString: {
testingutils.TestingDutySlot,
},
},
ShareValidatorsPK: []types.ShareValidatorPK{sharePKBytes},
}
}
Loading

0 comments on commit b072467

Please sign in to comment.