mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-31 23:41:22 +00:00
607f086de9
* min max span update logic * add comment to exported method * Update slasher/rpc/update_min_max_span.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/update_min_max_span.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/update_min_max_span.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/update_min_max_span_test.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/update_min_max_span.go Co-Authored-By: terence tsao <terence@prysmaticlabs.com> * Update slasher/rpc/update_min_max_span.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * weak subjectivity error * add context * SlasherDb change to SlasherDB * gaz * raul feedback * fix old problem * gofmt goimports * gaz * import fix * change order * min max span detection * added benchmark * max diff without error * Update slasher/rpc/detect_update_min_max_span_bench_test.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/db/indexed_attestations.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span_bench_test.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span_test.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span_test.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span_bench_test.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * raul feedback, benchmark fix * raul feedback * gaz * fix merge * bench fix * another bench fix * comments * changed names of functions and proto * name change fix * name change fix * fix test * clarification comment * change to interface * Update proto/eth/v1alpha1/slasher.proto Co-Authored-By: Ivan Martinez <ivanthegreatdev@gmail.com> * Update slasher/rpc/detect_update_min_max_span.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span.go Co-Authored-By: Raul Jordan <raul@prysmaticlabs.com> * change order to reduce confusion * Update proto/eth/v1alpha1/slasher.proto Co-Authored-By: terence tsao <terence@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span.go Co-Authored-By: terence tsao <terence@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span.go Co-Authored-By: terence tsao <terence@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span.go Co-Authored-By: terence tsao <terence@prysmaticlabs.com> * Apply suggestions from code review Co-Authored-By: terence tsao <terence@prysmaticlabs.com> * Update slasher/rpc/detect_update_min_max_span.go * Fix some comments * terence feedback * preston feedback * fix test * fix comments
128 lines
4.6 KiB
Go
128 lines
4.6 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
|
"github.com/prysmaticlabs/prysm/shared/params"
|
|
)
|
|
|
|
// Detector is a function type used to implement the slashable surrounding/surrounded
|
|
// vote detection methods.
|
|
type detectFn = func(attestationEpochSpan uint64, recorderEpochSpan *ethpb.MinMaxEpochSpan, sourceEpoch uint64) uint64
|
|
|
|
// detectMax is a function for maxDetector used to detect surrounding attestations.
|
|
func detectMax(
|
|
attestationEpochSpan uint64,
|
|
recorderEpochSpan *ethpb.MinMaxEpochSpan,
|
|
attestationSourceEpoch uint64) uint64 {
|
|
|
|
maxSpan := uint64(recorderEpochSpan.MaxEpochSpan)
|
|
if maxSpan > attestationEpochSpan {
|
|
return maxSpan + attestationSourceEpoch
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// detectMin is a function for minDetecter used to detect surrounded attestations.
|
|
func detectMin(attestationEpochSpan uint64,
|
|
recorderEpochSpan *ethpb.MinMaxEpochSpan,
|
|
attestationSourceEpoch uint64) uint64 {
|
|
|
|
minSpan := uint64(recorderEpochSpan.MinEpochSpan)
|
|
if minSpan < attestationEpochSpan {
|
|
return minSpan + attestationSourceEpoch
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// DetectAndUpdateMaxEpochSpan is used to detect and update the max span of an incoming attestation.
|
|
// This is used for detecting surrounding votes.
|
|
// The max span is the span between the current attestation's source epoch and the furthest attestation's
|
|
// target epoch that has a lower (earlier) source epoch.
|
|
// Logic for this detection method was designed by https://github.com/protolambda
|
|
// Detailed here: https://github.com/protolambda/eth2-surround/blob/master/README.md#min-max-surround
|
|
func (ss *Server) DetectAndUpdateMaxEpochSpan(ctx context.Context, source uint64, target uint64, validatorIdx uint64) (uint64, error) {
|
|
targetEpoch, span, spanMap, err := ss.detectSlashingByEpochSpan(source, target, validatorIdx, detectMax)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if targetEpoch > 0 {
|
|
return targetEpoch, nil
|
|
}
|
|
for i := uint64(1); i < target-source; i++ {
|
|
val := uint32(span - i - 1)
|
|
if _, ok := spanMap.EpochSpanMap[source+i]; !ok {
|
|
spanMap.EpochSpanMap[source+i] = ðpb.MinMaxEpochSpan{}
|
|
}
|
|
if spanMap.EpochSpanMap[source+i].MaxEpochSpan < val {
|
|
spanMap.EpochSpanMap[source+i].MaxEpochSpan = val
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
if err := ss.SlasherDB.SaveValidatorSpansMap(validatorIdx, spanMap); err != nil {
|
|
return 0, err
|
|
}
|
|
return 0, nil
|
|
}
|
|
|
|
// DetectAndUpdateMinEpochSpan is used to detect surrounded votes and update the min epoch span
|
|
// of an incoming attestation.
|
|
// The min span is the span between the current attestations target epoch and the
|
|
// closest attestation's target distance.
|
|
//
|
|
// Logic is following the detection method designed by https://github.com/protolambda
|
|
// Detailed here: https://github.com/protolambda/eth2-surround/blob/master/README.md#min-max-surround
|
|
func (ss *Server) DetectAndUpdateMinEpochSpan(ctx context.Context, source uint64, target uint64, validatorIdx uint64) (uint64, error) {
|
|
targetEpoch, _, spanMap, err := ss.detectSlashingByEpochSpan(source, target, validatorIdx, detectMin)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if targetEpoch > 0 {
|
|
return targetEpoch, nil
|
|
}
|
|
if source == 0 {
|
|
return 0, nil
|
|
}
|
|
for i := source - 1; i > 0; i-- {
|
|
val := uint32(target - (i))
|
|
if _, ok := spanMap.EpochSpanMap[i]; !ok {
|
|
spanMap.EpochSpanMap[i] = ðpb.MinMaxEpochSpan{}
|
|
}
|
|
if spanMap.EpochSpanMap[i].MinEpochSpan == 0 || spanMap.EpochSpanMap[i].MinEpochSpan > val {
|
|
spanMap.EpochSpanMap[i].MinEpochSpan = val
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
if err := ss.SlasherDB.SaveValidatorSpansMap(validatorIdx, spanMap); err != nil {
|
|
return 0, errors.Wrap(err, "could not save validator spans")
|
|
}
|
|
return 0, nil
|
|
}
|
|
|
|
// detectSlashingByEpochSpan is used to detect if a slashable event is present
|
|
// in the db by checking either the closest attestation target or the furthest
|
|
// attestation target. This method receives a detector function in order to be used
|
|
// for both surrounding and surrounded vote cases.
|
|
func (ss *Server) detectSlashingByEpochSpan(source, target, validatorIdx uint64, detector detectFn) (uint64, uint64, *ethpb.EpochSpanMap, error) {
|
|
span := target - source + 1
|
|
if span > params.BeaconConfig().WeakSubjectivityPeriod {
|
|
return 0, span, nil, fmt.Errorf("target: %d - source: %d > weakSubjectivityPeriod",
|
|
params.BeaconConfig().WeakSubjectivityPeriod,
|
|
span,
|
|
)
|
|
}
|
|
spanMap, err := ss.SlasherDB.ValidatorSpansMap(validatorIdx)
|
|
if err != nil {
|
|
return 0, span, nil, errors.Wrapf(err, "could not retrieve span map for validator index: %d", validatorIdx)
|
|
}
|
|
if _, ok := spanMap.EpochSpanMap[source]; ok {
|
|
return detector(span, spanMap.EpochSpanMap[source], source), span, spanMap, nil
|
|
}
|
|
return 0, span, spanMap, nil
|
|
}
|