mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-21 14:24:09 +01:00
bitcoin/psbt: handle anchor spends.
Turns out it's a single sig, identical to the already-handled case where we spend a to_remote output. We also close a temporary memleak: stack was unused, but tallocated off the psbt, so it lives as long as the PSBT. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
c2dffcab0f
commit
313354329d
6 changed files with 57 additions and 3 deletions
|
@ -586,7 +586,7 @@ bool psbt_finalize(struct wally_psbt *psbt)
|
|||
tal_wally_start();
|
||||
|
||||
/* Wally doesn't know how to finalize P2WSH; this happens with
|
||||
* option_anchor_outputs, and finalizing is trivial. */
|
||||
* option_anchor_outputs, and finalizing those two cases is trivial. */
|
||||
/* FIXME: miniscript! miniscript! miniscript! */
|
||||
for (size_t i = 0; i < psbt->num_inputs; i++) {
|
||||
struct wally_psbt_input *input = &psbt->inputs[i];
|
||||
|
@ -594,10 +594,16 @@ bool psbt_finalize(struct wally_psbt *psbt)
|
|||
const struct wally_map_item *iws;
|
||||
|
||||
iws = wally_map_get_integer(&input->psbt_fields, /* PSBT_IN_WITNESS_SCRIPT */ 0x05);
|
||||
if (!iws || !is_to_remote_anchored_witness_script(iws->value,
|
||||
iws->value_len))
|
||||
if (!iws)
|
||||
continue;
|
||||
|
||||
if (!is_to_remote_anchored_witness_script(iws->value,
|
||||
iws->value_len)
|
||||
&& !is_anchor_witness_script(iws->value,
|
||||
iws->value_len)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input->signatures.num_items != 1)
|
||||
continue;
|
||||
|
||||
|
@ -615,6 +621,19 @@ bool psbt_finalize(struct wally_psbt *psbt)
|
|||
*
|
||||
* <remote_sig>
|
||||
*/
|
||||
/* BOLT #3:
|
||||
* #### `to_local_anchor` and `to_remote_anchor` Output (option_anchors)
|
||||
*...
|
||||
* <local_funding_pubkey/remote_funding_pubkey> OP_CHECKSIG OP_IFDUP
|
||||
* OP_NOTIF
|
||||
* OP_16 OP_CHECKSEQUENCEVERIFY
|
||||
* OP_ENDIF
|
||||
*...
|
||||
* Spending of the output requires the following witness:
|
||||
* <local_sig/remote_sig>
|
||||
*/
|
||||
|
||||
/* i.e. in both cases, this is the same thing */
|
||||
wally_tx_witness_stack_init_alloc(2, &stack);
|
||||
wally_tx_witness_stack_add(stack,
|
||||
input->signatures.items[0].value,
|
||||
|
@ -623,6 +642,7 @@ bool psbt_finalize(struct wally_psbt *psbt)
|
|||
iws->value,
|
||||
iws->value_len);
|
||||
wally_psbt_input_set_final_witness(input, stack);
|
||||
wally_tx_witness_stack_free(stack);
|
||||
}
|
||||
|
||||
ok = (wally_psbt_finalize(psbt, 0 /* flags */) == WALLY_OK);
|
||||
|
|
|
@ -874,9 +874,31 @@ u8 *bitcoin_wscript_anchor(const tal_t *ctx,
|
|||
add_op(&script, OP_CHECKSEQUENCEVERIFY);
|
||||
add_op(&script, OP_ENDIF);
|
||||
|
||||
assert(is_anchor_witness_script(script, tal_bytelen(script)));
|
||||
return script;
|
||||
}
|
||||
|
||||
bool is_anchor_witness_script(const u8 *script, size_t script_len)
|
||||
{
|
||||
if (script_len != 34 + 1 + 1 + 1 + 1 + 1 + 1)
|
||||
return false;
|
||||
if (script[0] != OP_PUSHBYTES(33))
|
||||
return false;
|
||||
if (script[34] != OP_CHECKSIG)
|
||||
return false;
|
||||
if (script[35] != OP_IFDUP)
|
||||
return false;
|
||||
if (script[36] != OP_NOTIF)
|
||||
return false;
|
||||
if (script[37] != 0x50 + 16)
|
||||
return false;
|
||||
if (script[38] != OP_CHECKSEQUENCEVERIFY)
|
||||
return false;
|
||||
if (script[39] != OP_ENDIF)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool scripteq(const u8 *s1, const u8 *s2)
|
||||
{
|
||||
memcheck(s1, tal_count(s1));
|
||||
|
|
|
@ -159,6 +159,9 @@ bool is_known_scripttype(const u8 *script);
|
|||
/* Is this a to-remote witness script (used for option_anchor_outputs)? */
|
||||
bool is_to_remote_anchored_witness_script(const u8 *script, size_t script_len);
|
||||
|
||||
/* Is this an anchor witness script? */
|
||||
bool is_anchor_witness_script(const u8 *script, size_t script_len);
|
||||
|
||||
/* Are these two scripts equal? */
|
||||
bool scripteq(const u8 *s1, const u8 *s2);
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
|||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for is_anchor_witness_script */
|
||||
bool is_anchor_witness_script(const u8 *script UNNEEDED, size_t script_len UNNEEDED)
|
||||
{ fprintf(stderr, "is_anchor_witness_script called!\n"); abort(); }
|
||||
/* Generated stub for is_to_remote_anchored_witness_script */
|
||||
bool is_to_remote_anchored_witness_script(const u8 *script UNNEEDED, size_t script_len UNNEEDED)
|
||||
{ fprintf(stderr, "is_to_remote_anchored_witness_script called!\n"); abort(); }
|
||||
|
|
|
@ -50,6 +50,9 @@ struct amount_sat amount_tx_fee(u32 fee_per_kw UNNEEDED, size_t weight UNNEEDED)
|
|||
void fromwire_sha256_double(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
struct sha256_double *sha256d UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_sha256_double called!\n"); abort(); }
|
||||
/* Generated stub for is_anchor_witness_script */
|
||||
bool is_anchor_witness_script(const u8 *script UNNEEDED, size_t script_len UNNEEDED)
|
||||
{ fprintf(stderr, "is_anchor_witness_script called!\n"); abort(); }
|
||||
/* Generated stub for is_to_remote_anchored_witness_script */
|
||||
bool is_to_remote_anchored_witness_script(const u8 *script UNNEEDED, size_t script_len UNNEEDED)
|
||||
{ fprintf(stderr, "is_to_remote_anchored_witness_script called!\n"); abort(); }
|
||||
|
|
|
@ -70,6 +70,9 @@ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
|||
/* Generated stub for fromwire_u8_array */
|
||||
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
|
||||
/* Generated stub for is_anchor_witness_script */
|
||||
bool is_anchor_witness_script(const u8 *script UNNEEDED, size_t script_len UNNEEDED)
|
||||
{ fprintf(stderr, "is_anchor_witness_script called!\n"); abort(); }
|
||||
/* Generated stub for is_to_remote_anchored_witness_script */
|
||||
bool is_to_remote_anchored_witness_script(const u8 *script UNNEEDED, size_t script_len UNNEEDED)
|
||||
{ fprintf(stderr, "is_to_remote_anchored_witness_script called!\n"); abort(); }
|
||||
|
|
Loading…
Add table
Reference in a new issue