Skip to content

Commit 0d064d4

Browse files
authored
Merge feature/signet-fork-450000: Signet-gated hard fork at block 450,000
Signet-gated hard fork at block 450,000
2 parents 75af302 + 6b5a698 commit 0d064d4

38 files changed

Lines changed: 5806 additions & 111 deletions

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,17 @@ dist/
166166
/ci/scratch/
167167

168168
.vscode
169+
170+
# Alpha mainnet signing keys
171+
.env
172+
.env.*
173+
174+
# Claude Code project instructions
175+
CLAUDE.md
176+
177+
# Local build artifacts and config
178+
build-output/
179+
config/
180+
181+
# Claude artifacts
182+
CLAUDE.md

CLAUDE.md

Lines changed: 0 additions & 31 deletions
This file was deleted.

configure.ac

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ define(_COPYRIGHT_HOLDERS,[The %s developers])
99
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin Core]])
1010

1111
dnl !ALPHA
12-
define(_ALPHA_CLIENT_RELEASE_NAME_MAJOR, [dubai])
12+
define(_ALPHA_CLIENT_RELEASE_NAME_MAJOR, [dubai-experimental])
1313
define(_ALPHA_CLIENT_VERSION_MAJOR, 1)
14-
define(_ALPHA_CLIENT_VERSION_MINOR, 7)
14+
define(_ALPHA_CLIENT_VERSION_MINOR, 8)
1515
define(_ALPHA_CLIENT_VERSION_BUILD, 0)
1616
AC_INIT([Alpha],m4_join([.], _ALPHA_CLIENT_VERSION_MAJOR, _ALPHA_CLIENT_VERSION_MINOR, _ALPHA_CLIENT_VERSION_BUILD)m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC)-_ALPHA_CLIENT_RELEASE_NAME_MAJOR-core-m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_BUILD),[https://github.com/unicitynetwork/alpha/issues],[alpha],[https://github.com/unicitynetwork/alpha])
1717
dnl !ALPHA END

doc/signet-fork-planning.md

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
# Timebomb fork @ height 450000 — instructions for Claude (PLAN ONLY, NO IMPLEMENTATION)
2+
3+
> **CRITICAL: Claude MUST NOT IMPLEMENT ANYTHING.**
4+
>
5+
> Claude’s only job is to produce **comprehensive, manual code-editing instructions** (file-by-file, function-by-function) so that **I** can apply every change manually and verify it.
6+
>
7+
> - No patches / diffs / PRs
8+
> - No “paste this code”
9+
> - No autonomous refactors
10+
> - Only: *where to edit, what to add, what to verify, and why*
11+
>
12+
> **Repeat:** Claude MUST NOT IMPLEMENT ANYTHING.
13+
14+
---
15+
16+
## Objective
17+
18+
At **block height 450000** (the “timebomb height”), our Bitcoin-based RandomX network must switch to a post-fork consensus regime:
19+
20+
1) **Set block subsidy to 0** (fees-only coinbase)
21+
2) **Reset difficulty** (one-time adjustment) to prevent stalling when hashrate drops from ~200 MHz to near 0
22+
3) **Enforce Signet-style block authorization** (only blocks authorized by our hardcoded allowlist are accepted)
23+
24+
This is a **consensus change / hard fork**. All nodes must upgrade before height 450000.
25+
26+
We already have **SegWit / witness commitments enabled**.
27+
28+
---
29+
30+
## Modes: full node vs block-producing template server
31+
32+
We have at least two operational modes:
33+
34+
- **Normal full node mode**: validates, relays, serves RPC, etc.
35+
✅ Must NOT require any mining private key. Must run normally without authorization key material.
36+
37+
- **Template-serving mode**: the node accepts `getblocktemplate`-like requests / builds block templates for miners/workers.
38+
✅ In this mode, post-fork templates **must** include authorization solution signatures.
39+
✅ Therefore, in this mode, the node must be able to sign using an authorized key.
40+
41+
**Claude must design the “startup key authorization invariant” to apply ONLY in template-serving mode.**
42+
43+
---
44+
45+
## Activation and boundary conditions
46+
47+
Let `H = 450000`.
48+
49+
- **Before H**:
50+
- Accept blocks as currently (RandomX PoW, normal subsidy schedule)
51+
- No Signet authorization required
52+
- **At/after H** (`height >= H`):
53+
- `subsidy(height) = 0`
54+
- difficulty reset triggers at height H (one-time)
55+
- blocks must pass Signet-style authorization check against a hardcoded allowlist challenge
56+
57+
---
58+
59+
## Required deliverable from Claude
60+
61+
Claude must output a **manual implementation plan** including:
62+
63+
- exact code locations (files, functions) to inspect and edit
64+
- specific height-gated logic changes required
65+
- how to keep changes minimal and isolated
66+
- testing plan + validation steps + reject reasons
67+
68+
> **Claude MUST NOT IMPLEMENT ANYTHING.** Only instructions.
69+
70+
---
71+
72+
## Workstream A — Subsidy becomes 0 at height 450000
73+
74+
### Goal
75+
From height `>= 450000`, coinbase may only pay **transaction fees**.
76+
77+
### Minimal enforcement
78+
Modify consensus subsidy function (likely `GetBlockSubsidy(height, ...)`):
79+
- return 0 when `height >= H`
80+
This naturally makes the existing “coinbase pays too much” check enforce fees-only.
81+
82+
### Claude must plan
83+
- identify subsidy function + block reward enforcement site
84+
- provide exact manual insertion point for height-gate
85+
86+
---
87+
88+
## Workstream B — Difficulty reset at height 450000 (avoid stall)
89+
90+
### Goal
91+
At height H, perform a **one-time reset** to an easy target (typically `powLimit`) so blocks continue even with huge hashrate drop.
92+
93+
### Minimal strategy
94+
In difficulty calculation (`GetNextWorkRequired` or equivalent):
95+
- compute `nextHeight = pindexLast->nHeight + 1`
96+
- if `nextHeight == H`: return min difficulty (powLimit compact)
97+
- otherwise: normal rules
98+
99+
### Claude must plan
100+
- identify difficulty function(s) for our RandomX fork
101+
- choose the least invasive reset method (prefer `powLimit`)
102+
- specify exactly how to encode the target into `nBits`
103+
- describe reorg implications (any chain’s height H must obey reset)
104+
105+
---
106+
107+
## Workstream C — Enforce Signet-style block authorization at height 450000
108+
109+
### Goal
110+
From `height >= H`, blocks must include a valid Signet/BIP325-style “solution” satisfying a **hardcoded allowlist challenge**.
111+
112+
### Minimal strategy
113+
Reuse existing Signet verification logic if present (e.g., `CheckSignetBlockSolution`):
114+
- do NOT enable signet globally from genesis
115+
- add a height-gated call in a height-aware validation path (e.g., `ContextualCheckBlock`)
116+
117+
### Allowlist
118+
Hardcode 5 authorized **pubkeys** in a single challenge script (recommended):
119+
- 1-of-5 multisig challenge (or other script), stored in consensus params
120+
121+
### Claude must plan
122+
- where to store challenge bytes in chainparams/consensus params
123+
- where to add `if (height >= H) require CheckSignetBlockSolution(...)`
124+
- what reject code/reason to use for unauthorized blocks
125+
- mining/template implications (solution must be present in coinbase witness commitment optional data)
126+
127+
---
128+
129+
## NEW Workstream D — Startup key authorization invariant (template-serving mode only)
130+
131+
> **Claude MUST NOT IMPLEMENT ANYTHING.** This section is for Claude to produce a manual edit plan.
132+
133+
### Requirement
134+
If (and only if) the node is started in **template-serving mode** (i.e., it will build templates for miners), then:
135+
136+
- the node must have access to a private key that corresponds to **one of the 5 authorized hardcoded pubkeys**
137+
- if it does not, the node must **terminate immediately** with a clear fatal error
138+
- in normal full node mode, the node must run without any mining key and must NOT perform this invariant check
139+
140+
### Define “template-serving mode”
141+
Claude must determine how our node currently enables template serving, for example:
142+
- RPC server enabled + `getblocktemplate` exposed
143+
- a dedicated `-mining` / `-server` / `-rpc` flag set
144+
- a pool mode flag
145+
- any existing “miner support” configuration
146+
147+
Claude must propose a precise trigger condition, e.g.:
148+
- `if (IsRPCEnabled && IsTemplateRPCEnabled && !-disablegbt)` OR
149+
- `if (-templatemode=1)` (if we add a flag)
150+
but Claude should prefer using **existing** flags/structure if possible.
151+
152+
### What must be checked at startup
153+
In template-serving mode only:
154+
155+
1) Obtain the configured “mining signing key” material (see Workstream E below).
156+
2) Derive pubkey (compressed/uncompressed rules must be clear).
157+
3) Compare against hardcoded allowlist pubkeys.
158+
4) If no match:
159+
- log a fatal message stating:
160+
- node is in template-serving mode
161+
- configured key is not authorized
162+
- list the authorized pubkey fingerprints (not full keys, if you prefer)
163+
- then exit via controlled fatal path (AbortNode / InitError / exception), not a segfault.
164+
165+
### Also required: runtime/template-time safety
166+
Even with startup checks, if template signing fails later (HSM down, wallet locked, key missing):
167+
- template creation at/after height H must hard-fail (do not serve unsigned templates)
168+
169+
Claude must include both layers in the plan:
170+
- startup invariant (mode-gated)
171+
- template generation hard-fail post-fork
172+
173+
---
174+
175+
## NEW Workstream E — How the node should be provided the signing private key (plan options)
176+
177+
We want minimal changes, but also predictable ops. Claude must evaluate these options and recommend one, with pros/cons and exact manual steps.
178+
179+
> Claude MUST NOT IMPLEMENT ANYTHING. Only provide instructions for me.
180+
181+
### Option 1 (recommended for clarity): dedicated config parameter for mining signing key
182+
Example (conceptual): `-miningsignkey=<WIF/hex/descriptor>` or `-miningsignkeyfile=...`
183+
184+
Pros:
185+
- explicit: avoids ambiguity between “wallet has key” vs “this is the mining signer”
186+
- easier to enforce allowlist match at startup
187+
- can work without a loaded wallet if desired
188+
189+
Cons:
190+
- adds a new configuration surface (small code change)
191+
192+
Claude must plan:
193+
- where to parse/store this option
194+
- how to keep it secure (permissions, avoid logging secrets)
195+
- how to derive pubkey reliably
196+
197+
### Option 2: use the standard wallet (loadwallet) mechanism
198+
Node obtains the signing key from a loaded wallet.
199+
200+
Typical sub-variants:
201+
- **A)** “coinbase destination address” belongs to wallet, and node picks that key as signer
202+
- **B)** explicit “mining address” config, and wallet must contain its privkey
203+
- **C)** descriptor wallet: pick key from descriptor
204+
205+
Pros:
206+
- no new secret storage format if you already manage wallet securely
207+
- can integrate with existing encryption/locking flows
208+
209+
Cons / gotchas (Claude must address explicitly):
210+
- wallet may be absent on some nodes (full validation nodes)
211+
- wallet could be locked (signing fails)
212+
- ambiguous key selection if wallet has many keys
213+
- using “address” is encoding-dependent; consensus allowlist should be pubkeys
214+
215+
If you choose wallet-based:
216+
- Claude must specify a deterministic way to select *the* signing key, not “first key found”.
217+
- Claude must define behavior when wallet is locked:
218+
- fail startup in template-serving mode OR
219+
- require `-walletpassphrase` usage / operator procedure (no silent fallback)
220+
221+
### Option 3: external signer / HSM via a thin node-side interface
222+
Node calls an external signer (HSM or local signing daemon) when building templates.
223+
224+
Pros:
225+
- private key not resident in node memory/disk
226+
- operationally aligns with HSM policies
227+
228+
Cons:
229+
- more plumbing; may be more than “minimal”
230+
- adds dependencies and failure modes
231+
232+
If considered:
233+
- Claude must keep plan minimal (reuse existing signer interface if already present)
234+
- must still satisfy startup invariant (connectivity / pubkey check)
235+
236+
### Required outcome
237+
Claude must recommend **one default** approach (likely Option 1 or Option 2), and also describe fallback options.
238+
239+
---
240+
241+
## Integration notes (all workstreams)
242+
243+
At `height >= H`:
244+
- difficulty reset impacts `nBits` at height H
245+
- subsidy=0 impacts coinbase max payout
246+
- authorization required impacts validation AND template construction
247+
248+
Claude must ensure the plan includes how miners will succeed in producing the first post-fork block:
249+
- template must already contain authorization solution
250+
- template must already use fees-only coinbase
251+
- template must already use reset difficulty at height H
252+
253+
---
254+
255+
## Testing plan (Claude must describe, not implement)
256+
257+
Boundary tests:
258+
- height H-1 block: old rules OK
259+
- height H block: must satisfy all three new rules (subsidy 0, reset difficulty, authorization)
260+
- height H+1 block: subsidy 0 + authorization; difficulty returns to normal algorithm (unless specified)
261+
262+
Reorg tests:
263+
- competing branches around H, ensure height-based rules apply per-branch
264+
265+
Template tests:
266+
- in template-serving mode:
267+
- startup fails if signing key not authorized
268+
- template generation at/after H fails if signing fails
269+
- in normal full node mode:
270+
- node starts and runs without any mining key
271+
272+
---
273+
274+
## Repeated critical instruction
275+
276+
**Claude MUST NOT IMPLEMENT ANYTHING.**
277+
Claude must only generate a comprehensive, manual code-editing plan.
278+
279+
---

0 commit comments

Comments
 (0)