Keep a list of notes we are spending and must lock which is different from the list of all notes we might spend
This commit is contained in:
@@ -234,14 +234,8 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds, no unspent notes found for zaddr from address.");
|
||||
}
|
||||
|
||||
// Now that find_unspent_notes() has run, we now know which
|
||||
// notes need to be locked
|
||||
|
||||
// Lock UTXOs
|
||||
lock_utxos();
|
||||
// Lock shielded input notes
|
||||
lock_notes();
|
||||
LogPrint("zrpc", "%s: z_sendmany input notes locked\n", getId());
|
||||
|
||||
CAmount t_inputs_total = 0;
|
||||
for (SendManyInputUTXO & t : t_inputs_) {
|
||||
@@ -412,7 +406,14 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
std::vector<SaplingOutPoint> ops;
|
||||
std::vector<SaplingNote> notes;
|
||||
CAmount sum = 0;
|
||||
for (auto t : z_sapling_inputs_) {
|
||||
|
||||
//NOTE: z_sapling_inputs_ is a list of all potential notes to spend
|
||||
// saplingNoteInputs_ is a list of notes we will actually spend
|
||||
// and need to lock. It is a subset of z_sapling_inputs_
|
||||
for (const auto t : z_sapling_inputs_) {
|
||||
// keep track of notes to lock later on in lock_notes()
|
||||
saplingNoteInputs_.emplace_back(t.op, t.note, t.note.value() );
|
||||
|
||||
ops.push_back(t.op);
|
||||
notes.push_back(t.note);
|
||||
sum += t.note.value();
|
||||
@@ -421,6 +422,9 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
}
|
||||
}
|
||||
|
||||
// Lock shielded input notes (zins) stored in saplingNoteInputs
|
||||
lock_notes();
|
||||
|
||||
// Fetch Sapling anchor and witnesses
|
||||
//LogPrintf("%s: Gathering anchors and witnesses\n", __FUNCTION__);
|
||||
uint256 anchor;
|
||||
@@ -665,9 +669,10 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() {
|
||||
pwalletMain->GetFilteredNotes(saplingEntries, fromaddress_, mindepth_);
|
||||
}
|
||||
|
||||
// store sapling inputs so we can correctly lock and unlock them
|
||||
|
||||
for (auto entry : saplingEntries) {
|
||||
z_sapling_inputs_.push_back(entry);
|
||||
|
||||
std::string data(entry.memo.begin(), entry.memo.end());
|
||||
LogPrint("zrpcunsafe", "%s: found unspent Sapling note (txid=%s, vShieldedSpend=%d, amount=%s, memo=%s)\n",
|
||||
getId(),
|
||||
@@ -805,17 +810,17 @@ void AsyncRPCOperation_sendmany::unlock_utxos() {
|
||||
// Lock input notes
|
||||
void AsyncRPCOperation_sendmany::lock_notes() {
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
fprintf(stderr,"%s: found %lu notes to lock\n", __func__, z_sapling_inputs_.size() );
|
||||
for (auto note : z_sapling_inputs_) {
|
||||
pwalletMain->LockNote(note.op);
|
||||
fprintf(stderr,"%s: found %lu notes to lock\n", __func__, saplingNoteInputs_.size() );
|
||||
for (auto note : saplingNoteInputs_) {
|
||||
pwalletMain->LockNote(std::get<0>(note));
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock input notes
|
||||
void AsyncRPCOperation_sendmany::unlock_notes() {
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
fprintf(stderr,"%s: found %lu notes to unlock\n", __func__, z_sapling_inputs_.size() );
|
||||
for (auto note : z_sapling_inputs_) {
|
||||
pwalletMain->UnlockNote(note.op);
|
||||
fprintf(stderr,"%s: found %lu notes to unlock\n", __func__, saplingNoteInputs_.size() );
|
||||
for (auto note : saplingNoteInputs_) {
|
||||
pwalletMain->UnlockNote(std::get<0>(note));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,9 @@ typedef std::tuple<std::string, CAmount, std::string> SendManyRecipient;
|
||||
// Input UTXO is a tuple (quadruple) of txid, vout, amount, coinbase)
|
||||
typedef std::tuple<uint256, int, CAmount, bool, CTxDestination> SendManyInputUTXO;
|
||||
|
||||
// Input note is a tuple of output, note, amount
|
||||
typedef std::tuple<SaplingOutPoint, SaplingNote, CAmount> SendManyInputSaplingNote;
|
||||
|
||||
class AsyncRPCOperation_sendmany : public AsyncRPCOperation {
|
||||
public:
|
||||
AsyncRPCOperation_sendmany(
|
||||
@@ -93,6 +96,7 @@ private:
|
||||
std::vector<SendManyRecipient> z_outputs_;
|
||||
std::vector<SendManyInputUTXO> t_inputs_;
|
||||
std::vector<SaplingNoteEntry> z_sapling_inputs_;
|
||||
std::vector<SendManyInputSaplingNote> saplingNoteInputs_;
|
||||
|
||||
TransactionBuilder builder_;
|
||||
CTransaction tx_;
|
||||
|
||||
Reference in New Issue
Block a user