Merge branch 'main' into eip-4844-interop

pull/5091/head
Fabio Di Fabio 2 years ago
commit d21574ae47
  1. 2
      CHANGELOG.md
  2. 10
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  3. 14
      besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java
  4. 25
      besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java
  5. 56
      besu/src/test/resources/valid_pos_checkpoint_pos_TD_equals_TTD.json
  6. 8
      config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java
  7. 12
      config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java
  8. 1
      config/src/main/resources/sepolia.json
  9. 32
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java
  10. 13
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java
  11. 13
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/AbstractTrieLogManager.java
  12. 38
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiLayeredWorldState.java
  13. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/DefaultTimestampSchedule.java
  14. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/HeaderBasedProtocolSchedule.java
  15. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolSchedule.java
  16. 13
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdTest.java
  17. 11
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/forkid/ForkIdTestUtil.java
  18. 11
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/TimestampScheduleBuilderTest.java
  19. 6
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/transactions/sorter/AbstractPendingTransactionsSorter.java
  20. 2
      ethereum/referencetests/src/reference-test/external-resources
  21. 12
      evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCreateOperation.java

@ -31,7 +31,7 @@ tests are updated to use EC private keys instead of RSA keys.
### Bug Fixes
- Mitigation fix for stale bonsai code storage leading to log rolling issues on contract recreates [#4906](https://github.com/hyperledger/besu/pull/4906)
- Ensure latest cached layered worldstate is subscribed to storage, fix problem with RPC calls using 'latest' [#5076](https://github.com/hyperledger/besu/pull/5076)
## 23.1.0-RC1

@ -3510,7 +3510,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
if (synchronizerConfiguration.isCheckpointPostMergeEnabled()) {
if (!checkpointConfigOptions.isValid()) {
throw new InvalidConfigurationException(
"Near head checkpoint sync requires a checkpoint block configured in the genesis file");
"PoS checkpoint sync requires a checkpoint block configured in the genesis file");
}
terminalTotalDifficulty.ifPresentOrElse(
ttd -> {
@ -3519,18 +3519,18 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.equals(UInt256.ZERO)
&& ttd.equals(UInt256.ZERO)) {
throw new InvalidConfigurationException(
"Post Merge checkpoint sync can't be used with TTD = 0 and checkpoint totalDifficulty = 0");
"PoS checkpoint sync can't be used with TTD = 0 and checkpoint totalDifficulty = 0");
}
if (UInt256.fromHexString(
genesisOptions.getCheckpointOptions().getTotalDifficulty().get())
.lessOrEqualThan(ttd)) {
.lessThan(ttd)) {
throw new InvalidConfigurationException(
"Near head checkpoint sync requires a block with total difficulty greater than the TTD");
"PoS checkpoint sync requires a block with total difficulty greater or equal than the TTD");
}
},
() -> {
throw new InvalidConfigurationException(
"Near head checkpoint sync requires TTD in the genesis file");
"PoS checkpoint sync requires TTD in the genesis file");
});
}
}

@ -24,14 +24,13 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.consensus.merge.TransitionProtocolSchedule;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.chain.GenesisState;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.forkid.ForkId;
import org.hyperledger.besu.ethereum.forkid.ForkIdManager;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import java.util.Collection;
import java.util.List;
@ -73,8 +72,9 @@ public class ForkIdsNetworkConfigTest {
NetworkName.SEPOLIA,
List.of(
new ForkId(Bytes.ofUnsignedInt(0xfe3366e7L), 1735371L),
new ForkId(Bytes.ofUnsignedInt(0xb96cbd13L), 0L),
new ForkId(Bytes.ofUnsignedInt(0xb96cbd13L), 0L))
new ForkId(Bytes.ofUnsignedInt(0xb96cbd13L), 1677557088L),
new ForkId(Bytes.ofUnsignedInt(0xf7f9bc08L), 0L),
new ForkId(Bytes.ofUnsignedInt(0xf7f9bc08L), 0L))
},
new Object[] {
NetworkName.RINKEBY,
@ -168,8 +168,7 @@ public class ForkIdsNetworkConfigTest {
final GenesisConfigFile genesisConfigFile =
GenesisConfigFile.fromConfig(EthNetworkConfig.jsonConfig(chainName));
final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions();
final ProtocolSchedule schedule =
MainnetProtocolSchedule.fromConfig(configOptions, EvmConfiguration.DEFAULT);
final ProtocolSchedule schedule = TransitionProtocolSchedule.fromConfig(configOptions);
final GenesisState genesisState = GenesisState.fromConfig(genesisConfigFile, schedule);
final Blockchain mockBlockchain = mock(Blockchain.class);
final BlockHeader mockBlockHeader = mock(BlockHeader.class);
@ -179,6 +178,7 @@ public class ForkIdsNetworkConfigTest {
final AtomicLong blockNumber = new AtomicLong();
when(mockBlockchain.getChainHeadHeader()).thenReturn(mockBlockHeader);
when(mockBlockHeader.getNumber()).thenAnswer(o -> blockNumber.get());
when(mockBlockHeader.getTimestamp()).thenAnswer(o -> blockNumber.get());
final ForkIdManager forkIdManager =
new ForkIdManager(
@ -187,7 +187,7 @@ public class ForkIdsNetworkConfigTest {
genesisConfigFile.getForkTimestamps(),
false);
final var actualForkIds =
final List<ForkId> actualForkIds =
Streams.concat(schedule.streamMilestoneBlocks(), Stream.of(Long.MAX_VALUE))
.map(
block -> {

@ -5518,7 +5518,7 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains("Near head checkpoint sync requires TTD in the genesis file");
.contains("PoS checkpoint sync requires TTD in the genesis file");
}
@Test
@ -5529,7 +5529,7 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
"Near head checkpoint sync requires a block with total difficulty greater than the TTD");
"PoS checkpoint sync requires a block with total difficulty greater or equal than the TTD");
}
@Test
@ -5559,6 +5559,25 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
@Test
public void checkpointPostMergeWithPostMergeBlockTDEqualsTTDSucceeds() throws IOException {
final String configText =
Resources.toString(
Resources.getResource("valid_pos_checkpoint_pos_TD_equals_TTD.json"),
StandardCharsets.UTF_8);
final Path genesisFile = createFakeGenesisFile(new JsonObject(configText));
parseCommand(
"--genesis-file",
genesisFile.toString(),
"--sync-mode",
"X_CHECKPOINT",
"--Xcheckpoint-post-merge-enabled");
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8)).isEmpty();
}
@Test
public void checkpointMergeAtGenesisWithGenesisBlockDifficultyZeroFails() throws IOException {
final String configText =
@ -5577,6 +5596,6 @@ public class BesuCommandTest extends CommandTestAbstract {
assertThat(commandOutput.toString(UTF_8)).isEmpty();
assertThat(commandErrorOutput.toString(UTF_8))
.contains(
"Post Merge checkpoint sync can't be used with TTD = 0 and checkpoint totalDifficulty = 0");
"PoS checkpoint sync can't be used with TTD = 0 and checkpoint totalDifficulty = 0");
}
}

@ -0,0 +1,56 @@
{
"config": {
"chainId": 1337,
"homesteadBlock": 0,
"daoForkBlock": 0,
"eip150Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"arrowGlacierBlock": 0,
"grayGlacierBlock": 0,
"terminalTotalDifficulty": 10,
"ethash": {
},
"discovery": {
"dns": "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.mainnet.ethdisco.net",
"bootnodes": [
"enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303",
"enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303",
"enode://8499da03c47d637b20eee24eec3c356c9a2e6148d6fe25ca195c7949ab8ec2c03e3556126b0d7ed644675e78c4318b08691b7b57de10e5f0d40d05b09238fa0a@52.187.207.27:30303",
"enode://103858bdb88756c71f15e9b5e09b56dc1be52f0a5021d46301dbbfb7e130029cc9d0d6f73f693bc29b665770fff7da4d34f3c6379fe12721b5d7a0bcb5ca1fc1@191.234.162.198:30303",
"enode://715171f50508aba88aecd1250af392a45a330af91d7b90701c436b618c86aaa1589c9184561907bebbb56439b8f8787bc01f49a7c77276c58c1b09822d75e8e8@52.231.165.108:30303",
"enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303",
"enode://2b252ab6a1d0f971d9722cb839a42cb81db019ba44c08754628ab4a823487071b5695317c8ccd085219c3a03af063495b2f1da8d18218da2d6a82981b45e6ffc@65.108.70.101:30303",
"enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303",
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
"enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303",
"enode://78de8a0916848093c73790ead81d1928bec737d565119932b98c6b100d944b7a95e94f847f689fc723399d2e31129d182f7ef3863f2b4c820abbf3ab2722344d@191.235.84.50:30303",
"enode://158f8aab45f6d19c6cbf4a089c2670541a8da11978a2f90dbf6a502a4a3bab80d288afdbeb7ec0ef6d92de563767f3b1ea9e8e334ca711e9f8e2df5a0385e8e6@13.75.154.138:30303",
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
"enode://979b7fa28feeb35a4741660a16076f1943202cb72b6af70d327f053e248bab9ba81760f39d0701ef1d8f89cc1fbd2cacba0710a12cd5314d5e0c9021aa3637f9@5.1.83.226:30303"
]
},
"checkpoint": {
"hash": "0x186642d6084eb7799cb01c7eb69c1a7f3b2c32cd141e62d309f30081a1ea3c91",
"number": 3,
"totalDifficulty": "0x0a"
}
},
"nonce": "0x42",
"timestamp": "0x0",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"000d836201318ec6899a67540690382780743280": {
"balance": "0xad78ebc5ac6200000"
}
}
}

@ -596,10 +596,6 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
getArrowGlacierBlockNumber(),
getGrayGlacierBlockNumber(),
getMergeNetSplitBlockNumber(),
getShanghaiTime(),
getCancunTime(),
getFutureEipsTime(),
getExperimentalEipsTime(),
getEcip1015BlockNumber(),
getDieHardBlockNumber(),
getGothamBlockNumber(),
@ -623,7 +619,9 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions {
@Override
public List<Long> getForkBlockTimestamps() {
Stream<OptionalLong> forkBlockTimestamps = Stream.of(getShanghaiTime(), getCancunTime());
Stream<OptionalLong> forkBlockTimestamps =
Stream.of(
getShanghaiTime(), getCancunTime(), getFutureEipsTime(), getExperimentalEipsTime());
// when adding forks add an entry to ${REPO_ROOT}/config/src/test/resources/all_forks.json
return forkBlockTimestamps

@ -622,22 +622,22 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions {
/**
* Future EIPs Time block.
*
* @param blockNumber the block number
* @param timestamp the block timestamp
* @return the stub genesis config options
*/
public StubGenesisConfigOptions futureEipsTime(final long blockNumber) {
futureEipsTime = OptionalLong.of(blockNumber);
public StubGenesisConfigOptions futureEipsTime(final long timestamp) {
futureEipsTime = OptionalLong.of(timestamp);
return this;
}
/**
* Experimental EIPs Time block.
*
* @param blockNumber the block number
* @param timestamp the block timestamp
* @return the stub genesis config options
*/
public StubGenesisConfigOptions experimentalEipsTime(final long blockNumber) {
experimentalEipsTime = OptionalLong.of(blockNumber);
public StubGenesisConfigOptions experimentalEipsTime(final long timestamp) {
experimentalEipsTime = OptionalLong.of(timestamp);
return this;
}

@ -13,6 +13,7 @@
"londonBlock":0,
"mergeNetSplitBlock": 1735371,
"terminalTotalDifficulty": 17000000000000000,
"shanghaiTime": 1677557088,
"ethash":{},
"discovery": {
"dns": "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.sepolia.ethdisco.net",

@ -16,11 +16,14 @@ package org.hyperledger.besu.consensus.merge;
import static org.hyperledger.besu.util.Slf4jLambdaHelper.debugLambda;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.core.TransactionFilter;
import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TimestampSchedule;
@ -60,6 +63,29 @@ public class TransitionProtocolSchedule implements ProtocolSchedule {
new TransitionUtils<>(preMergeProtocolSchedule, postMergeProtocolSchedule, mergeContext);
}
/**
* Create a Proof-of-Stake protocol schedule from a config object
*
* @param genesisConfigOptions {@link GenesisConfigOptions} containing the config options for the
* milestone starting points
* @return an initialised TransitionProtocolSchedule using post-merge defaults
*/
public static TransitionProtocolSchedule fromConfig(
final GenesisConfigOptions genesisConfigOptions) {
ProtocolSchedule preMergeProtocolSchedule =
MainnetProtocolSchedule.fromConfig(genesisConfigOptions);
ProtocolSchedule postMergeProtocolSchedule =
MergeProtocolSchedule.create(genesisConfigOptions, false);
TimestampSchedule timestampSchedule =
MergeProtocolSchedule.createTimestamp(
genesisConfigOptions, PrivacyParameters.DEFAULT, false);
return new TransitionProtocolSchedule(
preMergeProtocolSchedule,
postMergeProtocolSchedule,
PostMergeContext.get(),
timestampSchedule);
}
/**
* Gets pre merge schedule.
*
@ -162,8 +188,10 @@ public class TransitionProtocolSchedule implements ProtocolSchedule {
*/
@Override
public Stream<Long> streamMilestoneBlocks() {
return transitionUtils.dispatchFunctionAccordingToMergeState(
ProtocolSchedule::streamMilestoneBlocks);
Stream<Long> milestoneBlockNumbers =
transitionUtils.dispatchFunctionAccordingToMergeState(
ProtocolSchedule::streamMilestoneBlocks);
return Stream.concat(milestoneBlockNumbers, timestampSchedule.streamMilestoneBlocks());
}
/**

@ -855,12 +855,19 @@ public class BlockchainQueries {
.getBlockHeader(blockHash)
.flatMap(
blockHeader -> {
try (var ws =
try (final var worldState =
worldStateArchive
.getMutable(blockHeader.getStateRoot(), blockHeader.getHash(), false)
.map(
ws -> {
if (!ws.isPersistable()) {
return ws.copy();
}
return ws;
})
.orElse(null)) {
if (ws != null) {
return Optional.ofNullable(mapper.apply(ws));
if (worldState != null) {
return Optional.ofNullable(mapper.apply(worldState));
}
} catch (Exception ex) {
LOG.error("failed worldstate query for " + blockHash.toShortHexString(), ex);

@ -97,16 +97,17 @@ public abstract class AbstractTrieLogManager<T extends MutableWorldState>
@VisibleForTesting
TrieLogLayer prepareTrieLog(
final BlockHeader blockHeader,
final Hash worldStateRootHash,
final BlockHeader forBlockHeader,
final Hash forWorldStateRootHash,
final BonsaiWorldStateUpdater localUpdater,
final BonsaiWorldStateArchive worldStateArchive,
final BonsaiPersistedWorldState forWorldState) {
debugLambda(LOG, "Adding layered world state for {}", blockHeader::toLogString);
final TrieLogLayer trieLog = localUpdater.generateTrieLog(blockHeader.getBlockHash());
debugLambda(LOG, "Adding layered world state for {}", forBlockHeader::toLogString);
final TrieLogLayer trieLog = localUpdater.generateTrieLog(forBlockHeader.getBlockHash());
trieLog.freeze();
addCachedLayer(blockHeader, worldStateRootHash, trieLog, worldStateArchive, forWorldState);
scrubCachedLayers(blockHeader.getNumber());
addCachedLayer(
forBlockHeader, forWorldStateRootHash, trieLog, worldStateArchive, forWorldState);
scrubCachedLayers(forBlockHeader.getNumber());
return trieLog;
}

@ -40,8 +40,13 @@ import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256;
/** A World State backed first by trie log layer and then by another world state. */
public class BonsaiLayeredWorldState implements MutableWorldState, BonsaiWorldView, WorldState {
private Optional<BonsaiWorldView> nextWorldView;
public class BonsaiLayeredWorldState
implements MutableWorldState,
BonsaiWorldView,
WorldState,
BonsaiWorldStateKeyValueStorage.BonsaiStorageSubscriber {
private Optional<BonsaiWorldView> nextWorldView = Optional.empty();
private Optional<Long> newtWorldViewSubscribeId = Optional.empty();
protected final long height;
protected final TrieLogLayer trieLog;
private final Hash worldStateRootHash;
@ -58,7 +63,7 @@ public class BonsaiLayeredWorldState implements MutableWorldState, BonsaiWorldVi
final TrieLogLayer trieLog) {
this.blockchain = blockchain;
this.archive = archive;
this.nextWorldView = nextWorldView;
this.setNextWorldView(nextWorldView);
this.height = height;
this.worldStateRootHash = worldStateRootHash;
this.trieLog = trieLog;
@ -76,7 +81,34 @@ public class BonsaiLayeredWorldState implements MutableWorldState, BonsaiWorldVi
}
public void setNextWorldView(final Optional<BonsaiWorldView> nextWorldView) {
maybeUnSubscribe(); // unsubscribe the old view
this.nextWorldView = nextWorldView;
maybeSubscribe(); // subscribe the next view
}
private void maybeSubscribe() {
nextWorldView
.filter(BonsaiPersistedWorldState.class::isInstance)
.map(BonsaiPersistedWorldState.class::cast)
.ifPresent(
worldState -> {
newtWorldViewSubscribeId = Optional.of(worldState.worldStateStorage.subscribe(this));
});
}
private void maybeUnSubscribe() {
nextWorldView
.filter(BonsaiPersistedWorldState.class::isInstance)
.map(BonsaiPersistedWorldState.class::cast)
.ifPresent(
worldState -> {
newtWorldViewSubscribeId.ifPresent(worldState.worldStateStorage::unSubscribe);
});
}
@Override
public void close() throws Exception {
maybeUnSubscribe();
}
public TrieLogLayer getTrieLog() {

@ -26,6 +26,7 @@ import java.util.NavigableSet;
import java.util.Optional;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DefaultTimestampSchedule implements TimestampSchedule {
private final NavigableSet<TimedProtocolSpec> protocolSpecs =
@ -46,6 +47,11 @@ public class DefaultTimestampSchedule implements TimestampSchedule {
return Optional.empty();
}
@Override
public Stream<Long> streamMilestoneBlocks() {
return protocolSpecs.stream().map(TimedProtocolSpec::getTimestamp).sorted();
}
@Override
public Optional<BigInteger> getChainId() {
return chainId;

@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import java.math.BigInteger;
import java.util.Optional;
import java.util.stream.Stream;
public interface HeaderBasedProtocolSchedule {
@ -31,4 +32,6 @@ public interface HeaderBasedProtocolSchedule {
void putMilestone(final long blockOrTimestamp, final ProtocolSpec protocolSpec);
String listMilestones();
Stream<Long> streamMilestoneBlocks();
}

@ -16,15 +16,11 @@ package org.hyperledger.besu.ethereum.mainnet;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import java.util.stream.Stream;
public interface ProtocolSchedule
extends HeaderBasedProtocolSchedule, PrivacySupportingProtocolSchedule {
ProtocolSpec getByBlockNumber(long number);
Stream<Long> streamMilestoneBlocks();
@Override
default ProtocolSpec getByBlockHeader(final ProcessableBlockHeader blockHeader) {
return getByBlockNumber(blockHeader.getNumber());

@ -313,11 +313,20 @@ public class ForkIdTest {
empty()
},
{
"Sepolia // Future",
"Sepolia // Shanghai",
Network.SEPOLIA,
1735371L,
0L,
ForkIdTestUtil.wantForkId("0xb96cbd13", 0L),
ForkIdTestUtil.wantForkId("0xb96cbd13", 1677557088L),
Optional.of(ForkIds.SEPOLIA),
empty()
},
{
"Sepolia // Future",
Network.SEPOLIA,
1735372L,
1677557088L,
ForkIdTestUtil.wantForkId("0xf7f9bc08", 0L),
Optional.of(ForkIds.SEPOLIA),
empty()
},

@ -73,8 +73,11 @@ public class ForkIdTestUtil {
Arrays.asList(
1920000L, 1150000L, 2463000L, 2675000L, 2675000L, 4370000L, 7280000L, 7280000L,
9069000L, 9200000L, 12244000L, 12965000L, 13773000L, 15050000L);
public static final List<Long> SEPOLIA =
public static final List<Long> SEPOLIA_BLOCKNUMBERS =
Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1735371L);
public static final List<Long> SEPOLIA_TIMESTAMPS = Arrays.asList(1677557088L);
public static final List<Long> RINKEBY =
Arrays.asList(1L, 2L, 3L, 3L, 1035301L, 3660663L, 4321234L, 5435345L);
public static final List<Long> GOERLI = Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1561651L);
@ -106,7 +109,8 @@ public class ForkIdTestUtil {
public static final List<ForkId> SEPOLIA =
Arrays.asList(
new ForkId(Bytes.fromHexString("0xfe3366e7"), 1735371L),
new ForkId(Bytes.fromHexString("0xb96cbd13"), 0L));
new ForkId(Bytes.fromHexString("0xb96cbd13"), 1677557088L),
new ForkId(Bytes.fromHexString("0xf7f9bc08"), 0L)); // First Shanghai block (timestamp)
public static final List<ForkId> RINKEBY =
Arrays.asList(
new ForkId(Bytes.fromHexString("0x3b8e0691"), 1L),
@ -145,7 +149,8 @@ public class ForkIdTestUtil {
public static class Network {
public static final Network MAINNET = network(GenesisHash.MAINNET, Forks.MAINNET, emptyList());
public static final Network SEPOLIA = network(GenesisHash.SEPOLIA, Forks.SEPOLIA, emptyList());
public static final Network SEPOLIA =
network(GenesisHash.SEPOLIA, Forks.SEPOLIA_BLOCKNUMBERS, Forks.SEPOLIA_TIMESTAMPS);
public static final Network RINKEBY = network(GenesisHash.RINKEBY, Forks.RINKEBY, emptyList());
public static final Network GOERLI = network(GenesisHash.GOERLI, Forks.GOERLI, emptyList());
public static final Network PRIVATE = network(GenesisHash.PRIVATE, Forks.PRIVATE, emptyList());

@ -138,4 +138,15 @@ public class TimestampScheduleBuilderTest {
assertThat(schedule.getByBlockHeader(BLOCK_HEADER)).isNull();
}
@Test
public void streamMilestoneBlocksReturnTimestampsInOrder() {
config.shanghaiTime(FIRST_TIMESTAMP_FORK);
config.cancunTime(2L);
config.experimentalEipsTime(5L);
config.futureEipsTime(3L);
final TimestampSchedule schedule = builder.createTimestampSchedule();
assertThat(schedule.streamMilestoneBlocks()).containsExactly(FIRST_TIMESTAMP_FORK, 2L, 3L, 5L);
}
}

@ -428,7 +428,11 @@ public abstract class AbstractPendingTransactionsSorter implements PendingTransa
LOG,
"Transaction {} not added because nonce too far in the future for sender {}",
transaction::toTraceLog,
maybeSenderAccount::toString);
() ->
maybeSenderAccount
.map(Account::getAddress)
.map(Address::toString)
.orElse("unknown"));
return NONCE_TOO_FAR_IN_FUTURE_FOR_SENDER;
}

@ -1 +1 @@
Subproject commit 69c4c2a98dc8a712d4c6f5a817da4f21ff719006
Subproject commit 638da7ca7b2ca371ebb33d7d7d2562981aafd9b2

@ -80,6 +80,12 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
final MutableAccount account = frame.getWorldUpdater().getAccount(address).getMutable();
frame.clearReturnData();
final long inputOffset = clampedToLong(frame.getStackItem(1));
final long inputSize = clampedToLong(frame.getStackItem(2));
if (inputSize > maxInitcodeSize) {
frame.popStackItems(getStackItemsConsumed());
return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE);
}
if (value.compareTo(account.getBalance()) > 0
|| frame.getMessageStackDepth() >= 1024
@ -88,12 +94,6 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
} else {
account.incrementNonce();
final long inputOffset = clampedToLong(frame.getStackItem(1));
final long inputSize = clampedToLong(frame.getStackItem(2));
if (inputSize > maxInitcodeSize) {
frame.popStackItems(getStackItemsConsumed());
return new OperationResult(cost, ExceptionalHaltReason.CODE_TOO_LARGE);
}
final Bytes inputData = frame.readMemory(inputOffset, inputSize);
// Never cache CREATEx initcode. The amount of reuse is very low, and caching mostly
// addresses disk loading delay, and we already have the code.

Loading…
Cancel
Save