Subject: Re: [bitcoin-dev] Exploring alternative activation mechanisms: decreasing threshold

From: Luke Dashjr <[email-masked]>
Date: Sat, 27 Feb 2021 17:55:00 +0000

This has the same problems BIP149 did: since there is no signalling, it is 
ambiguous whether the softfork has activated at all. Both anti-SF and pro-SF 
nodes will remain on the same chain, with conflicting perceptions of the 
rules, and resolution (if ever) will be chaotic. Absent resolution, however, 
there is a strong incentive not to rely on the rules, and thus it may never 
get used, and therefore also never resolved.

Additionally, it loses the flexibility of BIP 8 to, after the initial 
deployment, move the timeoutheight sooner.

Luke

On Thursday 25 February 2021 22:33:25 Gregorio Guidi via bitcoin-dev wrote:
> Hello,
>
> I followed the debate on LOT=false / LOT=true trying to get a grasp of
> the balance of risks and advantages. The summary by Aaron van Wirdum [1]
> explains well the difficulties to find a good equilibrium... it
> concludes that "perhaps, a new possibility will present itself".
>
> Thinking about such a "new possibility" that overcomes the
> LOT=true/false dichotomy, I would like to offer the following proposal.
> It could be called "decreasing threshold activation".
>
> Decreasing threshold activation works similarly to BIP8, with the
> difference that the threshold that triggers the STARTED -> LOCKED_IN
> transition starts at 100% for the first retargeting period, and then is
> gradually reduced on each period in steps of 24 blocks (~1,2%). More
> precisely:
>
> On the 1st period (starting on start_height): if 2016 out of 2016 blocks
> signal, the state is changed to LOCKED_IN on the next period (otherwise
> stays STARTED)
> On the 2nd period: if 1992 out of 2016 blocks signal (~98.8%), the state
> transitions to LOCKED_IN on the next period
> On the 3rd period: if 1968 out of 2016 blocks signal (~97.6%), the state
> transitions to LOCKED_IN on the next period
> ...
> On the 14th period (~6 months): if 1704 out of 2016 blocks signal
> (~84.5%), the state transitions to LOCKED_IN on the next period
> ...
> On the 27th period (~12 months): if 1392 out of 2016 blocks signal
> (~69.0%), the state transitions to LOCKED_IN on the next period
> ...
> On the 40th period (~18 months): if 1080 out of 2016 blocks signal
> (~53.6%), the state transitions to LOCKED_IN on the next period
> ...
> On the 53th period (~24 months): if 768 out of 2016 blocks signal
> (~38.1%), the state transitions to LOCKED_IN on the next period
> ...
> On the 66th period (~30 months): if 456 out of 2016 blocks signal
> (~22.6%), the state transitions to LOCKED_IN on the next period
> ...
> On the 79th period (~36 months): if 144 out of 2016 blocks signal
> (~7.1%), the state transitions to LOCKED_IN on the next period
> ...
> On the 84th and final period (~39 months): if 24 out of 2016 blocks
> signal (~1.2%), the state transitions to LOCKED_IN on the next period,
> otherwise goes to FAILED
>
> (For reference, I include below a snippet of pseudocode for the
> decreasing thresholds in the style of BIP8 and BIP9.)
>
> Here are the main features and advantages of this approach:
>
> 1. It is relatively conservative at the beginning: for activation to
> happen in the first year, it requires a clear majority of signaling
> hashrate, indicating that the activation is relatively safe. Only later
> the threshold starts to move towards "unsafe" territory, accepting the
> tradeoff of less support from existing hashrate in exchange for ensuring
> that the activation eventually happens.
>
> 2. Like LOT=true, the activation will always occur in the end (except in
> the negligible case where less than 1.2% of hashrate supports it).
>
> 3. This approach is quite easy to implement, in particular it avoids the
> extra code to deal with the MUST_SIGNAL period.
>
> 4. There are no parameters to set (except startheight). I am a KISS fan,
> so this is a plus for me, making the activation mechanism robust and
> predictable with less chance for users to shoot themselves in the foot.
> It is also a plus for me that - if adopted as the default mechanism - it
> would require very little discussion on how to activate future
> soft-forks. In fact I think it would be a winning move for Core to
> commit to such a scheme, to avoid getting lost in game-theoretic rabbit
> holes.
>
> 5. Since there is no MUST_SIGNAL period, no automatic chain split occurs
> around activation when not all miners have upgraded (so activation is
> generally as benign as a MASF). A chain split will occur only when/if an
> invalid block is created (and this requires dedicated effort! it can
> only happen by circumventing the normal policy rules [2]). This
> mitigates the risk of reorgs and involuntary forks around activation,
> even with low miner signaling.
>
> 6. It removes motivation to create UASF clients that force activation.
> While individual nodes could still try to force a quicker activation,
> the motivation to do so is reduced since the same result is obtained
> just by waiting a little more.
>
> 7. Compared to LOT=true, activation is cleaner and quicker when it is
> relatively safe to do so (when the signaling hashrate is - let's say -
> in the 70%-80% range). On the other hand, activation is pushed further
> and further in time when it is less safe (when signaling hashrate is
> <50%, meaning that there is a serious risk that users/miners that did
> not upgrade start following an alternative chain). This gives everyone
> time to prepare properly for such a potentially disruptive event.
>
> 8. If a significant number of users and miners consciously decide (for
> whatever reasons) that they don't want to upgrade and want to fork
> themselves off from the chain followed by Core (as is their
> prerogative), they will have time to do so safely.
>
> 9. Compared to the strategy of doing LOT=false and then LOT=true if it
> fails, using the decreasing threshold approach may not seem very
> different. But it completely removes the need to fiddle with different
> client releases and with the issues associated with deployed nodes with
> different consensus parameters.
>
> All in all, reading the various perspectives on this mailing list and
> outside I have the feeling that the strongest arguments against LOT=true
> have at their core a certain uneasiness with the MUST_SIGNAL mechanism
> and the related automatic chain split on activation, which is something
> that greatly complicates the analysis (but please tell me if I am
> wrong...). In this sense, this proposal achieves the big objective of
> always ending in activation (like LOT=true) without resorting to
> MUST_SIGNAL and chain splits.
>
> A final note: this proposal should be seen as somewhat independent from
> the discussion on taproot activation. Personally I would be happy with a
> LOT=false activation for taproot that succeeds quickly, while the
> decreasing threshold approach could be evaluated as potential default
> activation mechanism for the future.
>
> I would be happy to hear what you think about this. What are the
> possible issues/drawbacks of using this mechanism?
>
> Thanks,
>
> Gregorio
>
> [1]
> https://bitcoinmagazine.com/articles/lottrue-or-lotfalse-this-is-the-last-h
>urdle-before-taproot-activation
>
> [2] This was not the case in the past for upgrades such as BIP16 (P2SH),
> which generated frequent reorgs due to a combination of low activation
> threshold (55%) and no policy protection. But for upgrades such as
> taproot the normal policy rules prevent the creation of invalid blocks
> by non-upgraded miners. See
> https://blog.bitmex.com/the-arts-of-making-softforks-protection-by-policy-r
>ule/
>
> Pseudocode:
>
>          case STARTED:
>              int elapsed_periods = (block.height - startheight) / 2016;
>              if (elapsed_periods > 2016 / 24) {
>                  return FAILED;
>              }
>              int threshold = 2016 - 24 * (elapsed_periods - 1);
>              int count = 0;
>              walk = block;
>              for (i = 0; i < 2016; i++) {
>                  walk = walk.parent;
>                  if (walk.nVersion & 0xE0000000 == 0x20000000 &&
> (walk.nVersion >> bit) & 1 == 1) { ++count;
>                  }
>              }
>              if (count >= threshold) {
>                  return LOCKED_IN;
>              }
>              return STARTED;
>
> _______________________________________________
> bitcoin-dev mailing list
> [email-masked]
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev