mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-22 08:34:20 +01:00
lightningd: fix crash when old openingd still around.
We weren't killing it. Eventually it would die, and peer_owner_finished() would access subd->peer->owner, but that peer was freed already. Closes: #261 Reported-by: Christian Decker <decker.christian@gmail.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
5889ad5fc4
commit
b19a4516d4
@@ -454,6 +454,7 @@ static bool peer_reconnected(struct lightningd *ld,
|
|||||||
int fd,
|
int fd,
|
||||||
const struct crypto_state *cs)
|
const struct crypto_state *cs)
|
||||||
{
|
{
|
||||||
|
struct subd *subd;
|
||||||
struct peer *peer = peer_by_id(ld, id);
|
struct peer *peer = peer_by_id(ld, id);
|
||||||
if (!peer)
|
if (!peer)
|
||||||
return false;
|
return false;
|
||||||
@@ -495,8 +496,9 @@ static bool peer_reconnected(struct lightningd *ld,
|
|||||||
|
|
||||||
case OPENINGD:
|
case OPENINGD:
|
||||||
/* Kill off openingd, forget old peer. */
|
/* Kill off openingd, forget old peer. */
|
||||||
|
subd = peer->owner;
|
||||||
peer->owner = NULL; /* We'll free it ourselves */
|
peer->owner = NULL; /* We'll free it ourselves */
|
||||||
tal_free(peer->owner);
|
tal_free(subd);
|
||||||
tal_free(peer);
|
tal_free(peer);
|
||||||
|
|
||||||
/* A fresh start. */
|
/* A fresh start. */
|
||||||
|
|||||||
@@ -816,6 +816,39 @@ class LightningDTests(BaseLightningDTests):
|
|||||||
l1.daemon.wait_for_log('-> CHANNELD_NORMAL')
|
l1.daemon.wait_for_log('-> CHANNELD_NORMAL')
|
||||||
l2.daemon.wait_for_log('-> CHANNELD_NORMAL')
|
l2.daemon.wait_for_log('-> CHANNELD_NORMAL')
|
||||||
|
|
||||||
|
def test_reconnect_openingd(self):
|
||||||
|
# Openingd thinks we're still opening; funder reconnects..
|
||||||
|
disconnects = ['0WIRE_ACCEPT_CHANNEL']
|
||||||
|
l1 = self.node_factory.get_node()
|
||||||
|
l2 = self.node_factory.get_node(disconnect=disconnects)
|
||||||
|
l1.rpc.connect('localhost', l2.info['port'], l2.info['id'])
|
||||||
|
|
||||||
|
addr = l1.rpc.newaddr()['address']
|
||||||
|
txid = l1.bitcoin.rpc.sendtoaddress(addr, 20000 / 10**6)
|
||||||
|
tx = l1.bitcoin.rpc.getrawtransaction(txid)
|
||||||
|
l1.rpc.addfunds(tx)
|
||||||
|
|
||||||
|
# It closes on us, we forget about it.
|
||||||
|
self.assertRaises(ValueError, l1.rpc.fundchannel, l2.info['id'], 20000)
|
||||||
|
assert l1.rpc.getpeer(l2.info['id']) == None
|
||||||
|
|
||||||
|
# Reconnect.
|
||||||
|
l1.rpc.connect('localhost', l2.info['port'], l2.info['id'])
|
||||||
|
|
||||||
|
# Truncate (hack to release old openingd).
|
||||||
|
with open(os.path.join(l2.daemon.lightning_dir, 'dev_disconnect'), "w"):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# We should get a message about old one exiting.
|
||||||
|
l2.daemon.wait_for_log('Subdaemon lightning_openingd died')
|
||||||
|
|
||||||
|
# Should work fine.
|
||||||
|
l1.rpc.fundchannel(l2.info['id'], 20000)
|
||||||
|
l1.daemon.wait_for_log('sendrawtx exit 0')
|
||||||
|
|
||||||
|
# Just to be sure, second openingd should die too.
|
||||||
|
l2.daemon.wait_for_log('Subdaemon lightning_openingd died \(0\)')
|
||||||
|
|
||||||
def test_reconnect_normal(self):
|
def test_reconnect_normal(self):
|
||||||
# Should reconnect fine even if locked message gets lost.
|
# Should reconnect fine even if locked message gets lost.
|
||||||
disconnects = ['-WIRE_FUNDING_LOCKED',
|
disconnects = ['-WIRE_FUNDING_LOCKED',
|
||||||
|
|||||||
Reference in New Issue
Block a user