From 983a5a626196fee6715134afe2707e97e9b74f88 Mon Sep 17 00:00:00 2001 From: yihuang Date: Wed, 24 Jul 2024 16:51:44 +0800 Subject: [PATCH 1/5] Problem: testground image don't have tmp directory (#1521) * Problem: testground image don't have tmp directory Solution: - create the directory inside the image, it's required by cronosd * fix image --- nix/testground-image.nix | 8 +++++++- testground/benchmark/compositions/docker-compose.jsonnet | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) 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/benchmark/compositions/docker-compose.jsonnet b/testground/benchmark/compositions/docker-compose.jsonnet index bec5e017f7..e3879941d8 100644 --- a/testground/benchmark/compositions/docker-compose.jsonnet +++ b/testground/benchmark/compositions/docker-compose.jsonnet @@ -6,7 +6,6 @@ std.manifestYamlDoc({ container_name: 'testplan-' + i, volumes: [ @'${DATADIR:-/tmp/data/out}:/data', - '/tmp:/tmp', ], environment: { JOB_COMPLETION_INDEX: i, From 19724372eeea9d8c15e34dfbaf1cd654222d94bf Mon Sep 17 00:00:00 2001 From: yihuang Date: Wed, 24 Jul 2024 21:37:01 +0800 Subject: [PATCH 2/5] Problem: testground test case requires persistent volume (#1522) * Problem: testground test case requires persistent volume Solution: - persistent volume is a headache in k8s cluster, but we can embed the data directory into image to avoid that. * cleanup * lint * nix develop -c black . --------- Co-authored-by: mmsqe --- testground/README.md | 12 ++++- testground/benchmark/benchmark/stateless.py | 44 +++++++++++++++---- .../compositions/docker-compose.jsonnet | 5 +-- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/testground/README.md b/testground/README.md index 8d03f11b76..80c3a325f2 100644 --- a/testground/README.md +++ b/testground/README.md @@ -75,14 +75,22 @@ 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 ``` +## Embed the data directory + +Patch the image to embed the data directory, it produce a local image: + +```bash +$ nix run github:crypto-org-chain/cronos#stateless-testcase patchimage cronos-testground:latest /tmp/data/out +``` + ## Run In Local Docker ```bash diff --git a/testground/benchmark/benchmark/stateless.py b/testground/benchmark/benchmark/stateless.py index 6a93fa95d8..7e935cf812 100644 --- a/testground/benchmark/benchmark/stateless.py +++ b/testground/benchmark/benchmark/stateless.py @@ -1,7 +1,9 @@ import json import os +import shutil import socket import subprocess +import tempfile from pathlib import Path from typing import List @@ -26,11 +28,17 @@ 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, + ): outdir = Path(outdir) cli = ChainCommand(LOCAL_CRONOSD_PATH) (outdir / VALIDATOR_GROUP).mkdir(parents=True, exist_ok=True) @@ -39,12 +47,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,6 +67,26 @@ def gen(self, outdir: str, validators: int, fullnodes: int): peers, genesis, outdir, FULLNODE_GROUP, i, i + validators ) + 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, @@ -100,12 +128,12 @@ def run( 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 e3879941d8..c9e83c9d85 100644 --- a/testground/benchmark/compositions/docker-compose.jsonnet +++ b/testground/benchmark/compositions/docker-compose.jsonnet @@ -1,12 +1,9 @@ std.manifestYamlDoc({ services: { ['testplan-' + i]: { - image: 'ghcr.io/crypto-org-chain/cronos-testground:latest', + image: 'cronos-testground:latest', command: 'stateless-testcase run /data 3 --num_accounts=10 --num_txs=1000', container_name: 'testplan-' + i, - volumes: [ - @'${DATADIR:-/tmp/data/out}:/data', - ], environment: { JOB_COMPLETION_INDEX: i, }, From d545b24c2dec0cc339c20987f4955e13b5cdb63d Mon Sep 17 00:00:00 2001 From: mmsqe Date: Wed, 24 Jul 2024 23:19:45 +0800 Subject: [PATCH 3/5] Problem: invalid chain id for signer (#1520) * Problem: invalid chain id for signer https://github.com/crypto-org-chain/cronos/actions/runs/10051584712/job/27781409154 * fix build * update deps --- CHANGELOG.md | 4 ++++ app/app.go | 1 + go.mod | 3 +-- go.sum | 4 ++-- gomod2nix.toml | 4 ++-- integration_tests/poetry.lock | 3 +-- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 763772f352..dd8cfc8382 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,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/app/app.go b/app/app.go index 32d7f409b8..f4031a3cbb 100644 --- a/app/app.go +++ b/app/app.go @@ -1225,6 +1225,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 f2a50561b6..efe64306ff 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 d1868a3e79..dc466784bd 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 459b0fc2b1..de6c886080 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" From 59c8b732e0c81bba40c5b4917eb26d28fbd3f63e Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 25 Jul 2024 15:38:51 +0800 Subject: [PATCH 4/5] Problem: testground stateless benchmark don't collect outputs (#1524) * Problem: testground stateless benchmark don't collect outputs Solution: - tar the home directory into outputs volume * fix readme * fix readme * Update testground/benchmark/benchmark/stateless.py Signed-off-by: yihuang * fix * log balance change after test --------- Signed-off-by: yihuang --- testground/README.md | 17 ++++++-- testground/benchmark/benchmark/sendtx.py | 8 +++- testground/benchmark/benchmark/stateless.py | 39 +++++++++++++++---- .../compositions/docker-compose.jsonnet | 5 ++- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/testground/README.md b/testground/README.md index 80c3a325f2..544c2f4825 100644 --- a/testground/README.md +++ b/testground/README.md @@ -80,12 +80,22 @@ To simplify cluster setup, we are introducing a stateless mode. 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 -Patch the image to embed the data directory, it produce a local image: +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 @@ -94,10 +104,11 @@ $ nix run github:crypto-org-chain/cronos#stateless-testcase patchimage cronos-te ## 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 7e935cf812..eaee7fd405 100644 --- a/testground/benchmark/benchmark/stateless.py +++ b/testground/benchmark/benchmark/stateless.py @@ -3,6 +3,7 @@ import shutil import socket import subprocess +import tarfile import tempfile from pathlib import Path from typing import List @@ -38,6 +39,8 @@ def gen( validators: int, fullnodes: int, hostname_template=HOSTNAME_TEMPLATE, + num_accounts=10, + num_txs=1000, ): outdir = Path(outdir) cli = ChainCommand(LOCAL_CRONOSD_PATH) @@ -67,6 +70,15 @@ def gen( 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, @@ -89,21 +101,24 @@ def patchimage( 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" @@ -122,9 +137,17 @@ 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( diff --git a/testground/benchmark/compositions/docker-compose.jsonnet b/testground/benchmark/compositions/docker-compose.jsonnet index c9e83c9d85..7589d67497 100644 --- a/testground/benchmark/compositions/docker-compose.jsonnet +++ b/testground/benchmark/compositions/docker-compose.jsonnet @@ -2,8 +2,11 @@ std.manifestYamlDoc({ services: { ['testplan-' + i]: { image: 'cronos-testground:latest', - command: 'stateless-testcase run /data 3 --num_accounts=10 --num_txs=1000', + command: 'stateless-testcase run', container_name: 'testplan-' + i, + volumes: [ + @'${OUTDIR:-/tmp/outputs}:/outputs', + ], environment: { JOB_COMPLETION_INDEX: i, }, From ce52c517fb733fd3d2628e01098266e61c27c941 Mon Sep 17 00:00:00 2001 From: fivecut Date: Thu, 25 Jul 2024 17:09:33 +0900 Subject: [PATCH 5/5] chore: remove repeat words (#1525) --- CODE_OF_CONDUCT.md | 2 +- x/cronos/spec/06_events.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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