diff --git a/CHANGELOG.md b/CHANGELOG.md index f9814b9304..1c10b7291d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,10 @@ * (store) [#1511](https://github.com/crypto-org-chain/cronos/pull/1511) Upgrade rocksdb to `v9.2.1`. * (block-stm) [#1515](https://github.com/crypto-org-chain/cronos/pull/1515) Improve performance by cache signature verification result between incarnations of same tx. +### Bug Fixes + +* [#1520](https://github.com/crypto-org-chain/cronos/pull/1520) Avoid invalid chain id for signer error when rpc call before chain id set in BeginBlock. + *Jun 18, 2024* ## v1.3.0-rc2 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index eacf32113a..15546f76db 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -48,4 +48,4 @@ And if someone takes issue with something you said or did, resist the urge to be The enforcement policies listed above apply to all official Cronos venues. For other projects adopting the Cronos Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. -* Adapted from the the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html), the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/). +* Adapted from the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html), the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/). diff --git a/app/app.go b/app/app.go index ac54ea8f71..b1ba42d3eb 100644 --- a/app/app.go +++ b/app/app.go @@ -1208,6 +1208,7 @@ func (app *App) SimulationManager() *module.SimulationManager { // API server. func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { clientCtx := apiSvr.ClientCtx + app.EvmKeeper.WithChainIDString(clientCtx.ChainID) // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register new tendermint queries routes from grpc-gateway. diff --git a/go.mod b/go.mod index 481f5dcabe..9060a77386 100644 --- a/go.mod +++ b/go.mod @@ -276,8 +276,7 @@ replace ( github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 github.com/ethereum/go-ethereum => github.com/crypto-org-chain/go-ethereum v1.10.20-0.20240425065928-ebb09502e7a7 // block-stm branch - github.com/evmos/ethermint => github.com/crypto-org-chain/ethermint v0.6.1-0.20240715061533-9c959a26e04f - + github.com/evmos/ethermint => github.com/crypto-org-chain/ethermint v0.6.1-0.20240724133625-f3e62cb25070 // Fix upstream GHSA-h395-qcrw-5vmq and GHSA-3vp4-m3rf-835h vulnerabilities. // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.0 diff --git a/go.sum b/go.sum index 5bb66817c7..93fd0fe432 100644 --- a/go.sum +++ b/go.sum @@ -430,8 +430,8 @@ github.com/crypto-org-chain/cosmos-sdk/store v0.0.0-20240722033504-50f1fa0c49d1 github.com/crypto-org-chain/cosmos-sdk/store v0.0.0-20240722033504-50f1fa0c49d1/go.mod h1:gjE3DZe4t/+VeIk6CmrouyqiuDbZ7QOVDDq3nLqBTpg= github.com/crypto-org-chain/cosmos-sdk/x/tx v0.0.0-20240722033504-50f1fa0c49d1 h1:r0ALP31Wnw19FqEmqzsK2SFNqdMetHshnM/X/FeJRIo= github.com/crypto-org-chain/cosmos-sdk/x/tx v0.0.0-20240722033504-50f1fa0c49d1/go.mod h1:RTiTs4hkXG6IvYGknvB8p79YgjYJdcbzLUOGJChsPnY= -github.com/crypto-org-chain/ethermint v0.6.1-0.20240715061533-9c959a26e04f h1:/27Pg87DNRG0xzctT8XcEANKF0OksPgFJtcQSRs5O0E= -github.com/crypto-org-chain/ethermint v0.6.1-0.20240715061533-9c959a26e04f/go.mod h1:Xap56y3WoiP7DyNammmB6N7P+Y83QQd6363RHGuaYV0= +github.com/crypto-org-chain/ethermint v0.6.1-0.20240724133625-f3e62cb25070 h1:BNjkJlyOAvr7Crd2kb2M/j3syKi4AjdiWN93M6iQaCA= +github.com/crypto-org-chain/ethermint v0.6.1-0.20240724133625-f3e62cb25070/go.mod h1:Xap56y3WoiP7DyNammmB6N7P+Y83QQd6363RHGuaYV0= github.com/crypto-org-chain/go-block-stm v0.0.0-20240408011717-9f11af197bde h1:sQIHTJfVt5VTrF7po9eZiFkZiPjlHbFvnXtGCOoBjNM= github.com/crypto-org-chain/go-block-stm v0.0.0-20240408011717-9f11af197bde/go.mod h1:iwQTX9xMX8NV9k3o2BiWXA0SswpsZrDk5q3gA7nWYiE= github.com/crypto-org-chain/go-ethereum v1.10.20-0.20240425065928-ebb09502e7a7 h1:V43F3JFcqG4MUThf9W/DytnPblpR6CcaLBw2Wx6zTgE= diff --git a/gomod2nix.toml b/gomod2nix.toml index 974649dce3..a45f453e44 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -262,8 +262,8 @@ schema = 3 hash = "sha256-lE4G5FaRb3MVi9FFVn+WlwsSTOB4SbjmVboKyQ5yB0A=" replaced = "github.com/crypto-org-chain/go-ethereum" [mod."github.com/evmos/ethermint"] - version = "v0.6.1-0.20240715061533-9c959a26e04f" - hash = "sha256-REZAPHulyi4veAg3ij721eSrF7yjopGkc6NPfTMaow8=" + version = "v0.6.1-0.20240724133625-f3e62cb25070" + hash = "sha256-XL7h6tMMIP3dWKO33UydnMlHZRotfbj1mQGonIEzHe0=" replaced = "github.com/crypto-org-chain/ethermint" [mod."github.com/fatih/color"] version = "v1.16.0" diff --git a/integration_tests/poetry.lock b/integration_tests/poetry.lock index 536fa9097a..b42209e692 100644 --- a/integration_tests/poetry.lock +++ b/integration_tests/poetry.lock @@ -1514,7 +1514,6 @@ python-dateutil = "^2.8" python-dotenv = "^1.0" pyyaml = "^6.0" pyyaml-include = "^1.3" -rpds-py = "^0.17.0" supervisor = "^4.2" tomlkit = "^0" @@ -1522,7 +1521,7 @@ tomlkit = "^0" type = "git" url = "https://github.com/crypto-com/pystarport.git" reference = "main" -resolved_reference = "4704c4a27b159eaa4d434ef44b9bf1046e81da1b" +resolved_reference = "ef603d05ccd6fd66459c9879d5c1be21d2665844" [[package]] name = "pytest" diff --git a/nix/testground-image.nix b/nix/testground-image.nix index 9058412f33..5644a3f78c 100644 --- a/nix/testground-image.nix +++ b/nix/testground-image.nix @@ -1,4 +1,4 @@ -{ dockerTools, cronos-matrix, testground-testcase }: +{ dockerTools, runCommandLocal, cronos-matrix, testground-testcase }: let patched-cronosd = cronos-matrix.cronosd.overrideAttrs (oldAttrs: { patches = oldAttrs.patches or [ ] ++ [ @@ -6,12 +6,18 @@ let ]; }); in +let + tmpDir = runCommandLocal "tmp" { } '' + mkdir -p $out/tmp/ + ''; +in dockerTools.buildLayeredImage { name = "cronos-testground"; created = "now"; contents = [ testground-testcase patched-cronosd + tmpDir ]; config = { Expose = [ 9090 26657 26656 1317 26658 26660 26659 30000 ]; diff --git a/testground/README.md b/testground/README.md index 8d03f11b76..544c2f4825 100644 --- a/testground/README.md +++ b/testground/README.md @@ -75,21 +75,40 @@ mounts: To simplify cluster setup, we are introducing a stateless mode. -## Generate Data Files Locally +## Generate data files locally -You need to have a `cronosd` in `PATH`. +You need to have the `cronosd` in `PATH`. ```bash -$ nix run github:crypto-org-chain/cronos#stateless-testcase gen /tmp/data/out 3 7 +$ nix run github:crypto-org-chain/cronos#stateless-testcase -- gen /tmp/data/out \ + --validators 3 \ + --fullnodes 7 \ + --hostname_template "testplan-{index}" \ + --num_accounts 10 \ + --num_txs 1000 +``` + +* `validators`/`fullnodes` is the number of validators/full nodes. +* `hostname_template` is the hostname of each node that can communicate. +* `num_accounts` is the number of test accounts for each full node. +* `num_txs` is the number of test transactions to be sent for each test account. + +## Embed the data directory + +Embed the data directory into the image, it produce a new image: + +```bash +$ nix run github:crypto-org-chain/cronos#stateless-testcase patchimage cronos-testground:latest /tmp/data/out ``` ## Run In Local Docker ```bash +$ mkdir /tmp/outputs $ jsonnet -S testground/benchmark/compositions/docker-compose.jsonnet | docker-compose -f /dev/stdin up ``` -It'll mount the data files to all the containers. +It'll collect the node data files to the `/tmp/outputs` directory. ## Run In Cluster diff --git a/testground/benchmark/benchmark/sendtx.py b/testground/benchmark/benchmark/sendtx.py index c0752bc34c..c700d302c5 100644 --- a/testground/benchmark/benchmark/sendtx.py +++ b/testground/benchmark/benchmark/sendtx.py @@ -28,7 +28,9 @@ def fund_test_accounts(w3, from_account, num_accounts) -> [Account]: def sendtx(w3: web3.Web3, acct: Account, tx_amount: int): - print("test address", acct.address, "balance", w3.eth.get_balance(acct.address)) + print( + "test begin, address", acct.address, "balance", w3.eth.get_balance(acct.address) + ) initial_nonce = w3.eth.get_transaction_count(acct.address) nonce = initial_nonce @@ -56,6 +58,10 @@ def sendtx(w3: web3.Web3, acct: Account, tx_amount: int): if nonce % 100 == 0: print(f"{acct.address} sent {nonce} transactions") + print( + "test end, address", acct.address, "balance", w3.eth.get_balance(acct.address) + ) + def generate_load(cli, num_accounts, num_txs, **kwargs): w3 = web3.Web3(web3.providers.HTTPProvider("http://localhost:8545")) diff --git a/testground/benchmark/benchmark/stateless.py b/testground/benchmark/benchmark/stateless.py index 6a93fa95d8..eaee7fd405 100644 --- a/testground/benchmark/benchmark/stateless.py +++ b/testground/benchmark/benchmark/stateless.py @@ -1,7 +1,10 @@ import json import os +import shutil import socket import subprocess +import tarfile +import tempfile from pathlib import Path from typing import List @@ -26,11 +29,19 @@ DEFAULT_CHAIN_ID = "cronos_777-1" DEFAULT_DENOM = "basecro" # the container must be deployed with the prefixed name -CONTAINER_PREFIX = "testplan-" +HOSTNAME_TEMPLATE = "testplan-{index}" class CLI: - def gen(self, outdir: str, validators: int, fullnodes: int): + def gen( + self, + outdir: str, + validators: int, + fullnodes: int, + hostname_template=HOSTNAME_TEMPLATE, + num_accounts=10, + num_txs=1000, + ): outdir = Path(outdir) cli = ChainCommand(LOCAL_CRONOSD_PATH) (outdir / VALIDATOR_GROUP).mkdir(parents=True, exist_ok=True) @@ -39,12 +50,12 @@ def gen(self, outdir: str, validators: int, fullnodes: int): peers = [] for i in range(validators): print("init validator", i) - peers.append(init_node_local(cli, outdir, VALIDATOR_GROUP, i, i)) + ip = hostname_template.format(index=i) + peers.append(init_node_local(cli, outdir, VALIDATOR_GROUP, i, ip)) for i in range(fullnodes): print("init fullnode", i) - peers.append( - init_node_local(cli, outdir, FULLNODE_GROUP, i, i + validators) - ) + ip = hostname_template.format(index=i + validators) + peers.append(init_node_local(cli, outdir, FULLNODE_GROUP, i, ip)) print("prepare genesis") # use a full node directory to prepare the genesis file @@ -59,23 +70,55 @@ def gen(self, outdir: str, validators: int, fullnodes: int): peers, genesis, outdir, FULLNODE_GROUP, i, i + validators ) + print("write config") + cfg = { + "validators": validators, + "fullnodes": fullnodes, + "num_accounts": num_accounts, + "num_txs": num_txs, + } + (outdir / "config.json").write_text(json.dumps(cfg)) + + def patchimage( + self, + toimage, + src, + dst="/data", + fromimage="ghcr.io/crypto-org-chain/cronos-testground:latest", + ): + """ + combine data directory with an exiting image to produce a new image + """ + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + shutil.copytree(src, tmpdir / "out") + content = f"""FROM {fromimage} +ADD ./out {dst} +""" + print(content) + (tmpdir / "Dockerfile").write_text(content) + subprocess.run(["docker", "build", "-t", toimage, tmpdir]) + def run( self, - outdir: str, - validators: int, + outdir: str = "/outputs", + datadir: str = "/data", cronosd=CONTAINER_CRONOSD_PATH, global_seq=None, - num_accounts=10, - num_txs=1000, ): - outdir = Path(outdir) + datadir = Path(datadir) + + cfg = json.loads((datadir / "config.json").read_text()) + if global_seq is None: global_seq = node_index() + + validators = cfg["validators"] group = VALIDATOR_GROUP if global_seq < validators else FULLNODE_GROUP group_seq = global_seq if group == VALIDATOR_GROUP else global_seq - validators print("node role", global_seq, group, group_seq) - home = outdir / group / str(group_seq) + home = datadir / group / str(group_seq) # start the node logfile = home / "node.log" @@ -94,18 +137,26 @@ def run( # validators don't quit proc.wait() else: - generate_load(cli, num_accounts, num_txs, home=home) - + generate_load(cli, cfg["num_accounts"], cfg["num_txs"], home=home) proc.kill() + proc.wait() + + # collect outputs + outdir = Path(outdir) + if outdir.exists(): + with tarfile.open( + outdir / f"{group}_{group_seq}.tar.bz2", "x:bz2" + ) as tar: + tar.add(home, arcname="data") def init_node_local( - cli: ChainCommand, outdir: Path, group: str, group_seq: int, global_seq: int + cli: ChainCommand, outdir: Path, group: str, group_seq: int, ip: str ) -> PeerPacket: return init_node( cli, outdir / group / str(group_seq), - CONTAINER_PREFIX + str(global_seq), + ip, DEFAULT_CHAIN_ID, group, group_seq, diff --git a/testground/benchmark/compositions/docker-compose.jsonnet b/testground/benchmark/compositions/docker-compose.jsonnet index bec5e017f7..7589d67497 100644 --- a/testground/benchmark/compositions/docker-compose.jsonnet +++ b/testground/benchmark/compositions/docker-compose.jsonnet @@ -1,12 +1,11 @@ std.manifestYamlDoc({ services: { ['testplan-' + i]: { - image: 'ghcr.io/crypto-org-chain/cronos-testground:latest', - command: 'stateless-testcase run /data 3 --num_accounts=10 --num_txs=1000', + image: 'cronos-testground:latest', + command: 'stateless-testcase run', container_name: 'testplan-' + i, volumes: [ - @'${DATADIR:-/tmp/data/out}:/data', - '/tmp:/tmp', + @'${OUTDIR:-/tmp/outputs}:/outputs', ], environment: { JOB_COMPLETION_INDEX: i, diff --git a/x/cronos/spec/06_events.md b/x/cronos/spec/06_events.md index 75ba19fb57..b460ce1cbc 100644 --- a/x/cronos/spec/06_events.md +++ b/x/cronos/spec/06_events.md @@ -6,7 +6,7 @@ order: 6 The Cronos module emits the Cosmos SDK [events](./../../../docs/quickstart/events.md#sdk-and-tendermint-events) after a state execution. It can be expected that the type `message`, with an attribute key of `action` will represent the first event for each message being processed as emitted -by the Cosmos SDK's `Baseapp` (i.e the the basic application that implements Tendermint Core's ABCI +by the Cosmos SDK's `Baseapp` (i.e the basic application that implements Tendermint Core's ABCI interface). ## MsgConvertVouchers