From 96a85a786c54a64a18c34ac9ca33012cf7bc9a05 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 27 Sep 2017 06:32:48 +0930 Subject: [PATCH] opening: save the correct commitment tx when we are the fundee. We were saving *our* commitment tx, not theirs. Signed-off-by: Rusty Russell --- openingd/opening.c | 18 ++++++++--------- tests/test_lightningd.py | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/openingd/opening.c b/openingd/opening.c index 291e222a..c9693d32 100644 --- a/openingd/opening.c +++ b/openingd/opening.c @@ -460,7 +460,7 @@ static u8 *fundee_channel(struct state *state, struct basepoints theirs; struct pubkey their_funding_pubkey; secp256k1_ecdsa_signature theirsig, sig; - struct bitcoin_tx *tx; + struct bitcoin_tx *their_commit, *our_commit; struct sha256_double chain_hash; u8 *msg; const u8 *wscript; @@ -609,16 +609,16 @@ static u8 *fundee_channel(struct state *state, * * The recipient MUST fail the channel if `signature` is incorrect. */ - tx = initial_channel_tx(state, &wscript, state->channel, - &state->next_per_commit[LOCAL], LOCAL); + their_commit = initial_channel_tx(state, &wscript, state->channel, + &state->next_per_commit[LOCAL], LOCAL); - if (!check_tx_sig(tx, 0, NULL, wscript, &their_funding_pubkey, + if (!check_tx_sig(their_commit, 0, NULL, wscript, &their_funding_pubkey, &theirsig)) { peer_failed(PEER_FD, &state->cs, &state->channel_id, "Bad signature %s on tx %s using key %s", type_to_string(trc, secp256k1_ecdsa_signature, &theirsig), - type_to_string(trc, struct bitcoin_tx, tx), + type_to_string(trc, struct bitcoin_tx, their_commit), type_to_string(trc, struct pubkey, &their_funding_pubkey)); } @@ -642,9 +642,9 @@ static u8 *fundee_channel(struct state *state, * commitment transaction, so they can broadcast it knowing they can * redeem their funds if they need to. */ - tx = initial_channel_tx(state, &wscript, state->channel, - &state->next_per_commit[REMOTE], REMOTE); - sign_tx_input(tx, 0, NULL, wscript, + our_commit = initial_channel_tx(state, &wscript, state->channel, + &state->next_per_commit[REMOTE], REMOTE); + sign_tx_input(our_commit, 0, NULL, wscript, &state->our_secrets.funding_privkey, our_funding_pubkey, &sig); @@ -654,7 +654,7 @@ static u8 *fundee_channel(struct state *state, return towire_opening_fundee_reply(state, state->remoteconf, - tx, + their_commit, &theirsig, &state->cs, &theirs.revocation, diff --git a/tests/test_lightningd.py b/tests/test_lightningd.py index 61095a69..6b897069 100644 --- a/tests/test_lightningd.py +++ b/tests/test_lightningd.py @@ -447,6 +447,48 @@ def test_permfail(self): bitcoind.rpc.generate(6) l2.daemon.wait_for_log('onchaind complete, forgetting peer') + def test_onchain_first_commit(self): + """Onchain handling where funder immediately drops to chain""" + + # HTLC 1->2, 1 fails just after funding. + disconnects = ['+WIRE_FUNDING_LOCKED', 'permfail'] + l1 = self.node_factory.get_node(disconnect=disconnects) + l2 = self.node_factory.get_node() + + l1.rpc.connect('localhost', l2.info['port'], l2.info['id']) + + # Like fundchannel, but we'll probably fail before CHANNELD_NORMAL. + addr = l1.rpc.newaddr()['address'] + + txid = l1.bitcoin.rpc.sendtoaddress(addr, 10**6 / 10**8 + 0.01) + tx = l1.bitcoin.rpc.getrawtransaction(txid) + + l1.rpc.addfunds(tx) + l1.rpc.fundchannel(l2.info['id'], 10**6) + l1.daemon.wait_for_log('sendrawtx exit 0') + + l1.bitcoin.rpc.generate(1) + + # l1 will drop to chain. + l1.daemon.wait_for_log('permfail') + l1.daemon.wait_for_log('sendrawtx exit 0') + l1.bitcoin.rpc.generate(1) + l1.daemon.wait_for_log('-> ONCHAIND_OUR_UNILATERAL') + l2.daemon.wait_for_log('-> ONCHAIND_THEIR_UNILATERAL') + + # 6 later, l1 should collect its to-self payment. + bitcoind.rpc.generate(6) + l1.daemon.wait_for_log('Broadcasting OUR_DELAYED_RETURN_TO_WALLET .* to resolve OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') + l1.daemon.wait_for_log('sendrawtx exit 0') + + # 94 later, l2 is done. + bitcoind.rpc.generate(94) + l2.daemon.wait_for_log('onchaind complete, forgetting peer') + + # Now, 100 blocks and l1 should be done. + bitcoind.rpc.generate(6) + l1.daemon.wait_for_log('onchaind complete, forgetting peer') + def test_onchain_dust_out(self): """Onchain handling of outgoing dust htlcs (they should fail)""" # HTLC 1->2, 1 fails after it's irrevocably committed