Skip to content

Commit e958ff9

Browse files
committed
wallet: Avoid use of Chain::Lock in CWallet::CreateTransaction
This is a step toward removing the Chain::Lock class and reducing cs_main locking. This change only affects behavior in the case where wallet last block processed falls behind the chain tip, where it may set a different lock time.
1 parent c0d07dc commit e958ff9

File tree

1 file changed

+8
-10
lines changed

1 file changed

+8
-10
lines changed

src/wallet/wallet.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,13 +2620,15 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
26202620
return true;
26212621
}
26222622

2623-
static bool IsCurrentForAntiFeeSniping(interfaces::Chain& chain, interfaces::Chain::Lock& locked_chain)
2623+
static bool IsCurrentForAntiFeeSniping(interfaces::Chain& chain, const uint256& block_hash)
26242624
{
26252625
if (chain.isInitialBlockDownload()) {
26262626
return false;
26272627
}
26282628
constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60; // in seconds
2629-
if (locked_chain.getBlockTime(*locked_chain.getHeight()) < (GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
2629+
int64_t block_time;
2630+
CHECK_NONFATAL(chain.findBlock(block_hash, FoundBlock().time(block_time)));
2631+
if (block_time < (GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
26302632
return false;
26312633
}
26322634
return true;
@@ -2636,9 +2638,8 @@ static bool IsCurrentForAntiFeeSniping(interfaces::Chain& chain, interfaces::Cha
26362638
* Return a height-based locktime for new transactions (uses the height of the
26372639
* current chain tip unless we are not synced with the current chain
26382640
*/
2639-
static uint32_t GetLocktimeForNewTransaction(interfaces::Chain& chain, interfaces::Chain::Lock& locked_chain)
2641+
static uint32_t GetLocktimeForNewTransaction(interfaces::Chain& chain, const uint256& block_hash, int block_height)
26402642
{
2641-
uint32_t const height = locked_chain.getHeight().get_value_or(-1);
26422643
uint32_t locktime;
26432644
// Discourage fee sniping.
26442645
//
@@ -2660,8 +2661,8 @@ static uint32_t GetLocktimeForNewTransaction(interfaces::Chain& chain, interface
26602661
// enough, that fee sniping isn't a problem yet, but by implementing a fix
26612662
// now we ensure code won't be written that makes assumptions about
26622663
// nLockTime that preclude a fix later.
2663-
if (IsCurrentForAntiFeeSniping(chain, locked_chain)) {
2664-
locktime = height;
2664+
if (IsCurrentForAntiFeeSniping(chain, block_hash)) {
2665+
locktime = block_height;
26652666

26662667
// Secondly occasionally randomly pick a nLockTime even further back, so
26672668
// that transactions that are delayed after signing for whatever reason,
@@ -2675,7 +2676,6 @@ static uint32_t GetLocktimeForNewTransaction(interfaces::Chain& chain, interface
26752676
// unique "nLockTime fingerprint", set nLockTime to a constant.
26762677
locktime = 0;
26772678
}
2678-
assert(locktime <= height);
26792679
assert(locktime < LOCKTIME_THRESHOLD);
26802680
return locktime;
26812681
}
@@ -2735,16 +2735,14 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
27352735
}
27362736

27372737
CMutableTransaction txNew;
2738-
2739-
txNew.nLockTime = GetLocktimeForNewTransaction(chain(), locked_chain);
2740-
27412738
FeeCalculation feeCalc;
27422739
CAmount nFeeNeeded;
27432740
int nBytes;
27442741
{
27452742
std::set<CInputCoin> setCoins;
27462743
auto locked_chain = chain().lock();
27472744
LOCK(cs_wallet);
2745+
txNew.nLockTime = GetLocktimeForNewTransaction(chain(), GetLastBlockHash(), GetLastBlockHeight());
27482746
{
27492747
std::vector<COutput> vAvailableCoins;
27502748
AvailableCoins(*locked_chain, vAvailableCoins, true, &coin_control, 1, MAX_MONEY, MAX_MONEY, 0);

0 commit comments

Comments
 (0)