diff --git a/beacon-chain/sync/rpc_send_request.go b/beacon-chain/sync/rpc_send_request.go index cd04b49c23..a8714445b9 100644 --- a/beacon-chain/sync/rpc_send_request.go +++ b/beacon-chain/sync/rpc_send_request.go @@ -31,7 +31,7 @@ var ErrInvalidFetchedData = errors.New("invalid data returned from peer") var errMaxRequestBlobSidecarsExceeded = errors.Wrap(ErrInvalidFetchedData, "peer exceeded req blob chunk tx limit") var errBlobChunkedReadFailure = errors.New("failed to read stream of chunk-encoded blobs") var errBlobUnmarshal = errors.New("Could not unmarshal chunk-encoded blob") -var errUnrequestedRoot = errors.New("Received BlobSidecar in response that was not requested") +var errUnrequested = errors.New("Received BlobSidecar in response that was not requested") var errBlobResponseOutOfBounds = errors.New("received BlobSidecar with slot outside BlobSidecarsByRangeRequest bounds") // BeaconBlockProcessor defines a block processing function, which allows to start utilizing @@ -199,13 +199,22 @@ func SendBlobSidecarByRoot( type blobResponseValidation func(blocks.ROBlob) error func blobValidatorFromRootReq(req *p2ptypes.BlobSidecarsByRootReq) blobResponseValidation { - roots := make(map[[32]byte]bool) + blobIds := make(map[[32]byte]map[uint64]bool) for _, sc := range *req { - roots[bytesutil.ToBytes32(sc.BlockRoot)] = true + blockRoot := bytesutil.ToBytes32(sc.BlockRoot) + if blobIds[blockRoot] == nil { + blobIds[blockRoot] = make(map[uint64]bool) + } + blobIds[blockRoot][sc.Index] = true } return func(sc blocks.ROBlob) error { - if requested := roots[sc.BlockRoot()]; !requested { - return errors.Wrapf(errUnrequestedRoot, "root=%#x", sc.BlockRoot()) + blobIndices := blobIds[sc.BlockRoot()] + if blobIndices == nil { + return errors.Wrapf(errUnrequested, "root=%#x", sc.BlockRoot()) + } + requested := blobIndices[sc.Index] + if !requested { + return errors.Wrapf(errUnrequested, "root=%#x index=%d", sc.BlockRoot(), sc.Index) } return nil } diff --git a/beacon-chain/sync/rpc_send_request_test.go b/beacon-chain/sync/rpc_send_request_test.go index 235f8ef628..d99de2733b 100644 --- a/beacon-chain/sync/rpc_send_request_test.go +++ b/beacon-chain/sync/rpc_send_request_test.go @@ -479,11 +479,12 @@ func TestSendRequest_SendBeaconBlocksByRootRequest(t *testing.T) { } func TestBlobValidatorFromRootReq(t *testing.T) { - validRoot := bytesutil.PadTo([]byte("valid"), 32) - invalidRoot := bytesutil.PadTo([]byte("invalid"), 32) + rootA := bytesutil.PadTo([]byte("valid"), 32) + rootB := bytesutil.PadTo([]byte("invalid"), 32) header := ðpb.SignedBeaconBlockHeader{} - validb := util.GenerateTestDenebBlobSidecar(t, bytesutil.ToBytes32(validRoot), header, 0, []byte{}, make([][]byte, 0)) - invalidb := util.GenerateTestDenebBlobSidecar(t, bytesutil.ToBytes32(invalidRoot), header, 0, []byte{}, make([][]byte, 0)) + blobSidecarA0 := util.GenerateTestDenebBlobSidecar(t, bytesutil.ToBytes32(rootA), header, 0, []byte{}, make([][]byte, 0)) + blobSidecarA1 := util.GenerateTestDenebBlobSidecar(t, bytesutil.ToBytes32(rootA), header, 1, []byte{}, make([][]byte, 0)) + blobSidecarB0 := util.GenerateTestDenebBlobSidecar(t, bytesutil.ToBytes32(rootB), header, 0, []byte{}, make([][]byte, 0)) cases := []struct { name string ids []*ethpb.BlobIdentifier @@ -491,15 +492,21 @@ func TestBlobValidatorFromRootReq(t *testing.T) { err error }{ { - name: "valid", - ids: []*ethpb.BlobIdentifier{{BlockRoot: validRoot}}, - response: []blocks.ROBlob{validb}, + name: "expected", + ids: []*ethpb.BlobIdentifier{{BlockRoot: rootA, Index: 0}}, + response: []blocks.ROBlob{blobSidecarA0}, }, { - name: "invalid", - ids: []*ethpb.BlobIdentifier{{BlockRoot: validRoot}}, - response: []blocks.ROBlob{invalidb}, - err: errUnrequestedRoot, + name: "wrong root", + ids: []*ethpb.BlobIdentifier{{BlockRoot: rootA, Index: 0}}, + response: []blocks.ROBlob{blobSidecarB0}, + err: errUnrequested, + }, + { + name: "wrong index", + ids: []*ethpb.BlobIdentifier{{BlockRoot: rootA, Index: 0}}, + response: []blocks.ROBlob{blobSidecarA1}, + err: errUnrequested, }, } for _, c := range cases {