Fabcoin Core  0.16.2
P2P Digital Currency
TransactionTests.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
23 #include <libethcore/SealEngine.h>
29 
30 using namespace std;
31 using namespace json_spirit;
32 using namespace dev;
33 using namespace dev::eth;
34 
35 namespace dev { namespace test {
36 
37 void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
38 {
39  TestOutputHelper::initTest(_v);
40  unique_ptr<SealEngineFace> se(ChainParams(genesisInfo(eth::Network::MainNetworkTest)).createSealEngine());
41  for (auto& i: _v.get_obj())
42  {
43  string testname = i.first;
44  json_spirit::mObject& o = i.second.get_obj();
45 
46  if (!TestOutputHelper::passTest(o, testname))
47  continue;
48 
49  BOOST_REQUIRE(o.count("blocknumber") > 0);
50  u256 transactionBlock = toInt(o["blocknumber"].get_str());
51  BlockHeader bh;
52  bh.setNumber(transactionBlock);
53 
54  if (_fillin)
55  {
56  BOOST_REQUIRE(o.count("transaction") > 0);
57  mObject tObj = o["transaction"].get_obj();
58 
59  //Construct Rlp of the given transaction
61  o["rlp"] = toHex(rlpStream.out(), 2, HexPrefix::Add);
62 
63  try
64  {
65  Transaction txFromFields(rlpStream.out(), CheckTransaction::Everything);
66  if (!txFromFields.signature().isValid())
67  BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(testname + "transaction from RLP signature is invalid") );
68  se->verifyTransaction(ImportRequirements::Everything, txFromFields, bh);
69 
70  if (o.count("sender") > 0)
71  {
72  string expectSender = toString(o["sender"].get_str());
73  BOOST_CHECK_MESSAGE(toString(txFromFields.sender()) == expectSender, "Error filling transaction test " + TestOutputHelper::testName() + ": expected another sender address! (got: " + toString(txFromFields.sender()) + "), expected: (" + expectSender + ")");
74  }
75  o["sender"] = toString(txFromFields.sender());
76  o["transaction"] = ImportTest::makeAllFieldsHex(tObj);
77  o["hash"] = toString(txFromFields.sha3());
78  }
79  catch(Exception const& _e)
80  {
81  //Transaction is InValid
82  cnote << "Transaction Exception: " << diagnostic_information(_e);
83  o.erase(o.find("transaction"));
84  if (o.count("expect") > 0)
85  {
86  bool expectInValid = (o["expect"].get_str() == "invalid");
87  if (Options::get().checkstate)
88  BOOST_CHECK_MESSAGE(expectInValid, testname + "Check state: Transaction '" << i.first << "' is expected to be valid!");
89  else
90  BOOST_WARN_MESSAGE(expectInValid, testname + "Check state: Transaction '" << i.first << "' is expected to be valid!");
91 
92  o.erase(o.find("expect"));
93  }
94  }
95 
96  //Transaction is Valid
97  if (o.count("expect") > 0)
98  {
99  bool expectValid = (o["expect"].get_str() == "valid");
100  if (Options::get().checkstate)
101  BOOST_CHECK_MESSAGE(expectValid, testname + "Check state: Transaction '" << i.first << "' is expected to be invalid!");
102  else
103  BOOST_WARN_MESSAGE(expectValid, testname + "Check state: Transaction '" << i.first << "' is expected to be invalid!");
104 
105  o.erase(o.find("expect"));
106  }
107  }
108  else
109  {
110  BOOST_REQUIRE(o.count("rlp") > 0);
111  Transaction txFromRlp;
112  try
113  {
114  bytes stream = importByteArray(o["rlp"].get_str());
115  RLP rlp(stream);
116  txFromRlp = Transaction(rlp.data(), CheckTransaction::Everything);
117  se->verifyTransaction(ImportRequirements::Everything, txFromRlp, bh);
118  if (!txFromRlp.signature().isValid())
119  BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(testname + "transaction from RLP signature is invalid") );
120  }
121  catch(Exception const& _e)
122  {
123  cnote << i.first;
124  cnote << "Transaction Exception: " << diagnostic_information(_e);
125  BOOST_CHECK_MESSAGE(o.count("transaction") == 0, testname + "A transaction object should not be defined because the RLP is invalid!");
126  continue;
127  }
128  catch(...)
129  {
130  BOOST_CHECK_MESSAGE(o.count("transaction") == 0, testname + "A transaction object should not be defined because the RLP is invalid!");
131  continue;
132  }
133 
134  BOOST_REQUIRE_MESSAGE(o.count("transaction") > 0, testname + "Expected a valid transaction!");
135 
136  mObject tObj = o["transaction"].get_obj();
137  h256 txSha3Expected = h256(o["hash"].get_str());
138  Transaction txFromFields(createRLPStreamFromTransactionFields(tObj).out(), CheckTransaction::Everything);
139 
140  //Check the fields restored from RLP to original fields
141  BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), testname + "Data in given RLP not matching the Transaction data!");
142  BOOST_CHECK_MESSAGE(txFromFields.value() == txFromRlp.value(), testname + "Value in given RLP not matching the Transaction value!");
143  BOOST_CHECK_MESSAGE(txFromFields.gasPrice() == txFromRlp.gasPrice(), testname + "GasPrice in given RLP not matching the Transaction gasPrice!");
144  BOOST_CHECK_MESSAGE(txFromFields.gas() == txFromRlp.gas(), testname + "Gas in given RLP not matching the Transaction gas!");
145  BOOST_CHECK_MESSAGE(txFromFields.nonce() == txFromRlp.nonce(), testname + "Nonce in given RLP not matching the Transaction nonce!");
146  BOOST_CHECK_MESSAGE(txFromFields.receiveAddress() == txFromRlp.receiveAddress(), testname + "Receive address in given RLP not matching the Transaction 'to' address!");
147  BOOST_CHECK_MESSAGE(txFromFields.sender() == txFromRlp.sender(), testname + "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!");
148  BOOST_CHECK_MESSAGE(txFromFields.sha3() == txFromRlp.sha3(), testname + "Transaction sha3 hash in given RLP not matching the Transaction 'vrs' signature!");
149  BOOST_CHECK_MESSAGE(txFromFields.sha3() == txSha3Expected, testname + "Expected different transaction hash!");
150  BOOST_CHECK_MESSAGE(txFromFields == txFromRlp, testname + "However, txFromFields != txFromRlp!");
151  BOOST_REQUIRE (o.count("sender") > 0);
152 
153  Address addressReaded = Address(o["sender"].get_str());
154  BOOST_CHECK_MESSAGE(txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded, testname + "Signature address of sender does not match given sender address!");
155  }
156  }//for
158 }//doTransactionTests
159 
160 } }// Namespace Close
161 
162 
163 BOOST_AUTO_TEST_SUITE(TransactionTests)
164 
165 BOOST_AUTO_TEST_CASE(ttMetropolisTests)
166 {
167  dev::test::executeTests("ttMetropolisTest", "/TransactionTests/Metropolis", "/TransactionTestsFiller/Metropolis", dev::test::doTransactionTests);
168 }
169 
170 BOOST_AUTO_TEST_CASE(ttTransactionTestEip155VitaliksTests)
171 {
172  dev::test::executeTests("ttTransactionTestEip155VitaliksTests", "/TransactionTests/EIP155", "/TransactionTestsFiller/EIP155", dev::test::doTransactionTests);
173 }
174 
175 BOOST_AUTO_TEST_CASE(ttTransactionTestEip155VCheck)
176 {
177  dev::test::executeTests("ttTransactionTestVRule", "/TransactionTests/EIP155", "/TransactionTestsFiller/EIP155", dev::test::doTransactionTests);
178 }
179 
180 BOOST_AUTO_TEST_CASE(ttTransactionTestEip155)
181 {
182  dev::test::executeTests("ttTransactionTest", "/TransactionTests/EIP155", "/TransactionTestsFiller/EIP155", dev::test::doTransactionTests);
183 }
184 
185 BOOST_AUTO_TEST_CASE(ttTransactionTestEip155VitaliksTestsHomestead)
186 {
187  dev::test::executeTests("ttTransactionTestEip155VitaliksTests", "/TransactionTests/Homestead", "/TransactionTestsFiller/Homestead", dev::test::doTransactionTests);
188 }
189 
190 BOOST_AUTO_TEST_CASE(ttTransactionTestHomestead)
191 {
192  dev::test::executeTests("ttTransactionTest", "/TransactionTests/Homestead", "/TransactionTestsFiller/Homestead", dev::test::doTransactionTests);
193 }
194 
195 BOOST_AUTO_TEST_CASE(ttTransactionTest)
196 {
197  dev::test::executeTests("ttTransactionTest", "/TransactionTests", "/TransactionTestsFiller", dev::test::doTransactionTests);
198 }
199 
200 BOOST_AUTO_TEST_CASE(ttWrongRLPTransactionHomestead)
201 {
202  std::string fillersPath = dev::test::getTestPath() + "/src/TransactionTestsFiller/Homestead";
203  if (!dev::test::Options::get().filltests)
204  dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests", "/TransactionTestsFiller/Homestead", dev::test::doTransactionTests);
205  else
206  {
208  dev::test::copyFile(fillersPath + "/ttWrongRLPTransaction.json", dev::test::getTestPath() + "/TransactionTests/Homestead/ttWrongRLPTransaction.json");
209  }
210 }
211 
212 BOOST_AUTO_TEST_CASE(ttWrongRLPTransaction)
213 {
214  std::string fillersPath = dev::test::getTestPath() + "/src/TransactionTestsFiller";
215  if (!dev::test::Options::get().filltests)
216  dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests", "/TransactionTestsFiller", dev::test::doTransactionTests);
217  else
218  {
220  dev::test::copyFile(fillersPath + "/ttWrongRLPTransaction.json", dev::test::getTestPath() + "/TransactionTests/ttWrongRLPTransaction.json");
221  }
222 }
223 
224 BOOST_AUTO_TEST_CASE(tt10mbDataFieldHomestead)
225 {
226  if (test::Options::get().bigData)
227  {
228  auto start = chrono::steady_clock::now();
229 
230  dev::test::executeTests("tt10mbDataField", "/TransactionTests/Homestead", "/TransactionTestsFiller/Homestead", dev::test::doTransactionTests);
231 
232  auto end = chrono::steady_clock::now();
233  auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
234  cnote << "test duration: " << duration.count() << " milliseconds.\n";
235  }
236 }
237 
238 BOOST_AUTO_TEST_CASE(tt10mbDataField)
239 {
240  if (test::Options::get().bigData)
241  {
242  auto start = chrono::steady_clock::now();
243 
244  dev::test::executeTests("tt10mbDataField", "/TransactionTests", "/TransactionTestsFiller", dev::test::doTransactionTests);
245 
246  auto end = chrono::steady_clock::now();
247  auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
248  cnote << "test duration: " << duration.count() << " milliseconds.\n";
249  }
250 }
251 
252 BOOST_AUTO_TEST_CASE(userDefinedFile)
253 {
255 }
256 
const Object & get_obj() const
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
BOOST_AUTO_TEST_CASE(ttMetropolisTests)
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
Definition: CommonData.h:54
static Options const & get(int argc=0, char **argv=0)
Get reference to options The first time used, options are parsed with argc, argv. ...
Definition: Options.cpp:203
bytes rlp(_T _t)
Export a single item in RLP format, returning a byte array.
Definition: RLP.h:467
bytesConstRef data() const
The bare data of the RLP.
Definition: RLP.h:97
Encapsulation of a block header.
Definition: BlockHeader.h:95
bytes const & out() const
Read the byte stream.
Definition: RLP.h:433
h160 Address
An Ethereum address: 20 bytes.
Definition: Common.h:62
Address const & sender() const
std::hash for asio::adress
Definition: Common.h:323
int Add(word *C, const word *A, const word *B, size_t N)
Definition: integer.cpp:2143
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
Definition: CommonData.cpp:141
Base class for all exceptions.
Definition: Exceptions.h:39
void userDefinedTest(std::function< void(json_spirit::mValue &, bool)> doTests)
Definition: TestHelper.cpp:386
void doTransactionTests(json_spirit::mValue &_v, bool _fillin)
RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject const &_tObj)
Definition: TestHelper.cpp:499
clock::duration duration
Definition: bench.h:50
void setNumber(u256 const &_v)
Definition: BlockHeader.h:146
std::vector< byte > bytes
Definition: Common.h:75
std::string getTestPath()
Definition: Common.cpp:35
bytes const & data() const
Definition: Transaction.h:131
h256 sha3(IncludeSignature _sig=WithSignature) const
FixedHash< 32 > h256
Definition: FixedHash.h:340
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
void copyFile(std::string const &_source, std::string const &_destination)
Definition: TestHelper.cpp:492
Encodes a transaction, ready to be exported to or freshly imported from RLP.
Definition: Transaction.h:84
mConfig::Object_type mObject
std::string const & genesisInfo(Network _n)
Definition: GenesisInfo.cpp:37
#define cnote
Definition: Log.h:303
boost::error_info< struct tag_comment, std::string > errinfo_comment
Definition: Assertions.h:78
#define BOOST_AUTO_TEST_SUITE_END()
Definition: object.cpp:16
void executeTests(const string &_name, const string &_testPathAppendix, const string &_fillerPathAppendix, std::function< void(json_spirit::mValue &, bool)> doTests, bool _addFillerSuffix)
Definition: TestHelper.cpp:434
bytes importByteArray(std::string const &_str)
Definition: TestHelper.cpp:221
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
Class for writing to an RLP bytestream.
Definition: RLP.h:383
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
u256 toInt(json_spirit::mValue const &_v)
Definition: TestHelper.cpp:195
Helper functions to work with json::spirit and test files.
Address receiveAddress() const
Definition: Transaction.h:122
static void initTest(int _maxTests=1)