Browse Source

Merge pull request #4414

a90689f Remove timing-based signature cache unit test (Gavin Andresen)
0.10
Wladimir J. van der Laan 11 years ago
parent
commit
f40d193c18
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 2
      src/script.h
  2. 87
      src/test/DoS_tests.cpp

2
src/script.h

@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
class CCoins;
class CKeyStore;
class CTransaction;
class CMutableTransaction;
struct CMutableTransaction;
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
static const unsigned int MAX_OP_RETURN_RELAY = 40; // bytes

87
src/test/DoS_tests.cpp

@ -231,91 +231,4 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) @@ -231,91 +231,4 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
BOOST_CHECK(mapOrphanTransactionsByPrev.empty());
}
BOOST_AUTO_TEST_CASE(DoS_checkSig)
{
// Test signature caching code (see key.cpp Verify() methods)
CKey key;
key.MakeNewKey(true);
CBasicKeyStore keystore;
keystore.AddKey(key);
unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
// 100 orphan transactions:
static const int NPREV=100;
CMutableTransaction orphans[NPREV];
for (int i = 0; i < NPREV; i++)
{
CMutableTransaction& tx = orphans[i];
tx.vin.resize(1);
tx.vin[0].prevout.n = 0;
tx.vin[0].prevout.hash = GetRandHash();
tx.vin[0].scriptSig << OP_1;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
AddOrphanTx(tx);
}
// Create a transaction that depends on orphans:
CMutableTransaction tx;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
tx.vin.resize(NPREV);
for (unsigned int j = 0; j < tx.vin.size(); j++)
{
tx.vin[j].prevout.n = 0;
tx.vin[j].prevout.hash = orphans[j].GetHash();
}
// Creating signatures primes the cache:
boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time();
for (unsigned int j = 0; j < tx.vin.size(); j++)
BOOST_CHECK(SignSignature(keystore, orphans[j], tx, j));
boost::posix_time::ptime mst2 = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration msdiff = mst2 - mst1;
long nOneValidate = msdiff.total_milliseconds();
if (fDebug) printf("DoS_Checksig sign: %ld\n", nOneValidate);
// ... now validating repeatedly should be quick:
// 2.8GHz machine, -g build: Sign takes ~760ms,
// uncached Verify takes ~250ms, cached Verify takes ~50ms
// (for 100 single-signature inputs)
mst1 = boost::posix_time::microsec_clock::local_time();
for (unsigned int i = 0; i < 5; i++)
for (unsigned int j = 0; j < tx.vin.size(); j++)
BOOST_CHECK(VerifySignature(CCoins(orphans[j], MEMPOOL_HEIGHT), tx, j, flags, SIGHASH_ALL));
mst2 = boost::posix_time::microsec_clock::local_time();
msdiff = mst2 - mst1;
long nManyValidate = msdiff.total_milliseconds();
if (fDebug) printf("DoS_Checksig five: %ld\n", nManyValidate);
BOOST_CHECK_MESSAGE(nManyValidate < nOneValidate, "Signature cache timing failed");
// Empty a signature, validation should fail:
CScript save = tx.vin[0].scriptSig;
tx.vin[0].scriptSig = CScript();
BOOST_CHECK(!VerifySignature(CCoins(orphans[0], MEMPOOL_HEIGHT), tx, 0, flags, SIGHASH_ALL));
tx.vin[0].scriptSig = save;
// Swap signatures, validation should fail:
std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig);
BOOST_CHECK(!VerifySignature(CCoins(orphans[0], MEMPOOL_HEIGHT), tx, 0, flags, SIGHASH_ALL));
BOOST_CHECK(!VerifySignature(CCoins(orphans[1], MEMPOOL_HEIGHT), tx, 1, flags, SIGHASH_ALL));
std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig);
// Exercise -maxsigcachesize code:
mapArgs["-maxsigcachesize"] = "10";
// Generate a new, different signature for vin[0] to trigger cache clear:
CScript oldSig = tx.vin[0].scriptSig;
BOOST_CHECK(SignSignature(keystore, orphans[0], tx, 0));
BOOST_CHECK(tx.vin[0].scriptSig != oldSig);
for (unsigned int j = 0; j < tx.vin.size(); j++)
BOOST_CHECK(VerifySignature(CCoins(orphans[j], MEMPOOL_HEIGHT), tx, j, flags, SIGHASH_ALL));
mapArgs.erase("-maxsigcachesize");
LimitOrphanTxSize(0);
}
BOOST_AUTO_TEST_SUITE_END()

Loading…
Cancel
Save