mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 16:08:26 -05:00
Remove unused DB functions and proto from Slasher (#4996)
* Remove unused DB functions * goimports * Fix bug and improve tests * Merge branch 'master' of https://github.com/prysmaticlabs/Prysm into slasher-remove-old-db
This commit is contained in:
committed by
GitHub
parent
139f51efaa
commit
e339b07ac7
894
proto/slashing/slashing.pb.go
generated
894
proto/slashing/slashing.pb.go
generated
File diff suppressed because it is too large
Load Diff
@@ -27,21 +27,6 @@ message AttesterSlashingResponse {
|
||||
repeated ethereum.eth.v1alpha1.AttesterSlashing attester_slashing = 1;
|
||||
}
|
||||
|
||||
// CompressedIdxAtt is an indexed attestation with the []byte data root
|
||||
// in place of its AttestationData.
|
||||
message CompressedIdxAtt {
|
||||
repeated uint64 indices = 1 ;
|
||||
bytes data_root = 2;
|
||||
// 96 bytes aggregate signature.
|
||||
bytes signature = 3;
|
||||
}
|
||||
|
||||
// CompressedIdxAttList is a list of CompressedIdxAtts used for
|
||||
// accessing an array from the DB.
|
||||
message CompressedIdxAttList {
|
||||
repeated CompressedIdxAtt list = 1;
|
||||
}
|
||||
|
||||
// In order to detect surrounded attestation we need to compare
|
||||
// each attestation source to those spans
|
||||
// see https://github.com/protolambda/eth2-surround/blob/master/README.md#min-max-surround
|
||||
|
||||
@@ -21,14 +21,11 @@ type ReadOnlyDatabase interface {
|
||||
BlockHeaders(ctx context.Context, epoch uint64, validatorID uint64) ([]*ethpb.SignedBeaconBlockHeader, error)
|
||||
HasBlockHeader(ctx context.Context, epoch uint64, validatorID uint64) bool
|
||||
|
||||
// IndexedAttestationsForEpoch related methods.
|
||||
// IndexedAttestations related methods.
|
||||
HasIndexedAttestation(ctx context.Context, att *ethpb.IndexedAttestation) (bool, error)
|
||||
IndexedAttestationsForTarget(ctx context.Context, targetEpoch uint64) ([]*ethpb.IndexedAttestation, error)
|
||||
IdxAttsForTargetFromID(ctx context.Context, targetEpoch uint64, validatorID uint64) ([]*ethpb.IndexedAttestation, error)
|
||||
IndexedAttestationsWithPrefix(ctx context.Context, targetEpoch uint64, sigBytes []byte) ([]*ethpb.IndexedAttestation, error)
|
||||
LatestIndexedAttestationsTargetEpoch(ctx context.Context) (uint64, error)
|
||||
LatestValidatorIdx(ctx context.Context) (uint64, error)
|
||||
DoubleVotes(ctx context.Context, validatorIdx uint64, dataRoot []byte, origAtt *ethpb.IndexedAttestation) ([]*ethpb.AttesterSlashing, error)
|
||||
HasIndexedAttestation(ctx context.Context, att *ethpb.IndexedAttestation) (bool, error)
|
||||
|
||||
// MinMaxSpan related methods.
|
||||
ValidatorSpansMap(ctx context.Context, validatorIdx uint64) (*slashpb.EpochSpanMap, error)
|
||||
@@ -56,7 +53,7 @@ type WriteAccessDatabase interface {
|
||||
DeleteBlockHeader(ctx context.Context, epoch uint64, validatorID uint64, blockHeader *ethpb.SignedBeaconBlockHeader) error
|
||||
PruneBlockHistory(ctx context.Context, currentEpoch uint64, pruningEpochAge uint64) error
|
||||
|
||||
// IndexedAttestationsForEpoch related methods.
|
||||
// IndexedAttestations related methods.
|
||||
SaveIndexedAttestation(ctx context.Context, idxAttestation *ethpb.IndexedAttestation) error
|
||||
SaveIndexedAttestations(ctx context.Context, idxAttestations []*ethpb.IndexedAttestation) error
|
||||
DeleteIndexedAttestation(ctx context.Context, idxAttestation *ethpb.IndexedAttestation) error
|
||||
|
||||
@@ -3,18 +3,12 @@ package kv
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
slashpb "github.com/prysmaticlabs/prysm/proto/slashing"
|
||||
"github.com/prysmaticlabs/prysm/shared/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
@@ -29,71 +23,17 @@ func unmarshalIndexedAttestation(ctx context.Context, enc []byte) (*ethpb.Indexe
|
||||
return protoIdxAtt, nil
|
||||
}
|
||||
|
||||
func unmarshalCompressedIdxAttList(ctx context.Context, enc []byte) (*slashpb.CompressedIdxAttList, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.unmarshalCompressedIdxAttList")
|
||||
defer span.End()
|
||||
protoIdxAtt := &slashpb.CompressedIdxAttList{}
|
||||
err := proto.Unmarshal(enc, protoIdxAtt)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal encoding")
|
||||
}
|
||||
return protoIdxAtt, nil
|
||||
}
|
||||
|
||||
// IdxAttsForTargetFromID accepts a epoch and validator index and returns a list of
|
||||
// indexed attestations from that validator for the given target epoch.
|
||||
// Returns nil if the indexed attestation does not exist.
|
||||
func (db *Store) IdxAttsForTargetFromID(ctx context.Context, targetEpoch uint64, validatorID uint64) ([]*ethpb.IndexedAttestation, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.IdxAttsForTargetFromID")
|
||||
defer span.End()
|
||||
var idxAtts []*ethpb.IndexedAttestation
|
||||
|
||||
err := db.view(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket(compressedIdxAttsBucket)
|
||||
enc := bucket.Get(bytesutil.Bytes8(targetEpoch))
|
||||
if enc == nil {
|
||||
return nil
|
||||
}
|
||||
idToIdxAttsList, err := unmarshalCompressedIdxAttList(ctx, enc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, idxAtt := range idToIdxAttsList.List {
|
||||
i := sort.Search(len(idxAtt.Indices), func(i int) bool {
|
||||
return idxAtt.Indices[i] >= validatorID
|
||||
})
|
||||
if i < len(idxAtt.Indices) && idxAtt.Indices[i] == validatorID {
|
||||
idxAttBucket := tx.Bucket(historicIndexedAttestationsBucket)
|
||||
key := encodeEpochSig(targetEpoch, idxAtt.Signature)
|
||||
enc = idxAttBucket.Get(key)
|
||||
if enc == nil {
|
||||
continue
|
||||
}
|
||||
att, err := unmarshalIndexedAttestation(ctx, enc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
idxAtts = append(idxAtts, att)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return idxAtts, err
|
||||
}
|
||||
|
||||
// IndexedAttestationsForTarget accepts a target epoch and returns a list of
|
||||
// indexed attestations.
|
||||
// Returns nil if the indexed attestation does not exist with that target epoch.
|
||||
func (db *Store) IndexedAttestationsForTarget(ctx context.Context, targetEpoch uint64) ([]*ethpb.IndexedAttestation, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.IdxAttsForTarget")
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.IndexedAttestationsForTarget")
|
||||
defer span.End()
|
||||
var idxAtts []*ethpb.IndexedAttestation
|
||||
key := bytesutil.Bytes8(targetEpoch)
|
||||
err := db.view(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket(historicIndexedAttestationsBucket).Cursor()
|
||||
for k, enc := c.Seek(key); k != nil && bytes.Equal(k[:8], key); k, _ = c.Next() {
|
||||
for k, enc := c.Seek(key); k != nil && bytes.Equal(k[:8], key); k, enc = c.Next() {
|
||||
idxAtt, err := unmarshalIndexedAttestation(ctx, enc)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -108,13 +48,13 @@ func (db *Store) IndexedAttestationsForTarget(ctx context.Context, targetEpoch u
|
||||
// IndexedAttestationsWithPrefix accepts a target epoch and signature bytes to find all attestations with the requested prefix.
|
||||
// Returns nil if the indexed attestation does not exist with that target epoch.
|
||||
func (db *Store) IndexedAttestationsWithPrefix(ctx context.Context, targetEpoch uint64, sigBytes []byte) ([]*ethpb.IndexedAttestation, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.IdxAttsForTarget")
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.IndexedAttestationsWithPrefix")
|
||||
defer span.End()
|
||||
var idxAtts []*ethpb.IndexedAttestation
|
||||
key := encodeEpochSig(targetEpoch, sigBytes[:])
|
||||
err := db.view(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket(historicIndexedAttestationsBucket).Cursor()
|
||||
for k, enc := c.Seek(key); k != nil && bytes.Equal(k[:len(key)], key); k, _ = c.Next() {
|
||||
for k, enc := c.Seek(key); k != nil && bytes.Equal(k[:len(key)], key); k, enc = c.Next() {
|
||||
idxAtt, err := unmarshalIndexedAttestation(ctx, enc)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -126,78 +66,6 @@ func (db *Store) IndexedAttestationsWithPrefix(ctx context.Context, targetEpoch
|
||||
return idxAtts, err
|
||||
}
|
||||
|
||||
// LatestIndexedAttestationsTargetEpoch returns latest target epoch in db
|
||||
// returns 0 if there is no indexed attestations in db.
|
||||
func (db *Store) LatestIndexedAttestationsTargetEpoch(ctx context.Context) (uint64, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.LatestIndexedAttestationsTargetEpoch")
|
||||
defer span.End()
|
||||
var lt uint64
|
||||
err := db.view(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket(historicIndexedAttestationsBucket).Cursor()
|
||||
k, _ := c.Last()
|
||||
if k == nil {
|
||||
return nil
|
||||
}
|
||||
lt = bytesutil.FromBytes8(k[:8])
|
||||
return nil
|
||||
})
|
||||
return lt, err
|
||||
}
|
||||
|
||||
// LatestValidatorIdx returns latest validator id in db
|
||||
// returns 0 if there is no validators in db.
|
||||
func (db *Store) LatestValidatorIdx(ctx context.Context) (uint64, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.LatestValidatorIdx")
|
||||
defer span.End()
|
||||
var lt uint64
|
||||
err := db.view(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket(compressedIdxAttsBucket).Cursor()
|
||||
k, _ := c.Last()
|
||||
if k == nil {
|
||||
return nil
|
||||
}
|
||||
lt = bytesutil.FromBytes8(k[:8])
|
||||
return nil
|
||||
})
|
||||
return lt, err
|
||||
}
|
||||
|
||||
// DoubleVotes looks up db for slashable attesting data that were preformed by the same validator.
|
||||
func (db *Store) DoubleVotes(ctx context.Context, validatorIdx uint64, dataRoot []byte, origAtt *ethpb.IndexedAttestation) ([]*ethpb.AttesterSlashing, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.DoubleVotes")
|
||||
defer span.End()
|
||||
idxAtts, err := db.IdxAttsForTargetFromID(ctx, origAtt.Data.Target.Epoch, validatorIdx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if idxAtts == nil || len(idxAtts) == 0 {
|
||||
return nil, fmt.Errorf("can't check nil indexed attestation for double vote")
|
||||
}
|
||||
|
||||
var idxAttsToSlash []*ethpb.IndexedAttestation
|
||||
for _, att := range idxAtts {
|
||||
if att.Data == nil {
|
||||
continue
|
||||
}
|
||||
root, err := hashutil.HashProto(att.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !bytes.Equal(root[:], dataRoot) {
|
||||
idxAttsToSlash = append(idxAttsToSlash, att)
|
||||
}
|
||||
}
|
||||
|
||||
var as []*ethpb.AttesterSlashing
|
||||
for _, idxAtt := range idxAttsToSlash {
|
||||
as = append(as, ðpb.AttesterSlashing{
|
||||
Attestation_1: origAtt,
|
||||
Attestation_2: idxAtt,
|
||||
})
|
||||
}
|
||||
return as, nil
|
||||
}
|
||||
|
||||
// HasIndexedAttestation accepts an attestation and returns true if it exists in the DB.
|
||||
func (db *Store) HasIndexedAttestation(ctx context.Context, att *ethpb.IndexedAttestation) (bool, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.HasIndexedAttestation")
|
||||
@@ -240,30 +108,21 @@ func (db *Store) SaveIndexedAttestation(ctx context.Context, idxAttestation *eth
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
// Prune history to max size every PruneSlasherStoragePeriod epoch.
|
||||
if idxAttestation.Data.Source.Epoch%params.BeaconConfig().PruneSlasherStoragePeriod == 0 {
|
||||
wsPeriod := params.BeaconConfig().WeakSubjectivityPeriod
|
||||
if err = db.PruneAttHistory(ctx, idxAttestation.Data.Source.Epoch, wsPeriod); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// SaveIndexedAttestations accepts multiple indexed attestations and writes them to the DB.
|
||||
func (db *Store) SaveIndexedAttestations(ctx context.Context, idxAttestations []*ethpb.IndexedAttestation) error {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.SaveIndexedAttestation")
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.SaveIndexedAttestations")
|
||||
defer span.End()
|
||||
keys := make([][]byte, len(idxAttestations))
|
||||
marshaledAtts := make([][]byte, len(idxAttestations))
|
||||
for i, att := range idxAttestations {
|
||||
key := encodeEpochSig(att.Data.Target.Epoch, att.Signature)
|
||||
enc, err := proto.Marshal(att)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal")
|
||||
}
|
||||
keys[i] = key
|
||||
keys[i] = encodeEpochSig(att.Data.Target.Epoch, att.Signature)
|
||||
marshaledAtts[i] = enc
|
||||
}
|
||||
|
||||
@@ -284,37 +143,6 @@ func (db *Store) SaveIndexedAttestations(ctx context.Context, idxAttestations []
|
||||
return err
|
||||
}
|
||||
|
||||
func saveCompressedIdxAttToEpochList(ctx context.Context, idxAttestation *ethpb.IndexedAttestation, tx *bolt.Tx) error {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.saveCompressedIdxAttToEpochList")
|
||||
defer span.End()
|
||||
dataRoot, err := hashutil.HashProto(idxAttestation.Data)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to hash indexed attestation data.")
|
||||
}
|
||||
protoIdxAtt := &slashpb.CompressedIdxAtt{
|
||||
Signature: idxAttestation.Signature,
|
||||
Indices: idxAttestation.AttestingIndices,
|
||||
DataRoot: dataRoot[:],
|
||||
}
|
||||
|
||||
key := bytesutil.Bytes8(idxAttestation.Data.Target.Epoch)
|
||||
bucket := tx.Bucket(compressedIdxAttsBucket)
|
||||
enc := bucket.Get(key)
|
||||
compressedIdxAttList, err := unmarshalCompressedIdxAttList(ctx, enc)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to decode value into CompressedIdxAtt")
|
||||
}
|
||||
compressedIdxAttList.List = append(compressedIdxAttList.List, protoIdxAtt)
|
||||
enc, err = proto.Marshal(compressedIdxAttList)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal")
|
||||
}
|
||||
if err := bucket.Put(key, enc); err != nil {
|
||||
return errors.Wrap(err, "failed to save indexed attestation into historical bucket")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteIndexedAttestation deletes a indexed attestation using the slot and its root as keys in their respective buckets.
|
||||
func (db *Store) DeleteIndexedAttestation(ctx context.Context, idxAttestation *ethpb.IndexedAttestation) error {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.DeleteIndexedAttestation")
|
||||
@@ -327,55 +155,12 @@ func (db *Store) DeleteIndexedAttestation(ctx context.Context, idxAttestation *e
|
||||
return nil
|
||||
}
|
||||
if err := bucket.Delete(key); err != nil {
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
return errors.Wrapf(rollbackErr, "failed to rollback after %v", err)
|
||||
}
|
||||
return errors.Wrap(err, "failed to delete indexed attestation from historical bucket")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func removeIdxAttIndicesByEpochFromDB(ctx context.Context, idxAttestation *ethpb.IndexedAttestation, tx *bolt.Tx) error {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.removeIdxAttIndicesByEpochFromDB")
|
||||
defer span.End()
|
||||
dataRoot, err := hashutil.HashProto(idxAttestation.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
protoIdxAtt := &slashpb.CompressedIdxAtt{
|
||||
Signature: idxAttestation.Signature,
|
||||
Indices: idxAttestation.AttestingIndices,
|
||||
DataRoot: dataRoot[:],
|
||||
}
|
||||
key := bytesutil.Bytes8(idxAttestation.Data.Target.Epoch)
|
||||
bucket := tx.Bucket(compressedIdxAttsBucket)
|
||||
enc := bucket.Get(key)
|
||||
if enc == nil {
|
||||
return errors.New("requested to delete data that is not present")
|
||||
}
|
||||
vIdxList, err := unmarshalCompressedIdxAttList(ctx, enc)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to decode value into ValidatorIDToIndexedAttestationList")
|
||||
}
|
||||
for i, attIdx := range vIdxList.List {
|
||||
if reflect.DeepEqual(attIdx, protoIdxAtt) {
|
||||
copy(vIdxList.List[i:], vIdxList.List[i+1:])
|
||||
vIdxList.List[len(vIdxList.List)-1] = nil // or the zero value of T
|
||||
vIdxList.List = vIdxList.List[:len(vIdxList.List)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
enc, err = proto.Marshal(vIdxList)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal")
|
||||
}
|
||||
if err := bucket.Put(key, enc); err != nil {
|
||||
return errors.Wrap(err, "failed to include indexed attestation in the historical bucket")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PruneAttHistory removes all attestations from the DB older than the pruning epoch age.
|
||||
func (db *Store) PruneAttHistory(ctx context.Context, currentEpoch uint64, pruningEpochAge uint64) error {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.pruneAttHistory")
|
||||
@@ -394,14 +179,24 @@ func (db *Store) PruneAttHistory(ctx context.Context, currentEpoch uint64, pruni
|
||||
return errors.Wrap(err, "failed to delete indexed attestation from historical bucket")
|
||||
}
|
||||
}
|
||||
|
||||
idxBucket := tx.Bucket(compressedIdxAttsBucket)
|
||||
c = tx.Bucket(compressedIdxAttsBucket).Cursor()
|
||||
for k, _ := c.First(); k != nil && bytes.Compare(k[:8], max) <= 0; k, _ = c.Next() {
|
||||
if err := idxBucket.Delete(k); err != nil {
|
||||
return errors.Wrap(err, "failed to delete indexed attestation from historical bucket")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// LatestIndexedAttestationsTargetEpoch returns latest target epoch in db
|
||||
// returns 0 if there is no indexed attestations in db.
|
||||
func (db *Store) LatestIndexedAttestationsTargetEpoch(ctx context.Context) (uint64, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "SlasherDB.LatestIndexedAttestationsTargetEpoch")
|
||||
defer span.End()
|
||||
var lt uint64
|
||||
err := db.view(func(tx *bolt.Tx) error {
|
||||
c := tx.Bucket(historicIndexedAttestationsBucket).Cursor()
|
||||
k, _ := c.Last()
|
||||
if k == nil {
|
||||
return nil
|
||||
}
|
||||
lt = bytesutil.FromBytes8(k[:8])
|
||||
return nil
|
||||
})
|
||||
return lt, err
|
||||
}
|
||||
|
||||
@@ -48,10 +48,20 @@ func init() {
|
||||
Signature: []byte{5, 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
idxAtt: ðpb.IndexedAttestation{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 1},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
},
|
||||
Signature: []byte{5, 6},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilDBHistoryIdxAtt(t *testing.T) {
|
||||
func TestHasIndexedAttestation_NilDB(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
db := setupDB(t, cli.NewContext(app, set, nil))
|
||||
@@ -75,8 +85,7 @@ func TestSaveIndexedAttestation(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range tests {
|
||||
err := db.SaveIndexedAttestation(ctx, tt.idxAtt)
|
||||
if err != nil {
|
||||
if err := db.SaveIndexedAttestation(ctx, tt.idxAtt); err != nil {
|
||||
t.Fatalf("save indexed attestation failed: %v", err)
|
||||
}
|
||||
|
||||
@@ -91,68 +100,631 @@ func TestSaveIndexedAttestation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexedAttestationWithPrefix(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
db := setupDB(t, cli.NewContext(app, set, nil))
|
||||
defer teardownDB(t, db)
|
||||
ctx := context.Background()
|
||||
func TestIndexedAttestationsWithPrefix(t *testing.T) {
|
||||
type prefixTestStruct struct {
|
||||
name string
|
||||
attsInDB []*ethpb.IndexedAttestation
|
||||
targetEpoch uint64
|
||||
searchPrefix []byte
|
||||
expectedResult []*ethpb.IndexedAttestation
|
||||
}
|
||||
prefixTests := []prefixTestStruct{
|
||||
{
|
||||
name: "single item, same sig, should find one",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2},
|
||||
},
|
||||
},
|
||||
searchPrefix: []byte{1, 2},
|
||||
targetEpoch: 1,
|
||||
expectedResult: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple item, same sig, should find 3",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 2, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there 3"),
|
||||
},
|
||||
Signature: []byte{1, 2, 5},
|
||||
},
|
||||
},
|
||||
searchPrefix: []byte{1, 2},
|
||||
targetEpoch: 1,
|
||||
expectedResult: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 2, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there 3"),
|
||||
},
|
||||
Signature: []byte{1, 2, 5},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple items, different sig and epoch, should find 2",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 2},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{1, 2, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there 3"),
|
||||
},
|
||||
Signature: []byte{1, 2, 5},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 3, 1},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 2},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{0, 2, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{4},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 2},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 2, 9},
|
||||
},
|
||||
},
|
||||
searchPrefix: []byte{1, 2},
|
||||
targetEpoch: 2,
|
||||
expectedResult: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 2},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{1, 2, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{4},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 2},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 2, 9},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple items, different sigs, should not find any atts",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 2},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{3, 5, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 2},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{3, 5, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 2, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there 3"),
|
||||
},
|
||||
Signature: []byte{1, 2, 5},
|
||||
},
|
||||
},
|
||||
searchPrefix: []byte{3, 5},
|
||||
targetEpoch: 1,
|
||||
},
|
||||
}
|
||||
for _, tt := range prefixTests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
db := setupDB(t, cli.NewContext(app, set, nil))
|
||||
defer teardownDB(t, db)
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range tests {
|
||||
err := db.SaveIndexedAttestation(ctx, tt.idxAtt)
|
||||
if err != nil {
|
||||
t.Fatalf("save indexed attestation failed: %v", err)
|
||||
}
|
||||
if err := db.SaveIndexedAttestations(ctx, tt.attsInDB); err != nil {
|
||||
t.Fatalf("save indexed attestation failed: %v", err)
|
||||
}
|
||||
for _, att := range tt.attsInDB {
|
||||
found, err := db.HasIndexedAttestation(ctx, att)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("Expected to save %v", att)
|
||||
}
|
||||
}
|
||||
|
||||
idxAtts, err := db.IndexedAttestationsWithPrefix(ctx, tt.idxAtt.Data.Target.Epoch, tt.idxAtt.Signature[:2])
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get indexed attestation: %v", err)
|
||||
}
|
||||
idxAtts, err := db.IndexedAttestationsWithPrefix(ctx, tt.targetEpoch, tt.searchPrefix)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get indexed attestation: %v", err)
|
||||
}
|
||||
|
||||
if idxAtts == nil || !reflect.DeepEqual(idxAtts[0], tt.idxAtt) {
|
||||
t.Fatalf("get should return indexed attestation: %v", idxAtts)
|
||||
}
|
||||
if !reflect.DeepEqual(tt.expectedResult, idxAtts) {
|
||||
t.Fatalf("Expected %v, received: %v", tt.expectedResult, idxAtts)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexedAttestationsForTarget(t *testing.T) {
|
||||
type prefixTestStruct struct {
|
||||
name string
|
||||
attsInDB []*ethpb.IndexedAttestation
|
||||
targetEpoch uint64
|
||||
expectedResult []*ethpb.IndexedAttestation
|
||||
}
|
||||
prefixTests := []prefixTestStruct{
|
||||
{
|
||||
name: "single item, should find one",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2},
|
||||
},
|
||||
},
|
||||
targetEpoch: 1,
|
||||
expectedResult: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple items, same epoch, should find 3",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 5, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there 3"),
|
||||
},
|
||||
Signature: []byte{8, 2, 5},
|
||||
},
|
||||
},
|
||||
targetEpoch: 3,
|
||||
expectedResult: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 5, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there 3"),
|
||||
},
|
||||
Signature: []byte{8, 2, 5},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple items, different epochs, should not find any atts",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{3, 5, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 2},
|
||||
BeaconBlockRoot: []byte("hi there"),
|
||||
},
|
||||
Signature: []byte{3, 5, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{1},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
BeaconBlockRoot: []byte("hi there 2"),
|
||||
},
|
||||
Signature: []byte{1, 2, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 5},
|
||||
BeaconBlockRoot: []byte("hi there 3"),
|
||||
},
|
||||
Signature: []byte{1, 2, 5},
|
||||
},
|
||||
},
|
||||
targetEpoch: 4,
|
||||
},
|
||||
}
|
||||
for _, tt := range prefixTests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
db := setupDB(t, cli.NewContext(app, set, nil))
|
||||
defer teardownDB(t, db)
|
||||
ctx := context.Background()
|
||||
|
||||
if err := db.SaveIndexedAttestations(ctx, tt.attsInDB); err != nil {
|
||||
t.Fatalf("save indexed attestation failed: %v", err)
|
||||
}
|
||||
for _, att := range tt.attsInDB {
|
||||
found, err := db.HasIndexedAttestation(ctx, att)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("Expected to save %v", att)
|
||||
}
|
||||
}
|
||||
|
||||
idxAtts, err := db.IndexedAttestationsForTarget(ctx, tt.targetEpoch)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get indexed attestation: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(tt.expectedResult, idxAtts) {
|
||||
t.Fatalf("Expected %v, received: %v", tt.expectedResult, idxAtts)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteIndexedAttestation(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
db := setupDB(t, cli.NewContext(app, set, nil))
|
||||
defer teardownDB(t, db)
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range tests {
|
||||
err := db.SaveIndexedAttestation(ctx, tt.idxAtt)
|
||||
if err != nil {
|
||||
t.Fatalf("save indexed attestation failed: %v", err)
|
||||
}
|
||||
type deleteTestStruct struct {
|
||||
name string
|
||||
attsInDB []*ethpb.IndexedAttestation
|
||||
deleteAtts []*ethpb.IndexedAttestation
|
||||
foundArray []bool
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
found, err := db.HasIndexedAttestation(ctx, tt.idxAtt)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get index attestation: %v", err)
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Fatalf("Expected indexed attestation: %v", tt.idxAtt)
|
||||
}
|
||||
err = db.DeleteIndexedAttestation(ctx, tt.idxAtt)
|
||||
if err != nil {
|
||||
t.Fatalf("delete index attestation failed: %v", err)
|
||||
}
|
||||
|
||||
found, err = db.HasIndexedAttestation(ctx, tt.idxAtt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if found {
|
||||
t.Error("Expected indexed attestation to be deleted")
|
||||
}
|
||||
|
||||
deleteTests := []deleteTestStruct{
|
||||
{
|
||||
name: "single item, should delete all",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2},
|
||||
},
|
||||
},
|
||||
deleteAtts: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2},
|
||||
},
|
||||
},
|
||||
foundArray: []bool{false},
|
||||
},
|
||||
{
|
||||
name: "multiple items, should delete 2",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 3},
|
||||
},
|
||||
Signature: []byte{2, 4},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 4},
|
||||
},
|
||||
Signature: []byte{3, 5},
|
||||
},
|
||||
},
|
||||
deleteAtts: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 4},
|
||||
},
|
||||
Signature: []byte{3, 5},
|
||||
},
|
||||
},
|
||||
foundArray: []bool{false, true, false},
|
||||
},
|
||||
{
|
||||
name: "multiple similar items, should delete 1",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2, 2},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2, 4},
|
||||
},
|
||||
},
|
||||
deleteAtts: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
},
|
||||
foundArray: []bool{true, false, true},
|
||||
},
|
||||
{
|
||||
name: "should not delete any if not in list",
|
||||
attsInDB: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2, 2},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2, 4},
|
||||
},
|
||||
},
|
||||
deleteAtts: []*ethpb.IndexedAttestation{
|
||||
{
|
||||
AttestingIndices: []uint64{3},
|
||||
Data: ðpb.AttestationData{
|
||||
Source: ðpb.Checkpoint{Epoch: 0},
|
||||
Target: ðpb.Checkpoint{Epoch: 1},
|
||||
},
|
||||
Signature: []byte{1, 2, 6},
|
||||
},
|
||||
},
|
||||
foundArray: []bool{true, true, true},
|
||||
},
|
||||
}
|
||||
for _, tt := range deleteTests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
app := cli.NewApp()
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
db := setupDB(t, cli.NewContext(app, set, nil))
|
||||
defer teardownDB(t, db)
|
||||
ctx := context.Background()
|
||||
|
||||
if err := db.SaveIndexedAttestations(ctx, tt.attsInDB); err != nil {
|
||||
t.Fatalf("save indexed attestation failed: %v", err)
|
||||
}
|
||||
|
||||
for _, att := range tt.attsInDB {
|
||||
found, err := db.HasIndexedAttestation(ctx, att)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("Expected to save %v", att)
|
||||
}
|
||||
}
|
||||
|
||||
for _, att := range tt.deleteAtts {
|
||||
if err := db.DeleteIndexedAttestation(ctx, att); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
for i, att := range tt.attsInDB {
|
||||
found, err := db.HasIndexedAttestation(ctx, att)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if found != tt.foundArray[i] {
|
||||
t.Fatalf("Expected found to be %t: %v", tt.foundArray[i], att)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasIndexedAttestation(t *testing.T) {
|
||||
@@ -195,8 +767,7 @@ func TestPruneHistoryIndexedAttestation(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range tests {
|
||||
err := db.SaveIndexedAttestation(ctx, tt.idxAtt)
|
||||
if err != nil {
|
||||
if err := db.SaveIndexedAttestation(ctx, tt.idxAtt); err != nil {
|
||||
t.Fatalf("save indexed attestation failed: %v", err)
|
||||
}
|
||||
|
||||
@@ -209,10 +780,9 @@ func TestPruneHistoryIndexedAttestation(t *testing.T) {
|
||||
t.Fatal("Expected to find attestation in DB")
|
||||
}
|
||||
}
|
||||
currentEpoch := uint64(3)
|
||||
currentEpoch := uint64(2)
|
||||
historyToKeep := uint64(1)
|
||||
err := db.PruneAttHistory(ctx, currentEpoch, historyToKeep)
|
||||
if err != nil {
|
||||
if err := db.PruneAttHistory(ctx, currentEpoch, historyToKeep); err != nil {
|
||||
t.Fatalf("failed to prune: %v", err)
|
||||
}
|
||||
|
||||
@@ -222,7 +792,7 @@ func TestPruneHistoryIndexedAttestation(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if tt.idxAtt.Data.Source.Epoch > currentEpoch-historyToKeep {
|
||||
if tt.idxAtt.Data.Target.Epoch > currentEpoch-historyToKeep {
|
||||
if !exists {
|
||||
t.Fatal("Expected to find attestation newer than prune age in DB")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user