mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
lease_rates: add csv lock to modify anchor scripts
This commit is contained in:
parent
e992b54410
commit
c9d2748081
@ -14,6 +14,8 @@
|
||||
/* To push 0-75 bytes onto stack. */
|
||||
#define OP_PUSHBYTES(val) (val)
|
||||
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
/* Bitcoin's OP_HASH160 is RIPEMD(SHA256()) */
|
||||
static void hash160(struct ripemd160 *redeemhash, const void *mem, size_t len)
|
||||
{
|
||||
@ -353,15 +355,21 @@ u8 *anchor_to_remote_redeem(const tal_t *ctx,
|
||||
|
||||
bool is_anchor_witness_script(const u8 *script, size_t script_len)
|
||||
{
|
||||
if (script_len != 34 + 1 + 1 + 1)
|
||||
size_t len = 34 + 1 + 1 + 1;
|
||||
/* With option_will_fund, the pushbytes can be up to 2 bytes more
|
||||
*
|
||||
* <remote_pubkey> OP_CHECKSIGVERIFY
|
||||
* MAX(1, lease_end - blockheight)
|
||||
* OP_CHECKSEQUENCEVERIFY
|
||||
*/
|
||||
if (script_len < len || script_len > len + 2)
|
||||
return false;
|
||||
if (script[0] != OP_PUSHBYTES(33))
|
||||
return false;
|
||||
if (script[34] != OP_CHECKSIGVERIFY)
|
||||
return false;
|
||||
if (script[35] != 0x51)
|
||||
return false;
|
||||
if (script[36] != OP_CHECKSEQUENCEVERIFY)
|
||||
/* FIXME: check for push value */
|
||||
if (script[script_len - 1] != OP_CHECKSEQUENCEVERIFY)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -521,7 +529,28 @@ u8 **bitcoin_witness_sig_and_element(const tal_t *ctx,
|
||||
* OP_ENDIF
|
||||
* OP_CHECKSIG
|
||||
*/
|
||||
/* BOLT- #3
|
||||
* ##### Leased channel (`option_will_fund`)
|
||||
* If a `lease` applies to the channel, the `to_local` output of the `accepter`
|
||||
* ensures the `leasor` funds are not spendable until the lease expires.
|
||||
*
|
||||
* In a leased channel, the `to_local` output that pays the `accepter` node
|
||||
* is modified so that its CSV is equal to the greater of the
|
||||
* `to_self_delay` or the `lease_end` - `blockheight`.
|
||||
*
|
||||
* OP_IF
|
||||
* # Penalty transaction
|
||||
* <revocationpubkey>
|
||||
* OP_ELSE
|
||||
* MAX(`to_self_delay`, `lease_end` - `blockheight`)
|
||||
* OP_CHECKSEQUENCEVERIFY
|
||||
* OP_DROP
|
||||
* <local_delayedpubkey>
|
||||
* OP_ENDIF
|
||||
* OP_CHECKSIG
|
||||
*/
|
||||
u8 *bitcoin_wscript_to_local(const tal_t *ctx, u16 to_self_delay,
|
||||
u32 lease_remaining,
|
||||
const struct pubkey *revocation_pubkey,
|
||||
const struct pubkey *local_delayedkey)
|
||||
{
|
||||
@ -529,7 +558,7 @@ u8 *bitcoin_wscript_to_local(const tal_t *ctx, u16 to_self_delay,
|
||||
add_op(&script, OP_IF);
|
||||
add_push_key(&script, revocation_pubkey);
|
||||
add_op(&script, OP_ELSE);
|
||||
add_number(&script, to_self_delay);
|
||||
add_number(&script, max(lease_remaining, to_self_delay));
|
||||
add_op(&script, OP_CHECKSEQUENCEVERIFY);
|
||||
add_op(&script, OP_DROP);
|
||||
add_push_key(&script, local_delayedkey);
|
||||
|
@ -67,7 +67,7 @@ u8 *scriptpubkey_p2wpkh_derkey(const tal_t *ctx, const u8 der[33]);
|
||||
u8 *scriptpubkey_witness_raw(const tal_t *ctx, u8 version,
|
||||
const u8 *wprog, size_t wprog_size);
|
||||
|
||||
/* To-remotekey with csv 1 delay. */
|
||||
/* To-remotekey with csv max(lease_expiry - blockheight, 1) delay. */
|
||||
u8 *anchor_to_remote_redeem(const tal_t *ctx,
|
||||
const struct pubkey *remote_key,
|
||||
u32 csv_lock);
|
||||
@ -91,8 +91,8 @@ u8 **bitcoin_witness_sig_and_element(const tal_t *ctx,
|
||||
const u8 *witnessscript);
|
||||
|
||||
/* BOLT #3 to-local output */
|
||||
u8 *bitcoin_wscript_to_local(const tal_t *ctx,
|
||||
u16 to_self_delay,
|
||||
u8 *bitcoin_wscript_to_local(const tal_t *ctx, u16 to_self_delay,
|
||||
u32 lease_remaining,
|
||||
const struct pubkey *revocation_pubkey,
|
||||
const struct pubkey *local_delayedkey);
|
||||
|
||||
|
@ -234,7 +234,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
||||
* output](#to_local-output).
|
||||
*/
|
||||
if (amount_msat_greater_eq_sat(self_pay, dust_limit)) {
|
||||
u8 *wscript = to_self_wscript(tmpctx, to_self_delay,keyset);
|
||||
u8 *wscript = to_self_wscript(tmpctx,
|
||||
to_self_delay,
|
||||
1, /* FIXME: csv_lock */
|
||||
keyset);
|
||||
u8 *p2wsh = scriptpubkey_p2wsh(tx, wscript);
|
||||
struct amount_sat amount = amount_msat_to_sat_round_down(self_pay);
|
||||
|
||||
@ -275,6 +278,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
||||
* Otherwise, this output is a simple P2WPKH to `remotepubkey`.
|
||||
*/
|
||||
if (option_anchor_outputs) {
|
||||
/* FIXME: use csv_lock */
|
||||
scriptpubkey = scriptpubkey_p2wsh(tmpctx,
|
||||
anchor_to_remote_redeem(tmpctx, &keyset->other_payment_key, 1));
|
||||
} else {
|
||||
|
@ -63,7 +63,8 @@ penalty_tx_create(const tal_t *ctx,
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed deriving keyset");
|
||||
|
||||
wscript = bitcoin_wscript_to_local(tmpctx, remote_to_self_delay,
|
||||
/* FIXME: csv_lock */
|
||||
wscript = bitcoin_wscript_to_local(tmpctx, remote_to_self_delay, 1,
|
||||
&keyset.self_revocation_key,
|
||||
&keyset.self_delayed_payment_key);
|
||||
|
||||
|
@ -120,6 +120,7 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx,
|
||||
0 ^ channel->commitment_number_obscurer,
|
||||
direct_outputs,
|
||||
side,
|
||||
0, /* FIXME: csv lock? */
|
||||
channel->option_anchor_outputs,
|
||||
err_reason);
|
||||
|
||||
|
@ -51,9 +51,10 @@ bool try_subtract_fee(enum side opener, enum side side,
|
||||
|
||||
u8 *to_self_wscript(const tal_t *ctx,
|
||||
u16 to_self_delay,
|
||||
u32 csv,
|
||||
const struct keyset *keyset)
|
||||
{
|
||||
return bitcoin_wscript_to_local(ctx, to_self_delay,
|
||||
return bitcoin_wscript_to_local(ctx, to_self_delay, csv,
|
||||
&keyset->self_revocation_key,
|
||||
&keyset->self_delayed_payment_key);
|
||||
}
|
||||
@ -87,6 +88,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
||||
u64 obscured_commitment_number,
|
||||
struct wally_tx_output *direct_outputs[NUM_SIDES],
|
||||
enum side side,
|
||||
u32 csv_lock,
|
||||
bool option_anchor_outputs,
|
||||
char** err_reason)
|
||||
{
|
||||
@ -208,7 +210,9 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
||||
* output](#to_local-output).
|
||||
*/
|
||||
if (amount_msat_greater_eq_sat(self_pay, dust_limit)) {
|
||||
u8 *wscript = to_self_wscript(tmpctx, to_self_delay, keyset);
|
||||
u8 *wscript = to_self_wscript(tmpctx,
|
||||
to_self_delay, csv_lock,
|
||||
keyset);
|
||||
amount = amount_msat_to_sat_round_down(self_pay);
|
||||
int pos = bitcoin_tx_add_output(
|
||||
tx, scriptpubkey_p2wsh(tx, wscript), wscript, amount);
|
||||
@ -242,7 +246,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
||||
amount = amount_msat_to_sat_round_down(other_pay);
|
||||
if (option_anchor_outputs) {
|
||||
scriptpubkey = scriptpubkey_p2wsh(tmpctx,
|
||||
anchor_to_remote_redeem(tmpctx, &keyset->other_payment_key, 1));
|
||||
anchor_to_remote_redeem(tmpctx, &keyset->other_payment_key, csv_lock));
|
||||
} else {
|
||||
scriptpubkey = scriptpubkey_p2wpkh(tmpctx,
|
||||
&keyset->other_payment_key);
|
||||
|
@ -121,6 +121,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
||||
u64 obscured_commitment_number,
|
||||
struct wally_tx_output *direct_outputs[NUM_SIDES],
|
||||
enum side side,
|
||||
u32 csv_lock,
|
||||
bool option_anchor_outputs,
|
||||
char** err_reason);
|
||||
|
||||
@ -134,6 +135,7 @@ bool try_subtract_fee(enum side opener, enum side side,
|
||||
* scriptpubkey_p2wsh(ctx, wscript) gives the scriptpubkey */
|
||||
u8 *to_self_wscript(const tal_t *ctx,
|
||||
u16 to_self_delay,
|
||||
u32 csv,
|
||||
const struct keyset *keyset);
|
||||
|
||||
/* To-other is simply: scriptpubkey_p2wpkh(tx, keyset->other_payment_key) */
|
||||
|
@ -388,7 +388,10 @@ static void sign_our_inputs(struct utxo **utxos, struct wally_psbt *psbt)
|
||||
|
||||
/* It's actually a P2WSH in this case. */
|
||||
if (utxo->close_info && utxo->close_info->option_anchor_outputs) {
|
||||
const u8 *wscript = anchor_to_remote_redeem(tmpctx, &pubkey, 1);
|
||||
const u8 *wscript
|
||||
= anchor_to_remote_redeem(tmpctx,
|
||||
&pubkey,
|
||||
1); /* FIXME: lease csv ? */
|
||||
psbt_input_set_witscript(psbt, j, wscript);
|
||||
psbt_input_set_wit_utxo(psbt, j,
|
||||
scriptpubkey_p2wsh(psbt, wscript),
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <common/initial_commit_tx.h>
|
||||
#include <common/key_derive.h>
|
||||
#include <common/keyset.h>
|
||||
#include <common/lease_rates.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/overflows.h>
|
||||
#include <common/peer_billboard.h>
|
||||
@ -2644,15 +2645,15 @@ static void handle_our_unilateral(const struct tx_parts *tx,
|
||||
type_to_string(tmpctx, struct pubkey,
|
||||
&keyset->other_htlc_key));
|
||||
|
||||
local_wscript = to_self_wscript(tmpctx, to_self_delay[LOCAL], keyset);
|
||||
local_wscript = to_self_wscript(tmpctx, to_self_delay[LOCAL],
|
||||
1, keyset);
|
||||
|
||||
/* Figure out what to-us output looks like. */
|
||||
script[LOCAL] = scriptpubkey_p2wsh(tmpctx, local_wscript);
|
||||
|
||||
/* Figure out what direct to-them output looks like. */
|
||||
script[REMOTE] = scriptpubkey_to_remote(tmpctx,
|
||||
&keyset->other_payment_key,
|
||||
1);
|
||||
&keyset->other_payment_key, 1);
|
||||
|
||||
/* Calculate all the HTLC scripts so we can match them */
|
||||
htlc_scripts = derive_htlc_scripts(htlcs, LOCAL);
|
||||
@ -2866,7 +2867,8 @@ static void handle_our_unilateral(const struct tx_parts *tx,
|
||||
/* We produce individual penalty txs. It's less efficient, but avoids them
|
||||
* using HTLC txs to block our penalties for long enough to pass the CSV
|
||||
* delay */
|
||||
static void steal_to_them_output(struct tracked_output *out, bool is_replay)
|
||||
static void steal_to_them_output(struct tracked_output *out,
|
||||
u32 csv, bool is_replay)
|
||||
{
|
||||
u8 *wscript;
|
||||
struct bitcoin_tx *tx;
|
||||
@ -2879,7 +2881,7 @@ static void steal_to_them_output(struct tracked_output *out, bool is_replay)
|
||||
*
|
||||
* <revocation_sig> 1
|
||||
*/
|
||||
wscript = bitcoin_wscript_to_local(tmpctx, to_self_delay[REMOTE],
|
||||
wscript = bitcoin_wscript_to_local(tmpctx, to_self_delay[REMOTE], csv,
|
||||
&keyset->self_revocation_key,
|
||||
&keyset->self_delayed_payment_key);
|
||||
|
||||
@ -3083,7 +3085,8 @@ static void handle_their_cheat(const struct tx_parts *tx,
|
||||
static_remotekey_start[LOCAL],
|
||||
static_remotekey_start[REMOTE]);
|
||||
|
||||
remote_wscript = to_self_wscript(tmpctx, to_self_delay[REMOTE], keyset);
|
||||
remote_wscript = to_self_wscript(tmpctx, to_self_delay[REMOTE],
|
||||
1, keyset);
|
||||
|
||||
/* Figure out what to-them output looks like. */
|
||||
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
||||
@ -3176,7 +3179,7 @@ static void handle_their_cheat(const struct tx_parts *tx,
|
||||
amt,
|
||||
DELAYED_CHEAT_OUTPUT_TO_THEM,
|
||||
NULL, NULL, NULL);
|
||||
steal_to_them_output(out, is_replay);
|
||||
steal_to_them_output(out, 1, is_replay);
|
||||
script[REMOTE] = NULL;
|
||||
add_amt(&total_outs, amt);
|
||||
continue;
|
||||
@ -3365,7 +3368,8 @@ static void handle_their_unilateral(const struct tx_parts *tx,
|
||||
type_to_string(tmpctx, struct pubkey,
|
||||
&keyset->other_htlc_key));
|
||||
|
||||
remote_wscript = to_self_wscript(tmpctx, to_self_delay[REMOTE], keyset);
|
||||
remote_wscript = to_self_wscript(tmpctx, to_self_delay[REMOTE],
|
||||
1, keyset);
|
||||
|
||||
/* Figure out what to-them output looks like. */
|
||||
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
||||
|
@ -213,6 +213,7 @@ void subdaemon_setup(int argc UNNEEDED, char *argv[])
|
||||
/* Generated stub for to_self_wscript */
|
||||
u8 *to_self_wscript(const tal_t *ctx UNNEEDED,
|
||||
u16 to_self_delay UNNEEDED,
|
||||
u32 csv UNNEEDED,
|
||||
const struct keyset *keyset UNNEEDED)
|
||||
{ fprintf(stderr, "to_self_wscript called!\n"); abort(); }
|
||||
/* Generated stub for towire */
|
||||
|
@ -230,6 +230,7 @@ void subdaemon_setup(int argc UNNEEDED, char *argv[])
|
||||
/* Generated stub for to_self_wscript */
|
||||
u8 *to_self_wscript(const tal_t *ctx UNNEEDED,
|
||||
u16 to_self_delay UNNEEDED,
|
||||
u32 csv UNNEEDED,
|
||||
const struct keyset *keyset UNNEEDED)
|
||||
{ fprintf(stderr, "to_self_wscript called!\n"); abort(); }
|
||||
/* Generated stub for towire */
|
||||
|
Loading…
Reference in New Issue
Block a user