@ -2531,12 +2531,15 @@ UniValue lockunspent(const JSONRPCRequest& request)
@@ -2531,12 +2531,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 ,
{
@ -2544,20 +2547,50 @@ UniValue lockunspent(const JSONRPCRequest& request)
@@ -2544,20 +2547,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 ;