Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
8585cf0
wip
james-prysm Aug 15, 2025
66e05f3
wip
james-prysm Aug 15, 2025
7c0304b
adding ssz marshalling
james-prysm Aug 18, 2025
5a9fe2e
updating function for readability
james-prysm Aug 18, 2025
42cee09
adding unit tests and fixing ssz
james-prysm Aug 19, 2025
46bab54
gaz
james-prysm Aug 20, 2025
02e30a3
linting
james-prysm Aug 20, 2025
a6fb39e
Merge branch 'develop' into get-blob-fulu
james-prysm Aug 20, 2025
24acebd
fixing test
james-prysm Aug 20, 2025
8ee42d9
Merge branch 'develop' into get-blob-fulu
james-prysm Aug 25, 2025
e5ccab8
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 12, 2025
f413658
wip
james-prysm Sep 13, 2025
cafd647
fixing mock blocker
james-prysm Sep 13, 2025
e6c24d7
fixing test
james-prysm Sep 13, 2025
ea07965
fixing tests and handler
james-prysm Sep 14, 2025
2a276fa
updating unit test for more coverage
james-prysm Sep 14, 2025
1ab2cf4
adding some comments
james-prysm Sep 15, 2025
a67009c
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 15, 2025
2f22c36
self review
james-prysm Sep 15, 2025
484ca08
gofmt
james-prysm Sep 15, 2025
a032673
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 15, 2025
9babcfd
updating and consolidating tests
james-prysm Sep 15, 2025
0951df7
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 15, 2025
ab251ed
moving functional options so it can be used properly
james-prysm Sep 15, 2025
7baaa25
gofmt
james-prysm Sep 15, 2025
6fb4c58
more missed gofmt
james-prysm Sep 15, 2025
4131f07
Update beacon-chain/rpc/endpoints.go
james-prysm Sep 16, 2025
77f5856
Update beacon-chain/rpc/lookup/blocker.go
james-prysm Sep 16, 2025
bcf95ad
Update beacon-chain/rpc/eth/beacon/handlers.go
james-prysm Sep 16, 2025
d9b51a8
radek feedback
james-prysm Sep 16, 2025
e34cb64
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 16, 2025
eed1ee4
fixing tests
james-prysm Sep 16, 2025
83d4291
fixing test
james-prysm Sep 16, 2025
b793b98
moving endpoint in test
james-prysm Sep 16, 2025
b878bce
removed unneeded comment
james-prysm Sep 16, 2025
6c32c0d
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 16, 2025
d736c2e
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 16, 2025
77151bc
fixing linting from latest develop merge
james-prysm Sep 16, 2025
bafa4c6
fixing linting from latest develop merge
james-prysm Sep 16, 2025
cf5d9d9
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 17, 2025
5d67e0c
Update beacon-chain/rpc/eth/blob/handlers.go
james-prysm Sep 17, 2025
ce38c57
Update beacon-chain/rpc/eth/blob/handlers.go
james-prysm Sep 17, 2025
7a49d28
reverting change
james-prysm Sep 17, 2025
1acb5f7
reverting change
james-prysm Sep 17, 2025
9c89696
Merge branch 'develop' into get-blob-fulu
james-prysm Sep 17, 2025
ddd726a
adding in better error for which hashes are missing
james-prysm Sep 17, 2025
f25289c
Update beacon-chain/rpc/lookup/blocker.go
james-prysm Sep 17, 2025
ea4f8c4
fixing unit test
james-prysm Sep 17, 2025
23fc075
gofmt
james-prysm Sep 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/server/structs/endpoints_beacon.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,9 @@ type GetProposerLookaheadResponse struct {
Finalized bool `json:"finalized"`
Data []string `json:"data"` // validator indexes
}

type GetBlobsResponse struct {
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
Data []string `json:"data"` //blobs
}
12 changes: 12 additions & 0 deletions beacon-chain/rpc/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ func (s *Service) blobEndpoints(blocker lookup.Blocker) []endpoint {
const namespace = "blob"
return []endpoint{
{
// Deprecated: /eth/v1/beacon/blob_sidecars/{block_id} in favor of /eth/v1/beacon/blobs/{block_id}
// the endpoint will continue to work post fulu for some time however
template: "/eth/v1/beacon/blob_sidecars/{block_id}",
name: namespace + ".Blobs",
middleware: []middleware.Middleware{
Expand All @@ -203,6 +205,16 @@ func (s *Service) blobEndpoints(blocker lookup.Blocker) []endpoint {
handler: server.Blobs,
methods: []string{http.MethodGet},
},
{
template: "/eth/v1/beacon/blobs/{block_id}",
name: namespace + ".GetBlobs",
middleware: []middleware.Middleware{
middleware.AcceptHeaderHandler([]string{api.JsonMediaType, api.OctetStreamMediaType}),
middleware.AcceptEncodingHeaderHandler(),
},
handler: server.GetBlobs,
methods: []string{http.MethodGet},
},
}
}

Expand Down
1 change: 1 addition & 0 deletions beacon-chain/rpc/endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func Test_endpoints(t *testing.T) {

blobRoutes := map[string][]string{
"/eth/v1/beacon/blob_sidecars/{block_id}": {http.MethodGet},
"/eth/v1/beacon/blobs/{block_id}": {http.MethodGet},
}

configRoutes := map[string][]string{
Expand Down
4 changes: 4 additions & 0 deletions beacon-chain/rpc/eth/blob/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ go_library(
"//api/server/structs:go_default_library",
"//beacon-chain/blockchain:go_default_library",
"//beacon-chain/rpc/core:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//beacon-chain/rpc/lookup:go_default_library",
"//beacon-chain/rpc/options:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
Expand All @@ -33,6 +35,7 @@ go_test(
deps = [
"//api:go_default_library",
"//api/server/structs:go_default_library",
"//beacon-chain/blockchain/kzg:go_default_library",
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/db/filesystem:go_default_library",
"//beacon-chain/db/testing:go_default_library",
Expand All @@ -41,6 +44,7 @@ go_test(
"//beacon-chain/verification:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/primitives:go_default_library",
"//network/httputil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
Expand Down
100 changes: 96 additions & 4 deletions beacon-chain/rpc/eth/blob/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
"github.com/OffchainLabs/prysm/v6/api"
"github.com/OffchainLabs/prysm/v6/api/server/structs"
"github.com/OffchainLabs/prysm/v6/beacon-chain/rpc/core"
field_params "github.com/OffchainLabs/prysm/v6/config/fieldparams"
"github.com/OffchainLabs/prysm/v6/beacon-chain/rpc/eth/shared"
"github.com/OffchainLabs/prysm/v6/beacon-chain/rpc/options"
fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the alias can be removed because it is identical to the package name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops not sure how that happened

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait it's called field_params so i need to leave it or use the old one
i think field_params is not preferred

"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/blocks"
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
Expand All @@ -22,6 +24,8 @@ import (
)

// Blobs is an HTTP handler for Beacon API getBlobs.
// Deprecated: /eth/v1/beacon/blob_sidecars/{block_id} in favor of /eth/v1/beacon/blobs/{block_id}
// the endpoint will continue to work post fulu for some time however
func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.Blobs")
defer span.End()
Expand All @@ -34,7 +38,7 @@ func (s *Server) Blobs(w http.ResponseWriter, r *http.Request) {
segments := strings.Split(r.URL.Path, "/")
blockId := segments[len(segments)-1]

verifiedBlobs, rpcErr := s.Blocker.Blobs(ctx, blockId, indices)
verifiedBlobs, rpcErr := s.Blocker.Blobs(ctx, blockId, options.WithIndices(indices))
if rpcErr != nil {
code := core.ErrorReasonToHTTP(rpcErr.Reason)
switch code {
Expand Down Expand Up @@ -127,6 +131,94 @@ loop:
return indices, nil
}

// GetBlobs retrieves blobs for a given block id. ( this is the new handler that replaces func (s *Server) Blobs )
func (s *Server) GetBlobs(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetBlobs")
defer span.End()

segments := strings.Split(r.URL.Path, "/")
blockId := segments[len(segments)-1]

var verifiedBlobs []*blocks.VerifiedROBlob
var rpcErr *core.RpcError

// Check if versioned_hashes parameter is provided
versionedHashesStr := r.URL.Query()["versioned_hashes"]
versionedHashes := make([][]byte, len(versionedHashesStr))
if len(versionedHashesStr) > 0 {
for i, hashStr := range versionedHashesStr {
hash, ok := shared.ValidateHex(w, fmt.Sprintf("versioned_hashes[%d]", i), hashStr, 32)
if !ok {
return
}
versionedHashes[i] = hash
}
}
verifiedBlobs, rpcErr = s.Blocker.Blobs(ctx, blockId, options.WithVersionedHashes(versionedHashes))
if rpcErr != nil {
code := core.ErrorReasonToHTTP(rpcErr.Reason)
switch code {
case http.StatusBadRequest:
httputil.HandleError(w, "Bad Request: "+rpcErr.Err.Error(), code)
return
case http.StatusNotFound:
httputil.HandleError(w, "Not found: "+rpcErr.Err.Error(), code)
return
case http.StatusInternalServerError:
httputil.HandleError(w, "Internal server error: "+rpcErr.Err.Error(), code)
return
default:
httputil.HandleError(w, rpcErr.Err.Error(), code)
return
}
}

blk, err := s.Blocker.Block(ctx, []byte(blockId))
if err != nil {
httputil.HandleError(w, "Could not fetch block: "+err.Error(), http.StatusInternalServerError)
return
}
if blk == nil {
httputil.HandleError(w, "Block not found", http.StatusNotFound)
return
}

if httputil.RespondWithSsz(r) {
sszLen := fieldparams.BlobSize
sszData := make([]byte, len(verifiedBlobs)*sszLen)
for i := range verifiedBlobs {
copy(sszData[i*sszLen:(i+1)*sszLen], verifiedBlobs[i].Blob)
}

w.Header().Set(api.VersionHeader, version.String(blk.Version()))
httputil.WriteSsz(w, sszData)
return
}

blkRoot, err := blk.Block().HashTreeRoot()
if err != nil {
httputil.HandleError(w, "Could not hash block: "+err.Error(), http.StatusInternalServerError)
return
}
isOptimistic, err := s.OptimisticModeFetcher.IsOptimisticForRoot(ctx, blkRoot)
if err != nil {
httputil.HandleError(w, "Could not check if block is optimistic: "+err.Error(), http.StatusInternalServerError)
return
}

data := make([]string, len(verifiedBlobs))
for i, v := range verifiedBlobs {
data[i] = hexutil.Encode(v.Blob)
}
resp := &structs.GetBlobsResponse{
Data: data,
ExecutionOptimistic: isOptimistic,
Finalized: s.FinalizationFetcher.IsFinalized(ctx, blkRoot),
}
w.Header().Set(api.VersionHeader, version.String(blk.Version()))
httputil.WriteJson(w, resp)
}

func buildSidecarsJsonResponse(verifiedBlobs []*blocks.VerifiedROBlob) []*structs.Sidecar {
sidecars := make([]*structs.Sidecar, len(verifiedBlobs))
for i, sc := range verifiedBlobs {
Expand All @@ -147,13 +239,13 @@ func buildSidecarsJsonResponse(verifiedBlobs []*blocks.VerifiedROBlob) []*struct
}

func buildSidecarsSSZResponse(verifiedBlobs []*blocks.VerifiedROBlob) ([]byte, error) {
ssz := make([]byte, field_params.BlobSidecarSize*len(verifiedBlobs))
ssz := make([]byte, fieldparams.BlobSidecarSize*len(verifiedBlobs))
for i, sidecar := range verifiedBlobs {
sszrep, err := sidecar.MarshalSSZ()
if err != nil {
return nil, errors.Wrap(err, "failed to marshal sidecar ssz")
}
copy(ssz[i*field_params.BlobSidecarSize:(i+1)*field_params.BlobSidecarSize], sszrep)
copy(ssz[i*fieldparams.BlobSidecarSize:(i+1)*fieldparams.BlobSidecarSize], sszrep)
}
return ssz, nil
}
Loading
Loading