diff options
author | Peter Todd <pete@petertodd.org> | 2013-08-25 14:13:25 -0400 |
---|---|---|
committer | Peter Todd <pete@petertodd.org> | 2014-10-13 08:18:06 -0400 |
commit | ba7fcc8de06602576ab6a5911879d3d8df80d36a (patch) | |
tree | c6150c3300576cd903c94ca0c5ef05ba25c2e95f | |
parent | fe36e031cde8cd0e1cb446d761f229c088a0403f (diff) |
Discourage fee sniping with nLockTime
-rw-r--r-- | src/wallet.cpp | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/wallet.cpp b/src/wallet.cpp index 026c53aa2e..a64d27a941 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1347,6 +1347,28 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend, wtxNew.BindWallet(this); CMutableTransaction txNew; + // Discourage fee sniping. + // + // However because of a off-by-one-error in previous versions we need to + // neuter it by setting nLockTime to at least one less than nBestHeight. + // Secondly currently propagation of transactions created for block heights + // corresponding to blocks that were just mined may be iffy - transactions + // aren't re-accepted into the mempool - we additionally neuter the code by + // going ten blocks back. Doesn't yet do anything for sniping, but does act + // to shake out wallet bugs like not showing nLockTime'd transactions at + // all. + txNew.nLockTime = std::max(0, chainActive.Height() - 10); + + // Secondly occasionally randomly pick a nLockTime even further back, so + // that transactions that are delayed after signing for whatever reason, + // e.g. high-latency mix networks and some CoinJoin implementations, have + // better privacy. + if (GetRandInt(10) == 0) + txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100)); + + assert(txNew.nLockTime <= (unsigned int)chainActive.Height()); + assert(txNew.nLockTime < LOCKTIME_THRESHOLD); + { LOCK2(cs_main, cs_wallet); { @@ -1440,8 +1462,12 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend, reservekey.ReturnKey(); // Fill vin + // + // Note how the sequence number is set to max()-1 so that the + // nLockTime set above actually works. BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) - txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second)); + txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), + std::numeric_limits<unsigned int>::max()-1)); // Sign int nIn = 0; |