summaryrefslogtreecommitdiff
path: root/36/18f5002cdbd9cf4c56b730f345f04ee2b7c923
blob: ad0af7105f8271a1a3403ccc0c32c9644b16b6c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
Return-Path: <kanzure@gmail.com>
Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org
	[172.17.192.35])
	by mail.linuxfoundation.org (Postfix) with ESMTPS id 302AFFFE
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Tue, 20 Feb 2018 22:42:24 +0000 (UTC)
X-Greylist: whitelisted by SQLgrey-1.7.6
Received: from mail-ua0-f175.google.com (mail-ua0-f175.google.com
	[209.85.217.175])
	by smtp1.linuxfoundation.org (Postfix) with ESMTPS id B1B44466
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Tue, 20 Feb 2018 22:42:21 +0000 (UTC)
Received: by mail-ua0-f175.google.com with SMTP id i15so9461737uak.3
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Tue, 20 Feb 2018 14:42:21 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
	h=mime-version:in-reply-to:references:from:date:message-id:subject:to; 
	bh=D+Ao4tdtbT7YJokj5xphKUVqVnyHJwqclfSGABSx3xs=;
	b=sUbie12E0yrM5rsVTeDkFuSnTh62GpQlbYLTh5oShLkcU++wq9FoEiJkRRz6XN3M+d
	BLyJp6EUqBBkNhO/a2V6H47TtWXgPp2gMNy86h6BykRhyCqZnCsCNnaTHlObCHCYYWHD
	PyPQGehTih8iQi4Ph/s1my8404L9pI7j9bhcTd4Kl2rdrYKt6my8AQWSQ/w53ogOob/t
	WACfEV7uTifiR47pw3ilj42HFw8GoPfOPELOp+zAO3CWcEa3+T4+cEz/13slQDvfic7w
	zrViqaq81o7pnjJY+eF0BSP8ID6Wg4ivY9rRsKsPz45+Nz3baMQuexr2ythRW36AcGks
	zQbw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
	d=1e100.net; s=20161025;
	h=x-gm-message-state:mime-version:in-reply-to:references:from:date
	:message-id:subject:to;
	bh=D+Ao4tdtbT7YJokj5xphKUVqVnyHJwqclfSGABSx3xs=;
	b=NRh/s1+SGUdxLWEmapGkSWae+j4Kj+k1mL+qKA2Aa9aGajrvsiYA0MtovME7Tc8IgY
	cEu7BmoRwJcyEBMmXVcbzLUprsn4ETv2JRrTZA2sj7gA9jnzDx5+PQB68tJIZO+wNhuu
	dFbcMdkPyNedBOF6Clhy4uj12qGCX7BKfaRUDJgTkBLlq36KT2fy9P7TXplk/F7s9VSp
	LFqG/VlN/wg4Ef4AR19sDhXExWHGPPjUODWSFL0O8s+apdjv0CbsJ/GhbpIDVs/8kGbY
	+IV3bc4e1a1ODhffYBeheRZiuiXJpXdmqfBnsPQq7UyciFIpXaioFyvuANcg8/8AKjUE
	iOsw==
X-Gm-Message-State: APf1xPDaqRj9DeqK4d3hscd77ssrJiM/Yg8yzS6OfJ0hofSwAPJJgucf
	uZZV6gFQH3pFtM90ELA36wwimESI76fps09wj2F/5w==
X-Google-Smtp-Source: AH8x227q5Ovfd3yqqxIHODv57PQD3omUB/7wzazfS2Phs4cinZuFVp3+T2qumMHM9gZ6FTdXQNCyI9MYaZMS/uY2ic4=
X-Received: by 10.159.54.47 with SMTP id r44mr984673uad.133.1519166540463;
	Tue, 20 Feb 2018 14:42:20 -0800 (PST)
MIME-Version: 1.0
Received: by 10.176.22.133 with HTTP; Tue, 20 Feb 2018 14:42:19 -0800 (PST)
In-Reply-To: <20180219225907.GA16444@erisian.com.au>
References: <20180219225907.GA16444@erisian.com.au>
From: Bryan Bishop <kanzure@gmail.com>
Date: Tue, 20 Feb 2018 16:42:19 -0600
Message-ID: <CABaSBawHbwZ2cxSLTMhD7qMQ8ingGmznc0K30PKecXFNWj_2AQ@mail.gmail.com>
To: Bitcoin Dev <bitcoin-dev@lists.linuxfoundation.org>,
	Bryan Bishop <kanzure@gmail.com>
Content-Type: multipart/alternative; boundary="001a1147b016ffc54b0565ac85bc"
X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,
	DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, HTML_MESSAGE,
	RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
	smtp1.linux-foundation.org
Subject: [bitcoin-dev] Fwd: [Lightning-dev] Post-Schnorr lightning txes
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>,
	<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>,
	<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Tue, 20 Feb 2018 22:42:24 -0000

--001a1147b016ffc54b0565ac85bc
Content-Type: text/plain; charset="UTF-8"

---------- Forwarded message ----------
From: Anthony Towns <aj@erisian.com.au>
Date: Mon, Feb 19, 2018 at 4:59 PM
Subject: [Lightning-dev] Post-Schnorr lightning txes
To: lightning-dev@lists.linuxfoundation.org


Hi *,

My understanding of lightning may be out of date, so please forgive
(or at least correct :) any errors on my behalf.

I was thinking about whether Greg Maxwell's graftroot might solve the
channel monitoring problem (spoiler: not really) and ended up with maybe
an interesting take on Schnorr. I don't think I've seen any specific
writeup of what that might look like, so hopefully at least some of this
is novel!

I'm assuming familiarity with current thinking on Schnorr sigs -- but all
you should need to know is the quick summary at footnote [0].

So I think there's four main scenarios for closing a lightning channel:

 - both parties are happy to close, do so cooperatively, and can
   sign a new unconditional transaction that they agree on. already fine.
   (should happen almost all of the time, call it 80%)

 - communications failure: one side has to close, but the other side
   is happy to cooperate as far as they're able but can only do so via
   the blockchain and maybe with some delay (maybe 15% of the time)

 - disappearance, uncooperative: one side effectively completely
   disappears so the other side has to fully close the channel on their
   own (5% of the time)

 - misbehaviour: one side tries publishing an old channel state due to
   error or maliciousness, and the other collects the entire balance as
   penalty (0% of the time)

With "graftroot" in mind, I was thinking that optimising for the last
case might be interesting -- despite expecting it to be vanishingly
rare. That would have to look something like:

   (0) funding tx
   (1) ...which is spent by a misbehaving commitment tx
   (2) ...which is spent by a penalty tx

You do need 3 txes for that case, but you really only need 1 output
for each: so (0) is 2-in-1-out, (1) is 1-in-1-out, (2) is 1-in-1-out;
which could all be relatively cheap. (And (2) could be batched with other
txes making it 1 input in a potentially large tx)

For concreteness, I'm going to treat A as the one doing the penalising,
and B (Bad?) as the one that's misbehaving.

If you treat each of those txes as a muSig Schnorr pay-to-pubkey, the
output addresses would be:

   (0) funding tx pays to [A,B]
   (1) commitment tx pays to [A(i),Revocation(B,i)]
   (2) pays to A

(where i is a commitment id / counter for the channel state)

If B misbehaves by posting the commitment tx after revealing the
revocation secret, A can calculate A(i) and Revocation(B,i) and claim
all the funds immediately.

As far as the other cases go:

  - In a cooperative close, you don't publish any commitment txes, you
    just spend the funding to each party's preferred destinations
    directly; so this is already great.

  - Otherwise, you need to be able to actually commit to how the funds
    get distributed.

But committing to distributing funds is easy: just jointly sign
a transaction with [A(i),Revocation(B,i)]. Since B is the one we're
worrying about misbehaving, it needs to hold a transaction with the
appropriate outputs that is:

  - timelocked to `to_self_delay` blocks/seconds in advance via nSequence
  - signed by A(i)

That ensures A has `to_self_delay` blocks/seconds to penalise misehaviour,
and that when closing properly, B can complete the signature using the
current revocation secret.

This means the "appropriate outputs" no longer need the OP_CSV step, which
should simplify the scripts a bit.

Having B have a distribution transaction isn't enough -- B could vanish
between publishing the commitment transaction and the distribution
transaction, leaving A without access to any funds. So A needs a
corresponding distribution transaction. But because that transaction can
only be published if B signs and publishes the corresponding commitment
transaction, the fact that it's published indicates both A and B are
happy with the channel close -- so this is a semi-cooperative close and
no delay is needed. So A should hold a partially signed transaction with
the same outputs:

  - without any timelock
  - signed by Revocation(B,i), waiting for signature by A(i)

Thus, if B does a non-cooperative close, either:

  - A proves misbehaviour and claims all the funds immediately
  - A agrees that the channel state is correct, signs and publishes
    the un-timelocked distribution transaction, then claims A's outputs;
    B can then immediately claim its outputs
  - A does nothing, and B waits for the `to_self_delay` period, signs
    and publishes its transaction, then claims B's outputs; A can eventually
    claim its own outputs

In that case all of the transactions except the in-flight HTLCs just look
like simple pay-to-pubkey transactions.

Further, other than the historical secrets no old information needs
to be retained: misbehaviour can be dealt with (and can only be dealt
with) by creating a new transaction signed by your own secrets and the
revocation information.

None of that actually relies on Schnorr-multisig, I think -- it could
be done today with normal 2-of-2 multisig as far as I can see.



I'm not 100% sure how this approach works compared to the current one
for the CSV/CLTV overlap problem. I think any case you could solve by
obtaining a HTLC-Timeout or HTLC-Success transaction currently, you could
solve in the above scenario by just updating the channel state to remove
the HTLC.


So I believe the above lets you completely forget info about old HTLCs,
while still enforcing correct behavior, and also makes enforcing correct
behaviour cheaper because it's just two extremely simple transactions
to post. If I haven't missed any corner cases, it also seems to simplify
the scripts a fair bit.

Does this make sense? It seems to to me...


So for completeness, it would make sense to do HTLCs via Schnorr --
at least to make them reveal elliptic curve private keys, and ideally
to make them mostly indistinguishable from regular transactions as a
"scriptless script" [1] or "discreet log contract" [2]. (I think, at
least for HTLCs, these end up being the same?)

The idea then is to have the HTLC payment hash be R=r*G, where r is the
secret/payment receipt.

Supposing your current commitment has n HTLCs in-flight, some paying A
if the HTLC succeeds and "r" is revealed, others paying B. We'll focus
on one paying A.

So you succeed by A completing a signature that reveals r to B,
and which simultaneously allows collection of the funds on chain. A
needs to be able to do this knowing nothing other than r (and their own
private keys). So agree to sign to muSig 2-of-2 multisig [A,B]. A and B
generate random values i and j respectively and reveal I=i*G and J=j*G,
and each calculates Q=I+J+R, and they generate partial signatures of a
transaction paying A:

    I, i + H(X,Q,m)*H(L,A)*a
    J, j + H(X,Q,m)*H(L,B)*b

where L = H(A,B) and X = H(L,A)*A + H(L,B)*B as usual. Once A knows r,
A can construct a full signature by adding R, r to the above values,
and B can then determine r by subtracting the above values from signature
A generated.

To ensure B gets paid if the HTLC timesout, they should also sign a
timelocked transaction paying B directly, that B can hold onto until
the channel state gets updated.

And once you're doing payment hashes via ECC, you can of course change
them at each hop to make it harder to correlate steps in a payment route.

I think that when combined with the above method of handling CSV delays
and revocation, this covers all the needed cases with a straightforward
pay-to-pubkey(hash) output, no script info needed at all. It does mean
each HTLC needs a signature every time the channel state updates (B needs
to sign a tx allowing A to claim the output once A knows the secret,
A needs to sign a tx allowing B to claim the output on timeout).


For channel monitoring this is pretty good, I think. You need to
keep track of the revocation info and your secret keys -- but that's
essentially a constant amount of data.

If you're happy to have the data grow by 64 bytes every time the channel
state updates, you can outsource channel monitoring: arrange a formula
for constructing a penalty tx based on the channel commitment tx --
eg, 95% of the balance goes to me, 4% goes to the monitor's address, 1%
goes to fees, there's a relative locktime of to_self_delay/3 to allow me
to directly claim 100% of the funds if I happen to be paying attention;
then do a partial signature with A(i), and then allow the monitoring
service to catch fraudulent transactions, work out the appropriate
revocation secret, and finish the signature.

If your channel updates 100 times a second for an entire year, that's
200GB of data, which seems pretty feasible. (You can't just regenerate
that data though, unless you keep each commitment tx) And it's pretty
easy to work out which bit of data you need to access: the funding
tx that's being spent tells you which channel, and the channel state
index is encoded in the locktime and sequence, so you should only need
small/logarithmic overhead even for frequently updated channels rather
than any serious indexes.

I don't think you can do better than that without serious changes to
bitcoin: if you let the monitoring agency sign on its own, you'd need some
sort of covenant opcode to ensure it sends any money to you; and with
segwit outputs, there's no way to provide a signature for a transaction
without committing to exactly which transaction you're signing.

I was hoping covenants and graftroot would be enough, but I don't
think they are. The idea would be that since the transaction spends to
A(i)+Rev(B,i), you'd sign an output script with A that uses covenant
opcodes to ensure the transaction only pays the appropriate monitoring
reward, and the monitor could then work out A(i)-A and Rev(B,i) and finish
the signature. But the signature by "A" would need to know A(i)+Rev(B,i)
when calculating the hash, and that's different for every commitment
transaction, so as far as I can see, it just doesn't work. You can't
drop the muSig-style construction because you need to be protect yourself
against potential malicious choice of the revocation secret [3].


Summary:

 - Funding txes as 2-of-2 multisig is still great. Convert to
   Schnorr/muSig when available of course.

 - Generate 6+8*n transactions everytime the channel state is updated,
   (n = number of HTLCs in-flight)

   1. Channel state commitment tx, held by A, spends funding tx,
      payable to Schnorr muSig address [A(i),Rev(B,i)], signed by B
   2. Channel fund distribution tx, held by A (CSV), spends (1),
      signed by Rev(B,i)
   3. Channel fund distribution tx, held by B (no CSV), spends (1),
      signed by A(i)
   4. Channel state commitment tx, held by B, spends funding tx
      payable to Schnorr muSig address [B(i),Rev(A,i)], signed by A
   5. Channel fund distribution tx, held by B (CSV), spends (4),
      signed by Rev(A,i)
   6. Channel fund distribution tx, held by A (no CSV), spends (4),
      signed by B(i)

   The fund distribution txs all pay the same collection of addresses:
     - channel balance for A directly to A's preferred address
     - channel balance for B directly to B's preferred address
     - HTLC balance to muSig address for [A,B] for each in-flight HTLC
       paying A on success
     - HTLC balance to muSig address for [B,A] for each in-flight HTLC
       paying B on success
     - (probably makes sense to bump the HTLC addresses by some random
       value to make it harder for third parties to tell which addresses
       were balances versus HTLCs)

   Both (1) and (4) include obscured channel state ids as per current
   standard.

   For each HTLC that pays X on timeout and Y on success:
     a. Timeout tx, held by X, signed by Y, spends from (2)
     b. Timeout tx, held by X, signed by Y, spends from (3)
     c. Timeout tx, held by X, signed by Y, spends from (5)
     d. Timeout tx, held by X, signed by Y, spends from (6)

     e. Success tx, held by Y, signed by X, spends from (2)
     f. Success tx, held by Y, signed by X, spends from (3)
     g. Success tx, held by Y, signed by X, spends from (5)
     h. Success tx, held by Y, signed by X, spends from (6)

     (these should all be able to be SIGHASH_SINGLE, ANYONECANPAY
      to allow some level of aggregation)

 - Fund distribution tx outputs can all be pay2pubkey(hash): HTLCs work
   by pre-signed timelocked transactions and scriptless
   scripts/discreet-log contracts to reveal the secret; balances work
   directly; CSV and revocations are already handled by that point

 - You can discard all old transaction info and HTLC parameters once
   they're not relevant to the current channel state

 - Channel monitoring can be outsourced pretty efficiently -- as little as
   a signature per state could be made to works as far as I can see,
   which doesn't add up too fast.

 - There's still no plausible way of doing constant space outsourced
   channel monitoring without some sort of SIGHASH_NOINPUT, at least
   that I can see

Thoughts?

[4]

Cheers,
aj, very sad that this didn't turn out to be a potential use case for
    graftroot :(

[0] In particular, I'm assuming that:

    - Schnorr sigs in bitcoin will look something like:
        R, r + H(X,R,m)*x

      (where m is the message being signed by private key x, r is a
      random per-sig nonce, R and X are public keys corresponding to r,x;
      H is the secure hash function)

    - muSig is a secure way for untrusting parties to construct an n-of-n
      combined signature; for public keys A and B, it produces a combined
      public key:
        X = H(L,A)*A + H(L,B)*B
      with L = H(A,B)

   See https://blockstream.com/2018/01/23/musig-key-aggregation-
schnorr-signatures.html

[1] https://scalingbitcoin.org/stanford2017/Day2/Using-the-
Chain-for-what-Chains-are-Good-For.pdf
    http://diyhpl.us/wiki/transcripts/scalingbitcoin/
stanford-2017/using-the-chain-for-what-chains-are-good-for/

[2] https://adiabat.github.io/dlc.pdf
    https://diyhpl.us/wiki/transcripts/discreet-log-contracts/

[3] Well, maybe you could request a zero-knowledge proof to ensure a new
    revocation hash conforms to the standard for generating revocation
    secrets without revealing the secret, and have the public key be
    a(i)*G + r(B,i)*G without using the muSig construct, but that would
    probably be obnoxious to have to generate every time you update
    the channel state.

[4] As an aside -- this could make it feasible and interesting to penalise
    disappearance as well as misbehaviour. If you add a transaction
    the B pre-signs, spending the commitment tx A holds, giving all the
    channel funds to A but only after a very large CSV timeout, perhaps
    `to_self_delay`*50, then the scenarios are:

    If A is present:

      - B publishes an old commitment: A immediately steals all the
        funds if active or outsourced misbehaviour monitoring. Whoops!

      - B publishes the current commitment: A publishes its distribution
        transaction and collects its funds immediately, allowing B to
        do likewise

    If A has disappeared:

      - B publises the current commitment and waits a modest amount
        of time, publishes its distribution transaction claiming its
        rightful funds, and allowing A to collect its funds if it ever
        does reappear and still knows its secrets

      - B publishes the current commitment, waits a fair while,
        A reappears and publishes its distribution transactions, both
        parties get their rightful funds

      - B publishes the current commitment, waits an extended period
        of time, and claims the entire channel's funds. If B is
        particularly reputable, and A can prove its identity (but not
        recover all its secrets) maybe B even refunds A some/all of its
        rightful balance

    Perhaps that provides too much of an incentive to try blocking
    someone from having access to the blockchain though.

_______________________________________________
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev



-- 
- Bryan
http://heybryan.org/
1 512 203 0507

--001a1147b016ffc54b0565ac85bc
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_quote">---------- Forwarded messag=
e ----------<br>From: <b class=3D"gmail_sendername">Anthony Towns</b> <span=
 dir=3D"ltr">&lt;<a href=3D"mailto:aj@erisian.com.au">aj@erisian.com.au</a>=
&gt;</span><br>Date: Mon, Feb 19, 2018 at 4:59 PM<br>Subject: [Lightning-de=
v] Post-Schnorr lightning txes<br>To: <a href=3D"mailto:lightning-dev@lists=
.linuxfoundation.org">lightning-dev@lists.linuxfoundation.org</a><br><br><b=
r>Hi *,<br>
<br>
My understanding of lightning may be out of date, so please forgive<br>
(or at least correct :) any errors on my behalf.<br>
<br>
I was thinking about whether Greg Maxwell&#39;s graftroot might solve the<b=
r>
channel monitoring problem (spoiler: not really) and ended up with maybe<br=
>
an interesting take on Schnorr. I don&#39;t think I&#39;ve seen any specifi=
c<br>
writeup of what that might look like, so hopefully at least some of this<br=
>
is novel!<br>
<br>
I&#39;m assuming familiarity with current thinking on Schnorr sigs -- but a=
ll<br>
you should need to know is the quick summary at footnote [0].<br>
<br>
So I think there&#39;s four main scenarios for closing a lightning channel:=
<br>
<br>
=C2=A0- both parties are happy to close, do so cooperatively, and can<br>
=C2=A0 =C2=A0sign a new unconditional transaction that they agree on. alrea=
dy fine.<br>
=C2=A0 =C2=A0(should happen almost all of the time, call it 80%)<br>
<br>
=C2=A0- communications failure: one side has to close, but the other side<b=
r>
=C2=A0 =C2=A0is happy to cooperate as far as they&#39;re able but can only =
do so via<br>
=C2=A0 =C2=A0the blockchain and maybe with some delay (maybe 15% of the tim=
e)<br>
<br>
=C2=A0- disappearance, uncooperative: one side effectively completely<br>
=C2=A0 =C2=A0disappears so the other side has to fully close the channel on=
 their<br>
=C2=A0 =C2=A0own (5% of the time)<br>
<br>
=C2=A0- misbehaviour: one side tries publishing an old channel state due to=
<br>
=C2=A0 =C2=A0error or maliciousness, and the other collects the entire bala=
nce as<br>
=C2=A0 =C2=A0penalty (0% of the time)<br>
<br>
With &quot;graftroot&quot; in mind, I was thinking that optimising for the =
last<br>
case might be interesting -- despite expecting it to be vanishingly<br>
rare. That would have to look something like:<br>
<br>
=C2=A0 =C2=A0(0) funding tx<br>
=C2=A0 =C2=A0(1) ...which is spent by a misbehaving commitment tx<br>
=C2=A0 =C2=A0(2) ...which is spent by a penalty tx<br>
<br>
You do need 3 txes for that case, but you really only need 1 output<br>
for each: so (0) is 2-in-1-out, (1) is 1-in-1-out, (2) is 1-in-1-out;<br>
which could all be relatively cheap. (And (2) could be batched with other<b=
r>
txes making it 1 input in a potentially large tx)<br>
<br>
For concreteness, I&#39;m going to treat A as the one doing the penalising,=
<br>
and B (Bad?) as the one that&#39;s misbehaving.<br>
<br>
If you treat each of those txes as a muSig Schnorr pay-to-pubkey, the<br>
output addresses would be:<br>
<br>
=C2=A0 =C2=A0(0) funding tx pays to [A,B]<br>
=C2=A0 =C2=A0(1) commitment tx pays to [A(i),Revocation(B,i)]<br>
=C2=A0 =C2=A0(2) pays to A<br>
<br>
(where i is a commitment id / counter for the channel state)<br>
<br>
If B misbehaves by posting the commitment tx after revealing the<br>
revocation secret, A can calculate A(i) and Revocation(B,i) and claim<br>
all the funds immediately.<br>
<br>
As far as the other cases go:<br>
<br>
=C2=A0 - In a cooperative close, you don&#39;t publish any commitment txes,=
 you<br>
=C2=A0 =C2=A0 just spend the funding to each party&#39;s preferred destinat=
ions<br>
=C2=A0 =C2=A0 directly; so this is already great.<br>
<br>
=C2=A0 - Otherwise, you need to be able to actually commit to how the funds=
<br>
=C2=A0 =C2=A0 get distributed.<br>
<br>
But committing to distributing funds is easy: just jointly sign<br>
a transaction with [A(i),Revocation(B,i)]. Since B is the one we&#39;re<br>
worrying about misbehaving, it needs to hold a transaction with the<br>
appropriate outputs that is:<br>
<br>
=C2=A0 - timelocked to `to_self_delay` blocks/seconds in advance via nSeque=
nce<br>
=C2=A0 - signed by A(i)<br>
<br>
That ensures A has `to_self_delay` blocks/seconds to penalise misehaviour,<=
br>
and that when closing properly, B can complete the signature using the<br>
current revocation secret.<br>
<br>
This means the &quot;appropriate outputs&quot; no longer need the OP_CSV st=
ep, which<br>
should simplify the scripts a bit.<br>
<br>
Having B have a distribution transaction isn&#39;t enough -- B could vanish=
<br>
between publishing the commitment transaction and the distribution<br>
transaction, leaving A without access to any funds. So A needs a<br>
corresponding distribution transaction. But because that transaction can<br=
>
only be published if B signs and publishes the corresponding commitment<br>
transaction, the fact that it&#39;s published indicates both A and B are<br=
>
happy with the channel close -- so this is a semi-cooperative close and<br>
no delay is needed. So A should hold a partially signed transaction with<br=
>
the same outputs:<br>
<br>
=C2=A0 - without any timelock<br>
=C2=A0 - signed by Revocation(B,i), waiting for signature by A(i)<br>
<br>
Thus, if B does a non-cooperative close, either:<br>
<br>
=C2=A0 - A proves misbehaviour and claims all the funds immediately<br>
=C2=A0 - A agrees that the channel state is correct, signs and publishes<br=
>
=C2=A0 =C2=A0 the un-timelocked distribution transaction, then claims A&#39=
;s outputs;<br>
=C2=A0 =C2=A0 B can then immediately claim its outputs<br>
=C2=A0 - A does nothing, and B waits for the `to_self_delay` period, signs<=
br>
=C2=A0 =C2=A0 and publishes its transaction, then claims B&#39;s outputs; A=
 can eventually<br>
=C2=A0 =C2=A0 claim its own outputs<br>
<br>
In that case all of the transactions except the in-flight HTLCs just look<b=
r>
like simple pay-to-pubkey transactions.<br>
<br>
Further, other than the historical secrets no old information needs<br>
to be retained: misbehaviour can be dealt with (and can only be dealt<br>
with) by creating a new transaction signed by your own secrets and the<br>
revocation information.<br>
<br>
None of that actually relies on Schnorr-multisig, I think -- it could<br>
be done today with normal 2-of-2 multisig as far as I can see.<br>
<br>
<br>
<br>
I&#39;m not 100% sure how this approach works compared to the current one<b=
r>
for the CSV/CLTV overlap problem. I think any case you could solve by<br>
obtaining a HTLC-Timeout or HTLC-Success transaction currently, you could<b=
r>
solve in the above scenario by just updating the channel state to remove<br=
>
the HTLC.<br>
<br>
<br>
So I believe the above lets you completely forget info about old HTLCs,<br>
while still enforcing correct behavior, and also makes enforcing correct<br=
>
behaviour cheaper because it&#39;s just two extremely simple transactions<b=
r>
to post. If I haven&#39;t missed any corner cases, it also seems to simplif=
y<br>
the scripts a fair bit.<br>
<br>
Does this make sense? It seems to to me...<br>
<br>
<br>
So for completeness, it would make sense to do HTLCs via Schnorr --<br>
at least to make them reveal elliptic curve private keys, and ideally<br>
to make them mostly indistinguishable from regular transactions as a<br>
&quot;scriptless script&quot; [1] or &quot;discreet log contract&quot; [2].=
 (I think, at<br>
least for HTLCs, these end up being the same?)<br>
<br>
The idea then is to have the HTLC payment hash be R=3Dr*G, where r is the<b=
r>
secret/payment receipt.<br>
<br>
Supposing your current commitment has n HTLCs in-flight, some paying A<br>
if the HTLC succeeds and &quot;r&quot; is revealed, others paying B. We&#39=
;ll focus<br>
on one paying A.<br>
<br>
So you succeed by A completing a signature that reveals r to B,<br>
and which simultaneously allows collection of the funds on chain. A<br>
needs to be able to do this knowing nothing other than r (and their own<br>
private keys). So agree to sign to muSig 2-of-2 multisig [A,B]. A and B<br>
generate random values i and j respectively and reveal I=3Di*G and J=3Dj*G,=
<br>
and each calculates Q=3DI+J+R, and they generate partial signatures of a<br=
>
transaction paying A:<br>
<br>
=C2=A0 =C2=A0 I, i + H(X,Q,m)*H(L,A)*a<br>
=C2=A0 =C2=A0 J, j + H(X,Q,m)*H(L,B)*b<br>
<br>
where L =3D H(A,B) and X =3D H(L,A)*A + H(L,B)*B as usual. Once A knows r,<=
br>
A can construct a full signature by adding R, r to the above values,<br>
and B can then determine r by subtracting the above values from signature<b=
r>
A generated.<br>
<br>
To ensure B gets paid if the HTLC timesout, they should also sign a<br>
timelocked transaction paying B directly, that B can hold onto until<br>
the channel state gets updated.<br>
<br>
And once you&#39;re doing payment hashes via ECC, you can of course change<=
br>
them at each hop to make it harder to correlate steps in a payment route.<b=
r>
<br>
I think that when combined with the above method of handling CSV delays<br>
and revocation, this covers all the needed cases with a straightforward<br>
pay-to-pubkey(hash) output, no script info needed at all. It does mean<br>
each HTLC needs a signature every time the channel state updates (B needs<b=
r>
to sign a tx allowing A to claim the output once A knows the secret,<br>
A needs to sign a tx allowing B to claim the output on timeout).<br>
<br>
<br>
For channel monitoring this is pretty good, I think. You need to<br>
keep track of the revocation info and your secret keys -- but that&#39;s<br=
>
essentially a constant amount of data.<br>
<br>
If you&#39;re happy to have the data grow by 64 bytes every time the channe=
l<br>
state updates, you can outsource channel monitoring: arrange a formula<br>
for constructing a penalty tx based on the channel commitment tx --<br>
eg, 95% of the balance goes to me, 4% goes to the monitor&#39;s address, 1%=
<br>
goes to fees, there&#39;s a relative locktime of to_self_delay/3 to allow m=
e<br>
to directly claim 100% of the funds if I happen to be paying attention;<br>
then do a partial signature with A(i), and then allow the monitoring<br>
service to catch fraudulent transactions, work out the appropriate<br>
revocation secret, and finish the signature.<br>
<br>
If your channel updates 100 times a second for an entire year, that&#39;s<b=
r>
200GB of data, which seems pretty feasible. (You can&#39;t just regenerate<=
br>
that data though, unless you keep each commitment tx) And it&#39;s pretty<b=
r>
easy to work out which bit of data you need to access: the funding<br>
tx that&#39;s being spent tells you which channel, and the channel state<br=
>
index is encoded in the locktime and sequence, so you should only need<br>
small/logarithmic overhead even for frequently updated channels rather<br>
than any serious indexes.<br>
<br>
I don&#39;t think you can do better than that without serious changes to<br=
>
bitcoin: if you let the monitoring agency sign on its own, you&#39;d need s=
ome<br>
sort of covenant opcode to ensure it sends any money to you; and with<br>
segwit outputs, there&#39;s no way to provide a signature for a transaction=
<br>
without committing to exactly which transaction you&#39;re signing.<br>
<br>
I was hoping covenants and graftroot would be enough, but I don&#39;t<br>
think they are. The idea would be that since the transaction spends to<br>
A(i)+Rev(B,i), you&#39;d sign an output script with A that uses covenant<br=
>
opcodes to ensure the transaction only pays the appropriate monitoring<br>
reward, and the monitor could then work out A(i)-A and Rev(B,i) and finish<=
br>
the signature. But the signature by &quot;A&quot; would need to know A(i)+R=
ev(B,i)<br>
when calculating the hash, and that&#39;s different for every commitment<br=
>
transaction, so as far as I can see, it just doesn&#39;t work. You can&#39;=
t<br>
drop the muSig-style construction because you need to be protect yourself<b=
r>
against potential malicious choice of the revocation secret [3].<br>
<br>
<br>
Summary:<br>
<br>
=C2=A0- Funding txes as 2-of-2 multisig is still great. Convert to<br>
=C2=A0 =C2=A0Schnorr/muSig when available of course.<br>
<br>
=C2=A0- Generate 6+8*n transactions everytime the channel state is updated,=
<br>
=C2=A0 =C2=A0(n =3D number of HTLCs in-flight)<br>
<br>
=C2=A0 =C2=A01. Channel state commitment tx, held by A, spends funding tx,<=
br>
=C2=A0 =C2=A0 =C2=A0 payable to Schnorr muSig address [A(i),Rev(B,i)], sign=
ed by B<br>
=C2=A0 =C2=A02. Channel fund distribution tx, held by A (CSV), spends (1),<=
br>
=C2=A0 =C2=A0 =C2=A0 signed by Rev(B,i)<br>
=C2=A0 =C2=A03. Channel fund distribution tx, held by B (no CSV), spends (1=
),<br>
=C2=A0 =C2=A0 =C2=A0 signed by A(i)<br>
=C2=A0 =C2=A04. Channel state commitment tx, held by B, spends funding tx<b=
r>
=C2=A0 =C2=A0 =C2=A0 payable to Schnorr muSig address [B(i),Rev(A,i)], sign=
ed by A<br>
=C2=A0 =C2=A05. Channel fund distribution tx, held by B (CSV), spends (4),<=
br>
=C2=A0 =C2=A0 =C2=A0 signed by Rev(A,i)<br>
=C2=A0 =C2=A06. Channel fund distribution tx, held by A (no CSV), spends (4=
),<br>
=C2=A0 =C2=A0 =C2=A0 signed by B(i)<br>
<br>
=C2=A0 =C2=A0The fund distribution txs all pay the same collection of addre=
sses:<br>
=C2=A0 =C2=A0 =C2=A0- channel balance for A directly to A&#39;s preferred a=
ddress<br>
=C2=A0 =C2=A0 =C2=A0- channel balance for B directly to B&#39;s preferred a=
ddress<br>
=C2=A0 =C2=A0 =C2=A0- HTLC balance to muSig address for [A,B] for each in-f=
light HTLC<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0paying A on success<br>
=C2=A0 =C2=A0 =C2=A0- HTLC balance to muSig address for [B,A] for each in-f=
light HTLC<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0paying B on success<br>
=C2=A0 =C2=A0 =C2=A0- (probably makes sense to bump the HTLC addresses by s=
ome random<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0value to make it harder for third parties to tel=
l which addresses<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0were balances versus HTLCs)<br>
<br>
=C2=A0 =C2=A0Both (1) and (4) include obscured channel state ids as per cur=
rent<br>
=C2=A0 =C2=A0standard.<br>
<br>
=C2=A0 =C2=A0For each HTLC that pays X on timeout and Y on success:<br>
=C2=A0 =C2=A0 =C2=A0a. Timeout tx, held by X, signed by Y, spends from (2)<=
br>
=C2=A0 =C2=A0 =C2=A0b. Timeout tx, held by X, signed by Y, spends from (3)<=
br>
=C2=A0 =C2=A0 =C2=A0c. Timeout tx, held by X, signed by Y, spends from (5)<=
br>
=C2=A0 =C2=A0 =C2=A0d. Timeout tx, held by X, signed by Y, spends from (6)<=
br>
<br>
=C2=A0 =C2=A0 =C2=A0e. Success tx, held by Y, signed by X, spends from (2)<=
br>
=C2=A0 =C2=A0 =C2=A0f. Success tx, held by Y, signed by X, spends from (3)<=
br>
=C2=A0 =C2=A0 =C2=A0g. Success tx, held by Y, signed by X, spends from (5)<=
br>
=C2=A0 =C2=A0 =C2=A0h. Success tx, held by Y, signed by X, spends from (6)<=
br>
<br>
=C2=A0 =C2=A0 =C2=A0(these should all be able to be SIGHASH_SINGLE, ANYONEC=
ANPAY<br>
=C2=A0 =C2=A0 =C2=A0 to allow some level of aggregation)<br>
<br>
=C2=A0- Fund distribution tx outputs can all be pay2pubkey(hash): HTLCs wor=
k<br>
=C2=A0 =C2=A0by pre-signed timelocked transactions and scriptless<br>
=C2=A0 =C2=A0scripts/discreet-log contracts to reveal the secret; balances =
work<br>
=C2=A0 =C2=A0directly; CSV and revocations are already handled by that poin=
t<br>
<br>
=C2=A0- You can discard all old transaction info and HTLC parameters once<b=
r>
=C2=A0 =C2=A0they&#39;re not relevant to the current channel state<br>
<br>
=C2=A0- Channel monitoring can be outsourced pretty efficiently -- as littl=
e as<br>
=C2=A0 =C2=A0a signature per state could be made to works as far as I can s=
ee,<br>
=C2=A0 =C2=A0which doesn&#39;t add up too fast.<br>
<br>
=C2=A0- There&#39;s still no plausible way of doing constant space outsourc=
ed<br>
=C2=A0 =C2=A0channel monitoring without some sort of SIGHASH_NOINPUT, at le=
ast<br>
=C2=A0 =C2=A0that I can see<br>
<br>
Thoughts?<br>
<br>
[4]<br>
<br>
Cheers,<br>
aj, very sad that this didn&#39;t turn out to be a potential use case for<b=
r>
=C2=A0 =C2=A0 graftroot :(<br>
<br>
[0] In particular, I&#39;m assuming that:<br>
<br>
=C2=A0 =C2=A0 - Schnorr sigs in bitcoin will look something like:<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 R, r + H(X,R,m)*x<br>
<br>
=C2=A0 =C2=A0 =C2=A0 (where m is the message being signed by private key x,=
 r is a<br>
=C2=A0 =C2=A0 =C2=A0 random per-sig nonce, R and X are public keys correspo=
nding to r,x;<br>
=C2=A0 =C2=A0 =C2=A0 H is the secure hash function)<br>
<br>
=C2=A0 =C2=A0 - muSig is a secure way for untrusting parties to construct a=
n n-of-n<br>
=C2=A0 =C2=A0 =C2=A0 combined signature; for public keys A and B, it produc=
es a combined<br>
=C2=A0 =C2=A0 =C2=A0 public key:<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 X =3D H(L,A)*A + H(L,B)*B<br>
=C2=A0 =C2=A0 =C2=A0 with L =3D H(A,B)<br>
<br>
=C2=A0 =C2=A0See <a href=3D"https://blockstream.com/2018/01/23/musig-key-ag=
gregation-schnorr-signatures.html" rel=3D"noreferrer" target=3D"_blank">htt=
ps://blockstream.com/2018/<wbr>01/23/musig-key-aggregation-<wbr>schnorr-sig=
natures.html</a><br>
<br>
[1] <a href=3D"https://scalingbitcoin.org/stanford2017/Day2/Using-the-Chain=
-for-what-Chains-are-Good-For.pdf" rel=3D"noreferrer" target=3D"_blank">htt=
ps://scalingbitcoin.org/<wbr>stanford2017/Day2/Using-the-<wbr>Chain-for-wha=
t-Chains-are-<wbr>Good-For.pdf</a><br>
=C2=A0 =C2=A0 <a href=3D"http://diyhpl.us/wiki/transcripts/scalingbitcoin/s=
tanford-2017/using-the-chain-for-what-chains-are-good-for/" rel=3D"noreferr=
er" target=3D"_blank">http://diyhpl.us/wiki/<wbr>transcripts/scalingbitcoin=
/<wbr>stanford-2017/using-the-chain-<wbr>for-what-chains-are-good-for/</a><=
br>
<br>
[2] <a href=3D"https://adiabat.github.io/dlc.pdf" rel=3D"noreferrer" target=
=3D"_blank">https://adiabat.github.io/dlc.<wbr>pdf</a><br>
=C2=A0 =C2=A0 <a href=3D"https://diyhpl.us/wiki/transcripts/discreet-log-co=
ntracts/" rel=3D"noreferrer" target=3D"_blank">https://diyhpl.us/wiki/<wbr>=
transcripts/discreet-log-<wbr>contracts/</a><br>
<br>
[3] Well, maybe you could request a zero-knowledge proof to ensure a new<br=
>
=C2=A0 =C2=A0 revocation hash conforms to the standard for generating revoc=
ation<br>
=C2=A0 =C2=A0 secrets without revealing the secret, and have the public key=
 be<br>
=C2=A0 =C2=A0 a(i)*G + r(B,i)*G without using the muSig construct, but that=
 would<br>
=C2=A0 =C2=A0 probably be obnoxious to have to generate every time you upda=
te<br>
=C2=A0 =C2=A0 the channel state.<br>
<br>
[4] As an aside -- this could make it feasible and interesting to penalise<=
br>
=C2=A0 =C2=A0 disappearance as well as misbehaviour. If you add a transacti=
on<br>
=C2=A0 =C2=A0 the B pre-signs, spending the commitment tx A holds, giving a=
ll the<br>
=C2=A0 =C2=A0 channel funds to A but only after a very large CSV timeout, p=
erhaps<br>
=C2=A0 =C2=A0 `to_self_delay`*50, then the scenarios are:<br>
<br>
=C2=A0 =C2=A0 If A is present:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 - B publishes an old commitment: A immediately steals =
all the<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 funds if active or outsourced misbehaviour moni=
toring. Whoops!<br>
<br>
=C2=A0 =C2=A0 =C2=A0 - B publishes the current commitment: A publishes its =
distribution<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 transaction and collects its funds immediately,=
 allowing B to<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 do likewise<br>
<br>
=C2=A0 =C2=A0 If A has disappeared:<br>
<br>
=C2=A0 =C2=A0 =C2=A0 - B publises the current commitment and waits a modest=
 amount<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 of time, publishes its distribution transaction=
 claiming its<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rightful funds, and allowing A to collect its f=
unds if it ever<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 does reappear and still knows its secrets<br>
<br>
=C2=A0 =C2=A0 =C2=A0 - B publishes the current commitment, waits a fair whi=
le,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 A reappears and publishes its distribution tran=
sactions, both<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 parties get their rightful funds<br>
<br>
=C2=A0 =C2=A0 =C2=A0 - B publishes the current commitment, waits an extende=
d period<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 of time, and claims the entire channel&#39;s fu=
nds. If B is<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 particularly reputable, and A can prove its ide=
ntity (but not<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 recover all its secrets) maybe B even refunds A=
 some/all of its<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rightful balance<br>
<br>
=C2=A0 =C2=A0 Perhaps that provides too much of an incentive to try blockin=
g<br>
=C2=A0 =C2=A0 someone from having access to the blockchain though.<br>
<br>
______________________________<wbr>_________________<br>
Lightning-dev mailing list<br>
<a href=3D"mailto:Lightning-dev@lists.linuxfoundation.org">Lightning-dev@li=
sts.<wbr>linuxfoundation.org</a><br>
<a href=3D"https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev=
" rel=3D"noreferrer" target=3D"_blank">https://lists.linuxfoundation.<wbr>o=
rg/mailman/listinfo/<wbr>lightning-dev</a><br>
</div><br><br clear=3D"all"><div><br></div>-- <br><div class=3D"gmail_signa=
ture" data-smartmail=3D"gmail_signature">- Bryan<br><a href=3D"http://heybr=
yan.org/" target=3D"_blank">http://heybryan.org/</a><br>1 512 203 0507</div=
>
</div>

--001a1147b016ffc54b0565ac85bc--