Skip to content

Commit 6f405a1

Browse files
committed
Shuffle inputs and outputs after joining psbts
1 parent 7821821 commit 6f405a1

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

doc/release-notes-16512.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
RPC changes
2+
-----------
3+
The RPC `joinpsbts` will shuffle the order of the inputs and outputs of the resulting joined psbt.
4+
Previously inputs and outputs were added in the order that the PSBTs were provided which makes correlating inputs to outputs extremely easy.

src/rpc/rawtransaction.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <policy/rbf.h>
1818
#include <primitives/transaction.h>
1919
#include <psbt.h>
20+
#include <random.h>
2021
#include <rpc/rawtransaction_util.h>
2122
#include <rpc/server.h>
2223
#include <rpc/util.h>
@@ -1604,8 +1605,30 @@ UniValue joinpsbts(const JSONRPCRequest& request)
16041605
merged_psbt.unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
16051606
}
16061607

1608+
// Generate list of shuffled indices for shuffling inputs and outputs of the merged PSBT
1609+
std::vector<int> input_indices(merged_psbt.inputs.size());
1610+
std::iota(input_indices.begin(), input_indices.end(), 0);
1611+
std::vector<int> output_indices(merged_psbt.outputs.size());
1612+
std::iota(output_indices.begin(), output_indices.end(), 0);
1613+
1614+
// Shuffle input and output indicies lists
1615+
Shuffle(input_indices.begin(), input_indices.end(), FastRandomContext());
1616+
Shuffle(output_indices.begin(), output_indices.end(), FastRandomContext());
1617+
1618+
PartiallySignedTransaction shuffled_psbt;
1619+
shuffled_psbt.tx = CMutableTransaction();
1620+
shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion;
1621+
shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
1622+
for (int i : input_indices) {
1623+
shuffled_psbt.AddInput(merged_psbt.tx->vin[i], merged_psbt.inputs[i]);
1624+
}
1625+
for (int i : output_indices) {
1626+
shuffled_psbt.AddOutput(merged_psbt.tx->vout[i], merged_psbt.outputs[i]);
1627+
}
1628+
shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(), merged_psbt.unknown.end());
1629+
16071630
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
1608-
ssTx << merged_psbt;
1631+
ssTx << shuffled_psbt;
16091632
return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size());
16101633
}
16111634

0 commit comments

Comments
 (0)