From 271b3cedb2bc2edffa1a058f8fbfd4f568dd4999 Mon Sep 17 00:00:00 2001 From: Gui Iribarren Date: Mon, 1 Jul 2024 18:31:37 +0200 Subject: [PATCH] cmd/e2etest: add createaccts test and also BenchmarkAPICreateNAccounts --- cmd/end2endtest/account.go | 45 +++++++++++++++++++++++++++- cmd/end2endtest/helpers.go | 6 ++++ test/createaccounts_test.go | 60 +++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 test/createaccounts_test.go diff --git a/cmd/end2endtest/account.go b/cmd/end2endtest/account.go index 5e928989f..d96e6d22c 100644 --- a/cmd/end2endtest/account.go +++ b/cmd/end2endtest/account.go @@ -30,9 +30,21 @@ func init() { example: os.Args[0] + " --operation=tokentxs " + "--host http://127.0.0.1:9090/v2", } + + ops["createaccts"] = operation{ + testFunc: func() VochainTest { + return &E2ECreateAccts{} + }, + description: "Creates N accounts", + example: os.Args[0] + " --operation=createaccts --votes=1000 " + + "--host http://127.0.0.1:9090/v2", + } } -var _ VochainTest = (*E2ETokenTxs)(nil) +var ( + _ VochainTest = (*E2ETokenTxs)(nil) + _ VochainTest = (*E2ECreateAccts)(nil) +) type E2ETokenTxs struct { api *apiclient.HTTPclient @@ -42,6 +54,8 @@ type E2ETokenTxs struct { aliceFP *models.FaucetPackage } +type E2ECreateAccts struct{ e2eElection } + func (t *E2ETokenTxs) Setup(api *apiclient.HTTPclient, config *config) error { t.api = api t.config = config @@ -382,3 +396,32 @@ func ensureAccountMetadataEquals(api *apiclient.HTTPclient, metadata *apipkg.Acc } return nil, fmt.Errorf("cannot set account %s metadata after %d retries", api.MyAddress(), retries) } + +func (t *E2ECreateAccts) Setup(api *apiclient.HTTPclient, c *config) error { + t.api = api + t.config = c + + return nil +} + +func (*E2ECreateAccts) Teardown() error { + // nothing to do here + return nil +} + +func (t *E2ECreateAccts) Run() error { + startTime := time.Now() + + voterAccounts := ethereum.NewSignKeysBatch(t.config.nvotes) + if err := t.registerAnonAccts(voterAccounts); err != nil { + return err + } + + log.Infow("accounts created successfully", + "n", t.config.nvotes, "time", time.Since(startTime), + "vps", int(float64(t.config.nvotes)/time.Since(startTime).Seconds())) + + log.Infof("voterAccounts: %d", len(voterAccounts)) + + return nil +} diff --git a/cmd/end2endtest/helpers.go b/cmd/end2endtest/helpers.go index a77847c30..d06a6748d 100644 --- a/cmd/end2endtest/helpers.go +++ b/cmd/end2endtest/helpers.go @@ -763,6 +763,8 @@ func (t *e2eElection) registerAnonAccts(voterAccounts []*ethereum.SignKeys) erro errorChan := make(chan error) wg := &sync.WaitGroup{} + sem := make(chan any, t.config.parallelCount) + for i, acc := range voterAccounts { if i%10 == 0 { // Print some information about progress on large censuses @@ -771,7 +773,11 @@ func (t *e2eElection) registerAnonAccts(voterAccounts []*ethereum.SignKeys) erro wg.Add(1) go func(i int, acc *ethereum.SignKeys) { + sem <- nil // acquire a token + defer func() { <-sem }() // release the token + defer wg.Done() + pKey := acc.PrivateKey() if _, _, err := t.createAccount(pKey.String()); err != nil && !strings.Contains(err.Error(), "createAccountTx: account already exists") { diff --git a/test/createaccounts_test.go b/test/createaccounts_test.go new file mode 100644 index 000000000..1fc94d866 --- /dev/null +++ b/test/createaccounts_test.go @@ -0,0 +1,60 @@ +package test + +import ( + "encoding/json" + "testing" + + qt "github.com/frankban/quicktest" + "github.com/google/uuid" + "go.vocdoni.io/dvote/api" + "go.vocdoni.io/dvote/test/testcommon" + "go.vocdoni.io/dvote/test/testcommon/testutil" +) + +func BenchmarkAPICreateNAccounts(b *testing.B) { + server := testcommon.APIserver{} + server.Start(b, + api.ChainHandler, + api.CensusHandler, + api.VoteHandler, + api.AccountHandler, + api.ElectionHandler, + api.WalletHandler, + ) + token1 := uuid.New() + c := testutil.NewTestHTTPclient(b, server.ListenAddr, &token1) + + // Block 1 + server.VochainAPP.AdvanceTestBlock() + waitUntilHeight(b, c, 1) + + countAccts := func() uint64 { + // get accounts count + resp, code := c.Request("GET", nil, "accounts", "count") + qt.Assert(b, code, qt.Equals, 200, qt.Commentf("response: %s", resp)) + + countAccts := struct { + Count uint64 `json:"count"` + }{} + + err := json.Unmarshal(resp, &countAccts) + qt.Assert(b, err, qt.IsNil) + + return countAccts.Count + } + + // create a new account + initBalance := uint64(80) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = createAccount(b, c, server, initBalance) + } + // Block 2 + server.VochainAPP.AdvanceTestBlock() + waitUntilHeight(b, c, 2) + + if count := countAccts(); count < uint64(b.N) { + qt.Assert(b, count, qt.Equals, b.N) + } +}