mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 11:32:09 +00:00
98fea2e94d
* optimizations to slasher runtime * remove unnecessary code * test for epoch update * commentary * Gaz * fmt * amend test * better logging * better logs * log * div 0 * more logging * no log * use map instead * passing * comments * passing * for select loop wait for init * sub * srv * debug * fix panic * gaz * builds * sim gen * ineff * commentary * data * log * base * try * rem logs * sim logs * fix wait for sync event * ev * init * init * Update beacon-chain/slasher/service.go Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> * comments * elapsed * Update testing/slasher/simulator/simulator.go Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com> * timeout * inner cancel * ctx err everywhere * Add context aware to several potentially long running db operations * Fix missing param after updating with develop Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com> Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
201 lines
7.0 KiB
Go
201 lines
7.0 KiB
Go
package slasher
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
types "github.com/prysmaticlabs/eth2-types"
|
|
dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
|
slashertypes "github.com/prysmaticlabs/prysm/beacon-chain/slasher/types"
|
|
"github.com/prysmaticlabs/prysm/config/params"
|
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
|
"github.com/prysmaticlabs/prysm/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 := types.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[types.ValidatorIndex]types.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 := types.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, []types.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, []types.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, []types.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, []types.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, []types.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, []types.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])
|
|
})
|
|
}
|