Author

Topic: Parallel Soft-fork Handling (Read 1031 times)

sr. member
Activity: 255
Merit: 250
Senior Developer - Armory
May 26, 2015, 08:52:43 PM
#4
Quote from: gmaxwell
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?)

I've been looking for it too and have been coming up empty. Peter Todd mentioned it here too. I assume it was discussed in IRC (can't find anything in various logs, sadly) and will be released sooner or later.

Update: sipa posted it as a provisional BIP. He has requested that any comments/corrections be made on the dev mailing list.
legendary
Activity: 1232
Merit: 1094
May 18, 2015, 12:02:51 PM
#3
I was thinking about an even easier version.  It just requires "int nBaseHeight" to be added as a field to the CBlockIndex class.

Code:
int PREV_MAX_VERSION = 3;
int MIN_VERSION = 0x00010000;
int MAX_VERSION = 0x0001FFFE;
int INCREMENT = 0x00000001;
int LSB = 0x00000002;

If blocks have a version greater than MAX_VERSION, they are treated like blocks with a version of MAX_VERSION.  This votes for all outstanding BIPs that haven't been rejected.

On blocks that are divisible by 1000, if 75% of the last 1000 blocks have the increment bit set, then nBaseVersion is incremented and the nBaseVersion BIP is rejected.

If 75% of the last 1000 blocks have a bit set, then enforce rules for that BIP in those blocks.

If 95% of the last 1000 blocks have a bit set, then blocks without that bit set are rejected.  If that bit is the LSB bit, then it also counts as an increment.  This locks the BIP as enabled.

The bits need to be adjusted if an increment happens during the last 1000 blocks.  An increment can happen at most every 1000 blocks.
sr. member
Activity: 255
Merit: 250
Senior Developer - Armory
May 09, 2015, 09:26:08 AM
#2
Quote from: gmaxwell
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?)

I've been looking for it too and have been coming up empty. Peter Todd mentioned it here too. I assume it was discussed in IRC (can't find anything in various logs, sadly) and will be released sooner or later.

As for your proposal, I like it as a general concept. I feel like there are probably some finer details that could be fine-tuned. I'd have to re-read the proposal a couple of times and let in sink in first before giving solid feedback, though.
legendary
Activity: 1232
Merit: 1094
May 07, 2015, 08:25:37 AM
#1
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.

Quote from: gmaxwell
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/Drafting

This step involves discussions of the merits of the change and the creation of the BIP document.

Reference implementation created

This 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 allocation

The 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

Code:
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 measurement

Each 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)

Activation

If 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 deallocation

If 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.

Locked

1000 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.

Rejection

If 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 operation

By 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.
Jump to: