PIVX Core  5.6.99
P2P Digital Currency
txvalidationcache_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Copyright (c) 2020-2021 The PIVX Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
5 
6 #include "test/test_pivx.h"
7 
8 #include "consensus/validation.h"
9 #include "pubkey.h"
10 #include "random.h"
11 #include "script/standard.h"
12 #include "utiltime.h"
13 #include "validation.h"
14 
15 #include <boost/test/unit_test.hpp>
16 
17 BOOST_AUTO_TEST_SUITE(tx_validationcache_tests)
18 
19 static bool ToMemPool(CMutableTransaction& tx)
20 {
21  LOCK(cs_main);
22  CValidationState state;
23  return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, nullptr, true, false, false);
24 }
25 
26 BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
27 {
28  // Make sure skipping validation of transactions that were
29  // validated going into the memory pool does not allow
30  // double-spends in blocks to pass validation when they should not.
31 
32  CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
33 
34  // Create a double-spend of mature coinbase txn:
35  std::vector<CMutableTransaction> spends;
36  spends.resize(2);
37  for (int i = 0; i < 2; i++)
38  {
39  spends[i].nVersion = 1;
40  spends[i].vin.resize(1);
41  spends[i].vin[0].prevout.hash = coinbaseTxns[0].GetHash();
42  spends[i].vin[0].prevout.n = 0;
43  spends[i].vout.resize(1);
44  spends[i].vout[0].nValue = 11*CENT;
45  spends[i].vout[0].scriptPubKey = scriptPubKey;
46 
47  // Sign:
48  std::vector<unsigned char> vchSig;
49  uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, 0, SIGVERSION_BASE);
50  BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
51  vchSig.push_back((unsigned char)SIGHASH_ALL);
52  spends[i].vin[0].scriptSig << vchSig;
53  }
54 
55  const uint256& tipHash = chainActive.Tip()->GetBlockHash();
56  CBlock block;
57 
58  // Test 1: block with both of those transactions should be rejected.
59  block = CreateAndProcessBlock(spends, scriptPubKey);
61  BOOST_CHECK(chainActive.Tip()->GetBlockHash() == tipHash);
62 
63  // Test 2: ... and should be rejected if spend1 is in the memory pool
64  BOOST_CHECK(ToMemPool(spends[0]));
65  block = CreateAndProcessBlock(spends, scriptPubKey);
67  BOOST_CHECK(chainActive.Tip()->GetBlockHash() == tipHash);
68  mempool.clear();
69 
70  // Test 3: ... and should be rejected if spend2 is in the memory pool
71  BOOST_CHECK(ToMemPool(spends[1]));
72  SetMockTime(GetTime() + 60); // to generate a different block hash
73  block = CreateAndProcessBlock(spends, scriptPubKey);
75  BOOST_CHECK(chainActive.Tip()->GetBlockHash() == tipHash);
76  mempool.clear();
77 
78  // Final sanity test: first spend in mempool, second in block, that's OK:
79  std::vector<CMutableTransaction> oneSpend;
80  oneSpend.push_back(spends[0]);
81  BOOST_CHECK(ToMemPool(spends[1]));
82  block = CreateAndProcessBlock(oneSpend, scriptPubKey);
84  // spends[1] should have been removed from the mempool when the
85  // block with spends[0] is accepted:
87 }
88 
uint256 GetHash() const
Definition: block.cpp:15
Definition: block.h:80
uint256 GetBlockHash() const
Definition: chain.h:215
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:405
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
void clear()
Definition: txmempool.cpp:887
unsigned long size() const
Definition: txmempool.h:629
Capture information about block/transaction validation.
Definition: validation.h:24
256-bit opaque blob.
Definition: uint256.h:138
BOOST_AUTO_TEST_SUITE(cuckoocache_tests)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
@ SIGHASH_ALL
Definition: interpreter.h:24
@ LOCK
Definition: lockunlock.h:16
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:43
@ OP_CHECKSIG
Definition: script.h:166
A mutable version of CTransaction.
Definition: transaction.h:409
@ SIGVERSION_BASE
Definition: transaction.h:27
BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
void SetMockTime(int64_t nMockTimeIn)
For testing.
Definition: utiltime.cpp:51
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
Definition: utiltime.cpp:27
CTxMemPool mempool(::minRelayTxFee)
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectInsaneFee, bool ignoreFees)
(try to) add transaction to memory pool
Definition: validation.cpp:649
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:84