mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Slasher: Remove unused RPC. (#13594)
This commit is contained in:
@@ -896,7 +896,6 @@ func (b *BeaconNode) registerRPCService(router *mux.Router) error {
|
||||
ExitPool: b.exitPool,
|
||||
SlashingsPool: b.slashingsPool,
|
||||
BLSChangesPool: b.blsToExecPool,
|
||||
SlashingChecker: slasherService,
|
||||
SyncCommitteeObjectPool: b.syncCommitteePool,
|
||||
ExecutionChainService: web3Service,
|
||||
ExecutionChainInfoFetcher: web3Service,
|
||||
|
||||
@@ -44,7 +44,6 @@ go_library(
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/node:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/v1alpha1/validator:go_default_library",
|
||||
"//beacon-chain/rpc/prysm/validator:go_default_library",
|
||||
"//beacon-chain/slasher:go_default_library",
|
||||
"//beacon-chain/startup:go_default_library",
|
||||
"//beacon-chain/state/stategen:go_default_library",
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
|
||||
@@ -57,7 +57,6 @@ import (
|
||||
debugv1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/debug"
|
||||
nodev1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/node"
|
||||
validatorv1alpha1 "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/v1alpha1/validator"
|
||||
slasherservice "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/startup"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stategen"
|
||||
chainSync "github.com/prysmaticlabs/prysm/v4/beacon-chain/sync"
|
||||
@@ -112,7 +111,6 @@ type Config struct {
|
||||
AttestationsPool attestations.Pool
|
||||
ExitPool voluntaryexits.PoolManager
|
||||
SlashingsPool slashings.PoolManager
|
||||
SlashingChecker slasherservice.SlashingChecker
|
||||
SyncCommitteeObjectPool synccommittee.Pool
|
||||
BLSChangesPool blstoexec.PoolManager
|
||||
SyncService chainSync.Checker
|
||||
|
||||
@@ -14,7 +14,6 @@ go_library(
|
||||
"process_slashings.go",
|
||||
"queue.go",
|
||||
"receive.go",
|
||||
"rpc.go",
|
||||
"service.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher",
|
||||
@@ -47,8 +46,6 @@ go_library(
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
"@org_golang_google_grpc//codes:go_default_library",
|
||||
"@org_golang_google_grpc//status:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -63,7 +60,6 @@ go_test(
|
||||
"process_slashings_test.go",
|
||||
"queue_test.go",
|
||||
"receive_test.go",
|
||||
"rpc_test.go",
|
||||
"service_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package slasher
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/time/slots"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// HighestAttestations committed for an input list of validator indices.
|
||||
func (s *Service) HighestAttestations(
|
||||
ctx context.Context, validatorIndices []primitives.ValidatorIndex,
|
||||
) ([]*ethpb.HighestAttestation, error) {
|
||||
atts, err := s.serviceCfg.Database.HighestAttestations(ctx, validatorIndices)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get highest attestations from database")
|
||||
}
|
||||
return atts, nil
|
||||
}
|
||||
|
||||
// IsSlashableBlock checks if an input block header is slashable
|
||||
// with respect to historical block proposal data.
|
||||
func (s *Service) IsSlashableBlock(
|
||||
ctx context.Context, block *ethpb.SignedBeaconBlockHeader,
|
||||
) (*ethpb.ProposerSlashing, error) {
|
||||
dataRoot, err := block.Header.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get block header hash tree root: %v", err)
|
||||
}
|
||||
signedBlockWrapper := &slashertypes.SignedBlockHeaderWrapper{
|
||||
SignedBeaconBlockHeader: block,
|
||||
SigningRoot: dataRoot,
|
||||
}
|
||||
proposerSlashings, err := s.detectProposerSlashings(ctx, []*slashertypes.SignedBlockHeaderWrapper{signedBlockWrapper})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if proposal is slashable: %v", err)
|
||||
}
|
||||
if len(proposerSlashings) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return proposerSlashings[0], nil
|
||||
}
|
||||
|
||||
// IsSlashableAttestation checks if an input indexed attestation is slashable
|
||||
// with respect to historical attestation data.
|
||||
func (s *Service) IsSlashableAttestation(
|
||||
ctx context.Context, attestation *ethpb.IndexedAttestation,
|
||||
) ([]*ethpb.AttesterSlashing, error) {
|
||||
dataRoot, err := attestation.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get attestation data hash tree root: %v", err)
|
||||
}
|
||||
indexedAttWrapper := &slashertypes.IndexedAttestationWrapper{
|
||||
IndexedAttestation: attestation,
|
||||
SigningRoot: dataRoot,
|
||||
}
|
||||
|
||||
currentEpoch := slots.EpochsSinceGenesis(s.genesisTime)
|
||||
attesterSlashings, err := s.checkSlashableAttestations(ctx, currentEpoch, []*slashertypes.IndexedAttestationWrapper{indexedAttWrapper})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not check if attestation is slashable: %v", err)
|
||||
}
|
||||
if len(attesterSlashings) == 0 {
|
||||
// If the incoming attestations are not slashable, we mark them as saved in
|
||||
// slasher's DB storage to help us with future detection.
|
||||
if err := s.serviceCfg.Database.SaveAttestationRecordsForValidators(
|
||||
ctx, []*slashertypes.IndexedAttestationWrapper{indexedAttWrapper},
|
||||
); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not save attestation records to DB: %v", err)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return attesterSlashings, nil
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
package slasher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
dbtest "github.com/prysmaticlabs/prysm/v4/beacon-chain/db/testing"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/slasher/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
func TestIsSlashableBlock(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
slasherDB := dbtest.SetupSlasherDB(t)
|
||||
s := &Service{
|
||||
serviceCfg: &ServiceConfig{
|
||||
Database: slasherDB,
|
||||
},
|
||||
params: DefaultParams(),
|
||||
blksQueue: newBlocksQueue(),
|
||||
}
|
||||
err := slasherDB.SaveBlockProposals(ctx, []*slashertypes.SignedBlockHeaderWrapper{
|
||||
createProposalWrapper(t, 2, 3, []byte{1}),
|
||||
createProposalWrapper(t, 3, 3, []byte{1}),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
tests := []struct {
|
||||
name string
|
||||
blockToCheck *slashertypes.SignedBlockHeaderWrapper
|
||||
shouldBeSlashable bool
|
||||
}{
|
||||
{
|
||||
name: "should not detect if same signing root",
|
||||
blockToCheck: createProposalWrapper(t, 2, 3, []byte{1}),
|
||||
shouldBeSlashable: false,
|
||||
},
|
||||
{
|
||||
name: "should not detect if different slot",
|
||||
blockToCheck: createProposalWrapper(t, 1, 3, []byte{2}),
|
||||
shouldBeSlashable: false,
|
||||
},
|
||||
{
|
||||
name: "should not detect if different validator index",
|
||||
blockToCheck: createProposalWrapper(t, 2, 4, []byte{2}),
|
||||
shouldBeSlashable: false,
|
||||
},
|
||||
{
|
||||
name: "detects differing signing root",
|
||||
blockToCheck: createProposalWrapper(t, 2, 3, []byte{2}),
|
||||
shouldBeSlashable: true,
|
||||
},
|
||||
{
|
||||
name: "should detect another slot",
|
||||
blockToCheck: createProposalWrapper(t, 3, 3, []byte{2}),
|
||||
shouldBeSlashable: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
proposerSlashing, err := s.IsSlashableBlock(ctx, tt.blockToCheck.SignedBeaconBlockHeader)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.shouldBeSlashable, proposerSlashing != nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSlashableAttestation(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
slasherDB := dbtest.SetupSlasherDB(t)
|
||||
|
||||
currentEpoch := primitives.Epoch(3)
|
||||
currentTime := time.Now()
|
||||
totalSlots := uint64(currentEpoch) * uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||
secondsSinceGenesis := time.Duration(totalSlots * params.BeaconConfig().SecondsPerSlot)
|
||||
genesisTime := currentTime.Add(-secondsSinceGenesis * time.Second)
|
||||
|
||||
s := &Service{
|
||||
serviceCfg: &ServiceConfig{
|
||||
Database: slasherDB,
|
||||
},
|
||||
params: DefaultParams(),
|
||||
blksQueue: newBlocksQueue(),
|
||||
genesisTime: genesisTime,
|
||||
latestEpochWrittenForValidator: map[primitives.ValidatorIndex]primitives.Epoch{},
|
||||
}
|
||||
prevAtts := []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 2, 3, []uint64{0}, []byte{1}),
|
||||
createAttestationWrapper(t, 2, 3, []uint64{1}, []byte{1}),
|
||||
}
|
||||
err := slasherDB.SaveAttestationRecordsForValidators(ctx, prevAtts)
|
||||
require.NoError(t, err)
|
||||
attesterSlashings, err := s.checkSlashableAttestations(ctx, currentEpoch, prevAtts)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(attesterSlashings))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
attToCheck *slashertypes.IndexedAttestationWrapper
|
||||
amtSlashable uint64
|
||||
}{
|
||||
{
|
||||
name: "should not detect if same attestation data",
|
||||
attToCheck: createAttestationWrapper(t, 2, 3, []uint64{1}, []byte{1}),
|
||||
amtSlashable: 0,
|
||||
},
|
||||
{
|
||||
name: "should not detect if different index",
|
||||
attToCheck: createAttestationWrapper(t, 0, 3, []uint64{2}, []byte{2}),
|
||||
amtSlashable: 0,
|
||||
},
|
||||
{
|
||||
name: "should detect double if same index",
|
||||
attToCheck: createAttestationWrapper(t, 0, 3, []uint64{0}, []byte{2}),
|
||||
amtSlashable: 1,
|
||||
},
|
||||
{
|
||||
name: "should detect multiple double if multiple same indices",
|
||||
attToCheck: createAttestationWrapper(t, 0, 3, []uint64{0, 1}, []byte{2}),
|
||||
amtSlashable: 2,
|
||||
},
|
||||
{
|
||||
name: "should detect multiple surround if multiple same indices",
|
||||
attToCheck: createAttestationWrapper(t, 1, 4, []uint64{0, 1}, []byte{2}),
|
||||
amtSlashable: 4,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
attesterSlashings, err = s.IsSlashableAttestation(ctx, tt.attToCheck.IndexedAttestation)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.amtSlashable, uint64(len(attesterSlashings)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_HighestAttestations(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
slasherDB := dbtest.SetupSlasherDB(t)
|
||||
|
||||
currentEpoch := primitives.Epoch(3)
|
||||
currentTime := time.Now()
|
||||
totalSlots := uint64(currentEpoch) * uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||
secondsSinceGenesis := time.Duration(totalSlots * params.BeaconConfig().SecondsPerSlot)
|
||||
genesisTime := currentTime.Add(-secondsSinceGenesis * time.Second)
|
||||
|
||||
s := &Service{
|
||||
serviceCfg: &ServiceConfig{
|
||||
Database: slasherDB,
|
||||
},
|
||||
params: DefaultParams(),
|
||||
blksQueue: newBlocksQueue(),
|
||||
genesisTime: genesisTime,
|
||||
}
|
||||
prevAtts := []*slashertypes.IndexedAttestationWrapper{
|
||||
createAttestationWrapper(t, 0, 1, []uint64{1}, []byte{1}),
|
||||
createAttestationWrapper(t, 2, 3, []uint64{2}, []byte{1}),
|
||||
}
|
||||
err := slasherDB.SaveAttestationRecordsForValidators(ctx, prevAtts)
|
||||
require.NoError(t, err)
|
||||
t.Run("single index not found", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{0})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(atts))
|
||||
})
|
||||
t.Run("single index case 1", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{1})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(atts))
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 1, HighestSourceEpoch: 0, HighestTargetEpoch: 1}, atts[0])
|
||||
})
|
||||
t.Run("single index case 2", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{2})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(atts))
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 2, HighestSourceEpoch: 2, HighestTargetEpoch: 3}, atts[0])
|
||||
})
|
||||
t.Run("multiple indices all found", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{1, 2})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(atts))
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 1, HighestSourceEpoch: 0, HighestTargetEpoch: 1}, atts[0])
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 2, HighestSourceEpoch: 2, HighestTargetEpoch: 3}, atts[1])
|
||||
})
|
||||
t.Run("multiple indices all not found", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{3, 4})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(atts))
|
||||
})
|
||||
t.Run("multiple indices some not found", func(t *testing.T) {
|
||||
atts, err := s.HighestAttestations(ctx, []primitives.ValidatorIndex{1, 4})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(atts))
|
||||
require.DeepEqual(t, ðpb.HighestAttestation{ValidatorIndex: 1, HighestSourceEpoch: 0, HighestTargetEpoch: 1}, atts[0])
|
||||
})
|
||||
}
|
||||
@@ -43,15 +43,6 @@ type ServiceConfig struct {
|
||||
ClockWaiter startup.ClockWaiter
|
||||
}
|
||||
|
||||
// SlashingChecker is an interface for defining services that the beacon node may interact with to provide slashing data.
|
||||
type SlashingChecker interface {
|
||||
IsSlashableBlock(ctx context.Context, proposal *ethpb.SignedBeaconBlockHeader) (*ethpb.ProposerSlashing, error)
|
||||
IsSlashableAttestation(ctx context.Context, attestation *ethpb.IndexedAttestation) ([]*ethpb.AttesterSlashing, error)
|
||||
HighestAttestations(
|
||||
ctx context.Context, indices []primitives.ValidatorIndex,
|
||||
) ([]*ethpb.HighestAttestation, error)
|
||||
}
|
||||
|
||||
// Service defining a slasher implementation as part of
|
||||
// the beacon node, able to detect eth2 slashable offenses.
|
||||
type Service struct {
|
||||
|
||||
@@ -19,8 +19,6 @@ import (
|
||||
logTest "github.com/sirupsen/logrus/hooks/test"
|
||||
)
|
||||
|
||||
var _ = SlashingChecker(&Service{})
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetOutput(io.Discard)
|
||||
|
||||
Reference in New Issue
Block a user