@@ -581,12 +581,13 @@ static bool IsCurrentForAntiFeeSniping(interfaces::Chain& chain, const uint256&
581581}
582582
583583/* *
584-  * Return  a height-based locktime for new transactions (uses the height of the 
584+  * Set  a height-based locktime for new transactions (uses the height of the 
585585 * current chain tip unless we are not synced with the current chain 
586586 */  
587- static  uint32_t   GetLocktimeForNewTransaction ( interfaces::Chain& chain, const  uint256& block_hash, int  block_height)
587+ static  void   DiscourageFeeSniping (CMutableTransaction& tx,  interfaces::Chain& chain, const  uint256& block_hash, int  block_height)
588588{
589-     uint32_t  locktime;
589+     //  All inputs must be added by now
590+     assert (!tx.vin .empty ());
590591    //  Discourage fee sniping.
591592    // 
592593    //  For a large miner the value of the transactions in the best block and
@@ -608,22 +609,32 @@ static uint32_t GetLocktimeForNewTransaction(interfaces::Chain& chain, const uin
608609    //  now we ensure code won't be written that makes assumptions about
609610    //  nLockTime that preclude a fix later.
610611    if  (IsCurrentForAntiFeeSniping (chain, block_hash)) {
611-         locktime  = block_height;
612+         tx. nLockTime  = block_height;
612613
613614        //  Secondly occasionally randomly pick a nLockTime even further back, so
614615        //  that transactions that are delayed after signing for whatever reason,
615616        //  e.g. high-latency mix networks and some CoinJoin implementations, have
616617        //  better privacy.
617-         if  (GetRandInt (10 ) == 0 )
618-             locktime = std::max (0 , (int )locktime - GetRandInt (100 ));
618+         if  (GetRandInt (10 ) == 0 ) {
619+             tx.nLockTime  = std::max (0 , int (tx.nLockTime ) - GetRandInt (100 ));
620+         }
619621    } else  {
620622        //  If our chain is lagging behind, we can't discourage fee sniping nor help
621623        //  the privacy of high-latency transactions. To avoid leaking a potentially
622624        //  unique "nLockTime fingerprint", set nLockTime to a constant.
623-         locktime = 0 ;
625+         tx.nLockTime  = 0 ;
626+     }
627+     //  Sanity check all values
628+     assert (tx.nLockTime  < LOCKTIME_THRESHOLD); //  Type must be block height
629+     assert (tx.nLockTime  <= uint64_t (block_height));
630+     for  (const  auto & in : tx.vin ) {
631+         //  Can not be FINAL for locktime to work
632+         assert (in.nSequence  != CTxIn::SEQUENCE_FINAL);
633+         //  May be MAX NONFINAL to disable BIP68
634+         if  (in.nSequence  == CTxIn::MAX_SEQUENCE_NONFINAL) continue ;
635+         //  The wallet does not support any other sequence-use right now.
636+         assert (false );
624637    }
625-     assert (locktime < LOCKTIME_THRESHOLD);
626-     return  locktime;
627638}
628639
629640static  bool  CreateTransactionInternal (
@@ -641,7 +652,6 @@ static bool CreateTransactionInternal(
641652    AssertLockHeld (wallet.cs_wallet );
642653
643654    CMutableTransaction txNew; //  The resulting transaction that we make
644-     txNew.nLockTime  = GetLocktimeForNewTransaction (wallet.chain (), wallet.GetLastBlockHash (), wallet.GetLastBlockHeight ());
645655
646656    CoinSelectionParams coin_selection_params; //  Parameters for coin selection, init with dummy
647657    coin_selection_params.m_avoid_partial_spends  = coin_control.m_avoid_partial_spends ;
@@ -811,12 +821,13 @@ static bool CreateTransactionInternal(
811821        }
812822    };
813823
814-     //  Note how the  sequence number is set to non-maxint so that
815-     //  the nLockTime set above actually  works.
816-     const  uint32_t  nSequence =  CTxIn::SEQUENCE_FINAL - 1 ;
824+     //  The  sequence number is set to non-maxint so that DiscourageFeeSniping 
825+     //  works.
826+     const  uint32_t  nSequence{ CTxIn::SEQUENCE_FINAL - 1 } ;
817827    for  (const  auto & coin : setCoins) {
818828        txNew.vin .push_back (CTxIn (coin.outpoint , CScript (), nSequence));
819829    }
830+     DiscourageFeeSniping (txNew, wallet.chain (), wallet.GetLastBlockHash (), wallet.GetLastBlockHeight ());
820831
821832    //  Fill in final vin and shuffle/sort it
822833    if  (sort_bip69) { std::sort (txNew.vin .begin (), txNew.vin .end (), CompareInputBIP69 ()); }
0 commit comments