summaryrefslogtreecommitdiff
path: root/41/5a632ad8d32a5f4ba85c7132723aa0d34d76d6
blob: 949be00d5df18cb3b84f22b0cb2fa39a703873a1 (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
Return-Path: <jeremy.l.rubin@gmail.com>
Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])
 by lists.linuxfoundation.org (Postfix) with ESMTP id BD7F6C000B
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sun, 13 Mar 2022 02:34:04 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
 by smtp2.osuosl.org (Postfix) with ESMTP id AA70F404C4
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sun, 13 Mar 2022 02:34:04 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
X-Spam-Flag: NO
X-Spam-Score: -2.098
X-Spam-Level: 
X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5
 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
 DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,
 HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: smtp2.osuosl.org (amavisd-new);
 dkim=pass (2048-bit key) header.d=gmail.com
Received: from smtp2.osuosl.org ([127.0.0.1])
 by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id rEzrX9fCn3Jm
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sun, 13 Mar 2022 02:34:02 +0000 (UTC)
X-Greylist: whitelisted by SQLgrey-1.8.0
Received: from mail-lf1-x12b.google.com (mail-lf1-x12b.google.com
 [IPv6:2a00:1450:4864:20::12b])
 by smtp2.osuosl.org (Postfix) with ESMTPS id 34EEA40545
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sun, 13 Mar 2022 02:34:02 +0000 (UTC)
Received: by mail-lf1-x12b.google.com with SMTP id s29so78604lfb.13
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 12 Mar 2022 18:34:02 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to;
 bh=eCSl/UNZW0nLQeGPlvzPcfzxHx2FVVazRkubUAkoDvE=;
 b=lwoi3ZIRvzUcgFotDyf7lkPf9/tW6RBDeuc0aQJqg1xy7S9LAQxT3UUcLHCh9tJ8FY
 jumeTLeWEhuQOVogaflF68QmfE1UbW5sW/yfH30hkmIoeOV60KA1Ln22qbEEihMXHAYG
 MIjqXdtY97UxNZ5Ge1dB65xbwtwiF/WBsrJQDtx171R/Ua/kSj3nRH7zdHfkr5+MiDb7
 xYUonju/IWc08pR3ceBfIqNYY5kP9+NFs89V5LXgTkrzHySQxws7de4vaPHypmwHQ1ZY
 sPBBK9/8QUjG1pUc+TvQsdwKwKoQKf3FwFyJzAEK4cNZgiGFA3/JNe/s5AVVPIRJqZmd
 37bw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to;
 bh=eCSl/UNZW0nLQeGPlvzPcfzxHx2FVVazRkubUAkoDvE=;
 b=6jZR/SEEgGOOWadoNIqGVKNPY1SNIquAM6HsU8hefDW/0nwbDxkDKdoB/9MT1GFkDm
 fFhHFhumHxm7cw6dtCCb+sbUMc7aTSyv3bSpy0SQcedeEW28d9dA9vd+jUug7JqRFcS7
 f6FYo6cL20HrU9e0uDaBPMZ6p9czkVQyUnTINeazm7dP188J0PS2QAgXoiAhSrWejHbH
 +9sgdicvPrNc4++BdmLparxIL6lAmP/qk3KoJ0XJEUROyPSQX5Ytv+M1uO4zyi/L7DMR
 vu/cgiQcdx72LicMBT3H3pYj9cAzzCgc6wTQI6X7mC9/l/yRdLnIpXgNrsU1StjQqxQh
 QRww==
X-Gm-Message-State: AOAM5323SA+6MD/KyvWeWkOQHbLm245EOZ066OovAdvZTRN28z4hQJF5
 nC1o+NuVAHmPqsIalpyBfYlxBEm+kgPEW0wXcb4=
X-Google-Smtp-Source: ABdhPJx3uAw4FD2sDf1hQC+An6LSJOUNim/gdIx8iEQHdp1VJqQZs7qfZaZJni7IUHPUvjA3EtTyUxKBFyi6Jl3KB88=
X-Received: by 2002:a05:6512:2190:b0:443:f5b2:67ef with SMTP id
 b16-20020a056512219000b00443f5b267efmr9315644lft.670.1647138839718; Sat, 12
 Mar 2022 18:33:59 -0800 (PST)
MIME-Version: 1.0
References: <Udzkz8ZPM4na6yNcGnINLCskodTve66hhpoXevwYuVVgfWfbJnLH70Btmp_dmvk8X8sNXqywBVviG3OzFzeoXQanPb8KkWNGjKG2mxxDsAo=@protonmail.com>
In-Reply-To: <Udzkz8ZPM4na6yNcGnINLCskodTve66hhpoXevwYuVVgfWfbJnLH70Btmp_dmvk8X8sNXqywBVviG3OzFzeoXQanPb8KkWNGjKG2mxxDsAo=@protonmail.com>
From: Jeremy Rubin <jeremy.l.rubin@gmail.com>
Date: Sat, 12 Mar 2022 18:33:48 -0800
Message-ID: <CAD5xwhgoxMnGpwn=4Ww_ZWP+ViZabvcxUV_n5=sXFdCwSe6-Mw@mail.gmail.com>
To: darosior <darosior@protonmail.com>, 
 Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Content-Type: multipart/alternative; boundary="0000000000006fed4305da1065d8"
Subject: Re: [bitcoin-dev] Covenants and feebumping
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.15
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: Sun, 13 Mar 2022 02:34:04 -0000

--0000000000006fed4305da1065d8
Content-Type: text/plain; charset="UTF-8"

Hi Antoine,

I have a few high level thoughts on your post comparing these types of
primitive to an explicit soft fork approach:

1) Transaction sponsors *is* a type of covenant. Precisely, it is very
similar to an "Impossible Input" covenant in conjunction with a "IUTXO" I
defined in my 2017 workshop
https://rubin.io/public/pdfs/multi-txn-contracts.pdf (I know, I know...
self citation, not cool, but helps with context).

However, for Sponsors itself we optimize the properties of how it works &
is represented, as well as "tighten the hatches" on binding to specific TX
vs merely spend of the outputs (which wouldn't work as well with APO).

Perhaps thinking of something like sponsors as a form of covenant, rather
than a special purpose thing, is helpful?

There's a lot you could do with a general "observe other txns in {this
block, the chain}" primitive. The catch is that for sponsors we don't
*care* to enable people to use this as a "smart contracting primitive", we
want to use it for fee bumping. So we don't care about programmability, we
care about being able to use the covenant to bump fees.

2) On Chain Efficiency.


A) Precommitted Levels
As you've noted, an approach like precomitted different fee levels might
work, but has substantial costs.

However, with sponsors, the minimum viable version of this (not quite what
is spec'd in my prior email, but it could be done this way if we care to
optimize for bytes) would require 1 in and 1 out with only 32 bytes extra.
So that's around 40 bytes outpoint + 64 bytes signature + 40 bytes output +
32 bytes metadata = 174 bytes per bump. Bumps in this way can also
amortize, so bumping >1 txn at the same time would hit the limit of 32
bytes + 144/n  bytes to bump more than one thing. You can imagine cases
where this might be popular, like "close >1 of my LN channels" or "start
withdrawals for 5 of my JamesOB vaulted coins"

B) Fancy(er) Covenants

We might also have something with OP_CAT and CSFS where bumps are done as
some sort of covenant-y thing that lets you arbitrarily rewrite
transactions.

Not too much to say other than that it is difficult to get these down in
size as the scripts become more complex, not to mention the (hotly
discussed of late) ramifications of those covenants more generally.

Absent a concrete fancy covenant with fee bumping, I can't comment.

3) On Capital Efficiency

Something like a precommitted or covenant fee bump requires the fee capital
to be pre-committed inside the UTXO, whereas for something like Sponsors
you can use capital you get sometime later. In certain models -- e.g.,
channels -- where you might expect only log(N) of your channels to fail in
a given epoch, you don't need to allocate as much capital as if you were to
have to do it in-band. This is also true for vaults where you know you only
want to open 1 per month let's say, and not <all of your vaults> per month,
which pre-committing requires.

4) On Protocol Design

It's nice that you can abstract away your protocol design concerns as a
"second tier composition check" v.s. having to modify your protocol to work
with a fee bumping thing.

There are a myriad of ways dynamic txns (e.g. for Eltoo) can lead to RBF
pinning and similar, Sponsor type things allow you to design such protocols
to not have any native way of paying for fees inside the actual
"Transaction Intents" and use an external system to create the intended
effect. It seems (to me) more robust that we can prove that a Sponsors
mechanism allows any transaction -- regardless of covenant stuff, bugs,
pinning, etc -- to move forward.

Still... careful protocol design may permit the use of optimized
constructions! For example, in a vault rather than assigning *no fee* maybe
you can have a single branch with a reasonable estimated fee. If you are
correct or overshot (let's say 50% chance?) then you don't need to add a
sponsor. If you undershot, not to worry, just add a sponsor. Adopted
broadly, this would cut the expected value of using sponsors by <however
good you are at estimating future fees>. This basically enables all
protocols to try to be more efficient, but backstop that with a guaranteed
to work safe mechanism.



There was something else I was going to say but I forgot about it... if it
comes to me I'll send a follow up email.

Cheers,

Jeremy

p.s.

>


> *Of course this makes for a perfect DoS: it would be trivial for a miner
> to infer that you are using*
> *a specific vault standard and guess other leaves and replace the witness
> to use the highest-feerate*
> *spending path. You could require a signature from any of the
> participants. Or, at the cost of an**additional depth, in the tree you
> could "salt" each leaf by pairing it with -say- an OP_RETURN leaf.*



you don't need a salt, you just need a unique payout addr (e.g. hardened
derivation) per revocation txn and you cannot guess the branch.

--
@JeremyRubin <https://twitter.com/JeremyRubin>

On Sat, Mar 12, 2022 at 10:34 AM darosior via bitcoin-dev <
bitcoin-dev@lists.linuxfoundation.org> wrote:

> The idea of a soft fork to fix dynamic fee bumping was recently put back
> on the table. It might
> sound radical, as what prevents today reasonable fee bumping for contracts
> with presigned
> transactions (pinning) has to do with nodes' relay policy. But the
> frustration is understandable
> given the complexity of designing fee bumping with today's primitives. [0]
> Recently too, there was a lot of discussions around covenants. Covenants
> (conceptually, not talking
> about any specific proposal) seem to open lots of new use cases and to be
> desired by (some?) Bitcoin
> application developers and users.
> I think that fee bumping using covenants has attractive properties, and it
> requires a soft fork that
> is already desirable beyond (trying) to fix fee bumping. However i could
> not come up with a solution
> as neat for other protocols than vaults. I'd like to hear from others
> about 1) taking this route for
> fee bumping 2) better ideas on applying this to other protocols.
>
>
> In a vault construction you have a UTxO which can only be spent by an
> Unvaulting transaction, whose
> output triggers a timelock before the expiration of which a revocation
> transaction may be confirmed.
> The revocation transaction being signed in advance (typically before
> sharing the signature for the
> Unvault transaction) you need fee bumping in order for the contract to
> actually be enforceable.
>
> Now, with a covenant you could commit to the revocation tx instead of
> presigning it. And using a
> Taproot tree you could commit to different versions of it with increasing
> feerate. Any network
> monitor (the brooadcaster, a watchtower, ..) would be able to RBF the
> revocation transaction if it
> doesn't confirm by spending using a leaf with a higher-feerate transaction
> being committed to.
>
> Of course this makes for a perfect DoS: it would be trivial for a miner to
> infer that you are using
> a specific vault standard and guess other leaves and replace the witness
> to use the highest-feerate
> spending path. You could require a signature from any of the participants.
> Or, at the cost of an
> additional depth, in the tree you could "salt" each leaf by pairing it
> with -say- an OP_RETURN leaf.
> But this leaves you with a possible internal blackmail for multi-party
> contracts (although it's less
> of an issue for vaults, and not one for single-party vaults).
> What you could do instead is attaching an increasing relative timelock to
> each leaf (as the committed
> revocation feerate increases, so does the timelock). You need to be
> careful to note wreck miner
> incentives here (see [0], [1], [2] on "miner harvesting"), but this
> enables the nice property of a
> feerate which "adapts" to the block space market. Another nice property of
> this approach is the
> integrated anti fee sniping protection if the revocation transaction pays
> a non-trivial amount of
> fees.
>
> Paying fees from "shared" funds instead of a per-watchtower fee-bumping
> wallet opened up the
> blackmail from the previous section, but the benefits of paying from
> internal funds shouldn't be
> understated.
> No need to decide on an amount to be refilled. No need to bother the user
> to refill the fee-bumping
> wallet (before they can participate in more contracts, or worse before a
> deadline at which all
> contracts are closed). No need for a potentially large amount of funds to
> just sit on a hot wallet
> "just in case". No need to duplicate this amount as you replicate the
> number of network monitors
> (which is critical to the security of such contracts).
> In addition, note how modifying the feerate of the revocation transaction
> in place is less expensive
> than adding a (pair of) new input (and output), let alone adding an entire
> new transaction to CPFP.
> Aside, and less importantly, it can be made to work with today's relay
> rules (just use fee thresholds
> adapted to the current RBF thresholds, potentially with some leeway to
> account for policy changes).
> Paying from shared funds (in addition to paying from internal funds) also
> prevents pervert
> incentives for contracts with more than 2 parties. In case one of the
> parties breaches it, all
> remaining parties have an incentive to enforce the contract.. But only one
> would otherwise pay for
> it! It would open up the door to some potential sneaky techniques to wait
> for another party to pay
> for the fees, which is at odd with the reactive security model.
>
> Let's examine how it could be concretely designed. Say you have a vault
> wallet software for a setup
> with 5 participants. The revocation delay is 144 blocks. You assume
> revocation to be infrequent (if
> one happens it's probably a misconfigured watchtower that needs be fixed
> before the next
> unvaulting), so you can afford infrequent overpayments and larger fee
> thresholds. Participants
> assume the vault will be spent within a year and assume a maximum possible
> feerate for this year of
> 10ksat/vb.
> They create a Taproot tree of depth 7. First leaf is the spending path
> (open to whomever the vault
> pays after the 144 blocks). Then the leaf `i` for `i` in `[1, 127]` is a
> covenant to the revocation
> transaction with a feerate `i * 79` sats/vb and a relative timelock of `i
> - 1` blocks.
> Assuming the covenant to the revocation transaction is 33 bytes [3],
> that's a witness of:
>     1 + 33     + 1 + 33 + 7 * 32 = 292 WU (73 vb)
>     ^^^^^^       ^^^^^^^^^^^^^^
>     witscript     control block
> for any of the revocation paths. The revocation transaction is 1-input
> 1-output, so in total it's
>     10.5 +   41 + 73      + 43    = 167.5 vb
>     ^^^^    ^^^^^^^^^^^    ^^^^
>     header  input|witness  output
> The transaction size is not what you'd necessarily want to optimize for
> first, still, it is smaller
> in this case than using other feebumping primitives and has a smaller
> footprint on the UTxO set. For
> instance for adding a feebumping input and change output assuming all
> Taproot inputs and outputs
> (CPFP is necessarily even larger):
>     5 * 64 +  1 + 5 * (32 + 1) + 1 + 33 = 520 WU (105 vb)
>     ^^^^^^    ^^^^^^^^^^^^^^^    ^^^^^^
>     witness      witscript       control
>     10.5  +  41 + 105      + 41 + 16.5         + 2 * 43  = 300 vb
>     ^^^^     ^^^^^^^^        ^^^^^^^^^           ^^^^^^
>     header   input|witness   fb input|witness    outputs
> From there, you can afford more depths at the tiny cost of 8 more vbytes
> each. You might want them
> for:
> - more granularity (if you can afford large enough timelocks)
> - optimizing for the spending path rather than the revocation one
> - adding a hashlock to prevent nuisance (with the above script a third
> party could malleate a
>   spending path into a revocation one). You can use the OP_RETURN trick
> from above to prevent that.
>
> Unfortunately, the timelocked-covenant approach to feebumping only applies
> to bumping the first
> transaction of a chain (you can't pay for the parent with a timelock) so
> for instance it's not
> usable for HTLC transactions in Lightning to bump the parent commitment
> tx. The same goes for
> bumping the update tx in Coinpool.
> It could be worked around by having a different covenant per participant
> (paying the fee from either
> of the participants' output) behind a signature check. Of course it
> requires funds to already be in
> the contract (HTLC, Coinpool leaf) to pay for your own unilateral close,
> but if you don't have any
> fund in the contract it doesn't make sense to try to feebump it in the
> first place. The same goes
> for small amounts: you'd only allocate up to the value of the contract
> (minus a dust preference) in
> fees in order to enforce it.
> This is less nice for external monitors as it requires a private key (or
> another secret) to be
> committed to in advance) to be able to bump [4] and does not get rid of
> the "who's gonna pay for the
> enforcement" issue in >2-parties contracts. Still, it's more optimal and
> usable than CPFP or adding
> a pair of input/output for all the reasons mentioned above.
>
>
> Thoughts?
> Antoine
>
>
> [0]
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-November/019614.html
> [1]
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-November/019615.html
> [2]
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-December/019627.html
> [3] That's obviously close to the CTV construction. But using another more
> flexible (and therefore
>     less optimized) construction would not be a big deal. It might in fact
> be necessary for more
>     elaborated (realistic?) usecases than the simple one detailed here.
> [4]
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

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

<div dir=3D"ltr"><div class=3D"gmail_default" style=3D"font-family:arial,he=
lvetica,sans-serif;font-size:small;color:#000000"><div class=3D"gmail_defau=
lt">Hi Antoine,</div><div class=3D"gmail_default"><br></div><div class=3D"g=
mail_default">I have a few high level thoughts on your post comparing these=
 types of primitive to an explicit soft fork approach:</div><div class=3D"g=
mail_default"><br></div><div class=3D"gmail_default">1) Transaction sponsor=
s *is* a type of covenant. Precisely, it is very similar to an &quot;Imposs=
ible Input&quot; covenant in conjunction with a &quot;IUTXO&quot; I defined=
 in my 2017 workshop<span class=3D"gmail-Apple-converted-space">=C2=A0</spa=
n><a href=3D"https://rubin.io/public/pdfs/multi-txn-contracts.pdf" target=
=3D"_blank">https://rubin.io/public/pdfs/multi-txn-contracts.pdf</a><span c=
lass=3D"gmail-Apple-converted-space">=C2=A0</span>(I know, I know... self c=
itation, not cool, but helps with context).</div><div class=3D"gmail_defaul=
t"><br></div><div class=3D"gmail_default">However, for Sponsors itself we o=
ptimize the properties of how it works &amp; is represented, as well as &qu=
ot;tighten the hatches&quot; on binding to specific TX vs merely spend of t=
he outputs (which wouldn&#39;t work as well with APO).</div><div class=3D"g=
mail_default"><br></div><div class=3D"gmail_default">Perhaps thinking of so=
mething like sponsors as a form of covenant, rather than a special purpose =
thing, is helpful?</div><div class=3D"gmail_default"><br></div><div class=
=3D"gmail_default">There&#39;s a lot you could do with a general &quot;obse=
rve other txns in {this block, the chain}&quot; primitive. The catch is tha=
t for sponsors we don&#39;t *care* to enable people to use this as a &quot;=
smart contracting primitive&quot;, we want to use it for fee bumping. So we=
 don&#39;t care about programmability, we care about being able to use the =
covenant to bump fees.</div><div class=3D"gmail_default"><br></div><div cla=
ss=3D"gmail_default">2) On Chain Efficiency.</div><div class=3D"gmail_defau=
lt"><br></div><div class=3D"gmail_default"><br></div><div class=3D"gmail_de=
fault">A) Precommitted Levels</div><div class=3D"gmail_default">As you&#39;=
ve noted, an approach like precomitted=C2=A0different fee levels might work=
, but has substantial costs.</div><div class=3D"gmail_default"><br></div><d=
iv class=3D"gmail_default">However, with sponsors, the minimum viable versi=
on of this (not quite what is spec&#39;d in my prior email, but it could be=
 done this way if we care to optimize for bytes) would require 1 in and 1 o=
ut with only 32 bytes extra. So that&#39;s around 40 bytes outpoint=C2=A0+ =
64 bytes signature=C2=A0+ 40 bytes output=C2=A0+ 32 bytes metadata =3D 174 =
bytes per bump. Bumps in this way can also amortize, so bumping &gt;1 txn a=
t the same time would hit the limit of 32 bytes=C2=A0+ 144/n =C2=A0bytes to=
 bump more than one thing. You can imagine cases where this might be popula=
r, like &quot;close &gt;1 of my LN channels&quot; or &quot;start withdrawal=
s for 5 of my JamesOB vaulted coins&quot;</div><div class=3D"gmail_default"=
><br></div><div class=3D"gmail_default">B) Fancy(er) Covenants</div><div cl=
ass=3D"gmail_default"><br></div><div class=3D"gmail_default">We might also =
have something with OP_CAT and CSFS where bumps are done as some sort of co=
venant-y thing that lets you arbitrarily rewrite transactions.</div><div cl=
ass=3D"gmail_default"><br></div><div class=3D"gmail_default">Not too much t=
o say other than that it is difficult to get these down in size as the scri=
pts become more complex, not to mention the (hotly discussed of late) ramif=
ications of those covenants more generally.</div><div class=3D"gmail_defaul=
t"><br></div><div class=3D"gmail_default">Absent a concrete fancy covenant =
with fee bumping, I can&#39;t comment.</div><div class=3D"gmail_default"><b=
r></div><div class=3D"gmail_default">3) On Capital Efficiency</div><div cla=
ss=3D"gmail_default"><br></div><div class=3D"gmail_default">Something like =
a precommitted=C2=A0or covenant fee bump requires the fee capital to be pre=
-committed inside the UTXO, whereas for something like Sponsors you can use=
 capital you get sometime later. In certain models -- e.g., channels -- whe=
re you might expect only log(N) of your channels to fail in a given epoch, =
you don&#39;t need to allocate as much capital as if you were to have to do=
 it in-band. This is also true for vaults where you know you only want to o=
pen 1 per month let&#39;s say, and not &lt;all of your vaults&gt; per month=
, which pre-committing requires.</div><div class=3D"gmail_default"><br></di=
v><div class=3D"gmail_default">4) On Protocol Design</div><div class=3D"gma=
il_default"><br></div><div class=3D"gmail_default">It&#39;s nice that you c=
an abstract away your protocol design concerns as a &quot;second tier compo=
sition check&quot; v.s. having to modify your protocol to work with a fee b=
umping thing.</div><div class=3D"gmail_default"><br></div><div class=3D"gma=
il_default">There are a myriad of ways dynamic txns (e.g. for Eltoo) can le=
ad to RBF pinning and similar, Sponsor type things allow you to design such=
 protocols to not have any native way of paying for fees inside the actual =
&quot;Transaction Intents&quot; and use an external system to create the in=
tended effect. It seems (to me) more robust that we can prove that a Sponso=
rs mechanism allows any transaction -- regardless of covenant stuff,=C2=A0b=
ugs, pinning, etc -- to move forward.</div><div class=3D"gmail_default"><br=
></div><div class=3D"gmail_default">Still... careful protocol design may pe=
rmit the use of optimized constructions! For example, in a vault rather tha=
n assigning *no fee* maybe you can have a single branch with a reasonable e=
stimated fee. If you are correct or overshot (let&#39;s say 50% chance?) th=
en you don&#39;t need to add a sponsor. If you undershot, not to worry, jus=
t add a sponsor. Adopted broadly, this would cut the expected value of usin=
g sponsors by &lt;however good you are at estimating future fees&gt;. This =
basically enables all protocols to try to be more efficient, but backstop t=
hat with a guaranteed to work safe mechanism.</div><div class=3D"gmail_defa=
ult"><br></div><div class=3D"gmail_default"><br></div><div class=3D"gmail_d=
efault"><br></div><div class=3D"gmail_default">There was something else I w=
as going to say but I forgot about it... if it comes to me I&#39;ll send a =
follow up email.</div><div class=3D"gmail_default"><br></div><div class=3D"=
gmail_default">Cheers,</div><div class=3D"gmail_default"><br></div><div cla=
ss=3D"gmail_default">Jeremy</div><div class=3D"gmail_default"><br></div><di=
v class=3D"gmail_default">p.s.</div><span class=3D"gmail-im" style=3D"color=
:rgb(80,0,80);font-family:Arial,Helvetica,sans-serif"><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border=
-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">=C2=
=A0</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rg=
b(204,204,204);padding-left:1ex"><i><span style=3D"color:rgb(34,34,34)">Of =
course this makes for a perfect DoS: it would be trivial for a miner to inf=
er that you are using<br></span></i><i><span style=3D"color:rgb(34,34,34)">=
a specific vault standard and guess other leaves and replace the witness to=
 use the highest-feerate<br></span></i><i><span style=3D"color:rgb(34,34,34=
)">spending path. You could require a signature from any of the participant=
s. Or, at the cost of an<br></span></i><i><span style=3D"color:rgb(34,34,34=
)">additional depth, in the tree you could &quot;salt&quot; each leaf by pa=
iring it with -say- an OP_RETURN leaf.</span></i></blockquote><div class=3D=
"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;color:rgb(0=
,0,0)"><br></div><div class=3D"gmail_default" style=3D"font-family:arial,he=
lvetica,sans-serif;color:rgb(0,0,0)"><br></div></span><div class=3D"gmail_d=
efault">you don&#39;t need a salt, you just need a unique payout addr (e.g.=
 hardened derivation) per revocation txn and you cannot guess the branch.</=
div></div><br clear=3D"all"><div><div dir=3D"ltr" class=3D"gmail_signature"=
 data-smartmail=3D"gmail_signature"><div dir=3D"ltr">--<br><a href=3D"https=
://twitter.com/JeremyRubin" target=3D"_blank">@JeremyRubin</a><br></div></d=
iv></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gma=
il_attr">On Sat, Mar 12, 2022 at 10:34 AM darosior via bitcoin-dev &lt;<a h=
ref=3D"mailto:bitcoin-dev@lists.linuxfoundation.org">bitcoin-dev@lists.linu=
xfoundation.org</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:so=
lid;border-left-color:rgb(204,204,204);padding-left:1ex">The idea of a soft=
 fork to fix dynamic fee bumping was recently put back on the table. It mig=
ht<br>
sound radical, as what prevents today reasonable fee bumping for contracts =
with presigned<br>
transactions (pinning) has to do with nodes&#39; relay policy. But the frus=
tration is understandable<br>
given the complexity of designing fee bumping with today&#39;s primitives. =
[0]<br>
Recently too, there was a lot of discussions around covenants. Covenants (c=
onceptually, not talking<br>
about any specific proposal) seem to open lots of new use cases and to be d=
esired by (some?) Bitcoin<br>
application developers and users.<br>
I think that fee bumping using covenants has attractive properties, and it =
requires a soft fork that<br>
is already desirable beyond (trying) to fix fee bumping. However i could no=
t come up with a solution<br>
as neat for other protocols than vaults. I&#39;d like to hear from others a=
bout 1) taking this route for<br>
fee bumping 2) better ideas on applying this to other protocols.<br>
<br>
<br>
In a vault construction you have a UTxO which can only be spent by an Unvau=
lting transaction, whose<br>
output triggers a timelock before the expiration of which a revocation tran=
saction may be confirmed.<br>
The revocation transaction being signed in advance (typically before sharin=
g the signature for the<br>
Unvault transaction) you need fee bumping in order for the contract to actu=
ally be enforceable.<br>
<br>
Now, with a covenant you could commit to the revocation tx instead of presi=
gning it. And using a<br>
Taproot tree you could commit to different versions of it with increasing f=
eerate. Any network<br>
monitor (the brooadcaster, a watchtower, ..) would be able to RBF the revoc=
ation transaction if it<br>
doesn&#39;t confirm by spending using a leaf with a higher-feerate transact=
ion being committed to.<br>
<br>
Of course this makes for a perfect DoS: it would be trivial for a miner to =
infer that you are using<br>
a specific vault standard and guess other leaves and replace the witness to=
 use the highest-feerate<br>
spending path. You could require a signature from any of the participants. =
Or, at the cost of an<br>
additional depth, in the tree you could &quot;salt&quot; each leaf by pairi=
ng it with -say- an OP_RETURN leaf.<br>
But this leaves you with a possible internal blackmail for multi-party cont=
racts (although it&#39;s less<br>
of an issue for vaults, and not one for single-party vaults).<br>
What you could do instead is attaching an increasing relative timelock to e=
ach leaf (as the committed<br>
revocation feerate increases, so does the timelock). You need to be careful=
 to note wreck miner<br>
incentives here (see [0], [1], [2] on &quot;miner harvesting&quot;), but th=
is enables the nice property of a<br>
feerate which &quot;adapts&quot; to the block space market. Another nice pr=
operty of this approach is the<br>
integrated anti fee sniping protection if the revocation transaction pays a=
 non-trivial amount of<br>
fees.<br>
<br>
Paying fees from &quot;shared&quot; funds instead of a per-watchtower fee-b=
umping wallet opened up the<br>
blackmail from the previous section, but the benefits of paying from intern=
al funds shouldn&#39;t be<br>
understated.<br>
No need to decide on an amount to be refilled. No need to bother the user t=
o refill the fee-bumping<br>
wallet (before they can participate in more contracts, or worse before a de=
adline at which all<br>
contracts are closed). No need for a potentially large amount of funds to j=
ust sit on a hot wallet<br>
&quot;just in case&quot;. No need to duplicate this amount as you replicate=
 the number of network monitors<br>
(which is critical to the security of such contracts).<br>
In addition, note how modifying the feerate of the revocation transaction i=
n place is less expensive<br>
than adding a (pair of) new input (and output), let alone adding an entire =
new transaction to CPFP.<br>
Aside, and less importantly, it can be made to work with today&#39;s relay =
rules (just use fee thresholds<br>
adapted to the current RBF thresholds, potentially with some leeway to acco=
unt for policy changes).<br>
Paying from shared funds (in addition to paying from internal funds) also p=
revents pervert<br>
incentives for contracts with more than 2 parties. In case one of the parti=
es breaches it, all<br>
remaining parties have an incentive to enforce the contract.. But only one =
would otherwise pay for<br>
it! It would open up the door to some potential sneaky techniques to wait f=
or another party to pay<br>
for the fees, which is at odd with the reactive security model.<br>
<br>
Let&#39;s examine how it could be concretely designed. Say you have a vault=
 wallet software for a setup<br>
with 5 participants. The revocation delay is 144 blocks. You assume revocat=
ion to be infrequent (if<br>
one happens it&#39;s probably a misconfigured watchtower that needs be fixe=
d before the next<br>
unvaulting), so you can afford infrequent overpayments and larger fee thres=
holds. Participants<br>
assume the vault will be spent within a year and assume a maximum possible =
feerate for this year of<br>
10ksat/vb.<br>
They create a Taproot tree of depth 7. First leaf is the spending path (ope=
n to whomever the vault<br>
pays after the 144 blocks). Then the leaf `i` for `i` in `[1, 127]` is a co=
venant to the revocation<br>
transaction with a feerate `i * 79` sats/vb and a relative timelock of `i -=
 1` blocks.<br>
Assuming the covenant to the revocation transaction is 33 bytes [3], that&#=
39;s a witness of:<br>
=C2=A0 =C2=A0 1 + 33=C2=A0 =C2=A0 =C2=A0+ 1 + 33 + 7 * 32 =3D 292 WU (73 vb=
)<br>
=C2=A0 =C2=A0 ^^^^^^=C2=A0 =C2=A0 =C2=A0 =C2=A0^^^^^^^^^^^^^^<br>
=C2=A0 =C2=A0 witscript=C2=A0 =C2=A0 =C2=A0control block<br>
for any of the revocation paths. The revocation transaction is 1-input 1-ou=
tput, so in total it&#39;s<br>
=C2=A0 =C2=A0 10.5 +=C2=A0 =C2=A041 + 73=C2=A0 =C2=A0 =C2=A0 + 43=C2=A0 =C2=
=A0 =3D 167.5 vb<br>
=C2=A0 =C2=A0 ^^^^=C2=A0 =C2=A0 ^^^^^^^^^^^=C2=A0 =C2=A0 ^^^^<br>
=C2=A0 =C2=A0 header=C2=A0 input|witness=C2=A0 output<br>
The transaction size is not what you&#39;d necessarily want to optimize for=
 first, still, it is smaller<br>
in this case than using other feebumping primitives and has a smaller footp=
rint on the UTxO set. For<br>
instance for adding a feebumping input and change output assuming all Tapro=
ot inputs and outputs<br>
(CPFP is necessarily even larger):<br>
=C2=A0 =C2=A0 5 * 64 +=C2=A0 1 + 5 * (32 + 1) + 1 + 33 =3D 520 WU (105 vb)<=
br>
=C2=A0 =C2=A0 ^^^^^^=C2=A0 =C2=A0 ^^^^^^^^^^^^^^^=C2=A0 =C2=A0 ^^^^^^<br>
=C2=A0 =C2=A0 witness=C2=A0 =C2=A0 =C2=A0 witscript=C2=A0 =C2=A0 =C2=A0 =C2=
=A0control<br>
=C2=A0 =C2=A0 10.5=C2=A0 +=C2=A0 41 + 105=C2=A0 =C2=A0 =C2=A0 + 41 + 16.5=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0+ 2 * 43=C2=A0 =3D 300 vb<br>
=C2=A0 =C2=A0 ^^^^=C2=A0 =C2=A0 =C2=A0^^^^^^^^=C2=A0 =C2=A0 =C2=A0 =C2=A0 ^=
^^^^^^^^=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0^^^^^^<br>
=C2=A0 =C2=A0 header=C2=A0 =C2=A0input|witness=C2=A0 =C2=A0fb input|witness=
=C2=A0 =C2=A0 outputs<br>
From there, you can afford more depths at the tiny cost of 8 more vbytes ea=
ch. You might want them<br>
for:<br>
- more granularity (if you can afford large enough timelocks)<br>
- optimizing for the spending path rather than the revocation one<br>
- adding a hashlock to prevent nuisance (with the above script a third part=
y could malleate a<br>
=C2=A0 spending path into a revocation one). You can use the OP_RETURN tric=
k from above to prevent that.<br>
<br>
Unfortunately, the timelocked-covenant approach to feebumping only applies =
to bumping the first<br>
transaction of a chain (you can&#39;t pay for the parent with a timelock) s=
o for instance it&#39;s not<br>
usable for HTLC transactions in Lightning to bump the parent commitment tx.=
 The same goes for<br>
bumping the update tx in Coinpool.<br>
It could be worked around by having a different covenant per participant (p=
aying the fee from either<br>
of the participants&#39; output) behind a signature check. Of course it req=
uires funds to already be in<br>
the contract (HTLC, Coinpool leaf) to pay for your own unilateral close, bu=
t if you don&#39;t have any<br>
fund in the contract it doesn&#39;t make sense to try to feebump it in the =
first place. The same goes<br>
for small amounts: you&#39;d only allocate up to the value of the contract =
(minus a dust preference) in<br>
fees in order to enforce it.<br>
This is less nice for external monitors as it requires a private key (or an=
other secret) to be<br>
committed to in advance) to be able to bump [4] and does not get rid of the=
 &quot;who&#39;s gonna pay for the<br>
enforcement&quot; issue in &gt;2-parties contracts. Still, it&#39;s more op=
timal and usable than CPFP or adding<br>
a pair of input/output for all the reasons mentioned above.<br>
<br>
<br>
Thoughts?<br>
Antoine<br>
<br>
<br>
[0] <a href=3D"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021=
-November/019614.html" rel=3D"noreferrer" target=3D"_blank">https://lists.l=
inuxfoundation.org/pipermail/bitcoin-dev/2021-November/019614.html</a><br>
[1] <a href=3D"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021=
-November/019615.html" rel=3D"noreferrer" target=3D"_blank">https://lists.l=
inuxfoundation.org/pipermail/bitcoin-dev/2021-November/019615.html</a><br>
[2] <a href=3D"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021=
-December/019627.html" rel=3D"noreferrer" target=3D"_blank">https://lists.l=
inuxfoundation.org/pipermail/bitcoin-dev/2021-December/019627.html</a><br>
[3] That&#39;s obviously close to the CTV construction. But using another m=
ore flexible (and therefore<br>
=C2=A0 =C2=A0 less optimized) construction would not be a big deal. It migh=
t in fact be necessary for more<br>
=C2=A0 =C2=A0 elaborated (realistic?) usecases than the simple one detailed=
 here.<br>
[4] <a href=3D"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022=
-February/019879.html" rel=3D"noreferrer" target=3D"_blank">https://lists.l=
inuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html</a><br>
_______________________________________________<br>
bitcoin-dev mailing list<br>
<a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" target=3D"_blank">=
bitcoin-dev@lists.linuxfoundation.org</a><br>
<a href=3D"https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev" =
rel=3D"noreferrer" target=3D"_blank">https://lists.linuxfoundation.org/mail=
man/listinfo/bitcoin-dev</a><br>
</blockquote></div>

--0000000000006fed4305da1065d8--