From 8661e0add0df57ca64f614a39c717f1e4cbb693c Mon Sep 17 00:00:00 2001 From: "JOSEPH NICHOLAS R. ALCANTARA" Date: Sun, 24 Nov 2019 01:23:57 +0800 Subject: [PATCH 1/5] Adding "codeFile" parameter into alet-vm options Part of https://github.com/ethereum/aleth/issues/4613 --- aleth-vm/main.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/aleth-vm/main.cpp b/aleth-vm/main.cpp index 8311efbdc7c..a8e366a6cc2 100644 --- a/aleth-vm/main.cpp +++ b/aleth-vm/main.cpp @@ -73,7 +73,7 @@ class LastBlockHashes : public eth::LastBlockHashesFace int main(int argc, char** argv) { setDefaultOrCLocale(); - string inputFile; + string codeFile; Mode mode = Mode::Statistics; State state(0); Address sender = Address(69); @@ -113,6 +113,7 @@ int main(int argc, char** argv) addTransactionOption("input", po::value(), " Transaction code should be "); addTransactionOption("code", po::value(), " Contract code . Makes transaction a call to this contract"); + addTransactionOption("codefile", po::value(), " File containing EVM code . If '-' is specified, code is read from stdin"); po::options_description networkOptions("Network options", c_lineWidth); networkOptions.add_options()("network", po::value(), @@ -174,8 +175,6 @@ int main(int argc, char** argv) mode = Mode::Trace; else if (arg == "test") mode = Mode::Test; - else if (inputFile.empty()) - inputFile = arg; // Assign input file name only once. else { cerr << "Unknown argument: " << arg << '\n'; @@ -240,22 +239,24 @@ int main(int argc, char** argv) data = fromHex(vm["input"].as()); if (vm.count("code")) code = fromHex(vm["code"].as()); + if (vm.count("codefile")) + codeFile = vm["codefile"].as(); // Read code from input file. - if (!inputFile.empty()) + if (!codeFile.empty()) { if (!code.empty()) - cerr << "--code argument overwritten by input file " << inputFile << '\n'; + cerr << "--code argument overwritten by input file " << codeFile << '\n'; - if (inputFile == "-") - for (int i = cin.get(); i != -1; i = cin.get()) - code.push_back(static_cast(i)); + string codeStr = ""; + if (codeFile == "-") + std::getline(std::cin, codeStr); else - code = contents(inputFile); + code = contents(codeFile); try // Try decoding from hex. { - std::string strCode{reinterpret_cast(code.data()), code.size()}; + std::string strCode = codeFile == "-" ? codeStr : string(reinterpret_cast(code.data()), code.size()); strCode.erase(strCode.find_last_not_of(" \t\n\r") + 1); // Right trim. code = fromHex(strCode, WhenError::Throw); } From f49f6f5c9926a9664716b8e126aa2107f08561fa Mon Sep 17 00:00:00 2001 From: "JOSEPH NICHOLAS R. ALCANTARA" Date: Tue, 26 Nov 2019 10:58:30 +0800 Subject: [PATCH 2/5] Changes from review: - change placeholder to . - use of single string for code. - try catch removed since ::erase might not throw. - add error message for using --code and --codefile at the same time. --- aleth-vm/main.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/aleth-vm/main.cpp b/aleth-vm/main.cpp index a8e366a6cc2..a109cc14426 100644 --- a/aleth-vm/main.cpp +++ b/aleth-vm/main.cpp @@ -89,7 +89,7 @@ int main(int argc, char** argv) blockHeader.setGasLimit(maxBlockGasLimit()); blockHeader.setTimestamp(0); bytes data; - bytes code; + string code; Ethash::init(); NoProof::init(); @@ -113,7 +113,7 @@ int main(int argc, char** argv) addTransactionOption("input", po::value(), " Transaction code should be "); addTransactionOption("code", po::value(), " Contract code . Makes transaction a call to this contract"); - addTransactionOption("codefile", po::value(), " File containing EVM code . If '-' is specified, code is read from stdin"); + addTransactionOption("codefile", po::value(), " File containing EVM code . If '-' is specified, code is read from stdin"); po::options_description networkOptions("Network options", c_lineWidth); networkOptions.add_options()("network", po::value(), @@ -238,31 +238,28 @@ int main(int argc, char** argv) if (vm.count("input")) data = fromHex(vm["input"].as()); if (vm.count("code")) - code = fromHex(vm["code"].as()); + code = vm["code"].as(); if (vm.count("codefile")) codeFile = vm["codefile"].as(); // Read code from input file. if (!codeFile.empty()) { + if (vm.count("code")) + { + cerr << "Options --code and --codefile shouldn't be used at the same time" << '\n'; + return AlethErrors::BadConfigOption; + } + if (!code.empty()) cerr << "--code argument overwritten by input file " << codeFile << '\n'; - string codeStr = ""; if (codeFile == "-") - std::getline(std::cin, codeStr); + std::getline(std::cin, code); else - code = contents(codeFile); + code = contentsString(codeFile); - try // Try decoding from hex. - { - std::string strCode = codeFile == "-" ? codeStr : string(reinterpret_cast(code.data()), code.size()); - strCode.erase(strCode.find_last_not_of(" \t\n\r") + 1); // Right trim. - code = fromHex(strCode, WhenError::Throw); - } - catch (BadHexCharacter const&) - { - } // Ignore decoding errors. + code.erase(code.find_last_not_of(" \t\n\r") + 1); // Right trim. } unique_ptr se(ChainParams(genesisInfo(networkName)).createSealEngine()); @@ -276,7 +273,7 @@ int main(int argc, char** argv) // Deploy the code on some fake account to be called later. Account account(0, 0); auto const latestVersion = se->evmSchedule(envInfo.number()).accountVersion; - account.setCode(bytes{code}, latestVersion); + account.setCode(bytes{static_cast(*code.c_str())}, latestVersion); std::unordered_map map; map[contractDestination] = account; state.populateFrom(map); From 99528a1a307c1bbd64ffdfd9e6169433b0c71269 Mon Sep 17 00:00:00 2001 From: "Joseph Nicholas R. Alcantara" Date: Wed, 27 Nov 2019 19:21:18 +0800 Subject: [PATCH 3/5] Revision based on review, and reverted back to original try-catch block --- aleth-vm/main.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/aleth-vm/main.cpp b/aleth-vm/main.cpp index a109cc14426..b580d9740d3 100644 --- a/aleth-vm/main.cpp +++ b/aleth-vm/main.cpp @@ -251,15 +251,18 @@ int main(int argc, char** argv) return AlethErrors::BadConfigOption; } - if (!code.empty()) - cerr << "--code argument overwritten by input file " << codeFile << '\n'; - if (codeFile == "-") std::getline(std::cin, code); else code = contentsString(codeFile); - code.erase(code.find_last_not_of(" \t\n\r") + 1); // Right trim. + try // Try decoding from hex. + { + code.erase(code.find_last_not_of(" \t\n\r") + 1); // Right trim. + } + catch (BadHexCharacter const&) + { + } // Ignore decoding errors./ Right trim. } unique_ptr se(ChainParams(genesisInfo(networkName)).createSealEngine()); @@ -273,7 +276,7 @@ int main(int argc, char** argv) // Deploy the code on some fake account to be called later. Account account(0, 0); auto const latestVersion = se->evmSchedule(envInfo.number()).accountVersion; - account.setCode(bytes{static_cast(*code.c_str())}, latestVersion); + account.setCode(fromHex(code, WhenError::Throw), latestVersion); std::unordered_map map; map[contractDestination] = account; state.populateFrom(map); From bb59c1092570281e0a1ee2dd6bf1282ab8a1b58c Mon Sep 17 00:00:00 2001 From: "Joseph Nicholas R. Alcantara" Date: Thu, 28 Nov 2019 00:59:18 +0800 Subject: [PATCH 4/5] Changes for this revision: - Added changelog for added parameter change. - Made some revisions based on review. --- CHANGELOG.md | 1 + aleth-vm/main.cpp | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3ddd9a389d..d0677c2f792 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Added: [#5699](https://github.com/ethereum/aleth/pull/5699) EIP 2046: Reduced gas cost for static calls made to precompiles. - Added: [#5741](https://github.com/ethereum/aleth/pull/5741) Support for individual EIP activation to facilitate EIP-centric network upgrade process. - Added: [#5752](https://github.com/ethereum/aleth/pull/5752) [#5753](https://github.com/ethereum/aleth/pull/5753) [#5809](https://github.com/ethereum/aleth/pull/5809) Implement EIP1380 (reduced gas costs for call-to-self). +- Added: [#5848](https://github.com/ethereum/aleth/pull/5848) Add "codefile" parameter into aleth-vm options. `aleth-vm --codefile ` now reads bytecode file from path and `aleth-vm --codefile - ` now reads bytcode from input. - Changed: [#5750](https://github.com/ethereum/aleth/pull/5750) Use `testeth -t -- --testfile ` to run the tests from file at any path. Use `testeth -t -- --testfile --singletest ` to run only single test from any file. - Changed: [#5801](https://github.com/ethereum/aleth/pull/5801) `testeth -t BlockchainTests` command now doesn't run the tests for the forks before Istanbul. To run those tests use a separate LegacyTests suite with command `testeth -t LegacyTests/Constantinople/BlockchainTests`. - Changed: [#5807](https://github.com/ethereum/aleth/pull/5807) Optimize selfdestruct opcode in LegacyVM by reducing state accesses in certain out-of-gas scenarios. diff --git a/aleth-vm/main.cpp b/aleth-vm/main.cpp index b580d9740d3..931b02c563a 100644 --- a/aleth-vm/main.cpp +++ b/aleth-vm/main.cpp @@ -245,7 +245,7 @@ int main(int argc, char** argv) // Read code from input file. if (!codeFile.empty()) { - if (vm.count("code")) + if (!code.empty()) { cerr << "Options --code and --codefile shouldn't be used at the same time" << '\n'; return AlethErrors::BadConfigOption; @@ -255,14 +255,7 @@ int main(int argc, char** argv) std::getline(std::cin, code); else code = contentsString(codeFile); - - try // Try decoding from hex. - { - code.erase(code.find_last_not_of(" \t\n\r") + 1); // Right trim. - } - catch (BadHexCharacter const&) - { - } // Ignore decoding errors./ Right trim. + code.erase(code.find_last_not_of(" \t\n\r") + 1); // Right trim. } unique_ptr se(ChainParams(genesisInfo(networkName)).createSealEngine()); @@ -276,7 +269,18 @@ int main(int argc, char** argv) // Deploy the code on some fake account to be called later. Account account(0, 0); auto const latestVersion = se->evmSchedule(envInfo.number()).accountVersion; - account.setCode(fromHex(code, WhenError::Throw), latestVersion); + + bytes codeBytes{}; + try + { + codeBytes = fromHex(code, WhenError::Throw); + }catch (BadHexCharacter const& e) + { + cerr << "Exception: " << e.what() << '\n'; + return AlethErrors::BadFormatOption; + } + + account.setCode(bytes{codeBytes}, latestVersion); std::unordered_map map; map[contractDestination] = account; state.populateFrom(map); From a4e6d351bbab825187070bec83b8694885142859 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Wed, 27 Nov 2019 19:11:54 +0100 Subject: [PATCH 5/5] Minor improvements --- CHANGELOG.md | 2 +- aleth-vm/main.cpp | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0677c2f792..cdaaf9e681a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,12 @@ - Added: [#5699](https://github.com/ethereum/aleth/pull/5699) EIP 2046: Reduced gas cost for static calls made to precompiles. - Added: [#5741](https://github.com/ethereum/aleth/pull/5741) Support for individual EIP activation to facilitate EIP-centric network upgrade process. - Added: [#5752](https://github.com/ethereum/aleth/pull/5752) [#5753](https://github.com/ethereum/aleth/pull/5753) [#5809](https://github.com/ethereum/aleth/pull/5809) Implement EIP1380 (reduced gas costs for call-to-self). -- Added: [#5848](https://github.com/ethereum/aleth/pull/5848) Add "codefile" parameter into aleth-vm options. `aleth-vm --codefile ` now reads bytecode file from path and `aleth-vm --codefile - ` now reads bytcode from input. - Changed: [#5750](https://github.com/ethereum/aleth/pull/5750) Use `testeth -t -- --testfile ` to run the tests from file at any path. Use `testeth -t -- --testfile --singletest ` to run only single test from any file. - Changed: [#5801](https://github.com/ethereum/aleth/pull/5801) `testeth -t BlockchainTests` command now doesn't run the tests for the forks before Istanbul. To run those tests use a separate LegacyTests suite with command `testeth -t LegacyTests/Constantinople/BlockchainTests`. - Changed: [#5807](https://github.com/ethereum/aleth/pull/5807) Optimize selfdestruct opcode in LegacyVM by reducing state accesses in certain out-of-gas scenarios. - Changed: [#5806](https://github.com/ethereum/aleth/pull/5806) Optimize selfdestruct opcode in aleth-interpreter by reducing state accesses in certain out-of-gas scenarios. - Changed: [#5837](https://github.com/ethereum/aleth/pull/5837) [#5839](https://github.com/ethereum/aleth/pull/5839) [#5845](https://github.com/ethereum/aleth/pull/5845) [#5846](https://github.com/ethereum/aleth/pull/5846) Output format of `testeth --jsontrace` command changed to better match output of geth's evm tool and to integrate with evmlab project. +- Changed: [#5848](https://github.com/ethereum/aleth/pull/5848) `aleth-vm --codefile ` now reads bytecode file from path and `aleth-vm --codefile - ` now reads bytecode from standard input. - Removed: [#5760](https://github.com/ethereum/aleth/pull/5760) Official support for Visual Studio 2015 has been dropped. Compilation with this compiler is expected to stop working after migration to C++14. - Fixed: [#5792](https://github.com/ethereum/aleth/pull/5792) Faster and cheaper execution of RPC functions which query blockchain state (e.g. getBalance). - Fixed: [#5811](https://github.com/ethereum/aleth/pull/5811) RPC methods querying transactions (`eth_getTransactionByHash`, `eth_getBlockByNumber`) return correct `v` value. diff --git a/aleth-vm/main.cpp b/aleth-vm/main.cpp index 931b02c563a..0fc60c9e6e9 100644 --- a/aleth-vm/main.cpp +++ b/aleth-vm/main.cpp @@ -113,7 +113,8 @@ int main(int argc, char** argv) addTransactionOption("input", po::value(), " Transaction code should be "); addTransactionOption("code", po::value(), " Contract code . Makes transaction a call to this contract"); - addTransactionOption("codefile", po::value(), " File containing EVM code . If '-' is specified, code is read from stdin"); + addTransactionOption("codefile", po::value(), + " File containing contract code. If '-' is specified, code is read from stdin"); po::options_description networkOptions("Network options", c_lineWidth); networkOptions.add_options()("network", po::value(), @@ -146,8 +147,7 @@ int main(int argc, char** argv) ->notifier([&](int64_t _t) { blockHeader.setTimestamp(_t); }), " Set timestamp"); - po::options_description allowedOptions( - "Usage ethvm [trace|stats|output|test] (|-)"); + po::options_description allowedOptions("Usage ethvm [trace|stats|output|test]"); allowedOptions.add(vmProgramOptions(c_lineWidth)) .add(networkOptions) .add(optionsForTrace) @@ -248,7 +248,7 @@ int main(int argc, char** argv) if (!code.empty()) { cerr << "Options --code and --codefile shouldn't be used at the same time" << '\n'; - return AlethErrors::BadConfigOption; + return AlethErrors::ArgumentProcessingFailure; } if (codeFile == "-") @@ -270,14 +270,15 @@ int main(int argc, char** argv) Account account(0, 0); auto const latestVersion = se->evmSchedule(envInfo.number()).accountVersion; - bytes codeBytes{}; + bytes codeBytes; try { codeBytes = fromHex(code, WhenError::Throw); - }catch (BadHexCharacter const& e) + } + catch (BadHexCharacter const&) { - cerr << "Exception: " << e.what() << '\n'; - return AlethErrors::BadFormatOption; + cerr << "Provided code contains invalid characters.\n"; + return AlethErrors::ArgumentProcessingFailure; } account.setCode(bytes{codeBytes}, latestVersion);