@ -111,10 +111,10 @@ void static EraseFromWallets(uint256 hash)
}
}
// make sure all wallets know about the given transaction, in the given block
// make sure all wallets know about the given transaction, in the given block
void SyncWithWallets ( const CTransaction & tx , const CBlock * pblock , bool fUpdate )
void SyncWithWallets ( const uint256 & hash , const CTransaction & tx , const CBlock * pblock , bool fUpdate )
{
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > AddToWalletIfInvolvingMe ( tx , pblock , fUpdate ) ;
pwallet - > AddToWalletIfInvolvingMe ( hash , tx , pblock , fUpdate ) ;
}
}
// notify wallets about a new best chain
// notify wallets about a new best chain
@ -1197,10 +1197,8 @@ unsigned int CTransaction::GetP2SHSigOpCount(CCoinsView& inputs) const
return nSigOps ;
return nSigOps ;
}
}
bool CTransaction : : UpdateCoins ( CCoinsView & inputs , CTxUndo & txundo , int nHeight ) const
bool CTransaction : : UpdateCoins ( CCoinsView & inputs , CTxUndo & txundo , int nHeight , const uint256 & txhash ) const
{
{
uint256 hash = GetHash ( ) ;
// mark inputs spent
// mark inputs spent
if ( ! IsCoinBase ( ) ) {
if ( ! IsCoinBase ( ) ) {
BOOST_FOREACH ( const CTxIn & txin , vin ) {
BOOST_FOREACH ( const CTxIn & txin , vin ) {
@ -1217,7 +1215,7 @@ bool CTransaction::UpdateCoins(CCoinsView &inputs, CTxUndo &txundo, int nHeight)
}
}
// add outputs
// add outputs
if ( ! inputs . SetCoins ( hash , CCoins ( * this , nHeight ) ) )
if ( ! inputs . SetCoins ( tx hash, CCoins ( * this , nHeight ) ) )
return error ( " UpdateCoins() : cannot update output " ) ;
return error ( " UpdateCoins() : cannot update output " ) ;
return true ;
return true ;
@ -1467,8 +1465,8 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsView &view, bool fJustCheck
bool fEnforceBIP30 = ! ( ( pindex - > nHeight = = 91842 & & pindex - > GetBlockHash ( ) = = uint256 ( " 0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec " ) ) | |
bool fEnforceBIP30 = ! ( ( pindex - > nHeight = = 91842 & & pindex - > GetBlockHash ( ) = = uint256 ( " 0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec " ) ) | |
( pindex - > nHeight = = 91880 & & pindex - > GetBlockHash ( ) = = uint256 ( " 0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721 " ) ) ) ;
( pindex - > nHeight = = 91880 & & pindex - > GetBlockHash ( ) = = uint256 ( " 0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721 " ) ) ) ;
if ( fEnforceBIP30 ) {
if ( fEnforceBIP30 ) {
BOOST_FOREACH ( CTransaction & tx , vtx ) {
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + ) {
uint256 hash = tx . GetHash ( ) ;
uint256 hash = GetTxHash ( i ) ;
CCoins coins ;
CCoins coins ;
if ( view . GetCoins ( hash , coins ) & & ! coins . IsPruned ( ) )
if ( view . GetCoins ( hash , coins ) & & ! coins . IsPruned ( ) )
return error ( " ConnectBlock() : tried to overwrite transaction " ) ;
return error ( " ConnectBlock() : tried to overwrite transaction " ) ;
@ -1483,8 +1481,10 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsView &view, bool fJustCheck
int64 nFees = 0 ;
int64 nFees = 0 ;
unsigned int nSigOps = 0 ;
unsigned int nSigOps = 0 ;
BOOST_FOREACH ( CTransaction & tx , vtx )
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + )
{
{
const CTransaction & tx = vtx [ i ] ;
nSigOps + = tx . GetLegacySigOpCount ( ) ;
nSigOps + = tx . GetLegacySigOpCount ( ) ;
if ( nSigOps > MAX_BLOCK_SIGOPS )
if ( nSigOps > MAX_BLOCK_SIGOPS )
return DoS ( 100 , error ( " ConnectBlock() : too many sigops " )) ;
return DoS ( 100 , error ( " ConnectBlock() : too many sigops " )) ;
@ -1511,7 +1511,7 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsView &view, bool fJustCheck
}
}
CTxUndo txundo ;
CTxUndo txundo ;
if ( ! tx . UpdateCoins ( view , txundo , pindex - > nHeight ) )
if ( ! tx . UpdateCoins ( view , txundo , pindex - > nHeight , GetTxHash ( i ) ) )
return error ( " ConnectBlock() : UpdateInputs failed " ) ;
return error ( " ConnectBlock() : UpdateInputs failed " ) ;
if ( ! tx . IsCoinBase ( ) )
if ( ! tx . IsCoinBase ( ) )
blockundo . vtxundo . push_back ( txundo ) ;
blockundo . vtxundo . push_back ( txundo ) ;
@ -1542,8 +1542,8 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsView &view, bool fJustCheck
return false ;
return false ;
// Watch for transactions paying to me
// Watch for transactions paying to me
BOOST_FOREACH ( CTransaction & tx , vtx )
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + )
SyncWithWallets ( tx , this , true ) ;
SyncWithWallets ( GetTxHash ( i ) , v tx[ i ] , this , true ) ;
return true ;
return true ;
}
}
@ -1755,7 +1755,7 @@ bool CBlock::AddToBlockIndex(const CDiskBlockPos &pos)
// Notify UI to display prev block's coinbase if it was ours
// Notify UI to display prev block's coinbase if it was ours
static uint256 hashPrevBestCoinBase ;
static uint256 hashPrevBestCoinBase ;
UpdatedTransaction ( hashPrevBestCoinBase ) ;
UpdatedTransaction ( hashPrevBestCoinBase ) ;
hashPrevBestCoinBase = vtx [ 0 ] . GetHash ( ) ;
hashPrevBestCoinBase = GetTxHash ( 0 ) ;
}
}
uiInterface . NotifyBlocksChanged ( ) ;
uiInterface . NotifyBlocksChanged ( ) ;
@ -1876,10 +1876,10 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const
// Check for duplicate txids. This is caught by ConnectInputs(),
// Check for duplicate txids. This is caught by ConnectInputs(),
// but catching it earlier avoids a potential DoS attack:
// but catching it earlier avoids a potential DoS attack:
BuildMerkleTree ( ) ;
set < uint256 > uniqueTx ;
set < uint256 > uniqueTx ;
BOOST_FOREACH ( const CTransaction & tx , vtx )
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + ) {
{
uniqueTx . insert ( GetTxHash ( i ) ) ;
uniqueTx . insert ( tx . GetHash ( ) ) ;
}
}
if ( uniqueTx . size ( ) ! = vtx . size ( ) )
if ( uniqueTx . size ( ) ! = vtx . size ( ) )
return DoS ( 100 , error ( " CheckBlock() : duplicate transaction " )) ;
return DoS ( 100 , error ( " CheckBlock() : duplicate transaction " )) ;
@ -2914,7 +2914,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
bool fMissingInputs = false ;
bool fMissingInputs = false ;
if ( tx . AcceptToMemoryPool ( true , & fMissingInputs ) )
if ( tx . AcceptToMemoryPool ( true , & fMissingInputs ) )
{
{
SyncWithWallets ( tx , NULL , true ) ;
SyncWithWallets ( inv . hash , tx , NULL , true ) ;
RelayMessage ( inv , vMsg ) ;
RelayMessage ( inv , vMsg ) ;
mapAlreadyAskedFor . erase ( inv ) ;
mapAlreadyAskedFor . erase ( inv ) ;
vWorkQueue . push_back ( inv . hash ) ;
vWorkQueue . push_back ( inv . hash ) ;
@ -2937,7 +2937,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if ( tx . AcceptToMemoryPool ( true , & fMissingInputs2 ) )
if ( tx . AcceptToMemoryPool ( true , & fMissingInputs2 ) )
{
{
printf ( " accepted orphan tx %s \n " , inv . hash . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) ) ;
printf ( " accepted orphan tx %s \n " , inv . hash . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) ) ;
SyncWithWallets ( tx , NULL , true ) ;
SyncWithWallets ( inv . hash , tx , NULL , true ) ;
RelayMessage ( inv , vMsg ) ;
RelayMessage ( inv , vMsg ) ;
mapAlreadyAskedFor . erase ( inv ) ;
mapAlreadyAskedFor . erase ( inv ) ;
vWorkQueue . push_back ( inv . hash ) ;
vWorkQueue . push_back ( inv . hash ) ;
@ -3729,7 +3729,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
continue ;
continue ;
CTxUndo txundo ;
CTxUndo txundo ;
if ( ! tx . UpdateCoins ( viewTemp , txundo , pindexPrev - > nHeight + 1 ) )
uint256 hash = tx . GetHash ( ) ;
if ( ! tx . UpdateCoins ( viewTemp , txundo , pindexPrev - > nHeight + 1 , hash ) )
continue ;
continue ;
// push changes from the second layer cache to the first one
// push changes from the second layer cache to the first one
@ -3749,7 +3750,6 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
}
}
// Add transactions that depend on this one to the priority queue
// Add transactions that depend on this one to the priority queue
uint256 hash = tx . GetHash ( ) ;
if ( mapDependers . count ( hash ) )
if ( mapDependers . count ( hash ) )
{
{
BOOST_FOREACH ( COrphan * porphan , mapDependers [ hash ] )
BOOST_FOREACH ( COrphan * porphan , mapDependers [ hash ] )