From 833b9461a82f50ed511e956ed94c5eb356484f90 Mon Sep 17 00:00:00 2001 From: Fausto Spoto Date: Tue, 28 May 2024 13:05:23 +0200 Subject: [PATCH] Fixed the initialization of the consensus of the node --- .../node/disk/internal/DiskNodeImpl.java | 12 +++++-- .../hotmoka/node/disk/internal/DiskStore.java | 6 ++-- .../io/hotmoka/node/local/AbstractStore.java | 8 ++--- .../node/local/AbstractTrieBasedStore.java | 10 +++--- .../AbstractCheckableLocalNodeImpl.java | 9 +---- .../local/internal/AbstractLocalNodeImpl.java | 7 ++-- .../node/local/internal/StoreCacheImpl.java | 18 ++++++++-- .../internal/store/AbstractStoreImpl.java | 36 +++++++++++-------- .../trie/AbstractTrieBasedStoreImpl.java | 18 +++------- .../internal/TendermintNodeImpl.java | 6 ++-- .../tendermint/internal/TendermintStore.java | 5 ++- 11 files changed, 73 insertions(+), 62 deletions(-) diff --git a/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskNodeImpl.java b/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskNodeImpl.java index a62f18fea..66f9a7f49 100644 --- a/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskNodeImpl.java +++ b/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskNodeImpl.java @@ -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 @@ -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) { @@ -76,8 +77,13 @@ public NodeInfo getNodeInfo() throws ClosedNodeException { } @Override - protected DiskStore mkStore(ExecutorService executors, ConsensusConfig consensus, DiskNodeConfig config, Hasher> hasher) { - return new DiskStore(executors, consensus, config, hasher); + protected DiskStore mkStore(ExecutorService executors, DiskNodeConfig config, Hasher> hasher) throws NodeException { + try { + return new DiskStore(executors, config, hasher); + } + catch (StoreException e) { + throw new NodeException(e); + } } @Override diff --git a/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskStore.java b/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskStore.java index 7d04fe96b..5fa17da26 100644 --- a/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskStore.java +++ b/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskStore.java @@ -101,12 +101,12 @@ class DiskStore extends AbstractStore { * 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> hasher) { - super(executors, consensus, config, hasher); + DiskStore(ExecutorService executors, LocalNodeConfig config, Hasher> hasher) throws StoreException { + super(executors, config, hasher); this.dir = config.getDir(); this.previousForRequests = Optional.empty(); diff --git a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/AbstractStore.java b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/AbstractStore.java index 800c3e478..168e2d231 100644 --- a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/AbstractStore.java +++ b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/AbstractStore.java @@ -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; /** @@ -39,12 +39,12 @@ public abstract class AbstractStore, 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> hasher) { - super(executors, consensus, config, hasher); + protected AbstractStore(ExecutorService executors, LocalNodeConfig config, Hasher> hasher) throws StoreException { + super(executors, config, hasher); } /** diff --git a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/AbstractTrieBasedStore.java b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/AbstractTrieBasedStore.java index 6b7503767..d38615a82 100644 --- a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/AbstractTrieBasedStore.java +++ b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/AbstractTrieBasedStore.java @@ -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. @@ -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; @@ -42,12 +42,12 @@ public abstract class AbstractTrieBasedStore consensus, LocalNodeConfig config, Hasher> hasher) { - super(env, executors, consensus, config, hasher); + protected AbstractTrieBasedStore(Environment env, ExecutorService executors, LocalNodeConfig config, Hasher> hasher) throws StoreException { + super(env, executors, config, hasher); } /** diff --git a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/AbstractCheckableLocalNodeImpl.java b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/AbstractCheckableLocalNodeImpl.java index 32d28c125..7ae7e9602 100644 --- a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/AbstractCheckableLocalNodeImpl.java +++ b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/AbstractCheckableLocalNodeImpl.java @@ -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; @@ -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; @@ -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)); diff --git a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/AbstractLocalNodeImpl.java b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/AbstractLocalNodeImpl.java index adb222ea9..ab19db357 100644 --- a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/AbstractLocalNodeImpl.java +++ b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/AbstractLocalNodeImpl.java @@ -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); } /** @@ -527,7 +526,7 @@ protected void closeResources() throws NodeException, InterruptedException { * * @return the store */ - protected abstract S mkStore(ExecutorService executors, ConsensusConfig config, C localConfig, Hasher> hasher) throws NodeException; + protected abstract S mkStore(ExecutorService executors, C localConfig, Hasher> hasher) throws NodeException; /** * Node-specific implementation to post the given request. Each node should implement this, diff --git a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/StoreCacheImpl.java b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/StoreCacheImpl.java index 2a1f593fc..2a99f9bd7 100644 --- a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/StoreCacheImpl.java +++ b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/StoreCacheImpl.java @@ -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; /** * @@ -69,8 +72,19 @@ public class StoreCacheImpl implements StoreCache { */ private final LRUCache 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(); diff --git a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/store/AbstractStoreImpl.java b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/store/AbstractStoreImpl.java index a5a1290e6..2407c42eb 100644 --- a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/store/AbstractStoreImpl.java +++ b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/store/AbstractStoreImpl.java @@ -68,17 +68,17 @@ public abstract class AbstractStoreImpl, 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> hasher) { + protected AbstractStoreImpl(ExecutorService executors, LocalNodeConfig config, Hasher> 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(); } /** @@ -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); } diff --git a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/store/trie/AbstractTrieBasedStoreImpl.java b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/store/trie/AbstractTrieBasedStoreImpl.java index 3752352bb..bba2137a0 100644 --- a/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/store/trie/AbstractTrieBasedStoreImpl.java +++ b/io-hotmoka-node-local/src/main/java/io/hotmoka/node/local/internal/store/trie/AbstractTrieBasedStoreImpl.java @@ -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; @@ -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; @@ -110,12 +107,12 @@ public abstract class AbstractTrieBasedStoreImpl consensus, LocalNodeConfig config, Hasher> hasher) { - super(executors, consensus, config, hasher); + protected AbstractTrieBasedStoreImpl(Environment env, ExecutorService executors, LocalNodeConfig config, Hasher> hasher) throws StoreException { + super(executors, config, hasher); this.env = env; this.storeOfResponses = env.computeInTransaction(txn -> env.openStoreWithoutDuplicates("responses", txn)); @@ -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 diff --git a/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintNodeImpl.java b/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintNodeImpl.java index 81bfed01f..935cf67c1 100644 --- a/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintNodeImpl.java +++ b/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintNodeImpl.java @@ -97,7 +97,7 @@ public TendermintNodeImpl(TendermintNodeConfig config, Optional consensus, TendermintNodeConfig config, Hasher> hasher) throws NodeException { + protected TendermintStore mkStore(ExecutorService executors, TendermintNodeConfig config, Hasher> 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); diff --git a/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintStore.java b/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintStore.java index 4d463d78e..f8a8118b8 100644 --- a/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintStore.java +++ b/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintStore.java @@ -60,12 +60,11 @@ public class TendermintStore extends AbstractTrieBasedStore consensus, TendermintNodeConfig config, Hasher> hasher) throws StoreException { - super(env, executors, consensus, config, hasher); + TendermintStore(Environment env, ExecutorService executors, TendermintNodeConfig config, Hasher> hasher) throws StoreException { + super(env, executors, config, hasher); try { this.hasherOfHashes = HashingAlgorithms.sha256().getHasher(Function.identity());