|
|
|
@ -17,6 +17,7 @@
|
|
|
|
|
#include <policy/rbf.h>
|
|
|
|
|
#include <primitives/transaction.h>
|
|
|
|
|
#include <psbt.h>
|
|
|
|
|
#include <random.h>
|
|
|
|
|
#include <rpc/rawtransaction_util.h>
|
|
|
|
|
#include <rpc/server.h>
|
|
|
|
|
#include <rpc/util.h>
|
|
|
|
@ -1604,8 +1605,30 @@ UniValue joinpsbts(const JSONRPCRequest& request)
|
|
|
|
|
merged_psbt.unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate list of shuffled indices for shuffling inputs and outputs of the merged PSBT
|
|
|
|
|
std::vector<int> input_indices(merged_psbt.inputs.size());
|
|
|
|
|
std::iota(input_indices.begin(), input_indices.end(), 0);
|
|
|
|
|
std::vector<int> output_indices(merged_psbt.outputs.size());
|
|
|
|
|
std::iota(output_indices.begin(), output_indices.end(), 0);
|
|
|
|
|
|
|
|
|
|
// Shuffle input and output indicies lists
|
|
|
|
|
Shuffle(input_indices.begin(), input_indices.end(), FastRandomContext());
|
|
|
|
|
Shuffle(output_indices.begin(), output_indices.end(), FastRandomContext());
|
|
|
|
|
|
|
|
|
|
PartiallySignedTransaction shuffled_psbt;
|
|
|
|
|
shuffled_psbt.tx = CMutableTransaction();
|
|
|
|
|
shuffled_psbt.tx->nVersion = merged_psbt.tx->nVersion;
|
|
|
|
|
shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
|
|
|
|
|
for (int i : input_indices) {
|
|
|
|
|
shuffled_psbt.AddInput(merged_psbt.tx->vin[i], merged_psbt.inputs[i]);
|
|
|
|
|
}
|
|
|
|
|
for (int i : output_indices) {
|
|
|
|
|
shuffled_psbt.AddOutput(merged_psbt.tx->vout[i], merged_psbt.outputs[i]);
|
|
|
|
|
}
|
|
|
|
|
shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(), merged_psbt.unknown.end());
|
|
|
|
|
|
|
|
|
|
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
|
|
|
|
ssTx << merged_psbt;
|
|
|
|
|
ssTx << shuffled_psbt;
|
|
|
|
|
return EncodeBase64((unsigned char*)ssTx.data(), ssTx.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|