Skip to content

Commit

Permalink
Problem: fund_test_accounts is slow with big num_accounts in testgrou…
Browse files Browse the repository at this point in the history
…nd (#1551)

* Problem: fund_test_accounts is slow with big num_accounts in testground

fund by batch

* fire txs to validator

* log txs

* use rocksdb

* cleanup

* larger timeout

* more balance

* larger timeout

* Revert "larger timeout"

This reverts commit 33bce0b.
  • Loading branch information
mmsqe authored Aug 21, 2024
1 parent f3509d7 commit 737bd9e
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 11 deletions.
3 changes: 2 additions & 1 deletion testground/benchmark/benchmark/peer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
VAL_ACCOUNT = "validator"
VAL_INITIAL_AMOUNT = "100000000000000000000basecro"
VAL_STAKED_AMOUNT = "10000000000000000000basecro"
ACC_INITIAL_AMOUNT = "100000000000000000000000basecro"
ACC_INITIAL_AMOUNT = "10000000000000000000000000basecro"
MEMPOOL_SIZE = 50000
DEFAULT_DENOM = "basecro"
VALIDATOR_GROUP = "validators"
Expand Down Expand Up @@ -119,6 +119,7 @@ def gen_genesis(cli: ChainCommand, leader_home: Path, peers: List[PeerPacket]):
def patch_configs(home: Path, group: str, peers: str, block_executor: str):
# update persistent_peers and other configs in config.toml
config_patch = {
"db_backend": "rocksdb",
"p2p.persistent_peers": peers,
"p2p.addr_book_strict": False,
"mempool.recheck": "false",
Expand Down
23 changes: 17 additions & 6 deletions testground/benchmark/benchmark/sendtx.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,37 @@
import web3
from eth_account import Account

from .utils import export_eth_account, send_transaction
from .utils import (
broadcast_tx_json,
build_batch_tx,
export_eth_account,
send_transaction,
)

TEST_AMOUNT = 1000000000000000000
GAS_PRICE = 1000000000


def fund_test_accounts(w3, from_account, num_accounts) -> [Account]:
def fund_test_accounts(cli, w3, from_account, num_accounts, **kwargs) -> [Account]:
accounts = []
sender = from_account.address
nonce = w3.eth.get_transaction_count(sender)
txs = []
for i in range(num_accounts):
acct = Account.create()
tx = {
"to": acct.address,
"value": TEST_AMOUNT,
"gas": 21000,
"gasPrice": GAS_PRICE,
"nonce": nonce + i,
}
receipt = send_transaction(w3, tx, from_account, wait=True)
assert receipt.status == 1
print("fund test account", acct.address, "balance", TEST_AMOUNT)
txs.append(tx)
accounts.append(acct)
cosmos_tx, hashes = build_batch_tx(w3, cli, txs, from_account, **kwargs)
print("batch size", len(hashes))
rsp = broadcast_tx_json(cli, cosmos_tx, **kwargs)
assert rsp["code"] == 0, rsp["raw_log"]
return accounts


Expand Down Expand Up @@ -77,7 +88,7 @@ def generate_load(cli, num_accounts, num_txs, **kwargs):
w3 = web3.Web3(web3.providers.HTTPProvider("http://localhost:8545"))
assert w3.eth.chain_id == 777
genesis_account = export_eth_account(cli, "account", **kwargs)
accounts = fund_test_accounts(w3, genesis_account, num_accounts)
accounts = fund_test_accounts(cli, w3, genesis_account, num_accounts, **kwargs)
with ThreadPoolExecutor(max_workers=num_accounts) as executor:
futs = (executor.submit(sendtx, w3, acct, num_txs) for acct in accounts)
for fut in as_completed(futs):
Expand Down
11 changes: 7 additions & 4 deletions testground/benchmark/benchmark/stateless.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,16 @@ def run(
wait_for_port(26657)
wait_for_port(8545)
wait_for_block(cli, 3)

wait_for_w3()
generate_load(
cli, cfg["num_accounts"], cfg["num_txs"], home=home, output="json"
)
if group == VALIDATOR_GROUP:
# validators quit when the chain is idle for a while
detect_idle(20, 20)
else:
wait_for_w3()
generate_load(cli, cfg["num_accounts"], cfg["num_txs"], home=home)
# wait more blocks to finish all tasks
detect_idle(4, 4)

with (home / "block_stats.log").open("w") as logfile:
dump_block_stats(logfile)
Expand Down Expand Up @@ -282,7 +285,7 @@ def wait_for_peers(home: Path):
for peer in peers.split(","):
host = peer.split("@", 1)[1].split(":", 1)[0]
print("wait for peer to be ready:", host)
wait_for_port(ECHO_SERVER_PORT, host=host, timeout=600)
wait_for_port(ECHO_SERVER_PORT, host=host, timeout=2400)


def dump_block_stats(fp):
Expand Down
71 changes: 71 additions & 0 deletions testground/benchmark/benchmark/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import json
import socket
import subprocess
import tempfile
import time
from pathlib import Path

Expand Down Expand Up @@ -111,3 +113,72 @@ def send_transaction(w3, tx, acct, wait=True):
def export_eth_account(cli, name: str, **kwargs) -> Account:
kwargs.setdefault("keyring_backend", "test")
return Account.from_key(cli("keys", "unsafe-export-eth-key", name, **kwargs))


def build_batch_tx(w3, cli, txs, acct, **kwargs):
"return cosmos batch tx and eth tx hashes"
signed_txs = [sign_transaction(w3, tx, acct) for tx in txs]
tmp_txs = [
json.loads(
cli(
"tx",
"evm",
"raw",
signed.rawTransaction.hex(),
"-y",
"--generate-only",
**kwargs,
)
)
for signed in signed_txs
]

msgs = [tx["body"]["messages"][0] for tx in tmp_txs]
fee = sum(int(tx["auth_info"]["fee"]["amount"][0]["amount"]) for tx in tmp_txs)
gas_limit = sum(int(tx["auth_info"]["fee"]["gas_limit"]) for tx in tmp_txs)

tx_hashes = [signed.hash for signed in signed_txs]

# build batch cosmos tx
return {
"body": {
"messages": msgs,
"memo": "",
"timeout_height": "0",
"extension_options": [
{"@type": "/ethermint.evm.v1.ExtensionOptionsEthereumTx"}
],
"non_critical_extension_options": [],
},
"auth_info": {
"signer_infos": [],
"fee": {
"amount": [{"denom": "basecro", "amount": str(fee)}],
"gas_limit": str(gas_limit),
"payer": "",
"granter": "",
},
},
"signatures": [],
}, tx_hashes


def broadcast_tx_json(cli, tx, **kwargs):
with tempfile.NamedTemporaryFile("w") as fp:
json.dump(tx, fp)
fp.flush()
rsp = json.loads(
cli("tx", "broadcast", fp.name, node="tcp://127.0.0.1:26657", **kwargs)
)
if rsp["code"] == 0:
rsp = json.loads(
cli(
"query",
"event-query-tx-for",
rsp["txhash"],
stderr=subprocess.DEVNULL,
timeout="120s",
**kwargs,
)
)
return rsp

0 comments on commit 737bd9e

Please sign in to comment.