mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 23:54:22 +01:00
type_to_string: move pretty printing of types from log
It's not just useful for logging. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
2
Makefile
2
Makefile
@@ -47,6 +47,7 @@ CORE_SRC := \
|
|||||||
opt_bits.c \
|
opt_bits.c \
|
||||||
permute_tx.c \
|
permute_tx.c \
|
||||||
protobuf_convert.c \
|
protobuf_convert.c \
|
||||||
|
type_to_string.c \
|
||||||
utils.c \
|
utils.c \
|
||||||
version.c
|
version.c
|
||||||
|
|
||||||
@@ -170,6 +171,7 @@ CORE_HEADERS := close_tx.h \
|
|||||||
permute_tx.h \
|
permute_tx.h \
|
||||||
protobuf_convert.h \
|
protobuf_convert.h \
|
||||||
remove_dust.h \
|
remove_dust.h \
|
||||||
|
type_to_string.h \
|
||||||
utils.h \
|
utils.h \
|
||||||
version.h
|
version.h
|
||||||
|
|
||||||
|
|||||||
93
daemon/log.c
93
daemon/log.c
@@ -1,12 +1,4 @@
|
|||||||
#include "bitcoin/locktime.h"
|
|
||||||
#include "bitcoin/pubkey.h"
|
|
||||||
#include "bitcoin/tx.h"
|
|
||||||
#include "channel.h"
|
|
||||||
#include "htlc.h"
|
|
||||||
#include "lightningd.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "peer.h"
|
|
||||||
#include "protobuf_convert.h"
|
|
||||||
#include "pseudorand.h"
|
#include "pseudorand.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <ccan/array_size/array_size.h>
|
#include <ccan/array_size/array_size.h>
|
||||||
@@ -274,94 +266,13 @@ void log_add(struct log *log, const char *fmt, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define to_string(ctx, lr, structtype, ptr) \
|
|
||||||
to_string_((ctx), lr, stringify(structtype), \
|
|
||||||
((void)sizeof((ptr) == (structtype *)NULL), \
|
|
||||||
((union loggable_structs)((const structtype *)ptr))))
|
|
||||||
|
|
||||||
static char *to_string_(const tal_t *ctx,
|
|
||||||
struct log_record *lr,
|
|
||||||
const char *structname,
|
|
||||||
union loggable_structs u)
|
|
||||||
{
|
|
||||||
char *s = NULL;
|
|
||||||
|
|
||||||
/* GCC checks we're one of these, so we should be. */
|
|
||||||
if (streq(structname, "struct pubkey"))
|
|
||||||
s = pubkey_to_hexstr(ctx, u.pubkey);
|
|
||||||
else if (streq(structname, "struct sha256_double"))
|
|
||||||
s = tal_hexstr(ctx, u.sha256_double, sizeof(*u.sha256_double));
|
|
||||||
else if (streq(structname, "struct sha256"))
|
|
||||||
s = tal_hexstr(ctx, u.sha256, sizeof(*u.sha256));
|
|
||||||
else if (streq(structname, "struct rel_locktime")) {
|
|
||||||
if (rel_locktime_is_seconds(u.rel_locktime))
|
|
||||||
s = tal_fmt(ctx, "+%usec",
|
|
||||||
rel_locktime_to_seconds(u.rel_locktime));
|
|
||||||
else
|
|
||||||
s = tal_fmt(ctx, "+%ublocks",
|
|
||||||
rel_locktime_to_blocks(u.rel_locktime));
|
|
||||||
} else if (streq(structname, "struct abs_locktime")) {
|
|
||||||
if (abs_locktime_is_seconds(u.abs_locktime))
|
|
||||||
s = tal_fmt(ctx, "%usec",
|
|
||||||
abs_locktime_to_seconds(u.abs_locktime));
|
|
||||||
else
|
|
||||||
s = tal_fmt(ctx, "%ublocks",
|
|
||||||
abs_locktime_to_blocks(u.abs_locktime));
|
|
||||||
} else if (streq(structname, "struct bitcoin_tx")) {
|
|
||||||
u8 *lin = linearize_tx(ctx, u.bitcoin_tx);
|
|
||||||
s = tal_hexstr(ctx, lin, tal_count(lin));
|
|
||||||
} else if (streq(structname, "struct htlc")) {
|
|
||||||
const struct htlc *h = u.htlc;
|
|
||||||
s = tal_fmt(ctx, "{ id=%"PRIu64
|
|
||||||
" msatoshi=%"PRIu64
|
|
||||||
" expiry=%s"
|
|
||||||
" rhash=%s"
|
|
||||||
" rval=%s"
|
|
||||||
" src=%s }",
|
|
||||||
h->id, h->msatoshi,
|
|
||||||
to_string(ctx, lr, struct abs_locktime, &h->expiry),
|
|
||||||
to_string(ctx, lr, struct sha256, &h->rhash),
|
|
||||||
h->r ? tal_hexstr(ctx, h->r, sizeof(*h->r))
|
|
||||||
: "UNKNOWN",
|
|
||||||
h->src ? to_string(ctx, lr, struct pubkey,
|
|
||||||
h->src->peer->id)
|
|
||||||
: "local");
|
|
||||||
} else if (streq(structname, "struct rval")) {
|
|
||||||
s = tal_hexstr(ctx, u.rval, sizeof(*u.rval));
|
|
||||||
} else if (streq(structname, "struct channel_oneside")) {
|
|
||||||
s = tal_fmt(ctx, "{ pay_msat=%u"
|
|
||||||
" fee_msat=%u"
|
|
||||||
" num_htlcs=%u }",
|
|
||||||
u.channel_oneside->pay_msat,
|
|
||||||
u.channel_oneside->fee_msat,
|
|
||||||
u.channel_oneside->num_htlcs);
|
|
||||||
} else if (streq(structname, "struct channel_state")) {
|
|
||||||
s = tal_fmt(ctx, "{ anchor=%"PRIu64
|
|
||||||
" fee_rate=%"PRIu64
|
|
||||||
" num_nondust=%u"
|
|
||||||
" ours=%s"
|
|
||||||
" theirs=%s }",
|
|
||||||
u.cstate->anchor,
|
|
||||||
u.cstate->fee_rate,
|
|
||||||
u.cstate->num_nondust,
|
|
||||||
to_string(ctx, lr, struct channel_oneside,
|
|
||||||
&u.cstate->side[LOCAL]),
|
|
||||||
to_string(ctx, lr, struct channel_oneside,
|
|
||||||
&u.cstate->side[REMOTE]));
|
|
||||||
} else if (streq(structname, "struct netaddr")) {
|
|
||||||
s = netaddr_name(ctx, u.netaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_struct_(struct log *log, int level,
|
void log_struct_(struct log *log, int level,
|
||||||
const char *structname,
|
const char *structname,
|
||||||
const char *fmt, ...)
|
const char *fmt, ...)
|
||||||
{
|
{
|
||||||
const tal_t *ctx = tal_tmpctx(log);
|
const tal_t *ctx = tal_tmpctx(log);
|
||||||
char *s;
|
char *s;
|
||||||
union loggable_structs u;
|
union printable_types u;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
/* Macro wrappers ensure we only have one arg. */
|
/* Macro wrappers ensure we only have one arg. */
|
||||||
@@ -370,7 +281,7 @@ void log_struct_(struct log *log, int level,
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
/* GCC checks we're one of these, so we should be. */
|
/* GCC checks we're one of these, so we should be. */
|
||||||
s = to_string_(ctx, log->lr, structname, u);
|
s = type_to_string_(ctx, structname, u);
|
||||||
if (!s)
|
if (!s)
|
||||||
fatal("Logging unknown type %s", structname);
|
fatal("Logging unknown type %s", structname);
|
||||||
|
|
||||||
|
|||||||
21
daemon/log.h
21
daemon/log.h
@@ -1,6 +1,7 @@
|
|||||||
#ifndef LIGHTNING_DAEMON_LOG_H
|
#ifndef LIGHTNING_DAEMON_LOG_H
|
||||||
#define LIGHTNING_DAEMON_LOG_H
|
#define LIGHTNING_DAEMON_LOG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "type_to_string.h"
|
||||||
#include <ccan/tal/tal.h>
|
#include <ccan/tal/tal.h>
|
||||||
#include <ccan/typesafe_cb/typesafe_cb.h>
|
#include <ccan/typesafe_cb/typesafe_cb.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -59,11 +60,11 @@ void log_blob_(struct log *log, int level, const char *fmt,
|
|||||||
#define log_broken_blob(log, fmt, blob, len) \
|
#define log_broken_blob(log, fmt, blob, len) \
|
||||||
log_blob_((log), LOG_BROKEN, (fmt), (len), (char *)(blob))
|
log_blob_((log), LOG_BROKEN, (fmt), (len), (char *)(blob))
|
||||||
|
|
||||||
/* Makes sure ptr is a 'structtype', makes sure it's in loggable_structs. */
|
/* Makes sure ptr is a 'structtype', makes sure it's in printable_types. */
|
||||||
#define log_struct_check_(log, loglevel, fmt, structtype, ptr) \
|
#define log_struct_check_(log, loglevel, fmt, structtype, ptr) \
|
||||||
log_struct_((log), (loglevel), stringify(structtype), (fmt), \
|
log_struct_((log), (loglevel), stringify(structtype), (fmt), \
|
||||||
((void)sizeof((ptr) == (structtype *)NULL), \
|
((void)sizeof((ptr) == (structtype *)NULL), \
|
||||||
((union loggable_structs)((const structtype *)ptr)).charp_))
|
((union printable_types)((const structtype *)ptr)).charp_))
|
||||||
|
|
||||||
/* These must have %s where the struct is to go. */
|
/* These must have %s where the struct is to go. */
|
||||||
#define log_add_struct(log, fmt, structtype, ptr) \
|
#define log_add_struct(log, fmt, structtype, ptr) \
|
||||||
@@ -78,22 +79,6 @@ void log_blob_(struct log *log, int level, const char *fmt,
|
|||||||
#define log_broken_struct(log, fmt, structtype, ptr) \
|
#define log_broken_struct(log, fmt, structtype, ptr) \
|
||||||
log_struct_check_((log), LOG_BROKEN, (fmt), structtype, (ptr))
|
log_struct_check_((log), LOG_BROKEN, (fmt), structtype, (ptr))
|
||||||
|
|
||||||
/* This must match the log_add_struct_ definitions. */
|
|
||||||
union loggable_structs {
|
|
||||||
const struct pubkey *pubkey;
|
|
||||||
const struct sha256_double *sha256_double;
|
|
||||||
const struct sha256 *sha256;
|
|
||||||
const struct rel_locktime *rel_locktime;
|
|
||||||
const struct abs_locktime *abs_locktime;
|
|
||||||
const struct bitcoin_tx *bitcoin_tx;
|
|
||||||
const struct htlc *htlc;
|
|
||||||
const struct rval *rval;
|
|
||||||
const struct channel_state *cstate;
|
|
||||||
const struct channel_oneside *channel_oneside;
|
|
||||||
const struct netaddr *netaddr;
|
|
||||||
const char *charp_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void PRINTF_FMT(4,5) log_struct_(struct log *log, int level,
|
void PRINTF_FMT(4,5) log_struct_(struct log *log, int level,
|
||||||
const char *structname,
|
const char *structname,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
|
|||||||
86
type_to_string.c
Normal file
86
type_to_string.c
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#include "bitcoin/locktime.h"
|
||||||
|
#include "bitcoin/pubkey.h"
|
||||||
|
#include "bitcoin/tx.h"
|
||||||
|
#include "daemon/channel.h"
|
||||||
|
#include "daemon/htlc.h"
|
||||||
|
#include "daemon/lightningd.h"
|
||||||
|
#include "daemon/peer.h"
|
||||||
|
#include "protobuf_convert.h"
|
||||||
|
#include "type_to_string.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include <ccan/tal/str/str.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
char *type_to_string_(const tal_t *ctx, const char *typename,
|
||||||
|
union printable_types u)
|
||||||
|
{
|
||||||
|
char *s = NULL;
|
||||||
|
|
||||||
|
/* GCC checks we're one of these, so we should be. */
|
||||||
|
if (streq(typename, "struct pubkey"))
|
||||||
|
s = pubkey_to_hexstr(ctx, u.pubkey);
|
||||||
|
else if (streq(typename, "struct sha256_double"))
|
||||||
|
s = tal_hexstr(ctx, u.sha256_double, sizeof(*u.sha256_double));
|
||||||
|
else if (streq(typename, "struct sha256"))
|
||||||
|
s = tal_hexstr(ctx, u.sha256, sizeof(*u.sha256));
|
||||||
|
else if (streq(typename, "struct rel_locktime")) {
|
||||||
|
if (rel_locktime_is_seconds(u.rel_locktime))
|
||||||
|
s = tal_fmt(ctx, "+%usec",
|
||||||
|
rel_locktime_to_seconds(u.rel_locktime));
|
||||||
|
else
|
||||||
|
s = tal_fmt(ctx, "+%ublocks",
|
||||||
|
rel_locktime_to_blocks(u.rel_locktime));
|
||||||
|
} else if (streq(typename, "struct abs_locktime")) {
|
||||||
|
if (abs_locktime_is_seconds(u.abs_locktime))
|
||||||
|
s = tal_fmt(ctx, "%usec",
|
||||||
|
abs_locktime_to_seconds(u.abs_locktime));
|
||||||
|
else
|
||||||
|
s = tal_fmt(ctx, "%ublocks",
|
||||||
|
abs_locktime_to_blocks(u.abs_locktime));
|
||||||
|
} else if (streq(typename, "struct bitcoin_tx")) {
|
||||||
|
u8 *lin = linearize_tx(ctx, u.bitcoin_tx);
|
||||||
|
s = tal_hexstr(ctx, lin, tal_count(lin));
|
||||||
|
} else if (streq(typename, "struct htlc")) {
|
||||||
|
const struct htlc *h = u.htlc;
|
||||||
|
s = tal_fmt(ctx, "{ id=%"PRIu64
|
||||||
|
" msatoshi=%"PRIu64
|
||||||
|
" expiry=%s"
|
||||||
|
" rhash=%s"
|
||||||
|
" rval=%s"
|
||||||
|
" src=%s }",
|
||||||
|
h->id, h->msatoshi,
|
||||||
|
type_to_string(ctx, struct abs_locktime, &h->expiry),
|
||||||
|
type_to_string(ctx, struct sha256, &h->rhash),
|
||||||
|
h->r ? tal_hexstr(ctx, h->r, sizeof(*h->r))
|
||||||
|
: "UNKNOWN",
|
||||||
|
h->src ? type_to_string(ctx, struct pubkey,
|
||||||
|
h->src->peer->id)
|
||||||
|
: "local");
|
||||||
|
} else if (streq(typename, "struct rval")) {
|
||||||
|
s = tal_hexstr(ctx, u.rval, sizeof(*u.rval));
|
||||||
|
} else if (streq(typename, "struct channel_oneside")) {
|
||||||
|
s = tal_fmt(ctx, "{ pay_msat=%u"
|
||||||
|
" fee_msat=%u"
|
||||||
|
" num_htlcs=%u }",
|
||||||
|
u.channel_oneside->pay_msat,
|
||||||
|
u.channel_oneside->fee_msat,
|
||||||
|
u.channel_oneside->num_htlcs);
|
||||||
|
} else if (streq(typename, "struct channel_state")) {
|
||||||
|
s = tal_fmt(ctx, "{ anchor=%"PRIu64
|
||||||
|
" fee_rate=%"PRIu64
|
||||||
|
" num_nondust=%u"
|
||||||
|
" ours=%s"
|
||||||
|
" theirs=%s }",
|
||||||
|
u.cstate->anchor,
|
||||||
|
u.cstate->fee_rate,
|
||||||
|
u.cstate->num_nondust,
|
||||||
|
type_to_string(ctx, struct channel_oneside,
|
||||||
|
&u.cstate->side[LOCAL]),
|
||||||
|
type_to_string(ctx, struct channel_oneside,
|
||||||
|
&u.cstate->side[REMOTE]));
|
||||||
|
} else if (streq(typename, "struct netaddr")) {
|
||||||
|
s = netaddr_name(ctx, u.netaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
30
type_to_string.h
Normal file
30
type_to_string.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef LIGHTNING_TYPE_TO_STRING_H
|
||||||
|
#define LIGHTNING_TYPE_TO_STRING_H
|
||||||
|
#include "config.h"
|
||||||
|
#include <ccan/tal/tal.h>
|
||||||
|
|
||||||
|
/* This must match the type_to_string_ cases. */
|
||||||
|
union printable_types {
|
||||||
|
const struct pubkey *pubkey;
|
||||||
|
const struct sha256_double *sha256_double;
|
||||||
|
const struct sha256 *sha256;
|
||||||
|
const struct rel_locktime *rel_locktime;
|
||||||
|
const struct abs_locktime *abs_locktime;
|
||||||
|
const struct bitcoin_tx *bitcoin_tx;
|
||||||
|
const struct htlc *htlc;
|
||||||
|
const struct rval *rval;
|
||||||
|
const struct channel_state *cstate;
|
||||||
|
const struct channel_oneside *channel_oneside;
|
||||||
|
const struct netaddr *netaddr;
|
||||||
|
const char *charp_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define type_to_string(ctx, type, ptr) \
|
||||||
|
type_to_string_((ctx), stringify(type), \
|
||||||
|
((void)sizeof((ptr) == (type *)NULL), \
|
||||||
|
((union printable_types)((const type *)ptr))))
|
||||||
|
|
||||||
|
char *type_to_string_(const tal_t *ctx, const char *typename,
|
||||||
|
union printable_types u);
|
||||||
|
|
||||||
|
#endif /* LIGHTNING_UTILS_H */
|
||||||
Reference in New Issue
Block a user