Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zero fee htlc: Finally add support (experimental!) #6137

Closed

Conversation

rustyrussell
Copy link
Contributor

@rustyrussell rustyrussell commented Apr 1, 2023

Builds on #6136 , so start from hsmd: command to sign anchor spends. MERGED

This is still experimental since it needs more testing (in particular, interop!), and we don't yet reserve utxos, so if you have no utxos you will find yourself unable to push a unilateral close through!

But it includes CPFP using anchors, and RBF using HTLC tx's SIGHASH_SINGLE|SIGHASH_ANYONECANPAY, so zero-fee htlcs are trivial to support.

@rustyrussell rustyrussell added this to the v23.05 milestone Apr 1, 2023
@rustyrussell rustyrussell requested a review from cdecker as a code owner April 1, 2023 04:08
@rustyrussell rustyrussell force-pushed the zero-fee-htlc-prep-5 branch 2 times, most recently from 894228c to 3e883a0 Compare April 3, 2023 05:20
Copy link
Member

@cdecker cdecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 3e883a0

lightningd/chaintopology.c Show resolved Hide resolved
@rustyrussell rustyrussell force-pushed the zero-fee-htlc-prep-5 branch 2 times, most recently from 04dc118 to 17caa31 Compare April 10, 2023 07:58
This is kind of a withdrawl to ourselves, except we also spend a
channel to-local anchor.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
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>
We don't actually use it anywhere, but we actually want to now for
CPFP.  So give it more parameters and make it return bool so it can
be set without necessarily suppressing rexmit.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
…nt tx.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Since we can CPFP, we don't have to track the feerate as closely.  But
it still needs to get in the mempool, so we use 10 sat/byte, or the
100 block estimate if that is higher.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: JSON-RPC: `feerates` has new output `unilateral_anchor_close` to show the feerate used for anchor channels (currently experimental)
Since HTLC txs when using anchors are
SIGHASH_SINGLE|SIGHASH_ANYONECANPAY, we can attach other inputs to
give it a higher feerate.  But we need the HSMd to actually sign the
combo.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
In most cases, it's the same as option_anchor_outputs, but for
fees it's different.  This transformation is the simplest:
pass it as a pair, and test it explicitly.

In future we could rationalize some paths, but this was nice
and mechanical.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We disabled experimental support for opening non-zero-fee anchor
channels (though old nodes may still have such channels if they turned
that on!).

So we simply call this `experimental-anchors`, since this is the variant
which we expect to be used widely.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Experimental: protocol: added support for zero-fee-htlc anchors (`option_anchors_zero_fee_htlc_tx`), using `--experimental-anchors`.
@rustyrussell rustyrussell force-pushed the zero-fee-htlc-prep-5 branch from 17caa31 to 0241ea1 Compare April 10, 2023 08:02
@rustyrussell
Copy link
Contributor Author

Rebased on master, fixed up hsm_version.h to include newer checksums.

Ack 0241ea1

Copy link
Contributor

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, there are a couple of nits from the compiler

cc wallet/db_sqlite3_sqlgen.c
lightningd/onchain_control.c:941:42: error: variable 'fee' is uninitialized when used here [-Werror,-Wuninitialized]
            || !amount_sat_sub(&change, change, fee)) {
                                                ^~~
lightningd/onchain_control.c:870:2: note: variable 'fee' is declared here
        struct amount_sat fee, excess, change;
        ^
lightningd/onchain_control.c:938:30: error: variable 'psbt' is uninitialized when used here [-Werror,-Wuninitialized]
                                BITCOIN_TX_RBF_SEQUENCE, psbt);
                                                         ^~~~
lightningd/onchain_control.c:876:25: note: initialize the variable 'psbt' to silence this warning
        struct wally_psbt *psbt;
                               ^
                                = NULL
2 errors generated.
make: *** [Makefile:292: lightningd/onchain_control.o] Error 1
make: *** Waiting for unfinished jobs....
rm external/x86_64-pc-linux-gnu/libwally-core-build/src/secp256k1/libsecp256k1.la
ld lightningd/lightning_hsmd
ld lightningd/lightning_gossipd
ld lightningd/lightning_openingd
ld lightningd/lightning_dualopend
ld lightningd/lightning_channeld
ld lightningd/lightning_closingd
ld lightningd/lightning_onchaind
ld lightningd/lightning_connectd
ld lightningd/lightning_websocketd
cc lightningd/onchain_control.c
lightningd/onchain_control.c:941:42: error: variable 'fee' is uninitialized when used here [-Werror,-Wuninitialized]
            || !amount_sat_sub(&change, change, fee)) {
                                                ^~~
lightningd/onchain_control.c:870:2: note: variable 'fee' is declared here
        struct amount_sat fee, excess, change;
        ^
lightningd/onchain_control.c:938:30: error: variable 'psbt' is uninitialized when used here [-Werror,-Wuninitialized]
                                BITCOIN_TX_RBF_SEQUENCE, psbt);
                                                         ^~~~
lightningd/onchain_control.c:876:25: note: initialize the variable 'psbt' to silence this warning
        struct wally_psbt *psbt;
                               ^
                                = NULL
2 errors generated.
make: *** [Makefile:292: lightningd/onchain_control.o] Error 1
Error: Process completed with exit code 2.

@rustyrussell rustyrussell marked this pull request as draft April 13, 2023 02:37
@rustyrussell
Copy link
Contributor Author

I worked on this quite a bit, it was definitely not ready. I am still failing on final tests, and am deferring it to next release.

@rustyrussell rustyrussell modified the milestones: v23.05, v23.08 Apr 13, 2023
const u8 *msg;
struct lightningd *ld = channel->peer->ld;

/* We can't do much without anchor outputs (we could CPFP?) */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cpfp only works in the case of revocation? making sure I understand the comment

utxos[0] = wallet_find_utxo(utxos, ld->wallet,
get_block_height(ld->topology),
NULL,
0, /* FIXME: unused! */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please annotate which one is unused (feerate_per_kw)

/* OK, we need to attach another input! */
/* FIXME: Maybe more than one! */
utxos = tal_arr(tmpctx, struct utxo *, 1);
utxos[0] = wallet_find_utxo(utxos, ld->wallet,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, this will return a random utxo from the wallet, but the value will be arbitrary. This means we will keep trying with random utxos until we get one that is big enough, is that right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If so, this may allow an attacker to dust you wallet to slow down progress at picking a "good enough" utxo. Might want to just keep grabbing utxos rather than aborting at a min?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should likely ensure that we aren't actually reducing our feerate by adding tiny inputs, that don't even pay for themselves. That'd also fix the dusting issue mentioned by @instagibbs.

/* Eliminate this output altogether. */
bitcoin_tx_remove_output(newtx, change_output);
} else {
bitcoin_tx_output_set_amount(newtx, change_output, amt);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this hits at dust values, and new tx meets_feerate, I think this makes dusty tx?

}

/* Now, get HSM to sign off. */
msg = towire_hsmd_sign_htlc_tx_mingle(NULL,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SIGHASH_SINGLE, ready to MINGLE

@rustyrussell rustyrussell added feature protocol These issues are protocol level issues that should be discussed on the protocol spec repo labels May 9, 2023
@cdecker
Copy link
Member

cdecker commented Jun 5, 2023

Looking quite good I think, love the anchor details handling in the first couple of commits.

Comment on lines +883 to +899
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A template comparison system would be nice here, but probably overkill 🤔

/* OK, we need to attach another input! */
/* FIXME: Maybe more than one! */
utxos = tal_arr(tmpctx, struct utxo *, 1);
utxos[0] = wallet_find_utxo(utxos, ld->wallet,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should likely ensure that we aren't actually reducing our feerate by adding tiny inputs, that don't even pay for themselves. That'd also fix the dusting issue mentioned by @instagibbs.

@rustyrussell
Copy link
Contributor Author

closed-by #6334

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature needs-rebase protocol These issues are protocol level issues that should be discussed on the protocol spec repo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants