|
19 | 19 | #include <policy/rbf.h> |
20 | 20 | #include <primitives/transaction.h> |
21 | 21 | #include <psbt.h> |
| 22 | +#include <random.h> |
22 | 23 | #include <rpc/rawtransaction.h> |
23 | 24 | #include <rpc/server.h> |
24 | 25 | #include <rpc/util.h> |
@@ -1861,8 +1862,30 @@ UniValue joinpsbts(const JSONRPCRequest& request) |
1861 | 1862 | merged_psbt.unknown.insert(psbt.unknown.begin(), psbt.unknown.end()); |
1862 | 1863 | } |
1863 | 1864 |
|
| 1865 | + // Generate list of shuffled indices for shuffling inputs and outputs of the merged PSBT |
| 1866 | + std::vector<int> input_indices(merged_psbt.inputs.size()); |
| 1867 | + std::iota(input_indices.begin(), input_indices.end(), 0); |
| 1868 | + std::vector<int> output_indices(merged_psbt.outputs.size()); |
| 1869 | + std::iota(output_indices.begin(), output_indices.end(), 0); |
| 1870 | + |
| 1871 | + // Shuffle input and output indicies lists |
| 1872 | + Shuffle(input_indices.begin(), input_indices.end(), FastRandomContext()); |
| 1873 | + Shuffle(output_indices.begin(), output_indices.end(), FastRandomContext()); |
| 1874 | + |
| 1875 | + PartiallySignedTransaction shuffled_psbt; |
| 1876 | + shuffled_psbt.tx = CMutableTransaction(); |
| 1877 | + shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion; |
| 1878 | + shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime; |
| 1879 | + for (int i : input_indices) { |
| 1880 | + shuffled_psbt.AddInput(merged_psbt.tx->vin[i], merged_psbt.inputs[i]); |
| 1881 | + } |
| 1882 | + for (int i : output_indices) { |
| 1883 | + shuffled_psbt.AddOutput(merged_psbt.tx->vout[i], merged_psbt.outputs[i]); |
| 1884 | + } |
| 1885 | + shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(), merged_psbt.unknown.end()); |
| 1886 | + |
1864 | 1887 | CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); |
1865 | | - ssTx << merged_psbt; |
| 1888 | + ssTx << shuffled_psbt; |
1866 | 1889 | return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size()); |
1867 | 1890 | } |
1868 | 1891 |
|
|
0 commit comments