Browse Source

Merge pull request #2340

ba7fcc8 Discourage fee sniping with nLockTime (Peter Todd)
0.13
Wladimir J. van der Laan 10 years ago
parent
commit
811c71d287
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 28
      src/wallet.cpp

28
src/wallet.cpp

@ -1382,6 +1382,28 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
wtxNew.BindWallet(this); wtxNew.BindWallet(this);
CMutableTransaction txNew; 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); LOCK2(cs_main, cs_wallet);
{ {
@ -1475,8 +1497,12 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
reservekey.ReturnKey(); reservekey.ReturnKey();
// Fill vin // 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) 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 // Sign
int nIn = 0; int nIn = 0;

Loading…
Cancel
Save