aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/DoS_tests.cpp51
-rw-r--r--src/test/addrman_tests.cpp2
-rw-r--r--src/test/allocator_tests.cpp2
-rw-r--r--src/test/arith_uint256_tests.cpp2
-rw-r--r--src/test/base58_tests.cpp2
-rw-r--r--src/test/blockencodings_tests.cpp47
-rw-r--r--src/test/bloom_tests.cpp2
-rw-r--r--src/test/coins_tests.cpp540
-rw-r--r--src/test/crypto_tests.cpp2
-rw-r--r--src/test/data/bitcoin-util-test.json11
-rw-r--r--src/test/data/blanktxv1.json (renamed from src/test/data/blanktx.json)0
-rw-r--r--src/test/data/txcreatesign.json33
-rw-r--r--src/test/dbwrapper_tests.cpp2
-rw-r--r--src/test/hash_tests.cpp2
-rw-r--r--src/test/limitedmap_tests.cpp2
-rw-r--r--src/test/main_tests.cpp2
-rw-r--r--src/test/mempool_tests.cpp2
-rw-r--r--src/test/merkle_tests.cpp2
-rw-r--r--src/test/miner_tests.cpp2
-rw-r--r--src/test/multisig_tests.cpp2
-rw-r--r--src/test/netbase_tests.cpp2
-rw-r--r--src/test/pmt_tests.cpp2
-rw-r--r--src/test/policyestimator_tests.cpp2
-rw-r--r--src/test/prevector_tests.cpp23
-rw-r--r--src/test/reverselock_tests.cpp2
-rw-r--r--src/test/rpc_tests.cpp2
-rw-r--r--src/test/scheduler_tests.cpp2
-rw-r--r--src/test/script_P2SH_tests.cpp2
-rw-r--r--src/test/script_tests.cpp5
-rw-r--r--src/test/serialize_tests.cpp2
-rw-r--r--src/test/sighash_tests.cpp2
-rw-r--r--src/test/sigopcount_tests.cpp34
-rw-r--r--src/test/skiplist_tests.cpp2
-rw-r--r--src/test/streams_tests.cpp2
-rw-r--r--src/test/test_bitcoin.cpp6
-rw-r--r--src/test/test_bitcoin.h2
-rw-r--r--src/test/test_bitcoin_fuzzy.cpp2
-rw-r--r--src/test/test_random.h2
-rw-r--r--src/test/transaction_tests.cpp17
-rw-r--r--src/test/txvalidationcache_tests.cpp4
-rw-r--r--src/test/uint256_tests.cpp2
-rw-r--r--src/test/univalue_tests.cpp2
-rw-r--r--src/test/util_tests.cpp10
43 files changed, 643 insertions, 198 deletions
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 131d667e0b..9345a44fb0 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"
@@ -23,11 +24,11 @@
#include <boost/test/unit_test.hpp>
// Tests this internal-to-main.cpp method:
-extern bool AddOrphanTx(const CTransaction& tx, NodeId peer);
+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;
};
@@ -46,6 +47,8 @@ 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);
@@ -53,7 +56,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
GetNodeSignals().InitializeNode(&dummyNode1, *connman);
dummyNode1.nVersion = 1;
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,37 +66,41 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
GetNodeSignals().InitializeNode(&dummyNode2, *connman);
dummyNode2.nVersion = 1;
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;
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()
@@ -105,7 +112,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
dummyNode.nVersion = 1;
Misbehaving(dummyNode.GetId(), 100);
- SendMessages(&dummyNode, *connman);
+ SendMessages(&dummyNode, *connman, interruptDummy);
BOOST_CHECK(connman->IsBanned(addr));
SetMockTime(nStartTime+60*60);
@@ -115,7 +122,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());
@@ -143,30 +150,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);
@@ -176,15 +183,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:
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index adff09f754..078c5bbf2d 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"
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 04a6506655..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.
diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp
index 7478758f73..e3876e9695 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.
@@ -85,17 +85,23 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
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);
@@ -181,17 +187,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 +213,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);
}
@@ -240,8 +253,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 +263,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);
}
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index b15ff9e44b..a67b292378 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.
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 79dea00e46..70b958c296 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)));
+ }
- UpdateCoins(tx, *(stack.back()), height);
+ //1/20 times undo a previous transaction
+ else if (utxoset.size()) {
+ TxData &txd = FindRandomFrom(utxoset);
+
+ 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,372 @@ 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);
+ WriteCoinsViewEntry(test.cache, child_value, child_flags);
+ 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_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, PRUNED, 0 , DIRTY|FRESH, DIRTY );
+ CheckWriteCoins(VALUE1, PRUNED, ABSENT, FRESH , DIRTY , NO_ENTRY );
+ CheckWriteCoins(VALUE1, PRUNED, ABSENT, FRESH , DIRTY|FRESH, NO_ENTRY );
+ CheckWriteCoins(VALUE1, PRUNED, PRUNED, DIRTY , DIRTY , DIRTY );
+ CheckWriteCoins(VALUE1, PRUNED, PRUNED, DIRTY , DIRTY|FRESH, DIRTY );
+ CheckWriteCoins(VALUE1, PRUNED, ABSENT, DIRTY|FRESH, DIRTY , NO_ENTRY );
+ CheckWriteCoins(VALUE1, PRUNED, ABSENT, DIRTY|FRESH, DIRTY|FRESH, NO_ENTRY );
+ CheckWriteCoins(VALUE1, VALUE2, VALUE2, 0 , DIRTY , DIRTY );
+ CheckWriteCoins(VALUE1, VALUE2, VALUE2, 0 , DIRTY|FRESH, DIRTY );
+ CheckWriteCoins(VALUE1, VALUE2, VALUE2, FRESH , DIRTY , DIRTY|FRESH);
+ CheckWriteCoins(VALUE1, VALUE2, VALUE2, FRESH , DIRTY|FRESH, DIRTY|FRESH);
+ CheckWriteCoins(VALUE1, VALUE2, VALUE2, DIRTY , DIRTY , DIRTY );
+ CheckWriteCoins(VALUE1, VALUE2, VALUE2, DIRTY , DIRTY|FRESH, DIRTY );
+ CheckWriteCoins(VALUE1, VALUE2, VALUE2, DIRTY|FRESH, DIRTY , DIRTY|FRESH);
+ CheckWriteCoins(VALUE1, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH, DIRTY|FRESH);
+
+ // 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/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json
index ab1a1385a3..d001b2056f 100644
--- a/src/test/data/bitcoin-util-test.json
+++ b/src/test/data/bitcoin-util-test.json
@@ -5,9 +5,9 @@
"description": "Creates a blank v1 transaction"
},
{ "exec": "./bitcoin-tx",
- "args": ["-json","-create"],
- "output_cmp": "blanktxv2.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": ["-"],
@@ -16,6 +16,11 @@
"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": "blanktxv2.hex",
"output_cmp": "blanktxv2.json",
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/txcreatesign.json b/src/test/data/txcreatesign.json
deleted file mode 100644
index ff39e71b40..0000000000
--- a/src/test/data/txcreatesign.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "txid": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af",
- "hash": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af",
- "version": 1,
- "locktime": 0,
- "vin": [
- {
- "txid": "4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485",
- "vout": 0,
- "scriptSig": {
- "asm": "304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e2[ALL] 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
- "hex": "48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"
- },
- "sequence": 4294967295
- }
- ],
- "vout": [
- {
- "value": 0.001,
- "n": 0,
- "scriptPubKey": {
- "asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG",
- "hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"
- ]
- }
- }
- ],
- "hex": "01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008b48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000"
-}
diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
index 2d791ee18d..a0e1ed0505 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.
diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp
index 8be9c580c4..b265cf93b7 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.
diff --git a/src/test/limitedmap_tests.cpp b/src/test/limitedmap_tests.cpp
index e3531486aa..55b9be5b00 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.
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 84871600b2..37f0de354e 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.
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 892e731a7a..2f74f57d00 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.
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index 581b0cee1e..e949bf7620 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.
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 18ad5dc90b..b0ad93e6f2 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.
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
index e6b689bc6c..da05385c80 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.
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/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/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..36a29867ba 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.
diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp
index 891ecf5015..e1b0ab9258 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.
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index 789cc70d7f..85da90c75d 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.
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index d7f3a3a657..deb2919f14 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.
@@ -145,8 +145,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;
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index 1dc86eb116..5c192a1f41 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.
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..edafb76c43 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.
@@ -73,7 +73,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 +84,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 +99,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 +131,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 +149,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 +159,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;
- 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 +173,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 +189,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;
- 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 +203,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;
- 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 +220,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;
- 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..5b4ef3fe7d 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.
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index 8b715ce93e..31bcebe919 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.
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index 2a5a78de02..672cd11428 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.
@@ -64,7 +64,7 @@ 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);
@@ -151,7 +151,7 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn, CTxMemPo
// Hack to assume either its completely dependent on other mempool txs or not at all
CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;
- return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
+ return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, dPriority, nHeight,
hasNoDependencies, inChainValue, spendsCoinbase, sigOpCost, lp);
}
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
index 3dea20445d..0fe77437e4 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.
diff --git a/src/test/test_bitcoin_fuzzy.cpp b/src/test/test_bitcoin_fuzzy.cpp
index 584e6ed008..376d8e428a 100644
--- a/src/test/test_bitcoin_fuzzy.cpp
+++ b/src/test/test_bitcoin_fuzzy.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2015 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/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/transaction_tests.cpp b/src/test/transaction_tests.cpp
index ae5406ef7e..cd9294c7a9 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -170,7 +170,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);
@@ -254,7 +254,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);
}
@@ -351,7 +351,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 +361,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,20 +379,14 @@ 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);
}
diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp
index 9f58f004d5..acccaee98c 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, true, 0);
}
BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
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..05876aae04 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.
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index bad72ffc0f..fc42748d34 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.
@@ -19,6 +19,8 @@
using namespace std;
+extern map<string, string> mapArgs;
+
BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_criticalsection)
@@ -115,13 +117,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)