@ -357,41 +357,23 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
@@ -357,41 +357,23 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
//////////////////////////////////////////////////////////////////////////////
//
// CTransaction / CTxOut
//
bool CTxOut : : IsDust ( ) const
bool IsStandardTx ( const CTransaction & tx )
{
// "Dust" is defined in terms of CTransaction::nMinRelayTxFee,
// which has units satoshis-per-kilobyte.
// If you'd pay more than 1/3 in fees
// to spend something, then we consider it dust.
// A typical txout is 33 bytes big, and will
// need a CTxIn of at least 148 bytes to spend,
// so dust is a txout less than 54 uBTC
// (5430 satoshis) with default nMinRelayTxFee
return ( ( nValue * 1000 ) / ( 3 * ( ( int ) GetSerializeSize ( SER_DISK , 0 ) + 148 ) ) < CTransaction : : nMinRelayTxFee ) ;
}
bool CTransaction : : IsStandard ( ) const
{
if ( nVersion > CTransaction : : CURRENT_VERSION )
if ( tx . nVersion > CTransaction : : CURRENT_VERSION )
return false ;
if ( ! IsFinal ( ) )
if ( ! IsFinalTx ( tx ) )
return false ;
// Extremely large transactions with lots of inputs can cost the network
// almost as much to process as they cost the sender in fees, because
// computing signature hashes is O(ninputs*txsize). Limiting transactions
// to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
unsigned int sz = this - > GetSerializeSize ( SER_NETWORK , CTransaction : : CURRENT_VERSION ) ;
unsigned int sz = tx . GetSerializeSize ( SER_NETWORK , CTransaction : : CURRENT_VERSION ) ;
if ( sz > = MAX_STANDARD_TX_SIZE )
return false ;
BOOST_FOREACH ( const CTxIn & txin , vin )
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
{
// Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG
// pay-to-script-hash, which is 3 ~80-byte signatures, 3
@ -401,15 +383,47 @@ bool CTransaction::IsStandard() const
@@ -401,15 +383,47 @@ bool CTransaction::IsStandard() const
if ( ! txin . scriptSig . IsPushOnly ( ) )
return false ;
}
BOOST_FOREACH ( const CTxOut & txout , vout ) {
BOOST_FOREACH ( const CTxOut & txout , tx . vout ) {
if ( ! : : IsStandard ( txout . scriptPubKey ) )
return false ;
if ( txout . IsDust ( ) )
if ( txout . IsDust ( CTransaction : : nMinRelayTxFee ) )
return false ;
}
return true ;
}
bool IsFinalTx ( const CTransaction & tx , int nBlockHeight , int64 nBlockTime )
{
// Time based nLockTime implemented in 0.1.6
if ( tx . nLockTime = = 0 )
return true ;
if ( nBlockHeight = = 0 )
nBlockHeight = nBestHeight ;
if ( nBlockTime = = 0 )
nBlockTime = GetAdjustedTime ( ) ;
if ( ( int64 ) tx . nLockTime < ( ( int64 ) tx . nLockTime < LOCKTIME_THRESHOLD ? ( int64 ) nBlockHeight : nBlockTime ) )
return true ;
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
if ( ! txin . IsFinal ( ) )
return false ;
return true ;
}
/** Amount of bitcoins spent by the transaction.
@ return sum of all outputs ( note : does not include fees )
*/
int64 GetValueOut ( const CTransaction & tx )
{
int64 nValueOut = 0 ;
BOOST_FOREACH ( const CTxOut & txout , tx . vout )
{
nValueOut + = txout . nValue ;
if ( ! MoneyRange ( txout . nValue ) | | ! MoneyRange ( nValueOut ) )
throw std : : runtime_error ( " GetValueOut() : value out of range " ) ;
}
return nValueOut ;
}
//
// Check transaction inputs, and make sure any
// pay-to-script-hash transactions are evaluating IsStandard scripts
@ -421,14 +435,14 @@ bool CTransaction::IsStandard() const
@@ -421,14 +435,14 @@ bool CTransaction::IsStandard() const
// expensive-to-check-upon-redemption script like:
// DUP CHECKSIG DROP ... repeated 100 times... OP_1
//
bool CTransaction : : AreInputsStandard ( CCoinsViewCache & mapInputs ) const
bool AreInputsStandard ( const CTransaction & tx , CCoinsViewCache & mapInputs )
{
if ( IsCoinBase ( ) )
if ( tx . IsCoinBase ( ) )
return true ; // Coinbases don't use vin normally
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + )
{
const CTxOut & prev = GetOutputFor ( vin [ i ] , mapInputs ) ;
const CTxOut & prev = mapInputs . GetOutputFor ( tx . vin [ i ] ) ;
vector < vector < unsigned char > > vSolutions ;
txnouttype whichType ;
@ -446,7 +460,7 @@ bool CTransaction::AreInputsStandard(CCoinsViewCache& mapInputs) const
@@ -446,7 +460,7 @@ bool CTransaction::AreInputsStandard(CCoinsViewCache& mapInputs) const
// beside "push data" in the scriptSig the
// IsStandard() call returns false
vector < vector < unsigned char > > stack ;
if ( ! EvalScript ( stack , vin [ i ] . scriptSig , * this , i , false , 0 ) )
if ( ! EvalScript ( stack , tx . vin [ i ] . scriptSig , tx , i , false , 0 ) )
return false ;
if ( whichType = = TX_SCRIPTHASH )
@ -475,20 +489,34 @@ bool CTransaction::AreInputsStandard(CCoinsViewCache& mapInputs) const
@@ -475,20 +489,34 @@ bool CTransaction::AreInputsStandard(CCoinsViewCache& mapInputs) const
return true ;
}
unsigned int CTransaction : : GetLegacySigOpCount ( ) const
unsigned int GetLegacySigOpCount ( const CTransaction & tx )
{
unsigned int nSigOps = 0 ;
BOOST_FOREACH ( const CTxIn & txin , vin )
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
{
nSigOps + = txin . scriptSig . GetSigOpCount ( false ) ;
}
BOOST_FOREACH ( const CTxOut & txout , vout )
BOOST_FOREACH ( const CTxOut & txout , tx . vout )
{
nSigOps + = txout . scriptPubKey . GetSigOpCount ( false ) ;
}
return nSigOps ;
}
unsigned int GetP2SHSigOpCount ( const CTransaction & tx , CCoinsViewCache & inputs )
{
if ( tx . IsCoinBase ( ) )
return 0 ;
unsigned int nSigOps = 0 ;
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + )
{
const CTxOut & prevout = inputs . GetOutputFor ( tx . vin [ i ] ) ;
if ( prevout . scriptPubKey . IsPayToScriptHash ( ) )
nSigOps + = prevout . scriptPubKey . GetSigOpCount ( tx . vin [ i ] . scriptSig ) ;
}
return nSigOps ;
}
int CMerkleTx : : SetMerkleBranch ( const CBlock * pblock )
{
@ -543,25 +571,25 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
@@ -543,25 +571,25 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
bool CTransaction : : CheckTransaction ( CValidationState & state ) const
bool CheckTransaction ( const CTransaction & tx , CValidationState & state )
{
// Basic checks that don't depend on any context
if ( vin . empty ( ) )
return state . DoS ( 10 , error ( " CTransaction::C heckTransaction() : vin empty " ) ) ;
if ( vout . empty ( ) )
return state . DoS ( 10 , error ( " CTransaction::C heckTransaction() : vout empty " ) ) ;
if ( tx . vin . empty ( ) )
return state . DoS ( 10 , error ( " CheckTransaction() : vin empty " ) ) ;
if ( tx . vout . empty ( ) )
return state . DoS ( 10 , error ( " CheckTransaction() : vout empty " ) ) ;
// Size limits
if ( : : GetSerializeSize ( * this , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
if ( : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : size limits failed " ) ) ;
// Check for negative or overflow output values
int64 nValueOut = 0 ;
BOOST_FOREACH ( const CTxOut & txout , vout )
BOOST_FOREACH ( const CTxOut & txout , tx . vout )
{
if ( txout . nValue < 0 )
return state . DoS ( 100 , error ( " CTransaction::C heckTransaction() : txout.nValue negative " ) ) ;
return state . DoS ( 100 , error ( " CheckTransaction() : txout.nValue negative " ) ) ;
if ( txout . nValue > MAX_MONEY )
return state . DoS ( 100 , error ( " CTransaction::C heckTransaction() : txout.nValue too high " ) ) ;
return state . DoS ( 100 , error ( " CheckTransaction() : txout.nValue too high " ) ) ;
nValueOut + = txout . nValue ;
if ( ! MoneyRange ( nValueOut ) )
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : txout total out of range " ) ) ;
@ -569,23 +597,23 @@ bool CTransaction::CheckTransaction(CValidationState &state) const
@@ -569,23 +597,23 @@ bool CTransaction::CheckTransaction(CValidationState &state) const
// Check for duplicate inputs
set < COutPoint > vInOutPoints ;
BOOST_FOREACH ( const CTxIn & txin , vin )
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
{
if ( vInOutPoints . count ( txin . prevout ) )
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : duplicate inputs " ) ) ;
vInOutPoints . insert ( txin . prevout ) ;
}
if ( IsCoinBase ( ) )
if ( tx . IsCoinBase ( ) )
{
if ( vin [ 0 ] . scriptSig . size ( ) < 2 | | vin [ 0 ] . scriptSig . size ( ) > 100 )
return state . DoS ( 100 , error ( " CTransaction::C heckTransaction() : coinbase script size " ) ) ;
if ( tx . vin [ 0 ] . scriptSig . size ( ) < 2 | | tx . vin [ 0 ] . scriptSig . size ( ) > 100 )
return state . DoS ( 100 , error ( " CheckTransaction() : coinbase script size " ) ) ;
}
else
{
BOOST_FOREACH ( const CTxIn & txin , vin )
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
if ( txin . prevout . IsNull ( ) )
return state . DoS ( 10 , error ( " CTransaction::C heckTransaction() : prevout is null " ) ) ;
return state . DoS ( 10 , error ( " CheckTransaction() : prevout is null " ) ) ;
}
return true ;
@ -657,7 +685,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
@@ -657,7 +685,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
if ( pfMissingInputs )
* pfMissingInputs = false ;
if ( ! tx . CheckTransaction ( state ) )
if ( ! CheckTransaction ( tx , state ) )
return error ( " CTxMemPool::accept() : CheckTransaction failed " ) ;
// Coinbase is only valid in a block, not as a loose transaction
@ -669,7 +697,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
@@ -669,7 +697,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
return error ( " CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet " ) ;
// Rather not work on nonstandard transactions (unless -testnet)
if ( ! fTestNet & & ! tx . IsStandard ( ) )
if ( ! fTestNet & & ! IsStandardTx ( tx ) )
return error ( " CTxMemPool::accept() : nonstandard transaction type " ) ;
// is it already in the memory pool?
@ -694,7 +722,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
@@ -694,7 +722,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
if ( i ! = 0 )
return false ;
ptxOld = mapNextTx [ outpoint ] . ptx ;
if ( ptxOld - > IsFinal ( ) )
if ( IsFinalTx ( * ptxOld ) )
return false ;
if ( ! tx . IsNewerThan ( * ptxOld ) )
return false ;
@ -734,7 +762,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
@@ -734,7 +762,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
}
// are the actual inputs available?
if ( ! tx . HaveInputs ( view ) )
if ( ! view . HaveInputs ( tx ) )
return state . Invalid ( error ( " CTxMemPool::accept() : inputs already spent " ) ) ;
// Bring the best block into scope
@ -745,14 +773,14 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
@@ -745,14 +773,14 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
}
// Check for non-standard pay-to-script-hash in inputs
if ( ! tx . AreInputsStandard ( view ) & & ! fTestNet )
if ( ! AreInputsStandard ( tx , view ) & & ! fTestNet )
return error ( " CTxMemPool::accept() : nonstandard transaction input " ) ;
// Note: if you modify this code to accept non-standard transactions, then
// you should add code here to check that the transaction does a
// reasonable number of ECDSA signature verifications.
int64 nFees = tx . GetValueIn ( view ) - tx . GetValueOut ( ) ;
int64 nFees = view . GetValueIn ( tx ) - GetValueOut ( tx ) ;
unsigned int nSize = : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) ;
// Don't accept it if it can't get into a block
@ -787,7 +815,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
@@ -787,7 +815,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if ( ! tx . CheckInputs ( state , view , true , SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC ) )
if ( ! CheckInputs ( tx , state , view , true , SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC ) )
{
return error ( " CTxMemPool::accept() : ConnectInputs failed % s " , hash.ToString().c_str()) ;
}
@ -816,14 +844,6 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
@@ -816,14 +844,6 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckIn
return true ;
}
bool CTransaction : : AcceptToMemoryPool ( CValidationState & state , bool fCheckInputs , bool fLimitFree , bool * pfMissingInputs )
{
try {
return mempool . accept ( state , * this , fCheckInputs , fLimitFree , pfMissingInputs ) ;
} catch ( std : : runtime_error & e ) {
return state . Abort ( _ ( " System error: " ) + e . what ( ) ) ;
}
}
bool CTxMemPool : : addUnchecked ( const uint256 & hash , CTransaction & tx )
{
@ -936,7 +956,7 @@ int CMerkleTx::GetBlocksToMaturity() const
@@ -936,7 +956,7 @@ int CMerkleTx::GetBlocksToMaturity() const
bool CMerkleTx : : AcceptToMemoryPool ( bool fCheckInputs , bool fLimitFree )
{
CValidationState state ;
return CTransaction : : AcceptToMemoryPool ( state , fCheckInputs , fLimitFree ) ;
return mempool . accept ( state , * this , fCheckInputs , fLimitFree , NULL ) ;
}
@ -1299,45 +1319,30 @@ void CBlockHeader::UpdateTime(const CBlockIndex* pindexPrev)
@@ -1299,45 +1319,30 @@ void CBlockHeader::UpdateTime(const CBlockIndex* pindexPrev)
const CTxOut & CTransaction : : GetOutputFor ( const CTxIn & input , CCoinsViewCache & view )
const CTxOut & CCoinsViewCache : : GetOutputFor ( const CTxIn & input )
{
const CCoins & coins = view . GetCoins ( input . prevout . hash ) ;
const CCoins & coins = GetCoins ( input . prevout . hash ) ;
assert ( coins . IsAvailable ( input . prevout . n ) ) ;
return coins . vout [ input . prevout . n ] ;
}
int64 CTransaction : : GetValueIn ( CCoinsViewCache & inputs ) const
int64 CCoinsViewCache : : GetValueIn ( const CTransaction & tx )
{
if ( IsCoinBase ( ) )
if ( tx . IsCoinBase ( ) )
return 0 ;
int64 nResult = 0 ;
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
nResult + = GetOutputFor ( vin [ i ] , inputs ) . nValue ;
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + )
nResult + = GetOutputFor ( tx . vin [ i ] ) . nValue ;
return nResult ;
}
unsigned int CTransaction : : GetP2SHSigOpCount ( CCoinsViewCache & inputs ) const
{
if ( IsCoinBase ( ) )
return 0 ;
unsigned int nSigOps = 0 ;
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
{
const CTxOut & prevout = GetOutputFor ( vin [ i ] , inputs ) ;
if ( prevout . scriptPubKey . IsPayToScriptHash ( ) )
nSigOps + = prevout . scriptPubKey . GetSigOpCount ( vin [ i ] . scriptSig ) ;
}
return nSigOps ;
}
void CTransaction : : UpdateCoins ( CValidationState & state , CCoinsViewCache & inputs , CTxUndo & txundo , int nHeight , const uint256 & txhash ) const
void UpdateCoins ( const CTransaction & tx , CValidationState & state , CCoinsViewCache & inputs , CTxUndo & txundo , int nHeight , const uint256 & txhash )
{
// mark inputs spent
if ( ! IsCoinBase ( ) ) {
BOOST_FOREACH ( const CTxIn & txin , vin ) {
if ( ! tx . IsCoinBase ( ) ) {
BOOST_FOREACH ( const CTxIn & txin , tx . vin ) {
CCoins & coins = inputs . GetCoins ( txin . prevout . hash ) ;
CTxInUndo undo ;
assert ( coins . Spend ( txin . prevout , undo ) ) ;
@ -1346,23 +1351,23 @@ void CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs,
@@ -1346,23 +1351,23 @@ void CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs,
}
// add outputs
assert ( inputs . SetCoins ( txhash , CCoins ( * this , nHeight ) ) ) ;
assert ( inputs . SetCoins ( txhash , CCoins ( tx , nHeight ) ) ) ;
}
bool CTransaction : : HaveInputs ( CCoinsViewCache & inputs ) const
bool CCoinsViewCache : : HaveInputs ( const CTransaction & tx )
{
if ( ! IsCoinBase ( ) ) {
if ( ! tx . IsCoinBase ( ) ) {
// first check whether information about the prevout hash is available
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + ) {
const COutPoint & prevout = vin [ i ] . prevout ;
if ( ! inputs . HaveCoins ( prevout . hash ) )
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + ) {
const COutPoint & prevout = tx . vin [ i ] . prevout ;
if ( ! HaveCoins ( prevout . hash ) )
return false ;
}
// then check whether the actual outputs are available
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + ) {
const COutPoint & prevout = vin [ i ] . prevout ;
const CCoins & coins = inputs . GetCoins ( prevout . hash ) ;
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + ) {
const COutPoint & prevout = tx . vin [ i ] . prevout ;
const CCoins & coins = GetCoins ( prevout . hash ) ;
if ( ! coins . IsAvailable ( prevout . n ) )
return false ;
}
@ -1382,26 +1387,26 @@ bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned in
@@ -1382,26 +1387,26 @@ bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned in
return CScriptCheck ( txFrom , txTo , nIn , flags , nHashType ) ( ) ;
}
bool CTransaction : : CheckInputs ( CValidationState & state , CCoinsViewCache & inputs , bool fScriptChecks , unsigned int flags , std : : vector < CScriptCheck > * pvChecks ) const
bool CheckInputs ( const CTransaction & tx , CValidationState & state , CCoinsViewCache & inputs , bool fScriptChecks , unsigned int flags , std : : vector < CScriptCheck > * pvChecks )
{
if ( ! IsCoinBase ( ) )
if ( ! tx . IsCoinBase ( ) )
{
if ( pvChecks )
pvChecks - > reserve ( vin . size ( ) ) ;
pvChecks - > reserve ( tx . vin . size ( ) ) ;
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// for an attacker to attempt to split the network.
if ( ! HaveInputs ( inputs ) )
return state . Invalid ( error ( " CheckInputs() : %s inputs unavailable " , GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
if ( ! inputs . HaveInputs ( tx ) )
return state . Invalid ( error ( " CheckInputs() : %s inputs unavailable " , tx . GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
// While checking, GetBestBlock() refers to the parent block.
// This is also true for mempool checks.
int nSpendHeight = inputs . GetBestBlock ( ) - > nHeight + 1 ;
int64 nValueIn = 0 ;
int64 nFees = 0 ;
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + )
{
const COutPoint & prevout = vin [ i ] . prevout ;
const COutPoint & prevout = tx . vin [ i ] . prevout ;
const CCoins & coins = inputs . GetCoins ( prevout . hash ) ;
// If prev is coinbase, check that it's matured
@ -1417,13 +1422,13 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs,
@@ -1417,13 +1422,13 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs,
}
if ( nValueIn < GetValueOut ( ) )
return state . DoS ( 100 , error ( " CheckInputs() : %s value in < value out " , GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
if ( nValueIn < GetValueOut ( tx ) )
return state . DoS ( 100 , error ( " CheckInputs() : %s value in < value out " , tx . GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
// Tally transaction fees
int64 nTxFee = nValueIn - GetValueOut ( ) ;
int64 nTxFee = nValueIn - GetValueOut ( tx ) ;
if ( nTxFee < 0 )
return state . DoS ( 100 , error ( " CheckInputs() : %s nTxFee < 0 " , GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
return state . DoS ( 100 , error ( " CheckInputs() : %s nTxFee < 0 " , tx . GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
nFees + = nTxFee ;
if ( ! MoneyRange ( nFees ) )
return state . DoS ( 100 , error ( " CheckInputs() : nFees out of range " ) ) ;
@ -1436,12 +1441,12 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs,
@@ -1436,12 +1441,12 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs,
// before the last block chain checkpoint. This is safe because block merkle hashes are
// still computed and checked, and any change will be caught at the next checkpoint.
if ( fScriptChecks ) {
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + ) {
const COutPoint & prevout = vin [ i ] . prevout ;
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + ) {
const COutPoint & prevout = tx . vin [ i ] . prevout ;
const CCoins & coins = inputs . GetCoins ( prevout . hash ) ;
// Verify signature
CScriptCheck check ( coins , * this , i , flags , 0 ) ;
CScriptCheck check ( coins , tx , i , flags , 0 ) ;
if ( pvChecks ) {
pvChecks - > push_back ( CScriptCheck ( ) ) ;
check . swap ( pvChecks - > back ( ) ) ;
@ -1449,7 +1454,7 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs,
@@ -1449,7 +1454,7 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs,
if ( flags & SCRIPT_VERIFY_STRICTENC ) {
// For now, check whether the failure was caused by non-canonical
// encodings or not; if so, don't trigger DoS protection.
CScriptCheck check ( coins , * this , i , flags & ( ~ SCRIPT_VERIFY_STRICTENC ) , 0 ) ;
CScriptCheck check ( coins , tx , i , flags & ( ~ SCRIPT_VERIFY_STRICTENC ) , 0 ) ;
if ( check ( ) )
return state . Invalid ( ) ;
}
@ -1464,7 +1469,6 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs,
@@ -1464,7 +1469,6 @@ bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs,
bool CBlock : : DisconnectBlock ( CValidationState & state , CBlockIndex * pindex , CCoinsViewCache & view , bool * pfClean )
{
assert ( pindex = = view . GetBestBlock ( ) ) ;
@ -1644,13 +1648,13 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi
@@ -1644,13 +1648,13 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi
const CTransaction & tx = vtx [ i ] ;
nInputs + = tx . vin . size ( ) ;
nSigOps + = tx . GetLegacySigOpCount ( ) ;
nSigOps + = GetLegacySigOpCount ( tx ) ;
if ( nSigOps > MAX_BLOCK_SIGOPS )
return state . DoS ( 100 , error ( " ConnectBlock() : too many sigops " ) ) ;
if ( ! tx . IsCoinBase ( ) )
{
if ( ! tx . HaveInputs ( view ) )
if ( ! view . HaveInputs ( tx ) )
return state . DoS ( 100 , error ( " ConnectBlock() : inputs missing/spent " ) ) ;
if ( fStrictPayToScriptHash )
@ -1658,21 +1662,21 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi
@@ -1658,21 +1662,21 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi
// Add in sigops done by pay-to-script-hash inputs;
// this is to prevent a "rogue miner" from creating
// an incredibly-expensive-to-validate block.
nSigOps + = tx . GetP2SHSigOpCount ( view ) ;
nSigOps + = GetP2SHSigOpCount ( tx , view ) ;
if ( nSigOps > MAX_BLOCK_SIGOPS )
return state . DoS ( 100 , error ( " ConnectBlock() : too many sigops " ) ) ;
}
nFees + = tx . GetValueIn ( view ) - tx . GetValueOut ( ) ;
nFees + = view . GetValueIn ( tx ) - GetValueOut ( tx ) ;
std : : vector < CScriptCheck > vChecks ;
if ( ! tx . CheckInputs ( state , view , fScriptChecks , flags , nScriptCheckThreads ? & vChecks : NULL ) )
if ( ! CheckInputs ( tx , state , view , fScriptChecks , flags , nScriptCheckThreads ? & vChecks : NULL ) )
return false ;
control . Add ( vChecks ) ;
}
CTxUndo txundo ;
tx . UpdateCoins ( state , view , txundo , pindex - > nHeight , GetTxHash ( i ) ) ;
UpdateCoins ( tx , state , view , txundo , pindex - > nHeight , GetTxHash ( i ) ) ;
if ( ! tx . IsCoinBase ( ) )
blockundo . vtxundo . push_back ( txundo ) ;
@ -1683,8 +1687,8 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi
@@ -1683,8 +1687,8 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi
if ( fBenchmark )
printf ( " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) \n " , ( unsigned ) vtx . size ( ) , 0.001 * nTime , 0.001 * nTime / vtx . size ( ) , nInputs < = 1 ? 0 : 0.001 * nTime / ( nInputs - 1 ) ) ;
if ( vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
return state . DoS ( 100 , error ( " ConnectBlock() : coinbase pays too much (actual=% " PRI64d " vs limit=% " PRI64d " ) " , vtx [ 0 ] . GetValueOut ( ) , GetBlockValue ( pindex - > nHeight , nFees ) ) ) ;
if ( GetValueOut ( vtx [ 0 ] ) > GetBlockValue ( pindex - > nHeight , nFees ) )
return state . DoS ( 100 , error ( " ConnectBlock() : coinbase pays too much (actual=% " PRI64d " vs limit=% " PRI64d " ) " , GetValueOut ( vtx [ 0 ] ) , GetBlockValue ( pindex - > nHeight , nFees ) ) ) ;
if ( ! control . Wait ( ) )
return state . DoS ( 100 , false ) ;
@ -1846,7 +1850,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
@@ -1846,7 +1850,7 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
BOOST_FOREACH ( CTransaction & tx , vResurrect ) {
// ignore validation errors in resurrected transactions
CValidationState stateDummy ;
tx . AcceptToMemoryPool ( stateDummy , true , false ) ;
mempool . accept ( stateDummy , tx , true , false , NULL ) ;
}
// Delete redundant memory transactions that are in the connected branch
@ -2076,7 +2080,7 @@ bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerk
@@ -2076,7 +2080,7 @@ bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerk
// Check transactions
BOOST_FOREACH ( const CTransaction & tx , vtx )
if ( ! tx . CheckTransaction ( state ) )
if ( ! CheckTransaction ( tx , state ) )
return error ( " CheckBlock() : CheckTransaction failed " ) ;
// Build the merkle tree already. We need it anyway later, and it makes the
@ -2096,7 +2100,7 @@ bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerk
@@ -2096,7 +2100,7 @@ bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerk
unsigned int nSigOps = 0 ;
BOOST_FOREACH ( const CTransaction & tx , vtx )
{
nSigOps + = tx . GetLegacySigOpCount ( ) ;
nSigOps + = GetLegacySigOpCount ( tx ) ;
}
if ( nSigOps > MAX_BLOCK_SIGOPS )
return state . DoS ( 100 , error ( " CheckBlock() : out-of-bounds SigOpCount " ) ) ;
@ -2135,7 +2139,7 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
@@ -2135,7 +2139,7 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
// Check that all transactions are finalized
BOOST_FOREACH ( const CTransaction & tx , vtx )
if ( ! tx . IsFinal ( nHeight , GetBlockTime ( ) ) )
if ( ! IsFinalTx ( tx , nHeight , GetBlockTime ( ) ) )
return state . DoS ( 10 , error ( " AcceptBlock() : contains a non-final transaction " ) ) ;
// Check that the block chain matches the known block chain up to a checkpoint
@ -3488,7 +3492,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
@@ -3488,7 +3492,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
bool fMissingInputs = false ;
CValidationState state ;
if ( tx . AcceptToMemoryPool ( state , true , true , & fMissingInputs ) )
if ( mempool . accept ( state , tx , true , true , & fMissingInputs ) )
{
RelayTransaction ( tx , inv . hash , vMsg ) ;
mapAlreadyAskedFor . erase ( inv ) ;
@ -3511,7 +3515,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
@@ -3511,7 +3515,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get anyone relaying LegitTxX banned)
CValidationState stateDummy ;
if ( tx . AcceptToMemoryPool ( stateDummy , true , true , & fMissingInputs2 ) )
if ( mempool . accept ( stateDummy , tx , true , true , & fMissingInputs2 ) )
{
printf ( " accepted orphan tx %s \n " , inv . hash . ToString ( ) . c_str ( ) ) ;
RelayTransaction ( tx , inv . hash , vMsg ) ;
@ -4194,7 +4198,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
@@ -4194,7 +4198,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
for ( map < uint256 , CTransaction > : : iterator mi = mempool . mapTx . begin ( ) ; mi ! = mempool . mapTx . end ( ) ; + + mi )
{
CTransaction & tx = ( * mi ) . second ;
if ( tx . IsCoinBase ( ) | | ! tx . IsFinal ( ) )
if ( tx . IsCoinBase ( ) | | ! IsFinalTx ( tx ) )
continue ;
COrphan * porphan = NULL ;
@ -4249,7 +4253,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
@@ -4249,7 +4253,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
// This is a more accurate fee-per-kilobyte than is used by the client code, because the
// client code rounds up the size to the nearest 1K. That's good, because it gives an
// incentive to create smaller transactions.
double dFeePerKb = double ( nTotalIn - tx . GetValueOut ( ) ) / ( double ( nTxSize ) / 1000.0 ) ;
double dFeePerKb = double ( nTotalIn - GetValueOut ( tx ) ) / ( double ( nTxSize ) / 1000.0 ) ;
if ( porphan )
{
@ -4285,7 +4289,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
@@ -4285,7 +4289,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
continue ;
// Legacy limits on sigOps:
unsigned int nTxSigOps = tx . GetLegacySigOpCount ( ) ;
unsigned int nTxSigOps = GetLegacySigOpCount ( tx ) ;
if ( nBlockSigOps + nTxSigOps > = MAX_BLOCK_SIGOPS )
continue ;
@ -4303,22 +4307,22 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
@@ -4303,22 +4307,22 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
std : : make_heap ( vecPriority . begin ( ) , vecPriority . end ( ) , comparer ) ;
}
if ( ! tx . HaveInputs ( view ) )
if ( ! view . HaveInputs ( tx ) )
continue ;
int64 nTxFees = tx . GetValueIn ( view ) - tx . GetValueOut ( ) ;
int64 nTxFees = view . GetValueIn ( tx ) - GetValueOut ( tx ) ;
nTxSigOps + = tx . GetP2SHSigOpCount ( view ) ;
nTxSigOps + = GetP2SHSigOpCount ( tx , view ) ;
if ( nBlockSigOps + nTxSigOps > = MAX_BLOCK_SIGOPS )
continue ;
CValidationState state ;
if ( ! tx . CheckInputs ( state , view , true , SCRIPT_VERIFY_P2SH ) )
if ( ! CheckInputs ( tx , state , view , true , SCRIPT_VERIFY_P2SH ) )
continue ;
CTxUndo txundo ;
uint256 hash = tx . GetHash ( ) ;
tx . UpdateCoins ( state , view , txundo , pindexPrev - > nHeight + 1 , hash ) ;
UpdateCoins ( tx , state , view , txundo , pindexPrev - > nHeight + 1 , hash ) ;
// Added
pblock - > vtx . push_back ( tx ) ;
@ -4366,7 +4370,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
@@ -4366,7 +4370,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
pblock - > nBits = GetNextWorkRequired ( pindexPrev , pblock ) ;
pblock - > nNonce = 0 ;
pblock - > vtx [ 0 ] . vin [ 0 ] . scriptSig = CScript ( ) < < OP_0 < < OP_0 ;
pblocktemplate - > vTxSigOps [ 0 ] = pblock - > vtx [ 0 ] . GetLegacySigOpCount ( ) ;
pblocktemplate - > vTxSigOps [ 0 ] = GetLegacySigOpCount ( pblock - > vtx [ 0 ] ) ;
CBlockIndex indexDummy ( * pblock ) ;
indexDummy . pprev = pindexPrev ;