The tree stamped 1.2.0 in both configure.ac and src/clientversion.h, but
v1.2.0 is an annotated tag already pushed at fad05d3ab and dev is 27
commits past it. Both trees therefore produced CLIENT_VERSION 1020050 and
announced an identical /DragonX:1.2.0/ subversion, so a released binary
would have been indistinguishable from the tag on the wire, in
getnetworkinfo, and to the wallet's in-app updater -- destroying the only
provenance check users have: build the tag, compare the binary.
Bump MINOR rather than REVISION: the delta since v1.2.0 adds a subsystem
(RandomX stratum) and a new RPC (stratummine).
configure.ac, src/clientversion.h 1.2.0 -> 1.3.0 (CLIENT_VERSION 1030050)
doc/man/*.1 version strings restamped
contrib/debian/changelog 1.3.0 entry for the 27 commits
src/chain.h stale "CLIENT_VERSION is 1010050" comment
Man page *content* still needs a real regeneration: util/gen-manpages.sh
requires help2man and built 1.3.0 binaries, so it belongs in the release
build, where it will also pick up the new stratum options.
doc/release-process.md is why v1.1.0 and v1.2.0 were tagged but never
became releases. Followed verbatim it produced a release the wallet
refuses to install:
- it directed releases to a branch named `dragonx`, which does not
exist; releases are cut on `master`
- it never once mentioned signing, yet the updater pins an ed25519 key
and sets kDaemonRequireSignature = true, so an unsigned release is
refused outright and every user silently stays on their old daemon
- it did not require the release tag to be annotated, and genbuild.sh
calls `git describe` without --tags, so a lightweight tag stamps the
build `v<older-tag>-<sha>` instead of the release version -- which is
exactly what happened to v1.0.0 through v1.0.3
- it referenced util/build-debian-package-ARM.sh, which is not in tree
Adds the signing and checksum-table steps, the annotated-tag requirement
with a `git describe` verification, and the rule that a new version must
exceed every existing tag including unpublished ones.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FU87LdsJZiZkfq1eXubpeo
11 KiB
DragonX Release Process
High-Level Philosophy
Beware of making high-risk changes (such as consensus changes, p2p layer changes and wallet/transaction changes) too close to a new release, because they will not get as much testing as they should. Don't merge large branches which haven't undergone lots of testing just before a release.
It is best to keep doc/relnotes/README.md up to date as changes and bug fixes are made. It's more work to summarize all changes and bugfixes just before the release.
Branch model
Development happens on the dev branch. Releases are cut on the default branch, master. Code changes should land on dev first and undergo testing before being merged into master.
Check for changes on master that should be on dev
Occasionally trivial changes are made directly on the master branch, such as documentation changes. In theory, no code changes should happen on master without being on dev first, but it's better to be safe than sorry. We want the dev branch which undergoes testing to be as close as possible to what the master branch will become, so we don't want to merge dev into master and just assume everything works. So it's best to merge the master branch into dev just before merging the dev branch into master.
To check if the master branch has any changes that the dev branch does not:
# this assumes you are working with https://git.dragonx.is/DragonX/dragonx as your remote
git checkout dev
git pull # make sure dev is up to date
git checkout master
git pull # make sure master is up to date
git diff dev...master # look at the set of changes which exist in master but not dev
If the last command has no output, congrats, there is nothing to do. If the last command has output, then you should merge master into dev:
git checkout dev
git merge master
git push origin dev
Use the --no-ff flag when merging dev into master for a release (see below). The --no-ff flag makes sure to make a merge commit, no matter what, even if a "fast forward" could be done. For those in the future looking back, it's much better to see evidence of when branches were merged.
Git Issues
Look for Git issues that should be fixed in the next release. Especially low-risk and simple things, like documentation changes, improvements to error messages and RPC help output.
Pre-release checklist:
- Is this release changing consensus rules? Definitely update protocol version.
Protocol Safety Checks:
- Does
PROTOCOL_VERSIONin src/version.h need to be increased?- All releases with a consensus change should increase the value by 1
- All releases with a large change to the networking (P2P) layer should increase the value by 1
- This identifies a nodes protocol version to all other peers it connects to.
- Does
MIN_PEER_PROTO_VERSIONin src/version.h need to change?- If it does, new nodes will not be able to talk to nodes with a version less than
MIN_PROTO_VERSION
- If it does, new nodes will not be able to talk to nodes with a version less than
- The main use of these is for newer nodes that know they do not want to talk to older nodes to prevent connecting to older nodes efficiently
- For instance, when a new release has different consensus rules than older nodes,
MIN_PROTO_VERSIONprevents wasting lots of network bandwidth talking to incompatible nodes which will eventually be banned for disagreeing on consensus rules
Release dependencies
Install deps on Linux:
apt-get install help2man devscripts
Release process
- If new seeds are being added or seeds are changing:
- Edit contrib/seeds/nodes_main.txt
- Run "make seeds"
- Commit the result
- Update version in configure.ac and src/clientversion.h to update the dragonxd version
- The new version MUST be higher than every version already tagged, including tags that were never built or published. Check with
git tag -l --sort=-v:refname | head. Two trees stamped with the sameCLIENT_VERSIONare indistinguishable on the wire, ingetnetworkinfo, and to the wallet's in-app updater — and a published archive that does not match its tag destroys the only provenance check users have. - In src/clientversion.h you update
CLIENT_VERSION_*variables. Usually you will just updateCLIENT_VERSION_REVISION - If there is a consensus change, it may be a good idea to update
CLIENT_VERSION_MINORorCLIENT_VERSION_MAJOR - To make a pre-release "beta" you can modify
CLIENT_VERSION_BUILDbut that is rarely done. - A
CLIENT_VERSION_BUILDof 50 means "actual non-beta release" - Make sure to keep the values in configure.ac and src/clientversion.h the same. The variables are prefixed wth an underscore in configure.ac
- The new version MUST be higher than every version already tagged, including tags that were never built or published. Check with
- Run
./util/gen-manpages.sh, commit + push results- There is a hack in the script where you can hardcode a version number if dragonxd isn't compiled on this machine
- Comment out the version line and uncomment the line above it with a hardcoded version number
- PROTIP: Man page creation must be done after updating the version number and recompiling and before Debian package creation
- TODO: How to regenerate html man pages?
- Update checkpoints in src/chainparams.cpp via util/checkpoints.pl
- Run "./util/checkpoints.pl help" to get example usage
- dragonxd must be running to run this script, since it uses dragonx-cli to get the data
- Look for the line which marks the end of the mainnet checkpoint data in chainparams.cpp, that is where checkpoint data ends
- Find the highest block height of checkpoint data, let's call it HEIGHT
- Run
./util/checkpoints.pl 1000 HEIGHT &> checkpoints.txtto generate the latest checkpoint data - To copy the new data from checkpoints.txt into the file, one way in Vim is to type ":r checkpoints.txt" which will read in a file and paste it as the current cursor
- You will see 3 lines of "stats" at the end of the output, you just pasted in the newest stats. Delete the old stats that should be the 3 lines under the current stats
- Make sure the new code compiles, commit and push
- Run
./util/checkpoints.pl helpto see some basic help- By default it will generate checkpoints for every 1000 blocks, the "stride"
- You can get a different "stride" by passing it in as the first arg to the script
- To get checkpoint data for every 5000 blocks:
./util/checkpoints.pl 5000 &> checkpoints.txt
- checkpoints.pl will just generate the data you need, it must be manually copied into the correct place
- Checkpoints are a list of block heights and block hashes that tell a full node the correct block history of the blockchain
- Checkpoints make block verification a bit faster, because nodes can say "is this block a descendant of a checkpoint block?" instead of doing full consensus checks, which take more time
- Checkpoints also provide a bit of security against some attacks that would create malicious chainforks
- They only provide limited security, because they talk about the past, not future block heights.
- Try to generate checkpoints as close to the release as possible, so you can have a recent block height be protected.
- For instance, don't update checkpoints and then do a release a month later. You can always update checkpoint data again or multiple times
- Update doc/relnotes/README.md
- To get the stats of file changes:
git diff --stat master...dev
- To get the stats of file changes:
- Do a fresh clone and fresh sync with new checkpoints
- Stop node, wait 20 minutes, and then do a partial sync with new checkpoints
- Merge dev into master:
git checkout dev && git pull && git checkout master && git pull && git merge --no-ff dev && git push- The above command makes sure that your local dev branch is up to date before doing anything
- The above command will not merge if "git pull" creates a merge conflict
- The above command will not push if there is a problem with merging dev
- Make Gitea release with git tag from the master branch (make sure to merge dev in first)
- Make sure git tag starts with a
vsuch asv1.0.3 - The tag MUST be annotated (
git tag -a v1.3.0 -m 'DragonX v1.3.0'), not lightweight.util/genbuild.shcallsgit describewithout--tags, which only ever sees annotated tags — a lightweight tag makes the build stamp itselfv<older-tag>-<sha>instead of the release version. v1.0.0 through v1.0.3 are lightweight, which is why their builds are labelled that way. - Verify before building:
git describemust print exactly the tag, with no-<n>-g<sha>suffix.
- Make sure git tag starts with a
- Use
./build.sh(container-based, see doc/build-containers.md) or util/gen-linux-binary-release.sh to make a Linux release binary - Sign every archive and publish the signatures. This step is mandatory and was missing from this document until v1.3.0 — its absence is why v1.1.0 and v1.2.0 were tagged but never became installable releases.
- The wallet's in-app daemon updater pins an ed25519 public key in
ObsidianDragon/src/util/daemon_updater.hand setskDaemonRequireSignature = true. An update is refused outright unless a valid<archive>.sigis published beside the archive. No signature means every existing user silently stays on their old daemon. - Sign with
ObsidianDragon/scripts/sign-daemon-release.sh:scripts/sign-daemon-release.sh sign <secret.key> <archive>...produces<archive>.sig(base64 of a detached 64-byte ed25519 signature over the exact archive bytes)- or
scripts/sign-daemon-release.sh release <secret.key> <version>to zip, sign, and print the checksum table in one step
- Keep the secret key offline, mode 600. The matching base64 public key must already be pinned in
kDaemonSignaturePublicKeyBase64.
- The wallet's in-app daemon updater pins an ed25519 public key in
- Upload each Linux binary archive and its
.sigto the Gitea release - Paste the SHA-256 checksum table into the release body as markdown rows of the form
| <archive>.zip ||. The updater parses this table and will not install an archive that is absent from it. - Confirm the release is actually consumable before announcing it: the updater looks for an asset whose name contains
"-" + platformToken + ".zip"(linux-amd64,macos,win64). An archive named for a distro variant instead of the platform token is invisible to it. - Create an x86 Debian package for the release:
- Edit contrib/debian/changelog to add information about the new release
- Use
util/build-debian-package.shto make an x86 Debian package for the release - Debian packages should be done after you make manpages, because those are included in Debian packages
lintianis an optional dependency, it's not needed to build the .deb- Upload .deb to Gitea release
- Add SHA256 checksum of .deb to release
- ARM Debian package:
util/build-debian-package-ARM.shis referenced here historically but is not present in the tree. Skip, or restore the script first. - Upload the debian packages to the Gitea release page, with SHA256 sums
Platform-specific notes
- Use
./util/build-mac.shto compile on Apple/Mac systems - Use
./util/build-win.shto build on Windows
Optional things
Updating RandomX
If you need to update the source code of our in tree copy of RandomX, open an issue in the DragonX Git repository to track the details. Currently we use RandomX v1.2.1 from the official repo at https://github.com/tevador/RandomX/releases/tag/v1.2.1