From de7fb4a83ff214a71409c125b8369630c7082b6f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 18 Aug 2016 14:23:45 +0930 Subject: [PATCH] test_protocol: restart support. We keep a "database" for each side's persistent state. Upon restart, each side tells the other where it was up to, in terms of the number of commit and revocation messages it receives. Because only one update can be in flight at a time, we can tell w Signed-off-by: Rusty Russell --- test/commits/20-restore-02.script | 24 + test/commits/20-restore-02.script.expected | 14 + test/commits/20-restore-03.script | 25 + test/commits/20-restore-03.script.expected | 14 + test/commits/20-restore-04.script | 24 + test/commits/20-restore-04.script.expected | 14 + test/commits/20-restore-05.script | 23 + test/commits/20-restore-05.script.expected | 14 + test/commits/20-restore-06.script | 23 + test/commits/20-restore-06.script.expected | 14 + test/commits/20-restore-07.script | 23 + test/commits/20-restore-07.script.expected | 14 + test/commits/20-restore-08.script | 23 + test/commits/20-restore-08.script.expected | 14 + test/commits/20-restore-09.script | 23 + test/commits/20-restore-09.script.expected | 14 + test/commits/20-restore-10.script | 24 + test/commits/20-restore-10.script.expected | 14 + test/commits/20-restore-11.script | 23 + test/commits/20-restore-11.script.expected | 14 + test/commits/20-restore-12.script | 24 + test/commits/20-restore-12.script.expected | 14 + test/commits/20-restore-13.script | 23 + test/commits/20-restore-13.script.expected | 14 + test/commits/20-restore-14.script | 23 + test/commits/20-restore-14.script.expected | 14 + test/commits/20-restore-15.script | 23 + test/commits/20-restore-15.script.expected | 14 + test/commits/20-restore-16.script | 23 + test/commits/20-restore-16.script.expected | 14 + test/commits/20-restore-17.script | 23 + test/commits/20-restore-17.script.expected | 14 + test/commits/21-restore-crossover-02.script | 25 + .../21-restore-crossover-02.script.expected | 22 + test/commits/21-restore-crossover-03.script | 26 + .../21-restore-crossover-03.script.expected | 22 + test/commits/21-restore-crossover-04.script | 25 + .../21-restore-crossover-04.script.expected | 22 + test/commits/21-restore-crossover-05.script | 24 + .../21-restore-crossover-05.script.expected | 22 + test/commits/21-restore-crossover-06.script | 25 + .../21-restore-crossover-06.script.expected | 22 + test/commits/21-restore-crossover-07.script | 26 + .../21-restore-crossover-07.script.expected | 22 + test/commits/21-restore-crossover-08.script | 25 + .../21-restore-crossover-08.script.expected | 22 + test/commits/21-restore-crossover-08a.script | 23 + .../21-restore-crossover-08a.script.expected | 22 + test/commits/21-restore-crossover-09.script | 24 + .../21-restore-crossover-09.script.expected | 22 + test/commits/21-restore-crossover-10.script | 24 + .../21-restore-crossover-10.script.expected | 22 + test/commits/21-restore-crossover-11.script | 24 + .../21-restore-crossover-11.script.expected | 22 + test/commits/21-restore-crossover-12.script | 24 + .../21-restore-crossover-12.script.expected | 22 + test/commits/21-restore-crossover-13.script | 24 + .../21-restore-crossover-13.script.expected | 22 + test/commits/21-restore-crossover-14.script | 24 + .../21-restore-crossover-14.script.expected | 22 + test/commits/21-restore-crossover-15.script | 24 + .../21-restore-crossover-15.script.expected | 22 + test/commits/21-restore-crossover-16.script | 24 + .../21-restore-crossover-16.script.expected | 22 + test/commits/21-restore-crossover-17.script | 24 + .../21-restore-crossover-17.script.expected | 22 + test/test_protocol.c | 585 +++++++++++++++--- 67 files changed, 1875 insertions(+), 97 deletions(-) create mode 100644 test/commits/20-restore-02.script create mode 100644 test/commits/20-restore-02.script.expected create mode 100644 test/commits/20-restore-03.script create mode 100644 test/commits/20-restore-03.script.expected create mode 100644 test/commits/20-restore-04.script create mode 100644 test/commits/20-restore-04.script.expected create mode 100644 test/commits/20-restore-05.script create mode 100644 test/commits/20-restore-05.script.expected create mode 100644 test/commits/20-restore-06.script create mode 100644 test/commits/20-restore-06.script.expected create mode 100644 test/commits/20-restore-07.script create mode 100644 test/commits/20-restore-07.script.expected create mode 100644 test/commits/20-restore-08.script create mode 100644 test/commits/20-restore-08.script.expected create mode 100644 test/commits/20-restore-09.script create mode 100644 test/commits/20-restore-09.script.expected create mode 100644 test/commits/20-restore-10.script create mode 100644 test/commits/20-restore-10.script.expected create mode 100644 test/commits/20-restore-11.script create mode 100644 test/commits/20-restore-11.script.expected create mode 100644 test/commits/20-restore-12.script create mode 100644 test/commits/20-restore-12.script.expected create mode 100644 test/commits/20-restore-13.script create mode 100644 test/commits/20-restore-13.script.expected create mode 100644 test/commits/20-restore-14.script create mode 100644 test/commits/20-restore-14.script.expected create mode 100644 test/commits/20-restore-15.script create mode 100644 test/commits/20-restore-15.script.expected create mode 100644 test/commits/20-restore-16.script create mode 100644 test/commits/20-restore-16.script.expected create mode 100644 test/commits/20-restore-17.script create mode 100644 test/commits/20-restore-17.script.expected create mode 100644 test/commits/21-restore-crossover-02.script create mode 100644 test/commits/21-restore-crossover-02.script.expected create mode 100644 test/commits/21-restore-crossover-03.script create mode 100644 test/commits/21-restore-crossover-03.script.expected create mode 100644 test/commits/21-restore-crossover-04.script create mode 100644 test/commits/21-restore-crossover-04.script.expected create mode 100644 test/commits/21-restore-crossover-05.script create mode 100644 test/commits/21-restore-crossover-05.script.expected create mode 100644 test/commits/21-restore-crossover-06.script create mode 100644 test/commits/21-restore-crossover-06.script.expected create mode 100644 test/commits/21-restore-crossover-07.script create mode 100644 test/commits/21-restore-crossover-07.script.expected create mode 100644 test/commits/21-restore-crossover-08.script create mode 100644 test/commits/21-restore-crossover-08.script.expected create mode 100644 test/commits/21-restore-crossover-08a.script create mode 100644 test/commits/21-restore-crossover-08a.script.expected create mode 100644 test/commits/21-restore-crossover-09.script create mode 100644 test/commits/21-restore-crossover-09.script.expected create mode 100644 test/commits/21-restore-crossover-10.script create mode 100644 test/commits/21-restore-crossover-10.script.expected create mode 100644 test/commits/21-restore-crossover-11.script create mode 100644 test/commits/21-restore-crossover-11.script.expected create mode 100644 test/commits/21-restore-crossover-12.script create mode 100644 test/commits/21-restore-crossover-12.script.expected create mode 100644 test/commits/21-restore-crossover-13.script create mode 100644 test/commits/21-restore-crossover-13.script.expected create mode 100644 test/commits/21-restore-crossover-14.script create mode 100644 test/commits/21-restore-crossover-14.script.expected create mode 100644 test/commits/21-restore-crossover-15.script create mode 100644 test/commits/21-restore-crossover-15.script.expected create mode 100644 test/commits/21-restore-crossover-16.script create mode 100644 test/commits/21-restore-crossover-16.script.expected create mode 100644 test/commits/21-restore-crossover-17.script create mode 100644 test/commits/21-restore-crossover-17.script.expected diff --git a/test/commits/20-restore-02.script b/test/commits/20-restore-02.script new file mode 100644 index 000000000..833af6d41 --- /dev/null +++ b/test/commits/20-restore-02.script @@ -0,0 +1,24 @@ +# Variety of tests for save/restore. +A:offer 1 +restart +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-02.script.expected b/test/commits/20-restore-02.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-02.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-03.script b/test/commits/20-restore-03.script new file mode 100644 index 000000000..c19630e4c --- /dev/null +++ b/test/commits/20-restore-03.script @@ -0,0 +1,25 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +restart +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-03.script.expected b/test/commits/20-restore-03.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-03.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-04.script b/test/commits/20-restore-04.script new file mode 100644 index 000000000..6af9c2b58 --- /dev/null +++ b/test/commits/20-restore-04.script @@ -0,0 +1,24 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +restart +B:recvoffer +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-04.script.expected b/test/commits/20-restore-04.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-04.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-05.script b/test/commits/20-restore-05.script new file mode 100644 index 000000000..fb8c08c59 --- /dev/null +++ b/test/commits/20-restore-05.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +restart +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-05.script.expected b/test/commits/20-restore-05.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-05.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-06.script b/test/commits/20-restore-06.script new file mode 100644 index 000000000..3db9a5295 --- /dev/null +++ b/test/commits/20-restore-06.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +restart +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-06.script.expected b/test/commits/20-restore-06.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-06.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-07.script b/test/commits/20-restore-07.script new file mode 100644 index 000000000..947a5d1bf --- /dev/null +++ b/test/commits/20-restore-07.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +restart +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-07.script.expected b/test/commits/20-restore-07.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-07.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-08.script b/test/commits/20-restore-08.script new file mode 100644 index 000000000..e6e78d266 --- /dev/null +++ b/test/commits/20-restore-08.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +restart +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-08.script.expected b/test/commits/20-restore-08.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-08.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-09.script b/test/commits/20-restore-09.script new file mode 100644 index 000000000..a0fe539d9 --- /dev/null +++ b/test/commits/20-restore-09.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +restart +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-09.script.expected b/test/commits/20-restore-09.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-09.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-10.script b/test/commits/20-restore-10.script new file mode 100644 index 000000000..23d2293af --- /dev/null +++ b/test/commits/20-restore-10.script @@ -0,0 +1,24 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +restart +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-10.script.expected b/test/commits/20-restore-10.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-10.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-11.script b/test/commits/20-restore-11.script new file mode 100644 index 000000000..225aaac74 --- /dev/null +++ b/test/commits/20-restore-11.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +restart +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-11.script.expected b/test/commits/20-restore-11.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-11.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-12.script b/test/commits/20-restore-12.script new file mode 100644 index 000000000..a788a2953 --- /dev/null +++ b/test/commits/20-restore-12.script @@ -0,0 +1,24 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +restart +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-12.script.expected b/test/commits/20-restore-12.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-12.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-13.script b/test/commits/20-restore-13.script new file mode 100644 index 000000000..518370033 --- /dev/null +++ b/test/commits/20-restore-13.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +restart +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-13.script.expected b/test/commits/20-restore-13.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-13.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-14.script b/test/commits/20-restore-14.script new file mode 100644 index 000000000..9f4ce908e --- /dev/null +++ b/test/commits/20-restore-14.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +restart +A:commit +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-14.script.expected b/test/commits/20-restore-14.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-14.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-15.script b/test/commits/20-restore-15.script new file mode 100644 index 000000000..e402526de --- /dev/null +++ b/test/commits/20-restore-15.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +restart +B:recvcommit +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-15.script.expected b/test/commits/20-restore-15.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-15.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-16.script b/test/commits/20-restore-16.script new file mode 100644 index 000000000..13f116d46 --- /dev/null +++ b/test/commits/20-restore-16.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +restart +A:recvrevoke +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-16.script.expected b/test/commits/20-restore-16.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-16.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/20-restore-17.script b/test/commits/20-restore-17.script new file mode 100644 index 000000000..98cc99d4b --- /dev/null +++ b/test/commits/20-restore-17.script @@ -0,0 +1,23 @@ +# Variety of tests for save/restore. +A:offer 1 +B:recvoffer +A:commit +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke +B:remove 1 +B:commit +A:recvremove +A:recvcommit +B:recvrevoke +A:commit +B:recvcommit +A:recvrevoke +restart +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/20-restore-17.script.expected b/test/commits/20-restore-17.script.expected new file mode 100644 index 000000000..79acdd358 --- /dev/null +++ b/test/commits/20-restore-17.script.expected @@ -0,0 +1,14 @@ +***A*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + SIGNED +REMOTE COMMIT: + Commit 2: + SIGNED diff --git a/test/commits/21-restore-crossover-02.script b/test/commits/21-restore-crossover-02.script new file mode 100644 index 000000000..5ee637d31 --- /dev/null +++ b/test/commits/21-restore-crossover-02.script @@ -0,0 +1,25 @@ +# Restart during commits which cross over still. +A:offer 1 +restart +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-02.script.expected b/test/commits/21-restore-crossover-02.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-02.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-03.script b/test/commits/21-restore-crossover-03.script new file mode 100644 index 000000000..15da68994 --- /dev/null +++ b/test/commits/21-restore-crossover-03.script @@ -0,0 +1,26 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +restart +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-03.script.expected b/test/commits/21-restore-crossover-03.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-03.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-04.script b/test/commits/21-restore-crossover-04.script new file mode 100644 index 000000000..ea5fb3084 --- /dev/null +++ b/test/commits/21-restore-crossover-04.script @@ -0,0 +1,25 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +restart +B:offer 2 +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-04.script.expected b/test/commits/21-restore-crossover-04.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-04.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-05.script b/test/commits/21-restore-crossover-05.script new file mode 100644 index 000000000..730363cbd --- /dev/null +++ b/test/commits/21-restore-crossover-05.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +restart +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-05.script.expected b/test/commits/21-restore-crossover-05.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-05.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-06.script b/test/commits/21-restore-crossover-06.script new file mode 100644 index 000000000..d8c7b6cf8 --- /dev/null +++ b/test/commits/21-restore-crossover-06.script @@ -0,0 +1,25 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +restart +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-06.script.expected b/test/commits/21-restore-crossover-06.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-06.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-07.script b/test/commits/21-restore-crossover-07.script new file mode 100644 index 000000000..99e554c4f --- /dev/null +++ b/test/commits/21-restore-crossover-07.script @@ -0,0 +1,26 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +restart +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-07.script.expected b/test/commits/21-restore-crossover-07.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-07.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-08.script b/test/commits/21-restore-crossover-08.script new file mode 100644 index 000000000..c7d8f51c9 --- /dev/null +++ b/test/commits/21-restore-crossover-08.script @@ -0,0 +1,25 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +restart +B:recvoffer +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-08.script.expected b/test/commits/21-restore-crossover-08.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-08.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-08a.script b/test/commits/21-restore-crossover-08a.script new file mode 100644 index 000000000..979b28e11 --- /dev/null +++ b/test/commits/21-restore-crossover-08a.script @@ -0,0 +1,23 @@ +# Restart during commits which cross over still. +# In this variant, A sends revocation *before* sending commit. +A:offer 1 +B:offer 2 +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +A:commit +restart +B:recvrevoke +B:recvoffer +B:recvcommit +A:recvrevoke +B:commit +A:recvcommit +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-08a.script.expected b/test/commits/21-restore-crossover-08a.script.expected new file mode 100644 index 000000000..f4ca6477a --- /dev/null +++ b/test/commits/21-restore-crossover-08a.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 1: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 1: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-09.script b/test/commits/21-restore-crossover-09.script new file mode 100644 index 000000000..65d66f255 --- /dev/null +++ b/test/commits/21-restore-crossover-09.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +restart +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-09.script.expected b/test/commits/21-restore-crossover-09.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-09.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-10.script b/test/commits/21-restore-crossover-10.script new file mode 100644 index 000000000..92b47ec07 --- /dev/null +++ b/test/commits/21-restore-crossover-10.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +restart +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-10.script.expected b/test/commits/21-restore-crossover-10.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-10.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-11.script b/test/commits/21-restore-crossover-11.script new file mode 100644 index 000000000..f73726bf8 --- /dev/null +++ b/test/commits/21-restore-crossover-11.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +restart +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-11.script.expected b/test/commits/21-restore-crossover-11.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-11.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-12.script b/test/commits/21-restore-crossover-12.script new file mode 100644 index 000000000..178e58730 --- /dev/null +++ b/test/commits/21-restore-crossover-12.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +restart +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-12.script.expected b/test/commits/21-restore-crossover-12.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-12.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-13.script b/test/commits/21-restore-crossover-13.script new file mode 100644 index 000000000..b81532ddd --- /dev/null +++ b/test/commits/21-restore-crossover-13.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +restart +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-13.script.expected b/test/commits/21-restore-crossover-13.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-13.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-14.script b/test/commits/21-restore-crossover-14.script new file mode 100644 index 000000000..b6d7b05d0 --- /dev/null +++ b/test/commits/21-restore-crossover-14.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +restart +B:recvcommit +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-14.script.expected b/test/commits/21-restore-crossover-14.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-14.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-15.script b/test/commits/21-restore-crossover-15.script new file mode 100644 index 000000000..13131790b --- /dev/null +++ b/test/commits/21-restore-crossover-15.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +restart +A:recvrevoke +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-15.script.expected b/test/commits/21-restore-crossover-15.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-15.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-16.script b/test/commits/21-restore-crossover-16.script new file mode 100644 index 000000000..5445dc2f6 --- /dev/null +++ b/test/commits/21-restore-crossover-16.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +restart +B:recvrevoke + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-16.script.expected b/test/commits/21-restore-crossover-16.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-16.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/commits/21-restore-crossover-17.script b/test/commits/21-restore-crossover-17.script new file mode 100644 index 000000000..85b234cb8 --- /dev/null +++ b/test/commits/21-restore-crossover-17.script @@ -0,0 +1,24 @@ +# Restart during commits which cross over still. +A:offer 1 +B:offer 2 +A:commit +B:commit +A:recvoffer +B:recvoffer +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +A:commit +B:commit +A:recvcommit +B:recvcommit +A:recvrevoke +B:recvrevoke +restart + +checksync +echo ***A*** +A:dump +echo ***B*** +B:dump diff --git a/test/commits/21-restore-crossover-17.script.expected b/test/commits/21-restore-crossover-17.script.expected new file mode 100644 index 000000000..56fb201da --- /dev/null +++ b/test/commits/21-restore-crossover-17.script.expected @@ -0,0 +1,22 @@ +***A*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 1 + Their htlcs: 2 + SIGNED +***B*** +LOCAL COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED +REMOTE COMMIT: + Commit 2: + Our htlcs: 2 + Their htlcs: 1 + SIGNED diff --git a/test/test_protocol.c b/test/test_protocol.c index 3924ea0de..247de4500 100644 --- a/test/test_protocol.c +++ b/test/test_protocol.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,9 @@ struct commit_info { bool revoked; /* Have their signature, ie. can be broadcast */ bool counterparty_signed; + u16 pad; + /* num_commit_or_revoke when we sent/received this. */ + size_t order; }; /* A "signature" is a copy of the commit tx state, for easy diagnosis. */ @@ -202,6 +206,20 @@ static struct commit_tx make_commit_tx(struct htlc **htlcs, int local_or_remote) return tx; } +struct database { + /* This keeps *all* our HTLCs, including expired ones. */ + size_t num_htlcs; + struct htlc htlcs[100]; + + /* This counts the number of received commit and revocation pkts. */ + size_t last_recv; + size_t last_sent; + + /* We keep remote_prev because it might not be revoked, and this + * makes our receive_revoke logic simpler. */ + struct commit_info local, remote, remote_prev; +}; + struct peer { const char *name; @@ -210,13 +228,71 @@ struct peer { /* For drawing svg */ char *info; + /* What we save on disk. */ + struct database db; + /* All htlcs. */ struct htlc **htlcs; - + /* Last one is the one we're changing. */ struct commit_info *local, *remote; }; +static void db_update_htlc(struct database *db, const struct htlc *htlc) +{ + size_t i; + + for (i = 0; i < db->num_htlcs; i++) { + if ((db->htlcs[i].state & (OURS|THEIRS)) + != (htlc->state & (OURS|THEIRS))) + continue; + /* FIXME: This isn't quite right for multiple fee changes. */ + if (db->htlcs[i].id == htlc->id) + break; + } + if (i == db->num_htlcs) { + db->num_htlcs++; + if (db->num_htlcs > ARRAY_SIZE(db->htlcs)) + errx(1, "Too many htlcs"); + } + db->htlcs[i] = *htlc; +} + +static void db_recv_local_commit(struct database *db, + const struct commit_info *ci) +{ + db->last_recv++; + db->local = *ci; +} + +static void db_send_remote_commit(struct peer *peer, + struct database *db, + const struct commit_info *ci, + struct signature sig) +{ + if (ci->prev) + db->remote_prev = *ci->prev; + db->remote = *ci; + db->remote.order = ++db->last_sent; +} + +static void db_send_local_revoke(struct database *db, + const struct commit_info *ci) +{ + db->last_sent++; +} + +static void db_recv_remote_revoke(struct database *db, + const struct commit_info *ci) +{ + assert(ci->revoked); + + db->last_recv++; + db->remote_prev.revoked = true; + + /* A real db would save the previous revocation hash here too */ +} + static struct htlc *find_htlc(struct peer *peer, unsigned int htlc_id, int side) { size_t i, n = tal_count(peer->htlcs); @@ -247,6 +323,7 @@ static struct htlc *new_htlc(struct peer *peer, unsigned int htlc_id, int side) static void htlc_changestate(struct peer *peer, struct htlc *htlc, + bool commit, enum htlc_state old, enum htlc_state new) { @@ -267,13 +344,15 @@ static void htlc_changestate(struct peer *peer, htlc_statename(new)); } htlc->state = new; + if (commit) + db_update_htlc(&peer->db, htlc); } struct state_table { enum htlc_state from, to; }; -static bool change_htlcs_(struct peer *peer, +static bool change_htlcs_(struct peer *peer, bool commit, const struct state_table *table, size_t n_table) { @@ -284,7 +363,7 @@ static bool change_htlcs_(struct peer *peer, size_t t; for (t = 0; t < n_table; t++) { if (peer->htlcs[i]->state == table[t].from) { - htlc_changestate(peer, peer->htlcs[i], + htlc_changestate(peer, peer->htlcs[i], commit, table[t].from, table[t].to); changed = true; break; @@ -294,8 +373,8 @@ static bool change_htlcs_(struct peer *peer, return changed; } -#define change_htlcs(peer, table) \ - change_htlcs_((peer), (table), ARRAY_SIZE(table)) +#define change_htlcs(peer, table, commit) \ + change_htlcs_((peer), (commit), (table), ARRAY_SIZE(table)) static struct commit_info *new_commit_info(const struct peer *peer, struct commit_info *prev) @@ -305,6 +384,8 @@ static struct commit_info *new_commit_info(const struct peer *peer, ci->prev = prev; ci->revoked = false; ci->counterparty_signed = false; + ci->pad = 0; + ci->order = 0; if (prev) ci->number = prev->number + 1; else @@ -433,6 +514,14 @@ static void PRINTF_FMT(2,3) record_send(struct peer *peer, const char *fmt, ...) tal_append_vfmt(&peer->info, fmt, ap); tal_append_fmt(&peer->info, "\n"); va_end(ap); + + if (verbose) { + va_start(ap, fmt); + printf("%s: SEND ", peer->name); + vprintf(fmt, ap); + printf("\n"); + va_end(ap); + } } static void PRINTF_FMT(2,3) record_recv(struct peer *peer, const char *fmt, ...) @@ -444,16 +533,56 @@ static void PRINTF_FMT(2,3) record_recv(struct peer *peer, const char *fmt, ...) tal_append_vfmt(&peer->info, fmt, ap); tal_append_fmt(&peer->info, "\n"); va_end(ap); + + if (verbose) { + va_start(ap, fmt); + printf("%s: RECEIVE ", peer->name); + vprintf(fmt, ap); + printf("\n"); + va_end(ap); + } +} + +static void xmit_add_htlc(struct peer *peer, const struct htlc *h) +{ + record_send(peer, "add_htlc %u", h->id); + write_out(peer->outfd, "+", 1); + write_out(peer->outfd, &h->id, sizeof(h->id)); +} + +static void xmit_remove_htlc(struct peer *peer, const struct htlc *h) +{ + record_send(peer, "fulfill_htlc %u", h->id); + write_out(peer->outfd, "-", 1); + write_out(peer->outfd, &h->id, sizeof(h->id)); +} + +static void xmit_feechange(struct peer *peer) +{ + record_send(peer, "update_fee"); + write_out(peer->outfd, "F", 1); +} + +static void xmit_commit(struct peer *peer, struct signature sig) +{ + record_send(peer, "update_commit"); + write_out(peer->outfd, "C", 1); + write_out(peer->outfd, &sig, sizeof(sig)); +} + +static void xmit_revoke(struct peer *peer, unsigned int number) +{ + record_send(peer, "update_revocation"); + write_out(peer->outfd, "R", 1); + write_out(peer->outfd, &number, sizeof(number)); } static void send_offer(struct peer *peer, unsigned int htlc) { struct htlc *h = new_htlc(peer, htlc, OURS); - htlc_changestate(peer, h, NONEXISTENT, SENT_ADD_HTLC); - record_send(peer, "add_htlc %u", htlc); - write_out(peer->outfd, "+", 1); - write_out(peer->outfd, &htlc, sizeof(htlc)); + htlc_changestate(peer, h, false, NONEXISTENT, SENT_ADD_HTLC); + xmit_add_htlc(peer, h); } static void send_remove(struct peer *peer, unsigned int htlc) @@ -461,22 +590,19 @@ static void send_remove(struct peer *peer, unsigned int htlc) struct htlc *h = find_htlc(peer, htlc, THEIRS); if (!h) - errx(1, "send_remove: htlc %u does not exist", htlc); + errx(1, "%s: send_remove: htlc %u does not exist", + peer->name, htlc); - htlc_changestate(peer, h, RECV_ADD_ACK_REVOCATION, SENT_REMOVE_HTLC); - - record_send(peer, "fulfill_htlc %u", htlc); - write_out(peer->outfd, "-", 1); - write_out(peer->outfd, &htlc, sizeof(htlc)); + htlc_changestate(peer, h, false, RECV_ADD_ACK_REVOCATION, SENT_REMOVE_HTLC); + xmit_remove_htlc(peer, h); } static void send_feechange(struct peer *peer) { struct htlc *fee = new_htlc(peer, 0, OURS); - htlc_changestate(peer, fee, NONEXISTENT, SENT_ADD_HTLC); - record_send(peer, "update_fee"); - write_out(peer->outfd, "F", 1); + htlc_changestate(peer, fee, false, NONEXISTENT, SENT_ADD_HTLC); + xmit_feechange(peer); } /* @@ -501,8 +627,9 @@ static struct commit_info *last_unrevoked(struct commit_info *ci) static void send_commit(struct peer *peer) { + struct commit_tx tx; struct signature sig; - struct commit_tx commit_tx; + static const struct state_table changes[] = { { SENT_ADD_HTLC, SENT_ADD_COMMIT }, { SENT_REMOVE_REVOCATION, SENT_REMOVE_ACK_COMMIT }, @@ -517,17 +644,7 @@ static void send_commit(struct peer *peer) * previous `update_commit`, so there is only ever one * unrevoked local commitment. */ if (peer->remote->prev && !peer->remote->prev->revoked) - errx(1, "commit: must wait for previous commit"); - - record_send(peer, "update_commit"); - - /* BOLT #2: - * - * A node MUST NOT send an `update_commit` message which does - * not include any updates. - */ - if (!change_htlcs(peer, changes)) - errx(1, "commit: no changes to commit"); + errx(1, "%s: commit: must wait for previous commit", peer->name); /* BOLT #2: * @@ -535,15 +652,23 @@ static void send_commit(struct peer *peer) * changes except unacked fee changes to the remote commitment * before generating `sig`. */ - commit_tx = make_commit_tx(peer->htlcs, REMOTE_); + if (!change_htlcs(peer, changes, true)) { + /* BOLT #2: + * + * A node MUST NOT send an `update_commit` message which does + * not include any updates. + */ + errx(1, "%s: commit: no changes to commit", peer->name); + } + tx = make_commit_tx(peer->htlcs, REMOTE_); + sig = commit_sig(&tx); peer->remote = new_commit_info(peer, peer->remote); peer->remote->counterparty_signed = true; - sig = commit_sig(&commit_tx); + db_send_remote_commit(peer, &peer->db, peer->remote, sig); /* Tell other side about commit and result (it should agree!) */ - write_out(peer->outfd, "C", 1); - write_out(peer->outfd, &sig, sizeof(sig)); + xmit_commit(peer, sig); } static void receive_revoke(struct peer *peer, u32 number) @@ -557,22 +682,29 @@ static void receive_revoke(struct peer *peer, u32 number) struct commit_info *ci = last_unrevoked(peer->remote); if (!ci) - errx(1, "receive_revoke: no commit to revoke"); + errx(1, "%s: receive_revoke: no commit to revoke", peer->name); if (ci->number != number) - errx(1, "receive_revoke: revoked %u but %u is next", - number, ci->number); + errx(1, "%s: receive_revoke: revoked %u but %u is next", + peer->name, number, ci->number); /* This shouldn't happen if we don't allow multiple commits. */ if (ci != peer->remote->prev) - errx(1, "receive_revoke: always revoke previous?"); + errx(1, "%s: receive_revoke: always revoke previous?", + peer->name); + + if (ci->revoked) + errx(1, "%s: receive_revoke: already revoked?", peer->name); record_recv(peer, "update_revocation"); ci->revoked = true; if (!ci->counterparty_signed) - errx(1, "receive_revoke: revoked unsigned commit?"); + errx(1, "%s: receive_revoke: revoked unsigned commit?", + peer->name); + + if (!change_htlcs(peer, changes, true)) + errx(1, "%s: receive_revoke: no changes?", peer->name); - if (!change_htlcs(peer, changes)) - errx(1, "receive_revoke: no changes?"); + db_recv_remote_revoke(&peer->db, ci); } /* BOLT #2: @@ -584,7 +716,7 @@ static void receive_offer(struct peer *peer, unsigned int htlc) { struct htlc *h = new_htlc(peer, htlc, THEIRS); - htlc_changestate(peer, h, NONEXISTENT, RECV_ADD_HTLC); + htlc_changestate(peer, h, false, NONEXISTENT, RECV_ADD_HTLC); record_recv(peer, "add_htlc %u", h->id); } @@ -598,9 +730,10 @@ static void receive_remove(struct peer *peer, unsigned int htlc) struct htlc *h = find_htlc(peer, htlc, OURS); if (!h) - errx(1, "recv_remove: htlc %u does not exist", htlc); + errx(1, "%s: recv_remove: htlc %u does not exist", + peer->name, htlc); - htlc_changestate(peer, h, SENT_ADD_ACK_REVOCATION, RECV_REMOVE_HTLC); + htlc_changestate(peer, h, false, SENT_ADD_ACK_REVOCATION, RECV_REMOVE_HTLC); record_recv(peer, "fulfill_htlc %u", h->id); } @@ -613,7 +746,7 @@ static void receive_feechange(struct peer *peer) { struct htlc *fee = new_htlc(peer, 0, THEIRS); - htlc_changestate(peer, fee, NONEXISTENT, RECV_ADD_HTLC); + htlc_changestate(peer, fee, false, NONEXISTENT, RECV_ADD_HTLC); record_recv(peer, "update_fee"); } @@ -628,7 +761,6 @@ static void send_revoke(struct peer *peer, struct commit_info *ci) { RECV_ADD_COMMIT, SENT_ADD_REVOCATION }, { RECV_REMOVE_ACK_COMMIT, SENT_REMOVE_ACK_REVOCATION } }; - record_send(peer, "update_revocation"); /* We always revoke in order. */ assert(!ci->prev || ci->prev->revoked); @@ -636,11 +768,11 @@ static void send_revoke(struct peer *peer, struct commit_info *ci) assert(!ci->revoked); ci->revoked = true; - if (!change_htlcs(peer, changes)) - errx(1, "update_revocation: no changes?"); + if (!change_htlcs(peer, changes, true)) + errx(1, "%s: update_revocation: no changes?", peer->name); - write_out(peer->outfd, "R", 1); - write_out(peer->outfd, &ci->number, sizeof(ci->number)); + db_send_local_revoke(&peer->db, ci); + xmit_revoke(peer, ci->number); } /* Receive commit: @@ -664,22 +796,135 @@ static void receive_commit(struct peer *peer, const struct signature *sig) * A node MUST NOT send an `update_commit` message which does * not include any updates. */ - if (!change_htlcs(peer, changes)) - errx(1, "receive_commit: no changes to commit"); + if (!change_htlcs(peer, changes, true)) + errx(1, "%s: receive_commit: no changes to commit", peer->name); commit_tx = make_commit_tx(peer->htlcs, LOCAL_); oursig = commit_sig(&commit_tx); if (!structeq(sig, &oursig)) - errx(1, "Commit state %#x/%#x/%u, they gave %#x/%#x/%u", + errx(1, "%s: Commit state %#x/%#x/%u, they gave %#x/%#x/%u", + peer->name, sig->f.inhtlcs, sig->f.outhtlcs, sig->f.fee, oursig.f.inhtlcs, oursig.f.outhtlcs, oursig.f.fee); peer->local = new_commit_info(peer, peer->local); peer->local->counterparty_signed = true; + db_recv_local_commit(&peer->db, peer->local); + send_revoke(peer, peer->local->prev); } +static void resend_updates(struct peer *peer) +{ + size_t i; + + /* Re-transmit our add, removes and fee changes. */ + for (i = 0; i < tal_count(peer->htlcs); i++) { + switch (peer->htlcs[i]->state) { + case SENT_ADD_COMMIT: + if (peer->htlcs[i]->id) + xmit_add_htlc(peer, peer->htlcs[i]); + else + xmit_feechange(peer); + break; + case SENT_REMOVE_COMMIT: + xmit_remove_htlc(peer, peer->htlcs[i]); + break; + default: + break; + } + } +} + +static void restore_state(struct peer *peer) +{ + size_t i, sent, num_revokes, revoke_idx; + + peer->htlcs = tal_arr(peer, struct htlc *, peer->db.num_htlcs); + for (i = 0; i < peer->db.num_htlcs; i++) { + peer->htlcs[i] = tal_dup(peer->htlcs, struct htlc, + &peer->db.htlcs[i]); + if (verbose) + printf("%s: HTLC %u %s\n", + peer->name, peer->htlcs[i]->id, + htlc_statename(peer->htlcs[i]->state)); + } + + *peer->local = peer->db.local; + peer->local->prev = NULL; + + *peer->remote = peer->db.remote; + if (peer->remote->number != 0) { + peer->remote->prev = tal(peer, struct commit_info); + *peer->remote->prev = peer->db.remote_prev; + peer->remote->prev->prev = NULL; + } else + peer->remote->prev = NULL; + + /* Tell peer where we've received. */ + write_out(peer->outfd, "!", 1); + write_out(peer->outfd, &peer->db.last_recv, sizeof(peer->db.last_recv)); + + /* Find out where peer is up to. */ + read_peer(peer, "!", "restore"); + read_in(peer->infd, &sent, sizeof(sent)); + + if (verbose) + printf("%s: peer is up to %zu/%zu: last commit at %zu\n", + peer->name, sent, peer->db.last_sent,peer->remote->order); + + if (sent > peer->db.last_sent) + errx(1, "%s: peer said up to %zu, but we only sent %zu", + peer->name, sent, peer->db.last_sent); + + /* All up to date? Nothing to do. */ + if (sent == peer->db.last_sent) + return; + + /* Since we wait for revocation replies, only one of the missing + * could be our update; the rest must be revocations. */ + num_revokes = peer->db.last_sent - sent - (sent < peer->remote->order); + + if (num_revokes > peer->local->number) + errx(1, "%s: can't rexmit %zu revoke txs at %u", + peer->name, num_revokes, peer->local->number); + + revoke_idx = peer->local->number - num_revokes; + + /* If we sent a revocation before the commit. */ + if (sent + 1 < peer->remote->order) { + xmit_revoke(peer, revoke_idx++); + num_revokes--; + sent++; + } + + /* If they didn't get the last commit, re-send all. */ + if (sent + 1 == peer->remote->order) { + struct commit_tx tx; + struct signature sig; + + resend_updates(peer); + tx = make_commit_tx(peer->htlcs, REMOTE_); + sig = commit_sig(&tx); + xmit_commit(peer, sig); + sent++; + } + + /* Now send any revocations after the commit. */ + if (sent + 1 == peer->db.last_sent) { + num_revokes--; + xmit_revoke(peer, revoke_idx++); + sent++; + } + + if (sent != peer->db.last_sent) + errx(1, "%s: could not catch up %zu to %zu", + peer->name, sent, peer->db.last_sent); + + assert(num_revokes == 0); +} + static void do_cmd(struct peer *peer) { char cmd[80]; @@ -729,6 +974,14 @@ static void do_cmd(struct peer *peer) read_peer(peer, "C", cmd); read_in(peer->infd, &sig, sizeof(sig)); receive_commit(peer, &sig); + } else if (streq(cmd, "save")) { + write_all(peer->cmddonefd, &peer->db, sizeof(peer->db)); + return; + } else if (streq(cmd, "restore")) { + write_all(peer->cmddonefd, "", 1); + /* Ack, then read in blob */ + read_all(peer->cmdfd, &peer->db, sizeof(peer->db)); + restore_state(peer); } else if (streq(cmd, "checksync")) { struct commit_tx ours, theirs; @@ -778,6 +1031,8 @@ static void new_peer(const char *name, peer = tal(NULL, struct peer); peer->name = name; peer->htlcs = tal_arr(peer, struct htlc *, 0); + + memset(&peer->db, 0, sizeof(peer->db)); /* Create first, signed commit info. */ peer->local = new_commit_info(peer, NULL); @@ -786,6 +1041,9 @@ static void new_peer(const char *name, peer->remote = new_commit_info(peer, NULL); peer->remote->counterparty_signed = true; + peer->db.local = *peer->local; + peer->db.remote = *peer->remote; + peer->infd = infdpair[0]; peer->outfd = outfdpair[1]; peer->cmdfd = cmdfdpair[0]; @@ -808,6 +1066,18 @@ static void add_sent(struct sent **sent, int y, const char *msg) (*sent)[n].desc = tal_strdup(*sent, msg); } +static void draw_restart(char **str, const char *name, + struct sent **a_sent, struct sent **b_sent, + int *y) +{ + *y += STEP_HEIGHT / 2; + tal_append_fmt(str, "\n", + A_TEXTX - 50, *y, B_TEXTX + 50, *y); + tal_append_fmt(str, "%s\n", + (A_TEXTX + B_TEXTX) / 2, *y - TEXT_HEIGHT/2, name); + *y += STEP_HEIGHT / 2; +} + static void draw_line(char **str, int old_x, struct sent **sent, const char *what, int new_x, int new_y) @@ -819,18 +1089,33 @@ static void draw_line(char **str, if (!streq((*sent)->desc, what)) errx(1, "Received %s but sent %s?", what, (*sent)->desc); - tal_append_fmt(str, "\n", - old_x, (*sent)[0].y - LINE_HEIGHT/2, - new_x, new_y - LINE_HEIGHT/2); - tal_append_fmt(str, "%s\n", - (old_x + new_x) / 2, - ((*sent)[0].y + new_y) / 2, - (*sent)[0].desc); + if (*str) { + tal_append_fmt(str, "\n", + old_x, (*sent)[0].y - LINE_HEIGHT/2, + new_x, new_y - LINE_HEIGHT/2); + tal_append_fmt(str, "%s\n", + (old_x + new_x) / 2, + ((*sent)[0].y + new_y) / 2, + (*sent)[0].desc); + } memmove(*sent, (*sent)+1, sizeof(**sent) * (n-1)); tal_resize(sent, n-1); } +static void reset_sends(char **svg, bool is_a, struct sent **sent, int *y) +{ + /* These sends were lost. */ + while (tal_count(*sent)) { + if (is_a) + draw_line(svg, A_LINEX, sent, (*sent)->desc, + (B_LINEX + A_LINEX)/2, *y - STEP_HEIGHT/2); + else + draw_line(svg, B_LINEX, sent, (*sent)->desc, + (B_LINEX + A_LINEX)/2, *y - STEP_HEIGHT/2); + } +} + static bool append_text(char **svg, bool is_a, int *y, const char *text, size_t *max_chars) { @@ -872,16 +1157,17 @@ static bool process_output(char **svg, bool is_a, const char *output, else draw_line(svg, A_LINEX, a_sent, outputs[i]+1, B_LINEX, *y); + *y += STEP_HEIGHT; } else if (strstarts(outputs[i], ">")) { if (is_a) add_sent(a_sent, *y, outputs[i]+1); else add_sent(b_sent, *y, outputs[i]+1); + *y += STEP_HEIGHT; } else { append_text(svg, is_a, y, outputs[i], max_chars); } } - *y += STEP_HEIGHT; return true; } @@ -904,6 +1190,81 @@ static void get_output(int donefd, char **svg, bool is_a, process_output(svg, is_a, output, a_sent, b_sent, y, max_chars); } +static void start_clients(int a_to_b[2], + int b_to_a[2], + int acmd[2], + int bcmd[2], + int adonefd[2], + int bdonefd[2]) +{ + if (pipe(a_to_b) || pipe(b_to_a) || pipe(adonefd) || pipe(acmd)) + err(1, "Creating pipes"); + + new_peer("A", a_to_b, b_to_a, acmd, adonefd); + + if (pipe(bdonefd) || pipe(bcmd)) + err(1, "Creating pipes"); + + new_peer("B", b_to_a, a_to_b, bcmd, bdonefd); + + close(acmd[0]); + close(bcmd[0]); + close(adonefd[1]); + close(bdonefd[1]); + close(b_to_a[0]); + close(b_to_a[1]); + close(a_to_b[0]); + close(a_to_b[1]); +} + +static void do_nothing(int sig) +{ +} + +static void read_from_client(const char *desc, int fd, void *dst, size_t len) +{ + alarm(5); + while (len) { + int r = read(fd, dst, len); + if (r < 0) + err(1, "Reading from %s", desc); + if (r == 0) + errx(1, "%s closed", desc); + len -= r; + dst += r; + } + alarm(0); +} + +static void write_to_client(const char *desc, int fd, const void *dst, size_t len) +{ + if (!write_all(fd, dst, len)) + err(1, "Writing to %s", desc); +} + + +static void stop_clients(int acmd[2], + int bcmd[2], + int adonefd[2], + int bdonefd[2]) +{ + char unused; + + write_to_client("A", acmd[1], "", 1); + write_to_client("B", bcmd[1], "", 1); + + /* Make sure they've finished */ + alarm(5); + if (read(adonefd[0], &unused, 1) || read(bdonefd[0], &unused, 1)) + errx(1, "Response after sending exit command"); + alarm(0); + + close(acmd[1]); + close(bcmd[1]); + close(adonefd[0]); + close(bdonefd[0]); +} + int main(int argc, char *argv[]) { char cmd[80], *svg; @@ -931,24 +1292,22 @@ int main(int argc, char *argv[]) else svg = NULL; - if (pipe(a_to_b) || pipe(b_to_a) || pipe(adonefd) || pipe(acmd)) - err(1, "Creating pipes"); +#if 1 + { + struct sigaction alarmed, old; - new_peer("A", a_to_b, b_to_a, acmd, adonefd); - - if (pipe(bdonefd) || pipe(bcmd)) - err(1, "Creating pipes"); - - new_peer("B", b_to_a, a_to_b, bcmd, bdonefd); + memset(&alarmed, 0, sizeof(alarmed)); + alarmed.sa_flags = SA_RESETHAND; + alarmed.sa_handler = do_nothing; - close(acmd[0]); - close(bcmd[0]); - close(adonefd[1]); - close(bdonefd[1]); - close(b_to_a[0]); - close(b_to_a[1]); - close(a_to_b[0]); - close(a_to_b[1]); + if (sigaction(SIGALRM, &alarmed, &old) != 0) + err(1, "Setting alarm handler"); + } +#else + signal(SIGALRM, do_nothing); +#endif + + start_clients(a_to_b, b_to_a, acmd, bcmd, adonefd, bdonefd); while (fgets(cmd, sizeof(cmd), stdin)) { int cmdfd, donefd; @@ -974,19 +1333,60 @@ int main(int argc, char *argv[]) continue; } else if (streq(cmd, "checksync")) { struct commit_tx fa_us, fa_them, fb_us, fb_them; - if (!write_all(acmd[1], cmd, strlen(cmd)+1) - || !write_all(bcmd[1], cmd, strlen(cmd)+1)) - errx(1, "Failed writing command to peers"); - alarm(5); - if (!read_all(adonefd[0], &fa_us, sizeof(fa_us)) - || !read_all(adonefd[0], &fa_them, sizeof(fa_them)) - || !read_all(bdonefd[0], &fb_us, sizeof(fb_us)) - || !read_all(bdonefd[0], &fb_them, sizeof(fb_them))) - errx(1, "Failed reading status from peers"); + write_to_client("A", acmd[1], cmd, strlen(cmd)+1); + write_to_client("B", bcmd[1], cmd, strlen(cmd)+1); + read_from_client("A", adonefd[0], &fa_us, sizeof(fa_us)); + read_from_client("B", bdonefd[0], &fb_us, sizeof(fb_us)); + read_from_client("A", adonefd[0], + &fa_them, sizeof(fa_them)); + read_from_client("A", bdonefd[0], + &fb_them, sizeof(fb_them)); if (!structeq(&fa_us, &fb_them) || !structeq(&fa_them, &fb_us)) errx(1, "checksync: not equal"); continue; + } else if (streq(cmd, "restart")) { + struct database a_db, b_db; + char ack; + + if (svg) + draw_restart(&svg, "RESTART", + &a_sent, &b_sent, &y); + + write_to_client("A", acmd[1], "save", strlen("save")+1); + write_to_client("B", bcmd[1], "save", strlen("save")+1); + + read_from_client("A", adonefd[0], &a_db, sizeof(a_db)); + read_from_client("B", bdonefd[0], &b_db, sizeof(b_db)); + + stop_clients(acmd, bcmd, adonefd, bdonefd); + + /* Forget everything they sent */ + reset_sends(&svg, true, &a_sent, &y); + reset_sends(&svg, false, &b_sent, &y); + + start_clients(a_to_b, b_to_a, acmd, bcmd, + adonefd, bdonefd); + + /* Send restore command, wait for ack, send blob */ + write_to_client("A", acmd[1], "restore", strlen("restore")+1); + write_to_client("B", bcmd[1], "restore", strlen("restore")+1); + + read_from_client("A", adonefd[0], &ack, 1); + read_from_client("B", bdonefd[0], &ack, 1); + + write_to_client("A", acmd[1], &a_db, sizeof(a_db)); + write_to_client("B", bcmd[1], &b_db, sizeof(b_db)); + + get_output(adonefd[0], &svg, true, + &a_sent, &b_sent, &y, &max_chars); + get_output(bdonefd[0], &svg, false, + &a_sent, &b_sent, &y, &max_chars); + + if (svg) + draw_restart(&svg, "RESTART END", + &a_sent, &b_sent, &y); + continue; } else if (strstarts(cmd, "#") || streq(cmd, "")) continue; else @@ -996,22 +1396,13 @@ int main(int argc, char *argv[]) if (svg && strstarts(cmd+2, "dump")) continue; - if (!write_all(cmdfd, cmd+2, strlen(cmd)-1)) - errx(1, "Sending %s", cmd); + write_to_client(cmd, cmdfd, cmd+2, strlen(cmd)-1); get_output(donefd, &svg, strstarts(cmd, "A:"), &a_sent, &b_sent, &y, &max_chars); } - write_all(acmd[1], "", 1); - write_all(bcmd[1], "", 1); - - /* Make sure they've finished */ - alarm(5); - if (read_all(adonefd[0], &y, 1) - || read_all(bdonefd[0], &y, 1)) - errx(1, "Response after sending exit command"); - alarm(0); + stop_clients(acmd, bcmd, adonefd, bdonefd); if (svg) printf("\n"