@ -233,7 +233,7 @@ namespace {
int nPeersWithValidatedDownloads = 0 ;
int nPeersWithValidatedDownloads = 0 ;
/** Relay map, protected by cs_main. */
/** Relay map, protected by cs_main. */
typedef std : : map < uint256 , std : : shared_ptr < const CTransaction > > MapRelay ;
typedef std : : map < uint256 , CTransactionRef > MapRelay ;
MapRelay mapRelay ;
MapRelay mapRelay ;
/** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */
/** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */
std : : deque < std : : pair < int64_t , MapRelay : : iterator > > vRelayExpiration ;
std : : deque < std : : pair < int64_t , MapRelay : : iterator > > vRelayExpiration ;
@ -1639,7 +1639,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::P
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
std : : shared_ptr < const CTransaction > ptx = mempool . get ( hash ) ;
CTransactionRef ptx = mempool . get ( hash ) ;
if ( ptx )
if ( ptx )
{
{
txOut = * ptx ;
txOut = * ptx ;
@ -1682,9 +1682,9 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::P
if ( pindexSlow ) {
if ( pindexSlow ) {
CBlock block ;
CBlock block ;
if ( ReadBlockFromDisk ( block , pindexSlow , consensusParams ) ) {
if ( ReadBlockFromDisk ( block , pindexSlow , consensusParams ) ) {
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
for ( const auto & tx : block . vtx ) {
if ( tx . GetHash ( ) = = hash ) {
if ( tx - > GetHash ( ) = = hash ) {
txOut = tx ;
txOut = * tx ;
hashBlock = pindexSlow - > GetBlockHash ( ) ;
hashBlock = pindexSlow - > GetBlockHash ( ) ;
return true ;
return true ;
}
}
@ -2223,7 +2223,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
// undo transactions in reverse order
// undo transactions in reverse order
for ( int i = block . vtx . size ( ) - 1 ; i > = 0 ; i - - ) {
for ( int i = block . vtx . size ( ) - 1 ; i > = 0 ; i - - ) {
const CTransaction & tx = block . vtx [ i ] ;
const CTransaction & tx = * ( block . vtx [ i ] ) ;
uint256 hash = tx . GetHash ( ) ;
uint256 hash = tx . GetHash ( ) ;
// Check that all outputs are available and match the outputs in the block itself
// Check that all outputs are available and match the outputs in the block itself
@ -2417,8 +2417,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
fEnforceBIP30 = fEnforceBIP30 & & ( ! pindexBIP34height | | ! ( pindexBIP34height - > GetBlockHash ( ) = = chainparams . GetConsensus ( ) . BIP34Hash ) ) ;
fEnforceBIP30 = fEnforceBIP30 & & ( ! pindexBIP34height | | ! ( pindexBIP34height - > GetBlockHash ( ) = = chainparams . GetConsensus ( ) . BIP34Hash ) ) ;
if ( fEnforceBIP30 ) {
if ( fEnforceBIP30 ) {
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
for ( const auto & tx : block . vtx ) {
const CCoins * coins = view . AccessCoins ( tx . GetHash ( ) ) ;
const CCoins * coins = view . AccessCoins ( tx - > GetHash ( ) ) ;
if ( coins & & ! coins - > IsPruned ( ) )
if ( coins & & ! coins - > IsPruned ( ) )
return state . DoS ( 100 , error ( " ConnectBlock(): tried to overwrite transaction " ) ,
return state . DoS ( 100 , error ( " ConnectBlock(): tried to overwrite transaction " ) ,
REJECT_INVALID , " bad-txns-BIP30 " ) ;
REJECT_INVALID , " bad-txns-BIP30 " ) ;
@ -2474,7 +2474,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
txdata . reserve ( block . vtx . size ( ) ) ; // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
txdata . reserve ( block . vtx . size ( ) ) ; // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
for ( unsigned int i = 0 ; i < block . vtx . size ( ) ; i + + )
for ( unsigned int i = 0 ; i < block . vtx . size ( ) ; i + + )
{
{
const CTransaction & tx = block . vtx [ i ] ;
const CTransaction & tx = * ( block . vtx [ i ] ) ;
nInputs + = tx . vin . size ( ) ;
nInputs + = tx . vin . size ( ) ;
@ -2544,10 +2544,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
LogPrint ( " bench " , " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs] \n " , ( unsigned ) block . vtx . size ( ) , 0.001 * ( nTime3 - nTime2 ) , 0.001 * ( nTime3 - nTime2 ) / block . vtx . size ( ) , nInputs < = 1 ? 0 : 0.001 * ( nTime3 - nTime2 ) / ( nInputs - 1 ) , nTimeConnect * 0.000001 ) ;
LogPrint ( " bench " , " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs] \n " , ( unsigned ) block . vtx . size ( ) , 0.001 * ( nTime3 - nTime2 ) , 0.001 * ( nTime3 - nTime2 ) / block . vtx . size ( ) , nInputs < = 1 ? 0 : 0.001 * ( nTime3 - nTime2 ) / ( nInputs - 1 ) , nTimeConnect * 0.000001 ) ;
CAmount blockReward = nFees + GetBlockSubsidy ( pindex - > nHeight , chainparams . GetConsensus ( ) ) ;
CAmount blockReward = nFees + GetBlockSubsidy ( pindex - > nHeight , chainparams . GetConsensus ( ) ) ;
if ( block . vtx [ 0 ] . GetValueOut ( ) > blockReward )
if ( block . vtx [ 0 ] - > GetValueOut ( ) > blockReward )
return state . DoS ( 100 ,
return state . DoS ( 100 ,
error ( " ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d) " ,
error ( " ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d) " ,
block . vtx [ 0 ] . GetValueOut ( ) , blockReward ) ,
block . vtx [ 0 ] - > GetValueOut ( ) , blockReward ) ,
REJECT_INVALID , " bad-cb-amount " ) ;
REJECT_INVALID , " bad-cb-amount " ) ;
if ( ! control . Wait ( ) )
if ( ! control . Wait ( ) )
@ -2590,7 +2590,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// Watch for changes to the previous coinbase transaction.
// Watch for changes to the previous coinbase transaction.
static uint256 hashPrevBestCoinBase ;
static uint256 hashPrevBestCoinBase ;
GetMainSignals ( ) . UpdatedTransaction ( hashPrevBestCoinBase ) ;
GetMainSignals ( ) . UpdatedTransaction ( hashPrevBestCoinBase ) ;
hashPrevBestCoinBase = block . vtx [ 0 ] . GetHash ( ) ;
hashPrevBestCoinBase = block . vtx [ 0 ] - > GetHash ( ) ;
// Erase orphan transactions include or precluded by this block
// Erase orphan transactions include or precluded by this block
if ( vOrphanErase . size ( ) ) {
if ( vOrphanErase . size ( ) ) {
@ -2807,7 +2807,8 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara
if ( ! fBare ) {
if ( ! fBare ) {
// Resurrect mempool transactions from the disconnected block.
// Resurrect mempool transactions from the disconnected block.
std : : vector < uint256 > vHashUpdate ;
std : : vector < uint256 > vHashUpdate ;
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
for ( const auto & it : block . vtx ) {
const CTransaction & tx = * it ;
// ignore validation errors in resurrected transactions
// ignore validation errors in resurrected transactions
CValidationState stateDummy ;
CValidationState stateDummy ;
if ( tx . IsCoinBase ( ) | | ! AcceptToMemoryPool ( mempool , stateDummy , tx , false , NULL , true ) ) {
if ( tx . IsCoinBase ( ) | | ! AcceptToMemoryPool ( mempool , stateDummy , tx , false , NULL , true ) ) {
@ -2828,8 +2829,8 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara
UpdateTip ( pindexDelete - > pprev , chainparams ) ;
UpdateTip ( pindexDelete - > pprev , chainparams ) ;
// Let wallets know transactions went from 1-confirmed to
// Let wallets know transactions went from 1-confirmed to
// 0-confirmed or conflicted:
// 0-confirmed or conflicted:
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
for ( const auto & tx : block . vtx ) {
GetMainSignals ( ) . SyncTransaction ( tx , pindexDelete - > pprev , CMainSignals : : SYNC_TRANSACTION_NOT_IN_BLOCK ) ;
GetMainSignals ( ) . SyncTransaction ( * tx , pindexDelete - > pprev , CMainSignals : : SYNC_TRANSACTION_NOT_IN_BLOCK ) ;
}
}
return true ;
return true ;
}
}
@ -2844,7 +2845,7 @@ static int64_t nTimePostConnect = 0;
* Connect a new block to chainActive . pblock is either NULL or a pointer to a CBlock
* Connect a new block to chainActive . pblock is either NULL or a pointer to a CBlock
* corresponding to pindexNew , to bypass loading it again from disk .
* corresponding to pindexNew , to bypass loading it again from disk .
*/
*/
bool static ConnectTip ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexNew , const CBlock * pblock , std : : vector < std : : shared_ptr < const CTransaction > > & txConflicted , std : : vector < std : : tuple < CTransaction , CBlockIndex * , int > > & txChanged )
bool static ConnectTip ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexNew , const CBlock * pblock , std : : vector < CTransactionRef > & txConflicted , std : : vector < std : : tuple < CTransactionRef , CBlockIndex * , int > > & txChanged )
{
{
assert ( pindexNew - > pprev = = chainActive . Tip ( ) ) ;
assert ( pindexNew - > pprev = = chainActive . Tip ( ) ) ;
// Read block from disk.
// Read block from disk.
@ -2884,7 +2885,7 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
// Update chainActive & related variables.
// Update chainActive & related variables.
UpdateTip ( pindexNew , chainparams ) ;
UpdateTip ( pindexNew , chainparams ) ;
for ( unsigned int i = 0 ; i < pblock - > vtx . size ( ) ; i + + )
for ( unsigned int i = 0 ; i < pblock - > vtx . size ( ) ; i + + )
txChanged . emplace_back ( pblock - > vtx [ i ] , pindexNew , i ) ;
txChanged . emplace_back ( pblock - > vtx [ i ] , pindexNew , i ) ;
int64_t nTime6 = GetTimeMicros ( ) ; nTimePostConnect + = nTime6 - nTime5 ; nTimeTotal + = nTime6 - nTime1 ;
int64_t nTime6 = GetTimeMicros ( ) ; nTimePostConnect + = nTime6 - nTime5 ; nTimeTotal + = nTime6 - nTime1 ;
@ -2967,7 +2968,7 @@ static void PruneBlockIndexCandidates() {
* Try to make some progress towards making pindexMostWork the active block .
* Try to make some progress towards making pindexMostWork the active block .
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork .
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork .
*/
*/
static bool ActivateBestChainStep ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexMostWork , const CBlock * pblock , bool & fInvalidFound , std : : vector < std : : shared_ptr < const CTransaction > > & txConflicted , std : : vector < std : : tuple < CTransaction , CBlockIndex * , int > > & txChanged )
static bool ActivateBestChainStep ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexMostWork , const CBlock * pblock , bool & fInvalidFound , std : : vector < CTransactionRef > & txConflicted , std : : vector < std : : tuple < CTransactionRef , CBlockIndex * , int > > & txChanged )
{
{
AssertLockHeld ( cs_main ) ;
AssertLockHeld ( cs_main ) ;
const CBlockIndex * pindexOldTip = chainActive . Tip ( ) ;
const CBlockIndex * pindexOldTip = chainActive . Tip ( ) ;
@ -3068,7 +3069,7 @@ static void NotifyHeaderTip() {
bool ActivateBestChain ( CValidationState & state , const CChainParams & chainparams , const CBlock * pblock ) {
bool ActivateBestChain ( CValidationState & state , const CChainParams & chainparams , const CBlock * pblock ) {
CBlockIndex * pindexMostWork = NULL ;
CBlockIndex * pindexMostWork = NULL ;
CBlockIndex * pindexNewTip = NULL ;
CBlockIndex * pindexNewTip = NULL ;
std : : vector < std : : tuple < CTransaction , CBlockIndex * , int > > txChanged ;
std : : vector < std : : tuple < CTransactionRef , CBlockIndex * , int > > txChanged ;
if ( pblock )
if ( pblock )
txChanged . reserve ( pblock - > vtx . size ( ) ) ;
txChanged . reserve ( pblock - > vtx . size ( ) ) ;
do {
do {
@ -3078,7 +3079,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
break ;
break ;
const CBlockIndex * pindexFork ;
const CBlockIndex * pindexFork ;
std : : vector < std : : shared_ptr < const CTransaction > > txConflicted ;
std : : vector < CTransactionRef > txConflicted ;
bool fInitialDownload ;
bool fInitialDownload ;
{
{
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
@ -3109,13 +3110,13 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
// throw all transactions though the signal-interface
// throw all transactions though the signal-interface
// while _not_ holding the cs_main lock
// while _not_ holding the cs_main lock
for ( std : : shared_ptr < const CTransaction > tx : txConflicted )
for ( const auto & tx : txConflicted )
{
{
GetMainSignals ( ) . SyncTransaction ( * tx , pindexNewTip , CMainSignals : : SYNC_TRANSACTION_NOT_IN_BLOCK ) ;
GetMainSignals ( ) . SyncTransaction ( * tx , pindexNewTip , CMainSignals : : SYNC_TRANSACTION_NOT_IN_BLOCK ) ;
}
}
// ... and about transactions that got confirmed:
// ... and about transactions that got confirmed:
for ( unsigned int i = 0 ; i < txChanged . size ( ) ; i + + )
for ( unsigned int i = 0 ; i < txChanged . size ( ) ; i + + )
GetMainSignals ( ) . SyncTransaction ( std : : get < 0 > ( txChanged [ i ] ) , std : : get < 1 > ( txChanged [ i ] ) , std : : get < 2 > ( txChanged [ i ] ) ) ;
GetMainSignals ( ) . SyncTransaction ( * std : : get < 0 > ( txChanged [ i ] ) , std : : get < 1 > ( txChanged [ i ] ) , std : : get < 2 > ( txChanged [ i ] ) ) ;
// Notify external listeners about the new tip.
// Notify external listeners about the new tip.
GetMainSignals ( ) . UpdatedBlockTip ( pindexNewTip , pindexFork , fInitialDownload ) ;
GetMainSignals ( ) . UpdatedBlockTip ( pindexNewTip , pindexFork , fInitialDownload ) ;
@ -3454,22 +3455,22 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
return state . DoS ( 100 , false , REJECT_INVALID , " bad-blk-length " , false , " size limits failed " ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " bad-blk-length " , false , " size limits failed " ) ;
// First transaction must be coinbase, the rest must not be
// First transaction must be coinbase, the rest must not be
if ( block . vtx . empty ( ) | | ! block . vtx [ 0 ] . IsCoinBase ( ) )
if ( block . vtx . empty ( ) | | ! block . vtx [ 0 ] - > IsCoinBase ( ) )
return state . DoS ( 100 , false , REJECT_INVALID , " bad-cb-missing " , false , " first tx is not coinbase " ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " bad-cb-missing " , false , " first tx is not coinbase " ) ;
for ( unsigned int i = 1 ; i < block . vtx . size ( ) ; i + + )
for ( unsigned int i = 1 ; i < block . vtx . size ( ) ; i + + )
if ( block . vtx [ i ] . IsCoinBase ( ) )
if ( block . vtx [ i ] - > IsCoinBase ( ) )
return state . DoS ( 100 , false , REJECT_INVALID , " bad-cb-multiple " , false , " more than one coinbase " ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " bad-cb-multiple " , false , " more than one coinbase " ) ;
// Check transactions
// Check transactions
for ( const auto & tx : block . vtx )
for ( const auto & tx : block . vtx )
if ( ! CheckTransaction ( tx , state , false ) )
if ( ! CheckTransaction ( * tx , state , false ) )
return state . Invalid ( false , state . GetRejectCode ( ) , state . GetRejectReason ( ) ,
return state . Invalid ( false , state . GetRejectCode ( ) , state . GetRejectReason ( ) ,
strprintf ( " Transaction check failed (tx hash %s) %s " , tx . GetHash ( ) . ToString ( ) , state . GetDebugMessage ( ) ) ) ;
strprintf ( " Transaction check failed (tx hash %s) %s " , tx - > GetHash ( ) . ToString ( ) , state . GetDebugMessage ( ) ) ) ;
unsigned int nSigOps = 0 ;
unsigned int nSigOps = 0 ;
for ( const auto & tx : block . vtx )
for ( const auto & tx : block . vtx )
{
{
nSigOps + = GetLegacySigOpCount ( tx ) ;
nSigOps + = GetLegacySigOpCount ( * tx ) ;
}
}
if ( nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST )
if ( nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST )
return state . DoS ( 100 , false , REJECT_INVALID , " bad-blk-sigops " , false , " out-of-bounds SigOpCount " ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " bad-blk-sigops " , false , " out-of-bounds SigOpCount " ) ;
@ -3505,8 +3506,8 @@ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& pa
static int GetWitnessCommitmentIndex ( const CBlock & block )
static int GetWitnessCommitmentIndex ( const CBlock & block )
{
{
int commitpos = - 1 ;
int commitpos = - 1 ;
for ( size_t o = 0 ; o < block . vtx [ 0 ] . vout . size ( ) ; o + + ) {
for ( size_t o = 0 ; o < block . vtx [ 0 ] - > vout . size ( ) ; o + + ) {
if ( block . vtx [ 0 ] . vout [ o ] . scriptPubKey . size ( ) > = 38 & & block . vtx [ 0 ] . vout [ o ] . scriptPubKey [ 0 ] = = OP_RETURN & & block . vtx [ 0 ] . vout [ o ] . scriptPubKey [ 1 ] = = 0x24 & & block . vtx [ 0 ] . vout [ o ] . scriptPubKey [ 2 ] = = 0xaa & & block . vtx [ 0 ] . vout [ o ] . scriptPubKey [ 3 ] = = 0x21 & & block . vtx [ 0 ] . vout [ o ] . scriptPubKey [ 4 ] = = 0xa9 & & block . vtx [ 0 ] . vout [ o ] . scriptPubKey [ 5 ] = = 0xed ) {
if ( block . vtx [ 0 ] - > vout [ o ] . scriptPubKey . size ( ) > = 38 & & block . vtx [ 0 ] - > vout [ o ] . scriptPubKey [ 0 ] = = OP_RETURN & & block . vtx [ 0 ] - > vout [ o ] . scriptPubKey [ 1 ] = = 0x24 & & block . vtx [ 0 ] - > vout [ o ] . scriptPubKey [ 2 ] = = 0xaa & & block . vtx [ 0 ] - > vout [ o ] . scriptPubKey [ 3 ] = = 0x21 & & block . vtx [ 0 ] - > vout [ o ] . scriptPubKey [ 4 ] = = 0xa9 & & block . vtx [ 0 ] - > vout [ o ] . scriptPubKey [ 5 ] = = 0xed ) {
commitpos = o ;
commitpos = o ;
}
}
}
}
@ -3517,10 +3518,12 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr
{
{
int commitpos = GetWitnessCommitmentIndex ( block ) ;
int commitpos = GetWitnessCommitmentIndex ( block ) ;
static const std : : vector < unsigned char > nonce ( 32 , 0x00 ) ;
static const std : : vector < unsigned char > nonce ( 32 , 0x00 ) ;
if ( commitpos ! = - 1 & & IsWitnessEnabled ( pindexPrev , consensusParams ) & & block . vtx [ 0 ] . wit . IsEmpty ( ) ) {
if ( commitpos ! = - 1 & & IsWitnessEnabled ( pindexPrev , consensusParams ) & & block . vtx [ 0 ] - > wit . IsEmpty ( ) ) {
block . vtx [ 0 ] . wit . vtxinwit . resize ( 1 ) ;
CMutableTransaction tx ( * block . vtx [ 0 ] ) ;
block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack . resize ( 1 ) ;
tx . wit . vtxinwit . resize ( 1 ) ;
block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] = nonce ;
tx . wit . vtxinwit [ 0 ] . scriptWitness . stack . resize ( 1 ) ;
tx . wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] = nonce ;
block . vtx [ 0 ] = MakeTransactionRef ( std : : move ( tx ) ) ;
}
}
}
}
@ -3530,7 +3533,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
int commitpos = GetWitnessCommitmentIndex ( block ) ;
int commitpos = GetWitnessCommitmentIndex ( block ) ;
bool fHaveWitness = false ;
bool fHaveWitness = false ;
for ( size_t t = 1 ; t < block . vtx . size ( ) ; t + + ) {
for ( size_t t = 1 ; t < block . vtx . size ( ) ; t + + ) {
if ( ! block . vtx [ t ] . wit . IsNull ( ) ) {
if ( ! block . vtx [ t ] - > wit . IsNull ( ) ) {
fHaveWitness = true ;
fHaveWitness = true ;
break ;
break ;
}
}
@ -3551,8 +3554,8 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
out . scriptPubKey [ 5 ] = 0xed ;
out . scriptPubKey [ 5 ] = 0xed ;
memcpy ( & out . scriptPubKey [ 6 ] , witnessroot . begin ( ) , 32 ) ;
memcpy ( & out . scriptPubKey [ 6 ] , witnessroot . begin ( ) , 32 ) ;
commitment = std : : vector < unsigned char > ( out . scriptPubKey . begin ( ) , out . scriptPubKey . end ( ) ) ;
commitment = std : : vector < unsigned char > ( out . scriptPubKey . begin ( ) , out . scriptPubKey . end ( ) ) ;
const_cast < std : : vector < CTxOut > * > ( & block . vtx [ 0 ] . vout ) - > push_back ( out ) ;
const_cast < std : : vector < CTxOut > * > ( & block . vtx [ 0 ] - > vout ) - > push_back ( out ) ;
block . vtx [ 0 ] . UpdateHash ( ) ;
block . vtx [ 0 ] - > UpdateHash ( ) ;
}
}
}
}
UpdateUncommittedBlockStructures ( block , pindexPrev , consensusParams ) ;
UpdateUncommittedBlockStructures ( block , pindexPrev , consensusParams ) ;
@ -3601,7 +3604,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
// Check that all transactions are finalized
// Check that all transactions are finalized
for ( const auto & tx : block . vtx ) {
for ( const auto & tx : block . vtx ) {
if ( ! IsFinalTx ( tx , nHeight , nLockTimeCutoff ) ) {
if ( ! IsFinalTx ( * tx , nHeight , nLockTimeCutoff ) ) {
return state . DoS ( 10 , false , REJECT_INVALID , " bad-txns-nonfinal " , false , " non-final transaction " ) ;
return state . DoS ( 10 , false , REJECT_INVALID , " bad-txns-nonfinal " , false , " non-final transaction " ) ;
}
}
}
}
@ -3610,8 +3613,8 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
if ( nHeight > = consensusParams . BIP34Height )
if ( nHeight > = consensusParams . BIP34Height )
{
{
CScript expect = CScript ( ) < < nHeight ;
CScript expect = CScript ( ) < < nHeight ;
if ( block . vtx [ 0 ] . vin [ 0 ] . scriptSig . size ( ) < expect . size ( ) | |
if ( block . vtx [ 0 ] - > vin [ 0 ] . scriptSig . size ( ) < expect . size ( ) | |
! std : : equal ( expect . begin ( ) , expect . end ( ) , block . vtx [ 0 ] . vin [ 0 ] . scriptSig . begin ( ) ) ) {
! std : : equal ( expect . begin ( ) , expect . end ( ) , block . vtx [ 0 ] - > vin [ 0 ] . scriptSig . begin ( ) ) ) {
return state . DoS ( 100 , false , REJECT_INVALID , " bad-cb-height " , false , " block height mismatch in coinbase " ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " bad-cb-height " , false , " block height mismatch in coinbase " ) ;
}
}
}
}
@ -3633,11 +3636,11 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
// The malleation check is ignored; as the transaction tree itself
// The malleation check is ignored; as the transaction tree itself
// already does not permit it, it is impossible to trigger in the
// already does not permit it, it is impossible to trigger in the
// witness tree.
// witness tree.
if ( block . vtx [ 0 ] . wit . vtxinwit . size ( ) ! = 1 | | block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack . size ( ) ! = 1 | | block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] . size ( ) ! = 32 ) {
if ( block . vtx [ 0 ] - > wit . vtxinwit . size ( ) ! = 1 | | block . vtx [ 0 ] - > wit . vtxinwit [ 0 ] . scriptWitness . stack . size ( ) ! = 1 | | block . vtx [ 0 ] - > wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] . size ( ) ! = 32 ) {
return state . DoS ( 100 , false , REJECT_INVALID , " bad-witness-nonce-size " , true , strprintf ( " %s : invalid witness nonce size " , __func__ ) ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " bad-witness-nonce-size " , true , strprintf ( " %s : invalid witness nonce size " , __func__ ) ) ;
}
}
CHash256 ( ) . Write ( hashWitness . begin ( ) , 32 ) . Write ( & block . vtx [ 0 ] . wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] [ 0 ] , 32 ) . Finalize ( hashWitness . begin ( ) ) ;
CHash256 ( ) . Write ( hashWitness . begin ( ) , 32 ) . Write ( & block . vtx [ 0 ] - > wit . vtxinwit [ 0 ] . scriptWitness . stack [ 0 ] [ 0 ] , 32 ) . Finalize ( hashWitness . begin ( ) ) ;
if ( memcmp ( hashWitness . begin ( ) , & block . vtx [ 0 ] . vout [ commitpos ] . scriptPubKey [ 6 ] , 32 ) ) {
if ( memcmp ( hashWitness . begin ( ) , & block . vtx [ 0 ] - > vout [ commitpos ] . scriptPubKey [ 6 ] , 32 ) ) {
return state . DoS ( 100 , false , REJECT_INVALID , " bad-witness-merkle-match " , true , strprintf ( " %s : witness merkle commitment mismatch " , __func__ ) ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " bad-witness-merkle-match " , true , strprintf ( " %s : witness merkle commitment mismatch " , __func__ ) ) ;
}
}
fHaveWitness = true ;
fHaveWitness = true ;
@ -3647,7 +3650,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
// No witness data is allowed in blocks that don't commit to witness data, as this would otherwise leave room for spam
// No witness data is allowed in blocks that don't commit to witness data, as this would otherwise leave room for spam
if ( ! fHaveWitness ) {
if ( ! fHaveWitness ) {
for ( size_t i = 0 ; i < block . vtx . size ( ) ; i + + ) {
for ( size_t i = 0 ; i < block . vtx . size ( ) ; i + + ) {
if ( ! block . vtx [ i ] . wit . IsNull ( ) ) {
if ( ! block . vtx [ i ] - > wit . IsNull ( ) ) {
return state . DoS ( 100 , false , REJECT_INVALID , " unexpected-witness " , true , strprintf ( " %s : unexpected witness data found " , __func__ ) ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " unexpected-witness " , true , strprintf ( " %s : unexpected witness data found " , __func__ ) ) ;
}
}
}
}
@ -4953,7 +4956,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
// however we MUST always provide at least what the remote peer needs
// however we MUST always provide at least what the remote peer needs
typedef std : : pair < unsigned int , uint256 > PairType ;
typedef std : : pair < unsigned int , uint256 > PairType ;
BOOST_FOREACH ( PairType & pair , merkleBlock . vMatchedTxn )
BOOST_FOREACH ( PairType & pair , merkleBlock . vMatchedTxn )
connman . PushMessageWithFlag ( pfrom , SERIALIZE_TRANSACTION_NO_WITNESS , NetMsgType : : TX , block . vtx [ pair . first ] ) ;
connman . PushMessageWithFlag ( pfrom , SERIALIZE_TRANSACTION_NO_WITNESS , NetMsgType : : TX , * block . vtx [ pair . first ] ) ;
}
}
// else
// else
// no response
// no response