From 96930a16169caf13edfbb97e19083d399c4806db Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Mon, 30 Jan 2023 11:29:56 -0600 Subject: [PATCH 01/24] Rename in prep to support additional trx desc files. --- tests/performance_tests/CMakeLists.txt | 4 ++-- tests/performance_tests/performance_test_basic.py | 2 +- .../{userTrxData.json => userTrxDataTransfer.json} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename tests/performance_tests/{userTrxData.json => userTrxDataTransfer.json} (100%) diff --git a/tests/performance_tests/CMakeLists.txt b/tests/performance_tests/CMakeLists.txt index 3d8ecc447d..aa3d180bec 100644 --- a/tests/performance_tests/CMakeLists.txt +++ b/tests/performance_tests/CMakeLists.txt @@ -7,10 +7,10 @@ configure_file(nodeos_log_2_0_14.txt.gz nodeos_log_2_0_14.txt.gz COPYONLY) configure_file(nodeos_log_3_2.txt.gz nodeos_log_3_2.txt.gz COPYONLY) configure_file(genesis.json genesis.json COPYONLY) configure_file(validate_nodeos_plugin_args.py validate_nodeos_plugin_args.py COPYONLY) -configure_file(userTrxData.json userTrxData.json COPYONLY) +configure_file(userTrxDataTransfer.json userTrxDataTransfer.json COPYONLY) add_test(NAME performance_test_basic COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -add_test(NAME performance_test_basic_ex_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run --user-trx-data-file tests/performance_tests/userTrxData.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME performance_test_basic_ex_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run --user-trx-data-file tests/performance_tests/userTrxDataTransfer.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME log_reader_tests COMMAND tests/performance_tests/log_reader_tests.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME validate_nodeos_plugin_args COMMAND tests/performance_tests/validate_nodeos_plugin_args.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST performance_test_basic PROPERTY LABELS nonparallelizable_tests) diff --git a/tests/performance_tests/performance_test_basic.py b/tests/performance_tests/performance_test_basic.py index 43334c497a..3130afd361 100755 --- a/tests/performance_tests/performance_test_basic.py +++ b/tests/performance_tests/performance_test_basic.py @@ -524,7 +524,7 @@ def createArgumentParser(): ptbParserGroup.add_argument("--target-tps", type=int, help="The target transfers per second to send during test", default=8000) ptbParserGroup.add_argument("--test-duration-sec", type=int, help="The duration of transfer trx generation for the test in seconds", default=90) - ptbParserGroup.add_argument("--user-trx-data-file", type=str, help="Path to userTrxData.json") + ptbParserGroup.add_argument("--user-trx-data-file", type=str, help="Path to userTrxDataTransfer.json") return ptbParser diff --git a/tests/performance_tests/userTrxData.json b/tests/performance_tests/userTrxDataTransfer.json similarity index 100% rename from tests/performance_tests/userTrxData.json rename to tests/performance_tests/userTrxDataTransfer.json From a4d6ecc40b444c2b28ad5d6289b9676ce1b37d4a Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Tue, 31 Jan 2023 04:38:27 -0600 Subject: [PATCH 02/24] Rename for generalization, not strictly for transfers. --- tests/trx_generator/trx_generator.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index 438a837a3b..88eeec8506 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -28,7 +28,7 @@ namespace eosio::testing { fc::crypto::private_key _second_act_priv_key; }; - signed_transaction_w_signer create_transfer_trx_w_signer(const action& act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { + signed_transaction_w_signer create_trx_w_action_and_signer(const action& act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { signed_transaction trx; trx.actions.push_back(act); trx.context_free_actions.emplace_back(action({}, config::null_account_name, name("nonce"), @@ -47,8 +47,8 @@ namespace eosio::testing { trxs.reserve(2 * action_pairs_vector.size()); for(action_pair_w_keys ap: action_pairs_vector) { - trxs.emplace_back(create_transfer_trx_w_signer(ap._first_act, ap._first_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); - trxs.emplace_back(create_transfer_trx_w_signer(ap._second_act, ap._second_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); + trxs.emplace_back(create_trx_w_action_and_signer(ap._first_act, ap._first_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); + trxs.emplace_back(create_trx_w_action_and_signer(ap._second_act, ap._second_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); } return trxs; @@ -199,7 +199,7 @@ namespace eosio::testing { act.authorization = vector{{_auth_account, config::active_name}}; act.data = std::move(packed_action_data); - _trxs.emplace_back(create_transfer_trx_w_signer(act, _private_key, ++_nonce_prefix, _nonce, _trx_expiration, _chain_id, _last_irr_block_id)); + _trxs.emplace_back(create_trx_w_action_and_signer(act, _private_key, ++_nonce_prefix, _nonce, _trx_expiration, _chain_id, _last_irr_block_id)); ilog("Setup p2p transaction provider"); From cfe83467aae5c41d93635d1f1f0fed0c4d8d2f09 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Wed, 1 Feb 2023 09:45:50 -0600 Subject: [PATCH 03/24] Add way to specify auth acct when using json trx description. Add support for actionAuthAcct and actionAuthPrivKey for more explicit control when specifying transaction directly. Add actionAuthAcct to json transaction description Add trx generator id to allow differentiation of trx generators for use in create accounts. Factored out set_transaction_headers into own helper function. --- tests/TestHarness/Cluster.py | 6 +-- .../launch_transaction_generators.py | 22 ++++++++-- .../performance_test_basic.py | 20 +++++++-- .../userTrxDataTransfer.json | 1 + tests/trx_generator/main.cpp | 41 +++++++++++++++---- tests/trx_generator/trx_generator.cpp | 41 +++++++++++-------- tests/trx_generator/trx_generator.hpp | 16 +++++--- tests/trx_generator/trx_generator_tests.cpp | 8 +++- 8 files changed, 112 insertions(+), 43 deletions(-) diff --git a/tests/TestHarness/Cluster.py b/tests/TestHarness/Cluster.py index 27ad8075cf..0c37513c05 100644 --- a/tests/TestHarness/Cluster.py +++ b/tests/TestHarness/Cluster.py @@ -1763,7 +1763,7 @@ def stripValues(lowestMaxes,greaterThan): def launchTrxGenerators(self, contractOwnerAcctName: str, acctNamesList: list, acctPrivKeysList: list, nodeId: int=0, tpsPerGenerator: int=10, numGenerators: int=1, durationSec: int=60, - waitToComplete:bool=False, abiFile=None, actionName=None, actionData=None): + waitToComplete:bool=False, abiFile=None, actionName=None, actionAuthAcct=None, actionAuthPrivKey=None, actionData=None): Utils.Print("Configure txn generators") node=self.getNode(nodeId) p2pListenPort = self.getNodeP2pPort(nodeId) @@ -1779,8 +1779,8 @@ def launchTrxGenerators(self, contractOwnerAcctName: str, acctNamesList: list, a tpsTrxGensConfig = TpsTrxGensConfig(targetTps=targetTps, tpsLimitPerGenerator=tpsLimitPerGenerator) self.trxGenLauncher = TransactionGeneratorsLauncher(chainId=chainId, lastIrreversibleBlockId=lib_id, contractOwnerAccount=contractOwnerAcctName, accts=','.join(map(str, acctNamesList)), - privateKeys=','.join(map(str, acctPrivKeysList)), trxGenDurationSec=durationSec, - logDir=Utils.DataDir, abiFile=abiFile, actionName=actionName, actionData=actionData, + privateKeys=','.join(map(str, acctPrivKeysList)), trxGenDurationSec=durationSec, logDir=Utils.DataDir, + abiFile=abiFile, actionName=actionName, actionAuthAcct=actionAuthAcct, actionAuthPrivKey=actionAuthPrivKey, actionData=actionData, peerEndpoint=self.host, port=p2pListenPort, tpsTrxGensConfig=tpsTrxGensConfig) Utils.Print("Launch txn generators and start generating/sending transactions") diff --git a/tests/TestHarness/launch_transaction_generators.py b/tests/TestHarness/launch_transaction_generators.py index 4faf0e7cd8..d80b0687b1 100755 --- a/tests/TestHarness/launch_transaction_generators.py +++ b/tests/TestHarness/launch_transaction_generators.py @@ -37,7 +37,8 @@ def __init__(self, targetTps: int, tpsLimitPerGenerator: int): class TransactionGeneratorsLauncher: def __init__(self, chainId: int, lastIrreversibleBlockId: int, contractOwnerAccount: str, accts: str, privateKeys: str, - trxGenDurationSec: int, logDir: str, abiFile: Path, actionName: str, actionData, peerEndpoint: str, port: int, tpsTrxGensConfig: TpsTrxGensConfig): + trxGenDurationSec: int, logDir: str, abiFile: Path, actionName: str, actionAuthAcct: str, actionAuthPrivKey: str, actionData, + peerEndpoint: str, port: int, tpsTrxGensConfig: TpsTrxGensConfig): self.chainId = chainId self.lastIrreversibleBlockId = lastIrreversibleBlockId self.contractOwnerAccount = contractOwnerAccount @@ -48,17 +49,20 @@ def __init__(self, chainId: int, lastIrreversibleBlockId: int, contractOwnerAcco self.logDir = logDir self.abiFile = abiFile self.actionName = actionName + self.actionAuthAcct = actionAuthAcct + self.actionAuthPrivKey = actionAuthPrivKey self.actionData = actionData self.peerEndpoint = peerEndpoint self.port = port def launch(self, waitToComplete=True): self.subprocess_ret_codes = [] - for targetTps in self.tpsTrxGensConfig.targetTpsPerGenList: - if self.abiFile is not None and self.actionName is not None and self.actionData is not None: + for id, targetTps in enumerate(self.tpsTrxGensConfig.targetTpsPerGenList): + if self.abiFile is not None and self.actionName is not None and self.actionData is not None and self.actionAuthAcct is not None and self.actionAuthPrivKey is not None: if Utils.Debug: Print( f'Running trx_generator: ./tests/trx_generator/trx_generator ' + f'--generator-id {id} ' f'--chain-id {self.chainId} ' f'--last-irreversible-block-id {self.lastIrreversibleBlockId} ' f'--contract-owner-account {self.contractOwnerAccount} ' @@ -68,6 +72,8 @@ def launch(self, waitToComplete=True): f'--target-tps {targetTps} ' f'--log-dir {self.logDir} ' f'--action-name {self.actionName} ' + f'--action-auth-acct {self.actionAuthAcct} ' + f'--action-auth-acct-priv-key {self.actionAuthPrivKey} ' f'--action-data {self.actionData} ' f'--abi-file {self.abiFile} ' f'--peer-endpoint {self.peerEndpoint} ' @@ -76,6 +82,7 @@ def launch(self, waitToComplete=True): self.subprocess_ret_codes.append( subprocess.Popen([ './tests/trx_generator/trx_generator', + '--generator-id', f'{id}', '--chain-id', f'{self.chainId}', '--last-irreversible-block-id', f'{self.lastIrreversibleBlockId}', '--contract-owner-account', f'{self.contractOwnerAccount}', @@ -85,6 +92,8 @@ def launch(self, waitToComplete=True): '--target-tps', f'{targetTps}', '--log-dir', f'{self.logDir}', '--action-name', f'{self.actionName}', + '--action-auth-acct', f'{self.actionAuthAcct}', + '--action-auth-acct-priv-key', f'{self.actionAuthPrivKey}', '--action-data', f'{self.actionData}', '--abi-file', f'{self.abiFile}', '--peer-endpoint', f'{self.peerEndpoint}', @@ -95,6 +104,7 @@ def launch(self, waitToComplete=True): if Utils.Debug: Print( f'Running trx_generator: ./tests/trx_generator/trx_generator ' + f'--generator-id {id} ' f'--chain-id {self.chainId} ' f'--last-irreversible-block-id {self.lastIrreversibleBlockId} ' f'--contract-owner-account {self.contractOwnerAccount} ' @@ -109,6 +119,7 @@ def launch(self, waitToComplete=True): self.subprocess_ret_codes.append( subprocess.Popen([ './tests/trx_generator/trx_generator', + '--generator-id', f'{id}', '--chain-id', f'{self.chainId}', '--last-irreversible-block-id', f'{self.lastIrreversibleBlockId}', '--contract-owner-account', f'{self.contractOwnerAccount}', @@ -145,6 +156,8 @@ def parseArgs(): parser.add_argument("tps_limit_per_generator", type=int, help="Maximum amount of transactions per second a single generator can have.", default=4000) parser.add_argument("log_dir", type=str, help="Path to directory where trx logs should be written.") parser.add_argument("action_name", type=str, help="The action name applied to the provided action data input") + parser.add_argument("action_auth_acct", type=str, help="The authorization account name used for trx action authorization") + parser.add_argument("action_auth_acct_priv_key", type=str, help="The authorization account's private key used for signing trx") parser.add_argument("action_data", type=str, help="The path to the json action data file or json action data description string to use") parser.add_argument("abi_file", type=str, help="The path to the contract abi file to use for the supplied transaction action data") parser.add_argument("peer_endpoint", type=str, help="set the peer endpoint to send transactions to", default="127.0.0.1") @@ -158,7 +171,8 @@ def main(): trxGenLauncher = TransactionGeneratorsLauncher(chainId=args.chain_id, lastIrreversibleBlockId=args.last_irreversible_block_id, contractOwnerAccount=args.contract_owner_account, accts=args.accounts, privateKeys=args.priv_keys, trxGenDurationSec=args.trx_gen_duration, logDir=args.log_dir, - abiFile=args.abi_file, actionName=args.action_name, actionData=args.action_data, + abiFile=args.abi_file, actionName=args.action_name, actionAuthAcct=args.action_auth_acct, + actionAuthPrivKey=args.action_auth_acct_priv_key, actionData=args.action_data, peerEndpoint=args.peer_endpoint, port=args.port, tpsTrxGensConfig=TpsTrxGensConfig(targetTps=args.target_tps, tpsLimitPerGenerator=args.tps_limit_per_generator)) diff --git a/tests/performance_tests/performance_test_basic.py b/tests/performance_tests/performance_test_basic.py index 3130afd361..23608bbb34 100755 --- a/tests/performance_tests/performance_test_basic.py +++ b/tests/performance_tests/performance_test_basic.py @@ -300,6 +300,7 @@ def setupContract(self): return None def runTpsTest(self) -> PtbTpsTestResult: + completedRun = False self.producerNode = self.cluster.getNode(self.producerNodeId) self.producerP2pPort = self.cluster.getNodeP2pPort(self.producerNodeId) @@ -312,13 +313,24 @@ def runTpsTest(self) -> PtbTpsTestResult: abiFile=None actionName=None + actionAuthAcct=None + actionAuthPrivKey=None actionData=None if (self.ptbConfig.userTrxDataFile is not None): self.readUserTrxDataFromFile(self.ptbConfig.userTrxDataFile) self.setupWalletAndAccounts(accountCnt=len(self.userTrxDataDict['accounts']), accountNames=self.userTrxDataDict['accounts']) abiFile = self.userTrxDataDict['abiFile'] actionName = self.userTrxDataDict['actionName'] + actionAuthAcct = self.userTrxDataDict['actionAuthAcct'] actionData = json.dumps(self.userTrxDataDict['actionData']) + + if actionAuthAcct == self.cluster.eosioAccount.name: + actionAuthPrivKey = self.cluster.eosioAccount.activePrivateKey + else: + for account in self.cluster.accounts: + if actionAuthAcct == account.name: + actionAuthPrivKey = account.activePrivateKey + break else: self.setupWalletAndAccounts() @@ -328,10 +340,10 @@ def runTpsTest(self) -> PtbTpsTestResult: tpsTrxGensConfig = TpsTrxGensConfig(targetTps=self.ptbConfig.targetTps, tpsLimitPerGenerator=self.ptbConfig.tpsLimitPerGenerator) trxGenLauncher = TransactionGeneratorsLauncher(chainId=chainId, lastIrreversibleBlockId=lib_id, - contractOwnerAccount=self.clusterConfig.specifiedContract.accountName, accts=','.join(map(str, self.accountNames)), - privateKeys=','.join(map(str, self.accountPrivKeys)), trxGenDurationSec=self.ptbConfig.testTrxGenDurationSec, - logDir=self.trxGenLogDirPath, abiFile=abiFile, actionName=actionName, actionData=actionData, - peerEndpoint=self.producerNode.host, port=self.producerP2pPort, tpsTrxGensConfig=tpsTrxGensConfig) + contractOwnerAccount=self.clusterConfig.specifiedContract.accountName, accts=','.join(map(str, self.accountNames)), + privateKeys=','.join(map(str, self.accountPrivKeys)), trxGenDurationSec=self.ptbConfig.testTrxGenDurationSec, logDir=self.trxGenLogDirPath, + abiFile=abiFile, actionName=actionName, actionAuthAcct=actionAuthAcct, actionAuthPrivKey=actionAuthPrivKey, actionData=actionData, + peerEndpoint=self.producerNode.host, port=self.producerP2pPort, tpsTrxGensConfig=tpsTrxGensConfig) trxGenExitCodes = trxGenLauncher.launch() print(f"Transaction Generator exit codes: {trxGenExitCodes}") diff --git a/tests/performance_tests/userTrxDataTransfer.json b/tests/performance_tests/userTrxDataTransfer.json index b247e44dc5..242652b4e9 100644 --- a/tests/performance_tests/userTrxDataTransfer.json +++ b/tests/performance_tests/userTrxDataTransfer.json @@ -2,6 +2,7 @@ "accounts": ["testacct1", "testacct2"], "abiFile": "unittests/contracts/eosio.token/eosio.token.abi", "actionName": "transfer", + "actionAuthAcct": "testacct1", "actionData": { "from":"testacct1", diff --git a/tests/trx_generator/main.cpp b/tests/trx_generator/main.cpp index b7a6c8282a..007be8f0a6 100644 --- a/tests/trx_generator/main.cpp +++ b/tests/trx_generator/main.cpp @@ -25,8 +25,10 @@ enum return_codes { int main(int argc, char** argv) { const int64_t TRX_EXPIRATION_MAX = 3600; + const uint16_t GENERATOR_ID_MAX = 960; variables_map vmap; options_description cli("Transaction Generator command line options."); + uint16_t gen_id; string chain_id_in; string contract_owner_acct; string accts; @@ -45,6 +47,8 @@ int main(int argc, char** argv) { bool transaction_specified = false; std::string action_name_in; + std::string action_auth_acct_in; + std::string action_auth_acct_priv_key_in; std::string action_data_file_or_str; std::string abi_file_path_in; @@ -53,6 +57,7 @@ int main(int argc, char** argv) { cli.add_options() + ("generator-id", bpo::value(&gen_id)->default_value(0), "Id for the transaction generator. Allowed range (0-960). Defaults to 0.") ("chain-id", bpo::value(&chain_id_in), "set the chain id") ("contract-owner-account", bpo::value(&contract_owner_acct), "Account name of the contract account for the transaction actions") ("accounts", bpo::value(&accts), "comma-separated list of accounts that will be used for transfers. Minimum required accounts: 2.") @@ -66,6 +71,8 @@ int main(int argc, char** argv) { ("monitor-max-lag-duration-us", bpo::value(&max_lag_duration_us)->default_value(1000000), "Max microseconds that transaction generation can be in violation before quitting. Defaults to 1000000 (1s).") ("log-dir", bpo::value(&log_dir_in), "set the logs directory") ("action-name", bpo::value(&action_name_in), "The action name applied to the provided action data input") + ("action-auth-acct", bpo::value(&action_auth_acct_in), "The action authorization account") + ("action-auth-acct-priv-key", bpo::value(&action_auth_acct_priv_key_in), "The action authorization account priv key for signing trxs") ("action-data", bpo::value(&action_data_file_or_str), "The path to the json action data file or json action data description string to use") ("abi-file", bpo::value(&abi_file_path_in), "The path to the contract abi file to use for the supplied transaction action data") ("stop-on-trx-failed", bpo::value(&stop_on_trx_failed)->default_value(true), "stop transaction generation if sending fails.") @@ -83,14 +90,15 @@ int main(int argc, char** argv) { return SUCCESS; } - if((vmap.count("action-name") || vmap.count("action-data") || vmap.count("abi-file")) && !(vmap.count("action-name") && vmap.count("action-data") && vmap.count("abi-file"))) { - ilog("Initialization error: If using action-name, action-data, or abi-file to specify a transaction type to generate, must provide all three inputs."); + if((vmap.count("action-name") || vmap.count("action-auth-acct") || vmap.count("action-auth-acct-priv-key") || vmap.count("action-data") || vmap.count("abi-file")) && + !(vmap.count("action-name") && vmap.count("action-auth-acct") && vmap.count("action-auth-acct-priv-key") && vmap.count("action-data") && vmap.count("abi-file"))) { + ilog("Initialization error: If using action-name, action-auth-acct, action-auth-acct-priv-key, action-data, or abi-file to specify a transaction type to generate, must provide all inputs."); cli.print(std::cerr); return INITIALIZE_FAIL; } - if(vmap.count("action-name") && vmap.count("action-data") && vmap.count("abi-file")) { - ilog("Specifying transaction to generate directly using action-name, action-data, and abi-file."); + if(vmap.count("action-name") && vmap.count("action-auth-acct") && vmap.count("action-auth-acct-priv-key") && vmap.count("action-data") && vmap.count("abi-file")) { + ilog("Specifying transaction to generate directly using action-name, action-auth-acct, action-auth-acct-priv-key, action-data, and abi-file."); transaction_specified = true; } @@ -155,6 +163,14 @@ int main(int argc, char** argv) { return INITIALIZE_FAIL; } + if(vmap.count("generation-id")) { + if(gen_id > GENERATOR_ID_MAX) { + ilog("Initialization error: Exceeded max value for generator id. Value must be less than ${max}.", ("max", GENERATOR_ID_MAX)); + cli.print(std::cerr); + return INITIALIZE_FAIL; + } + } + if(vmap.count("trx-expiration")) { if(trx_expr > TRX_EXPIRATION_MAX) { ilog("Initialization error: Exceeded max value for transaction expiration. Value must be less than ${max}.", ("max", TRX_EXPIRATION_MAX)); @@ -192,6 +208,7 @@ int main(int argc, char** argv) { return INITIALIZE_FAIL; } + ilog("Initial generator id ${id}", ("id", gen_id)); ilog("Initial chain id ${chainId}", ("chainId", chain_id_in)); ilog("Contract owner account ${acct}", ("acct", contract_owner_acct)); ilog("Transfer accounts ${accts}", ("accts", accts)); @@ -203,13 +220,21 @@ int main(int argc, char** argv) { ilog("Logs directory ${logDir}", ("logDir", log_dir_in)); ilog("Peer Endpoint ${peer-endpoint}:${peer-port}", ("peer-endpoint", peer_endpoint)("peer-port", port)); + if (transaction_specified) { + ilog("User Transaction Specified: Action Name ${act}", ("act", action_name_in)); + ilog("User Transaction Specified: Action Auth Acct Name ${acct}", ("acct", action_auth_acct_in)); + ilog("User Transaction Specified: Action Auth Acct Priv Key ${key}", ("key", action_auth_acct_priv_key_in)); + ilog("User Transaction Specified: Action Data File or Str ${data}", ("data", action_data_file_or_str)); + ilog("User Transaction Specified: Abi File ${abi}", ("abi", abi_file_path_in)); + } + fc::microseconds trx_expr_ms = fc::seconds(trx_expr); std::shared_ptr monitor; if (transaction_specified) { - auto generator = std::make_shared(chain_id_in, abi_file_path_in, contract_owner_acct, account_str_vector.at(0), action_name_in, - action_data_file_or_str, trx_expr_ms, private_keys_str_vector.at(0), lib_id_str, log_dir_in, - stop_on_trx_failed, peer_endpoint, port); + auto generator = std::make_shared(gen_id, chain_id_in, abi_file_path_in, contract_owner_acct, + action_name_in, action_auth_acct_in, action_auth_acct_priv_key_in, action_data_file_or_str, + trx_expr_ms, lib_id_str, log_dir_in, stop_on_trx_failed, peer_endpoint, port); monitor = std::make_shared(spinup_time_us, max_lag_per, max_lag_duration_us); trx_tps_tester tester{generator, monitor, gen_duration, target_tps}; @@ -217,7 +242,7 @@ int main(int argc, char** argv) { return OTHER_FAIL; } } else { - auto generator = std::make_shared(chain_id_in, contract_owner_acct, account_str_vector, trx_expr_ms, private_keys_str_vector, + auto generator = std::make_shared(gen_id, chain_id_in, contract_owner_acct, account_str_vector, trx_expr_ms, private_keys_str_vector, lib_id_str, log_dir_in, stop_on_trx_failed, peer_endpoint, port); monitor = std::make_shared(spinup_time_us, max_lag_per, max_lag_duration_us); diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index 88eeec8506..4205acc969 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -28,16 +28,23 @@ namespace eosio::testing { fc::crypto::private_key _second_act_priv_key; }; + void set_transaction_headers(transaction& trx, const block_id_type& last_irr_block_id, const fc::microseconds expiration, uint32_t delay_sec = 0) { + trx.expiration = fc::time_point::now() + expiration; + trx.set_reference_block(last_irr_block_id); + + trx.max_net_usage_words = 0;// No limit + trx.max_cpu_usage_ms = 0; // No limit + trx.delay_sec = delay_sec; + } + signed_transaction_w_signer create_trx_w_action_and_signer(const action& act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { signed_transaction trx; + set_transaction_headers(trx, last_irr_block_id, trx_expiration); trx.actions.push_back(act); trx.context_free_actions.emplace_back(action({}, config::null_account_name, name("nonce"), fc::raw::pack(std::to_string(nonce_prefix) + ":" + std::to_string(++nonce) + ":" + fc::time_point::now().time_since_epoch().count()))); - trx.set_reference_block(last_irr_block_id); - trx.expiration = fc::time_point::now() + trx_expiration; - trx.max_net_usage_words = 100; trx.sign(priv_key, chain_id); return signed_transaction_w_signer(trx, priv_key); } @@ -57,8 +64,7 @@ namespace eosio::testing { void update_resign_transaction(signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { trx.context_free_actions.clear(); trx.context_free_actions.emplace_back(action({}, config::null_account_name, name("nonce"), fc::raw::pack(std::to_string(nonce_prefix) + ":" + std::to_string(++nonce) + ":" + fc::time_point::now().time_since_epoch().count()))); - trx.set_reference_block(last_irr_block_id); - trx.expiration = fc::time_point::now() + trx_expiration; + set_transaction_headers(trx, last_irr_block_id, trx_expiration); trx.signatures.clear(); trx.sign(priv_key, chain_id); } @@ -91,14 +97,14 @@ namespace eosio::testing { return actions_pairs_vector; } - trx_generator_base::trx_generator_base(std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, + trx_generator_base::trx_generator_base(uint16_t id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) - : _provider(peer_endpoint, port), _chain_id(chain_id_in), _contract_owner_account(contract_owner_account), _trx_expiration(trx_expr), + : _provider(peer_endpoint, port), _id(id), _chain_id(chain_id_in), _contract_owner_account(contract_owner_account), _trx_expiration(trx_expr), _last_irr_block_id(fc::variant(lib_id_str).as()), _log_dir(log_dir), _stop_on_trx_failed(stop_on_trx_failed) {} - transfer_trx_generator::transfer_trx_generator(std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, + transfer_trx_generator::transfer_trx_generator(uint16_t id, std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, fc::microseconds trx_expr, const std::vector& private_keys_str_vector, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) - : trx_generator_base(chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), _accts(accts), _private_keys_str_vector(private_keys_str_vector) {} + : trx_generator_base(id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), _accts(accts), _private_keys_str_vector(private_keys_str_vector) {} vector transfer_trx_generator::get_accounts(const vector& account_str_vector) { vector acct_name_list; @@ -166,10 +172,13 @@ namespace eosio::testing { } } - trx_generator::trx_generator(std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, std::string auth_account, std::string action_name, - const std::string& action_data_file_or_str, fc::microseconds trx_expr, const std::string& private_key_str, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) - : trx_generator_base(chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), _abi_data_file_path(abi_data_file), _auth_account(auth_account), - _action(action_name), _action_data_file_or_str(action_data_file_or_str), _private_key(fc::crypto::private_key(private_key_str)) {} + trx_generator::trx_generator(uint16_t id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, + std::string action_name, std::string action_auth_account, const std::string& private_key_str, const std::string& action_data_file_or_str, + fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, + const std::string& peer_endpoint, unsigned short port) + : trx_generator_base(id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), + _abi_data_file_path(abi_data_file), _action(action_name), _action_auth_account(action_auth_account), + _action_auth_priv_key(fc::crypto::private_key(private_key_str)), _action_data_file_or_str(action_data_file_or_str) {} bool trx_generator::setup() { _nonce_prefix = 0; @@ -186,7 +195,7 @@ namespace eosio::testing { bytes packed_action_data; try { auto action_type = abi.get_action_type( _action ); - FC_ASSERT( !action_type.empty(), "Unknown action ${action} in contract ${contract}", ("action", _action)( "contract", _auth_account )); + FC_ASSERT( !action_type.empty(), "Unknown action ${action} in contract ${contract}", ("action", _action)( "contract", _action_auth_account )); packed_action_data = abi.variant_to_binary( action_type, unpacked_action_data_json, abi_serializer::create_yield_function( abi_serializer_max_time ) ); } EOS_RETHROW_EXCEPTIONS(transaction_type_exception, "Fail to parse unpacked action data JSON") @@ -196,10 +205,10 @@ namespace eosio::testing { eosio::chain::action act; act.account = _contract_owner_account; act.name = _action; - act.authorization = vector{{_auth_account, config::active_name}}; + act.authorization = vector{{_action_auth_account, config::active_name}}; act.data = std::move(packed_action_data); - _trxs.emplace_back(create_trx_w_action_and_signer(act, _private_key, ++_nonce_prefix, _nonce, _trx_expiration, _chain_id, _last_irr_block_id)); + _trxs.emplace_back(create_trx_w_action_and_signer(act, _action_auth_priv_key, ++_nonce_prefix, _nonce, _trx_expiration, _chain_id, _last_irr_block_id)); ilog("Setup p2p transaction provider"); diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index db3007672c..9ae93bdbbe 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -17,6 +17,7 @@ namespace eosio::testing { struct trx_generator_base { p2p_trx_provider _provider; + uint16_t _id; eosio::chain::chain_id_type _chain_id; eosio::chain::name _contract_owner_account; fc::microseconds _trx_expiration; @@ -33,12 +34,14 @@ namespace eosio::testing { bool _stop_on_trx_failed = true; - trx_generator_base(std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, + trx_generator_base(uint16_t id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); void push_transaction(p2p_trx_provider& provider, signed_transaction_w_signer& trx, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); + + bool generate_and_send(); bool tear_down(); void stop_generation(); @@ -49,7 +52,7 @@ namespace eosio::testing { const std::vector _accts; std::vector _private_keys_str_vector; - transfer_trx_generator(std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, + transfer_trx_generator(uint16_t id, std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, fc::microseconds trx_expr, const std::vector& private_keys_str_vector, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); @@ -61,15 +64,16 @@ namespace eosio::testing { struct trx_generator : public trx_generator_base{ std::string _abi_data_file_path; - eosio::chain::name _auth_account; eosio::chain::name _action; + eosio::chain::name _action_auth_account; + fc::crypto::private_key _action_auth_priv_key; std::string _action_data_file_or_str; - fc::crypto::private_key _private_key; const fc::microseconds abi_serializer_max_time = fc::seconds(10); // No risk to client side serialization taking a long time - trx_generator(std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, std::string auth_account, std::string action_name, const std::string& action_data_file_or_str, - fc::microseconds trx_expr, const std::string& private_key_str, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, + trx_generator(uint16_t id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, + std::string action_name, std::string action_auth_account, const std::string& action_auth_priv_key_str, const std::string& action_data_file_or_str, + fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); bool setup(); diff --git a/tests/trx_generator/trx_generator_tests.cpp b/tests/trx_generator/trx_generator_tests.cpp index 9bb1a3804a..01000bd84e 100644 --- a/tests/trx_generator/trx_generator_tests.cpp +++ b/tests/trx_generator/trx_generator_tests.cpp @@ -325,21 +325,25 @@ BOOST_AUTO_TEST_CASE(tps_cant_keep_up_monitored) BOOST_AUTO_TEST_CASE(trx_generator_constructor) { + uint16_t id = 1; std::string chain_id = "999"; std::string contract_owner_account = "eosio"; std::string acct = "aaa"; std::string action_name = "transfer"; + std::string action_auth_acct = "aaa"; + std::string action_auth_priv_key_str = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"; const std::string action_data = "{\"from\":\"aaa\",\"to\":\"bbb\",\"quantity\":\"10.0000 SYS\",\"memo\":\"hello\"}"; const std::string abi_file = "../../unittests/contracts/eosio.token/eosio.token.abi"; fc::microseconds trx_expr = fc::seconds(3600); std::string log_dir = "."; std::string lib_id_str = "00000062989f69fd251df3e0b274c3364ffc2f4fce73de3f1c7b5e11a4c92f21"; - std::string private_key_str = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"; std::string peer_endpoint = "127.0.0.1"; unsigned short port = 9876; bool stop_on_trx_failed = true; - auto generator = trx_generator(chain_id, abi_file, contract_owner_account, acct, action_name, action_data, trx_expr, private_key_str, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port); + auto generator = trx_generator(id, chain_id, abi_file, contract_owner_account, + action_name, action_auth_acct, action_auth_priv_key_str, action_data, trx_expr, + lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port); } BOOST_AUTO_TEST_SUITE_END() From caa8f41586ca1fa42c1e84ecd311c7e240cdd0bb Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Wed, 1 Feb 2023 10:35:45 -0600 Subject: [PATCH 04/24] Refactoring. Moving functions into classes. --- tests/trx_generator/trx_generator.cpp | 29 +++++++++------------------ tests/trx_generator/trx_generator.hpp | 27 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index 4205acc969..7e0cb56284 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -5,9 +5,7 @@ #include #include #include -#include #include -#include #include #include @@ -18,17 +16,8 @@ using namespace appbase; namespace bpo=boost::program_options; namespace eosio::testing { - struct action_pair_w_keys { - action_pair_w_keys(eosio::chain::action first_action, eosio::chain::action second_action, fc::crypto::private_key first_act_signer, fc::crypto::private_key second_act_signer) - : _first_act(first_action), _second_act(second_action), _first_act_priv_key(first_act_signer), _second_act_priv_key(second_act_signer) {} - eosio::chain::action _first_act; - eosio::chain::action _second_act; - fc::crypto::private_key _first_act_priv_key; - fc::crypto::private_key _second_act_priv_key; - }; - - void set_transaction_headers(transaction& trx, const block_id_type& last_irr_block_id, const fc::microseconds expiration, uint32_t delay_sec = 0) { + void trx_generator_base::set_transaction_headers(transaction& trx, const block_id_type& last_irr_block_id, const fc::microseconds expiration, uint32_t delay_sec) { trx.expiration = fc::time_point::now() + expiration; trx.set_reference_block(last_irr_block_id); @@ -37,7 +26,7 @@ namespace eosio::testing { trx.delay_sec = delay_sec; } - signed_transaction_w_signer create_trx_w_action_and_signer(const action& act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { + signed_transaction_w_signer trx_generator_base::create_trx_w_action_and_signer(const action& act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { signed_transaction trx; set_transaction_headers(trx, last_irr_block_id, trx_expiration); trx.actions.push_back(act); @@ -49,7 +38,7 @@ namespace eosio::testing { return signed_transaction_w_signer(trx, priv_key); } - vector create_initial_transfer_transactions(const vector& action_pairs_vector, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { + vector transfer_trx_generator::create_initial_transfer_transactions(const vector& action_pairs_vector, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { std::vector trxs; trxs.reserve(2 * action_pairs_vector.size()); @@ -61,7 +50,7 @@ namespace eosio::testing { return trxs; } - void update_resign_transaction(signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { + void trx_generator_base::update_resign_transaction(signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { trx.context_free_actions.clear(); trx.context_free_actions.emplace_back(action({}, config::null_account_name, name("nonce"), fc::raw::pack(std::to_string(nonce_prefix) + ":" + std::to_string(++nonce) + ":" + fc::time_point::now().time_since_epoch().count()))); set_transaction_headers(trx, last_irr_block_id, trx_expiration); @@ -69,16 +58,16 @@ namespace eosio::testing { trx.sign(priv_key, chain_id); } - chain::bytes make_transfer_data(const chain::name& from, const chain::name& to, const chain::asset& quantity, const std::string&& memo) { + chain::bytes transfer_trx_generator::make_transfer_data(const chain::name& from, const chain::name& to, const chain::asset& quantity, const std::string&& memo) { return fc::raw::pack(from, to, quantity, memo); } - auto make_transfer_action(chain::name account, chain::name from, chain::name to, chain::asset quantity, std::string memo) { + auto transfer_trx_generator::make_transfer_action(chain::name account, chain::name from, chain::name to, chain::asset quantity, std::string memo) { return chain::action(std::vector{{from, chain::config::active_name}}, account, "transfer"_n, make_transfer_data(from, to, quantity, std::move(memo))); } - vector create_initial_transfer_actions(const std::string& salt, const uint64_t& period, const name& contract_owner_account, const vector& accounts, const vector& priv_keys) { + vector transfer_trx_generator::create_initial_transfer_actions(const std::string& salt, const uint64_t& period, const name& contract_owner_account, const vector& accounts, const vector& priv_keys) { vector actions_pairs_vector; for(size_t i = 0; i < accounts.size(); ++i) { @@ -157,7 +146,7 @@ namespace eosio::testing { return true; } - fc::variant json_from_file_or_string(const string& file_or_str, fc::json::parse_type ptype = fc::json::parse_type::legacy_parser) + fc::variant trx_generator::json_from_file_or_string(const string& file_or_str, fc::json::parse_type ptype) { regex r("^[ \t]*[\{\[]"); if ( !regex_search(file_or_str, r) && fc::is_regular_file(file_or_str) ) { @@ -253,7 +242,7 @@ namespace eosio::testing { return true; } - void log_first_trx(const std::string& log_dir, const chain::signed_transaction& trx) { + void trx_generator_base::log_first_trx(const std::string& log_dir, const chain::signed_transaction& trx) { std::ostringstream fileName; fileName << log_dir << "/first_trx_" << getpid() << ".txt"; std::ofstream out(fileName.str()); diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index 9ae93bdbbe..d308ab47fb 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include namespace eosio::testing { @@ -15,6 +17,16 @@ namespace eosio::testing { fc::crypto::private_key _signer; }; + struct action_pair_w_keys { + action_pair_w_keys(eosio::chain::action first_action, eosio::chain::action second_action, fc::crypto::private_key first_act_signer, fc::crypto::private_key second_act_signer) + : _first_act(first_action), _second_act(second_action), _first_act_priv_key(first_act_signer), _second_act_priv_key(second_act_signer) {} + + eosio::chain::action _first_act; + eosio::chain::action _second_act; + fc::crypto::private_key _first_act_priv_key; + fc::crypto::private_key _second_act_priv_key; + }; + struct trx_generator_base { p2p_trx_provider _provider; uint16_t _id; @@ -37,10 +49,17 @@ namespace eosio::testing { trx_generator_base(uint16_t id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); + void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, + const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); + void push_transaction(p2p_trx_provider& provider, signed_transaction_w_signer& trx, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); + void set_transaction_headers(eosio::chain::transaction& trx, const eosio::chain::block_id_type& last_irr_block_id, const fc::microseconds expiration, uint32_t delay_sec = 0); + signed_transaction_w_signer create_trx_w_action_and_signer(const eosio::chain::action& act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, + const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); + void log_first_trx(const std::string& log_dir, const eosio::chain::signed_transaction& trx); bool generate_and_send(); bool tear_down(); @@ -59,6 +78,12 @@ namespace eosio::testing { std::vector get_accounts(const std::vector& account_str_vector); std::vector get_private_keys(const std::vector& priv_key_str_vector); + std::vector create_initial_transfer_transactions(const std::vector& action_pairs_vector, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); + eosio::chain::bytes make_transfer_data(const eosio::chain::name& from, const eosio::chain::name& to, const eosio::chain::asset& quantity, const std::string&& memo); + auto make_transfer_action(eosio::chain::name account, eosio::chain::name from, eosio::chain::name to, eosio::chain::asset quantity, std::string memo); + std::vector create_initial_transfer_actions(const std::string& salt, const uint64_t& period, const eosio::chain::name& contract_owner_account, + const std::vector& accounts, const std::vector& priv_keys); + bool setup(); }; @@ -76,6 +101,8 @@ namespace eosio::testing { fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); + fc::variant json_from_file_or_string(const std::string& file_or_str, fc::json::parse_type ptype = fc::json::parse_type::legacy_parser); + bool setup(); }; } From f52beda0a266398c37c4f53e7e8c86d53c207bcf Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Wed, 1 Feb 2023 10:41:10 -0600 Subject: [PATCH 05/24] Fix compiler warnings in tests. --- tests/trx_generator/trx_generator_tests.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/trx_generator/trx_generator_tests.cpp b/tests/trx_generator/trx_generator_tests.cpp index 01000bd84e..6f185c940e 100644 --- a/tests/trx_generator/trx_generator_tests.cpp +++ b/tests/trx_generator/trx_generator_tests.cpp @@ -75,8 +75,8 @@ BOOST_AUTO_TEST_CASE(tps_short_run_high_tps) constexpr uint64_t expected_runtime_us = test_duration_s * 1000000; constexpr uint64_t allowable_runtime_deviation_per = 20; constexpr uint64_t allowable_runtime_deviation_us = expected_runtime_us / allowable_runtime_deviation_per; - constexpr uint64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; - constexpr uint64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; + constexpr int64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; + constexpr int64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; std::shared_ptr generator = std::make_shared(expected_trxs); std::shared_ptr monitor = std::make_shared(expected_trxs); @@ -109,8 +109,8 @@ BOOST_AUTO_TEST_CASE(tps_short_run_med_tps_med_delay) constexpr uint64_t expected_runtime_us = test_duration_s * 1000000; constexpr uint64_t allowable_runtime_deviation_per = 20; constexpr uint64_t allowable_runtime_deviation_us = expected_runtime_us / allowable_runtime_deviation_per; - constexpr uint64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; - constexpr uint64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; + constexpr int64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; + constexpr int64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; std::shared_ptr generator = std::make_shared(expected_trxs, trx_delay_us); std::shared_ptr monitor = std::make_shared(expected_trxs); @@ -142,8 +142,8 @@ BOOST_AUTO_TEST_CASE(tps_med_run_med_tps_med_delay) constexpr uint64_t expected_runtime_us = test_duration_s * 1000000; constexpr uint64_t allowable_runtime_deviation_per = 20; constexpr uint64_t allowable_runtime_deviation_us = expected_runtime_us / allowable_runtime_deviation_per; - constexpr uint64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; - constexpr uint64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; + constexpr int64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; + constexpr int64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; std::shared_ptr generator = std::make_shared(expected_trxs, trx_delay_us); std::shared_ptr monitor = std::make_shared(expected_trxs); @@ -174,8 +174,8 @@ BOOST_AUTO_TEST_CASE(tps_cant_keep_up) constexpr uint64_t expected_runtime_us = test_duration_s * 1000000; constexpr uint64_t allowable_runtime_deviation_per = 20; constexpr uint64_t allowable_runtime_deviation_us = expected_runtime_us / allowable_runtime_deviation_per; - constexpr uint64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; - constexpr uint64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; + constexpr int64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; + constexpr int64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; std::shared_ptr generator = std::make_shared(expected_trxs, trx_delay_us); std::shared_ptr monitor = std::make_shared(expected_trxs); @@ -206,8 +206,8 @@ BOOST_AUTO_TEST_CASE(tps_med_run_med_tps_30us_delay) constexpr uint64_t expected_runtime_us = test_duration_s * 1000000; constexpr uint64_t allowable_runtime_deviation_per = 20; constexpr uint64_t allowable_runtime_deviation_us = expected_runtime_us / allowable_runtime_deviation_per; - constexpr uint64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; - constexpr uint64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; + constexpr int64_t minimum_runtime_us = expected_runtime_us - allowable_runtime_deviation_us; + constexpr int64_t maximum_runtime_us = expected_runtime_us + allowable_runtime_deviation_us; std::shared_ptr generator = std::make_shared(expected_trxs, trx_delay_us); std::shared_ptr monitor = std::make_shared(expected_trxs); From b35c3d6fbaa3306c277d4f8fb3339baef029ce65 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Thu, 2 Feb 2023 13:35:14 -0600 Subject: [PATCH 06/24] Add ability to configure log level for cluster via cli arg. --- tests/performance_tests/performance_test_basic.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/performance_tests/performance_test_basic.py b/tests/performance_tests/performance_test_basic.py index 23608bbb34..6c5f3d8fae 100755 --- a/tests/performance_tests/performance_test_basic.py +++ b/tests/performance_tests/performance_test_basic.py @@ -86,6 +86,7 @@ class SpecifiedContract: genesisPath: Path = Path("tests")/"performance_tests"/"genesis.json" maximumP2pPerHost: int = 5000 maximumClients: int = 0 + loggingLevel: str = "info" loggingDict: dict = field(default_factory=lambda: { "bios": "off" }) prodsEnableTraceApi: bool = False nodeosVers: str = "" @@ -171,7 +172,7 @@ def __init__(self, testHelperConfig: TestHelperConfig=TestHelperConfig(), cluste # Setup cluster and its wallet manager self.walletMgr=WalletMgr(True) - self.cluster=Cluster(walletd=True, loggingLevel="info", loggingLevelDict=self.clusterConfig.loggingDict, + self.cluster=Cluster(walletd=True, loggingLevel=self.clusterConfig.loggingLevel, loggingLevelDict=self.clusterConfig.loggingDict, nodeosVers=self.clusterConfig.nodeosVers) self.cluster.setWalletMgr(self.walletMgr) @@ -502,6 +503,10 @@ def createBaseArgumentParser(): In \"heap\" mode database is preloaded in to swappable memory and will use huge pages if available. \ In \"locked\" mode database is preloaded, locked in to memory, and will use huge pages if available.", choices=["mapped", "heap", "locked"], default="mapped") + ptbBaseParserGroup.add_argument("--cluster-log-lvl", type=str, help="Cluster log level (\"all\", \"debug\", \"info\", \"warn\", \"error\", or \"off\"). \ + Performance Harness Test Basic relies on some logging at \"info\" level, so it is recommended lowest logging level to use. \ + However, there are instances where more verbose logging can be useful.", + choices=["all", "debug", "info", "warn", "error", "off"], default="info") ptbBaseParserGroup.add_argument("--net-threads", type=int, help="Number of worker threads in net_plugin thread pool", default=2) ptbBaseParserGroup.add_argument("--disable-subjective-billing", type=bool, help="Disable subjective CPU billing for API/P2P transactions", default=True) ptbBaseParserGroup.add_argument("--last-block-time-offset-us", type=int, help="Offset of last block producing time in microseconds. Valid range 0 .. -block_time_interval.", default=0) @@ -571,11 +576,12 @@ def main(): netPluginArgs = NetPluginArgs(netThreads=args.net_threads) ENA = PerformanceTestBasic.ClusterConfig.ExtraNodeosArgs extraNodeosArgs = ENA(chainPluginArgs=chainPluginArgs, httpPluginArgs=httpPluginArgs, producerPluginArgs=producerPluginArgs, netPluginArgs=netPluginArgs) + SC = PerformanceTestBasic.ClusterConfig.SpecifiedContract + specifiedContract=SC(accountName=args.account_name, ownerPublicKey=args.owner_public_key, activePublicKey=args.active_public_key, + contractDir=args.contract_dir, wasmFile=args.wasm_file, abiFile=args.abi_file) testClusterConfig = PerformanceTestBasic.ClusterConfig(pnodes=args.p, totalNodes=args.n, topo=args.s, genesisPath=args.genesis, prodsEnableTraceApi=args.prods_enable_trace_api, extraNodeosArgs=extraNodeosArgs, - specifiedContract=PerformanceTestBasic.ClusterConfig.SpecifiedContract(accountName=args.account_name, - ownerPublicKey=args.owner_public_key, activePublicKey=args.active_public_key, contractDir=args.contract_dir, - wasmFile=args.wasm_file, abiFile=args.abi_file), + specifiedContract=specifiedContract, loggingLevel=args.cluster_log_lvl, nodeosVers=Utils.getNodeosVersion().split('.')[0]) ptbConfig = PerformanceTestBasic.PtbConfig(targetTps=args.target_tps, testTrxGenDurationSec=args.test_duration_sec, tpsLimitPerGenerator=args.tps_limit_per_generator, numAddlBlocksToPrune=args.num_blocks_to_prune, logDirRoot=".", delReport=args.del_report, quiet=args.quiet, delPerfLogs=args.del_perf_logs, From d8d9fa31958b7ae4e79d5e1291420fdfa2ec984b Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Wed, 8 Feb 2023 17:35:47 -0600 Subject: [PATCH 07/24] Expand transaction generator to support new account trx Update user data transaction specification to support multiple actions and automatically generating an account namer per transaction to substitute into defined actions using the 'ACCT_PER_TRX' key word. Removed arguments for action data pieces that have been moved into the larger transaction spec in the json files. Added/Updated tests to exercise the new feature. --- .../launch_transaction_generators.py | 33 ++-- tests/performance_tests/CMakeLists.txt | 4 +- .../performance_test_basic.py | 89 ++++++---- .../userTrxDataNewAccount.json | 53 ++++++ .../userTrxDataTransfer.json | 26 ++- tests/trx_generator/main.cpp | 41 ++--- tests/trx_generator/trx_generator.cpp | 160 +++++++++++++++--- tests/trx_generator/trx_generator.hpp | 77 ++++++++- tests/trx_generator/trx_generator_tests.cpp | 15 +- 9 files changed, 366 insertions(+), 132 deletions(-) create mode 100644 tests/performance_tests/userTrxDataNewAccount.json diff --git a/tests/TestHarness/launch_transaction_generators.py b/tests/TestHarness/launch_transaction_generators.py index d80b0687b1..2379987840 100755 --- a/tests/TestHarness/launch_transaction_generators.py +++ b/tests/TestHarness/launch_transaction_generators.py @@ -36,8 +36,8 @@ def __init__(self, targetTps: int, tpsLimitPerGenerator: int): class TransactionGeneratorsLauncher: - def __init__(self, chainId: int, lastIrreversibleBlockId: int, contractOwnerAccount: str, accts: str, privateKeys: str, - trxGenDurationSec: int, logDir: str, abiFile: Path, actionName: str, actionAuthAcct: str, actionAuthPrivKey: str, actionData, + def __init__(self, chainId: int, lastIrreversibleBlockId: int, contractOwnerAccount: str, accts: str, privateKeys: str, trxGenDurationSec: int, logDir: str, + abiFile: Path, actionsData, actionsAuths, peerEndpoint: str, port: int, tpsTrxGensConfig: TpsTrxGensConfig): self.chainId = chainId self.lastIrreversibleBlockId = lastIrreversibleBlockId @@ -48,17 +48,15 @@ def __init__(self, chainId: int, lastIrreversibleBlockId: int, contractOwnerAcco self.tpsTrxGensConfig = tpsTrxGensConfig self.logDir = logDir self.abiFile = abiFile - self.actionName = actionName - self.actionAuthAcct = actionAuthAcct - self.actionAuthPrivKey = actionAuthPrivKey - self.actionData = actionData + self.actionsData=actionsData + self.actionsAuths=actionsAuths self.peerEndpoint = peerEndpoint self.port = port def launch(self, waitToComplete=True): self.subprocess_ret_codes = [] for id, targetTps in enumerate(self.tpsTrxGensConfig.targetTpsPerGenList): - if self.abiFile is not None and self.actionName is not None and self.actionData is not None and self.actionAuthAcct is not None and self.actionAuthPrivKey is not None: + if self.abiFile is not None and self.actionsData is not None and self.actionsAuths is not None: if Utils.Debug: Print( f'Running trx_generator: ./tests/trx_generator/trx_generator ' @@ -71,11 +69,9 @@ def launch(self, waitToComplete=True): f'--trx-gen-duration {self.trxGenDurationSec} ' f'--target-tps {targetTps} ' f'--log-dir {self.logDir} ' - f'--action-name {self.actionName} ' - f'--action-auth-acct {self.actionAuthAcct} ' - f'--action-auth-acct-priv-key {self.actionAuthPrivKey} ' - f'--action-data {self.actionData} ' f'--abi-file {self.abiFile} ' + f'--actions-data {self.actionsData} ' + f'--actions-auths {self.actionsAuths} ' f'--peer-endpoint {self.peerEndpoint} ' f'--port {self.port}' ) @@ -91,11 +87,9 @@ def launch(self, waitToComplete=True): '--trx-gen-duration', f'{self.trxGenDurationSec}', '--target-tps', f'{targetTps}', '--log-dir', f'{self.logDir}', - '--action-name', f'{self.actionName}', - '--action-auth-acct', f'{self.actionAuthAcct}', - '--action-auth-acct-priv-key', f'{self.actionAuthPrivKey}', - '--action-data', f'{self.actionData}', '--abi-file', f'{self.abiFile}', + '--actions-data', f'{self.actionsData}', + '--actions-auths', f'{self.actionsAuths}', '--peer-endpoint', f'{self.peerEndpoint}', '--port', f'{self.port}' ]) @@ -155,11 +149,9 @@ def parseArgs(): parser.add_argument("target_tps", type=int, help="Goal transactions per second") parser.add_argument("tps_limit_per_generator", type=int, help="Maximum amount of transactions per second a single generator can have.", default=4000) parser.add_argument("log_dir", type=str, help="Path to directory where trx logs should be written.") - parser.add_argument("action_name", type=str, help="The action name applied to the provided action data input") - parser.add_argument("action_auth_acct", type=str, help="The authorization account name used for trx action authorization") - parser.add_argument("action_auth_acct_priv_key", type=str, help="The authorization account's private key used for signing trx") - parser.add_argument("action_data", type=str, help="The path to the json action data file or json action data description string to use") parser.add_argument("abi_file", type=str, help="The path to the contract abi file to use for the supplied transaction action data") + parser.add_argument("actions_data", type=str, help="The json actions data file or json actions data description string to use") + parser.add_argument("actions_auths", type=str, help="The json actions auth file or json actions auths description string to use, containting authAcctName to activePrivateKey pairs.") parser.add_argument("peer_endpoint", type=str, help="set the peer endpoint to send transactions to", default="127.0.0.1") parser.add_argument("port", type=int, help="set the peer endpoint port to send transactions to", default=9876) args = parser.parse_args() @@ -171,8 +163,7 @@ def main(): trxGenLauncher = TransactionGeneratorsLauncher(chainId=args.chain_id, lastIrreversibleBlockId=args.last_irreversible_block_id, contractOwnerAccount=args.contract_owner_account, accts=args.accounts, privateKeys=args.priv_keys, trxGenDurationSec=args.trx_gen_duration, logDir=args.log_dir, - abiFile=args.abi_file, actionName=args.action_name, actionAuthAcct=args.action_auth_acct, - actionAuthPrivKey=args.action_auth_acct_priv_key, actionData=args.action_data, + abiFile=args.abi_file, actionsData=args.actions_data, actionsAuths=args.actions_auths, peerEndpoint=args.peer_endpoint, port=args.port, tpsTrxGensConfig=TpsTrxGensConfig(targetTps=args.target_tps, tpsLimitPerGenerator=args.tps_limit_per_generator)) diff --git a/tests/performance_tests/CMakeLists.txt b/tests/performance_tests/CMakeLists.txt index aa3d180bec..b7f32ba183 100644 --- a/tests/performance_tests/CMakeLists.txt +++ b/tests/performance_tests/CMakeLists.txt @@ -8,9 +8,11 @@ configure_file(nodeos_log_3_2.txt.gz nodeos_log_3_2.txt.gz COPYONLY) configure_file(genesis.json genesis.json COPYONLY) configure_file(validate_nodeos_plugin_args.py validate_nodeos_plugin_args.py COPYONLY) configure_file(userTrxDataTransfer.json userTrxDataTransfer.json COPYONLY) +configure_file(userTrxDataNewAccount.json userTrxDataNewAccount.json COPYONLY) add_test(NAME performance_test_basic COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -add_test(NAME performance_test_basic_ex_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run --user-trx-data-file tests/performance_tests/userTrxDataTransfer.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME performance_test_basic_ex_transfer_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run --user-trx-data-file tests/performance_tests/userTrxDataTransfer.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME performance_test_basic_ex_new_acct_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run --user-trx-data-file tests/performance_tests/userTrxDataNewAccount.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME log_reader_tests COMMAND tests/performance_tests/log_reader_tests.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME validate_nodeos_plugin_args COMMAND tests/performance_tests/validate_nodeos_plugin_args.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST performance_test_basic PROPERTY LABELS nonparallelizable_tests) diff --git a/tests/performance_tests/performance_test_basic.py b/tests/performance_tests/performance_test_basic.py index 6c5f3d8fae..9ceb0f8f24 100755 --- a/tests/performance_tests/performance_test_basic.py +++ b/tests/performance_tests/performance_test_basic.py @@ -70,8 +70,10 @@ def __str__(self) -> str: @dataclass class SpecifiedContract: - accountName: str = "c" + accountName: str = "eosio" + ownerPrivateKey: str = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" ownerPublicKey: str = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + activePrivateKey: str = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" activePublicKey: str = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" contractDir: str = "unittests/contracts/eosio.system" wasmFile: str = "eosio.system.wasm" @@ -288,20 +290,32 @@ def readUserTrxDataFromFile(self, userTrxDataFile: Path): self.userTrxDataDict = json.load(f) def setupContract(self): - specifiedAccount = Account(self.clusterConfig.specifiedContract.accountName) - specifiedAccount.ownerPublicKey = self.clusterConfig.specifiedContract.ownerPublicKey - specifiedAccount.activePublicKey = self.clusterConfig.specifiedContract.activePublicKey - self.cluster.createAccountAndVerify(specifiedAccount, self.cluster.eosioAccount, validationNodeIndex=self.validationNodeId) - print("Publishing contract") - transaction=self.cluster.biosNode.publishContract(specifiedAccount, self.clusterConfig.specifiedContract.contractDir, - self.clusterConfig.specifiedContract.wasmFile, - self.clusterConfig.specifiedContract.abiFile, waitForTransBlock=True) - if transaction is None: - print("ERROR: Failed to publish contract.") - return None + if (self.clusterConfig.specifiedContract.accountName != self.cluster.eosioAccount.name): + specifiedAccount = Account(self.clusterConfig.specifiedContract.accountName) + specifiedAccount.ownerPublicKey = self.clusterConfig.specifiedContract.ownerPublicKey + specifiedAccount.ownerPrivateKey = self.clusterConfig.specifiedContract.ownerPrivateKey + specifiedAccount.activePublicKey = self.clusterConfig.specifiedContract.activePublicKey + specifiedAccount.activePrivateKey = self.clusterConfig.specifiedContract.activePrivateKey + self.cluster.createAccountAndVerify(specifiedAccount, self.cluster.eosioAccount, validationNodeIndex=self.validationNodeId) + print("Publishing contract") + transaction=self.cluster.biosNode.publishContract(specifiedAccount, self.clusterConfig.specifiedContract.contractDir, + self.clusterConfig.specifiedContract.wasmFile, + self.clusterConfig.specifiedContract.abiFile, waitForTransBlock=True) + if transaction is None: + print("ERROR: Failed to publish contract.") + return None + else: + self.clusterConfig.specifiedContract.activePrivateKey = self.cluster.eosioAccount.activePrivateKey + self.clusterConfig.specifiedContract.activePublicKey = self.cluster.eosioAccount.activePublicKey + self.clusterConfig.specifiedContract.ownerPrivateKey = self.cluster.eosioAccount.ownerPrivateKey + self.clusterConfig.specifiedContract.ownerPublicKey = self.cluster.eosioAccount.ownerPublicKey + print(f"setupContract: default {self.clusterConfig.specifiedContract.accountName} \ + activePrivateKey: {self.clusterConfig.specifiedContract.activePrivateKey} \ + activePublicKey: {self.clusterConfig.specifiedContract.activePublicKey} \ + ownerPrivateKey: {self.clusterConfig.specifiedContract.ownerPrivateKey} \ + ownerPublicKey: {self.clusterConfig.specifiedContract.ownerPublicKey}") def runTpsTest(self) -> PtbTpsTestResult: - completedRun = False self.producerNode = self.cluster.getNode(self.producerNodeId) self.producerP2pPort = self.cluster.getNodeP2pPort(self.producerNodeId) @@ -313,25 +327,34 @@ def runTpsTest(self) -> PtbTpsTestResult: self.data = log_reader.chainData() abiFile=None - actionName=None - actionAuthAcct=None - actionAuthPrivKey=None - actionData=None + actionsDataJson=None + actionsAuthsJson=None + self.accountNames=[] + self.accountPrivKeys=[] if (self.ptbConfig.userTrxDataFile is not None): self.readUserTrxDataFromFile(self.ptbConfig.userTrxDataFile) - self.setupWalletAndAccounts(accountCnt=len(self.userTrxDataDict['accounts']), accountNames=self.userTrxDataDict['accounts']) + if self.userTrxDataDict['initAccounts']: + print(f"Creating accounts specified in userTrxData: {self.userTrxDataDict['initAccounts']}") + self.setupWalletAndAccounts(accountCnt=len(self.userTrxDataDict['initAccounts']), accountNames=self.userTrxDataDict['initAccounts']) abiFile = self.userTrxDataDict['abiFile'] - actionName = self.userTrxDataDict['actionName'] - actionAuthAcct = self.userTrxDataDict['actionAuthAcct'] - actionData = json.dumps(self.userTrxDataDict['actionData']) - if actionAuthAcct == self.cluster.eosioAccount.name: - actionAuthPrivKey = self.cluster.eosioAccount.activePrivateKey - else: - for account in self.cluster.accounts: - if actionAuthAcct == account.name: - actionAuthPrivKey = account.activePrivateKey - break + actionsDataJson = json.dumps(self.userTrxDataDict['actions']) + + authorizations={} + for act in self.userTrxDataDict['actions']: + actionAuthAcct=act["actionAuthAcct"] + actionAuthPrivKey=None + if actionAuthAcct == self.cluster.eosioAccount.name: + actionAuthPrivKey = self.cluster.eosioAccount.activePrivateKey + else: + for account in self.cluster.accounts: + if actionAuthAcct == account.name: + actionAuthPrivKey = account.activePrivateKey + break + + if actionAuthPrivKey is not None: + authorizations[actionAuthAcct]=actionAuthPrivKey + actionsAuthsJson = json.dumps(authorizations) else: self.setupWalletAndAccounts() @@ -340,10 +363,10 @@ def runTpsTest(self) -> PtbTpsTestResult: self.data.startBlock = self.waitForEmptyBlocks(self.validationNode, self.emptyBlockGoal) tpsTrxGensConfig = TpsTrxGensConfig(targetTps=self.ptbConfig.targetTps, tpsLimitPerGenerator=self.ptbConfig.tpsLimitPerGenerator) - trxGenLauncher = TransactionGeneratorsLauncher(chainId=chainId, lastIrreversibleBlockId=lib_id, - contractOwnerAccount=self.clusterConfig.specifiedContract.accountName, accts=','.join(map(str, self.accountNames)), - privateKeys=','.join(map(str, self.accountPrivKeys)), trxGenDurationSec=self.ptbConfig.testTrxGenDurationSec, logDir=self.trxGenLogDirPath, - abiFile=abiFile, actionName=actionName, actionAuthAcct=actionAuthAcct, actionAuthPrivKey=actionAuthPrivKey, actionData=actionData, + trxGenLauncher = TransactionGeneratorsLauncher(chainId=chainId, lastIrreversibleBlockId=lib_id, contractOwnerAccount=self.clusterConfig.specifiedContract.accountName, + accts=','.join(map(str, self.accountNames)), privateKeys=','.join(map(str, self.accountPrivKeys)), + trxGenDurationSec=self.ptbConfig.testTrxGenDurationSec, logDir=self.trxGenLogDirPath, + abiFile=abiFile, actionsData=actionsDataJson, actionsAuths=actionsAuthsJson, peerEndpoint=self.producerNode.host, port=self.producerP2pPort, tpsTrxGensConfig=tpsTrxGensConfig) trxGenExitCodes = trxGenLauncher.launch() @@ -520,7 +543,7 @@ def createBaseArgumentParser(): ptbBaseParserGroup.add_argument("--quiet", help="Whether to quiet printing intermediate results and reports to stdout", action='store_true') ptbBaseParserGroup.add_argument("--prods-enable-trace-api", help="Determines whether producer nodes should have eosio::trace_api_plugin enabled", action='store_true') ptbBaseParserGroup.add_argument("--print-missing-transactions", type=bool, help="Toggles if missing transactions are be printed upon test completion.", default=False) - ptbBaseParserGroup.add_argument("--account-name", type=str, help="Name of the account to create and assign a contract to", default="c") + ptbBaseParserGroup.add_argument("--account-name", type=str, help="Name of the account to create and assign a contract to", default="eosio") ptbBaseParserGroup.add_argument("--owner-public-key", type=str, help="Owner public key to use with specified account name", default="EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV") ptbBaseParserGroup.add_argument("--active-public-key", type=str, help="Active public key to use with specified account name", default="EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV") ptbBaseParserGroup.add_argument("--contract-dir", type=str, help="Path to contract dir", default="unittests/contracts/eosio.system") diff --git a/tests/performance_tests/userTrxDataNewAccount.json b/tests/performance_tests/userTrxDataNewAccount.json new file mode 100644 index 0000000000..de4cdc7647 --- /dev/null +++ b/tests/performance_tests/userTrxDataNewAccount.json @@ -0,0 +1,53 @@ +{ + "initAccounts": [], + "abiFile": "unittests/contracts/eosio.system/eosio.system.abi", + "actions": [ + { + "actionAuthAcct": "eosio", + "actionName": "newaccount", + "authorization": { + "actor": "eosio", + "permission": "active" + }, + "actionData": { + "creator": "eosio", + "name": "ACCT_PER_TRX", + "owner": { + "threshold": 1, + "keys": [ + { + "key": "EOS65rXebLhtk2aTTzP4e9x1AQZs7c5NNXJp89W8R3HyaA6Zyd4im", + "weight": 1 + } + ], + "accounts": [], + "waits": [] + }, + "active": { + "threshold": 1, + "keys": [ + { + "key": "EOS65rXebLhtk2aTTzP4e9x1AQZs7c5NNXJp89W8R3HyaA6Zyd4im", + "weight": 1 + } + ], + "accounts": [], + "waits": [] + } + } + }, + { + "actionAuthAcct": "eosio", + "actionName": "buyrambytes", + "authorization": { + "actor": "eosio", + "permission": "active" + }, + "actionData": { + "payer": "eosio", + "receiver": "ACCT_PER_TRX", + "bytes": "3000" + } + } + ] +} diff --git a/tests/performance_tests/userTrxDataTransfer.json b/tests/performance_tests/userTrxDataTransfer.json index 242652b4e9..4e17595eb1 100644 --- a/tests/performance_tests/userTrxDataTransfer.json +++ b/tests/performance_tests/userTrxDataTransfer.json @@ -1,13 +1,23 @@ { - "accounts": ["testacct1", "testacct2"], + "initAccounts": [ + "testacct1", + "testacct2" + ], "abiFile": "unittests/contracts/eosio.token/eosio.token.abi", - "actionName": "transfer", - "actionAuthAcct": "testacct1", - "actionData": + "actions": [ { - "from":"testacct1", - "to":"testacct2", - "quantity":"0.0001 CUR", - "memo":"transaction specified" + "actionAuthAcct": "testacct1", + "actionName": "transfer", + "authorization": { + "actor": "testacct1", + "permission": "active" + }, + "actionData": { + "from": "testacct1", + "to": "testacct2", + "quantity": "0.0001 CUR", + "memo": "transaction specified" + } } + ] } diff --git a/tests/trx_generator/main.cpp b/tests/trx_generator/main.cpp index 007be8f0a6..686b937493 100644 --- a/tests/trx_generator/main.cpp +++ b/tests/trx_generator/main.cpp @@ -46,11 +46,9 @@ int main(int argc, char** argv) { unsigned short port; bool transaction_specified = false; - std::string action_name_in; - std::string action_auth_acct_in; - std::string action_auth_acct_priv_key_in; - std::string action_data_file_or_str; std::string abi_file_path_in; + std::string actions_data_json_file_or_str; + std::string actions_auths_json_file_or_str; vector account_str_vector; vector private_keys_str_vector; @@ -70,12 +68,9 @@ int main(int argc, char** argv) { ("monitor-max-lag-percent", bpo::value(&max_lag_per)->default_value(5), "Max percentage off from expected transactions sent before being in violation. Defaults to 5.") ("monitor-max-lag-duration-us", bpo::value(&max_lag_duration_us)->default_value(1000000), "Max microseconds that transaction generation can be in violation before quitting. Defaults to 1000000 (1s).") ("log-dir", bpo::value(&log_dir_in), "set the logs directory") - ("action-name", bpo::value(&action_name_in), "The action name applied to the provided action data input") - ("action-auth-acct", bpo::value(&action_auth_acct_in), "The action authorization account") - ("action-auth-acct-priv-key", bpo::value(&action_auth_acct_priv_key_in), "The action authorization account priv key for signing trxs") - ("action-data", bpo::value(&action_data_file_or_str), "The path to the json action data file or json action data description string to use") ("abi-file", bpo::value(&abi_file_path_in), "The path to the contract abi file to use for the supplied transaction action data") - ("stop-on-trx-failed", bpo::value(&stop_on_trx_failed)->default_value(true), "stop transaction generation if sending fails.") + ("actions-data", bpo::value(&actions_data_json_file_or_str), "The json actions data file or json actions data description string to use") + ("actions-auths", bpo::value(&actions_auths_json_file_or_str), "The json actions auth file or json actions auths description string to use, containting authAcctName to activePrivateKey pairs.") ("peer-endpoint", bpo::value(&peer_endpoint)->default_value("127.0.0.1"), "set the peer endpoint to send transactions to") ("port", bpo::value(&port)->default_value(9876), "set the peer endpoint port to send transactions to") ("help,h", "print this list") @@ -90,15 +85,15 @@ int main(int argc, char** argv) { return SUCCESS; } - if((vmap.count("action-name") || vmap.count("action-auth-acct") || vmap.count("action-auth-acct-priv-key") || vmap.count("action-data") || vmap.count("abi-file")) && - !(vmap.count("action-name") && vmap.count("action-auth-acct") && vmap.count("action-auth-acct-priv-key") && vmap.count("action-data") && vmap.count("abi-file"))) { - ilog("Initialization error: If using action-name, action-auth-acct, action-auth-acct-priv-key, action-data, or abi-file to specify a transaction type to generate, must provide all inputs."); + if((vmap.count("abi-file") || vmap.count("actions-data") || vmap.count("actions-auths")) && + !(vmap.count("abi-file") && vmap.count("actions-data") && vmap.count("actions-auths"))) { + ilog("Initialization error: If using abi-file, actions-data, and actions-auths to specify a transaction type to generate, must provide all inputs."); cli.print(std::cerr); return INITIALIZE_FAIL; } - if(vmap.count("action-name") && vmap.count("action-auth-acct") && vmap.count("action-auth-acct-priv-key") && vmap.count("action-data") && vmap.count("abi-file")) { - ilog("Specifying transaction to generate directly using action-name, action-auth-acct, action-auth-acct-priv-key, action-data, and abi-file."); + if(vmap.count("abi-file") && vmap.count("actions-data") && vmap.count("actions-auths")) { + ilog("Specifying transaction to generate directly using abi-file, actions-data, and actions-auths."); transaction_specified = true; } @@ -134,11 +129,6 @@ int main(int argc, char** argv) { cli.print(std::cerr); return INITIALIZE_FAIL; } - if (transaction_specified && account_str_vector.size() < 1) { - ilog("Initialization error: Specifying transaction to generate requires at minimum 1 account."); - cli.print(std::cerr); - return INITIALIZE_FAIL; - } } else { ilog("Initialization error: did not specify transfer accounts. Auto transfer transaction generation requires at minimum 2 transfer accounts, while providing transaction action data requires at least one."); cli.print(std::cerr); @@ -152,11 +142,6 @@ int main(int argc, char** argv) { cli.print(std::cerr); return INITIALIZE_FAIL; } - if (transaction_specified && private_keys_str_vector.size() < 1) { - ilog("Initialization error: Specifying transaction to generate requires at minimum 1 private key"); - cli.print(std::cerr); - return INITIALIZE_FAIL; - } } else { ilog("Initialization error: did not specify accounts' private keys. Auto transfer transaction generation requires at minimum 2 private keys, while providing transaction action data requires at least one."); cli.print(std::cerr); @@ -221,11 +206,9 @@ int main(int argc, char** argv) { ilog("Peer Endpoint ${peer-endpoint}:${peer-port}", ("peer-endpoint", peer_endpoint)("peer-port", port)); if (transaction_specified) { - ilog("User Transaction Specified: Action Name ${act}", ("act", action_name_in)); - ilog("User Transaction Specified: Action Auth Acct Name ${acct}", ("acct", action_auth_acct_in)); - ilog("User Transaction Specified: Action Auth Acct Priv Key ${key}", ("key", action_auth_acct_priv_key_in)); - ilog("User Transaction Specified: Action Data File or Str ${data}", ("data", action_data_file_or_str)); ilog("User Transaction Specified: Abi File ${abi}", ("abi", abi_file_path_in)); + ilog("User Transaction Specified: Actions Data ${acts}", ("acts", actions_data_json_file_or_str)); + ilog("User Transaction Specified: Actions Auths ${auths}", ("auths", actions_auths_json_file_or_str)); } fc::microseconds trx_expr_ms = fc::seconds(trx_expr); @@ -233,7 +216,7 @@ int main(int argc, char** argv) { std::shared_ptr monitor; if (transaction_specified) { auto generator = std::make_shared(gen_id, chain_id_in, abi_file_path_in, contract_owner_acct, - action_name_in, action_auth_acct_in, action_auth_acct_priv_key_in, action_data_file_or_str, + actions_data_json_file_or_str, actions_auths_json_file_or_str, trx_expr_ms, lib_id_str, log_dir_in, stop_on_trx_failed, peer_endpoint, port); monitor = std::make_shared(spinup_time_us, max_lag_per, max_lag_duration_us); trx_tps_tester tester{generator, monitor, gen_duration, target_tps}; diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index 7e0cb56284..f5ec6f95bd 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -26,10 +26,12 @@ namespace eosio::testing { trx.delay_sec = delay_sec; } - signed_transaction_w_signer trx_generator_base::create_trx_w_action_and_signer(const action& act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { + signed_transaction_w_signer trx_generator_base::create_trx_w_actions_and_signer(std::vector acts, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { signed_transaction trx; set_transaction_headers(trx, last_irr_block_id, trx_expiration); - trx.actions.push_back(act); + for (auto act:acts) { + trx.actions.push_back(act); + } trx.context_free_actions.emplace_back(action({}, config::null_account_name, name("nonce"), fc::raw::pack(std::to_string(nonce_prefix) + ":" + std::to_string(++nonce) + ":" + fc::time_point::now().time_since_epoch().count()))); @@ -42,9 +44,14 @@ namespace eosio::testing { std::vector trxs; trxs.reserve(2 * action_pairs_vector.size()); + std::vector act_vec; for(action_pair_w_keys ap: action_pairs_vector) { - trxs.emplace_back(create_trx_w_action_and_signer(ap._first_act, ap._first_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); - trxs.emplace_back(create_trx_w_action_and_signer(ap._second_act, ap._second_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); + act_vec.push_back(ap._first_act); + trxs.emplace_back(create_trx_w_actions_and_signer(act_vec, ap._first_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); + act_vec.clear(); + act_vec.push_back(ap._second_act); + trxs.emplace_back(create_trx_w_actions_and_signer(act_vec, ap._second_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); + act_vec.clear(); } return trxs; @@ -161,13 +168,102 @@ namespace eosio::testing { } } + void trx_generator::locate_key_words_in_action_mvo(std::vector& acct_gen_fields_out, fc::mutable_variant_object& action_mvo, const std::string& key_word) { + for(const mutable_variant_object::entry& e: action_mvo) { + if(e.value().get_type() == fc::variant::string_type && e.value() == key_word) { + acct_gen_fields_out.push_back(e.key()); + } else if(e.value().get_type() == fc::variant::object_type) { + auto inner_mvo = fc::mutable_variant_object(e.value()); + locate_key_words_in_action_mvo(acct_gen_fields_out, inner_mvo, key_word); + } + } + } + + void trx_generator::locate_key_words_in_action_array(std::map>& acct_gen_fields_out, fc::variants& action_array, const std::string& key_word) { + for(size_t i = 0; i < action_array.size(); ++i) { + auto action_mvo = fc::mutable_variant_object(action_array[i]); + locate_key_words_in_action_mvo(acct_gen_fields_out[i], action_mvo, key_word); + } + } + + void trx_generator::update_key_word_fields_in_sub_action(std::string key, fc::mutable_variant_object& action_mvo, std::string action_inner_key, const std::string key_word) { + auto mvo = action_mvo.find(action_inner_key); + if(mvo != action_mvo.end()) { + fc::mutable_variant_object inner_mvo = fc::mutable_variant_object(action_mvo[action_inner_key].get_object()); + if (inner_mvo.find(key) != inner_mvo.end()) { + inner_mvo.set(key, key_word); + action_mvo.set(action_inner_key, inner_mvo); + } + } + } + + void trx_generator::update_key_word_fields_in_action(std::vector& acct_gen_fields, fc::mutable_variant_object& action_mvo, const std::string key_word) { + for(auto key: acct_gen_fields) { + auto mvo = action_mvo.find(key); + if(mvo != action_mvo.end()) { + action_mvo.set(key, key_word); + } else { + for(auto e: action_mvo) { + if(e.value().get_type() == fc::variant::object_type) { + update_key_word_fields_in_sub_action(key, action_mvo, e.key(), key_word); + } + } + } + } + } + + void trx_generator::update_resign_transaction(signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { + trx.actions.clear(); + update_actions(); + for(auto act: _actions) { + trx.actions.push_back(act); + } + trx_generator_base::update_resign_transaction(trx, priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id); + } + trx_generator::trx_generator(uint16_t id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, - std::string action_name, std::string action_auth_account, const std::string& private_key_str, const std::string& action_data_file_or_str, + const std::string& actions_data_json_file_or_str, const std::string& actions_auths_json_file_or_str, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) : trx_generator_base(id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), - _abi_data_file_path(abi_data_file), _action(action_name), _action_auth_account(action_auth_account), - _action_auth_priv_key(fc::crypto::private_key(private_key_str)), _action_data_file_or_str(action_data_file_or_str) {} + _abi_data_file_path(abi_data_file), + _actions_data_json_file_or_str(actions_data_json_file_or_str), _actions_auths_json_file_or_str(actions_auths_json_file_or_str), + _acct_name_generator() {} + + void trx_generator::update_actions() { + _actions.clear(); + + if (!_acct_gen_fields.empty()) { + std::string generated_account_name = _acct_name_generator.calcName(); + _acct_name_generator.increment(); + + for (auto const& [key, val] : _acct_gen_fields) { + update_key_word_fields_in_action(_acct_gen_fields.at(key), _unpacked_actions.at(key), generated_account_name); + } + } + + for (auto action_mvo : _unpacked_actions) { + chain::name action_name = chain::name(action_mvo["actionName"].as_string()); + chain::name action_auth_acct = chain::name(action_mvo["actionAuthAcct"].as_string()); + bytes packed_action_data; + try { + auto action_type = _abi.get_action_type( action_name ); + FC_ASSERT( !action_type.empty(), "Unknown action ${action} in contract ${contract}", ("action", action_name)( "contract", action_auth_acct )); + packed_action_data = _abi.variant_to_binary( action_type, action_mvo["actionData"], abi_serializer::create_yield_function( abi_serializer_max_time ) ); + } EOS_RETHROW_EXCEPTIONS(transaction_type_exception, "Fail to parse unpacked action data JSON") + + eosio::chain::action act; + act.account = _contract_owner_account; + act.name = action_name; + + chain::name auth_actor = chain::name(action_mvo["authorization"].get_object()["actor"].as_string()); + chain::name auth_perm = chain::name(action_mvo["authorization"].get_object()["permission"].as_string()); + + act.authorization = vector{{auth_actor, auth_perm}}; + act.data = std::move(packed_action_data); + _actions.push_back(act); + } + } bool trx_generator::setup() { _nonce_prefix = 0; @@ -177,31 +273,47 @@ namespace eosio::testing { stop_generation(); ilog("Create Initial Transaction with action data."); - abi_serializer abi = abi_serializer(fc::json::from_file(_abi_data_file_path).as(), abi_serializer::create_yield_function( abi_serializer_max_time )); - fc::variant unpacked_action_data_json = json_from_file_or_string(_action_data_file_or_str); - ilog("action data variant: ${data}", ("data", fc::json::to_pretty_string(unpacked_action_data_json))); + _abi = abi_serializer(fc::json::from_file(_abi_data_file_path).as(), abi_serializer::create_yield_function( abi_serializer_max_time )); + fc::variant unpacked_actions_data_json = json_from_file_or_string(_actions_data_json_file_or_str); + fc::variant unpacked_actions_auths_data_json = json_from_file_or_string(_actions_auths_json_file_or_str); + ilog("Loaded actions data: ${data}", ("data", fc::json::to_pretty_string(unpacked_actions_data_json))); + ilog("Loaded actions auths data: ${auths}", ("auths", fc::json::to_pretty_string(unpacked_actions_auths_data_json))); - bytes packed_action_data; - try { - auto action_type = abi.get_action_type( _action ); - FC_ASSERT( !action_type.empty(), "Unknown action ${action} in contract ${contract}", ("action", _action)( "contract", _action_auth_account )); - packed_action_data = abi.variant_to_binary( action_type, unpacked_action_data_json, abi_serializer::create_yield_function( abi_serializer_max_time ) ); + const std::string gen_acct_name_per_trx("ACCT_PER_TRX"); - } EOS_RETHROW_EXCEPTIONS(transaction_type_exception, "Fail to parse unpacked action data JSON") + auto action_array = unpacked_actions_data_json.get_array(); + for (size_t i =0; i < action_array.size(); ++i ) { + _unpacked_actions.push_back(fc::mutable_variant_object(action_array[i])); + } + locate_key_words_in_action_array(_acct_gen_fields, action_array, gen_acct_name_per_trx); - ilog("${packed_data}", ("packed_data", fc::to_hex(packed_action_data.data(), packed_action_data.size()))); + if(!_acct_gen_fields.empty()) { + ilog("Located the following account names that need to be generated and populted in each transaction:"); + for(auto e: _acct_gen_fields) { + ilog("acct_gen_fields entry: ${value}", ("value", e)); + } + ilog("Priming name generator for trx generator prefix."); + _acct_name_generator.setPrefix(_id); + } + + ilog("Setting up transaction signer."); + fc::crypto::private_key signer_key; + signer_key = fc::crypto::private_key(unpacked_actions_auths_data_json.get_object()[_unpacked_actions.at(0)["actionAuthAcct"].as_string()].as_string()); - eosio::chain::action act; - act.account = _contract_owner_account; - act.name = _action; - act.authorization = vector{{_action_auth_account, config::active_name}}; - act.data = std::move(packed_action_data); + ilog("Setting up initial transaction actions."); + update_actions(); + ilog("Initial actions (${count}):", ("count", _unpacked_actions.size())); + for (size_t i = 0; i < _unpacked_actions.size(); ++i) { + ilog("Initial action ${index}: ${act}", ("index", i)("act", fc::json::to_pretty_string(_unpacked_actions.at(i)))); + ilog("Initial action packed data ${index}: ${packed_data}", ("packed_data", fc::to_hex(_actions.at(i).data.data(), _actions.at(i).data.size()))); + } - _trxs.emplace_back(create_trx_w_action_and_signer(act, _action_auth_priv_key, ++_nonce_prefix, _nonce, _trx_expiration, _chain_id, _last_irr_block_id)); + ilog("Populate initial transaction."); + _trxs.emplace_back(create_trx_w_actions_and_signer(_actions, signer_key, ++_nonce_prefix, _nonce, _trx_expiration, _chain_id, _last_irr_block_id)); ilog("Setup p2p transaction provider"); - ilog("Update each trx to qualify as unique and fresh timestamps, re-sign trx, and send each updated transactions via p2p transaction provider"); + ilog("Update each trx to qualify as unique and fresh timestamps and update each action with unique generated account name if necessary, re-sign trx, and send each updated transactions via p2p transaction provider"); _provider.setup(); return true; diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index d308ab47fb..01180bfb0b 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace eosio::testing { @@ -27,6 +28,53 @@ namespace eosio::testing { fc::crypto::private_key _second_act_priv_key; }; + struct account_name_generator { + account_name_generator() : _name_index_vec(ACCT_NAME_LEN, 0) {} + + const char* CHARMAP = "12345abcdefghijklmnopqrstuvwxyz"; + const int ACCT_NAME_CHAR_CNT = 31; + const int ACCT_NAME_LEN = 12; + const int MAX_PREFEX = 960; + std::vector _name_index_vec; + + void increment(int index) { + _name_index_vec[index]++; + if(_name_index_vec[index] >= ACCT_NAME_CHAR_CNT) { + _name_index_vec[index] = 0; + increment(index - 1); + } + } + + void increment() { + increment(_name_index_vec.size() - 1); + } + + void incrementPrefix() { + increment(1); + } + + void setPrefix(int id) { + if (id > MAX_PREFEX) { + elog("Account Name Generator Prefix above allowable ${max}", ("max", MAX_PREFEX)); + return; + } + _name_index_vec[0] = 0; + _name_index_vec[1] = 0; + for(int i = 0; i < id; i++) { + incrementPrefix(); + } + }; + + std::string calcName() { + std::string name; + name.reserve(12); + for(auto i: _name_index_vec) { + name += CHARMAP[i]; + } + return name; + } + }; + struct trx_generator_base { p2p_trx_provider _provider; uint16_t _id; @@ -49,14 +97,16 @@ namespace eosio::testing { trx_generator_base(uint16_t id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); - void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, + virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); void push_transaction(p2p_trx_provider& provider, signed_transaction_w_signer& trx, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); + void set_transaction_headers(eosio::chain::transaction& trx, const eosio::chain::block_id_type& last_irr_block_id, const fc::microseconds expiration, uint32_t delay_sec = 0); - signed_transaction_w_signer create_trx_w_action_and_signer(const eosio::chain::action& act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, + + signed_transaction_w_signer create_trx_w_actions_and_signer(std::vector act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); void log_first_trx(const std::string& log_dir, const eosio::chain::signed_transaction& trx); @@ -89,18 +139,31 @@ namespace eosio::testing { struct trx_generator : public trx_generator_base{ std::string _abi_data_file_path; - eosio::chain::name _action; - eosio::chain::name _action_auth_account; - fc::crypto::private_key _action_auth_priv_key; - std::string _action_data_file_or_str; + std::string _actions_data_json_file_or_str; + std::string _actions_auths_json_file_or_str; + account_name_generator _acct_name_generator; + + eosio::chain::abi_serializer _abi; + std::vector _unpacked_actions; + std::map> _acct_gen_fields; + std::vector _actions; const fc::microseconds abi_serializer_max_time = fc::seconds(10); // No risk to client side serialization taking a long time trx_generator(uint16_t id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, - std::string action_name, std::string action_auth_account, const std::string& action_auth_priv_key_str, const std::string& action_data_file_or_str, + const std::string& actions_data_json_file_or_str, const std::string& actions_auths_json_file_or_str, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); + void locate_key_words_in_action_mvo(std::vector& acctGenFieldsOut, fc::mutable_variant_object& action_mvo, const std::string& keyword); + void locate_key_words_in_action_array(std::map>& acctGenFieldsOut, fc::variants& action_array, const std::string& keyword); + void update_key_word_fields_in_sub_action(std::string key, fc::mutable_variant_object& action_mvo, std::string action_inner_key, const std::string keyWord); + void update_key_word_fields_in_action(std::vector& acctGenFields, fc::mutable_variant_object& action_mvo, const std::string keyWord); + + void update_actions(); + virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, + const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); + fc::variant json_from_file_or_string(const std::string& file_or_str, fc::json::parse_type ptype = fc::json::parse_type::legacy_parser); bool setup(); diff --git a/tests/trx_generator/trx_generator_tests.cpp b/tests/trx_generator/trx_generator_tests.cpp index 6f185c940e..99d5abdafb 100644 --- a/tests/trx_generator/trx_generator_tests.cpp +++ b/tests/trx_generator/trx_generator_tests.cpp @@ -327,23 +327,20 @@ BOOST_AUTO_TEST_CASE(trx_generator_constructor) { uint16_t id = 1; std::string chain_id = "999"; - std::string contract_owner_account = "eosio"; - std::string acct = "aaa"; - std::string action_name = "transfer"; - std::string action_auth_acct = "aaa"; - std::string action_auth_priv_key_str = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"; - const std::string action_data = "{\"from\":\"aaa\",\"to\":\"bbb\",\"quantity\":\"10.0000 SYS\",\"memo\":\"hello\"}"; const std::string abi_file = "../../unittests/contracts/eosio.token/eosio.token.abi"; + std::string contract_owner_account = "eosio"; + std::string actions_data = "[{\"actionAuthAcct\": \"testacct1\",\"actionName\": \"transfer\",\"authorization\": {\"actor\": \"testacct1\",\"permission\": \"active\"},\"actionData\": {\"from\": \"testacct1\",\"to\": \"testacct2\",\"quantity\": \"0.0001 CUR\",\"memo\": \"transaction specified\"}}]"; + std::string action_auths = "{\"testacct1\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\",\"testacct2\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\",\"eosio\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\"}"; fc::microseconds trx_expr = fc::seconds(3600); std::string log_dir = "."; std::string lib_id_str = "00000062989f69fd251df3e0b274c3364ffc2f4fce73de3f1c7b5e11a4c92f21"; + bool stop_on_trx_failed = true; std::string peer_endpoint = "127.0.0.1"; unsigned short port = 9876; - bool stop_on_trx_failed = true; auto generator = trx_generator(id, chain_id, abi_file, contract_owner_account, - action_name, action_auth_acct, action_auth_priv_key_str, action_data, trx_expr, - lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port); + actions_data, action_auths, + trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port); } BOOST_AUTO_TEST_SUITE_END() From df12ef4835b6ebe92d39108a328ccfd25da0902d Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Thu, 9 Feb 2023 08:07:06 -0600 Subject: [PATCH 08/24] Fix argument names. --- tests/trx_generator/trx_generator.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index 01180bfb0b..6082ac5d24 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -155,10 +155,10 @@ namespace eosio::testing { fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); - void locate_key_words_in_action_mvo(std::vector& acctGenFieldsOut, fc::mutable_variant_object& action_mvo, const std::string& keyword); - void locate_key_words_in_action_array(std::map>& acctGenFieldsOut, fc::variants& action_array, const std::string& keyword); - void update_key_word_fields_in_sub_action(std::string key, fc::mutable_variant_object& action_mvo, std::string action_inner_key, const std::string keyWord); - void update_key_word_fields_in_action(std::vector& acctGenFields, fc::mutable_variant_object& action_mvo, const std::string keyWord); + void locate_key_words_in_action_mvo(std::vector& acct_gen_fields_out, fc::mutable_variant_object& action_mvo, const std::string& key_word); + void locate_key_words_in_action_array(std::map>& acct_gen_fields_out, fc::variants& action_array, const std::string& key_word); + void update_key_word_fields_in_sub_action(std::string key, fc::mutable_variant_object& action_mvo, std::string action_inner_key, const std::string key_word); + void update_key_word_fields_in_action(std::vector& acct_gen_fields, fc::mutable_variant_object& action_mvo, const std::string key_word); void update_actions(); virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, From 9a8d79212d796d340b717c03e76989a9e83f9d91 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Thu, 9 Feb 2023 08:07:44 -0600 Subject: [PATCH 09/24] Control test-duration-sec for these tests. Default is 90 sec, don't need that long for these tests. --- tests/performance_tests/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/performance_tests/CMakeLists.txt b/tests/performance_tests/CMakeLists.txt index b7f32ba183..1fcf61f0c0 100644 --- a/tests/performance_tests/CMakeLists.txt +++ b/tests/performance_tests/CMakeLists.txt @@ -10,9 +10,9 @@ configure_file(validate_nodeos_plugin_args.py validate_nodeos_plugin_args.py COP configure_file(userTrxDataTransfer.json userTrxDataTransfer.json COPYONLY) configure_file(userTrxDataNewAccount.json userTrxDataNewAccount.json COPYONLY) -add_test(NAME performance_test_basic COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -add_test(NAME performance_test_basic_ex_transfer_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run --user-trx-data-file tests/performance_tests/userTrxDataTransfer.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -add_test(NAME performance_test_basic_ex_new_acct_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --clean-run --user-trx-data-file tests/performance_tests/userTrxDataNewAccount.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME performance_test_basic COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --clean-run WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME performance_test_basic_ex_transfer_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --clean-run --user-trx-data-file tests/performance_tests/userTrxDataTransfer.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME performance_test_basic_ex_new_acct_trx_spec COMMAND tests/performance_tests/performance_test_basic.py -v -p 1 -n 1 --target-tps 20 --tps-limit-per-generator 10 --test-duration-sec 5 --clean-run --user-trx-data-file tests/performance_tests/userTrxDataNewAccount.json WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME log_reader_tests COMMAND tests/performance_tests/log_reader_tests.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME validate_nodeos_plugin_args COMMAND tests/performance_tests/validate_nodeos_plugin_args.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST performance_test_basic PROPERTY LABELS nonparallelizable_tests) From 68fe107e1a54bf4886911f04340505ed29b621e2 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Thu, 9 Feb 2023 10:08:32 -0600 Subject: [PATCH 10/24] Apply nonparallelizable_tests flag to new tests. --- tests/performance_tests/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/performance_tests/CMakeLists.txt b/tests/performance_tests/CMakeLists.txt index 1fcf61f0c0..08d232f60d 100644 --- a/tests/performance_tests/CMakeLists.txt +++ b/tests/performance_tests/CMakeLists.txt @@ -16,5 +16,7 @@ add_test(NAME performance_test_basic_ex_new_acct_trx_spec COMMAND tests/performa add_test(NAME log_reader_tests COMMAND tests/performance_tests/log_reader_tests.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME validate_nodeos_plugin_args COMMAND tests/performance_tests/validate_nodeos_plugin_args.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST performance_test_basic PROPERTY LABELS nonparallelizable_tests) +set_property(TEST performance_test_basic_ex_transfer_trx_spec PROPERTY LABELS nonparallelizable_tests) +set_property(TEST performance_test_basic_ex_new_acct_trx_spec PROPERTY LABELS nonparallelizable_tests) add_subdirectory( NodeosPluginArgs ) From 310e6b8de7272d2ce3dc9174a4f356ebf6857a62 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Thu, 9 Feb 2023 10:52:39 -0600 Subject: [PATCH 11/24] Make actions data and auths const. --- tests/trx_generator/trx_generator_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/trx_generator/trx_generator_tests.cpp b/tests/trx_generator/trx_generator_tests.cpp index 99d5abdafb..509d603383 100644 --- a/tests/trx_generator/trx_generator_tests.cpp +++ b/tests/trx_generator/trx_generator_tests.cpp @@ -329,8 +329,8 @@ BOOST_AUTO_TEST_CASE(trx_generator_constructor) std::string chain_id = "999"; const std::string abi_file = "../../unittests/contracts/eosio.token/eosio.token.abi"; std::string contract_owner_account = "eosio"; - std::string actions_data = "[{\"actionAuthAcct\": \"testacct1\",\"actionName\": \"transfer\",\"authorization\": {\"actor\": \"testacct1\",\"permission\": \"active\"},\"actionData\": {\"from\": \"testacct1\",\"to\": \"testacct2\",\"quantity\": \"0.0001 CUR\",\"memo\": \"transaction specified\"}}]"; - std::string action_auths = "{\"testacct1\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\",\"testacct2\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\",\"eosio\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\"}"; + const std::string actions_data = "[{\"actionAuthAcct\": \"testacct1\",\"actionName\": \"transfer\",\"authorization\": {\"actor\": \"testacct1\",\"permission\": \"active\"},\"actionData\": {\"from\": \"testacct1\",\"to\": \"testacct2\",\"quantity\": \"0.0001 CUR\",\"memo\": \"transaction specified\"}}]"; + const std::string action_auths = "{\"testacct1\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\",\"testacct2\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\",\"eosio\":\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\"}"; fc::microseconds trx_expr = fc::seconds(3600); std::string log_dir = "."; std::string lib_id_str = "00000062989f69fd251df3e0b274c3364ffc2f4fce73de3f1c7b5e11a4c92f21"; From 299c9e9ee0ed1fe28e1d24455cb724c27eccb8ce Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Thu, 9 Feb 2023 10:53:00 -0600 Subject: [PATCH 12/24] Fix Cluster's arguments for TransactionGeneratorsLauncher. --- tests/TestHarness/Cluster.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/TestHarness/Cluster.py b/tests/TestHarness/Cluster.py index 81976d24b6..c0d66391d6 100644 --- a/tests/TestHarness/Cluster.py +++ b/tests/TestHarness/Cluster.py @@ -1763,7 +1763,7 @@ def stripValues(lowestMaxes,greaterThan): def launchTrxGenerators(self, contractOwnerAcctName: str, acctNamesList: list, acctPrivKeysList: list, nodeId: int=0, tpsPerGenerator: int=10, numGenerators: int=1, durationSec: int=60, - waitToComplete:bool=False, abiFile=None, actionName=None, actionAuthAcct=None, actionAuthPrivKey=None, actionData=None): + waitToComplete:bool=False, abiFile=None, actionsData=None, actionsAuths=None): Utils.Print("Configure txn generators") node=self.getNode(nodeId) p2pListenPort = self.getNodeP2pPort(nodeId) @@ -1780,7 +1780,7 @@ def launchTrxGenerators(self, contractOwnerAcctName: str, acctNamesList: list, a self.trxGenLauncher = TransactionGeneratorsLauncher(chainId=chainId, lastIrreversibleBlockId=lib_id, contractOwnerAccount=contractOwnerAcctName, accts=','.join(map(str, acctNamesList)), privateKeys=','.join(map(str, acctPrivKeysList)), trxGenDurationSec=durationSec, logDir=Utils.DataDir, - abiFile=abiFile, actionName=actionName, actionAuthAcct=actionAuthAcct, actionAuthPrivKey=actionAuthPrivKey, actionData=actionData, + abiFile=abiFile, actionsData=actionsData, actionsAuths=actionsAuths, peerEndpoint=self.host, port=p2pListenPort, tpsTrxGensConfig=tpsTrxGensConfig) Utils.Print("Launch txn generators and start generating/sending transactions") From f6f56e5c5d2e2d174f4a544a6217c6fdc2596f57 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Thu, 9 Feb 2023 14:31:13 -0600 Subject: [PATCH 13/24] Fix logic in log_transactions. Now that default contract is loaded to eosio again, it teased out a logic error here. Should be 'or' not 'and'. --- tests/performance_tests/performance_test_basic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/performance_tests/performance_test_basic.py b/tests/performance_tests/performance_test_basic.py index da19eceeea..3cf9407837 100755 --- a/tests/performance_tests/performance_test_basic.py +++ b/tests/performance_tests/performance_test_basic.py @@ -98,7 +98,7 @@ class SpecifiedContract: def log_transactions(self, trxDataFile, block): for trx in block['payload']['transactions']: for actions in trx['actions']: - if actions['account'] != 'eosio' and actions['action'] != 'onblock': + if actions['account'] != 'eosio' or actions['action'] != 'onblock': trxDataFile.write(f"{trx['id']},{trx['block_num']},{trx['block_time']},{trx['cpu_usage_us']},{trx['net_usage_words']},{trx['actions']}\n") def __post_init__(self): From 0dc7b3ae582278575be3c2b73c74705ff486de91 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Fri, 10 Feb 2023 13:04:45 -0600 Subject: [PATCH 14/24] Rename id to generator_id to be more specific. --- tests/trx_generator/trx_generator.cpp | 14 +++++++------- tests/trx_generator/trx_generator.hpp | 14 +++++++------- tests/trx_generator/trx_generator_tests.cpp | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index f5ec6f95bd..863f0c6f03 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -93,14 +93,14 @@ namespace eosio::testing { return actions_pairs_vector; } - trx_generator_base::trx_generator_base(uint16_t id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, + trx_generator_base::trx_generator_base(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) - : _provider(peer_endpoint, port), _id(id), _chain_id(chain_id_in), _contract_owner_account(contract_owner_account), _trx_expiration(trx_expr), + : _provider(peer_endpoint, port), _generator_id(generator_id), _chain_id(chain_id_in), _contract_owner_account(contract_owner_account), _trx_expiration(trx_expr), _last_irr_block_id(fc::variant(lib_id_str).as()), _log_dir(log_dir), _stop_on_trx_failed(stop_on_trx_failed) {} - transfer_trx_generator::transfer_trx_generator(uint16_t id, std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, + transfer_trx_generator::transfer_trx_generator(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, fc::microseconds trx_expr, const std::vector& private_keys_str_vector, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) - : trx_generator_base(id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), _accts(accts), _private_keys_str_vector(private_keys_str_vector) {} + : trx_generator_base(generator_id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), _accts(accts), _private_keys_str_vector(private_keys_str_vector) {} vector transfer_trx_generator::get_accounts(const vector& account_str_vector) { vector acct_name_list; @@ -221,11 +221,11 @@ namespace eosio::testing { trx_generator_base::update_resign_transaction(trx, priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id); } - trx_generator::trx_generator(uint16_t id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, + trx_generator::trx_generator(uint16_t generator_id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, const std::string& actions_data_json_file_or_str, const std::string& actions_auths_json_file_or_str, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) - : trx_generator_base(id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), + : trx_generator_base(generator_id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), _abi_data_file_path(abi_data_file), _actions_data_json_file_or_str(actions_data_json_file_or_str), _actions_auths_json_file_or_str(actions_auths_json_file_or_str), _acct_name_generator() {} @@ -293,7 +293,7 @@ namespace eosio::testing { ilog("acct_gen_fields entry: ${value}", ("value", e)); } ilog("Priming name generator for trx generator prefix."); - _acct_name_generator.setPrefix(_id); + _acct_name_generator.setPrefix(_generator_id); } ilog("Setting up transaction signer."); diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index 6082ac5d24..66ce82005f 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -53,14 +53,14 @@ namespace eosio::testing { increment(1); } - void setPrefix(int id) { - if (id > MAX_PREFEX) { + void setPrefix(int generator_id) { + if (generator_id > MAX_PREFEX) { elog("Account Name Generator Prefix above allowable ${max}", ("max", MAX_PREFEX)); return; } _name_index_vec[0] = 0; _name_index_vec[1] = 0; - for(int i = 0; i < id; i++) { + for(int i = 0; i < generator_id; i++) { incrementPrefix(); } }; @@ -77,7 +77,7 @@ namespace eosio::testing { struct trx_generator_base { p2p_trx_provider _provider; - uint16_t _id; + uint16_t _generator_id; eosio::chain::chain_id_type _chain_id; eosio::chain::name _contract_owner_account; fc::microseconds _trx_expiration; @@ -94,7 +94,7 @@ namespace eosio::testing { bool _stop_on_trx_failed = true; - trx_generator_base(uint16_t id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, + trx_generator_base(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, @@ -121,7 +121,7 @@ namespace eosio::testing { const std::vector _accts; std::vector _private_keys_str_vector; - transfer_trx_generator(uint16_t id, std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, + transfer_trx_generator(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, fc::microseconds trx_expr, const std::vector& private_keys_str_vector, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); @@ -150,7 +150,7 @@ namespace eosio::testing { const fc::microseconds abi_serializer_max_time = fc::seconds(10); // No risk to client side serialization taking a long time - trx_generator(uint16_t id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, + trx_generator(uint16_t generator_id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, const std::string& actions_data_json_file_or_str, const std::string& actions_auths_json_file_or_str, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); diff --git a/tests/trx_generator/trx_generator_tests.cpp b/tests/trx_generator/trx_generator_tests.cpp index 509d603383..c92fb21f55 100644 --- a/tests/trx_generator/trx_generator_tests.cpp +++ b/tests/trx_generator/trx_generator_tests.cpp @@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(tps_cant_keep_up_monitored) BOOST_AUTO_TEST_CASE(trx_generator_constructor) { - uint16_t id = 1; + uint16_t generator_id = 1; std::string chain_id = "999"; const std::string abi_file = "../../unittests/contracts/eosio.token/eosio.token.abi"; std::string contract_owner_account = "eosio"; @@ -338,7 +338,7 @@ BOOST_AUTO_TEST_CASE(trx_generator_constructor) std::string peer_endpoint = "127.0.0.1"; unsigned short port = 9876; - auto generator = trx_generator(id, chain_id, abi_file, contract_owner_account, + auto generator = trx_generator(generator_id, chain_id, abi_file, contract_owner_account, actions_data, action_auths, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port); } From 1ad0888997851e98d132d614a55513117915d33f Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Fri, 10 Feb 2023 13:19:45 -0600 Subject: [PATCH 15/24] Address some peer review comments. --- tests/trx_generator/trx_generator.cpp | 24 ++++++++++++------------ tests/trx_generator/trx_generator.hpp | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index 863f0c6f03..bac91ce5be 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -17,7 +17,7 @@ namespace bpo=boost::program_options; namespace eosio::testing { - void trx_generator_base::set_transaction_headers(transaction& trx, const block_id_type& last_irr_block_id, const fc::microseconds expiration, uint32_t delay_sec) { + void trx_generator_base::set_transaction_headers(transaction& trx, const block_id_type& last_irr_block_id, const fc::microseconds& expiration, uint32_t delay_sec) { trx.expiration = fc::time_point::now() + expiration; trx.set_reference_block(last_irr_block_id); @@ -186,9 +186,9 @@ namespace eosio::testing { } } - void trx_generator::update_key_word_fields_in_sub_action(std::string key, fc::mutable_variant_object& action_mvo, std::string action_inner_key, const std::string key_word) { - auto mvo = action_mvo.find(action_inner_key); - if(mvo != action_mvo.end()) { + void trx_generator::update_key_word_fields_in_sub_action(const std::string& key, fc::mutable_variant_object& action_mvo, const std::string& action_inner_key, const std::string& key_word) { + auto itr = action_mvo.find(action_inner_key); + if(itr != action_mvo.end()) { fc::mutable_variant_object inner_mvo = fc::mutable_variant_object(action_mvo[action_inner_key].get_object()); if (inner_mvo.find(key) != inner_mvo.end()) { inner_mvo.set(key, key_word); @@ -197,13 +197,13 @@ namespace eosio::testing { } } - void trx_generator::update_key_word_fields_in_action(std::vector& acct_gen_fields, fc::mutable_variant_object& action_mvo, const std::string key_word) { - for(auto key: acct_gen_fields) { - auto mvo = action_mvo.find(key); - if(mvo != action_mvo.end()) { + void trx_generator::update_key_word_fields_in_action(std::vector& acct_gen_fields, fc::mutable_variant_object& action_mvo, const std::string& key_word) { + for(const auto& key: acct_gen_fields) { + auto itr = action_mvo.find(key); + if(itr != action_mvo.end()) { action_mvo.set(key, key_word); } else { - for(auto e: action_mvo) { + for(const auto& e: action_mvo) { if(e.value().get_type() == fc::variant::object_type) { update_key_word_fields_in_sub_action(key, action_mvo, e.key(), key_word); } @@ -215,7 +215,7 @@ namespace eosio::testing { void trx_generator::update_resign_transaction(signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { trx.actions.clear(); update_actions(); - for(auto act: _actions) { + for(const auto& act: _actions) { trx.actions.push_back(act); } trx_generator_base::update_resign_transaction(trx, priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id); @@ -242,7 +242,7 @@ namespace eosio::testing { } } - for (auto action_mvo : _unpacked_actions) { + for (const auto& action_mvo : _unpacked_actions) { chain::name action_name = chain::name(action_mvo["actionName"].as_string()); chain::name action_auth_acct = chain::name(action_mvo["actionAuthAcct"].as_string()); bytes packed_action_data; @@ -289,7 +289,7 @@ namespace eosio::testing { if(!_acct_gen_fields.empty()) { ilog("Located the following account names that need to be generated and populted in each transaction:"); - for(auto e: _acct_gen_fields) { + for(const auto& e: _acct_gen_fields) { ilog("acct_gen_fields entry: ${value}", ("value", e)); } ilog("Priming name generator for trx generator prefix."); diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index 66ce82005f..2f7c089a1e 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -77,7 +77,7 @@ namespace eosio::testing { struct trx_generator_base { p2p_trx_provider _provider; - uint16_t _generator_id; + uint16_t _generator_id = 0; eosio::chain::chain_id_type _chain_id; eosio::chain::name _contract_owner_account; fc::microseconds _trx_expiration; @@ -104,7 +104,7 @@ namespace eosio::testing { uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); - void set_transaction_headers(eosio::chain::transaction& trx, const eosio::chain::block_id_type& last_irr_block_id, const fc::microseconds expiration, uint32_t delay_sec = 0); + void set_transaction_headers(eosio::chain::transaction& trx, const eosio::chain::block_id_type& last_irr_block_id, const fc::microseconds& expiration, uint32_t delay_sec = 0); signed_transaction_w_signer create_trx_w_actions_and_signer(std::vector act, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); @@ -157,8 +157,8 @@ namespace eosio::testing { void locate_key_words_in_action_mvo(std::vector& acct_gen_fields_out, fc::mutable_variant_object& action_mvo, const std::string& key_word); void locate_key_words_in_action_array(std::map>& acct_gen_fields_out, fc::variants& action_array, const std::string& key_word); - void update_key_word_fields_in_sub_action(std::string key, fc::mutable_variant_object& action_mvo, std::string action_inner_key, const std::string key_word); - void update_key_word_fields_in_action(std::vector& acct_gen_fields, fc::mutable_variant_object& action_mvo, const std::string key_word); + void update_key_word_fields_in_sub_action(const std::string& key, fc::mutable_variant_object& action_mvo, const std::string& action_inner_key, const std::string& key_word); + void update_key_word_fields_in_action(std::vector& acct_gen_fields, fc::mutable_variant_object& action_mvo, const std::string& key_word); void update_actions(); virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, From 24e376cf87f5ee0902567685644be2d9d836a34d Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Fri, 10 Feb 2023 13:51:14 -0600 Subject: [PATCH 16/24] Additional peer review comments being addressed. --- tests/trx_generator/main.cpp | 12 ++++++------ tests/trx_generator/trx_generator.cpp | 2 +- tests/trx_generator/trx_generator.hpp | 22 +++++++++++----------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/trx_generator/main.cpp b/tests/trx_generator/main.cpp index 686b937493..a4a797aaf0 100644 --- a/tests/trx_generator/main.cpp +++ b/tests/trx_generator/main.cpp @@ -24,8 +24,8 @@ enum return_codes { }; int main(int argc, char** argv) { - const int64_t TRX_EXPIRATION_MAX = 3600; - const uint16_t GENERATOR_ID_MAX = 960; + const int64_t trx_expiration_max = 3600; + const uint16_t generator_id_max = 960; variables_map vmap; options_description cli("Transaction Generator command line options."); uint16_t gen_id; @@ -149,16 +149,16 @@ int main(int argc, char** argv) { } if(vmap.count("generation-id")) { - if(gen_id > GENERATOR_ID_MAX) { - ilog("Initialization error: Exceeded max value for generator id. Value must be less than ${max}.", ("max", GENERATOR_ID_MAX)); + if(gen_id > generator_id_max) { + ilog("Initialization error: Exceeded max value for generator id. Value must be less than ${max}.", ("max", generator_id_max)); cli.print(std::cerr); return INITIALIZE_FAIL; } } if(vmap.count("trx-expiration")) { - if(trx_expr > TRX_EXPIRATION_MAX) { - ilog("Initialization error: Exceeded max value for transaction expiration. Value must be less than ${max}.", ("max", TRX_EXPIRATION_MAX)); + if(trx_expr > trx_expiration_max) { + ilog("Initialization error: Exceeded max value for transaction expiration. Value must be less than ${max}.", ("max", trx_expiration_max)); cli.print(std::cerr); return INITIALIZE_FAIL; } diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index bac91ce5be..07c14a3721 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -234,7 +234,7 @@ namespace eosio::testing { _actions.clear(); if (!_acct_gen_fields.empty()) { - std::string generated_account_name = _acct_name_generator.calcName(); + std::string generated_account_name = _acct_name_generator.calc_name(); _acct_name_generator.increment(); for (auto const& [key, val] : _acct_gen_fields) { diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index 2f7c089a1e..d4af803518 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -20,7 +20,7 @@ namespace eosio::testing { struct action_pair_w_keys { action_pair_w_keys(eosio::chain::action first_action, eosio::chain::action second_action, fc::crypto::private_key first_act_signer, fc::crypto::private_key second_act_signer) - : _first_act(first_action), _second_act(second_action), _first_act_priv_key(first_act_signer), _second_act_priv_key(second_act_signer) {} + : _first_act(std::move(first_action)), _second_act(std::move(second_action)), _first_act_priv_key(std::move(first_act_signer)), _second_act_priv_key(std::move(second_act_signer)) {} eosio::chain::action _first_act; eosio::chain::action _second_act; @@ -29,17 +29,17 @@ namespace eosio::testing { }; struct account_name_generator { - account_name_generator() : _name_index_vec(ACCT_NAME_LEN, 0) {} + account_name_generator() : _name_index_vec(acct_name_len, 0) {} - const char* CHARMAP = "12345abcdefghijklmnopqrstuvwxyz"; - const int ACCT_NAME_CHAR_CNT = 31; - const int ACCT_NAME_LEN = 12; - const int MAX_PREFEX = 960; + static constexpr char char_map[] = "12345abcdefghijklmnopqrstuvwxyz"; + static constexpr int acct_name_char_cnt = sizeof(char_map) - 1; + const int acct_name_len = 12; + const int prefix_max = 960; std::vector _name_index_vec; void increment(int index) { _name_index_vec[index]++; - if(_name_index_vec[index] >= ACCT_NAME_CHAR_CNT) { + if(_name_index_vec[index] >= acct_name_char_cnt) { _name_index_vec[index] = 0; increment(index - 1); } @@ -54,8 +54,8 @@ namespace eosio::testing { } void setPrefix(int generator_id) { - if (generator_id > MAX_PREFEX) { - elog("Account Name Generator Prefix above allowable ${max}", ("max", MAX_PREFEX)); + if (generator_id > prefix_max) { + elog("Account Name Generator Prefix above allowable ${max}", ("max", prefix_max)); return; } _name_index_vec[0] = 0; @@ -65,11 +65,11 @@ namespace eosio::testing { } }; - std::string calcName() { + std::string calc_name() { std::string name; name.reserve(12); for(auto i: _name_index_vec) { - name += CHARMAP[i]; + name += char_map[i]; } return name; } From 12868230fbe1663b95511a8952846ac99a3c74e2 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Fri, 10 Feb 2023 15:29:34 -0600 Subject: [PATCH 17/24] Address peer review comment. Virtual destructor added. --- tests/trx_generator/trx_generator.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index d4af803518..0200be603f 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -97,6 +97,8 @@ namespace eosio::testing { trx_generator_base(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); + virtual ~trx_generator_base() = default; + virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); From 56863d0f69e19f8552330164de748661e2769297 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Fri, 10 Feb 2023 15:44:15 -0600 Subject: [PATCH 18/24] Address additional peer review comments. --- tests/trx_generator/trx_generator.cpp | 59 ++++++++++++--------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index 07c14a3721..8e4652f7a2 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -44,14 +44,9 @@ namespace eosio::testing { std::vector trxs; trxs.reserve(2 * action_pairs_vector.size()); - std::vector act_vec; - for(action_pair_w_keys ap: action_pairs_vector) { - act_vec.push_back(ap._first_act); - trxs.emplace_back(create_trx_w_actions_and_signer(act_vec, ap._first_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); - act_vec.clear(); - act_vec.push_back(ap._second_act); - trxs.emplace_back(create_trx_w_actions_and_signer(act_vec, ap._second_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); - act_vec.clear(); + for (action_pair_w_keys ap: action_pairs_vector) { + trxs.emplace_back(create_trx_w_actions_and_signer({ap._first_act}, ap._first_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); + trxs.emplace_back(create_trx_w_actions_and_signer({ap._second_act}, ap._second_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); } return trxs; @@ -77,8 +72,8 @@ namespace eosio::testing { vector transfer_trx_generator::create_initial_transfer_actions(const std::string& salt, const uint64_t& period, const name& contract_owner_account, const vector& accounts, const vector& priv_keys) { vector actions_pairs_vector; - for(size_t i = 0; i < accounts.size(); ++i) { - for(size_t j = i + 1; j < accounts.size(); ++j) { + for (size_t i = 0; i < accounts.size(); ++i) { + for (size_t j = i + 1; j < accounts.size(); ++j) { //create the actions here ilog("create_initial_transfer_actions: creating transfer from ${acctA} to ${acctB}", ("acctA", accounts.at(i))("acctB", accounts.at(j))); action act_a_to_b = make_transfer_action(contract_owner_account, accounts.at(i), accounts.at(j), asset::from_string("1.0000 CUR"), salt); @@ -104,7 +99,7 @@ namespace eosio::testing { vector transfer_trx_generator::get_accounts(const vector& account_str_vector) { vector acct_name_list; - for(string account_name: account_str_vector) { + for (string account_name: account_str_vector) { ilog("get_account about to try to create name for ${acct}", ("acct", account_name)); acct_name_list.push_back(eosio::chain::name(account_name)); } @@ -113,7 +108,7 @@ namespace eosio::testing { vector transfer_trx_generator::get_private_keys(const vector& priv_key_str_vector) { vector key_list; - for(const string& private_key: priv_key_str_vector) { + for (const string& private_key: priv_key_str_vector) { ilog("get_private_keys about to try to create private_key for ${key} : gen key ${newKey}", ("key", private_key)("newKey", fc::crypto::private_key(private_key))); key_list.push_back(fc::crypto::private_key(private_key)); } @@ -169,10 +164,10 @@ namespace eosio::testing { } void trx_generator::locate_key_words_in_action_mvo(std::vector& acct_gen_fields_out, fc::mutable_variant_object& action_mvo, const std::string& key_word) { - for(const mutable_variant_object::entry& e: action_mvo) { - if(e.value().get_type() == fc::variant::string_type && e.value() == key_word) { + for (const mutable_variant_object::entry& e: action_mvo) { + if (e.value().get_type() == fc::variant::string_type && e.value() == key_word) { acct_gen_fields_out.push_back(e.key()); - } else if(e.value().get_type() == fc::variant::object_type) { + } else if (e.value().get_type() == fc::variant::object_type) { auto inner_mvo = fc::mutable_variant_object(e.value()); locate_key_words_in_action_mvo(acct_gen_fields_out, inner_mvo, key_word); } @@ -180,31 +175,29 @@ namespace eosio::testing { } void trx_generator::locate_key_words_in_action_array(std::map>& acct_gen_fields_out, fc::variants& action_array, const std::string& key_word) { - for(size_t i = 0; i < action_array.size(); ++i) { + for (size_t i = 0; i < action_array.size(); ++i) { auto action_mvo = fc::mutable_variant_object(action_array[i]); locate_key_words_in_action_mvo(acct_gen_fields_out[i], action_mvo, key_word); } } void trx_generator::update_key_word_fields_in_sub_action(const std::string& key, fc::mutable_variant_object& action_mvo, const std::string& action_inner_key, const std::string& key_word) { - auto itr = action_mvo.find(action_inner_key); - if(itr != action_mvo.end()) { - fc::mutable_variant_object inner_mvo = fc::mutable_variant_object(action_mvo[action_inner_key].get_object()); - if (inner_mvo.find(key) != inner_mvo.end()) { + if (action_mvo.find(action_inner_key) != action_mvo.end()) { + if (action_mvo[action_inner_key].get_object().find(key) != action_mvo[action_inner_key].get_object().end()) { + fc::mutable_variant_object inner_mvo = fc::mutable_variant_object(action_mvo[action_inner_key].get_object()); inner_mvo.set(key, key_word); - action_mvo.set(action_inner_key, inner_mvo); + action_mvo.set(action_inner_key, std::move(inner_mvo)); } } } void trx_generator::update_key_word_fields_in_action(std::vector& acct_gen_fields, fc::mutable_variant_object& action_mvo, const std::string& key_word) { - for(const auto& key: acct_gen_fields) { - auto itr = action_mvo.find(key); - if(itr != action_mvo.end()) { + for (const auto& key: acct_gen_fields) { + if (action_mvo.find(key) != action_mvo.end()) { action_mvo.set(key, key_word); } else { - for(const auto& e: action_mvo) { - if(e.value().get_type() == fc::variant::object_type) { + for (const auto& e: action_mvo) { + if (e.value().get_type() == fc::variant::object_type) { update_key_word_fields_in_sub_action(key, action_mvo, e.key(), key_word); } } @@ -215,7 +208,7 @@ namespace eosio::testing { void trx_generator::update_resign_transaction(signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { trx.actions.clear(); update_actions(); - for(const auto& act: _actions) { + for (const auto& act: _actions) { trx.actions.push_back(act); } trx_generator_base::update_resign_transaction(trx, priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id); @@ -261,7 +254,7 @@ namespace eosio::testing { act.authorization = vector{{auth_actor, auth_perm}}; act.data = std::move(packed_action_data); - _actions.push_back(act); + _actions.emplace_back(std::move(act)); } } @@ -283,13 +276,13 @@ namespace eosio::testing { auto action_array = unpacked_actions_data_json.get_array(); for (size_t i =0; i < action_array.size(); ++i ) { - _unpacked_actions.push_back(fc::mutable_variant_object(action_array[i])); + _unpacked_actions.emplace_back(fc::mutable_variant_object(action_array[i])); } locate_key_words_in_action_array(_acct_gen_fields, action_array, gen_acct_name_per_trx); - if(!_acct_gen_fields.empty()) { - ilog("Located the following account names that need to be generated and populted in each transaction:"); - for(const auto& e: _acct_gen_fields) { + if (!_acct_gen_fields.empty()) { + ilog("Located the following account names that need to be generated and populated in each transaction:"); + for (const auto& e: _acct_gen_fields) { ilog("acct_gen_fields entry: ${value}", ("value", e)); } ilog("Priming name generator for trx generator prefix."); @@ -374,7 +367,7 @@ namespace eosio::testing { void trx_generator_base::stop_generation() { ilog("Stopping transaction generation"); - if(_txcount) { + if (_txcount) { ilog("${d} transactions executed, ${t}us / transaction", ("d", _txcount)("t", _total_us / (double) _txcount)); _txcount = _total_us = 0; } From dd4fb9143fe47456bd90bb3df02e6dc98403e528 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Mon, 13 Feb 2023 11:20:10 -0600 Subject: [PATCH 19/24] Add commentary and unit tests for account name generator. --- tests/trx_generator/trx_generator.hpp | 20 +++ tests/trx_generator/trx_generator_tests.cpp | 151 ++++++++++++++++---- 2 files changed, 147 insertions(+), 24 deletions(-) diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index 0200be603f..dc09c03b95 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -29,11 +29,31 @@ namespace eosio::testing { }; struct account_name_generator { + // This account_name_generator provides the means to generate 12 character account names where the left-most 2 characters are reserved + // to identify the trx generator. The right 10 characters are determined based on incrementing through the allowed char_map one at a + // before incrementing the next character to the left. + // The _name_index_vec tracks the index into the char_map for each of the 12 characters of the name. + // For example: + // Transaction Generators would create new account names as follows: + // generator ID: 5 generator ID: 41 + // 1a1111111111 2f1111111111 + // 1a1111111112 2f1111111112 + // 1a1111111113 2f1111111113 + // 1a1111111114 2f1111111114 + // 1a1111111115 2f1111111115 + // ... ... + // 1a111111111z 2f111111111z + // 1a1111111121 2f1111111121 + // 1a1111111122 2f1111111122 account_name_generator() : _name_index_vec(acct_name_len, 0) {} static constexpr char char_map[] = "12345abcdefghijklmnopqrstuvwxyz"; static constexpr int acct_name_char_cnt = sizeof(char_map) - 1; const int acct_name_len = 12; + + // Reserving the first 2 characters in the 12 char account name to identify the transaction generator sending the trx to create the new account. + // So 31 ^ 2 gives 961 (so w/0 based index, 960) since more than 31 generators may be desired, but > 961 is likely unwarranted. + // This provides an easy way to deduplicate the names being generated by the parallel trx generators. const int prefix_max = 960; std::vector _name_index_vec; diff --git a/tests/trx_generator/trx_generator_tests.cpp b/tests/trx_generator/trx_generator_tests.cpp index c92fb21f55..c5bb3832fd 100644 --- a/tests/trx_generator/trx_generator_tests.cpp +++ b/tests/trx_generator/trx_generator_tests.cpp @@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE(tps_short_run_low_tps) fc::time_point start = fc::time_point::now(); t1.run(); fc::time_point end = fc::time_point::now(); - fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch() ; + fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch(); BOOST_REQUIRE_EQUAL(generator->_calls.size(), expected_trxs); BOOST_REQUIRE_GT(runtime_us.count(), minimum_runtime_us); @@ -87,17 +87,16 @@ BOOST_AUTO_TEST_CASE(tps_short_run_high_tps) fc::time_point start = fc::time_point::now(); t1.run(); fc::time_point end = fc::time_point::now(); - fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch() ; + fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch(); BOOST_REQUIRE_EQUAL(generator->_calls.size(), expected_trxs); BOOST_REQUIRE_GT(runtime_us.count(), minimum_runtime_us); if (runtime_us.count() > maximum_runtime_us) { ilog("couldn't sustain transaction rate. ran ${rt}us vs expected max ${mx}us", - ("rt", runtime_us.count())("mx", maximum_runtime_us ) ); + ("rt", runtime_us.count())("mx", maximum_runtime_us)); BOOST_REQUIRE_LT(monitor->_calls.back().time_to_next_trx_us, 0); } - } BOOST_AUTO_TEST_CASE(tps_short_run_med_tps_med_delay) @@ -121,14 +120,14 @@ BOOST_AUTO_TEST_CASE(tps_short_run_med_tps_med_delay) fc::time_point start = fc::time_point::now(); t1.run(); fc::time_point end = fc::time_point::now(); - fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch() ; + fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch(); BOOST_REQUIRE_EQUAL(generator->_calls.size(), expected_trxs); BOOST_REQUIRE_GT(runtime_us.count(), minimum_runtime_us); if (runtime_us.count() > maximum_runtime_us) { ilog("couldn't sustain transaction rate. ran ${rt}us vs expected max ${mx}us", - ("rt", runtime_us.count())("mx", maximum_runtime_us ) ); + ("rt", runtime_us.count())("mx", maximum_runtime_us)); BOOST_REQUIRE_LT(monitor->_calls.back().time_to_next_trx_us, 0); } } @@ -154,17 +153,18 @@ BOOST_AUTO_TEST_CASE(tps_med_run_med_tps_med_delay) fc::time_point start = fc::time_point::now(); t1.run(); fc::time_point end = fc::time_point::now(); - fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch() ; + fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch(); BOOST_REQUIRE_EQUAL(generator->_calls.size(), expected_trxs); BOOST_REQUIRE_GT(runtime_us.count(), minimum_runtime_us); if (runtime_us.count() > maximum_runtime_us) { ilog("couldn't sustain transaction rate. ran ${rt}us vs expected max ${mx}us", - ("rt", runtime_us.count())("mx", maximum_runtime_us ) ); + ("rt", runtime_us.count())("mx", maximum_runtime_us)); BOOST_REQUIRE_LT(monitor->_calls.back().time_to_next_trx_us, 0); } } + BOOST_AUTO_TEST_CASE(tps_cant_keep_up) { constexpr uint32_t test_duration_s = 5; @@ -186,17 +186,18 @@ BOOST_AUTO_TEST_CASE(tps_cant_keep_up) fc::time_point start = fc::time_point::now(); t1.run(); fc::time_point end = fc::time_point::now(); - fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch() ; + fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch(); BOOST_REQUIRE_EQUAL(generator->_calls.size(), expected_trxs); BOOST_REQUIRE_GT(runtime_us.count(), minimum_runtime_us); if (runtime_us.count() > maximum_runtime_us) { ilog("couldn't sustain transaction rate. ran ${rt}us vs expected max ${mx}us", - ("rt", runtime_us.count())("mx", maximum_runtime_us ) ); + ("rt", runtime_us.count())("mx", maximum_runtime_us)); BOOST_REQUIRE_LT(monitor->_calls.back().time_to_next_trx_us, 0); } } + BOOST_AUTO_TEST_CASE(tps_med_run_med_tps_30us_delay) { constexpr uint32_t test_duration_s = 15; @@ -218,17 +219,16 @@ BOOST_AUTO_TEST_CASE(tps_med_run_med_tps_30us_delay) fc::time_point start = fc::time_point::now(); t1.run(); fc::time_point end = fc::time_point::now(); - fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch() ; + fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch(); BOOST_REQUIRE_EQUAL(generator->_calls.size(), expected_trxs); BOOST_REQUIRE_GT(runtime_us.count(), minimum_runtime_us); if (runtime_us.count() > maximum_runtime_us) { ilog("couldn't sustain transaction rate. ran ${rt}us vs expected max ${mx}us", - ("rt", runtime_us.count())("mx", maximum_runtime_us ) ); + ("rt", runtime_us.count())("mx", maximum_runtime_us)); BOOST_REQUIRE_LT(monitor->_calls.back().time_to_next_trx_us, 0); } - } BOOST_AUTO_TEST_CASE(tps_performance_monitor_during_spin_up) @@ -241,11 +241,11 @@ BOOST_AUTO_TEST_CASE(tps_performance_monitor_during_spin_up) stats.trxs_sent = 90; // behind, but still within spin up window - stats.last_run = fc::time_point{fc::microseconds{100000}}; + stats.last_run = fc::time_point{fc::microseconds{100000}}; BOOST_REQUIRE(monitor.monitor_test(stats)); // violation, but still within spin up window - stats.last_run = fc::time_point{fc::microseconds{1100000}}; + stats.last_run = fc::time_point{fc::microseconds{1100000}}; BOOST_REQUIRE(monitor.monitor_test(stats)); } @@ -259,11 +259,11 @@ BOOST_AUTO_TEST_CASE(tps_performance_monitor_outside_spin_up) stats.trxs_sent = 90; // behind, out of spin up window - stats.last_run = fc::time_point{fc::microseconds{5500000}}; + stats.last_run = fc::time_point{fc::microseconds{5500000}}; BOOST_REQUIRE(monitor.monitor_test(stats)); // violation, out of spin up window - stats.last_run = fc::time_point{fc::microseconds{6600000}}; + stats.last_run = fc::time_point{fc::microseconds{6600000}}; BOOST_REQUIRE(!monitor.monitor_test(stats)); } @@ -277,25 +277,25 @@ BOOST_AUTO_TEST_CASE(tps_performance_monitor_outside_spin_up_within_limit) stats.trxs_sent = 90; // outside of limit, out of spin up window - stats.last_run = fc::time_point{fc::microseconds{5500000}}; + stats.last_run = fc::time_point{fc::microseconds{5500000}}; BOOST_REQUIRE(monitor.monitor_test(stats)); // outside of limit, less than max violation duration - stats.last_run = fc::time_point{fc::microseconds{6000000}}; + stats.last_run = fc::time_point{fc::microseconds{6000000}}; BOOST_REQUIRE(monitor.monitor_test(stats)); stats.trxs_sent = 98; // behind, but within limit, out of spin up window - stats.last_run = fc::time_point{fc::microseconds{6600000}}; + stats.last_run = fc::time_point{fc::microseconds{6600000}}; BOOST_REQUIRE(monitor.monitor_test(stats)); stats.expected_sent = 150; // outside of limit again, out of spin up window - stats.last_run = fc::time_point{fc::microseconds{7000000}}; + stats.last_run = fc::time_point{fc::microseconds{7000000}}; BOOST_REQUIRE(monitor.monitor_test(stats)); // outside of limit for too long - stats.last_run = fc::time_point{fc::microseconds{8100000}}; + stats.last_run = fc::time_point{fc::microseconds{8100000}}; BOOST_REQUIRE(!monitor.monitor_test(stats)); } @@ -316,11 +316,10 @@ BOOST_AUTO_TEST_CASE(tps_cant_keep_up_monitored) fc::time_point start = fc::time_point::now(); t1.run(); fc::time_point end = fc::time_point::now(); - fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch() ; + fc::microseconds runtime_us = end.time_since_epoch() - start.time_since_epoch(); BOOST_REQUIRE_LT(runtime_us.count(), expected_runtime_us); BOOST_REQUIRE_LT(generator->_calls.size(), expected_trxs); - } BOOST_AUTO_TEST_CASE(trx_generator_constructor) @@ -343,4 +342,108 @@ BOOST_AUTO_TEST_CASE(trx_generator_constructor) trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port); } +BOOST_AUTO_TEST_CASE(account_name_generator_tests) +{ + auto acct_gen = account_name_generator(); + BOOST_REQUIRE_EQUAL(acct_gen.calc_name(), "111111111111"); + + //Test account name prefixes for differentiating between transaction generator instances + acct_gen.setPrefix(1); + BOOST_REQUIRE_EQUAL(acct_gen.calc_name(), "121111111111"); + acct_gen.setPrefix(30); + BOOST_REQUIRE_EQUAL(acct_gen.calc_name(), "1z1111111111"); + acct_gen.setPrefix(31); + BOOST_REQUIRE_EQUAL(acct_gen.calc_name(), "211111111111"); + acct_gen.setPrefix(960); + BOOST_REQUIRE_EQUAL(acct_gen.calc_name(), "zz1111111111"); + + //Test account name generation + std::vector expected = { + "zz1111111111", + "zz1111111112", + "zz1111111113", + "zz1111111114", + "zz1111111115", + "zz111111111a", + "zz111111111b", + "zz111111111c", + "zz111111111d", + "zz111111111e", + "zz111111111f", + "zz111111111g", + "zz111111111h", + "zz111111111i", + "zz111111111j", + "zz111111111k", + "zz111111111l", + "zz111111111m", + "zz111111111n", + "zz111111111o", + "zz111111111p", + "zz111111111q", + "zz111111111r", + "zz111111111s", + "zz111111111t", + "zz111111111u", + "zz111111111v", + "zz111111111w", + "zz111111111x", + "zz111111111y", + "zz111111111z", + "zz1111111121", + "zz1111111122"}; + for(size_t i = 0; i < expected.size(); ++i) { + BOOST_REQUIRE_EQUAL(acct_gen.calc_name(), expected.at(i)); + acct_gen.increment(); + } + + + //Test account name generation starting at 31 ^ 5 - 1 = 28629150 + std::vector expected2 = { + "1211111zzzzz", + "121111211111", + "121111211112", + "121111211113", + "121111211114", + "121111211115", + "12111121111a", + "12111121111b", + "12111121111c", + "12111121111d", + "12111121111e", + "12111121111f", + "12111121111g", + "12111121111h", + "12111121111i", + "12111121111j", + "12111121111k", + "12111121111l", + "12111121111m", + "12111121111n", + "12111121111o", + "12111121111p", + "12111121111q", + "12111121111r", + "12111121111s", + "12111121111t", + "12111121111u", + "12111121111v", + "12111121111w", + "12111121111x", + "12111121111y", + "12111121111z", + "121111211121", + "121111211122"}; + auto acct_gen2 = account_name_generator(); + acct_gen2.setPrefix(1); + int initialVal = 28629150; + for(int i = 0; i < initialVal; ++i) { + acct_gen2.increment(); + } + for(size_t i = 0; i < expected2.size(); ++i) { + BOOST_REQUIRE_EQUAL(acct_gen2.calc_name(), expected2.at(i)); + acct_gen2.increment(); + } +} + BOOST_AUTO_TEST_SUITE_END() From 77ba8eacfe643c9afa9da479e1a187ff75ff7f10 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Mon, 13 Feb 2023 11:42:34 -0600 Subject: [PATCH 20/24] Fix typo in argument. --- tests/trx_generator/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/trx_generator/main.cpp b/tests/trx_generator/main.cpp index a4a797aaf0..56951f0c51 100644 --- a/tests/trx_generator/main.cpp +++ b/tests/trx_generator/main.cpp @@ -148,7 +148,7 @@ int main(int argc, char** argv) { return INITIALIZE_FAIL; } - if(vmap.count("generation-id")) { + if(vmap.count("generator-id")) { if(gen_id > generator_id_max) { ilog("Initialization error: Exceeded max value for generator id. Value must be less than ${max}.", ("max", generator_id_max)); cli.print(std::cerr); From 43844554811e50d22db56d466e4805850a812da5 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Mon, 13 Feb 2023 12:03:59 -0600 Subject: [PATCH 21/24] Make private helper to protect usage. --- tests/trx_generator/trx_generator.hpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index dc09c03b95..fe5e74cd53 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -57,14 +57,6 @@ namespace eosio::testing { const int prefix_max = 960; std::vector _name_index_vec; - void increment(int index) { - _name_index_vec[index]++; - if(_name_index_vec[index] >= acct_name_char_cnt) { - _name_index_vec[index] = 0; - increment(index - 1); - } - } - void increment() { increment(_name_index_vec.size() - 1); } @@ -93,6 +85,15 @@ namespace eosio::testing { } return name; } + + private: + void increment(int index) { + _name_index_vec[index]++; + if(_name_index_vec[index] >= acct_name_char_cnt) { + _name_index_vec[index] = 0; + increment(index - 1); + } + } }; struct trx_generator_base { From 66fc7ddeecfe193f989c6a77eb758c267466eac0 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Mon, 13 Feb 2023 12:04:40 -0600 Subject: [PATCH 22/24] Correct the default priv keys to be valid key format. --- tests/performance_tests/performance_test_basic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/performance_tests/performance_test_basic.py b/tests/performance_tests/performance_test_basic.py index 3cf9407837..b2d1df31bd 100755 --- a/tests/performance_tests/performance_test_basic.py +++ b/tests/performance_tests/performance_test_basic.py @@ -71,9 +71,9 @@ def __str__(self) -> str: @dataclass class SpecifiedContract: accountName: str = "eosio" - ownerPrivateKey: str = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + ownerPrivateKey: str = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3" ownerPublicKey: str = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" - activePrivateKey: str = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + activePrivateKey: str = "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3" activePublicKey: str = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" contractDir: str = "unittests/contracts/eosio.system" wasmFile: str = "eosio.system.wasm" From 239fa1fdc80f7daf8ff619a0dd78d991b7cc40d1 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Mon, 13 Feb 2023 14:09:20 -0600 Subject: [PATCH 23/24] Addressing peer review comments. --- tests/trx_generator/trx_generator.cpp | 10 +++++----- tests/trx_generator/trx_generator.hpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index 8e4652f7a2..2663787095 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -88,13 +88,13 @@ namespace eosio::testing { return actions_pairs_vector; } - trx_generator_base::trx_generator_base(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, + trx_generator_base::trx_generator_base(uint16_t generator_id, const std::string& chain_id_in, const std::string& contract_owner_account, const fc::microseconds& trx_expr, const std::string& lib_id_str, const std::string& log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) : _provider(peer_endpoint, port), _generator_id(generator_id), _chain_id(chain_id_in), _contract_owner_account(contract_owner_account), _trx_expiration(trx_expr), _last_irr_block_id(fc::variant(lib_id_str).as()), _log_dir(log_dir), _stop_on_trx_failed(stop_on_trx_failed) {} - transfer_trx_generator::transfer_trx_generator(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, - fc::microseconds trx_expr, const std::vector& private_keys_str_vector, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) + transfer_trx_generator::transfer_trx_generator(uint16_t generator_id, const std::string& chain_id_in, const std::string& contract_owner_account, const std::vector& accts, + const fc::microseconds& trx_expr, const std::vector& private_keys_str_vector, const std::string& lib_id_str, const std::string& log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) : trx_generator_base(generator_id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), _accts(accts), _private_keys_str_vector(private_keys_str_vector) {} vector transfer_trx_generator::get_accounts(const vector& account_str_vector) { @@ -214,9 +214,9 @@ namespace eosio::testing { trx_generator_base::update_resign_transaction(trx, priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id); } - trx_generator::trx_generator(uint16_t generator_id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, + trx_generator::trx_generator(uint16_t generator_id, const std::string& chain_id_in, const std::string& abi_data_file, const std::string& contract_owner_account, const std::string& actions_data_json_file_or_str, const std::string& actions_auths_json_file_or_str, - fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, + const fc::microseconds& trx_expr, const std::string& lib_id_str, const std::string& log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint, unsigned short port) : trx_generator_base(generator_id, chain_id_in, contract_owner_account, trx_expr, lib_id_str, log_dir, stop_on_trx_failed, peer_endpoint, port), _abi_data_file_path(abi_data_file), diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index fe5e74cd53..c53b7ebdd3 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -115,7 +115,7 @@ namespace eosio::testing { bool _stop_on_trx_failed = true; - trx_generator_base(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, + trx_generator_base(uint16_t generator_id, const std::string& chain_id_in, const std::string& contract_owner_account, const fc::microseconds& trx_expr, const std::string& lib_id_str, const std::string& log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); virtual ~trx_generator_base() = default; @@ -144,8 +144,8 @@ namespace eosio::testing { const std::vector _accts; std::vector _private_keys_str_vector; - transfer_trx_generator(uint16_t generator_id, std::string chain_id_in, std::string contract_owner_account, const std::vector& accts, - fc::microseconds trx_expr, const std::vector& private_keys_str_vector, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, + transfer_trx_generator(uint16_t generator_id, const std::string& chain_id_in, const std::string& contract_owner_account, const std::vector& accts, + const fc::microseconds& trx_expr, const std::vector& private_keys_str_vector, const std::string& lib_id_str, const std::string& log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); std::vector get_accounts(const std::vector& account_str_vector); @@ -173,9 +173,9 @@ namespace eosio::testing { const fc::microseconds abi_serializer_max_time = fc::seconds(10); // No risk to client side serialization taking a long time - trx_generator(uint16_t generator_id, std::string chain_id_in, const std::string& abi_data_file, std::string contract_owner_account, + trx_generator(uint16_t generator_id, const std::string& chain_id_in, const std::string& abi_data_file, const std::string& contract_owner_account, const std::string& actions_data_json_file_or_str, const std::string& actions_auths_json_file_or_str, - fc::microseconds trx_expr, std::string lib_id_str, std::string log_dir, bool stop_on_trx_failed, + const fc::microseconds& trx_expr, const std::string& lib_id_str, const std::string& log_dir, bool stop_on_trx_failed, const std::string& peer_endpoint="127.0.0.1", unsigned short port=9876); void locate_key_words_in_action_mvo(std::vector& acct_gen_fields_out, fc::mutable_variant_object& action_mvo, const std::string& key_word); From f25de1b5a8e69588160184bdd4b1316433a776c2 Mon Sep 17 00:00:00 2001 From: Peter Oschwald Date: Mon, 13 Feb 2023 15:34:21 -0600 Subject: [PATCH 24/24] Addressing peer review comments. --- tests/trx_generator/main.cpp | 18 +++++++++--------- tests/trx_generator/trx_generator.cpp | 25 +++++++++++++------------ tests/trx_generator/trx_generator.hpp | 6 +++--- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/tests/trx_generator/main.cpp b/tests/trx_generator/main.cpp index 56951f0c51..20fea0444d 100644 --- a/tests/trx_generator/main.cpp +++ b/tests/trx_generator/main.cpp @@ -28,22 +28,22 @@ int main(int argc, char** argv) { const uint16_t generator_id_max = 960; variables_map vmap; options_description cli("Transaction Generator command line options."); - uint16_t gen_id; + uint16_t gen_id = 0; string chain_id_in; string contract_owner_acct; string accts; string p_keys; - int64_t trx_expr; - uint32_t gen_duration; - uint32_t target_tps; + int64_t trx_expr = 3600; + uint32_t gen_duration = 60; + uint32_t target_tps = 1; string lib_id_str; - int64_t spinup_time_us; - uint32_t max_lag_per; - int64_t max_lag_duration_us; + int64_t spinup_time_us = 1000000; + uint32_t max_lag_per = 5; + int64_t max_lag_duration_us = 1000000; string log_dir_in; bool stop_on_trx_failed; - std::string peer_endpoint; - unsigned short port; + std::string peer_endpoint = "127.0.0.1"; + unsigned short port = 9876; bool transaction_specified = false; std::string abi_file_path_in; diff --git a/tests/trx_generator/trx_generator.cpp b/tests/trx_generator/trx_generator.cpp index 2663787095..9df763505a 100644 --- a/tests/trx_generator/trx_generator.cpp +++ b/tests/trx_generator/trx_generator.cpp @@ -29,8 +29,8 @@ namespace eosio::testing { signed_transaction_w_signer trx_generator_base::create_trx_w_actions_and_signer(std::vector acts, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { signed_transaction trx; set_transaction_headers(trx, last_irr_block_id, trx_expiration); - for (auto act:acts) { - trx.actions.push_back(act); + for (auto& act : acts) { + trx.actions.emplace_back(std::move(act)); } trx.context_free_actions.emplace_back(action({}, config::null_account_name, name("nonce"), fc::raw::pack(std::to_string(nonce_prefix) + ":" + std::to_string(++nonce) + ":" + @@ -44,7 +44,7 @@ namespace eosio::testing { std::vector trxs; trxs.reserve(2 * action_pairs_vector.size()); - for (action_pair_w_keys ap: action_pairs_vector) { + for (const action_pair_w_keys& ap : action_pairs_vector) { trxs.emplace_back(create_trx_w_actions_and_signer({ap._first_act}, ap._first_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); trxs.emplace_back(create_trx_w_actions_and_signer({ap._second_act}, ap._second_act_priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id)); } @@ -52,7 +52,8 @@ namespace eosio::testing { return trxs; } - void trx_generator_base::update_resign_transaction(signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { + void trx_generator_base::update_resign_transaction(signed_transaction& trx, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, + const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { trx.context_free_actions.clear(); trx.context_free_actions.emplace_back(action({}, config::null_account_name, name("nonce"), fc::raw::pack(std::to_string(nonce_prefix) + ":" + std::to_string(++nonce) + ":" + fc::time_point::now().time_since_epoch().count()))); set_transaction_headers(trx, last_irr_block_id, trx_expiration); @@ -60,7 +61,7 @@ namespace eosio::testing { trx.sign(priv_key, chain_id); } - chain::bytes transfer_trx_generator::make_transfer_data(const chain::name& from, const chain::name& to, const chain::asset& quantity, const std::string&& memo) { + chain::bytes transfer_trx_generator::make_transfer_data(const chain::name& from, const chain::name& to, const chain::asset& quantity, const std::string& memo) { return fc::raw::pack(from, to, quantity, memo); } @@ -81,7 +82,7 @@ namespace eosio::testing { ilog("create_initial_transfer_actions: creating transfer from ${acctB} to ${acctA}", ("acctB", accounts.at(j))("acctA", accounts.at(i))); action act_b_to_a = make_transfer_action(contract_owner_account, accounts.at(j), accounts.at(i), asset::from_string("1.0000 CUR"), salt); - actions_pairs_vector.push_back(action_pair_w_keys(act_a_to_b, act_b_to_a, priv_keys.at(i), priv_keys.at(j))); + actions_pairs_vector.emplace_back(action_pair_w_keys(act_a_to_b, act_b_to_a, priv_keys.at(i), priv_keys.at(j))); } } ilog("create_initial_transfer_actions: total action pairs created: ${pairs}", ("pairs", actions_pairs_vector.size())); @@ -99,9 +100,9 @@ namespace eosio::testing { vector transfer_trx_generator::get_accounts(const vector& account_str_vector) { vector acct_name_list; - for (string account_name: account_str_vector) { + for (const string& account_name : account_str_vector) { ilog("get_account about to try to create name for ${acct}", ("acct", account_name)); - acct_name_list.push_back(eosio::chain::name(account_name)); + acct_name_list.emplace_back(eosio::chain::name(account_name)); } return acct_name_list; } @@ -110,7 +111,7 @@ namespace eosio::testing { vector key_list; for (const string& private_key: priv_key_str_vector) { ilog("get_private_keys about to try to create private_key for ${key} : gen key ${newKey}", ("key", private_key)("newKey", fc::crypto::private_key(private_key))); - key_list.push_back(fc::crypto::private_key(private_key)); + key_list.emplace_back(fc::crypto::private_key(private_key)); } return key_list; } @@ -166,7 +167,7 @@ namespace eosio::testing { void trx_generator::locate_key_words_in_action_mvo(std::vector& acct_gen_fields_out, fc::mutable_variant_object& action_mvo, const std::string& key_word) { for (const mutable_variant_object::entry& e: action_mvo) { if (e.value().get_type() == fc::variant::string_type && e.value() == key_word) { - acct_gen_fields_out.push_back(e.key()); + acct_gen_fields_out.emplace_back(e.key()); } else if (e.value().get_type() == fc::variant::object_type) { auto inner_mvo = fc::mutable_variant_object(e.value()); locate_key_words_in_action_mvo(acct_gen_fields_out, inner_mvo, key_word); @@ -205,11 +206,11 @@ namespace eosio::testing { } } - void trx_generator::update_resign_transaction(signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { + void trx_generator::update_resign_transaction(signed_transaction& trx, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const chain_id_type& chain_id, const block_id_type& last_irr_block_id) { trx.actions.clear(); update_actions(); for (const auto& act: _actions) { - trx.actions.push_back(act); + trx.actions.emplace_back(act); } trx_generator_base::update_resign_transaction(trx, priv_key, nonce_prefix, nonce, trx_expiration, chain_id, last_irr_block_id); } diff --git a/tests/trx_generator/trx_generator.hpp b/tests/trx_generator/trx_generator.hpp index c53b7ebdd3..c00dea2805 100644 --- a/tests/trx_generator/trx_generator.hpp +++ b/tests/trx_generator/trx_generator.hpp @@ -120,7 +120,7 @@ namespace eosio::testing { virtual ~trx_generator_base() = default; - virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, + virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); void push_transaction(p2p_trx_provider& provider, signed_transaction_w_signer& trx, uint64_t& nonce_prefix, @@ -152,7 +152,7 @@ namespace eosio::testing { std::vector get_private_keys(const std::vector& priv_key_str_vector); std::vector create_initial_transfer_transactions(const std::vector& action_pairs_vector, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); - eosio::chain::bytes make_transfer_data(const eosio::chain::name& from, const eosio::chain::name& to, const eosio::chain::asset& quantity, const std::string&& memo); + eosio::chain::bytes make_transfer_data(const eosio::chain::name& from, const eosio::chain::name& to, const eosio::chain::asset& quantity, const std::string& memo); auto make_transfer_action(eosio::chain::name account, eosio::chain::name from, eosio::chain::name to, eosio::chain::asset quantity, std::string memo); std::vector create_initial_transfer_actions(const std::string& salt, const uint64_t& period, const eosio::chain::name& contract_owner_account, const std::vector& accounts, const std::vector& priv_keys); @@ -184,7 +184,7 @@ namespace eosio::testing { void update_key_word_fields_in_action(std::vector& acct_gen_fields, fc::mutable_variant_object& action_mvo, const std::string& key_word); void update_actions(); - virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, fc::crypto::private_key priv_key, uint64_t& nonce_prefix, uint64_t& nonce, + virtual void update_resign_transaction(eosio::chain::signed_transaction& trx, const fc::crypto::private_key& priv_key, uint64_t& nonce_prefix, uint64_t& nonce, const fc::microseconds& trx_expiration, const eosio::chain::chain_id_type& chain_id, const eosio::chain::block_id_type& last_irr_block_id); fc::variant json_from_file_or_string(const std::string& file_or_str, fc::json::parse_type ptype = fc::json::parse_type::legacy_parser);