-
Notifications
You must be signed in to change notification settings - Fork 18
Hardfork Procedure
A hardfork in a blockchain is a change in which an older version of the code cannot process blocks generated by the newer version. However, the new version still has to be able to process the entire blockchain, so it needs to handle blocks generated by both versions.
In Peerplays, hardforks are defined only by their name (in most cases a number) and a timestamp. The timestamp is after a new version of the software was released, so that users have time to upgrade. Up to this timestamp, blocks are generated according to the old version, and after the timestamp the new version kicks in.
On the block processing side, the hardfork timestamps are used in the same way: If the block was generated before a certain hardfork's timestamp, the old parsing rules are used. If it was generated later, the new rules are used.
Peerplays stores a list of hardforks and their timestamps in the libraries/chain/hardfork.d
directory. To add a hardfork called myhf
in the code, create a new file in that directory with the filename of myhf.hf
with contents like
#ifndef HARDFORK_MYHF_TIME
#define HARDFORK_MYHF_TIME (fc::time_point_sec( 1540000000 ))
#endif
where MYHF
should be replaced with the uppercase hardfork name and 1540000000
with the Unix timestamp of your desired hardfork time.
After the hardfork is defined, you can use its defined timestamp to perform runtime checks.
If the hardfork includes introducing new operations to the blockchain, all the code dealing with these operations can safely assert that the current time is later the hardfork timestamp
FC_ASSERT(db().head_block_time() >= HARDFORK_MYHF_TIME);
FC_ASSERT(block_time >= HARDFORK_MYHF_TIME, "my_new_cool_operation not allowed yet!" );
Or you can use it in conditionals to run extra code before or after the hardfork
if (block_time < HARDFORK_MYHF_TIME) {
// do whatever
}
This includes both code for creating/manipulating such operations and for parsing/applying them.
Since changes requiring hardforks are by definition incompatible, they should be kept in the hardfork/hf-<hf_number>
branch. While in this branch, the hardfork timestamp can still be edited, so that it always remains in the future. The main develop
branch is then regularly merged into the hardfork/hf-<hf_number>
branch. For hardfork related changes, Contributors can create new branch feature/<Jira-ID>
from specific hardfork/hf-<hf_number>
. Once the development is done, contributors can raise PR to merge their changes back to hardfork/hf-<hf_number>
. We can handle multiple hardforks in parallel this way.
QA Deployment of hardfork:
- Validate all required PRs are merged into
hardfork/hf-<hf_number>
- Set
GRAPHENE_SYMBOL
andGRAPHENE_ADDRESS_PREFIX
value as "PPY" in filelibraries/chain/include/graphene/chain/config.hpp
- Rebase
hardfork/hf-<hf_number>
ontodevelop
and push the changes to github - Ensure CI is passed
- Deploy binaries into QA environment
Once the hardfork/hf-<hf_number>
is QA verified, Special care must be taken to keep the hardfork timestamp far enough in the future for the release. Merge hardfork/hf-<hf_number>
into master
. A release Tag is made from the master
branch. It follows the normal rules for release, including merging back into both develop
and hardfork/hf-<hf_number>
once the release it made.
- Merge
hardfork/hf-<hf_number>
intomaster
- Ensure CI is passed.
- Goto release tab and create new release.
- Add release note and upload all required binaries.
- Delete
hardfork/hf-<hf_number>
branch