Skip to content

Commit

Permalink
Support Shanghai in Reference Tests (#4900)
Browse files Browse the repository at this point in the history
* Support Shanghai in Reference Tests

Add support for Shanghai in reference tests
* Add Shanghai and Cancun milestones
* Add "withdrawals" and "withdrawalsRoot" to json objects
* Migrate to schedule by block header.

Signed-off-by: Danno Ferrin <[email protected]>

* Add pending withdrawal code to test case spec

Signed-off-by: Danno Ferrin <[email protected]>

Signed-off-by: Danno Ferrin <[email protected]>
Co-authored-by: Sally MacFarlane <[email protected]>
  • Loading branch information
shemnon and macfarla committed Jan 10, 2023
1 parent 57f0110 commit e129c9f
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.evm.log.LogsBloomFilter;

import java.time.Instant;
Expand Down Expand Up @@ -72,6 +73,26 @@ public static BlockHeaderBuilder create() {
return new BlockHeaderBuilder();
}

public static BlockHeaderBuilder createDefault() {
return new BlockHeaderBuilder()
.parentHash(Hash.EMPTY)
.coinbase(Address.ZERO)
.difficulty(Difficulty.ONE)
.number(0)
.gasLimit(30_000_000)
.timestamp(0)
.ommersHash(Hash.EMPTY_LIST_HASH)
.stateRoot(Hash.EMPTY_TRIE_HASH)
.transactionsRoot(Hash.EMPTY)
.receiptsRoot(Hash.EMPTY)
.logsBloom(LogsBloomFilter.empty())
.gasUsed(0)
.extraData(Bytes.EMPTY)
.mixHash(Hash.EMPTY)
.nonce(0)
.blockHeaderFunctions(new MainnetBlockHeaderFunctions());
}

public static BlockHeaderBuilder fromHeader(final BlockHeader header) {
return create()
.parentHash(header.getParentHash())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
Expand Down Expand Up @@ -207,13 +207,13 @@ private void traceTestSpecs(final String test, final List<GeneralStateTestCaseEi
}

final String forkName = fork == null ? spec.getFork() : fork;
final ProtocolSchedule protocolSchedule =
final HeaderBasedProtocolSchedule protocolSchedule =
referenceTestProtocolSchedules.getByName(forkName);
if (protocolSchedule == null) {
throw new UnsupportedForkException(forkName);
}

ProtocolSpec protocolSpec = protocolSchedule.getByBlockNumber(0);
ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(blockHeader);
final MainnetTransactionProcessor processor = protocolSpec.getTransactionProcessor();
final WorldUpdater worldStateUpdater = worldState.updater();
final ReferenceTestBlockchain blockchain =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ public ReferenceTestBlockHeader(
@JsonProperty("baseFeePerGas") final String baseFee,
@JsonProperty("mixHash") final String mixHash,
@JsonProperty("nonce") final String nonce,
@JsonProperty("withdrawalsRoot") final String withdrawalsRoot,
@JsonProperty("hash") final String hash) {
super(
Hash.fromHexString(parentHash), // parentHash
Expand All @@ -175,6 +176,7 @@ public ReferenceTestBlockHeader(
baseFee != null ? Wei.fromHexString(baseFee) : null, // baseFee
Hash.fromHexString(mixHash), // mixHash
Bytes.fromHexStringLenient(nonce).toLong(),
// withdrawalsRoot == null ? Hash.EMPTY : Hash.fromHexString(withdrawalsRoot),
new BlockHeaderFunctions() {
@Override
public Hash hash(final BlockHeader header) {
Expand Down Expand Up @@ -216,7 +218,8 @@ public CandidateBlock(
@JsonProperty("rlp") final String rlp,
@JsonProperty("blockHeader") final Object blockHeader,
@JsonProperty("transactions") final Object transactions,
@JsonProperty("uncleHeaders") final Object uncleHeaders) {
@JsonProperty("uncleHeaders") final Object uncleHeaders,
@JsonProperty("withdrawals") final Object withdrawals) {
boolean blockVaid = true;
// The BLOCK__WrongCharAtRLP_0 test has an invalid character in its rlp string.
Bytes rlpAttempt = null;
Expand All @@ -227,7 +230,10 @@ public CandidateBlock(
}
this.rlp = rlpAttempt;

if (blockHeader == null && transactions == null && uncleHeaders == null) {
if (blockHeader == null
&& transactions == null
&& uncleHeaders == null
&& withdrawals == null) {
blockVaid = false;
}

Expand All @@ -251,6 +257,10 @@ public Block getBlock() {
new BlockBody(
input.readList(Transaction::readFrom),
input.readList(inputData -> BlockHeader.readFrom(inputData, blockHeaderFunctions)));
// input.readList(inputData -> BlockHeader.readFrom(inputData, blockHeaderFunctions),
// input.isEndOfCurrentList()
// ? Optional.empty()
// : Optional.of(input.readList(Withdrawal::readFrom))));
return new Block(header, body);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.StubGenesisConfigOptions;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters;
import org.hyperledger.besu.ethereum.mainnet.TimestampSchedule;
import org.hyperledger.besu.ethereum.mainnet.TimestampScheduleBuilder;
import org.hyperledger.besu.evm.internal.EvmConfiguration;

import java.math.BigInteger;
Expand All @@ -39,7 +42,8 @@ public class ReferenceTestProtocolSchedules {
Arrays.asList("Frontier", "Homestead", "EIP150");

public static ReferenceTestProtocolSchedules create() {
final ImmutableMap.Builder<String, ProtocolSchedule> builder = ImmutableMap.builder();
final ImmutableMap.Builder<String, HeaderBasedProtocolSchedule> builder =
ImmutableMap.builder();
builder.put("Frontier", createSchedule(new StubGenesisConfigOptions()));
builder.put(
"FrontierToHomesteadAt5", createSchedule(new StubGenesisConfigOptions().homesteadBlock(5)));
Expand Down Expand Up @@ -73,21 +77,23 @@ public static ReferenceTestProtocolSchedules create() {
builder.put(
"Merge",
createSchedule(new StubGenesisConfigOptions().mergeNetSplitBlock(0).baseFeePerGas(0x0a)));
builder.put("Shanghai", createSchedule(new StubGenesisConfigOptions().shanghaiTime(0)));
builder.put("Cancun", createSchedule(new StubGenesisConfigOptions().cancunTime(0)));
builder.put("FutureEips", createSchedule(new StubGenesisConfigOptions().futureEipsTime(0)));
builder.put(
"ExperimentalEips", createSchedule(new StubGenesisConfigOptions().experimentalEipsTime(0)));
"Shanghai",
createTimestampSchedule(
new StubGenesisConfigOptions().shanghaiTime(0).baseFeePerGas(0x0a)));
builder.put(
"Cancun",
createTimestampSchedule(new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a)));
return new ReferenceTestProtocolSchedules(builder.build());
}

private final Map<String, ProtocolSchedule> schedules;
private final Map<String, HeaderBasedProtocolSchedule> schedules;

private ReferenceTestProtocolSchedules(final Map<String, ProtocolSchedule> schedules) {
private ReferenceTestProtocolSchedules(final Map<String, HeaderBasedProtocolSchedule> schedules) {
this.schedules = schedules;
}

public ProtocolSchedule getByName(final String name) {
public HeaderBasedProtocolSchedule getByName(final String name) {
return schedules.get(name);
}

Expand All @@ -103,6 +109,18 @@ private static ProtocolSchedule createSchedule(final GenesisConfigOptions option
.createProtocolSchedule();
}

private static TimestampSchedule createTimestampSchedule(final GenesisConfigOptions options) {
return new TimestampScheduleBuilder(
options,
CHAIN_ID,
ProtocolSpecAdapters.create(0, Function.identity()),
PrivacyParameters.DEFAULT,
false,
options.isQuorum(),
EvmConfiguration.DEFAULT)
.createTimestampSchedule();
}

public static boolean shouldClearEmptyAccounts(final String fork) {
return !SPECS_PRIOR_TO_DELETING_EMPTY_ACCOUNTS.contains(fork);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public class TransactionTest {
private static MainnetTransactionValidator transactionValidator(final String name) {
return REFERENCE_TEST_PROTOCOL_SCHEDULES
.getByName(name)
.getByBlockNumber(0)
.getByBlockHeader(BlockHeaderBuilder.createDefault().buildBlockHeader())
.getTransactionValidator();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import org.hyperledger.besu.ethereum.core.BlockImporter;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.mainnet.BlockImportResult;
import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
import org.hyperledger.besu.ethereum.referencetests.BlockchainReferenceTestCaseSpec;
import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedules;
Expand Down Expand Up @@ -103,7 +103,7 @@ public static void executeTest(final BlockchainReferenceTestCaseSpec spec) {
.get();
assertThat(worldState.rootHash()).isEqualTo(genesisBlockHeader.getStateRoot());

final ProtocolSchedule schedule =
final HeaderBasedProtocolSchedule schedule =
REFERENCE_TEST_PROTOCOL_SCHEDULES.getByName(spec.getNetwork());

final MutableBlockchain blockchain = spec.getBlockchain();
Expand All @@ -118,7 +118,7 @@ public static void executeTest(final BlockchainReferenceTestCaseSpec spec) {
try {
final Block block = candidateBlock.getBlock();

final ProtocolSpec protocolSpec = schedule.getByBlockNumber(block.getHeader().getNumber());
final ProtocolSpec protocolSpec = schedule.getByBlockHeader(block.getHeader());
final BlockImporter blockImporter = protocolSpec.getBlockImporter();
final HeaderValidationMode validationMode =
"NoProof".equalsIgnoreCase(spec.getSealEngine())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
Expand Down Expand Up @@ -50,7 +51,7 @@ public class GeneralStateReferenceTestTools {
private static MainnetTransactionProcessor transactionProcessor(final String name) {
return REFERENCE_TEST_PROTOCOL_SCHEDULES
.getByName(name)
.getByBlockNumber(0)
.getByBlockHeader(BlockHeaderBuilder.createDefault().buildBlockHeader())
.getTransactionProcessor();
}

Expand Down

0 comments on commit e129c9f

Please sign in to comment.