Skip to content

Purge channels from the DB after they have been irrevocably committed #740

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

Merged
merged 2 commits into from
Jan 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lightningd/peer_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -1244,8 +1244,8 @@ static void handle_irrevocably_resolved(struct peer *peer, const u8 *msg)
/* FIXME: Implement check_htlcs to ensure no dangling hout->in ptrs! */
free_htlcs(peer->ld, peer);

/* FIXME: Remove peer from db. */
log_info(peer->log, "onchaind complete, forgetting peer");
wallet_channel_delete(peer->ld->wallet, peer->channel->id);

/* This will also free onchaind. */
free_peer(peer, "onchaind complete, forgetting peer");
Expand Down
23 changes: 17 additions & 6 deletions tests/test_lightningd.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ def wait_for(success, timeout=30, interval=0.1):
if time.time() > start_time + timeout:
raise ValueError("Error waiting for {}", success)

def wait_forget_channels(node):
"""This node is closing all of its channels, check we are forgetting them
"""
node.daemon.wait_for_log(r'onchaind complete, forgetting peer')
assert node.rpc.listpeers()['peers'] == []
assert node.db_query("SELECT * FROM channels") == []

def sync_blockheight(nodes):
target = bitcoind.rpc.getblockcount()
Expand Down Expand Up @@ -865,6 +871,11 @@ def test_closing(self):
assert closetxid in set([o['txid'] for o in l1.rpc.listfunds()['outputs']])
assert closetxid in set([o['txid'] for o in l2.rpc.listfunds()['outputs']])

# Make sure both have forgotten about it
l1.bitcoin.rpc.generate(100)
wait_forget_channels(l1)
wait_forget_channels(l2)

@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
def test_permfail(self):
l1,l2 = self.connect()
Expand Down Expand Up @@ -909,11 +920,11 @@ def test_permfail(self):

# 100 after l1 sees tx, it should be done.
bitcoind.generate_block(95)
l1.daemon.wait_for_log('onchaind complete, forgetting peer')
wait_forget_channels(l1)

# Now, 100 blocks l2 should be done.
bitcoind.generate_block(5)
l2.daemon.wait_for_log('onchaind complete, forgetting peer')
wait_forget_channels(l2)

# Only l1 has a direct output since all of l2's outputs are respent (it failed)
assert closetxid in set([o['txid'] for o in l1.rpc.listfunds()['outputs']])
Expand Down Expand Up @@ -1273,7 +1284,7 @@ def test_penalty_outhtlc(self):
bitcoind.generate_block(100)

# FIXME: Test wallet balance...
l2.daemon.wait_for_log('onchaind complete, forgetting peer')
wait_forget_channels(l2)

@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
def test_permfail_new_commit(self):
Expand Down Expand Up @@ -1308,8 +1319,8 @@ def test_permfail_new_commit(self):

# Now, 100 blocks it should be done.
bitcoind.generate_block(100)
l1.daemon.wait_for_log('onchaind complete, forgetting peer')
l2.daemon.wait_for_log('onchaind complete, forgetting peer')
wait_forget_channels(l1)
wait_forget_channels(l2)

@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
def test_permfail_htlc_in(self):
Expand Down Expand Up @@ -1401,7 +1412,7 @@ def test_permfail_htlc_out(self):
bitcoind.generate_block(5)
assert not l2.daemon.is_in_log('onchaind complete, forgetting peer')
bitcoind.generate_block(1)
l2.daemon.wait_for_log('onchaind complete, forgetting peer')
wait_forget_channels(l2)

def test_gossip_jsonrpc(self):
l1, l2 = self.line_graph(n=2)
Expand Down
8 changes: 8 additions & 0 deletions wallet/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,14 @@ void wallet_channel_save(struct wallet *w, struct wallet_channel *chan,
tal_free(tmpctx);
}

void wallet_channel_delete(struct wallet *w, u64 wallet_id)
{
sqlite3_stmt *stmt;
stmt = db_prepare(w->db, "DELETE FROM channels WHERE id=?");
sqlite3_bind_int64(stmt, 1, wallet_id);
db_exec_prepared(w->db, stmt);
}

int wallet_extract_owned_outputs(struct wallet *w, const struct bitcoin_tx *tx,
u64 *total_satoshi)
{
Expand Down
5 changes: 5 additions & 0 deletions wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ bool wallet_shachain_load(struct wallet *wallet, u64 id,
void wallet_channel_save(struct wallet *w, struct wallet_channel *chan,
u32 current_block_height);

/**
* wallet_channel_delete -- After resolving a channel, forget about it
*/
void wallet_channel_delete(struct wallet *w, u64 wallet_id);

/**
* wallet_channel_config_save -- Upsert a channel_config into the database
*/
Expand Down