diff --git a/openingd/common.c b/openingd/common.c index 92a0e9b22..7ee1f34e1 100644 --- a/openingd/common.c +++ b/openingd/common.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -210,6 +211,43 @@ u8 *no_upfront_shutdown_script(const tal_t *ctx, return NULL; } +char *validate_remote_upfront_shutdown(const tal_t *ctx, + struct feature_set *our_features, + const u8 *their_features, + u8 *shutdown_scriptpubkey STEALS, + u8 **state_script) +{ + bool anysegwit = feature_negotiated(our_features, + their_features, + OPT_SHUTDOWN_ANYSEGWIT); + bool anchors = feature_negotiated(our_features, + their_features, + OPT_ANCHOR_OUTPUTS) + || feature_negotiated(our_features, + their_features, + OPT_ANCHORS_ZERO_FEE_HTLC_TX); + + /* BOLT #2: + * + * - MUST include `upfront_shutdown_script` with either a valid + * `shutdown_scriptpubkey` as required by `shutdown` `scriptpubkey`, + * or a zero-length `shutdown_scriptpubkey` (ie. `0x0000`). + */ + /* We turn empty into NULL. */ + if (tal_bytelen(shutdown_scriptpubkey) == 0) + shutdown_scriptpubkey = tal_free(shutdown_scriptpubkey); + + *state_script = tal_steal(ctx, shutdown_scriptpubkey); + + if (shutdown_scriptpubkey + && !valid_shutdown_scriptpubkey(shutdown_scriptpubkey, anysegwit, !anchors)) + return tal_fmt(tmpctx, + "Unacceptable upfront_shutdown_script %s", + tal_hex(tmpctx, shutdown_scriptpubkey)); + return NULL; +} + + void validate_initial_commitment_signature(int hsm_fd, struct bitcoin_tx *tx, struct bitcoin_signature *sig) diff --git a/openingd/common.h b/openingd/common.h index 99914cf7c..86a2be41d 100644 --- a/openingd/common.h +++ b/openingd/common.h @@ -26,4 +26,10 @@ u8 *no_upfront_shutdown_script(const tal_t *ctx, void validate_initial_commitment_signature(int hsm_fd, struct bitcoin_tx *tx, struct bitcoin_signature *sig); + +char *validate_remote_upfront_shutdown(const tal_t *ctx, + struct feature_set *our_features, + const u8 *their_features, + u8 *shutdown_scriptpubkey STEALS, + u8 **state_script); #endif /* LIGHTNING_OPENINGD_COMMON_H */ diff --git a/openingd/openingd.c b/openingd/openingd.c index 2f0b7a08f..33f886aee 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -287,35 +286,15 @@ static bool setup_channel_funder(struct state *state) static void set_remote_upfront_shutdown(struct state *state, u8 *shutdown_scriptpubkey STEALS) { - bool anysegwit = feature_negotiated(state->our_features, - state->their_features, - OPT_SHUTDOWN_ANYSEGWIT); - bool anchors = feature_negotiated(state->our_features, - state->their_features, - OPT_ANCHOR_OUTPUTS) - || feature_negotiated(state->our_features, - state->their_features, - OPT_ANCHORS_ZERO_FEE_HTLC_TX); + char *err; - /* BOLT #2: - * - * - MUST include `upfront_shutdown_script` with either a valid - * `shutdown_scriptpubkey` as required by `shutdown` `scriptpubkey`, - * or a zero-length `shutdown_scriptpubkey` (ie. `0x0000`). - */ - /* We turn empty into NULL. */ - if (tal_bytelen(shutdown_scriptpubkey) == 0) - shutdown_scriptpubkey = tal_free(shutdown_scriptpubkey); + err = validate_remote_upfront_shutdown(state, state->our_features, + state->their_features, + shutdown_scriptpubkey, + &state->upfront_shutdown_script[REMOTE]); - state->upfront_shutdown_script[REMOTE] - = tal_steal(state, shutdown_scriptpubkey); - - if (shutdown_scriptpubkey - && !valid_shutdown_scriptpubkey(shutdown_scriptpubkey, anysegwit, !anchors)) - peer_failed_err(state->pps, - &state->channel_id, - "Unacceptable upfront_shutdown_script %s", - tal_hex(tmpctx, shutdown_scriptpubkey)); + if (err) + peer_failed_err(state->pps, &state->channel_id, "%s", err); } /* We start the 'open a channel' negotation with the supplied peer, but