@ -1029,8 +1029,8 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
return state . DoS ( 10 , false , REJECT_INVALID , " bad-txns-vin-empty " ) ;
return state . DoS ( 10 , false , REJECT_INVALID , " bad-txns-vin-empty " ) ;
if ( tx . vout . empty ( ) )
if ( tx . vout . empty ( ) )
return state . DoS ( 10 , false , REJECT_INVALID , " bad-txns-vout-empty " ) ;
return state . DoS ( 10 , false , REJECT_INVALID , " bad-txns-vout-empty " ) ;
// Size limits
// Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
if ( : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
if ( : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS ) > MAX_BLOCK_SIZE )
return state . DoS ( 100 , false , REJECT_INVALID , " bad-txns-oversize " ) ;
return state . DoS ( 100 , false , REJECT_INVALID , " bad-txns-oversize " ) ;
// Check for negative or overflow output values
// Check for negative or overflow output values
@ -3396,7 +3396,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
// because we receive the wrong transactions for it.
// because we receive the wrong transactions for it.
// Size limits
// Size limits
if ( block . vtx . empty ( ) | | block . vtx . size ( ) > MAX_BLOCK_SIZE | | : : GetSerializeSize ( block , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
if ( block . vtx . empty ( ) | | block . vtx . size ( ) > MAX_BLOCK_SIZE | | : : GetSerializeSize ( block , SER_NETWORK , PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS ) > MAX_BLOCK_SIZE )
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
@ -4508,6 +4508,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
switch ( inv . type )
switch ( inv . type )
{
{
case MSG_TX :
case MSG_TX :
case MSG_WITNESS_TX :
{
{
assert ( recentRejects ) ;
assert ( recentRejects ) ;
if ( chainActive . Tip ( ) - > GetBlockHash ( ) ! = hashRecentRejectsChainTip )
if ( chainActive . Tip ( ) - > GetBlockHash ( ) ! = hashRecentRejectsChainTip )
@ -4528,6 +4529,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
pcoinsTip - > HaveCoinsInCache ( inv . hash ) ;
pcoinsTip - > HaveCoinsInCache ( inv . hash ) ;
}
}
case MSG_BLOCK :
case MSG_BLOCK :
case MSG_WITNESS_BLOCK :
return mapBlockIndex . count ( inv . hash ) ;
return mapBlockIndex . count ( inv . hash ) ;
}
}
// Don't know what it is, just say we already got one
// Don't know what it is, just say we already got one
@ -4552,7 +4554,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
boost : : this_thread : : interruption_point ( ) ;
boost : : this_thread : : interruption_point ( ) ;
it + + ;
it + + ;
if ( inv . type = = MSG_BLOCK | | inv . type = = MSG_FILTERED_BLOCK | | inv . type = = MSG_CMPCT_BLOCK )
if ( inv . type = = MSG_BLOCK | | inv . type = = MSG_FILTERED_BLOCK | | inv . type = = MSG_CMPCT_BLOCK | | inv . type = = MSG_WITNESS_BLOCK )
{
{
bool send = false ;
bool send = false ;
BlockMap : : iterator mi = mapBlockIndex . find ( inv . hash ) ;
BlockMap : : iterator mi = mapBlockIndex . find ( inv . hash ) ;
@ -4593,6 +4595,8 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
if ( ! ReadBlockFromDisk ( block , ( * mi ) . second , consensusParams ) )
if ( ! ReadBlockFromDisk ( block , ( * mi ) . second , consensusParams ) )
assert ( ! " cannot load block from disk " ) ;
assert ( ! " cannot load block from disk " ) ;
if ( inv . type = = MSG_BLOCK )
if ( inv . type = = MSG_BLOCK )
pfrom - > PushMessageWithFlag ( SERIALIZE_TRANSACTION_NO_WITNESS , NetMsgType : : BLOCK , block ) ;
else if ( inv . type = = MSG_WITNESS_BLOCK )
pfrom - > PushMessage ( NetMsgType : : BLOCK , block ) ;
pfrom - > PushMessage ( NetMsgType : : BLOCK , block ) ;
else if ( inv . type = = MSG_FILTERED_BLOCK )
else if ( inv . type = = MSG_FILTERED_BLOCK )
{
{
@ -4609,7 +4613,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 )
pfrom - > PushMessage ( NetMsgType : : TX , block . vtx [ pair . first ] ) ;
pfrom - > PushMessageWithFlag ( SERIALIZE_TRANSACTION_NO_WITNESS , NetMsgType : : TX , block . vtx [ pair . first ] ) ;
}
}
// else
// else
// no response
// no response
@ -4622,9 +4626,9 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
// instead we respond with the full, non-compact block.
// instead we respond with the full, non-compact block.
if ( mi - > second - > nHeight > = chainActive . Height ( ) - 10 ) {
if ( mi - > second - > nHeight > = chainActive . Height ( ) - 10 ) {
CBlockHeaderAndShortTxIDs cmpctblock ( block ) ;
CBlockHeaderAndShortTxIDs cmpctblock ( block ) ;
pfrom - > PushMessage ( NetMsgType : : CMPCTBLOCK , cmpctblock ) ;
pfrom - > PushMessageWithFlag ( SERIALIZE_TRANSACTION_NO_WITNESS , NetMsgType : : CMPCTBLOCK , cmpctblock ) ;
} else
} else
pfrom - > PushMessage ( NetMsgType : : BLOCK , block ) ;
pfrom - > PushMessageWithFlag ( SERIALIZE_TRANSACTION_NO_WITNESS , NetMsgType : : BLOCK , block ) ;
}
}
// Trigger the peer node to send a getblocks request for the next batch of inventory
// Trigger the peer node to send a getblocks request for the next batch of inventory
@ -4640,20 +4644,20 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
}
}
}
}
}
}
else if ( inv . type = = MSG_TX )
else if ( inv . type = = MSG_TX | | inv . type = = MSG_WITNESS_TX )
{
{
// Send stream from relay memory
// Send stream from relay memory
bool push = false ;
bool push = false ;
auto mi = mapRelay . find ( inv . hash ) ;
auto mi = mapRelay . find ( inv . hash ) ;
if ( mi ! = mapRelay . end ( ) ) {
if ( mi ! = mapRelay . end ( ) ) {
pfrom - > PushMessage ( NetMsgType : : TX , * mi - > second ) ;
pfrom - > PushMessageWithFlag ( inv . type = = MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0 , NetMsgType : : TX , * mi - > second ) ;
push = true ;
push = true ;
} else if ( pfrom - > timeLastMempoolReq ) {
} else if ( pfrom - > timeLastMempoolReq ) {
auto txinfo = mempool . info ( inv . hash ) ;
auto txinfo = mempool . info ( inv . hash ) ;
// To protect privacy, do not answer getdata using the mempool when
// To protect privacy, do not answer getdata using the mempool when
// that TX couldn't have been INVed in reply to a MEMPOOL request.
// that TX couldn't have been INVed in reply to a MEMPOOL request.
if ( txinfo . tx & & txinfo . nTime < = pfrom - > timeLastMempoolReq ) {
if ( txinfo . tx & & txinfo . nTime < = pfrom - > timeLastMempoolReq ) {
pfrom - > PushMessage ( NetMsgType : : TX , * txinfo . tx ) ;
pfrom - > PushMessageWithFlag ( inv . type = = MSG_TX ? SERIALIZE_TRANSACTION_NO_WITNESS : 0 , NetMsgType : : TX , * txinfo . tx ) ;
push = true ;
push = true ;
}
}
}
}
@ -4665,7 +4669,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
// Track requests for our stuff.
// Track requests for our stuff.
GetMainSignals ( ) . Inventory ( inv . hash ) ;
GetMainSignals ( ) . Inventory ( inv . hash ) ;
if ( inv . type = = MSG_BLOCK | | inv . type = = MSG_FILTERED_BLOCK | | inv . type = = MSG_CMPCT_BLOCK )
if ( inv . type = = MSG_BLOCK | | inv . type = = MSG_FILTERED_BLOCK | | inv . type = = MSG_CMPCT_BLOCK | | inv . type = = MSG_WITNESS_BLOCK )
break ;
break ;
}
}
}
}
@ -5146,7 +5150,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
}
resp . txn [ i ] = block . vtx [ req . indexes [ i ] ] ;
resp . txn [ i ] = block . vtx [ req . indexes [ i ] ] ;
}
}
pfrom - > PushMessage ( NetMsgType : : BLOCKTXN , resp ) ;
pfrom - > PushMessageWithFlag ( SERIALIZE_TRANSACTION_NO_WITNESS , NetMsgType : : BLOCKTXN , resp ) ;
}
}