diff --git a/beacon-chain/sync/validate_beacon_blocks.go b/beacon-chain/sync/validate_beacon_blocks.go index 7c3424493..98fbe2c29 100644 --- a/beacon-chain/sync/validate_beacon_blocks.go +++ b/beacon-chain/sync/validate_beacon_blocks.go @@ -166,11 +166,11 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms err = s.validateBeaconBlock(ctx, blk, blockRoot) if err != nil { - // If the parent is optimistic, be gracious and don't penalize the peer. - if errors.Is(ErrOptimisticParent, err) { - return pubsub.ValidationIgnore, err + // If the parent is optimistic, process the block as usual + // This also does not penalize a peer which sends optimistic blocks + if !errors.Is(ErrOptimisticParent, err) { + return pubsub.ValidationReject, err } - return pubsub.ValidationReject, err } // Record attribute of valid block. diff --git a/beacon-chain/sync/validate_beacon_blocks_test.go b/beacon-chain/sync/validate_beacon_blocks_test.go index b9d638356..7478cd3b6 100644 --- a/beacon-chain/sync/validate_beacon_blocks_test.go +++ b/beacon-chain/sync/validate_beacon_blocks_test.go @@ -1305,3 +1305,77 @@ func Test_validateBellatrixBeaconBlockParentValidation(t *testing.T) { require.NoError(t, err) require.ErrorContains(t, "parent of the block is optimistic", r.validateBellatrixBeaconBlock(ctx, beaconState, blk.Block())) } + +func Test_validateBeaconBlockProcessingWhenParentIsOptimistic(t *testing.T) { + db := dbtest.SetupDB(t) + p := p2ptest.NewTestP2P(t) + ctx := context.Background() + stateGen := stategen.New(db) + + beaconState, privKeys := util.DeterministicGenesisStateBellatrix(t, 100) + parentBlock := util.NewBeaconBlockBellatrix() + signedParentBlock, err := wrapper.WrappedSignedBeaconBlock(parentBlock) + require.NoError(t, err) + require.NoError(t, db.SaveBlock(ctx, signedParentBlock)) + bRoot, err := parentBlock.Block.HashTreeRoot() + require.NoError(t, err) + require.NoError(t, db.SaveState(ctx, beaconState, bRoot)) + require.NoError(t, db.SaveStateSummary(ctx, ðpb.StateSummary{Root: bRoot[:]})) + copied := beaconState.Copy() + require.NoError(t, copied.SetSlot(1)) + proposerIdx, err := helpers.BeaconProposerIndex(ctx, copied) + require.NoError(t, err) + + msg := util.NewBeaconBlockBellatrix() + msg.Block.ParentRoot = bRoot[:] + msg.Block.Slot = 1 + msg.Block.ProposerIndex = proposerIdx + msg.Block.Body.ExecutionPayload.Timestamp = beaconState.GenesisTime() + params.BeaconConfig().SecondsPerSlot + msg.Block.Body.ExecutionPayload.GasUsed = 10 + msg.Block.Body.ExecutionPayload.GasLimit = 11 + msg.Block.Body.ExecutionPayload.BlockHash = bytesutil.PadTo([]byte("blockHash"), 32) + msg.Block.Body.ExecutionPayload.ParentHash = bytesutil.PadTo([]byte("parentHash"), 32) + msg.Block.Body.ExecutionPayload.Transactions = append(msg.Block.Body.ExecutionPayload.Transactions, []byte("transaction 1")) + msg.Block.Body.ExecutionPayload.Transactions = append(msg.Block.Body.ExecutionPayload.Transactions, []byte("transaction 2")) + msg.Signature, err = signing.ComputeDomainAndSign(beaconState, 0, msg.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx]) + require.NoError(t, err) + + chainService := &mock.ChainService{Genesis: time.Unix(int64(beaconState.GenesisTime()), 0), + Optimistic: true, + FinalizedCheckPoint: ðpb.Checkpoint{ + Epoch: 0, + Root: make([]byte, 32), + }} + r := &Service{ + cfg: &config{ + beaconDB: db, + p2p: p, + initialSync: &mockSync.Sync{IsSyncing: false}, + chain: chainService, + blockNotifier: chainService.BlockNotifier(), + stateGen: stateGen, + }, + seenBlockCache: lruwrpr.New(10), + badBlockCache: lruwrpr.New(10), + } + + buf := new(bytes.Buffer) + _, err = p.Encoding().EncodeGossip(buf, msg) + require.NoError(t, err) + topic := p2p.GossipTypeMapping[reflect.TypeOf(msg)] + genesisValidatorsRoot := r.cfg.chain.GenesisValidatorsRoot() + BellatrixDigest, err := signing.ComputeForkDigest(params.BeaconConfig().BellatrixForkVersion, genesisValidatorsRoot[:]) + require.NoError(t, err) + topic = r.addDigestToTopic(topic, BellatrixDigest) + m := &pubsub.Message{ + Message: &pubsubpb.Message{ + Data: buf.Bytes(), + Topic: &topic, + }, + } + + res, err := r.validateBeaconBlockPubSub(ctx, "", m) + require.NoError(t, err) + result := res == pubsub.ValidationAccept + assert.Equal(t, true, result) +}