shuffle selected coins before transaction finalization

This commit is contained in:
Gregory Sanders 2018-03-15 16:18:48 -04:00
parent 1ec1602a45
commit 2fb9c1e668
1 changed files with 23 additions and 14 deletions

View File

@ -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) {
@ -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;