Blob API - invalid indicies should error instead of ignored (#13616)

* addressing ux issue when using API

* Update beacon-chain/rpc/eth/blob/handlers.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* Update beacon-chain/rpc/eth/blob/handlers.go

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>

* fixing tests

---------

Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
This commit is contained in:
james-prysm 2024-02-15 13:54:42 -06:00 committed by GitHub
parent 3a2734f249
commit 2d0fe20917
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 7 deletions

View File

@ -1,6 +1,7 @@
package blob
import (
"fmt"
"net/http"
"net/url"
"strconv"
@ -21,7 +22,11 @@ func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
defer span.End()
var sidecars []*eth.BlobSidecar
indices := parseIndices(r.URL)
indices, err := parseIndices(r.URL)
if err != nil {
httputil.HandleError(w, err.Error(), http.StatusBadRequest)
return
}
segments := strings.Split(r.URL.Path, "/")
blockId := segments[len(segments)-1]
@ -63,16 +68,19 @@ func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
}
// parseIndices filters out invalid and duplicate blob indices
func parseIndices(url *url.URL) []uint64 {
func parseIndices(url *url.URL) ([]uint64, error) {
rawIndices := url.Query()["indices"]
indices := make([]uint64, 0, field_params.MaxBlobsPerBlock)
invalidIndices := make([]string, 0)
loop:
for _, raw := range rawIndices {
ix, err := strconv.ParseUint(raw, 10, 64)
if err != nil {
invalidIndices = append(invalidIndices, raw)
continue
}
if ix >= field_params.MaxBlobsPerBlock {
invalidIndices = append(invalidIndices, raw)
continue
}
for i := range indices {
@ -82,7 +90,11 @@ loop:
}
indices = append(indices, ix)
}
return indices
if len(invalidIndices) > 0 {
return nil, fmt.Errorf("requested blob indices %v are invalid", invalidIndices)
}
return indices, nil
}
func buildSidecarsResponse(sidecars []*eth.BlobSidecar) *structs.SidecarsResponse {

View File

@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"reflect"
"strings"
"testing"
"time"
@ -27,10 +28,6 @@ import (
"github.com/prysmaticlabs/prysm/v5/testing/util"
)
func TestParseIndices(t *testing.T) {
assert.DeepEqual(t, []uint64{1, 2, 3}, parseIndices(&url.URL{RawQuery: "indices=100&indices=1&indices=2&indices=foo&indices=1&indices=3&bar=bar"}))
}
func TestBlobs(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig().Copy()
@ -372,3 +369,46 @@ func TestBlobs(t *testing.T) {
require.Equal(t, len(writer.Body.Bytes()), 131932)
})
}
func Test_parseIndices(t *testing.T) {
tests := []struct {
name string
query string
want []uint64
wantErr string
}{
{
name: "happy path with duplicate indices within bound and other query parameters ignored",
query: "indices=1&indices=2&indices=1&indices=3&bar=bar",
want: []uint64{1, 2, 3},
},
{
name: "out of bounds indices throws error",
query: "indices=6&indices=7",
wantErr: "requested blob indices [6 7] are invalid",
},
{
name: "negative indices",
query: "indices=-1&indices=-8",
wantErr: "requested blob indices [-1 -8] are invalid",
},
{
name: "invalid indices",
query: "indices=foo&indices=bar",
wantErr: "requested blob indices [foo bar] are invalid",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parseIndices(&url.URL{RawQuery: tt.query})
if err != nil && tt.wantErr != "" {
require.StringContains(t, tt.wantErr, err.Error())
return
}
require.NoError(t, err)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("parseIndices() got = %v, want %v", got, tt.want)
}
})
}
}