Browse Source

lightningd: minor cleanups in setchannelfee parsing.

1. amount operations should force you to check validity, rather than
   needing a separate call, so make amount_msat_to_u32 return bool,
   and WARN_UNUSED_RESULT it.
2. Create a special parsing function for this; not only does this mean
   we now only need that one amount call, but also 'check' will correctly
   fail with invalid amounts (it only does the parsing step).
3. If we create a primitive which we immediately take(), we allocate it
   off NULL to make it clear we expect its lifetime to end here.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
issue-2504
Rusty Russell 6 years ago
parent
commit
0ed03648f4
  1. 17
      common/amount.c
  2. 11
      common/amount.h
  3. 53
      lightningd/peer_control.c

17
common/amount.c

@ -362,19 +362,12 @@ bool amount_msat_less_eq_sat(struct amount_msat msat, struct amount_sat sat)
return msat.millisatoshis <= msat_from_sat.millisatoshis; return msat.millisatoshis <= msat_from_sat.millisatoshis;
} }
bool amount_msat_overflow_u32(struct amount_msat msat) bool amount_msat_to_u32(struct amount_msat msat, u32 *millisatoshis)
{ {
return amount_msat_greater_eq(msat, AMOUNT_MSAT(0x100000000)); if (amount_msat_greater_eq(msat, AMOUNT_MSAT(0x100000000)))
} return false;
*millisatoshis = msat.millisatoshis;
u32 amount_msat_to_u32(struct amount_msat msat) return true;
{
return (u32)msat.millisatoshis;
}
void amount_msat_from_u32(struct amount_msat *msat, u32 value)
{
msat->millisatoshis = (u64)value;
} }
bool amount_msat_fee(struct amount_msat *fee, bool amount_msat_fee(struct amount_msat *fee,

11
common/amount.h

@ -98,14 +98,9 @@ bool amount_msat_less_sat(struct amount_msat msat, struct amount_sat sat);
/* Is msat <= sat? */ /* Is msat <= sat? */
bool amount_msat_less_eq_sat(struct amount_msat msat, struct amount_sat sat); bool amount_msat_less_eq_sat(struct amount_msat msat, struct amount_sat sat);
/* Does value overflow u32 bit */ /* Returns true if msat fits in a u32 value. */
bool amount_msat_overflow_u32(struct amount_msat msat); WARN_UNUSED_RESULT bool amount_msat_to_u32(struct amount_msat msat,
u32 *millisatoshis);
/* Return unchecked u32 value */
u32 amount_msat_to_u32(struct amount_msat msat);
/* Set by u32 value */
void amount_msat_from_u32(struct amount_msat *msat, u32 value);
/* Common operation: what is the HTLC fee for given feerate? Can overflow! */ /* Common operation: what is the HTLC fee for given feerate? Can overflow! */
WARN_UNUSED_RESULT bool amount_msat_fee(struct amount_msat *fee, WARN_UNUSED_RESULT bool amount_msat_fee(struct amount_msat *fee,

53
lightningd/peer_control.c

@ -1339,6 +1339,33 @@ static const struct json_command getinfo_command = {
}; };
AUTODATA(json_command, &getinfo_command); AUTODATA(json_command, &getinfo_command);
/* 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,
const char *name,
const char *buffer,
const jsmntok_t *tok,
u32 **num)
{
struct amount_msat *msat;
struct command_result *res;
/* Parse just like an msat. */
res = param_msat(cmd, name, buffer, tok, &msat);
if (res)
return res;
*num = tal(cmd, u32);
if (!amount_msat_to_u32(*msat, *num)) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%s' value '%s' exceeds u32 max",
name,
type_to_string(tmpctx, struct amount_msat,
msat));
}
return NULL;
}
static struct command_result *json_setchannelfee(struct command *cmd, static struct command_result *json_setchannelfee(struct command *cmd,
const char *buffer, const char *buffer,
@ -1351,26 +1378,18 @@ static struct command_result *json_setchannelfee(struct command *cmd,
struct channel *channel; struct channel *channel;
struct channel_id cid; struct channel_id cid;
struct command_result *res; struct command_result *res;
struct amount_msat *base, base_default; u32 *base, *ppm;
u32 *ppm, ppm_default;
/* Use daemon config values base/ppm as default */
amount_msat_from_u32(&base_default, cmd->ld->config.fee_base);
ppm_default = cmd->ld->config.fee_per_satoshi;
/* Parse the JSON command */ /* Parse the JSON command */
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
p_req("id", param_tok, &idtok), p_req("id", param_tok, &idtok),
p_opt_def("base", param_msat, &base, base_default), p_opt_def("base", param_msat_u32,
p_opt_def("ppm", param_number, &ppm, ppm_default), &base, cmd->ld->config.fee_base),
p_opt_def("ppm", param_number, &ppm,
cmd->ld->config.fee_per_satoshi),
NULL)) NULL))
return command_param_failed(); return command_param_failed();
/* Check base for u32 overflow */
if (amount_msat_overflow_u32(*base))
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Value 'base' exceeds u32 max");
/* Find the channel */ /* Find the channel */
peer = peer_from_json(cmd->ld, buffer, idtok); peer = peer_from_json(cmd->ld, buffer, idtok);
if (peer) { if (peer) {
@ -1395,14 +1414,14 @@ static struct command_result *json_setchannelfee(struct command *cmd,
"Channel is in state %s", channel_state_name(channel)); "Channel is in state %s", channel_state_name(channel));
/* set, notify and save new values */ /* set, notify and save new values */
channel->feerate_base = amount_msat_to_u32(*base); channel->feerate_base = *base;
channel->feerate_ppm = *ppm; channel->feerate_ppm = *ppm;
/* tell channeld to make a send_channel_update */ /* tell channeld to make a send_channel_update */
if (channel->owner && streq(channel->owner->name, "lightning_channeld")) if (channel->owner && streq(channel->owner->name, "lightning_channeld"))
subd_send_msg(channel->owner, subd_send_msg(channel->owner,
take(towire_channel_specific_feerates(channel, take(towire_channel_specific_feerates(NULL,
amount_msat_to_u32(*base), *ppm))); *base, *ppm)));
/* save values to database */ /* save values to database */
wallet_channel_save(cmd->ld->wallet, channel); wallet_channel_save(cmd->ld->wallet, channel);
@ -1413,7 +1432,7 @@ static struct command_result *json_setchannelfee(struct command *cmd,
/* write response */ /* write response */
response = json_stream_success(cmd); response = json_stream_success(cmd);
json_object_start(response, NULL); json_object_start(response, NULL);
json_add_num(response, "base", amount_msat_to_u32(*base)); json_add_num(response, "base", *base);
json_add_num(response, "ppm", *ppm); json_add_num(response, "ppm", *ppm);
json_add_pubkey(response, "peer_id", &peer->id); json_add_pubkey(response, "peer_id", &peer->id);
json_add_string(response, "channel_id", json_add_string(response, "channel_id",

Loading…
Cancel
Save