From b1a3a88229430259becb018a5338ea8cc65b0973 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Thu, 17 Oct 2024 15:48:16 +0800 Subject: [PATCH 1/4] Problem: single validator benchmark can't run natively single validator benchmark should be runnable locally, since there are no port issues temp --- CHANGELOG.md | 4 ++ testground/benchmark/benchmark/stateless.py | 58 +++++++++++++------ testground/benchmark/benchmark/transaction.py | 5 +- testground/benchmark/benchmark/utils.py | 5 +- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b30a2bbb2..f47ca71003 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## UNRELEASED +### Bug Fixes + +* (testground)[]() Fix running single validator benchmark locally. + ### Improvements * [#1645](https://github.com/crypto-org-chain/cronos/pull/1645) Gen test tx in parallel even in single node. diff --git a/testground/benchmark/benchmark/stateless.py b/testground/benchmark/benchmark/stateless.py index 1aac7554a7..a77d3ace72 100644 --- a/testground/benchmark/benchmark/stateless.py +++ b/testground/benchmark/benchmark/stateless.py @@ -4,6 +4,7 @@ import shutil import socket import subprocess +import sys import tarfile import tempfile import time @@ -175,7 +176,7 @@ def patchimage(toimage, src, dst, fromimage): @click.option("--outdir", default="/outputs") @click.option("--datadir", default="/data") @click.option("--cronosd", default=CONTAINER_CRONOSD_PATH) -@click.option("--global-seq", default=None) +@click.option("--global-seq", default=None, type=int) def run(outdir: str, datadir: str, cronosd, global_seq): datadir = Path(datadir) cfg = json.loads((datadir / "config.json").read_text()) @@ -194,14 +195,19 @@ def run(outdir: str, datadir: str, cronosd, global_seq): finally: # collect outputs output = Path("/data.tar.bz2") - with tarfile.open(output, "x:bz2") as tar: - tar.add(home, arcname="data", filter=output_filter(group, group_seq)) - outdir = Path(outdir) - if outdir.exists(): - assert outdir.is_dir() - filename = outdir / f"{group}_{group_seq}.tar.bz2" - filename.unlink(missing_ok=True) - shutil.copy(output, filename) + try: + with tarfile.open(output, "x:bz2") as tar: + tar.add(home, arcname="data", filter=output_filter(group, group_seq)) + except OSError: + # ignore if the file is not writable when running in bare metal + pass + else: + outdir = Path(outdir) + if outdir.exists(): + assert outdir.is_dir() + filename = outdir / f"{group}_{group_seq}.tar.bz2" + filename.unlink(missing_ok=True) + shutil.copy(output, filename) @cli.command() @@ -221,6 +227,19 @@ def generic_gen_txs(options: dict): return _gen_txs(**options) +@cli.command() +@click.option("--datadir", default="/data", type=Path) +@click.option("--global-seq", default=0) +def generate_load(datadir: Path, global_seq: int): + cfg = json.loads((datadir / "config.json").read_text()) + txs = prepare_txs(cfg, datadir, global_seq) + asyncio.run(transaction.send(txs)) + print("sent", len(txs), "txs") + print("wait for 20 idle blocks") + detect_idle_halted(cfg["num_idle"], 20) + dump_block_stats(sys.stdout) + + def _gen_txs( outdir: str, nodes: int = 10, @@ -248,14 +267,7 @@ def do_run( datadir: Path, home: Path, cronosd: str, group: str, global_seq: int, cfg: dict ): if group == FULLNODE_GROUP or cfg.get("validator-generate-load", True): - txs = transaction.load(datadir, global_seq) - if txs: - print("loaded", len(txs), "txs") - else: - print("generating", cfg["num_accounts"] * cfg["num_txs"], "txs") - txs = transaction.gen( - global_seq, cfg["num_accounts"], cfg["num_txs"], cfg["tx_type"] - ) + txs = prepare_txs(cfg, datadir, global_seq) else: txs = [] @@ -415,5 +427,17 @@ def wait_for_peers(home: Path): wait_for_port(ECHO_SERVER_PORT, host=host, timeout=2400) +def prepare_txs(cfg, datadir, global_seq): + txs = transaction.load(datadir, global_seq) + if txs: + print("loaded", len(txs), "txs") + else: + print("generating", cfg["num_accounts"] * cfg["num_txs"], "txs") + txs = transaction.gen( + global_seq, cfg["num_accounts"], cfg["num_txs"], cfg["tx_type"] + ) + return txs + + if __name__ == "__main__": cli() diff --git a/testground/benchmark/benchmark/transaction.py b/testground/benchmark/benchmark/transaction.py index c54d944e92..78c77a3804 100644 --- a/testground/benchmark/benchmark/transaction.py +++ b/testground/benchmark/benchmark/transaction.py @@ -11,11 +11,10 @@ import ujson from .erc20 import CONTRACT_ADDRESS -from .utils import gen_account, split +from .utils import LOCAL_JSON_RPC, gen_account, split GAS_PRICE = 1000000000 CHAIN_ID = 777 -LOCAL_JSON_RPC = "http://localhost:8545" CONNECTION_POOL_SIZE = 1024 TXS_DIR = "txs" RECIPIENT = "0x1" + "0" * 39 @@ -128,7 +127,7 @@ async def async_sendtx(session, raw): async def send(txs): - connector = aiohttp.TCPConnector(limit=1024) + connector = aiohttp.TCPConnector(limit=CONNECTION_POOL_SIZE) async with aiohttp.ClientSession( connector=connector, json_serialize=ujson.dumps ) as session: diff --git a/testground/benchmark/benchmark/utils.py b/testground/benchmark/benchmark/utils.py index 421c7d1ccd..5a0c033c98 100644 --- a/testground/benchmark/benchmark/utils.py +++ b/testground/benchmark/benchmark/utils.py @@ -13,7 +13,8 @@ from web3._utils.transactions import fill_nonce, fill_transaction_defaults CRONOS_ADDRESS_PREFIX = "crc" -LOCAL_RPC = "http://localhost:26657" +LOCAL_RPC = "http://127.0.0.1:26657" +LOCAL_JSON_RPC = "http://127.0.0.1:8545" def patch_toml_doc(doc, patch): @@ -93,7 +94,7 @@ def wait_for_block(cli, target: int, timeout=40): def wait_for_w3(timeout=40): for i in range(timeout): try: - w3 = web3.Web3(web3.providers.HTTPProvider("http://localhost:8545")) + w3 = web3.Web3(web3.providers.HTTPProvider(LOCAL_JSON_RPC)) w3.eth.get_balance("0x0000000000000000000000000000000000000001") except: # noqa time.sleep(1) From a8413f7bb25d6dbc7a274e420e7bae25891823e2 Mon Sep 17 00:00:00 2001 From: yihuang Date: Fri, 18 Oct 2024 11:42:16 +0800 Subject: [PATCH 2/4] Update CHANGELOG.md Signed-off-by: yihuang --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f47ca71003..e60eb302c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Bug Fixes -* (testground)[]() Fix running single validator benchmark locally. +* (testground)[1649](https://github.com/crypto-org-chain/cronos/pull/1649) Fix running single validator benchmark locally. ### Improvements From dc4b14598a56fdc97699199bed6f6ee30757984e Mon Sep 17 00:00:00 2001 From: yihuang Date: Fri, 18 Oct 2024 11:43:27 +0800 Subject: [PATCH 3/4] Update testground/benchmark/benchmark/stateless.py Signed-off-by: yihuang --- testground/benchmark/benchmark/stateless.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testground/benchmark/benchmark/stateless.py b/testground/benchmark/benchmark/stateless.py index a77d3ace72..d9541d285d 100644 --- a/testground/benchmark/benchmark/stateless.py +++ b/testground/benchmark/benchmark/stateless.py @@ -231,6 +231,9 @@ def generic_gen_txs(options: dict): @click.option("--datadir", default="/data", type=Path) @click.option("--global-seq", default=0) def generate_load(datadir: Path, global_seq: int): + ''' + manually generate load to an existing node + ''' cfg = json.loads((datadir / "config.json").read_text()) txs = prepare_txs(cfg, datadir, global_seq) asyncio.run(transaction.send(txs)) From 864c777eac2c707eb6076bd391f27e77b3b44d46 Mon Sep 17 00:00:00 2001 From: yihuang Date: Fri, 18 Oct 2024 12:11:28 +0800 Subject: [PATCH 4/4] Update testground/benchmark/benchmark/stateless.py Signed-off-by: yihuang --- testground/benchmark/benchmark/stateless.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testground/benchmark/benchmark/stateless.py b/testground/benchmark/benchmark/stateless.py index d9541d285d..8ac87f20b8 100644 --- a/testground/benchmark/benchmark/stateless.py +++ b/testground/benchmark/benchmark/stateless.py @@ -231,9 +231,9 @@ def generic_gen_txs(options: dict): @click.option("--datadir", default="/data", type=Path) @click.option("--global-seq", default=0) def generate_load(datadir: Path, global_seq: int): - ''' + """ manually generate load to an existing node - ''' + """ cfg = json.loads((datadir / "config.json").read_text()) txs = prepare_txs(cfg, datadir, global_seq) asyncio.run(transaction.send(txs))