@ -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 ( )