Skip to content

Commit

Permalink
shuffle selected coins before transaction finalization
Browse files Browse the repository at this point in the history
  • Loading branch information
instagibbs committed Mar 21, 2018
1 parent 1ec1602 commit 2fb9c1e
Showing 1 changed file with 23 additions and 14 deletions.
37 changes: 23 additions & 14 deletions src/wallet/wallet.cpp
Expand Up @@ -2889,20 +2889,11 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
nChangePosInOut = -1;
}

// Fill vin
// Dummy fill vin for maximum size estimation
//
// Note how the sequence number is set to non-maxint so that
// the nLockTime set above actually works.
//
// BIP125 defines opt-in RBF as any nSequence < maxint-1, so
// we use the highest possible value in that range (maxint-2)
// to avoid conflicting with other possible uses of nSequence,
// and in the spirit of "smallest possible change from prior
// behavior."
const uint32_t nSequence = coin_control.signalRbf ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
for (const auto& coin : setCoins)
txNew.vin.push_back(CTxIn(coin.outpoint,CScript(),
nSequence));
for (const auto& coin : setCoins) {
txNew.vin.push_back(CTxIn(coin.outpoint,CScript()));
}

nBytes = CalculateMaximumSignedTxSize(txNew, this);
if (nBytes < 0) {
Expand Down Expand Up @@ -2992,11 +2983,29 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac

if (nChangePosInOut == -1) reservekey.ReturnKey(); // Return any reserved key if we don't have change

// Shuffle selected coins and fill in final vin
txNew.vin.clear();
std::vector<CInputCoin> selected_coins(setCoins.begin(), setCoins.end());
std::shuffle(selected_coins.begin(), selected_coins.end(), FastRandomContext());

// Note how the sequence number is set to non-maxint so that
// the nLockTime set above actually works.
//
// BIP125 defines opt-in RBF as any nSequence < maxint-1, so
// we use the highest possible value in that range (maxint-2)
// to avoid conflicting with other possible uses of nSequence,
// and in the spirit of "smallest possible change from prior
// behavior."
const uint32_t nSequence = coin_control.signalRbf ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
for (const auto& coin : selected_coins) {
txNew.vin.push_back(CTxIn(coin.outpoint, CScript(), nSequence));
}

if (sign)
{
CTransaction txNewConst(txNew);
int nIn = 0;
for (const auto& coin : setCoins)
for (const auto& coin : selected_coins)
{
const CScript& scriptPubKey = coin.txout.scriptPubKey;
SignatureData sigdata;
Expand Down

0 comments on commit 2fb9c1e

Please sign in to comment.