@ -620,34 +620,11 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
bool IsStandardTx ( const CTransaction & tx , string & reason )
bool IsStandardTx ( const CTransaction & tx , string & reason )
{
{
AssertLockHeld ( cs_main ) ;
if ( tx . nVersion > CTransaction : : CURRENT_VERSION | | tx . nVersion < 1 ) {
if ( tx . nVersion > CTransaction : : CURRENT_VERSION | | tx . nVersion < 1 ) {
reason = " version " ;
reason = " version " ;
return false ;
return false ;
}
}
// Treat non-final transactions as non-standard to prevent a specific type
// of double-spend attack, as well as DoS attacks. (if the transaction
// can't be mined, the attacker isn't expending resources broadcasting it)
// Basically we don't want to propagate transactions that can't be included in
// the next block.
//
// However, IsFinalTx() is confusing... Without arguments, it uses
// chainActive.Height() to evaluate nLockTime; when a block is accepted, chainActive.Height()
// is set to the value of nHeight in the block. However, when IsFinalTx()
// is called within CBlock::AcceptBlock(), the height of the block *being*
// evaluated is what is used. Thus if we want to know if a transaction can
// be part of the *next* block, we need to call IsFinalTx() with one more
// than chainActive.Height().
//
// Timestamps on the other hand don't get any special treatment, because we
// can't know what timestamp the next block will have, and there aren't
// timestamp applications where it matters.
if ( ! IsFinalTx ( tx , chainActive . Height ( ) + 1 ) ) {
reason = " non-final " ;
return false ;
}
// Extremely large transactions with lots of inputs can cost the network
// Extremely large transactions with lots of inputs can cost the network
// almost as much to process as they cost the sender in fees, because
// almost as much to process as they cost the sender in fees, because
// computing signature hashes is O(ninputs*txsize). Limiting transactions
// computing signature hashes is O(ninputs*txsize). Limiting transactions
@ -936,6 +913,26 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
error ( " AcceptToMemoryPool : nonstandard transaction: %s " , reason ) ,
error ( " AcceptToMemoryPool : nonstandard transaction: %s " , reason ) ,
REJECT_NONSTANDARD , reason ) ;
REJECT_NONSTANDARD , reason ) ;
// Only accept nLockTime-using transactions that can be mined in the next
// block; we don't want our mempool filled up with transactions that can't
// be mined yet.
//
// However, IsFinalTx() is confusing... Without arguments, it uses
// chainActive.Height() to evaluate nLockTime; when a block is accepted,
// chainActive.Height() is set to the value of nHeight in the block.
// However, when IsFinalTx() is called within CBlock::AcceptBlock(), the
// height of the block *being* evaluated is what is used. Thus if we want
// to know if a transaction can be part of the *next* block, we need to
// call IsFinalTx() with one more than chainActive.Height().
//
// Timestamps on the other hand don't get any special treatment, because we
// can't know what timestamp the next block will have, and there aren't
// timestamp applications where it matters.
if ( ! IsFinalTx ( tx , chainActive . Height ( ) + 1 ) )
return state . DoS ( 0 ,
error ( " AcceptToMemoryPool : non-final " ) ,
REJECT_NONSTANDARD , " non-final " ) ;
// is it already in the memory pool?
// is it already in the memory pool?
uint256 hash = tx . GetHash ( ) ;
uint256 hash = tx . GetHash ( ) ;
if ( pool . exists ( hash ) )
if ( pool . exists ( hash ) )