Commit 7ef1bcf1 authored by zhiqiangxu's avatar zhiqiangxu Committed by GitHub

make `l1.beacon-archiver` work (#10269)

* make l1.beacon-archiver work

* check #blobs inside BeaconBlobSideCars

* compatible with fetchAllSidecars

* also check inside BeaconBlobSideCars

* check index set inclusion in BeaconBlobSideCars

* preallocate

* add test for BeaconBlobSideCars

* assert error string
parent 93891de2
// Code generated by mockery v2.28.1. DO NOT EDIT.
package mocks
import (
context "context"
http "net/http"
mock "github.com/stretchr/testify/mock"
url "net/url"
)
// HTTP is an autogenerated mock type for the HTTP type
type HTTP struct {
mock.Mock
}
type HTTP_Expecter struct {
mock *mock.Mock
}
func (_m *HTTP) EXPECT() *HTTP_Expecter {
return &HTTP_Expecter{mock: &_m.Mock}
}
// Get provides a mock function with given fields: ctx, path, query, headers
func (_m *HTTP) Get(ctx context.Context, path string, query url.Values, headers http.Header) (*http.Response, error) {
ret := _m.Called(ctx, path, query, headers)
var r0 *http.Response
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, url.Values, http.Header) (*http.Response, error)); ok {
return rf(ctx, path, query, headers)
}
if rf, ok := ret.Get(0).(func(context.Context, string, url.Values, http.Header) *http.Response); ok {
r0 = rf(ctx, path, query, headers)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*http.Response)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, url.Values, http.Header) error); ok {
r1 = rf(ctx, path, query, headers)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// HTTP_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get'
type HTTP_Get_Call struct {
*mock.Call
}
// Get is a helper method to define mock.On call
// - ctx context.Context
// - path string
// - query url.Values
// - headers http.Header
func (_e *HTTP_Expecter) Get(ctx interface{}, path interface{}, query interface{}, headers interface{}) *HTTP_Get_Call {
return &HTTP_Get_Call{Call: _e.mock.On("Get", ctx, path, query, headers)}
}
func (_c *HTTP_Get_Call) Run(run func(ctx context.Context, path string, query url.Values, headers http.Header)) *HTTP_Get_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(url.Values), args[3].(http.Header))
})
return _c
}
func (_c *HTTP_Get_Call) Return(_a0 *http.Response, _a1 error) *HTTP_Get_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *HTTP_Get_Call) RunAndReturn(run func(context.Context, string, url.Values, http.Header) (*http.Response, error)) *HTTP_Get_Call {
_c.Call.Return(run)
return _c
}
type mockConstructorTestingTNewHTTP interface {
mock.TestingT
Cleanup(func())
}
// NewHTTP creates a new instance of HTTP. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewHTTP(t mockConstructorTestingTNewHTTP) *HTTP {
mock := &HTTP{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
\ No newline at end of file
......@@ -129,6 +129,19 @@ func (cl *BeaconHTTPClient) BeaconBlobSideCars(ctx context.Context, fetchAllSide
if err := cl.apiReq(ctx, &resp, reqPath, reqQuery); err != nil {
return eth.APIGetBlobSidecarsResponse{}, err
}
indices := make(map[uint64]struct{}, len(hashes))
for _, h := range hashes {
indices[h.Index] = struct{}{}
}
for _, apisc := range resp.Data {
delete(indices, uint64(apisc.Index))
}
if len(indices) > 0 {
return eth.APIGetBlobSidecarsResponse{}, fmt.Errorf("#returned blobs(%d) != #requested blobs(%d)", len(hashes)-len(indices), len(hashes))
}
return resp, nil
}
......
package sources
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"path"
"strconv"
"testing"
client_mocks "github.com/ethereum-optimism/optimism/op-service/client/mocks"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/sources/mocks"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
......@@ -174,6 +183,37 @@ func TestBeaconClientFallback(t *testing.T) {
}
func TestBeaconHTTPClient(t *testing.T) {
c := client_mocks.NewHTTP(t)
b := NewBeaconHTTPClient(c)
ctx := context.Background()
indices := []uint64{3, 9, 11}
index0, _ := makeTestBlobSidecar(indices[0])
index1, _ := makeTestBlobSidecar(indices[1])
index2, _ := makeTestBlobSidecar(indices[2])
hashes := []eth.IndexedBlobHash{index0, index1, index2}
// mocks returning a 200 with empty list
respBytes, _ := json.Marshal(eth.APIGetBlobSidecarsResponse{})
slot := uint64(2)
path := path.Join(sidecarsMethodPrefix, strconv.FormatUint(slot, 10))
reqQuery := url.Values{}
for i := range hashes {
reqQuery.Add("indices", strconv.FormatUint(hashes[i].Index, 10))
}
headers := http.Header{}
headers.Add("Accept", "application/json")
c.EXPECT().Get(ctx, path, reqQuery, headers).Return(&http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewReader(respBytes))}, nil)
// BeaconBlobSideCars should return error when client.HTTP returns a 200 with empty list
_, err := b.BeaconBlobSideCars(ctx, false, slot, hashes)
require.Error(t, err)
require.Equal(t, err.Error(), fmt.Sprintf("#returned blobs(%d) != #requested blobs(%d)", 0, len(hashes)))
}
func TestClientPoolSingle(t *testing.T) {
p := NewClientPool[int](1)
for i := 0; i < 10; i++ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment