Skip to content
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -2918,6 +2918,26 @@ static size_t calc_weight(enum tx_role role, const struct wally_psbt *psbt)
return weight;
}

/* Get the non-initiator (acceptor) amount after the splice */
static struct amount_msat splice_acceptor_balance(struct peer *peer,
enum tx_role our_role)
{
struct amount_msat acceptor_value;

/* Start with the acceptor's balance before the splice */
acceptor_value =
peer->channel->view->owed[our_role == TX_INITIATOR ? REMOTE : LOCAL];

/* Adjust by the acceptor's relative splice amount (signed) */
if (!amount_msat_add_sat_s64(&acceptor_value, acceptor_value,
peer->splicing->accepter_relative))
peer_failed_warn(
peer->pps, &peer->channel_id,
"Unable to add accepter's relative splice to prior balance.");

return acceptor_value;
}

/* Returns the total channel funding output amount if all checks pass.
* Otherwise, exits via peer_failed_warn. DTODO: Change to `tx_abort`. */
static struct amount_sat check_balances(struct peer *peer,
Expand Down Expand Up @@ -3450,6 +3470,39 @@ static struct inflight *inflights_new(struct peer *peer)
return inf;
}

static void update_hsmd_with_splice(struct peer *peer,
struct inflight *inflight,
const struct amount_msat push_val)
{
u8 *msg;

/* local_upfront_shutdown_script, local_upfront_shutdown_wallet_index,
* remote_upfront_shutdown_script aren't allowed to change, so we
* don't need to gather them */
msg = towire_hsmd_setup_channel(
NULL,
peer->channel->opener == LOCAL,
inflight->amnt,
push_val,
&inflight->outpoint.txid,
inflight->outpoint.n,
peer->channel->config[LOCAL].to_self_delay,
/*local_upfront_shutdown_script*/ NULL,
/*local_upfront_shutdown_wallet_index*/ NULL,
&peer->channel->basepoints[REMOTE],
&peer->channel->funding_pubkey[REMOTE],
Copy link
Member

@devrandom devrandom Sep 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the funding pubkey is allowed to vary in the splice, and we need to be involved in that. I'm wondering where that happens and how we will be informed of the remote one (and asked about the local one).

(note that the funding keys will be the same for all splice candidates)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to be involved in that

Are you saying that roundtrips/protocol is missing?

how we will be informed of the remote one

I think we are being informed with this call. Am I missing something?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

funding pubkey is allowed to vary in the splice

https://github.com/lightning-signer/c-lightning/blob/2023-08-explore-splicing/channeld/channeld.c#L3536-L3539

That seems to imply it is not changing?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each of the prior is one side, presume there are similar in the other "direction"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the spec allows for it to change (for the whole splice, not per RBF candidate). we should ask the CLN team about this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just scoured the spec looking for where it is allowed to change ... can you point me to it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/lightning/bolts/pull/863/files#diff-ed04ca2c673fd6aabde69389511fa9ee60cb44d6b2ef6c88b549ffaa753d6afeR522

    type: 74 (splice)

    data:
        [chain_hash:chain_hash]
        [channel_id:channel_id]
        [u64:funding_satoshis]
        [u32:funding_feerate_perkw]
        [u32:locktime]
        [point:funding_pubkey]

    type: 76 (splice_ack)

    data:
        [chain_hash:chain_hash]
        [channel_id:channel_id]
        [u64:funding_satoshis]
        [point:funding_pubkey]

Copy link
Member

@devrandom devrandom Sep 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like CLN explicitly doesn't support changing them (they send an error to the peer if the key changes), but I assume that will be fixed before release. need to ask them.

peer->channel->config[REMOTE].to_self_delay,
/*remote_upfront_shutdown_script*/ NULL,
peer->channel->type);

wire_sync_write(HSM_FD, take(msg));
msg = wire_sync_read(tmpctx, HSM_FD);
if (!fromwire_hsmd_setup_channel_reply(msg))
status_failed(STATUS_FAIL_HSM_IO, "Bad ready_channel_reply %s",
tal_hex(tmpctx, msg));
}


/* ACCEPTER side of the splice. Here we handle all the accepter's steps for the
* splice. Since the channel must be in STFU mode we block the daemon here until
* the splice is finished or aborted. */
Expand Down Expand Up @@ -3586,6 +3639,10 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg)
new_inflight->last_tx = NULL;
new_inflight->i_am_initiator = false;

update_hsmd_with_splice(peer,
new_inflight,
splice_acceptor_balance(peer, TX_ACCEPTER));

update_view_from_inflights(peer);

peer->splice_state->count++;
Expand Down Expand Up @@ -3820,6 +3877,10 @@ static void splice_initiator_user_finalized(struct peer *peer)
new_inflight->last_tx = NULL;
new_inflight->i_am_initiator = true;

update_hsmd_with_splice(peer,
new_inflight,
splice_acceptor_balance(peer, TX_INITIATOR));

update_view_from_inflights(peer);

peer->splice_state->count++;
Expand Down
43 changes: 32 additions & 11 deletions common/psbt_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,33 +379,54 @@ u64 psbt_new_output_serial(struct wally_psbt *psbt, enum tx_role role)
return serial_id;
}

#include <stdio.h>
#include <common/type_to_string.h>

bool psbt_has_required_fields(struct wally_psbt *psbt)
{
psbt_set_version(psbt, 0);
fprintf(stderr, "wally_psbt: %s\n", type_to_string(tmpctx, struct wally_psbt, psbt));
psbt_set_version(psbt, 2);

u64 serial_id;
for (size_t i = 0; i < psbt->num_inputs; i++) {
const struct wally_map_item *redeem_script;
struct wally_psbt_input *input = &psbt->inputs[i];

if (!psbt_get_serial_id(&input->unknowns, &serial_id))
if (!psbt_get_serial_id(&input->unknowns, &serial_id)) {
fprintf(stderr, "in[%ld]: missing serial id\n", i);
return false;
}

/* Required because we send the full tx over the wire now */
if (!input->utxo)
/* Only insist on PSBT_IN_NON_WITNESS_UTXO (.utxo) if
* PSBT_IN_WITNESS_UTXO (.witness_utxo) is not present
* because PSBT_IN_NON_WITNESS_UTXO uses a lot of
* memory */
if (!input->witness_utxo && !input->utxo) {
fprintf(stderr, "in[%ld]: missing both utxo\n", i);
return false;
}

/* If is P2SH, redeemscript must be present */
assert(psbt->inputs[i].index < input->utxo->num_outputs);
const u8 *outscript =
wally_tx_output_get_script(tmpctx,
&input->utxo->outputs[psbt->inputs[i].index]);
redeem_script = wally_map_get_integer(&psbt->inputs[i].psbt_fields, /* PSBT_IN_REDEEM_SCRIPT */ 0x04);
if (is_p2sh(outscript, NULL) && (!redeem_script || redeem_script->value_len == 0))
return false;
if (input->utxo) {
/* If is P2SH, redeemscript must be present */
assert(psbt->inputs[i].index < input->utxo->num_outputs);
const u8 *outscript =
wally_tx_output_get_script(tmpctx,
&input->utxo->outputs[psbt->inputs[i].index]);
redeem_script = wally_map_get_integer(&psbt->inputs[i].psbt_fields, /* PSBT_IN_REDEEM_SCRIPT */ 0x04);
if (is_p2sh(outscript, NULL) && (!redeem_script || redeem_script->value_len == 0)) {
fprintf(stderr, "in[%ld]: missing redeemscript\n", i);
return false;
}
}
}

for (size_t i = 0; i < psbt->num_outputs; i++) {
if (!psbt_get_serial_id(&psbt->outputs[i].unknowns, &serial_id))
if (!psbt_get_serial_id(&psbt->outputs[i].unknowns, &serial_id)) {
fprintf(stderr, "out[%ld]: missing serial id\n", i);
return false;
}
}

return true;
Expand Down
Loading