eth/catalyst: benchmark GetBlobsV2 at API level (#33196)

This is to benchmark how much the internal parts of GetBlobsV2 take. 
This is not an RPC-level benchmark, so JSON-RPC overhead is not
included.

Signed-off-by: Csaba Kiraly <csaba.kiraly@gmail.com>
This commit is contained in:
Csaba Kiraly 2025-12-03 22:35:00 +01:00 committed by GitHub
parent d3679c2f2e
commit 129c562900
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -426,7 +426,7 @@ func TestEth2DeepReorg(t *testing.T) {
} }
// startEthService creates a full node instance for testing. // startEthService creates a full node instance for testing.
func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block) (*node.Node, *eth.Ethereum) { func startEthService(t testing.TB, genesis *core.Genesis, blocks []*types.Block) (*node.Node, *eth.Ethereum) {
t.Helper() t.Helper()
n, err := node.New(&node.Config{ n, err := node.New(&node.Config{
@ -1873,7 +1873,7 @@ func makeMultiBlobTx(chainConfig *params.ChainConfig, nonce uint64, blobCount in
return types.MustSignNewTx(key, types.LatestSigner(chainConfig), blobtx) return types.MustSignNewTx(key, types.LatestSigner(chainConfig), blobtx)
} }
func newGetBlobEnv(t *testing.T, version byte) (*node.Node, *ConsensusAPI) { func newGetBlobEnv(t testing.TB, version byte) (*node.Node, *ConsensusAPI) {
var ( var (
// Create a database pre-initialize with a genesis block // Create a database pre-initialize with a genesis block
config = *params.MergedTestChainConfig config = *params.MergedTestChainConfig
@ -2045,36 +2045,57 @@ func TestGetBlobsV2(t *testing.T) {
}, },
} }
for i, suite := range suites { for i, suite := range suites {
// Fill the request for retrieving blobs runGetBlobsV2(t, api, suite.start, suite.limit, suite.fillRandom, fmt.Sprintf("suite=%d", i))
var ( }
vhashes []common.Hash }
expect []*engine.BlobAndProofV2
) // Benchmark GetBlobsV2 internals
// fill missing blob // Note that this is not an RPC-level benchmark, so JSON-RPC overhead is not included.
if suite.fillRandom { func BenchmarkGetBlobsV2(b *testing.B) {
vhashes = append(vhashes, testrand.Hash()) n, api := newGetBlobEnv(b, 1)
} defer n.Close()
for j := suite.start; j < suite.limit; j++ {
vhashes = append(vhashes, testBlobVHashes[j]) // for blobs in [1, 2, 4, 6], print string and run benchmark
var cellProofs []hexutil.Bytes for _, blobs := range []int{1, 2, 4, 6} {
for _, proof := range testBlobCellProofs[j] { name := fmt.Sprintf("blobs=%d", blobs)
cellProofs = append(cellProofs, proof[:]) b.Run(name, func(b *testing.B) {
} for b.Loop() {
expect = append(expect, &engine.BlobAndProofV2{ runGetBlobsV2(b, api, 0, blobs, false, name)
Blob: testBlobs[j][:], }
CellProofs: cellProofs, })
}) }
} }
result, err := api.GetBlobsV2(vhashes)
if err != nil { func runGetBlobsV2(t testing.TB, api *ConsensusAPI, start, limit int, fillRandom bool, name string) {
t.Errorf("Unexpected error for case %d, %v", i, err) // Fill the request for retrieving blobs
} var (
// null is responded if any blob is missing vhashes []common.Hash
if suite.fillRandom { expect []*engine.BlobAndProofV2
expect = nil )
} // fill missing blob
if !reflect.DeepEqual(result, expect) { if fillRandom {
t.Fatalf("Unexpected result for case %d", i) vhashes = append(vhashes, testrand.Hash())
} }
for j := start; j < limit; j++ {
vhashes = append(vhashes, testBlobVHashes[j])
var cellProofs []hexutil.Bytes
for _, proof := range testBlobCellProofs[j] {
cellProofs = append(cellProofs, proof[:])
}
expect = append(expect, &engine.BlobAndProofV2{
Blob: testBlobs[j][:],
CellProofs: cellProofs,
})
}
result, err := api.GetBlobsV2(vhashes)
if err != nil {
t.Errorf("Unexpected error for case %s, %v", name, err)
}
// null is responded if any blob is missing
if fillRandom {
expect = nil
}
if !reflect.DeepEqual(result, expect) {
t.Fatalf("Unexpected result for case %s", name)
} }
} }