Skip to content

Commit

Permalink
Merge pull request #2408 from 0xPolygonHermez/test/uniswap-benchmark-…
Browse files Browse the repository at this point in the history
…script

Add `uniswap-transfers` Benchmark Script to `zkevm-node`
  • Loading branch information
Psykepro authored Aug 17, 2023
2 parents a2b49f7 + c9c8d4d commit c4d4904
Show file tree
Hide file tree
Showing 17 changed files with 615 additions and 314 deletions.
24 changes: 22 additions & 2 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ benchmark-sequencer-eth-transfers: stop
$(RUNJSONRPC)
docker ps -a
docker logs $(DOCKERCOMPOSEZKPROVER)
@ cd benchmarks/sequencer/eth-transfers ; \
@ cd benchmarks/sequencer/e2e/eth-transfers ; \
mkdir -p results ; \
touch ./results/out.dat ; \
go test -bench=. -timeout=600m | tee ./results/out.dat ;
Expand All @@ -253,7 +253,27 @@ benchmark-sequencer-erc20-transfers: stop
$(RUNJSONRPC)
docker ps -a
docker logs $(DOCKERCOMPOSEZKPROVER)
@ cd benchmarks/sequencer/erc20-transfers ; \
@ cd benchmarks/sequencer/e2e/erc20-transfers ; \
mkdir -p results ; \
touch ./results/out.dat ; \
go test -bench=. -timeout=600m | tee ./results/out.dat ;


.PHONY: benchmark-sequencer-uniswap-transfers
benchmark-sequencer-uniswap-transfers: stop
$(RUNL1NETWORK)
$(RUNSTATEDB)
$(RUNPOOLDB)
$(RUNEVENTDB)
sleep 5
$(RUNZKPROVER)
$(RUNSYNC)
sleep 2
$(RUNL2GASPRICER)
$(RUNJSONRPC)
docker ps -a
docker logs $(DOCKERCOMPOSEZKPROVER)
@ cd benchmarks/sequencer/e2e/uniswap-transfers ; \
mkdir -p results ; \
touch ./results/out.dat ; \
go test -bench=. -timeout=600m | tee ./results/out.dat ;
Expand Down
4 changes: 2 additions & 2 deletions test/benchmarks/sequencer/common/params/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ const (
MaxCumulativeGasUsed = 80000000000
// PrometheusPort is the port where prometheus is running
PrometheusPort = 9092
// NumberOfTxs is the number of transactions to send
NumberOfTxs = 1000
// NumberOfOperations is the number of transactions to send
NumberOfOperations = 300
)
65 changes: 46 additions & 19 deletions test/benchmarks/sequencer/common/transactions/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package transactions

import (
"context"
"io/ioutil"
"math/big"
"net/http"
"strconv"
"time"

Expand All @@ -11,62 +13,87 @@ import (
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params"
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20"
"github.com/0xPolygonHermez/zkevm-node/test/operations"
"github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
)

// SendAndWait sends a number of transactions and waits for them to be marked as pending in the pool
func SendAndWait(
ctx context.Context,
auth *bind.TransactOpts,
client *ethclient.Client,
countByStatusFunc func(ctx context.Context, status ...pool.TxStatus) (uint64, error),
getTxsByStatus func(ctx context.Context, status pool.TxStatus, limit uint64) ([]pool.Transaction, error),
nTxs int,
erc20SC *ERC20.ERC20,
txSenderFunc func(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth *bind.TransactOpts, erc20SC *ERC20.ERC20) error,
) error {
uniswapDeployments *pkg.Deployments,
txSenderFunc func(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth *bind.TransactOpts, erc20SC *ERC20.ERC20, uniswapDeployments *pkg.Deployments) ([]*types.Transaction, error),
) ([]*types.Transaction, error) {
auth.GasLimit = 2100000
log.Debugf("Sending %d txs ...", nTxs)
startingNonce := auth.Nonce.Uint64()
maxNonce := uint64(nTxs) + startingNonce
initialPendingCount, err := countByStatusFunc(params.Ctx, pool.TxStatusPending)
if err != nil {
panic(err)
startingNonce := uint64(0)
if auth.Nonce != nil {
startingNonce = auth.Nonce.Uint64()
}
maxNonce := uint64(nTxs) + startingNonce
IP := getPublicIP()

allTxs := make([]*types.Transaction, 0, nTxs)
for nonce := startingNonce; nonce < maxNonce; nonce++ {
err = txSenderFunc(client, auth.GasPrice, nonce, auth, erc20SC)
txs, err := txSenderFunc(client, auth.GasPrice, nonce, auth, erc20SC, uniswapDeployments)
if err != nil {
for err != nil && err.Error() == "nonce intrinsic error" {
log.Warnf("nonce intrinsic error, retrying with nonce %d", nonce)
err = txSenderFunc(client, auth.GasPrice, nonce, auth, erc20SC)
txs, err = txSenderFunc(client, auth.GasPrice, nonce, auth, erc20SC, uniswapDeployments)
}
if err == nil {
continue
}
return err
return nil, err
}
allTxs = append(allTxs, txs...)
}
log.Debug("All txs were sent!")
log.Debug("Waiting pending transactions To be added in the pool ...")
err = operations.Poll(1*time.Second, params.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 := countByStatusFunc(ctx, pool.TxStatusPending)
pendingTxs, err := getTxsByStatus(params.Ctx, pool.TxStatusPending, 0)
if err != nil {
return false, err
panic(err)
}
pendingTxsCount := 0
for _, tx := range pendingTxs {
if tx.IP == IP {
pendingTxsCount++
}
}

log.Debugf("amount of pending txs: %d\n", count)
done := count-initialPendingCount <= 0
log.Debugf("amount of pending txs: %d\n", pendingTxsCount)
done := pendingTxsCount == 0
return done, nil
})
if err != nil {
return err
return nil, err
}

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

return nil
return allTxs, nil
}

func getPublicIP() string {
resp, err := http.Get("https://api.ipify.org?format=text")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()

ip, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}

return string(ip)
}

// WaitStatusSelected waits for a number of transactions to be marked as selected in the pool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ func BenchmarkSequencerERC20TransfersPoolProcess(b *testing.B) {
}
initialCount, err := pl.CountTransactionsByStatus(params.Ctx, pool.TxStatusSelected)
require.NoError(b, err)
err = transactions.SendAndWait(params.Ctx, auth, client, pl.CountTransactionsByStatus, params.NumberOfTxs, erc20SC, TxSender)
_, err = transactions.SendAndWait(auth, client, pl.GetTxsByStatus, params.NumberOfOperations, erc20SC, nil, TxSender)
require.NoError(b, err)

var (
elapsed time.Duration
prometheusResponse *http.Response
)

b.Run(fmt.Sprintf("sequencer_selecting_%d_txs", params.NumberOfTxs), func(b *testing.B) {
b.Run(fmt.Sprintf("sequencer_selecting_%d_txs", params.NumberOfOperations), func(b *testing.B) {
// Wait all txs to be selected by the sequencer
err = transactions.WaitStatusSelected(pl.CountTransactionsByStatus, initialCount, params.NumberOfTxs)
err = transactions.WaitStatusSelected(pl.CountTransactionsByStatus, initialCount, params.NumberOfOperations)
require.NoError(b, err)
elapsed = time.Since(start)
log.Infof("Total elapsed time: %s", elapsed)
Expand All @@ -77,7 +77,7 @@ func BenchmarkSequencerERC20TransfersPoolProcess(b *testing.B) {
elapsed,
deployMetricsValues.SequencerTotalProcessingTime,
deployMetricsValues.ExecutorTotalProcessingTime,
params.NumberOfTxs,
params.NumberOfOperations,
)
timeForFetchAndPrintMetrics := time.Since(startMetrics)
log.Infof("########################################")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package erc20_transfers
import (
"math/big"

"github.com/ethereum/go-ethereum/core/types"

"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params"
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20"
uniswap "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/ethclient"
)
Expand All @@ -22,7 +25,7 @@ var (
)

// TxSender sends ERC20 transfer to the sequencer
func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth *bind.TransactOpts, erc20SC *ERC20.ERC20) error {
func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth *bind.TransactOpts, erc20SC *ERC20.ERC20, uniswapDeployments *uniswap.Deployments) ([]*types.Transaction, error) {
log.Debugf("sending tx num: %d nonce: %d", countTxs, nonce)
auth.Nonce = new(big.Int).SetUint64(nonce)
var actualTransferAmount *big.Int
Expand All @@ -31,10 +34,10 @@ func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth
} else {
actualTransferAmount = big.NewInt(0).Add(transferAmountBig, auth.Nonce)
}
_, err := erc20SC.Transfer(auth, params.To, actualTransferAmount)
tx, err := erc20SC.Transfer(auth, params.To, actualTransferAmount)
if err == nil {
countTxs += 1
}

return err
return []*types.Transaction{tx}, err
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ func BenchmarkSequencerEthTransfersPoolProcess(b *testing.B) {
require.NoError(b, err)
timeForSetup := time.Since(start)
setup.BootstrapSequencer(b, opsman)
err = transactions.SendAndWait(params.Ctx, auth, client, pl.CountTransactionsByStatus, params.NumberOfTxs, nil, TxSender)
_, err = transactions.SendAndWait(auth, client, pl.GetTxsByStatus, params.NumberOfOperations, nil, nil, TxSender)
require.NoError(b, err)

var (
elapsed time.Duration
prometheusResponse *http.Response
)

b.Run(fmt.Sprintf("sequencer_selecting_%d_txs", params.NumberOfTxs), func(b *testing.B) {
err = transactions.WaitStatusSelected(pl.CountTransactionsByStatus, initialCount, params.NumberOfTxs)
b.Run(fmt.Sprintf("sequencer_selecting_%d_txs", params.NumberOfOperations), func(b *testing.B) {
err = transactions.WaitStatusSelected(pl.CountTransactionsByStatus, initialCount, params.NumberOfOperations)
require.NoError(b, err)
elapsed = time.Since(start)
log.Infof("Total elapsed time: %s", elapsed)
Expand All @@ -51,7 +51,7 @@ func BenchmarkSequencerEthTransfersPoolProcess(b *testing.B) {
require.NoError(b, err)
}

metrics.CalculateAndPrint(prometheusResponse, profilingResult, elapsed, 0, 0, params.NumberOfTxs)
metrics.CalculateAndPrint(prometheusResponse, profilingResult, elapsed, 0, 0, params.NumberOfOperations)
fmt.Printf("%s\n", profilingResult)
timeForFetchAndPrintMetrics := time.Since(startMetrics)
log.Infof("Time for setup: %s", timeForSetup)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params"
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20"
uniswap "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
Expand All @@ -22,13 +23,20 @@ var (
)

// TxSender sends eth transfer to the sequencer
func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth *bind.TransactOpts, erc20SC *ERC20.ERC20) error {
func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth *bind.TransactOpts, erc20SC *ERC20.ERC20, uniswapDeployments *uniswap.Deployments) ([]*types.Transaction, error) {
log.Debugf("sending tx num: %d nonce: %d", countTxs, nonce)
auth.Nonce = big.NewInt(int64(nonce))
tx := types.NewTransaction(nonce, params.To, ethAmount, uint64(gasLimit), gasPrice, nil)
auth.Nonce = new(big.Int).SetUint64(nonce)
tx := types.NewTx(&types.LegacyTx{
GasPrice: gasPrice,
Nonce: nonce,
Gas: uint64(gasLimit),
To: &params.To,
Value: ethAmount,
Data: nil,
})
signedTx, err := auth.Signer(auth.From, tx)
if err != nil {
return err
return nil, err
}

err = l2Client.SendTransaction(params.Ctx, signedTx)
Expand All @@ -43,5 +51,5 @@ func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth
countTxs += 1
}

return err
return []*types.Transaction{signedTx}, err
}
47 changes: 47 additions & 0 deletions test/benchmarks/sequencer/e2e/uniswap-transfers/tx_sender.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package uniswap_transfers

import (
"errors"
"fmt"
"math/big"
"strings"
"time"

"github.com/ethereum/go-ethereum/core/types"

"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20"
uniswap "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/ethclient"
)

var (
gasLimit = 21000
sleepTime = 5 * time.Second
countTxs = 0
txTimeout = 60 * time.Second
)

// TxSender sends eth transfer to the sequencer
func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, nonce uint64, auth *bind.TransactOpts, erc20SC *ERC20.ERC20, uniswapDeployments *uniswap.Deployments) ([]*types.Transaction, error) {
msg := fmt.Sprintf("# swap cycle number: %d #", countTxs)
delimiter := strings.Repeat("#", len(msg))
log.Infof("%s\n%s\n%s", delimiter, msg, delimiter)
var err error

transactions := uniswap.SwapTokens(l2Client, auth, *uniswapDeployments)
if errors.Is(err, state.ErrStateNotSynchronized) || errors.Is(err, state.ErrInsufficientFunds) {
for errors.Is(err, state.ErrStateNotSynchronized) || errors.Is(err, state.ErrInsufficientFunds) {
time.Sleep(sleepTime)
transactions = uniswap.SwapTokens(l2Client, auth, *uniswapDeployments)
}
}

if err == nil {
countTxs += 1
}

return transactions, err
}
4 changes: 2 additions & 2 deletions test/benchmarks/sequencer/scripts/common/environment/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var (
)

// Init sets up the environment for the benchmark
func Init() (context.Context, *pgpoolstorage.PostgresPoolStorage, *state.PostgresStorage, *ethclient.Client, *bind.TransactOpts) {
func Init() (*pgpoolstorage.PostgresPoolStorage, *state.PostgresStorage, *ethclient.Client, *bind.TransactOpts) {
ctx := context.Background()
pl, err := pgpoolstorage.NewPostgresPoolStorage(db.Config{
Name: poolDbName,
Expand Down Expand Up @@ -93,5 +93,5 @@ func Init() (context.Context, *pgpoolstorage.PostgresPoolStorage, *state.Postgre
stateStorage := state.NewPostgresStorage(stateDb)
auth.Nonce = new(big.Int).SetUint64(senderNonce)

return ctx, pl, stateStorage, l2Client, auth
return pl, stateStorage, l2Client, auth
}
Loading

0 comments on commit c4d4904

Please sign in to comment.