spec: update to latest dual-funding wire changes

the witnesses are maddeningly weird now (you concat everything together)

we also changed some things to be s64's (it's a teeny tiny change)
This commit is contained in:
niftynei 2023-06-29 15:03:50 -05:00 committed by Rusty Russell
parent 388f27edce
commit 0cd7fe5089
6 changed files with 177 additions and 79 deletions

View file

@ -2091,7 +2091,7 @@ static void handle_peer_shutdown(struct peer *peer, const u8 *shutdown)
static void handle_unexpected_tx_sigs(struct peer *peer, const u8 *msg)
{
const struct witness_stack **ws;
const struct witness **witnesses;
struct channel_id cid;
struct bitcoin_txid txid;
@ -2099,7 +2099,7 @@ static void handle_unexpected_tx_sigs(struct peer *peer, const u8 *msg)
* This happens when they've/we've exchanged channel_ready,
* but they did not receive our channel_ready. */
if (!fromwire_tx_signatures(tmpctx, msg, &cid, &txid,
cast_const3(struct witness_stack ***, &ws)))
cast_const3(struct witness ***, &witnesses)))
peer_failed_warn(peer->pps, &peer->channel_id,
"Bad tx_signatures %s",
tal_hex(msg, msg));

View file

@ -1,33 +1,97 @@
#include "config.h"
#include <assert.h>
#include <bitcoin/psbt.h>
#include <bitcoin/script.h>
#include <bitcoin/varint.h>
#include <common/psbt_internal.h>
#include <common/psbt_open.h>
#include <wire/peer_wire.h>
static bool next_size(const u8 **cursor, size_t *max, size_t *size)
{
size_t len;
varint_t varint;
if (*max < 1)
return false;
len = varint_get(*cursor, *max, &varint);
if (len < 1)
return false;
if (*max < len) {
*max = 0;
return false;
}
*cursor += len;
*max -= len;
*size = varint;
return true;
}
static u8 *next_script(const tal_t *ctx, const u8 **cursor, size_t *max)
{
const u8 *p;
size_t size;
u8 *ret;
if (!next_size(cursor, max, &size))
return NULL;
if (*max < size) {
*max = 0;
return NULL;
}
p = *cursor;
*max -= size;
*cursor += size;
ret = tal_arr(ctx, u8, size);
memcpy(ret, p, size);
return ret;
}
static void
psbt_input_set_final_witness_stack(const tal_t *ctx,
struct wally_psbt_input *in,
const struct witness_element **elements)
const struct witness *witness)
{
u8 *script, *sctx;
const u8 *data = witness->witness_data;
size_t size, max = tal_count(data);
bool ok;
wally_tx_witness_stack_free(in->final_witness);
tal_wally_start();
wally_tx_witness_stack_init_alloc(tal_count(elements),
&in->final_witness);
/* FIXME: return an error?? */
if (!next_size(&data, &max, &size))
return;
tal_wally_start();
sctx = tal(NULL, u8);
wally_tx_witness_stack_init_alloc(size, &in->final_witness);
while ((script = next_script(sctx, &data, &max)) && script != NULL) {
ok = (wally_tx_witness_stack_add(in->final_witness,
script, tal_count(script)) == WALLY_OK);
assert(ok);
}
for (size_t i = 0; i < tal_count(elements); i++)
wally_tx_witness_stack_add(in->final_witness,
elements[i]->witness_data,
tal_bytelen(elements[i]->witness_data));
tal_wally_end(ctx);
tal_free(sctx);
}
void psbt_finalize_input(const tal_t *ctx,
struct wally_psbt_input *in,
const struct witness_element **elements)
const struct witness *witness)
{
const struct wally_map_item *redeem_script;
psbt_input_set_final_witness_stack(ctx, in, elements);
psbt_input_set_final_witness_stack(ctx, in, witness);
/* There's this horrible edgecase where we set the final_witnesses
* directly onto the PSBT, but the input is a P2SH-wrapped input
@ -49,22 +113,20 @@ void psbt_finalize_input(const tal_t *ctx,
}
}
const struct witness_stack **
psbt_to_witness_stacks(const tal_t *ctx,
const struct wally_psbt *psbt,
enum tx_role side_to_stack)
const struct witness **
psbt_to_witnesses(const tal_t *ctx,
const struct wally_psbt *psbt,
enum tx_role side_to_stack)
{
size_t stack_index;
u64 serial_id;
const struct witness_stack **stacks
= tal_arr(ctx, const struct witness_stack *, psbt->num_inputs);
const struct witness **witnesses =
tal_arr(ctx, const struct witness *, 0);
stack_index = 0;
for (size_t i = 0; i < psbt->num_inputs; i++) {
if (!psbt_get_serial_id(&psbt->inputs[i].unknowns,
&serial_id))
/* FIXME: throw an error ? */
return NULL;
return tal_free(witnesses);
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2:
* - if is the *initiator*:
@ -73,32 +135,29 @@ psbt_to_witness_stacks(const tal_t *ctx,
if (serial_id % 2 == side_to_stack) {
struct wally_tx_witness_stack *wtx_s =
psbt->inputs[i].final_witness;
struct witness_stack *stack =
tal(stacks, struct witness_stack);
/* Convert the wally_tx_witness_stack to
* a witness_stack entry */
stack->witness_elements =
tal_arr(stack, struct witness_element *,
wtx_s->num_items);
for (size_t j = 0; j < tal_count(stack->witness_elements); j++) {
stack->witness_elements[j] = tal(stack,
struct witness_element);
stack->witness_elements[j]->witness_data =
tal_dup_arr(stack, u8,
wtx_s->items[j].witness,
wtx_s->items[j].witness_len,
0);
/* BOLT-e299850cb5ebd8bd9c55763bbc498fcdf94a9567 #2:
*
* The `witness_data` is encoded as per bitcoin's
* wire protocol (a CompactSize number of elements,
* with each element a CompactSize length and that
* many bytes following. Each `witness_data` field
* contains all of the witness elements for a single input,
* including the leading counter of elements.
*/
struct witness *wit = tal(witnesses, struct witness);
wit->witness_data = tal_arr(wit, u8, 0);
add_varint(&wit->witness_data, wtx_s->num_items);
for (size_t j = 0; j < wtx_s->num_items; j++) {
add_varint(&wit->witness_data, wtx_s->items[j].witness_len);
tal_expand(&wit->witness_data, wtx_s->items[j].witness,
wtx_s->items[j].witness_len);
}
stacks[stack_index++] = stack;
tal_arr_expand(&witnesses, wit);
}
}
if (stack_index == 0)
return tal_free(stacks);
tal_resize(&stacks, stack_index);
return stacks;
return witnesses;
}

View file

@ -7,7 +7,7 @@
struct wally_psbt;
struct wally_psbt_input;
struct witness_element;
struct witness;
/* psbt_finalize_input - Finalize an input with a given witness stack
*
@ -15,21 +15,22 @@ struct witness_element;
* the redeem_script, if any.
* @ctx - the context to allocate onto
* @in - input to set final_witness for
* @witness_element - elements to add to witness stack
* @witness - witness data to add to witness stack
*/
void psbt_finalize_input(const tal_t *ctx,
struct wally_psbt_input *in,
const struct witness_element **elements);
/* psbt_to_witness_stacks - Take all sigs on a PSBT and copy to a
* witness_stack
const struct witness *witness);
/* psbt_to_witness_stacks - Take a side's sigs from a PSBT and copy to a
* wire witness
*
* @ctx - allocation context
* @psbt - PSBT to copy sigs from
* @opener - which side initiated this tx
* @side_to_stack - which side to stack witnesses of
*/
const struct witness_stack **
psbt_to_witness_stacks(const tal_t *ctx,
const struct wally_psbt *psbt,
enum tx_role side_to_stack);
const struct witness **
psbt_to_witnesses(const tal_t *ctx,
const struct wally_psbt *psbt,
enum tx_role side_to_stack);
#endif /* LIGHTNING_COMMON_PSBT_INTERNAL_H */

View file

@ -1021,9 +1021,8 @@ static u8 *psbt_to_tx_sigs_msg(const tal_t *ctx,
struct state *state,
const struct wally_psbt *psbt)
{
const struct witness_stack **ws =
psbt_to_witness_stacks(tmpctx, psbt,
state->our_role);
const struct witness **ws =
psbt_to_witnesses(tmpctx, psbt, state->our_role);
return towire_tx_signatures(ctx, &state->channel_id,
&state->tx_state->funding.txid,
@ -1034,16 +1033,15 @@ static void handle_tx_sigs(struct state *state, const u8 *msg)
{
struct channel_id cid;
struct bitcoin_txid txid;
const struct witness_stack **ws;
size_t j = 0;
const struct witness **witnesses;
struct tx_state *tx_state = state->tx_state;
enum tx_role their_role = state->our_role == TX_INITIATOR ?
TX_ACCEPTER : TX_INITIATOR;
if (!fromwire_tx_signatures(tmpctx, msg, &cid, &txid,
cast_const3(
struct witness_stack ***,
&ws)))
struct witness ***,
&witnesses)))
open_err_fatal(state, "Bad tx_signatures %s",
tal_hex(msg, msg));
@ -1085,11 +1083,10 @@ static void handle_tx_sigs(struct state *state, const u8 *msg)
&tx_state->funding.txid));
/* We put the PSBT + sigs all together */
for (size_t i = 0; i < tx_state->psbt->num_inputs; i++) {
for (size_t i = 0, j = 0; i < tx_state->psbt->num_inputs; i++) {
struct wally_psbt_input *in =
&tx_state->psbt->inputs[i];
u64 in_serial;
const struct witness_element **elem;
if (!psbt_get_serial_id(&in->unknowns, &in_serial)) {
status_broken("PSBT input %zu missing serial_id %s",
@ -1101,13 +1098,12 @@ static void handle_tx_sigs(struct state *state, const u8 *msg)
if (in_serial % 2 != their_role)
continue;
if (j == tal_count(ws))
open_err_warn(state, "Mismatch witness stack count %s",
if (j == tal_count(witnesses))
open_err_warn(state, "Mismatched witness stack count %s",
tal_hex(msg, msg));
elem = cast_const2(const struct witness_element **,
ws[j++]->witness_elements);
psbt_finalize_input(tx_state->psbt, in, elem);
psbt_finalize_input(tx_state->psbt, in, witnesses[j]);
j++;
}
tx_state->remote_funding_sigs_rcvd = true;
@ -3526,9 +3522,9 @@ static void rbf_local_start(struct state *state, u8 *msg)
tx_state->tx_locktime = locktime;
/* For now, we always just echo/send the funding amount */
init_rbf_tlvs->funding_output_contribution
= tal(init_rbf_tlvs, u64);
= tal(init_rbf_tlvs, s64);
*init_rbf_tlvs->funding_output_contribution
= tx_state->opener_funding.satoshis; /* Raw: wire conversion */
= (s64)tx_state->opener_funding.satoshis; /* Raw: wire conversion */
msg = towire_tx_init_rbf(tmpctx, &state->channel_id,
tx_state->tx_locktime,
@ -3795,9 +3791,9 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
/* We always send the funding amount */
ack_rbf_tlvs->funding_output_contribution
= tal(ack_rbf_tlvs, u64);
= tal(ack_rbf_tlvs, s64);
*ack_rbf_tlvs->funding_output_contribution
= tx_state->accepter_funding.satoshis; /* Raw: wire conversion */
= (s64)tx_state->accepter_funding.satoshis; /* Raw: wire conversion */
msg = towire_tx_ack_rbf(tmpctx, &state->channel_id, ack_rbf_tlvs);
peer_write(state->pps, msg);

View file

@ -0,0 +1,43 @@
--- wire/peer_wire.csv 2023-06-29 14:36:10.986268579 -0500
+++ - 2023-06-29 14:37:45.737004393 -0500
@@ -62,25 +62,22 @@
msgdata,tx_signatures,channel_id,channel_id,
msgdata,tx_signatures,txid,sha256,
msgdata,tx_signatures,num_witnesses,u16,
-msgdata,tx_signatures,witnesses,witness_stack,num_witnesses
-subtype,witness_stack
-subtypedata,witness_stack,num_witness_elements,u16,
-subtypedata,witness_stack,witness_elements,witness_element,num_witness_elements
-subtype,witness_element
-subtypedata,witness_element,len,u16,
-subtypedata,witness_element,witness_data,byte,len
+msgdata,tx_signatures,witnesses,witness,num_witnesses
+subtype,witness
+subtypedata,witness,len,u16,
+subtypedata,witness,witness_data,byte,len
msgtype,tx_init_rbf,72
msgdata,tx_init_rbf,channel_id,channel_id,
msgdata,tx_init_rbf,locktime,u32,
msgdata,tx_init_rbf,feerate,u32,
msgdata,tx_init_rbf,tlvs,tx_init_rbf_tlvs,
tlvtype,tx_init_rbf_tlvs,funding_output_contribution,0
-tlvdata,tx_init_rbf_tlvs,funding_output_contribution,satoshis,tu64,
+tlvdata,tx_init_rbf_tlvs,funding_output_contribution,satoshis,s64,
msgtype,tx_ack_rbf,73
msgdata,tx_ack_rbf,channel_id,channel_id,
msgdata,tx_ack_rbf,tlvs,tx_ack_rbf_tlvs,
tlvtype,tx_ack_rbf_tlvs,funding_output_contribution,0
-tlvdata,tx_ack_rbf_tlvs,funding_output_contribution,satoshis,tu64,
+tlvdata,tx_ack_rbf_tlvs,funding_output_contribution,satoshis,s64,
msgtype,tx_abort,74
msgdata,tx_abort,channel_id,channel_id,
msgdata,tx_abort,len,u16,
@@ -257,6 +235,8 @@
msgdata,channel_reestablish,your_last_per_commitment_secret,byte,32
msgdata,channel_reestablish,my_current_per_commitment_point,point,
msgdata,channel_reestablish,tlvs,channel_reestablish_tlvs,
+tlvtype,channel_reestablish_tlvs,next_funding,0
+tlvdata,channel_reestablish_tlvs,next_funding,next_funding_txid,sha256,
tlvtype,channel_reestablish_tlvs,next_to_send,1
tlvdata,channel_reestablish_tlvs,next_to_send,commitment_number,tu64,
tlvtype,channel_reestablish_tlvs,desired_channel_type,3

View file

@ -62,25 +62,22 @@ msgtype,tx_signatures,71
msgdata,tx_signatures,channel_id,channel_id,
msgdata,tx_signatures,txid,sha256,
msgdata,tx_signatures,num_witnesses,u16,
msgdata,tx_signatures,witnesses,witness_stack,num_witnesses
subtype,witness_stack
subtypedata,witness_stack,num_witness_elements,u16,
subtypedata,witness_stack,witness_elements,witness_element,num_witness_elements
subtype,witness_element
subtypedata,witness_element,len,u16,
subtypedata,witness_element,witness_data,byte,len
msgdata,tx_signatures,witnesses,witness,num_witnesses
subtype,witness
subtypedata,witness,len,u16,
subtypedata,witness,witness_data,byte,len
msgtype,tx_init_rbf,72
msgdata,tx_init_rbf,channel_id,channel_id,
msgdata,tx_init_rbf,locktime,u32,
msgdata,tx_init_rbf,feerate,u32,
msgdata,tx_init_rbf,tlvs,tx_init_rbf_tlvs,
tlvtype,tx_init_rbf_tlvs,funding_output_contribution,0
tlvdata,tx_init_rbf_tlvs,funding_output_contribution,satoshis,tu64,
tlvdata,tx_init_rbf_tlvs,funding_output_contribution,satoshis,s64,
msgtype,tx_ack_rbf,73
msgdata,tx_ack_rbf,channel_id,channel_id,
msgdata,tx_ack_rbf,tlvs,tx_ack_rbf_tlvs,
tlvtype,tx_ack_rbf_tlvs,funding_output_contribution,0
tlvdata,tx_ack_rbf_tlvs,funding_output_contribution,satoshis,tu64,
tlvdata,tx_ack_rbf_tlvs,funding_output_contribution,satoshis,s64,
msgtype,tx_abort,74
msgdata,tx_abort,channel_id,channel_id,
msgdata,tx_abort,len,u16,
@ -267,6 +264,8 @@ msgdata,channel_reestablish,next_revocation_number,u64,
msgdata,channel_reestablish,your_last_per_commitment_secret,byte,32
msgdata,channel_reestablish,my_current_per_commitment_point,point,
msgdata,channel_reestablish,tlvs,channel_reestablish_tlvs,
tlvtype,channel_reestablish_tlvs,next_funding,0
tlvdata,channel_reestablish_tlvs,next_funding,next_funding_txid,sha256,
tlvtype,channel_reestablish_tlvs,next_to_send,1
tlvdata,channel_reestablish_tlvs,next_to_send,commitment_number,tu64,
tlvtype,channel_reestablish_tlvs,desired_channel_type,3

1 msgtype,init,16
62 msgdata,tx_signatures,channel_id,channel_id,
63 msgdata,tx_signatures,txid,sha256,
64 msgdata,tx_signatures,num_witnesses,u16,
65 msgdata,tx_signatures,witnesses,witness_stack,num_witnesses msgdata,tx_signatures,witnesses,witness,num_witnesses
66 subtype,witness_stack subtype,witness
67 subtypedata,witness_stack,num_witness_elements,u16, subtypedata,witness,len,u16,
68 subtypedata,witness_stack,witness_elements,witness_element,num_witness_elements subtypedata,witness,witness_data,byte,len
subtype,witness_element
subtypedata,witness_element,len,u16,
subtypedata,witness_element,witness_data,byte,len
69 msgtype,tx_init_rbf,72
70 msgdata,tx_init_rbf,channel_id,channel_id,
71 msgdata,tx_init_rbf,locktime,u32,
72 msgdata,tx_init_rbf,feerate,u32,
73 msgdata,tx_init_rbf,tlvs,tx_init_rbf_tlvs,
74 tlvtype,tx_init_rbf_tlvs,funding_output_contribution,0
75 tlvdata,tx_init_rbf_tlvs,funding_output_contribution,satoshis,tu64, tlvdata,tx_init_rbf_tlvs,funding_output_contribution,satoshis,s64,
76 msgtype,tx_ack_rbf,73
77 msgdata,tx_ack_rbf,channel_id,channel_id,
78 msgdata,tx_ack_rbf,tlvs,tx_ack_rbf_tlvs,
79 tlvtype,tx_ack_rbf_tlvs,funding_output_contribution,0
80 tlvdata,tx_ack_rbf_tlvs,funding_output_contribution,satoshis,tu64, tlvdata,tx_ack_rbf_tlvs,funding_output_contribution,satoshis,s64,
81 msgtype,tx_abort,74
82 msgdata,tx_abort,channel_id,channel_id,
83 msgdata,tx_abort,len,u16,
264 msgdata,channel_reestablish,your_last_per_commitment_secret,byte,32
265 msgdata,channel_reestablish,my_current_per_commitment_point,point,
266 msgdata,channel_reestablish,tlvs,channel_reestablish_tlvs,
267 tlvtype,channel_reestablish_tlvs,next_funding,0
268 tlvdata,channel_reestablish_tlvs,next_funding,next_funding_txid,sha256,
269 tlvtype,channel_reestablish_tlvs,next_to_send,1
270 tlvdata,channel_reestablish_tlvs,next_to_send,commitment_number,tu64,
271 tlvtype,channel_reestablish_tlvs,desired_channel_type,3