Skip to content

Commit

Permalink
Problem: cometbft rpc is more efficient to broadcast tx (#1651)
Browse files Browse the repository at this point in the history
* Problem: cometbft rpc is more efficient to broadcast tx

* Update CHANGELOG.md

Signed-off-by: yihuang <huang@crypto.com>

* Update testground/benchmark/benchmark/cosmostx.py

Signed-off-by: yihuang <huang@crypto.com>

* Update testground/benchmark/benchmark/cosmostx.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: yihuang <huang@crypto.com>

* renmae

---------

Signed-off-by: yihuang <huang@crypto.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
yihuang and coderabbitai[bot] authored Oct 18, 2024
1 parent 85ca58b commit 3303077
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* [#1645](https://github.com/crypto-org-chain/cronos/pull/1645) Gen test tx in parallel even in single node.
* (testground)[#1644](https://github.com/crypto-org-chain/cronos/pull/1644) load generator retry with backoff on error.
* [#1648](https://github.com/crypto-org-chain/cronos/pull/1648) Add abort OE in PrepareProposal.
* (testground)[#1651](https://github.com/crypto-org-chain/cronos/pull/1651) Benchmark use cosmos broadcast rpc.

*Oct 14, 2024*

Expand Down
82 changes: 82 additions & 0 deletions testground/benchmark/benchmark/cosmostx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from typing import Optional

from cprotobuf import Field, ProtoEntity


class ProtoAny(ProtoEntity):
type_url = Field("string", 1)
value = Field("bytes", 2)


def build_any(type_url: str, msg: Optional[ProtoEntity] = None) -> ProtoAny:
value = b""
if msg is not None:
value = msg.SerializeToString()
return ProtoAny(type_url=type_url, value=value)


class TxBody(ProtoEntity):
messages = Field(ProtoAny, 1, repeated=True)
memo = Field("string", 2)
timeout_height = Field("uint64", 3)
extension_options = Field(ProtoAny, 1023, repeated=True)
non_critical_extension_options = Field(ProtoAny, 2047, repeated=True)


class CompactBitArray(ProtoEntity):
extra_bits_stored = Field("uint32", 1)
elems = Field("bytes", 2)


class ModeInfoSingle(ProtoEntity):
mode = Field("int32", 1)


class ModeInfoMulti(ProtoEntity):
bitarray = Field(CompactBitArray, 1)
mode_infos = Field("ModeInfo", 2, repeated=True)


class ModeInfo(ProtoEntity):
single = Field(ModeInfoSingle, 1)
multi = Field(ModeInfoMulti, 2)


class SignerInfo(ProtoEntity):
public_key = Field(ProtoAny, 1)
mode_info = Field(ModeInfo, 2)
sequence = Field("uint64", 3)


class Coin(ProtoEntity):
denom = Field("string", 1)
amount = Field("string", 2)


class Fee(ProtoEntity):
amount = Field(Coin, 1, repeated=True)
gas_limit = Field("uint64", 2)
payer = Field("string", 3)
granter = Field("string", 4)


class Tip(ProtoEntity):
amount = Field(Coin, 1, repeated=True)
tipper = Field("string", 2)


class AuthInfo(ProtoEntity):
signer_infos = Field(SignerInfo, 1, repeated=True)
fee = Field(Fee, 2)
tip = Field(Tip, 3)


class TxRaw(ProtoEntity):
body = Field("bytes", 1)
auth_info = Field("bytes", 2)
signatures = Field("bytes", 3, repeated=True)


class MsgEthereumTx(ProtoEntity):
from_ = Field("bytes", 5)
raw = Field("bytes", 6)
2 changes: 1 addition & 1 deletion testground/benchmark/benchmark/peer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .cli import ChainCommand
from .types import Balance, GenesisAccount, PeerPacket
from .utils import (
DEFAULT_DENOM,
bech32_to_eth,
eth_to_bech32,
gen_account,
Expand All @@ -19,7 +20,6 @@
patch_toml,
)

DEFAULT_DENOM = "basecro"
VAL_ACCOUNT = "validator"
VAL_INITIAL_AMOUNT = Balance(amount="100000000000000000000", denom=DEFAULT_DENOM)
VAL_STAKED_AMOUNT = Balance(amount="10000000000000000000", denom=DEFAULT_DENOM)
Expand Down
46 changes: 41 additions & 5 deletions testground/benchmark/benchmark/transaction.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import base64
import itertools
import multiprocessing
import os
Expand All @@ -9,9 +10,11 @@
import backoff
import eth_abi
import ujson
from hexbytes import HexBytes

from . import cosmostx
from .erc20 import CONTRACT_ADDRESS
from .utils import LOCAL_JSON_RPC, gen_account, split
from .utils import DEFAULT_DENOM, LOCAL_RPC, gen_account, split

GAS_PRICE = 1000000000
CHAIN_ID = 777
Expand Down Expand Up @@ -63,7 +66,9 @@ def _do_job(job: Job):
for acct in accounts:
txs = []
for i in range(job.num_txs):
txs.append(acct.sign_transaction(job.create_tx(i)).rawTransaction.hex())
tx = job.create_tx(i)
raw = acct.sign_transaction(tx).rawTransaction
txs.append(build_cosmos_tx(tx, raw, HexBytes(acct.address)))
total += 1
if total % 1000 == 0:
print("generated", total, "txs for node", job.global_seq)
Expand Down Expand Up @@ -107,15 +112,46 @@ def load(datadir: Path, global_seq: int) -> [str]:
return ujson.load(f)


def build_cosmos_tx(tx: dict, raw: bytes, sender: bytes) -> str:
"""
return base64 encoded cosmos tx
"""
msg = cosmostx.build_any(
"/ethermint.evm.v1.MsgEthereumTx",
cosmostx.MsgEthereumTx(
from_=sender,
raw=raw,
),
)
fee = tx["gas"] * tx["gasPrice"]
body = cosmostx.TxBody(
messages=[msg],
extension_options=[
cosmostx.build_any("/ethermint.evm.v1.ExtensionOptionsEthereumTx")
],
)
auth_info = cosmostx.AuthInfo(
fee=cosmostx.Fee(
amount=[cosmostx.Coin(denom=DEFAULT_DENOM, amount=str(fee))],
gas_limit=tx["gas"],
)
)
return base64.b64encode(
cosmostx.TxRaw(
body=body.SerializeToString(), auth_info=auth_info.SerializeToString()
).SerializeToString()
).decode()


@backoff.on_predicate(backoff.expo, max_time=60, max_value=5)
@backoff.on_exception(backoff.expo, aiohttp.ClientError, max_time=60, max_value=5)
async def async_sendtx(session, raw):
async with session.post(
LOCAL_JSON_RPC,
LOCAL_RPC,
json={
"jsonrpc": "2.0",
"method": "eth_sendRawTransaction",
"params": [raw],
"method": "broadcast_tx_async",
"params": {"tx": raw},
"id": 1,
},
) as rsp:
Expand Down
1 change: 1 addition & 0 deletions testground/benchmark/benchmark/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from hexbytes import HexBytes
from web3._utils.transactions import fill_nonce, fill_transaction_defaults

DEFAULT_DENOM = "basecro"
CRONOS_ADDRESS_PREFIX = "crc"
LOCAL_RPC = "http://127.0.0.1:26657"
LOCAL_JSON_RPC = "http://127.0.0.1:8545"
Expand Down
1 change: 1 addition & 0 deletions testground/benchmark/overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ let
docker = [ "hatchling" "hatch-vcs" ];
pyunormalize = [ "setuptools" ];
pytest-github-actions-annotate-failures = [ "setuptools" ];
cprotobuf = [ "setuptools" ];
};
in
lib.mapAttrs
Expand Down
12 changes: 11 additions & 1 deletion testground/benchmark/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions testground/benchmark/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ujson = "^5.10.0"
jsonmerge = "^1.9.2"

backoff = "^2.2.1"
cprotobuf = "^0.1.11"
[tool.poetry.group.dev.dependencies]
pytest = "^8.2"
pytest-github-actions-annotate-failures = "^0.2.0"
Expand Down

0 comments on commit 3303077

Please sign in to comment.