aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Sanders <gsanders87@gmail.com>2018-03-15 16:18:48 -0400
committerGregory Sanders <gsanders87@gmail.com>2018-03-21 15:03:24 -0400
commit2fb9c1e6681370478e24a19172ed6d78d95d50d3 (patch)
treecea38f2e51b940f75151a24ab77f9d12af70940f
parent1ec1602a4549f6b68586cead8eff701bceb624f5 (diff)
shuffle selected coins before transaction finalization
-rw-r--r--src/wallet/wallet.cpp37
1 files changed, 23 insertions, 14 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 3f1a2c1990..5472062a20 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -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;