Reject blobs with invalid parent (#13047)

* Reject blobs with invalid parent

* remove unused comment
This commit is contained in:
Potuz
2023-10-13 10:15:40 -03:00
committed by GitHub
parent 97a99874e8
commit 806a394c89
2 changed files with 51 additions and 4 deletions

View File

@@ -22,6 +22,19 @@ import (
"github.com/sirupsen/logrus"
)
func (s *Service) handleBlobParentStatus(ctx context.Context, root [32]byte) pubsub.ValidationResult {
if s.cfg.chain.HasBlock(ctx, root) {
// the parent will not be kept if it's invalid
return pubsub.ValidationAccept
}
if s.hasBadBlock(root) {
// [REJECT] The sidecar's block's parent (defined by sidecar.block_parent_root) passes validation.
return pubsub.ValidationReject
}
// [IGNORE] The sidecar's block's parent (defined by sidecar.block_parent_root) has been seen (via both gossip and non-gossip sources)
return pubsub.ValidationIgnore
}
func (s *Service) validateBlob(ctx context.Context, pid peer.ID, msg *pubsub.Message) (pubsub.ValidationResult, error) {
receivedTime := prysmTime.Now()
@@ -74,19 +87,23 @@ func (s *Service) validateBlob(ctx context.Context, pid peer.ID, msg *pubsub.Mes
return pubsub.ValidationIgnore, err
}
// [IGNORE] The sidecar's block's parent (defined by sidecar.block_parent_root) has been seen (via both gossip and non-gossip sources)
// Handle the parent status (not seen or invalid cases)
parentRoot := bytesutil.ToBytes32(blob.BlockParentRoot)
if !s.cfg.chain.HasBlock(ctx, parentRoot) {
switch parentStatus := s.handleBlobParentStatus(ctx, parentRoot); parentStatus {
case pubsub.ValidationIgnore:
log.WithFields(blobFields(blob)).Debug("Ignored blob: parent block not found")
return pubsub.ValidationIgnore, nil
case pubsub.ValidationReject:
log.WithFields(blobFields(blob)).Warning("Rejected blob: parent block is invalid")
return pubsub.ValidationReject, nil
default:
}
// [REJECT] The sidecar's block's parent (defined by sidecar.block_parent_root) passes validation.
// [REJECT] The sidecar is from a higher slot than the sidecar's block's parent (defined by sidecar.block_parent_root).
parentSlot, err := s.cfg.chain.RecentBlockSlot(parentRoot)
if err != nil {
return pubsub.ValidationIgnore, err
}
// [REJECT] The sidecar is from a higher slot than the sidecar's block's parent (defined by sidecar.block_parent_root).
if parentSlot >= blob.Slot {
err := fmt.Errorf("parent block slot %d greater or equal to blob slot %d", parentSlot, blob.Slot)
log.WithFields(blobFields(blob)).Debug(err)

View File

@@ -370,3 +370,33 @@ func TestValidateBlob_EverythingPasses(t *testing.T) {
require.NoError(t, err)
require.Equal(t, result, pubsub.ValidationAccept)
}
func TestValidateBlob_handleParentStatus(t *testing.T) {
db := dbtest.SetupDB(t)
ctx := context.Background()
p := p2ptest.NewTestP2P(t)
chainService := &mock.ChainService{Genesis: time.Now(), FinalizedCheckPoint: &eth.Checkpoint{}, DB: db}
s := &Service{
cfg: &config{
p2p: p,
initialSync: &mockSync.Sync{},
chain: chainService,
clock: startup.NewClock(chainService.Genesis, chainService.ValidatorsRoot)},
badBlockCache: lruwrpr.New(10),
}
chainService.BlockSlot = chainService.CurrentSlot() + 1
bb := util.NewBeaconBlock()
bb.Block.Slot = chainService.CurrentSlot() + 1
signedBb, err := blocks.NewSignedBeaconBlock(bb)
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, signedBb))
r, err := signedBb.Block().HashTreeRoot()
require.NoError(t, err)
require.Equal(t, pubsub.ValidationAccept, s.handleBlobParentStatus(ctx, r))
badRoot := [32]byte{'a'}
require.Equal(t, pubsub.ValidationIgnore, s.handleBlobParentStatus(ctx, badRoot))
s.setBadBlock(ctx, badRoot)
require.Equal(t, pubsub.ValidationReject, s.handleBlobParentStatus(ctx, badRoot))
}