Browse Source

cleanup: extract and formalize feerate conversion.

I didn't want to create a new file for this now, as that would totally
break #1880.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
e2d4b7cc8d
  1. 3
      lightningd/bitcoind.c
  2. 56
      lightningd/chaintopology.c
  3. 6
      lightningd/chaintopology.h
  4. 35
      lightningd/json.c
  5. 12
      lightningd/json.h
  6. 2
      tests/test_misc.py

3
lightningd/bitcoind.c

@ -332,7 +332,8 @@ static bool process_estimatefee(struct bitcoin_cli *bcli)
efee->satoshi_per_kw[efee->i] = 0;
} else
/* Rate in satoshi per kw. */
efee->satoshi_per_kw[efee->i] = feerate / 4;
efee->satoshi_per_kw[efee->i]
= feerate_from_style(feerate, FEERATE_PER_KBYTE);
efee->i++;
if (efee->i == tal_count(efee->satoshi_per_kw)) {

56
lightningd/chaintopology.c

@ -19,7 +19,6 @@
#include <inttypes.h>
#include <lightningd/channel_control.h>
#include <lightningd/gossip_control.h>
#include <lightningd/json.h>
#include <lightningd/jsonrpc_errors.h>
#include <lightningd/param.h>
@ -422,6 +421,32 @@ u32 unilateral_feerate(struct chain_topology *topo)
return try_get_feerate(topo, FEERATE_URGENT);
}
u32 feerate_from_style(u32 feerate, enum feerate_style style)
{
switch (style) {
case FEERATE_PER_KSIPA:
return feerate;
case FEERATE_PER_KBYTE:
/* Everyone uses satoshi per kbyte, but we use satoshi per ksipa
* (don't round down to zero though)! */
return (feerate + 3) / 4;
}
abort();
}
u32 feerate_to_style(u32 feerate_perkw, enum feerate_style style)
{
switch (style) {
case FEERATE_PER_KSIPA:
return feerate_perkw;
case FEERATE_PER_KBYTE:
if ((u64)feerate_perkw * 4 > UINT_MAX)
return UINT_MAX;
return feerate_perkw * 4;
}
abort();
}
static void json_feerates(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
@ -429,12 +454,10 @@ static void json_feerates(struct command *cmd,
struct json_result *response;
u32 *urgent, *normal, *slow, feerates[NUM_FEERATES];
bool missing;
const jsmntok_t *style;
bool bitcoind_style;
u64 mulfactor;
enum feerate_style *style;
if (!param(cmd, buffer, params,
p_req("style", json_tok_tok, &style),
p_req("style", json_tok_feerate_style, &style),
p_opt("urgent", json_tok_number, &urgent),
p_opt("normal", json_tok_number, &normal),
p_opt("slow", json_tok_number, &slow),
@ -446,20 +469,8 @@ static void json_feerates(struct command *cmd,
feerates[FEERATE_NORMAL] = normal ? *normal : 0;
feerates[FEERATE_SLOW] = slow ? *slow : 0;
if (json_tok_streq(buffer, style, "perkw")) {
bitcoind_style = false;
mulfactor = 1;
} else if (json_tok_streq(buffer, style, "perkb")) {
/* Everyone uses satoshi per kbyte, but we use satoshi per ksipa
* (don't round down to zero though)! */
for (size_t i = 0; i < ARRAY_SIZE(feerates); i++)
feerates[i] = (feerates[i] + 3) / 4;
bitcoind_style = true;
mulfactor = 4;
} else {
command_fail(cmd, JSONRPC2_INVALID_PARAMS, "invalid style");
return;
}
feerates[i] = feerate_from_style(feerates[i], *style);
log_info(topo->log,
"feerates: inserting feerates in sipa/kb %u/%u/%u",
@ -478,16 +489,17 @@ static void json_feerates(struct command *cmd,
response = new_json_result(cmd);
json_object_start(response, NULL);
json_object_start(response, bitcoind_style ? "perkb" : "perkw");
json_object_start(response, json_feerate_style_name(*style));
for (size_t i = 0; i < ARRAY_SIZE(feerates); i++) {
if (!feerates[i])
continue;
json_add_num(response, feerate_name(i), feerates[i] * mulfactor);
json_add_num(response, feerate_name(i),
feerate_to_style(feerates[i], *style));
}
json_add_u64(response, "min_acceptable",
feerate_min(cmd->ld, NULL) * mulfactor);
feerate_to_style(feerate_min(cmd->ld, NULL), *style));
json_add_u64(response, "max_acceptable",
feerate_max(cmd->ld, NULL) * mulfactor);
feerate_to_style(feerate_max(cmd->ld, NULL), *style));
json_object_end(response);
if (missing)

6
lightningd/chaintopology.h

@ -8,6 +8,7 @@
#include <ccan/structeq/structeq.h>
#include <ccan/time/time.h>
#include <jsmn.h>
#include <lightningd/json.h>
#include <lightningd/watch.h>
#include <math.h>
#include <stddef.h>
@ -19,6 +20,7 @@ struct lightningd;
struct peer;
struct txwatch;
/* FIXME: move all feerate stuff out to new lightningd/feerate.[ch] files */
enum feerate {
FEERATE_URGENT, /* Aka: aim for next block. */
FEERATE_NORMAL, /* Aka: next 4 blocks or so. */
@ -144,6 +146,10 @@ u32 mutual_close_feerate(struct chain_topology *topo);
u32 opening_feerate(struct chain_topology *topo);
u32 unilateral_feerate(struct chain_topology *topo);
/* We always use feerate-per-ksipa, ie. perkw */
u32 feerate_from_style(u32 feerate, enum feerate_style style);
u32 feerate_to_style(u32 feerate_perkw, enum feerate_style style);
/* Broadcast a single tx, and rebroadcast as reqd (copies tx).
* If failed is non-NULL, call that and don't rebroadcast. */
void broadcast_tx(struct chain_topology *topo,

35
lightningd/json.c

@ -223,6 +223,41 @@ bool json_tok_short_channel_id(struct command *cmd, const char *name,
return false;
}
const char *json_feerate_style_name(enum feerate_style style)
{
switch (style) {
case FEERATE_PER_KBYTE:
return "perkb";
case FEERATE_PER_KSIPA:
return "perkw";
}
abort();
}
bool json_tok_feerate_style(struct command *cmd, const char *name,
const char *buffer, const jsmntok_t *tok,
enum feerate_style **style)
{
*style = tal(cmd, enum feerate_style);
if (json_tok_streq(buffer, tok,
json_feerate_style_name(FEERATE_PER_KSIPA))) {
**style = FEERATE_PER_KSIPA;
return true;
} else if (json_tok_streq(buffer, tok,
json_feerate_style_name(FEERATE_PER_KBYTE))) {
**style = FEERATE_PER_KBYTE;
return true;
}
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"'%s' should be '%s' or '%s', not '%.*s'",
name,
json_feerate_style_name(FEERATE_PER_KSIPA),
json_feerate_style_name(FEERATE_PER_KBYTE),
tok->end - tok->start, buffer + tok->start);
return false;
}
bool
json_tok_channel_id(const char *buffer, const jsmntok_t *tok,
struct channel_id *cid)

12
lightningd/json.h

@ -83,6 +83,18 @@ bool json_tok_u64(struct command *cmd, const char *name,
const char *buffer, const jsmntok_t *tok,
uint64_t **num);
enum feerate_style {
FEERATE_PER_KSIPA,
FEERATE_PER_KBYTE
};
/* Extract a feerate style. */
bool json_tok_feerate_style(struct command *cmd, const char *name,
const char *buffer, const jsmntok_t *tok,
enum feerate_style **style);
const char *json_feerate_style_name(enum feerate_style style);
/* '"fieldname" : "1234:5:6"' */
void json_add_short_channel_id(struct json_result *response,
const char *fieldname,

2
tests/test_misc.py

@ -876,7 +876,7 @@ def test_feerates(node_factory):
assert len(feerates['perkb']) == 2
assert feerates['warning'] == 'Some fee estimates unavailable: bitcoind startup?'
assert 'perkw' not in feerates
assert feerates['perkb']['max_acceptable'] == (2**32 - 1) * 4
assert feerates['perkb']['max_acceptable'] == (2**32 - 1)
assert feerates['perkb']['min_acceptable'] == 253 * 4
# Now try setting them, one at a time.

Loading…
Cancel
Save