@@ -2680,6 +2680,16 @@ bool CheckColdStakeFreeOutput(const CTransaction& tx, const int nHeight)
26802680 return true ;
26812681}
26822682
2683+ // cumulative size of all shielded txes inside a block
2684+ static unsigned int GetTotalShieldedTxSize (const CBlock& block)
2685+ {
2686+ unsigned int nSizeShielded = 0 ;
2687+ for (const auto & tx : block.vtx ) {
2688+ if (tx->IsShieldedTx ()) nSizeShielded += tx->GetTotalSize ();
2689+ }
2690+ return nSizeShielded;
2691+ }
2692+
26832693bool CheckBlock (const CBlock& block, CValidationState& state, bool fCheckPOW , bool fCheckMerkleRoot , bool fCheckSig )
26842694{
26852695 if (block.fChecked )
@@ -2713,9 +2723,14 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
27132723
27142724 // Size limits
27152725 unsigned int nMaxBlockSize = MAX_BLOCK_SIZE_CURRENT;
2716- if (block.vtx .empty () || block.vtx .size () > nMaxBlockSize || ::GetSerializeSize (block, SER_NETWORK, PROTOCOL_VERSION) > nMaxBlockSize)
2726+ const unsigned int nBlockSize = ::GetSerializeSize (block, SER_NETWORK, PROTOCOL_VERSION);
2727+ if (block.vtx .empty () || block.vtx .size () > nMaxBlockSize || nBlockSize > nMaxBlockSize)
27172728 return state.DoS (100 , false , REJECT_INVALID, " bad-blk-length" , false , " size limits failed" );
27182729
2730+ // Check shielded txes limits (no need to check if the block size is already under 750kB)
2731+ if (nBlockSize > MAX_BLOCK_SHIELDED_TXES_SIZE && GetTotalShieldedTxSize (block) > MAX_BLOCK_SHIELDED_TXES_SIZE)
2732+ return state.DoS (100 , false , REJECT_INVALID, " bad-blk-shielded-size" , false , " shielded size limits failed" );
2733+
27192734 // First transaction must be coinbase, the rest must not be
27202735 if (block.vtx .empty () || !block.vtx [0 ]->IsCoinBase ())
27212736 return state.DoS (100 , false , REJECT_INVALID, " bad-cb-missing" , false , " first tx is not coinbase" );
0 commit comments