|
|
@ -7,6 +7,7 @@ |
|
|
|
#include "test/test_bitcoin.h" |
|
|
|
#include "test/test_bitcoin.h" |
|
|
|
|
|
|
|
|
|
|
|
#include "clientversion.h" |
|
|
|
#include "clientversion.h" |
|
|
|
|
|
|
|
#include "checkqueue.h" |
|
|
|
#include "consensus/validation.h" |
|
|
|
#include "consensus/validation.h" |
|
|
|
#include "core_io.h" |
|
|
|
#include "core_io.h" |
|
|
|
#include "key.h" |
|
|
|
#include "key.h" |
|
|
@ -421,6 +422,86 @@ void ReplaceRedeemScript(CScript& script, const CScript& redeemScript) |
|
|
|
script = PushAll(stack); |
|
|
|
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) |
|
|
|
BOOST_AUTO_TEST_CASE(test_witness) |
|
|
|
{ |
|
|
|
{ |
|
|
|
CBasicKeyStore keystore, keystore2; |
|
|
|
CBasicKeyStore keystore, keystore2; |
|
|
|