From 7d7f4f858a75d5971fe8811643203fc4d053c40f Mon Sep 17 00:00:00 2001 From: Lazar <12626340+Lazar955@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:30:15 +0100 Subject: [PATCH] chore: benchmark pub randomness commit (#190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For numPubRand ≤ 1000, the growth appears roughly linear, with execution time increasing by similar factors as numPubRand --- Benchmark ran on M3 Pro. numPubRand | Iterations (b.N) | Time per Iteration (ns/op) | Approx. Time (ms) | Approx. Time (s) -- | -- | -- | -- | -- 10 | 38 | 29,210,366 | ~29.2 ms | ~0.03 s 50 | 16 | 68,297,312 | ~68.3 ms | ~0.07 s 100 | 9 | 120,456,028 | ~120.5 ms | ~0.12 s 200 | 5 | 224,715,767 | ~224.7 ms | ~0.22 s 500 | 2 | 536,105,584 | ~536.1 ms | ~0.54 s 1,000 | 1 | 1,056,664,416 | ~1.1 s | ~1.1 s 5,000 | 1 | 5,159,288,750 | ~5.2 s | ~5.2 s 10,000 | 1 | 10,353,431,958 | ~10.4 s | ~10.4 s 25,000 | 1 | 26,828,946,167 | ~26.8 s | ~26.8 s 50,000 | 1 | 53,123,792,875 | ~53.1 s | ~53.1 s 75,000 | 1 | 156,188,836,166 | ~156.2 s | ~2.6 m 100,000 | 1 | 211,468,613,458 | ~211.5 s | ~3.5 m --- ![image](https://github.com/user-attachments/assets/dad4f1cc-b197-46ae-80e9-37902db8b6c4) --- References [issue](https://github.com/babylonlabs-io/finality-provider/issues/68) --- CHANGELOG.md | 1 + finality-provider/service/fp_instance_test.go | 78 ++++++++++++++++--- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b02b99d..e5959f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * [#179](https://github.com/babylonlabs-io/finality-provider/pull/179) Change `btc_pk` text to `eots_pk` in CLI * [#182](https://github.com/babylonlabs-io/finality-provider/pull/182) Remove fp manager * [#184](https://github.com/babylonlabs-io/finality-provider/pull/184) eots manager sign record store +* [#190](https://github.com/babylonlabs-io/finality-provider/pull/190) Benchmark pub rand ### Bug Fixes diff --git a/finality-provider/service/fp_instance_test.go b/finality-provider/service/fp_instance_test.go index 34d2481..9bbf8cd 100644 --- a/finality-provider/service/fp_instance_test.go +++ b/finality-provider/service/fp_instance_test.go @@ -1,15 +1,15 @@ package service_test import ( - "math/rand" - "os" - "path/filepath" - "testing" - + "fmt" bbntypes "github.com/babylonlabs-io/babylon/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "go.uber.org/zap" + "math/rand" + "os" + "path/filepath" + "testing" "github.com/babylonlabs-io/babylon/testutil/datagen" ftypes "github.com/babylonlabs-io/babylon/x/finality/types" @@ -36,7 +36,7 @@ func FuzzCommitPubRandList(f *testing.F) { mockClientController := testutil.PrepareMockedClientController(t, r, randomStartingHeight, currentHeight, 0) mockClientController.EXPECT().QueryFinalityProviderVotingPower(gomock.Any(), gomock.Any()). Return(uint64(0), nil).AnyTimes() - _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, true, randomStartingHeight) + _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, true, randomStartingHeight, testutil.TestPubRandNum) defer cleanUp() expectedTxHash := testutil.GenRandomHexStr(r, 32) @@ -60,7 +60,7 @@ func FuzzSubmitFinalitySigs(f *testing.F) { startingBlock := &types.BlockInfo{Height: randomStartingHeight, Hash: testutil.GenRandomByteArray(r, 32)} mockClientController := testutil.PrepareMockedClientController(t, r, randomStartingHeight, currentHeight, 0) mockClientController.EXPECT().QueryLatestFinalizedBlocks(gomock.Any()).Return(nil, nil).AnyTimes() - _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, true, randomStartingHeight) + _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, true, randomStartingHeight, testutil.TestPubRandNum) defer cleanUp() // commit pub rand @@ -124,7 +124,7 @@ func FuzzDetermineStartHeight(f *testing.F) { }} mockClientController.EXPECT().QueryLatestFinalizedBlocks(uint64(1)).Return(finalizedBlocks, nil).AnyTimes() - _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, false, randomStartingHeight) + _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, false, randomStartingHeight, testutil.TestPubRandNum) defer cleanUp() fpIns.MustUpdateStateAfterFinalitySigSubmission(lastVotedHeight) @@ -139,7 +139,14 @@ func FuzzDetermineStartHeight(f *testing.F) { }) } -func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc clientcontroller.ClientController, isStaticStartHeight bool, startingHeight uint64) (*service.FinalityProviderApp, *service.FinalityProviderInstance, func()) { +func startFinalityProviderAppWithRegisteredFp( + t *testing.T, + r *rand.Rand, + cc clientcontroller.ClientController, + isStaticStartHeight bool, + startingHeight uint64, + numPubRand uint32, +) (*service.FinalityProviderApp, *service.FinalityProviderInstance, func()) { logger := zap.NewNop() // create an EOTS manager eotsHomeDir := filepath.Join(t.TempDir(), "eots-home") @@ -152,7 +159,7 @@ func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc cli // create finality-provider app with randomized config fpHomeDir := filepath.Join(t.TempDir(), "fp-home") fpCfg := config.DefaultConfigWithHome(fpHomeDir) - fpCfg.NumPubRand = testutil.TestPubRandNum + fpCfg.NumPubRand = numPubRand fpCfg.PollerConfig.AutoChainScanningMode = !isStaticStartHeight fpCfg.PollerConfig.StaticChainScanningStartHeight = startingHeight db, err := fpCfg.DatabaseConfig.GetDBBackend() @@ -194,3 +201,54 @@ func startFinalityProviderAppWithRegisteredFp(t *testing.T, r *rand.Rand, cc cli return app, fpIns, cleanUp } + +func setupBenchmarkEnvironment(t *testing.T, seed int64, numPubRand uint32) (*types.BlockInfo, *service.FinalityProviderInstance, func()) { + r := rand.New(rand.NewSource(seed)) + + randomStartingHeight := uint64(r.Int63n(100) + 1) + currentHeight := randomStartingHeight + uint64(r.Int63n(10)+2) + startingBlock := &types.BlockInfo{ + Height: randomStartingHeight, + Hash: testutil.GenRandomByteArray(r, 32), + } + + // Mock client controller setup + mockClientController := testutil.PrepareMockedClientController(t, r, randomStartingHeight, currentHeight, 0) + mockClientController.EXPECT().QueryFinalityProviderVotingPower(gomock.Any(), gomock.Any()). + Return(uint64(0), nil).AnyTimes() + + // Set up finality provider app + _, fpIns, cleanUp := startFinalityProviderAppWithRegisteredFp(t, r, mockClientController, true, randomStartingHeight, numPubRand) + + // Configure additional mocks + expectedTxHash := testutil.GenRandomHexStr(r, 32) + mockClientController.EXPECT(). + CommitPubRandList(fpIns.GetBtcPk(), startingBlock.Height+1, gomock.Any(), gomock.Any(), gomock.Any()). + Return(&types.TxResponse{TxHash: expectedTxHash}, nil).AnyTimes() + mockClientController.EXPECT().QueryLastCommittedPublicRand(gomock.Any(), uint64(1)).Return(nil, nil).AnyTimes() + + return startingBlock, fpIns, cleanUp +} +func BenchmarkCommitPubRand(b *testing.B) { + for _, numPubRand := range []uint32{10, 50, 100, 200, 500, 1000, 5000, 10000, 25000, 50000, 75000, 100000} { + b.Run(fmt.Sprintf("numPubRand=%d", numPubRand), func(b *testing.B) { + t := &testing.T{} + startingBlock, fpIns, cleanUp := setupBenchmarkEnvironment(t, 42, numPubRand) + defer cleanUp() + + // exclude setup time + b.ResetTimer() + + for i := 0; i < b.N; i++ { + res, err := fpIns.CommitPubRand(startingBlock.Height) + if err != nil { + b.Fatalf("unexpected error: %v", err) + } + + if res == nil { + b.Fatalf("unexpected result") + } + } + }) + } +}