@ -1339,6 +1339,43 @@ static const struct json_command getinfo_command = {
} ;
AUTODATA ( json_command , & getinfo_command ) ;
static struct command_result * param_channel_or_all ( struct command * cmd ,
const char * name ,
const char * buffer ,
const jsmntok_t * tok ,
struct channel * * channel )
{
struct command_result * res ;
struct peer * peer ;
/* early return the easy case */
if ( json_tok_streq ( buffer , tok , " all " ) ) {
* channel = NULL ;
return NULL ;
}
/* Find channel by peer_id */
peer = peer_from_json ( cmd - > ld , buffer , tok ) ;
if ( peer ) {
* channel = peer_active_channel ( peer ) ;
if ( ! * channel )
return command_fail ( cmd , LIGHTNINGD ,
" Could not find active channel of peer with that id " ) ;
return NULL ;
/* Find channel by id or scid */
} else {
res = command_find_channel ( cmd , buffer , tok , channel ) ;
if ( res )
return res ;
/* check channel is found and in valid state */
if ( ! * channel )
return command_fail ( cmd , LIGHTNINGD ,
" Could not find channel with that id " ) ;
return NULL ;
}
}
/* Fee base is a u32, but it's convenient to let them specify it using
* msat etc . suffix . */
static struct command_result * param_msat_u32 ( struct command * cmd ,
@ -1367,22 +1404,47 @@ static struct command_result *param_msat_u32(struct command *cmd,
return NULL ;
}
static void set_channel_fees ( struct command * cmd , struct channel * channel ,
u32 base , u32 ppm , struct json_stream * response )
{
struct channel_id cid ;
/* set new values */
channel - > feerate_base = base ;
channel - > feerate_ppm = ppm ;
/* tell channeld to make a send_channel_update */
if ( channel - > owner & & streq ( channel - > owner - > name , " lightning_channeld " ) )
subd_send_msg ( channel - > owner ,
take ( towire_channel_specific_feerates ( NULL , base , ppm ) ) ) ;
/* save values to database */
wallet_channel_save ( cmd - > ld - > wallet , channel ) ;
/* write JSON response entry */
derive_channel_id ( & cid , & channel - > funding_txid , channel - > funding_outnum ) ;
json_object_start ( response , NULL ) ;
json_add_pubkey ( response , " peer_id " , & channel - > peer - > id ) ;
json_add_string ( response , " channel_id " ,
type_to_string ( tmpctx , struct channel_id , & cid ) ) ;
if ( channel - > scid )
json_add_short_channel_id ( response , " short_channel_id " , channel - > scid ) ;
json_object_end ( response ) ;
}
static struct command_result * json_setchannelfee ( struct command * cmd ,
const char * buffer ,
const jsmntok_t * obj UNNEEDED ,
const jsmntok_t * params )
{
struct json_stream * response ;
const jsmntok_t * idtok ;
struct peer * peer ;
struct channel * channel ;
struct channel_id cid ;
struct command_result * res ;
u32 * base , * ppm ;
/* Parse the JSON command */
if ( ! param ( cmd , buffer , params ,
p_req ( " id " , param_tok , & idtok ) ,
p_req ( " id " , param_channel_or_all , & channel ) ,
p_opt_def ( " base " , param_msat_u32 ,
& base , cmd - > ld - > config . fee_base ) ,
p_opt_def ( " ppm " , param_number , & ppm ,
@ -1390,55 +1452,38 @@ static struct command_result *json_setchannelfee(struct command *cmd,
NULL ) )
return command_param_failed ( ) ;
/* Find the channel */
peer = peer_from_json ( cmd - > ld , buffer , idtok ) ;
if ( peer ) {
/* Open JSON response object for later iteration */
response = json_stream_success ( cmd ) ;
json_object_start ( response , NULL ) ;
json_add_num ( response , " base " , * base ) ;
json_add_num ( response , " ppm " , * ppm ) ;
json_array_start ( response , " channels " ) ;
/* If the users requested 'all' channels we need to iterate */
if ( channel = = NULL ) {
list_for_each ( & cmd - > ld - > peers , peer , list ) {
list_for_each ( & peer - > channels , channel , list ) {
channel = peer_active_channel ( peer ) ;
if ( ! channel )
return command_fail ( cmd , LIGHTNINGD ,
" Could not find active channel of peer with that id " ) ;
} else {
res = command_find_channel ( cmd , buffer , idtok , & channel ) ;
if ( res )
return res ;
/* check channel is found and in valid state */
if ( ! channel )
return command_fail ( cmd , LIGHTNINGD ,
" Could not find channel with that id " ) ;
peer = channel - > peer ;
continue ;
if ( channel - > state ! = CHANNELD_NORMAL & &
channel - > state ! = CHANNELD_AWAITING_LOCKIN )
continue ;
set_channel_fees ( cmd , channel , * base , * ppm , response ) ;
}
}
/* single channel should be updated */
} else {
if ( channel - > state ! = CHANNELD_NORMAL & &
channel - > state ! = CHANNELD_AWAITING_LOCKIN )
return command_fail ( cmd , LIGHTNINGD ,
" Channel is in state %s " , channel_state_name ( channel ) ) ;
set_channel_fees ( cmd , channel , * base , * ppm , response ) ;
}
/* set, notify and save new values */
channel - > feerate_base = * base ;
channel - > feerate_ppm = * ppm ;
/* tell channeld to make a send_channel_update */
if ( channel - > owner & & streq ( channel - > owner - > name , " lightning_channeld " ) )
subd_send_msg ( channel - > owner ,
take ( towire_channel_specific_feerates ( NULL ,
* base , * ppm ) ) ) ;
/* save values to database */
wallet_channel_save ( cmd - > ld - > wallet , channel ) ;
/* get channel id */
derive_channel_id ( & cid , & channel - > funding_txid , channel - > funding_outnum ) ;
/* write response */
response = json_stream_success ( cmd ) ;
json_object_start ( response , NULL ) ;
json_add_num ( response , " base " , * base ) ;
json_add_num ( response , " ppm " , * ppm ) ;
json_add_pubkey ( response , " peer_id " , & peer - > id ) ;
json_add_string ( response , " channel_id " ,
type_to_string ( tmpctx , struct channel_id , & cid ) ) ;
if ( channel - > scid )
json_add_short_channel_id ( response , " short_channel_id " , channel - > scid ) ;
/* Close and return response */
json_array_end ( response ) ;
json_object_end ( response ) ;
return command_success ( cmd , response ) ;
}