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.
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()
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)
}
func newGetBlobEnv(t *testing.T, version byte) (*node.Node, *ConsensusAPI) {
func newGetBlobEnv(t testing.TB, version byte) (*node.Node, *ConsensusAPI) {
var (
// Create a database pre-initialize with a genesis block
config = *params.MergedTestChainConfig
@ -2045,36 +2045,57 @@ func TestGetBlobsV2(t *testing.T) {
},
}
for i, suite := range suites {
// Fill the request for retrieving blobs
var (
vhashes []common.Hash
expect []*engine.BlobAndProofV2
)
// fill missing blob
if suite.fillRandom {
vhashes = append(vhashes, testrand.Hash())
}
for j := suite.start; j < suite.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 %d, %v", i, err)
}
// null is responded if any blob is missing
if suite.fillRandom {
expect = nil
}
if !reflect.DeepEqual(result, expect) {
t.Fatalf("Unexpected result for case %d", i)
}
runGetBlobsV2(t, api, suite.start, suite.limit, suite.fillRandom, fmt.Sprintf("suite=%d", i))
}
}
// Benchmark GetBlobsV2 internals
// Note that this is not an RPC-level benchmark, so JSON-RPC overhead is not included.
func BenchmarkGetBlobsV2(b *testing.B) {
n, api := newGetBlobEnv(b, 1)
defer n.Close()
// for blobs in [1, 2, 4, 6], print string and run benchmark
for _, blobs := range []int{1, 2, 4, 6} {
name := fmt.Sprintf("blobs=%d", blobs)
b.Run(name, func(b *testing.B) {
for b.Loop() {
runGetBlobsV2(b, api, 0, blobs, false, name)
}
})
}
}
func runGetBlobsV2(t testing.TB, api *ConsensusAPI, start, limit int, fillRandom bool, name string) {
// Fill the request for retrieving blobs
var (
vhashes []common.Hash
expect []*engine.BlobAndProofV2
)
// fill missing blob
if fillRandom {
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)
}
}