diff options
Diffstat (limited to 'src/test')
94 files changed, 2296 insertions, 593 deletions
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index a8c3c4ebb9..c62e6ae838 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,7 @@ #include "script/sign.h" #include "serialize.h" #include "util.h" +#include "validation.h" #include "test/test_bitcoin.h" @@ -22,17 +23,16 @@ #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> -// Tests this internal-to-main.cpp method: -extern bool AddOrphanTx(const CTransaction& tx, NodeId peer); +// Tests these internal-to-net_processing.cpp methods: +extern bool AddOrphanTx(const CTransactionRef& tx, NodeId peer); extern void EraseOrphansFor(NodeId peer); extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans); struct COrphanTx { - CTransaction tx; + CTransactionRef tx; NodeId fromPeer; int64_t nTimeExpire; }; extern std::map<uint256, COrphanTx> mapOrphanTransactions; -extern std::map<uint256, std::set<uint256> > mapOrphanTransactionsByPrev; CService ip(uint32_t i) { @@ -47,14 +47,17 @@ BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup) BOOST_AUTO_TEST_CASE(DoS_banning) { + std::atomic<bool> interruptDummy(false); + connman->ClearBanned(); CAddress addr1(ip(0xa0b0c001), NODE_NONE); CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, "", true); dummyNode1.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode1, *connman); dummyNode1.nVersion = 1; + dummyNode1.fSuccessfullyConnected = true; Misbehaving(dummyNode1.GetId(), 100); // Should get banned - SendMessages(&dummyNode1, *connman); + SendMessages(&dummyNode1, *connman, interruptDummy); BOOST_CHECK(connman->IsBanned(addr1)); BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned @@ -63,38 +66,44 @@ BOOST_AUTO_TEST_CASE(DoS_banning) dummyNode2.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode2, *connman); dummyNode2.nVersion = 1; + dummyNode2.fSuccessfullyConnected = true; Misbehaving(dummyNode2.GetId(), 50); - SendMessages(&dummyNode2, *connman); + SendMessages(&dummyNode2, *connman, interruptDummy); BOOST_CHECK(!connman->IsBanned(addr2)); // 2 not banned yet... BOOST_CHECK(connman->IsBanned(addr1)); // ... but 1 still should be Misbehaving(dummyNode2.GetId(), 50); - SendMessages(&dummyNode2, *connman); + SendMessages(&dummyNode2, *connman, interruptDummy); BOOST_CHECK(connman->IsBanned(addr2)); } BOOST_AUTO_TEST_CASE(DoS_banscore) { + std::atomic<bool> interruptDummy(false); + connman->ClearBanned(); - mapArgs["-banscore"] = "111"; // because 11 is my favorite number + ForceSetArg("-banscore", "111"); // because 11 is my favorite number CAddress addr1(ip(0xa0b0c001), NODE_NONE); CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, "", true); dummyNode1.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode1, *connman); dummyNode1.nVersion = 1; + dummyNode1.fSuccessfullyConnected = true; Misbehaving(dummyNode1.GetId(), 100); - SendMessages(&dummyNode1, *connman); + SendMessages(&dummyNode1, *connman, interruptDummy); BOOST_CHECK(!connman->IsBanned(addr1)); Misbehaving(dummyNode1.GetId(), 10); - SendMessages(&dummyNode1, *connman); + SendMessages(&dummyNode1, *connman, interruptDummy); BOOST_CHECK(!connman->IsBanned(addr1)); Misbehaving(dummyNode1.GetId(), 1); - SendMessages(&dummyNode1, *connman); + SendMessages(&dummyNode1, *connman, interruptDummy); BOOST_CHECK(connman->IsBanned(addr1)); - mapArgs.erase("-banscore"); + ForceSetArg("-banscore", std::to_string(DEFAULT_BANSCORE_THRESHOLD)); } BOOST_AUTO_TEST_CASE(DoS_bantime) { + std::atomic<bool> interruptDummy(false); + connman->ClearBanned(); int64_t nStartTime = GetTime(); SetMockTime(nStartTime); // Overrides future calls to GetTime() @@ -104,9 +113,10 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) dummyNode.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode, *connman); dummyNode.nVersion = 1; + dummyNode.fSuccessfullyConnected = true; Misbehaving(dummyNode.GetId(), 100); - SendMessages(&dummyNode, *connman); + SendMessages(&dummyNode, *connman, interruptDummy); BOOST_CHECK(connman->IsBanned(addr)); SetMockTime(nStartTime+60*60); @@ -116,7 +126,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) BOOST_CHECK(!connman->IsBanned(addr)); } -CTransaction RandomOrphan() +CTransactionRef RandomOrphan() { std::map<uint256, COrphanTx>::iterator it; it = mapOrphanTransactions.lower_bound(GetRandHash()); @@ -144,30 +154,30 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); - AddOrphanTx(tx, i); + AddOrphanTx(MakeTransactionRef(tx), i); } // ... and 50 that depend on other orphans: for (int i = 0; i < 50; i++) { - CTransaction txPrev = RandomOrphan(); + CTransactionRef txPrev = RandomOrphan(); CMutableTransaction tx; tx.vin.resize(1); tx.vin[0].prevout.n = 0; - tx.vin[0].prevout.hash = txPrev.GetHash(); + tx.vin[0].prevout.hash = txPrev->GetHash(); tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); - SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL); + SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL); - AddOrphanTx(tx, i); + AddOrphanTx(MakeTransactionRef(tx), i); } // This really-big orphan should be ignored: for (int i = 0; i < 10; i++) { - CTransaction txPrev = RandomOrphan(); + CTransactionRef txPrev = RandomOrphan(); CMutableTransaction tx; tx.vout.resize(1); @@ -177,15 +187,15 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) for (unsigned int j = 0; j < tx.vin.size(); j++) { tx.vin[j].prevout.n = j; - tx.vin[j].prevout.hash = txPrev.GetHash(); + tx.vin[j].prevout.hash = txPrev->GetHash(); } - SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL); + SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL); // Re-use same signature for other inputs // (they don't have to be valid for this test) for (unsigned int j = 1; j < tx.vin.size(); j++) tx.vin[j].scriptSig = tx.vin[0].scriptSig; - BOOST_CHECK(!AddOrphanTx(tx, i)); + BOOST_CHECK(!AddOrphanTx(MakeTransactionRef(tx), i)); } // Test EraseOrphansFor: @@ -203,7 +213,6 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) BOOST_CHECK(mapOrphanTransactions.size() <= 10); LimitOrphanTxSize(0); BOOST_CHECK(mapOrphanTransactions.empty()); - BOOST_CHECK(mapOrphanTransactionsByPrev.empty()); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index adff09f754..322addc9f6 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "addrman.h" @@ -10,8 +10,6 @@ #include "netbase.h" #include "random.h" -using namespace std; - class CAddrManTest : public CAddrMan { uint64_t state; @@ -299,7 +297,7 @@ BOOST_AUTO_TEST_CASE(addrman_find) // Test 18; Find does not discriminate by port number. CAddrInfo* info2 = addrman.Find(addr2); BOOST_CHECK(info2); - if (info2) + if (info2 && info1) BOOST_CHECK(info2->ToString() == info1->ToString()); // Test 19: Find returns another IP matching what we searched on. @@ -365,7 +363,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) // Test 22: Sanity check, GetAddr should never return anything if addrman // is empty. BOOST_CHECK(addrman.size() == 0); - vector<CAddress> vAddr1 = addrman.GetAddr(); + std::vector<CAddress> vAddr1 = addrman.GetAddr(); BOOST_CHECK(vAddr1.size() == 0); CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE); @@ -401,7 +399,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) int octet1 = i % 256; int octet2 = (i / 256) % 256; int octet3 = (i / (256 * 2)) % 256; - string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; + std::string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; CAddress addr = CAddress(ResolveService(strAddr), NODE_NONE); // Ensure that for all addrs in addrman, isTerrible == false. @@ -410,7 +408,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) if (i % 8 == 0) addrman.Good(addr); } - vector<CAddress> vAddr = addrman.GetAddr(); + std::vector<CAddress> vAddr = addrman.GetAddr(); size_t percent23 = (addrman.size() * 23) / 100; BOOST_CHECK(vAddr.size() == percent23); @@ -452,7 +450,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) BOOST_CHECK(info1.GetKey() != info2.GetKey()); BOOST_CHECK(info1.GetTriedBucket(nKey1) != info2.GetTriedBucket(nKey1)); - set<int> buckets; + std::set<int> buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( CAddress(ResolveService("250.1.1." + boost::to_string(i)), NODE_NONE), @@ -505,7 +503,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) BOOST_CHECK(info1.GetKey() != info2.GetKey()); BOOST_CHECK(info1.GetNewBucket(nKey1) == info2.GetNewBucket(nKey1)); - set<int> buckets; + std::set<int> buckets; for (int i = 0; i < 255; i++) { CAddrInfo infoi = CAddrInfo( CAddress(ResolveService("250.1.1." + boost::to_string(i)), NODE_NONE), diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 77e9df5d82..3f15a0dec1 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index b19d2faea0..45ae7d4636 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index ac3ab4c83f..6cd998990b 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58) std::vector<unsigned char> sourcedata = ParseHex(test[0].get_str()); std::string base58string = test[1].get_str(); BOOST_CHECK_MESSAGE( - EncodeBase58(begin_ptr(sourcedata), end_ptr(sourcedata)) == base58string, + EncodeBase58(sourcedata.data(), sourcedata.data() + sourcedata.size()) == base58string, strTest); } } diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 7f1c2a32dd..c148ad6d82 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -78,6 +78,15 @@ TestVector test2 = "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j", 0); +TestVector test3 = + TestVector("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be") + ("xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13", + "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6", + 0x80000000) + ("xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y", + "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L", + 0); + void RunTest(const TestVector &test) { std::vector<unsigned char> seed = ParseHex(test.strHexMaster); CExtKey key; @@ -146,4 +155,8 @@ BOOST_AUTO_TEST_CASE(bip32_test2) { RunTest(test2); } +BOOST_AUTO_TEST_CASE(bip32_test3) { + RunTest(test3); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py index 1c090b3f3f..e2087187aa 100755 --- a/src/test/bitcoin-util-test.py +++ b/src/test/bitcoin-util-test.py @@ -5,7 +5,6 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from __future__ import division,print_function,unicode_literals import os -import sys import bctest import buildenv import argparse diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index b013cda6d7..311ac024f3 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -11,6 +11,8 @@ #include <boost/test/unit_test.hpp> +std::vector<std::pair<uint256, CTransactionRef>> extra_txn; + struct RegtestingSetup : public TestingSetup { RegtestingSetup() : TestingSetup(CBaseChainParams::REGTEST) {} }; @@ -73,29 +75,35 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest) stream >> shortIDs2; PartiallyDownloadedBlock partialBlock(&pool); - BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK); BOOST_CHECK( partialBlock.IsTxAvailable(0)); BOOST_CHECK(!partialBlock.IsTxAvailable(1)); BOOST_CHECK( partialBlock.IsTxAvailable(2)); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); - std::vector<CTransactionRef> removed; - pool.removeRecursive(*block.vtx[2], &removed); - BOOST_CHECK_EQUAL(removed.size(), 1); + size_t poolSize = pool.size(); + pool.removeRecursive(*block.vtx[2]); + BOOST_CHECK_EQUAL(pool.size(), poolSize - 1); CBlock block2; - std::vector<CTransactionRef> vtx_missing; - BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions + { + PartiallyDownloadedBlock tmp = partialBlock; + BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_INVALID); // No transactions + partialBlock = tmp; + } - vtx_missing.push_back(block.vtx[2]); // Wrong transaction - partialBlock.FillBlock(block2, vtx_missing); // Current implementation doesn't check txn here, but don't require that + // Wrong transaction + { + PartiallyDownloadedBlock tmp = partialBlock; + partialBlock.FillBlock(block2, {block.vtx[2]}); // Current implementation doesn't check txn here, but don't require that + partialBlock = tmp; + } bool mutated; BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated)); - vtx_missing[0] = block.vtx[1]; CBlock block3; - BOOST_CHECK(partialBlock.FillBlock(block3, vtx_missing) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[1]}) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString()); BOOST_CHECK(!mutated); @@ -173,7 +181,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) stream >> shortIDs2; PartiallyDownloadedBlock partialBlock(&pool); - BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK); BOOST_CHECK(!partialBlock.IsTxAvailable(0)); BOOST_CHECK( partialBlock.IsTxAvailable(1)); BOOST_CHECK( partialBlock.IsTxAvailable(2)); @@ -181,17 +189,24 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); CBlock block2; - std::vector<CTransactionRef> vtx_missing; - BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions + { + PartiallyDownloadedBlock tmp = partialBlock; + BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_INVALID); // No transactions + partialBlock = tmp; + } - vtx_missing.push_back(block.vtx[1]); // Wrong transaction - partialBlock.FillBlock(block2, vtx_missing); // Current implementation doesn't check txn here, but don't require that + // Wrong transaction + { + PartiallyDownloadedBlock tmp = partialBlock; + partialBlock.FillBlock(block2, {block.vtx[1]}); // Current implementation doesn't check txn here, but don't require that + partialBlock = tmp; + } bool mutated; BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated)); - vtx_missing[0] = block.vtx[0]; CBlock block3; - BOOST_CHECK(partialBlock.FillBlock(block3, vtx_missing) == READ_STATUS_OK); + PartiallyDownloadedBlock partialBlockCopy = partialBlock; + BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[0]}) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString()); BOOST_CHECK(!mutated); @@ -200,7 +215,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) block.vtx.clear(); block2.vtx.clear(); block3.vtx.clear(); - BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); + BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); // + 1 because of partialBlockCopy. } BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); } @@ -232,7 +247,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) stream >> shortIDs2; PartiallyDownloadedBlock partialBlock(&pool); - BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK); BOOST_CHECK( partialBlock.IsTxAvailable(0)); BOOST_CHECK( partialBlock.IsTxAvailable(1)); BOOST_CHECK( partialBlock.IsTxAvailable(2)); @@ -240,8 +255,8 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); CBlock block2; - std::vector<CTransactionRef> vtx_missing; - BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK); + PartiallyDownloadedBlock partialBlockCopy = partialBlock; + BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); bool mutated; BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString()); @@ -250,7 +265,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) txhash = block.vtx[1]->GetHash(); block.vtx.clear(); block2.vtx.clear(); - BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); + BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); // + 1 because of partialBlockCopy. } BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0); } @@ -287,7 +302,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) stream >> shortIDs2; PartiallyDownloadedBlock partialBlock(&pool); - BOOST_CHECK(partialBlock.InitData(shortIDs2) == READ_STATUS_OK); + BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK); BOOST_CHECK(partialBlock.IsTxAvailable(0)); CBlock block2; diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index b15ff9e44b..27bc92d670 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -21,8 +21,6 @@ #include <boost/test/unit_test.hpp> #include <boost/tuple/tuple.hpp> -using namespace std; - BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize) @@ -43,8 +41,8 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << filter; - vector<unsigned char> vch = ParseHex("03614e9b050000000000000001"); - vector<char> expected(vch.size()); + std::vector<unsigned char> vch = ParseHex("03614e9b050000000000000001"); + std::vector<char> expected(vch.size()); for (unsigned int i = 0; i < vch.size(); i++) expected[i] = (char)vch[i]; @@ -75,8 +73,8 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << filter; - vector<unsigned char> vch = ParseHex("03ce4299050000000100008001"); - vector<char> expected(vch.size()); + std::vector<unsigned char> vch = ParseHex("03ce4299050000000100008001"); + std::vector<char> expected(vch.size()); for (unsigned int i = 0; i < vch.size(); i++) expected[i] = (char)vch[i]; @@ -86,24 +84,24 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak) BOOST_AUTO_TEST_CASE(bloom_create_insert_key) { - string strSecret = string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C"); + std::string strSecret = std::string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C"); CBitcoinSecret vchSecret; BOOST_CHECK(vchSecret.SetString(strSecret)); CKey key = vchSecret.GetKey(); CPubKey pubkey = key.GetPubKey(); - vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end()); + std::vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end()); CBloomFilter filter(2, 0.001, 0, BLOOM_UPDATE_ALL); filter.insert(vchPubKey); uint160 hash = pubkey.GetID(); - filter.insert(vector<unsigned char>(hash.begin(), hash.end())); + filter.insert(std::vector<unsigned char>(hash.begin(), hash.end())); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << filter; - vector<unsigned char> vch = ParseHex("038fc16b080000000000000001"); - vector<char> expected(vch.size()); + std::vector<unsigned char> vch = ParseHex("038fc16b080000000000000001"); + std::vector<char> expected(vch.size()); for (unsigned int i = 0; i < vch.size(); i++) expected[i] = (char)vch[i]; @@ -119,7 +117,7 @@ BOOST_AUTO_TEST_CASE(bloom_match) // and one which spends it (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436) 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}; - vector<unsigned char> vch(ch, ch + sizeof(ch) -1); + std::vector<unsigned char> vch(ch, ch + sizeof(ch) -1); CDataStream spendStream(vch, SER_DISK, CLIENT_VERSION); CTransaction spendingTx(deserialize, spendStream); @@ -156,7 +154,7 @@ BOOST_AUTO_TEST_CASE(bloom_match) filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL); COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0); { - vector<unsigned char> data(32 + sizeof(unsigned int)); + std::vector<unsigned char> data(32 + sizeof(unsigned int)); memcpy(&data[0], prevOutPoint.hash.begin(), 32); memcpy(&data[32], &prevOutPoint.n, sizeof(unsigned int)); filter.insert(data); @@ -196,13 +194,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; + std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8); - vector<uint256> vMatched; - vector<unsigned int> vIndex; + std::vector<uint256> vMatched; + std::vector<unsigned int> vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) @@ -242,13 +240,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_2) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; + std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); - vector<uint256> vMatched; - vector<unsigned int> vIndex; + std::vector<uint256> vMatched; + std::vector<unsigned int> vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) @@ -297,13 +295,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; + std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); - vector<uint256> vMatched; - vector<unsigned int> vIndex; + std::vector<uint256> vMatched; + std::vector<unsigned int> vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) @@ -353,8 +351,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0); - vector<uint256> vMatched; - vector<unsigned int> vIndex; + std::vector<uint256> vMatched; + std::vector<unsigned int> vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) @@ -363,8 +361,8 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize) CDataStream merkleStream(SER_NETWORK, PROTOCOL_VERSION); merkleStream << merkleBlock; - vector<unsigned char> vch = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101"); - vector<char> expected(vch.size()); + std::vector<unsigned char> vch = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101"); + std::vector<char> expected(vch.size()); for (unsigned int i = 0; i < vch.size(); i++) expected[i] = (char)vch[i]; @@ -388,13 +386,13 @@ BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash()); BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1); - pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; + std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154")); BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6); - vector<uint256> vMatched; - vector<unsigned int> vIndex; + std::vector<uint256> vMatched; + std::vector<unsigned int> vIndex; BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot); BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size()); for (unsigned int i = 0; i < vMatched.size(); i++) diff --git a/src/test/bswap_tests.cpp b/src/test/bswap_tests.cpp new file mode 100644 index 0000000000..7b3134d327 --- /dev/null +++ b/src/test/bswap_tests.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "compat/byteswap.h" +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(bswap_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(bswap_tests) +{ + // Sibling in bitcoin/src/qt/test/compattests.cpp + uint16_t u1 = 0x1234; + uint32_t u2 = 0x56789abc; + uint64_t u3 = 0xdef0123456789abc; + uint16_t e1 = 0x3412; + uint32_t e2 = 0xbc9a7856; + uint64_t e3 = 0xbc9a78563412f0de; + BOOST_CHECK(bswap_16(u1) == e1); + BOOST_CHECK(bswap_32(u2) == e2); + BOOST_CHECK(bswap_64(u3) == e3); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 6c0a56c10e..31ed1a50b9 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -1,10 +1,11 @@ -// Copyright (c) 2014-2015 The Bitcoin Core developers +// Copyright (c) 2014-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "coins.h" #include "script/standard.h" #include "uint256.h" +#include "undo.h" #include "utilstrencodings.h" #include "test/test_bitcoin.h" #include "test/test_random.h" @@ -16,6 +17,9 @@ #include <boost/test/unit_test.hpp> +bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out); +void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight); + namespace { class CCoinsViewTest : public CCoinsView @@ -80,6 +84,8 @@ public: BOOST_CHECK_EQUAL(DynamicMemoryUsage(), ret); } + CCoinsMap& map() { return cacheCoins; } + size_t& usage() { return cachedCoinsUsage; } }; } @@ -211,6 +217,22 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) BOOST_CHECK(missed_an_entry); } +typedef std::tuple<CTransaction,CTxUndo,CCoins> TxData; +// Store of all necessary tx and undo data for next test +std::map<uint256, TxData> alltxs; + +TxData &FindRandomFrom(const std::set<uint256> &txidset) { + assert(txidset.size()); + std::set<uint256>::iterator txIt = txidset.lower_bound(GetRandHash()); + if (txIt == txidset.end()) { + txIt = txidset.begin(); + } + std::map<uint256, TxData>::iterator txdit = alltxs.find(*txIt); + assert(txdit != alltxs.end()); + return txdit->second; +} + + // This test is similar to the previous test // except the emphasis is on testing the functionality of UpdateCoins // random txs are created and UpdateCoins is used to update the cache stack @@ -227,77 +249,139 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) std::vector<CCoinsViewCacheTest*> stack; // A stack of CCoinsViewCaches on top. stack.push_back(new CCoinsViewCacheTest(&base)); // Start with one cache. - // Track the txids we've used and whether they have been spent or not - std::map<uint256, CAmount> coinbaseids; - std::set<uint256> alltxids; + // Track the txids we've used in various sets + std::set<uint256> coinbaseids; + std::set<uint256> disconnectedids; std::set<uint256> duplicateids; + std::set<uint256> utxoset; for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { - { + uint32_t randiter = insecure_rand(); + + // 19/20 txs add a new transaction + if (randiter % 20 < 19) { CMutableTransaction tx; tx.vin.resize(1); tx.vout.resize(1); tx.vout[0].nValue = i; //Keep txs unique unless intended to duplicate unsigned int height = insecure_rand(); + CCoins oldcoins; - // 1/10 times create a coinbase - if (insecure_rand() % 10 == 0 || coinbaseids.size() < 10) { - // 1/100 times create a duplicate coinbase + // 2/20 times create a new coinbase + if (randiter % 20 < 2 || coinbaseids.size() < 10) { + // 1/10 of those times create a duplicate coinbase if (insecure_rand() % 10 == 0 && coinbaseids.size()) { - std::map<uint256, CAmount>::iterator coinbaseIt = coinbaseids.lower_bound(GetRandHash()); - if (coinbaseIt == coinbaseids.end()) { - coinbaseIt = coinbaseids.begin(); - } - //Use same random value to have same hash and be a true duplicate - tx.vout[0].nValue = coinbaseIt->second; - assert(tx.GetHash() == coinbaseIt->first); - duplicateids.insert(coinbaseIt->first); + TxData &txd = FindRandomFrom(coinbaseids); + // Reuse the exact same coinbase + tx = std::get<0>(txd); + // shouldn't be available for reconnection if its been duplicated + disconnectedids.erase(tx.GetHash()); + + duplicateids.insert(tx.GetHash()); } else { - coinbaseids[tx.GetHash()] = tx.vout[0].nValue; + coinbaseids.insert(tx.GetHash()); } assert(CTransaction(tx).IsCoinBase()); } - // 9/10 times create a regular tx + + // 17/20 times reconnect previous or add a regular tx else { + uint256 prevouthash; - // equally likely to spend coinbase or non coinbase - std::set<uint256>::iterator txIt = alltxids.lower_bound(GetRandHash()); - if (txIt == alltxids.end()) { - txIt = alltxids.begin(); + // 1/20 times reconnect a previously disconnected tx + if (randiter % 20 == 2 && disconnectedids.size()) { + TxData &txd = FindRandomFrom(disconnectedids); + tx = std::get<0>(txd); + prevouthash = tx.vin[0].prevout.hash; + if (!CTransaction(tx).IsCoinBase() && !utxoset.count(prevouthash)) { + disconnectedids.erase(tx.GetHash()); + continue; + } + + // If this tx is already IN the UTXO, then it must be a coinbase, and it must be a duplicate + if (utxoset.count(tx.GetHash())) { + assert(CTransaction(tx).IsCoinBase()); + assert(duplicateids.count(tx.GetHash())); + } + disconnectedids.erase(tx.GetHash()); } - prevouthash = *txIt; - // Construct the tx to spend the coins of prevouthash - tx.vin[0].prevout.hash = prevouthash; - tx.vin[0].prevout.n = 0; + // 16/20 times create a regular tx + else { + TxData &txd = FindRandomFrom(utxoset); + prevouthash = std::get<0>(txd).GetHash(); + // Construct the tx to spend the coins of prevouthash + tx.vin[0].prevout.hash = prevouthash; + tx.vin[0].prevout.n = 0; + assert(!CTransaction(tx).IsCoinBase()); + } + // In this simple test coins only have two states, spent or unspent, save the unspent state to restore + oldcoins = result[prevouthash]; // Update the expected result of prevouthash to know these coins are spent - CCoins& oldcoins = result[prevouthash]; - oldcoins.Clear(); + result[prevouthash].Clear(); - // It is of particular importance here that once we spend a coinbase tx hash - // it is no longer available to be duplicated (or spent again) - // BIP 34 in conjunction with enforcing BIP 30 (at least until BIP 34 was active) - // results in the fact that no coinbases were duplicated after they were already spent - alltxids.erase(prevouthash); - coinbaseids.erase(prevouthash); + utxoset.erase(prevouthash); // The test is designed to ensure spending a duplicate coinbase will work properly // if that ever happens and not resurrect the previously overwritten coinbase if (duplicateids.count(prevouthash)) spent_a_duplicate_coinbase = true; - assert(!CTransaction(tx).IsCoinBase()); } - // Track this tx to possibly spend later - alltxids.insert(tx.GetHash()); - // Update the expected result to know about the new output coins - CCoins &coins = result[tx.GetHash()]; - coins.FromTx(tx, height); + result[tx.GetHash()].FromTx(tx, height); + + // Call UpdateCoins on the top cache + CTxUndo undo; + UpdateCoins(tx, *(stack.back()), undo, height); + + // Update the utxo set for future spends + utxoset.insert(tx.GetHash()); + + // Track this tx and undo info to use later + alltxs.insert(std::make_pair(tx.GetHash(),std::make_tuple(tx,undo,oldcoins))); + } + + //1/20 times undo a previous transaction + else if (utxoset.size()) { + TxData &txd = FindRandomFrom(utxoset); - UpdateCoins(tx, *(stack.back()), height); + CTransaction &tx = std::get<0>(txd); + CTxUndo &undo = std::get<1>(txd); + CCoins &origcoins = std::get<2>(txd); + + uint256 undohash = tx.GetHash(); + + // Update the expected result + // Remove new outputs + result[undohash].Clear(); + // If not coinbase restore prevout + if (!tx.IsCoinBase()) { + result[tx.vin[0].prevout.hash] = origcoins; + } + + // Disconnect the tx from the current UTXO + // See code in DisconnectBlock + // remove outputs + { + CCoinsModifier outs = stack.back()->ModifyCoins(undohash); + outs->Clear(); + } + // restore inputs + if (!tx.IsCoinBase()) { + const COutPoint &out = tx.vin[0].prevout; + const CTxInUndo &undoin = undo.vprevout[0]; + ApplyTxInUndo(undoin, *(stack.back()), out); + } + // Store as a candidate for reconnection + disconnectedids.insert(undohash); + + // Update the utxoset + utxoset.erase(undohash); + if (!tx.IsCoinBase()) + utxoset.insert(tx.vin[0].prevout.hash); } // Once every 1000 iterations and at the end, verify the full cache. @@ -306,9 +390,9 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) const CCoins* coins = stack.back()->AccessCoins(it->first); if (coins) { BOOST_CHECK(*coins == it->second); - } else { + } else { BOOST_CHECK(it->second.IsPruned()); - } + } } } @@ -332,7 +416,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) tip = stack.back(); } stack.push_back(new CCoinsViewCacheTest(tip)); - } + } } } @@ -415,4 +499,378 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization) } } +const static uint256 TXID; +const static CAmount PRUNED = -1; +const static CAmount ABSENT = -2; +const static CAmount FAIL = -3; +const static CAmount VALUE1 = 100; +const static CAmount VALUE2 = 200; +const static CAmount VALUE3 = 300; +const static char DIRTY = CCoinsCacheEntry::DIRTY; +const static char FRESH = CCoinsCacheEntry::FRESH; +const static char NO_ENTRY = -1; + +const static auto FLAGS = {char(0), FRESH, DIRTY, char(DIRTY | FRESH)}; +const static auto CLEAN_FLAGS = {char(0), FRESH}; +const static auto ABSENT_FLAGS = {NO_ENTRY}; + +void SetCoinsValue(CAmount value, CCoins& coins) +{ + assert(value != ABSENT); + coins.Clear(); + assert(coins.IsPruned()); + if (value != PRUNED) { + coins.vout.emplace_back(); + coins.vout.back().nValue = value; + assert(!coins.IsPruned()); + } +} + +size_t InsertCoinsMapEntry(CCoinsMap& map, CAmount value, char flags) +{ + if (value == ABSENT) { + assert(flags == NO_ENTRY); + return 0; + } + assert(flags != NO_ENTRY); + CCoinsCacheEntry entry; + entry.flags = flags; + SetCoinsValue(value, entry.coins); + auto inserted = map.emplace(TXID, std::move(entry)); + assert(inserted.second); + return inserted.first->second.coins.DynamicMemoryUsage(); +} + +void GetCoinsMapEntry(const CCoinsMap& map, CAmount& value, char& flags) +{ + auto it = map.find(TXID); + if (it == map.end()) { + value = ABSENT; + flags = NO_ENTRY; + } else { + if (it->second.coins.IsPruned()) { + assert(it->second.coins.vout.size() == 0); + value = PRUNED; + } else { + assert(it->second.coins.vout.size() == 1); + value = it->second.coins.vout[0].nValue; + } + flags = it->second.flags; + assert(flags != NO_ENTRY); + } +} + +void WriteCoinsViewEntry(CCoinsView& view, CAmount value, char flags) +{ + CCoinsMap map; + InsertCoinsMapEntry(map, value, flags); + view.BatchWrite(map, {}); +} + +class SingleEntryCacheTest +{ +public: + SingleEntryCacheTest(CAmount base_value, CAmount cache_value, char cache_flags) + { + WriteCoinsViewEntry(base, base_value, base_value == ABSENT ? NO_ENTRY : DIRTY); + cache.usage() += InsertCoinsMapEntry(cache.map(), cache_value, cache_flags); + } + + CCoinsView root; + CCoinsViewCacheTest base{&root}; + CCoinsViewCacheTest cache{&base}; +}; + +void CheckAccessCoins(CAmount base_value, CAmount cache_value, CAmount expected_value, char cache_flags, char expected_flags) +{ + SingleEntryCacheTest test(base_value, cache_value, cache_flags); + test.cache.AccessCoins(TXID); + test.cache.SelfTest(); + + CAmount result_value; + char result_flags; + GetCoinsMapEntry(test.cache.map(), result_value, result_flags); + BOOST_CHECK_EQUAL(result_value, expected_value); + BOOST_CHECK_EQUAL(result_flags, expected_flags); +} + +BOOST_AUTO_TEST_CASE(ccoins_access) +{ + /* Check AccessCoin behavior, requesting a coin from a cache view layered on + * top of a base view, and checking the resulting entry in the cache after + * the access. + * + * Base Cache Result Cache Result + * Value Value Value Flags Flags + */ + CheckAccessCoins(ABSENT, ABSENT, ABSENT, NO_ENTRY , NO_ENTRY ); + CheckAccessCoins(ABSENT, PRUNED, PRUNED, 0 , 0 ); + CheckAccessCoins(ABSENT, PRUNED, PRUNED, FRESH , FRESH ); + CheckAccessCoins(ABSENT, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckAccessCoins(ABSENT, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoins(ABSENT, VALUE2, VALUE2, 0 , 0 ); + CheckAccessCoins(ABSENT, VALUE2, VALUE2, FRESH , FRESH ); + CheckAccessCoins(ABSENT, VALUE2, VALUE2, DIRTY , DIRTY ); + CheckAccessCoins(ABSENT, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoins(PRUNED, ABSENT, PRUNED, NO_ENTRY , FRESH ); + CheckAccessCoins(PRUNED, PRUNED, PRUNED, 0 , 0 ); + CheckAccessCoins(PRUNED, PRUNED, PRUNED, FRESH , FRESH ); + CheckAccessCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckAccessCoins(PRUNED, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoins(PRUNED, VALUE2, VALUE2, 0 , 0 ); + CheckAccessCoins(PRUNED, VALUE2, VALUE2, FRESH , FRESH ); + CheckAccessCoins(PRUNED, VALUE2, VALUE2, DIRTY , DIRTY ); + CheckAccessCoins(PRUNED, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoins(VALUE1, ABSENT, VALUE1, NO_ENTRY , 0 ); + CheckAccessCoins(VALUE1, PRUNED, PRUNED, 0 , 0 ); + CheckAccessCoins(VALUE1, PRUNED, PRUNED, FRESH , FRESH ); + CheckAccessCoins(VALUE1, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckAccessCoins(VALUE1, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoins(VALUE1, VALUE2, VALUE2, 0 , 0 ); + CheckAccessCoins(VALUE1, VALUE2, VALUE2, FRESH , FRESH ); + CheckAccessCoins(VALUE1, VALUE2, VALUE2, DIRTY , DIRTY ); + CheckAccessCoins(VALUE1, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); +} + +void CheckModifyCoins(CAmount base_value, CAmount cache_value, CAmount modify_value, CAmount expected_value, char cache_flags, char expected_flags) +{ + SingleEntryCacheTest test(base_value, cache_value, cache_flags); + SetCoinsValue(modify_value, *test.cache.ModifyCoins(TXID)); + test.cache.SelfTest(); + + CAmount result_value; + char result_flags; + GetCoinsMapEntry(test.cache.map(), result_value, result_flags); + BOOST_CHECK_EQUAL(result_value, expected_value); + BOOST_CHECK_EQUAL(result_flags, expected_flags); +}; + +BOOST_AUTO_TEST_CASE(ccoins_modify) +{ + /* Check ModifyCoin behavior, requesting a coin from a cache view layered on + * top of a base view, writing a modification to the coin, and then checking + * the resulting entry in the cache after the modification. + * + * Base Cache Write Result Cache Result + * Value Value Value Value Flags Flags + */ + CheckModifyCoins(ABSENT, ABSENT, PRUNED, ABSENT, NO_ENTRY , NO_ENTRY ); + CheckModifyCoins(ABSENT, ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY|FRESH); + CheckModifyCoins(ABSENT, PRUNED, PRUNED, PRUNED, 0 , DIRTY ); + CheckModifyCoins(ABSENT, PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckModifyCoins(ABSENT, PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckModifyCoins(ABSENT, PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckModifyCoins(ABSENT, PRUNED, VALUE3, VALUE3, 0 , DIRTY ); + CheckModifyCoins(ABSENT, PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH); + CheckModifyCoins(ABSENT, PRUNED, VALUE3, VALUE3, DIRTY , DIRTY ); + CheckModifyCoins(ABSENT, PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); + CheckModifyCoins(ABSENT, VALUE2, PRUNED, PRUNED, 0 , DIRTY ); + CheckModifyCoins(ABSENT, VALUE2, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckModifyCoins(ABSENT, VALUE2, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckModifyCoins(ABSENT, VALUE2, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckModifyCoins(ABSENT, VALUE2, VALUE3, VALUE3, 0 , DIRTY ); + CheckModifyCoins(ABSENT, VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH); + CheckModifyCoins(ABSENT, VALUE2, VALUE3, VALUE3, DIRTY , DIRTY ); + CheckModifyCoins(ABSENT, VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); + CheckModifyCoins(PRUNED, ABSENT, PRUNED, ABSENT, NO_ENTRY , NO_ENTRY ); + CheckModifyCoins(PRUNED, ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY|FRESH); + CheckModifyCoins(PRUNED, PRUNED, PRUNED, PRUNED, 0 , DIRTY ); + CheckModifyCoins(PRUNED, PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckModifyCoins(PRUNED, PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckModifyCoins(PRUNED, PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckModifyCoins(PRUNED, PRUNED, VALUE3, VALUE3, 0 , DIRTY ); + CheckModifyCoins(PRUNED, PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH); + CheckModifyCoins(PRUNED, PRUNED, VALUE3, VALUE3, DIRTY , DIRTY ); + CheckModifyCoins(PRUNED, PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); + CheckModifyCoins(PRUNED, VALUE2, PRUNED, PRUNED, 0 , DIRTY ); + CheckModifyCoins(PRUNED, VALUE2, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckModifyCoins(PRUNED, VALUE2, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckModifyCoins(PRUNED, VALUE2, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckModifyCoins(PRUNED, VALUE2, VALUE3, VALUE3, 0 , DIRTY ); + CheckModifyCoins(PRUNED, VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH); + CheckModifyCoins(PRUNED, VALUE2, VALUE3, VALUE3, DIRTY , DIRTY ); + CheckModifyCoins(PRUNED, VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); + CheckModifyCoins(VALUE1, ABSENT, PRUNED, PRUNED, NO_ENTRY , DIRTY ); + CheckModifyCoins(VALUE1, ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY ); + CheckModifyCoins(VALUE1, PRUNED, PRUNED, PRUNED, 0 , DIRTY ); + CheckModifyCoins(VALUE1, PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckModifyCoins(VALUE1, PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckModifyCoins(VALUE1, PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckModifyCoins(VALUE1, PRUNED, VALUE3, VALUE3, 0 , DIRTY ); + CheckModifyCoins(VALUE1, PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH); + CheckModifyCoins(VALUE1, PRUNED, VALUE3, VALUE3, DIRTY , DIRTY ); + CheckModifyCoins(VALUE1, PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); + CheckModifyCoins(VALUE1, VALUE2, PRUNED, PRUNED, 0 , DIRTY ); + CheckModifyCoins(VALUE1, VALUE2, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckModifyCoins(VALUE1, VALUE2, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckModifyCoins(VALUE1, VALUE2, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckModifyCoins(VALUE1, VALUE2, VALUE3, VALUE3, 0 , DIRTY ); + CheckModifyCoins(VALUE1, VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH); + CheckModifyCoins(VALUE1, VALUE2, VALUE3, VALUE3, DIRTY , DIRTY ); + CheckModifyCoins(VALUE1, VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); +} + +void CheckModifyNewCoinsBase(CAmount base_value, CAmount cache_value, CAmount modify_value, CAmount expected_value, char cache_flags, char expected_flags, bool coinbase) +{ + SingleEntryCacheTest test(base_value, cache_value, cache_flags); + + CAmount result_value; + char result_flags; + try { + SetCoinsValue(modify_value, *test.cache.ModifyNewCoins(TXID, coinbase)); + GetCoinsMapEntry(test.cache.map(), result_value, result_flags); + } catch (std::logic_error& e) { + result_value = FAIL; + result_flags = NO_ENTRY; + } + + BOOST_CHECK_EQUAL(result_value, expected_value); + BOOST_CHECK_EQUAL(result_flags, expected_flags); +} + +// Simple wrapper for CheckModifyNewCoinsBase function above that loops through +// different possible base_values, making sure each one gives the same results. +// This wrapper lets the modify_new test below be shorter and less repetitive, +// while still verifying that the CoinsViewCache::ModifyNewCoins implementation +// ignores base values. +template <typename... Args> +void CheckModifyNewCoins(Args&&... args) +{ + for (CAmount base_value : {ABSENT, PRUNED, VALUE1}) + CheckModifyNewCoinsBase(base_value, std::forward<Args>(args)...); +} + +BOOST_AUTO_TEST_CASE(ccoins_modify_new) +{ + /* Check ModifyNewCoin behavior, requesting a new coin from a cache view, + * writing a modification to the coin, and then checking the resulting + * entry in the cache after the modification. Verify behavior with the + * with the ModifyNewCoin coinbase argument set to false, and to true. + * + * Cache Write Result Cache Result Coinbase + * Value Value Value Flags Flags + */ + CheckModifyNewCoins(ABSENT, PRUNED, ABSENT, NO_ENTRY , NO_ENTRY , false); + CheckModifyNewCoins(ABSENT, PRUNED, PRUNED, NO_ENTRY , DIRTY , true ); + CheckModifyNewCoins(ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY|FRESH, false); + CheckModifyNewCoins(ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY , true ); + CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, 0 , NO_ENTRY , false); + CheckModifyNewCoins(PRUNED, PRUNED, PRUNED, 0 , DIRTY , true ); + CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY , false); + CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY , true ); + CheckModifyNewCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY , false); + CheckModifyNewCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY , true ); + CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY , false); + CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY , true ); + CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, 0 , DIRTY|FRESH, false); + CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, 0 , DIRTY , true ); + CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH, false); + CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH, true ); + CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, DIRTY , DIRTY , false); + CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, DIRTY , DIRTY , true ); + CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, false); + CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, true ); + CheckModifyNewCoins(VALUE2, PRUNED, FAIL , 0 , NO_ENTRY , false); + CheckModifyNewCoins(VALUE2, PRUNED, PRUNED, 0 , DIRTY , true ); + CheckModifyNewCoins(VALUE2, PRUNED, FAIL , FRESH , NO_ENTRY , false); + CheckModifyNewCoins(VALUE2, PRUNED, ABSENT, FRESH , NO_ENTRY , true ); + CheckModifyNewCoins(VALUE2, PRUNED, FAIL , DIRTY , NO_ENTRY , false); + CheckModifyNewCoins(VALUE2, PRUNED, PRUNED, DIRTY , DIRTY , true ); + CheckModifyNewCoins(VALUE2, PRUNED, FAIL , DIRTY|FRESH, NO_ENTRY , false); + CheckModifyNewCoins(VALUE2, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY , true ); + CheckModifyNewCoins(VALUE2, VALUE3, FAIL , 0 , NO_ENTRY , false); + CheckModifyNewCoins(VALUE2, VALUE3, VALUE3, 0 , DIRTY , true ); + CheckModifyNewCoins(VALUE2, VALUE3, FAIL , FRESH , NO_ENTRY , false); + CheckModifyNewCoins(VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH, true ); + CheckModifyNewCoins(VALUE2, VALUE3, FAIL , DIRTY , NO_ENTRY , false); + CheckModifyNewCoins(VALUE2, VALUE3, VALUE3, DIRTY , DIRTY , true ); + CheckModifyNewCoins(VALUE2, VALUE3, FAIL , DIRTY|FRESH, NO_ENTRY , false); + CheckModifyNewCoins(VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, true ); +} + +void CheckWriteCoins(CAmount parent_value, CAmount child_value, CAmount expected_value, char parent_flags, char child_flags, char expected_flags) +{ + SingleEntryCacheTest test(ABSENT, parent_value, parent_flags); + + CAmount result_value; + char result_flags; + try { + WriteCoinsViewEntry(test.cache, child_value, child_flags); + test.cache.SelfTest(); + GetCoinsMapEntry(test.cache.map(), result_value, result_flags); + } catch (std::logic_error& e) { + result_value = FAIL; + result_flags = NO_ENTRY; + } + + BOOST_CHECK_EQUAL(result_value, expected_value); + BOOST_CHECK_EQUAL(result_flags, expected_flags); +} + +BOOST_AUTO_TEST_CASE(ccoins_write) +{ + /* Check BatchWrite behavior, flushing one entry from a child cache to a + * parent cache, and checking the resulting entry in the parent cache + * after the write. + * + * Parent Child Result Parent Child Result + * Value Value Value Flags Flags Flags + */ + CheckWriteCoins(ABSENT, ABSENT, ABSENT, NO_ENTRY , NO_ENTRY , NO_ENTRY ); + CheckWriteCoins(ABSENT, PRUNED, PRUNED, NO_ENTRY , DIRTY , DIRTY ); + CheckWriteCoins(ABSENT, PRUNED, ABSENT, NO_ENTRY , DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(ABSENT, VALUE2, VALUE2, NO_ENTRY , DIRTY , DIRTY ); + CheckWriteCoins(ABSENT, VALUE2, VALUE2, NO_ENTRY , DIRTY|FRESH, DIRTY|FRESH); + CheckWriteCoins(PRUNED, ABSENT, PRUNED, 0 , NO_ENTRY , 0 ); + CheckWriteCoins(PRUNED, ABSENT, PRUNED, FRESH , NO_ENTRY , FRESH ); + CheckWriteCoins(PRUNED, ABSENT, PRUNED, DIRTY , NO_ENTRY , DIRTY ); + CheckWriteCoins(PRUNED, ABSENT, PRUNED, DIRTY|FRESH, NO_ENTRY , DIRTY|FRESH); + CheckWriteCoins(PRUNED, PRUNED, PRUNED, 0 , DIRTY , DIRTY ); + CheckWriteCoins(PRUNED, PRUNED, PRUNED, 0 , DIRTY|FRESH, DIRTY ); + CheckWriteCoins(PRUNED, PRUNED, ABSENT, FRESH , DIRTY , NO_ENTRY ); + CheckWriteCoins(PRUNED, PRUNED, ABSENT, FRESH , DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY , DIRTY ); + CheckWriteCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY|FRESH, DIRTY ); + CheckWriteCoins(PRUNED, PRUNED, ABSENT, DIRTY|FRESH, DIRTY , NO_ENTRY ); + CheckWriteCoins(PRUNED, PRUNED, ABSENT, DIRTY|FRESH, DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(PRUNED, VALUE2, VALUE2, 0 , DIRTY , DIRTY ); + CheckWriteCoins(PRUNED, VALUE2, VALUE2, 0 , DIRTY|FRESH, DIRTY ); + CheckWriteCoins(PRUNED, VALUE2, VALUE2, FRESH , DIRTY , DIRTY|FRESH); + CheckWriteCoins(PRUNED, VALUE2, VALUE2, FRESH , DIRTY|FRESH, DIRTY|FRESH); + CheckWriteCoins(PRUNED, VALUE2, VALUE2, DIRTY , DIRTY , DIRTY ); + CheckWriteCoins(PRUNED, VALUE2, VALUE2, DIRTY , DIRTY|FRESH, DIRTY ); + CheckWriteCoins(PRUNED, VALUE2, VALUE2, DIRTY|FRESH, DIRTY , DIRTY|FRESH); + CheckWriteCoins(PRUNED, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH, DIRTY|FRESH); + CheckWriteCoins(VALUE1, ABSENT, VALUE1, 0 , NO_ENTRY , 0 ); + CheckWriteCoins(VALUE1, ABSENT, VALUE1, FRESH , NO_ENTRY , FRESH ); + CheckWriteCoins(VALUE1, ABSENT, VALUE1, DIRTY , NO_ENTRY , DIRTY ); + CheckWriteCoins(VALUE1, ABSENT, VALUE1, DIRTY|FRESH, NO_ENTRY , DIRTY|FRESH); + CheckWriteCoins(VALUE1, PRUNED, PRUNED, 0 , DIRTY , DIRTY ); + CheckWriteCoins(VALUE1, PRUNED, FAIL , 0 , DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(VALUE1, PRUNED, ABSENT, FRESH , DIRTY , NO_ENTRY ); + CheckWriteCoins(VALUE1, PRUNED, FAIL , FRESH , DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(VALUE1, PRUNED, PRUNED, DIRTY , DIRTY , DIRTY ); + CheckWriteCoins(VALUE1, PRUNED, FAIL , DIRTY , DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(VALUE1, PRUNED, ABSENT, DIRTY|FRESH, DIRTY , NO_ENTRY ); + CheckWriteCoins(VALUE1, PRUNED, FAIL , DIRTY|FRESH, DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(VALUE1, VALUE2, VALUE2, 0 , DIRTY , DIRTY ); + CheckWriteCoins(VALUE1, VALUE2, FAIL , 0 , DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(VALUE1, VALUE2, VALUE2, FRESH , DIRTY , DIRTY|FRESH); + CheckWriteCoins(VALUE1, VALUE2, FAIL , FRESH , DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(VALUE1, VALUE2, VALUE2, DIRTY , DIRTY , DIRTY ); + CheckWriteCoins(VALUE1, VALUE2, FAIL , DIRTY , DIRTY|FRESH, NO_ENTRY ); + CheckWriteCoins(VALUE1, VALUE2, VALUE2, DIRTY|FRESH, DIRTY , DIRTY|FRESH); + CheckWriteCoins(VALUE1, VALUE2, FAIL , DIRTY|FRESH, DIRTY|FRESH, NO_ENTRY ); + + // The checks above omit cases where the child flags are not DIRTY, since + // they would be too repetitive (the parent cache is never updated in these + // cases). The loop below covers these cases and makes sure the parent cache + // is always left unchanged. + for (CAmount parent_value : {ABSENT, PRUNED, VALUE1}) + for (CAmount child_value : {ABSENT, PRUNED, VALUE2}) + for (char parent_flags : parent_value == ABSENT ? ABSENT_FLAGS : FLAGS) + for (char child_flags : child_value == ABSENT ? ABSENT_FLAGS : CLEAN_FLAGS) + CheckWriteCoins(parent_value, child_value, parent_value, parent_flags, child_flags, parent_flags); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 7dcd548edf..4d17417179 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2015 The Bitcoin Core developers +// Copyright (c) 2014-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/cuckoocache_tests.cpp b/src/test/cuckoocache_tests.cpp new file mode 100644 index 0000000000..00446aa11e --- /dev/null +++ b/src/test/cuckoocache_tests.cpp @@ -0,0 +1,394 @@ +// Copyright (c) 2012-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <boost/test/unit_test.hpp> +#include "cuckoocache.h" +#include "test/test_bitcoin.h" +#include "random.h" +#include <thread> +#include <boost/thread.hpp> + + +/** Test Suite for CuckooCache + * + * 1) All tests should have a deterministic result (using insecure rand + * with deterministic seeds) + * 2) Some test methods are templated to allow for easier testing + * against new versions / comparing + * 3) Results should be treated as a regression test, i.e., did the behavior + * change significantly from what was expected. This can be OK, depending on + * the nature of the change, but requires updating the tests to reflect the new + * expected behavior. For example improving the hit rate may cause some tests + * using BOOST_CHECK_CLOSE to fail. + * + */ +FastRandomContext insecure_rand(true); + +BOOST_AUTO_TEST_SUITE(cuckoocache_tests); + + +/** insecure_GetRandHash fills in a uint256 from insecure_rand + */ +void insecure_GetRandHash(uint256& t) +{ + uint32_t* ptr = (uint32_t*)t.begin(); + for (uint8_t j = 0; j < 8; ++j) + *(ptr++) = insecure_rand.rand32(); +} + +/** Definition copied from /src/script/sigcache.cpp + */ +class uint256Hasher +{ +public: + template <uint8_t hash_select> + uint32_t operator()(const uint256& key) const + { + static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available."); + uint32_t u; + std::memcpy(&u, key.begin() + 4 * hash_select, 4); + return u; + } +}; + + +/* Test that no values not inserted into the cache are read out of it. + * + * There are no repeats in the first 200000 insecure_GetRandHash calls + */ +BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes) +{ + insecure_rand = FastRandomContext(true); + CuckooCache::cache<uint256, uint256Hasher> cc{}; + cc.setup_bytes(32 << 20); + uint256 v; + for (int x = 0; x < 100000; ++x) { + insecure_GetRandHash(v); + cc.insert(v); + } + for (int x = 0; x < 100000; ++x) { + insecure_GetRandHash(v); + BOOST_CHECK(!cc.contains(v, false)); + } +}; + +/** This helper returns the hit rate when megabytes*load worth of entries are + * inserted into a megabytes sized cache + */ +template <typename Cache> +double test_cache(size_t megabytes, double load) +{ + insecure_rand = FastRandomContext(true); + std::vector<uint256> hashes; + Cache set{}; + size_t bytes = megabytes * (1 << 20); + set.setup_bytes(bytes); + uint32_t n_insert = static_cast<uint32_t>(load * (bytes / sizeof(uint256))); + hashes.resize(n_insert); + for (uint32_t i = 0; i < n_insert; ++i) { + uint32_t* ptr = (uint32_t*)hashes[i].begin(); + for (uint8_t j = 0; j < 8; ++j) + *(ptr++) = insecure_rand.rand32(); + } + /** We make a copy of the hashes because future optimizations of the + * cuckoocache may overwrite the inserted element, so the test is + * "future proofed". + */ + std::vector<uint256> hashes_insert_copy = hashes; + /** Do the insert */ + for (uint256& h : hashes_insert_copy) + set.insert(h); + /** Count the hits */ + uint32_t count = 0; + for (uint256& h : hashes) + count += set.contains(h, false); + double hit_rate = ((double)count) / ((double)n_insert); + return hit_rate; +} + +/** The normalized hit rate for a given load. + * + * The semantics are a little confusing, so please see the below + * explanation. + * + * Examples: + * + * 1) at load 0.5, we expect a perfect hit rate, so we multiply by + * 1.0 + * 2) at load 2.0, we expect to see half the entries, so a perfect hit rate + * would be 0.5. Therefore, if we see a hit rate of 0.4, 0.4*2.0 = 0.8 is the + * normalized hit rate. + * + * This is basically the right semantics, but has a bit of a glitch depending on + * how you measure around load 1.0 as after load 1.0 your normalized hit rate + * becomes effectively perfect, ignoring freshness. + */ +double normalize_hit_rate(double hits, double load) +{ + return hits * std::max(load, 1.0); +} + +/** Check the hit rate on loads ranging from 0.1 to 2.0 */ +BOOST_AUTO_TEST_CASE(cuckoocache_hit_rate_ok) +{ + /** Arbitrarily selected Hit Rate threshold that happens to work for this test + * as a lower bound on performance. + */ + double HitRateThresh = 0.98; + size_t megabytes = 32; + for (double load = 0.1; load < 2; load *= 2) { + double hits = test_cache<CuckooCache::cache<uint256, uint256Hasher>>(megabytes, load); + BOOST_CHECK(normalize_hit_rate(hits, load) > HitRateThresh); + } +} + + +/** This helper checks that erased elements are preferentially inserted onto and + * that the hit rate of "fresher" keys is reasonable*/ +template <typename Cache> +void test_cache_erase(size_t megabytes) +{ + double load = 1; + insecure_rand = FastRandomContext(true); + std::vector<uint256> hashes; + Cache set{}; + size_t bytes = megabytes * (1 << 20); + set.setup_bytes(bytes); + uint32_t n_insert = static_cast<uint32_t>(load * (bytes / sizeof(uint256))); + hashes.resize(n_insert); + for (uint32_t i = 0; i < n_insert; ++i) { + uint32_t* ptr = (uint32_t*)hashes[i].begin(); + for (uint8_t j = 0; j < 8; ++j) + *(ptr++) = insecure_rand.rand32(); + } + /** We make a copy of the hashes because future optimizations of the + * cuckoocache may overwrite the inserted element, so the test is + * "future proofed". + */ + std::vector<uint256> hashes_insert_copy = hashes; + + /** Insert the first half */ + for (uint32_t i = 0; i < (n_insert / 2); ++i) + set.insert(hashes_insert_copy[i]); + /** Erase the first quarter */ + for (uint32_t i = 0; i < (n_insert / 4); ++i) + set.contains(hashes[i], true); + /** Insert the second half */ + for (uint32_t i = (n_insert / 2); i < n_insert; ++i) + set.insert(hashes_insert_copy[i]); + + /** elements that we marked erased but that are still there */ + size_t count_erased_but_contained = 0; + /** elements that we did not erase but are older */ + size_t count_stale = 0; + /** elements that were most recently inserted */ + size_t count_fresh = 0; + + for (uint32_t i = 0; i < (n_insert / 4); ++i) + count_erased_but_contained += set.contains(hashes[i], false); + for (uint32_t i = (n_insert / 4); i < (n_insert / 2); ++i) + count_stale += set.contains(hashes[i], false); + for (uint32_t i = (n_insert / 2); i < n_insert; ++i) + count_fresh += set.contains(hashes[i], false); + + double hit_rate_erased_but_contained = double(count_erased_but_contained) / (double(n_insert) / 4.0); + double hit_rate_stale = double(count_stale) / (double(n_insert) / 4.0); + double hit_rate_fresh = double(count_fresh) / (double(n_insert) / 2.0); + + // Check that our hit_rate_fresh is perfect + BOOST_CHECK_EQUAL(hit_rate_fresh, 1.0); + // Check that we have a more than 2x better hit rate on stale elements than + // erased elements. + BOOST_CHECK(hit_rate_stale > 2 * hit_rate_erased_but_contained); +} + +BOOST_AUTO_TEST_CASE(cuckoocache_erase_ok) +{ + size_t megabytes = 32; + test_cache_erase<CuckooCache::cache<uint256, uint256Hasher>>(megabytes); +} + +template <typename Cache> +void test_cache_erase_parallel(size_t megabytes) +{ + double load = 1; + insecure_rand = FastRandomContext(true); + std::vector<uint256> hashes; + Cache set{}; + size_t bytes = megabytes * (1 << 20); + set.setup_bytes(bytes); + uint32_t n_insert = static_cast<uint32_t>(load * (bytes / sizeof(uint256))); + hashes.resize(n_insert); + for (uint32_t i = 0; i < n_insert; ++i) { + uint32_t* ptr = (uint32_t*)hashes[i].begin(); + for (uint8_t j = 0; j < 8; ++j) + *(ptr++) = insecure_rand.rand32(); + } + /** We make a copy of the hashes because future optimizations of the + * cuckoocache may overwrite the inserted element, so the test is + * "future proofed". + */ + std::vector<uint256> hashes_insert_copy = hashes; + boost::shared_mutex mtx; + + { + /** Grab lock to make sure we release inserts */ + boost::unique_lock<boost::shared_mutex> l(mtx); + /** Insert the first half */ + for (uint32_t i = 0; i < (n_insert / 2); ++i) + set.insert(hashes_insert_copy[i]); + } + + /** Spin up 3 threads to run contains with erase. + */ + std::vector<std::thread> threads; + /** Erase the first quarter */ + for (uint32_t x = 0; x < 3; ++x) + /** Each thread is emplaced with x copy-by-value + */ + threads.emplace_back([&, x] { + boost::shared_lock<boost::shared_mutex> l(mtx); + size_t ntodo = (n_insert/4)/3; + size_t start = ntodo*x; + size_t end = ntodo*(x+1); + for (uint32_t i = start; i < end; ++i) + set.contains(hashes[i], true); + }); + + /** Wait for all threads to finish + */ + for (std::thread& t : threads) + t.join(); + /** Grab lock to make sure we observe erases */ + boost::unique_lock<boost::shared_mutex> l(mtx); + /** Insert the second half */ + for (uint32_t i = (n_insert / 2); i < n_insert; ++i) + set.insert(hashes_insert_copy[i]); + + /** elements that we marked erased but that are still there */ + size_t count_erased_but_contained = 0; + /** elements that we did not erase but are older */ + size_t count_stale = 0; + /** elements that were most recently inserted */ + size_t count_fresh = 0; + + for (uint32_t i = 0; i < (n_insert / 4); ++i) + count_erased_but_contained += set.contains(hashes[i], false); + for (uint32_t i = (n_insert / 4); i < (n_insert / 2); ++i) + count_stale += set.contains(hashes[i], false); + for (uint32_t i = (n_insert / 2); i < n_insert; ++i) + count_fresh += set.contains(hashes[i], false); + + double hit_rate_erased_but_contained = double(count_erased_but_contained) / (double(n_insert) / 4.0); + double hit_rate_stale = double(count_stale) / (double(n_insert) / 4.0); + double hit_rate_fresh = double(count_fresh) / (double(n_insert) / 2.0); + + // Check that our hit_rate_fresh is perfect + BOOST_CHECK_EQUAL(hit_rate_fresh, 1.0); + // Check that we have a more than 2x better hit rate on stale elements than + // erased elements. + BOOST_CHECK(hit_rate_stale > 2 * hit_rate_erased_but_contained); +} +BOOST_AUTO_TEST_CASE(cuckoocache_erase_parallel_ok) +{ + size_t megabytes = 32; + test_cache_erase_parallel<CuckooCache::cache<uint256, uint256Hasher>>(megabytes); +} + + +template <typename Cache> +void test_cache_generations() +{ + // This test checks that for a simulation of network activity, the fresh hit + // rate is never below 99%, and the number of times that it is worse than + // 99.9% are less than 1% of the time. + double min_hit_rate = 0.99; + double tight_hit_rate = 0.999; + double max_rate_less_than_tight_hit_rate = 0.01; + // A cache that meets this specification is therefore shown to have a hit + // rate of at least tight_hit_rate * (1 - max_rate_less_than_tight_hit_rate) + + // min_hit_rate*max_rate_less_than_tight_hit_rate = 0.999*99%+0.99*1% == 99.89% + // hit rate with low variance. + + // We use deterministic values, but this test has also passed on many + // iterations with non-deterministic values, so it isn't "overfit" to the + // specific entropy in FastRandomContext(true) and implementation of the + // cache. + insecure_rand = FastRandomContext(true); + + // block_activity models a chunk of network activity. n_insert elements are + // adde to the cache. The first and last n/4 are stored for removal later + // and the middle n/2 are not stored. This models a network which uses half + // the signatures of recently (since the last block) added transactions + // immediately and never uses the other half. + struct block_activity { + std::vector<uint256> reads; + block_activity(uint32_t n_insert, Cache& c) : reads() + { + std::vector<uint256> inserts; + inserts.resize(n_insert); + reads.reserve(n_insert / 2); + for (uint32_t i = 0; i < n_insert; ++i) { + uint32_t* ptr = (uint32_t*)inserts[i].begin(); + for (uint8_t j = 0; j < 8; ++j) + *(ptr++) = insecure_rand.rand32(); + } + for (uint32_t i = 0; i < n_insert / 4; ++i) + reads.push_back(inserts[i]); + for (uint32_t i = n_insert - (n_insert / 4); i < n_insert; ++i) + reads.push_back(inserts[i]); + for (auto h : inserts) + c.insert(h); + } + }; + + const uint32_t BLOCK_SIZE = 10000; + // We expect window size 60 to perform reasonably given that each epoch + // stores 45% of the cache size (~472k). + const uint32_t WINDOW_SIZE = 60; + const uint32_t POP_AMOUNT = (BLOCK_SIZE / WINDOW_SIZE) / 2; + const double load = 10; + const size_t megabytes = 32; + const size_t bytes = megabytes * (1 << 20); + const uint32_t n_insert = static_cast<uint32_t>(load * (bytes / sizeof(uint256))); + + std::vector<block_activity> hashes; + Cache set{}; + set.setup_bytes(bytes); + hashes.reserve(n_insert / BLOCK_SIZE); + std::deque<block_activity> last_few; + uint32_t out_of_tight_tolerance = 0; + uint32_t total = n_insert / BLOCK_SIZE; + // we use the deque last_few to model a sliding window of blocks. at each + // step, each of the last WINDOW_SIZE block_activities checks the cache for + // POP_AMOUNT of the hashes that they inserted, and marks these erased. + for (uint32_t i = 0; i < total; ++i) { + if (last_few.size() == WINDOW_SIZE) + last_few.pop_front(); + last_few.emplace_back(BLOCK_SIZE, set); + uint32_t count = 0; + for (auto& act : last_few) + for (uint32_t k = 0; k < POP_AMOUNT; ++k) { + count += set.contains(act.reads.back(), true); + act.reads.pop_back(); + } + // We use last_few.size() rather than WINDOW_SIZE for the correct + // behavior on the first WINDOW_SIZE iterations where the deque is not + // full yet. + double hit = (double(count)) / (last_few.size() * POP_AMOUNT); + // Loose Check that hit rate is above min_hit_rate + BOOST_CHECK(hit > min_hit_rate); + // Tighter check, count number of times we are less than tight_hit_rate + // (and implicityly, greater than min_hit_rate) + out_of_tight_tolerance += hit < tight_hit_rate; + } + // Check that being out of tolerance happens less than + // max_rate_less_than_tight_hit_rate of the time + BOOST_CHECK(double(out_of_tight_tolerance) / double(total) < max_rate_less_than_tight_hit_rate); +} +BOOST_AUTO_TEST_CASE(cuckoocache_generations) +{ + test_cache_generations<CuckooCache::cache<uint256, uint256Hasher>>(); +} + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index 98be75919b..a80ab51901 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -1,24 +1,29 @@ [ { "exec": "./bitcoin-tx", - "args": ["-create"], - "output_cmp": "blanktx.hex", - "description": "Creates a blank transaction" + "args": ["-create", "nversion=1"], + "output_cmp": "blanktxv1.hex", + "description": "Creates a blank v1 transaction" }, { "exec": "./bitcoin-tx", - "args": ["-json","-create"], - "output_cmp": "blanktx.json", - "description": "Creates a blank transaction (output in json)" + "args": ["-json","-create", "nversion=1"], + "output_cmp": "blanktxv1.json", + "description": "Creates a blank v1 transaction (output in json)" }, { "exec": "./bitcoin-tx", "args": ["-"], - "input": "blanktx.hex", - "output_cmp": "blanktx.hex", + "input": "blanktxv2.hex", + "output_cmp": "blanktxv2.hex", "description": "Creates a blank transaction when nothing is piped into bitcoin-tx" }, { "exec": "./bitcoin-tx", + "args": ["-json","-create"], + "output_cmp": "blanktxv2.json", + "description": "Creates a blank transaction (output in json)" + }, + { "exec": "./bitcoin-tx", "args": ["-json","-"], - "input": "blanktx.hex", - "output_cmp": "blanktx.json", + "input": "blanktxv2.hex", + "output_cmp": "blanktxv2.json", "description": "Creates a blank transaction when nothing is piped into bitcoin-tx (output in json)" }, { "exec": "./bitcoin-tx", @@ -103,37 +108,124 @@ "description": "Creates a new transaction with a single empty output script (output in json)" }, { "exec": "./bitcoin-tx", - "args": ["01000000000100000000000000000000000000"], + "args": ["02000000000100000000000000000000000000"], "output_cmp": "txcreate2.hex", "description": "Parses a transation with no inputs and a single output script" }, { "exec": "./bitcoin-tx", - "args": ["-json", "01000000000100000000000000000000000000"], + "args": ["-json", "02000000000100000000000000000000000000"], "output_cmp": "txcreate2.json", "description": "Parses a transation with no inputs and a single output script (output in json)" }, { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:OP_DROP", "nversion=1"], + "output_cmp": "txcreatescript1.hex", + "description": "Create a new transaction with a single output script (OP_DROP)" + }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outscript=0:OP_DROP", "nversion=1"], + "output_cmp": "txcreatescript1.json", + "description": "Create a new transaction with a single output script (OP_DROP) (output as json)" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:OP_DROP:S", "nversion=1"], + "output_cmp": "txcreatescript2.hex", + "description": "Create a new transaction with a single output script (OP_DROP) in a P2SH" + }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outscript=0:OP_DROP:S", "nversion=1"], + "output_cmp": "txcreatescript2.json", + "description": "Create a new transaction with a single output script (OP_DROP) in a P2SH (output as json)" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:OP_DROP:W", "nversion=1"], + "output_cmp": "txcreatescript3.hex", + "description": "Create a new transaction with a single output script (OP_DROP) in a P2WSH" + }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outscript=0:OP_DROP:W", "nversion=1"], + "output_cmp": "txcreatescript3.json", + "description": "Create a new transaction with a single output script (OP_DROP) in a P2WSH (output as json)" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:OP_DROP:WS", "nversion=1"], + "output_cmp": "txcreatescript4.hex", + "description": "Create a new transaction with a single output script (OP_DROP) in a P2WSH, wrapped in a P2SH" + }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outscript=0:OP_DROP:WS", "nversion=1"], + "output_cmp": "txcreatescript4.json", + "description": "Create a new transaction with a single output script (OP_DROP) in a P2SH, wrapped in a P2SH (output as json)" + }, + { "exec": "./bitcoin-tx", "args": - ["-create", + ["-create", "nversion=1", "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]", "sign=ALL", "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], - "output_cmp": "txcreatesign.hex", - "description": "Creates a new transaction with a single input and a single output, and then signs the transaction" + "output_cmp": "txcreatesignv1.hex", + "description": "Creates a new v1 transaction with a single input and a single output, and then signs the transaction" }, { "exec": "./bitcoin-tx", "args": ["-json", - "-create", + "-create", "nversion=1", "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]", "sign=ALL", "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], - "output_cmp": "txcreatesign.json", - "description": "Creates a new transaction with a single input and a single output, and then signs the transaction (output in json)" + "output_cmp": "txcreatesignv1.json", + "description": "Creates a new v1 transaction with a single input and a single output, and then signs the transaction (output in json)" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", + "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", + "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", + "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]", + "sign=ALL", + "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], + "output_cmp": "txcreatesignv2.hex", + "description": "Creates a new transaction with a single input and a single output, and then signs the transaction" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397", "nversion=1"], + "output_cmp": "txcreateoutpubkey1.hex", + "description": "Creates a new transaction with a single pay-to-pubkey output" + }, + { "exec": "./bitcoin-tx", + "args": + ["-json", "-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397", "nversion=1"], + "output_cmp": "txcreateoutpubkey1.json", + "description": "Creates a new transaction with a single pay-to-pubkey output (output as json)" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:W", "nversion=1"], + "output_cmp": "txcreateoutpubkey2.hex", + "description": "Creates a new transaction with a single pay-to-witness-pubkey output" + }, + { "exec": "./bitcoin-tx", + "args": + ["-json", "-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:W", "nversion=1"], + "output_cmp": "txcreateoutpubkey2.json", + "description": "Creates a new transaction with a single pay-to-witness-pubkey output (output as json)" + }, + { "exec": "./bitcoin-tx", + "args": + ["-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:WS", "nversion=1"], + "output_cmp": "txcreateoutpubkey3.hex", + "description": "Creates a new transaction with a single pay-to-witness-pubkey, wrapped in P2SH output" + }, + { "exec": "./bitcoin-tx", + "args": + ["-json", "-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:WS", "nversion=1"], + "output_cmp": "txcreateoutpubkey3.json", + "description": "Creates a new transaction with a single pay-to-pub-key output, wrapped in P2SH (output as json)" }, { "exec": "./bitcoin-tx", "args": @@ -163,12 +255,12 @@ { "exec": "./bitcoin-tx", "args": ["-json", - "-create", + "-create", "nversion=1", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o", "outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], "output_cmp": "txcreatedata1.json", - "description": "Creates a new transaction with one input, one address output and one data output (output in json)" + "description": "Creates a new v1 transaction with one input, one address output and one data output (output in json)" }, { "exec": "./bitcoin-tx", "args": @@ -220,5 +312,45 @@ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"], "output_cmp": "txcreatedata_seq1.json", "description": "Adds a new input with sequence number to a transaction (output in json)" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"], + "output_cmp": "txcreatemultisig1.hex", + "description": "Creates a new transaction with a single 2-of-3 multisig output" + }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485", "nversion=1"], + "output_cmp": "txcreatemultisig1.json", + "description": "Creates a new transaction with a single 2-of-3 multisig output (output in json)" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:S", "nversion=1"], + "output_cmp": "txcreatemultisig2.hex", + "description": "Creates a new transaction with a single 2-of-3 multisig in a P2SH output" + }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:S", "nversion=1"], + "output_cmp": "txcreatemultisig2.json", + "description": "Creates a new transaction with a single 2-of-3 multisig in a P2SH output (output in json)" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:W", "nversion=1"], + "output_cmp": "txcreatemultisig3.hex", + "description": "Creates a new transaction with a single 2-of-3 multisig in a P2WSH output" + }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:W", "nversion=1"], + "output_cmp": "txcreatemultisig3.json", + "description": "Creates a new transaction with a single 2-of-3 multisig in a P2WSH output (output in json)" + }, + { "exec": "./bitcoin-tx", + "args": ["-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:WS", "nversion=1"], + "output_cmp": "txcreatemultisig4.hex", + "description": "Creates a new transaction with a single 2-of-3 multisig in a P2WSH output, wrapped in P2SH" + }, + { "exec": "./bitcoin-tx", + "args": ["-json", "-create", "outmultisig=1:2:3:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397:021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d:02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485:WS", "nversion=1"], + "output_cmp": "txcreatemultisig4.json", + "description": "Creates a new transaction with a single 2-of-3 multisig in a P2WSH output, wrapped in P2SH (output in json)" } ] diff --git a/src/test/data/blanktx.hex b/src/test/data/blanktxv1.hex index 36b6f00fb6..36b6f00fb6 100644 --- a/src/test/data/blanktx.hex +++ b/src/test/data/blanktxv1.hex diff --git a/src/test/data/blanktx.json b/src/test/data/blanktxv1.json index 51c25a5a98..51c25a5a98 100644 --- a/src/test/data/blanktx.json +++ b/src/test/data/blanktxv1.json diff --git a/src/test/data/blanktxv2.hex b/src/test/data/blanktxv2.hex new file mode 100644 index 0000000000..22d830eda1 --- /dev/null +++ b/src/test/data/blanktxv2.hex @@ -0,0 +1 @@ +02000000000000000000 diff --git a/src/test/data/blanktxv2.json b/src/test/data/blanktxv2.json new file mode 100644 index 0000000000..266919f445 --- /dev/null +++ b/src/test/data/blanktxv2.json @@ -0,0 +1,11 @@ +{ + "txid": "4ebd325a4b394cff8c57e8317ccf5a8d0e2bdf1b8526f8aad6c8e43d8240621a", + "hash": "4ebd325a4b394cff8c57e8317ccf5a8d0e2bdf1b8526f8aad6c8e43d8240621a", + "version": 2, + "locktime": 0, + "vin": [ + ], + "vout": [ + ], + "hex": "02000000000000000000" +} diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index f7d9e1847f..2235bd0ae7 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -1,7 +1,7 @@ [ ["The following are deserialized transactions which are invalid."], ["They are in the form"], -["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], +["[[[prevout hash, prevout index, prevout scriptPubKey, amount?], [input 2], ...],"], ["serializedTransaction, verifyFlags]"], ["Objects that are only a single string (like this one) are ignored"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 27acb2f16a..d70fa54333 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -1,7 +1,7 @@ [ ["The following are deserialized transactions which are valid."], ["They are in the form"], -["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], +["[[[prevout hash, prevout index, prevout scriptPubKey, amount?], [input 2], ...],"], ["serializedTransaction, verifyFlags]"], ["Objects that are only a single string (like this one) are ignored"], @@ -478,7 +478,7 @@ ["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215]], "01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"], -["BIP143 example: Same as the previous example with input-output paris swapped"], +["BIP143 example: Same as the previous example with input-output pairs swapped"], [[["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215], ["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215]], "0100000000010280e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffffe9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff0280969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac80969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"], diff --git a/src/test/data/txcreate1.hex b/src/test/data/txcreate1.hex index e2981a51c9..9ec6ee3531 100644 --- a/src/test/data/txcreate1.hex +++ b/src/test/data/txcreate1.hex @@ -1 +1 @@ -01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000 +02000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000 diff --git a/src/test/data/txcreate1.json b/src/test/data/txcreate1.json index 567e8026a3..f83e036f33 100644 --- a/src/test/data/txcreate1.json +++ b/src/test/data/txcreate1.json @@ -1,7 +1,7 @@ { - "txid": "f70f0d6c71416ed538e37549f430ab3665fee2437a42f10238c1bd490e782231", - "hash": "f70f0d6c71416ed538e37549f430ab3665fee2437a42f10238c1bd490e782231", - "version": 1, + "txid": "fe7d174f42dce0cffa7a527e9bc8368956057619ec817648f6138b98f2533e8f", + "hash": "fe7d174f42dce0cffa7a527e9bc8368956057619ec817648f6138b98f2533e8f", + "version": 2, "locktime": 0, "vin": [ { @@ -60,5 +60,5 @@ } } ], - "hex": "01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000" + "hex": "02000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000" } diff --git a/src/test/data/txcreate2.hex b/src/test/data/txcreate2.hex index 5243c2d02e..38bb7b1046 100644 --- a/src/test/data/txcreate2.hex +++ b/src/test/data/txcreate2.hex @@ -1 +1 @@ -01000000000100000000000000000000000000 +02000000000100000000000000000000000000 diff --git a/src/test/data/txcreate2.json b/src/test/data/txcreate2.json index a70c1d302a..fb5e177db7 100644 --- a/src/test/data/txcreate2.json +++ b/src/test/data/txcreate2.json @@ -1,7 +1,7 @@ { - "txid": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13", - "hash": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13", - "version": 1, + "txid": "0481afb29931341d0d7861d8a2f6f26456fa042abf54a23e96440ed7946e0715", + "hash": "0481afb29931341d0d7861d8a2f6f26456fa042abf54a23e96440ed7946e0715", + "version": 2, "locktime": 0, "vin": [ ], @@ -16,5 +16,5 @@ } } ], - "hex": "01000000000100000000000000000000000000" + "hex": "02000000000100000000000000000000000000" } diff --git a/src/test/data/txcreatedata1.hex b/src/test/data/txcreatedata1.hex index eccc7604e6..cefd1a05a6 100644 --- a/src/test/data/txcreatedata1.hex +++ b/src/test/data/txcreatedata1.hex @@ -1 +1 @@ -01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d71700000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000 +02000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d71700000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000 diff --git a/src/test/data/txcreatedata2.hex b/src/test/data/txcreatedata2.hex index 3c7644c297..d69cf58ba1 100644 --- a/src/test/data/txcreatedata2.hex +++ b/src/test/data/txcreatedata2.hex @@ -1 +1 @@ -01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000 +02000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000 diff --git a/src/test/data/txcreatedata2.json b/src/test/data/txcreatedata2.json index 56dfe4a1b0..3c6da40f90 100644 --- a/src/test/data/txcreatedata2.json +++ b/src/test/data/txcreatedata2.json @@ -1,7 +1,7 @@ { - "txid": "4ed17118f5e932ba8c75c461787d171bc02a016d8557cb5bcf34cd416c27bb8b", - "hash": "4ed17118f5e932ba8c75c461787d171bc02a016d8557cb5bcf34cd416c27bb8b", - "version": 1, + "txid": "c14b007fa3a6c1e7765919c1d14c1cfc2b8642c3a5d3be4b1fa8c4ccfec98bb0", + "hash": "c14b007fa3a6c1e7765919c1d14c1cfc2b8642c3a5d3be4b1fa8c4ccfec98bb0", + "version": 2, "locktime": 0, "vin": [ { @@ -38,5 +38,5 @@ } } ], - "hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000" + "hex": "02000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000" } diff --git a/src/test/data/txcreatedata_seq0.hex b/src/test/data/txcreatedata_seq0.hex index db02b5e4a4..54b89d2381 100644 --- a/src/test/data/txcreatedata_seq0.hex +++ b/src/test/data/txcreatedata_seq0.hex @@ -1 +1 @@ -01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000 +02000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000 diff --git a/src/test/data/txcreatedata_seq0.json b/src/test/data/txcreatedata_seq0.json index 9bc0ed4593..d272a4c447 100644 --- a/src/test/data/txcreatedata_seq0.json +++ b/src/test/data/txcreatedata_seq0.json @@ -1,7 +1,7 @@ { - "txid": "71603ccb1cd76d73d76eb6cfd5f0b9df6d65d90d76860ee52cb461c4be7032e8", - "hash": "71603ccb1cd76d73d76eb6cfd5f0b9df6d65d90d76860ee52cb461c4be7032e8", - "version": 1, + "txid": "8df6ed527472542dd5e137c242a7c5a9f337ac34f7b257ae4af886aeaebb51b0", + "hash": "8df6ed527472542dd5e137c242a7c5a9f337ac34f7b257ae4af886aeaebb51b0", + "version": 2, "locktime": 0, "vin": [ { @@ -29,5 +29,5 @@ } } ], - "hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000" + "hex": "02000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000" } diff --git a/src/test/data/txcreatemultisig1.hex b/src/test/data/txcreatemultisig1.hex new file mode 100644 index 0000000000..9c00004d38 --- /dev/null +++ b/src/test/data/txcreatemultisig1.hex @@ -0,0 +1 @@ +01000000000100e1f5050000000069522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae00000000 diff --git a/src/test/data/txcreatemultisig1.json b/src/test/data/txcreatemultisig1.json new file mode 100644 index 0000000000..f6ce43c202 --- /dev/null +++ b/src/test/data/txcreatemultisig1.json @@ -0,0 +1,26 @@ +{ + "txid": "0d1d4edfc217d9db3ab6a9298f26a52eae3c52f55a6cb8ccbc14f7c727572894", + "hash": "0d1d4edfc217d9db3ab6a9298f26a52eae3c52f55a6cb8ccbc14f7c727572894", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 1.00, + "n": 0, + "scriptPubKey": { + "asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG", + "hex": "522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae", + "reqSigs": 2, + "type": "multisig", + "addresses": [ + "1FoG2386FG2tAJS9acMuiDsKy67aGg9MKz", + "1FXtz9KU8JNmQDyHdiEm5HDiALuP3zdHvV", + "14LuavcBbXZYJ6Tsz3cAUQj9SuQoL2xCQX" + ] + } + } + ], + "hex": "01000000000100e1f5050000000069522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae00000000" +} diff --git a/src/test/data/txcreatemultisig2.hex b/src/test/data/txcreatemultisig2.hex new file mode 100644 index 0000000000..07835c54d3 --- /dev/null +++ b/src/test/data/txcreatemultisig2.hex @@ -0,0 +1 @@ +01000000000100e1f5050000000017a9141c6fbaf46d64221e80cbae182c33ddf81b9294ac8700000000 diff --git a/src/test/data/txcreatemultisig2.json b/src/test/data/txcreatemultisig2.json new file mode 100644 index 0000000000..e09d22060f --- /dev/null +++ b/src/test/data/txcreatemultisig2.json @@ -0,0 +1,24 @@ +{ + "txid": "0d861f278a3b7bce7cb5a88d71e6e6a903336f95ad5a2c29b295b63835b6eee3", + "hash": "0d861f278a3b7bce7cb5a88d71e6e6a903336f95ad5a2c29b295b63835b6eee3", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 1.00, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL", + "hex": "a9141c6fbaf46d64221e80cbae182c33ddf81b9294ac87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "34HNh57oBCRKkxNyjTuWAJkTbuGh6jg2Ms" + ] + } + } + ], + "hex": "01000000000100e1f5050000000017a9141c6fbaf46d64221e80cbae182c33ddf81b9294ac8700000000" +} diff --git a/src/test/data/txcreatemultisig3.hex b/src/test/data/txcreatemultisig3.hex new file mode 100644 index 0000000000..8d34f28f87 --- /dev/null +++ b/src/test/data/txcreatemultisig3.hex @@ -0,0 +1 @@ +01000000000100e1f50500000000220020e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f0500000000 diff --git a/src/test/data/txcreatemultisig3.json b/src/test/data/txcreatemultisig3.json new file mode 100644 index 0000000000..88e32bd310 --- /dev/null +++ b/src/test/data/txcreatemultisig3.json @@ -0,0 +1,20 @@ +{ + "txid": "ccc552220b46a3b5140048b03395987ce4f0fa1ddf8c635bba1fa44e0f8c1d7f", + "hash": "ccc552220b46a3b5140048b03395987ce4f0fa1ddf8c635bba1fa44e0f8c1d7f", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 1.00, + "n": 0, + "scriptPubKey": { + "asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05", + "hex": "0020e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05", + "type": "witness_v0_scripthash" + } + } + ], + "hex": "01000000000100e1f50500000000220020e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f0500000000" +} diff --git a/src/test/data/txcreatemultisig4.hex b/src/test/data/txcreatemultisig4.hex new file mode 100644 index 0000000000..7da54366c7 --- /dev/null +++ b/src/test/data/txcreatemultisig4.hex @@ -0,0 +1 @@ +01000000000100e1f5050000000017a9146edf12858999f0dae74f9c692e6694ee3621b2ac8700000000 diff --git a/src/test/data/txcreatemultisig4.json b/src/test/data/txcreatemultisig4.json new file mode 100644 index 0000000000..fc69c7269c --- /dev/null +++ b/src/test/data/txcreatemultisig4.json @@ -0,0 +1,24 @@ +{ + "txid": "5e8b1cc73234e208d4b7ca9075f136b908c34101be7a048df4ba9ac758b61567", + "hash": "5e8b1cc73234e208d4b7ca9075f136b908c34101be7a048df4ba9ac758b61567", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 1.00, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL", + "hex": "a9146edf12858999f0dae74f9c692e6694ee3621b2ac87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "3BoFUz1StqcNcgUTZE5cC1eFhuYFzj3fGH" + ] + } + } + ], + "hex": "01000000000100e1f5050000000017a9146edf12858999f0dae74f9c692e6694ee3621b2ac8700000000" +} diff --git a/src/test/data/txcreateoutpubkey1.hex b/src/test/data/txcreateoutpubkey1.hex new file mode 100644 index 0000000000..4a08244b2f --- /dev/null +++ b/src/test/data/txcreateoutpubkey1.hex @@ -0,0 +1 @@ +0100000000010000000000000000232102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397ac00000000 diff --git a/src/test/data/txcreateoutpubkey1.json b/src/test/data/txcreateoutpubkey1.json new file mode 100644 index 0000000000..6019fa2dcd --- /dev/null +++ b/src/test/data/txcreateoutpubkey1.json @@ -0,0 +1,24 @@ +{ + "txid": "f42b38ac12e3fafc96ba1a9ba70cbfe326744aef75df5fb9db5d6e2855ca415f", + "hash": "f42b38ac12e3fafc96ba1a9ba70cbfe326744aef75df5fb9db5d6e2855ca415f", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 OP_CHECKSIG", + "hex": "2102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397ac", + "reqSigs": 1, + "type": "pubkey", + "addresses": [ + "1FoG2386FG2tAJS9acMuiDsKy67aGg9MKz" + ] + } + } + ], + "hex": "0100000000010000000000000000232102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397ac00000000" +} diff --git a/src/test/data/txcreateoutpubkey2.hex b/src/test/data/txcreateoutpubkey2.hex new file mode 100644 index 0000000000..8283c722ab --- /dev/null +++ b/src/test/data/txcreateoutpubkey2.hex @@ -0,0 +1 @@ +0100000000010000000000000000160014a2516e770582864a6a56ed21a102044e388c62e300000000 diff --git a/src/test/data/txcreateoutpubkey2.json b/src/test/data/txcreateoutpubkey2.json new file mode 100644 index 0000000000..6fc3d57527 --- /dev/null +++ b/src/test/data/txcreateoutpubkey2.json @@ -0,0 +1,20 @@ +{ + "txid": "70f2a088cde460e677415fa1fb71895e90c231e6ed38ed203a35b6f848e9cc73", + "hash": "70f2a088cde460e677415fa1fb71895e90c231e6ed38ed203a35b6f848e9cc73", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "0 a2516e770582864a6a56ed21a102044e388c62e3", + "hex": "0014a2516e770582864a6a56ed21a102044e388c62e3", + "type": "witness_v0_keyhash" + } + } + ], + "hex": "0100000000010000000000000000160014a2516e770582864a6a56ed21a102044e388c62e300000000" +} diff --git a/src/test/data/txcreateoutpubkey3.hex b/src/test/data/txcreateoutpubkey3.hex new file mode 100644 index 0000000000..84adff4d89 --- /dev/null +++ b/src/test/data/txcreateoutpubkey3.hex @@ -0,0 +1 @@ +010000000001000000000000000017a914a5ab14c9804d0d8bf02f1aea4e82780733ad0a838700000000 diff --git a/src/test/data/txcreateoutpubkey3.json b/src/test/data/txcreateoutpubkey3.json new file mode 100644 index 0000000000..a1a25fc834 --- /dev/null +++ b/src/test/data/txcreateoutpubkey3.json @@ -0,0 +1,24 @@ +{ + "txid": "bfc7e898ee9f6a9652d7b8cca147e2da134502e2ada0f279ed634fc8cf833f8c", + "hash": "bfc7e898ee9f6a9652d7b8cca147e2da134502e2ada0f279ed634fc8cf833f8c", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL", + "hex": "a914a5ab14c9804d0d8bf02f1aea4e82780733ad0a8387", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "3GnzN8FqgvYGYdhj8NW6UNxxVv3Uj1ApQn" + ] + } + } + ], + "hex": "010000000001000000000000000017a914a5ab14c9804d0d8bf02f1aea4e82780733ad0a838700000000" +} diff --git a/src/test/data/txcreatescript1.hex b/src/test/data/txcreatescript1.hex new file mode 100644 index 0000000000..0adce270fb --- /dev/null +++ b/src/test/data/txcreatescript1.hex @@ -0,0 +1 @@ +0100000000010000000000000000017500000000 diff --git a/src/test/data/txcreatescript1.json b/src/test/data/txcreatescript1.json new file mode 100644 index 0000000000..8ffecba411 --- /dev/null +++ b/src/test/data/txcreatescript1.json @@ -0,0 +1,20 @@ +{ + "txid": "f0851b68202f736b792649cfc960259c2374badcb644ab20cac726b5f72f61c9", + "hash": "f0851b68202f736b792649cfc960259c2374badcb644ab20cac726b5f72f61c9", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "OP_DROP", + "hex": "75", + "type": "nonstandard" + } + } + ], + "hex": "0100000000010000000000000000017500000000" +} diff --git a/src/test/data/txcreatescript2.hex b/src/test/data/txcreatescript2.hex new file mode 100644 index 0000000000..5afe8786e3 --- /dev/null +++ b/src/test/data/txcreatescript2.hex @@ -0,0 +1 @@ +010000000001000000000000000017a91471ed53322d470bb96657deb786b94f97dd46fb158700000000 diff --git a/src/test/data/txcreatescript2.json b/src/test/data/txcreatescript2.json new file mode 100644 index 0000000000..41eb69f1af --- /dev/null +++ b/src/test/data/txcreatescript2.json @@ -0,0 +1,24 @@ +{ + "txid": "6e07a7cc075e0703f32ee8c4e5373fe654bfbc315148fda364e1be286ff290d0", + "hash": "6e07a7cc075e0703f32ee8c4e5373fe654bfbc315148fda364e1be286ff290d0", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL", + "hex": "a91471ed53322d470bb96657deb786b94f97dd46fb1587", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "3C5QarEGh9feKbDJ3QbMf2YNjnMoiPDhNp" + ] + } + } + ], + "hex": "010000000001000000000000000017a91471ed53322d470bb96657deb786b94f97dd46fb158700000000" +} diff --git a/src/test/data/txcreatescript3.hex b/src/test/data/txcreatescript3.hex new file mode 100644 index 0000000000..8a2b973bf0 --- /dev/null +++ b/src/test/data/txcreatescript3.hex @@ -0,0 +1 @@ +01000000000100000000000000002200200bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad600000000 diff --git a/src/test/data/txcreatescript3.json b/src/test/data/txcreatescript3.json new file mode 100644 index 0000000000..90e7e27f9f --- /dev/null +++ b/src/test/data/txcreatescript3.json @@ -0,0 +1,20 @@ +{ + "txid": "8a234037b088e987c877030efc83374a07441c321bf9dc6dd2f206bc26507df8", + "hash": "8a234037b088e987c877030efc83374a07441c321bf9dc6dd2f206bc26507df8", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6", + "hex": "00200bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6", + "type": "witness_v0_scripthash" + } + } + ], + "hex": "01000000000100000000000000002200200bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad600000000" +} diff --git a/src/test/data/txcreatescript4.hex b/src/test/data/txcreatescript4.hex new file mode 100644 index 0000000000..b4cfe58f42 --- /dev/null +++ b/src/test/data/txcreatescript4.hex @@ -0,0 +1 @@ +010000000001000000000000000017a9146a2c482f4985f57e702f325816c90e3723ca81ae8700000000 diff --git a/src/test/data/txcreatescript4.json b/src/test/data/txcreatescript4.json new file mode 100644 index 0000000000..11783751a4 --- /dev/null +++ b/src/test/data/txcreatescript4.json @@ -0,0 +1,24 @@ +{ + "txid": "24225cf5e9391100d6b218134b9f03383ca4c880a1f634ac12990cf28b66adbc", + "hash": "24225cf5e9391100d6b218134b9f03383ca4c880a1f634ac12990cf28b66adbc", + "version": 1, + "locktime": 0, + "vin": [ + ], + "vout": [ + { + "value": 0.00, + "n": 0, + "scriptPubKey": { + "asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL", + "hex": "a9146a2c482f4985f57e702f325816c90e3723ca81ae87", + "reqSigs": 1, + "type": "scripthash", + "addresses": [ + "3BNQbeFeJJGMAyDxPwWPuqxPMrjsFLjk3f" + ] + } + } + ], + "hex": "010000000001000000000000000017a9146a2c482f4985f57e702f325816c90e3723ca81ae8700000000" +} diff --git a/src/test/data/txcreatesign.hex b/src/test/data/txcreatesignv1.hex index a46fcc88cb..a46fcc88cb 100644 --- a/src/test/data/txcreatesign.hex +++ b/src/test/data/txcreatesignv1.hex diff --git a/src/test/data/txcreatesign.json b/src/test/data/txcreatesignv1.json index ff39e71b40..ff39e71b40 100644 --- a/src/test/data/txcreatesign.json +++ b/src/test/data/txcreatesignv1.json diff --git a/src/test/data/txcreatesignv2.hex b/src/test/data/txcreatesignv2.hex new file mode 100644 index 0000000000..ee425cd98c --- /dev/null +++ b/src/test/data/txcreatesignv2.hex @@ -0,0 +1 @@ +02000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008a473044022079c7aa014177a2e973caf6df7c7b8f15399083b91eba370ea1e19c4caed9181e02205f8f8763505ce8e6cbdd2cd28fab3fd407a75003e7d0dc04e6bebb0a3c89e7cb01410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000 diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 2d791ee18d..22c90bd95b 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,13 +10,9 @@ #include <boost/assign/std/vector.hpp> // for 'operator+=()' #include <boost/assert.hpp> #include <boost/test/unit_test.hpp> - -using namespace std; -using namespace boost::assign; // bring 'operator+=()' into scope -using namespace boost::filesystem; - + // Test if a string consists entirely of null characters -bool is_null_key(const vector<unsigned char>& key) { +bool is_null_key(const std::vector<unsigned char>& key) { bool isnull = true; for (unsigned int i = 0; i < key.size(); i++) @@ -32,7 +28,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper) // Perform tests both obfuscated and non-obfuscated. for (int i = 0; i < 2; i++) { bool obfuscate = (bool)i; - path ph = temp_directory_path() / unique_path(); + boost::filesystem::path ph = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'k'; uint256 in = GetRandHash(); @@ -53,7 +49,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch) // Perform tests both obfuscated and non-obfuscated. for (int i = 0; i < 2; i++) { bool obfuscate = (bool)i; - path ph = temp_directory_path() / unique_path(); + boost::filesystem::path ph = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'i'; @@ -80,7 +76,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch) BOOST_CHECK(dbw.Read(key2, res)); BOOST_CHECK_EQUAL(res.ToString(), in2.ToString()); - // key3 never should've been written + // key3 should've never been written BOOST_CHECK(dbw.Read(key3, res) == false); } } @@ -90,7 +86,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) // Perform tests both obfuscated and non-obfuscated. for (int i = 0; i < 2; i++) { bool obfuscate = (bool)i; - path ph = temp_directory_path() / unique_path(); + boost::filesystem::path ph = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); // The two keys are intentionally chosen for ordering @@ -129,8 +125,8 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) // Test that we do not obfuscation if there is existing data. BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) { - // We're going to share this path between two wrappers - path ph = temp_directory_path() / unique_path(); + // We're going to share this boost::filesystem::path between two wrappers + boost::filesystem::path ph = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. @@ -170,8 +166,8 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) // Ensure that we start obfuscating during a reindex. BOOST_AUTO_TEST_CASE(existing_data_reindex) { - // We're going to share this path between two wrappers - path ph = temp_directory_path() / unique_path(); + // We're going to share this boost::filesystem::path between two wrappers + boost::filesystem::path ph = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. @@ -206,7 +202,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) BOOST_AUTO_TEST_CASE(iterator_ordering) { - path ph = temp_directory_path() / unique_path(); + boost::filesystem::path ph = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<256; ++x) { uint8_t key = x; @@ -241,11 +237,11 @@ BOOST_AUTO_TEST_CASE(iterator_ordering) struct StringContentsSerializer { // Used to make two serialized objects the same while letting them have a different lengths // This is a terrible idea - string str; + std::string str; StringContentsSerializer() {} - StringContentsSerializer(const string& inp) : str(inp) {} + StringContentsSerializer(const std::string& inp) : str(inp) {} - StringContentsSerializer& operator+=(const string& s) { + StringContentsSerializer& operator+=(const std::string& s) { str += s; return *this; } @@ -277,11 +273,11 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) { char buf[10]; - path ph = temp_directory_path() / unique_path(); + boost::filesystem::path ph = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<10; ++x) { for (int y = 0; y < 10; y++) { - sprintf(buf, "%d", x); + snprintf(buf, sizeof(buf), "%d", x); StringContentsSerializer key(buf); for (int z = 0; z < y; z++) key += key; @@ -297,13 +293,13 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) seek_start = 0; else seek_start = 5; - sprintf(buf, "%d", seek_start); + snprintf(buf, sizeof(buf), "%d", seek_start); StringContentsSerializer seek_key(buf); it->Seek(seek_key); for (int x=seek_start; x<10; ++x) { for (int y = 0; y < 10; y++) { - sprintf(buf, "%d", x); - string exp_key(buf); + snprintf(buf, sizeof(buf), "%d", x); + std::string exp_key(buf); for (int z = 0; z < y; z++) exp_key += exp_key; StringContentsSerializer key; diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index fa9624f13d..d8de765db1 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2015 The Bitcoin Core developers +// Copyright (c) 2013-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,8 +10,6 @@ #include <boost/test/unit_test.hpp> -using namespace std; - BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(murmurhash3) @@ -124,7 +122,11 @@ BOOST_AUTO_TEST_CASE(siphash) } CHashWriter ss(SER_DISK, CLIENT_VERSION); - ss << CTransaction(); + CMutableTransaction tx; + // Note these tests were originally written with tx.nVersion=1 + // and the test would be affected by default tx version bumps if not fixed. + tx.nVersion = 1; + ss << tx; BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL); } diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 4978c95130..40a7fdf11d 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -16,19 +16,17 @@ #include <boost/test/unit_test.hpp> -using namespace std; - -static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj"); -static const string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3"); -static const string strSecret1C ("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw"); -static const string strSecret2C ("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g"); +static const std::string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj"); +static const std::string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3"); +static const std::string strSecret1C ("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw"); +static const std::string strSecret2C ("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g"); static const CBitcoinAddress addr1 ("1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ"); static const CBitcoinAddress addr2 ("1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ"); static const CBitcoinAddress addr1C("1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs"); static const CBitcoinAddress addr2C("1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs"); -static const string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF"); +static const std::string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF"); #ifdef KEY_TESTS_DUMPINFO @@ -37,7 +35,7 @@ void dumpKeyInfo(uint256 privkey) CKey key; key.resize(32); memcpy(&secret[0], &privkey, 32); - vector<unsigned char> sec; + std::vector<unsigned char> sec; sec.resize(32); memcpy(&sec[0], &secret[0], 32); printf(" * secret (hex): %s\n", HexStr(sec).c_str()); @@ -51,7 +49,7 @@ void dumpKeyInfo(uint256 privkey) printf(" * secret (base58): %s\n", bsecret.ToString().c_str()); CKey key; key.SetSecret(secret, fCompressed); - vector<unsigned char> vchPubKey = key.GetPubKey(); + std::vector<unsigned char> vchPubKey = key.GetPubKey(); printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str()); printf(" * address (base58): %s\n", CBitcoinAddress(vchPubKey).ToString().c_str()); } @@ -111,12 +109,12 @@ BOOST_AUTO_TEST_CASE(key_test1) for (int n=0; n<16; n++) { - string strMsg = strprintf("Very secret message %i: 11", n); + std::string strMsg = strprintf("Very secret message %i: 11", n); uint256 hashMsg = Hash(strMsg.begin(), strMsg.end()); // normal signatures - vector<unsigned char> sign1, sign2, sign1C, sign2C; + std::vector<unsigned char> sign1, sign2, sign1C, sign2C; BOOST_CHECK(key1.Sign (hashMsg, sign1)); BOOST_CHECK(key2.Sign (hashMsg, sign2)); @@ -145,7 +143,7 @@ BOOST_AUTO_TEST_CASE(key_test1) // compact signatures (with key recovery) - vector<unsigned char> csign1, csign2, csign1C, csign2C; + std::vector<unsigned char> csign1, csign2, csign1C, csign2C; BOOST_CHECK(key1.SignCompact (hashMsg, csign1)); BOOST_CHECK(key2.SignCompact (hashMsg, csign2)); @@ -168,7 +166,7 @@ BOOST_AUTO_TEST_CASE(key_test1) // test deterministic signing std::vector<unsigned char> detsig, detsigc; - string strMsg = "Very deterministic message"; + std::string strMsg = "Very deterministic message"; uint256 hashMsg = Hash(strMsg.begin(), strMsg.end()); BOOST_CHECK(key1.Sign(hashMsg, detsig)); BOOST_CHECK(key1C.Sign(hashMsg, detsigc)); diff --git a/src/test/limitedmap_tests.cpp b/src/test/limitedmap_tests.cpp index e3531486aa..b071ab117b 100644 --- a/src/test/limitedmap_tests.cpp +++ b/src/test/limitedmap_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(limitedmap_test) // make sure that the size is updated BOOST_CHECK(map.size() == 1); - // make sure that the new items is in the map + // make sure that the new item is in the map BOOST_CHECK(map.count(-1) == 1); // insert 10 new items diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 697fbf792c..d52104b4cc 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2015 The Bitcoin Core developers +// Copyright (c) 2014-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 1faf8b6aeb..91f549fe48 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -55,17 +55,17 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) CTxMemPool testPool(CFeeRate(0)); - std::vector<CTransactionRef> removed; // Nothing in pool, remove should do nothing: - testPool.removeRecursive(txParent, &removed); - BOOST_CHECK_EQUAL(removed.size(), 0); + unsigned int poolSize = testPool.size(); + testPool.removeRecursive(txParent); + BOOST_CHECK_EQUAL(testPool.size(), poolSize); // Just the parent: testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); - testPool.removeRecursive(txParent, &removed); - BOOST_CHECK_EQUAL(removed.size(), 1); - removed.clear(); + poolSize = testPool.size(); + testPool.removeRecursive(txParent); + BOOST_CHECK_EQUAL(testPool.size(), poolSize - 1); // Parent, children, grandchildren: testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); @@ -75,19 +75,21 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) testPool.addUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i])); } // Remove Child[0], GrandChild[0] should be removed: - testPool.removeRecursive(txChild[0], &removed); - BOOST_CHECK_EQUAL(removed.size(), 2); - removed.clear(); + poolSize = testPool.size(); + testPool.removeRecursive(txChild[0]); + BOOST_CHECK_EQUAL(testPool.size(), poolSize - 2); // ... make sure grandchild and child are gone: - testPool.removeRecursive(txGrandChild[0], &removed); - BOOST_CHECK_EQUAL(removed.size(), 0); - testPool.removeRecursive(txChild[0], &removed); - BOOST_CHECK_EQUAL(removed.size(), 0); + poolSize = testPool.size(); + testPool.removeRecursive(txGrandChild[0]); + BOOST_CHECK_EQUAL(testPool.size(), poolSize); + poolSize = testPool.size(); + testPool.removeRecursive(txChild[0]); + BOOST_CHECK_EQUAL(testPool.size(), poolSize); // Remove parent, all children/grandchildren should go: - testPool.removeRecursive(txParent, &removed); - BOOST_CHECK_EQUAL(removed.size(), 5); + poolSize = testPool.size(); + testPool.removeRecursive(txParent); + BOOST_CHECK_EQUAL(testPool.size(), poolSize - 5); BOOST_CHECK_EQUAL(testPool.size(), 0); - removed.clear(); // Add children and grandchildren, but NOT the parent (simulate the parent being in a block) for (int i = 0; i < 3; i++) @@ -97,10 +99,10 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) } // Now remove the parent, as might happen if a block-re-org occurs but the parent cannot be // put into the mempool (maybe because it is non-standard): - testPool.removeRecursive(txParent, &removed); - BOOST_CHECK_EQUAL(removed.size(), 6); + poolSize = testPool.size(); + testPool.removeRecursive(txParent); + BOOST_CHECK_EQUAL(testPool.size(), poolSize - 6); BOOST_CHECK_EQUAL(testPool.size(), 0); - removed.clear(); } template<typename name> @@ -118,7 +120,6 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) { CTxMemPool pool(CFeeRate(0)); TestMemPoolEntryHelper entry; - entry.hadNoDependencies = true; /* 3rd highest fee */ CMutableTransaction tx1 = CMutableTransaction(); @@ -321,7 +322,6 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) { CTxMemPool pool(CFeeRate(0)); TestMemPoolEntryHelper entry; - entry.hadNoDependencies = true; /* 3rd highest fee */ CMutableTransaction tx1 = CMutableTransaction(); @@ -388,7 +388,12 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6)); BOOST_CHECK_EQUAL(pool.size(), 6); - sortedOrder.push_back(tx6.GetHash().ToString()); + // Ties are broken by hash + if (tx3.GetHash() < tx6.GetHash()) + sortedOrder.push_back(tx6.GetHash().ToString()); + else + sortedOrder.insert(sortedOrder.end()-1,tx6.GetHash().ToString()); + CheckSort<ancestor_score>(pool, sortedOrder); CMutableTransaction tx7 = CMutableTransaction(); @@ -412,10 +417,14 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) /* after tx6 is mined, tx7 should move up in the sort */ std::vector<CTransactionRef> vtx; vtx.push_back(MakeTransactionRef(tx6)); - pool.removeForBlock(vtx, 1, NULL, false); + pool.removeForBlock(vtx, 1); sortedOrder.erase(sortedOrder.begin()+1); - sortedOrder.pop_back(); + // Ties are broken by hash + if (tx3.GetHash() < tx6.GetHash()) + sortedOrder.pop_back(); + else + sortedOrder.erase(sortedOrder.end()-2); sortedOrder.insert(sortedOrder.begin(), tx7.GetHash().ToString()); CheckSort<ancestor_score>(pool, sortedOrder); } diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp index 55e6852a15..af02d67f74 100644 --- a/src/test/merkle_tests.cpp +++ b/src/test/merkle_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015 The Bitcoin Core developers +// Copyright (c) 2015-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index bc1bdd8874..5dbbb1b634 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,6 +9,7 @@ #include "consensus/validation.h" #include "validation.h" #include "miner.h" +#include "policy/policy.h" #include "pubkey.h" #include "script/standard.h" #include "txmempool.h" @@ -24,6 +25,17 @@ BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup) +static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE); + +static BlockAssembler AssemblerForTest(const CChainParams& params) { + BlockAssembler::Options options; + + options.nBlockMaxWeight = MAX_BLOCK_WEIGHT; + options.nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; + options.blockMinFeeRate = blockMinFeeRate; + return BlockAssembler(params, options); +} + static struct { unsigned char extranonce; @@ -107,12 +119,12 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, uint256 hashHighFeeTx = tx.GetHash(); mempool.addUnchecked(hashHighFeeTx, entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx); BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx); BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx); - // Test that a package below the min relay fee doesn't get included + // Test that a package below the block min tx fee doesn't get included tx.vin[0].prevout.hash = hashHighFeeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee uint256 hashFreeTx = tx.GetHash(); @@ -120,14 +132,14 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, size_t freeTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Calculate a fee on child transaction that will put the package just - // below the min relay fee (assuming 1 child tx of the same size). - CAmount feeToUse = minRelayTxFee.GetFee(2*freeTxSize) - 1; + // below the block min tx fee (assuming 1 child tx of the same size). + CAmount feeToUse = blockMinFeeRate.GetFee(2*freeTxSize) - 1; tx.vin[0].prevout.hash = hashFreeTx; tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; uint256 hashLowFeeTx = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); // Verify that the free tx and the low fee tx didn't get selected for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx); @@ -141,7 +153,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, tx.vout[0].nValue -= 2; // Now we should be just over the min relay fee hashLowFeeTx = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx, entry.Fee(feeToUse+2).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashFreeTx); BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashLowFeeTx); @@ -158,11 +170,11 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, // This tx can't be mined by itself tx.vin[0].prevout.hash = hashFreeTx2; tx.vout.resize(1); - feeToUse = minRelayTxFee.GetFee(freeTxSize); + feeToUse = blockMinFeeRate.GetFee(freeTxSize); tx.vout[0].nValue = 5000000000LL - 100000000 - feeToUse; uint256 hashLowFeeTx2 = tx.GetHash(); mempool.addUnchecked(hashLowFeeTx2, entry.Fee(feeToUse).SpendsCoinbase(false).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); // Verify that this tx isn't selected. for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { @@ -175,7 +187,7 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, tx.vin[0].prevout.n = 1; tx.vout[0].nValue = 100000000 - 10000; // 10k satoshi fee mempool.addUnchecked(tx.GetHash(), entry.Fee(10000).FromTx(tx)); - pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey); + pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); BOOST_CHECK(pblocktemplate->block.vtx[8]->GetHash() == hashLowFeeTx2); } @@ -198,7 +210,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) fCheckpointsEnabled = false; // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -224,12 +236,12 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->nNonce = blockinfo[i].nonce; std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock); - BOOST_CHECK(ProcessNewBlock(chainparams, shared_pblock, true, NULL, NULL)); + BOOST_CHECK(ProcessNewBlock(chainparams, shared_pblock, true, NULL)); pblock->hashPrevBlock = pblock->GetHash(); } // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); const CAmount BLOCKSUBSIDY = 50*COIN; const CAmount LOWFEE = CENT; @@ -253,7 +265,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); tx.vin[0].prevout.hash = txFirst[0]->GetHash(); @@ -267,7 +279,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); mempool.clear(); // block size > limit @@ -287,13 +299,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); mempool.clear(); // orphan in mempool, template creation fails hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // child with higher priority than parent @@ -310,7 +322,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = tx.vout[0].nValue+BLOCKSUBSIDY-HIGHERFEE; //First txn output + fresh coinbase - new txn fee hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(HIGHERFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); mempool.clear(); // coinbase in mempool, template creation fails @@ -321,7 +333,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) hash = tx.GetHash(); // give it a fee so it'll get mined mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // invalid (pre-p2sh) txn in mempool, template creation fails @@ -338,7 +350,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // double spend txn pair in mempool, template creation fails @@ -351,7 +363,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK_THROW(BlockAssembler(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); + BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); // subsidy changing @@ -367,7 +379,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) next->BuildSkip(); chainActive.SetTip(next); } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // Extend to a 210000-long block chain. while (chainActive.Tip()->nHeight < 210000) { CBlockIndex* prev = chainActive.Tip(); @@ -379,7 +391,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) next->BuildSkip(); chainActive.SetTip(next); } - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // Delete the dummy blocks again. while (chainActive.Tip()->nHeight > nHeight) { CBlockIndex* del = chainActive.Tip(); @@ -465,7 +477,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | 1; BOOST_CHECK(!TestSequenceLocks(tx, flags)); // Sequence locks fail - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // None of the of the absolute height/time locked tx should have made // it into the template because we still check IsFinalTx in CreateNewBlock, @@ -478,7 +490,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) chainActive.Tip()->nHeight++; SetMockTime(chainActive.Tip()->GetMedianTimePast() + 1); - BOOST_CHECK(pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5); chainActive.Tip()->nHeight--; diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 581b0cee1e..dd5678ea6e 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,14 +17,12 @@ #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> -using namespace std; - -typedef vector<unsigned char> valtype; +typedef std::vector<unsigned char> valtype; BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup) CScript -sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn) +sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction, int whichIn) { uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SIGVERSION_BASE); @@ -32,7 +30,7 @@ sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, result << OP_0; // CHECKMULTISIG bug workaround BOOST_FOREACH(const CKey &key, keys) { - vector<unsigned char> vchSig; + std::vector<unsigned char> vchSig; BOOST_CHECK(key.Sign(hash, vchSig)); vchSig.push_back((unsigned char)SIGHASH_ALL); result << vchSig; @@ -75,7 +73,7 @@ BOOST_AUTO_TEST_CASE(multisig_verify) txTo[i].vout[0].nValue = 1; } - vector<CKey> keys; + std::vector<CKey> keys; CScript s; // Test a AND b: @@ -200,7 +198,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) partialkeystore.AddKey(key[0]); { - vector<valtype> solutions; + std::vector<valtype> solutions; txnouttype whichType; CScript s; s << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; @@ -213,7 +211,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(!IsMine(emptykeystore, s)); } { - vector<valtype> solutions; + std::vector<valtype> solutions; txnouttype whichType; CScript s; s << OP_DUP << OP_HASH160 << ToByteVector(key[0].GetPubKey().GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; @@ -226,7 +224,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(!IsMine(emptykeystore, s)); } { - vector<valtype> solutions; + std::vector<valtype> solutions; txnouttype whichType; CScript s; s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; @@ -239,13 +237,13 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(!IsMine(partialkeystore, s)); } { - vector<valtype> solutions; + std::vector<valtype> solutions; txnouttype whichType; CScript s; s << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(solutions.size(), 4U); - vector<CTxDestination> addrs; + std::vector<CTxDestination> addrs; int nRequired; BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired)); BOOST_CHECK(addrs[0] == keyaddr[0]); @@ -256,7 +254,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(!IsMine(partialkeystore, s)); } { - vector<valtype> solutions; + std::vector<valtype> solutions; txnouttype whichType; CScript s; s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG; diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 87cb38daac..b9ed4952bb 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -12,8 +12,6 @@ #include "netbase.h" #include "chainparams.h" -using namespace std; - class CAddrManSerializationMock : public CAddrMan { public: @@ -68,7 +66,7 @@ CDataStream AddrmanToStream(CAddrManSerializationMock& _addrman) ssPeersIn << FLATDATA(Params().MessageStart()); ssPeersIn << _addrman; std::string str = ssPeersIn.str(); - vector<unsigned char> vchData(str.begin(), str.end()); + std::vector<unsigned char> vchData(str.begin(), str.end()); return CDataStream(vchData, SER_DISK, CLIENT_VERSION); } @@ -164,12 +162,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) bool fInboundIn = false; // Test that fFeeler is false by default. - CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn); + std::unique_ptr<CNode> pnode1(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn)); BOOST_CHECK(pnode1->fInbound == false); BOOST_CHECK(pnode1->fFeeler == false); fInboundIn = true; - CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn); + std::unique_ptr<CNode> pnode2(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn)); BOOST_CHECK(pnode2->fInbound == true); BOOST_CHECK(pnode2->fFeeler == false); } diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 18ad5dc90b..1afef5b1ce 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,8 +10,6 @@ #include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> -using namespace std; - BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup) static CNetAddr ResolveIP(const char* ip) @@ -64,9 +62,9 @@ BOOST_AUTO_TEST_CASE(netbase_properties) } -bool static TestSplitHost(string test, string host, int port) +bool static TestSplitHost(std::string test, std::string host, int port) { - string hostOut; + std::string hostOut; int portOut = -1; SplitHostPort(test, portOut, hostOut); return hostOut == host && port == portOut; @@ -91,7 +89,7 @@ BOOST_AUTO_TEST_CASE(netbase_splithost) BOOST_CHECK(TestSplitHost("", "", -1)); } -bool static TestParse(string src, string canon) +bool static TestParse(std::string src, std::string canon) { CService addr(LookupNumeric(src.c_str(), 65535)); return canon == addr.ToString(); diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index e6b689bc6c..a1cb32019a 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,8 +17,6 @@ #include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> -using namespace std; - class CPartialMerkleTreeTester : public CPartialMerkleTree { public: diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index c57feaec90..0c060801bc 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index b6eb39bc38..4ca6f1caf0 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -11,8 +11,6 @@ #include <boost/test/unit_test.hpp> -using namespace std; - BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) /* Test calculation of next difficulty target with no constraints applying */ diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 1e5de2021c..bd8a7819a4 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015 The Bitcoin Core developers +// Copyright (c) 2015-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -169,6 +169,19 @@ public: pre_vector.swap(pre_vector_alt); test(); } + + void move() { + real_vector = std::move(real_vector_alt); + real_vector_alt.clear(); + pre_vector = std::move(pre_vector_alt); + pre_vector_alt.clear(); + } + + void copy() { + real_vector = real_vector_alt; + pre_vector = pre_vector_alt; + } + ~prevector_tester() { BOOST_CHECK_MESSAGE(passed, "insecure_rand_Rz: " << rand_cache.Rz @@ -240,9 +253,15 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt) if (((r >> 21) % 512) == 12) { test.assign(insecure_rand() % 32, insecure_rand()); } - if (((r >> 15) % 64) == 3) { + if (((r >> 15) % 8) == 3) { test.swap(); } + if (((r >> 15) % 16) == 8) { + test.copy(); + } + if (((r >> 15) % 32) == 18) { + test.move(); + } } } } diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp new file mode 100644 index 0000000000..0f40874f55 --- /dev/null +++ b/src/test/raii_event_tests.cpp @@ -0,0 +1,94 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <event2/event.h> + +#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED +// It would probably be ideal to define dummy test(s) that report skipped, but boost::test doesn't seem to make that practical (at least not in versions available with common distros) + +#include <map> +#include <stdlib.h> + +#include "support/events.h" + +#include "test/test_bitcoin.h" + +#include <vector> + +#include <boost/test/unit_test.hpp> + +static std::map<void*, short> tags; +static std::map<void*, uint16_t> orders; +static uint16_t tagSequence = 0; + +static void* tag_malloc(size_t sz) { + void* mem = malloc(sz); + if (!mem) return mem; + tags[mem]++; + orders[mem] = tagSequence++; + return mem; +} + +static void tag_free(void* mem) { + tags[mem]--; + orders[mem] = tagSequence++; + free(mem); +} + +BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(raii_event_creation) +{ + event_set_mem_functions(tag_malloc, realloc, tag_free); + + void* base_ptr = NULL; + { + auto base = obtain_event_base(); + base_ptr = (void*)base.get(); + BOOST_CHECK(tags[base_ptr] == 1); + } + BOOST_CHECK(tags[base_ptr] == 0); + + void* event_ptr = NULL; + { + auto base = obtain_event_base(); + auto event = obtain_event(base.get(), -1, 0, NULL, NULL); + + base_ptr = (void*)base.get(); + event_ptr = (void*)event.get(); + + BOOST_CHECK(tags[base_ptr] == 1); + BOOST_CHECK(tags[event_ptr] == 1); + } + BOOST_CHECK(tags[base_ptr] == 0); + BOOST_CHECK(tags[event_ptr] == 0); + + event_set_mem_functions(malloc, realloc, free); +} + +BOOST_AUTO_TEST_CASE(raii_event_order) +{ + event_set_mem_functions(tag_malloc, realloc, tag_free); + + void* base_ptr = NULL; + void* event_ptr = NULL; + { + auto base = obtain_event_base(); + auto event = obtain_event(base.get(), -1, 0, NULL, NULL); + + base_ptr = (void*)base.get(); + event_ptr = (void*)event.get(); + + // base should have allocated before event + BOOST_CHECK(orders[base_ptr] < orders[event_ptr]); + } + // base should be freed after event + BOOST_CHECK(orders[base_ptr] > orders[event_ptr]); + + event_set_mem_functions(malloc, realloc, free); +} + +BOOST_AUTO_TEST_SUITE_END() + +#endif // EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp new file mode 100644 index 0000000000..d2c46c0daa --- /dev/null +++ b/src/test/random_tests.cpp @@ -0,0 +1,19 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "random.h" + +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(random_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(osrandom_tests) +{ + BOOST_CHECK(Random_SanityCheck()); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp index 8bdff97000..00dc47e13e 100644 --- a/src/test/reverselock_tests.cpp +++ b/src/test/reverselock_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015 The Bitcoin Core developers +// Copyright (c) 2015-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index a359598ddc..399bdbc811 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,13 +16,11 @@ #include <univalue.h> -using namespace std; - -UniValue CallRPC(string args) +UniValue CallRPC(std::string args) { - vector<string> vArgs; + std::vector<std::string> vArgs; boost::split(vArgs, args, boost::is_any_of(" \t")); - string strMethod = vArgs[0]; + std::string strMethod = vArgs[0]; vArgs.erase(vArgs.begin()); JSONRPCRequest request; request.strMethod = strMethod; @@ -35,7 +33,7 @@ UniValue CallRPC(string args) return result; } catch (const UniValue& objError) { - throw runtime_error(find_value(objError, "message").get_str()); + throw std::runtime_error(find_value(objError, "message").get_str()); } } @@ -47,41 +45,41 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) // Test raw transaction API argument handling UniValue r; - BOOST_CHECK_THROW(CallRPC("getrawtransaction"), runtime_error); - BOOST_CHECK_THROW(CallRPC("getrawtransaction not_hex"), runtime_error); - BOOST_CHECK_THROW(CallRPC("getrawtransaction a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed not_int"), runtime_error); + BOOST_CHECK_THROW(CallRPC("getrawtransaction"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("getrawtransaction not_hex"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("getrawtransaction a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed not_int"), std::runtime_error); - BOOST_CHECK_THROW(CallRPC("createrawtransaction"), runtime_error); - BOOST_CHECK_THROW(CallRPC("createrawtransaction null null"), runtime_error); - BOOST_CHECK_THROW(CallRPC("createrawtransaction not_array"), runtime_error); - BOOST_CHECK_THROW(CallRPC("createrawtransaction [] []"), runtime_error); - BOOST_CHECK_THROW(CallRPC("createrawtransaction {} {}"), runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction null null"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction not_array"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction [] []"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction {} {}"), std::runtime_error); BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [] {}")); - BOOST_CHECK_THROW(CallRPC("createrawtransaction [] {} extra"), runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction [] {} extra"), std::runtime_error); - BOOST_CHECK_THROW(CallRPC("decoderawtransaction"), runtime_error); - BOOST_CHECK_THROW(CallRPC("decoderawtransaction null"), runtime_error); - BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), runtime_error); - string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"; - BOOST_CHECK_NO_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx)); + BOOST_CHECK_THROW(CallRPC("decoderawtransaction"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("decoderawtransaction null"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), std::runtime_error); + std::string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"; + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx)); BOOST_CHECK_EQUAL(find_value(r.get_obj(), "size").get_int(), 193); BOOST_CHECK_EQUAL(find_value(r.get_obj(), "version").get_int(), 1); BOOST_CHECK_EQUAL(find_value(r.get_obj(), "locktime").get_int(), 0); - BOOST_CHECK_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx+" extra"), runtime_error); + BOOST_CHECK_THROW(r = CallRPC(std::string("decoderawtransaction ")+rawtx+" extra"), std::runtime_error); - BOOST_CHECK_THROW(CallRPC("signrawtransaction"), runtime_error); - BOOST_CHECK_THROW(CallRPC("signrawtransaction null"), runtime_error); - BOOST_CHECK_THROW(CallRPC("signrawtransaction ff00"), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx)); - BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" null null NONE|ANYONECANPAY")); - BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" [] [] NONE|ANYONECANPAY")); - BOOST_CHECK_THROW(CallRPC(string("signrawtransaction ")+rawtx+" null null badenum"), runtime_error); + BOOST_CHECK_THROW(CallRPC("signrawtransaction"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("signrawtransaction null"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("signrawtransaction ff00"), std::runtime_error); + BOOST_CHECK_NO_THROW(CallRPC(std::string("signrawtransaction ")+rawtx)); + BOOST_CHECK_NO_THROW(CallRPC(std::string("signrawtransaction ")+rawtx+" null null NONE|ANYONECANPAY")); + BOOST_CHECK_NO_THROW(CallRPC(std::string("signrawtransaction ")+rawtx+" [] [] NONE|ANYONECANPAY")); + BOOST_CHECK_THROW(CallRPC(std::string("signrawtransaction ")+rawtx+" null null badenum"), std::runtime_error); // Only check failure cases for sendrawtransaction, there's no network to send to... - BOOST_CHECK_THROW(CallRPC("sendrawtransaction"), runtime_error); - BOOST_CHECK_THROW(CallRPC("sendrawtransaction null"), runtime_error); - BOOST_CHECK_THROW(CallRPC("sendrawtransaction DEADBEEF"), runtime_error); - BOOST_CHECK_THROW(CallRPC(string("sendrawtransaction ")+rawtx+" extra"), runtime_error); + BOOST_CHECK_THROW(CallRPC("sendrawtransaction"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("sendrawtransaction null"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("sendrawtransaction DEADBEEF"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC(std::string("sendrawtransaction ")+rawtx+" extra"), std::runtime_error); } BOOST_AUTO_TEST_CASE(rpc_togglenetwork) @@ -110,18 +108,18 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) { UniValue r; // input is a 1-of-2 multisig (so is output): - string prevout = + std::string prevout = "[{\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\"," "\"vout\":1,\"scriptPubKey\":\"a914b10c9df5f7edf436c697f02f1efdba4cf399615187\"," "\"redeemScript\":\"512103debedc17b3df2badbcdd86d5feb4562b86fe182e5998abd8bcd4f122c6155b1b21027e940bb73ab8732bfdf7f9216ecefca5b94d6df834e77e108f68e66f126044c052ae\"}]"; - r = CallRPC(string("createrawtransaction ")+prevout+" "+ + r = CallRPC(std::string("createrawtransaction ")+prevout+" "+ "{\"3HqAe9LtNBjnsfM4CyYaWTnvCaUYT7v4oZ\":11}"); - string notsigned = r.get_str(); - string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\""; - string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\""; - r = CallRPC(string("signrawtransaction ")+notsigned+" "+prevout+" "+"[]"); + std::string notsigned = r.get_str(); + std::string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\""; + std::string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\""; + r = CallRPC(std::string("signrawtransaction ")+notsigned+" "+prevout+" "+"[]"); BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false); - r = CallRPC(string("signrawtransaction ")+notsigned+" "+prevout+" "+"["+privkey1+","+privkey2+"]"); + r = CallRPC(std::string("signrawtransaction ")+notsigned+" "+prevout+" "+"["+privkey1+","+privkey2+"]"); BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true); } @@ -133,11 +131,11 @@ BOOST_AUTO_TEST_CASE(rpc_createraw_op_return) BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"68656c6c6f776f726c64\",\"data\":\"68656c6c6f776f726c64\"}")); // Key not "data" (bad address) - BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"somedata\":\"68656c6c6f776f726c64\"}"), runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"somedata\":\"68656c6c6f776f726c64\"}"), std::runtime_error); // Bad hex encoding of data output - BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345\"}"), runtime_error); - BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345g\"}"), runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345\"}"), std::runtime_error); + BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345g\"}"), std::runtime_error); // Data 81 bytes long BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081\"}")); @@ -241,23 +239,23 @@ BOOST_AUTO_TEST_CASE(json_parse_errors) BOOST_AUTO_TEST_CASE(rpc_ban) { - BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); - + BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); + UniValue r; - BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0 add"))); - BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.0:8334")), runtime_error); //portnumber for setban not allowed - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0 add"))); + BOOST_CHECK_THROW(r = CallRPC(std::string("setban 127.0.0.0:8334")), std::runtime_error); //portnumber for setban not allowed + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); UniValue ar = r.get_array(); UniValue o1 = ar[0].get_obj(); UniValue adr = find_value(o1, "address"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32"); - BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(CallRPC(std::string("setban 127.0.0.0 remove"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); - BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/24 add 1607731200 true"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/24 add 1607731200 true"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); @@ -265,10 +263,10 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); BOOST_CHECK_EQUAL(banned_until.get_int64(), 1607731200); // absolute time check - BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); + BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/24 add 200"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/24 add 200"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); @@ -279,43 +277,43 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK(banned_until.get_int64()-now <= 200); // must throw an exception because 127.0.0.1 is in already banned suubnet range - BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.1 add")), runtime_error); + BOOST_CHECK_THROW(r = CallRPC(std::string("setban 127.0.0.1 add")), std::runtime_error); - BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(CallRPC(std::string("setban 127.0.0.0/24 remove"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); - BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0/255.255.0.0 add"))); - BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.1.1 add")), runtime_error); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/255.255.0.0 add"))); + BOOST_CHECK_THROW(r = CallRPC(std::string("setban 127.0.1.1 add")), std::runtime_error); - BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); - BOOST_CHECK_THROW(r = CallRPC(string("setban test add")), runtime_error); //invalid IP + BOOST_CHECK_THROW(r = CallRPC(std::string("setban test add")), std::runtime_error); //invalid IP //IPv6 tests - BOOST_CHECK_NO_THROW(r = CallRPC(string("setban FE80:0000:0000:0000:0202:B3FF:FE1E:8329 add"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban FE80:0000:0000:0000:0202:B3FF:FE1E:8329 add"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/128"); - BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:db8::/ffff:fffc:0:0:0:0:0:0 add"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 2001:db8::/ffff:fffc:0:0:0:0:0:0 add"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/30"); - BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128 add"))); - BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); + BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128 add"))); + BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); o1 = ar[0].get_obj(); adr = find_value(o1, "address"); diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index 891ecf5015..e4ddf9d618 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -47,8 +47,8 @@ BOOST_AUTO_TEST_CASE(manythreads) // // So... ten shared counters, which if all the tasks execute // properly will sum to the number of tasks done. - // Each task adds or subtracts from one of the counters a - // random amount, and then schedules another task 0-1000 + // Each task adds or subtracts a random amount from one of the + // counters, and then schedules another task 0-1000 // microseconds in the future to subtract or add from // the counter -random_amount+1, so in the end the shared // counters should sum to the number of initial tasks performed. diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 789cc70d7f..f8fd8cc30c 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,8 +17,6 @@ #include <boost/test/unit_test.hpp> -using namespace std; - // Helpers: static std::vector<unsigned char> Serialize(const CScript& s) @@ -80,7 +78,7 @@ BOOST_AUTO_TEST_CASE(sign) } CMutableTransaction txFrom; // Funding transaction: - string reason; + std::string reason; txFrom.vout.resize(8); for (int i = 0; i < 4; i++) { @@ -178,7 +176,7 @@ BOOST_AUTO_TEST_CASE(set) } CMutableTransaction txFrom; // Funding transaction: - string reason; + std::string reason; txFrom.vout.resize(4); for (int i = 0; i < 4; i++) { @@ -263,7 +261,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) CCoinsViewCache coins(&coinsDummy); CBasicKeyStore keystore; CKey key[6]; - vector<CPubKey> keys; + std::vector<CPubKey> keys; for (int i = 0; i < 6; i++) { key[i].MakeNewKey(true); @@ -335,8 +333,8 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) // SignSignature doesn't know how to sign these. We're // not testing validating signatures, so just create // dummy signatures that DO include the correct P2SH scripts: - txTo.vin[3].scriptSig << OP_11 << OP_11 << vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end()); - txTo.vin[4].scriptSig << vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end()); + txTo.vin[3].scriptSig << OP_11 << OP_11 << std::vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end()); + txTo.vin[4].scriptSig << std::vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end()); BOOST_CHECK(::AreInputsStandard(txTo, coins)); // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4] @@ -349,7 +347,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd1.vin.resize(1); txToNonStd1.vin[0].prevout.n = 5; txToNonStd1.vin[0].prevout.hash = txFrom.GetHash(); - txToNonStd1.vin[0].scriptSig << vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end()); + txToNonStd1.vin[0].scriptSig << std::vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end()); BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U); @@ -361,7 +359,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd2.vin.resize(1); txToNonStd2.vin[0].prevout.n = 6; txToNonStd2.vin[0].prevout.hash = txFrom.GetHash(); - txToNonStd2.vin[0].scriptSig << vector<unsigned char>(twentySigops.begin(), twentySigops.end()); + txToNonStd2.vin[0].scriptSig << std::vector<unsigned char>(twentySigops.begin(), twentySigops.end()); BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index eb324d5a6b..32184165f7 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -29,15 +29,13 @@ #include <univalue.h> -using namespace std; - // Uncomment if you want to output updated JSON tests. // #define UPDATE_JSON_TESTS static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; -unsigned int ParseScriptFlags(string strFlags); -string FormatScriptFlags(unsigned int flags); +unsigned int ParseScriptFlags(std::string strFlags); +std::string FormatScriptFlags(unsigned int flags); UniValue read_json(const std::string& jsondata) @@ -145,8 +143,7 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CSc txSpend.nLockTime = 0; txSpend.vin.resize(1); txSpend.vout.resize(1); - txSpend.wit.vtxinwit.resize(1); - txSpend.wit.vtxinwit[0].scriptWitness = scriptWitness; + txSpend.vin[0].scriptWitness = scriptWitness; txSpend.vin[0].prevout.hash = txCredit.GetHash(); txSpend.vin[0].prevout.n = 0; txSpend.vin[0].scriptSig = scriptSig; @@ -176,10 +173,10 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript int libconsensus_flags = flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL; if (libconsensus_flags == flags) { if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect, message); } else { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(begin_ptr(scriptPubKey), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect, message); - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect,message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, NULL) == expect,message); } } #endif @@ -468,7 +465,7 @@ public: std::string JSONPrettyPrint(const UniValue& univalue) { std::string ret = univalue.write(4); - // Workaround for libunivalue pretty printer, which puts a space between comma's and newlines + // Workaround for libunivalue pretty printer, which puts a space between commas and newlines size_t pos = 0; while ((pos = ret.find(" \n", pos)) != std::string::npos) { ret.replace(pos, 2, "\n"); @@ -801,7 +798,7 @@ BOOST_AUTO_TEST_CASE(script_build) CScript witscript = CScript() << ToByteVector(keys.pubkey0); uint256 hash; CSHA256().Write(&witscript[0], witscript.size()).Finalize(hash.begin()); - vector<unsigned char> hashBytes = ToByteVector(hash); + std::vector<unsigned char> hashBytes = ToByteVector(hash); hashBytes.pop_back(); tests.push_back(TestBuilder(CScript() << OP_0 << hashBytes, "P2WPKH with wrong witness program length", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false @@ -966,7 +963,7 @@ BOOST_AUTO_TEST_CASE(script_json_test) for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; - string strTest = test.write(); + std::string strTest = test.write(); CScriptWitness witness; CAmount nValue = 0; unsigned int pos = 0; @@ -985,9 +982,9 @@ BOOST_AUTO_TEST_CASE(script_json_test) } continue; } - string scriptSigString = test[pos++].get_str(); + std::string scriptSigString = test[pos++].get_str(); CScript scriptSig = ParseScript(scriptSigString); - string scriptPubKeyString = test[pos++].get_str(); + std::string scriptPubKeyString = test[pos++].get_str(); CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[pos++].get_str()); int scriptError = ParseScriptError(test[pos++].get_str()); @@ -1006,21 +1003,21 @@ BOOST_AUTO_TEST_CASE(script_PushData) static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a }; ScriptError err; - vector<vector<unsigned char> > directStack; + std::vector<std::vector<unsigned char> > directStack; BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); - vector<vector<unsigned char> > pushdata1Stack; + std::vector<std::vector<unsigned char> > pushdata1Stack; BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(pushdata1Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); - vector<vector<unsigned char> > pushdata2Stack; + std::vector<std::vector<unsigned char> > pushdata2Stack; BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(pushdata2Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); - vector<vector<unsigned char> > pushdata4Stack; + std::vector<std::vector<unsigned char> > pushdata4Stack; BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SIGVERSION_BASE, &err)); BOOST_CHECK(pushdata4Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); @@ -1043,7 +1040,7 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac result << OP_0; BOOST_FOREACH(const CKey &key, keys) { - vector<unsigned char> vchSig; + std::vector<unsigned char> vchSig; BOOST_CHECK(key.Sign(hash, vchSig)); vchSig.push_back((unsigned char)SIGHASH_ALL); result << vchSig; @@ -1162,8 +1159,8 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) // Test the CombineSignatures function CAmount amount = 0; CBasicKeyStore keystore; - vector<CKey> keys; - vector<CPubKey> pubkeys; + std::vector<CKey> keys; + std::vector<CPubKey> pubkeys; for (int i = 0; i < 3; i++) { CKey key; @@ -1224,15 +1221,15 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) BOOST_CHECK(combined.scriptSig == scriptSig); // A couple of partially-signed versions: - vector<unsigned char> sig1; + std::vector<unsigned char> sig1; uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, SIGVERSION_BASE); BOOST_CHECK(keys[0].Sign(hash1, sig1)); sig1.push_back(SIGHASH_ALL); - vector<unsigned char> sig2; + std::vector<unsigned char> sig2; uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, SIGVERSION_BASE); BOOST_CHECK(keys[1].Sign(hash2, sig2)); sig2.push_back(SIGHASH_NONE); - vector<unsigned char> sig3; + std::vector<unsigned char> sig3; uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, SIGVERSION_BASE); BOOST_CHECK(keys[2].Sign(hash3, sig3)); sig3.push_back(SIGHASH_SINGLE); @@ -1306,9 +1303,9 @@ BOOST_AUTO_TEST_CASE(script_GetScriptAsm) BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2)); BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY)); - string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090"); - string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2"); - vector<unsigned char> vchPubKey = ToByteVector(ParseHex(pubKey)); + std::string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090"); + std::string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2"); + std::vector<unsigned char> vchPubKey = ToByteVector(ParseHex(pubKey)); BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey, true)); BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey, true)); diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index 6b6689c7d3..1d5893bdc3 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -12,8 +12,10 @@ BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup) -static const int64_t values[] = \ -{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX }; +/** A selection of numbers that do not trigger int64_t overflow + * when added/subtracted. */ +static const int64_t values[] = { 0, 1, -2, 127, 128, -255, 256, (1LL << 15) - 1, -(1LL << 16), (1LL << 24) - 1, (1LL << 31), 1 - (1LL << 32), 1LL << 40 }; + static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000}; static bool verify(const CScriptNum10& bignum, const CScriptNum& scriptnum) diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 1dc86eb116..9661a66514 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,7 +10,6 @@ #include <stdint.h> #include <boost/test/unit_test.hpp> -using namespace std; BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup) @@ -91,7 +90,7 @@ BOOST_AUTO_TEST_CASE(sizes) BOOST_AUTO_TEST_CASE(floats_conversion) { - // Choose values that map unambigiously to binary floating point to avoid + // Choose values that map unambiguously to binary floating point to avoid // rounding issues at the compiler side. BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F); BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F); @@ -110,7 +109,7 @@ BOOST_AUTO_TEST_CASE(floats_conversion) BOOST_AUTO_TEST_CASE(doubles_conversion) { - // Choose values that map unambigiously to binary floating point to avoid + // Choose values that map unambiguously to binary floating point to avoid // rounding issues at the compiler side. BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0); BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5); @@ -227,7 +226,7 @@ BOOST_AUTO_TEST_CASE(varints_bitpatterns) BOOST_AUTO_TEST_CASE(compactsize) { CDataStream ss(SER_DISK, 0); - vector<char>::size_type i, j; + std::vector<char>::size_type i, j; for (i = 1; i <= MAX_SIZE; i *= 2) { @@ -260,7 +259,7 @@ BOOST_AUTO_TEST_CASE(noncanonical) // Write some non-canonical CompactSize encodings, and // make sure an exception is thrown when read back. CDataStream ss(SER_DISK, 0); - vector<char>::size_type n; + std::vector<char>::size_type n; // zero encoded with three bytes: ss.write("\xfd\x00\x00", 3); diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index a524f5b946..5279cb243b 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2015 The Bitcoin Core developers +// Copyright (c) 2013-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 2e974cc612..13d8911f03 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,8 +15,6 @@ #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> -using namespace std; - // Helpers: static std::vector<unsigned char> Serialize(const CScript& s) @@ -73,7 +71,7 @@ ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction { ScriptError error; CTransaction inputi(input); - bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, inputi.wit.vtxinwit.size() > 0 ? &inputi.wit.vtxinwit[0].scriptWitness : NULL, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error); + bool ret = VerifyScript(inputi.vin[0].scriptSig, output.vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output.vout[0].nValue), &error); BOOST_CHECK((ret == true) == (error == SCRIPT_ERR_OK)); return error; @@ -84,13 +82,12 @@ ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction * and witness such that spendingTx spends output zero of creationTx. * Also inserts creationTx's output into the coins view. */ -void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CTxInWitness& witness) +void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableTransaction& creationTx, const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& witness) { creationTx.nVersion = 1; creationTx.vin.resize(1); creationTx.vin[0].prevout.SetNull(); creationTx.vin[0].scriptSig = CScript(); - creationTx.wit.vtxinwit.resize(1); creationTx.vout.resize(1); creationTx.vout[0].nValue = 1; creationTx.vout[0].scriptPubKey = scriptPubKey; @@ -100,8 +97,7 @@ void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableT spendingTx.vin[0].prevout.hash = creationTx.GetHash(); spendingTx.vin[0].prevout.n = 0; spendingTx.vin[0].scriptSig = scriptSig; - spendingTx.wit.vtxinwit.resize(1); - spendingTx.wit.vtxinwit[0] = witness; + spendingTx.vin[0].scriptWitness = witness; spendingTx.vout.resize(1); spendingTx.vout[0].nValue = 1; spendingTx.vout[0].scriptPubKey = CScript(); @@ -133,7 +129,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) // Do not use a valid signature to avoid using wallet operations. CScript scriptSig = CScript() << OP_0 << OP_0; - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxInWitness()); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CScriptWitness()); // Legacy counting only includes signature operations in scriptSigs and scriptPubKeys // of a transaction and does not take the actual executed sig operations into account. // spendingTx in itself does not contain a signature operation. @@ -151,7 +147,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); CScript scriptSig = CScript() << OP_0 << OP_0 << ToByteVector(redeemScript); - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CTxInWitness()); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, CScriptWitness()); assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2 * WITNESS_SCALE_FACTOR); assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); } @@ -161,14 +157,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript p2pk = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; CScript scriptPubKey = GetScriptForWitness(p2pk); CScript scriptSig = CScript(); - CTxInWitness witness; CScriptWitness scriptWitness; - scriptWitness.stack.push_back(vector<unsigned char>(0)); - scriptWitness.stack.push_back(vector<unsigned char>(0)); - witness.scriptWitness = scriptWitness; + scriptWitness.stack.push_back(std::vector<unsigned char>(0)); + scriptWitness.stack.push_back(std::vector<unsigned char>(0)); - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 1); // No signature operations if we don't verify the witness. assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags & ~SCRIPT_VERIFY_WITNESS) == 0); @@ -177,10 +171,10 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) // The sig op cost for witness version != 0 is zero. assert(scriptPubKey[0] == 0x00); scriptPubKey[0] = 0x51; - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 0); scriptPubKey[0] = 0x00; - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); // The witness of a coinbase transaction is not taken into account. spendingTx.vin[0].prevout.SetNull(); @@ -193,13 +187,11 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript scriptSig = GetScriptForWitness(p2pk); CScript scriptPubKey = GetScriptForDestination(CScriptID(scriptSig)); scriptSig = CScript() << ToByteVector(scriptSig); - CTxInWitness witness; CScriptWitness scriptWitness; - scriptWitness.stack.push_back(vector<unsigned char>(0)); - scriptWitness.stack.push_back(vector<unsigned char>(0)); - witness.scriptWitness = scriptWitness; + scriptWitness.stack.push_back(std::vector<unsigned char>(0)); + scriptWitness.stack.push_back(std::vector<unsigned char>(0)); - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 1); assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_EQUALVERIFY); } @@ -209,14 +201,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript witnessScript = CScript() << 1 << ToByteVector(pubkey) << ToByteVector(pubkey) << 2 << OP_CHECKMULTISIGVERIFY; CScript scriptPubKey = GetScriptForWitness(witnessScript); CScript scriptSig = CScript(); - CTxInWitness witness; CScriptWitness scriptWitness; - scriptWitness.stack.push_back(vector<unsigned char>(0)); - scriptWitness.stack.push_back(vector<unsigned char>(0)); - scriptWitness.stack.push_back(vector<unsigned char>(witnessScript.begin(), witnessScript.end())); - witness.scriptWitness = scriptWitness; + scriptWitness.stack.push_back(std::vector<unsigned char>(0)); + scriptWitness.stack.push_back(std::vector<unsigned char>(0)); + scriptWitness.stack.push_back(std::vector<unsigned char>(witnessScript.begin(), witnessScript.end())); - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2); assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags & ~SCRIPT_VERIFY_WITNESS) == 0); assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); @@ -228,14 +218,12 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost) CScript redeemScript = GetScriptForWitness(witnessScript); CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); CScript scriptSig = CScript() << ToByteVector(redeemScript); - CTxInWitness witness; CScriptWitness scriptWitness; - scriptWitness.stack.push_back(vector<unsigned char>(0)); - scriptWitness.stack.push_back(vector<unsigned char>(0)); - scriptWitness.stack.push_back(vector<unsigned char>(witnessScript.begin(), witnessScript.end())); - witness.scriptWitness = scriptWitness; + scriptWitness.stack.push_back(std::vector<unsigned char>(0)); + scriptWitness.stack.push_back(std::vector<unsigned char>(0)); + scriptWitness.stack.push_back(std::vector<unsigned char>(witnessScript.begin(), witnessScript.end())); - BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, witness); + BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig, scriptWitness); assert(GetTransactionSigOpCost(CTransaction(spendingTx), coins, flags) == 2); assert(VerifyWithFlag(creationTx, spendingTx, flags) == SCRIPT_ERR_CHECKMULTISIGVERIFY); } diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index d6835df71f..0b2fe0ef9d 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2015 The Bitcoin Core developers +// Copyright (c) 2014-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -100,4 +100,47 @@ BOOST_AUTO_TEST_CASE(getlocator_test) } } +BOOST_AUTO_TEST_CASE(findearliestatleast_test) +{ + std::vector<uint256> vHashMain(100000); + std::vector<CBlockIndex> vBlocksMain(100000); + for (unsigned int i=0; i<vBlocksMain.size(); i++) { + vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height + vBlocksMain[i].nHeight = i; + vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL; + vBlocksMain[i].phashBlock = &vHashMain[i]; + vBlocksMain[i].BuildSkip(); + if (i < 10) { + vBlocksMain[i].nTime = i; + vBlocksMain[i].nTimeMax = i; + } else { + // randomly choose something in the range [MTP, MTP*2] + int64_t medianTimePast = vBlocksMain[i].GetMedianTimePast(); + int r = insecure_rand() % medianTimePast; + vBlocksMain[i].nTime = r + medianTimePast; + vBlocksMain[i].nTimeMax = std::max(vBlocksMain[i].nTime, vBlocksMain[i-1].nTimeMax); + } + } + // Check that we set nTimeMax up correctly. + unsigned int curTimeMax = 0; + for (unsigned int i=0; i<vBlocksMain.size(); ++i) { + curTimeMax = std::max(curTimeMax, vBlocksMain[i].nTime); + BOOST_CHECK(curTimeMax == vBlocksMain[i].nTimeMax); + } + + // Build a CChain for the main branch. + CChain chain; + chain.SetTip(&vBlocksMain.back()); + + // Verify that FindEarliestAtLeast is correct. + for (unsigned int i=0; i<10000; ++i) { + // Pick a random element in vBlocksMain. + int r = insecure_rand() % vBlocksMain.size(); + int64_t test_time = vBlocksMain[r].nTime; + CBlockIndex *ret = chain.FindEarliestAtLeast(test_time); + BOOST_CHECK(ret->nTimeMax >= test_time); + BOOST_CHECK((ret->pprev==NULL) || ret->pprev->nTimeMax < test_time); + BOOST_CHECK(vBlocksMain[r].GetAncestor(ret->nHeight) == ret); + } +} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index 8b715ce93e..94b5cc119b 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers +// Copyright (c) 2012-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,8 +9,7 @@ #include <boost/assign/std/vector.hpp> // for 'operator+=()' #include <boost/assert.hpp> #include <boost/test/unit_test.hpp> - -using namespace std; + using namespace boost::assign; // bring 'operator+=()' into scope BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup) diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 139389117a..6039424480 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,6 +20,7 @@ #include "ui_interface.h" #include "rpc/server.h" #include "rpc/register.h" +#include "script/sigcache.h" #include "test/testutil.h" @@ -40,6 +41,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName) ECC_Start(); SetupEnvironment(); SetupNetworking(); + InitSignatureCache(); fPrintToDebugLog = false; // don't want to write to debug.log file fCheckBlockIndex = true; SelectParams(chainName); @@ -62,16 +64,16 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); + ForceSetArg("-datadir", pathTemp.string()); mempool.setSanityCheck(1.0); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); - InitBlockIndex(chainparams); + BOOST_REQUIRE(InitBlockIndex(chainparams)); { CValidationState state; bool ok = ActivateBestChain(state, chainparams); - BOOST_CHECK(ok); + BOOST_REQUIRE(ok); } nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) @@ -128,7 +130,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce; std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block); - ProcessNewBlock(chainparams, shared_pblock, true, NULL, NULL); + ProcessNewBlock(chainparams, shared_pblock, true, NULL); CBlock result = block; return result; @@ -145,22 +147,21 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction &tx, CT } CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn, CTxMemPool *pool) { - bool hasNoDependencies = pool ? pool->HasNoInputsOf(txn) : hadNoDependencies; - // Hack to assume either its completely dependent on other mempool txs or not at all - CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0; + // Hack to assume either it's completely dependent on other mempool txs or not at all + CAmount inChainValue = pool && pool->HasNoInputsOf(txn) ? txn.GetValueOut() : 0; - return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight, - hasNoDependencies, inChainValue, spendsCoinbase, sigOpCost, lp); + return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, dPriority, nHeight, + inChainValue, spendsCoinbase, sigOpCost, lp); } void Shutdown(void* parg) { - exit(0); + exit(EXIT_SUCCESS); } void StartShutdown() { - exit(0); + exit(EXIT_SUCCESS); } bool ShutdownRequested() diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 3dea20445d..5ef6fa764f 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -1,4 +1,4 @@ -// Copyright (c) 2015 The Bitcoin Core developers +// Copyright (c) 2015-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -70,14 +70,13 @@ struct TestMemPoolEntryHelper int64_t nTime; double dPriority; unsigned int nHeight; - bool hadNoDependencies; bool spendsCoinbase; unsigned int sigOpCost; LockPoints lp; TestMemPoolEntryHelper() : nFee(0), nTime(0), dPriority(0.0), nHeight(1), - hadNoDependencies(false), spendsCoinbase(false), sigOpCost(4) { } + spendsCoinbase(false), sigOpCost(4) { } CTxMemPoolEntry FromTx(const CMutableTransaction &tx, CTxMemPool *pool = NULL); CTxMemPoolEntry FromTx(const CTransaction &tx, CTxMemPool *pool = NULL); @@ -87,7 +86,6 @@ struct TestMemPoolEntryHelper TestMemPoolEntryHelper &Time(int64_t _time) { nTime = _time; return *this; } TestMemPoolEntryHelper &Priority(double _priority) { dPriority = _priority; return *this; } TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; } - TestMemPoolEntryHelper &HadNoDependencies(bool _hnd) { hadNoDependencies = _hnd; return *this; } TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; } TestMemPoolEntryHelper &SigOpsCost(unsigned int _sigopsCost) { sigOpCost = _sigopsCost; return *this; } }; diff --git a/src/test/test_bitcoin_fuzzy.cpp b/src/test/test_bitcoin_fuzzy.cpp new file mode 100644 index 0000000000..c4983f6f5c --- /dev/null +++ b/src/test/test_bitcoin_fuzzy.cpp @@ -0,0 +1,258 @@ +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include "consensus/merkle.h" +#include "primitives/block.h" +#include "script/script.h" +#include "addrman.h" +#include "chain.h" +#include "coins.h" +#include "compressor.h" +#include "net.h" +#include "protocol.h" +#include "streams.h" +#include "undo.h" +#include "version.h" +#include "pubkey.h" + +#include <stdint.h> +#include <unistd.h> + +#include <algorithm> +#include <vector> + +enum TEST_ID { + CBLOCK_DESERIALIZE=0, + CTRANSACTION_DESERIALIZE, + CBLOCKLOCATOR_DESERIALIZE, + CBLOCKMERKLEROOT, + CADDRMAN_DESERIALIZE, + CBLOCKHEADER_DESERIALIZE, + CBANENTRY_DESERIALIZE, + CTXUNDO_DESERIALIZE, + CBLOCKUNDO_DESERIALIZE, + CCOINS_DESERIALIZE, + CNETADDR_DESERIALIZE, + CSERVICE_DESERIALIZE, + CMESSAGEHEADER_DESERIALIZE, + CADDRESS_DESERIALIZE, + CINV_DESERIALIZE, + CBLOOMFILTER_DESERIALIZE, + CDISKBLOCKINDEX_DESERIALIZE, + CTXOUTCOMPRESSOR_DESERIALIZE, + TEST_ID_END +}; + +bool read_stdin(std::vector<char> &data) { + char buffer[1024]; + ssize_t length=0; + while((length = read(STDIN_FILENO, buffer, 1024)) > 0) { + data.insert(data.end(), buffer, buffer+length); + + if (data.size() > (1<<20)) return false; + } + return length==0; +} + +int main(int argc, char **argv) +{ + ECCVerifyHandle globalVerifyHandle; + std::vector<char> buffer; + if (!read_stdin(buffer)) return 0; + + if (buffer.size() < sizeof(uint32_t)) return 0; + + uint32_t test_id = 0xffffffff; + memcpy(&test_id, &buffer[0], sizeof(uint32_t)); + buffer.erase(buffer.begin(), buffer.begin() + sizeof(uint32_t)); + + if (test_id >= TEST_ID_END) return 0; + + CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); + try { + int nVersion; + ds >> nVersion; + ds.SetVersion(nVersion); + } catch (const std::ios_base::failure& e) { + return 0; + } + + switch(test_id) { + case CBLOCK_DESERIALIZE: + { + try + { + CBlock block; + ds >> block; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CTRANSACTION_DESERIALIZE: + { + try + { + CTransaction tx(deserialize, ds); + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CBLOCKLOCATOR_DESERIALIZE: + { + try + { + CBlockLocator bl; + ds >> bl; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CBLOCKMERKLEROOT: + { + try + { + CBlock block; + ds >> block; + bool mutated; + BlockMerkleRoot(block, &mutated); + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CADDRMAN_DESERIALIZE: + { + try + { + CAddrMan am; + ds >> am; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CBLOCKHEADER_DESERIALIZE: + { + try + { + CBlockHeader bh; + ds >> bh; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CBANENTRY_DESERIALIZE: + { + try + { + CBanEntry be; + ds >> be; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CTXUNDO_DESERIALIZE: + { + try + { + CTxUndo tu; + ds >> tu; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CBLOCKUNDO_DESERIALIZE: + { + try + { + CBlockUndo bu; + ds >> bu; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CCOINS_DESERIALIZE: + { + try + { + CCoins block; + ds >> block; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CNETADDR_DESERIALIZE: + { + try + { + CNetAddr na; + ds >> na; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CSERVICE_DESERIALIZE: + { + try + { + CService s; + ds >> s; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CMESSAGEHEADER_DESERIALIZE: + { + CMessageHeader::MessageStartChars pchMessageStart = {0x00, 0x00, 0x00, 0x00}; + try + { + CMessageHeader mh(pchMessageStart); + ds >> mh; + if (!mh.IsValid(pchMessageStart)) {return 0;} + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CADDRESS_DESERIALIZE: + { + try + { + CAddress a; + ds >> a; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CINV_DESERIALIZE: + { + try + { + CInv i; + ds >> i; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CBLOOMFILTER_DESERIALIZE: + { + try + { + CBloomFilter bf; + ds >> bf; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CDISKBLOCKINDEX_DESERIALIZE: + { + try + { + CDiskBlockIndex dbi; + ds >> dbi; + } catch (const std::ios_base::failure& e) {return 0;} + break; + } + case CTXOUTCOMPRESSOR_DESERIALIZE: + { + CTxOut to; + CTxOutCompressor toc(to); + try + { + ds >> toc; + } catch (const std::ios_base::failure& e) {return 0;} + + break; + } + default: + return 0; + } + return 0; +} + diff --git a/src/test/test_random.h b/src/test/test_random.h index e61b92b7bc..4a1637ac72 100644 --- a/src/test/test_random.h +++ b/src/test/test_random.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/testutil.cpp b/src/test/testutil.cpp index 304cffb798..e6d8622979 100644 --- a/src/test/testutil.cpp +++ b/src/test/testutil.cpp @@ -11,23 +11,5 @@ #include <boost/filesystem.hpp> boost::filesystem::path GetTempPath() { -#if BOOST_FILESYSTEM_VERSION == 3 return boost::filesystem::temp_directory_path(); -#else - // TODO: remove when we don't support filesystem v2 anymore - boost::filesystem::path path; -#ifdef WIN32 - char pszPath[MAX_PATH] = ""; - - if (GetTempPathA(MAX_PATH, pszPath)) - path = boost::filesystem::path(pszPath); -#else - path = boost::filesystem::path("/tmp"); -#endif - if (path.empty() || !boost::filesystem::is_directory(path)) { - LogPrintf("GetTempPath(): failed to find temp path\n"); - return boost::filesystem::path(""); - } - return path; -#endif } diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index 1224ff8454..34863fd9d0 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -7,8 +7,6 @@ #include <boost/test/unit_test.hpp> -using namespace std; - BOOST_FIXTURE_TEST_SUITE(timedata_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(util_MedianFilter) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index ae5406ef7e..374423179c 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -32,42 +32,40 @@ #include <univalue.h> -using namespace std; - -typedef vector<unsigned char> valtype; +typedef std::vector<unsigned char> valtype; // In script_tests.cpp extern UniValue read_json(const std::string& jsondata); -static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of - (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) - (string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH) - (string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC) - (string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG) - (string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S) - (string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY) - (string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA) - (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) - (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) - (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) - (string("MINIMALIF"), (unsigned int)SCRIPT_VERIFY_MINIMALIF) - (string("NULLFAIL"), (unsigned int)SCRIPT_VERIFY_NULLFAIL) - (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) - (string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY) - (string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS) - (string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) - (string("WITNESS_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_WITNESS_PUBKEYTYPE); - -unsigned int ParseScriptFlags(string strFlags) +static std::map<std::string, unsigned int> mapFlagNames = boost::assign::map_list_of + (std::string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) + (std::string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH) + (std::string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC) + (std::string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG) + (std::string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S) + (std::string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY) + (std::string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA) + (std::string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) + (std::string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) + (std::string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) + (std::string("MINIMALIF"), (unsigned int)SCRIPT_VERIFY_MINIMALIF) + (std::string("NULLFAIL"), (unsigned int)SCRIPT_VERIFY_NULLFAIL) + (std::string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) + (std::string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY) + (std::string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS) + (std::string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) + (std::string("WITNESS_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_WITNESS_PUBKEYTYPE); + +unsigned int ParseScriptFlags(std::string strFlags) { if (strFlags.empty()) { return 0; } unsigned int flags = 0; - vector<string> words; + std::vector<std::string> words; boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(",")); - BOOST_FOREACH(string word, words) + BOOST_FOREACH(std::string word, words) { if (!mapFlagNames.count(word)) BOOST_ERROR("Bad test: unknown verification flag '" << word << "'"); @@ -77,13 +75,13 @@ unsigned int ParseScriptFlags(string strFlags) return flags; } -string FormatScriptFlags(unsigned int flags) +std::string FormatScriptFlags(unsigned int flags) { if (flags == 0) { return ""; } - string ret; - std::map<string, unsigned int>::const_iterator it = mapFlagNames.begin(); + std::string ret; + std::map<std::string, unsigned int>::const_iterator it = mapFlagNames.begin(); while (it != mapFlagNames.end()) { if (flags & it->second) { ret += it->first + ","; @@ -109,7 +107,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) ScriptError err; for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; - string strTest = test.write(); + std::string strTest = test.write(); if (test[0].isArray()) { if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) @@ -118,8 +116,8 @@ BOOST_AUTO_TEST_CASE(tx_valid) continue; } - map<COutPoint, CScript> mapprevOutScriptPubKeys; - map<COutPoint, int64_t> mapprevOutValues; + std::map<COutPoint, CScript> mapprevOutScriptPubKeys; + std::map<COutPoint, int64_t> mapprevOutValues; UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { @@ -148,7 +146,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) continue; } - string transaction = test[1].get_str(); + std::string transaction = test[1].get_str(); CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION); CTransaction tx(deserialize, stream); @@ -170,7 +168,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) amount = mapprevOutValues[tx.vin[i].prevout]; } unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); - const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL; + const CScriptWitness *witness = &tx.vin[i].scriptWitness; BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], witness, verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err), strTest); @@ -194,7 +192,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) ScriptError err; for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; - string strTest = test.write(); + std::string strTest = test.write(); if (test[0].isArray()) { if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) @@ -203,8 +201,8 @@ BOOST_AUTO_TEST_CASE(tx_invalid) continue; } - map<COutPoint, CScript> mapprevOutScriptPubKeys; - map<COutPoint, int64_t> mapprevOutValues; + std::map<COutPoint, CScript> mapprevOutScriptPubKeys; + std::map<COutPoint, int64_t> mapprevOutValues; UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { @@ -233,7 +231,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) continue; } - string transaction = test[1].get_str(); + std::string transaction = test[1].get_str(); CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION ); CTransaction tx(deserialize, stream); @@ -254,7 +252,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) if (mapprevOutValues.count(tx.vin[i].prevout)) { amount = mapprevOutValues[tx.vin[i].prevout]; } - const CScriptWitness *witness = (i < tx.wit.vtxinwit.size()) ? &tx.wit.vtxinwit[i].scriptWitness : NULL; + const CScriptWitness *witness = &tx.vin[i].scriptWitness; fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], witness, verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err); } @@ -268,7 +266,7 @@ BOOST_AUTO_TEST_CASE(basic_transaction_tests) { // Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436) 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}; - vector<unsigned char> vch(ch, ch + sizeof(ch) -1); + std::vector<unsigned char> vch(ch, ch + sizeof(ch) -1); CDataStream stream(vch, SER_DISK, CLIENT_VERSION); CMutableTransaction tx; stream >> tx; @@ -351,7 +349,6 @@ void CreateCreditAndSpend(const CKeyStore& keystore, const CScript& outscript, C outputm.vin.resize(1); outputm.vin[0].prevout.SetNull(); outputm.vin[0].scriptSig = CScript(); - outputm.wit.vtxinwit.resize(1); outputm.vout.resize(1); outputm.vout[0].nValue = 1; outputm.vout[0].scriptPubKey = outscript; @@ -362,14 +359,12 @@ void CreateCreditAndSpend(const CKeyStore& keystore, const CScript& outscript, C assert(output->vin[0] == outputm.vin[0]); assert(output->vout.size() == 1); assert(output->vout[0] == outputm.vout[0]); - assert(output->wit.vtxinwit.size() == 0); CMutableTransaction inputm; inputm.nVersion = 1; inputm.vin.resize(1); inputm.vin[0].prevout.hash = output->GetHash(); inputm.vin[0].prevout.n = 0; - inputm.wit.vtxinwit.resize(1); inputm.vout.resize(1); inputm.vout[0].nValue = 1; inputm.vout[0].scriptPubKey = CScript(); @@ -382,24 +377,18 @@ void CreateCreditAndSpend(const CKeyStore& keystore, const CScript& outscript, C assert(input.vin[0] == inputm.vin[0]); assert(input.vout.size() == 1); assert(input.vout[0] == inputm.vout[0]); - if (inputm.wit.IsNull()) { - assert(input.wit.IsNull()); - } else { - assert(!input.wit.IsNull()); - assert(input.wit.vtxinwit.size() == 1); - assert(input.wit.vtxinwit[0].scriptWitness.stack == inputm.wit.vtxinwit[0].scriptWitness.stack); - } + assert(input.vin[0].scriptWitness.stack == inputm.vin[0].scriptWitness.stack); } void CheckWithFlag(const CTransactionRef& output, const CMutableTransaction& input, int flags, bool success) { ScriptError error; CTransaction inputi(input); - bool ret = VerifyScript(inputi.vin[0].scriptSig, output->vout[0].scriptPubKey, inputi.wit.vtxinwit.size() > 0 ? &inputi.wit.vtxinwit[0].scriptWitness : NULL, flags, TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue), &error); + bool ret = VerifyScript(inputi.vin[0].scriptSig, output->vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue), &error); assert(ret == success); } -static CScript PushAll(const vector<valtype>& values) +static CScript PushAll(const std::vector<valtype>& values) { CScript result; BOOST_FOREACH(const valtype& v, values) { @@ -416,7 +405,7 @@ static CScript PushAll(const vector<valtype>& values) void ReplaceRedeemScript(CScript& script, const CScript& redeemScript) { - vector<valtype> stack; + std::vector<valtype> stack; EvalScript(stack, script, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SIGVERSION_BASE); assert(stack.size() > 0); stack.back() = std::vector<unsigned char>(redeemScript.begin(), redeemScript.end()); @@ -434,7 +423,7 @@ BOOST_AUTO_TEST_CASE(test_big_witness_transaction) { CKeyID hash = key.GetPubKey().GetID(); CScript scriptPubKey = CScript() << OP_0 << std::vector<unsigned char>(hash.begin(), hash.end()); - vector<int> sigHashes; + std::vector<int> sigHashes; sigHashes.push_back(SIGHASH_NONE | SIGHASH_ANYONECANPAY); sigHashes.push_back(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY); sigHashes.push_back(SIGHASH_ALL | SIGHASH_ANYONECANPAY); @@ -697,11 +686,11 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) key.MakeNewKey(true); t.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); - string reason; + std::string reason; BOOST_CHECK(IsStandardTx(t, reason)); // Check dust with default relay fee: - CAmount nDustThreshold = 182 * minRelayTxFee.GetFeePerK()/1000 * 3; + CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK()/1000 * 3; BOOST_CHECK_EQUAL(nDustThreshold, 546); // dust: t.vout[0].nValue = nDustThreshold - 1; @@ -712,14 +701,14 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) // Check dust with odd relay fee to verify rounding: // nDustThreshold = 182 * 1234 / 1000 * 3 - minRelayTxFee = CFeeRate(1234); + dustRelayFee = CFeeRate(1234); // dust: t.vout[0].nValue = 672 - 1; BOOST_CHECK(!IsStandardTx(t, reason)); // not dust: t.vout[0].nValue = 672; BOOST_CHECK(IsStandardTx(t, reason)); - minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); + dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE); t.vout[0].scriptPubKey = CScript() << OP_1; BOOST_CHECK(!IsStandardTx(t, reason)); diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index 55b4d28fb2..c5367208ba 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -23,7 +23,7 @@ ToMemPool(CMutableTransaction& tx) LOCK(cs_main); CValidationState state; - return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, 0); + return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, NULL, NULL, true, 0); } BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) @@ -39,6 +39,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) spends.resize(2); for (int i = 0; i < 2; i++) { + spends[i].nVersion = 1; spends[i].vin.resize(1); spends[i].vin[0].prevout.hash = coinbaseTxns[0].GetHash(); spends[i].vin[0].prevout.n = 0; diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index 2732948060..70d83a2e54 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "arith_uint256.h" diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 7f794fcbe9..dffe8e55a8 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 BitPay Inc. -// Copyright (c) 2014-2015 The Bitcoin Core developers +// Copyright (c) 2014-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,8 +12,6 @@ #include <boost/test/unit_test.hpp> -using namespace std; - BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(univalue_constructor) @@ -53,7 +51,7 @@ BOOST_AUTO_TEST_CASE(univalue_constructor) BOOST_CHECK(v7.isNum()); BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21"); - string vs("yawn"); + std::string vs("yawn"); UniValue v8(vs); BOOST_CHECK(v8.isStr()); BOOST_CHECK_EQUAL(v8.getValStr(), "yawn"); @@ -69,41 +67,41 @@ BOOST_AUTO_TEST_CASE(univalue_typecheck) UniValue v1; BOOST_CHECK(v1.setNumStr("1")); BOOST_CHECK(v1.isNum()); - BOOST_CHECK_THROW(v1.get_bool(), runtime_error); + BOOST_CHECK_THROW(v1.get_bool(), std::runtime_error); UniValue v2; BOOST_CHECK(v2.setBool(true)); BOOST_CHECK_EQUAL(v2.get_bool(), true); - BOOST_CHECK_THROW(v2.get_int(), runtime_error); + BOOST_CHECK_THROW(v2.get_int(), std::runtime_error); UniValue v3; BOOST_CHECK(v3.setNumStr("32482348723847471234")); - BOOST_CHECK_THROW(v3.get_int64(), runtime_error); + BOOST_CHECK_THROW(v3.get_int64(), std::runtime_error); BOOST_CHECK(v3.setNumStr("1000")); BOOST_CHECK_EQUAL(v3.get_int64(), 1000); UniValue v4; BOOST_CHECK(v4.setNumStr("2147483648")); BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648); - BOOST_CHECK_THROW(v4.get_int(), runtime_error); + BOOST_CHECK_THROW(v4.get_int(), std::runtime_error); BOOST_CHECK(v4.setNumStr("1000")); BOOST_CHECK_EQUAL(v4.get_int(), 1000); - BOOST_CHECK_THROW(v4.get_str(), runtime_error); + BOOST_CHECK_THROW(v4.get_str(), std::runtime_error); BOOST_CHECK_EQUAL(v4.get_real(), 1000); - BOOST_CHECK_THROW(v4.get_array(), runtime_error); - BOOST_CHECK_THROW(v4.getKeys(), runtime_error); - BOOST_CHECK_THROW(v4.getValues(), runtime_error); - BOOST_CHECK_THROW(v4.get_obj(), runtime_error); + BOOST_CHECK_THROW(v4.get_array(), std::runtime_error); + BOOST_CHECK_THROW(v4.getKeys(), std::runtime_error); + BOOST_CHECK_THROW(v4.getValues(), std::runtime_error); + BOOST_CHECK_THROW(v4.get_obj(), std::runtime_error); UniValue v5; BOOST_CHECK(v5.read("[true, 10]")); BOOST_CHECK_NO_THROW(v5.get_array()); std::vector<UniValue> vals = v5.getValues(); - BOOST_CHECK_THROW(vals[0].get_int(), runtime_error); + BOOST_CHECK_THROW(vals[0].get_int(), std::runtime_error); BOOST_CHECK_EQUAL(vals[0].get_bool(), true); BOOST_CHECK_EQUAL(vals[1].get_int(), 10); - BOOST_CHECK_THROW(vals[1].get_bool(), runtime_error); + BOOST_CHECK_THROW(vals[1].get_bool(), std::runtime_error); } BOOST_AUTO_TEST_CASE(univalue_set) @@ -172,13 +170,13 @@ BOOST_AUTO_TEST_CASE(univalue_array) UniValue v((int64_t)1023LL); BOOST_CHECK(arr.push_back(v)); - string vStr("zippy"); + std::string vStr("zippy"); BOOST_CHECK(arr.push_back(vStr)); const char *s = "pippy"; BOOST_CHECK(arr.push_back(s)); - vector<UniValue> vec; + std::vector<UniValue> vec; v.setStr("boing"); vec.push_back(v); @@ -206,7 +204,7 @@ BOOST_AUTO_TEST_CASE(univalue_array) BOOST_AUTO_TEST_CASE(univalue_object) { UniValue obj(UniValue::VOBJ); - string strKey, strVal; + std::string strKey, strVal; UniValue v; strKey = "age"; @@ -266,7 +264,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) BOOST_CHECK(!obj.exists("nyuknyuknyuk")); - map<string, UniValue::VType> objTypes; + std::map<std::string, UniValue::VType> objTypes; objTypes["age"] = UniValue::VNUM; objTypes["first"] = UniValue::VSTR; objTypes["last"] = UniValue::VSTR; @@ -294,7 +292,7 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite) UniValue v; BOOST_CHECK(v.read(json1)); - string strJson1(json1); + std::string strJson1(json1); BOOST_CHECK(v.read(strJson1)); BOOST_CHECK(v.isArray()); @@ -333,4 +331,3 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite) } BOOST_AUTO_TEST_SUITE_END() - diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index bad72ffc0f..641655621c 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2015 The Bitcoin Core developers +// Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,7 +17,7 @@ #include <boost/test/unit_test.hpp> -using namespace std; +extern std::map<std::string, std::string> mapArgs; BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup) @@ -115,13 +115,13 @@ BOOST_AUTO_TEST_CASE(util_ParseParameters) // -a, -b and -ccc end up in map, -d ignored because it is after // a non-option argument (non-GNU option parsing) BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3); - BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc") - && !mapArgs.count("f") && !mapArgs.count("-d")); + BOOST_CHECK(IsArgSet("-a") && IsArgSet("-b") && IsArgSet("-ccc") + && !IsArgSet("f") && !IsArgSet("-d")); BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc") && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d")); BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple"); - BOOST_CHECK(mapMultiArgs["-ccc"].size() == 2); + BOOST_CHECK(mapMultiArgs.at("-ccc").size() == 2); } BOOST_AUTO_TEST_CASE(util_GetArg) diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index bae0eff7e5..e2b5573abd 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -292,7 +292,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) blocksToMine--; nTime += 600; nHeight += 1; - }; + } nTime = nTimeout; // FAILED is only triggered at the end of a period, so CBV should be setting |