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
This commit is contained in:
niftynei 2020-08-07 11:35:32 -05:00 committed by Rusty Russell
parent 32e40b2cfc
commit 722fa1df6c
2 changed files with 22 additions and 2 deletions

View File

@ -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));
}

View File

@ -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;