Skip to content

Commit

Permalink
Unit test for sighash caching
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasDorier authored and sipa committed Aug 16, 2016
1 parent d2c5d04 commit ab48c5e
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/test/transaction_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "test/test_bitcoin.h"

#include "clientversion.h"
#include "checkqueue.h"
#include "consensus/validation.h"
#include "core_io.h"
#include "key.h"
Expand Down Expand Up @@ -421,6 +422,86 @@ void ReplaceRedeemScript(CScript& script, const CScript& redeemScript)
script = PushAll(stack);
}

BOOST_AUTO_TEST_CASE(test_big_witness_transaction) {
CMutableTransaction mtx;
mtx.nVersion = 1;

CKey key;
key.MakeNewKey(false);
CBasicKeyStore keystore;
keystore.AddKeyPubKey(key, key.GetPubKey());
CKeyID hash = key.GetPubKey().GetID();
CScript scriptPubKey = CScript() << OP_0 << std::vector<unsigned char>(hash.begin(), hash.end());

vector<int> sigHashes;
sigHashes.push_back(SIGHASH_NONE | SIGHASH_ANYONECANPAY);
sigHashes.push_back(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY);
sigHashes.push_back(SIGHASH_ALL | SIGHASH_ANYONECANPAY);
sigHashes.push_back(SIGHASH_NONE);
sigHashes.push_back(SIGHASH_SINGLE);
sigHashes.push_back(SIGHASH_ALL);

// create a big transaction of 4500 inputs signed by the same key
for(uint32_t ij = 0; ij < 4500; ij++) {
uint32_t i = mtx.vin.size();
uint256 prevId;
prevId.SetHex("0000000000000000000000000000000000000000000000000000000000000100");
COutPoint outpoint(prevId, i);

mtx.vin.resize(mtx.vin.size() + 1);
mtx.vin[i].prevout = outpoint;
mtx.vin[i].scriptSig = CScript();

mtx.vout.resize(mtx.vout.size() + 1);
mtx.vout[i].nValue = 1000;
mtx.vout[i].scriptPubKey = CScript() << OP_1;
}

// sign all inputs
for(uint32_t i = 0; i < mtx.vin.size(); i++) {
bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size()));
assert(hashSigned);
}

CTransaction tx;
CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION);
WithOrVersion(&ssout, 0) << mtx;
WithOrVersion(&ssout, 0) >> tx;

// check all inputs concurrently, with the cache
CachedHashes cachedHashes(tx);
boost::thread_group threadGroup;
CCheckQueue<CScriptCheck> scriptcheckqueue(128);
CCheckQueueControl<CScriptCheck> control(&scriptcheckqueue);

for (int i=0; i<20; i++)
threadGroup.create_thread(boost::bind(&CCheckQueue<CScriptCheck>::Thread, boost::ref(scriptcheckqueue)));

CCoins coins;
coins.nVersion = 1;
coins.fCoinBase = false;
for(uint32_t i = 0; i < mtx.vin.size(); i++) {
CTxOut txout;
txout.nValue = 1000;
txout.scriptPubKey = scriptPubKey;
coins.vout.push_back(txout);
}

for(uint32_t i = 0; i < mtx.vin.size(); i++) {
std::vector<CScriptCheck> vChecks;
CScriptCheck check(coins, tx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &cachedHashes);
vChecks.push_back(CScriptCheck());
check.swap(vChecks.back());
control.Add(vChecks);
}

bool controlCheck = control.Wait();
assert(controlCheck);

threadGroup.interrupt_all();
threadGroup.join_all();
}

BOOST_AUTO_TEST_CASE(test_witness)
{
CBasicKeyStore keystore, keystore2;
Expand Down

0 comments on commit ab48c5e

Please sign in to comment.