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 59796c96b..898ac4552 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 @@ -96,8 +96,6 @@ class DiskStore extends AbstractStore { * @param toClone the store to clone */ private DiskStore(DiskStore toClone) { - super(toClone); - this.dir = toClone.dir; this.histories = toClone.histories; this.errors = toClone.errors; @@ -157,7 +155,7 @@ public Optional> getRequest(TransactionReference reference @Override public StoreTransaction beginTransaction() { - return new DiskStoreTransaction(this, lock); + return new DiskStoreTransaction(this); } @Override diff --git a/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskStoreTransaction.java b/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskStoreTransaction.java index 8dfe092e1..1d82c14fe 100644 --- a/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskStoreTransaction.java +++ b/io-hotmoka-node-disk/src/main/java/io/hotmoka/node/disk/internal/DiskStoreTransaction.java @@ -14,9 +14,7 @@ import io.hotmoka.stores.StoreException; public class DiskStoreTransaction extends AbstractStoreTransaction { - private final DiskStore store; - private final ConcurrentMap> requests = new ConcurrentHashMap<>(); private final ConcurrentMap responses = new ConcurrentHashMap<>(); @@ -37,9 +35,7 @@ public class DiskStoreTransaction extends AbstractStoreTransaction { */ private final AtomicReference manifest = new AtomicReference<>(); - public DiskStoreTransaction(DiskStore store, Object lock) { - super(lock); - + public DiskStoreTransaction(DiskStore store) { this.store = store; } 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 7a6debb40..d9e8c0fe4 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 @@ -100,14 +100,12 @@ public Optional> getRequest(TransactionReference reference */ byte[] getHash() { try { - synchronized (lock) { - return isEmpty() ? - new byte[0] : // Tendermint requires an empty array at the beginning, for consensus - // we do not use the info part of the hash, so that the hash - // remains stable when the responses and the histories are stable, - // although the info part has changed for the update of the number of commits - hasherOfHashes.hash(mergeRootsOfTriesWithoutInfo()); // we hash the result into 32 bytes - } + return isEmpty() ? + new byte[0] : // Tendermint requires an empty array at the beginning, for consensus + // we do not use the info part of the hash, so that the hash + // remains stable when the responses and the histories are stable, + // although the info part has changed for the update of the number of commits + hasherOfHashes.hash(mergeRootsOfTriesWithoutInfo()); // we hash the result into 32 bytes } catch (StoreException e) { throw new RuntimeException(e); // TODO @@ -149,6 +147,6 @@ protected TendermintStore mkClone(Optional rootOfResponses, Optional { - protected TendermintStoreTransaction(TendermintStore store, Object lock, Transaction txn) throws StoreException { - super(store, lock, txn); + protected TendermintStoreTransaction(TendermintStore store, Transaction txn) throws StoreException { + super(store, txn); } @Override diff --git a/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractStore.java b/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractStore.java index bf6b416e6..8d9cab49d 100644 --- a/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractStore.java +++ b/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractStore.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. @@ -25,26 +25,10 @@ @ThreadSafe public abstract class AbstractStore> implements Store { - /** - * The lock for modifications of the store. - */ - protected final Object lock; - /** * Builds the store for a node. */ - protected AbstractStore() { - this.lock = new Object(); - } - - /** - * Creates a clone of the given store. - * - * @param toClone the store to clone - */ - protected AbstractStore(AbstractStore toClone) { - this.lock = toClone.lock; - } + protected AbstractStore() {} protected abstract T mkClone(); diff --git a/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractStoreTransaction.java b/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractStoreTransaction.java index 49674ee79..419883d2c 100644 --- a/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractStoreTransaction.java +++ b/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractStoreTransaction.java @@ -24,7 +24,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import io.hotmoka.annotations.ThreadSafe; import io.hotmoka.node.api.requests.InitializationTransactionRequest; import io.hotmoka.node.api.requests.TransactionRequest; import io.hotmoka.node.api.responses.GameteCreationTransactionResponse; @@ -41,58 +40,48 @@ * its hash is held in the node, if consensus is needed. Stores must be thread-safe, since they can * be used concurrently for executing more requests. */ -@ThreadSafe public abstract class AbstractStoreTransaction> implements StoreTransaction { - private final Object lock; private final static Logger LOGGER = Logger.getLogger(AbstractStoreTransaction.class.getName()); - protected AbstractStoreTransaction(Object lock) { - this.lock = lock; - } + protected AbstractStoreTransaction() {} @Override public final void push(TransactionReference reference, TransactionRequest request, TransactionResponse response) throws StoreException { - synchronized (lock) { - if (response instanceof TransactionResponseWithUpdates trwu) { - setRequest(reference, request); - setResponse(reference, response); - expandHistory(reference, trwu); + if (response instanceof TransactionResponseWithUpdates trwu) { + setRequest(reference, request); + setResponse(reference, response); + expandHistory(reference, trwu); - if (response instanceof GameteCreationTransactionResponse gctr) - LOGGER.info(gctr.getGamete() + ": created as gamete"); - } - else if (response instanceof InitializationTransactionResponse) { - if (request instanceof InitializationTransactionRequest itr) { - setRequest(reference, request); - setResponse(reference, response); - StorageReference manifest = itr.getManifest(); - setManifest(manifest); - LOGGER.info(manifest + ": set as manifest"); - LOGGER.info("the node has been initialized"); - } - else - throw new StoreException("Trying to initialize the node with a request of class " + request.getClass().getSimpleName()); - } - else { + if (response instanceof GameteCreationTransactionResponse gctr) + LOGGER.info(gctr.getGamete() + ": created as gamete"); + } + else if (response instanceof InitializationTransactionResponse) { + if (request instanceof InitializationTransactionRequest itr) { setRequest(reference, request); setResponse(reference, response); + StorageReference manifest = itr.getManifest(); + setManifest(manifest); + LOGGER.info(manifest + ": set as manifest"); + LOGGER.info("the node has been initialized"); } + else + throw new StoreException("Trying to initialize the node with a request of class " + request.getClass().getSimpleName()); + } + else { + setRequest(reference, request); + setResponse(reference, response); } } @Override public final void push(TransactionReference reference, TransactionRequest request, String errorMessage) throws StoreException { - synchronized (lock) { - setRequest(reference, request); - setError(reference, errorMessage); - } + setRequest(reference, request); + setError(reference, errorMessage); } @Override public final void replace(TransactionReference reference, TransactionRequest request, TransactionResponse response) throws StoreException { - synchronized (lock) { - setResponse(reference, response); - } + setResponse(reference, response); } /** diff --git a/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractTrieBasedStore.java b/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractTrieBasedStore.java index 9e8a20050..660b654f5 100644 --- a/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractTrieBasedStore.java +++ b/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractTrieBasedStore.java @@ -200,54 +200,44 @@ protected AbstractTrieBasedStore(Path dir) { } protected AbstractTrieBasedStore(AbstractTrieBasedStore toClone) { - super(toClone); - this.env = toClone.env; this.storeOfResponses = toClone.storeOfResponses; this.storeOfInfo = toClone.storeOfInfo; this.storeOfErrors = toClone.storeOfErrors; - this.storeOfHistories = toClone.storeOfHistories; - this.storeOfRequests = toClone.storeOfRequests; - - synchronized (toClone.lock) { - this.rootOfResponses = toClone.rootOfResponses; - this.rootOfInfo = toClone.rootOfInfo; - this.rootOfErrors = toClone.rootOfErrors; - this.rootOfHistories = toClone.rootOfHistories; - this.rootOfRequests = toClone.rootOfRequests; - this.txn = toClone.txn; - } + this.storeOfHistories = toClone.storeOfHistories; + this.storeOfRequests = toClone.storeOfRequests; + this.rootOfResponses = toClone.rootOfResponses; + this.rootOfInfo = toClone.rootOfInfo; + this.rootOfErrors = toClone.rootOfErrors; + this.rootOfHistories = toClone.rootOfHistories; + this.rootOfRequests = toClone.rootOfRequests; + this.txn = toClone.txn; } protected AbstractTrieBasedStore(AbstractTrieBasedStore toClone, Optional rootOfResponses, Optional rootOfInfo, Optional rootOfErrors, Optional rootOfHistories, Optional rootOfRequests) { - super(toClone); - this.env = toClone.env; this.storeOfResponses = toClone.storeOfResponses; this.storeOfInfo = toClone.storeOfInfo; this.storeOfErrors = toClone.storeOfErrors; - this.storeOfHistories = toClone.storeOfHistories; - this.storeOfRequests = toClone.storeOfRequests; - - synchronized (toClone.lock) { - this.rootOfResponses = rootOfResponses; - this.rootOfInfo = rootOfInfo; - this.rootOfErrors = rootOfErrors; - this.rootOfHistories = rootOfHistories; - this.rootOfRequests = rootOfRequests; - this.txn = toClone.txn; - } + this.storeOfHistories = toClone.storeOfHistories; + this.storeOfRequests = toClone.storeOfRequests; + this.rootOfResponses = rootOfResponses; + this.rootOfInfo = rootOfInfo; + this.rootOfErrors = rootOfErrors; + this.rootOfHistories = rootOfHistories; + this.rootOfRequests = rootOfRequests; + this.txn = toClone.txn; } protected abstract T mkClone(Optional rootOfResponses, Optional rootOfInfo, Optional rootOfErrors, Optional rootOfHistories, Optional rootOfRequests); @Override public void close() { - if (txn != null && !txn.isFinished()) { + /*if (txn != null && !txn.isFinished()) { // store closed with yet uncommitted transactions: we abort them LOGGER.log(Level.WARNING, "store closed with uncommitted transactions: they are being aborted"); txn.abort(); - } + }*/ try { env.close(); @@ -261,19 +251,15 @@ public void close() { @Override public Optional getResponse(TransactionReference reference) { - synchronized (lock) { - return env.computeInReadonlyTransaction // TODO: recheck - (UncheckFunction.uncheck(txn -> mkTrieOfResponses(txn).get(reference))); - } + return env.computeInReadonlyTransaction // TODO: recheck + (UncheckFunction.uncheck(txn -> mkTrieOfResponses(txn).get(reference))); } @Override public Optional getManifest() throws StoreException { try { - synchronized (lock) { - return CheckSupplier.check(TrieException.class, () -> - env.computeInReadonlyTransaction(UncheckFunction.uncheck(txn -> mkTrieOfInfo(txn).getManifest()))); - } + return CheckSupplier.check(TrieException.class, () -> env.computeInReadonlyTransaction + (UncheckFunction.uncheck(txn -> mkTrieOfInfo(txn).getManifest()))); } catch (ExodusException | TrieException e) { throw new StoreException(e); @@ -282,34 +268,28 @@ public Optional getManifest() throws StoreException { @Override public Optional getError(TransactionReference reference) throws StoreException { - synchronized (lock) { - try { - return CheckSupplier.check(TrieException.class, () -> env.computeInReadonlyTransaction + try { + return CheckSupplier.check(TrieException.class, () -> env.computeInReadonlyTransaction (UncheckFunction.uncheck(txn -> mkTrieOfErrors(txn).get(reference)))); - } - catch (TrieException e) { - throw new StoreException(e); - } - } + } + catch (ExodusException | TrieException e) { + throw new StoreException(e); + } } @Override public Optional> getRequest(TransactionReference reference) { - synchronized (lock) { - return env.computeInReadonlyTransaction // TODO: recheck - (UncheckFunction.uncheck(txn -> mkTrieOfRequests(txn).get(reference))); - } + return env.computeInReadonlyTransaction // TODO: recheck + (UncheckFunction.uncheck(txn -> mkTrieOfRequests(txn).get(reference))); } @Override public Stream getHistory(StorageReference object) throws StoreException { try { - synchronized (lock) { - return CheckSupplier.check(TrieException.class, () -> env.computeInReadonlyTransaction - (UncheckFunction.uncheck(txn -> mkTrieOfHistories(txn).get(object))).orElse(Stream.empty())); - } + return CheckSupplier.check(TrieException.class, () -> env.computeInReadonlyTransaction + (UncheckFunction.uncheck(txn -> mkTrieOfHistories(txn).get(object))).orElse(Stream.empty())); } - catch (TrieException e) { + catch (ExodusException | TrieException e) { throw new StoreException(e); } } diff --git a/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractTrieBasedStoreTransaction.java b/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractTrieBasedStoreTransaction.java index ccd1a7f30..a81c82357 100644 --- a/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractTrieBasedStoreTransaction.java +++ b/io-hotmoka-stores/src/main/java/io/hotmoka/stores/AbstractTrieBasedStoreTransaction.java @@ -52,9 +52,7 @@ public abstract class AbstractTrieBasedStoreTransaction