mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 15:09:59 +01:00
@@ -2447,12 +2447,15 @@ UniValue lockunspent(const JSONRPCRequest& request)
|
||||
|
||||
RPCTypeCheckArgument(request.params[1], UniValue::VARR);
|
||||
|
||||
UniValue outputs = request.params[1].get_array();
|
||||
for (unsigned int idx = 0; idx < outputs.size(); idx++) {
|
||||
const UniValue& output = outputs[idx];
|
||||
if (!output.isObject())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
|
||||
const UniValue& o = output.get_obj();
|
||||
const UniValue& output_params = request.params[1];
|
||||
|
||||
// Create and validate the COutPoints first.
|
||||
|
||||
std::vector<COutPoint> outputs;
|
||||
outputs.reserve(output_params.size());
|
||||
|
||||
for (unsigned int idx = 0; idx < output_params.size(); idx++) {
|
||||
const UniValue& o = output_params[idx].get_obj();
|
||||
|
||||
RPCTypeCheckObj(o,
|
||||
{
|
||||
@@ -2460,20 +2463,50 @@ UniValue lockunspent(const JSONRPCRequest& request)
|
||||
{"vout", UniValueType(UniValue::VNUM)},
|
||||
});
|
||||
|
||||
std::string txid = find_value(o, "txid").get_str();
|
||||
if (!IsHex(txid))
|
||||
const std::string& txid = find_value(o, "txid").get_str();
|
||||
if (!IsHex(txid)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
|
||||
}
|
||||
|
||||
int nOutput = find_value(o, "vout").get_int();
|
||||
if (nOutput < 0)
|
||||
const int nOutput = find_value(o, "vout").get_int();
|
||||
if (nOutput < 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
|
||||
}
|
||||
|
||||
COutPoint outpt(uint256S(txid), nOutput);
|
||||
const COutPoint outpt(uint256S(txid), nOutput);
|
||||
|
||||
if (fUnlock)
|
||||
pwallet->UnlockCoin(outpt);
|
||||
else
|
||||
pwallet->LockCoin(outpt);
|
||||
const auto it = pwallet->mapWallet.find(outpt.hash);
|
||||
if (it == pwallet->mapWallet.end()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, unknown transaction");
|
||||
}
|
||||
|
||||
const CWalletTx& trans = it->second;
|
||||
|
||||
if (outpt.n >= trans.tx->vout.size()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout index out of bounds");
|
||||
}
|
||||
|
||||
if (pwallet->IsSpent(outpt.hash, outpt.n)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected unspent output");
|
||||
}
|
||||
|
||||
const bool is_locked = pwallet->IsLockedCoin(outpt.hash, outpt.n);
|
||||
|
||||
if (fUnlock && !is_locked) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected locked output");
|
||||
}
|
||||
|
||||
if (!fUnlock && is_locked) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output already locked");
|
||||
}
|
||||
|
||||
outputs.push_back(outpt);
|
||||
}
|
||||
|
||||
// Atomically set (un)locked status for the outputs.
|
||||
for (const COutPoint& outpt : outputs) {
|
||||
if (fUnlock) pwallet->UnlockCoin(outpt);
|
||||
else pwallet->LockCoin(outpt);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user