aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwinsvega <winsvega@mail.ru>2015-01-06 06:39:02 +0800
committerwinsvega <winsvega@mail.ru>2015-01-22 17:04:58 +0800
commit91ccc1b7ab56af5ecb94b0c9741067db0e5c8443 (patch)
tree0e48f0eb5742dab13a598bed05efac40f462856a
parenta0ecb5d4e876aeff12a58e45563f0ea39f1bdf87 (diff)
downloaddexon-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.cpp15
-rw-r--r--TestHelper.h1
-rw-r--r--stTransactionTestFiller.json105
-rw-r--r--transaction.cpp236
-rw-r--r--ttTransactionTestFiller.json80
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"
+ }
+ }
+}