Skip to content

Commit

Permalink
update genesis root hash generation logic
Browse files Browse the repository at this point in the history
Signed-off-by: Karim Taam <karim.t2am@gmail.com>
  • Loading branch information
matkt committed Dec 18, 2023
1 parent 6bad380 commit 068d300
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 206 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,9 @@ public BesuController build() {
prepForBuild();

final ProtocolSchedule protocolSchedule = createProtocolSchedule();
final GenesisState genesisState = GenesisState.fromConfig(dataStorageConfiguration.getDataStorageFormat(), genesisConfig, protocolSchedule);
final GenesisState genesisState =
GenesisState.fromConfig(
dataStorageConfiguration.getDataStorageFormat(), genesisConfig, protocolSchedule);

final VariablesStorage variablesStorage = storageProvider.createVariablesStorage();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,10 @@
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.WorldStatePreimageKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.cache.CachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.bonsai.cache.CachedWorldStorageManager;
import org.hyperledger.besu.ethereum.trie.bonsai.cache.NoOpCachedWorldStorageManager;
import org.hyperledger.besu.ethereum.trie.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogAddedEvent;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogManager;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogPruner;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.NoOpTrieLogManager;
import org.hyperledger.besu.ethereum.trie.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.bonsai.worldview.BonsaiWorldStateUpdateAccumulator;
import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.forest.worldview.ForestMutableWorldState;
import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat;
Expand All @@ -50,8 +47,8 @@
import org.hyperledger.besu.evm.log.LogsBloomFilter;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.trielogs.TrieLog;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
import org.hyperledger.besu.services.kvstore.SegmentedInMemoryKeyValueStorage;

import java.math.BigInteger;
import java.util.HashMap;
Expand All @@ -67,7 +64,6 @@
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt256;
import org.hyperledger.besu.services.kvstore.SegmentedInMemoryKeyValueStorage;

public final class GenesisState {

Expand All @@ -90,6 +86,21 @@ public static GenesisState fromJson(final String json, final ProtocolSchedule pr
return fromConfig(GenesisConfigFile.fromConfig(json), protocolSchedule);
}

/**
* Construct a {@link GenesisState} from a JSON string.
*
* @param dataStorageFormat A {@link DataStorageFormat} describing the storage format to use
* @param json A JSON string describing the genesis block
* @param protocolSchedule A protocol Schedule associated with
* @return A new {@link GenesisState}.
*/
public static GenesisState fromJson(
final DataStorageFormat dataStorageFormat,
final String json,
final ProtocolSchedule protocolSchedule) {
return fromConfig(dataStorageFormat, GenesisConfigFile.fromConfig(json), protocolSchedule);
}

/**
* Construct a {@link GenesisState} from a JSON object.
*
Expand All @@ -105,18 +116,23 @@ public static GenesisState fromConfig(
/**
* Construct a {@link GenesisState} from a JSON object.
*
* @param dataStorageFormat A {@link DataStorageFormat} describing the storage format to use
* @param dataStorageFormat A {@link DataStorageFormat} describing the storage format to use
* @param config A {@link GenesisConfigFile} describing the genesis block.
* @param protocolSchedule A protocol Schedule associated with
* @return A new {@link GenesisState}.
*/
public static GenesisState fromConfig(
final DataStorageFormat dataStorageFormat, final GenesisConfigFile config, final ProtocolSchedule protocolSchedule) {
final DataStorageFormat dataStorageFormat,
final GenesisConfigFile config,
final ProtocolSchedule protocolSchedule) {
final List<GenesisAccount> genesisAccounts = parseAllocations(config).toList();
final Block block =
new Block(
buildHeader(config, calculateGenesisStateHash(dataStorageFormat, genesisAccounts), protocolSchedule),
buildBody(config));
new Block(
buildHeader(
config,
calculateGenesisStateHash(dataStorageFormat, genesisAccounts),
protocolSchedule),
buildBody(config));
return new GenesisState(block, genesisAccounts);
}

Expand Down Expand Up @@ -159,103 +175,42 @@ private static void writeAccountsTo(
target.persist(rootHeader);
}

private static Hash calculateGenesisStateHash(final DataStorageFormat dataStorageFormat, final List<GenesisAccount> genesisAccounts) {
final MutableWorldState worldState;
if(dataStorageFormat.equals(DataStorageFormat.BONSAI)){
final CachedMerkleTrieLoader cachedMerkleTrieLoader =
new CachedMerkleTrieLoader(new NoOpMetricsSystem());
BonsaiWorldStateKeyValueStorage bonsaiWorldStateKeyValueStorage = new BonsaiWorldStateKeyValueStorage(
new KeyValueStorageProvider(segmentIdentifiers -> new SegmentedInMemoryKeyValueStorage(), new InMemoryKeyValueStorage(), new NoOpMetricsSystem()), new NoOpMetricsSystem());
worldState = new BonsaiWorldState(bonsaiWorldStateKeyValueStorage, cachedMerkleTrieLoader, new NoOpCachedWorldStorageManager(bonsaiWorldStateKeyValueStorage), new NoOpTrieLogManager(), EvmConfiguration.DEFAULT);
System.out.println("iici");
} else {
final ForestWorldStateKeyValueStorage stateStorage =
new ForestWorldStateKeyValueStorage(new InMemoryKeyValueStorage());
final WorldStatePreimageKeyValueStorage preimageStorage =
new WorldStatePreimageKeyValueStorage(new InMemoryKeyValueStorage());
worldState =
new ForestMutableWorldState(stateStorage, preimageStorage, EvmConfiguration.DEFAULT);
}
private static Hash calculateGenesisStateHash(
final DataStorageFormat dataStorageFormat, final List<GenesisAccount> genesisAccounts) {
final MutableWorldState worldState = loadWorldState(dataStorageFormat);
writeAccountsTo(worldState, genesisAccounts, null);
System.out.println("iici"+worldState.rootHash());
return worldState.rootHash();
}


static class NoOpCachedWorldStorageManager extends CachedWorldStorageManager {

public NoOpCachedWorldStorageManager(final BonsaiWorldStateKeyValueStorage bonsaiWorldStateKeyValueStorage) {
super(
null,
bonsaiWorldStateKeyValueStorage,
new NoOpMetricsSystem());
}

@Override
public synchronized void addCachedLayer(
final BlockHeader blockHeader,
final Hash worldStateRootHash,
final BonsaiWorldState forWorldState) {
// reference test world states are not cached
}

@Override
public boolean containWorldStateStorage(final Hash blockHash) {
return false;
}

@Override
public Optional<BonsaiWorldState> getWorldState(final Hash blockHash) {
return Optional.empty();
}

@Override
public Optional<BonsaiWorldState> getNearestWorldState(final BlockHeader blockHeader) {
return Optional.empty();
}

@Override
public Optional<BonsaiWorldState> getHeadWorldState(
final Function<Hash, Optional<BlockHeader>> hashBlockHeaderFunction) {
return Optional.empty();
}

@Override
public void reset() {
// reference test world states are not re-used
}
}

static class NoOpTrieLogManager extends TrieLogManager {

public NoOpTrieLogManager() {
super(null, null, 0, null, TrieLogPruner.noOpTrieLogPruner());
}

@SuppressWarnings({"UnsynchronizedOverridesSynchronized", "squid:S3551"})
@Override
public void saveTrieLog(
final BonsaiWorldStateUpdateAccumulator localUpdater,
final Hash forWorldStateRootHash,
final BlockHeader forBlockHeader,
final BonsaiWorldState forWorldState) {
// notify trie log added observers, synchronously
TrieLog trieLog = trieLogFactory.create(localUpdater, forBlockHeader);
trieLogObservers.forEach(o -> o.onTrieLogAdded(new TrieLogAddedEvent(trieLog)));
}

@Override
public long getMaxLayersToLoad() {
return 0;
}

@Override
public Optional<TrieLog> getTrieLogLayer(final Hash blockHash) {
return Optional.empty();
private static MutableWorldState loadWorldState(final DataStorageFormat dataStorageFormat) {
switch (dataStorageFormat) {
case BONSAI -> {
final CachedMerkleTrieLoader cachedMerkleTrieLoader =
new CachedMerkleTrieLoader(new NoOpMetricsSystem());
final BonsaiWorldStateKeyValueStorage bonsaiWorldStateKeyValueStorage =
new BonsaiWorldStateKeyValueStorage(
new KeyValueStorageProvider(
segmentIdentifiers -> new SegmentedInMemoryKeyValueStorage(),
new InMemoryKeyValueStorage(),
new NoOpMetricsSystem()),
new NoOpMetricsSystem());
return new BonsaiWorldState(
bonsaiWorldStateKeyValueStorage,
cachedMerkleTrieLoader,
new NoOpCachedWorldStorageManager(bonsaiWorldStateKeyValueStorage),
new NoOpTrieLogManager(),
EvmConfiguration.DEFAULT);
}
default -> {
final ForestWorldStateKeyValueStorage stateStorage =
new ForestWorldStateKeyValueStorage(new InMemoryKeyValueStorage());
final WorldStatePreimageKeyValueStorage preimageStorage =
new WorldStatePreimageKeyValueStorage(new InMemoryKeyValueStorage());
return new ForestMutableWorldState(stateStorage, preimageStorage, EvmConfiguration.DEFAULT);
}
}
}


private static BlockHeader buildHeader(
final GenesisConfigFile genesis,
final Hash genesisRootHash,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.trie.bonsai.cache;

import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.trie.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;

import java.util.Optional;
import java.util.function.Function;

public class NoOpCachedWorldStorageManager extends CachedWorldStorageManager {

public NoOpCachedWorldStorageManager(
final BonsaiWorldStateKeyValueStorage bonsaiWorldStateKeyValueStorage) {
super(null, bonsaiWorldStateKeyValueStorage, new NoOpMetricsSystem());
}

@Override
public synchronized void addCachedLayer(
final BlockHeader blockHeader,
final Hash worldStateRootHash,
final BonsaiWorldState forWorldState) {
// no cache
}

@Override
public boolean containWorldStateStorage(final Hash blockHash) {
return false;
}

@Override
public Optional<BonsaiWorldState> getWorldState(final Hash blockHash) {
return Optional.empty();
}

@Override
public Optional<BonsaiWorldState> getNearestWorldState(final BlockHeader blockHeader) {
return Optional.empty();
}

@Override
public Optional<BonsaiWorldState> getHeadWorldState(
final Function<Hash, Optional<BlockHeader>> hashBlockHeaderFunction) {
return Optional.empty();
}

@Override
public void reset() {
// world states are not re-used
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.trie.bonsai.trielog;

import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.trie.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.bonsai.worldview.BonsaiWorldStateUpdateAccumulator;
import org.hyperledger.besu.plugin.services.trielogs.TrieLog;

import java.util.Optional;

public class NoOpTrieLogManager extends TrieLogManager {

public NoOpTrieLogManager() {
super(null, null, 0, null, TrieLogPruner.noOpTrieLogPruner());
}

@SuppressWarnings({"UnsynchronizedOverridesSynchronized", "squid:S3551"})
@Override
public void saveTrieLog(
final BonsaiWorldStateUpdateAccumulator localUpdater,
final Hash forWorldStateRootHash,
final BlockHeader forBlockHeader,
final BonsaiWorldState forWorldState) {
// notify trie log added observers, synchronously
TrieLog trieLog = trieLogFactory.create(localUpdater, forBlockHeader);
trieLogObservers.forEach(o -> o.onTrieLogAdded(new TrieLogAddedEvent(trieLog)));
}

@Override
public long getMaxLayersToLoad() {
return 0;
}

@Override
public Optional<TrieLog> getTrieLogLayer(final Hash blockHash) {
return Optional.empty();
}
}
Loading

0 comments on commit 068d300

Please sign in to comment.