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