@@ -490,16 +490,21 @@ pub enum ConsensusError {
490490 InvalidPoW ( String ) ,
491491}
492492
493- /// Calculates transaction weight according to BQIP-0007 (BQSegWit) .
493+ /// Calculates transaction weight according to BQIP-0002 .
494494///
495- /// Formula: `weight = ( base_bytes × 4 ) + (witness_bytes × 1 )`
495+ /// Formula: `weight = base_bytes + (sig_count × alpha ) + (witness_bytes × beta )`
496496///
497- /// This gives witness data (Dilithium5 signatures) a 4x discount compared to
498- /// base transaction data, allowing ~4x more transactions per block.
499- /// Equivalent to Bitcoin's SegWit weight formula.
497+ /// Parameters:
498+ /// - `alpha = 384`: fixed cost per signature (algorithm-agnostic)
499+ /// - `beta = 0.5`: 50% discount on witness data (Dilithium5 signatures)
500+ ///
501+ /// This gives PQC signatures a 50% size discount plus a fixed per-sig cost,
502+ /// allowing ~2x more transactions per block compared to BQIP-0007 which
503+ /// was optimized for ECDSA-size signatures.
500504pub fn calculate_tx_weight ( tx : & bitquan_types:: Transaction ) -> Result < usize , ConsensusError > {
501- // Witness scale factor: base data costs 4 weight units per byte
502- const WITNESS_SCALE_FACTOR : usize = 4 ;
505+ // BQIP-0002 parameters
506+ const ALPHA : usize = 384 ; // Fixed cost per signature (algorithm-agnostic)
507+ const BETA : f32 = 0.5 ; // Witness byte discount factor
503508
504509 // Total serialized size (base + witness)
505510 let total_size = tx
@@ -518,15 +523,23 @@ pub fn calculate_tx_weight(tx: &bitquan_types::Transaction) -> Result<usize, Con
518523 "transaction base size calculation" ,
519524 ) ) ?;
520525
521- // BQIP-0007: weight = base_bytes*4 + witness_bytes*1
522- // Witness (signatures) get a 4x discount → 4x more txs fit per block
523- let base_weight = base_size
524- . checked_mul ( WITNESS_SCALE_FACTOR )
525- . ok_or ( ConsensusError :: WeightOverflow ( "base weight calculation" ) ) ?;
526+ // Signature weight: fixed cost per signature regardless of algorithm
527+ let sig_count = tx
528+ . signature_count ( )
529+ . map_err ( |_| ConsensusError :: WeightOverflow ( "transaction signature count" ) ) ?;
530+ let sig_weight = sig_count
531+ . checked_mul ( ALPHA )
532+ . ok_or ( ConsensusError :: WeightOverflow (
533+ "signature weight calculation" ,
534+ ) ) ?;
535+
536+ // Witness weight: 50% discount on witness bytes
537+ let witness_weight = ( BETA * witness_size as f32 ) . round ( ) as usize ;
526538
527- // witness_bytes × 1 (discount factor)
528- base_weight
529- . checked_add ( witness_size)
539+ // BQIP-0002: weight = base_bytes + sig_count*alpha + witness_bytes*beta
540+ base_size
541+ . checked_add ( sig_weight)
542+ . and_then ( |v| v. checked_add ( witness_weight) )
530543 . ok_or ( ConsensusError :: WeightOverflow ( "total transaction weight" ) )
531544}
532545
@@ -541,33 +554,14 @@ pub fn calculate_block_weight(block: &Block) -> Result<usize, ConsensusError> {
541554 } )
542555}
543556
544- /// Legacy function - calculates the block weight given an `alpha` multiplier .
557+ /// Legacy function - removed in favor of calculate_block_weight() using BQIP-0002 formula .
545558///
546- /// Deprecated: Use calculate_block_weight() instead for BQIP-0002 compliance.
547- ///
548- /// **Note:** This function is internal-only for testing weight formulas.
549- /// External callers should use `calculate_block_weight()` with production parameters.
559+ /// The BQIP-0002 formula (base + sig_count*alpha + witness*beta) is now the primary
560+ /// weight calculation, making this beta-parameterized function redundant.
550561#[ deprecated( note = "Use calculate_block_weight() for BQIP-0002 compliance" ) ]
551- #[ allow( dead_code) ] // Deprecated API - kept for potential external references
552- pub ( crate ) fn calculate_block_weight_with_beta ( block : & Block , alpha : u32 , beta : f32 ) -> u64 {
553- use bitquan_types:: CompactUint ;
554- // Total bytes (base + witness) - return 0 on error (deprecated anyway)
555- let total = block. serialized_size_hint ( ) . unwrap_or ( 0 ) as u64 ;
556- // Approximate witness bytes from tx structure (count prefix + witnesses)
557- let mut witness_bytes: u64 = 0 ;
558- for tx in & block. transactions {
559- witness_bytes += CompactUint :: from_usize ( tx. witnesses . len ( ) ) . encoded_length ( ) as u64 ;
560- witness_bytes += tx
561- . witnesses
562- . iter ( )
563- . filter_map ( |w| w. serialized_size_hint ( ) . ok ( ) )
564- . map ( |size| size as u64 )
565- . sum :: < u64 > ( ) ;
566- }
567- let base_bytes = total. saturating_sub ( witness_bytes) ;
568- let signature_weight = count_signatures ( block) * alpha as u64 ;
569- let witness_weight = ( beta * witness_bytes as f32 ) . round ( ) as u64 ;
570- base_bytes + signature_weight + witness_weight
562+ #[ allow( dead_code) ]
563+ pub ( crate ) fn calculate_block_weight_with_beta ( block : & Block , _alpha : u32 , _beta : f32 ) -> u64 {
564+ calculate_block_weight ( block) . unwrap_or ( 0 ) as u64
571565}
572566
573567/// Validates a block against the supplied consensus parameters (BQIP-0002).
0 commit comments