Skip to content

Commit

Permalink
Fixed the initialization of the consensus of the node
Browse files Browse the repository at this point in the history
  • Loading branch information
spoto committed May 28, 2024
1 parent f8d1715 commit 833b946
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.hotmoka.node.disk.api.DiskNode;
import io.hotmoka.node.disk.api.DiskNodeConfig;
import io.hotmoka.node.local.AbstractLocalNode;
import io.hotmoka.node.local.api.StoreException;

/**
* An implementation of a node that stores transactions in a directory
Expand Down Expand Up @@ -59,7 +60,7 @@ public DiskNodeImpl(DiskNodeConfig config, ConsensusConfig<?,?> consensus) throw
super(Optional.of(consensus), config);

try {
initWithEmptyStore(consensus);
initWithEmptyStore();
this.mempool = new Mempool(this, config.getTransactionsPerBlock());
}
catch (NodeException e) {
Expand All @@ -76,8 +77,13 @@ public NodeInfo getNodeInfo() throws ClosedNodeException {
}

@Override
protected DiskStore mkStore(ExecutorService executors, ConsensusConfig<?,?> consensus, DiskNodeConfig config, Hasher<TransactionRequest<?>> hasher) {
return new DiskStore(executors, consensus, config, hasher);
protected DiskStore mkStore(ExecutorService executors, DiskNodeConfig config, Hasher<TransactionRequest<?>> hasher) throws NodeException {
try {
return new DiskStore(executors, config, hasher);
}
catch (StoreException e) {
throw new NodeException(e);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ class DiskStore extends AbstractStore<DiskStore, DiskStoreTransformation> {
* Creates an empty disk store for a node.
*
* @param executors the executors to use for running transactions
* @param consensus the consensus configuration of the node having the store
* @param config the local configuration of the node having the store
* @param hasher the hasher for computing the transaction reference from the requests
* @throws StoreException if the operation cannot be completed correctly
*/
DiskStore(ExecutorService executors, ConsensusConfig<?,?> consensus, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) {
super(executors, consensus, config, hasher);
DiskStore(ExecutorService executors, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) throws StoreException {
super(executors, config, hasher);

this.dir = config.getDir();
this.previousForRequests = Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@

import io.hotmoka.annotations.Immutable;
import io.hotmoka.crypto.api.Hasher;
import io.hotmoka.node.api.nodes.ConsensusConfig;
import io.hotmoka.node.api.requests.TransactionRequest;
import io.hotmoka.node.local.api.LocalNodeConfig;
import io.hotmoka.node.local.api.StoreException;
import io.hotmoka.node.local.internal.store.AbstractStoreImpl;

/**
Expand All @@ -39,12 +39,12 @@ public abstract class AbstractStore<S extends AbstractStore<S,T>, T extends Abst
* Creates an empty store.
*
* @param executors the executors to use for running transactions
* @param consensus the consensus configuration of the node having the store
* @param config the local configuration of the node having the store
* @param hasher the hasher for computing the transaction reference from the requests
* @throws StoreException if the operation cannot be completed correctly
*/
protected AbstractStore(ExecutorService executors, ConsensusConfig<?,?> consensus, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) {
super(executors, consensus, config, hasher);
protected AbstractStore(ExecutorService executors, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) throws StoreException {
super(executors, config, hasher);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2021 Fausto Spoto
Copyright 2024 Fausto Spoto
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -20,9 +20,9 @@

import io.hotmoka.annotations.Immutable;
import io.hotmoka.crypto.api.Hasher;
import io.hotmoka.node.api.nodes.ConsensusConfig;
import io.hotmoka.node.api.requests.TransactionRequest;
import io.hotmoka.node.local.api.LocalNodeConfig;
import io.hotmoka.node.local.api.StoreException;
import io.hotmoka.node.local.internal.store.trie.AbstractTrieBasedStoreImpl;
import io.hotmoka.xodus.env.Environment;

Expand All @@ -42,12 +42,12 @@ public abstract class AbstractTrieBasedStore<S extends AbstractTrieBasedStore<S,
*
* @param env the Xodus environment to use for storing the tries
* @param executors the executors to use for running transactions
* @param consensus the consensus configuration of the node having the store
* @param config the local configuration of the node having the store
* @param hasher the hasher for computing the transaction reference from the requests
* @throws StoreException if the operation cannot be completed correctly
*/
protected AbstractTrieBasedStore(Environment env, ExecutorService executors, ConsensusConfig<?,?> consensus, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) {
super(env, executors, consensus, config, hasher);
protected AbstractTrieBasedStore(Environment env, ExecutorService executors, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) throws StoreException {
super(env, executors, config, hasher);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package io.hotmoka.node.local.internal;

import java.security.NoSuchAlgorithmException;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
Expand All @@ -25,7 +24,6 @@

import io.hotmoka.annotations.ThreadSafe;
import io.hotmoka.crypto.Hex;
import io.hotmoka.node.ValidatorsConsensusConfigBuilders;
import io.hotmoka.node.api.NodeException;
import io.hotmoka.node.api.nodes.ConsensusConfig;
import io.hotmoka.node.local.AbstractLocalNode;
Expand Down Expand Up @@ -103,12 +101,7 @@ protected final Environment getEnvironment() {
@Override
protected void initWithSavedStore() throws NodeException {
// we start from the empty store
try {
super.initWithEmptyStore(ValidatorsConsensusConfigBuilders.defaults().build());
}
catch (NoSuchAlgorithmException e) {
throw new NodeException(e);
}
super.initWithEmptyStore();

// then we check it out at its store branch
var root = env.computeInTransaction(txn -> Optional.ofNullable(storeOfNode.get(txn, ROOT)).map(ByteIterable::getBytes));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,11 @@ public final MethodFuture postStaticMethodCallTransaction(StaticMethodCallTransa
/**
* Initializes the node with an empty store.
*
* @param consensus the initial consensus of the node
* @throws NodeException if the operation cannot be completed correctly
*/
protected void initWithEmptyStore(ConsensusConfig<?,?> consensus) throws NodeException {
protected void initWithEmptyStore() throws NodeException {
// the node is starting from scratch: the caches are left empty and the consensus is well-known
this.store = mkStore(executors, consensus, config, hasher);
this.store = mkStore(executors, config, hasher);
}

/**
Expand Down Expand Up @@ -527,7 +526,7 @@ protected void closeResources() throws NodeException, InterruptedException {
*
* @return the store
*/
protected abstract S mkStore(ExecutorService executors, ConsensusConfig<?,?> config, C localConfig, Hasher<TransactionRequest<?>> hasher) throws NodeException;
protected abstract S mkStore(ExecutorService executors, C localConfig, Hasher<TransactionRequest<?>> hasher) throws NodeException;

/**
* Node-specific implementation to post the given request. Each node should implement this,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
package io.hotmoka.node.local.internal;

import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.function.Function;

import io.hotmoka.node.ValidatorsConsensusConfigBuilders;
import io.hotmoka.node.api.nodes.ConsensusConfig;
import io.hotmoka.node.api.transactions.TransactionReference;
import io.hotmoka.node.api.values.StorageReference;
import io.hotmoka.node.local.StoreCache;
import io.hotmoka.node.local.api.EngineClassLoader;
import io.hotmoka.node.local.api.StoreException;

/**
*
Expand Down Expand Up @@ -69,8 +72,19 @@ public class StoreCacheImpl implements StoreCache {
*/
private final LRUCache<TransactionReference, Boolean> checkedSignatures;

public StoreCacheImpl(ConsensusConfig<?,?> consensus) {
this.consensus = consensus;
/**
* Creates empty caches.
*
* @throws StoreException if the operation cannot be completed correctly
*/
public StoreCacheImpl() throws StoreException {
try {
this.consensus = ValidatorsConsensusConfigBuilders.defaults().build();
}
catch (NoSuchAlgorithmException e) {
throw new StoreException(e);
}

this.gasPrice = Optional.empty();
this.inflation = OptionalLong.empty();
this.validators = Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@ public abstract class AbstractStoreImpl<S extends AbstractStoreImpl<S,T>, T exte
* Creates an empty store.
*
* @param executors the executors to use for running transactions
* @param consensus the consensus configuration of the node having the store
* @param config the local configuration of the node having the store
* @param hasher the hasher for computing the transaction reference from the requests
* @throws StoreException if the operation cannot be completed correctly
*/
protected AbstractStoreImpl(ExecutorService executors, ConsensusConfig<?,?> consensus, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) {
protected AbstractStoreImpl(ExecutorService executors, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) throws StoreException {
super(executors);

this.hasher = hasher;
this.cache = new StoreCacheImpl(consensus);
this.cache = new StoreCacheImpl();
this.maxGasPerView = config.getMaxGasPerViewTransaction();
this.consensusForViews = consensus.toBuilder().setMaxGasPerTransaction(maxGasPerView).build();
this.consensusForViews = cache.getConfig().toBuilder().setMaxGasPerTransaction(maxGasPerView).build();
}

/**
Expand Down Expand Up @@ -126,20 +126,28 @@ public final void checkTransaction(TransactionRequest<?> request) throws Transac
}

/**
* Yields a clone of this store, but for its caches that are initialized with information extracted from this store.
* Yields a clone of this store, but for its cache, that is initialized with information extracted from this store.
*
* @return the resulting store
* @throws StoreException if the operation cannot be completed correctly
*/
public final S initCaches() throws StoreException {
var newCache = cache
.setConfig(extractConsensus())
.invalidateClassLoaders()
.setValidators(extractValidators())
.setGasStation(extractGasStation())
.setVersions(extractVersions())
.setGasPrice(extractGasPrice())
.setInflation(extractInflation());
protected final S reloadCache() throws StoreException {
StoreCache newCache = cache;

// if this store is already initialized, we can extract the cache information
// from the store itself, otherwise the default information will be kept
if (getManifest().isPresent()) {
newCache = newCache
.setConfig(extractConsensus())
.invalidateClassLoaders()
.setValidators(extractValidators())
.setGasStation(extractGasStation())
.setVersions(extractVersions())
.setGasPrice(extractGasPrice())
.setInflation(extractInflation());

LOGGER.info("the store's cache has been reloaded");
}

return setCache(newCache);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package io.hotmoka.node.local.internal.store.trie;

import java.security.NoSuchAlgorithmException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
Expand All @@ -29,9 +28,7 @@
import io.hotmoka.exceptions.CheckSupplier;
import io.hotmoka.exceptions.UncheckConsumer;
import io.hotmoka.exceptions.UncheckFunction;
import io.hotmoka.node.ValidatorsConsensusConfigBuilders;
import io.hotmoka.node.api.UnknownReferenceException;
import io.hotmoka.node.api.nodes.ConsensusConfig;
import io.hotmoka.node.api.requests.TransactionRequest;
import io.hotmoka.node.api.responses.TransactionResponse;
import io.hotmoka.node.api.transactions.TransactionReference;
Expand Down Expand Up @@ -110,12 +107,12 @@ public abstract class AbstractTrieBasedStoreImpl<S extends AbstractTrieBasedStor
*
* @param env the Xodus environment to use for creating the tries
* @param executors the executors to use for running transactions
* @param consensus the consensus configuration of the node having the store
* @param config the local configuration of the node having the store
* @param hasher the hasher for computing the transaction reference from the requests
* @throws StoreException if the operation cannot be completed correctly
*/
protected AbstractTrieBasedStoreImpl(Environment env, ExecutorService executors, ConsensusConfig<?,?> consensus, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) {
super(executors, consensus, config, hasher);
protected AbstractTrieBasedStoreImpl(Environment env, ExecutorService executors, LocalNodeConfig<?,?> config, Hasher<TransactionRequest<?>> hasher) throws StoreException {
super(executors, config, hasher);

this.env = env;
this.storeOfResponses = env.computeInTransaction(txn -> env.openStoreWithoutDuplicates("responses", txn));
Expand Down Expand Up @@ -287,13 +284,8 @@ public final S checkoutAt(byte[] stateId) throws StoreException {
var rootOfHistories = new byte[32];
System.arraycopy(stateId, 96, rootOfHistories, 0, 32);

try {
return make(new StoreCacheImpl(ValidatorsConsensusConfigBuilders.defaults().build()), rootOfResponses, rootOfInfo, rootOfHistories, rootOfRequests)
.initCaches();
}
catch (NoSuchAlgorithmException e) {
throw new StoreException(e);
}
// we provide an empty cache and then ask to reload it from the state of the resulting store
return make(new StoreCacheImpl(), rootOfResponses, rootOfInfo, rootOfHistories, rootOfRequests).reloadCache();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public TendermintNodeImpl(TendermintNodeConfig config, Optional<ConsensusConfig<

try {
if (consensus.isPresent()) {
initWithEmptyStore(consensus.get());
initWithEmptyStore();
initWorkingDirectoryOfTendermintProcess(config);
}
else
Expand Down Expand Up @@ -157,9 +157,9 @@ protected void closeResources() throws NodeException, InterruptedException {
}

@Override
protected TendermintStore mkStore(ExecutorService executors, ConsensusConfig<?,?> consensus, TendermintNodeConfig config, Hasher<TransactionRequest<?>> hasher) throws NodeException {
protected TendermintStore mkStore(ExecutorService executors, TendermintNodeConfig config, Hasher<TransactionRequest<?>> hasher) throws NodeException {
try {
return new TendermintStore(getEnvironment(), executors, consensus, config, hasher);
return new TendermintStore(getEnvironment(), executors, config, hasher);
}
catch (StoreException e) {
throw new NodeException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,11 @@ public class TendermintStore extends AbstractTrieBasedStore<TendermintStore, Ten
*
* @param env the Xodus environment to use for storing the tries
* @param executors the executors to use for running transactions
* @param consensus the consensus configuration of the node having the store
* @param config the local configuration of the node having the store
* @param hasher the hasher for computing the transaction reference from the requests
*/
TendermintStore(Environment env, ExecutorService executors, ConsensusConfig<?,?> consensus, TendermintNodeConfig config, Hasher<TransactionRequest<?>> hasher) throws StoreException {
super(env, executors, consensus, config, hasher);
TendermintStore(Environment env, ExecutorService executors, TendermintNodeConfig config, Hasher<TransactionRequest<?>> hasher) throws StoreException {
super(env, executors, config, hasher);

try {
this.hasherOfHashes = HashingAlgorithms.sha256().getHasher(Function.identity());
Expand Down

0 comments on commit 833b946

Please sign in to comment.