The system for handling soft forks is to increment the block version. Since the BIP66 soft-fork is currently in play (going from version 2 to version 3 blocks), no other soft fork can be considered.
If BIP XYZ used block version 4, then the only options on how to "vote" would be
no soft fork (stay with version 2 blocks)
BIP66 only (go to version 3 blocks)
BIP66 and BIP-XYZ only (go to version 4 blocks)
If there were many soft forks going at the same time, then miners couldn't pick which ones they wanted to vote for.
The proposed solution to this is to change the meaning of the version field in the block header. It would stop being a counter and have each bit acting independently.
Pieter has a new proposal which makes major improvements: every softfork is signaled by a single bit, the when the bit crossed threshold it 'latches' and
becomes available for reuse again, and there is a deadline by which if it fails to latch its aborted and becomes available for use again.
The details don't seem to be available for linking (maybe it was discussed on IRC?)
In the interests of discussion, I will suggest a possible scheme.
The version field is a 4 byte field in the header.
Legacy clients check which rules are in effect by comparing the block version number to a threshold (
link). This means that to maintain backwards compatibility with legacy nodes, future version numbers must be at least 3. This assumes that BIP66 is accepted.
Setting the MSB to 1 guarantees that that the version number is greater than 3.
I suggest the following soft-fork process.
- Discussion/Drafting
- Reference implementation created
- Release of updated software (backports?)
- Nomination and bit allocation
- Consensus measurement
- Activation (>75%)
- Lock and bit deallocation
- (or Rejection)
Discussion/DraftingThis step involves discussions of the merits of the change and the creation of the BIP document.
Reference implementation createdThis step involves adding the code to the reference client with switch logic so that it is disabled unless the BIP is activated.
There could be a soft fork handler that handles the soft forking rules. Soft forks could indicate if they depend on any other soft forks already being accepted. If so, the BIP would do nothing unless its dependencies are also active.
Nomination and bit allocationThe MSB of the version field is used to indicate if the block is nominating a new BIP. The version field is interpreted as follows.
31: not-nominating a soft fork
30-24: version offset
23-2: BIP number
1-0: must be set to 3
bool nominating_header = version & 0x80000000 == 0;
uint8_t offset = (version & 0x7F000000) >> 24;
uint32_t BIP_number = (version & 0x00FFFFFC) >> 2;
uint8_t reserved = version & 0x3; // must be set to 3
When in nomination mode, the version field for the block is copied from a previous block header. The version offset indicates how many blocks to go back. The block uses that block's version field to indicate what bits to use. This can be chained. If the target block header was a nomination header, then it uses the version field pointed to by that header.
If there is no version field within the last 127 blocks that matches the desired version field, then the client would skip the nomination process.
The BIP number indicates which BIP to nominate.
If the BIP has already been assigned a slot or it is already active/locked, then the nomination is ignored.
Otherwise, if 250 of the last 1000 blocks nominate the same BIP number and there is a free slot, then the lowest free slot is allocated to that BIP.
Otherwise, if 550 of the last 1000 blocks nominate the same BIP number and a slot is used up by an inactive BIP, then the oldest inactive BIP is dropped and the slot given to the BIP.
On success the BIP's status is changed from UNASSIGNED to INACTIVE.
Consensus measurementEach bit counts as a slot for indicating which soft-forks are in use for the block.
Since 1 bits is used up (bit 31 for nomination), that gives 31 slots available for voting.
There are 2 vote options
0: No vote (and block is potentially non-compliant with the soft fork rules)
1: In favor (and that the block conforms to the soft fork rules)
ActivationIf at least 750 out of the last 1000 blocks vote in favor of the soft fork then it changes state from INACTIVE to ACTIVE. This means that blocks that have the bit set must be compliant.
It switches from ACTIVE to INACTIVE if support drops below 750 out of the last 1000 blocks.
Lock and bit deallocationIf at least 950 out of the last 1000 blocks vote in favor of the soft fork then it changes state from ACTIVE to LOCKING. This state works the same as the ACTIVE state.
Once the BIP enters the LOCKING state, there is no way to reject the BIP. The bits are still used to indicate if the block is compliant.
Locked1000 blocks after entering the LOCKING state, the BIP should enter the LOCKED state.
This means that blocks will be rejected unless they are compliant.
The slot that was used by the BIP becomes a free slot.
RejectionIf 550 of the last 1000 blocks vote against, then the BIP is considered rejected and it changes state from INACTIVE to UNASSIGNED. The slot that was used by the BIP becomes a free slot.
Blocks before the BIP was nominated don't count as votes against.
Reference client operationBy default, the reference client should vote in favor of all soft-forks it knows about. It should vote against/non compliant for all BIPs that it doesn't know about.
If an unknown BIP enters the LOCKING state, a warning should be given to the node operator.
There should be command line options to control how the reference client votes. This would allow it to vote against BIPs that it knows about. It is probably not a good idea to allow it to mine even though an unknown BIP has entered the LOCKED state. A command line switch could disable that for spam BIPs.
The node should nominate the lowest numbered known BIP that has no slot assigned (and is not locked).
[Edit]
Drop it to one bit per BIP.