mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 22:45:27 +01:00
df-spec: use an empty bit-set as the basepoint for chan-id at start
> If the peer's revocation basepoint is unknown (e.g. `open_channel2`), > a temporary `channel_id` should be found by using a zeroed out basepoint > for the unknown peer.
This commit is contained in:
parent
31e3bdb42d
commit
a5fedc4e1f
3 changed files with 74 additions and 32 deletions
|
@ -47,6 +47,24 @@ void derive_channel_id_v2(struct channel_id *channel_id,
|
||||||
memcpy(channel_id, &sha, sizeof(*channel_id));
|
memcpy(channel_id, &sha, sizeof(*channel_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void derive_tmp_channel_id(struct channel_id *channel_id,
|
||||||
|
const struct pubkey *opener_basepoint)
|
||||||
|
{
|
||||||
|
struct sha256 sha;
|
||||||
|
|
||||||
|
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2:
|
||||||
|
* If the peer's revocation basepoint is unknown
|
||||||
|
* (e.g. `open_channel2`), a temporary `channel_id` should be
|
||||||
|
* found by using a zeroed out basepoint for the unknown peer.
|
||||||
|
*/
|
||||||
|
u8 der_keys[PUBKEY_CMPR_LEN * 2];
|
||||||
|
memset(der_keys, 0, PUBKEY_CMPR_LEN);
|
||||||
|
pubkey_to_der(der_keys + PUBKEY_CMPR_LEN, opener_basepoint);
|
||||||
|
sha256(&sha, der_keys, sizeof(der_keys));
|
||||||
|
BUILD_ASSERT(sizeof(*channel_id) == sizeof(sha));
|
||||||
|
memcpy(channel_id, &sha, sizeof(*channel_id));
|
||||||
|
}
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* The sending node:
|
* The sending node:
|
||||||
|
|
|
@ -20,14 +20,22 @@ struct channel_id {
|
||||||
/* Define channel_id_eq (no padding) */
|
/* Define channel_id_eq (no padding) */
|
||||||
STRUCTEQ_DEF(channel_id, 0, id);
|
STRUCTEQ_DEF(channel_id, 0, id);
|
||||||
|
|
||||||
|
/* For v1 channel establishment */
|
||||||
void derive_channel_id(struct channel_id *channel_id,
|
void derive_channel_id(struct channel_id *channel_id,
|
||||||
const struct bitcoin_txid *txid, u16 txout);
|
const struct bitcoin_txid *txid, u16 txout);
|
||||||
|
|
||||||
|
/* For v1 channel establishment */
|
||||||
|
void temporary_channel_id(struct channel_id *channel_id);
|
||||||
|
|
||||||
|
/* For v2 channel establishment */
|
||||||
void derive_channel_id_v2(struct channel_id *channel_id,
|
void derive_channel_id_v2(struct channel_id *channel_id,
|
||||||
const struct pubkey *basepoint_1,
|
const struct pubkey *basepoint_1,
|
||||||
const struct pubkey *basepoint_2);
|
const struct pubkey *basepoint_2);
|
||||||
|
|
||||||
void temporary_channel_id(struct channel_id *channel_id);
|
/* For v2 channel establishment */
|
||||||
|
void derive_tmp_channel_id(struct channel_id *channel_id,
|
||||||
|
const struct pubkey *opener_basepoint);
|
||||||
|
|
||||||
/* Marshalling/unmarshalling functions */
|
/* Marshalling/unmarshalling functions */
|
||||||
void towire_channel_id(u8 **pptr, const struct channel_id *channel_id);
|
void towire_channel_id(u8 **pptr, const struct channel_id *channel_id);
|
||||||
void fromwire_channel_id(const u8 **cursor, size_t *max,
|
void fromwire_channel_id(const u8 **cursor, size_t *max,
|
||||||
|
|
|
@ -434,6 +434,13 @@ static void check_channel_id(struct state *state,
|
||||||
id_in));
|
id_in));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_dust(struct tx_state *tx_state,
|
||||||
|
struct amount_sat amount)
|
||||||
|
{
|
||||||
|
return !amount_sat_greater(amount, tx_state->localconf.dust_limit)
|
||||||
|
|| !amount_sat_greater(amount, tx_state->remoteconf.dust_limit);
|
||||||
|
}
|
||||||
|
|
||||||
static void set_reserve(struct tx_state *tx_state,
|
static void set_reserve(struct tx_state *tx_state,
|
||||||
struct amount_sat funding_total,
|
struct amount_sat funding_total,
|
||||||
enum tx_role our_role)
|
enum tx_role our_role)
|
||||||
|
@ -542,7 +549,8 @@ static char *check_balances(const tal_t *ctx,
|
||||||
* - segwit marker + flag
|
* - segwit marker + flag
|
||||||
* - input count
|
* - input count
|
||||||
* - output count
|
* - output count
|
||||||
* - locktime */
|
* - locktime
|
||||||
|
*/
|
||||||
size_t initiator_weight =
|
size_t initiator_weight =
|
||||||
bitcoin_tx_core_weight(psbt->num_inputs,
|
bitcoin_tx_core_weight(psbt->num_inputs,
|
||||||
psbt->num_outputs);
|
psbt->num_outputs);
|
||||||
|
@ -596,12 +604,8 @@ static char *check_balances(const tal_t *ctx,
|
||||||
* - the value of the funding output is
|
* - the value of the funding output is
|
||||||
* less than the `dust_limit`
|
* less than the `dust_limit`
|
||||||
*/
|
*/
|
||||||
if (!amount_sat_greater(output_val,
|
if (is_dust(tx_state, output_val))
|
||||||
tx_state->remoteconf.dust_limit) ||
|
|
||||||
!amount_sat_greater(output_val,
|
|
||||||
tx_state->localconf.dust_limit)) {
|
|
||||||
return "funding output is dust";
|
return "funding output is dust";
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2:
|
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2:
|
||||||
*
|
*
|
||||||
|
@ -667,12 +671,8 @@ static char *check_balances(const tal_t *ctx,
|
||||||
* - the `sats` amount is less than or equal to
|
* - the `sats` amount is less than or equal to
|
||||||
* the `dust_limit`
|
* the `dust_limit`
|
||||||
*/
|
*/
|
||||||
if (!amount_sat_greater(amt,
|
if (is_dust(tx_state, amt))
|
||||||
tx_state->remoteconf.dust_limit) ||
|
|
||||||
!amount_sat_greater(amt,
|
|
||||||
tx_state->localconf.dust_limit)) {
|
|
||||||
return "output is dust";
|
return "output is dust";
|
||||||
}
|
|
||||||
|
|
||||||
if (is_openers(&psbt->outputs[i].unknowns)) {
|
if (is_openers(&psbt->outputs[i].unknowns)) {
|
||||||
/* Don't add the funding output to
|
/* Don't add the funding output to
|
||||||
|
@ -704,9 +704,9 @@ static char *check_balances(const tal_t *ctx,
|
||||||
* ...
|
* ...
|
||||||
* - the peer's total input satoshis is less than their outputs
|
* - the peer's total input satoshis is less than their outputs
|
||||||
*/
|
*/
|
||||||
if (!amount_sat_greater_eq(tot_input_amt, tot_output_amt)) {
|
/* We check both, why not? */
|
||||||
return "inputs less than total outputs";
|
if (!amount_sat_greater_eq(initiator_inputs, initiator_outs))
|
||||||
}
|
return "initiator inputs less than outputs";
|
||||||
|
|
||||||
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2:
|
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2:
|
||||||
* The receiving node: ...
|
* The receiving node: ...
|
||||||
|
@ -1424,6 +1424,7 @@ static bool run_tx_interactive(struct state *state,
|
||||||
* to a currently added input (or output)
|
* to a currently added input (or output)
|
||||||
*/
|
*/
|
||||||
input_index = psbt_find_serial_input(psbt, serial_id);
|
input_index = psbt_find_serial_input(psbt, serial_id);
|
||||||
|
/* We choose to error/fail negotiation */
|
||||||
if (input_index == -1)
|
if (input_index == -1)
|
||||||
open_err_warn(state,
|
open_err_warn(state,
|
||||||
"No input added with serial_id"
|
"No input added with serial_id"
|
||||||
|
@ -1853,7 +1854,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
||||||
struct bitcoin_blkid chain_hash;
|
struct bitcoin_blkid chain_hash;
|
||||||
struct tlv_opening_tlvs *open_tlv;
|
struct tlv_opening_tlvs *open_tlv;
|
||||||
char *err_reason;
|
char *err_reason;
|
||||||
struct channel_id cid;
|
struct channel_id tmp_chan_id;
|
||||||
u8 *msg;
|
u8 *msg;
|
||||||
struct amount_sat total;
|
struct amount_sat total;
|
||||||
enum dualopend_wire msg_type;
|
enum dualopend_wire msg_type;
|
||||||
|
@ -1863,7 +1864,7 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
||||||
open_tlv = tlv_opening_tlvs_new(tmpctx);
|
open_tlv = tlv_opening_tlvs_new(tmpctx);
|
||||||
|
|
||||||
if (!fromwire_open_channel2(oc2_msg, &chain_hash,
|
if (!fromwire_open_channel2(oc2_msg, &chain_hash,
|
||||||
&state->channel_id,
|
&state->channel_id, /* Temporary! */
|
||||||
&state->feerate_per_kw_funding,
|
&state->feerate_per_kw_funding,
|
||||||
&state->feerate_per_kw_commitment,
|
&state->feerate_per_kw_commitment,
|
||||||
&tx_state->opener_funding,
|
&tx_state->opener_funding,
|
||||||
|
@ -1890,6 +1891,27 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
||||||
} else
|
} else
|
||||||
state->upfront_shutdown_script[REMOTE] = NULL;
|
state->upfront_shutdown_script[REMOTE] = NULL;
|
||||||
|
|
||||||
|
/* BOLT-* #2
|
||||||
|
* If the peer's revocation basepoint is unknown (e.g.
|
||||||
|
* `open_channel2`), a temporary `channel_id` should be found
|
||||||
|
* by using a zeroed out basepoint for the unknown peer.
|
||||||
|
*/
|
||||||
|
derive_tmp_channel_id(&tmp_chan_id,
|
||||||
|
&state->their_points.revocation);
|
||||||
|
if (!channel_id_eq(&state->channel_id, &tmp_chan_id))
|
||||||
|
negotiation_failed(state, "open_channel2 channel_id incorrect."
|
||||||
|
" Expected %s, received %s",
|
||||||
|
type_to_string(tmpctx, struct channel_id,
|
||||||
|
&tmp_chan_id),
|
||||||
|
type_to_string(tmpctx, struct channel_id,
|
||||||
|
&state->channel_id));
|
||||||
|
|
||||||
|
/* Everything's ok. Let's figure out the actual channel_id now */
|
||||||
|
derive_channel_id_v2(&state->channel_id,
|
||||||
|
&state->our_points.revocation,
|
||||||
|
&state->their_points.revocation);
|
||||||
|
|
||||||
|
|
||||||
/* Save feerate on the tx_state as well */
|
/* Save feerate on the tx_state as well */
|
||||||
tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding;
|
tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding;
|
||||||
|
|
||||||
|
@ -1925,13 +1947,8 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can figure out the channel id now */
|
|
||||||
derive_channel_id_v2(&cid,
|
|
||||||
&state->our_points.revocation,
|
|
||||||
&state->their_points.revocation);
|
|
||||||
|
|
||||||
msg = towire_dualopend_got_offer(NULL,
|
msg = towire_dualopend_got_offer(NULL,
|
||||||
&cid,
|
&state->channel_id,
|
||||||
tx_state->opener_funding,
|
tx_state->opener_funding,
|
||||||
tx_state->remoteconf.dust_limit,
|
tx_state->remoteconf.dust_limit,
|
||||||
tx_state->remoteconf.max_htlc_value_in_flight,
|
tx_state->remoteconf.max_htlc_value_in_flight,
|
||||||
|
@ -1965,9 +1982,6 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
|
||||||
* the original feerate we'll base any increases off of. */
|
* the original feerate we'll base any increases off of. */
|
||||||
state->feerate_per_kw_funding = tx_state->feerate_per_kw_funding;
|
state->feerate_per_kw_funding = tx_state->feerate_per_kw_funding;
|
||||||
|
|
||||||
/* Set the channel id now */
|
|
||||||
state->channel_id = cid;
|
|
||||||
|
|
||||||
if (!tx_state->psbt)
|
if (!tx_state->psbt)
|
||||||
tx_state->psbt = create_psbt(tx_state, 0, 0,
|
tx_state->psbt = create_psbt(tx_state, 0, 0,
|
||||||
tx_state->tx_locktime);
|
tx_state->tx_locktime);
|
||||||
|
@ -2353,11 +2367,13 @@ static void opener_start(struct state *state, u8 *msg)
|
||||||
tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding;
|
tx_state->feerate_per_kw_funding = state->feerate_per_kw_funding;
|
||||||
open_tlv = tlv_opening_tlvs_new(tmpctx);
|
open_tlv = tlv_opening_tlvs_new(tmpctx);
|
||||||
|
|
||||||
/* Set the channel_id to a temporary id, we'll update
|
/* BOLT-* #2
|
||||||
* this as soon as we hear back from accept, but if they
|
* If the peer's revocation basepoint is unknown (e.g.
|
||||||
* send us an error in the meantime, we need to be able to
|
* `open_channel2`), a temporary `channel_id` should be found
|
||||||
* understand it */
|
* by using a zeroed out basepoint for the unknown peer.
|
||||||
temporary_channel_id(&state->channel_id);
|
*/
|
||||||
|
derive_tmp_channel_id(&state->channel_id,
|
||||||
|
&state->our_points.revocation);
|
||||||
|
|
||||||
if (!state->upfront_shutdown_script[LOCAL])
|
if (!state->upfront_shutdown_script[LOCAL])
|
||||||
state->upfront_shutdown_script[LOCAL]
|
state->upfront_shutdown_script[LOCAL]
|
||||||
|
@ -2432,7 +2448,7 @@ static void opener_start(struct state *state, u8 *msg)
|
||||||
} else
|
} else
|
||||||
state->upfront_shutdown_script[REMOTE] = NULL;
|
state->upfront_shutdown_script[REMOTE] = NULL;
|
||||||
|
|
||||||
/* Now we can set the 'real channel id' */
|
/* Now we know the 'real channel id' */
|
||||||
derive_channel_id_v2(&state->channel_id,
|
derive_channel_id_v2(&state->channel_id,
|
||||||
&state->our_points.revocation,
|
&state->our_points.revocation,
|
||||||
&state->their_points.revocation);
|
&state->their_points.revocation);
|
||||||
|
|
Loading…
Add table
Reference in a new issue