From 79712de8880d3fda4dfe02ee2e81ecf760dbc35c Mon Sep 17 00:00:00 2001 From: niftynei Date: Fri, 7 Aug 2020 11:35:32 -0500 Subject: [PATCH] psbt-utils: ignore the 'unknown' map for input + output comparison There's no stable ordering on unknown serialization, so linearizing identical but mis-ordered unknown data will lead to 'wrong' results. Instead, we just ignore any data that's in the psbt unknown struct. There's probably also problems here with other PSBT maps. Really, this needs a finer grained comparison function .... fuck --- common/psbt_open.c | 9 +++++++-- common/test/run-psbt_diff.c | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/common/psbt_open.c b/common/psbt_open.c index eb9201b423c3..2061a17968ca 100644 --- a/common/psbt_open.c +++ b/common/psbt_open.c @@ -61,11 +61,13 @@ static const u8 *linearize_input(const tal_t *ctx, struct wally_psbt *psbt = create_psbt(NULL, 1, 0); size_t byte_len; - if (wally_tx_add_input(psbt->tx, tx_in) != WALLY_OK) abort(); psbt->inputs[0] = *in; psbt->num_inputs++; + /* Blank out unknowns. These are unordered and serializing + * them might have different outputs for identical data */ + psbt->inputs[0].unknowns.num_items = 0; const u8 *bytes = psbt_get_bytes(ctx, psbt, &byte_len); @@ -89,8 +91,12 @@ static const u8 *linearize_output(const tal_t *ctx, if (wally_tx_add_output(psbt->tx, tx_out) != WALLY_OK) abort(); + psbt->outputs[0] = *out; psbt->num_outputs++; + /* Blank out unknowns. These are unordered and serializing + * them might have different outputs for identical data */ + psbt->outputs[0].unknowns.num_items = 0; const u8 *bytes = psbt_get_bytes(ctx, psbt, &byte_len); @@ -127,7 +133,6 @@ static bool output_identical(const struct wally_psbt *a, const u8 *b_out = linearize_output(tmpctx, &b->outputs[b_index], &b->tx->outputs[b_index]); - return memeq(a_out, tal_bytelen(a_out), b_out, tal_bytelen(b_out)); } diff --git a/common/test/run-psbt_diff.c b/common/test/run-psbt_diff.c index 337a34853701..d7476448a3e5 100644 --- a/common/test/run-psbt_diff.c +++ b/common/test/run-psbt_diff.c @@ -171,6 +171,21 @@ int main(int argc, const char *argv[]) diff_count(start, end, 1, 1); diff_count(end, start, 1, 1); + /* Add some extra unknown info to a PSBT */ + psbt_input_add_max_witness_len(&end->inputs[1], 100); + psbt_input_add_max_witness_len(&start->inputs[1], 100); + + /* Swap locations */ + struct wally_map_item tmp; + tmp = end->inputs[1].unknowns.items[0]; + end->inputs[1].unknowns.items[0] = end->inputs[1].unknowns.items[1]; + end->inputs[1].unknowns.items[1] = tmp; + + /* We expect nothing to change ? */ + /* FIXME: stable ordering of unknowns ? */ + diff_count(start, end, 1, 1); + diff_count(end, start, 1, 1); + /* No memory leaks please */ common_shutdown(); return 0;