You've already forked specification
Added missing hard forks and ASERT documentation.
This commit is contained in:
@@ -31,7 +31,18 @@
|
||||
[Bitcoin Keys (Public/Private)](/protocol/blockchain/cryptography/keys) — [Signatures (ECDSA/Schnorr)](/protocol/blockchain/cryptography/signatures) — [Multisignature (M-of-N multisig)](/protocol/blockchain/cryptography/multisignature)
|
||||
|
||||
### Network upgrades
|
||||
[Bip-16](/protocol/forks/bip-0016) — [Bip-34](/protocol/forks/bip-0034) — [Bip-37](/protocol/forks/bip-0037) — [Bip-65](/protocol/forks/bip-0065) — [Bip-66](/protocol/forks/bip-0066) — [Bip-68](/protocol/forks/bip-0068) — [Bip-112](/protocol/forks/bip-0112) — [Bip-113](/protocol/forks/bip-0113) — [Bip-133](/protocol/forks/bip-0133) — [Bip-157](/protocol/forks/bip-0157) — [Bip-158](/protocol/forks/bip-0158) — [Bip-159](/protocol/forks/bip-0159) — [BCH-UAHF (BUIP-55)](/protocol/forks/bch-uahf) — [HF-20171113](/protocol/forks/hf-20171113) — [HF-20180515](/protocol/forks/hf-20180515) — [HF-20181115](/protocol/forks/hf-20181115) — [HF-20190515](/protocol/forks/hf-20190515) — [HF-20191115](/protocol/forks/hf-20191115)
|
||||
|
||||
**Pre-BCH:** [Bip-9](/protocol/forks/bip-0009) — [Bip-16](/protocol/forks/bip-0016) — [Bip-34](/protocol/forks/bip-0034) — [Bip-37](/protocol/forks/bip-0037) — [Bip-65](/protocol/forks/bip-0065) — [Bip-66](/protocol/forks/bip-0066) — [Bip-68](/protocol/forks/bip-0068) — [Bip-112](/protocol/forks/bip-0112) — [Bip-113](/protocol/forks/bip-0113) — [Bip-133](/protocol/forks/bip-0133) — [Bip-157](/protocol/forks/bip-0157) — [Bip-158](/protocol/forks/bip-0158) — [Bip-159](/protocol/forks/bip-0159)
|
||||
|
||||
**2017:** [BCH-UAHF (BUIP-55)](/protocol/forks/bch-uahf) — [HF-20171113](/protocol/forks/hf-20171113)
|
||||
|
||||
**2018:** [HF-20180515](/protocol/forks/hf-20180515) — [HF-20181115](/protocol/forks/hf-20181115)
|
||||
|
||||
**2019:** [HF-20190515](/protocol/forks/hf-20190515) — [HF-20191115](/protocol/forks/hf-20191115)
|
||||
|
||||
**2020:** [HF-20200515](/protocol/forks/hf-20200515) — [HF-20201115](/protocol/forks/hf-20201115)
|
||||
|
||||
**2021:** [HF-20210515](/protocol/forks/hf-20210515)
|
||||
|
||||
### Network protocol
|
||||
|
||||
|
||||
@@ -1,22 +1,83 @@
|
||||
# Difficulty Adjustment Algorithm
|
||||
|
||||
In order to correct for changes in the Bitcoin Cash network's total hashing power (i.e. as hardware improves or nodes are added to or removed from the network), the amount of work required to mine a block must change in tandem.
|
||||
Bitcoin Cash solves this by adjusting the difficulty according to an algorithm that looks at recent block timestamps, infers the hashing power that led to those timestamps, and adjusts the difficulty for future blocks accordingly.
|
||||
Bitcoin Cash solves this by adjusting the [target](/protocol/blockchain/proof-of-work#target) according to an algorithm that looks at recent block timestamps, infers the hashing power that led to those timestamps, and attempts to change the [difficulty](/protocol/blockchain/proof-of-work#difficulty) of mining future blocks accordingly.
|
||||
The calculation used is referred to as the Difficulty Adjustment Algorithm, or DAA, and has changed a number of times.
|
||||
In order to validate the blockchain, however, the difficulty must be verified using the DAA that was in use when that block was mined.
|
||||
Consequently, the historical DAAs remain relevant to node implementation that wish to validate historical headers.
|
||||
|
||||
The current Bitcoin Cash difficulty adjustment algorithm attempts to ensure that the difficulty of new blocks is always closely tied to recent block difficulties.
|
||||
The algorithms used, from newest to oldest, are:
|
||||
|
||||
- [ASERT](#asert)
|
||||
- [CW-144](#cw-144)
|
||||
- [Emergency DAA](#emergency-daa)
|
||||
- [Legacy DAA](#legacy-daa)
|
||||
|
||||
## ASERT
|
||||
|
||||
Absolutely Scheduled Exponentially Rising Targets (ASERT), more specifically [aserti3-2d](/protocol/forks/2020-11-15-asert), was implemented as a part of [HF-20201115](/protocol/forks/hf-20201115).
|
||||
It uses an [exponential moving average](https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average) approach that should theoretically always target a correction toward a 10 minute average block time.
|
||||
ASERT bases it's calculations on the following components:
|
||||
|
||||
1. The **fork block**: The first block mined with the ASERT DAA
|
||||
2. The **anchor block**: The parent of the fork block
|
||||
3. The current head block
|
||||
|
||||
Though this is not used directly in practice, the exponential form of the calculation of the target for the next block is:
|
||||
|
||||
```
|
||||
exponent = (time_delta - ideal_block_time * (height_delta + 1)) / halflife
|
||||
next_target = anchor_target * 2**(exponent)
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
- `anchor_target` is the unsigned 256 bit integer equivalent of the `nBits` value in
|
||||
the header of the anchor block.
|
||||
- `time_delta` is the difference, in signed integer seconds, between the
|
||||
timestamp in the header of the current block and the timestamp in the
|
||||
parent of the anchor block.
|
||||
- `ideal_block_time` is a constant: 600 seconds, the targeted
|
||||
average time between blocks.
|
||||
- `height_delta` is the difference in block height between the current
|
||||
block and the anchor block.
|
||||
- `halflife` is a constant parameter sometimes referred to as
|
||||
'tau', with a value of 172800 (seconds) on mainnet.
|
||||
- `next_target` is the integer value of the target computed for the block
|
||||
after the current block.
|
||||
|
||||
In order to avoid subtle platform-dependent floating point issues, however, ASERT is instead calculated using fixed-point integer arithmetic with a cubic polynomial approximation of the exponential.
|
||||
See [ASERT:target computeration](/protocol/forks/2020-11-15-asert#target-computation) for the Python reference implementation and additional details on where new implementations of the algorithm must be cautious to ensure full compatibility.
|
||||
|
||||
## CW-144
|
||||
|
||||
CW-144 attempts to ensure that the difficulty of new blocks is always closely tied to the amount of work done on recent blocks.
|
||||
The name referes to the fact that it evaluates the difference in [chainwork](/protocol/blockchain/proof-of-work#chainwork) (CW) across the most recent 144 blocks.
|
||||
Put into place as a part of [HF-20171113](/protocol/forks/hf-20171113), it performs the following calculation to determine the difficulty of a block, <code>B<sub>n+1</sub></code>, with block height `n+1`:
|
||||
|
||||
- Select <code>B<sub>new</sub></code>: The block with the median timestamp of the blocks <code>B<sub>n</sub></code>, <code>B<sub>n-1</sub></code>, and <code>B<sub>n-2</sub></code>
|
||||
- Select <code>B<sub>old</sub></code>: The block with the median timestamp of the blocks <code>B<sub>n-144</sub></code>, <code>B<sub>n-145</sub></code>, and <code>B<sub>n-146</sub></code>.
|
||||
- Calculate `t`, the difference between the timestamps of <code>B<sub>new</sub></code> and <code>B<sub>old</sub></code>. If this difference is less than `72 * 600`, use `72 * 600`, if it is above `288 * 600`, use `288 * 600`.
|
||||
- Calculate `W`, the difference in [chainwork](/protocol/blockchain/proof-of-work#chainwork) between <code>B<sub>new</sub></code> and <code>B<sub>old</sub></code>.
|
||||
- Calculate `W`, the difference in chainwork between <code>B<sub>new</sub></code> and <code>B<sub>old</sub></code>.
|
||||
- Calculate `PW`, the projected work for the next block, as `(W * 600) / t`.
|
||||
- Calculate `T`, the target difficulty, as <code>(2<sup>256</sup> - PW) / PW</code>. In 256-bit two's-complement arithmetic, this is equivalent to `(-PW) / PW`.
|
||||
- If `T` is greater than the maximum target of `0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF`, use the maximum target. Otherwise, use `T`.
|
||||
|
||||
In other words, for any given block the projected work is be equal to the difference in chainwork multiplied by an adjustment. The adjustment is 600 seconds (the goal timeframe for a block to be mined) divided by the difference in timestamps between the median block (by timestamp) of its prior three immediate ancestors and its 144th, 145th, and 146th ancestors (bounded by `72 * 600` and `288 * 600`). The projected work is then converted into the target by subtracting it from 2<sup>256</sup> and then dividing the result by the projected work. Then minimum of that calculated value and the maximum target is then used as the target for that block.
|
||||
|
||||
## Legacy Difficulty Adjustment Algorithm
|
||||
## Emergency DAA
|
||||
|
||||
As a part of [BCH-UAHF](/protocol/forks/bch-uahf), due to the anticipated decrease in hashing power, the following adjustment to the legacy difficulty adjustment algorithm above was put into place:
|
||||
|
||||
>In case the MTP of the tip of the chain is 12h or more after the MTP 6 block before the tip, the proof of work target is increased by a quarter, or 25%, which corresponds to a difficulty reduction of 20% .
|
||||
>
|
||||
> RATIONALE: The hashrate supporting the chain is dependent on market price and hard to predict. In order to make sure the chain remains viable no matter what difficulty needs to adjust down in case of abrupt hashrate drop.
|
||||
|
||||
That is, if the block height is not divisible by 2016, the target may still be adjusted if the current MTP is more than 12 hours after the MTP from 6 blocks prior. In this case, the target is multiplied by 1.25.
|
||||
|
||||
This algorithm was superseded by the current difficulty adjustment algorithm as a part of HF-20171113.
|
||||
|
||||
## Legacy DAA
|
||||
|
||||
Prior to [BCH-UAHF](/protocol/forks/bch-uahf), the original Bitcoin difficulty adjustment algorithm was used.
|
||||
To determine the difficulty of a block, <code>B<sub>n+1</sub></code>, with block height `n+1`:
|
||||
@@ -30,15 +91,3 @@ To determine the difficulty of a block, <code>B<sub>n+1</sub></code>, with block
|
||||
- If `T` is greater than the maximum target of `0x00000000FFFF0000000000000000000000000000000000000000000000000000`, use the maximum target instead. Otherwise, use `T`.
|
||||
|
||||
This boils down to a possible change in difficulty every 2016 blocks, where the new target (for the next 2016 blocks) is calculated by dividing the time taken for the last 2015 blocks by the time expectation for 2016 blocks (bounded by 0.25 and 4) and multiplying that ratio by the existing target.
|
||||
|
||||
## Emergency Difficulty Adjustment Algorithm
|
||||
|
||||
As a part of BCH-UAHF, due to the anticipated decrease in hashing power, the following adjustment to the legacy difficulty adjustment algorithm above was put into place:
|
||||
|
||||
>In case the MTP of the tip of the chain is 12h or more after the MTP 6 block before the tip, the proof of work target is increased by a quarter, or 25%, which corresponds to a difficulty reduction of 20% .
|
||||
>
|
||||
> RATIONALE: The hashrate supporting the chain is dependent on market price and hard to predict. In order to make sure the chain remains viable no matter what difficulty needs to adjust down in case of abrupt hashrate drop.
|
||||
|
||||
That is, if the block height is not divisible by 2016, the target may still be adjusted if the current MTP is more than 12 hours after the MTP from 6 blocks prior. In this case, the target is multiplied by 1.25.
|
||||
|
||||
This algorithm was superseded by the current difficulty adjustment algorithm as a part of HF-20171113.
|
||||
@@ -0,0 +1,44 @@
|
||||
# 2020-05-15 IFP
|
||||
|
||||
layout: specification
|
||||
title: Infrastructure Funding Plan Specification
|
||||
category: spec
|
||||
date: 2020-04-10
|
||||
activation: 1589544000
|
||||
version: 0.1
|
||||
author: Antony Zegers
|
||||
|
||||
## Infrastructure Funding Plan
|
||||
|
||||
The purpose of the Infrastructure Funding Plan (IFP) is to provide funding to development projects working on common Bitcoin Cash infrastructure. If activated, it enforces that 5% of the block reward is spent to one of a set of specified addresses.
|
||||
|
||||
## IFP Destination Addresses
|
||||
|
||||
The IFP contains four destination addresses, each associated with a separate BIP 9 activation `bit` as follows:
|
||||
|
||||
| Name | Destination Address | BIP 9 `bit` |
|
||||
| ---------------------------- | ------------------------------------------ | ----------- |
|
||||
| MinerFundDestination | pqv2r67sgz3qumufap3h2uuj0zfmnzuv8vqhqfgddk | 0 |
|
||||
| MinerABCDestination | qzvz0es48sf8wrqy7kn5j5cugka95ztskcanc9laay | 1 |
|
||||
| MinerBCHDDestination | qrhea03074073ff3zv9whh0nggxc7k03ssh8jv9mkx | 2 |
|
||||
| MinerElectronCashDestination | pp8d685l8kecnmtyy52ndvq625arz2qwmu42qeeqek | 3 |
|
||||
|
||||
## Activation
|
||||
|
||||
Activation is triggered separately for each destination address via [BIP 9](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki), with the following parameters:
|
||||
* `activation threshold` is set to 1344 (which is ~66.6% of the 2016 block retarget periods)
|
||||
* `starttime` is set to 1573819200 (Nov 15, 2019 12:00:00 UTC)
|
||||
* `timeout` is set to 1589544000 (May 15, 2020 12:00:00 UTC ** note:** this is the same time as the May 15, 2020 upgrade activation)
|
||||
* `bit` is set according to the table above.
|
||||
|
||||
## Enforcement
|
||||
|
||||
If activated, the IFP enforcement begins once the 15th May 2020 upgrade is activated.
|
||||
|
||||
If one or more IFP destination addresses are activated, then the coinbase transaction in each block must contain an output sending 5% of the block reward to one of the activated addresses.
|
||||
|
||||
## References
|
||||
|
||||
[1] [BIP 9](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki)
|
||||
|
||||
[2] [Sample implementation](https://reviews.bitcoinabc.org/D5282)
|
||||
@@ -0,0 +1,161 @@
|
||||
# 2020-05-15 OP_REVERSEBYTES
|
||||
|
||||
layout: specification
|
||||
title: OP_REVERSEBYTES Specification
|
||||
category: spec
|
||||
date: 2019-05-29
|
||||
activation: 1589544000
|
||||
version: 0.2
|
||||
author: Tobias Ruck
|
||||
|
||||
## OP_REVERSEBYTES
|
||||
|
||||
OP_REVERSEBYTES reverses the bytes of the top stackitem.
|
||||
|
||||
### Rationale
|
||||
|
||||
Bitcoin's protocol almost exclusively uses little-endian encoding [[8]](#references), and Script provides various tools for using integers encoded in little endian, such as `OP_NUM2BIN` and `OP_BIN2NUM` [[11]](#references). Using covenants [[2]](#references), sophisticated smart contracts can be created, and Script already has a great arsenal of arithmetic operators (opcodes 139 to 165) to enforce e.g. how input and output amounts of transactions have to be related.
|
||||
|
||||
However, many protocols do not use little endian encoding, and it is by no means clear that one is superior to the other. Both AMQP [[12]](#references) and Apache Thrift [[13]](#references), for instance, use big-endian encoding. The Simple Ledger Protocol (SLP) uses big-endian encoding as well [[1]](#references). Bitdb, when using the `hN` elements, returns stack items in a format that can be directly interpreted as base16 big-endian encoded numbers, and to use this feature, it has to be possible to encode values as big-endian.
|
||||
|
||||
Further, now that oracles using OP_CHECKDATASIG are possible, likely used to retrieve numeric data, it would be unnecessarily limiting to assume all oracles will use little-endian encoding.
|
||||
|
||||
Among the mentioned protocols, SLP tokens are likely the most important ones. Various new use cases combining the power of covenants and looping transactions [[5]](#references) emerge, among them:
|
||||
|
||||
* Decentralized exchanges (such as SLP Agora or SLPDEX) [[3, 4, 6]](#references)
|
||||
* Donation mintable tokens
|
||||
* DAOs, which charge a fee for services and distribute revenue proportional to shares [[7]](#references)
|
||||
* Native tokens (not yet possible)
|
||||
|
||||
Note that values can be converted to big-endian encoding if the size of the encoding is both fixed and not too large. Currently, Script only supports 32-bit integers, and they can be encoded in big-endian using OP_SPLIT, OP_SWAP and OP_CAT:
|
||||
|
||||
```
|
||||
// initial: // <value>
|
||||
// convert to little-endian
|
||||
PUSH 4 // <value> 4
|
||||
OP_NUM2BIN // <value 4-byte little endian>
|
||||
|
||||
// split into individual bytes
|
||||
PUSH 1 // <value 4-byte little endian> 1
|
||||
OP_SPLIT // <value 1st byte> <value 2nd-4th byte>
|
||||
PUSH 1 // <value 1st byte> <value 2nd-4th byte> 1
|
||||
OP_SPLIT // <value 1st byte> <value 2nd byte> <value 3rd-4th byte>
|
||||
PUSH 1 // <value 1st byte> <value 2nd byte> <value 3rd-4th byte> 1
|
||||
OP_SPLIT // <value 1st byte> <value 2nd byte> <value 3rd byte> <value 4th byte>
|
||||
|
||||
// reverse individual bytes and concat
|
||||
// results in 4-byte big endian
|
||||
OP_SWAP // <value 1st byte> <value 2nd byte> <value 4th byte> <value 3rd byte>
|
||||
OP_CAT // <value 1st byte> <value 2nd byte> <value 4th, 3rd byte>
|
||||
OP_SWAP // <value 1st byte> <value 4th, 3rd byte> <value 2nd byte>
|
||||
OP_CAT // <value 1st byte> <value 4th, 3rd, 2nd byte>
|
||||
OP_SWAP // <value 4th, 3rd, 2nd byte> <value 1st byte>
|
||||
OP_CAT // <value 4-byte big endian>
|
||||
```
|
||||
|
||||
However, if with OP_REVERSEBYTES, this becomes trivial:
|
||||
|
||||
```
|
||||
// convert to bytes
|
||||
PUSH 4 // <SLP value> 4
|
||||
OP_NUM2BIN // <SLP value 4-byte little endian>
|
||||
OP_REVERSEBYTES // <SLP value 4-byte big endian>
|
||||
```
|
||||
|
||||
That's 11 bytes (9 operations and 3 pushdata) saved.
|
||||
|
||||
There are multiple reasons why the second version would be preferable:
|
||||
|
||||
* Covenants and looping scripts usually take the script code of the preimage [[9]](#references) as input, which means every operation counts twice: Once for the stack item containing the script code, and once for the P2SH script stack item [[10]](#references). For a conversion to 8-byte big-endian, this would save 32 bytes per conversion, and if there's, say, three of those conversions in a script, it would already amount to 96 bytes - a non-trivial number of bytes for a transaction.
|
||||
* The cognitive load of developing scripts using the larger snippet above is increased unnecessarily. Developing scripts, by hand or by using tools such as macros or Spedn, already puts a lot of cognitive load on developers, and errors can be devastating to the community. A prominent example of such a failure is the contentious hard-fork on the Ethereum blockchain that was caused by a bug in The DAO smart contract.
|
||||
* The first version assumes that Script uses 32-bit numbers, however, once integers with larger width are implemented, the script gets linearly longer (4 bytes/byte) with each additional byte. For 256-bit numbers, it would require a whopping 124 bytes (93 operations and 31 pushdata) to convert to big-endian. As the opcode limit currently is 201, that wouldn't leave much room for other operations. In contrast, `<N> OP_NUM2BIN OP_REVERSEBYTES` always encodes integers as N-byte big-endian number, with a constant script size independent of N.
|
||||
|
||||
Also, suppose an oracle returns an ordered list of 1-byte items (e.g. indices), however, if the script requires the bytes to be in the reversed order, then OP_REVERSEBYTES would allow to do this trivially.
|
||||
|
||||
### A Note On Signs
|
||||
|
||||
For unsigned integers, the behavior is always the expected one: the number will be encoded as unsigned big-endian integer. However, as integers in Script are encoded rather curiously, signed integers might result in unexpected behavior:
|
||||
|
||||
`-1 4 OP_NUM2BIN OP_REVERSEBYTES -> {0x80, 0x00, 0x00, 0x01}`
|
||||
|
||||
Here, the sign bit is the first bit of the resulting stackitem. Usually, negative numbers are encoded in two's complement, and the number should be `{0xff, 0xff, 0xff, 0xff}`. However, as long as developers are aware of this quite Script specific encoding, there's no issue at hand.
|
||||
|
||||
## OP_REVERSEBYTES Specification
|
||||
|
||||
This specification uses the same syntax for the stack/stackitems as [[11]](#references).
|
||||
|
||||
### Semantics
|
||||
|
||||
`a OP_REVERSEBYTES -> b`.
|
||||
|
||||
OP_REVERSEBYTES fails immediately if the stack is empty.
|
||||
|
||||
Otherwise, the top stack item is removed from the stack, and a byte-reversed version is pushed onto the stack.
|
||||
|
||||
Examples:
|
||||
|
||||
* `{} OP_REVERSEBYTES -> {}`
|
||||
* `{0x01} OP_REVERSEBYTES -> {0x01}`
|
||||
* `{0x01, 0x02, 0x03, 0x04} OP_REVERSEBYTES -> {0x04, 0x03, 0x02, 0x01}`
|
||||
|
||||
### Opcode Number
|
||||
|
||||
OP_REVERSEBYTES proposes to use the previously unused opcode with number 188 (0xbc in hex encoding), which comes after the most recently added opcode, `OP_CHECKDATASIGVERIFY`.
|
||||
|
||||
### Name
|
||||
|
||||
The naming of this opcode turned out to become a bit of a bikeshed. In a previous proposal, this opcode has been named `OP_REVERSE`. After that, it has been renamed to `OP_BSWAP`, as that is a more technically accurate term, which is commonly used for reversing the byteorder of integers [[14, 15]](#references). However, after some more consideration, it has been renamed to `OP_ENDIAN_REVERSE` following Boost‘s nomenclature [[16]](#references), then to `OP_REVERSEENDIAN` and finally to `OP_REVERSEBYTES`, which are both more consistent with Script‘s opcode naming system. However, as, “endian” is usually used for numbers which are a power of two—which isn‘t the case for this opcode—`OP_REVERSEBYTES` is the prefered choice here.
|
||||
|
||||
`OP_REVERSEBYTES` is preferable to `OP_BSWAP` because `OP_BSWAP` is lexically very similar to the already existing `OP_SWAP` and would make Script harder to read. Also, while the technical term for the instruction is indeed `bswap`, it isn‘t well known for developers of higher level languages and could thus spark confusion that would be avoided by using the name `OP_REVERSEBYTES`, which is more self-descriptive.
|
||||
|
||||
### Activation
|
||||
|
||||
The opcode will be activated during the 15th May 2020 hardfork.
|
||||
|
||||
### Unit Tests
|
||||
|
||||
The following unit tests are used by the ABC implementation of the opcode as of Feb 17th 2020.
|
||||
- `<item> OP_REVERSEBYTES` fails if 15th May 2020 protocol upgrade is not yet activated.
|
||||
- `OP_REVERSEBYTES` fails if the stack is empty.
|
||||
- `{} OP_REVERSEBYTES -> {}`
|
||||
- `{99} OP_REVERSEBYTES -> {99}`
|
||||
- `{0xde, 0xad} OP_REVERSEBYTES -> {0xad, 0xde}`
|
||||
- `{0xde, 0xad, 0xa1} OP_REVERSEBYTES -> {0xa1, 0xad, 0xde}`
|
||||
- `{0xde, 0xad, 0xbe, 0xef} OP_REVERSEBYTES -> {0xef, 0xbe, 0xad, 0xde}`
|
||||
- `{0x12, 0x34, 0x56} OP_REVERSEBYTES -> {0x56, 0x34, 0x12}`
|
||||
- for all n ∈ [0; 520]: `{i mod 256 | i < n} OP_REVERSEBYTES -> {(n - i - 1) mod 256 | i < n}`
|
||||
- for all n ∈ [0; 520]: `{(if (i < (n + 1) / 2) then (i) else (n - i - 1)) % 256) | i < n} OP_DUP OP_REVERSEBYTES OP_EQUAL -> OP_TRUE`
|
||||
|
||||
## References
|
||||
|
||||
[1] SLP Token specification: https://github.com/simpleledger/slp-specifications/blob/master/slp-token-type-1.md
|
||||
|
||||
[2] Spending constraints with OP_CHECKDATASIG: https://honest.cash/pein_sama/spending-constraints-with-op_checkdatasig-172
|
||||
|
||||
[3] SLP Agora: https://github.com/EyeOfPython/slpagora
|
||||
|
||||
[4] Sample SLPDEX transaction: https://blockchair.com/bitcoin-cash/transaction/2e69f47a985673c5a645e20ad09025a0892321f096224679657f98e6152c845c
|
||||
|
||||
[5] Let's play chess on the BCH Blockchain: https://tobiasruck.com/content/lets-play-chess-on-bch/
|
||||
|
||||
[6] SLPDEX (discontinued): slpdex.cash
|
||||
|
||||
[7] DAO: https://en.wikipedia.org/wiki/Decentralized_autonomous_organization
|
||||
|
||||
[8] Bitcoin protocol documentation, common structures: https://en.bitcoin.it/wiki/Protocol_documentation#Common_structures
|
||||
|
||||
[9] BIP143: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
|
||||
|
||||
[10] BIP16: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
|
||||
|
||||
[11] May 2018, reenabled opcodes: https://github.com/EyeOfPython/bitcoincash.org/blob/master/spec/may-2018-reenabled-opcodes.md
|
||||
|
||||
[12] AMQP specification, page 14: http://www.amqp.org/sites/amqp.org/files/amqp.pdf
|
||||
|
||||
[13] Apache Thrift binary protocol: https://github.com/apache/thrift/blob/master/doc/specs/thrift-binary-protocol.md
|
||||
|
||||
[14] https://docs.rs/bswap/1.0.0/bswap/
|
||||
|
||||
[15] https://www.npmjs.com/package/bswap
|
||||
|
||||
[16] https://www.boost.org/doc/libs/1_63_0/libs/endian/doc/conversion.html#endian_reverse
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 145 KiB |
@@ -0,0 +1,167 @@
|
||||
# 2020-05-15 SigChecks
|
||||
|
||||
layout: specification
|
||||
title: 2020-MAY-15 script SigChecks counting and limiting specification
|
||||
date: 2020-03-05
|
||||
category: spec
|
||||
activation: 1589544000
|
||||
version: 0.2 (DRAFT)
|
||||
author: Mark B. Lundeberg
|
||||
|
||||
# Summary
|
||||
|
||||
Bitcoin Cash's SigOps counting and limiting system will be replaced with a new system, referred to as SigChecks.
|
||||
|
||||
# Motivation
|
||||
|
||||
Since early days, Bitcoin has had a SigOps counting rule for limiting the amount of CPU usage possible in a given transaction or block, based on the principle that signature verifications are by far the most CPU-intense operations.
|
||||
|
||||
Although partly effective, there are well known issues with sigops, which mainly stem from the fact that SigOps are judged by parsing scripts, rather than executing them.
|
||||
Bitcoin splits scripts into two transactions (the scriptPubKey of the transaction that creates a coin, and the scriptSig of the transaction that spends it), yet the actual CPU work of verifying a transaction solely happens in the spending transaction, and this leads to some paradoxical situations: a transaction/block that contains high sigops might involve very little CPU work, and conversely a transaction with low sigops may require very high CPU work.
|
||||
|
||||
The essential idea of SigChecks is to perform counting solely in the spending transaction, and count actual executed signature check operations.
|
||||
|
||||
# Specification
|
||||
|
||||
## Counting rule
|
||||
|
||||
The SigChecks count for a given script is discovered during execution of the script.
|
||||
|
||||
- Executing OP_CHECKSIG / OP_CHECKSIGVERIFY / OP_CHECKDATASIG / OP_CHECKDATASIGVERIFY increments SigChecks by:
|
||||
- +0, if signature is NULL.
|
||||
- +1, if signature is non-NULL.
|
||||
- Executing an M-of-N OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY increments SigChecks by:
|
||||
- +0, if all M signatures are NULL.
|
||||
- +M, if at least one signature is non-NULL and the verification is in [New/Schnorr mode](/protocol/forks/2019-11-15-schnorrmultisig) (dummy element is non-NULL).
|
||||
- +N, if at least one signature is non-NULL and the verification is in Old/ECDSA mode (dummy element is NULL).
|
||||
|
||||
Here NULL means a script stack element that has length 0; passing NULL in place of an expected signature is the canonical way of cancelling the signature check, i.e., making the signature checking opcode fail / return false (and the only way permitted way to cause this result ever since NULLFAIL rule activated).
|
||||
|
||||
## Per-block limitation (consensus rule)
|
||||
|
||||
After activation, any block where the total number of SigChecks accumulated (during all script executions - scriptSig, scriptPubKey, and P2SH redeemScript - in all inputs excepting coinbase) violates the following limit based on the maximum block size shall be rejected:
|
||||
|
||||
block_SigChecks <= max_Blocksize // 141
|
||||
|
||||
Here, max_Blocksize refers to the consensus limit that is enforced on the full serialized block size (including block header, transaction counter, and all serialized transaction).
|
||||
|
||||
Currently, `max_BlockSize` = 32000000 so the maximum allowed `block_SigChecks` would be 226950 for all blocks. However, in future block size increases, it should be assumed that the SigChecks limit increases proportionally.
|
||||
|
||||
## Per-transaction limits (consensus rule)
|
||||
|
||||
After activation, any transaction where the total number of SigChecks accumulated (during all script executions - scriptSig, scriptPubKey, and P2SH redeemScript - in all inputs excepting coinbase) violates the following limit shall be rejected:
|
||||
|
||||
transaction_SigChecks <= 3000
|
||||
|
||||
## Per-input limitation (standardness rule)
|
||||
|
||||
For a given transaction input, the number of SigChecks accumulated during all script execution (scriptSig, scriptPubKey, and P2SH redeemScript) is to be limited according to the byte-length of the scriptSig, `len_scriptSig`:
|
||||
|
||||
txin_SigChecks <= (len_scriptSig + 60) // 43, where // indicates floor division.
|
||||
- or equivalently -
|
||||
len_scriptSig >= 43 * txin_SigChecks - 60
|
||||
|
||||
Any transaction that contains an input violating this limit should be rejected from nodes' mempools and not relayed. However, blocks may contain inputs that violate this limit.
|
||||
|
||||
This is only a non-consensus standardness (transaction relay) rule, meaning that transactions within blocks do not need to obey this rule. Nodes should only enforce this rule starting at the activation time, and if any transactions in mempool violate this rule at precisely the time of activation, they should be ejected.
|
||||
|
||||
## Removal of SigOps
|
||||
|
||||
After the activation, nodes shall disable the all consensus rules and all standardness rules relating to the old SigOps counting mechanism. There are four such rules:
|
||||
|
||||
- The consensus limit of 20000 sigops per MB of block shall be disabled.
|
||||
- The consensus limit of 20000 sigops per transaction shall be disabled.
|
||||
- The standardness limit of 4000 sigops per transaction shall be disabled.
|
||||
- The standardness limit of 15 sigops per P2SH input shall be disabled.
|
||||
|
||||
## Notes
|
||||
|
||||
- The question of whether all signatures are null is not precisely the inverse of whether the opcode returns true/false to stack: consider the case of 0-of-N OP_CHECKMULTISIG, which always returns true, yet also has "all null" signatures. Also, historically pre-NULLFAIL opcodes would return false for non-null invalid signatures, instead of failing.
|
||||
|
||||
# Rationale and commentary on design decisions
|
||||
|
||||
## Counting rule
|
||||
|
||||
The proposed counting rule is easy to implement, but it's not the simplest / most obvious approach. There is one primary design feature we wanted to ensure: *The proposed counting rule means that the sigchecks count can be evaluated by executing a script with a 'dummy'/deferred signature verifier, i.e., without performing any CPU-intensive elliptic curve math.*
|
||||
|
||||
We currently have the NULLFAIL rule, which means that signature check opcodes will either:
|
||||
- fail with error, because the non-null signatures were not valid, or there was a mixture of null / non-null signatures, or because the checked public keys were incorrectly encoded, or some other reason.
|
||||
- return true, if all signatures are non-null and valid, or,
|
||||
- return false, if all signatures are null and there is at least 1 signature.
|
||||
|
||||
Right now, nodes can optionally use this fact to defer public key and signature checks until after script execution, simply placing true/false on stack depending on whether the signatures are null or not, and continuing execution as if the checks were done.
|
||||
Later, after the script has finished executing successfully, the deferred checks can be finally executed to determine whether the script should in fact be failed entirely.
|
||||
This deferment allows some efficiency advantages (like allowing Schnorr batch validation, fast rejection of some invalid blocks/transactions, etc.).
|
||||
|
||||
The simplest imaginable rule would be to only count signature check function calls that are actually done.
|
||||
The main problem with this approach is that M-of-N ECDSA multisig verifications perform a variable number of signature checks, at least M but as many as N.
|
||||
Some of these checks fail, some succeed. The count would then be only determinable by actually performing full signature checks.
|
||||
With the deferment mentioned above, this would mean that any limits on sigchecks could not be accurately enforced before actually carrying out the signature checks.
|
||||
|
||||
A secondary aspect of counting is that when all signatures are null, we assign a sigchecks count of 0.
|
||||
This is a rare case since most scripts want only valid signatures anyway.
|
||||
However, it does increase accuracy of the count, and it can be useful in smart contracting to use null signatures instead of booleans to control branching flows (booleans pushed from scriptSig can be malleated).
|
||||
Since it is easy to implement the 0 sigchecks counting and it's more accurate that way, we decided to include this.
|
||||
|
||||
## Why have limits?
|
||||
|
||||
The SigOps and SigChecks limits exist solely to limit the impact of denial of service attacks. There are a variety of attacks that might occur, but these are the main ones:
|
||||
- An attacking miner can craft valid/invalid blocks packed full with valid and CPU-intensive non-standard scripts that would require huge amounts of time (perhaps hours) to validate.
|
||||
- Anyone may flood the mempool with valid but CPU-intensive transactions. Since these are valid, they will be propagated to all nodes 'for free' and load down the network.
|
||||
|
||||
While these might sound bad, it's worth noting that the disruption would be temporary.
|
||||
The mempool and block attack vectors are essentially decoupled since efficient nodes use transaction validity caching: if they have accepted a transaction already, they don't need to re-verify it when they see it mined in a block.
|
||||
Also, CPU-intensive blocks do not cause any kind of "permanent damage" to new nodes coming online, since again efficient nodes typically provide for an 'assume-valid' setting that only requires fully verifying recent blocks.
|
||||
|
||||
*Blocks*:
|
||||
Slow blocks can be made without any setup, but the slowest possible block would require a many setup blocks to be mined beforehand that generate attack outputs.
|
||||
These attack outputs would then all be spent in the attack block.
|
||||
Since scripts are limited to 201 opcodes and inputs are at least 41 bytes, this could achieve about 5 signature checks for every byte in the spending block, or 160 million signature checks with today's maximum block size.
|
||||
As a rough rule of thumb, each signature check takes 50 microseconds, so such a block would take a couple of CPU-hours to validate (though this is trivially parallelized).
|
||||
The proposed limit of 141 bytes / sigcheck cuts the worst case down by a factor of 700.
|
||||
The main motivation here isn't just to ensure nondisruption with current block sizes, but also to make sure future block size increases can be made with needing to worry so much about slow block attacks.
|
||||
|
||||
*Mempool*:
|
||||
As far as mempool attacks go, these currently are already greatly limited by standardness rules on mainnet that 1) whitelist only certain allowed output script templates and 2) limit P2SH to 15 sigops.
|
||||
If either rule were simply removed, it would permit abusive scripts that perform a large number of verifications in a tight space.
|
||||
Since we are planning to remove sigops, then something needs to go in place of that P2SH sigops rule.
|
||||
Besides limiting the density of CPU usage, it also makes sense to limit signature checks density in transactions as a *support* for the block limit: we don't want that the mempool can be totally filled with high-sigchecks transactions that take ages to clear out (since each block can only consume so many of them).
|
||||
|
||||
It's worth pointing out some of the indirect limits that are created as a result:
|
||||
- As mentioned above it is impossible for the number of SigChecks in an input to exceed 201, which is the current limit on the 'opcode count' for a single script.
|
||||
- However, a mainnet standard transaction cannot have a scriptSig longer than 1650 bytes, which means an input in a standard transaction won't be able to have more than 39 SigChecks.
|
||||
- The per-input rule means that the overall density of SigChecks in a standard transaction cannot exceed 33.5 bytes / SigCheck. This occurs with many inputs having each two SigChecks in a scriptSig of length 26, i.e., an input of size 26+41 = 67 bytes.
|
||||
- Due to additional script template standardness rules on mainnet, it is practically not possible to produce such a short scriptSig containing two sigchecks. So, practically one can only achieve 36.67 bytes/SigCheck (three SigChecks in a scriptSig of length 69), using 1-of-3 bare multisignatures or some P2SH tricks.
|
||||
- Likewise standard transactions on mainnet are limited to 100000 bytes, so a standard transaction won't be able to have more than 3000 sigchecks.
|
||||
|
||||
## Choice of numbers
|
||||
|
||||
The numbers proposed for the per-input and per-block limits are based on an examination of current typical uses, and an examination of the historical blockchain.
|
||||
|
||||
The per-input limit is designed to support the two most extreme standard use cases, which deserve continuing support and (though rare) are still used occasionally:
|
||||
|
||||
* Spending a bare 1-of-3 multisignature in ECDSA mode will have 3 SigChecks in around 73 bytes. (Bare multisigs like 1-of-4 and beyond are nonstandard to fund.)
|
||||
* Spending a P2SH 1-of-15 multisignature in ECDSA mode will have 15 SigChecks in around 589 bytes.
|
||||
|
||||
The proposed per-input rule is a line interpolating between those two cases, with a spare allowance of 4 bytes for each (since ECDSA signatures are variable size, and very rarely are they shorter than this in normal usage).
|
||||
|
||||
Typical use cases are much much lower density than these. P2PK and P2PKH have 1 SigCheck in ~70 bytes and ~105 bytes respectively, and most P2SH multisignatures are 2-of-3 spent with ECDSA which have 3 SigChecks in a ~250 byte scriptSig. I've plotted the common standard use cases below. As can be seen
|
||||
|
||||

|
||||
|
||||
The block limit is based on an examination of normal usage patterns and observations on historical blocks. Historically, the bulk (75%) of blocks have had a density of between 150 and 250 bytes/SigCheck, and the average density of the whole chain is 176 bytes/SigCheck. Only 2% of blocks have been more dense than 141 bytes/SigCheck. This matches the fact that the vast majority of inputs/outputs are P2PKH, which on the whole (considering funding and spending) have a density of around 182 bytes/SigCheck. Rarely, one sees a block that is packed full of an unusually high fraction of P2SH 2-of-3 multisignature consolidations, which pushes down to the 100 bytes/SigCheck level. Blocks more dense than 98 bytes/SigCheck have been extremely rare, making up 0.01% of blocks.
|
||||
|
||||
The exact number of 141 bytes/SigCheck comes from considering a fairly common use case, which is consolidating many P2PKH inputs. If done with Schnorr signatures then each input is 141 bytes and one SigCheck.
|
||||
|
||||
The choice of 141 bytes/SigCheck for a block is ~4x times more aggressive than the ~36.67 bytes/SigCheck standardness rule. It's worth emphasizing however that this block limit is based on the maximum block size. Thus, it may happen that a normally mined block has an actual density of ~36.67 bytes/SigCheck, however, such a block could not be more than ~1/4th of the maximum block byte size.
|
||||
|
||||
A histogram of historical block densities is plotted below:
|
||||

|
||||
|
||||
# Implementation
|
||||
|
||||
**Implementation information to be added - TBD**
|
||||
|
||||
# Acknowledgements
|
||||
|
||||
Thanks to Amaury Sechet, Josh Green, Tobias Ruck, Tyler Smith, Calin Culianu, and Andrew Stone for valuable feedback.
|
||||
Binary file not shown.
@@ -0,0 +1,428 @@
|
||||
# 2020-11-15 ASERT
|
||||
|
||||
layout: specification
|
||||
title: ASERT Difficulty Adjustment Algorithm (aserti3-2d)
|
||||
date: 2020-08-17
|
||||
category: spec
|
||||
activation: 1605441600
|
||||
version: 0.6.3
|
||||
author: freetrader, Jonathan Toomim, Calin Culianu, Mark Lundeberg, Tobias Ruck
|
||||
|
||||
## Summary
|
||||
|
||||
Activation of a new new difficulty adjustment algorithm 'aserti3-2d'
|
||||
(or 'ASERT' for short) for the November 2020 Bitcoin Cash upgrade. Activation will be
|
||||
based on MTP, with the last pre-fork block used as the anchor block.
|
||||
|
||||
## Motivation
|
||||
|
||||
- To eliminate periodic oscillations in difficulty and hashrate
|
||||
- To reduce the difference in profitability between steady miners and
|
||||
those who switch to mining other blockchains.
|
||||
- To maintain average block intervals close to the 10 minute target.
|
||||
- To bring the average transaction confirmation time close to target time.
|
||||
|
||||
## Technical background
|
||||
|
||||
The November 2017 Bitcoin Cash upgrade introduced a simple moving average as
|
||||
difficulty adjustment algorithm. This change unfortunately introduced daily
|
||||
periodic difficulty oscillations, which resulted in long confirmation times
|
||||
followed by a burst of rapid blocks. This harms the user experience of Bitcoin
|
||||
Cash, and punishes steady hashrate miners.
|
||||
|
||||
Research into the family of difficulty algorithms based on an exponential
|
||||
moving average (EMA) resulted in ASERT (Absolutely Scheduled Exponentially
|
||||
Rising Targets) [[1]](#references), which has been developed by Mark Lundeberg in 2019 and
|
||||
fully described by him in 2020. An equivalent formula was independently
|
||||
discovered in 2018 by Jacob Eliosoff and in 2020 by Werner et. al [[6]](#references).
|
||||
|
||||
ASERT does not have the same oscillations as the DAA introduced in the November
|
||||
2017 upgrade and has a range of other attractive qualities such as robustness
|
||||
against singularities [[15]](#references) without a need for additional rules, and absence of
|
||||
accumulation of rounding/approximation errors.
|
||||
|
||||
In extensive simulation against a range of other stable algorithms [[2]](#references),
|
||||
an ASERT algorithm performed best across criteria that included:
|
||||
|
||||
- Average block times closest to an ideal target time of 600 seconds.
|
||||
- Average transaction confirmation times closest to the target time.
|
||||
- Reducing the advantage of non-steady mining strategies, thereby maximizing
|
||||
the relative profitability of steady mining.
|
||||
|
||||
## Specification
|
||||
|
||||
### Terms and conventions
|
||||
|
||||
* Fork block: The first block mined according to the new consensus rules.
|
||||
* Anchor block: The parent of the fork block.
|
||||
|
||||
|
||||
### Requirements
|
||||
|
||||
#### Target computation
|
||||
The current block's target bits are calculated by the following algorithm.
|
||||
|
||||
The aserti3-2d algorithm can be described by the following formula:
|
||||
|
||||
```
|
||||
next_target = anchor_target * 2**((time_delta - ideal_block_time * (height_delta + 1)) / halflife)
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
- `anchor_target` is the unsigned 256 bit integer equivalent of the `nBits` value in
|
||||
the header of the anchor block.
|
||||
- `time_delta` is the difference, in signed integer seconds, between the
|
||||
timestamp in the header of the current block and the timestamp in the
|
||||
parent of the anchor block.
|
||||
- `ideal_block_time` is a constant: 600 seconds, the targeted
|
||||
average time between blocks.
|
||||
- `height_delta` is the difference in block height between the current
|
||||
block and the anchor block.
|
||||
- `halflife` is a constant parameter sometimes referred to as
|
||||
'tau', with a value of 172800 (seconds) on mainnet.
|
||||
- `next_target` is the integer value of the target computed for the block
|
||||
after the current block.
|
||||
|
||||
The algorithm below implements the above formula using fixed-point integer
|
||||
arithmetic and a cubic polynomial approximation to the 2^x term.
|
||||
|
||||
The 'target' values used as input and output are the compact representations
|
||||
of actual 256-bit integer targets as specified for the 'nBits' field in the
|
||||
block header.
|
||||
|
||||
|
||||
Python-code, uses Python 3 syntax:
|
||||
|
||||
```python
|
||||
def next_target_aserti3_2d(
|
||||
anchor_height: int, # height of the anchor block.
|
||||
anchor_parent_time: int, # timestamp (nTime) of the parent of the anchor block.
|
||||
anchor_bits: int, # 'nBits' value of the anchor block.
|
||||
current_height: int, # height of the current block.
|
||||
current_time: int, # timestamp of the current block.
|
||||
) -> int: # 'target' nBits of the current block.
|
||||
ideal_block_time = 600 # in seconds
|
||||
halflife = 172_800 # 2 days (in seconds)
|
||||
radix = 2**16 # 16 bits for decimal part of fixed-point integer arithmetic
|
||||
max_bits = 0x1d00_ffff # maximum target in nBits representation
|
||||
max_target = bits_to_target(max_bits) # maximum target as integer
|
||||
|
||||
anchor_target = bits_to_target(anchor_bits)
|
||||
time_delta = current_time - anchor_parent_time
|
||||
height_delta = current_height - anchor_height # can be negative
|
||||
# `//` is truncating division (int.__floordiv__) - see note 3 below
|
||||
exponent = time_delta - ideal_block_time * (height_delta + 1) // halflife
|
||||
|
||||
# Compute equivalent of `num_shifts = math.floor(exponent / 2**16)`
|
||||
num_shifts = exponent >> 16
|
||||
|
||||
exponent = exponent - num_shifts * radix
|
||||
factor = ((195_766_423_245_049 * exponent +
|
||||
971_821_376 * exponent**2 +
|
||||
5_127 * exponent**3 +
|
||||
2**47) >> 48) + radix
|
||||
next_target = anchor_target * factor
|
||||
|
||||
# Calculate `next_target = math.floor(next_target * 2**factor)`
|
||||
if num_shifts < 0:
|
||||
next_target >>= -num_shifts
|
||||
else:
|
||||
# Implementations should be careful of overflow here (see note 6 below).
|
||||
next_target <<= num_shifts
|
||||
|
||||
next_target >>= 16
|
||||
if next_target == 0:
|
||||
return target_to_bits(1) # hardest valid target
|
||||
|
||||
if next_target > max_target:
|
||||
return max_bits # limit on easiest target
|
||||
return target_to_bits(next_target)
|
||||
```
|
||||
|
||||
Note 1: The reference implementations make use of signed integer arithmetic.
|
||||
Alternative implementations may use strictly unsigned integer
|
||||
arithmetic.
|
||||
|
||||
Note 2: All implementations should strictly avoid use of floating point
|
||||
arithmetic in the computation of the exponent.
|
||||
|
||||
Note 3: In the calculation of the exponent, truncating integer division [[7, 10]](#references)
|
||||
must be used, as indicated by the `//` division operator (`int.__floordiv__`).
|
||||
|
||||
Note 5: The convenience functions `bits_to_target()` and `target_to_bits()`
|
||||
are assumed to be available for conversion between compact 'nBits'
|
||||
and unsigned 256-bit integer representations of targets.
|
||||
Examples of such functions are available in the C++ and Python3
|
||||
reference implementations.
|
||||
|
||||
Note 6: If a limited-width integer type is used for `current_target`, then the `<<`
|
||||
operator may cause an overflow exception or silent discarding of
|
||||
most-significant bits.
|
||||
Implementations must detect and handle such cases to correctly emulate
|
||||
the behaviour of an unlimited-width calculation. Note that if the result
|
||||
at this point would exceed `radix * max_target` then `max_bits` may be returned
|
||||
immediately.
|
||||
|
||||
Note 7: The polynomial approximation that computes `factor` must be performed
|
||||
with 64 bit unsigned integer arithmetic or better. It *will*
|
||||
overflow a signed 64 bit integer. Since exponent is signed, it may be
|
||||
necessary to cast it to unsigned 64 bit integer. In languages like
|
||||
Java where long is always signed, an unsigned shift `>>> 48` must be
|
||||
used to divide by 2^48.
|
||||
|
||||
|
||||
#### Activation
|
||||
|
||||
The ASERT algorithm will be activated according to the top-level upgrade spec [[3]](#references).
|
||||
|
||||
#### Anchor block
|
||||
|
||||
ASERT requires the choice of an anchor block to schedule future target
|
||||
computations.
|
||||
|
||||
The first block with an MTP that is greater/equal to the upgrade activation time
|
||||
will be used as the anchor block for subsequent ASERT calculations.
|
||||
|
||||
This corresponds to the last block mined under the pre-ASERT DAA rules.
|
||||
|
||||
Note 1: The anchor block is the block whose height and target
|
||||
(nBits) are used as the 'absolute' basis for ASERT's
|
||||
scheduled target. The timestamp (nTime) of the anchor block's
|
||||
*parent* is used.
|
||||
|
||||
Note 2: The height, timestamp, and nBits of this block are not known ahead of
|
||||
the upgrade. Implementations MUST dynamically determine it across the
|
||||
upgrade. Once the network upgrade has been consolidated by
|
||||
sufficient chain work or a checkpoint, implementations can simply
|
||||
hard-code the known height, nBits and associated (parent) timestamp
|
||||
this anchor block. Implementations MAY also hard-code other equivalent
|
||||
representations, such as an nBits value and a time offset from the
|
||||
genesis block.
|
||||
|
||||
|
||||
#### REQ-ASERT-TESTNET-DIFF-RESET (testnet difficulty reset)
|
||||
|
||||
On testnet, an additional rule will be included: Any block with a timestamp
|
||||
that is more than 1200 seconds after its parent's timestamp must use an
|
||||
nBits value of `max_bits` (`0x1d00ffff`).
|
||||
|
||||
|
||||
## Rationale and commentary on requirements / design decisions
|
||||
|
||||
1. Choice of anchor block determination
|
||||
|
||||
Choosing an anchor block that is far enough in the past would result
|
||||
in slightly simpler coding requirements but would create the possibility
|
||||
of a significant difficulty adjustment at the upgrade.
|
||||
|
||||
The last block mined according to the old DAA was chosen since this block is
|
||||
the most proximal anchor and allows for the smoothest transition to the new
|
||||
algorithm.
|
||||
|
||||
2. Avoidance of floating point calculations
|
||||
|
||||
Compliance with IEEE-754 floating point arithmetic is not generally
|
||||
guaranteed by programming languages on which a new DAA needs to be
|
||||
implemented. This could result in floating point calculations yielding
|
||||
different results depending on compilers, interpreters or hardware.
|
||||
|
||||
It is therefore highly advised to perform all calculations purely using
|
||||
integers and highly specific operators to ensure identical difficulty
|
||||
targets are enforced across all implementations.
|
||||
|
||||
3. Choice of half-life
|
||||
|
||||
A half-life of 2 days (`halflife = 2 * 24 * 3600`), equivalent to an e^x-based
|
||||
time constant of `2 * 144 * ln(2)` or aserti3-415.5, was chosen because it reaches
|
||||
near-optimal performance in simulations by balancing the need to buffer
|
||||
against statistical noise and the need to respond rapidly to swings in price
|
||||
or hashrate, while also being easy for humans to understand: For every 2 days
|
||||
ahead of schedule a block's timestamp becomes, the difficulty doubles.
|
||||
|
||||
4. Choice of approximation polynomial
|
||||
|
||||
The DAA is part of a control system feedback loop that regulates hashrate,
|
||||
and the exponential function and its integer approximation comprise its
|
||||
transfer function. As such, standard guidelines for ensuring control system
|
||||
stability apply. Control systems tend to be far more sensitive to
|
||||
differential nonlinearity (DNL) than integral nonlinearity (INL) in their
|
||||
transfer functions. Our requirements were to have a transfer function that
|
||||
was (a) monotonic, (b) contained no abrupt changes, (c) had precision and
|
||||
differential nonlinearity that was better than our multi-block statistical
|
||||
noise floor, (d) was simple to implement, and (e) had integral nonlinearity
|
||||
that was no worse than our single-block statistical noise floor.
|
||||
|
||||
A simple, fast to compute cubic approximation of 2^x for 0 <= x < 1 was
|
||||
found to satisfy all of these requirements. It maintains an absolute error
|
||||
margin below 0.013% over this range [8]. In order to address the full
|
||||
(-infinity, +infinity) domain of the exponential function, we found the
|
||||
`2**(x + n) = 2**n * 2**x` identity to be of use. Our cubic approximation gives
|
||||
the exactly correct values `f(0) == 1` and `f(1) == 2`, which allows us to
|
||||
use this identity without concern for discontinuities at the edges of the
|
||||
approximation's domain.
|
||||
|
||||
First, there is the issue of DNL. Our goal was to ensure that our algorithm
|
||||
added no more than 25% as much noise as is inherent in our dataset. Our
|
||||
algorithm is effectively trying to estimate the characteristic hashrate over
|
||||
the recent past, using a 2-day (~288-block) half-life. Our expected
|
||||
exponential distribution of block intervals has a standard deviation (stddev)
|
||||
of 600 seconds. Over a 2-day half-life, our noise floor in our estimated
|
||||
hashrate should be about `sqrt(1 / 288) * 600` seconds, or 35.3 seconds. Our
|
||||
chosen approximation method is able to achieve precision of 3 seconds in most
|
||||
circumstances, limited in two places by 16-bit operations:
|
||||
`172800 sec / 65536 = 2.6367 sec`
|
||||
Our worst-case precision is 8 seconds, and is limited by the worst-case
|
||||
15-bit precision of the nBits value. This 8 second worst-case is not within
|
||||
the scope of this work to address, as it would require a change to the block
|
||||
header. Our worst-case step size is 0.00305%,[[11]](#references) due to the worst-case
|
||||
15-bit nBits mantissa issue. Outside the 15-bit nBits mantissa range, our
|
||||
approximation has a worst-case precision of 0.0021%. Overall, we considered
|
||||
this to be satisfactory DNL performance.
|
||||
|
||||
Second, there is the issue of INL. Simulation testing showed that difficulty
|
||||
and hashrate regulation performance was remarkably insensitive to
|
||||
integral non-linearity. We found that even the use of `f(x) = 1 + x` as an
|
||||
approximation of `2**x` in the `aserti1` algorithm was satisfactory when
|
||||
coupled with the `2**(x + n) = 2^n * 2^x` identity, despite having 6%
|
||||
worst-case INL.[[12, 13]](#references) An approximation with poor INL will still show good
|
||||
hashrate regulation ability, but will have a different amount of drift for a
|
||||
given change in hashrate depending on where in the \[0, 1) domain our exponent
|
||||
(modulo 1) lies. With INL of +/- 1%, for any given difficulty (or target), a
|
||||
block's timestamp might end up being 1% of 172800 seconds ahead of or behind
|
||||
schedule. However, out of an abundance of caution, and because achieving
|
||||
higher precision was easy, we chose to aim for INL that would be comparable
|
||||
to or less than the typical drift that can be caused by one block. Out of
|
||||
a 2-day half-life window, one block's variance comprises:
|
||||
`600 / 172800 = 0.347%`
|
||||
Our cubic approximation's INL performance is better than 0.013%,[[14]](#references) which
|
||||
exceeds that requirement by a comfortable margin.
|
||||
|
||||
5. Conversion of difficulty bits (nBits) to 256-bit target representations
|
||||
|
||||
As there are few calculations in ASERT which involve 256-bit integers
|
||||
and the algorithm is executed infrequently, it was considered unnecessary
|
||||
to require more complex operations such as doing arithmetic directly on
|
||||
the compact target representations (nBits) that are the inputs/output of
|
||||
the difficulty algorithm.
|
||||
|
||||
Furthermore, 256-bit (or even bignum) arithmetic is available in existing
|
||||
implementation and used within the previous DAA. Performance impacts are
|
||||
negligible.
|
||||
|
||||
6. Choice of 16-bits of precision for fixed-point math
|
||||
|
||||
The nBits format is comprised of 8 bits of base_256 exponent, followed by a
|
||||
24-bit mantissa. The mantissa must have a value of at least 0x008000, which
|
||||
means that the worst-case scenario gives the mantissa only 15 bits of
|
||||
precision. The choice of 16-bit precision in our fixed point math ensures
|
||||
that overall precision is limited by this 15-bit nBits limit.
|
||||
|
||||
7. Choice of name
|
||||
|
||||
The specific algorithm name 'aserti3-2d' was chosen based on:
|
||||
|
||||
- the 'i' refers to the integer-only arithmetic
|
||||
- the '3' refers to the cubic approximation of the exponential
|
||||
- the '2d' refers to the 2-day (172800 second) halflife
|
||||
|
||||
|
||||
## Implementation advice
|
||||
|
||||
Implementations must not make any rounding errors during their calculations.
|
||||
Rounding must be done exactly as specified in the algorithm. In practice,
|
||||
to guarantee that, you likely need to use integer arithmetic exclusively.
|
||||
|
||||
Implementations which use signed integers and use bit-shifting must ensure
|
||||
that the bit-shifting is arithmetic.
|
||||
|
||||
Note 1: In C++ compilers, right shifting negative signed integers
|
||||
is formally unspecified behavior until C++20 when it
|
||||
will become standard [[5]](#references). In practice, C/C++ compilers
|
||||
commonly implement arithmetic bit shifting for signed
|
||||
numbers. Implementers are advised to verify good behavior
|
||||
through compile-time assertions or unit tests.
|
||||
|
||||
|
||||
## Reference implementations
|
||||
|
||||
- C++ code for aserti3-2d (see pow.cpp): https://reviews.bitcoinabc.org/D7174
|
||||
- Python3 code (see contrib/testgen/validate_nbits_aserti3_2d.py): https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/692
|
||||
- Java code: https://github.com/pokkst/asert-java
|
||||
|
||||
|
||||
## Test vectors
|
||||
|
||||
Test vectors suitable for validating further implementations of the aserti3-2d
|
||||
algorithm are available at:
|
||||
|
||||
[Here](/protocol/forks/2020-11-15-asert-test-vectors.zip)
|
||||
|
||||
alternatively at:
|
||||
|
||||
https://gitlab.com/bitcoin-cash-node/bchn-sw/qa-assets/-/tree/master/test_vectors/aserti3-2d
|
||||
|
||||
and alternatively at:
|
||||
|
||||
https://download.bitcoincashnode.org/misc/data/asert/test_vectors
|
||||
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Thanks to Mark Lundeberg for granting permission to publish the ASERT paper [[1]](#references),
|
||||
Jonathan Toomim for developing the initial Python and C++ implementations,
|
||||
upgrading the simulation framework [[9]](#references) and evaluating the various difficulty
|
||||
algorithms.
|
||||
|
||||
Thanks to Jacob Eliosoff, Tom Harding and Scott Roberts for evaluation work
|
||||
on the families of EMA and other algorithms considered as replacements for
|
||||
the Bitcoin Cash DAA, and thanks to the following for review and their
|
||||
valuable suggestions for improvement:
|
||||
|
||||
- Andrea Suisani (sickpig)
|
||||
- BigBlockIfTrue
|
||||
- Fernando Pellicioni
|
||||
- imaginary_username
|
||||
- mtrycz
|
||||
- Jochen Hoenicke
|
||||
- John Nieri (emergent_reasons)
|
||||
- Tom Zander
|
||||
|
||||
|
||||
## References
|
||||
|
||||
[1] "[Static difficulty adjustments, with absolutely scheduled exponentially rising targets (DA-ASERT) -- v2](http://toom.im/files/da-asert.pdf)", Mark B. Lundeberg, July 31, 2020
|
||||
|
||||
[2] "[BCH upgrade proposal: Use ASERT as the new DAA](https://read.cash/@jtoomim/bch-upgrade-proposal-use-asert-as-the-new-daa-1d875696)", Jonathan Toomim, 8 July 2020
|
||||
|
||||
[3] [Bitcoin Cash November 15, 2020 Upgrade Specification](2020-11-15-upgrade.md).
|
||||
|
||||
[4] <https://en.wikipedia.org/wiki/Arithmetic_shift>
|
||||
|
||||
[5] <https://en.cppreference.com/w/cpp/language/operator_arithmetic>
|
||||
|
||||
[6] "[Unstable Throughput: When the Difficulty Algorithm Breaks](https://arxiv.org/pdf/2006.03044.pdf)", Sam M. Werner, Dragos I. Ilie, Iain Stewart, William J. Knottenbelt, June 2020
|
||||
|
||||
[7] "[Different kinds of integer division](https://harry.garrood.me/blog/integer-division)", Harry Garrood, blog, 2018
|
||||
|
||||
[8] [Error in a cubic approximation of 2^x for 0 <= x < 1](https://twitter.com/MarkLundeberg/status/1191831127306031104)
|
||||
|
||||
[9] Jonathan Toomim adaptation of kyuupichan's difficulty algorithm simulator: <https://github.com/jtoomim/difficulty/tree/comparator>
|
||||
|
||||
[10] "[The Euclidean definition of the functions div and mod](dl.acm.org/doi/10.1145/128861.128862)", Raymond T. Boute, 1992, ACM Transactions on Programming Languages and Systems (TOPLAS). 14. 127-144. 10.1145/128861.128862
|
||||
|
||||
[11] <http://toom.im/bch/aserti3_step_size.html>
|
||||
|
||||
[12] [f(x) = (1 + x)/2^x for 0<x<1](https://www.wolframalpha.com/input/?i=f%28x%29+%3D+%281+%2B+x%29%2F2%5Ex+for+0%3Cx%3C1), WolframAlpha.
|
||||
|
||||
[13] <https://github.com/zawy12/difficulty-algorithms/issues/62#issuecomment-647060200>
|
||||
|
||||
[14] <http://toom.im/bch/aserti3_approx_error.html>
|
||||
|
||||
[15] <https://github.com/zawy12/difficulty-algorithms/issues/62#issuecomment-646187957>
|
||||
|
||||
|
||||
## License
|
||||
|
||||
This specification is dual-licensed under the Creative Commons CC0 1.0 Universal and
|
||||
GNU All-Permissive licenses.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,229 @@
|
||||
# BIP-0009
|
||||
BIP: 9
|
||||
Title: Version bits with timeout and delay
|
||||
Author: Pieter Wuille <pieter.wuille@gmail.com>
|
||||
Peter Todd <pete@petertodd.org>
|
||||
Greg Maxwell <greg@xiph.org>
|
||||
Rusty Russell <rusty@rustcorp.com.au>
|
||||
Comments-Summary: No comments yet.
|
||||
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0009
|
||||
Status: Final
|
||||
Type: Informational
|
||||
Created: 2015-10-04
|
||||
License: PD
|
||||
|
||||
## Abstract
|
||||
|
||||
This document specifies a proposed change to the semantics of the 'version' field in Bitcoin blocks, allowing multiple backward-compatible changes (further called "soft forks") to be deployed in parallel. It relies on interpreting the version field as a bit vector, where each bit can be used to track an independent change. These are tallied each retarget period. Once the consensus change succeeds or times out, there is a "fallow" pause after which the bit can be reused for later changes.
|
||||
|
||||
## Motivation
|
||||
|
||||
[BIP 34](/protocol/forks/bip-0034) introduced a mechanism for doing soft-forking changes without a predefined flag timestamp (or flag block height), instead relying on measuring miner support indicated by a higher version number in block headers. As it relies on comparing version numbers as integers however, it only supports one single change being rolled out at once, requiring coordination between proposals, and does not allow for permanent rejection: as long as one soft fork is not fully rolled out, no future one can be scheduled.
|
||||
|
||||
In addition, BIP 34 made the integer comparison (nVersion >= 2) a consensus rule after its 95% threshold was reached, removing 2<sup>31</sup>+2 values from the set of valid version numbers (all negative numbers, as nVersion is interpreted as a signed integer, as well as 0 and 1). This indicates another downside this approach: every upgrade permanently restricts the set of allowed nVersion field values. This approach was later reused in [BIP 66](/protocol/forks/bip-0066) and [BIP 65](/protocol/forks/bip-0065), which further removed nVersions 2 and 3 as valid options. As will be shown further, this is unnecessary.
|
||||
|
||||
## Specification
|
||||
|
||||
Each soft fork deployment is specified by the following per-chain parameters (further elaborated below):
|
||||
|
||||
1. The **name** specifies a very brief description of the soft fork, reasonable for use as an identifier. For deployments described in a single BIP, it is recommended to use the name "bipN" where N is the appropriate BIP number.
|
||||
2. The **bit** determines which bit in the nVersion field of the block is to be used to signal the soft fork lock-in and activation. It is chosen from the set {0,1,2,...,28}.
|
||||
3. The **starttime** specifies a minimum median time past of a block at which the bit gains its meaning.
|
||||
4. The **timeout** specifies a time at which the deployment is considered failed. If the median time past of a block >= timeout and the soft fork has not yet locked in (including this block's bit state), the deployment is considered failed on all descendants of the block.
|
||||
|
||||
### Selection guidelines
|
||||
|
||||
The following guidelines are suggested for selecting these parameters for a soft fork:
|
||||
|
||||
1. **name** should be selected such that no two softforks, concurrent or otherwise, ever use the same name.
|
||||
2. **bit** should be selected such that no two concurrent softforks use the same bit.
|
||||
3. **starttime** should be set to some date in the future, approximately one month after a software release date including the soft fork. This allows for some release delays, while preventing triggers as a result of parties running pre-release software.
|
||||
4. **timeout** should be 1 year (31536000 seconds) after starttime.
|
||||
|
||||
A later deployment using the same bit is possible as long as the starttime is after the previous one's
|
||||
timeout or activation, but it is discouraged until necessary, and even then recommended to have a pause in between to detect buggy software.
|
||||
|
||||
### States
|
||||
|
||||
With each block and soft fork, we associate a deployment state. The possible states are:
|
||||
|
||||
1. **DEFINED** is the first state that each soft fork starts out as. The genesis block is by definition in this state for each deployment.
|
||||
2. **STARTED** for blocks past the starttime.
|
||||
3. **LOCKED_IN** for one retarget period after the first retarget period with STARTED blocks of which at least threshold have the associated bit set in nVersion.
|
||||
4. **ACTIVE** for all blocks after the LOCKED_IN retarget period.
|
||||
5. **FAILED** for one retarget period past the timeout time, if LOCKED_IN was not reached.
|
||||
|
||||
### Bit flags
|
||||
|
||||
The nVersion block header field is to be interpreted as a 32-bit little-endian integer (as present), and bits are selected within this integer as values (1 << N) where N is the bit number.
|
||||
|
||||
Blocks in the STARTED state get an nVersion whose bit position bit is set to 1. The top 3 bits of such blocks must be
|
||||
001, so the range of actually possible nVersion values is [0x20000000...0x3FFFFFFF], inclusive.
|
||||
|
||||
Due to the constraints set by BIP 34, BIP 66 and BIP 65, we only have 0x7FFFFFFB possible nVersion values available.
|
||||
This restricts us to at most 30 independent deployments. By restricting the top 3 bits to 001 we get 29 out of those
|
||||
for the purposes of this proposal, and support two future upgrades for different mechanisms (top bits 010 and 011).
|
||||
When a block nVersion does not have top bits 001, it is treated as if all
|
||||
bits are 0 for the purposes of deployments.
|
||||
|
||||
Miners should continue setting the bit in LOCKED_IN phase so uptake is visible, though this has no effect on
|
||||
consensus rules.
|
||||
|
||||
### New consensus rules
|
||||
|
||||
The new consensus rules for each soft fork are enforced for each block that has ACTIVE state.
|
||||
|
||||
### State transitions
|
||||
|
||||

|
||||
|
||||
The genesis block has state DEFINED for each deployment, by definition.
|
||||
|
||||
State GetStateForBlock(block) {
|
||||
if (block.height == 0) {
|
||||
return DEFINED;
|
||||
}
|
||||
|
||||
All blocks within a retarget period have the same state. This means that if
|
||||
floor(block1.height / 2016) = floor(block2.height / 2016), they are guaranteed to have the same state for every
|
||||
deployment.
|
||||
|
||||
if ((block.height % 2016) != 0) {
|
||||
return GetStateForBlock(block.parent);
|
||||
}
|
||||
|
||||
Otherwise, the next state depends on the previous state:
|
||||
|
||||
switch (GetStateForBlock(GetAncestorAtHeight(block, block.height - 2016))) {
|
||||
|
||||
We remain in the initial state until either we pass the start time or the timeout. GetMedianTimePast in the code below
|
||||
refers to the median nTime of a block and its 10 predecessors. The expression GetMedianTimePast(block.parent) is
|
||||
referred to as MTP in the diagram above, and is treated as a monotonic clock defined by the chain.
|
||||
|
||||
case DEFINED:
|
||||
if (GetMedianTimePast(block.parent) >= timeout) {
|
||||
return FAILED;
|
||||
}
|
||||
if (GetMedianTimePast(block.parent) >= starttime) {
|
||||
return STARTED;
|
||||
}
|
||||
return DEFINED;
|
||||
|
||||
After a period in the STARTED state, if we're past the timeout, we switch to FAILED. If not, we tally the bits set,
|
||||
and transition to LOCKED_IN if a sufficient number of blocks in the past period set the deployment bit in their
|
||||
version numbers. The threshold is ≥1916 blocks (95% of 2016), or ≥1512 for testnet (75% of 2016).
|
||||
The transition to FAILED takes precedence, as otherwise an ambiguity can arise.
|
||||
There could be two non-overlapping deployments on the same bit, where the first one transitions to LOCKED_IN while the
|
||||
other one simultaneously transitions to STARTED, which would mean both would demand setting the bit.
|
||||
|
||||
Note that a block's state never depends on its own nVersion; only on that of its ancestors.
|
||||
|
||||
case STARTED:
|
||||
if (GetMedianTimePast(block.parent) >= timeout) {
|
||||
return FAILED;
|
||||
}
|
||||
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;
|
||||
|
||||
After a retarget period of LOCKED_IN, we automatically transition to ACTIVE.
|
||||
|
||||
case LOCKED_IN:
|
||||
return ACTIVE;
|
||||
|
||||
And ACTIVE and FAILED are terminal states, which a deployment stays in once they're reached.
|
||||
|
||||
case ACTIVE:
|
||||
return ACTIVE;
|
||||
|
||||
case FAILED:
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
**Implementation**
|
||||
|
||||
It should be noted that the states are maintained along block chain
|
||||
branches, but may need recomputation when a reorganization happens.
|
||||
|
||||
Given that the state for a specific block/deployment combination is completely determined by its ancestry before the
|
||||
current retarget period (i.e. up to and including its ancestor with height block.height - 1 - (block.height % 2016)),
|
||||
it is possible to implement the mechanism above efficiently and safely by caching the resulting state of every multiple-of-2016
|
||||
block, indexed by its parent.
|
||||
|
||||
### Warning mechanism
|
||||
|
||||
To support upgrade warnings, an extra "unknown upgrade" is tracked, using the "implicit bit" mask = (block.nVersion & ~expectedVersion) != 0. Mask will be non-zero whenever an unexpected bit is set in nVersion. Whenever LOCKED_IN for the unknown upgrade is detected, the software should warn loudly about the upcoming soft fork. It should warn even more loudly after the next retarget period (when the unknown upgrade is in the ACTIVE state).
|
||||
|
||||
### getblocktemplate changes
|
||||
|
||||
The template request Object is extended to include a new item:
|
||||
|
||||
**template request**
|
||||
|
||||
| Key | Required | Type | Description |
|
||||
|------|-----------|-------|---------------|
|
||||
| rules | No | Array of Strings | list of supported softfork deployments, by name |
|
||||
|
||||
The template Object is also extended:
|
||||
|
||||
**template**
|
||||
|
||||
| Key | Required | Type | Description |
|
||||
|------|-----------|-------|---------------|
|
||||
| rules | Yes | Array of Strings | list of softfork deployments, by name, that are active state |
|
||||
| vbavailable | Yes | Object | set of pending, supported softfork deployments; each uses the softfork name as the key, and the softfork bit as its value |
|
||||
| vbrequired | No | Number | bit mask of softfork deployment version bits the server requires enabled in submissions |
|
||||
|
||||
The "version" key of the template is retained, and used to indicate the server's preference of deployments.
|
||||
If versionbits is being used, "version" MUST be within the versionbits range of [0x20000000...0x3FFFFFFF].
|
||||
Miners MAY clear or set bits in the block version WITHOUT any special "mutable" key, provided they are listed among the template's "vbavailable" and (when clearing is desired) NOT included as a bit in "vbrequired".
|
||||
|
||||
Softfork deployment names listed in "rules" or as keys in "vbavailable" may be prefixed by a '!' character.
|
||||
Without this prefix, GBT clients may assume the rule will not impact usage of the template as-is; typical examples of this would be when previously valid transactions cease to be valid, such as BIPs [16](/protocol/forks/bip-0016), [65](/protocol/forks/bip-0065), [66](/protocol/forks/bip-0066), [68](/protocol/forks/bip-0068), [112](/protocol/forks/bip-0112), and [113](/protocol/forks/bip-0113).
|
||||
If a client does not understand a rule without the prefix, it may use it unmodified for mining.
|
||||
On the other hand, when this prefix is used, it indicates a more subtle change to the block structure or generation transaction; examples of this would be BIP 34 (because it modifies coinbase construction) and 141 (since it modifies the txid hashing and adds a commitment to the generation transaction).
|
||||
A client that does not understand a rule prefixed by '!' must not attempt to process the template, and must not attempt to use it for mining even unmodified.
|
||||
|
||||
## Support for future changes
|
||||
|
||||
The mechanism described above is very generic, and variations are possible for future soft forks. Here are some ideas that can be taken into account.
|
||||
|
||||
**Modified thresholds**
|
||||
|
||||
The 1916 threshold (based on in BIP 34's 95%) does not have to be maintained for eternity, but changes should take the effect on the warning system into account. In particular, having a lock-in threshold that is incompatible with the one used for the warning system may have long-term effects, as the warning system cannot rely on a permanently detectable condition anymore.
|
||||
|
||||
**Conflicting soft forks**
|
||||
At some point, two mutually exclusive soft forks may be proposed. The naive way to deal with this is to never create software that implements both, but that is making a bet that at least one side is guaranteed to lose. Better would be to encode "soft fork X cannot be locked-in" as consensus rule for the conflicting soft fork - allowing software that supports both, but can never trigger conflicting changes.
|
||||
|
||||
**Multi-stage soft forks**
|
||||
Soft forks right now are typically treated as booleans: they go from an inactive to an active state in blocks. Perhaps at some point there is demand for a change that has a larger number of stages, with additional validation rules that get enabled one by one. The above mechanism can be adapted to support this, by interpreting a combination of bits as an integer, rather than as isolated bits. The warning system is compatible with this, as (nVersion & ~nExpectedVersion) will always be non-zero for increasing integers.
|
||||
|
||||
## Rationale
|
||||
|
||||
The failure timeout allows eventual reuse of bits even if a soft fork was
|
||||
never activated, so it's clear that the new use of the bit refers to a
|
||||
new BIP. It's deliberately very coarse-grained, to take into account
|
||||
reasonable development and deployment delays. There are unlikely to be
|
||||
enough failed proposals to cause a bit shortage.
|
||||
|
||||
The fallow period at the conclusion of a soft fork attempt allows some
|
||||
detection of buggy clients, and allows time for warnings and software
|
||||
upgrades for successful soft forks.
|
||||
|
||||
## Deployments
|
||||
|
||||
~~A living list of deployment proposals can be found [here](https://github.com/bitcoin/bips/blob/master/bip-0009/assignments.mediawiki)~~.
|
||||
|
||||
## Copyright
|
||||
|
||||
This document is placed in the public domain.
|
||||
@@ -0,0 +1,205 @@
|
||||
# CHIP: Multiple OP_RETURNs for Bitcoin Cash
|
||||
|
||||
Title: Multiple OP_RETURNs for Bitcoin Cash
|
||||
First Submission Date: 2021-03-12
|
||||
Owner: Benjamin Scherrey @proteusguy on Telegram
|
||||
Authors: Benjamin Scherrey
|
||||
Earlier concept - Jonathan Silverblood
|
||||
Technical spec - BigBlockIfTrue
|
||||
Type: Technical
|
||||
Is consensus change: No
|
||||
Status: FINAL
|
||||
Last Edit Date: 2021-05-17
|
||||
|
||||
This CHIP was included in [HF-20210515](/protocol/forks/hf-20210515).
|
||||
|
||||
## Discussions
|
||||
|
||||
[CHIP Discussion at Bitcoincashresearch.org](https://bitcoincashresearch.org/t/multiple-op-returns-this-time-for-real/315)
|
||||
|
||||
[Issues/PRs for this CHIP](https://github.com/ActorForth/Auction-Protocol/issues)
|
||||
|
||||
Our team is available for chat on the [ActorForth gitter](https://gitter.im/ActorForth/community).
|
||||
|
||||
## Summary
|
||||
|
||||
We propose to make presence of multiple OP_RETURN outputs qualify as standard transactions subject to the existing 223 byte limit for OP_RETURNs across all outputs of the transaction. We are silent in this proposal as to whether or not the [223 byte limit](https://github.com/bitcoincashorg/bitcoincash.org/blob/1b2008d3ac2b30a2ab26193dc8d3652fc33fb798/spec/may-2018-hardfork.md) is the correct one for BCH but are content to leave that alone in order to improve the chances of getting consensus for this change for the May 2021 fork. This makes the impact on nodes and miners as minimal and risk-free as possible while allowing developers to use OP_RETURN in a manner that justifies its core benefit - experimentation of new features/protocol updates without breaking existing systems or stressing the block chain with extraneous UTXOs which is an undesirable alternative option should this improvement not be accepted.
|
||||
|
||||
## Motivation and Benefits
|
||||
|
||||
Quite early in Bitcoin history, attempts to inject miscellaneous data into the block chain were made that made correct parsing and identification of transactions more difficult but, most importantly, bloated the UTXOs with superfluous data that potentially had a very real negative impact on operators of nodes, miners, and wallet users. The introduction of OP_RETURN with a restricted size limit that was deemed unspendable by the protocol was the compromise that protected everyone's interests. Allowing this data to be inserted but then also ignored by all who didn't care about it gave BCH developers an excellent tool in which to try out development ideas and protocol improvements in an isolated manner without introducing backwards or forward incompatibilities. Perhaps more importantly, it gave the entire BCH community an experimental model that allowed a natural maturity for protocol proposals to mature informed by actual use on the block chain rather than depend entirely on theoretical opinions on how such a protocol change might impact the BCH chain. SLP is an excellent example of such a circumstance where, after considerable efforts and real-life trials have been made, has resulted in serious proposals such as OP_GROUP to be able to be realistically considered for incorporation into the core protocol with significantly less risk than would otherwise have been possible.
|
||||
|
||||
The primary limitation of OP_RETURN is that the protocol standard only allows for one instance of an OP_RETURN output per transaction which means developers who want to build on top of other OP_RETURN utilizing capabilities must either create complex parsing scripts or divide their efforts across multiple transactions. Both of these options introduce incredible complexity and often are simply not viable for demonstrating a real-world use case for how the feature would behave on the BCH chain should it be incorporated into the core protocol.
|
||||
|
||||
This proposal aims to correct this minor oversight in order to bring the full potential of OP_RETURN's experimental expressiveness to the BCH chain without incurring any additional trade-offs that were part of its original design.
|
||||
|
||||
The benefits of this proposal also reach users and businesses in drastically reducing foodprint when dealing with several OP_RETURN for their given use cases. Users will be able to use OP_RETURN space more efficiently, pack information in fewer transactions, use less space in mined blocks and save fees while mempool will see fewer congestions –for this specific cause.
|
||||
|
||||
## Specification
|
||||
|
||||
The only technical elements we've identified are changes to the existing node systems to remove the limit of a single OP_RETURN and to enforce the existing size limit for OP_RETURN based outputs across all aggregate OP_RETURN outputs in the transaction.
|
||||
|
||||
Formally, we set the rules as follows:
|
||||
|
||||
* An OP_RETURN output is an output with a locking script consisting of the OP_RETURN opcode followed by zero or more data pushes.
|
||||
* A transaction is non-standard if the total byte size of the locking scripts of all OP_RETURN outputs is greater than 223.
|
||||
* While the [BIP113](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki) median time is less than 1621080000 (2021-05-15T12:00:00Z), a transaction is also non-standard if the number of OP_RETURN outputs is greater than one.
|
||||
|
||||
Some remarks:
|
||||
|
||||
* The size of the locking script is not just the raw data size, but includes the OP_RETURN opcode and the data push opcodes. In case of a single OP_RETURN output, only up to 220 bytes of data can be stored, because you need 1 byte for the OP_RETURN opcode, 1 byte for the OP_PUSHDATA1 opcode, and 1 byte for the length of the data. More bytes are lost if there is more than one data push operation, e.g. when the [4-byte prefix guideline](https://upgradespecs.bitcoincashnode.org/op_return-prefix-guideline/) is followed.
|
||||
* In case of a single OP_RETURN output, the rules are identical to the status quo.
|
||||
* In the extreme case, the rules imply a maximum of 223 OP_RETURN outputs, because the locking script of every OP_RETURN output is at least one byte (the OP_RETURN opcode itself).
|
||||
|
||||
## Current Implementations
|
||||
|
||||
* [Full implementation of the rules in Bitcoin Cash Node, including activation logic](https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1115).
|
||||
* [Implementation of the rules in Flowee, without activation logic](https://gitlab.com/FloweeTheHub/thehub/-/blob/master/libs/server/policy/policy.cpp) (allows multiple outputs immediately instead of only after 2021-05-15T12:00:00Z).
|
||||
|
||||
Both implementations introduce `"oversize-op-return"` as a new standardness error code, besides the existing `"multi-op-return"` error which becomes obsolete after multiple OP_RETURN outputs are allowed. In both implementations, the number 223 used in the rules can be overridden with the `-datacarriersize=<n>` command-line option.
|
||||
|
||||
* [Implementation of the rules in Bitcoin Unlimited, without activation logic](https://gitlab.com/bitcoinunlimited/BCHUnlimited/-/merge_requests/2453).
|
||||
|
||||
|
||||
## Implementation Costs and Risks
|
||||
|
||||
Evaluating the changes required across the popular nodes demonstrates that the impact in terms of lines of code affected are minor and isolated. For Bitcoin Unlimited there's an existing check that only one OP_RETURN exists which can be removed. A mechanism for counting the aggregate size of all the OP_RETURNs is quite simple to introduce in the same source file. Unit tests would be approximately twice the implementation size which we find typical of well designed C++ code.
|
||||
|
||||
APIs that want to support multiple OP_RETURN are also easy to modify.
|
||||
|
||||
## Ongoing Costs and Risks
|
||||
|
||||
After the initial changes are made to the core node systems no ongoing costs are anticipated. Risks are restricted to other non-standard experimental development code that may depend/demand that there only be a single OP_RETURN but, unless the code serves some purpose such as a linter or tx compliance tool, it's unlikely that such code was appropriate in the first place.
|
||||
|
||||
Presently the [SLP specification](https://github.com/simpleledger/slp-specifications/blob/master/slp-token-type-1.md#consensus-rules) requires its OP_RETURN to be at vout[0]. Any protocol code seeking to co-exist with SLP would want to ensure that it be in a later output to appear in the transaction in order to prevent accidental conflicts. We recommend that OP_RETURN based protocols no longer specify a positional requirement for their data but, instead, establish another mechanism for identifying which OP_RETURN belongs to them.
|
||||
|
||||
Now that the limit of a single OP_RETURN has been removed, future well behaved development utilizing OP_RETURN would no longer be designed with such a presumption in mind.
|
||||
|
||||
### Design & Implementation Process Timeline
|
||||
|
||||
2020-09-21 [Initial comment on bitcoincashresearch.org](https://bitcoincashresearch.org/t/2021-bch-upgrade-items-brainstorm/130/23).
|
||||
|
||||
2020-10-14 [Trial implementation of proposal on Bitcoin Unlimited node](https://github.com/ActorForth/BitcoinUnlimited/commit/fd10cbd9872b157d906a03d3a4ccf7c0ddd42c65). (note: this doesn't implement aggregate size limit)
|
||||
|
||||
2020-10-?? Trial modifications to a [test fork of the Javascript bch-js API](https://github.com/ActorForth/bch-js) and the python Bitcash API libraries (currently in a private repo) completed.
|
||||
|
||||
2021-02-24 [Proposal to be introduced for the May 2021 fork](https://bitcoincashresearch.org/t/multiple-op-returns-this-time-for-real/315).
|
||||
|
||||
2021-03-21 This CHIP created.
|
||||
|
||||
2021-03-24 Proposed completion for PRs to public Bitcoin Unlimited, Bitcoin Cash Node, bch-js API, and Bitcash API projects to support this CHIP. Basically T+9 days after proposal is approved.
|
||||
|
||||
2021-03-13 [Flowee PR](https://gitlab.com/FloweeTheHub/thehub/-/commit/a9d3c2ee9279f2aa46890d74ce26f6e252623e72), [2](https://gitlab.com/FloweeTheHub/thehub/-/commit/45dd785f3916caa336a628d879dc7228fb73e520) support implemented by Tom Zander.
|
||||
|
||||
2021-03-14 [BCHN PR](https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1115) support implemented by BigBlockIfTrue.
|
||||
|
||||
2021-03-25 [Bitcoin Unlimited PR](https://gitlab.com/bitcoinunlimited/BCHUnlimited/-/merge_requests/2453) support implemented by Nicolai Skye.
|
||||
|
||||
2021-05-15 Deployment to BCH Mainnet Chain
|
||||
|
||||
## Evaluation of Alternatives
|
||||
|
||||
Alternatives to this proposal amount to restating original alternatives to OP_RETURN (such as the multi-sig data hack), introducing complex parsing requirements to OP_RETURN outputs, or dividing OP_RETURN dependent submissions across multiple transactions. All are more complex and risky than this proposal.
|
||||
|
||||
Jonathan Silverblood identified 3 other alternative proposals considered in 2020, [BUIP149: Delimited OP_RETURNs](https://bitco.in/forum/threads/buip149-delimited-op_returns.26362/), [BUIP139](https://bitco.in/forum/threads/buip139-multiple-op_return-with-less-rules.24951/), and [BUIP140](https://bitco.in/forum/threads/buip140-multiple-op_return-with-shared-size-limit.24952/).
|
||||
|
||||
BUIP149 puts multiple OP_RETURNs in a single output and requires complex parsing scripts and potentially could collide with existing protocols using OP_RETURNs already including SLP. It also proposes to change the maximum size of OP_RETURN data in a transaction. Community efforts to incorporate this option are significantly higher than this CHIP.
|
||||
|
||||
BUIP139 is actually quite similar to this CHIP except it proposes that there be some fixed limit to the number of OP_RETURNs. One reason why BUIP139 should be considered inferior is because it makes it more difficult to change the op_return max bytes in the future, as it would magnify the impact, for example:
|
||||
|
||||
If BUIP139 took place, and was set to 4 op_returns / transaction, then if we want to change the byte size it now has to be an even number of 4. If we naively increase by 10 bytes, then a total of 40 more bytes can be used, rather than the 10 byte intended.
|
||||
|
||||
BUIP140 is similar to this CHIP but was just not taken forward. Major difference is that it debates or introduces the explicit possibility of increasing the total size of OP_RETURN data but does not require it.
|
||||
|
||||
Without the aggregate size consideration, the future impact of changing the legal sizes of OP_RETURN becomes more profound and possibly difficult to predict but saves tx creators from having to track a total across all OP_RETURNs. The opinion of the author is that the days of being able to consider parts of transactions independent of others are long gone so this is not a meaningful shortcoming. Size reductions would be profound and dangerous changes and are unlikely to be practical to deploy. Size increases should be based on empirical demonstrations of value through experimental apps that push these limits while demonstrating real value to the BCH ecosystem. Regardless of the ultimate size, having that quantity come from a shared pool helps allow OP_RETURN based protocols to be expressed naturally in a manner more closely resembling what their ultimate core protocol implementations would look like rather than having to perform hacks to fit within a per-OP_RETURN limit that would necessarily be smaller. Again these are future considerations outside of the direct scope of this CHIP.
|
||||
|
||||
## List of Major Stakeholders
|
||||
|
||||
|
||||
## Statements
|
||||
|
||||
### Full node developers
|
||||
|
||||
from Tom Zander, owner [Flowee](https://flowee.org)
|
||||
|
||||
> This change will have little to no cost on our ecosystem while enabling more usecases to be added over time, to be developed without touching consensus rules in the traditional permissionless manner. I fully support this proposal and have code ready to ship for this.
|
||||
|
||||
from freetrader, lead maintainer of Bitcoin Cash Node
|
||||
|
||||
> This is a simple and logical change that provides more flexibility for OP_RETURN users without affecting the trade-offs associated with the limit. The proposal has been implemented in a BCHN change request and a majority of BCHN maintainers supports activating this change on 15 May 2021.
|
||||
|
||||
> While this CHIP arrived at a fairly late moment, we believe that sufficient awareness has been raised such that it can nevertheless be activated in May provided all major full node clients can implement it by then.
|
||||
|
||||
### Major businesses
|
||||
|
||||
from Benjaim Scherrey
|
||||
|
||||
> My company, [Biggest Fan Productions](https://biggestfan.net), has developed a [protocol](https://github.com/ActorForth/Auction-Protocol/blob/main/proposal-spec.md) that utilizes SLP NFTs & FTs to perform on-chain tracked open call auctions for assets such as concert tickets. To fully be able to represent the state of the auction in a trustless manner it requires an additional OP_RETURN to be allowed in BCH transactions. This is notice of my support and personal interest in this CHIP.
|
||||
|
||||
### Miners and pools
|
||||
|
||||
I have sought out contacts for such organizations and have received no responses. Appreciate any follow up on contacting these entities.
|
||||
|
||||
### Wallets and clients
|
||||
|
||||
I have sought out contacts for such organizations and have received few responses. Appreciate any follow up on contacting these entities.
|
||||
|
||||
An ElectronCash SLP wallet dev had no strong opinion on this CHIP (or the CHIP process) and registered no objection when asked.
|
||||
|
||||
### Application Developers
|
||||
|
||||
from Jonathan Silverblood:
|
||||
|
||||
> I believe multiple OP_RETURNs should be adopted, it is highly valuable as it makes it possible for OP_RETURN based protocols to work together to create value. I also believe that counting the aggregate number of bytes is in line with the intent of the original functionality.
|
||||
|
||||
from Joey Masterpig
|
||||
|
||||
> I would like to add my support to this proposal as a Stakeholder. Founder of the upcoming SLP NFT game enter-the-sphere.com . Co-Founder of Spice Token, and a Director of the SLP Foundation.
|
||||
|
||||
> I believe having multiple_opreturns will add some interesting possibilities for NFTs for Enter The Sphere, our token solution needs to be as competitive as possible, and anything that expands the chance of something innovative being done on SLP, is something I support.
|
||||
|
||||
> As I understand, implementation of this change will allow multiple assets to be on a single tx, something that can be very useful for pairing NFTs with other assets. A function that allows us to link NFT items with other assets easier than current.
|
||||
|
||||
> This is my personal opinion and support as a non-technical stakeholder, this is not a technical endorsement nor have i reviewed deeply about whether these changes have cons on a technical basis (as far as I understand there is none).
|
||||
|
||||
Stoyan Zhekov, bch-js developer
|
||||
|
||||
> I think Multiple OP_RETURN CHIP will provide a way for better NFTs - both NFT (SLP) payload and BCP payload can be parts of one transaction, which will reduce the number of queries to retrieve the external content.
|
||||
|
||||
### Users
|
||||
|
||||
from Leandro Di Marco
|
||||
|
||||
> I see this initiative with great value for users, who will engage with the OP_RETURN resource more efficiently. And while such optimization would seem samll at the moment, it will surely become more relevant as Bitcoin Cash grows in adoption.
|
||||
|
||||
## Copyright
|
||||
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2018, 2020 Benjamin Scherrey, BiggestFan Productions Co. Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,141 @@
|
||||
# CHIP: Unconfirmed Transaction Chain Limit
|
||||
|
||||
This CHIP was included in [HF-20210515](/protocol/forks/hf-20210515).
|
||||
|
||||
## Authors
|
||||
|
||||
**CHIP Owner:**
|
||||
Josh Green, Software Verde
|
||||
|
||||
**Contributors:**
|
||||
|
||||
John Jamiel, Software Verde
|
||||
Doug McCollough, City of Dublin, OH
|
||||
Emil Oldenburg, Bitcoin.com
|
||||
Roger Ver, Bitcoin.com
|
||||
Mark Lamb, CoinFLEX
|
||||
|
||||
## Summary
|
||||
**Version 1.2.1**
|
||||
|
||||
When a transaction is first transmitted on the Bitcoin Cash network, it is considered “unconfirmed” until it is “mined” into a block. These transactions that are not yet mined are also referred to as “zero-conf” transactions. Transactions are dependent upon other transactions, such that they are chained together; the value allocated by one transaction is then spent by a subsequent transaction.
|
||||
|
||||
Currently, the Bitcoin Cash network only permits transactions to be chained together 50 times before a block must include them. Transactions exceeding the 50th chain are often ignored by the network, despite being valid. Once a transaction is submitted to the network, it cannot be revoked. This situation, when encountered, can be extremely difficult to remedy with today’s available tools and simultaneously creates an unnecessary amount of complexity when being accounted for by network and applications developers. This CHIP is a formal request to remove the unconfirmed transaction chain limit=depth (50tx) and size (101kb) entirely from the Bitcoin Cash ecosystem.
|
||||
|
||||
**Discussion URL:** https://bitcoincashresearch.org/t/chip-unconfirmed-transaction-chain-limit/302/32
|
||||
|
||||
**Full Change History URL:** https://github.com/softwareverde/bitcoin-cash-chips/blob/master/unconfirmed-transaction-chain-limit.md
|
||||
|
||||
|
||||
## Motivations
|
||||
|
||||
Transactions exceeding the unconfirmed transaction chaining limit are often ignored by the network, despite being considered a valid transaction. For these transactions, this leaves the value transferred in an ambiguous state: it has been transferred, but some (or all) of the network may not record this transfer. Once value has been transferred by a transaction, the balance may not be distributed in a different proportion or to a separate receiver (often known as a “double-spend”) due to the network’s convention to prefer the first-seen transfer rather than the newer transfer. Therefore, the only viable path forward in this scenario is to transmit the same (perfectly identical) transaction again to the network. However, if the wallet or service is connected to peers that accepted the transaction, rebroadcasting the same transaction does not cause the connected peers to retransmit it themselves--causing the transaction to be stuck with no recourse other than hoping to connect to a new peer that has not yet seen the transaction. For this reason, it is important that all nodes agree on the unconfirmed transaction chain limit.
|
||||
|
||||
Additionally, determining if the transaction was not accepted by the network is a difficult to solve problem with the current available toolset. Error-responses from nodes rejecting a transaction have not been standardized, and often times nodes will silently reject the transaction--sometimes the node may not even be aware that the transaction is invalid because its dependent has not been seen yet, and the node itself cannot determine the transaction’s chain depth.
|
||||
|
||||
It is also not always known to the user, service, or wallet how deep the unconfirmed transaction already is when it’s received; it’s entirely possible the coins received are at the limit, and determining that state can be near-impossible without the help of a full-node.
|
||||
|
||||
The problem from a user/app’s perspective is that they have created a valid transaction and are given little indication that it will not be mined within a block. The tools for recourse are limited, and the tools for monitoring for such a situation is also limited.
|
||||
|
||||
|
||||
The unconfirmed transaction chain limit is mostly an artifact of a relatively unused feature heldover from artificially restricting block size, a feature called “Child Pays for Parent”. According to research conducted by Tom Zander found [here](https://flowee.org/news/2020-07-cpfp-research/), there is very limited usage of CPfP on the BCH network. In short, in his 3 months of monitoring network activity there were only 7 valid use cases where CPfP was used to lift the transaction above the 1-sat-per-byte. This feature is not used in BCH yet still restricts the user experience and increases the complexity of development of wallets and applications built on top of Bitcoin Cash.
|
||||
|
||||
Issues with transaction chaining are exacerbated by the long block times periodically seen in Bitcoin Cash, the causes of which have been discussed elsewhere and were a major motivating factor in switching to the ASERT difficult adjustment algorithm. Having a static transaction chaining limit while blocks somewhat frequently take over an hour (or even two hours) to be mined, results in a scenario where transactions could be significantly more at risk than normal. Note, though, that even without these extenuating circumstances, this is always a risk with the proof of work system.
|
||||
|
||||
Given the motivations for implementing the transaction chaining limit are largely no longer relevant, the lack of sufficient tooling to allow SPV clients to account for it, and its poor interaction with the current semantics of transaction relaying, it appears that the transaction chaining limit provides little value while simultaneously increasing the difficulty of transacting on the Bitcoin Cash network.
|
||||
|
||||
**Personal Impacts**
|
||||
|
||||
During a Dublin Identity beta test with real users, an issue occurred causing sign-ups to periodically fail. After investigation, it was identified that users’ transactions from the server used to fund SLP token transfers were not being accepted by the network due to the transaction chain limit being enforced. This problem has since been mitigated by the limit being increased to 50, along with some process changes.
|
||||
|
||||
CoinFLEX uses SLP to distribute FLEX token dividends to its users. The server distributes these dividends periodically, via chaining transactions. These distributions were found to periodically fail due to reaching the unconfirmed transaction chaining limit. CoinFLEX is mitigating this problem by using multiple UTXOs to spawn the chains, however their large user base and small limit of 50 transactions per UTXO, are causing disproportionate complexity within their system. Raising the limit combined with increasing the base number of originating UTXOs helps to limit backend complexity. Removing the limit would remove significant complexity for rejection edge-cases where a rejection was unable to be determined or was left unnoticed.
|
||||
|
||||
During Bitcoin Cash meetups it is not uncommon for users of the Bitcoin.com wallet to make more than 50 transactions within the timespan of a block, especially due to the encouraged behavior of brand-new users to transfer their BCH to other members of the meetup to “try it out”. The user experience and “wow” factor of the technology is quickly doused when a new user’s transaction fails to send because their received UTXO is deeply chained. Varying block times exacerbates this problem.
|
||||
|
||||
Software Verde has developed multiple applications that create and distribute transactions across the BCH network. Managing multiple UTXO pools in order to handle appropriately scaling is doable but creates additional unwanted complexity. While transactions will likely never completely be “fire and forget” on BCH, creating a balance with a larger buffer (i.e. supporting a longer chain limit) and having better available tools would allow us to produce applications more reliably and for less cost, facilitating the adoption of Bitcoin Cash to businesses and enterprises.
|
||||
|
||||
|
||||
## Technical Description
|
||||
|
||||
The current policy limit of 50 unconfirmed ancestors or descendants, and the 101kb chain limit, is to be removed entirely once MTP >= 1621080000 and this limit removal remains in affect even in the case of a subsequent re-org to below that MTP.
|
||||
|
||||
|
||||
## Security Considerations
|
||||
|
||||
Uncoordinated changes to mempool rules would likely result in a degradation of 0-conf transaction security. 0-conf transaction security is dependent on the network’s solution to circumventing double-spends. If nodes do not agree to enforce the same limits, merchants accepting transactions that have exceeded the unconfirmed transaction chaining limit would be at an increased risk of encountering and accepting a double-spend transaction.
|
||||
|
||||
Example: A malicious user submits a transaction exceeding the current chaining limit, knowing the merchant is connected to a node that does not enforce the limit. The node accepts this transaction as it is considered valid and the merchant believes they’ve received a payment from a valid 0-conf transaction. Due to its unconfirmed chain depth, for this transaction to propagate the node in question must wait to broadcast the transaction to its peers until after a new block has been found. During this time a malicious user could prepare a second transaction spending the same coin. If submitted immediately after the new block has been found the two transactions will be in a race. Since the first transaction has not yet been broadcast to the rest of the network, there is an increased likelihood the second transaction could be seen by the majority of the network before the first transaction has had an opportunity to propagate. This situation is exacerbated if the node accepting the longer unconfirmed chain depth transaction does not also re-relay the transaction after a new block is mined that does not contain the transaction.
|
||||
|
||||
|
||||
## Implementation Costs and Risks
|
||||
|
||||
From our research and discussions removal of the Unconfirmed Transaction Chain Limit does not present any apparent risks if conducted in a coordinated manner and presents zero risk of a network split. According to the research conducted by developer FreeTrader of BCHN, there is no apparent loss of performance in BCHN with the limit removed. However, if changes to the mempool rules are not coordinated by the different node implementations, 0-conf transaction facility and security will likely suffer.
|
||||
|
||||
Costs associated with implementing this change are hard to encapsulate in this proposal. At a minimum, this CHIP recognizes there is an operational burden that coordinated network upgrades place on node developers and users. Overall, this change will require a non-negligible amount of development time to implement, translating to a cost of labor, of which is bound to vary depending on the full-node implementation and route to resolution.
|
||||
|
||||
Additionally, the cost of investigating solutions for the unconfirmed transaction chaining limit have been significant for those who have undertaken the task. Based on an informal survey of BU and BCHN members, General Protocols has estimated approximately 500 engineering hours have been invested in development and general investigation of increasing the chained tx limit. This commitment of hours has been useful to understand the potential limitations bounding the limit from being completely removed. After thorough investigation, no ill effect on performance has been found.
|
||||
|
||||
|
||||
## Evaluation of Alternatives
|
||||
|
||||
If it is deemed necessary to keep the unconfirmed transaction chain limit in some capacity then a significantly larger increase to the limit would be a reasonable alternative.
|
||||
|
||||
From our research, there isn’t a resource that becomes exhausted by a deep 0-conf chain. If there is indeed a technical limit, then we would advocate for node-developers to find what a responsible value is for that limit and suggest that here.
|
||||
|
||||
For the purposes of proposing an alternative solution: a 32MB block can hold approximately 135k transactions. This limit could serve as a hypothetical starting point.
|
||||
|
||||
|
||||
## Stakeholders
|
||||
|
||||
Stakeholders relative to this proposal include:
|
||||
|
||||
Full-node implementations
|
||||
Node Developers
|
||||
Wallet Developers
|
||||
Bitcoin Cash related businesses.
|
||||
|
||||
In our previous discussion we have engaged with several key stakeholders to understand their position on the requested change.
|
||||
|
||||
**Stakeholders Engaged in Discussion**
|
||||
|
||||
BCHN
|
||||
Bitcoin Unlimited
|
||||
Bitcoin Verde
|
||||
General Protocols
|
||||
Bitcoin.com
|
||||
Coinflex
|
||||
Flowee
|
||||
General Protocols
|
||||
|
||||
**Stakeholders Position Unknown**
|
||||
|
||||
BCHD
|
||||
Knuth
|
||||
|
||||
## Stakeholders Statements
|
||||
|
||||
Jonathan Silverblood - Casual Wallet
|
||||
>I believe that for money to be useful, it needs to be able to move at low cost and with ease. The current unconfirmed transaction chain limitation is effectively friction that makes Bitcoin Cash less useful as money, and I support a complete removal of the limit.
|
||||
|
||||
John Nieri - General Protocols
|
||||
>GP supports the updated recommendations of this CHIP and commits any reasonable resources toward its realization. There is still room to expand security considerations and costs which are not trivial. Although this is a non-consensus CHIP, the expansion would make it an even better precedent for the high bar that we want to establish in the BCH ecosystem.
|
||||
|
||||
## CHIP Sponsors
|
||||
|
||||
**Software Verde** is a custom software development company based out of Columbus, Ohio, USA that has been in operation since 2011 and working within public and crypto sectors since early 2017. Software Verde has extensive experience working with local governments to promote the adoption of blockchain technology and utilization of cryptocurrencies, and is the author and maintainer of the BCH Full Node, Bitcoin Verde.
|
||||
|
||||
**City of Dublin, OH** is a municipality of approximately 50k residents that has made an investment into the adoption of blockchain technology. In turn, Dublin has built a blockchain-based digital identity management system utilizing BCH SLP tokens as a reward mechanism. In late 2019, Dublin’s identity management project moved into a beta-testing phase where Software Verde was tasked with creating digital IDs for city employees and rewarding them with tokens for their participation.
|
||||
|
||||
**Bitcoin.com** is a provider of Bitcoin Cash related financial services and the owners of the Bitcoin.com wallet, one of Bitcoin Cash’s most popular non-custodial mobile friendly wallets. Their website provides important services such as a cryptocurrency exchange, reporting network related news, and providing information to help influence the growth and adoption of Bitcoin Cash and Bitcoin Cash related businesses.
|
||||
|
||||
**CoinFLEX** is a popular cryptocurrency exchange service as well as the providers of the first Bitcoin Cash futures and lending exchange. CoinFLEX is the primary distributor of Flex Coins, an SLP token used to pay dividends to their users. Their business provides several unique financial services that attract cryptocurrency investors to the network, as well as foster a culture of professional trading within the Bitcoin Cash community.
|
||||
|
||||
## Timeline
|
||||
|
||||
This proposal is low risk and stands to provide high benefit to the network as a whole. In addition, this request is a network-change only and therefore is not at risk of causing a chain split; however, uncoordinated changes to mempool rules by different full-nodes would likely result in a degradation of 0-conf transaction security. For these reasons, it is requested that this change be implemented in a coordinated manner on May 15th.
|
||||
|
||||
Choosing this date in particular is not significant in and of itself, although there seems to be no reason to deviate from history purely for the sake of it.
|
||||
|
||||
## License
|
||||
|
||||
To the extent possible under law, this work has waived all copyright and related or neighboring rights to this work under CC0.
|
||||
@@ -0,0 +1,72 @@
|
||||
# HF-20200515
|
||||
|
||||
layout: specification
|
||||
title: 2020-MAY-15 Network Upgrade Specification
|
||||
date: 2020-04-26
|
||||
category: spec
|
||||
activation: 1589544000
|
||||
version: 0.4
|
||||
|
||||
## Summary
|
||||
|
||||
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is greater than or equal to UNIX timestamp 1589544000 (May 15th, 2020, 12:00PM UTC),
|
||||
Bitcoin Cash will execute an upgrade of the network consensus rules according to this specification.
|
||||
Starting from the next block these consensus rules changes will take effect:
|
||||
|
||||
* Bitcoin Cash's SigOps counting and limiting system is replaced with a new system, referred to as SigChecks.
|
||||
* A new opcode called OP_REVERSEBYTES has been added to the script system.
|
||||
* Enforcement of the Infrastructure Funding Plan, subject to activation by [BIP 9](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki) miner signalling.
|
||||
|
||||
The following are not consensus changes, but are recommended policy changes for Bitcoin Cash implementations:
|
||||
|
||||
* The default for max number of in-mempool ancestors is changed from 25 to 50.
|
||||
* The default for max number of in-mempool descendants is changed from 25 to 50.
|
||||
* Automatic replay protection for future upgrade.
|
||||
|
||||
## SigChecks
|
||||
|
||||
Enforcement of sigops limits is removed, and replaced with new limits based on the number of signature checks that are actually executed when running a script. This new system is called SigChecks.
|
||||
|
||||
Details can be found in the [full specification: SigChecks](/protocol/forks/2020-05-15-sigchecks).
|
||||
|
||||
## OP_REVERSEBYTES
|
||||
|
||||
This new opcode reverses the order of bytes in a string. It can be used to change endianness.
|
||||
|
||||
Details can be found in the [full specification: OP_REVERSEBYTES](/protocol/forks/2020-05-15-op_reversebytes).
|
||||
|
||||
## Infrastructure Funding Plan
|
||||
|
||||
The purpose of the Infrastructure Funding Plan (IFP) is to provide funding to development projects working on common Bitcoin Cash infrastructure.
|
||||
If activated, it enforces that 5% of the block reward is spent to one of a set of specified addresses.
|
||||
Activation is triggered via [BIP 9](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki) version bits signalling prior to the May 15 upgrade.
|
||||
|
||||
More detailed can be found in the [full specification](/protocol/forks/2020-05-15-ifp).
|
||||
|
||||
## Automatic Replay Protection
|
||||
|
||||
The purpose of Automatic Replay Protection is to serve as a full node version-deprecation mechanism. It is intended to cause
|
||||
full validating nodes which do not upgrade, to automatically separate themselves from the main network after the next
|
||||
upgrade on 15 May 2020. Nodes which implement the next upgrade will remove this automatic replay protection, and thus all regular
|
||||
wallets can continue using the default ForkID with no change to follow the main upgraded chain.
|
||||
|
||||
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is less than UNIX timestamp 1605441600 (Nov 2020 upgrade)
|
||||
Bitcoin Cash full nodes MUST enforce the following rule:
|
||||
|
||||
* `forkid` [[2]](#references) to be equal to 0.
|
||||
|
||||
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is greater than or equal to UNIX timestamp 1605441600
|
||||
(Nov 2020 upgrade) Bitcoin Cash full nodes implementing the May 2020 consensus rules SHOULD enforce the following change:
|
||||
|
||||
* Update `forkid` [[2]](#references) to be equal to `0xFFXXXX`, where `XXXX` is some arbitrary hex value.
|
||||
ForkIDs beginning with 0xFF will be reserved for future protocol upgrades.
|
||||
|
||||
This particular consensus rule MUST NOT be implemented by Bitcoin Cash wallet software. Wallets that follow the upgrade
|
||||
should not have to change anything.
|
||||
|
||||
## References
|
||||
|
||||
[1] Median Time Past is described [here](/protocol/blockchain/transaction#median-time-past).
|
||||
It is guaranteed by consensus rules to be monotonically increasing.
|
||||
|
||||
[2] The `forkId` is defined as per the [replay protected sighash](/protocol/forks/replay-protected-sighash) specification.
|
||||
@@ -0,0 +1,67 @@
|
||||
# HF-20201115
|
||||
|
||||
layout: specification
|
||||
title: 2020-NOV-15 Network Upgrade Specification
|
||||
date: 2020-08-15
|
||||
category: spec
|
||||
activation: 1605441600
|
||||
version: 0.1
|
||||
|
||||
## Summary
|
||||
|
||||
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is greater than or equal to UNIX timestamp 1605441600 (Nov 15th, 2020, 12:00PM UTC),
|
||||
Bitcoin Cash will execute an upgrade of the network consensus rules according to this specification.
|
||||
Starting from the next block these consensus rules changes will take effect:
|
||||
|
||||
* Bitcoin Cash's Difficulty Adjustment Algorithm (DAA) is replaced with a new system, referred to as aserti3-2d.
|
||||
* The addition of a new coinbase rule.
|
||||
|
||||
The following are not consensus changes, but are recommended policy changes for Bitcoin Cash implementations:
|
||||
|
||||
* Automatic replay protection for future upgrade.
|
||||
|
||||
## Difficulty Adjustment Algorithm
|
||||
|
||||
Bitcoin Cash's Difficulty Adjustment Algorithm (DAA) is replaced with a new algorithm called [ASERT](http://toom.im/files/da-asert.pdf).
|
||||
|
||||
The specific implementation is called aserti3-2d. Details can be found in the [full specification: ASERT](/protocol/forks/2020-11-15-asert).
|
||||
|
||||
## Coinbase Rule
|
||||
|
||||
The purpose of the new coinbase rule is to provide funding to development projects working on common Bitcoin Cash infrastructure.
|
||||
|
||||
The coinbase rule enforces that at least 8% of the block reward must be spent as a single output to the following Bitcoin Cash address:
|
||||
`bitcoincash:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgnlxww9j9`.
|
||||
|
||||
The amount of the output must be equal to or greater than the integer `required`, calculated as follows using integer math:
|
||||
```
|
||||
required = (8 * blockReward) / 100
|
||||
```
|
||||
|
||||
## Automatic Replay Protection
|
||||
|
||||
The purpose of Automatic Replay Protection is to serve as a full node version-deprecation mechanism. It is intended to cause
|
||||
full validating nodes which do not upgrade, to automatically separate themselves from the main network after the next
|
||||
upgrade on 15 May 2021. Nodes which implement the next upgrade will remove this automatic replay protection, and thus all regular
|
||||
wallets can continue using the default ForkID with no change to follow the main upgraded chain.
|
||||
|
||||
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is less than UNIX timestamp 1621080000 (May 2021 upgrade)
|
||||
Bitcoin Cash full nodes MUST enforce the following rule:
|
||||
|
||||
* `forkid` [[2]](#references) to be equal to 0.
|
||||
|
||||
When the median time past [[1]](#references) of the most recent 11 blocks (MTP-11) is greater than or equal to UNIX timestamp 1621080000
|
||||
(May 2021 upgrade) Bitcoin Cash full nodes implementing the Nov 2020 consensus rules SHOULD enforce the following change:
|
||||
|
||||
* Update `forkid` [[2]](#references) to be equal to `0xFFXXXX`, where `XXXX` is some arbitrary hex value.
|
||||
ForkIDs beginning with 0xFF will be reserved for future protocol upgrades.
|
||||
|
||||
This particular consensus rule MUST NOT be implemented by Bitcoin Cash wallet software. Wallets that follow the upgrade
|
||||
should not have to change anything.
|
||||
|
||||
## References
|
||||
|
||||
[1] Median Time Past is described [here](/protocol/blockchain/transaction#median-time-past).
|
||||
It is guaranteed by consensus rules to be monotonically increasing.
|
||||
|
||||
[2] The `forkId` is defined as per the [replay protected sighash](/protocol/forks/replay-protected-sighash) specification.
|
||||
@@ -0,0 +1,22 @@
|
||||
# HF-20210515
|
||||
|
||||
The May 2021 hard fork was the first to be comprised of [CHIPs](#chips).
|
||||
|
||||
## CHIPs
|
||||
|
||||
A CasH Improvement Proposal (CHIP) is a change request for the Bitcoin Cash protocol.
|
||||
CHIPs can be written and published by any member of the Bitcoin Cash community.
|
||||
They are evaluated publicly, giving the authors an opportunity to make any clarifications or adjustments based on feedback from the rest of the community.
|
||||
Once there is sufficient support for a CHIP amongst node developers, it is scheduled for release in a future hard fork.
|
||||
Changes from multiple CHIPs may be included in a single hard fork.
|
||||
|
||||
Along with the creation of the CHIP system, the expectation of biannual releases was relaxed.
|
||||
If no CHIPs have support, there will be no hard-fork.
|
||||
|
||||
## Contents
|
||||
|
||||
The May 2021 hard fork is comprised the following CHIPs:
|
||||
|
||||
1. [Unconfirmed Transaction Chain Limit](/protocol/forks/chips/2021-05-unconfirmed-transaction-chain-limit)
|
||||
2. [Multiple OP_RETURNs for Bitcoin Cash](/protocol/forks/chips/2021-05-multiple-op-returns-for-bitcoin-cash)
|
||||
|
||||
Reference in New Issue
Block a user