|
|
@ -1342,7 +1342,7 @@ unsigned int CTransaction::GetP2SHSigOpCount(CCoinsViewCache& inputs) const |
|
|
|
return nSigOps; |
|
|
|
return nSigOps; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash) const |
|
|
|
void CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
// mark inputs spent
|
|
|
|
// mark inputs spent
|
|
|
|
if (!IsCoinBase()) { |
|
|
|
if (!IsCoinBase()) { |
|
|
@ -1356,8 +1356,6 @@ bool CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs, |
|
|
|
|
|
|
|
|
|
|
|
// add outputs
|
|
|
|
// add outputs
|
|
|
|
assert(inputs.SetCoins(txhash, CCoins(*this, nHeight))); |
|
|
|
assert(inputs.SetCoins(txhash, CCoins(*this, nHeight))); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CTransaction::HaveInputs(CCoinsViewCache &inputs) const |
|
|
|
bool CTransaction::HaveInputs(CCoinsViewCache &inputs) const |
|
|
@ -1683,8 +1681,7 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
CTxUndo txundo; |
|
|
|
CTxUndo txundo; |
|
|
|
if (!tx.UpdateCoins(state, view, txundo, pindex->nHeight, GetTxHash(i))) |
|
|
|
tx.UpdateCoins(state, view, txundo, pindex->nHeight, GetTxHash(i)); |
|
|
|
return error("ConnectBlock() : UpdateInputs failed"); |
|
|
|
|
|
|
|
if (!tx.IsCoinBase()) |
|
|
|
if (!tx.IsCoinBase()) |
|
|
|
blockundo.vtxundo.push_back(txundo); |
|
|
|
blockundo.vtxundo.push_back(txundo); |
|
|
|
|
|
|
|
|
|
|
@ -4233,8 +4230,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) |
|
|
|
BOOST_FOREACH(const CTxIn& txin, tx.vin) |
|
|
|
BOOST_FOREACH(const CTxIn& txin, tx.vin) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Read prev transaction
|
|
|
|
// Read prev transaction
|
|
|
|
CCoins coins; |
|
|
|
if (!view.HaveCoins(txin.prevout.hash)) |
|
|
|
if (!view.GetCoins(txin.prevout.hash, coins)) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
// This should never happen; all transactions in the memory
|
|
|
|
// This should never happen; all transactions in the memory
|
|
|
|
// pool should connect to either transactions in the chain
|
|
|
|
// pool should connect to either transactions in the chain
|
|
|
@ -4261,6 +4257,7 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) |
|
|
|
nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue; |
|
|
|
nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue; |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const CCoins &coins = view.GetCoins(txin.prevout.hash); |
|
|
|
|
|
|
|
|
|
|
|
int64 nValueIn = coins.vout[txin.prevout.n].nValue; |
|
|
|
int64 nValueIn = coins.vout[txin.prevout.n].nValue; |
|
|
|
nTotalIn += nValueIn; |
|
|
|
nTotalIn += nValueIn; |
|
|
@ -4308,9 +4305,6 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) |
|
|
|
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); |
|
|
|
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); |
|
|
|
vecPriority.pop_back(); |
|
|
|
vecPriority.pop_back(); |
|
|
|
|
|
|
|
|
|
|
|
// second layer cached modifications just for this transaction
|
|
|
|
|
|
|
|
CCoinsViewCache viewTemp(view, true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Size limits
|
|
|
|
// Size limits
|
|
|
|
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); |
|
|
|
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); |
|
|
|
if (nBlockSize + nTxSize >= nBlockMaxSize) |
|
|
|
if (nBlockSize + nTxSize >= nBlockMaxSize) |
|
|
@ -4335,26 +4329,22 @@ CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) |
|
|
|
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); |
|
|
|
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!tx.HaveInputs(viewTemp)) |
|
|
|
if (!tx.HaveInputs(view)) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
int64 nTxFees = tx.GetValueIn(viewTemp)-tx.GetValueOut(); |
|
|
|
int64 nTxFees = tx.GetValueIn(view)-tx.GetValueOut(); |
|
|
|
|
|
|
|
|
|
|
|
nTxSigOps += tx.GetP2SHSigOpCount(viewTemp); |
|
|
|
nTxSigOps += tx.GetP2SHSigOpCount(view); |
|
|
|
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) |
|
|
|
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
CValidationState state; |
|
|
|
CValidationState state; |
|
|
|
if (!tx.CheckInputs(state, viewTemp, true, SCRIPT_VERIFY_P2SH)) |
|
|
|
if (!tx.CheckInputs(state, view, true, SCRIPT_VERIFY_P2SH)) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
CTxUndo txundo; |
|
|
|
CTxUndo txundo; |
|
|
|
uint256 hash = tx.GetHash(); |
|
|
|
uint256 hash = tx.GetHash(); |
|
|
|
if (!tx.UpdateCoins(state, viewTemp, txundo, pindexPrev->nHeight+1, hash)) |
|
|
|
tx.UpdateCoins(state, view, txundo, pindexPrev->nHeight+1, hash); |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// push changes from the second layer cache to the first one
|
|
|
|
|
|
|
|
viewTemp.Flush(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Added
|
|
|
|
// Added
|
|
|
|
pblock->vtx.push_back(tx); |
|
|
|
pblock->vtx.push_back(tx); |
|
|
|