Skip to content

Commit

Permalink
Merge pull request #1683 from 0xPolygonHermez/tests/benchmark-scripts
Browse files Browse the repository at this point in the history
Tests/benchmark scripts
  • Loading branch information
Psykepro committed Feb 23, 2023
2 parents b788401 + 2439dda commit 17b8a03
Show file tree
Hide file tree
Showing 16 changed files with 481 additions and 157 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
**/.DS_Store
.vscode
.idea/

.env
out.dat

cmd/__debug_bin
11 changes: 11 additions & 0 deletions state/pgstatestorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,17 @@ func (p *PostgresStorage) GetL2BlockByNumber(ctx context.Context, blockNumber ui
return block, nil
}

// GetLastL2BlockCreatedAt gets the timestamp of the last l2 block
func (p *PostgresStorage) GetLastL2BlockCreatedAt(ctx context.Context, dbTx pgx.Tx) (*time.Time, error) {
var createdAt time.Time
q := p.getExecQuerier(dbTx)
err := q.QueryRow(ctx, "SELECT created_at FROM state.l2block b order by b.block_num desc LIMIT 1").Scan(&createdAt)
if err != nil {
return nil, err
}
return &createdAt, nil
}

// GetTransactionByHash gets a transaction accordingly to the provided transaction hash
func (p *PostgresStorage) GetTransactionByHash(ctx context.Context, transactionHash common.Hash, dbTx pgx.Tx) (*types.Transaction, error) {
var encoded string
Expand Down
37 changes: 23 additions & 14 deletions test/benchmarks/sequencer/common/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
metricsLib "github.com/0xPolygonHermez/zkevm-node/metrics"
"github.com/0xPolygonHermez/zkevm-node/sequencer/metrics"
metricsState "github.com/0xPolygonHermez/zkevm-node/state/metrics"
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/shared"
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params"
"github.com/0xPolygonHermez/zkevm-node/test/testutils"
)

Expand All @@ -21,22 +21,31 @@ const (

// CalculateAndPrint calculates and prints the results
func CalculateAndPrint(prometheusResp *http.Response, profilingResult string, elapsed time.Duration, sequencerTimeSub, executorTimeSub float64, nTxs int) {
sequencerTime, executorTime, workerTime, err := GetValues(prometheusResp)
if err != nil {
log.Fatalf("error getting prometheus metrics: %v", err)
var (
sequencerTime, executorTime, workerTime float64
err error
)
if prometheusResp != nil {
sequencerTime, executorTime, workerTime, err = GetValues(prometheusResp)
if err != nil {
log.Fatalf("error getting prometheus metrics: %v", err)
}
}

log.Info("##########")
log.Info("# Result #")
log.Info("##########")
log.Infof("Total time took for the sequencer To select all txs from the pool: %v", elapsed)
log.Info("######################")
log.Info("# Prometheus Metrics #")
log.Info("######################")
actualTotalTime := sequencerTime - sequencerTimeSub
actualExecutorTime := executorTime - executorTimeSub
PrintPrometheus(actualTotalTime, actualExecutorTime, workerTime)
log.Infof("[Transactions per second]: %v", float64(nTxs)/actualTotalTime)
log.Infof("Total time (including setup of environment and starting containers): %v", elapsed)

if prometheusResp != nil {
log.Info("######################")
log.Info("# Prometheus Metrics #")
log.Info("######################")
actualTotalTime := sequencerTime - sequencerTimeSub
actualExecutorTime := executorTime - executorTimeSub
PrintPrometheus(actualTotalTime, actualExecutorTime, workerTime)
log.Infof("[Transactions per second]: %v", float64(nTxs)/actualTotalTime)
}
if profilingResult != "" {
log.Info("#####################")
log.Info("# Profiling Metrics #")
Expand Down Expand Up @@ -83,14 +92,14 @@ func GetValues(metricsResponse *http.Response) (float64, float64, float64, error
// FetchPrometheus fetches the prometheus metrics
func FetchPrometheus() (*http.Response, error) {
log.Infof("Fetching prometheus metrics ...")
return http.Get(fmt.Sprintf("http://localhost:%d%s", shared.PrometheusPort, metricsLib.Endpoint))
return http.Get(fmt.Sprintf("http://localhost:%d%s", params.PrometheusPort, metricsLib.Endpoint))
}

// FetchProfiling fetches the profiling metrics
func FetchProfiling() (string, error) {
fullUrl := fmt.Sprintf("http://localhost:%d%s", profilingPort, metricsLib.ProfileEndpoint)
log.Infof("Fetching profiling metrics from: %s ...", fullUrl)
cmd := exec.Command("go", "tool", "pprof", "-top", fullUrl)
cmd := exec.Command("go", "tool", "pprof", "-show=sequencer", "-top", fullUrl)
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("Error running pprof: %v\n%s", err, out)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package shared
package params

import (
"time"
Expand All @@ -11,4 +11,6 @@ const (
MaxCumulativeGasUsed = 80000000000
// PrometheusPort is the port where prometheus is running
PrometheusPort = 9092
// NumberOfTxs is the number of transactions to send
NumberOfTxs = 100
)
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package shared
package params

import (
"context"
"math/big"
"strings"

"github.com/0xPolygonHermez/zkevm-node/test/dbutils"
"github.com/0xPolygonHermez/zkevm-node/test/operations"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
Expand All @@ -29,6 +27,4 @@ var (
To = common.HexToAddress(ToAddress)
// PrivateKey is the private key of the sender
PrivateKey, _ = crypto.HexToECDSA(strings.TrimPrefix(SequencerPrivateKey, "0x"))
// Auth is the auth of the sender
Auth, _ = bind.NewKeyedTransactorWithChainID(PrivateKey, new(big.Int).SetUint64(ChainID))
)
30 changes: 20 additions & 10 deletions test/benchmarks/sequencer/common/setup/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import (
"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/pool"
"github.com/0xPolygonHermez/zkevm-node/pool/pgpoolstorage"
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/shared"
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params"
"github.com/0xPolygonHermez/zkevm-node/test/operations"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
Expand All @@ -19,16 +20,16 @@ import (
const sleepDuration = 5 * time.Second

// Environment sets up the environment for the benchmark
func Environment(ctx context.Context, b *testing.B) (*operations.Manager, *ethclient.Client, *pool.Pool, uint64, *big.Int) {
func Environment(ctx context.Context, b *testing.B) (*operations.Manager, *ethclient.Client, *pool.Pool, *bind.TransactOpts) {
if testing.Short() {
b.Skip()
}

err := operations.Teardown()
require.NoError(b, err)

shared.OpsCfg.State.MaxCumulativeGasUsed = shared.MaxCumulativeGasUsed
opsman, err := operations.NewManager(ctx, shared.OpsCfg)
params.OpsCfg.State.MaxCumulativeGasUsed = params.MaxCumulativeGasUsed
opsman, err := operations.NewManager(ctx, params.OpsCfg)
require.NoError(b, err)

err = Components(opsman)
Expand All @@ -39,20 +40,20 @@ func Environment(ctx context.Context, b *testing.B) (*operations.Manager, *ethcl
auth, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL2ChainID)
require.NoError(b, err)

// Load common client
// Load params client
client, err := ethclient.Dial(operations.DefaultL2NetworkURL)
require.NoError(b, err)

st := opsman.State()
s, err := pgpoolstorage.NewPostgresPoolStorage(shared.PoolDbConfig)
s, err := pgpoolstorage.NewPostgresPoolStorage(params.PoolDbConfig)
require.NoError(b, err)

config := pool.Config{
FreeClaimGasLimit: 1000000, //nolint:gomnd
DB: shared.PoolDbConfig,
DB: params.PoolDbConfig,
}

pl := pool.NewPool(config, s, st, common.Address{}, shared.ChainID)
pl := pool.NewPool(config, s, st, common.Address{}, params.ChainID)

// Print Info before send
senderBalance, err := client.BalanceAt(ctx, auth.From, nil)
Expand All @@ -61,15 +62,24 @@ func Environment(ctx context.Context, b *testing.B) (*operations.Manager, *ethcl
require.NoError(b, err)

// Print Initial Stats
log.Infof("Receiver Addr: %v", shared.To.String())
log.Infof("Receiver Addr: %v", params.To.String())
log.Infof("Sender Addr: %v", auth.From.String())
log.Infof("Sender Balance: %v", senderBalance.String())
log.Infof("Sender Nonce: %v", senderNonce)

gasPrice, err := client.SuggestGasPrice(ctx)
require.NoError(b, err)

return opsman, client, pl, senderNonce, gasPrice
// PrivateKey is the private key of the sender
// Auth is the auth of the sender
auth, err = bind.NewKeyedTransactorWithChainID(params.PrivateKey, new(big.Int).SetUint64(params.ChainID))
if err != nil {
panic(err)
}
auth.GasPrice = gasPrice
auth.Nonce = new(big.Int).SetUint64(senderNonce)

return opsman, client, pl, auth
}

// Components runs the network container, starts synchronizer and JSON-RPC components, and approves matic
Expand Down
80 changes: 60 additions & 20 deletions test/benchmarks/sequencer/common/transactions/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,90 @@ package transactions
import (
"context"
"math/big"
"testing"
"strconv"
"time"

"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/pool"
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/shared"
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params"
"github.com/0xPolygonHermez/zkevm-node/test/operations"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
)

// SendAndWait sends a number of transactions and waits for them to be marked as pending in the pool
func SendAndWait(
b *testing.B,
senderNonce uint64,
client *ethclient.Client,
gasPrice *big.Int,
pl *pool.Pool,
ctx context.Context,
auth *bind.TransactOpts,
client *ethclient.Client,
countByStatusFunc func(ctx context.Context, status pool.TxStatus) (uint64, error),
nTxs int,
txSenderFunc func(b *testing.B, l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64),
) {
shared.Auth.GasPrice = gasPrice
shared.Auth.GasLimit = 2100000
txSenderFunc func(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth *bind.TransactOpts) error,
) error {
auth.GasLimit = 2100000
log.Debugf("Sending %d txs ...", nTxs)
maxNonce := uint64(nTxs) + senderNonce
startingNonce := auth.Nonce.Uint64()
maxNonce := uint64(nTxs) + startingNonce

for nonce := senderNonce; nonce < maxNonce; nonce++ {
txSenderFunc(b, client, gasPrice, nonce)
for nonce := startingNonce; nonce < maxNonce; nonce++ {
err := txSenderFunc(client, auth.GasPrice, nonce, auth)
if err != nil {
return err
}
}
log.Debug("All txs were sent!")

log.Debug("Waiting pending transactions To be added in the pool ...")
err := operations.Poll(1*time.Second, shared.DefaultDeadline, func() (bool, error) {
err := operations.Poll(1*time.Second, params.DefaultDeadline, func() (bool, error) {
// using a closure here To capture st and currentBatchNumber
count, err := pl.CountPendingTransactions(ctx)
count, err := countByStatusFunc(ctx, pool.TxStatusPending)
if err != nil {
return false, err
}

log.Debugf("amount of pending txs: %d\n", count)
done := count == uint64(nTxs)
done := count == 0
return done, nil
})
require.NoError(b, err)
if err != nil {
return err
}

log.Debug("All pending txs are added in the pool!")

return nil
}

// WaitStatusSelected waits for a number of transactions to be marked as selected in the pool
func WaitStatusSelected(countByStatusFunc func(ctx context.Context, status pool.TxStatus) (uint64, error), initialCount uint64, nTxs uint64) error {
log.Debug("Wait for sequencer to select all txs from the pool")
pollingInterval := 1 * time.Second

prevCount := uint64(0)
txsPerSecond := 0
txsPerSecondAsStr := "N/A"
estimatedTimeToFinish := "N/A"
err := operations.Poll(pollingInterval, params.DefaultDeadline, func() (bool, error) {
selectedCount, err := countByStatusFunc(params.Ctx, pool.TxStatusSelected)
if err != nil {
return false, err
}
currCount := selectedCount - initialCount
remainingTxs := nTxs - currCount
if prevCount > 0 {
txsPerSecond = int(currCount - prevCount)
if txsPerSecond == 0 {
estimatedTimeToFinish = "N/A"
} else {
estimatedTimeToFinish = (time.Duration(int(remainingTxs)/txsPerSecond) * time.Second).String()
}
txsPerSecondAsStr = strconv.Itoa(txsPerSecond)
}
log.Debugf("amount of selected txs: %d/%d, estimated txs per second: %s, time to finish: %s", selectedCount-initialCount, nTxs, txsPerSecondAsStr, estimatedTimeToFinish)
prevCount = currCount

done := (int64(selectedCount) - int64(initialCount)) >= int64(nTxs)
return done, nil
})

return err
}
Loading

0 comments on commit 17b8a03

Please sign in to comment.