diff options
author | Billy Tetrud <billy.tetrud@gmail.com> | 2021-08-01 21:40:47 -0700 |
---|---|---|
committer | bitcoindev <bitcoindev@gnusha.org> | 2021-08-02 04:41:08 +0000 |
commit | 111ddd44e9fd220ea86135b9c9d99e27bb2f6933 (patch) | |
tree | 46e8fe0021aa65783a4a84970e1a2f89230a8589 | |
parent | 5ee604f555de4c8c698247ff2b3e3cadb05e6ff1 (diff) | |
download | pi-bitcoindev-111ddd44e9fd220ea86135b9c9d99e27bb2f6933.tar.gz pi-bitcoindev-111ddd44e9fd220ea86135b9c9d99e27bb2f6933.zip |
Re: [bitcoin-dev] Exploring: limiting transaction output amount as a function of total input value
-rw-r--r-- | fe/2ab567561ce5f734c653fb7b824390d6fd6990 | 498 |
1 files changed, 498 insertions, 0 deletions
diff --git a/fe/2ab567561ce5f734c653fb7b824390d6fd6990 b/fe/2ab567561ce5f734c653fb7b824390d6fd6990 new file mode 100644 index 000000000..3157c402e --- /dev/null +++ b/fe/2ab567561ce5f734c653fb7b824390d6fd6990 @@ -0,0 +1,498 @@ +Return-Path: <fresheneesz@gmail.com> +Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) + by lists.linuxfoundation.org (Postfix) with ESMTP id F225BC000E + for <bitcoin-dev@lists.linuxfoundation.org>; + Mon, 2 Aug 2021 04:41:08 +0000 (UTC) +Received: from localhost (localhost [127.0.0.1]) + by smtp3.osuosl.org (Postfix) with ESMTP id DAF5860677 + for <bitcoin-dev@lists.linuxfoundation.org>; + Mon, 2 Aug 2021 04:41:08 +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: smtp3.osuosl.org (amavisd-new); + dkim=pass (2048-bit key) header.d=gmail.com +Received: from smtp3.osuosl.org ([127.0.0.1]) + by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id fBXfO04b_wEB + for <bitcoin-dev@lists.linuxfoundation.org>; + Mon, 2 Aug 2021 04:41:06 +0000 (UTC) +X-Greylist: whitelisted by SQLgrey-1.8.0 +Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com + [IPv6:2a00:1450:4864:20::531]) + by smtp3.osuosl.org (Postfix) with ESMTPS id 79FF960652 + for <bitcoin-dev@lists.linuxfoundation.org>; + Mon, 2 Aug 2021 04:41:06 +0000 (UTC) +Received: by mail-ed1-x531.google.com with SMTP id v20so8677653eda.1 + for <bitcoin-dev@lists.linuxfoundation.org>; + Sun, 01 Aug 2021 21:41:06 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; + h=mime-version:references:in-reply-to:from:date:message-id:subject:to; + bh=Btrg3QyzSX/pjPBDg6tiMejGld/2pMlLMeY16SyZsP4=; + b=VF1eN2detN3N7CR+shOb7s+EU0O/jgRCbaXPRBUSiHqAEoGSRaWUFo3PaMmnabJG9S + Lv3sd2so60GYPPIB7UUwCYyKhVjz6eYgM9bIpZeYsV2sgB8fATtytvP/gPjnLKP0hsW+ + mJdR0MJ8fRdghyy61qj+94L4RbDBsd6HKxMtpvKDudRGfawLmyc3IcZ9sTF/OT348ZF4 + OS/T+yfjcdwECdpkVgVwqyYsmw2IuOTjt8qvVMeJqqcVkXveIGC9+UX6R529oE+lBcoW + nMKljBjnbbO6OfF5RWwQIJurw8cgOXdgaDhRG+Yr35ze2yOIWj8VRyrjda4M9tE0ypSR + o/2g== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20161025; + h=x-gm-message-state:mime-version:references:in-reply-to:from:date + :message-id:subject:to; + bh=Btrg3QyzSX/pjPBDg6tiMejGld/2pMlLMeY16SyZsP4=; + b=ttTUZe5bVBrzIh2U6GF3eJTeGZGcbcBubr+UkA9EHV1io56lCKGsTBKUFF1aGxmLh7 + uA7cWZn9aR7tv4c+H4nDL4ehw2akypc5QL3yggS9da8dx6H5hCF0WHL8/aS2FQzD75Zm + RqVSfdhBjAg2Efh6JNVfdxBoKnAu1481D5W6tKS+J970VeGdodsQkBJEiX53MV9fBpQz + +LeZVf6LPKAOyILNC6oGCXJvRm/p7ebe9nVngzGpxeF5uBP9MxrJpem0mnZ/UdYLYk8K + AldwqsoMpr0RGbQr2Ng2z7L2/myB5ElBqUiZEZIbAY8evpFLljcok76WsAT8d0H+S8eW + eftA== +X-Gm-Message-State: AOAM532Pepxiw1MwMdGu/dQ8FUeZKDhHBMpE0QtqfgUPu+tOs6FMErVc + O1u9Ho9Gi8EEGwg1N5+WXsWNc2hYlbIDZUXwnnQ= +X-Google-Smtp-Source: ABdhPJzqo6ZDh9K0KDbihL5S2J6wJlj+kqIt0AuHEGw08B31A1bXoWfBQSyzGKRD8VTgl9634sPYnmc4g0x4sBV9UfM= +X-Received: by 2002:a50:fb05:: with SMTP id d5mr16514737edq.5.1627879264540; + Sun, 01 Aug 2021 21:41:04 -0700 (PDT) +MIME-Version: 1.0 +References: <CAGpPWDZ0aos5qHw2=popCpjuH7OXC0geEj8i3dwDTfP0j=or4w@mail.gmail.com> + <20210725053803.fnmd6etv3f7x3u3p@ganymede> + <CAGpPWDZ8EWd7kGV5pFZadQM1kqETrTK2zybsGF1hW9fx2oZb7w@mail.gmail.com> + <CAH+Axy7cPufMUCMQbCz2MUgRqQbgenAozPBFD8kPYrSjwcRG8w@mail.gmail.com> + <CAGpPWDb8yzGO-VtCO-x09e-phKHT7ezOms+DzeWc9vS3rN1AAw@mail.gmail.com> + <CAJ4-pEDWuNfdE4NXkZBsOnuSQ4YOv28YVwGavyiU+FPvpC6y1w@mail.gmail.com> + <CAGpPWDZL6BpzoNa0Qgf-Ux60fyWPjZH=NESkgbhEQO_My=XiAg@mail.gmail.com> + <CAJ4-pEBwdUJ3kg=yb-kWZLoaX5f_2t353K7Tr+dJy+JpAoKTmQ@mail.gmail.com> + <CAGpPWDYMZ+w3VSaLhR68f4WVq7NCUp3SedwW2e8QnRHOgLQqQg@mail.gmail.com> + <CAJ4-pEAT8Rrf7dN9A+F2SUvaRz0-DqgDw45whtZcWCTPeQ+uxA@mail.gmail.com> +In-Reply-To: <CAJ4-pEAT8Rrf7dN9A+F2SUvaRz0-DqgDw45whtZcWCTPeQ+uxA@mail.gmail.com> +From: Billy Tetrud <billy.tetrud@gmail.com> +Date: Sun, 1 Aug 2021 21:40:47 -0700 +Message-ID: <CAGpPWDZ8sCEjqbN-PM4kc7k7K-3qUqzmHW8hHrBzh7tTJRUs6A@mail.gmail.com> +To: Zac Greenwood <zachgrw@gmail.com>, + Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org> +Content-Type: multipart/alternative; boundary="0000000000004cdb6c05c88c2dc3" +X-Mailman-Approved-At: Mon, 02 Aug 2021 08:02:49 +0000 +Subject: Re: [bitcoin-dev] Exploring: limiting transaction output amount as + a function of total input value +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: Mon, 02 Aug 2021 04:41:09 -0000 + +--0000000000004cdb6c05c88c2dc3 +Content-Type: text/plain; charset="UTF-8" + +Hey Zac, + +I think this could be a useful opcode. It kinda seems like UC1 and UC2 are +basically the same use case: using rate-limiting to reduce risk of theft or +mistake. I think this could be a helpful addition to a good wallet setup. + +I don't quite understand why you'd want to define a specific span of blocks +for the rate limit. Why not just specify the size of the window (in blocks) +to rate limit within, and the limit? + +You mentioned change addresses, however, with the parameters you defined, +there would be no way to connect together the change address with the +original address, meaning they would have completely separate rate limits, +which wouldn't work since the change output would ignore the previous rate +limit. I can think of the following options: + +A. You could always send change back to the *same* address. This is the +simplest option, and the only downside I can think of is exposing the +public key of an address. I'm not quite sure what the consensus is on the +dangers of exposing the public key. It theoretically reduces quantum +resistance a bit, but I think I read that some of taproot's mechanisms +expose the bare public key, so maybe consensus has changed about that in +recent years? + +B. Have some way to specify connected addresses in the output. This has the +edge case that one of the addresses wouldn't be able to specify all the +addresses that it should be connected with, because it would create a hash +loop (ie if you had address A and B that should be connected, you can +create address A and then specify that address B be connected to address A, +but address A cannot specify its connection to B because A was created +before B was created). You wouldn't want one address to be able to simply +define a connection to another address, because this would open up attack +vectors where people could encumber other people's addresses with rate +limits connected to theirs. You could define connections based on +signatures, which could be done without creating a hash loop, however it +would require exposing the public keys of other addresses when you do that, +at which point you might as well go with option A. + +C. You could specify that rate limits follow a certain output. Eg, if you +create a transaction with destination output 1 and change output 2, your +rate limiting opcode could specify that output 2 should inherit the rate +limit. These inherited rate limits could all be connected together +automatically. + +Another consideration is what to use for a receive-address. I would say the +simplest option here is to receive at an address that contains an existing +output already. If you allowed receiving at an address that contains no +coins, you'd have to specify at least one other address to connect it with. +This could work, but I don't see any advantage to it, since you don't gain +any privacy by creating a new address if you're going to immediately +programmatically tie it to the other addresses. + +One thing to consider is the cost of carrying around and checking these +rate limits. Ideally it should be a very small amount of data carried +around in the UTXO set, and be very cheap to verify when the opcode comes +up. I think it would make sense for such an opcode to only be able to track +rate-limits over short spans, like a month or less. Allowing the user to +specify an arbitrary window over which to track a rate-limit seems like +something that would probably open up a dos vector or other node resource +usage abuse attacks. It might be useful enough to simply rate limit over +each epoch (two weeks), but having a small set of options could also be +useful (eg 1 day, 1 week, or 1 month). + +In any case, I'd be interested in seeing you write a BIP for this. Of +course, don't take my word as community interest. I'm reasonably new to the +bitcoin dev community, so definitely don't jump the gun based on my +interest. + +On Sat, Jul 31, 2021 at 2:51 PM Zac Greenwood via bitcoin-dev < +bitcoin-dev@lists.linuxfoundation.org> wrote: + +> Hi list, +> +> I'd like to explore whether it is feasible to implement new scripting +> capabilities in Bitcoin that enable limiting the output amount of a +> transaction based on the total value of its inputs. In other words, to +> implement the ability to limit the maximum amount that can be sent from an +> address. +> +> Two use cases come to mind: +> +> UC1: enable a user to add additional protection their funds by +> rate-limiting the amount they are able to send during a certain period +> (measured in blocks). A typical use case might be a user that intends to +> hodl their bitcoin, but still wishes to occasionally send small amounts. +> This avoids an attacker from sweeping all their funds in a single +> transaction, allowing the user to become aware of the theft and intervene +> to prevent further theft. +> +> UC2: exchanges may wish to rate-limit addresses containing large amounts +> of bitcoin, adding warm- or hot-wallet functionality to a cold-storage +> address. This would enable an exchange to drastically reduce the number of +> times a cold wallet must be accessed with private keys that enable access +> to the full amount. +> +> In a typical setup, I'd envision using multisig such that the user has two +> sets of private keys to their encumbered address (with a "set" of keys +> meaning "one or more" keys). One set of private keys allows only for +> sending with rate-limiting restrictions in place, and a s second set of +> private keys allowing for sending any amount without rate-limiting, +> effectively overriding such restriction. +> +> The parameters that define in what way an output is rate-limited might be +> defined as follows: +> +> Param 1: a block height "h0" indicating the first block height of an epoch; +> Param 2: a block height "h1" indicating the last block height of an epoch; +> Param 3: an amount "a" in satoshi indicating the maximum amount that is +> allowed to be sent in any epoch; +> Param 4: an amount "a_remaining" (in satoshi) indicating the maximum +> amount that is allowed to be sent within the current epoch. +> +> For example, consider an input containing 100m sats (1 BTC) which has been +> rate-limited with parameters (h0, h1, a, a_remaning) of (800000, 800143, +> 500k, 500k). These parameters define that the address is rate-limited to +> sending a maximum of 500k sats in the current epoch that starts at block +> height 800000 and ends at height 800143 (or about one day ignoring block +> time variance) and that the full amount of 500k is still sendable. These +> rate-limiting parameters ensure that it takes at minimum 100m / 500k = 200 +> transactions and 200 x 144 blocks or about 200 days to spend the full 100m +> sats. As noted earlier, in a typical setup a user should retain the option +> to transact the entire amount using a second (set of) private key(s). +> +> For rate-limiting to work, any change output created by a transaction from +> a rate-limited address must itself be rate-limited as well. For instance, +> expanding on the above example, assume that the user spends 200k sats from +> a rate-limited address a1 containing 100m sats: +> +> Start situation: +> At block height 800000: rate-limited address a1 is created; +> Value of a1: 100.0m sats; +> Rate limiting params of a1: h0=800000, h1=800143, a=500k, a_remaining=500k; +> +> Transaction t1: +> Included at block height 800100; +> Spend: 200k + fee; +> Rate limiting params: h0=800000, h1=800143, a=500k, a_remaining=300k. +> +> Result: +> Value at destination address: 200k sats; +> Rate limiting params at destination address: none; +> Value at change address a2: 99.8m sats; +> Rate limiting params at change address a2: h0=800000, h1=800143, a=500k, +> a_remaining=300k. +> +> In order to properly enforce rate limiting, the change address must be +> rate-limited such that the original rate limit of 500k sats per 144 blocks +> cannot be exceeded. In this example, the change address a2 were given the +> same rate limiting parameters as the transaction that served as its input. +> As a result, from block 800100 up until and including block 800143, a +> maximum amount of 300k sats is allowed to be spent from the change address. +> +> Example continued: +> a2: 99.8 sats at height 800100; +> Rate-limit params: h0=800000, h1=800143, a=500k, a_remaining=300k; +> +> Transaction t2: +> Included at block height 800200 +> Spend: 400k + fees. +> Rate-limiting params: h0=800144, h1=800287, a=500k, a_remaining=100k. +> +> Result: +> Value at destination address: 400k sats; +> Rate limiting params at destination address: none; +> Value at change address a3: 99.4m sats; +> Rate limiting params at change address a3: h0=800144, h1=800287, a=500k, +> a_remaining=100k. +> +> Transaction t2 is allowed because it falls within the next epoch (running +> from 800144 to 800287) so a spend of 400k does not violate the constraint +> of 500k per epoch. +> +> As could be seen, the rate limiting parameters are part of the transaction +> and chosen by the user (or their wallet). This means that the parameters +> must be validated to ensure that they do not violate the intended +> constraints. +> +> For instance, this transaction should not be allowed: +> a2: 99.8 sats at height 800100; +> Rate-limit params of a2: h0=800000, h1=800143, a=500k, a_remaining=300k; +> +> Transaction t2a: +> Included at block height 800200; +> Spend: 400k + fees; +> Rate-limit params: h0=800124, h1=800267, a=500k, a_remaining=100k. +> +> This transaction t2a attempts to shift the epoch forward by 20 blocks such +> that it starts at 800124 instead of 800144. Shifting the epoch forward like +> this must not be allowed because it enables spending more that the rate +> limit allows, which is 500k in any epoch of 144 blocks. It would enable +> overspending: +> +> t1: spend 200k at 800100 (epoch 1: total: 200k); +> t2a: spend 400k at 800200 (epoch 2: total: 400k); +> t3a: spend 100k at 800201 (epoch 2: total: 500k); +> t4a: spend 500k at 800268 (epoch 2: total: 1000k, overspending for epoch +> 2). +> +> Specifying the rate-limiting parameters explicitly at every transaction +> allows the user to tighten the spending limit by setting tighter limits or +> for instance by setting a_remainder to 0 if they wish to enforce not +> spending more during an epoch. +> +> I will stop here because I would like to gauge interest in this idea first +> before continuing work on other aspects. Two main pieces of work jump to +> mind: +> +> Define all validations; +> Describe aggregate behaviour of multiple (rate-limited) inputs, proof that +> two rate-limited addresses cannot spend more than the sum of their +> individual limits. +> +> Zac +> +> +> +> +> +> +> _______________________________________________ +> bitcoin-dev mailing list +> bitcoin-dev@lists.linuxfoundation.org +> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev +> + +--0000000000004cdb6c05c88c2dc3 +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +<div dir=3D"ltr"><div>Hey Zac,</div><div><br></div><div>I think this could = +be a useful opcode. It kinda seems like UC1 and UC2 are basically=C2=A0the = +same use case: using rate-limiting to reduce risk of theft or mistake. I th= +ink this could be a helpful addition to a good wallet setup.=C2=A0</div><di= +v><br></div>I don't quite understand why you'd want to define a spe= +cific span of blocks for the rate limit. Why not just specify the size of t= +he window (in blocks) to rate limit within, and the limit?=C2=A0<div><br></= +div><div>You mentioned change addresses, however, with the parameters you d= +efined, there would be no way to connect together the change address with t= +he original address, meaning they would have completely separate rate limit= +s, which wouldn't work since the change output would ignore the previou= +s rate limit. I can think of the following options:=C2=A0</div><div><br></d= +iv><div>A. You could always send change back to the *same* address. This is= + the simplest option, and the only downside I can think of is exposing the = +public key of an address. I'm not quite sure what the consensus is on t= +he dangers of exposing the public key. It theoretically reduces quantum res= +istance a bit, but I think I read that some of taproot's mechanisms exp= +ose the bare public key, so maybe consensus has changed about that in recen= +t years?</div><div><br></div><div>B. Have some way to specify connected add= +resses in the output. This has the edge case that one of the addresses woul= +dn't be able to specify all the addresses that it should be connected w= +ith, because it would create a hash loop (ie if you had address A and B tha= +t should be connected, you can create address A and then specify that addre= +ss B be connected to address A, but address A cannot specify its connection= + to B because A was created before B was created). You wouldn't want on= +e address to be able to simply define a connection to another address, beca= +use this would open up attack vectors where people could encumber other peo= +ple's addresses with rate limits connected to theirs. You could define = +connections based on signatures, which could be done without creating a has= +h loop, however it would require exposing the public keys of other addresse= +s when you do that, at which point you might as well go with option A.=C2= +=A0</div><div><br></div><div>C. You could specify that rate limits follow a= + certain output. Eg, if you create a transaction with destination output 1 = +and change output 2, your rate limiting opcode could specify that output 2 = +should inherit the rate limit. These inherited rate limits could all be con= +nected together automatically.=C2=A0</div><div><br></div><div>Another consi= +deration is what to use for a receive-address. I would say the simplest opt= +ion here is to receive at an address that contains an existing output alrea= +dy. If you allowed receiving at an address that contains no coins, you'= +d have to specify at least one other address to connect it with. This could= + work, but I don't see any advantage to it, since you don't gain an= +y privacy by creating a new address if you're going to immediately prog= +rammatically tie it to the other addresses.</div><div><br></div><div>One th= +ing to consider is the cost of carrying around and checking these rate limi= +ts. Ideally it should be a very small amount of data carried around in the = +UTXO set, and be very cheap to verify when the opcode comes up. I think it = +would make sense for such an opcode to only be able to track rate-limits ov= +er short spans, like a month or less. Allowing the user to specify an arbit= +rary window over which to track a rate-limit seems like something that woul= +d probably open up a dos vector or other node resource usage abuse attacks.= + It might be useful enough to simply rate limit over each epoch (two weeks)= +, but having a small set of options could also be useful (eg 1 day, 1 week,= + or 1 month).=C2=A0</div><div><br></div><div>In any case, I'd be intere= +sted in seeing you write a BIP for this. Of course, don't take my word = +as community interest. I'm reasonably new to the bitcoin dev community,= + so definitely don't jump the gun based on my interest.=C2=A0</div></di= +v><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On S= +at, Jul 31, 2021 at 2:51 PM Zac Greenwood via bitcoin-dev <<a href=3D"ma= +ilto:bitcoin-dev@lists.linuxfoundation.org" target=3D"_blank">bitcoin-dev@l= +ists.linuxfoundation.org</a>> wrote:<br></div><blockquote class=3D"gmail= +_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204= +,204);padding-left:1ex"><div dir=3D"ltr"><div>Hi list,</div><div><br></div>= +<div>I'd like to explore whether it is feasible to implement new script= +ing capabilities in Bitcoin that enable limiting the output amount of a tra= +nsaction based on the total value of its inputs. In other words, to impleme= +nt the ability to limit the maximum amount that can be sent from an address= +.</div><div><br></div><div>Two use cases come to mind:</div><div><br></div>= +<div>UC1: enable a user to add additional protection their funds by rate-li= +miting the amount they are able to send during a certain period (measured i= +n blocks). A typical use case might be a user that intends to hodl their bi= +tcoin, but still wishes to occasionally send small amounts. This avoids an = +attacker from sweeping all their funds in a single transaction, allowing th= +e user to become aware of the theft and intervene to prevent further theft.= +</div><div><br></div><div>UC2: exchanges may wish to rate-limit addresses c= +ontaining large amounts of bitcoin, adding warm- or hot-wallet functionalit= +y to a cold-storage address. This would enable an exchange to drastically r= +educe the number of times a cold wallet must be accessed with private keys = +that enable access to the full amount.</div><div><br></div><div>In a typica= +l setup, I'd envision using multisig such that the user has two sets of= + private keys to their encumbered address (with a "set" of keys m= +eaning "one or more" keys). One set of private keys allows only f= +or sending with rate-limiting restrictions in place, and a s second set of = +private keys allowing for sending any amount without rate-limiting, effecti= +vely overriding such restriction.</div><div><br></div><div>The parameters t= +hat define in what way an output is rate-limited might be defined as follow= +s:</div><div><br></div><div>Param 1: a block height "h0" indicati= +ng the first block height of an epoch;</div><div><div>Param 2: a block heig= +ht "h1" indicating the last block height of an epoch;</div><div>P= +aram 3: an amount "a" in satoshi indicating the maximum amount th= +at is allowed to be sent in any epoch;<br></div><div>Param 4: an amount &qu= +ot;a_remaining" (in satoshi) indicating the maximum amount that is all= +owed to be sent within the current epoch.</div></div><div><br></div><div>Fo= +r example, consider an input containing 100m sats (1 BTC) which has been ra= +te-limited with parameters (h0, h1, a, a_remaning) of (800000, 800143, 500k= +, 500k). These parameters define that the address is rate-limited to sendin= +g a maximum of 500k sats in the current epoch that starts at block height 8= +00000 and ends at height 800143 (or about one day ignoring block time varia= +nce) and that the full amount of 500k is still sendable. These rate-limitin= +g parameters ensure that it takes at minimum 100m / 500k =3D 200 transactio= +ns and 200 x 144 blocks or about 200 days to spend the full 100m sats. As n= +oted earlier, in a typical setup a user should retain the option to transac= +t the entire amount using a second (set of) private key(s).</div><div><br><= +/div><div>For rate-limiting to work, any change output created by a transac= +tion from a rate-limited address must itself be rate-limited as well. For i= +nstance, expanding on the above example, assume that the user spends 200k s= +ats from a rate-limited address a1 containing 100m sats:</div><div><br></di= +v><div>Start situation:</div><div>At block height 800000: rate-limited addr= +ess a1 is created;</div><div>Value of a1: 100.0m sats;</div><div>Rate limit= +ing params of a1: h0=3D800000, h1=3D800143, a=3D500k, a_remaining=3D500k;</= +div><div><br></div><div>Transaction t1:</div><div>Included at block height = +800100;</div><div>Spend: 200k + fee;</div><div>Rate limiting params: h0=3D8= +00000, h1=3D800143, a=3D500k, a_remaining=3D300k.</div><div><br></div><div>= +Result:</div><div>Value at destination address: 200k sats;</div><div>Rate l= +imiting params at destination address: none;</div><div>Value at change addr= +ess a2: 99.8m sats;</div><div>Rate limiting params at change address a2: h0= +=3D800000, h1=3D800143, a=3D500k, a_remaining=3D300k.</div><div><br></div><= +div>In order to properly enforce rate limiting, the change address must be = +rate-limited such that the original rate limit of 500k sats per 144 blocks = +cannot be exceeded. In this example, the change address a2 were given the s= +ame rate limiting parameters as the transaction that served as its input. A= +s a result, from block 800100 up until and including block 800143, a maximu= +m amount of 300k sats is allowed to be spent from the change address.</div>= +<div><br></div><div>Example continued:</div><div>a2: 99.8 sats at height=C2= +=A0800100;</div><div>Rate-limit params: h0=3D800000, h1=3D800143, a=3D500k,= + a_remaining=3D300k;</div><div><br></div><div>Transaction t2:</div><div>Inc= +luded at block height 800200</div><div>Spend: 400k=C2=A0+ fees.</div><div>R= +ate-limiting params: h0=3D800144, h1=3D800287, a=3D500k, a_remaining=3D100k= +.<br></div><div><br></div><div><div>Result:</div><div>Value at destination = +address: 400k sats;</div><div>Rate limiting params at destination address: = +none;</div><div>Value at change address a3: 99.4m sats;</div><div>Rate limi= +ting params at change address a3: h0=3D800144, h1=3D800287, a=3D500k, a_rem= +aining=3D100k.</div><div><br></div><div>Transaction t2 is allowed because i= +t falls within the next epoch (running from 800144 to 800287) so a spend of= + 400k does not violate the constraint of 500k per epoch.</div><div><br></di= +v><div>As could be seen, the rate limiting parameters are part of the trans= +action and chosen by the user (or their wallet). This means that the parame= +ters must be validated to ensure that they do not violate the intended cons= +traints.</div><div><br></div><div>For instance, this transaction should not= + be allowed:</div><div><div>a2: 99.8 sats at height=C2=A0800100;</div><div>= +Rate-limit params of a2: h0=3D800000, h1=3D800143, a=3D500k, a_remaining=3D= +300k;</div><div><br></div><div>Transaction t2a:</div><div>Included at block= + height 800200;</div><div>Spend: 400k=C2=A0+ fees;</div><div><div>Rate-limi= +t params: h0=3D800124, h1=3D800267, a=3D500k, a_remaining=3D100k.</div><div= +><br></div></div><div>This transaction t2a attempts to shift the epoch forw= +ard by 20 blocks such that it starts at 800124 instead of 800144. Shifting = +the epoch forward like this must not be allowed because it enables spending= + more that the rate limit allows, which is 500k in any epoch of 144 blocks.= + It would enable overspending:</div></div><div><br></div><div>t1: spend 200= +k at 800100 (epoch 1: total: 200k);</div><div>t2a: spend 400k at 800200 (ep= +och 2: total: 400k);</div><div>t3a: spend 100k at 800201 (epoch 2: total: 5= +00k);</div><div>t4a: spend 500k at 800268 (epoch 2: total: 1000k, overspend= +ing for epoch 2).</div><div><br></div><div>Specifying the rate-limiting par= +ameters explicitly at every transaction allows the user to tighten the spen= +ding limit by setting tighter limits or for instance by setting a_remainder= + to 0 if they wish to enforce not spending more during an epoch.</div><div>= +<br></div><div>I will stop here because I would like to gauge interest in t= +his idea first before continuing work on other aspects. Two main pieces of = +work jump to mind:</div><div><br></div><div>Define all validations;</div><d= +iv>Describe aggregate behaviour of multiple (rate-limited) inputs, proof th= +at two rate-limited addresses cannot spend more than the sum of their indiv= +idual limits.</div><div><br></div><div>Zac</div><div><br></div><div><br></d= +iv><div><br></div><div><br></div><div><br></div><div><br></div></div></div> +_______________________________________________<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> + +--0000000000004cdb6c05c88c2dc3-- + |