mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-11 20:20:05 +00:00
f70635a992
* WIP add deposits * Modify validator component * Merge branch 'master' of https://github.com/prysmaticlabs/prysm into e2e-add-depsoits * Fix e2e * Merge branch 'master' of https://github.com/prysmaticlabs/prysm into e2e-add-depsoits * Merge branch 'master' of https://github.com/prysmaticlabs/prysm into e2e-add-depsoits * Start running with extra deposits * Begin adding evluator for e2e deposit * Get deposit E2E working * Add more rigorous testing for deposits * Merge branch 'master' of https://github.com/prysmaticlabs/prysm into e2e-add-depsoits * Improve policy for deposits * Fix build * Remove sync testing for long running e2e * Undo shard change * Undo unneeded changes * Adjust for comments * Merge branch 'master' into e2e-add-depsoits * Fix bug where long running E2E would always run * Merge branch 'master' of https://github.com/prysmaticlabs/prysm into e2e-add-depsoits * Merge branch 'e2e-add-depsoits' of https://github.com/0xKiwi/Prysm into e2e-add-depsoits * Merge branch 'master' into e2e-add-depsoits
183 lines
5.1 KiB
Go
183 lines
5.1 KiB
Go
package evaluators
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
ptypes "github.com/gogo/protobuf/types"
|
|
eth "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
|
"github.com/prysmaticlabs/go-bitfield"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
|
"github.com/prysmaticlabs/prysm/endtoend/types"
|
|
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
|
"github.com/prysmaticlabs/prysm/shared/params"
|
|
"github.com/prysmaticlabs/prysm/shared/sliceutil"
|
|
"github.com/prysmaticlabs/prysm/shared/testutil"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// InjectDoubleVote broadcasts a double vote into the beacon node pool for the slasher to detect.
|
|
var InjectDoubleVote = types.Evaluator{
|
|
Name: "inject_double_vote_%d",
|
|
Policy: beforeEpoch(2),
|
|
Evaluation: insertDoubleAttestationIntoPool,
|
|
}
|
|
|
|
// ValidatorsSlashed ensures the expected amount of validators are slashed.
|
|
var ValidatorsSlashed = types.Evaluator{
|
|
Name: "validators_slashed_epoch_%d",
|
|
Policy: afterNthEpoch(0),
|
|
Evaluation: validatorsSlashed,
|
|
}
|
|
|
|
// SlashedValidatorsLoseBalance checks if the validators slashed lose the right balance.
|
|
var SlashedValidatorsLoseBalance = types.Evaluator{
|
|
Name: "slashed_validators_lose_valance_epoch_%d",
|
|
Policy: afterNthEpoch(0),
|
|
Evaluation: validatorsLoseBalance,
|
|
}
|
|
|
|
var slashedIndices []uint64
|
|
|
|
// Not including first epoch because of issues with genesis.
|
|
func beforeEpoch(epoch uint64) func(uint64) bool {
|
|
return func(currentEpoch uint64) bool {
|
|
return currentEpoch < epoch
|
|
}
|
|
}
|
|
|
|
func validatorsSlashed(conns ...*grpc.ClientConn) error {
|
|
conn := conns[0]
|
|
ctx := context.Background()
|
|
client := eth.NewBeaconChainClient(conn)
|
|
req := ð.GetValidatorActiveSetChangesRequest{}
|
|
changes, err := client.GetValidatorActiveSetChanges(ctx, req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(changes.SlashedIndices) != 2 && len(changes.SlashedIndices) != 4 {
|
|
return fmt.Errorf("expected 2 or 4 indices to be slashed, received %d", len(changes.SlashedIndices))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validatorsLoseBalance(conns ...*grpc.ClientConn) error {
|
|
conn := conns[0]
|
|
ctx := context.Background()
|
|
client := eth.NewBeaconChainClient(conn)
|
|
|
|
for i, indice := range slashedIndices {
|
|
req := ð.GetValidatorRequest{
|
|
QueryFilter: ð.GetValidatorRequest_Index{
|
|
Index: indice,
|
|
},
|
|
}
|
|
valResp, err := client.GetValidator(ctx, req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
slashedPenalty := params.BeaconConfig().MaxEffectiveBalance / params.BeaconConfig().MinSlashingPenaltyQuotient
|
|
slashedBal := params.BeaconConfig().MaxEffectiveBalance - slashedPenalty + params.BeaconConfig().EffectiveBalanceIncrement/10
|
|
if valResp.EffectiveBalance >= slashedBal {
|
|
return fmt.Errorf(
|
|
"expected slashed validator %d to balance less than %d, received %d",
|
|
i,
|
|
slashedBal,
|
|
valResp.EffectiveBalance,
|
|
)
|
|
}
|
|
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func insertDoubleAttestationIntoPool(conns ...*grpc.ClientConn) error {
|
|
conn := conns[0]
|
|
valClient := eth.NewBeaconNodeValidatorClient(conn)
|
|
beaconClient := eth.NewBeaconChainClient(conn)
|
|
|
|
ctx := context.Background()
|
|
chainHead, err := beaconClient.GetChainHead(ctx, &ptypes.Empty{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, privKeys, err := testutil.DeterministicDepositsAndKeys(64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pubKeys := make([][]byte, len(privKeys))
|
|
for i, priv := range privKeys {
|
|
pubKeys[i] = priv.PublicKey().Marshal()
|
|
}
|
|
duties, err := valClient.GetDuties(ctx, ð.DutiesRequest{
|
|
Epoch: chainHead.HeadEpoch,
|
|
PublicKeys: pubKeys,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var committeeIndex uint64
|
|
var committee []uint64
|
|
for _, duty := range duties.Duties {
|
|
if duty.AttesterSlot == chainHead.HeadSlot-1 {
|
|
committeeIndex = duty.CommitteeIndex
|
|
committee = duty.Committee
|
|
break
|
|
}
|
|
}
|
|
|
|
attDataReq := ð.AttestationDataRequest{
|
|
CommitteeIndex: committeeIndex,
|
|
Slot: chainHead.HeadSlot - 1,
|
|
}
|
|
|
|
attData, err := valClient.GetAttestationData(ctx, attDataReq)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
blockRoot := bytesutil.ToBytes32([]byte("muahahahaha I'm an evil validator"))
|
|
attData.BeaconBlockRoot = blockRoot[:]
|
|
|
|
req := ð.DomainRequest{
|
|
Epoch: chainHead.HeadEpoch,
|
|
Domain: params.BeaconConfig().DomainBeaconAttester[:],
|
|
}
|
|
resp, err := valClient.DomainData(ctx, req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
signingRoot, err := helpers.ComputeSigningRoot(attData, resp.SignatureDomain)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
valsToSlash := uint64(2)
|
|
for i := uint64(0); i < valsToSlash && i < uint64(len(committee)); i++ {
|
|
if len(sliceutil.IntersectionUint64(slashedIndices, []uint64{committee[i]})) > 0 {
|
|
valsToSlash++
|
|
continue
|
|
}
|
|
// Set the bits of half the committee to be slashed.
|
|
attBitfield := bitfield.NewBitlist(uint64(len(committee)))
|
|
attBitfield.SetBitAt(i, true)
|
|
|
|
att := ð.Attestation{
|
|
AggregationBits: attBitfield,
|
|
Data: attData,
|
|
Signature: privKeys[committee[i]].Sign(signingRoot[:]).Marshal(),
|
|
}
|
|
for _, conn := range conns {
|
|
client := eth.NewBeaconNodeValidatorClient(conn)
|
|
_, err = client.ProposeAttestation(ctx, att)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
slashedIndices = append(slashedIndices, committee[i])
|
|
}
|
|
return nil
|
|
}
|