Skip to content

Commit

Permalink
T8n support for isStateTest and empty accounts (hyperledger#7275)
Browse files Browse the repository at this point in the history
Update t8n executor to support new isStateTest env flag that will
disable extra-transactional processing such as block rewards and beacon
root.
Also, make sure such extra-transactional commits don't create empty
accounts.

Signed-off-by: Danno Ferrin <danno@numisight.com>
Co-authored-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
  • Loading branch information
2 people authored and daniellehrner committed Jul 16, 2024
1 parent defa218 commit 4019bb6
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 26 deletions.
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

0 comments on commit 4019bb6

Please sign in to comment.