Patch 0005: the import proof was attempted, and it found what no green test had
A from-genesis sync of a patches-only build stopped at block 9,189,161, the futureEipsTime activation, with a stateroot mismatch. Two causes, one patch: upstream bases futureEips on the unreleased amsterdam definition while chain 2800 isolates it on Osaka, and the fleet activates EIP-2935 history storage in the same fork, one system state write per block that a build without this patch never performs. With 0005 applied the same node, same data directory, crossed the activation and keeps importing. The fleet's optional Block-STM wiring is deliberately omitted and the omission is stated in the patch header.
This commit is contained in:
parent
54f6ffed05
commit
600a716070
@ -67,11 +67,23 @@ network refuses to finalize blocks without that post-quantum quorum.
|
||||
The anchor ships in this repository both as source, under `anchor/`, and as
|
||||
`patches/0003-aere-pq-anchor.patch`. A node built without it has not been shown to import
|
||||
headers past block 13,014,000: the second client needed an explicit change to accept the sixth
|
||||
element, and no floor-only build has been observed following the chain past that height. What
|
||||
this repository does NOT yet contain is an import proof for a node built from these patches
|
||||
alone, of the kind the rest of this file insists on; until that proof is added here, apply
|
||||
`0001`, `0003` and `0004` together and treat a build without `0003` as unable to follow the
|
||||
current chain.
|
||||
element, and no floor-only build has been observed following the chain past that height. Apply
|
||||
`0001`, `0003`, `0004` and `0005` together and treat a build missing any of them as unable to
|
||||
follow the current chain.
|
||||
|
||||
## Patch 0005 exists because the import proof was actually attempted
|
||||
|
||||
Measured 2026-08-15, on a real from-genesis sync of a build from patches
|
||||
`0001+0003+0004` alone: the node followed chain 2800 for 9.18 million blocks and stopped at
|
||||
block 9,189,161, the `futureEipsTime` activation, with `failed persisting block due to
|
||||
stateroot mismatch`. Not one cause but two, both in `MainnetProtocolSpecs.java`, both now
|
||||
carried by `patches/0005-aere-eip2935-futureeips.patch`: upstream bases the futureEips
|
||||
milestone on the unreleased amsterdam definition (Block Access Lists, a different state-root
|
||||
committer), while chain 2800 isolates it on Osaka; and the fleet activates EIP-2935 historical
|
||||
block hashes in that same fork, one system state write per block from 9,189,161 onward, which
|
||||
a build without the patch never performs. No amount of green unit tests found this; importing
|
||||
the real chain found it in one afternoon. The sync continues past the activation with `0005`
|
||||
applied, and this section will carry the measured height as it climbs.
|
||||
|
||||
Measured 2026-08-15: on a pristine `d2032017` checkout, `git apply` (no flags) accepted
|
||||
`0001`, `0003` and `0004` in that order, and `./gradlew --no-daemon installDist
|
||||
|
||||
82
patches/0005-aere-eip2935-futureeips.patch
Normal file
82
patches/0005-aere-eip2935-futureeips.patch
Normal file
@ -0,0 +1,82 @@
|
||||
AERE patch 0005: futureEips activation isolated on Osaka, plus protocol-native EIP-2935
|
||||
|
||||
Why this patch exists, measured 2026-08-15 on a from-genesis sync: a node built
|
||||
from patches 0001+0003+0004 alone followed chain 2800 to block 9,189,160 and
|
||||
stopped at 9,189,161, the futureEipsTime activation block, with
|
||||
"failed persisting block due to stateroot mismatch". Two independent causes,
|
||||
both fixed here, both in MainnetProtocolSpecs.java:
|
||||
|
||||
1. Upstream bases futureEips on amsterdamDefinition, which drags in unreleased
|
||||
amsterdam-milestone changes (EIP-7928 Block Access Lists with a new state
|
||||
root committer, EIP-7708 transfer logs, 2D gas accounting). Chain 2800 runs
|
||||
Osaka; the fleet isolates the AERE milestone on osakaDefinition so the
|
||||
post-activation block format stays identical to Osaka.
|
||||
2. The fleet activates EIP-2935 (historical block hashes, ring buffer in the
|
||||
system contract at 0x0000F90827F1C53a10cb7A02335B175320002935) in the SAME
|
||||
futureEips fork, so every block from 9,189,161 onward performs one system
|
||||
state write. A build without it computes a different state root on the very
|
||||
first activation block, which is exactly what was measured.
|
||||
|
||||
Modified upstream file: MainnetProtocolSpecs.java (plus one build.gradle line).
|
||||
The upstream copyright header is unchanged, per Apache License 2.0 section 4(c);
|
||||
the in-diff comments state exactly what changed, per section 4(b). The base is
|
||||
upstream commit d2032017bb3b8cb215a97303980a1e4a643f7180.
|
||||
|
||||
One deliberate omission: the fleet's own copy of this change also wires an optional
|
||||
Block-STM parallel block processor behind an environment gate. That wiring references
|
||||
source files not published here, and with the gate unset it reproduces the default
|
||||
builder exactly, so this patch carries the consensus-relevant part only: the Osaka
|
||||
isolation and EIP-2935. A build from this patch follows the chain; it does not enable
|
||||
parallel execution.
|
||||
|
||||
diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
|
||||
index 87f1a6b..545aeb2 100644
|
||||
--- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
|
||||
+++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
|
||||
@@ -1321,7 +1321,17 @@ public abstract class MainnetProtocolSpecs {
|
||||
final boolean isParallelTxProcessingEnabled,
|
||||
final BalConfiguration balConfiguration,
|
||||
final MetricsSystem metricsSystem) {
|
||||
- return amsterdamDefinition(
|
||||
+ // AERE MILESTONE ISOLATION: base the AerePQC (futureEips) activation on the
|
||||
+ // OSAKA spec, NOT amsterdam. Mainnet runs Osaka/Fusaka, and inheriting
|
||||
+ // amsterdamDefinition would have silently activated every unreleased
|
||||
+ // amsterdam-milestone change on futureEipsTime, notably EIP-7928 Block
|
||||
+ // Access Lists (new block field + BAL state-root committer), EIP-7708
|
||||
+ // transfer logs, and EIP-7778/EIP-8037 2D pre-refund gas accounting +
|
||||
+ // Amsterdam gas calculator. Those are block-format / state-transition
|
||||
+ // changes that would fork the chain away from Osaka. Basing on osaka makes
|
||||
+ // the post-activation block format IDENTICAL to Osaka and adds ONLY the two
|
||||
+ // AERE features below: (a) the 5 PQC precompiles and (b) EIP-2935.
|
||||
+ return osakaDefinition(
|
||||
chainId,
|
||||
enableRevertReason,
|
||||
genesisConfigOptions,
|
||||
@@ -1330,7 +1340,15 @@ public abstract class MainnetProtocolSpecs {
|
||||
isParallelTxProcessingEnabled,
|
||||
balConfiguration,
|
||||
metricsSystem)
|
||||
+ // AERE EIP-2935: historical block hashes (ring buffer in the system
|
||||
+ // contract at 0x0000f9...2935), wired into the SAME futureEips (AerePQC)
|
||||
+ // hard fork as the PQC precompiles so a single futureEipsTime activation
|
||||
+ // delivers both. Forced on unconditionally here: the inherited Prague
|
||||
+ // definition falls back to FrontierPreExecutionProcessor for QBFT/PoA
|
||||
+ // chains without system-contract addresses, which would silently skip
|
||||
+ // EIP-2935 history storage. This override restores it, protocol-native.
|
||||
+ .preExecutionProcessor(new PraguePreExecutionProcessor())
|
||||
.precompileContractRegistryBuilder(MainnetPrecompiledContractRegistries::futureEips)
|
||||
.hardforkId(FUTURE_EIPS);
|
||||
}
|
||||
|
||||
diff --git a/evm/build.gradle b/evm/build.gradle
|
||||
index b416c99..9b4e0a5 100644
|
||||
--- a/evm/build.gradle
|
||||
+++ b/evm/build.gradle
|
||||
@@ -37,6 +37,7 @@ dependencies {
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler'
|
||||
|
||||
implementation project(':crypto:algorithms')
|
||||
+ implementation 'org.bouncycastle:bcprov-jdk18on'
|
||||
implementation project(':datatypes')
|
||||
implementation project(':ethereum:rlp')
|
||||
implementation project(':util')
|
||||
Loading…
Reference in New Issue
Block a user