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. */
|
/* To push 0-75 bytes onto stack. */
|
||||||
#define OP_PUSHBYTES(val) (val)
|
#define OP_PUSHBYTES(val) (val)
|
||||||
|
|
||||||
|
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
/* Bitcoin's OP_HASH160 is RIPEMD(SHA256()) */
|
/* Bitcoin's OP_HASH160 is RIPEMD(SHA256()) */
|
||||||
static void hash160(struct ripemd160 *redeemhash, const void *mem, size_t len)
|
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)
|
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;
|
return false;
|
||||||
if (script[0] != OP_PUSHBYTES(33))
|
if (script[0] != OP_PUSHBYTES(33))
|
||||||
return false;
|
return false;
|
||||||
if (script[34] != OP_CHECKSIGVERIFY)
|
if (script[34] != OP_CHECKSIGVERIFY)
|
||||||
return false;
|
return false;
|
||||||
if (script[35] != 0x51)
|
/* FIXME: check for push value */
|
||||||
return false;
|
if (script[script_len - 1] != OP_CHECKSEQUENCEVERIFY)
|
||||||
if (script[36] != OP_CHECKSEQUENCEVERIFY)
|
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -521,7 +529,28 @@ u8 **bitcoin_witness_sig_and_element(const tal_t *ctx,
|
|||||||
* OP_ENDIF
|
* OP_ENDIF
|
||||||
* OP_CHECKSIG
|
* 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,
|
u8 *bitcoin_wscript_to_local(const tal_t *ctx, u16 to_self_delay,
|
||||||
|
u32 lease_remaining,
|
||||||
const struct pubkey *revocation_pubkey,
|
const struct pubkey *revocation_pubkey,
|
||||||
const struct pubkey *local_delayedkey)
|
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_op(&script, OP_IF);
|
||||||
add_push_key(&script, revocation_pubkey);
|
add_push_key(&script, revocation_pubkey);
|
||||||
add_op(&script, OP_ELSE);
|
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_CHECKSEQUENCEVERIFY);
|
||||||
add_op(&script, OP_DROP);
|
add_op(&script, OP_DROP);
|
||||||
add_push_key(&script, local_delayedkey);
|
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,
|
u8 *scriptpubkey_witness_raw(const tal_t *ctx, u8 version,
|
||||||
const u8 *wprog, size_t wprog_size);
|
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,
|
u8 *anchor_to_remote_redeem(const tal_t *ctx,
|
||||||
const struct pubkey *remote_key,
|
const struct pubkey *remote_key,
|
||||||
u32 csv_lock);
|
u32 csv_lock);
|
||||||
@ -91,8 +91,8 @@ u8 **bitcoin_witness_sig_and_element(const tal_t *ctx,
|
|||||||
const u8 *witnessscript);
|
const u8 *witnessscript);
|
||||||
|
|
||||||
/* BOLT #3 to-local output */
|
/* BOLT #3 to-local output */
|
||||||
u8 *bitcoin_wscript_to_local(const tal_t *ctx,
|
u8 *bitcoin_wscript_to_local(const tal_t *ctx, u16 to_self_delay,
|
||||||
u16 to_self_delay,
|
u32 lease_remaining,
|
||||||
const struct pubkey *revocation_pubkey,
|
const struct pubkey *revocation_pubkey,
|
||||||
const struct pubkey *local_delayedkey);
|
const struct pubkey *local_delayedkey);
|
||||||
|
|
||||||
|
@ -234,7 +234,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
|||||||
* output](#to_local-output).
|
* output](#to_local-output).
|
||||||
*/
|
*/
|
||||||
if (amount_msat_greater_eq_sat(self_pay, dust_limit)) {
|
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);
|
u8 *p2wsh = scriptpubkey_p2wsh(tx, wscript);
|
||||||
struct amount_sat amount = amount_msat_to_sat_round_down(self_pay);
|
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`.
|
* Otherwise, this output is a simple P2WPKH to `remotepubkey`.
|
||||||
*/
|
*/
|
||||||
if (option_anchor_outputs) {
|
if (option_anchor_outputs) {
|
||||||
|
/* FIXME: use csv_lock */
|
||||||
scriptpubkey = scriptpubkey_p2wsh(tmpctx,
|
scriptpubkey = scriptpubkey_p2wsh(tmpctx,
|
||||||
anchor_to_remote_redeem(tmpctx, &keyset->other_payment_key, 1));
|
anchor_to_remote_redeem(tmpctx, &keyset->other_payment_key, 1));
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,7 +63,8 @@ penalty_tx_create(const tal_t *ctx,
|
|||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
"Failed deriving keyset");
|
"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_revocation_key,
|
||||||
&keyset.self_delayed_payment_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,
|
0 ^ channel->commitment_number_obscurer,
|
||||||
direct_outputs,
|
direct_outputs,
|
||||||
side,
|
side,
|
||||||
|
0, /* FIXME: csv lock? */
|
||||||
channel->option_anchor_outputs,
|
channel->option_anchor_outputs,
|
||||||
err_reason);
|
err_reason);
|
||||||
|
|
||||||
|
@ -51,9 +51,10 @@ bool try_subtract_fee(enum side opener, enum side side,
|
|||||||
|
|
||||||
u8 *to_self_wscript(const tal_t *ctx,
|
u8 *to_self_wscript(const tal_t *ctx,
|
||||||
u16 to_self_delay,
|
u16 to_self_delay,
|
||||||
|
u32 csv,
|
||||||
const struct keyset *keyset)
|
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_revocation_key,
|
||||||
&keyset->self_delayed_payment_key);
|
&keyset->self_delayed_payment_key);
|
||||||
}
|
}
|
||||||
@ -87,6 +88,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
|||||||
u64 obscured_commitment_number,
|
u64 obscured_commitment_number,
|
||||||
struct wally_tx_output *direct_outputs[NUM_SIDES],
|
struct wally_tx_output *direct_outputs[NUM_SIDES],
|
||||||
enum side side,
|
enum side side,
|
||||||
|
u32 csv_lock,
|
||||||
bool option_anchor_outputs,
|
bool option_anchor_outputs,
|
||||||
char** err_reason)
|
char** err_reason)
|
||||||
{
|
{
|
||||||
@ -208,7 +210,9 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
|||||||
* output](#to_local-output).
|
* output](#to_local-output).
|
||||||
*/
|
*/
|
||||||
if (amount_msat_greater_eq_sat(self_pay, dust_limit)) {
|
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);
|
amount = amount_msat_to_sat_round_down(self_pay);
|
||||||
int pos = bitcoin_tx_add_output(
|
int pos = bitcoin_tx_add_output(
|
||||||
tx, scriptpubkey_p2wsh(tx, wscript), wscript, amount);
|
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);
|
amount = amount_msat_to_sat_round_down(other_pay);
|
||||||
if (option_anchor_outputs) {
|
if (option_anchor_outputs) {
|
||||||
scriptpubkey = scriptpubkey_p2wsh(tmpctx,
|
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 {
|
} else {
|
||||||
scriptpubkey = scriptpubkey_p2wpkh(tmpctx,
|
scriptpubkey = scriptpubkey_p2wpkh(tmpctx,
|
||||||
&keyset->other_payment_key);
|
&keyset->other_payment_key);
|
||||||
|
@ -121,6 +121,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
|||||||
u64 obscured_commitment_number,
|
u64 obscured_commitment_number,
|
||||||
struct wally_tx_output *direct_outputs[NUM_SIDES],
|
struct wally_tx_output *direct_outputs[NUM_SIDES],
|
||||||
enum side side,
|
enum side side,
|
||||||
|
u32 csv_lock,
|
||||||
bool option_anchor_outputs,
|
bool option_anchor_outputs,
|
||||||
char** err_reason);
|
char** err_reason);
|
||||||
|
|
||||||
@ -134,6 +135,7 @@ bool try_subtract_fee(enum side opener, enum side side,
|
|||||||
* scriptpubkey_p2wsh(ctx, wscript) gives the scriptpubkey */
|
* scriptpubkey_p2wsh(ctx, wscript) gives the scriptpubkey */
|
||||||
u8 *to_self_wscript(const tal_t *ctx,
|
u8 *to_self_wscript(const tal_t *ctx,
|
||||||
u16 to_self_delay,
|
u16 to_self_delay,
|
||||||
|
u32 csv,
|
||||||
const struct keyset *keyset);
|
const struct keyset *keyset);
|
||||||
|
|
||||||
/* To-other is simply: scriptpubkey_p2wpkh(tx, keyset->other_payment_key) */
|
/* 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. */
|
/* It's actually a P2WSH in this case. */
|
||||||
if (utxo->close_info && utxo->close_info->option_anchor_outputs) {
|
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_witscript(psbt, j, wscript);
|
||||||
psbt_input_set_wit_utxo(psbt, j,
|
psbt_input_set_wit_utxo(psbt, j,
|
||||||
scriptpubkey_p2wsh(psbt, wscript),
|
scriptpubkey_p2wsh(psbt, wscript),
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <common/initial_commit_tx.h>
|
#include <common/initial_commit_tx.h>
|
||||||
#include <common/key_derive.h>
|
#include <common/key_derive.h>
|
||||||
#include <common/keyset.h>
|
#include <common/keyset.h>
|
||||||
|
#include <common/lease_rates.h>
|
||||||
#include <common/memleak.h>
|
#include <common/memleak.h>
|
||||||
#include <common/overflows.h>
|
#include <common/overflows.h>
|
||||||
#include <common/peer_billboard.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,
|
type_to_string(tmpctx, struct pubkey,
|
||||||
&keyset->other_htlc_key));
|
&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. */
|
/* Figure out what to-us output looks like. */
|
||||||
script[LOCAL] = scriptpubkey_p2wsh(tmpctx, local_wscript);
|
script[LOCAL] = scriptpubkey_p2wsh(tmpctx, local_wscript);
|
||||||
|
|
||||||
/* Figure out what direct to-them output looks like. */
|
/* Figure out what direct to-them output looks like. */
|
||||||
script[REMOTE] = scriptpubkey_to_remote(tmpctx,
|
script[REMOTE] = scriptpubkey_to_remote(tmpctx,
|
||||||
&keyset->other_payment_key,
|
&keyset->other_payment_key, 1);
|
||||||
1);
|
|
||||||
|
|
||||||
/* Calculate all the HTLC scripts so we can match them */
|
/* Calculate all the HTLC scripts so we can match them */
|
||||||
htlc_scripts = derive_htlc_scripts(htlcs, LOCAL);
|
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
|
/* 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
|
* using HTLC txs to block our penalties for long enough to pass the CSV
|
||||||
* delay */
|
* 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;
|
u8 *wscript;
|
||||||
struct bitcoin_tx *tx;
|
struct bitcoin_tx *tx;
|
||||||
@ -2879,7 +2881,7 @@ static void steal_to_them_output(struct tracked_output *out, bool is_replay)
|
|||||||
*
|
*
|
||||||
* <revocation_sig> 1
|
* <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_revocation_key,
|
||||||
&keyset->self_delayed_payment_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[LOCAL],
|
||||||
static_remotekey_start[REMOTE]);
|
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. */
|
/* Figure out what to-them output looks like. */
|
||||||
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
||||||
@ -3176,7 +3179,7 @@ static void handle_their_cheat(const struct tx_parts *tx,
|
|||||||
amt,
|
amt,
|
||||||
DELAYED_CHEAT_OUTPUT_TO_THEM,
|
DELAYED_CHEAT_OUTPUT_TO_THEM,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
steal_to_them_output(out, is_replay);
|
steal_to_them_output(out, 1, is_replay);
|
||||||
script[REMOTE] = NULL;
|
script[REMOTE] = NULL;
|
||||||
add_amt(&total_outs, amt);
|
add_amt(&total_outs, amt);
|
||||||
continue;
|
continue;
|
||||||
@ -3365,7 +3368,8 @@ static void handle_their_unilateral(const struct tx_parts *tx,
|
|||||||
type_to_string(tmpctx, struct pubkey,
|
type_to_string(tmpctx, struct pubkey,
|
||||||
&keyset->other_htlc_key));
|
&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. */
|
/* Figure out what to-them output looks like. */
|
||||||
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
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 */
|
/* Generated stub for to_self_wscript */
|
||||||
u8 *to_self_wscript(const tal_t *ctx UNNEEDED,
|
u8 *to_self_wscript(const tal_t *ctx UNNEEDED,
|
||||||
u16 to_self_delay UNNEEDED,
|
u16 to_self_delay UNNEEDED,
|
||||||
|
u32 csv UNNEEDED,
|
||||||
const struct keyset *keyset UNNEEDED)
|
const struct keyset *keyset UNNEEDED)
|
||||||
{ fprintf(stderr, "to_self_wscript called!\n"); abort(); }
|
{ fprintf(stderr, "to_self_wscript called!\n"); abort(); }
|
||||||
/* Generated stub for towire */
|
/* Generated stub for towire */
|
||||||
|
@ -230,6 +230,7 @@ void subdaemon_setup(int argc UNNEEDED, char *argv[])
|
|||||||
/* Generated stub for to_self_wscript */
|
/* Generated stub for to_self_wscript */
|
||||||
u8 *to_self_wscript(const tal_t *ctx UNNEEDED,
|
u8 *to_self_wscript(const tal_t *ctx UNNEEDED,
|
||||||
u16 to_self_delay UNNEEDED,
|
u16 to_self_delay UNNEEDED,
|
||||||
|
u32 csv UNNEEDED,
|
||||||
const struct keyset *keyset UNNEEDED)
|
const struct keyset *keyset UNNEEDED)
|
||||||
{ fprintf(stderr, "to_self_wscript called!\n"); abort(); }
|
{ fprintf(stderr, "to_self_wscript called!\n"); abort(); }
|
||||||
/* Generated stub for towire */
|
/* Generated stub for towire */
|
||||||
|
Loading…
Reference in New Issue
Block a user