Skip to content

Commit

Permalink
Merge branch 'main' into bft-wait-for-sync
Browse files Browse the repository at this point in the history
  • Loading branch information
matthew1001 authored Sep 14, 2023
2 parents 99f750d + 4b2ef68 commit 00cf1ac
Show file tree
Hide file tree
Showing 105 changed files with 1,302 additions and 758 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 23.7.3
### Additions and Improvements
- Add access to an immutable world view to start/end transaction hooks in the tracing API[#5836](https://github.com/hyperledger/besu/pull/5836)

### Breaking Changes
- Removed support for Kotti network (ETC) [#5816](https://github.com/hyperledger/besu/pull/5816)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,12 @@ private List<TransactionProcessingResult> trace(
.map(parent -> calculateExcessBlobGasForParent(protocolSpec, parent))
.orElse(BlobGas.ZERO));

tracer.traceStartTransaction(transaction);

final WorldUpdater worldUpdater = chainUpdater.getNextUpdater();
tracer.traceStartTransaction(worldUpdater, transaction);
final TransactionProcessingResult result =
transactionProcessor.processTransaction(
blockchain,
chainUpdater.getNextUpdater(),
worldUpdater,
header,
transaction,
header.getCoinbase(),
Expand All @@ -188,7 +188,14 @@ private List<TransactionProcessingResult> trace(
blobGasPrice);

long transactionGasUsed = transaction.getGasLimit() - result.getGasRemaining();
tracer.traceEndTransaction(result.getOutput(), transactionGasUsed, 0);
tracer.traceEndTransaction(
worldUpdater,
transaction,
result.isSuccessful(),
result.getOutput(),
result.getLogs(),
transactionGasUsed,
0);

results.add(result);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,21 @@
import static org.assertj.core.api.Assertions.assertThat;

import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.worldstate.WorldView;
import org.hyperledger.besu.plugin.services.TraceService;
import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer;

import java.util.List;

import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -102,4 +109,103 @@ void shouldRetrieveStateUpdatePostTracingForAllBlocks() {
assertThat(worldStateArchive.getMutable().get(addressToVerify).getNonce())
.isEqualTo(persistedNonceForAccount);
}

@Test
void shouldReturnTheCorrectWorldViewForTxStartEnd() {
final TxStartEndTracer txStartEndTracer = new TxStartEndTracer();

// block contains 1 transaction
traceService.traceBlock(31, txStartEndTracer);

assertThat(txStartEndTracer.txStartWorldView).isNotNull();
assertThat(txStartEndTracer.txEndWorldView).isNotNull();

assertThat(txStartEndTracer.txStartTransaction.getNonce())
.isEqualTo(txStartEndTracer.txEndTransaction.getNonce())
.isEqualTo(30);
assertThat(txStartEndTracer.txStartTransaction.getGasLimit())
.isEqualTo(txStartEndTracer.txEndTransaction.getGasLimit())
.isEqualTo(314159);
assertThat(txStartEndTracer.txStartTransaction.getTo().get())
.isEqualTo(txStartEndTracer.txEndTransaction.getTo().get())
.isEqualTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"));
assertThat(txStartEndTracer.txStartTransaction.getValue())
.isEqualTo(txStartEndTracer.txEndTransaction.getValue())
.isEqualTo(
Wei.fromHexString(
"0x000000000000000000000000000000000000000000000000000000000000000a"));
assertThat(txStartEndTracer.txStartTransaction.getPayload())
.isEqualTo(txStartEndTracer.txEndTransaction.getPayload())
.isEqualTo(Bytes.fromHexString("0xfd408767"));

assertThat(txStartEndTracer.txEndStatus).isTrue();
assertThat(txStartEndTracer.txEndOutput).isEqualTo(Bytes.fromHexString("0x"));
assertThat(txStartEndTracer.txEndGasUsed).isEqualTo(24303);
assertThat(txStartEndTracer.txEndTimeNs).isNotNull();

assertThat(txStartEndTracer.txEndLogs).isNotEmpty();

final Log actualLog = txStartEndTracer.txEndLogs.get(0);
assertThat(actualLog.getLogger())
.isEqualTo(Address.fromHexString("0x6295ee1b4f6dd65047762f924ecd367c17eabf8f"));
assertThat(actualLog.getData())
.isEqualTo(
Bytes.fromHexString(
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe9000000000000000000000000000000000000000000000000000000000000002a"));
assertThat(actualLog.getTopics()).hasSize(4);
assertThat(actualLog.getTopics().get(0))
.isEqualTo(
Bytes.fromHexString(
"0xd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e"));
assertThat(actualLog.getTopics().get(1))
.isEqualTo(
Bytes.fromHexString(
"0x0000000000000000000000000000000000000000000000000000000000000001"));
assertThat(actualLog.getTopics().get(2))
.isEqualTo(
Bytes.fromHexString(
"0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"));
assertThat(actualLog.getTopics().get(3))
.isEqualTo(
Bytes.fromHexString(
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
}

private static class TxStartEndTracer implements BlockAwareOperationTracer {
public WorldView txStartWorldView;
public WorldView txEndWorldView;

public Transaction txStartTransaction;
public Transaction txEndTransaction;

public boolean txEndStatus;
public Bytes txEndOutput;
public List<Log> txEndLogs;
public long txEndGasUsed;
public Long txEndTimeNs;

@Override
public void traceStartTransaction(final WorldView worldView, final Transaction transaction) {
txStartWorldView = worldView;
txStartTransaction = transaction;
}

@Override
public void traceEndTransaction(
final WorldView worldView,
final Transaction transaction,
final boolean status,
final Bytes output,
final List<Log> logs,
final long gasUsed,
final long timeNs) {
txEndWorldView = worldView;
txEndTransaction = transaction;
txEndStatus = status;
txEndOutput = output;
txEndLogs = logs;
txEndGasUsed = gasUsed;
txEndTimeNs = timeNs;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
import org.hyperledger.besu.ethereum.mainnet.feemarket.BaseFeeMarket;
import org.hyperledger.besu.ethereum.mainnet.feemarket.ExcessBlobGasCalculator;
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
import org.hyperledger.besu.evm.account.EvmAccount;
import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException;
Expand Down Expand Up @@ -190,10 +190,10 @@ protected BlockCreationResult createBlock(

final List<BlockHeader> ommers = maybeOmmers.orElse(selectOmmers());

if (maybeParentBeaconBlockRoot.isPresent()) {
ParentBeaconBlockRootHelper.storeParentBeaconBlockRoot(
disposableWorldState.updater(), timestamp, maybeParentBeaconBlockRoot.get());
}
maybeParentBeaconBlockRoot.ifPresent(
bytes32 ->
ParentBeaconBlockRootHelper.storeParentBeaconBlockRoot(
disposableWorldState.updater(), timestamp, bytes32));

throwIfStopped();
final TransactionSelectionResults transactionResults =
Expand Down Expand Up @@ -466,9 +466,9 @@ boolean rewardBeneficiary(
.getBlockProcessor()
.getCoinbaseReward(blockReward, header.getNumber(), ommers.size());
final WorldUpdater updater = worldState.updater();
final EvmAccount beneficiary = updater.getOrCreate(miningBeneficiary);
final MutableAccount beneficiary = updater.getOrCreate(miningBeneficiary);

beneficiary.getMutable().incrementBalance(coinbaseReward);
beneficiary.incrementBalance(coinbaseReward);
for (final BlockHeader ommerHeader : ommers) {
if (ommerHeader.getNumber() - header.getNumber() > MAX_GENERATION) {
LOG.trace(
Expand All @@ -479,12 +479,12 @@ boolean rewardBeneficiary(
return false;
}

final EvmAccount ommerCoinbase = updater.getOrCreate(ommerHeader.getCoinbase());
final MutableAccount ommerCoinbase = updater.getOrCreate(ommerHeader.getCoinbase());
final Wei ommerReward =
protocolSpec
.getBlockProcessor()
.getOmmerReward(blockReward, header.getNumber(), ommerHeader.getNumber());
ommerCoinbase.getMutable().incrementBalance(ommerReward);
ommerCoinbase.incrementBalance(ommerReward);
}

updater.commit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class EntriesFromIntegrationTest {
public void shouldCollectStateEntries() {
final MutableWorldState worldState = createInMemoryWorldStateArchive().getMutable();
final WorldUpdater updater = worldState.updater();
MutableAccount account = updater.getOrCreate(Address.fromHexString("0x56")).getMutable();
MutableAccount account = updater.getOrCreate(Address.fromHexString("0x56"));
final Map<Bytes32, AccountStorageEntry> expectedValues = new TreeMap<>();
final int nodeCount = 100_000;
final Random random = new Random(42989428249L);
Expand All @@ -49,19 +49,19 @@ public void shouldCollectStateEntries() {
addExpectedValue(
account,
expectedValues,
UInt256.valueOf(Math.abs(random.nextLong())),
UInt256.valueOf(i * 10 + 1));
UInt256.valueOf(random.nextLong(Long.MAX_VALUE)),
UInt256.valueOf(i * 10 + 1L));
}
updater.commit();

// Add some changes on top that AbstractWorldUpdater.UpdateTrackingAccount will have to merge.
account = worldState.updater().getOrCreate(Address.fromHexString("0x56")).getMutable();
account = worldState.updater().getOrCreate(Address.fromHexString("0x56"));
for (int i = 0; i <= nodeCount; i++) {
addExpectedValue(
account,
expectedValues,
UInt256.valueOf(Math.abs(random.nextLong())),
UInt256.valueOf(i * 10 + 1));
UInt256.valueOf(random.nextLong(Long.MAX_VALUE)),
UInt256.valueOf(i * 10 + 1L));
}

final Map<Bytes32, AccountStorageEntry> values =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private MessageFrame createMessageFrame(final Address address) {
.blockHeader(blockHeader)
.blockchain(blockchain)
.build();
worldStateUpdater.getOrCreate(address).getMutable().setBalance(Wei.of(1));
worldStateUpdater.getOrCreate(address).setBalance(Wei.of(1));
worldStateUpdater.commit();

return benchmarkFrame;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
import org.hyperledger.besu.evm.ModificationNotAllowedException;
import org.hyperledger.besu.evm.account.AccountStorageEntry;
import org.hyperledger.besu.evm.account.EvmAccount;
import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.UpdateTrackingAccount;

Expand All @@ -41,9 +40,9 @@
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256;

public class BonsaiAccount implements MutableAccount, EvmAccount, AccountValue {
public class BonsaiAccount implements MutableAccount, AccountValue {
private final BonsaiWorldView context;
private final boolean mutable;
private boolean mutable;

private final Address address;
private final Hash addressHash;
Expand Down Expand Up @@ -163,7 +162,7 @@ public long getNonce() {
@Override
public void setNonce(final long value) {
if (!mutable) {
throw new UnsupportedOperationException("Account is immutable");
throw new ModificationNotAllowedException();
}
nonce = value;
}
Expand All @@ -176,7 +175,7 @@ public Wei getBalance() {
@Override
public void setBalance(final Wei value) {
if (!mutable) {
throw new UnsupportedOperationException("Account is immutable");
throw new ModificationNotAllowedException();
}
balance = value;
}
Expand All @@ -192,7 +191,7 @@ public Bytes getCode() {
@Override
public void setCode(final Bytes code) {
if (!mutable) {
throw new UnsupportedOperationException("Account is immutable");
throw new ModificationNotAllowedException();
}
this.code = code;
if (code == null || code.isEmpty()) {
Expand Down Expand Up @@ -220,7 +219,7 @@ public UInt256 getOriginalStorageValue(final UInt256 key) {
@Override
public NavigableMap<Bytes32, AccountStorageEntry> storageEntriesFrom(
final Bytes32 startKeyHash, final int limit) {
throw new RuntimeException("Bonsai Tries does not currently support enumerating storage");
return context.getWorldStateStorage().storageEntriesFrom(this.addressHash, startKeyHash, limit);
}

public Bytes serializeAccount() {
Expand All @@ -244,7 +243,7 @@ public void writeTo(final RLPOutput out) {
@Override
public void setStorageValue(final UInt256 key, final UInt256 value) {
if (!mutable) {
throw new UnsupportedOperationException("Account is immutable");
throw new ModificationNotAllowedException();
}
updatedStorage.put(key, value);
}
Expand All @@ -259,27 +258,23 @@ public Map<UInt256, UInt256> getUpdatedStorage() {
return updatedStorage;
}

@Override
public MutableAccount getMutable() throws ModificationNotAllowedException {
if (mutable) {
return this;
} else {
throw new ModificationNotAllowedException();
}
}

@Override
public Hash getStorageRoot() {
return storageRoot;
}

public void setStorageRoot(final Hash storageRoot) {
if (!mutable) {
throw new UnsupportedOperationException("Account is immutable");
throw new ModificationNotAllowedException();
}
this.storageRoot = storageRoot;
}

@Override
public void becomeImmutable() {
mutable = false;
}

@Override
public String toString() {
return "AccountState{"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ public BonsaiWorldStateProvider(
pluginContext);
this.blockchain = blockchain;
this.worldStateStorage = worldStateStorage;
this.persistedState = new BonsaiWorldState(this, worldStateStorage);
this.cachedMerkleTrieLoader = cachedMerkleTrieLoader;
this.persistedState = new BonsaiWorldState(this, worldStateStorage);
blockchain
.getBlockHeader(persistedState.getWorldStateBlockHash())
.ifPresent(
Expand Down
Loading

0 comments on commit 00cf1ac

Please sign in to comment.