diff options
author | winsvega <winsvega@mail.ru> | 2015-01-06 06:39:02 +0800 |
---|---|---|
committer | winsvega <winsvega@mail.ru> | 2015-01-22 17:04:58 +0800 |
commit | 91ccc1b7ab56af5ecb94b0c9741067db0e5c8443 (patch) | |
tree | 0e48f0eb5742dab13a598bed05efac40f462856a | |
parent | a0ecb5d4e876aeff12a58e45563f0ea39f1bdf87 (diff) | |
download | dexon-solidity-91ccc1b7ab56af5ecb94b0c9741067db0e5c8443.tar.gz dexon-solidity-91ccc1b7ab56af5ecb94b0c9741067db0e5c8443.tar.zst dexon-solidity-91ccc1b7ab56af5ecb94b0c9741067db0e5c8443.zip |
Transaction Tests
transaction tests
Transaction Test Work In Progress
transaction test work in progress
work in progress. check for transaction is valid
Transaction Tests Work In Progress
compiler error fix
-rw-r--r-- | TestHelper.cpp | 15 | ||||
-rw-r--r-- | TestHelper.h | 1 | ||||
-rw-r--r-- | stTransactionTestFiller.json | 105 | ||||
-rw-r--r-- | transaction.cpp | 236 | ||||
-rw-r--r-- | ttTransactionTestFiller.json | 80 |
5 files changed, 426 insertions, 11 deletions
diff --git a/TestHelper.cpp b/TestHelper.cpp index ea848c7c..1b854162 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -228,14 +228,21 @@ byte toByte(json_spirit::mValue const& _v) return 0; } +bytes importByteArray(const std::string& str) +{ + bytes data; + if (str.find_first_of("0x") == 0) + data = fromHex(str.substr(2)); + else + data = fromHex(str); + return data; +} + bytes importData(json_spirit::mObject& _o) { bytes data; if (_o["data"].type() == json_spirit::str_type) - if (_o["data"].get_str().find_first_of("0x") == 0) - data = fromHex(_o["data"].get_str().substr(2)); - else - data = fromHex(_o["data"].get_str()); + data = importByteArray(_o["data"].get_str()); else for (auto const& j: _o["data"].get_array()) data.push_back(toByte(j)); diff --git a/TestHelper.h b/TestHelper.h index 20328c91..e605c74a 100644 --- a/TestHelper.h +++ b/TestHelper.h @@ -68,6 +68,7 @@ u256 toInt(json_spirit::mValue const& _v); byte toByte(json_spirit::mValue const& _v); bytes importCode(json_spirit::mObject& _o); bytes importData(json_spirit::mObject& _o); +bytes importByteArray(const std::string& str); eth::LogEntries importLog(json_spirit::mArray& _o); json_spirit::mArray exportLog(eth::LogEntries _logs); void checkOutput(bytes const& _output, json_spirit::mObject& _o); diff --git a/stTransactionTestFiller.json b/stTransactionTestFiller.json index 09c323cf..c1c71a53 100644 --- a/stTransactionTestFiller.json +++ b/stTransactionTestFiller.json @@ -289,7 +289,7 @@ } }, - "TransactionTooManyRlpElements" : { + "InternlCallStoreClearsOOG" : { "env" : { "currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", "currentDifficulty" : "45678256", @@ -301,24 +301,115 @@ "pre" : { "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "100000", + "balance" : "7000", "code" : "", "nonce" : "0", "storage" : { } + }, + + "c94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10", + "//" : "gas = 19 going OOG, gas = 20 fine", + "code" : "{ (CALL 19 0 1 0 0 0 0) }", + "nonce" : "0", + "storage" : { + } + }, + + "0000000000000000000000000000000000000000" : { + "balance" : "0", + "code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 0)}", + "nonce" : "0", + "storage" : { + "0x" : "0x0c", + "0x01" : "0x0c", + "0x02" : "0x0c", + "0x03" : "0x0c", + "0x04" : "0x0c", + "0x05" : "0x0c", + "0x06" : "0x0c", + "0x07" : "0x0c", + "0x08" : "0x0c", + "0x09" : "0x0c" + } } + }, + "transaction" : { "data" : "", - "gasLimit" : "600", - "gasLimit" : "1600", + "gasLimit" : "700", "gasPrice" : "1", - "gasPrice" : "12", "nonce" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d9", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "d2571607e241ecf590ed94b12d87c94babe36db6", + "to" : "c94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + } + }, + + "StoreClearsAndInternlCallStoreClearsOOG" : { + "env" : { + "currentCoinbase" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty" : "45678256", + "currentGasLimit" : "10000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "7000", + "code" : "", + "nonce" : "0", + "storage" : { + } + }, + + "c94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10", + "//" : "gas = 19 going OOG, gas = 20 fine", + "code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0) (CALL 19 0 1 0 0 0 0) }", + "nonce" : "0", + "storage" : { + "0x" : "0x0c", + "0x01" : "0x0c", + "0x02" : "0x0c", + "0x03" : "0x0c", + "0x04" : "0x0c" + } + }, + + "0000000000000000000000000000000000000000" : { + "balance" : "0", + "code" : "{(SSTORE 0 0)(SSTORE 1 0)(SSTORE 2 0)(SSTORE 3 0)(SSTORE 4 0)(SSTORE 5 0)(SSTORE 6 0)(SSTORE 7 0)(SSTORE 8 0)(SSTORE 9 0)}", + "nonce" : "0", + "storage" : { + "0x" : "0x0c", + "0x01" : "0x0c", + "0x02" : "0x0c", + "0x03" : "0x0c", + "0x04" : "0x0c", + "0x05" : "0x0c", + "0x06" : "0x0c", + "0x07" : "0x0c", + "0x08" : "0x0c", + "0x09" : "0x0c" + } + } + + }, + + "transaction" : + { + "data" : "", + "gasLimit" : "700", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c94f5374fce5edbc8e2a8697c15331677e6ebf0b", "value" : "10" } }, diff --git a/transaction.cpp b/transaction.cpp new file mode 100644 index 00000000..db66b33e --- /dev/null +++ b/transaction.cpp @@ -0,0 +1,236 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. +*/ +/** @file transaction.cpp + * @author Dmitrii Khokhlov <winsvega@mail.ru> + * @date 2014 + * Transaaction test functions. + */ + +#include <boost/filesystem/operations.hpp> +#include <boost/test/unit_test.hpp> +#include "JsonSpiritHeaders.h" +#include <libdevcore/CommonIO.h> +#include <libethereum/BlockChain.h> +#include <libethereum/State.h> +#include <libethereum/ExtVM.h> +#include <libethereum/Defaults.h> +#include <libevm/VM.h> +#include "TestHelper.h" + +using namespace std; +using namespace json_spirit; +using namespace dev; +using namespace dev::eth; +using namespace dev::eth; + +namespace dev { namespace test { + +Transaction createTransactionFromFields(mObject& _tObj) +{ + BOOST_REQUIRE(_tObj.count("data") > 0); + BOOST_REQUIRE(_tObj.count("value") > 0); + BOOST_REQUIRE(_tObj.count("gasPrice") > 0); + BOOST_REQUIRE(_tObj.count("gasLimit") > 0); + BOOST_REQUIRE(_tObj.count("nonce")> 0); + BOOST_REQUIRE(_tObj.count("to") > 0); + + BOOST_REQUIRE(_tObj.count("v") > 0); + BOOST_REQUIRE(_tObj.count("r") > 0); + BOOST_REQUIRE(_tObj.count("s") > 0); + + //Construct Rlp of the given transaction + RLPStream rlpStream; + rlpStream.appendList(9); + rlpStream << toInt(_tObj["nonce"]) << toInt(_tObj["gasPrice"]) << toInt(_tObj["gasLimit"]); + if (_tObj["to"].get_str().empty()) + rlpStream << ""; + else + rlpStream << Address(_tObj["to"].get_str()); + rlpStream << toInt(_tObj["value"]) << importData(_tObj); + + u256 r = h256(fromHex(_tObj["r"].get_str())); + u256 s = h256(fromHex(_tObj["s"].get_str())); + rlpStream << toInt(_tObj["v"]) << r << s; + + return Transaction(rlpStream.out(), true); +} + +void doTransactionTests(json_spirit::mValue& _v, bool _fillin) +{ + for (auto& i: _v.get_obj()) + { + cerr << i.first << endl; + mObject& o = i.second.get_obj(); + + if(_fillin == false) + { + BOOST_REQUIRE(o.count("rlp") > 0); + bytes rlpReaded = importByteArray(o["rlp"].get_str()); + Transaction txFromRlp; + + try + { + txFromRlp = Transaction(rlpReaded, true); + if (!txFromRlp.signature().isValid()) + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") ); + } + catch(...) + { + BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transction object should not be defined because the RLP is invalid!"); + return; + } + + BOOST_REQUIRE(o.count("transaction") > 0); + + mObject tObj = o["transaction"].get_obj(); + Transaction txFromFields = createTransactionFromFields(tObj); + + //Check the fields restored from RLP to original fields + BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), "Data in given RLP not matching the Transaction data!"); + BOOST_CHECK_MESSAGE(txFromFields.value() == txFromRlp.value(), "Value in given RLP not matching the Transaction value!"); + BOOST_CHECK_MESSAGE(txFromFields.gasPrice() == txFromRlp.gasPrice(), "GasPrice in given RLP not matching the Transaction gasPrice!"); + BOOST_CHECK_MESSAGE(txFromFields.gas() == txFromRlp.gas(),"Gas in given RLP not matching the Transaction gas!"); + BOOST_CHECK_MESSAGE(txFromFields.nonce() == txFromRlp.nonce(),"Nonce in given RLP not matching the Transaction nonce!"); + BOOST_CHECK_MESSAGE(txFromFields.receiveAddress() == txFromRlp.receiveAddress(), "Receive address in given RLP not matching the Transaction 'to' address!"); + BOOST_CHECK_MESSAGE(txFromFields.sender() == txFromRlp.sender(), "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!"); + BOOST_CHECK_MESSAGE(txFromFields == txFromRlp, "However, txFromFields != txFromRlp!"); + BOOST_REQUIRE (o.count("sender") > 0); + + Address addressReaded = Address(o["sender"].get_str()); + BOOST_CHECK_MESSAGE(txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded, "Signature address of sender does not match given sender address!"); + } + + if(_fillin == true) + { + BOOST_REQUIRE(o.count("transaction") > 0); + mObject tObj = o["transaction"].get_obj(); + + //Construct Rlp of the given transaction + RLPStream rlpStream; + rlpStream.appendList(tObj.size()); + + if(tObj.count("nonce") > 0) + rlpStream << toInt(tObj["nonce"]); + + if(tObj.count("gasPrice") > 0) + rlpStream << toInt(tObj["gasPrice"]); + + if(tObj.count("gasLimit") > 0) + rlpStream << toInt(tObj["gasLimit"]); + + if(tObj.count("to") > 0) + { + if (tObj["to"].get_str().empty()) + rlpStream << ""; + else + rlpStream << Address(tObj["to"].get_str()); + } + + if(tObj.count("value") > 0) + rlpStream << toInt(tObj["value"]); + + + if(tObj.count("data") > 0) + rlpStream << importData(tObj); + + if(tObj.count("v") > 0) + rlpStream << toInt(tObj["v"]); + + if(tObj.count("r") > 0) + { + u256 r = h256(fromHex(tObj["r"].get_str())); + rlpStream << r; + } + + if(tObj.count("s") > 0) + { + u256 s = h256(fromHex(tObj["s"].get_str())); + rlpStream << s; + } + + if(tObj.count("extrafield") > 0) + rlpStream << toInt(tObj["extrafield"]); + + o["rlp"] = "0x" + toHex(rlpStream.out()); + + try + { + Transaction txFromFields(rlpStream.out(), true); + if (!txFromFields.signature().isValid()) + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") ); + + o["sender"] = toString(txFromFields.sender()); + + } + catch(...) + { + o.erase(o.find("transaction")); + } + } + }//for +}//doTransactionTests + +} }// Namespace Close + + +BOOST_AUTO_TEST_SUITE(TransactionTests) + +BOOST_AUTO_TEST_CASE(ttFillerTest) +{ + dev::test::executeTests("ttTransactionTest", "/TransactionTests", dev::test::doTransactionTests); +} + +BOOST_AUTO_TEST_CASE(ttCreateTest) +{ + for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) + { + string arg = boost::unit_test::framework::master_test_suite().argv[i]; + if (arg == "--createtest") + { + if (boost::unit_test::framework::master_test_suite().argc <= i + 2) + { + cnote << "usage: ./testeth --createtest <PathToConstructor> <PathToDestiny>\n"; + return; + } + try + { + cnote << "Populating tests..."; + json_spirit::mValue v; + string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1])); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty."); + json_spirit::read_string(s, v); + dev::test::doTransactionTests(v, true); + writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true))); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed transaction test with Exception: " << diagnostic_information(_e)); + } + catch (std::exception const& _e) + { + BOOST_ERROR("Failed transaction test with Exception: " << _e.what()); + } + } + } +} + +BOOST_AUTO_TEST_CASE(userDefinedFileTT) +{ + dev::test::userDefinedTest("--ttTest", dev::test::doTransactionTests); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/ttTransactionTestFiller.json b/ttTransactionTestFiller.json new file mode 100644 index 00000000..6c68bd75 --- /dev/null +++ b/ttTransactionTestFiller.json @@ -0,0 +1,80 @@ +{ + "RightVRSTest" : { + "transaction" : + { + "data" : "", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "0", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10", + "v" : "28", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + + } + }, + + "WrongVRSTest" : { + "transaction" : + { + "data" : "", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "0", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10", + "v" : "1", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + }, + + "SenderTest" : { + "//" : "sender a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "transaction" : + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10", + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + } + }, + + "TransactionWithTooManyRLPElements" : { + "transaction" : + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10", + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", + "extrafield" : "128472387293" + } + }, + + "TransactionWithHihghValue" : { + "transaction" : + { + "data" : "", + "gasLimit" : "850", + "gasPrice" : "1", + "nonce" : "0", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", + "v" : "27", + "r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", + "s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" + } + } +} |