Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 7: [PATCH 07/68] build: adapt Roots maintenance and assurance to Core 30.3

contrib/roots/README.md

Before: /dev/null · After: contrib/roots/README.md

File metadata
new file mode 100644
index 0000000000000000000000000000000000000000..df403a466e4a989d7301650dcd82cd0e0af79214

Download original patch · Release notes

Diff rows 1–262 of 262. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.

contrib/roots/README.md ADDED
@@ -0,0 +1,262 @@
1
+ # Bitcoin Roots maintainer workflow
2
+
3
+ Bitcoin Roots is maintained as a small, reviewable Git history on top of
4
+ Bitcoin Core. Bitcoin Core v30.3 is the direct upstream base for this release.
5
+ Bitcoin Knots is historical provenance for selected Roots policy features, not
6
+ an upstream, a dependency, or a source of consensus rules.
7
+
8
+ Git history is the canonical representation of Roots changes. Do not maintain
9
+ replay frameworks, patch manifests, generated evidence, frozen candidate state,
10
+ or promotion metadata alongside it. The archived replay branch is historical
11
+ evidence only; do not rewrite or depend on it.
12
+
13
+ ## Branch roles
14
+
15
+ Keep the source patch series, product integration history, and generated
16
+ release artifacts separate:
17
+
18
+ - `roots/<core-version>` is the canonical release line. It starts at the exact
19
+ matching Bitcoin Core tag and contains a linear series of semantic Roots
20
+ commits. Released tips are immutable.
21
+ - `topic/<core-version>/<area>` holds work for one reviewable area. Accepted
22
+ commits are applied to the canonical release line.
23
+ - `integration/<core-version>` is disposable combined-CI state. It may be
24
+ rebuilt and must not be used as the base for durable work.
25
+ - `main` is the currently promoted product history. An explicit promotion merge
26
+ connects it to a reviewed canonical release line; the merge result must have
27
+ exactly the same tree as that canonical tip.
28
+ - `archive/*` preserves superseded candidates and retired maintenance systems.
29
+ Archive branches are evidence, not dependencies or release inputs.
30
+
31
+ For example, `roots/29.4` starts directly at `v29.4`, while `roots/30.3`
32
+ starts directly at `v30.3`. Do not merge the complete 29.4 branch into the 30.3
33
+ branch. Port the semantic Roots commits to the new Core base, dropping behavior
34
+ that Core has adopted and adapting or splitting commits when its APIs changed.
35
+
36
+ Pull requests that promote a release into `main` and pull requests that review
37
+ the canonical patch series have different bases. Never rebase or squash the
38
+ canonical series merely to make a promotion pull request appear linear. Build
39
+ the promotion from `main`, retain the canonical tip as a merge parent, and
40
+ verify tree equality before publishing it.
41
+
42
+ ## Inspecting a maintenance branch
43
+
44
+ Start from a clean worktree and name the Core base explicitly. For the v30.3
45
+ work, the peeled Core commit is `49faec4f87f5cd19c88db01a82e5c68b087c8227`.
46
+ The following commands inspect history without changing it:
47
+
48
+ ```sh
49
+ core_base=49faec4f87f5cd19c88db01a82e5c68b087c8227
50
+ git status --short
51
+ git show --no-patch --decorate "$core_base"
52
+ git log --oneline --decorate "$core_base"..HEAD
53
+ git diff --stat "$core_base"..HEAD
54
+ git merge-base --is-ancestor "$core_base" HEAD
55
+ ```
56
+
57
+ Use `git show-ref --heads --tags` and `git rev-parse --verify <ref>` before
58
+ using a local name in automation. `git merge-base --is-ancestor A B` succeeds
59
+ only when `A` is an ancestor of `B`; it is preferable to inferring ancestry
60
+ from a graph view. Confirm object identities with `git rev-parse <ref>^{commit}`.
61
+
62
+ Authenticate the official tag and its signer key through independent trusted
63
+ sources before claiming verification. A missing local signer key is not proof
64
+ of an invalid signature. Run `git verify-tag v30.3` with the authenticated key
65
+ and record both the signature result and its trust basis.
66
+
67
+ ## Exporting and reviewing a series
68
+
69
+ Export the reviewed range directly from Git. Choose an output directory outside
70
+ the repository or an ignored disposable directory:
71
+
72
+ ```sh
73
+ git format-patch --cover-letter --output-directory /tmp/roots-patches \
74
+ "$core_base"..HEAD
75
+ git format-patch --stdout "$core_base"..HEAD > /tmp/roots-series.mbox
76
+ git diff --check "$core_base"..HEAD
77
+ ```
78
+
79
+ Before and after a rewrite, retain the previous tip in a local variable or
80
+ named branch and compare the two series. `range-diff` makes changes to commit
81
+ content and ordering visible to reviewers:
82
+
83
+ ```sh
84
+ previous_tip=<previous-reviewed-tip>
85
+ git range-diff "$core_base"..."$previous_tip" "$core_base"...HEAD
86
+ git diff --check "$previous_tip"..HEAD
87
+ ```
88
+
89
+ Do not use an exported series as a second source of truth. It is a review or
90
+ transfer artifact; the Git commits remain canonical.
91
+
92
+ ## Porting a Core release
93
+
94
+ Fetch and inspect the intended Core tag or commit first. Configure `core` to
95
+ the official Bitcoin Core repository once, or select an already-configured
96
+ remote explicitly; do not assume that every checkout has a remote named
97
+ `core`. Create a dedicated maintenance branch, then port the Roots series with
98
+ ordinary Git operations:
99
+
100
+ ```sh
101
+ core_remote=<configured-bitcoin-core-remote>
102
+ core_tag=v30.3
103
+ git remote get-url "$core_remote"
104
+ git fetch "$core_remote" --tags
105
+ core_commit=$(git rev-parse "$core_tag^{commit}")
106
+ git show --no-patch --decorate "$core_commit"
107
+ git switch --create roots/30.3 "$core_commit"
108
+ git cherry-pick -x <semantic-roots-commit>
109
+ ```
110
+
111
+ Repeat the cherry-pick for each semantic commit after deciding whether that
112
+ change is still needed. `-x` records the source commit when the new commit is a
113
+ true cherry-pick. When a conflict requires a material rewrite, explain the old
114
+ commit and the deviation in the new commit message rather than retaining a
115
+ misleading cherry-pick identity.
116
+
117
+ Compare the old and new generations as patch series:
118
+
119
+ ```sh
120
+ git range-diff v29.4..roots/29.4 v30.3..roots/30.3
121
+ ```
122
+
123
+ Resolve only identified conflicts, inspect the result with `git diff` and
124
+ targeted tests, then use `git cherry-pick --continue`. If the port premise is
125
+ wrong, stop with `git cherry-pick --abort`; do not hide a conflict with a bulk
126
+ overwrite. The range-diff must explain commits that were added, dropped, split,
127
+ or materially changed before requesting review.
128
+
129
+ ## Maintaining supported release lines
130
+
131
+ Apply a security or correctness fix first to the oldest supported Roots line
132
+ that needs it. After review and testing, cherry-pick it with `-x` into each newer
133
+ affected line. Document deviations required by newer Core code. Do not rewrite
134
+ published release commits or tags.
135
+
136
+ A maintenance release therefore advances its own canonical branch, for example
137
+ from `v29.4-roots.1` to `v29.4-roots.2`; it does not require merging a newer
138
+ Core line into the older one.
139
+
140
+ ## Promoting a canonical line into `main`
141
+
142
+ Create the promotion in a separate worktree so that the canonical branch stays
143
+ clean:
144
+
145
+ ```sh
146
+ canonical_ref=origin/roots/30.3
147
+ git switch --create promote/30.3 origin/main
148
+ git merge --no-ff --no-commit "$canonical_ref"
149
+ # Resolve deliberately, then verify the proposed index and worktree.
150
+ git diff --cached --name-status
151
+ git commit
152
+ git diff --exit-code "$canonical_ref"..HEAD
153
+ test "$(git rev-parse HEAD^{tree})" = "$(git rev-parse "$canonical_ref^{tree}")"
154
+ ```
155
+
156
+ The last two commands are the defining promotion check: the merge records both
157
+ histories, but its product tree is identical to the canonical release tip. A
158
+ promotion branch is review state and may be rebuilt with a force-with-lease;
159
+ the canonical release branch is not rewritten after publication.
160
+
161
+ ## Editing policy safely
162
+
163
+ Roots may retain configurable conservative mempool, relay, and mining-template
164
+ policy. Keep that behavior in policy/admission/template boundaries and include
165
+ operator help/configuration plus feature-owned tests in the same reviewable
166
+ commit. Do not import Knots as an upstream dependency.
167
+
168
+ Policy rejection is not block validity. For every change that can reject a
169
+ consensus-valid transaction locally, test both sides of the boundary:
170
+
171
+ 1. the configured node rejects it from admission, relay, or template selection;
172
+ 2. a consensus-valid block containing it is still accepted.
173
+
174
+ Never add RDTS/BIP110 consensus enforcement. Audit every essential touch to
175
+ `src/consensus/`, `src/script/`, or validation code, and make no incidental
176
+ consensus-adjacent cleanup. Run focused unit and functional tests while editing,
177
+ then the relevant broad suite. At handoff, also run:
178
+
179
+ ```sh
180
+ cmake -S . -B build
181
+ cmake --build build --target bitcoind test_bitcoin -j 4
182
+ build/test/functional/test_runner.py mempool_dust.py
183
+ git diff --check
184
+ git status --short
185
+ ctest --test-dir build --output-on-failure
186
+ ```
187
+
188
+ Use a configured build directory appropriate to the affected targets; see the
189
+ repository `AGENTS.md` for safe regtest and build guidance.
190
+
191
+ ## Rewrites and public history
192
+
193
+ Use interactive rebase only on an unpublished maintenance branch, and review
194
+ the resulting series before sharing it:
195
+
196
+ ```sh
197
+ git branch reviewed-before-rebase HEAD
198
+ git rebase --interactive "$core_base"
199
+ git range-diff "$core_base"...reviewed-before-rebase "$core_base"...HEAD
200
+ ```
201
+
202
+ Do not rewrite a branch other people may have based work on without explicit
203
+ coordination. When a reviewed public branch must be updated, inspect its remote
204
+ tracking state and use a lease rather than an unrestricted force push:
205
+
206
+ ```sh
207
+ git fetch origin
208
+ git log --left-right --graph --cherry-pick origin/<branch>...HEAD
209
+ git push --force-with-lease origin HEAD:<branch>
210
+ ```
211
+
212
+ Never force-push release tags. Preserve archival branches.
213
+
214
+ ## Release handoff
215
+
216
+ Release tags use the Roots form `v<core-version>-roots.<positive-integer>`;
217
+ release candidates may use `v<core-version>rc<n>-roots.<positive-integer>`.
218
+ Before creating or pushing a tag, run the repository checks and verify the
219
+ annotated tag target and ancestry:
220
+
221
+ ```sh
222
+ release_tag=v30.3-roots.1
223
+ git check-ref-format "refs/tags/$release_tag"
224
+ git tag --annotate "$release_tag" -m "Bitcoin Roots $release_tag"
225
+ git rev-parse "$release_tag^{commit}"
226
+ test "$(git rev-parse "$release_tag^{commit}")" = \
227
+ "$(git rev-parse origin/roots/30.3^{commit})"
228
+ ci/release/validate-release-source.sh "$release_tag"
229
+ ```
230
+
231
+ Run the retained release metadata tests before pushing:
232
+
233
+ ```sh
234
+ python3 ci/test/test_prepare_release.py
235
+ python3 ci/test/test_create_patch_series.py
236
+ python3 ci/test/test_sign_manifest.py
237
+ python3 ci/test/test_validate_release_tag.py
238
+ python3 ci/test/test_validate_release_source.py
239
+ python3 ci/test/test_release_version.py
240
+ ```
241
+
242
+ GitHub Actions tag workflows check out the tagged commit; a release tag does not
243
+ need to be reachable from `main`. Release validation instead requires the tag
244
+ target to match its canonical `roots/<core-version>` branch. The release patch
245
+ is generated from the Core tag and canonical commits at release time and is not
246
+ checked into the repository. Do not create nightly, promotion, or
247
+ generated-evidence control planes around this workflow.
248
+
249
+ Before pushing a tag, the patch artifact can be generated and replay-verified
250
+ locally without adding it to Git:
251
+
252
+ ```sh
253
+ ci/release/create-patch-series.sh "$release_tag" \
254
+ "/tmp/bitcoin-roots-${release_tag#v}.patch"
255
+ ```
256
+
257
+ Pushing the annotated tag builds Linux x86_64, Linux aarch64, macOS x86_64,
258
+ macOS arm64, and Windows x86_64 archives. The draft release also contains the
259
+ Git-am-compatible patch series and `SHA512SUMS`; `SHA512SUMS.asc` is included
260
+ when the release environment has a matching signing key configured. The
261
+ workflow can be dispatched manually with an existing tag to build and validate
262
+ the same artifacts without creating or updating a GitHub release.