channeld: check option_data_loss_protect fields.

Firstly, if they claim to know a future value, we ask the HSM; if
they're right, we tell master what the per-commitment-secret it gave
us (we have no way to validate this, though) and it will not broadcast
a unilateral (knowing it will cause them to use a penalty tx!).

Otherwise, we check the results they sent were valid.  The spec says
to do this (and close the channel if it's wrong!), because otherwise they
could continually lie and give us a bad per-commitment-secret when we
actually need it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2018-08-17 14:36:36 +09:30
committed by Christian Decker
parent e7116284f0
commit 6aed936799
2 changed files with 215 additions and 11 deletions

View File

@@ -1156,7 +1156,12 @@ def test_dataloss_protection(node_factory):
"8a")
l1.fund_channel(l2, 10**6)
l2.restart()
l2.stop()
# Save copy of the db.
dbpath = os.path.join(l2.daemon.lightning_dir, "lightningd.sqlite3")
orig_db = open(dbpath, "rb").read()
l2.start()
# l1 should have sent WIRE_CHANNEL_REESTABLISH with option_data_loss_protect.
l1.daemon.wait_for_log("\[OUT\] 0088"
@@ -1192,3 +1197,21 @@ def test_dataloss_protection(node_factory):
"[0-9a-f]{64}"
# my_current_per_commitment_point
"0[23][0-9a-f]{64}")
# Now, move l2 back in time.
l2.stop()
# Overwrite with OLD db.
open(dbpath, "wb").write(orig_db)
l2.start()
# l2 should freak out!
l2.daemon.wait_for_log("Catastrophic failure: please close channel")
# l1 should drop to chain.
l1.daemon.wait_for_log('sendrawtx exit 0')
# l2 must NOT drop to chain.
l2.daemon.wait_for_log("Cannot broadcast our commitment tx: they have a future one")
assert not l2.daemon.is_in_log('sendrawtx exit 0')
# FIXME: l2 should still be able to collect onchain.