You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

transaction_tests.cpp 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. // Copyright (c) 2011-2014 The Bitcoin Core developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "data/tx_invalid.json.h"
  5. #include "data/tx_valid.json.h"
  6. #include "test/test_bitcoin.h"
  7. #include "clientversion.h"
  8. #include "key.h"
  9. #include "keystore.h"
  10. #include "main.h"
  11. #include "script/script.h"
  12. #include "script/script_error.h"
  13. #include "core_io.h"
  14. #include <map>
  15. #include <string>
  16. #include <boost/algorithm/string/classification.hpp>
  17. #include <boost/algorithm/string/split.hpp>
  18. #include <boost/test/unit_test.hpp>
  19. #include <boost/assign/list_of.hpp>
  20. #include "json/json_spirit_writer_template.h"
  21. using namespace std;
  22. using namespace json_spirit;
  23. // In script_tests.cpp
  24. extern Array read_json(const std::string& jsondata);
  25. static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
  26. (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE)
  27. (string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH)
  28. (string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC)
  29. (string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG)
  30. (string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S)
  31. (string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY)
  32. (string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA)
  33. (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY)
  34. (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
  35. (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK);
  36. unsigned int ParseScriptFlags(string strFlags)
  37. {
  38. if (strFlags.empty()) {
  39. return 0;
  40. }
  41. unsigned int flags = 0;
  42. vector<string> words;
  43. boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(","));
  44. BOOST_FOREACH(string word, words)
  45. {
  46. if (!mapFlagNames.count(word))
  47. BOOST_ERROR("Bad test: unknown verification flag '" << word << "'");
  48. flags |= mapFlagNames[word];
  49. }
  50. return flags;
  51. }
  52. string FormatScriptFlags(unsigned int flags)
  53. {
  54. if (flags == 0) {
  55. return "";
  56. }
  57. string ret;
  58. std::map<string, unsigned int>::const_iterator it = mapFlagNames.begin();
  59. while (it != mapFlagNames.end()) {
  60. if (flags & it->second) {
  61. ret += it->first + ",";
  62. }
  63. it++;
  64. }
  65. return ret.substr(0, ret.size() - 1);
  66. }
  67. BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
  68. BOOST_AUTO_TEST_CASE(tx_valid)
  69. {
  70. // Read tests from test/data/tx_valid.json
  71. // Format is an array of arrays
  72. // Inner arrays are either [ "comment" ]
  73. // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, verifyFlags
  74. // ... where all scripts are stringified scripts.
  75. //
  76. // verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
  77. Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid)));
  78. ScriptError err;
  79. BOOST_FOREACH(Value& tv, tests)
  80. {
  81. Array test = tv.get_array();
  82. string strTest = write_string(tv, false);
  83. if (test[0].type() == array_type)
  84. {
  85. if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type)
  86. {
  87. BOOST_ERROR("Bad test: " << strTest);
  88. continue;
  89. }
  90. map<COutPoint, CScript> mapprevOutScriptPubKeys;
  91. Array inputs = test[0].get_array();
  92. bool fValid = true;
  93. BOOST_FOREACH(Value& input, inputs)
  94. {
  95. if (input.type() != array_type)
  96. {
  97. fValid = false;
  98. break;
  99. }
  100. Array vinput = input.get_array();
  101. if (vinput.size() != 3)
  102. {
  103. fValid = false;
  104. break;
  105. }
  106. mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
  107. }
  108. if (!fValid)
  109. {
  110. BOOST_ERROR("Bad test: " << strTest);
  111. continue;
  112. }
  113. string transaction = test[1].get_str();
  114. CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION);
  115. CTransaction tx;
  116. stream >> tx;
  117. CValidationState state;
  118. BOOST_CHECK_MESSAGE(CheckTransaction(tx, state), strTest);
  119. BOOST_CHECK(state.IsValid());
  120. for (unsigned int i = 0; i < tx.vin.size(); i++)
  121. {
  122. if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout))
  123. {
  124. BOOST_ERROR("Bad test: " << strTest);
  125. break;
  126. }
  127. unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
  128. BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
  129. verify_flags, TransactionSignatureChecker(&tx, i), &err),
  130. strTest);
  131. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
  132. }
  133. }
  134. }
  135. }
  136. BOOST_AUTO_TEST_CASE(tx_invalid)
  137. {
  138. // Read tests from test/data/tx_invalid.json
  139. // Format is an array of arrays
  140. // Inner arrays are either [ "comment" ]
  141. // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, verifyFlags
  142. // ... where all scripts are stringified scripts.
  143. //
  144. // verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
  145. Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
  146. ScriptError err;
  147. BOOST_FOREACH(Value& tv, tests)
  148. {
  149. Array test = tv.get_array();
  150. string strTest = write_string(tv, false);
  151. if (test[0].type() == array_type)
  152. {
  153. if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type)
  154. {
  155. BOOST_ERROR("Bad test: " << strTest);
  156. continue;
  157. }
  158. map<COutPoint, CScript> mapprevOutScriptPubKeys;
  159. Array inputs = test[0].get_array();
  160. bool fValid = true;
  161. BOOST_FOREACH(Value& input, inputs)
  162. {
  163. if (input.type() != array_type)
  164. {
  165. fValid = false;
  166. break;
  167. }
  168. Array vinput = input.get_array();
  169. if (vinput.size() != 3)
  170. {
  171. fValid = false;
  172. break;
  173. }
  174. mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
  175. }
  176. if (!fValid)
  177. {
  178. BOOST_ERROR("Bad test: " << strTest);
  179. continue;
  180. }
  181. string transaction = test[1].get_str();
  182. CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION);
  183. CTransaction tx;
  184. stream >> tx;
  185. CValidationState state;
  186. fValid = CheckTransaction(tx, state) && state.IsValid();
  187. for (unsigned int i = 0; i < tx.vin.size() && fValid; i++)
  188. {
  189. if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout))
  190. {
  191. BOOST_ERROR("Bad test: " << strTest);
  192. break;
  193. }
  194. unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
  195. fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
  196. verify_flags, TransactionSignatureChecker(&tx, i), &err);
  197. }
  198. BOOST_CHECK_MESSAGE(!fValid, strTest);
  199. BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err));
  200. }
  201. }
  202. }
  203. BOOST_AUTO_TEST_CASE(basic_transaction_tests)
  204. {
  205. // Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
  206. unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
  207. vector<unsigned char> vch(ch, ch + sizeof(ch) -1);
  208. CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
  209. CMutableTransaction tx;
  210. stream >> tx;
  211. CValidationState state;
  212. BOOST_CHECK_MESSAGE(CheckTransaction(tx, state) && state.IsValid(), "Simple deserialized transaction should be valid.");
  213. // Check that duplicate txins fail
  214. tx.vin.push_back(tx.vin[0]);
  215. BOOST_CHECK_MESSAGE(!CheckTransaction(tx, state) || !state.IsValid(), "Transaction with duplicate txins should be invalid.");
  216. }
  217. //
  218. // Helper: create two dummy transactions, each with
  219. // two outputs. The first has 11 and 50 CENT outputs
  220. // paid to a TX_PUBKEY, the second 21 and 22 CENT outputs
  221. // paid to a TX_PUBKEYHASH.
  222. //
  223. static std::vector<CMutableTransaction>
  224. SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsViewCache& coinsRet)
  225. {
  226. std::vector<CMutableTransaction> dummyTransactions;
  227. dummyTransactions.resize(2);
  228. // Add some keys to the keystore:
  229. CKey key[4];
  230. for (int i = 0; i < 4; i++)
  231. {
  232. key[i].MakeNewKey(i % 2);
  233. keystoreRet.AddKey(key[i]);
  234. }
  235. // Create some dummy input transactions
  236. dummyTransactions[0].vout.resize(2);
  237. dummyTransactions[0].vout[0].nValue = 11*CENT;
  238. dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
  239. dummyTransactions[0].vout[1].nValue = 50*CENT;
  240. dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
  241. coinsRet.ModifyCoins(dummyTransactions[0].GetHash())->FromTx(dummyTransactions[0], 0);
  242. dummyTransactions[1].vout.resize(2);
  243. dummyTransactions[1].vout[0].nValue = 21*CENT;
  244. dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID());
  245. dummyTransactions[1].vout[1].nValue = 22*CENT;
  246. dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID());
  247. coinsRet.ModifyCoins(dummyTransactions[1].GetHash())->FromTx(dummyTransactions[1], 0);
  248. return dummyTransactions;
  249. }
  250. BOOST_AUTO_TEST_CASE(test_Get)
  251. {
  252. CBasicKeyStore keystore;
  253. CCoinsView coinsDummy;
  254. CCoinsViewCache coins(&coinsDummy);
  255. std::vector<CMutableTransaction> dummyTransactions = SetupDummyInputs(keystore, coins);
  256. CMutableTransaction t1;
  257. t1.vin.resize(3);
  258. t1.vin[0].prevout.hash = dummyTransactions[0].GetHash();
  259. t1.vin[0].prevout.n = 1;
  260. t1.vin[0].scriptSig << std::vector<unsigned char>(65, 0);
  261. t1.vin[1].prevout.hash = dummyTransactions[1].GetHash();
  262. t1.vin[1].prevout.n = 0;
  263. t1.vin[1].scriptSig << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4);
  264. t1.vin[2].prevout.hash = dummyTransactions[1].GetHash();
  265. t1.vin[2].prevout.n = 1;
  266. t1.vin[2].scriptSig << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4);
  267. t1.vout.resize(2);
  268. t1.vout[0].nValue = 90*CENT;
  269. t1.vout[0].scriptPubKey << OP_1;
  270. BOOST_CHECK(AreInputsStandard(t1, coins));
  271. BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT);
  272. // Adding extra junk to the scriptSig should make it non-standard:
  273. t1.vin[0].scriptSig << OP_11;
  274. BOOST_CHECK(!AreInputsStandard(t1, coins));
  275. // ... as should not having enough:
  276. t1.vin[0].scriptSig = CScript();
  277. BOOST_CHECK(!AreInputsStandard(t1, coins));
  278. }
  279. BOOST_AUTO_TEST_CASE(test_IsStandard)
  280. {
  281. LOCK(cs_main);
  282. CBasicKeyStore keystore;
  283. CCoinsView coinsDummy;
  284. CCoinsViewCache coins(&coinsDummy);
  285. std::vector<CMutableTransaction> dummyTransactions = SetupDummyInputs(keystore, coins);
  286. CMutableTransaction t;
  287. t.vin.resize(1);
  288. t.vin[0].prevout.hash = dummyTransactions[0].GetHash();
  289. t.vin[0].prevout.n = 1;
  290. t.vin[0].scriptSig << std::vector<unsigned char>(65, 0);
  291. t.vout.resize(1);
  292. t.vout[0].nValue = 90*CENT;
  293. CKey key;
  294. key.MakeNewKey(true);
  295. t.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
  296. string reason;
  297. BOOST_CHECK(IsStandardTx(t, reason));
  298. t.vout[0].nValue = 501; // dust
  299. BOOST_CHECK(!IsStandardTx(t, reason));
  300. t.vout[0].nValue = 601; // not dust
  301. BOOST_CHECK(IsStandardTx(t, reason));
  302. t.vout[0].scriptPubKey = CScript() << OP_1;
  303. BOOST_CHECK(!IsStandardTx(t, reason));
  304. // 80-byte TX_NULL_DATA (standard)
  305. t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
  306. BOOST_CHECK(IsStandardTx(t, reason));
  307. // 81-byte TX_NULL_DATA (non-standard)
  308. t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
  309. BOOST_CHECK(!IsStandardTx(t, reason));
  310. // TX_NULL_DATA w/o PUSHDATA
  311. t.vout.resize(1);
  312. t.vout[0].scriptPubKey = CScript() << OP_RETURN;
  313. BOOST_CHECK(IsStandardTx(t, reason));
  314. // Only one TX_NULL_DATA permitted in all cases
  315. t.vout.resize(2);
  316. t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
  317. t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
  318. BOOST_CHECK(!IsStandardTx(t, reason));
  319. t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
  320. t.vout[1].scriptPubKey = CScript() << OP_RETURN;
  321. BOOST_CHECK(!IsStandardTx(t, reason));
  322. t.vout[0].scriptPubKey = CScript() << OP_RETURN;
  323. t.vout[1].scriptPubKey = CScript() << OP_RETURN;
  324. BOOST_CHECK(!IsStandardTx(t, reason));
  325. }
  326. BOOST_AUTO_TEST_SUITE_END()