diff --git a/RUN-A-NODE.md b/RUN-A-NODE.md index 05d9a0f..0a8bf24 100644 --- a/RUN-A-NODE.md +++ b/RUN-A-NODE.md @@ -156,7 +156,7 @@ measured heights of each run. **Revision note, 2026-09-05:** the anchor patch an below were updated for the hybrid certificate and the interval schedule; the from-genesis import proof has NOT yet been repeated against this revision (the last measured run is the one above, on the previous revision). What is measured for this revision is that the same code follows the live tip on -the network's reading nodes, and validates every hybrid anchor there, since 2026-09-05. +the network's reading nodes, and validates every hybrid anchor there, since 2026-09-05. **Revision note, 2026-09-10:** patches `0001`, `0003` and `0004` were regenerated from the production tree over the same file sets (the source files now carry the Apache-2.0 section 4(b) modification notices that production carries; `0003` keeps its 169 files). Measured the same day: a build from this recipe reproduces the fleet's three consensus jars class by class, and `LondonFeeMarket` and the precompile classes byte for byte. What the recipe still does not ship is the fleet's parallel block processor (a separate package and one hunk in `MainnetProtocolSpecs`), which does not change consensus; it is listed by the comparison, not hidden. --- diff --git a/patches/0001-aere-pqc-precompiles-mainnet.patch b/patches/0001-aere-pqc-precompiles-mainnet.patch index d0c8e7f..620b460 100644 --- a/patches/0001-aere-pqc-precompiles-mainnet.patch +++ b/patches/0001-aere-pqc-precompiles-mainnet.patch @@ -1,92 +1,15 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aere Network -Date: Mon, 20 Jul 2026 10:05:53 +0300 +Date: Thu, 10 Sep 2026 21:47:55 +0300 Subject: [PATCH] Aere Network: post-quantum signature verification precompiles - (mainnet 0x0ae1-0x0ae5) -Adds five native precompiled contracts exposing post-quantum signature -verification to the EVM, and registers them in populateForFutureEIPs so they -activate by fork timestamp rather than at genesis. - - 0x0ae1 Falcon-512 verify NIST Falcon round 3 - 0x0ae2 Falcon-1024 verify NIST Falcon round 3 - 0x0ae3 ML-DSA-44 verify FIPS 204 - 0x0ae4 SLH-DSA-SHA2-128s verify FIPS 205 - 0x0ae5 SHAKE256 XOF FIPS 202 - -Live on Aere Network chain 2800 from block 9,189,161. - -Scope: these precompiles verify post-quantum signatures inside the EVM. They -do not change consensus. Block sealing and validator identity on chain 2800 -remain classical secp256k1 ECDSA QBFT. - -populateForFutureEIPs is additionally repointed from populateForCancun to -populateForOsaka, so the fork carries the full Osaka precompile set. - -No build file change is required: bcprov-jdk18on is already exposed to the evm -module as an api dependency of crypto:algorithms, and jakarta.validation-api is -a global subproject dependency. -Modified upstream files. Two files touched by this patch are modified copies -of Hyperledger Besu sources, not new work by Aere Network: - - datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java - evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java - -Aere Network changed both, against upstream commit -d2032017bb3b8cb215a97303980a1e4a643f7180. Both keep their original -"Copyright contributors to Hyperledger Besu" headers unchanged, which is what -Apache License 2.0 section 4(c) requires, and this patch adds to each a -separate "Modifications Copyright" block naming exactly what was changed. That -in-file block is the notice required by Apache License 2.0 section 4(b). It -travels inside the diff, so a tree with this patch applied carries the notice -whether you used git am or git apply. Every other file this patch touches is -new and was written by Aere Network, and each carries its own Apache-2.0 -header. - ---- - .../hyperledger/besu/datatypes/Address.java | 30 ++++++ - .../evm/precompile/AereFalconSupport.java | 94 +++++++++++++++++++ - .../Falcon1024PrecompiledContract.java | 62 ++++++++++++ - .../Falcon512PrecompiledContract.java | 62 ++++++++++++ - .../MLDSA44PrecompiledContract.java | 84 +++++++++++++++++ - .../MainnetPrecompiledContracts.java | 25 ++++- - .../SHAKE256PrecompiledContract.java | 93 ++++++++++++++++++ - .../SLHDSA128sPrecompiledContract.java | 84 +++++++++++++++++ - 8 files changed, 533 insertions(+), 1 deletion(-) - create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/precompile/AereFalconSupport.java - create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/precompile/Falcon1024PrecompiledContract.java - create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/precompile/Falcon512PrecompiledContract.java - create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/precompile/MLDSA44PrecompiledContract.java - create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/precompile/SHAKE256PrecompiledContract.java - create mode 100644 evm/src/main/java/org/hyperledger/besu/evm/precompile/SLHDSA128sPrecompiledContract.java +Regenerated 2026-09-10 from the production tree (overlay applied) over the same file set. diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java -index 950cd59e3..51397dc38 100644 +index 950cd59e3..0f486dfcf 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java -@@ -12,6 +12,21 @@ - * - * SPDX-License-Identifier: Apache-2.0 - */ -+ -+/* -+ * Modifications Copyright 2026 Aere Network. -+ * -+ * This file was changed by Aere Network: five post-quantum precompile address -+ * constants were added (AERE_FALCON512, AERE_FALCON1024, AERE_MLDSA44, -+ * AERE_SLHDSA128S, AERE_SHAKE256, at 0x0ae1 through 0x0ae5). Nothing upstream -+ * was removed or rewritten. -+ * -+ * The unmodified original is Hyperledger Besu commit -+ * d2032017bb3b8cb215a97303980a1e4a643f7180. The upstream copyright header above is -+ * left exactly as it was found. -+ * -+ * This notice is required by Apache License 2.0 section 4(b). -+ */ - package org.hyperledger.besu.datatypes; - - import static com.google.common.base.Preconditions.checkArgument; -@@ -91,6 +106,21 @@ public class Address extends BytesHolder { +@@ -91,6 +91,21 @@ public class Address extends BytesHolder { /** Precompile address for P256_VERIFY. */ public static final Address P256_VERIFY = Address.precompiled(0x0100); @@ -110,12 +33,12 @@ index 950cd59e3..51397dc38 100644 diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AereFalconSupport.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AereFalconSupport.java new file mode 100644 -index 000000000..011fc2164 +index 000000000..1dbb2b85c --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AereFalconSupport.java @@ -0,0 +1,94 @@ +/* -+ * Copyright contributors to the Aere Network. ++ * Copyright contributors to the AERE Network. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at @@ -210,12 +133,12 @@ index 000000000..011fc2164 +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/Falcon1024PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Falcon1024PrecompiledContract.java new file mode 100644 -index 000000000..e383b1f8f +index 000000000..80aca574d --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Falcon1024PrecompiledContract.java @@ -0,0 +1,62 @@ +/* -+ * Copyright contributors to the Aere Network. ++ * Copyright contributors to the AERE Network. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at @@ -278,12 +201,12 @@ index 000000000..e383b1f8f +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/Falcon512PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Falcon512PrecompiledContract.java new file mode 100644 -index 000000000..8c0a07ee6 +index 000000000..5df074ceb --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/Falcon512PrecompiledContract.java @@ -0,0 +1,62 @@ +/* -+ * Copyright contributors to the Aere Network. ++ * Copyright contributors to the AERE Network. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at @@ -346,12 +269,12 @@ index 000000000..8c0a07ee6 +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/MLDSA44PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/MLDSA44PrecompiledContract.java new file mode 100644 -index 000000000..8c41a2fb1 +index 000000000..f25be641f --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/MLDSA44PrecompiledContract.java @@ -0,0 +1,84 @@ +/* -+ * Copyright contributors to the Aere Network. ++ * Copyright contributors to the AERE Network. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at @@ -435,31 +358,10 @@ index 000000000..8c41a2fb1 + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java -index 28d84abf1..d75afaf57 100644 +index 28d84abf1..43d9fb73a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java -@@ -12,6 +12,20 @@ - * - * SPDX-License-Identifier: Apache-2.0 - */ -+ -+/* -+ * Modifications Copyright 2026 Aere Network. -+ * -+ * This file was changed by Aere Network: populateForFutureEIPs was repointed -+ * from populateForCancun to populateForOsaka, and five post-quantum precompiles -+ * were registered in it (0x0ae1 through 0x0ae5). Nothing upstream was removed. -+ * -+ * The unmodified original is Hyperledger Besu commit -+ * d2032017bb3b8cb215a97303980a1e4a643f7180. The upstream copyright header above is -+ * left exactly as it was found. -+ * -+ * This notice is required by Apache License 2.0 section 4(b). -+ */ - package org.hyperledger.besu.evm.precompile; - - import static org.hyperledger.besu.datatypes.Address.P256_VERIFY; -@@ -226,6 +240,15 @@ public interface MainnetPrecompiledContracts { +@@ -226,6 +226,15 @@ public interface MainnetPrecompiledContracts { */ static void populateForFutureEIPs( final PrecompileContractRegistry registry, final GasCalculator gasCalculator) { @@ -468,7 +370,7 @@ index 28d84abf1..d75afaf57 100644 + // Activated on a running chain via genesis config "futureEipsTime"; no re-genesis needed. + populateForOsaka(registry, gasCalculator); + -+ // Native post-quantum precompiles (Bouncy Castle BCPQC verifiers). ++ // Native post-quantum precompiles (audited Bouncy Castle BCPQC verifiers). + registry.put(Address.AERE_FALCON512, new Falcon512PrecompiledContract(gasCalculator)); + registry.put(Address.AERE_FALCON1024, new Falcon1024PrecompiledContract(gasCalculator)); + registry.put(Address.AERE_MLDSA44, new MLDSA44PrecompiledContract(gasCalculator)); @@ -478,12 +380,12 @@ index 28d84abf1..d75afaf57 100644 } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/SHAKE256PrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/SHAKE256PrecompiledContract.java new file mode 100644 -index 000000000..fe0f0cf32 +index 000000000..0c20e6a66 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/SHAKE256PrecompiledContract.java @@ -0,0 +1,93 @@ +/* -+ * Copyright contributors to the Aere Network. ++ * Copyright contributors to the AERE Network. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at @@ -512,7 +414,7 @@ index 000000000..fe0f0cf32 + * Output: exactly {@code outLen} bytes of SHAKE256(data). + * + *

SHAKE256 is the hashing bottleneck inside Falcon, ML-DSA and SLH-DSA; exposing it natively lets -+ * on-chain PQC flows offload the hot path to Bouncy Castle rather than hand-rolled Solidity. ++ * on-chain PQC flows offload the hot path to audited Bouncy Castle rather than hand-rolled Solidity. + */ +public class SHAKE256PrecompiledContract extends AbstractPrecompiledContract { + @@ -577,12 +479,12 @@ index 000000000..fe0f0cf32 +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/SLHDSA128sPrecompiledContract.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/SLHDSA128sPrecompiledContract.java new file mode 100644 -index 000000000..5e7527aab +index 000000000..2666602f4 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/SLHDSA128sPrecompiledContract.java @@ -0,0 +1,84 @@ +/* -+ * Copyright contributors to the Aere Network. ++ * Copyright contributors to the AERE Network. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at diff --git a/patches/0003-aere-pq-anchor.patch b/patches/0003-aere-pq-anchor.patch index 25d06ac..1b66521 100644 --- a/patches/0003-aere-pq-anchor.patch +++ b/patches/0003-aere-pq-anchor.patch @@ -1,356 +1,15 @@ From 65a97c099634691fed1c2ee619b74b5cf0254739 Mon Sep 17 00:00:00 2001 From: Aere Network -Date: Sat, 5 Sep 2026 07:53:19 +0300 +Date: Thu, 10 Sep 2026 21:47:55 +0300 Subject: [PATCH] Aere Network: post-quantum certificate anchor for QBFT -Puts a 32-byte digest of the validator certificate into vanityData, which is -already covered by the block hash, so that the hash commits to the certificate. -The certificate itself still rides outside the hash and is pinned by the digest. - -Apache License 2.0, section 4(b): the files this patch modifies are the work of -Hyperledger Besu and carry its copyright notice. This patch changes them. The -modifications are by contributors to the Aere Network and are offered under the -same Apache License 2.0; the upstream copyright headers are left as found. - -The slhdsa/ package under consensus/common is derived from Bouncy Castle 1.80 -and stays under the Bouncy Castle licence; its notice is carried alongside -(LICENSE-BouncyCastle.txt). - -Updated 2026-09-05: the v2, scheme-tagged hybrid certificate (Falcon-512 and -SLH-DSA-SHA2-128s seals, live on chain 2800 since block 17,047,600), the in-tree -SLH-DSA engine on the JDK digest, the seal-store repair (a commit heard before -the round held its proposal, or a late commit, was dropped from the store; the -round-0 proposer of an anchor then refused to propose), and the anchor interval -schedule (aere.pq.anchorIntervalSchedule, 17225968:128 on chain 2800). The -post-quantum message layers (PROPOSAL, PREPARE, COMMIT, ROUND-CHANGE seals with -per-type domains) are included with their emission and enforcement height -switches; see anchor/README.md for what is armed on chain 2800. ---- - .../org/hyperledger/besu/cli/BesuCommand.java | 24 + - .../cli/options/AerePqEmergencyOptions.java | 244 + - .../controller/QbftBesuControllerBuilder.java | 281 ++ - .../options/AerePqEmergencyOptionsTest.java | 136 + - .../besu/config/JsonGenesisConfigOptions.java | 22 + - consensus/common/build.gradle | 7 + - .../common/bft/AereAnchorProposalDelay.java | 152 + - .../common/bft/BftBlockInterface.java | 26 +- - .../consensus/common/bft/BftExtraData.java | 87 +- - .../besu/consensus/common/bft/BlockTimer.java | 10 +- - .../besu/consensus/common/bft/FalconSeal.java | 88 + - .../common/bft/FalconSealScheme.java | 104 + - .../common/bft/FalconSealSupport.java | 4130 +++++++++++++++++ - .../common/bft/HybridSealProducer.java | 140 + - .../common/bft/HybridSealSupport.java | 295 ++ - .../common/bft/HybridSignerRegistry.java | 307 ++ - .../besu/consensus/common/bft/PqAnchor.java | 547 +++ - .../consensus/common/bft/PqAnchorConfig.java | 1580 +++++++ - .../consensus/common/bft/PqAnchorLapse.java | 375 ++ - .../common/bft/PqAnchorNotReadyException.java | 132 + - .../common/bft/PqAnchorSyncModeGuard.java | 130 + - .../common/bft/PqAnchorThresholdGuard.java | 282 ++ - .../besu/consensus/common/bft/PqAnchorV2.java | 185 + - .../common/bft/PqRegistryBinding.java | 496 ++ - .../consensus/common/bft/PqRegistryHash.java | 2339 ++++++++++ - .../common/bft/PqRegistryHashTool.java | 481 ++ - .../common/bft/PqSchemeSchedule.java | 139 + - .../consensus/common/bft/PqSealCache.java | 431 ++ - .../consensus/common/bft/PqSealStore.java | 401 ++ - .../common/bft/PqSignerRegistry.java | 167 + - .../besu/consensus/common/bft/SchemeSeal.java | 69 + - .../besu/consensus/common/bft/SealScheme.java | 96 + - .../consensus/common/bft/SealSchemes.java | 56 + - .../common/bft/SlhDsaSealScheme.java | 136 + - .../blockcreation/BftBlockCreatorFactory.java | 25 +- - .../bft/blockcreation/PqAnchorProducer.java | 524 +++ - .../consensus/common/bft/slhdsa/ADRS.java | 115 + - .../consensus/common/bft/slhdsa/Fors.java | 178 + - .../besu/consensus/common/bft/slhdsa/HT.java | 225 + - .../common/bft/slhdsa/IndexedDigest.java | 26 + - .../common/bft/slhdsa/JdkDigest.java | 104 + - .../bft/slhdsa/LICENSE-BouncyCastle.txt | 22 + - .../common/bft/slhdsa/NodeEntry.java | 24 + - .../besu/consensus/common/bft/slhdsa/PK.java | 24 + - .../besu/consensus/common/bft/slhdsa/SIG.java | 77 + - .../consensus/common/bft/slhdsa/SIG_FORS.java | 34 + - .../consensus/common/bft/slhdsa/SIG_XMSS.java | 34 + - .../besu/consensus/common/bft/slhdsa/SK.java | 24 + - .../common/bft/slhdsa/SLHDSAEngine.java | 466 ++ - .../bft/slhdsa/SLHDSAEngineProvider.java | 19 + - .../slhdsa/SLHDSAKeyGenerationParameters.java | 33 + - .../bft/slhdsa/SLHDSAKeyPairGenerator.java | 70 + - .../bft/slhdsa/SLHDSAKeyParameters.java | 31 + - .../common/bft/slhdsa/SLHDSAParameters.java | 186 + - .../slhdsa/SLHDSAPrivateKeyParameters.java | 80 + - .../bft/slhdsa/SLHDSAPublicKeyParameters.java | 52 + - .../common/bft/slhdsa/SLHDSASigner.java | 236 + - .../consensus/common/bft/slhdsa/WotsPlus.java | 177 + - .../common/bft/tools/PqRegistryHashTool.java | 231 + - .../bft/AereAnchorProposalDelayTest.java | 106 + - .../common/bft/D177NeutralNamesTest.java | 97 + - .../common/bft/FalconAttachIntervalTest.java | 228 + - .../common/bft/HybridSealProducerTest.java | 177 + - .../common/bft/HybridSealSupportTest.java | 206 + - .../common/bft/HybridSignerRegistryTest.java | 225 + - .../common/bft/PqAnchorConfigTest.java | 754 +++ - .../bft/PqAnchorEmergencyConfigTest.java | 120 + - .../common/bft/PqAnchorIntervalTest.java | 184 + - .../common/bft/PqAnchorLapseTest.java | 249 + - .../common/bft/PqAnchorMinSealsFloorTest.java | 152 + - .../bft/PqAnchorProducerCacheHygieneTest.java | 104 + - .../common/bft/PqAnchorProducerCostTest.java | 250 + - .../common/bft/PqAnchorSealCapTest.java | 150 + - .../consensus/common/bft/PqAnchorTest.java | 301 ++ - .../bft/PqAnchorThresholdGuardTest.java | 232 + - .../common/bft/PqAnchorV2ProducerTest.java | 326 ++ - .../consensus/common/bft/PqAnchorV2Test.java | 192 + - .../common/bft/PqArmingGateTest.java | 387 ++ - .../common/bft/PqCallerIntentTest.java | 386 ++ - .../common/bft/PqFleetRestartArmingTest.java | 411 ++ - .../common/bft/PqForkArmingTest.java | 370 ++ - .../bft/PqForkThresholdReachabilityTest.java | 354 ++ - .../bft/PqForkValidatorSetChangeTest.java | 430 ++ - .../common/bft/PqInertBinaryTest.java | 475 ++ - .../bft/PqParentHeightAlignmentTest.java | 229 + - .../common/bft/PqRegistryBindingTest.java | 595 +++ - .../bft/PqRegistryHeightRefusalTest.java | 326 ++ - .../common/bft/PqRegistryRotationTest.java | 486 ++ - .../common/bft/PqSchemeScheduleTest.java | 127 + - .../common/bft/PqSealPersistenceTest.java | 652 +++ - .../common/bft/PqSignedHeightTest.java | 402 ++ - .../common/bft/PqStartupHistoryTest.java | 324 ++ - .../consensus/common/bft/PqV2Fixture.java | 232 + - .../common/bft/PreparePqAttachGateTest.java | 101 + - .../common/bft/ProposalPqAttachGateTest.java | 104 + - .../bft/RoundChangePqAttachGateTest.java | 108 + - .../common/bft/SealSchemeAgilityTest.java | 145 + - .../common/bft/SlhDsaCrossVectorTest.java | 82 + - .../common/bft/SlhDsaFastEngineTest.java | 141 + - .../qbft/core/messagewrappers/Commit.java | 32 + - .../core/network/QbftMessageTransmitter.java | 117 +- - .../qbft/core/payload/CommitPayload.java | 262 +- - .../qbft/core/payload/MessageFactory.java | 124 +- - .../qbft/core/payload/PreparePayload.java | 112 +- - .../qbft/core/payload/ProposalPayload.java | 101 +- - .../qbft/core/payload/RoundChangePayload.java | 97 +- - .../statemachine/QbftBlockHeightManager.java | 81 +- - .../core/statemachine/QbftController.java | 57 + - .../qbft/core/statemachine/QbftRound.java | 410 +- - .../qbft/core/statemachine/RoundState.java | 37 + - .../qbft/core/types/QbftBlockCreator.java | 37 + - .../qbft/core/validation/CommitValidator.java | 124 +- - .../core/validation/MessageValidator.java | 24 +- - .../core/validation/PqCommitEnforcement.java | 369 ++ - .../core/validation/PqPrepareEnforcement.java | 206 + - .../validation/PqProposalEnforcement.java | 202 + - .../validation/PqRoundChangeEnforcement.java | 209 + - .../core/validation/PrepareValidator.java | 50 +- - .../validation/ProposalPayloadValidator.java | 55 +- - .../RoundChangePayloadValidator.java | 54 +- - .../network/ProposalSealPlumbingTest.java | 101 + - .../network/RoundChangeSealPlumbingTest.java | 88 + - .../core/payload/CommitPayloadHybridTest.java | 277 ++ - .../core/payload/PreparePayloadPqTest.java | 209 + - .../core/payload/ProposalPayloadPqTest.java | 202 + - .../payload/RoundChangePayloadPqTest.java | 236 + - .../PqHybridExtrasNeverThrowTest.java | 69 + - .../statemachine/PqLateSealSalvageTest.java | 195 + - .../PqSealsWithoutProposalTest.java | 168 + - .../CommitValidatorAnchorFormTest.java | 216 + - .../CommitValidatorPqEnforcementTest.java | 152 + - ...essageValidatorAnchorFormPlumbingTest.java | 109 + - .../validation/PqCommitEnforcementTest.java | 159 + - .../core/validation/PqCommitPlumbingTest.java | 108 + - .../validation/PqHybridEnforcementTest.java | 312 ++ - .../core/validation/PqMessageAgilityTest.java | 198 + - .../core/validation/PqPrepareAgilityTest.java | 180 + - .../validation/PqPrepareEnforcementTest.java | 266 ++ - .../validation/PqProposalEnforcementTest.java | 297 ++ - .../PqRoundChangeEnforcementTest.java | 422 ++ - .../PqTransportIndependenceTest.java | 437 ++ - .../PrepareValidatorPqWiringTest.java | 118 + - .../ProposalPayloadValidatorPqWiringTest.java | 133 + - .../RoundChangeJustificationPqTest.java | 298 ++ - ...undChangePayloadValidatorPqWiringTest.java | 125 + - ...ftBlockHeaderValidationRulesetFactory.java | 120 +- - .../consensus/qbft/QbftExtraDataCodec.java | 122 +- - .../qbft/adaptor/QbftBlockCreatorAdaptor.java | 213 +- - .../QbftBlockCreatorFactory.java | 35 +- - .../AereBaseFeeImportRule.java | 135 + - .../FalconSealValidationRule.java | 513 ++ - .../PqAnchorDigestAttachedRule.java | 115 + - .../PqAnchorDigestRule.java | 310 ++ - .../PqAnchorSealsRule.java | 579 +++ - .../PqEmergencyShoutRule.java | 134 + - .../PqRegistryBindingRule.java | 90 + - .../qbft/QbftAnchorRuleWiringTest.java | 246 + - .../AereBaseFeeImportRuleTest.java | 142 + - .../FalconSealLogThrottleTest.java | 181 + - ...alconSealValidationRuleRetirementTest.java | 85 + - .../PqAnchorDigestRuleTest.java | 359 ++ - .../PqAnchorDisarmedWindowTest.java | 548 +++ - .../PqAnchorSealsRuleTest.java | 691 +++ - .../PqAnchorTestSupport.java | 144 + - .../PqAnchorV2RulesTest.java | 361 ++ - .../PqArmedWithoutRegistryTest.java | 185 + - .../PqEmergencyShoutRuleTest.java | 78 + - .../PqForkGateFeedTest.java | 191 + - .../eth/sync/DownloadHeadersStep.java | 103 +- - 169 files changed, 41451 insertions(+), 96 deletions(-) - create mode 100755 app/src/main/java/org/hyperledger/besu/cli/options/AerePqEmergencyOptions.java - create mode 100755 app/src/test/java/org/hyperledger/besu/cli/options/AerePqEmergencyOptionsTest.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereAnchorProposalDelay.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/FalconSeal.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/FalconSealScheme.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/FalconSealSupport.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/HybridSealProducer.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/HybridSealSupport.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/HybridSignerRegistry.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchor.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfig.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorLapse.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorNotReadyException.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorSyncModeGuard.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuard.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV2.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqRegistryBinding.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqRegistryHash.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqRegistryHashTool.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSchemeSchedule.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealCache.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSealStore.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/PqSignerRegistry.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/SchemeSeal.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/SealScheme.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/SealSchemes.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/SlhDsaSealScheme.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/PqAnchorProducer.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/ADRS.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/Fors.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/HT.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/IndexedDigest.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/JdkDigest.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/LICENSE-BouncyCastle.txt - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/NodeEntry.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/PK.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SIG.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SIG_FORS.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SIG_XMSS.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SK.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSAEngine.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSAEngineProvider.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSAKeyGenerationParameters.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSAKeyPairGenerator.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSAKeyParameters.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSAParameters.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSAPrivateKeyParameters.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSAPublicKeyParameters.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/SLHDSASigner.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/slhdsa/WotsPlus.java - create mode 100755 consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/tools/PqRegistryHashTool.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/AereAnchorProposalDelayTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/D177NeutralNamesTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/FalconAttachIntervalTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/HybridSealProducerTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/HybridSealSupportTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/HybridSignerRegistryTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorConfigTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorEmergencyConfigTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorIntervalTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorLapseTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorMinSealsFloorTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCacheHygieneTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCostTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorSealCapTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorThresholdGuardTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV2ProducerTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorV2Test.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqArmingGateTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqCallerIntentTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqFleetRestartArmingTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqForkArmingTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqForkThresholdReachabilityTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqForkValidatorSetChangeTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqInertBinaryTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqParentHeightAlignmentTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqRegistryBindingTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqRegistryHeightRefusalTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqRegistryRotationTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSchemeScheduleTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSealPersistenceTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqSignedHeightTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqStartupHistoryTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqV2Fixture.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PreparePqAttachGateTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/ProposalPqAttachGateTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/RoundChangePqAttachGateTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/SealSchemeAgilityTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/SlhDsaCrossVectorTest.java - create mode 100755 consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/SlhDsaFastEngineTest.java - create mode 100755 consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitEnforcement.java - create mode 100755 consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqPrepareEnforcement.java - create mode 100755 consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqProposalEnforcement.java - create mode 100755 consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqRoundChangeEnforcement.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/network/ProposalSealPlumbingTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/network/RoundChangeSealPlumbingTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/payload/CommitPayloadHybridTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparePayloadPqTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/payload/ProposalPayloadPqTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/payload/RoundChangePayloadPqTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqHybridExtrasNeverThrowTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqLateSealSalvageTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/statemachine/PqSealsWithoutProposalTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorAnchorFormTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidatorPqEnforcementTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidatorAnchorFormPlumbingTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitEnforcementTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitPlumbingTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqHybridEnforcementTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqMessageAgilityTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqPrepareAgilityTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqPrepareEnforcementTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqProposalEnforcementTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqRoundChangeEnforcementTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PqTransportIndependenceTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidatorPqWiringTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidatorPqWiringTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangeJustificationPqTest.java - create mode 100755 consensus/qbft-core/src/test/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidatorPqWiringTest.java - create mode 100755 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/AereBaseFeeImportRule.java - create mode 100755 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/FalconSealValidationRule.java - create mode 100755 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestAttachedRule.java - create mode 100755 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRule.java - create mode 100755 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorSealsRule.java - create mode 100755 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqEmergencyShoutRule.java - create mode 100755 consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqRegistryBindingRule.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/QbftAnchorRuleWiringTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/AereBaseFeeImportRuleTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/FalconSealLogThrottleTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/FalconSealValidationRuleRetirementTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDigestRuleTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorDisarmedWindowTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorSealsRuleTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorTestSupport.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqAnchorV2RulesTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqArmedWithoutRegistryTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqEmergencyShoutRuleTest.java - create mode 100755 consensus/qbft/src/test/java/org/hyperledger/besu/consensus/qbft/headervalidationrules/PqForkGateFeedTest.java +Regenerated 2026-09-10 from the production tree (overlay applied) over the same file set. diff --git a/app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index 2767db2eb..df19c1dd2 100644 --- a/app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java -@@ -1,63 +1,70 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -363,30 +22,7 @@ index 2767db2eb..df19c1dd2 100644 */ package org.hyperledger.besu.cli; - import static com.google.common.base.Preconditions.checkNotNull; - import static com.google.common.base.Preconditions.checkState; - import static java.lang.Long.parseLong; - import static java.nio.charset.StandardCharsets.UTF_8; - import static java.util.Arrays.asList; - import static org.hyperledger.besu.cli.DefaultCommandValues.getDefaultBesuDataPath; - import static org.hyperledger.besu.cli.util.CommandLineUtils.DEPENDENCY_WARNING_MSG; - import static org.hyperledger.besu.cli.util.CommandLineUtils.isOptionSet; - import static org.hyperledger.besu.config.NetworkDefinition.EPHEMERY; - import static org.hyperledger.besu.config.NetworkDefinition.MAINNET; - import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; - import static org.hyperledger.besu.ethereum.api.jsonrpc.authentication.EngineAuthService.EPHEMERAL_JWT_FILE; - - import org.hyperledger.besu.Runner; - import org.hyperledger.besu.RunnerBuilder; - import org.hyperledger.besu.chainexport.Era1BlockExporter; - import org.hyperledger.besu.chainexport.RlpBlockExporter; - import org.hyperledger.besu.chainimport.Era1BlockImporter; - import org.hyperledger.besu.chainimport.JsonBlockImporter; - import org.hyperledger.besu.chainimport.RlpBlockImporter; - import org.hyperledger.besu.cli.config.EthNetworkConfig; - import org.hyperledger.besu.cli.config.NativeRequirement; - import org.hyperledger.besu.cli.config.NativeRequirement.NativeRequirementResult; - import org.hyperledger.besu.cli.config.ProfilesCompletionCandidates; +@@ -41,6 +47,7 @@ import org.hyperledger.besu.cli.config.ProfilesCompletionCandidates; import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; import org.hyperledger.besu.cli.error.BesuExecutionExceptionHandler; import org.hyperledger.besu.cli.error.BesuParameterExceptionHandler; @@ -394,41 +30,7 @@ index 2767db2eb..df19c1dd2 100644 import org.hyperledger.besu.cli.options.ApiConfigurationOptions; import org.hyperledger.besu.cli.options.BalConfigurationOptions; import org.hyperledger.besu.cli.options.ChainPruningOptions; - import org.hyperledger.besu.cli.options.DnsOptions; - import org.hyperledger.besu.cli.options.EngineRPCConfiguration; - import org.hyperledger.besu.cli.options.EngineRPCOptions; - import org.hyperledger.besu.cli.options.EthProtocolOptions; - import org.hyperledger.besu.cli.options.EthstatsOptions; - import org.hyperledger.besu.cli.options.EvmOptions; - import org.hyperledger.besu.cli.options.GraphQlOptions; - import org.hyperledger.besu.cli.options.InProcessRpcOptions; - import org.hyperledger.besu.cli.options.IpcOptions; - import org.hyperledger.besu.cli.options.JsonRpcHttpOptions; - import org.hyperledger.besu.cli.options.LoggingLevelOption; - import org.hyperledger.besu.cli.options.MetricsOptions; - import org.hyperledger.besu.cli.options.MiningOptions; - import org.hyperledger.besu.cli.options.NatOptions; - import org.hyperledger.besu.cli.options.NativeLibraryOptions; - import org.hyperledger.besu.cli.options.NetworkingOptions; - import org.hyperledger.besu.cli.options.NodePrivateKeyFileOption; -@@ -282,40 +289,47 @@ public class BesuCommand implements DefaultCommandValues, Runnable { - private final Supplier rlpBlockImporter; - private final Function jsonBlockImporterFactory; - private final Supplier era1BlockImporter; - private final Function rlpBlockExporterFactory; - private final BiFunction - era1BlockExporterFactory; - - // Unstable CLI options - final NetworkingOptions unstableNetworkingOptions = NetworkingOptions.create(); - final SynchronizerOptions unstableSynchronizerOptions = SynchronizerOptions.create(); - final EthProtocolOptions unstableEthProtocolOptions = EthProtocolOptions.create(); - private final DnsOptions unstableDnsOptions = DnsOptions.create(); - private final NatOptions unstableNatOptions = NatOptions.create(); - private final NativeLibraryOptions unstableNativeLibraryOptions = NativeLibraryOptions.create(); - private final RPCOptions unstableRPCOptions = RPCOptions.create(); - private final EvmOptions unstableEvmOptions = EvmOptions.create(); - private final IpcOptions unstableIpcOptions = IpcOptions.create(); +@@ -299,6 +306,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private final ChainPruningOptions unstableChainPruningOptions = ChainPruningOptions.create(); private final QBFTOptions unstableQbftOptions = QBFTOptions.create(); @@ -442,41 +44,7 @@ index 2767db2eb..df19c1dd2 100644 // stable CLI options final DataStorageOptions dataStorageOptions = DataStorageOptions.create(); private final EthstatsOptions ethstatsOptions = EthstatsOptions.create(); - private final NodePrivateKeyFileOption nodePrivateKeyFileOption = - NodePrivateKeyFileOption.create(); - private final LoggingLevelOption loggingLevelOption = LoggingLevelOption.create(); - - @CommandLine.ArgGroup(validate = false, heading = "@|bold Tx Pool Common Options|@%n") - final TransactionPoolOptions transactionPoolOptions = TransactionPoolOptions.create(); - - @CommandLine.ArgGroup(validate = false, heading = "@|bold Block Builder Options|@%n") - final MiningOptions miningOptions = MiningOptions.create(); - - private final RunnerBuilder runnerBuilder; - private final BesuController.Builder controllerBuilder; - private final BesuPluginContextImpl besuPluginContext; - private final StorageServiceImpl storageService; - private final SecurityModuleServiceImpl securityModuleService; - private final PermissioningServiceImpl permissioningService; - private final RpcEndpointServiceImpl rpcEndpointServiceImpl; -@@ -933,40 +947,47 @@ public class BesuCommand implements DefaultCommandValues, Runnable { - .setCaseInsensitiveEnumValuesAllowed(true) - .setToggleBooleanFlags(false); - } - - @Override - public void run() { - if (network != null && network.isDeprecated()) { - logger.warn(NetworkDeprecationMessage.generate(network)); - } - try { - configureLogging(true); - - if (printPathsAndExit) { - // Print configured paths requiring read/write permissions to be adjusted - checkPermissionsAndPrintPaths(besuUserName); - System.exit(0); // Exit before any services are started - } +@@ -950,6 +964,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { logger.info("Starting Besu"); @@ -490,41 +58,7 @@ index 2767db2eb..df19c1dd2 100644 // set merge config on the basis of genesis config setMergeConfigOptions(); - instantiateSignatureAlgorithmFactory(); - - // Need to create vertx after cmdline has been parsed, such that metricsSystem is configurable - vertx = createVertx(besuComponent.getMetricsSystem()); - - validateOptions(); - - initialProcess(); - - if (network.equals(EPHEMERY)) { - long lastGenesisTimestamp = parseLong(genesisConfigOverrides.get("timestamp")); - runner.scheduleEphemeryRestart(this, lastGenesisTimestamp); - } - runner.awaitStop(); - - } catch (final Exception e) { - logger.error("Failed to start Besu: {}", e.getMessage()); -@@ -1226,40 +1247,43 @@ public class BesuCommand implements DefaultCommandValues, Runnable { - commandLine.addMixin("Logging level", loggingLevelOption); - commandLine.addMixin("Data Storage Options", dataStorageOptions); - } - - private void handleUnstableOptions() { - // Add unstable options - final ImmutableMap.Builder unstableOptionsBuild = ImmutableMap.builder(); - final ImmutableMap unstableOptions = - unstableOptionsBuild - .put("Ethereum Wire Protocol", unstableEthProtocolOptions) - .put("P2P Network", unstableNetworkingOptions) - .put("RPC", unstableRPCOptions) - .put("DNS Configuration", unstableDnsOptions) - .put("NAT Configuration", unstableNatOptions) - .put("Synchronizer", unstableSynchronizerOptions) - .put("Native Library", unstableNativeLibraryOptions) - .put("EVM Options", unstableEvmOptions) +@@ -1243,6 +1264,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .put("IPC Options", unstableIpcOptions) .put("Chain Data Pruning Options", unstableChainPruningOptions) .put("QBFT Options", unstableQbftOptions) @@ -534,23 +68,6 @@ index 2767db2eb..df19c1dd2 100644 .build(); UnstableOptionsSubCommand.createUnstableOptions(commandLine, unstableOptions); - } - - private void preparePlugins() { - besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); - - metricCategoryRegistry.addCategories(BesuMetricCategory.class); - metricCategoryRegistry.addCategories(StandardMetricCategory.class); - - BesuPluginServiceRegistrar.registerEarlyServices( - besuPluginContext, - securityModuleService, - storageService, - metricCategoryRegistry, - permissioningService, - rpcEndpointServiceImpl, - transactionSelectionServiceImpl, - transactionPoolValidatorServiceImpl, diff --git a/app/src/main/java/org/hyperledger/besu/cli/options/AerePqEmergencyOptions.java b/app/src/main/java/org/hyperledger/besu/cli/options/AerePqEmergencyOptions.java new file mode 100755 index 000000000..509c81f73 @@ -802,20 +319,10 @@ index 000000000..509c81f73 + } +} diff --git a/app/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java b/app/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java -index 7fbf58d0b..c9bd35074 100644 +index 7fbf58d0b..281add4c9 100644 --- a/app/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java +++ b/app/src/main/java/org/hyperledger/besu/controller/QbftBesuControllerBuilder.java -@@ -1,56 +1,71 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -828,7 +335,7 @@ index 7fbf58d0b..c9bd35074 100644 */ package org.hyperledger.besu.controller; - import static com.google.common.base.Preconditions.checkNotNull; +@@ -18,6 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import org.hyperledger.besu.config.BftConfigOptions; import org.hyperledger.besu.config.BftFork; @@ -836,15 +343,7 @@ index 7fbf58d0b..c9bd35074 100644 import org.hyperledger.besu.config.QbftConfigOptions; import org.hyperledger.besu.config.QbftFork; import org.hyperledger.besu.consensus.common.BftValidatorOverrides; - import org.hyperledger.besu.consensus.common.EpochManager; - import org.hyperledger.besu.consensus.common.ForksSchedule; - import org.hyperledger.besu.consensus.common.bft.BftBlockInterface; - import org.hyperledger.besu.consensus.common.bft.BftContext; - import org.hyperledger.besu.consensus.common.bft.BftEventQueue; - import org.hyperledger.besu.consensus.common.bft.BftExecutors; - import org.hyperledger.besu.consensus.common.bft.BftProcessor; - import org.hyperledger.besu.consensus.common.bft.BftProtocolSchedule; - import org.hyperledger.besu.consensus.common.bft.BftRoundExpiryTimeCalculator; +@@ -33,7 +40,15 @@ import org.hyperledger.besu.consensus.common.bft.BftRoundExpiryTimeCalculator; import org.hyperledger.besu.consensus.common.bft.BlockTimer; import org.hyperledger.besu.consensus.common.bft.EthSynchronizerUpdater; import org.hyperledger.besu.consensus.common.bft.EventMultiplexer; @@ -860,41 +359,7 @@ index 7fbf58d0b..c9bd35074 100644 import org.hyperledger.besu.consensus.common.bft.RoundTimer; import org.hyperledger.besu.consensus.common.bft.UniqueMessageMulticaster; import org.hyperledger.besu.consensus.common.bft.blockcreation.BftMiningCoordinator; - import org.hyperledger.besu.consensus.common.bft.blockcreation.BftProposerSelector; - import org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector; - import org.hyperledger.besu.consensus.common.bft.network.ValidatorPeers; - import org.hyperledger.besu.consensus.common.bft.protocol.BftProtocolManager; - import org.hyperledger.besu.consensus.common.bft.statemachine.BftEventHandler; - import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffer; - import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; - import org.hyperledger.besu.consensus.common.validator.blockbased.BlockValidatorProvider; - import org.hyperledger.besu.consensus.qbft.FutureMessageSynchronizerHandler; - import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec; - import org.hyperledger.besu.consensus.qbft.QbftForksSchedulesFactory; - import org.hyperledger.besu.consensus.qbft.QbftProtocolScheduleBuilder; - import org.hyperledger.besu.consensus.qbft.adaptor.AdaptorUtil; - import org.hyperledger.besu.consensus.qbft.adaptor.BftEventHandlerAdaptor; - import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockCodecAdaptor; - import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockCreatorFactoryAdaptor; - import org.hyperledger.besu.consensus.qbft.adaptor.QbftBlockInterfaceAdaptor; -@@ -180,69 +195,299 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder { - new BftProtocolManager( - bftEventQueue, - peers, - Istanbul100SubProtocol.ISTANBUL_100, - Istanbul100SubProtocol.get().getName())); - maybeSnapProtocolManager.ifPresent( - snapProtocolManager -> - subProtocolConfiguration.withSubProtocol(SnapProtocol.get(), snapProtocolManager)); - return subProtocolConfiguration; - } - - @Override - protected MiningCoordinator createMiningCoordinator( - final ProtocolSchedule protocolSchedule, - final ProtocolContext protocolContext, - final TransactionPool transactionPool, - final MiningConfiguration miningConfiguration, +@@ -197,6 +212,283 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder { final SyncState syncState, final EthProtocolManager ethProtocolManager) { final MutableBlockchain blockchain = protocolContext.getBlockchain(); @@ -1004,6 +469,69 @@ index 7fbf58d0b..c9bd35074 100644 + + "opens again.", + e.toString()); + } ++ ++ // AERE-D358 (2026-09-10, measured on validator 8 of chain 2800): the "import path" named above ++ // is FalconSealValidationRule, and on 2800 that rule is RETIRED from the anchor block ++ // (PqAnchorConfig.legacyFalconRuleRetirementBlock), so it never runs. The startup attempt ++ // above is therefore the ONLY attempt, and it is silent when the head world state is not yet ++ // readable at that instant: after a plain container restart at 15:41Z the manifest loaded as ++ // PENDING, no STARTUP line was logged at all, and the node stayed PENDING for 55 minutes - ++ // refusing every peer Commit and Prepare as "NO post-quantum seal", emitting nothing, timing ++ // out its proposer slot every rotation, and slowing the whole chain from 0.56 to 1.07 s/block. ++ // A second restart activated at once, which is exactly what a race looks like. ++ // ++ // The repair: while the late anchor is PENDING, retry the same read (same contract, same ++ // slot 0, same activateLateAnchor) on every block added to the chain, and stop retrying once ++ // it is activated or terminally failed. It invents nothing and weakens no check. ++ if (FalconSealSupport.instance().anchorAddress() != null ++ && FalconSealSupport.instance().lateAnchorPending()) { ++ final java.util.concurrent.atomic.AtomicLong aereD358Retries = ++ new java.util.concurrent.atomic.AtomicLong(); ++ blockchain.observeBlockAdded( ++ event -> { ++ final FalconSealSupport pqc = FalconSealSupport.instance(); ++ if (!pqc.lateAnchorPending()) { ++ return; ++ } ++ try { ++ final BlockHeader h = event.getBlock().getHeader(); ++ protocolContext ++ .getWorldStateArchive() ++ .get(h.getStateRoot(), h.getHash()) ++ .ifPresent( ++ ws -> { ++ final var cont = ++ ws.get(Address.fromHexString(pqc.anchorAddress())); ++ if (cont == null) { ++ return; ++ } ++ final var slot0 = ++ cont.getStorageValue( ++ org.apache.tuweni.units.bigints.UInt256.ZERO); ++ if (slot0 == null || slot0.isZero()) { ++ return; ++ } ++ final long n = aereD358Retries.incrementAndGet(); ++ final boolean armat = ++ pqc.activateLateAnchor(slot0.toBytes().toUnprefixedHexString()); ++ if (armat || n == 1 || n % 100 == 0) { ++ LOG.info( ++ "AERE-D358: late-anchor activation retried at block {} (attempt {}): {}", ++ h.getNumber(), ++ n, ++ armat ++ ? "SUCCEEDED" ++ : "still pending (contract present, hash mismatch or refused)"); ++ } ++ }); ++ } catch (final Exception e) { ++ LOG.debug("AERE-D358: retry could not read the head state ({})", e.toString()); ++ } ++ }); ++ LOG.info( ++ "AERE-D358: late anchor is PENDING after the startup attempt; activation will be " ++ + "retried on every imported block until it succeeds or terminally fails."); ++ } + } + + // AERE A8 (2026-08-01): bind the Falcon registry to consensus. @@ -1115,29 +643,7 @@ index 7fbf58d0b..c9bd35074 100644 final BftExecutors bftExecutors = BftExecutors.create(metricsSystem, BftExecutors.ConsensusType.QBFT); final QbftBlockCodec blockEncoder = new QbftBlockCodecAdaptor(qbftExtraDataCodec); - - final Address localAddress = Util.publicKeyToAddress(nodeKey.getPublicKey()); - final BftProtocolSchedule bftProtocolSchedule = (BftProtocolSchedule) protocolSchedule; - QbftProtocolSchedule qbftProtocolSchedule = - new QbftProtocolScheduleAdaptor(bftProtocolSchedule, protocolContext); - final QbftBlockCreatorFactory blockCreatorFactory = - new QbftBlockCreatorFactory( - transactionPool, - protocolContext, - bftProtocolSchedule, - qbftForksSchedule, - miningConfiguration, - localAddress, - qbftExtraDataCodec, - ethProtocolManager.ethContext().getScheduler()); - - final ValidatorProvider validatorProvider; - if (qbftConfig.getStartBlock().isPresent()) { - validatorProvider = - protocolContext - .getConsensusContext(BftContext.class, qbftConfig.getStartBlock().getAsLong()) - .getValidatorProvider(); - } else { +@@ -226,6 +518,22 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder { validatorProvider = protocolContext.getConsensusContext(BftContext.class).getValidatorProvider(); } @@ -1160,41 +666,7 @@ index 7fbf58d0b..c9bd35074 100644 final QbftValidatorProvider qbftValidatorProvider = new QbftValidatorProviderAdaptor(validatorProvider); - final QbftBlockInterface qbftBlockInterface = new QbftBlockInterfaceAdaptor(bftBlockInterface); - - final ProposerSelector proposerSelector = - new BftProposerSelector(blockchain, bftBlockInterface, true, validatorProvider); - - // NOTE: peers should not be used for accessing the network as it does not enforce the - // "only send once" filter applied by the UniqueMessageMulticaster. - peers = new ValidatorPeers(validatorProvider, Istanbul100SubProtocol.NAME); - - final UniqueMessageMulticaster uniqueMessageMulticaster = - new UniqueMessageMulticaster(peers, qbftConfig.getGossipedHistoryLimit()); - - final QbftGossiperImpl gossiper = new QbftGossiperImpl(uniqueMessageMulticaster, blockEncoder); - - final QbftFinalState finalState = - new QbftFinalStateImpl( - validatorProvider, -@@ -430,36 +675,72 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder { - return new BftContext(validatorProvider, epochManager, bftBlockInterface); - } - - private BftValidatorOverrides convertBftForks(final List bftForks) { - final Map> result = new HashMap<>(); - - for (final BftFork fork : bftForks) { - fork.getValidators() - .ifPresent( - validators -> - result.put( - fork.getForkBlock(), - validators.stream() - .map(Address::fromHexString) - .collect(Collectors.toList()))); - } - +@@ -447,6 +755,42 @@ public class QbftBesuControllerBuilder extends BesuControllerBuilder { return new BftValidatorOverrides(result); } @@ -1237,19 +709,6 @@ index 7fbf58d0b..c9bd35074 100644 private static MinedBlockObserver blockLogger( final TransactionPool transactionPool, final Address localAddress) { return block -> - LOG.info( - String.format( - "%s %s #%,d / %d tx / %d pending / %,d (%01.1f%%) gas / (%s)", - block.getHeader().getCoinbase().equals(localAddress) ? "Produced" : "Imported", - block.getBody().getTransactions().isEmpty() ? "empty block" : "block", - block.getHeader().getNumber(), - block.getBody().getTransactions().size(), - transactionPool.count(), - block.getHeader().getGasUsed(), - (block.getHeader().getGasUsed() * 100.0) / block.getHeader().getGasLimit(), - block.getHash().getBytes().toHexString())); - } - } diff --git a/app/src/test/java/org/hyperledger/besu/cli/options/AerePqEmergencyOptionsTest.java b/app/src/test/java/org/hyperledger/besu/cli/options/AerePqEmergencyOptionsTest.java new file mode 100755 index 000000000..b77a549b2 @@ -1396,17 +855,7 @@ diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigO index eeaa4ac3e..79581600f 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java -@@ -1,33 +1,39 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -1419,41 +868,7 @@ index eeaa4ac3e..79581600f 100644 */ package org.hyperledger.besu.config; - import static java.util.Collections.emptyMap; - import static java.util.Objects.isNull; - - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.datatypes.Hash; - import org.hyperledger.besu.datatypes.Wei; - - import java.math.BigInteger; - import java.util.List; - import java.util.Map; - import java.util.Objects; - import java.util.Optional; - import java.util.OptionalInt; - import java.util.OptionalLong; - import java.util.TreeMap; - import java.util.stream.Stream; - -@@ -622,21 +628,37 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { - .filter(OptionalLong::isPresent) - .map(OptionalLong::getAsLong) - .distinct() - .sorted() - .toList(); - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final JsonGenesisConfigOptions that = (JsonGenesisConfigOptions) o; - return Objects.equals(configRoot, that.configRoot) - && Objects.equals(configOverrides, that.configOverrides); - } - - @Override +@@ -639,4 +645,20 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { public int hashCode() { return Objects.hash(configRoot, configOverrides); } @@ -1478,17 +893,7 @@ diff --git a/consensus/common/build.gradle b/consensus/common/build.gradle index 499c974f1..a6f5276f2 100644 --- a/consensus/common/build.gradle +++ b/consensus/common/build.gradle -@@ -1,69 +1,76 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -1501,36 +906,7 @@ index 499c974f1..a6f5276f2 100644 */ apply plugin: 'java-library' - - jar { - archiveBaseName = calculateArtifactId(project) - manifest { - attributes( - 'Specification-Title': archiveBaseName, - 'Specification-Version': project.version, - 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion(), - 'Commit-Hash': getGitCommitDetails(40).hash - ) - } - } - - dependencies { - api project(':plugin-api') - - implementation project(':config') - implementation project(':crypto:services') - implementation project(':datatypes') - implementation project(':ethereum:api') - implementation project(':ethereum:blockcreation') - implementation project(':ethereum:core') - implementation project(':ethereum:eth') - implementation project(':ethereum:p2p') - implementation project(':ethereum:rlp') - implementation project(':evm') - implementation project(':util') - - compileOnly 'org.jspecify:jspecify' +@@ -47,6 +53,7 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'com.google.guava:guava' @@ -1538,23 +914,6 @@ index 499c974f1..a6f5276f2 100644 implementation 'io.consensys.tuweni:tuweni-bytes' testImplementation project(':config') - testImplementation project(':crypto:algorithms') - testImplementation project(':testutil') - testImplementation project( path: ':ethereum:core', configuration: 'testSupportArtifacts') - testImplementation project( path: ':crypto:services', configuration: 'testSupportArtifacts') - testImplementation project(':metrics:core') - - testImplementation 'org.assertj:assertj-core' - testImplementation 'org.awaitility:awaitility' - testImplementation 'org.junit.jupiter:junit-jupiter' - testImplementation 'org.mockito:mockito-core' - testImplementation 'org.mockito:mockito-junit-jupiter' - - testSupportImplementation project( path: ':crypto:services', configuration: 'testSupportArtifacts') - testSupportImplementation project( path: ':ethereum:core', configuration: 'testSupportArtifacts') - testSupportImplementation 'org.mockito:mockito-core' - testSupportImplementation 'org.assertj:assertj-core' - } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereAnchorProposalDelay.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/AereAnchorProposalDelay.java new file mode 100755 index 000000000..84eeb15a4 @@ -1717,17 +1076,7 @@ diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/commo index b7a886c29..77af53d68 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftBlockInterface.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftBlockInterface.java -@@ -1,33 +1,39 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -1740,41 +1089,7 @@ index b7a886c29..77af53d68 100644 */ package org.hyperledger.besu.consensus.common.bft; - import org.hyperledger.besu.consensus.common.BlockInterface; - import org.hyperledger.besu.consensus.common.validator.ValidatorVote; - import org.hyperledger.besu.consensus.common.validator.VoteType; - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.datatypes.Hash; - import org.hyperledger.besu.ethereum.core.Block; - import org.hyperledger.besu.ethereum.core.BlockHeader; - import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; - import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; - import org.hyperledger.besu.ethereum.core.Util; - - import java.util.Collection; - import java.util.List; - import java.util.Optional; - import java.util.stream.Collectors; - - /** The Bft block interface. */ -@@ -62,55 +68,73 @@ public class BftBlockInterface implements BlockInterface { - final Vote headerVote = bftExtraData.getVote().get(); - final ValidatorVote vote = - new ValidatorVote( - headerVote.isAuth() ? VoteType.ADD : VoteType.DROP, - getProposerOfBlock(header), - headerVote.getRecipient()); - return Optional.of(vote); - } - return Optional.empty(); - } - - @Override - public Collection

validatorsInBlock(final BlockHeader header) { - final BftExtraData bftExtraData = bftExtraDataCodec.decode(header); - return bftExtraData.getValidators(); - } - +@@ -79,6 +85,19 @@ public class BftBlockInterface implements BlockInterface { /** * Replace round in block. * @@ -1794,14 +1109,7 @@ index b7a886c29..77af53d68 100644 * @param block the block * @param round the round * @param blockHeaderFunctions the block header functions - * @return the block - */ - public Block replaceRoundInBlock( - final Block block, final int round, final BlockHeaderFunctions blockHeaderFunctions) { - final BftExtraData prevExtraData = bftExtraDataCodec.decode(block.getHeader()); - final BftExtraData substituteExtraData = - new BftExtraData( - prevExtraData.getVanityData(), +@@ -93,7 +112,12 @@ public class BftBlockInterface implements BlockInterface { prevExtraData.getSeals(), prevExtraData.getVote(), round, @@ -1815,38 +1123,11 @@ index b7a886c29..77af53d68 100644 final BlockHeaderBuilder headerBuilder = BlockHeaderBuilder.fromHeader(block.getHeader()); headerBuilder - .extraData(bftExtraDataCodec.encode(substituteExtraData)) - .blockHeaderFunctions(blockHeaderFunctions); - - final BlockHeader newHeader = headerBuilder.buildBlockHeader(); - - return new Block(newHeader, block.getBody()); - } - - /** - * Gets extra data. - * - * @param header the header - * @return the extra data - */ - public BftExtraData getExtraData(final BlockHeader header) { - return bftExtraDataCodec.decode(header); - } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java index a24c33a93..c444a1514 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftExtraData.java -@@ -1,78 +1,141 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -1859,10 +1140,7 @@ index a24c33a93..c444a1514 100644 */ package org.hyperledger.besu.consensus.common.bft; - import static com.google.common.base.Preconditions.checkNotNull; - - import org.hyperledger.besu.crypto.SECPSignature; - import org.hyperledger.besu.datatypes.Address; +@@ -21,6 +27,8 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.core.ParsedExtraData; import java.util.Collection; @@ -1871,13 +1149,7 @@ index a24c33a93..c444a1514 100644 import java.util.Optional; import org.apache.tuweni.bytes.Bytes; - - /** The Bft extra data. */ - public class BftExtraData implements ParsedExtraData { - private final Bytes vanityData; - private final Collection seals; - private final Collection
validators; - private final Optional vote; +@@ -34,7 +42,17 @@ public class BftExtraData implements ParsedExtraData { private final int round; /** @@ -1896,13 +1168,7 @@ index a24c33a93..c444a1514 100644 * * @param vanityData the vanity data * @param seals the seals - * @param vote the vote - * @param round the round - * @param validators the validators - */ - public BftExtraData( - final Bytes vanityData, - final Collection seals, +@@ -48,14 +66,59 @@ public class BftExtraData implements ParsedExtraData { final Optional vote, final int round, final Collection
validators) { @@ -1962,41 +1228,7 @@ index a24c33a93..c444a1514 100644 } /** - * Gets vanity data. - * - * @return the vanity data - */ - public Bytes getVanityData() { - return vanityData; - } - - /** - * Gets seals. - * - * @return the seals - */ - public Collection getSeals() { - return seals; - } - -@@ -86,36 +149,58 @@ public class BftExtraData implements ParsedExtraData { - } - - /** - * Gets vote. - * - * @return the vote - */ - public Optional getVote() { - return vote; - } - - /** - * Gets round. - * - * @return the round - */ - public int getRound() { +@@ -103,6 +166,24 @@ public class BftExtraData implements ParsedExtraData { return round; } @@ -2021,13 +1253,7 @@ index a24c33a93..c444a1514 100644 @Override public String toString() { return "BftExtraData{" - + "vanityData=" - + vanityData - + ", seals=" - + seals - + ", validators=" - + validators - + ", vote=" +@@ -116,6 +197,10 @@ public class BftExtraData implements ParsedExtraData { + vote + ", round=" + round @@ -2039,70 +1265,36 @@ index a24c33a93..c444a1514 100644 } } diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BlockTimer.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BlockTimer.java -index 80f6815c8..78178359e 100644 +index 80f6815c8..73493403c 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BlockTimer.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BlockTimer.java -@@ -36,40 +36,42 @@ public class BlockTimer { - private final BftExecutors bftExecutors; - private Optional> currentTimerTask; - private final BftEventQueue queue; - private final Clock clock; - private long blockPeriodSeconds; - private long emptyBlockPeriodSeconds; +@@ -11,6 +11,12 @@ + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. + */ + package org.hyperledger.besu.consensus.common.bft; - /** - * Construct a BlockTimer with primed executor service ready to start timers - * - * @param queue The queue in which to put block expiry events - * @param forksSchedule Bft fork schedule that contains block period seconds - * @param bftExecutors Executor services that timers can be scheduled with - * @param clock System clock - */ - public BlockTimer( - final BftEventQueue queue, +@@ -53,6 +59,12 @@ public class BlockTimer { final ForksSchedule forksSchedule, final BftExecutors bftExecutors, final Clock clock) { -+ // D-334: o configuratie gresita se refuza la PORNIRE, nu la prima intrebuintare in masina de stari ++ // Load the anchor proposal-delay configuration HERE, at construction, so a malformed value ++ // refuses START-UP rather than surfacing on its first use inside the consensus state machine. ++ // Measured 2026-09-03 on mainnet: a lazily-loaded consensus setting turned an unreadable file ++ // into 125 seconds of halted chain, while every configuration gate stayed green because the ++ // files existed. + AereAnchorProposalDelay.configuredMillis(); this.queue = queue; this.forksSchedule = forksSchedule; this.bftExecutors = bftExecutors; - this.currentTimerTask = Optional.empty(); - this.clock = clock; - this.blockPeriodSeconds = 0; - this.emptyBlockPeriodSeconds = 0; - } - - /** Cancels the current running round timer if there is one */ - public synchronized void cancelTimer() { - currentTimerTask.ifPresent(t -> t.cancel(false)); - currentTimerTask = Optional.empty(); - } - - /** - * Whether there is a timer currently running or not - * - * @return boolean of whether a timer is ticking or not - */ -@@ -106,41 +108,47 @@ public class BlockTimer { - } - - // Experimental option for test scenarios only. Not for production use. - final long blockPeriodMilliseconds = currentForkOptions.getBlockPeriodMilliseconds(); - if (blockPeriodMilliseconds > 0) { - // Experimental mode for setting < 1 second block periods e.g. for CI/CD pipelines - // running tests against Besu - expiryTime = clock.millis() + blockPeriodMilliseconds; - LOG.warn( - "Test-mode only xblockperiodmilliseconds has been set to {} millisecond blocks. Do not use in a production system.", - blockPeriodMilliseconds); - } else { - // absolute time when the timer is supposed to expire - final long minimumTimeBetweenBlocksMillis = currentBlockPeriodSeconds * 1000L; - expiryTime = headerTimestamp.get() * 1_000 + minimumTimeBetweenBlocksMillis; - } - +@@ -123,7 +135,13 @@ public class BlockTimer { final int emptyBlockPeriodSeconds = currentForkOptions.getEmptyBlockPeriodSeconds(); setBlockTimes(currentBlockPeriodSeconds, emptyBlockPeriodSeconds); @@ -2117,23 +1309,6 @@ index 80f6815c8..78178359e 100644 } /** - * Checks if the empty block timer is expired - * - * @param headerTimestamp Function to get the chain head timestamp - * @param currentTimeInMillis The current time - * @return a boolean value - */ - public synchronized boolean checkEmptyBlockExpired( - final Supplier headerTimestamp, final long currentTimeInMillis) { - final long emptyBlockPeriodExpiryTime = - (headerTimestamp.get() + emptyBlockPeriodSeconds) * 1000; - - if (currentTimeInMillis > emptyBlockPeriodExpiryTime) { - LOG.debug("Empty Block expired"); - return true; - } - LOG.debug("Empty Block NOT expired"); - return false; diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/FalconSeal.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/FalconSeal.java new file mode 100755 index 000000000..9f290a1aa @@ -15388,17 +14563,7 @@ diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/commo index 20c072202..1ecdcbf34 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java -@@ -1,33 +1,39 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -15411,41 +14576,7 @@ index 20c072202..1ecdcbf34 100644 */ package org.hyperledger.besu.consensus.common.bft.blockcreation; - import static com.google.common.base.Preconditions.checkState; - - import org.hyperledger.besu.config.BftConfigOptions; - import org.hyperledger.besu.consensus.common.ConsensusHelpers; - import org.hyperledger.besu.consensus.common.ForksSchedule; - import org.hyperledger.besu.consensus.common.bft.BftContext; - import org.hyperledger.besu.consensus.common.bft.BftExtraData; - import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; - import org.hyperledger.besu.consensus.common.bft.Vote; - import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; - import org.hyperledger.besu.consensus.common.validator.ValidatorVote; - import org.hyperledger.besu.consensus.common.validator.VoteProvider; - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.datatypes.Wei; - import org.hyperledger.besu.ethereum.ProtocolContext; - import org.hyperledger.besu.ethereum.blockcreation.BlockCreator; - import org.hyperledger.besu.ethereum.core.BlockHeader; -@@ -140,61 +146,78 @@ public class BftBlockCreatorFactory { - return miningConfiguration.getMinTransactionGasPrice(); - } - - /** - * Gets min priority fee per gas - * - * @return min priority fee per gas - */ - public Wei getMinPriorityFeePerGas() { - return miningConfiguration.getMinPriorityFeePerGas(); - } - - /** - * Create extra data bytes. - * - * @param round the round - * @param parentHeader the parent header +@@ -157,6 +163,23 @@ public class BftBlockCreatorFactory { * @return the bytes */ public Bytes createExtraData(final int round, final BlockHeader parentHeader) { @@ -15469,20 +14600,7 @@ index 20c072202..1ecdcbf34 100644 final BftContext bftContext = protocolContext.getConsensusContext(BftContext.class); final ValidatorProvider validatorProvider = bftContext.getValidatorProvider(); Optional voteProviderAfterBlock = - validatorProvider.getVoteProviderAfterBlock(parentHeader); - checkState(voteProviderAfterBlock.isPresent(), "Bft requires a vote provider"); - final Optional proposal = - voteProviderAfterBlock.get().getVoteAfterBlock(parentHeader, localAddress); - - final List
validators = - new ArrayList<>(validatorProvider.getValidatorsAfterBlock(parentHeader)); - - final BftExtraData extraData = - new BftExtraData( - ConsensusHelpers.zeroLeftPad( - miningConfiguration.getExtraData(), BftExtraDataCodec.EXTRA_VANITY_LENGTH), - Collections.emptyList(), - toVote(proposal), +@@ -177,7 +200,7 @@ public class BftBlockCreatorFactory { round, validators); @@ -15491,23 +14609,6 @@ index 20c072202..1ecdcbf34 100644 } /** - * Change target gas limit. - * - * @param newTargetGasLimit the new target gas limit - */ - public void changeTargetGasLimit(final Long newTargetGasLimit) { - if (AbstractGasLimitSpecification.isValidTargetGasLimit(newTargetGasLimit)) { - miningConfiguration.setTargetGasLimit(newTargetGasLimit); - } else { - throw new UnsupportedOperationException("Specified target gas limit is invalid"); - } - } - - /** - * Gets local address. - * - * @return the local address - */ diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/PqAnchorProducer.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/PqAnchorProducer.java new file mode 100755 index 000000000..a46b7d887 @@ -21209,7 +20310,7 @@ index 000000000..651c63ba3 + } +} diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCacheHygieneTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCacheHygieneTest.java -new file mode 100755 +new file mode 100644 index 000000000..7230f1eff --- /dev/null +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/PqAnchorProducerCacheHygieneTest.java @@ -29808,17 +28909,7 @@ diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qb index 142069ec7..00d7b78c2 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Commit.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/messagewrappers/Commit.java -@@ -1,68 +1,100 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,9 +11,16 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -29835,8 +28926,7 @@ index 142069ec7..00d7b78c2 100644 import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; import org.hyperledger.besu.consensus.qbft.core.payload.CommitPayload; - import org.hyperledger.besu.crypto.SECPSignature; - import org.hyperledger.besu.datatypes.Hash; +@@ -22,6 +29,8 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.rlp.RLP; import org.hyperledger.besu.ethereum.rlp.RLPInput; @@ -29845,23 +28935,7 @@ index 142069ec7..00d7b78c2 100644 import org.apache.tuweni.bytes.Bytes; /** The Commit payload message. */ - public class Commit extends BftMessage { - - /** - * Instantiates a new Commit. - * - * @param payload the payload - */ - public Commit(final SignedData payload) { - super(payload); - } - - /** - * Gets commit seal. - * - * @return the commit seal - */ - public SECPSignature getCommitSeal() { +@@ -45,11 +54,34 @@ public class Commit extends BftMessage { return getPayload().getCommitSeal(); } @@ -29896,34 +28970,11 @@ index 142069ec7..00d7b78c2 100644 public Hash getDigest() { return getPayload().getDigest(); } - - /** - * Decode. - * - * @param data the data - * @return the commit - */ - public static Commit decode(final Bytes data) { - final RLPInput rlpIn = RLP.input(data); - - return new Commit(readPayload(rlpIn, CommitPayload::readFrom)); - } - } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftMessageTransmitter.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftMessageTransmitter.java index 30156ed6d..18437e30f 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftMessageTransmitter.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/network/QbftMessageTransmitter.java -@@ -1,37 +1,45 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,10 +11,18 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -29942,41 +28993,7 @@ index 30156ed6d..18437e30f 100644 import org.hyperledger.besu.consensus.common.bft.network.ValidatorMulticaster; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; import org.hyperledger.besu.consensus.qbft.core.messagedata.CommitMessageData; - import org.hyperledger.besu.consensus.qbft.core.messagedata.PrepareMessageData; - import org.hyperledger.besu.consensus.qbft.core.messagedata.ProposalMessageData; - import org.hyperledger.besu.consensus.qbft.core.messagedata.RoundChangeMessageData; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; - import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; - import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; - import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; - import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock; - import org.hyperledger.besu.crypto.SECPSignature; - import org.hyperledger.besu.datatypes.Hash; - import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList; - import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException; - -@@ -59,94 +67,195 @@ public class QbftMessageTransmitter { - final MessageFactory messageFactory, final ValidatorMulticaster multicaster) { - this.messageFactory = messageFactory; - this.multicaster = multicaster; - } - - /** - * Multicast proposal. - * - * @param roundIdentifier the round identifier - * @param block the block - * @param blockAccessList the block access list - * @param roundChanges the round changes - * @param prepares the prepares - */ - public void multicastProposal( - final ConsensusRoundIdentifier roundIdentifier, - final QbftBlock block, +@@ -76,10 +84,42 @@ public class QbftMessageTransmitter { final Optional blockAccessList, final List> roundChanges, final List> prepares) { @@ -30021,16 +29038,7 @@ index 30156ed6d..18437e30f 100644 final ProposalMessageData message = ProposalMessageData.create(data); - multicaster.send(message); - } catch (final SecurityModuleException e) { - LOG.warn("Failed to generate signature for Proposal (not sent): {} ", e.getMessage()); - } - } - - /** - * Multicast prepare. - * - * @param roundIdentifier the round identifier +@@ -96,8 +136,27 @@ public class QbftMessageTransmitter { * @param digest the digest */ public void multicastPrepare(final ConsensusRoundIdentifier roundIdentifier, final Hash digest) { @@ -30059,20 +29067,7 @@ index 30156ed6d..18437e30f 100644 final PrepareMessageData message = PrepareMessageData.create(data); - multicaster.send(message); - } catch (final SecurityModuleException e) { - LOG.warn("Failed to generate signature for Prepare (not sent): {} ", e.getMessage()); - } - } - - /** - * Multicast commit. - * - * @param roundIdentifier the round identifier - * @param digest the digest - * @param commitSeal the commit seal - */ - public void multicastCommit( +@@ -118,8 +177,44 @@ public class QbftMessageTransmitter { final ConsensusRoundIdentifier roundIdentifier, final Hash digest, final SECPSignature commitSeal) { @@ -30118,29 +29113,7 @@ index 30156ed6d..18437e30f 100644 final CommitMessageData message = CommitMessageData.create(data); - multicaster.send(message); - } catch (final SecurityModuleException e) { - LOG.warn("Failed to generate signature for Commit (not sent): {} ", e.getMessage()); - } - } - - /** - * Multicast round change. - * - * @param roundIdentifier the round identifier - * @param preparedRoundCertificate the prepared round certificate - */ - public void multicastRoundChange( - final ConsensusRoundIdentifier roundIdentifier, - final Optional preparedRoundCertificate) { - try { - final RoundChange data = - messageFactory.createRoundChange(roundIdentifier, preparedRoundCertificate); - - final RoundChangeMessageData message = RoundChangeMessageData.create(data); - - multicaster.send(message); - } catch (final SecurityModuleException e) { +@@ -149,4 +244,18 @@ public class QbftMessageTransmitter { LOG.warn("Failed to generate signature for RoundChange (not sent): {} ", e.getMessage()); } } @@ -30163,17 +29136,7 @@ diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qb index db481acd0..8b788f499 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/CommitPayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/CommitPayload.java -@@ -1,133 +1,375 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,30 +11,62 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -30238,9 +29201,7 @@ index db481acd0..8b788f499 100644 * * @param roundIdentifier the round identifier * @param digest the digest - * @param commitSeal the commit seal - */ - public CommitPayload( +@@ -44,26 +76,197 @@ public class CommitPayload extends QbftPayload { final ConsensusRoundIdentifier roundIdentifier, final Hash digest, final SECPSignature commitSeal) { @@ -30444,8 +29405,7 @@ index db481acd0..8b788f499 100644 } @Override - public void writeTo(final RLPOutput rlpOutput) { - rlpOutput.startList(); +@@ -72,6 +275,23 @@ public class CommitPayload extends QbftPayload { writeConsensusRound(rlpOutput); rlpOutput.writeBytes(digest.getBytes()); rlpOutput.writeBytes(commitSeal.encodedBytes()); @@ -30469,26 +29429,7 @@ index db481acd0..8b788f499 100644 rlpOutput.endList(); } - @Override - public int getMessageType() { - return TYPE; - } - - /** - * Gets digest. - * - * @return the digest - */ - public Hash getDigest() { - return digest; - } - - /** - * Gets commit seal. - * - * @return the commit seal - */ - public SECPSignature getCommitSeal() { +@@ -98,6 +318,24 @@ public class CommitPayload extends QbftPayload { return commitSeal; } @@ -30513,16 +29454,7 @@ index db481acd0..8b788f499 100644 @Override public ConsensusRoundIdentifier getRoundIdentifier() { return roundIdentifier; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } +@@ -114,12 +352,14 @@ public class CommitPayload extends QbftPayload { final CommitPayload that = (CommitPayload) o; return Objects.equals(roundIdentifier, that.roundIdentifier) && Objects.equals(digest, that.digest) @@ -30539,8 +29471,7 @@ index db481acd0..8b788f499 100644 } @Override - public String toString() { - return new StringJoiner(", ", CommitPayload.class.getSimpleName() + "[", "]") +@@ -128,6 +368,8 @@ public class CommitPayload extends QbftPayload { .add("roundIdentifier=" + roundIdentifier) .add("digest=" + digest) .add("commitSeal=" + commitSeal) @@ -30553,17 +29484,7 @@ diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qb index 1bcd73ae9..11426d6a6 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/MessageFactory.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/MessageFactory.java -@@ -1,37 +1,44 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,10 +11,17 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -30581,41 +29502,7 @@ index 1bcd73ae9..11426d6a6 100644 import org.hyperledger.besu.consensus.common.bft.payload.Payload; import org.hyperledger.besu.consensus.common.bft.payload.SignedData; import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; - import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec; - import org.hyperledger.besu.crypto.SECPSignature; - import org.hyperledger.besu.cryptoservices.NodeKey; - import org.hyperledger.besu.datatypes.Hash; - import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList; - - import java.util.Collections; - import java.util.List; - import java.util.Optional; - - import org.apache.tuweni.bytes.Bytes32; - -@@ -58,111 +65,220 @@ public class MessageFactory { - * @param roundIdentifier the round identifier - * @param block the block - * @param blockAccessList the block access list - * @param roundChanges the round changes - * @param prepares the prepares - * @return the proposal - */ - public Proposal createProposal( - final ConsensusRoundIdentifier roundIdentifier, - final QbftBlock block, - final Optional blockAccessList, - final List> roundChanges, - final List> prepares) { - - final ProposalPayload payload = - new ProposalPayload(roundIdentifier, block, blockEncoder, blockAccessList); - +@@ -75,6 +82,35 @@ public class MessageFactory { return new Proposal(createSignedMessage(payload), roundChanges, prepares); } @@ -30651,25 +29538,7 @@ index 1bcd73ae9..11426d6a6 100644 /** * Create proposal. * - * @param roundIdentifier the round identifier - * @param block the block - * @param roundChanges the round changes - * @param prepares the prepares - * @return the proposal - */ - public Proposal createProposal( - final ConsensusRoundIdentifier roundIdentifier, - final QbftBlock block, - final List> roundChanges, - final List> prepares) { - return createProposal(roundIdentifier, block, Optional.empty(), roundChanges, prepares); - } - - /** - * Create Prepare payload. - * - * @param roundIdentifier the round identifier - * @param digest the digest +@@ -100,7 +136,27 @@ public class MessageFactory { * @return the prepare */ public Prepare createPrepare(final ConsensusRoundIdentifier roundIdentifier, final Hash digest) { @@ -30698,15 +29567,7 @@ index 1bcd73ae9..11426d6a6 100644 return new Prepare(createSignedMessage(payload)); } - /** - * Create commit payload. - * - * @param roundIdentifier the round identifier - * @param digest the digest - * @param commitSeal the commit seal - * @return the commit - */ - public Commit createCommit( +@@ -116,7 +172,47 @@ public class MessageFactory { final ConsensusRoundIdentifier roundIdentifier, final Hash digest, final SECPSignature commitSeal) { @@ -30755,13 +29616,7 @@ index 1bcd73ae9..11426d6a6 100644 return new Commit(createSignedMessage(payload)); } - /** - * Create round change payload. - * - * @param roundIdentifier the round identifier - * @param preparedRoundData the prepared round data - * @return the round change - */ +@@ -130,6 +226,25 @@ public class MessageFactory { public RoundChange createRoundChange( final ConsensusRoundIdentifier roundIdentifier, final Optional preparedRoundData) { @@ -30787,10 +29642,7 @@ index 1bcd73ae9..11426d6a6 100644 final RoundChangePayload payload; if (preparedRoundData.isPresent()) { - - final QbftBlock preparedBlock = preparedRoundData.get().getBlock(); - payload = - new RoundChangePayload( +@@ -140,7 +255,8 @@ public class MessageFactory { roundIdentifier, Optional.of( new PreparedRoundMetadata( @@ -30800,9 +29652,7 @@ index 1bcd73ae9..11426d6a6 100644 return new RoundChange( createSignedMessage(payload), - Optional.of(preparedBlock), - preparedRoundData.get().getBlockAccessList(), - blockEncoder, +@@ -150,7 +266,7 @@ public class MessageFactory { preparedRoundData.get().getPrepares()); } else { @@ -30811,36 +29661,20 @@ index 1bcd73ae9..11426d6a6 100644 return new RoundChange( createSignedMessage(payload), Optional.empty(), - Optional.empty(), - blockEncoder, - Collections.emptyList()); - } - } - - private SignedData createSignedMessage(final M payload) { - final SECPSignature signature = - nodeKey.sign(Bytes32.wrap(payload.hashForSignature().getBytes())); - return SignedData.create(payload, signature); - } - } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparePayload.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparePayload.java -index b9d53d35f..5533ef604 100644 +index b9d53d35f..727cbccc8 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparePayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/PreparePayload.java -@@ -1,110 +1,204 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,48 +11,127 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. */ package org.hyperledger.besu.consensus.qbft.core.payload; @@ -30966,7 +29800,7 @@ index b9d53d35f..5533ef604 100644 } @Override - public void writeTo(final RLPOutput rlpOutput) { +@@ -60,6 +139,16 @@ public class PreparePayload extends QbftPayload { rlpOutput.startList(); writeConsensusRound(rlpOutput); rlpOutput.writeBytes(digest.getBytes()); @@ -30983,17 +29817,7 @@ index b9d53d35f..5533ef604 100644 rlpOutput.endList(); } - @Override - public int getMessageType() { - return TYPE; - } - - /** - * Gets digest. - * - * @return the digest - */ - public Hash getDigest() { +@@ -77,6 +166,15 @@ public class PreparePayload extends QbftPayload { return digest; } @@ -31009,15 +29833,7 @@ index b9d53d35f..5533ef604 100644 @Override public ConsensusRoundIdentifier getRoundIdentifier() { return roundIdentifier; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; +@@ -92,12 +190,13 @@ public class PreparePayload extends QbftPayload { } final PreparePayload that = (PreparePayload) o; return Objects.equals(roundIdentifier, that.roundIdentifier) @@ -31033,7 +29849,7 @@ index b9d53d35f..5533ef604 100644 } @Override - public String toString() { +@@ -105,6 +204,7 @@ public class PreparePayload extends QbftPayload { return new StringJoiner(", ", PreparePayload.class.getSimpleName() + "[", "]") .add("roundIdentifier=" + roundIdentifier) .add("digest=" + digest) @@ -31042,23 +29858,19 @@ index b9d53d35f..5533ef604 100644 } } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/ProposalPayload.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/ProposalPayload.java -index eb1a2246c..8daf65caf 100644 +index eb1a2246c..813e798a9 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/ProposalPayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/ProposalPayload.java -@@ -1,167 +1,254 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,15 +11,23 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. */ package org.hyperledger.besu.consensus.qbft.core.payload; @@ -31073,8 +29885,7 @@ index eb1a2246c..8daf65caf 100644 import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.rlp.RLPOutput; - import java.util.Objects; - import java.util.Optional; +@@ -28,7 +36,33 @@ import java.util.Optional; import com.google.common.base.MoreObjects; @@ -31109,7 +29920,7 @@ index eb1a2246c..8daf65caf 100644 public class ProposalPayload extends QbftPayload { private static final int TYPE = QbftV1.PROPOSAL; - private final ConsensusRoundIdentifier roundIdentifier; +@@ -36,24 +70,45 @@ public class ProposalPayload extends QbftPayload { private final QbftBlock proposedBlock; private final QbftBlockCodec blockEncoder; private final Optional blockAccessList; @@ -31157,13 +29968,7 @@ index eb1a2246c..8daf65caf 100644 } /** - * Instantiates a new Proposal payload. - * - * @param roundIdentifier the round identifier - * @param proposedBlock the proposed block - * @param blockEncoder the qbft block encoder - */ - public ProposalPayload( +@@ -67,7 +122,7 @@ public class ProposalPayload extends QbftPayload { final ConsensusRoundIdentifier roundIdentifier, final QbftBlock proposedBlock, final QbftBlockCodec blockEncoder) { @@ -31172,15 +29977,7 @@ index eb1a2246c..8daf65caf 100644 } /** - * Read from rlp input and return proposal payload. - * - * @param rlpInput the rlp input - * @param blockEncoder the qbft block encoder - * @return the proposal payload - */ - public static ProposalPayload readFrom( - final RLPInput rlpInput, final QbftBlockCodec blockEncoder) { - rlpInput.enterList(); +@@ -83,9 +138,28 @@ public class ProposalPayload extends QbftPayload { final ConsensusRoundIdentifier roundIdentifier = readConsensusRound(rlpInput); final QbftBlock proposedBlock = blockEncoder.readFrom(rlpInput); final Optional blockAccessList = readBlockAccessList(rlpInput); @@ -31210,8 +30007,7 @@ index eb1a2246c..8daf65caf 100644 } @Override - public void writeTo(final RLPOutput rlpOutput) { - rlpOutput.startList(); +@@ -94,6 +168,14 @@ public class ProposalPayload extends QbftPayload { writeConsensusRound(rlpOutput); blockEncoder.writeTo(proposedBlock, rlpOutput); blockAccessList.ifPresentOrElse((bal) -> bal.writeTo(rlpOutput), rlpOutput::writeNull); @@ -31226,21 +30022,7 @@ index eb1a2246c..8daf65caf 100644 rlpOutput.endList(); } - /** - * Gets proposed block. - * - * @return the proposed block - */ - public QbftBlock getProposedBlock() { - return proposedBlock; - } - - /** - * Gets block access list. - * - * @return the block access list - */ - public Optional getBlockAccessList() { +@@ -115,6 +197,15 @@ public class ProposalPayload extends QbftPayload { return blockAccessList; } @@ -31256,21 +30038,7 @@ index eb1a2246c..8daf65caf 100644 @Override public int getMessageType() { return TYPE; - } - - @Override - public ConsensusRoundIdentifier getRoundIdentifier() { - return roundIdentifier; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } +@@ -136,12 +227,13 @@ public class ProposalPayload extends QbftPayload { ProposalPayload that = (ProposalPayload) o; return Objects.equals(roundIdentifier, that.roundIdentifier) && Objects.equals(proposedBlock, that.proposedBlock) @@ -31286,8 +30054,7 @@ index eb1a2246c..8daf65caf 100644 } @Override - public String toString() { - return MoreObjects.toStringHelper(this) +@@ -150,6 +242,7 @@ public class ProposalPayload extends QbftPayload { .add("roundIdentifier", roundIdentifier) .add("proposedBlock", proposedBlock) .add("blockAccessList", blockAccessList) @@ -31295,36 +30062,20 @@ index eb1a2246c..8daf65caf 100644 .toString(); } - private static Optional readBlockAccessList(final RLPInput rlpInput) { - if (rlpInput.isEndOfCurrentList()) { - // Backward compatibility: pre-26.1.0 messages do not include blockAccessList - return Optional.empty(); - } - if (!rlpInput.nextIsNull()) { - return Optional.of(BlockAccessListDecoder.decode(rlpInput)); - } - rlpInput.skipNext(); - return Optional.empty(); - } - } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/RoundChangePayload.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/RoundChangePayload.java -index 9f4d9abed..32c061304 100644 +index 9f4d9abed..8804b6a46 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/RoundChangePayload.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/payload/RoundChangePayload.java -@@ -1,126 +1,211 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,11 +11,19 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. */ package org.hyperledger.besu.consensus.qbft.core.payload; @@ -31335,8 +30086,7 @@ index 9f4d9abed..32c061304 100644 import org.hyperledger.besu.ethereum.rlp.RLPInput; import org.hyperledger.besu.ethereum.rlp.RLPOutput; - import java.util.Objects; - import java.util.Optional; +@@ -24,23 +32,68 @@ import java.util.Optional; import com.google.common.base.MoreObjects; @@ -31408,16 +30158,7 @@ index 9f4d9abed..32c061304 100644 } @Override - public ConsensusRoundIdentifier getRoundIdentifier() { - return roundChangeIdentifier; - } - - /** - * Gets prepared round metadata. - * - * @return the prepared round metadata - */ - public Optional getPreparedRoundMetadata() { +@@ -57,6 +110,15 @@ public class RoundChangePayload extends QbftPayload { return preparedRoundMetadata; } @@ -31433,10 +30174,7 @@ index 9f4d9abed..32c061304 100644 @Override public void writeTo(final RLPOutput rlpOutput) { // RLP encode of the message data content (round identifier and prepared certificate) - rlpOutput.startList(); - writeConsensusRound(rlpOutput); - - rlpOutput.startList(); +@@ -67,6 +129,15 @@ public class RoundChangePayload extends QbftPayload { preparedRoundMetadata.ifPresent(prm -> prm.writeTo(rlpOutput)); rlpOutput.endList(); @@ -31452,22 +30190,7 @@ index 9f4d9abed..32c061304 100644 rlpOutput.endList(); } - /** - * Read from rlp input and return round change payload. - * - * @param rlpInput the rlp input - * @return the round change payload - */ - public static RoundChangePayload readFrom(final RLPInput rlpInput) { - rlpInput.enterList(); - final ConsensusRoundIdentifier roundIdentifier = readConsensusRound(rlpInput); - final Optional preparedRoundMetadata; - - rlpInput.enterList(); - if (rlpInput.isEndOfCurrentList()) { - preparedRoundMetadata = Optional.empty(); - } else { - preparedRoundMetadata = Optional.of(PreparedRoundMetadata.readFrom(rlpInput)); +@@ -89,8 +160,26 @@ public class RoundChangePayload extends QbftPayload { } rlpInput.leaveList(); @@ -31495,17 +30218,7 @@ index 9f4d9abed..32c061304 100644 } @Override - public int getMessageType() { - return TYPE; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; +@@ -108,12 +197,13 @@ public class RoundChangePayload extends QbftPayload { } RoundChangePayload that = (RoundChangePayload) o; return Objects.equals(roundChangeIdentifier, that.roundChangeIdentifier) @@ -31521,7 +30234,7 @@ index 9f4d9abed..32c061304 100644 } @Override - public String toString() { +@@ -121,6 +211,7 @@ public class RoundChangePayload extends QbftPayload { return MoreObjects.toStringHelper(this) .add("roundChangeIdentifier", roundChangeIdentifier) .add("preparedRoundMetadata", preparedRoundMetadata) @@ -31533,17 +30246,7 @@ diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qb index 49099c2c1..bc404409c 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManager.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftBlockHeightManager.java -@@ -1,39 +1,46 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,12 +11,19 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -31563,41 +30266,7 @@ index 49099c2c1..bc404409c 100644 import org.hyperledger.besu.consensus.common.bft.payload.Payload; import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; - import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter; - import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCreator; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader; - import org.hyperledger.besu.consensus.qbft.core.types.QbftFinalState; - import org.hyperledger.besu.consensus.qbft.core.types.QbftValidatorProvider; - import org.hyperledger.besu.consensus.qbft.core.validation.FutureRoundProposalMessageValidator; - import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidatorFactory; - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList; - import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException; - - import java.time.Clock; - import java.util.Collection; -@@ -183,42 +190,60 @@ public class QbftBlockHeightManager implements BaseQbftBlockHeightManager { - "Block timer expired for a round ({}) other than current ({})", - roundIdentifier, - qbftRound.getRoundIdentifier()); - } - } - - private void buildBlockAndMaybePropose( - final ConsensusRoundIdentifier roundIdentifier, final QbftRound qbftRound) { - - // mining will be checked against round 0 as the current round is initialised to 0 above - final boolean isProposer = - finalState.isLocalNodeProposerForRound(qbftRound.getRoundIdentifier()); - - if (!isProposer) { - // nothing to do here... - LOG.trace("This node is not a proposer so it will not send a proposal: " + roundIdentifier); - return; +@@ -200,8 +207,26 @@ public class QbftBlockHeightManager implements BaseQbftBlockHeightManager { } final long headerTimeStampSeconds = Math.round(clock.millis() / 1000D); @@ -31626,41 +30295,7 @@ index 49099c2c1..bc404409c 100644 final QbftBlock block = blockCreationResult.block(); final Optional blockAccessList = blockCreationResult.blockAccessList(); if (!block.isEmpty()) { - LOG.trace( - "Block is not empty and this node is a proposer so it will send a proposal: " - + roundIdentifier); - qbftRound.updateStateWithProposalAndTransmit( - block, blockAccessList, Collections.emptyList(), Collections.emptyList()); - } else { - // handle the block times period - final long currentTimeInMillis = finalState.getClock().millis(); - boolean emptyBlockExpired = - finalState - .getBlockTimer() - .checkEmptyBlockExpired(parentHeader::getTimestamp, currentTimeInMillis); - if (emptyBlockExpired) { - LOG.trace( - "Block has no transactions and this node is a proposer so it will send a proposal: " - + roundIdentifier); - qbftRound.updateStateWithProposalAndTransmit( -@@ -287,53 +312,97 @@ public class QbftBlockHeightManager implements BaseQbftBlockHeightManager { - && currentRound.get().getRoundIdentifier().getRoundNumber() >= newRoundNumber) { - return; - } - LOG.debug( - "Round has expired or changing based on RC quorum, creating PreparedCertificate and notifying peers. round={}", - currentRound.get().getRoundIdentifier()); - final Optional preparedCertificate = - currentRound.get().constructPreparedCertificate(); - - if (preparedCertificate.isPresent()) { - latestPreparedCertificate = preparedCertificate; - } - - startNewRound(newRoundNumber); - if (currentRound.isEmpty()) { - LOG.info("Failed to start round "); - return; +@@ -304,10 +329,16 @@ public class QbftBlockHeightManager implements BaseQbftBlockHeightManager { } QbftRound qbftRoundNew = currentRound.get(); @@ -31680,8 +30315,7 @@ index 49099c2c1..bc404409c 100644 // Its possible the locally created RoundChange triggers the transmission of a NewRound // message - so it must be handled accordingly. - handleRoundChangePayload(localRoundChange); - } catch (final SecurityModuleException e) { +@@ -316,7 +347,45 @@ public class QbftBlockHeightManager implements BaseQbftBlockHeightManager { LOG.warn("Failed to create signed RoundChange message.", e); } @@ -31728,45 +30362,24 @@ index 49099c2c1..bc404409c 100644 } @Override - public void handleProposalPayload(final Proposal proposal) { - LOG.trace("Received a Proposal Payload."); - final MessageAge messageAge = - determineAgeOfPayload(proposal.getRoundIdentifier().getRoundNumber()); - - if (messageAge == MessageAge.PRIOR_ROUND) { - LOG.trace("Received Proposal Payload for a prior round={}", proposal.getRoundIdentifier()); - } else { - if (messageAge == MessageAge.FUTURE_ROUND) { - if (!futureRoundProposalMessageValidator.validateProposalMessage(proposal)) { - LOG.info("Received future Proposal which is illegal, no round change triggered."); - return; - } - startNewRound(proposal.getRoundIdentifier().getRoundNumber()); - } - currentRound.ifPresent(r -> r.handleProposalMessage(proposal)); - } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java -index c049ccfe9..e586889ab 100644 +index c049ccfe9..50100fd7a 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftController.java -@@ -2,63 +2,66 @@ - * Copyright contributors to Besu. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. */ package org.hyperledger.besu.consensus.qbft.core.statemachine; - import static org.hyperledger.besu.consensus.qbft.core.validation.ValidatorUtil.isMsgForCurrentHeight; - import static org.hyperledger.besu.consensus.qbft.core.validation.ValidatorUtil.isMsgForFutureChainHeight; +@@ -19,6 +25,8 @@ import static org.hyperledger.besu.consensus.qbft.core.validation.ValidatorUtil. import static org.hyperledger.besu.consensus.qbft.core.validation.ValidatorUtil.isMsgFromKnownValidator; import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; @@ -31775,23 +30388,7 @@ index c049ccfe9..e586889ab 100644 import org.hyperledger.besu.consensus.common.bft.MessageTracker; import org.hyperledger.besu.consensus.common.bft.events.BlockTimerExpiry; import org.hyperledger.besu.consensus.common.bft.events.RoundExpiry; - import org.hyperledger.besu.consensus.common.bft.messagewrappers.BftMessage; - import org.hyperledger.besu.consensus.common.bft.statemachine.FutureMessageBuffer; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.QbftMessageDecoder; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.RoundChange; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockchain; - import org.hyperledger.besu.consensus.qbft.core.types.QbftEventHandler; - import org.hyperledger.besu.consensus.qbft.core.types.QbftFinalState; - import org.hyperledger.besu.consensus.qbft.core.types.QbftGossiper; - import org.hyperledger.besu.consensus.qbft.core.types.QbftMessage; - import org.hyperledger.besu.consensus.qbft.core.types.QbftNewChainHead; - import org.hyperledger.besu.consensus.qbft.core.types.QbftReceivedMessageEvent; - import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator; +@@ -42,6 +50,7 @@ import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator; import org.hyperledger.besu.consensus.qbft.core.validation.RoundChangeMessageValidator; import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; @@ -31799,41 +30396,7 @@ index c049ccfe9..e586889ab 100644 import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; - - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - - /** The Qbft controller. */ - public class QbftController implements QbftEventHandler { - - private static final Logger LOG = LoggerFactory.getLogger(QbftController.class); - private final QbftBlockchain blockchain; - private final QbftFinalState finalState; - private final FutureMessageBuffer futureMessageBuffer; - private final QbftGossiper gossiper; - private final MessageTracker duplicateMessageTracker; - private final AtomicBoolean started = new AtomicBoolean(false); - private final QbftBlockCodec blockEncoder; - private final QbftMessageDecoder messageDecoder = new QbftMessageDecoder(); - private BaseQbftBlockHeightManager currentHeightManager; -@@ -194,53 +197,107 @@ public class QbftController implements QbftEventHandler { - /** - * Consume message. - * - * @param

the type parameter of BftMessage - * @param message the message - * @param bftMessage the bft message - * @param handleMessage the handle message - * @param isReplayed the message is being replayed - */ - protected

> void consumeMessage( - final QbftMessage message, - final P bftMessage, - final Consumer

handleMessage, - final boolean isReplayed) { - LOG.trace("Received BFT {} message", bftMessage.getClass().getSimpleName()); - - // Discard all messages which target the BLOCKCHAIN height (which SHOULD be 1 less than +@@ -211,6 +220,8 @@ public class QbftController implements QbftEventHandler { // the currentHeightManager, but CAN be the same directly following import). if (bftMessage.getRoundIdentifier().getSequenceNumber() <= blockchain.getChainHeadBlockNumber()) { @@ -31842,13 +30405,7 @@ index c049ccfe9..e586889ab 100644 LOG.debug( "Discarding a message which targets a height {} not above current chain height {}.", bftMessage.getRoundIdentifier().getSequenceNumber(), - blockchain.getChainHeadBlockNumber()); - return; - } - - if (processMessage(bftMessage, message)) { - gossiper.send(message, isReplayed); - handleMessage.accept(bftMessage); +@@ -224,6 +235,58 @@ public class QbftController implements QbftEventHandler { } } @@ -31907,38 +30464,11 @@ index c049ccfe9..e586889ab 100644 @Override public void handleNewBlockEvent(final QbftNewChainHead newChainHead) { final QbftBlockHeader newBlockHeader = newChainHead.newChainHeadHeader(); - final QbftBlockHeader currentMiningParent = getCurrentHeightManager().getParentBlockHeader(); - LOG.debug( - "New chain head detected (block number={})," + " currently mining on top of {}.", - newBlockHeader.getNumber(), - currentMiningParent.getNumber()); - if (newBlockHeader.getNumber() < currentMiningParent.getNumber()) { - LOG.trace( - "Discarding NewChainHead event, was for previous block height. chainHeight={} eventHeight={}", - currentMiningParent.getNumber(), - newBlockHeader.getNumber()); - return; - } - - if (newBlockHeader.getNumber() == currentMiningParent.getNumber()) { - if (newBlockHeader.getHash().equals(currentMiningParent.getHash())) { - LOG.trace( - "Discarding duplicate NewChainHead event. chainHeight={} newBlockHash={} parentBlockHash={}", diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java index 832149e2f..3d0138d9c 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/QbftRound.java -@@ -1,97 +1,126 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,13 +11,25 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -31964,24 +30494,7 @@ index 832149e2f..3d0138d9c 100644 import org.hyperledger.besu.consensus.common.bft.payload.SignedData; import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; - import org.hyperledger.besu.consensus.qbft.core.network.QbftMessageTransmitter; - import org.hyperledger.besu.consensus.qbft.core.payload.MessageFactory; - import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; - import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCreator; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCreator.BlockCreationResult; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockImporter; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface; - import org.hyperledger.besu.consensus.qbft.core.types.QbftMinedBlockObserver; - import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule; - import org.hyperledger.besu.crypto.SECPSignature; - import org.hyperledger.besu.cryptoservices.NodeKey; - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.datatypes.Hash; - import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList; +@@ -42,6 +54,7 @@ import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList; import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException; import org.hyperledger.besu.util.Subscribers; @@ -31989,33 +30502,7 @@ index 832149e2f..3d0138d9c 100644 import java.util.List; import java.util.Optional; - import org.apache.tuweni.bytes.Bytes32; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - - /** The Qbft round. */ - public class QbftRound { - - private static final Logger LOG = LoggerFactory.getLogger(QbftRound.class); - - private final Subscribers observers; - - /** The Round state. */ - protected final RoundState roundState; - - /** The Block creator. */ - protected final QbftBlockCreator blockCreator; - - /** The Protocol context. */ - protected final QbftBlockInterface blockInterface; - - /** The Protocol schedule. */ - protected final QbftProtocolSchedule protocolSchedule; - - private final NodeKey nodeKey; - private final Address localAddress; - private final MessageFactory messageFactory; // used only to create stored local msgs - private final QbftMessageTransmitter transmitter; +@@ -75,6 +88,22 @@ public class QbftRound { private final QbftBlockHeader parentHeader; @@ -32038,41 +30525,7 @@ index 832149e2f..3d0138d9c 100644 /** * Instantiates a new Qbft round. * - * @param roundState the round state - * @param blockCreator the block creator - * @param blockInterface the block interface - * @param protocolSchedule the protocol schedule - * @param observers the observers - * @param nodeKey the node key - * @param localAddress the local address - * @param messageFactory the message factory - * @param transmitter the transmitter - * @param roundTimer the round timer - * @param parentHeader the parent header - */ - public QbftRound( - final RoundState roundState, - final QbftBlockCreator blockCreator, - final QbftBlockInterface blockInterface, - final QbftProtocolSchedule protocolSchedule, -@@ -142,257 +171,576 @@ public class QbftRound { - public BlockCreationResult createBlock(final long headerTimeStampSeconds) { - LOG.debug("Creating proposed block. round={}", roundState.getRoundIdentifier()); - return blockCreator.createBlock(headerTimeStampSeconds, this.parentHeader); - } - - /** - * Start round with. - * - * @param roundChangeArtifacts the round change artifacts - * @param headerTimestamp the header timestamp - */ - public void startRoundWith( - final RoundChangeArtifacts roundChangeArtifacts, final long headerTimestamp) { - final Optional bestPreparedCertificate = - roundChangeArtifacts.getBestPreparedPeer(); - - final QbftBlock blockToPublish; +@@ -159,8 +188,26 @@ public class QbftRound { final Optional blockAccessList; if (bestPreparedCertificate.isEmpty()) { LOG.debug("Sending proposal with new block. round={}", roundState.getRoundIdentifier()); @@ -32101,36 +30554,7 @@ index 832149e2f..3d0138d9c 100644 blockToPublish = blockCreationResult.block(); blockAccessList = blockCreationResult.blockAccessList(); } else { - LOG.debug( - "Sending proposal from PreparedCertificate. round={}", roundState.getRoundIdentifier()); - QbftBlock preparedBlock = bestPreparedCertificate.get().getBlock(); - blockToPublish = - blockInterface.replaceRoundAndProposerForProposalBlock( - preparedBlock, roundState.getRoundIdentifier().getRoundNumber(), localAddress); - blockAccessList = bestPreparedCertificate.get().getBlockAccessList(); - } - - LOG.debug(" proposal - new/prepared block hash : {}", blockToPublish.getHash()); - - updateStateWithProposalAndTransmit( - blockToPublish, - blockAccessList, - roundChangeArtifacts.getRoundChanges(), - bestPreparedCertificate.map(PreparedCertificate::getPrepares).orElse(emptyList())); - } - - /** - * Update state with proposal and transmit. - * - * @param block the block - * @param blockAccessList optional block access list - * @param roundChanges the round changes - * @param prepares the prepares - */ - protected void updateStateWithProposalAndTransmit( - final QbftBlock block, - final Optional blockAccessList, - final List> roundChanges, +@@ -197,20 +244,48 @@ public class QbftRound { final List> prepares) { final Proposal proposal; try { @@ -32187,24 +30611,7 @@ index 832149e2f..3d0138d9c 100644 if (updateStateWithProposedBlock(proposal)) { sendPrepare(block); } - } - - /** - * Handle proposal message. - * - * @param msg the msg - */ - public void handleProposalMessage(final Proposal msg) { - LOG.debug( - "Received a proposal message. round={}. author={}", - roundState.getRoundIdentifier(), - msg.getAuthor()); - final QbftBlock block = msg.getSignedPayload().getPayload().getProposedBlock(); - if (updateStateWithProposedBlock(msg)) { - sendPrepare(block); - } - } - +@@ -235,16 +310,70 @@ public class QbftRound { private void sendPrepare(final QbftBlock block) { LOG.debug("Sending prepare message. round={}", roundState.getRoundIdentifier()); try { @@ -32278,37 +30685,7 @@ index 832149e2f..3d0138d9c 100644 /** * Handle prepare message. * - * @param msg the msg - */ - public void handlePrepareMessage(final Prepare msg) { - LOG.debug( - "Received a prepare message. round={}. author={}", - roundState.getRoundIdentifier(), - msg.getAuthor()); - peerIsPrepared(msg); - } - - /** - * Handle commit message. - * - * @param msg the msg - */ - public void handleCommitMessage(final Commit msg) { - LOG.debug( - "Received a commit message. round={}. author={}", - roundState.getRoundIdentifier(), - msg.getAuthor()); - peerIsCommitted(msg); - } - - /** - * Construct prepared certificate. - * - * @return the optional PreparedCertificate - */ - public Optional constructPreparedCertificate() { - return roundState.constructPreparedCertificate(); - } +@@ -282,23 +411,39 @@ public class QbftRound { private boolean updateStateWithProposedBlock(final Proposal msg) { final boolean wasPrepared = roundState.isPrepared(); @@ -32351,7 +30728,7 @@ index 832149e2f..3d0138d9c 100644 } // can automatically add _our_ commit message to the roundState - // cannot create a prepare message here, as it may be _our_ proposal, and thus we cannot also +@@ -306,18 +451,27 @@ public class QbftRound { // prepare try { final Commit localCommitMessage = @@ -32384,12 +30761,7 @@ index 832149e2f..3d0138d9c 100644 } return blockAccepted; - } - - private void peerIsPrepared(final Prepare msg) { - final boolean wasPrepared = roundState.isPrepared(); - roundState.addPrepareMessage(msg); - if (wasPrepared != roundState.isPrepared()) { +@@ -330,7 +484,20 @@ public class QbftRound { LOG.debug("Sending commit message. round={}", roundState.getRoundIdentifier()); final QbftBlock block = roundState.getProposedBlock().get(); try { @@ -32411,9 +30783,7 @@ index 832149e2f..3d0138d9c 100644 // Note: the local-node's commit message was added to RoundState on block acceptance // and thus does not need to be done again here. } catch (final SecurityModuleException e) { - LOG.warn("Failed to construct a commit seal: {}", e.getMessage()); - } - } +@@ -340,20 +507,50 @@ public class QbftRound { } private void peerIsCommitted(final Commit msg) { @@ -32470,19 +30840,7 @@ index 832149e2f..3d0138d9c 100644 final long blockNumber = blockToImport.getHeader().getNumber(); if (getRoundIdentifier().getRoundNumber() > 0) { - LOG.info( - "Importing proposed block to chain. round={}, hash={}", - getRoundIdentifier(), - blockToImport.getHash()); - } else { - LOG.debug( - "Importing proposed block to chain. round={}, hash={}", - getRoundIdentifier(), - blockToImport.getHash()); - } - - final QbftBlockImporter blockImporter = - protocolSchedule.getBlockImporter(blockToImport.getHeader()); +@@ -373,19 +570,170 @@ public class QbftRound { final boolean result = blockImporter.importBlock(blockToImport, roundState.getProposedBlockAccessList()); if (!result) { @@ -32656,28 +31014,11 @@ index 832149e2f..3d0138d9c 100644 } private QbftBlock createCommitBlock(final QbftBlock block) { - return blockInterface.replaceRoundForCommitBlock(block, getRoundIdentifier().getRoundNumber()); - } - - private void notifyNewBlockListeners(final QbftBlock block) { - observers.forEach(obs -> obs.blockMined(block)); - } - } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundState.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundState.java index 1c3078602..2c798c9e2 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundState.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/statemachine/RoundState.java -@@ -1,49 +1,57 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,10 +11,17 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -32695,12 +31036,7 @@ index 1c3078602..2c798c9e2 100644 import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock; - import org.hyperledger.besu.consensus.qbft.core.validation.MessageValidator; - import org.hyperledger.besu.crypto.SECPSignature; - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList; - +@@ -27,6 +34,7 @@ import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; @@ -32708,41 +31044,7 @@ index 1c3078602..2c798c9e2 100644 import java.util.Optional; import java.util.stream.Collectors; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - - /** - * The Round state holds all the messages for a given round and tracks whether quorum has been - * reached for the round to be prepared or committed. - */ - public class RoundState { - private static final Logger LOG = LoggerFactory.getLogger(RoundState.class); - - private final ConsensusRoundIdentifier roundIdentifier; - private final MessageValidator validator; - private final long quorum; - - private Optional proposalMessage = Optional.empty(); - - // Must track the actual Prepare message, not just the sender, as these may need to be reused -@@ -179,39 +187,68 @@ public class RoundState { - /** - * Is committed. - * - * @return the boolean - */ - public boolean isCommitted() { - return committed; - } - - /** - * Gets commit seals. - * - * @return the commit seals - */ - public Collection getCommitSeals() { - return commitMessages.values().stream() - .map(cp -> cp.getSignedPayload().getPayload().getCommitSeal()) +@@ -196,6 +204,35 @@ public class RoundState { .collect(Collectors.toList()); } @@ -32778,37 +31080,11 @@ index 1c3078602..2c798c9e2 100644 /** * Construct prepared certificate. * - * @return the optional prepared certificate - */ - public Optional constructPreparedCertificate() { - if (isPrepared()) { - return Optional.of( - new PreparedCertificate( - proposalMessage.get().getSignedPayload().getPayload().getProposedBlock(), - prepareMessages.values().stream() - .map(Prepare::getSignedPayload) - .collect(Collectors.toList()), - roundIdentifier.getRoundNumber(), - proposalMessage.get().getBlockAccessList())); - } - return Optional.empty(); - } - } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/types/QbftBlockCreator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/types/QbftBlockCreator.java index afe4fb00e..c397cab98 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/types/QbftBlockCreator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/types/QbftBlockCreator.java -@@ -1,53 +1,90 @@ - /* - * Copyright contributors to Besu. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,13 +11,21 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -32830,32 +31106,7 @@ index afe4fb00e..c397cab98 100644 import java.util.Optional; /** Responsible for creating a block. */ - public interface QbftBlockCreator { - - /** - * Block creation result. - * - * @param block the block - * @param blockAccessList optional block access list - */ - public record BlockCreationResult(QbftBlock block, Optional blockAccessList) {} - - /** - * Create a block. - * - * @param headerTimeStampSeconds the header timestamp - * @param parentHeader the parent header - * @return the block - */ - BlockCreationResult createBlock(long headerTimeStampSeconds, QbftBlockHeader parentHeader); - - /** - * Create sealed block. - * - * @param block the block - * @param roundNumber the round number - * @param commitSeals the commit seals - * @return the block +@@ -50,4 +58,33 @@ public interface QbftBlockCreator { */ QbftBlock createSealedBlock( final QbftBlock block, final int roundNumber, final Collection commitSeals); @@ -32893,17 +31144,7 @@ diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qb index e211c6a8e..918607ad2 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/CommitValidator.java -@@ -1,78 +1,184 @@ - /* - * Copyright 2020 ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,14 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -32918,12 +31159,7 @@ index e211c6a8e..918607ad2 100644 */ package org.hyperledger.besu.consensus.qbft.core.validation; - import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; - import org.hyperledger.besu.consensus.common.bft.payload.SignedData; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Commit; - import org.hyperledger.besu.consensus.qbft.core.payload.CommitPayload; - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.datatypes.Hash; +@@ -23,6 +31,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.Util; import java.util.Collection; @@ -32931,15 +31167,7 @@ index e211c6a8e..918607ad2 100644 import org.slf4j.Logger; import org.slf4j.LoggerFactory; - - /** The Commit validator. */ - public class CommitValidator { - - private static final String ERROR_PREFIX = "Invalid Commit Message"; - - private static final Logger LOG = LoggerFactory.getLogger(CommitValidator.class); - - private final Collection

validators; +@@ -38,9 +47,23 @@ public class CommitValidator { private final ConsensusRoundIdentifier targetRound; private final Hash expectedDigest; private final Hash expectedCommitDigest; @@ -32964,11 +31192,7 @@ index e211c6a8e..918607ad2 100644 * * @param validators the validators * @param targetRound the target round - * @param expectedDigest the expected digest - * @param expectedCommitDigest the expected commit digest - */ - public CommitValidator( - final Collection
validators, +@@ -52,10 +75,93 @@ public class CommitValidator { final ConsensusRoundIdentifier targetRound, final Hash expectedDigest, final Hash expectedCommitDigest) { @@ -33062,41 +31286,7 @@ index e211c6a8e..918607ad2 100644 } /** - * Validate. - * - * @param msg the msg - * @return the boolean - */ - public boolean validate(final Commit msg) { - return validate(msg.getSignedPayload()); - } - - /** - * Validate. - * - * @param signedPayload the signed payload - * @return the boolean - */ - public boolean validate(final SignedData signedPayload) { - if (!validators.contains(signedPayload.getAuthor())) { -@@ -95,23 +201,39 @@ public class CommitValidator { - LOG.info( - "{}: did not contain expected digest {} was {}", - ERROR_PREFIX, - expectedDigest, - payload.getDigest()); - return false; - } - - final Address commitSealCreator = - Util.signatureToAddress(payload.getCommitSeal(), expectedCommitDigest); - - if (!commitSealCreator.equals(signedPayload.getAuthor())) { - LOG.info( - "{}: Seal was not created by the message transmitter {} was {}", - ERROR_PREFIX, - commitSealCreator, - signedPayload.getAuthor()); +@@ -112,6 +218,22 @@ public class CommitValidator { return false; } @@ -33120,23 +31310,19 @@ index e211c6a8e..918607ad2 100644 } } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java -index d15d19e91..7623e630e 100644 +index d15d19e91..0f26c79a8 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/MessageValidator.java -@@ -1,98 +1,120 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,16 +11,24 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. */ package org.hyperledger.besu.consensus.qbft.core.validation; @@ -33152,34 +31338,7 @@ index d15d19e91..7623e630e 100644 import java.util.Collection; import java.util.Optional; - - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - - /** The Message validator. */ - public class MessageValidator { - - private static final Logger LOG = LoggerFactory.getLogger(MessageValidator.class); - - /** The Subsequent message validator. */ - public static class SubsequentMessageValidator { - - private final PrepareValidator prepareValidator; - private final CommitValidator commitValidator; - - /** - * Instantiates a new Subsequent message validator. - * - * @param validators the validators - * @param targetRound the target round - * @param proposalBlock the proposal block - * @param blockInterface the block interface - */ - public SubsequentMessageValidator( - final Collection
validators, - final ConsensusRoundIdentifier targetRound, - final QbftBlock proposalBlock, - final QbftBlockInterface blockInterface) { +@@ -55,9 +63,23 @@ public class MessageValidator { final QbftBlock commitBlock = blockInterface.replaceRoundForCommitBlock(proposalBlock, targetRound.getRoundNumber()); prepareValidator = new PrepareValidator(validators, targetRound, proposalBlock.getHash()); @@ -33204,18 +31363,7 @@ index d15d19e91..7623e630e 100644 } /** - * Validate. - * - * @param msg the Prepare payload msg - * @return the boolean - */ - public boolean validate(final Prepare msg) { - return prepareValidator.validate(msg); - } - - /** - * Validate. - * +@@ -76,6 +98,12 @@ public class MessageValidator { * @param msg the Commit payload msg * @return the boolean */ @@ -33228,23 +31376,6 @@ index d15d19e91..7623e630e 100644 public boolean validate(final Commit msg) { return commitValidator.validate(msg); } - } - - /** The interface Subsequent message validator factory. */ - @FunctionalInterface - public interface SubsequentMessageValidatorFactory { - /** - * Create subsequent message validator. - * - * @param proposalBlock the proposal block - * @return the subsequent message validator - */ - SubsequentMessageValidator create(QbftBlock proposalBlock); - } - - private final SubsequentMessageValidatorFactory subsequentMessageValidatorFactory; - private final ProposalValidator proposalValidator; - diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitEnforcement.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PqCommitEnforcement.java new file mode 100755 index 000000000..d1aa1be8e @@ -34256,27 +32387,23 @@ index 000000000..1b952f619 + } +} diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidator.java -index 61bde6a80..460ffe8ec 100644 +index 61bde6a80..bfe651ad6 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/PrepareValidator.java -@@ -5,88 +5,134 @@ - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. */ package org.hyperledger.besu.consensus.qbft.core.validation; - import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; - import org.hyperledger.besu.consensus.common.bft.payload.SignedData; - import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare; - import org.hyperledger.besu.consensus.qbft.core.payload.PreparePayload; - import org.hyperledger.besu.datatypes.Address; +@@ -22,11 +28,20 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import java.util.Collection; @@ -34298,9 +32425,7 @@ index 61bde6a80..460ffe8ec 100644 public class PrepareValidator { private static final String ERROR_PREFIX = "Invalid Prepare Message"; - - private static final Logger LOG = LoggerFactory.getLogger(PrepareValidator.class); - +@@ -36,9 +51,13 @@ public class PrepareValidator { private final Collection
validators; private final ConsensusRoundIdentifier targetRound; private final Hash expectedDigest; @@ -34315,9 +32440,7 @@ index 61bde6a80..460ffe8ec 100644 * * @param validators the validators * @param targetRound the target round - * @param expectedDigest the expected digest - */ - public PrepareValidator( +@@ -48,9 +67,26 @@ public class PrepareValidator { final Collection
validators, final ConsensusRoundIdentifier targetRound, final Hash expectedDigest) { @@ -34344,36 +32467,7 @@ index 61bde6a80..460ffe8ec 100644 } /** - * Validate. - * - * @param msg the msg - * @return the boolean - */ - public boolean validate(final Prepare msg) { - return validate(msg.getSignedPayload()); - } - - /** - * Validate. - * - * @param signedPayload the signed payload - * @return the boolean - */ - public boolean validate(final SignedData signedPayload) { - if (!validators.contains(signedPayload.getAuthor())) { - LOG.info("{}: did not originate from a recognized validator.", ERROR_PREFIX); - return false; - } - - final PreparePayload payload = signedPayload.getPayload(); - - if (!payload.getRoundIdentifier().equals(targetRound)) { - LOG.info("{}: did not target expected round/height", ERROR_PREFIX); - return false; - } - - if (!payload.getDigest().equals(expectedDigest)) { - LOG.info("{}: did not contain expected digest", ERROR_PREFIX); +@@ -87,6 +123,22 @@ public class PrepareValidator { return false; } @@ -34397,27 +32491,23 @@ index 61bde6a80..460ffe8ec 100644 } } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidator.java -index 58b768531..57e15d070 100644 +index 58b768531..7d8c72076 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/ProposalPayloadValidator.java -@@ -13,65 +13,99 @@ +@@ -11,6 +11,12 @@ + * specific language governing permissions and limitations under the License. + * * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. */ package org.hyperledger.besu.consensus.qbft.core.validation; - import static com.google.common.base.Preconditions.checkState; - - import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier; - import org.hyperledger.besu.consensus.common.bft.payload.SignedData; - import org.hyperledger.besu.consensus.qbft.core.payload.ProposalPayload; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock; - import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockValidator; - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList; - - import java.util.Optional; - - import com.google.common.annotations.VisibleForTesting; +@@ -30,7 +36,20 @@ import com.google.common.annotations.VisibleForTesting; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34439,8 +32529,7 @@ index 58b768531..57e15d070 100644 public class ProposalPayloadValidator { private static final String ERROR_PREFIX = "Invalid Proposal Payload"; - - private static final Logger LOG = LoggerFactory.getLogger(ProposalPayloadValidator.class); +@@ -39,9 +58,11 @@ public class ProposalPayloadValidator { private final Address expectedProposer; private final ConsensusRoundIdentifier targetRound; private final QbftBlockValidator blockValidator; @@ -34453,10 +32542,7 @@ index 58b768531..57e15d070 100644 * * @param expectedProposer the expected proposer * @param targetRound the target round - * @param blockValidator the block validator - */ - @VisibleForTesting - public ProposalPayloadValidator( +@@ -52,9 +73,28 @@ public class ProposalPayloadValidator { final Address expectedProposer, final ConsensusRoundIdentifier targetRound, final QbftBlockValidator blockValidator) { @@ -34485,41 +32571,7 @@ index 58b768531..57e15d070 100644 } /** - * Validate. - * - * @param signedPayload the signed Proposal payload - * @return the boolean - */ - public boolean validate(final SignedData signedPayload) { - return validate(signedPayload, true); - } - - /** - * Validate without block validation. - * - * @param signedPayload the signed Proposal payload - * @return the boolean - */ - public boolean validateWithoutBlockValidation(final SignedData signedPayload) { - return validate(signedPayload, false); -@@ -92,40 +126,57 @@ public class ProposalPayloadValidator { - return false; - } - - final ProposalPayload payload = signedPayload.getPayload(); - - if (!payload.getRoundIdentifier().equals(targetRound)) { - LOG.info("{}: proposal is not for expected round", ERROR_PREFIX); - return false; - } - - final QbftBlock block = payload.getProposedBlock(); - if (validateBlock && !validateBlock(block, payload.getBlockAccessList())) { - return false; - } - - if (block.getHeader().getNumber() != payload.getRoundIdentifier().getSequenceNumber()) { - LOG.info("{}: block number does not match sequence number", ERROR_PREFIX); +@@ -109,6 +149,23 @@ public class ProposalPayloadValidator { return false; } @@ -34543,45 +32595,24 @@ index 58b768531..57e15d070 100644 return true; } - private boolean validateBlock( - final QbftBlock block, final Optional blockAccessList) { - checkState(blockValidator != null, "block validation not possible, no block validator."); - - final var validationResult = blockValidator.validateBlock(block, blockAccessList); - - if (!validationResult.success()) { - LOG.info( - "{}: block did not pass validation. Reason {}", - ERROR_PREFIX, - validationResult.errorMessage()); - return false; - } - - return true; - } - } diff --git a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidator.java b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidator.java -index 549acdd9c..718651abe 100644 +index 549acdd9c..8fd9bed3e 100644 --- a/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidator.java +++ b/consensus/qbft-core/src/main/java/org/hyperledger/besu/consensus/qbft/core/validation/RoundChangePayloadValidator.java -@@ -3,89 +3,141 @@ - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0003-aere-pq-anchor.patch. */ package org.hyperledger.besu.consensus.qbft.core.validation; - import org.hyperledger.besu.consensus.common.bft.payload.SignedData; - import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata; - import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; +@@ -20,7 +26,9 @@ import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload; import org.hyperledger.besu.datatypes.Address; import java.util.Collection; @@ -34591,7 +32622,7 @@ index 549acdd9c..718651abe 100644 import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** +@@ -28,6 +36,19 @@ import org.slf4j.LoggerFactory; * Note: This does not validate that the received payload is for a future round, only that it was * signed by a known validator, and is for the current chain height. Future-round check must be * performed elsewhere (eg. the BlockHeightManager) @@ -34611,8 +32642,7 @@ index 549acdd9c..718651abe 100644 */ public class RoundChangePayloadValidator { - private static final String ERROR_PREFIX = "Invalid RoundChange Payload"; - private static final Logger LOG = LoggerFactory.getLogger(RoundChangePayloadValidator.class); +@@ -36,16 +57,35 @@ public class RoundChangePayloadValidator { private final Collection
validators; private final long chainHeight; @@ -34649,40 +32679,7 @@ index 549acdd9c..718651abe 100644 } /** - * Validate. - * - * @param signedPayload the signed payload - * @return the boolean - */ - public boolean validate(final SignedData signedPayload) { - - if (!validators.contains(signedPayload.getAuthor())) { - LOG.info("{}: did not originate from a recognized validator.", ERROR_PREFIX); - return false; - } - - final RoundChangePayload payload = signedPayload.getPayload(); - - if (payload.getRoundIdentifier().getSequenceNumber() != chainHeight) { - LOG.info("{}: did not target expected height", ERROR_PREFIX); - return false; - } - - final int targetRound = payload.getRoundIdentifier().getRoundNumber(); - if (targetRound <= 0) { - LOG.info("{}: must contain a positive target round number", ERROR_PREFIX); - return false; - } - - if (payload.getPreparedRoundMetadata().isPresent()) { - final PreparedRoundMetadata metadata = payload.getPreparedRoundMetadata().get(); - if (metadata.getPreparedRound() >= targetRound) { - LOG.info("{}: prepared metadata is from a round ahead of target round", ERROR_PREFIX); - return false; - } - - if (metadata.getPreparedRound() < 0) { - LOG.info("{}: prepared metadata is from a negative round number", ERROR_PREFIX); +@@ -86,6 +126,24 @@ public class RoundChangePayloadValidator { return false; } } @@ -39936,17 +37933,7 @@ diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/Qb index f54d7bfcd..cfc67a900 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactory.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftBlockHeaderValidationRulesetFactory.java -@@ -1,86 +1,204 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -39959,7 +37946,7 @@ index f54d7bfcd..cfc67a900 100644 */ package org.hyperledger.besu.consensus.qbft; - import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification.DEFAULT_MAX_GAS_LIMIT; +@@ -18,8 +24,17 @@ import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecificatio import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification.DEFAULT_MIN_GAS_LIMIT; import org.hyperledger.besu.consensus.common.bft.BftHelpers; @@ -39977,34 +37964,7 @@ index f54d7bfcd..cfc67a900 100644 import org.hyperledger.besu.consensus.qbft.headervalidationrules.QbftValidatorsValidationRule; import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; - import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket; - import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.AncestryValidationRule; - import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.ConstantFieldValidationRule; - import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.GasLimitRangeAndDeltaValidationRule; - import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.GasUsageValidationRule; - import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampBoundedByFutureParameter; - import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampMoreRecentThanParent; - - import java.time.Duration; - import java.util.Optional; - - import org.apache.tuweni.units.bigints.UInt256; - - /** The Qbft block header validation ruleset factory. */ - public class QbftBlockHeaderValidationRulesetFactory { - /** Default constructor */ - private QbftBlockHeaderValidationRulesetFactory() {} - - /** - * Produces a BlockHeaderValidator configured for assessing bft block headers which are to form - * part of the BlockChain (i.e. not proposed blocks, which do not contain commit seals) - * - * @param minimumTimeBetweenBlocks the minimum amount of time that must elapse between blocks. - * @param useValidatorContract whether validator selection is using a validator contract - * @param baseFeeMarket an {@link Optional} wrapping {@link BaseFeeMarket} class if appropriate. - * @return BlockHeaderValidator configured for assessing bft block headers - */ - public static BlockHeaderValidator.Builder blockHeaderValidator( +@@ -54,14 +69,90 @@ public class QbftBlockHeaderValidationRulesetFactory { final Duration minimumTimeBetweenBlocks, final boolean useValidatorContract, final Optional baseFeeMarket) { @@ -40095,8 +38055,7 @@ index f54d7bfcd..cfc67a900 100644 .addRule( new ConstantFieldValidationRule<>( "MixHash", BlockHeader::getMixHash, BftHelpers.EXPECTED_MIX_HASH)) - .addRule( - new ConstantFieldValidationRule<>( +@@ -70,7 +161,34 @@ public class QbftBlockHeaderValidationRulesetFactory { "Difficulty", BlockHeader::getDifficulty, UInt256.ONE)) .addRule(new QbftValidatorsValidationRule(useValidatorContract)) .addRule(new BftCoinbaseValidationRule()) @@ -40132,31 +38091,11 @@ index f54d7bfcd..cfc67a900 100644 // Currently the minimum acceptable time between blocks is 1 second. The timestamp of an // Ethereum header is stored as seconds since Unix epoch so blocks being produced more - // frequently than once a second cannot pass this validator. For non-production scenarios - // (e.g. for testing block production much more frequently than once a second) Besu has - // an experimental 'xblockperiodmilliseconds' option for BFT chains. If this is enabled - // we cannot apply the TimestampMoreRecentThanParent validation rule so we do not add it - if (minimumTimeBetweenBlocks.compareTo(Duration.ofSeconds(1)) >= 0) { - ruleBuilder.addRule(new TimestampMoreRecentThanParent(minimumTimeBetweenBlocks.toSeconds())); - } - return ruleBuilder; - } - } diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java index 39c7aa300..b3096d331 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/QbftExtraDataCodec.java -@@ -1,63 +1,81 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -40169,8 +38108,7 @@ index 39c7aa300..b3096d331 100644 */ package org.hyperledger.besu.consensus.qbft; - import static org.hyperledger.besu.consensus.common.bft.Vote.ADD_BYTE_VALUE; - import static org.hyperledger.besu.consensus.common.bft.Vote.DROP_BYTE_VALUE; +@@ -19,6 +25,9 @@ import static org.hyperledger.besu.consensus.common.bft.Vote.DROP_BYTE_VALUE; import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; @@ -40180,22 +38118,7 @@ index 39c7aa300..b3096d331 100644 import org.hyperledger.besu.consensus.common.bft.Vote; import org.hyperledger.besu.consensus.common.validator.VoteType; import org.hyperledger.besu.crypto.SECPSignature; - import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; - import org.hyperledger.besu.datatypes.Address; - import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; - import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; - import org.hyperledger.besu.ethereum.rlp.RLPException; - import org.hyperledger.besu.ethereum.rlp.RLPInput; - import org.hyperledger.besu.ethereum.rlp.RLPOutput; - - import java.util.Collection; - import java.util.Collections; - import java.util.List; - import java.util.Optional; - - import com.google.common.collect.ImmutableBiMap; - import org.apache.tuweni.bytes.Bytes; - +@@ -41,6 +50,15 @@ import org.apache.tuweni.bytes.Bytes; /** * Represents the data structure stored in the extraData field of the BlockHeader used when * operating under an BFT consensus mechanism. @@ -40211,41 +38134,7 @@ index 39c7aa300..b3096d331 100644 */ public class QbftExtraDataCodec extends BftExtraDataCodec { private static final ImmutableBiMap voteToValue = - ImmutableBiMap.of( - VoteType.ADD, ADD_BYTE_VALUE, - VoteType.DROP, DROP_BYTE_VALUE); - - /** Default constructor */ - public QbftExtraDataCodec() {} - - /** - * Encode from addresses. - * - * @param addresses the addresses - * @return the bytes - */ - public static Bytes encodeFromAddresses(final Collection
addresses) { - return new QbftExtraDataCodec() - .encode( - new BftExtraData( -@@ -85,64 +103,164 @@ public class QbftExtraDataCodec extends BftExtraDataCodec { - } - - final RLPInput rlpInput = new BytesValueRLPInput(input, false); - - rlpInput.enterList(); // This accounts for the "root node" which contains BFT data items. - final Bytes vanityData = rlpInput.readBytes(); - final List
validators = rlpInput.readList(Address::readFrom); - - final Optional vote; - if (rlpInput.nextIsList() && rlpInput.nextSize() == 0) { - vote = Optional.empty(); - rlpInput.skipNext(); - } else { - vote = Optional.of(decodeVote(rlpInput)); - } - - final int round = rlpInput.readIntScalar(); +@@ -102,9 +120,91 @@ public class QbftExtraDataCodec extends BftExtraDataCodec { final List seals = rlpInput.readList( rlp -> SignatureAlgorithmFactory.getInstance().decodeSignature(rlp.readBytes())); @@ -40339,21 +38228,7 @@ index 39c7aa300..b3096d331 100644 } @Override - protected Bytes encode(final BftExtraData bftExtraData, final EncodingType encodingType) { - final BytesValueRLPOutput encoder = new BytesValueRLPOutput(); - encoder.startList(); - encoder.writeBytes(bftExtraData.getVanityData()); - encoder.writeList( - bftExtraData.getValidators(), (validator, rlp) -> rlp.writeBytes(validator.getBytes())); - - if (bftExtraData.getVote().isPresent()) { - encodeVote(encoder, bftExtraData.getVote().get()); - } else { - encoder.writeList(Collections.emptyList(), (o, rlpOutput) -> {}); - } - - if (encodingType != EncodingType.EXCLUDE_COMMIT_SEALS_AND_ROUND_NUMBER) { - encoder.writeIntScalar(bftExtraData.getRound()); +@@ -126,6 +226,24 @@ public class QbftExtraDataCodec extends BftExtraDataCodec { if (encodingType != EncodingType.EXCLUDE_COMMIT_SEALS) { encoder.writeList( bftExtraData.getSeals(), (committer, rlp) -> rlp.writeBytes(committer.encodedBytes())); @@ -40378,38 +38253,11 @@ index 39c7aa300..b3096d331 100644 } else { encoder.writeEmptyList(); } - } else { - encoder.writeIntScalar(0); - encoder.writeEmptyList(); - } - encoder.endList(); - - return encoder.encoded(); - } - - /** - * Encode vote. - * - * @param rlpOutput the rlp output - * @param vote the vote - */ - protected void encodeVote(final RLPOutput rlpOutput, final Vote vote) { - final VoteType voteType = vote.isAuth() ? VoteType.ADD : VoteType.DROP; diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java index 594fe83e4..dd67707b1 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/adaptor/QbftBlockCreatorAdaptor.java -@@ -1,83 +1,294 @@ - /* - * Copyright contributors to Besu. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,26 +11,51 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -40461,28 +38309,7 @@ index 594fe83e4..dd67707b1 100644 private final BlockCreator besuBlockCreator; private final BftExtraDataCodec bftExtraDataCodec; - /** - * Constructs a new QbftBlockCreator - * - * @param besuBftBlockCreator the Besu BFT block creator - * @param bftExtraDataCodec the bftExtraDataCodec used to encode extra data for the new header - */ - public QbftBlockCreatorAdaptor( - final BlockCreator besuBftBlockCreator, final BftExtraDataCodec bftExtraDataCodec) { - this.besuBlockCreator = besuBftBlockCreator; - this.bftExtraDataCodec = bftExtraDataCodec; - } - - @Override - public BlockCreationResult createBlock( - final long headerTimeStampSeconds, final QbftBlockHeader parentHeader) { - var blockResult = - besuBlockCreator.createBlock( - headerTimeStampSeconds, AdaptorUtil.toBesuBlockHeader(parentHeader)); - return new BlockCreationResult( - new QbftBlockAdaptor(blockResult.getBlock()), blockResult.getBlockAccessList()); - } - +@@ -59,11 +84,60 @@ public class QbftBlockCreatorAdaptor implements QbftBlockCreator { @Override public QbftBlock createSealedBlock( final QbftBlock block, final int roundNumber, final Collection commitSeals) { @@ -40543,8 +38370,7 @@ index 594fe83e4..dd67707b1 100644 final BftExtraData sealedExtraData = new BftExtraData( initialExtraData.getVanityData(), - commitSeals, - initialExtraData.getVote(), +@@ -72,12 +146,149 @@ public class QbftBlockCreatorAdaptor implements QbftBlockCreator { roundNumber, initialExtraData.getValidators()); @@ -40699,17 +38525,7 @@ diff --git a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/bl index 5e6de291b..cabeba99c 100644 --- a/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/QbftBlockCreatorFactory.java +++ b/consensus/qbft/src/main/java/org/hyperledger/besu/consensus/qbft/blockcreation/QbftBlockCreatorFactory.java -@@ -1,42 +1,49 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +@@ -11,6 +11,12 @@ * specific language governing permissions and limitations under the License. * * SPDX-License-Identifier: Apache-2.0 @@ -40722,9 +38538,7 @@ index 5e6de291b..cabeba99c 100644 */ package org.hyperledger.besu.consensus.qbft.blockcreation; - import org.hyperledger.besu.config.QbftConfigOptions; - import org.hyperledger.besu.consensus.common.ConsensusHelpers; - import org.hyperledger.besu.consensus.common.ForksSchedule; +@@ -20,6 +26,7 @@ import org.hyperledger.besu.consensus.common.ForksSchedule; import org.hyperledger.besu.consensus.common.bft.BftExtraData; import org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec; import org.hyperledger.besu.consensus.common.bft.blockcreation.BftBlockCreatorFactory; @@ -40732,41 +38546,7 @@ index 5e6de291b..cabeba99c 100644 import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.core.BlockHeader; - import org.hyperledger.besu.ethereum.core.MiningConfiguration; - import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; - import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; - import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; - - import java.util.Collections; - import java.util.Optional; - - import org.apache.tuweni.bytes.Bytes; - - /** Supports contract based voters and validators in extra data */ - public class QbftBlockCreatorFactory extends BftBlockCreatorFactory { - /** - * Instantiates a new Qbft block creator factory. - * - * @param transactionPool the pending transactions - * @param protocolContext the protocol context -@@ -50,41 +57,63 @@ public class QbftBlockCreatorFactory extends BftBlockCreatorFactory forksSchedule, - final MiningConfiguration miningParams, - final Address localAddress, - final BftExtraDataCodec bftExtraDataCodec, - final EthScheduler ethScheduler) { - super( - transactionPool, - protocolContext, - protocolSchedule, - forksSchedule, - miningParams, - localAddress, - bftExtraDataCodec, +@@ -67,14 +74,34 @@ public class QbftBlockCreatorFactory extends BftBlockCreatorFactory> { - private static final Logger LOG = LoggerFactory.getLogger(DownloadHeadersStep.class); - private final ProtocolSchedule protocolSchedule; - private final ProtocolContext protocolContext; - private final EthContext ethContext; - private final ValidationPolicy validationPolicy; - private final int headerRequestSize; - private final MetricsSystem metricsSystem; -@@ -95,40 +104,132 @@ public class DownloadHeadersStep - LOG.debug("Downloading headers starting from {}", range.getStart().getNumber()); - return ethContext - .getScheduler() - .scheduleServiceTask( - () -> { - GetHeadersFromPeerTask task = - new GetHeadersFromPeerTask( - range.getStart().getHash(), - range.getStart().getNumber(), - headerRequestSize, - 0, - GetHeadersFromPeerTask.Direction.FORWARD, - protocolSchedule); - PeerTaskExecutorResult> taskResult = - ethContext.getPeerTaskExecutor().execute(task); - if (taskResult.responseCode() != PeerTaskExecutorResponseCode.SUCCESS - || taskResult.result().isEmpty()) { +@@ -112,11 +121,103 @@ public class DownloadHeadersStep return CompletableFuture.failedFuture( new RuntimeException("Unable to download headers for range " + range)); } @@ -46202,18 +43930,3 @@ index c8eb53639..76c435677 100644 private RangeHeaders processHeaders( final SyncTargetRange checkpointRange, final List headers) { if (checkpointRange.hasEnd()) { - final List headersToImport = new ArrayList<>(headers); - headersToImport.add(checkpointRange.getEnd()); - return new RangeHeaders(checkpointRange, headersToImport); - } else { - List headersToImport = headers; - if (!headers.isEmpty() && headers.getFirst().equals(checkpointRange.getStart())) { - headersToImport = headers.subList(1, headers.size()); - } - return new RangeHeaders(checkpointRange, headersToImport); - } - } - } --- -2.43.0 - diff --git a/patches/0004-aere-basefee-floor.patch b/patches/0004-aere-basefee-floor.patch index fbc713b..7380324 100644 --- a/patches/0004-aere-basefee-floor.patch +++ b/patches/0004-aere-basefee-floor.patch @@ -1,66 +1,15 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aere Network -Date: Sat, 05 Sep 2026 09:53:25 +0000 +Date: Thu, 10 Sep 2026 21:47:56 +0300 Subject: [PATCH] Aere Network: base-fee floor for chain 2800 (production form) -Apache License 2.0, section 4(b): the files this patch modifies are the work of -Hyperledger Besu and carry its copyright notice; the modifications are by -contributors to the Aere Network under the same licence. +Regenerated 2026-09-10 from the production tree (overlay applied) over the same file set. -Regenerated 2026-09-05 from the production tree, so that the public recipe -reproduces the live binary class for class: the floor and its fork height are -read from the system properties aere.basefee.floor.forkBlock and -aere.basefee.floor.value (or the AERE_BASEFEE_FLOOR_* environment variables), -absent = disarmed, exactly as RUN-A-NODE.md tells an operator to set them. -The previous revision of this patch hard-coded both as constants, so the -operator's property was dead on a node built from the public recipe (found -2026-09-05 by comparing the fleet's jars with the public build class by class). ---- diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java -index 0ee4f74..72913d4 100644 +index 0ee4f7409..558076166 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java -@@ -1,136 +1,252 @@ - /* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 -+ * -+ * Modifications Copyright contributors to the Aere Network. -+ * -+ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the -+ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was -+ * found, as section 4(c) requires. The change is the chain 2800 base-fee floor below, armed only -+ * by the aere.basefee.floor.* properties; with them absent this file behaves exactly as upstream. - */ - package org.hyperledger.besu.ethereum.mainnet.feemarket; - - import org.hyperledger.besu.config.GenesisConfig; - import org.hyperledger.besu.datatypes.Wei; - import org.hyperledger.besu.ethereum.core.Transaction; - import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator; - - import java.util.Optional; - - import org.apache.tuweni.units.bigints.UInt256s; - import org.slf4j.Logger; - import org.slf4j.LoggerFactory; - - public class LondonFeeMarket implements BaseFeeMarket { - private static final Logger LOG = LoggerFactory.getLogger(LondonFeeMarket.class); - - static final Wei DEFAULT_BASEFEE_INITIAL_VALUE = GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE; - static final long DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR = 8L; - static final long DEFAULT_SLACK_COEFFICIENT = 2L; +@@ -34,11 +34,36 @@ public class LondonFeeMarket implements BaseFeeMarket { private static final Wei DEFAULT_BASEFEE_FLOOR = Wei.of(7L); @@ -97,8 +46,7 @@ index 0ee4f74..72913d4 100644 LondonFeeMarket(final long londonForkBlockNumber, final Optional baseFeePerGasOverride) { this(TransactionPriceCalculator.eip1559(), londonForkBlockNumber, baseFeePerGasOverride); } - - LondonFeeMarket( +@@ -47,10 +72,94 @@ public class LondonFeeMarket implements BaseFeeMarket { final TransactionPriceCalculator txPriceCalculator, final long londonForkBlockNumber, final Optional baseFeePerGasOverride) { @@ -193,28 +141,7 @@ index 0ee4f74..72913d4 100644 } @Override - public long getBasefeeMaxChangeDenominator() { - return DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR; - } - - @Override - public Wei getInitialBasefee() { - return baseFeeInitialValue; - } - - @Override - public long getSlackCoefficient() { - return DEFAULT_SLACK_COEFFICIENT; - } - - @Override - public TransactionPriceCalculator getTransactionPriceCalculator() { - return txPriceCalculator; - } - - @Override - public boolean satisfiesFloorTxFee(final Transaction txn) { - // ensure effective baseFee is at least above floor +@@ -79,7 +188,7 @@ public class LondonFeeMarket implements BaseFeeMarket { return txn.getGasPrice() .map(Optional::of) .orElse(txn.getMaxFeePerGas()) @@ -223,10 +150,7 @@ index 0ee4f74..72913d4 100644 .isPresent(); } - @Override - public Wei computeBaseFee( - final long blockNumber, - final Wei parentBaseFee, +@@ -90,13 +199,13 @@ public class LondonFeeMarket implements BaseFeeMarket { final long parentBlockGasUsed, final long targetGasUsed) { if (londonForkBlockNumber == blockNumber) { @@ -242,20 +166,7 @@ index 0ee4f74..72913d4 100644 } else if (parentBlockGasUsed > targetGasUsed) { gasDelta = parentBlockGasUsed - targetGasUsed; final long denominator = getBasefeeMaxChangeDenominator(); - feeDelta = - UInt256s.max( - parentBaseFee.multiply(gasDelta).divide(targetGasUsed).divide(denominator), Wei.ONE); - baseFee = parentBaseFee.add(feeDelta); - } else { - gasDelta = targetGasUsed - parentBlockGasUsed; - final long denominator = getBasefeeMaxChangeDenominator(); - feeDelta = parentBaseFee.multiply(gasDelta).divide(targetGasUsed).divide(denominator); - baseFee = parentBaseFee.subtract(feeDelta); - } - LOG.trace( - "block #{} parentBaseFee: {} parentGasUsed: {} parentGasTarget: {} baseFee: {}", - blockNumber, - parentBaseFee, +@@ -117,7 +226,7 @@ public class LondonFeeMarket implements BaseFeeMarket { parentBlockGasUsed, targetGasUsed, baseFee); @@ -264,16 +175,3 @@ index 0ee4f74..72913d4 100644 } @Override - public ValidationMode baseFeeValidationMode(final long blockNumber) { - return londonForkBlockNumber == blockNumber ? ValidationMode.INITIAL : ValidationMode.ONGOING; - } - - @Override - public ValidationMode gasLimitValidationMode(final long blockNumber) { - return londonForkBlockNumber == blockNumber ? ValidationMode.INITIAL : ValidationMode.ONGOING; - } - - @Override - public boolean isBeforeForkBlock(final long blockNumber) { - return londonForkBlockNumber > blockNumber; - }