Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T8n support for isStateTest and empty accounts #7275

Merged
merged 2 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.trie.diffbased.common.DiffBasedAccount;
import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.log.Log;
Expand Down Expand Up @@ -265,9 +266,11 @@ static T8nResult runTest(
.blobGasPricePerGas(calculateExcessBlobGasForParent(protocolSpec, blockHeader));
long blobGasLimit = protocolSpec.getGasLimitCalculator().currentBlobGasLimit();

protocolSpec
.getBlockHashProcessor()
.processBlockHashes(blockchain, worldState, referenceTestEnv);
if (!referenceTestEnv.isStateTest()) {
protocolSpec
.getBlockHashProcessor()
.processBlockHashes(blockchain, worldState, referenceTestEnv);
}

final WorldUpdater rootWorldStateUpdater = worldState.updater();
List<TransactionReceipt> receipts = new ArrayList<>();
Expand Down Expand Up @@ -318,13 +321,12 @@ static T8nResult runTest(
timer.stop();

if (shouldClearEmptyAccounts(fork)) {
final Account coinbase = worldStateUpdater.getOrCreate(blockHeader.getCoinbase());
if (coinbase != null && coinbase.isEmpty()) {
worldStateUpdater.deleteAccount(coinbase.getAddress());
}
final Account txSender = worldStateUpdater.getAccount(transaction.getSender());
if (txSender != null && txSender.isEmpty()) {
worldStateUpdater.deleteAccount(txSender.getAddress());
var entries = new ArrayList<>(worldState.getAccumulator().getAccountsToUpdate().entrySet());
for (var entry : entries) {
DiffBasedAccount updated = entry.getValue().getUpdated();
if (updated != null && updated.isEmpty()) {
worldState.getAccumulator().deleteAccount(entry.getKey());
}
}
}
if (result.isInvalid()) {
Expand Down Expand Up @@ -397,7 +399,9 @@ static T8nResult runTest(

// block reward
// The max production reward was 5 Eth, longs can hold over 18 Eth.
if (!validTransactions.isEmpty() && (rewardString == null || Long.decode(rewardString) > 0)) {
if (!referenceTestEnv.isStateTest()
&& !validTransactions.isEmpty()
&& (rewardString == null || Long.decode(rewardString) > 0)) {
Wei reward =
(rewardString == null)
? protocolSpec.getBlockReward()
Expand All @@ -408,15 +412,24 @@ static T8nResult runTest(
}

rootWorldStateUpdater.commit();
// Invoke the withdrawal processor to handle CL withdrawals.
if (!referenceTestEnv.getWithdrawals().isEmpty()) {
try {
protocolSpec
.getWithdrawalsProcessor()
.ifPresent(
p -> p.processWithdrawals(referenceTestEnv.getWithdrawals(), worldState.updater()));
} catch (RuntimeException re) {
resultObject.put("exception", re.getMessage());

if (referenceTestEnv.isStateTest()) {
if (!referenceTestEnv.getWithdrawals().isEmpty()) {
resultObject.put("exception", "withdrawals are not supported in state tests");
}
} else {
// Invoke the withdrawal processor to handle CL withdrawals.
if (!referenceTestEnv.getWithdrawals().isEmpty()) {
try {
protocolSpec
.getWithdrawalsProcessor()
.ifPresent(
p ->
p.processWithdrawals(
referenceTestEnv.getWithdrawals(), worldState.updater()));
} catch (RuntimeException re) {
resultObject.put("exception", re.getMessage());
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ public CandidateBlock(
@JsonProperty("uncleHeaders") final Object uncleHeaders,
@JsonProperty("withdrawals") final Object withdrawals,
@JsonProperty("depositRequests") final Object depositRequests,
@JsonProperty("withdrawalRequests") final Object withdrawalRequests) {
@JsonProperty("withdrawalRequests") final Object withdrawalRequests,
@JsonProperty("consolidationRequests") final Object consolidationRequests) {
boolean blockVaid = true;
// The BLOCK__WrongCharAtRLP_0 test has an invalid character in its rlp string.
Bytes rlpAttempt = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ Withdrawal asWithdrawal() {

private final Bytes32 beaconRoot;

private final boolean isStateTest;

/**
* Public constructor.
*
Expand Down Expand Up @@ -120,7 +122,8 @@ public ReferenceTestEnv(
@JsonProperty("parentGasLimit") final String parentGasLimit,
@JsonProperty("parentGasUsed") final String parentGasUsed,
@JsonProperty("parentTimestamp") final String parentTimestamp,
@JsonProperty("parentUncleHash") final String _parentUncleHash) {
@JsonProperty("parentUncleHash") final String _parentUncleHash,
@JsonProperty("isStateTest") final String isStateTest) {
super(
generateTestBlockHash(previousHash, number),
Hash.EMPTY_LIST_HASH, // ommersHash
Expand Down Expand Up @@ -164,10 +167,16 @@ public ReferenceTestEnv(
Map.entry(
Long.decode(entry.getKey()), Hash.fromHexString(entry.getValue())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
this.beaconRoot =
beaconRoot == null
? (currentBeaconRoot == null ? null : Hash.fromHexString(currentBeaconRoot))
: Hash.fromHexString(beaconRoot);
if (beaconRoot == null) {
if (currentBeaconRoot == null) {
this.beaconRoot = null;
} else {
this.beaconRoot = Hash.fromHexString(currentBeaconRoot);
}
} else {
this.beaconRoot = Hash.fromHexString(beaconRoot);
}
this.isStateTest = Boolean.parseBoolean(isStateTest);
}

@Override
Expand Down Expand Up @@ -239,6 +248,10 @@ public Map<Long, Hash> getBlockHashes() {
return blockHashes;
}

public boolean isStateTest() {
return isStateTest;
}

@Override
public boolean equals(final Object o) {
if (this == o) return true;
Expand Down
Loading