aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2014-12-19 18:54:06 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2014-12-19 18:54:51 +0100
commit811c71d287eb5a11b82af223774563036cb3fedd (patch)
tree6338ed23541366a9436c42213ed587c9b3e6d763
parent84857e87e42e412336ea60d0f8544c1679bab827 (diff)
parentba7fcc8de06602576ab6a5911879d3d8df80d36a (diff)
Merge pull request #2340
ba7fcc8 Discourage fee sniping with nLockTime (Peter Todd)
-rw-r--r--src/wallet.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 32a64daac0..94e6ccf99e 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -1382,6 +1382,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);
{
@@ -1475,8 +1497,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;