There's a few ground rules here about how we store/keep * the PSBT input/outputs in such a way that we can Do The * Right Thing for each of our peers. * * Core Lightning will make sure that our peer isn't removing/adding * any updates that it's not allowed to (i.e. ours or a different * node's that we're pretending are 'ours'). * * The parent copy of the PSBT has all of the inputs/outputs
| 62 | * The peer's inputs/outputs updates are then copied to the parent psbt. |
| 63 | */ |
| 64 | static bool update_parent_psbt(const tal_t *ctx, |
| 65 | struct multifundchannel_destination *dest, |
| 66 | struct wally_psbt *old_node_psbt, |
| 67 | struct wally_psbt *new_node_psbt, |
| 68 | struct wally_psbt **parent_psbt) |
| 69 | { |
| 70 | struct psbt_changeset *changes; |
| 71 | struct wally_psbt *clone, *new_node_copy; |
| 72 | |
| 73 | /* Clone the parent, so we don't make any changes to it |
| 74 | * until we've succesfully done everything */ |
| 75 | |
| 76 | /* Only failure is alloc, should we even check? */ |
| 77 | tal_wally_start(); |
| 78 | if (wally_psbt_clone_alloc(*parent_psbt, 0, &clone) != WALLY_OK) |
| 79 | abort(); |
| 80 | tal_wally_end_onto(ctx, clone, struct wally_psbt); |
| 81 | |
| 82 | /* This makes it such that we can reparent/steal added |
| 83 | * inputs/outputs without impacting the 'original'. We |
| 84 | * could avoid this if there was a 'wally_psbt_input_clone_into' |
| 85 | * function, or the like */ |
| 86 | tal_wally_start(); |
| 87 | if (wally_psbt_clone_alloc(new_node_psbt, 0, &new_node_copy) |
| 88 | != WALLY_OK) |
| 89 | abort(); |
| 90 | /* copy is cleaned up below, but we need parts we steal from it |
| 91 | * owned by the clone. */ |
| 92 | tal_wally_end(clone); |
| 93 | |
| 94 | changes = psbt_get_changeset(NULL, old_node_psbt, |
| 95 | new_node_copy); |
| 96 | /* Inputs */ |
| 97 | for (size_t i = 0; i < tal_count(changes->added_ins); i++) { |
| 98 | u64 serial; |
| 99 | int s_idx; |
| 100 | const struct wally_psbt_input *in = |
| 101 | &changes->added_ins[i].input; |
| 102 | size_t idx = clone->num_inputs; |
| 103 | |
| 104 | if (!psbt_get_serial_id(&in->unknowns, &serial)) |
| 105 | goto fail; |
| 106 | |
| 107 | /* Ignore any input that's ours */ |
| 108 | if (serial % 2 == TX_INITIATOR) |
| 109 | continue; |
| 110 | |
| 111 | /* Check that serial does not exist on parent already */ |
| 112 | s_idx = psbt_find_serial_input(clone, serial - 1); |
| 113 | if (s_idx != -1) |
| 114 | goto fail; |
| 115 | |
| 116 | const struct wally_psbt_input *input = &changes->added_ins[i].input; |
| 117 | struct bitcoin_outpoint outpoint; |
| 118 | wally_psbt_input_get_outpoint(input, &outpoint); |
| 119 | psbt_append_input(clone, |
| 120 | &outpoint, |
| 121 | input->sequence, |
no test coverage detected