@@ -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