tools/generate-wire.py: have printwire routines do demarshal.

This works better in general: let printwire_x do the work of figuring
out how to demarshal x.  This is particularly important for TLVs, which
require a call to tlv_x_new() first.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-03-23 10:01:14 +10:30
parent 88de64a580
commit 8f39002715
6 changed files with 178 additions and 102 deletions

View file

@ -7,29 +7,90 @@
#include <errno.h>
#include <stdio.h>
void printwire_u8(const char *fieldname, const u8 *v)
bool printwire_u8(const char *fieldname, const u8 **cursor, size_t *plen)
{
printf("%u\n", *v);
u8 v = fromwire_u8(cursor, plen);
if (!*cursor) {
printf("**TRUNCATED u8 %s**\n", fieldname);
return false;
}
printf("%u\n", v);
return true;
}
void printwire_u16(const char *fieldname, const u16 *v)
bool printwire_u16(const char *fieldname, const u8 **cursor, size_t *plen)
{
printf("%u\n", *v);
u16 v = fromwire_u16(cursor, plen);
if (!*cursor) {
printf("**TRUNCATED u16 %s**\n", fieldname);
return false;
}
printf("%u\n", v);
return true;
}
void printwire_u32(const char *fieldname, const u32 *v)
bool printwire_u32(const char *fieldname, const u8 **cursor, size_t *plen)
{
printf("%u\n", *v);
u32 v = fromwire_u32(cursor, plen);
if (!*cursor) {
printf("**TRUNCATED u32 %s**\n", fieldname);
return false;
}
printf("%u\n", v);
return true;
}
void printwire_u64(const char *fieldname, const u64 *v)
bool printwire_u64(const char *fieldname, const u8 **cursor, size_t *plen)
{
printf("%"PRIu64"\n", *v);
u64 v = fromwire_u64(cursor, plen);
if (!*cursor) {
printf("**TRUNCATED u64 %s**\n", fieldname);
return false;
}
printf("%"PRIu64"\n", v);
return true;
}
void printwire_wireaddr(const char *fieldname, const struct wireaddr *wireaddr)
bool printwire_tu16(const char *fieldname, const u8 **cursor, size_t *plen)
{
printf("%s\n", fmt_wireaddr(tmpctx, wireaddr));
u16 v = fromwire_tu16(cursor, plen);
if (!*cursor) {
printf("**TRUNCATED tu16 %s**\n", fieldname);
return false;
}
printf("%u\n", v);
return true;
}
bool printwire_tu32(const char *fieldname, const u8 **cursor, size_t *plen)
{
u32 v = fromwire_tu32(cursor, plen);
if (!*cursor) {
printf("**TRUNCATED tu32 %s**\n", fieldname);
return false;
}
printf("%u\n", v);
return true;
}
bool printwire_tu64(const char *fieldname, const u8 **cursor, size_t *plen)
{
u64 v = fromwire_tu64(cursor, plen);
if (!*cursor) {
printf("**TRUNCATED tu64 %s**\n", fieldname);
return false;
}
printf("%"PRIu64"\n", v);
return true;
}
bool printwire_wireaddr(const char *fieldname, const u8 **cursor, size_t *plen)
{
struct wireaddr w;
if (!fromwire_wireaddr(cursor, plen, &w))
return false;
printf("%s\n", fmt_wireaddr(tmpctx, &w));
return true;
}
/* Returns false if we ran out of data. */
@ -37,15 +98,17 @@ static bool print_hexstring(const u8 **cursor, size_t *plen, size_t len)
{
while (len) {
u8 v = fromwire_u8(cursor, plen);
if (!*cursor)
if (!*cursor) {
printf("**TRUNCATED**\n");
return false;
}
printf("%02x", v);
len--;
}
return true;
}
static void printwire_alias(const u8 **cursor, size_t *plen, size_t len)
static bool printwire_alias(const u8 **cursor, size_t *plen, size_t len)
{
struct utf8_state utf8 = UTF8_STATE_INIT;
const char *p = (const char *)*cursor;
@ -83,11 +146,12 @@ static void printwire_alias(const u8 **cursor, size_t *plen, size_t len)
hexdump:
if (!print_hexstring(cursor, plen, len))
return;
return false;
printf(" ]\n");
return true;
}
static void printwire_addresses(const u8 **cursor, size_t *plen, size_t len)
static bool printwire_addresses(const u8 **cursor, size_t *plen, size_t len)
{
struct wireaddr addr;
size_t to_go = len;
@ -99,23 +163,24 @@ static void printwire_addresses(const u8 **cursor, size_t *plen, size_t len)
printf(" %s", fmt_wireaddr(NULL, &addr));
}
if (!*cursor)
return;
return false;
if (to_go) {
printf(" UNKNOWN:");
if (!print_hexstring(cursor, plen, len))
return;
return false;
}
printf(" ]\n");
return true;
}
static void printwire_encoded_short_ids(const u8 **cursor, size_t *plen, size_t len)
static bool printwire_encoded_short_ids(const u8 **cursor, size_t *plen, size_t len)
{
struct short_channel_id *scids;
u8 *arr = fromwire_tal_arrn(tmpctx, cursor, plen, len);
if (!arr)
return;
return false;
printf("[");
scids = decode_short_ids(tmpctx, arr);
@ -139,34 +204,32 @@ static void printwire_encoded_short_ids(const u8 **cursor, size_t *plen, size_t
|| arr[0] == ARR_UNCOMPRESSED
|| arr[0] == ARR_ZLIB) {
printf(" **CORRUPT**");
return;
return true;
} else {
printf(" UNKNOWN:");
print_hexstring(cursor, plen, len);
}
}
printf(" ]\n");
return true;
}
void printwire_u8_array(const char *fieldname, const u8 **cursor, size_t *plen, size_t len)
bool printwire_u8_array(const char *fieldname, const u8 **cursor, size_t *plen, size_t len)
{
if (streq(fieldname, "node_announcement.alias")) {
printwire_alias(cursor, plen, len);
return;
}
if (streq(fieldname, "node_announcement.addresses")) {
printwire_addresses(cursor, plen, len);
return;
}
if (strends(fieldname, ".encoded_short_ids")) {
printwire_encoded_short_ids(cursor, plen, len);
return;
}
if (streq(fieldname, "node_announcement.alias"))
return printwire_alias(cursor, plen, len);
if (streq(fieldname, "node_announcement.addresses"))
return printwire_addresses(cursor, plen, len);
if (strends(fieldname, ".encoded_short_ids"))
return printwire_encoded_short_ids(cursor, plen, len);
printf("[");
if (!print_hexstring(cursor, plen, len))
return;
return false;
printf("]\n");
return true;
}
static const struct tlv_print_record_type *
@ -220,25 +283,48 @@ fail:
}
#define PRINTWIRE_TYPE_TO_STRING(T, N) \
void printwire_##N(const char *fieldname, const T *v) \
bool printwire_##N(const char *fieldname, const u8 **cursor, \
size_t *plen) \
{ \
const char *s = type_to_string(NULL, T, v); \
T v; \
fromwire_##N(cursor, plen, &v); \
if (!*cursor) { \
printf("**TRUNCATED " stringify(N) "\n"); \
return false; \
} \
const char *s = type_to_string(NULL, T, &v); \
printf("%s\n", s); \
tal_free(s); \
return true; \
}
#define PRINTWIRE_ASSIGNABLE_STRUCT_TO_STRING(N) \
bool printwire_##N(const char *fieldname, const u8 **cursor, \
size_t *plen) \
{ \
struct N v = fromwire_##N(cursor, plen); \
if (!*cursor) { \
printf("**TRUNCATED " stringify(N) "\n"); \
return false; \
} \
const char *s = type_to_string(NULL, struct N, &v); \
printf("%s\n", s); \
tal_free(s); \
return true; \
}
#define PRINTWIRE_STRUCT_TYPE_TO_STRING(T) \
PRINTWIRE_TYPE_TO_STRING(struct T, T)
PRINTWIRE_STRUCT_TYPE_TO_STRING(bitcoin_blkid);
PRINTWIRE_STRUCT_TYPE_TO_STRING(bitcoin_txid);
PRINTWIRE_STRUCT_TYPE_TO_STRING(channel_id);
PRINTWIRE_STRUCT_TYPE_TO_STRING(node_id);
PRINTWIRE_STRUCT_TYPE_TO_STRING(preimage);
PRINTWIRE_STRUCT_TYPE_TO_STRING(pubkey);
PRINTWIRE_STRUCT_TYPE_TO_STRING(sha256);
PRINTWIRE_STRUCT_TYPE_TO_STRING(secret);
PRINTWIRE_STRUCT_TYPE_TO_STRING(short_channel_id);
PRINTWIRE_STRUCT_TYPE_TO_STRING(amount_sat);
PRINTWIRE_STRUCT_TYPE_TO_STRING(amount_msat);
PRINTWIRE_TYPE_TO_STRING(secp256k1_ecdsa_signature, secp256k1_ecdsa_signature);
PRINTWIRE_STRUCT_TYPE_TO_STRING(bitcoin_blkid)
PRINTWIRE_STRUCT_TYPE_TO_STRING(bitcoin_txid)
PRINTWIRE_STRUCT_TYPE_TO_STRING(channel_id)
PRINTWIRE_STRUCT_TYPE_TO_STRING(node_id)
PRINTWIRE_STRUCT_TYPE_TO_STRING(preimage)
PRINTWIRE_STRUCT_TYPE_TO_STRING(pubkey)
PRINTWIRE_STRUCT_TYPE_TO_STRING(sha256)
PRINTWIRE_STRUCT_TYPE_TO_STRING(secret)
PRINTWIRE_STRUCT_TYPE_TO_STRING(short_channel_id)
PRINTWIRE_ASSIGNABLE_STRUCT_TO_STRING(amount_sat)
PRINTWIRE_ASSIGNABLE_STRUCT_TO_STRING(amount_msat)
PRINTWIRE_TYPE_TO_STRING(secp256k1_ecdsa_signature, secp256k1_ecdsa_signature)

View file

@ -16,26 +16,29 @@ typedef u64 bigsize;
#define printwire_bigsize printwire_u64
struct wireaddr;
void printwire_u8(const char *fieldname, const u8 *v);
void printwire_u16(const char *fieldname, const u16 *v);
void printwire_u32(const char *fieldname, const u32 *v);
void printwire_u64(const char *fieldname, const u64 *v);
void printwire_u8_array(const char *fieldname, const u8 **cursor, size_t *plen, size_t len);
bool printwire_u8(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_u16(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_u32(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_u64(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_tu16(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_tu32(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_tu64(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_u8_array(const char *fieldname, const u8 **cursor, size_t *plen, size_t len);
bool printwire_tlvs(const char *tlv_name, const u8 **cursor, size_t *plen,
const struct tlv_print_record_type types[], size_t num_types);
void printwire_bitcoin_blkid(const char *fieldname, const struct bitcoin_blkid *bitcoin_blkid);
void printwire_wireaddr(const char *fieldname, const struct wireaddr *wireaddr);
void printwire_bitcoin_txid(const char *fieldname, const struct bitcoin_txid *bitcoin_txid);
void printwire_channel_id(const char *fieldname, const struct channel_id *channel_id);
void printwire_amount_sat(const char *fieldname, const struct amount_sat *sat);
void printwire_amount_msat(const char *fieldname, const struct amount_msat *msat);
void printwire_preimage(const char *fieldname, const struct preimage *preimage);
void printwire_pubkey(const char *fieldname, const struct pubkey *pubkey);
void printwire_node_id(const char *fieldname, const struct node_id *id);
void printwire_secp256k1_ecdsa_signature(const char *fieldname, const secp256k1_ecdsa_signature *);
void printwire_sha256(const char *fieldname, const struct sha256 *sha256);
void printwire_secret(const char *fieldname, const struct secret *secret);
void printwire_short_channel_id(const char *fieldname, const struct short_channel_id *short_channel_id);
bool printwire_bitcoin_blkid(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_wireaddr(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_bitcoin_txid(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_channel_id(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_amount_sat(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_amount_msat(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_preimage(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_pubkey(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_node_id(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_secp256k1_ecdsa_signature(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_sha256(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_secret(const char *fieldname, const u8 **cursor, size_t *plen);
bool printwire_short_channel_id(const char *fieldname, const u8 **cursor, size_t *plen);
#endif /* LIGHTNING_DEVTOOLS_PRINT_WIRE_H */

View file

@ -59,39 +59,14 @@ bool print${options.enum_name}_message(const u8 *msg)
% else:
for (size_t i = 0; i < ${f.size()}; i++) {
% endif
printf("{\n");
% if f.type_obj.is_subtype() or f.type_obj.is_varsize():
printf("{\n");
printwire_${f.type_obj.name}(tal_fmt(NULL, "%s.${f.name}", fieldname), cursor, plen);
printf("}\n");
% else:
${f.type_obj.type_name()} v;
% if f.type_obj.is_assignable():
v = fromwire_${f.type_obj.name}(cursor, plen);
% else:
fromwire_${f.type_obj.name}(cursor, plen, &v);
% endif
${truncate_check()}
<% typename = f.type_obj.name if not f.type_obj.is_truncated() else f.type_obj.name[1:] %>\
printwire_${typename}(tal_fmt(NULL, "%s.${f.name}", fieldname), &v);
% endif
if (!printwire_${f.type_obj.name}(tal_fmt(NULL, "%s.${f.name}", fieldname), cursor, plen))
return false;
}
printf("]");
% endif
${truncate_check()} \
% elif f.type_obj.is_subtype() or f.type_obj.is_varsize():
printf("{\n");
printwire_${f.type_obj.name}(tal_fmt(NULL, "%s.${f.name}", fieldname), cursor, plen);
printf("}\n");
% else:
% if f.type_obj.is_assignable():
${f.type_obj.type_name()} ${f.name} = fromwire_${f.type_obj.name}(cursor, plen);
% else:
${f.type_obj.type_name()} ${f.name};
fromwire_${f.type_obj.name}(cursor, plen, &${f.name});
% endif
<% typename = f.type_obj.name if not f.type_obj.is_truncated() else f.type_obj.name[1:] %>
printwire_${typename}(tal_fmt(NULL, "%s.${f.name}", fieldname), &${f.name}); ${truncate_check()} \
if (!printwire_${f.type_obj.name}(tal_fmt(NULL, "%s.${f.name}", fieldname), cursor, plen))
return false;
% endif
% endfor
</%def> \

View file

@ -13,7 +13,11 @@ enum test_enum fromwire_test_enum(const u8 **cursor, size_t *max)
return TEST_ONE;
}
void printwire_test_enum(const char *fieldname, const enum test_enum *test_enum)
bool printwire_test_enum(const char *fieldname, const u8 **cursor, size_t *max)
{
printf("%u\n", *test_enum);
enum test_enum e = fromwire_test_enum(cursor, max);
if (!*cursor)
return false;
printf("%u\n", e);
return true;
}

View file

@ -2,6 +2,7 @@
#define LIGHTNING_TOOLS_TEST_ENUM_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <stdbool.h>
#include <stdlib.h>
#define TEST_IFDEF 0
@ -13,6 +14,6 @@ enum test_enum {
void towire_test_enum(u8 **pptr, const enum test_enum test_enum);
enum test_enum fromwire_test_enum(const u8 **cursor, size_t *max);
void printwire_test_enum(const char *fieldname, const enum test_enum *test_enum);
bool printwire_test_enum(const char *fieldname, const u8 **cursor, size_t *max);
#endif /* LIGHTNING_TOOLS_TEST_ENUM_H */

View file

@ -10,24 +10,31 @@
/* Generated stub for fromwire_peektype */
int fromwire_peektype(const u8 *cursor UNNEEDED)
{ fprintf(stderr, "fromwire_peektype called!\n"); abort(); }
/* Could not find declaration for fromwire_test_enum */
/* Generated stub for printwire_amount_msat */
void printwire_amount_msat(const char *fieldname UNNEEDED, const struct amount_msat *msat UNNEEDED)
bool printwire_amount_msat(const char *fieldname UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "printwire_amount_msat called!\n"); abort(); }
/* Generated stub for printwire_tlvs */
bool printwire_tlvs(const char *tlv_name UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED,
const struct tlv_print_record_type types[] UNNEEDED, size_t num_types UNNEEDED)
{ fprintf(stderr, "printwire_tlvs called!\n"); abort(); }
/* Generated stub for printwire_tu32 */
bool printwire_tu32(const char *fieldname UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "printwire_tu32 called!\n"); abort(); }
/* Generated stub for printwire_tu64 */
bool printwire_tu64(const char *fieldname UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "printwire_tu64 called!\n"); abort(); }
/* Generated stub for printwire_u16 */
void printwire_u16(const char *fieldname UNNEEDED, const u16 *v UNNEEDED)
bool printwire_u16(const char *fieldname UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "printwire_u16 called!\n"); abort(); }
/* Generated stub for printwire_u32 */
void printwire_u32(const char *fieldname UNNEEDED, const u32 *v UNNEEDED)
bool printwire_u32(const char *fieldname UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "printwire_u32 called!\n"); abort(); }
/* Generated stub for printwire_u64 */
void printwire_u64(const char *fieldname UNNEEDED, const u64 *v UNNEEDED)
bool printwire_u64(const char *fieldname UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "printwire_u64 called!\n"); abort(); }
/* Generated stub for printwire_u8_array */
void printwire_u8_array(const char *fieldname UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED, size_t len UNNEEDED)
bool printwire_u8_array(const char *fieldname UNNEEDED, const u8 **cursor UNNEEDED, size_t *plen UNNEEDED, size_t len UNNEEDED)
{ fprintf(stderr, "printwire_u8_array called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */