@ -1221,8 +1221,17 @@ struct command_result *param_psbt(struct command *cmd,
json_tok_full ( buffer , tok ) ) ;
json_tok_full ( buffer , tok ) ) ;
}
}
static bool in_only_inputs ( const u32 * only_inputs , u32 this )
{
for ( size_t i = 0 ; i < tal_count ( only_inputs ) ; i + + )
if ( only_inputs [ i ] = = this )
return true ;
return false ;
}
static struct command_result * match_psbt_inputs_to_utxos ( struct command * cmd ,
static struct command_result * match_psbt_inputs_to_utxos ( struct command * cmd ,
struct wally_psbt * psbt ,
struct wally_psbt * psbt ,
const u32 * only_inputs ,
struct utxo * * * utxos )
struct utxo * * * utxos )
{
{
* utxos = tal_arr ( cmd , struct utxo * , 0 ) ;
* utxos = tal_arr ( cmd , struct utxo * , 0 ) ;
@ -1230,11 +1239,21 @@ static struct command_result *match_psbt_inputs_to_utxos(struct command *cmd,
struct utxo * utxo ;
struct utxo * utxo ;
struct bitcoin_txid txid ;
struct bitcoin_txid txid ;
if ( only_inputs & & ! in_only_inputs ( only_inputs , i ) )
continue ;
wally_tx_input_get_txid ( & psbt - > tx - > inputs [ i ] , & txid ) ;
wally_tx_input_get_txid ( & psbt - > tx - > inputs [ i ] , & txid ) ;
utxo = wallet_utxo_get ( * utxos , cmd - > ld - > wallet ,
utxo = wallet_utxo_get ( * utxos , cmd - > ld - > wallet ,
& txid , psbt - > tx - > inputs [ i ] . index ) ;
& txid , psbt - > tx - > inputs [ i ] . index ) ;
if ( ! utxo )
if ( ! utxo ) {
if ( only_inputs )
return command_fail ( cmd , LIGHTNINGD ,
" Aborting PSBT signing. UTXO %s:%u is unknown (and specified by signonly) " ,
type_to_string ( tmpctx , struct bitcoin_txid ,
& txid ) ,
psbt - > tx - > inputs [ i ] . index ) ;
continue ;
continue ;
}
/* Oops we haven't reserved this utxo yet! */
/* Oops we haven't reserved this utxo yet! */
if ( ! is_reserved ( utxo , get_block_height ( cmd - > ld - > topology ) ) )
if ( ! is_reserved ( utxo , get_block_height ( cmd - > ld - > topology ) ) )
@ -1249,6 +1268,32 @@ static struct command_result *match_psbt_inputs_to_utxos(struct command *cmd,
return NULL ;
return NULL ;
}
}
static struct command_result * param_input_numbers ( struct command * cmd ,
const char * name ,
const char * buffer ,
const jsmntok_t * tok ,
u32 * * input_nums )
{
struct command_result * res ;
const jsmntok_t * arr , * t ;
size_t i ;
res = param_array ( cmd , name , buffer , tok , & arr ) ;
if ( res )
return res ;
* input_nums = tal_arr ( cmd , u32 , arr - > size ) ;
json_for_each_arr ( i , t , arr ) {
u32 * num ;
res = param_number ( cmd , name , buffer , t , & num ) ;
if ( res )
return res ;
( * input_nums ) [ i ] = * num ;
tal_free ( num ) ;
}
return NULL ;
}
static struct command_result * json_signpsbt ( struct command * cmd ,
static struct command_result * json_signpsbt ( struct command * cmd ,
const char * buffer ,
const char * buffer ,
const jsmntok_t * obj UNNEEDED ,
const jsmntok_t * obj UNNEEDED ,
@ -1258,17 +1303,27 @@ static struct command_result *json_signpsbt(struct command *cmd,
struct json_stream * response ;
struct json_stream * response ;
struct wally_psbt * psbt , * signed_psbt ;
struct wally_psbt * psbt , * signed_psbt ;
struct utxo * * utxos ;
struct utxo * * utxos ;
u32 * input_nums ;
if ( ! param ( cmd , buffer , params ,
if ( ! param ( cmd , buffer , params ,
p_req ( " psbt " , param_psbt , & psbt ) ,
p_req ( " psbt " , param_psbt , & psbt ) ,
p_opt ( " signonly " , param_input_numbers , & input_nums ) ,
NULL ) )
NULL ) )
return command_param_failed ( ) ;
return command_param_failed ( ) ;
/* Sanity check! */
for ( size_t i = 0 ; i < tal_count ( input_nums ) ; i + + ) {
if ( input_nums [ i ] > = psbt - > num_inputs )
return command_fail ( cmd , JSONRPC2_INVALID_PARAMS ,
" signonly[%zu]: %u out of range " ,
i , input_nums [ i ] ) ;
}
/* We have to find/locate the utxos that are ours on this PSBT,
/* We have to find/locate the utxos that are ours on this PSBT,
* so that the HSM knows how / what to sign for ( it ' s possible some of
* so that the HSM knows how / what to sign for ( it ' s possible some of
* our utxos require more complicated data to sign for e . g .
* our utxos require more complicated data to sign for e . g .
* closeinfo outputs */
* closeinfo outputs */
res = match_psbt_inputs_to_utxos ( cmd , psbt , & utxos ) ;
res = match_psbt_inputs_to_utxos ( cmd , psbt , input_nums , & utxos ) ;
if ( res )
if ( res )
return res ;
return res ;
@ -1334,7 +1389,7 @@ static struct command_result *json_sendpsbt(struct command *cmd,
/* We have to find/locate the utxos that are ours on this PSBT,
/* We have to find/locate the utxos that are ours on this PSBT,
* so that we know who to mark as used .
* so that we know who to mark as used .
*/
*/
res = match_psbt_inputs_to_utxos ( cmd , psbt , & utxos ) ;
res = match_psbt_inputs_to_utxos ( cmd , psbt , NULL , & utxos ) ;
if ( res )
if ( res )
return res ;
return res ;