Browse Source

opening: save the correct commitment tx when we are the fundee.

We were saving *our* commitment tx, not theirs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
96a85a786c
  1. 14
      openingd/opening.c
  2. 42
      tests/test_lightningd.py

14
openingd/opening.c

@ -460,7 +460,7 @@ static u8 *fundee_channel(struct state *state,
struct basepoints theirs; struct basepoints theirs;
struct pubkey their_funding_pubkey; struct pubkey their_funding_pubkey;
secp256k1_ecdsa_signature theirsig, sig; secp256k1_ecdsa_signature theirsig, sig;
struct bitcoin_tx *tx; struct bitcoin_tx *their_commit, *our_commit;
struct sha256_double chain_hash; struct sha256_double chain_hash;
u8 *msg; u8 *msg;
const u8 *wscript; const u8 *wscript;
@ -609,16 +609,16 @@ static u8 *fundee_channel(struct state *state,
* *
* The recipient MUST fail the channel if `signature` is incorrect. * The recipient MUST fail the channel if `signature` is incorrect.
*/ */
tx = initial_channel_tx(state, &wscript, state->channel, their_commit = initial_channel_tx(state, &wscript, state->channel,
&state->next_per_commit[LOCAL], LOCAL); &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)) { &theirsig)) {
peer_failed(PEER_FD, &state->cs, &state->channel_id, peer_failed(PEER_FD, &state->cs, &state->channel_id,
"Bad signature %s on tx %s using key %s", "Bad signature %s on tx %s using key %s",
type_to_string(trc, secp256k1_ecdsa_signature, type_to_string(trc, secp256k1_ecdsa_signature,
&theirsig), &theirsig),
type_to_string(trc, struct bitcoin_tx, tx), type_to_string(trc, struct bitcoin_tx, their_commit),
type_to_string(trc, struct pubkey, type_to_string(trc, struct pubkey,
&their_funding_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 * commitment transaction, so they can broadcast it knowing they can
* redeem their funds if they need to. * redeem their funds if they need to.
*/ */
tx = initial_channel_tx(state, &wscript, state->channel, our_commit = initial_channel_tx(state, &wscript, state->channel,
&state->next_per_commit[REMOTE], REMOTE); &state->next_per_commit[REMOTE], REMOTE);
sign_tx_input(tx, 0, NULL, wscript, sign_tx_input(our_commit, 0, NULL, wscript,
&state->our_secrets.funding_privkey, &state->our_secrets.funding_privkey,
our_funding_pubkey, &sig); our_funding_pubkey, &sig);
@ -654,7 +654,7 @@ static u8 *fundee_channel(struct state *state,
return towire_opening_fundee_reply(state, return towire_opening_fundee_reply(state,
state->remoteconf, state->remoteconf,
tx, their_commit,
&theirsig, &theirsig,
&state->cs, &state->cs,
&theirs.revocation, &theirs.revocation,

42
tests/test_lightningd.py

@ -447,6 +447,48 @@ class LightningDTests(BaseLightningDTests):
bitcoind.rpc.generate(6) bitcoind.rpc.generate(6)
l2.daemon.wait_for_log('onchaind complete, forgetting peer') 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): def test_onchain_dust_out(self):
"""Onchain handling of outgoing dust htlcs (they should fail)""" """Onchain handling of outgoing dust htlcs (they should fail)"""
# HTLC 1->2, 1 fails after it's irrevocably committed # HTLC 1->2, 1 fails after it's irrevocably committed

Loading…
Cancel
Save