aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Todd <pete@petertodd.org>2013-08-25 14:13:25 -0400
committerPeter Todd <pete@petertodd.org>2014-10-13 08:18:06 -0400
commitba7fcc8de06602576ab6a5911879d3d8df80d36a (patch)
treec6150c3300576cd903c94ca0c5ef05ba25c2e95f
parentfe36e031cde8cd0e1cb446d761f229c088a0403f (diff)
Discourage fee sniping with nLockTime
-rw-r--r--src/wallet.cpp28
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;