Skip to content
Open
Changes from all commits
Commits
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
43 changes: 23 additions & 20 deletions util/headerreader/blob_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ func beaconRequest[T interface{}](b *BlobClient, ctx context.Context, beaconPath
if queryParams != nil {
beaconUrl.RawQuery = queryParams.Encode()
}
req, err := http.NewRequestWithContext(ctx, "GET", beaconUrl.String(), http.NoBody)
fullUrl := beaconUrl.String()
req, err := http.NewRequestWithContext(ctx, "GET", fullUrl, http.NoBody)
if err != nil {
return nil, err
}
Expand All @@ -149,12 +150,8 @@ func beaconRequest[T interface{}](b *BlobClient, ctx context.Context, beaconPath
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
bodyStr := string(body)
log.Debug("beacon request returned response with non 200 OK status", "status", resp.Status, "body", bodyStr)
if len(bodyStr) > 100 {
return nil, fmt.Errorf("response returned with status %s, want 200 OK. body: %s ", resp.Status, bodyStr[len(bodyStr)-trailingCharsOfResponse:])
} else {
return nil, fmt.Errorf("response returned with status %s, want 200 OK. body: %s", resp.Status, bodyStr)
}
log.Debug("beacon request returned response with non 200 OK status", "url", fullUrl, "status", resp.Status, "body", bodyStr)
return nil, fmt.Errorf("response returned with status %s, want 200 OK. url: %s, body: %s", resp.Status, fullUrl, bodyStr)
}
return resp, nil
}
Expand Down Expand Up @@ -228,19 +225,25 @@ func (b *BlobClient) GetBlobsBySlot(ctx context.Context, slot uint64, versionedH
}

func (b *BlobClient) getBlobs(ctx context.Context, slot uint64, versionedHashes []common.Hash) ([]kzg4844.Blob, error) {
beaconPath := fmt.Sprintf("/eth/v1/beacon/blobs/%d", slot)
queryParams := url.Values{}
for _, hash := range versionedHashes {
queryParams.Add("versioned_hashes", hash.Hex())
}

response, err := beaconRequest[[]hexutil.Bytes](b, ctx, fmt.Sprintf("/eth/v1/beacon/blobs/%d", slot), queryParams)
// Construct the full URL for error reporting
fullUrl := *b.beaconUrl
fullUrl.Path = path.Join(fullUrl.Path, beaconPath)
fullUrl.RawQuery = queryParams.Encode()

response, err := beaconRequest[[]hexutil.Bytes](b, ctx, beaconPath, queryParams)
if err != nil {
// #nosec G115
roughAgeOfSlot := uint64(time.Now().Unix()) - (b.genesisTime + slot*b.secondsPerSlot)
if roughAgeOfSlot > b.secondsPerSlot*32*4096 {
return nil, fmt.Errorf("beacon client in getBlobs got error fetching older blobs in slot: %d, an archive endpoint is required, please refer to https://docs.arbitrum.io/run-arbitrum-node/l1-ethereum-beacon-chain-rpc-providers, err: %w", slot, err)
return nil, fmt.Errorf("beacon client in getBlobs got error fetching older blobs in slot: %d, url: %s, an archive endpoint is required, please refer to https://docs.arbitrum.io/run-arbitrum-node/l1-ethereum-beacon-chain-rpc-providers, err: %w", slot, fullUrl.String(), err)
} else {
return nil, fmt.Errorf("beacon client in getBlobs got error fetching non-expired blobs in slot: %d, err: %w", slot, err)
return nil, fmt.Errorf("beacon client in getBlobs got error fetching non-expired blobs in slot: %d, url: %s, err: %w", slot, fullUrl.String(), err)
}
}

Expand Down Expand Up @@ -281,29 +284,29 @@ type blobResponseItem struct {
KzgProof hexutil.Bytes `json:"kzg_proof"`
}

const trailingCharsOfResponse = 25

func (b *BlobClient) blobSidecars(ctx context.Context, slot uint64, versionedHashes []common.Hash) ([]kzg4844.Blob, error) {
rawData, err := beaconRequest[json.RawMessage](b, ctx, fmt.Sprintf("/eth/v1/beacon/blob_sidecars/%d", slot), nil)
beaconPath := fmt.Sprintf("/eth/v1/beacon/blob_sidecars/%d", slot)

// Construct the full URL for error reporting
fullUrl := *b.beaconUrl
fullUrl.Path = path.Join(fullUrl.Path, beaconPath)

rawData, err := beaconRequest[json.RawMessage](b, ctx, beaconPath, nil)
if err != nil || len(rawData) == 0 {
// blobs are pruned after 4096 epochs (1 epoch = 32 slots), we determine if the requested slot was to be pruned by a non-archive endpoint
// #nosec G115
roughAgeOfSlot := uint64(time.Now().Unix()) - (b.genesisTime + slot*b.secondsPerSlot)
if roughAgeOfSlot > b.secondsPerSlot*32*4096 {
return nil, fmt.Errorf("beacon client in blobSidecars got error or empty response fetching older blobs in slot: %d, an archive endpoint is required, please refer to https://docs.arbitrum.io/run-arbitrum-node/l1-ethereum-beacon-chain-rpc-providers, err: %w", slot, err)
return nil, fmt.Errorf("beacon client in blobSidecars got error or empty response fetching older blobs in slot: %d, url: %s, an archive endpoint is required, please refer to https://docs.arbitrum.io/run-arbitrum-node/l1-ethereum-beacon-chain-rpc-providers, err: %w", slot, fullUrl.String(), err)
} else {
return nil, fmt.Errorf("beacon client in blobSidecars got error or empty response fetching non-expired blobs in slot: %d, if using a Prysm endpoint, try --enable-experimental-backfill flag, err: %w", slot, err)
return nil, fmt.Errorf("beacon client in blobSidecars got error or empty response fetching non-expired blobs in slot: %d, url: %s, if using a Prysm endpoint, try --enable-experimental-backfill flag, err: %w", slot, fullUrl.String(), err)
}
}
var response []blobResponseItem
if err := json.Unmarshal(rawData, &response); err != nil {
rawDataStr := string(rawData)
log.Debug("response from beacon URL cannot be unmarshalled into array of blobResponseItem in blobSidecars", "slot", slot, "responseLength", len(rawDataStr), "response", rawDataStr)
if len(rawDataStr) > 100 {
return nil, fmt.Errorf("error unmarshalling response from beacon URL into array of blobResponseItem in blobSidecars: %w. Trailing %d characters of the response: %s", err, trailingCharsOfResponse, rawDataStr[len(rawDataStr)-trailingCharsOfResponse:])
} else {
return nil, fmt.Errorf("error unmarshalling response from beacon URL into array of blobResponseItem in blobSidecars: %w. Response: %s", err, rawDataStr)
}
return nil, fmt.Errorf("error unmarshalling response from beacon URL into array of blobResponseItem in blobSidecars: %w. Response: %s", err, rawDataStr)
}

if len(response) < len(versionedHashes) {
Expand Down
Loading