aere-node/patches/0005-aere-eip2935-futureeips.patch
Aere Network 600a716070 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.
2026-08-15 16:07:02 +03:00

83 lines
4.8 KiB
Diff

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')