aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorSamuel Dobson <dobsonsa68@gmail.com>2021-09-23 00:18:39 +1200
committerSamuel Dobson <dobsonsa68@gmail.com>2021-09-25 23:50:06 +1200
commitf13fc16295c19a156f2974d2d73fba56d52fc161 (patch)
treec50e2ebcaa6d7699830dae95e917eb1ac6601a74 /src/wallet
parentc52789365e5dbcb25aa5f1775de4d318da79e5a7 (diff)
Allow lockunspent to store the lock in the wallet DB
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/rpcwallet.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 7d194ae262..d75673d344 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2137,8 +2137,9 @@ static RPCHelpMan lockunspent()
"If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
"A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
"Manually selected coins are automatically unlocked.\n"
- "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
- "is always cleared (by virtue of process exit) when a node stops or fails.\n"
+ "Locks are stored in memory only, unless persistent=true, in which case they will be written to the\n"
+ "wallet database and loaded on node start. Unwritten (persistent=false) locks are always cleared\n"
+ "(by virtue of process exit) when a node stops or fails. Unlocking will clear both persistent and not.\n"
"Also see the listunspent call\n",
{
{"unlock", RPCArg::Type::BOOL, RPCArg::Optional::NO, "Whether to unlock (true) or lock (false) the specified transactions"},
@@ -2152,6 +2153,7 @@ static RPCHelpMan lockunspent()
},
},
},
+ {"persistent", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether to write/erase this lock in the wallet database, or keep the change in memory only. Ignored for unlocking."},
},
RPCResult{
RPCResult::Type::BOOL, "", "Whether the command was successful or not"
@@ -2165,6 +2167,8 @@ static RPCHelpMan lockunspent()
+ HelpExampleCli("listlockunspent", "") +
"\nUnlock the transaction again\n"
+ HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
+ "\nLock the transaction persistently in the wallet database\n"
+ + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\" true") +
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
},
@@ -2183,9 +2187,13 @@ static RPCHelpMan lockunspent()
bool fUnlock = request.params[0].get_bool();
+ const bool persistent{request.params[2].isNull() ? false : request.params[2].get_bool()};
+
if (request.params[1].isNull()) {
- if (fUnlock)
- pwallet->UnlockAllCoins();
+ if (fUnlock) {
+ if (!pwallet->UnlockAllCoins())
+ throw JSONRPCError(RPC_WALLET_ERROR, "Unlocking coins failed");
+ }
return true;
}
@@ -2236,17 +2244,24 @@ static RPCHelpMan lockunspent()
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected locked output");
}
- if (!fUnlock && is_locked) {
+ if (!fUnlock && is_locked && !persistent) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output already locked");
}
outputs.push_back(outpt);
}
+ std::unique_ptr<WalletBatch> batch = nullptr;
+ // Unlock is always persistent
+ if (fUnlock || persistent) batch = std::make_unique<WalletBatch>(pwallet->GetDatabase());
+
// Atomically set (un)locked status for the outputs.
for (const COutPoint& outpt : outputs) {
- if (fUnlock) pwallet->UnlockCoin(outpt);
- else pwallet->LockCoin(outpt);
+ if (fUnlock) {
+ if (!pwallet->UnlockCoin(outpt, batch.get())) throw JSONRPCError(RPC_WALLET_ERROR, "Unlocking coin failed");
+ } else {
+ if (!pwallet->LockCoin(outpt, batch.get())) throw JSONRPCError(RPC_WALLET_ERROR, "Locking coin failed");
+ }
}
return true;