Skip to content

Commit c75be1f

Browse files
committed
eth/catalyst: implement getBlobsV3
1 parent 16f5028 commit c75be1f

File tree

2 files changed

+59
-11
lines changed

2 files changed

+59
-11
lines changed

eth/catalyst/api.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ var (
9393

9494
// Number of times getBlobsV2 responded with “miss”
9595
getBlobsV2RequestMiss = metrics.NewRegisteredCounter("engine/getblobs/miss", nil)
96+
97+
// Number of blobs getBlobsV3 could return
98+
getBlobsV3RequestHit = metrics.NewRegisteredCounter("engine/getblobsV3/hit", nil)
99+
100+
// Number of blobs getBlobsV3 could not return
101+
getBlobsV3RequestMiss = metrics.NewRegisteredCounter("engine/getblobsV3/miss", nil)
96102
)
97103

98104
type ConsensusAPI struct {
@@ -606,6 +612,41 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo
606612
return res, nil
607613
}
608614

615+
// GetBlobsV3 returns a set of blobs from the transaction pool. Same as
616+
// GetBlobsV2, except will return partial responses in case there is a missing
617+
// blob.
618+
func (api *ConsensusAPI) GetBlobsV3(hashes []common.Hash) ([]*engine.BlobAndProofV2, error) {
619+
if len(hashes) > 128 {
620+
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes)))
621+
}
622+
available := api.eth.BlobTxPool().AvailableBlobs(hashes)
623+
getBlobsRequestedCounter.Inc(int64(len(hashes)))
624+
getBlobsAvailableCounter.Inc(int64(available))
625+
626+
blobs, _, proofs, err := api.eth.BlobTxPool().GetBlobs(hashes, types.BlobSidecarVersion1, false)
627+
if err != nil {
628+
return nil, engine.InvalidParams.With(err)
629+
}
630+
631+
res := make([]*engine.BlobAndProofV2, len(hashes))
632+
for i := range blobs {
633+
if blobs[i] == nil {
634+
getBlobsV3RequestMiss.Inc(1)
635+
continue
636+
}
637+
getBlobsV3RequestHit.Inc(1)
638+
var cellProofs []hexutil.Bytes
639+
for _, proof := range proofs[i] {
640+
cellProofs = append(cellProofs, proof[:])
641+
}
642+
res[i] = &engine.BlobAndProofV2{
643+
Blob: blobs[i][:],
644+
CellProofs: cellProofs,
645+
}
646+
}
647+
return res, nil
648+
}
649+
609650
// Helper for NewPayload* methods.
610651
var invalidStatus = engine.PayloadStatusV1{Status: engine.INVALID}
611652

eth/catalyst/api_test.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,7 +2016,7 @@ func TestGetBlobsV1AfterOsakaFork(t *testing.T) {
20162016
}
20172017
}
20182018

2019-
func TestGetBlobsV2(t *testing.T) {
2019+
func TestGetBlobsV2And3(t *testing.T) {
20202020
n, api := newGetBlobEnv(t, 1)
20212021
defer n.Close()
20222022

@@ -2045,7 +2045,8 @@ func TestGetBlobsV2(t *testing.T) {
20452045
},
20462046
}
20472047
for i, suite := range suites {
2048-
runGetBlobsV2(t, api, suite.start, suite.limit, suite.fillRandom, fmt.Sprintf("suite=%d", i))
2048+
runGetBlobs(t, api.GetBlobsV2, suite.start, suite.limit, suite.fillRandom, false, fmt.Sprintf("GetBlobsV2 suite=%d", i))
2049+
runGetBlobs(t, api.GetBlobsV3, suite.start, suite.limit, suite.fillRandom, true, fmt.Sprintf("GetBlobsV3 suite=%d %v", i, suite))
20492050
}
20502051
}
20512052

@@ -2060,22 +2061,20 @@ func BenchmarkGetBlobsV2(b *testing.B) {
20602061
name := fmt.Sprintf("blobs=%d", blobs)
20612062
b.Run(name, func(b *testing.B) {
20622063
for b.Loop() {
2063-
runGetBlobsV2(b, api, 0, blobs, false, name)
2064+
runGetBlobs(b, api.GetBlobsV2, 0, blobs, false, false, name)
20642065
}
20652066
})
20662067
}
20672068
}
20682069

2069-
func runGetBlobsV2(t testing.TB, api *ConsensusAPI, start, limit int, fillRandom bool, name string) {
2070+
type getBlobsFn func(hashes []common.Hash) ([]*engine.BlobAndProofV2, error)
2071+
2072+
func runGetBlobs(t testing.TB, getBlobs getBlobsFn, start, limit int, fillRandom bool, expectPartialResponse bool, name string) {
20702073
// Fill the request for retrieving blobs
20712074
var (
20722075
vhashes []common.Hash
20732076
expect []*engine.BlobAndProofV2
20742077
)
2075-
// fill missing blob
2076-
if fillRandom {
2077-
vhashes = append(vhashes, testrand.Hash())
2078-
}
20792078
for j := start; j < limit; j++ {
20802079
vhashes = append(vhashes, testBlobVHashes[j])
20812080
var cellProofs []hexutil.Bytes
@@ -2087,13 +2086,21 @@ func runGetBlobsV2(t testing.TB, api *ConsensusAPI, start, limit int, fillRandom
20872086
CellProofs: cellProofs,
20882087
})
20892088
}
2090-
result, err := api.GetBlobsV2(vhashes)
2089+
// fill missing blob
2090+
if fillRandom {
2091+
vhashes = append(vhashes, testrand.Hash())
2092+
}
2093+
result, err := getBlobs(vhashes)
20912094
if err != nil {
20922095
t.Errorf("Unexpected error for case %s, %v", name, err)
20932096
}
2094-
// null is responded if any blob is missing
20952097
if fillRandom {
2096-
expect = nil
2098+
if expectPartialResponse {
2099+
expect = append(expect, nil)
2100+
} else {
2101+
// Nil is expected if getBlobs can not return a partial response
2102+
expect = nil
2103+
}
20972104
}
20982105
if !reflect.DeepEqual(result, expect) {
20992106
t.Fatalf("Unexpected result for case %s", name)

0 commit comments

Comments
 (0)