From 67ec6dda40a344ffd7406b656082dcabbd7fc411 Mon Sep 17 00:00:00 2001 From: Fausto Spoto Date: Fri, 14 Jun 2024 18:37:37 +0200 Subject: [PATCH] Started the Hotmoka nodes based on Mokamint --- io-hotmoka-node-mokamint-api/pom.xml | 51 ++++++ .../node/mokamint/api/MokamintNode.java | 27 +++ .../node/mokamint/api/MokamintNodeConfig.java | 27 +++ .../api/MokamintNodeConfigBuilder.java | 25 +++ .../src/main/java/module-info.java | 27 +++ io-hotmoka-node-mokamint/pom.xml | 57 ++++++ .../hotmoka/node/mokamint/MokamintNodes.java | 57 ++++++ .../src/main/java/module-info.java | 29 +++ .../tendermint/api/TendermintNodeConfig.java | 2 +- .../api/TendermintNodeConfigBuilder.java | 2 +- .../internal/TendermintNodeConfigImpl.java | 2 +- .../tests/ExampleCoinSnapshotPerformance.java | 14 +- .../test/java/io/hotmoka/tests/Faucet.java | 4 +- .../java/io/hotmoka/tests/HotmokaTest.java | 165 ++++++++++-------- .../io/hotmoka/tests/NodeFromNetwork.java | 12 +- .../java/io/hotmoka/tests/Signatures.java | 6 +- .../java/io/hotmoka/tests/WrongChainId.java | 2 +- .../test/java/io/hotmoka/tests/WrongKey.java | 2 +- .../io/hotmoka/tests/errors/Repeated.java | 12 +- pom.xml | 3 + 20 files changed, 424 insertions(+), 102 deletions(-) create mode 100644 io-hotmoka-node-mokamint-api/pom.xml create mode 100644 io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNode.java create mode 100644 io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNodeConfig.java create mode 100644 io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNodeConfigBuilder.java create mode 100644 io-hotmoka-node-mokamint-api/src/main/java/module-info.java create mode 100644 io-hotmoka-node-mokamint/pom.xml create mode 100644 io-hotmoka-node-mokamint/src/main/java/io/hotmoka/node/mokamint/MokamintNodes.java create mode 100644 io-hotmoka-node-mokamint/src/main/java/module-info.java diff --git a/io-hotmoka-node-mokamint-api/pom.xml b/io-hotmoka-node-mokamint-api/pom.xml new file mode 100644 index 000000000..f337a1f43 --- /dev/null +++ b/io-hotmoka-node-mokamint-api/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + + io-hotmoka-node-mokamint-api + jar + io-hotmoka-node-mokamint-api + ${hotmoka.version} + This module defines the API of Hotmoka nodes running over the Mokamint engine. They can be used to build an actual blockchain network based on proof of space. + + + io.hotmoka + hotmoka + parent + + + + + io.hotmoka + io-hotmoka-node-local-api + ${hotmoka.version} + + + io.hotmoka + io-hotmoka-node-api + ${hotmoka.version} + + + io.hotmoka.annotations + io-hotmoka-annotations + ${io.hotmoka.annotations.version} + + + + + + release + + + + org.sonatype.plugins + nexus-staging-maven-plugin + + false + + + + + + + + \ No newline at end of file diff --git a/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNode.java b/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNode.java new file mode 100644 index 000000000..96eef8e8a --- /dev/null +++ b/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNode.java @@ -0,0 +1,27 @@ +/* +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. +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. +*/ + +package io.hotmoka.node.mokamint.api; + +import io.hotmoka.annotations.ThreadSafe; +import io.hotmoka.node.local.api.LocalNode; + +/** + * A node of a blockchain that relies on the Mokamint engine. + */ +@ThreadSafe +public interface MokamintNode extends LocalNode { +} \ No newline at end of file diff --git a/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNodeConfig.java b/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNodeConfig.java new file mode 100644 index 000000000..0b0a6c8c2 --- /dev/null +++ b/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNodeConfig.java @@ -0,0 +1,27 @@ +/* +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. +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. +*/ + +package io.hotmoka.node.mokamint.api; + +import io.hotmoka.annotations.Immutable; +import io.hotmoka.node.local.api.LocalNodeConfig; + +/** + * The configuration of a Mokamint node. + */ +@Immutable +public interface MokamintNodeConfig extends LocalNodeConfig { +} \ No newline at end of file diff --git a/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNodeConfigBuilder.java b/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNodeConfigBuilder.java new file mode 100644 index 000000000..42c10b3e5 --- /dev/null +++ b/io-hotmoka-node-mokamint-api/src/main/java/io/hotmoka/node/mokamint/api/MokamintNodeConfigBuilder.java @@ -0,0 +1,25 @@ +/* +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. +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. +*/ + +package io.hotmoka.node.mokamint.api; + +import io.hotmoka.node.local.api.LocalNodeConfigBuilder; + +/** + * The builder of a configuration of a Mokamint node. + */ +public interface MokamintNodeConfigBuilder extends LocalNodeConfigBuilder { +} \ No newline at end of file diff --git a/io-hotmoka-node-mokamint-api/src/main/java/module-info.java b/io-hotmoka-node-mokamint-api/src/main/java/module-info.java new file mode 100644 index 000000000..5e0fbb80f --- /dev/null +++ b/io-hotmoka-node-mokamint-api/src/main/java/module-info.java @@ -0,0 +1,27 @@ +/* +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. +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. +*/ + +/** + * This module defines the API of Hotmoka nodes running over the Mokamint engine. + * They can be used to build an actual blockchain network based on proof of space. + */ +module io.hotmoka.node.mokamint.api { + exports io.hotmoka.node.mokamint.api; + + requires io.hotmoka.annotations; + requires io.hotmoka.node.api; + requires io.hotmoka.node.local.api; +} \ No newline at end of file diff --git a/io-hotmoka-node-mokamint/pom.xml b/io-hotmoka-node-mokamint/pom.xml new file mode 100644 index 000000000..3f059701e --- /dev/null +++ b/io-hotmoka-node-mokamint/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + + io-hotmoka-node-mokamint + jar + io-hotmoka-node-mokamint + ${hotmoka.version} + This module implements Hotmoka nodes based on the Mokamint proof of space engine. + + + io.hotmoka + hotmoka + parent + + + + + io.hotmoka + io-hotmoka-node-mokamint-api + ${hotmoka.version} + + + io.hotmoka + io-hotmoka-node-local + ${hotmoka.version} + + + io.hotmoka + io-takamaka-code-constants + ${io.takamaka.code.version} + + + io.hotmoka.annotations + io-hotmoka-annotations + ${io.hotmoka.annotations.version} + + + + + + release + + + + org.sonatype.plugins + nexus-staging-maven-plugin + + false + + + + + + + + \ No newline at end of file diff --git a/io-hotmoka-node-mokamint/src/main/java/io/hotmoka/node/mokamint/MokamintNodes.java b/io-hotmoka-node-mokamint/src/main/java/io/hotmoka/node/mokamint/MokamintNodes.java new file mode 100644 index 000000000..80ae71e82 --- /dev/null +++ b/io-hotmoka-node-mokamint/src/main/java/io/hotmoka/node/mokamint/MokamintNodes.java @@ -0,0 +1,57 @@ +/* +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. +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. +*/ + +package io.hotmoka.node.mokamint; + +import io.hotmoka.node.api.NodeException; +import io.hotmoka.node.mokamint.api.MokamintNode; +import io.hotmoka.node.mokamint.api.MokamintNodeConfig; + +/** + * Providers of blockchain nodes that rely on the Mokamint proof of space engine. + */ +public abstract class MokamintNodes { + + private MokamintNodes() {} + + /** + * Creates and starts a node with a brand new store, of a blockchain based on Mokamint. + * It spawns the Mokamint engine with an application for handling its transactions. + * + * @param config the configuration of the blockchain + * @return the Mokamint node + * @throws InterruptedException if the current thread is interrupted before completing the operation + * @throws NodeException if the operation cannot be completed correctly + */ + public static MokamintNode init(MokamintNodeConfig config) throws NodeException, InterruptedException { + return null; //new TendermintNodeImpl(config, true); + } + + /** + * Starts a Mokamint node that uses an already existing store. The consensus + * parameters are recovered from the manifest in the store, hence the store must + * be that of an already initialized blockchain. It spawns the Mokamint engine + * and connects it to an application for handling its transactions. + * + * @param config the configuration of the blockchain + * @return the Mokamint node + * @throws InterruptedException if the current thread is interrupted before completing the operation + * @throws NodeException if the operation cannot be completed correctly + */ + public static MokamintNode resume(MokamintNodeConfig config) throws NodeException, InterruptedException { + return null; //new TendermintNodeImpl(config, false); + } +} \ No newline at end of file diff --git a/io-hotmoka-node-mokamint/src/main/java/module-info.java b/io-hotmoka-node-mokamint/src/main/java/module-info.java new file mode 100644 index 000000000..1d702fec6 --- /dev/null +++ b/io-hotmoka-node-mokamint/src/main/java/module-info.java @@ -0,0 +1,29 @@ +/* +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. +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. +*/ + +/** + * This module implements Hotmoka nodes running over the Mokamint engine. + * They can be used to build an actual blockchain network based on proof of space. + */ +module io.hotmoka.node.mokamint { + exports io.hotmoka.node.mokamint; + //exports io.hotmoka.node.mokamint.internal.beans to com.google.gson; + + requires transitive io.hotmoka.node.mokamint.api; + requires transitive io.hotmoka.node.api; + requires io.hotmoka.annotations; + requires java.logging; +} \ No newline at end of file diff --git a/io-hotmoka-node-tendermint-api/src/main/java/io/hotmoka/node/tendermint/api/TendermintNodeConfig.java b/io-hotmoka-node-tendermint-api/src/main/java/io/hotmoka/node/tendermint/api/TendermintNodeConfig.java index b6a446b09..14b0aa6ce 100644 --- a/io-hotmoka-node-tendermint-api/src/main/java/io/hotmoka/node/tendermint/api/TendermintNodeConfig.java +++ b/io-hotmoka-node-tendermint-api/src/main/java/io/hotmoka/node/tendermint/api/TendermintNodeConfig.java @@ -23,7 +23,7 @@ import io.hotmoka.node.local.api.LocalNodeConfig; /** - * The configuration of a Tendermint blockchain. + * The configuration of a Tendermint node. */ @Immutable public interface TendermintNodeConfig extends LocalNodeConfig { diff --git a/io-hotmoka-node-tendermint-api/src/main/java/io/hotmoka/node/tendermint/api/TendermintNodeConfigBuilder.java b/io-hotmoka-node-tendermint-api/src/main/java/io/hotmoka/node/tendermint/api/TendermintNodeConfigBuilder.java index ea8546b3d..d68399c30 100644 --- a/io-hotmoka-node-tendermint-api/src/main/java/io/hotmoka/node/tendermint/api/TendermintNodeConfigBuilder.java +++ b/io-hotmoka-node-tendermint-api/src/main/java/io/hotmoka/node/tendermint/api/TendermintNodeConfigBuilder.java @@ -21,7 +21,7 @@ import io.hotmoka.node.local.api.LocalNodeConfigBuilder; /** - * The builder of a configuration of a Tendermint blockchain. + * The builder of a configuration of a Tendermint node. */ public interface TendermintNodeConfigBuilder extends LocalNodeConfigBuilder { diff --git a/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintNodeConfigImpl.java b/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintNodeConfigImpl.java index 636efae8d..6b3bc8c17 100644 --- a/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintNodeConfigImpl.java +++ b/io-hotmoka-node-tendermint/src/main/java/io/hotmoka/node/tendermint/internal/TendermintNodeConfigImpl.java @@ -39,7 +39,7 @@ public class TendermintNodeConfigImpl extends AbstractLocalNodeConfig tendermintConfigurationToClone; diff --git a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/ExampleCoinSnapshotPerformance.java b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/ExampleCoinSnapshotPerformance.java index d50cb0975..8bf93fc83 100644 --- a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/ExampleCoinSnapshotPerformance.java +++ b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/ExampleCoinSnapshotPerformance.java @@ -262,13 +262,13 @@ private void createCreator() throws TransactionException, CodeExecutionException privateKeyOfCreator = keys.getPrivate(); String publicKey = Base64.toBase64String(signature().encodingOf(keys.getPublic())); var request = TransactionRequests.constructorCall - (signature().getSigner(nodeWithAccounts.privateKey(numberOfInvestors), SignedTransactionRequest::toByteArrayWithoutSignature), nodeWithAccounts.account(numberOfInvestors), ZERO, chainId, _50_000, ZERO, jar(), ConstructorSignatures.of(CREATOR, StorageTypes.BIG_INTEGER, StorageTypes.STRING), + (signature().getSigner(nodeWithAccounts.privateKey(numberOfInvestors), SignedTransactionRequest::toByteArrayWithoutSignature), nodeWithAccounts.account(numberOfInvestors), ZERO, chainId(), _50_000, ZERO, jar(), ConstructorSignatures.of(CREATOR, StorageTypes.BIG_INTEGER, StorageTypes.STRING), StorageValues.bigIntegerOf(level2(500)), StorageValues.stringOf(publicKey)); creator = node.addConstructorCallTransaction(request); } private void distributeInitialTokens() throws InvalidKeyException, SignatureException, TransactionRejectedException, TransactionException, CodeExecutionException, UnknownReferenceException, NodeException, TimeoutException, InterruptedException { - var request = TransactionRequests.instanceMethodCall(signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, ONE, chainId, _100_000.multiply(BigInteger.valueOf(numberOfInvestors)), ZERO, jar(), + var request = TransactionRequests.instanceMethodCall(signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, ONE, chainId(), _100_000.multiply(BigInteger.valueOf(numberOfInvestors)), ZERO, jar(), MethodSignatures.ofVoid(CREATOR, "distribute", StorageTypes.ACCOUNTS, StorageTypes.IERC20, StorageTypes.INT), creator, nodeWithAccounts.container(), coin, StorageValues.intOf(50_000)); node.addInstanceMethodCallTransaction(request); trace(TransactionReferences.of(hasher.hash(request))); @@ -276,7 +276,7 @@ private void distributeInitialTokens() throws InvalidKeyException, SignatureExce private void createCoin() throws InvalidKeyException, SignatureException, TransactionRejectedException, TransactionException, CodeExecutionException, UnknownReferenceException, NodeException, TimeoutException, InterruptedException { var request = TransactionRequests.constructorCall - (signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, ZERO, chainId, _500_000, panarea(1), jar(), ConstructorSignatures.of(COIN)); + (signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, ZERO, chainId(), _500_000, panarea(1), jar(), ConstructorSignatures.of(COIN)); coin = node.addConstructorCallTransaction(request); trace(TransactionReferences.of(hasher.hash(request))); } @@ -339,7 +339,7 @@ private void actionsOfAccount(int index) { */ private void transfer(StorageReference sender, PrivateKey privateKeyOfSender, StorageReference receiver, int howMuch) throws SignatureException, TransactionException, CodeExecutionException, InvalidKeyException, TransactionRejectedException, NoSuchElementException, NodeException, InterruptedException, TimeoutException, UnknownReferenceException { var request = TransactionRequests.instanceMethodCall - (signature().getSigner(privateKeyOfSender, SignedTransactionRequest::toByteArrayWithoutSignature), sender, nonceHelper.getNonceOf(sender), chainId, _10_000_000, ZERO, jar(), + (signature().getSigner(privateKeyOfSender, SignedTransactionRequest::toByteArrayWithoutSignature), sender, nonceHelper.getNonceOf(sender), chainId(), _10_000_000, ZERO, jar(), TRANSFER, coin, receiver, StorageValues.intOf(howMuch)); node.addInstanceMethodCallTransaction(request); trace(TransactionReferences.of(hasher.hash(request))); @@ -348,7 +348,7 @@ private void transfer(StorageReference sender, PrivateKey privateKeyOfSender, St private void burn(StorageReference victim, int howMuch) throws InvalidKeyException, SignatureException, NoSuchElementException, TransactionRejectedException, TransactionException, CodeExecutionException, NodeException, InterruptedException, TimeoutException, UnknownReferenceException { var request = TransactionRequests.instanceMethodCall - (signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, nonceHelper.getNonceOf(creator), chainId, _10_000_000, ZERO, jar(), BURN, coin, victim, StorageValues.intOf(howMuch)); + (signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, nonceHelper.getNonceOf(creator), chainId(), _10_000_000, ZERO, jar(), BURN, coin, victim, StorageValues.intOf(howMuch)); node.addInstanceMethodCallTransaction(request); trace(TransactionReferences.of(hasher.hash(request))); numberOfBurns.getAndIncrement(); @@ -356,7 +356,7 @@ private void burn(StorageReference victim, int howMuch) throws InvalidKeyExcepti private void mint(StorageReference beneficiary, int howMuch) throws InvalidKeyException, SignatureException, NoSuchElementException, TransactionRejectedException, TransactionException, CodeExecutionException, NodeException, InterruptedException, TimeoutException, UnknownReferenceException { var request = TransactionRequests.instanceMethodCall - (signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, nonceHelper.getNonceOf(creator), chainId, _10_000_000, ZERO, jar(), MINT, coin, beneficiary, StorageValues.intOf(howMuch)); + (signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, nonceHelper.getNonceOf(creator), chainId(), _10_000_000, ZERO, jar(), MINT, coin, beneficiary, StorageValues.intOf(howMuch)); node.addInstanceMethodCallTransaction(request); trace(TransactionReferences.of(hasher.hash(request))); numberOfMints.getAndIncrement(); @@ -372,7 +372,7 @@ private int convertUBItoInt(StorageReference ubi) throws TransactionException, C private StorageReference createSnapshot() throws SignatureException, TransactionException, CodeExecutionException, InvalidKeyException, TransactionRejectedException, NoSuchElementException, NodeException, InterruptedException, TimeoutException, UnknownReferenceException { var request = TransactionRequests.instanceMethodCall - (signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, nonceHelper.getNonceOf(creator), chainId, _500_000, ZERO, jar(), YIELD_SNAPSHOT, coin); + (signature().getSigner(privateKeyOfCreator, SignedTransactionRequest::toByteArrayWithoutSignature), creator, nonceHelper.getNonceOf(creator), chainId(), _500_000, ZERO, jar(), YIELD_SNAPSHOT, coin); StorageReference result = node.addInstanceMethodCallTransaction(request) .orElseThrow(NodeException::new) .asReturnedReference(YIELD_SNAPSHOT, NodeException::new); diff --git a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/Faucet.java b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/Faucet.java index 8dc5f13e8..eb66904a3 100644 --- a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/Faucet.java +++ b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/Faucet.java @@ -66,7 +66,7 @@ void fundNewAccount() throws TransactionException, CodeExecutionException, Trans var method = MethodSignatures.ofNonVoid(StorageTypes.GAMETE, "faucet", StorageTypes.EOA, StorageTypes.INT, StorageTypes.STRING); var account = (StorageReference) node.addInstanceMethodCallTransaction(TransactionRequests.instanceMethodCall - (signer, gamete, getNonceOf(gamete), chainId, _100_000, ONE, takamakaCode(), + (signer, gamete, getNonceOf(gamete), chainId(), _100_000, ONE, takamakaCode(), method, gamete, StorageValues.intOf(100_000), StorageValues.stringOf(publicKey))) .orElseThrow(() -> new NodeException(method + " should not return void")); @@ -87,7 +87,7 @@ void callToFaucetFailsIfCallerIsNotTheGamete() throws TransactionException, Code throwsTransactionExceptionWithCause(Constants.REQUIREMENT_VIOLATION_EXCEPTION_NAME, () -> node.addInstanceMethodCallTransaction(TransactionRequests.instanceMethodCall - (signer, caller, getNonceOf(caller), chainId, _50_000, ONE, takamakaCode(), + (signer, caller, getNonceOf(caller), chainId(), _50_000, ONE, takamakaCode(), MethodSignatures.ofNonVoid(StorageTypes.GAMETE, "faucet", StorageTypes.EOA, StorageTypes.INT, StorageTypes.STRING), gamete, StorageValues.intOf(100_000), StorageValues.stringOf(publicKey)))); } diff --git a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/HotmokaTest.java b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/HotmokaTest.java index 3e1cc312c..0d2a0b5be 100644 --- a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/HotmokaTest.java +++ b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/HotmokaTest.java @@ -40,6 +40,9 @@ import java.util.stream.Stream; import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; import io.hotmoka.crypto.Entropies; import io.hotmoka.crypto.SignatureAlgorithms; @@ -92,7 +95,7 @@ import io.takamaka.code.constants.Constants; import jakarta.websocket.DeploymentException; - +@ExtendWith(HotmokaTest.NodeHandler.class) public abstract class HotmokaTest extends AbstractLoggedTests { protected static final BigInteger _50_000 = BigInteger.valueOf(50_000); protected static final BigInteger _100_000 = BigInteger.valueOf(100_000); @@ -102,12 +105,88 @@ public abstract class HotmokaTest extends AbstractLoggedTests { protected static final BigInteger _1_000_000_000 = BigInteger.valueOf(1_000_000_000); protected static final BigInteger _10_000_000_000 = BigInteger.valueOf(10_000_000_000L); + static class NodeHandler implements BeforeAllCallback, ExtensionContext.Store.CloseableResource { + + private static boolean started = false; + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + if (!started) { + started = true; + context.getRoot().getStore(org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL).put("any unique name", this); + + // we use always the same entropy and password, so that the tests become deterministic (if they are not explicitly non-deterministic) + var entropy = Entropies.of(new byte[16]); + var password = ""; + var localSignature = signature = SignatureAlgorithms.ed25519det(); // good for testing + var keys = entropy.keys(password, localSignature); + consensus = ValidatorsConsensusConfigBuilders.defaults() + .setSignatureForRequests(signature) + .allowUnsignedFaucet(true) // good for testing + .ignoreGasPrice(true) // good for testing + .setInitialSupply(Coin.level7(10000000)) // enough for all tests + .setInitialRedSupply(Coin.level7(10000000)) // enough for all tests + .setPublicKeyOfGamete(keys.getPublic()) + .build(); + privateKeyOfGamete = keys.getPrivate(); + + Node wrapped; + //node = wrapped = mkDiskNode(); + //node = wrapped = mkTendermintNode(); + node = mkRemoteNode(wrapped = mkDiskNode()); + //node = mkRemoteNode(wrapped = mkTendermintNode()); + //node = wrapped = mkRemoteNode("ec2-54-194-239-91.eu-west-1.compute.amazonaws.com:8080"); + //node = wrapped = mkRemoteNode("localhost:8080"); + initializeNodeIfNeeded(wrapped); + + manifest = node.getManifest(); + takamakaCode = node.getTakamakaCode(); + + var gamete = node.runInstanceMethodCallTransaction(TransactionRequests.instanceViewMethodCall + (manifest, _100_000, takamakaCode, MethodSignatures.GET_GAMETE, manifest)) + .orElseThrow(() -> new NodeException(MethodSignatures.GET_GAMETE + " should not return void")) + .asReturnedReference(MethodSignatures.GET_GAMETE, NodeException::new); + + chainId = node.runInstanceMethodCallTransaction(TransactionRequests.instanceViewMethodCall + (manifest, _100_000, takamakaCode, MethodSignatures.GET_CHAIN_ID, manifest)) + .orElseThrow(() -> new NodeException(MethodSignatures.GET_CHAIN_ID + " should not return void")) + .asReturnedString(MethodSignatures.GET_CHAIN_ID, NodeException::new); + + BigInteger nonce = node.runInstanceMethodCallTransaction(TransactionRequests.instanceViewMethodCall + (gamete, _100_000, takamakaCode, MethodSignatures.NONCE, gamete)) + .orElseThrow(() -> new NodeException(MethodSignatures.NONCE + " should not return void")) + .asReturnedBigInteger(MethodSignatures.NONCE, NodeException::new); + + BigInteger aLot = Coin.level6(1000000000); + + // we set the thresholds for the faucets of the gamete + Signer> signerOfGamete = signature.getSigner(privateKeyOfGamete, SignedTransactionRequest::toByteArrayWithoutSignature); + node.addInstanceMethodCallTransaction(TransactionRequests.instanceMethodCall + (signerOfGamete, gamete, nonce, chainId, _100_000, BigInteger.ONE, takamakaCode, + MethodSignatures.ofVoid(StorageTypes.GAMETE, "setMaxFaucet", StorageTypes.BIG_INTEGER, StorageTypes.BIG_INTEGER), gamete, + StorageValues.bigIntegerOf(aLot), StorageValues.bigIntegerOf(aLot))); + + var local = AccountsNodes.ofGreenRed(node, gamete, privateKeyOfGamete, aLot, aLot); + localGamete = local.account(0); + privateKeyOfLocalGamete = local.privateKey(0); + + System.out.println("initialized the test node " + node.getNodeInfo()); + } + } + + @Override + public void close() throws Exception { + node.close(); + System.out.println("closed the test node"); + } + } + /** * The node that gets created before starting running the tests. * This node will hence be created only once and * each test will create the accounts and add the jars that it needs. */ - protected final static Node node; + protected static Node node; /** * The consensus parameters of the node. @@ -117,27 +196,27 @@ public abstract class HotmokaTest extends AbstractLoggedTests { /** * The private key of the account used at each run of the tests. */ - private final static PrivateKey privateKeyOfLocalGamete; + private static PrivateKey privateKeyOfLocalGamete; /** * The account that can be used as gamete for each run of the tests. */ - private final static StorageReference localGamete; + private static StorageReference localGamete; /** * The signature algorithm used for signing the requests. */ - private final static SignatureAlgorithm signature; + private static SignatureAlgorithm signature; /** * The reference to the manifest in the test node. */ - private final static StorageReference manifest; + private static StorageReference manifest; /** * The transaction that installed the Takamaka runtime in the test node. */ - private final static TransactionReference takamakaCode; + private static TransactionReference takamakaCode; /** * The jar under test. @@ -158,81 +237,17 @@ public abstract class HotmokaTest extends AbstractLoggedTests { /** * The chain identifier of the node used for the tests. */ - protected final static String chainId; + private static String chainId; /** * The private key of the gamete. */ - private static final PrivateKey privateKeyOfGamete; + private static PrivateKey privateKeyOfGamete; public interface TestBody { void run() throws Exception; } - static { - try { - // we use always the same entropy and password, so that the tests become deterministic (if they are not explicitly non-deterministic) - var entropy = Entropies.of(new byte[16]); - var password = ""; - var localSignature = signature = SignatureAlgorithms.ed25519det(); // good for testing - var keys = entropy.keys(password, localSignature); - consensus = ValidatorsConsensusConfigBuilders.defaults() - .setSignatureForRequests(signature) - .allowUnsignedFaucet(true) // good for testing - .ignoreGasPrice(true) // good for testing - .setInitialSupply(Coin.level7(10000000)) // enough for all tests - .setInitialRedSupply(Coin.level7(10000000)) // enough for all tests - .setPublicKeyOfGamete(keys.getPublic()) - .build(); - privateKeyOfGamete = keys.getPrivate(); - - Node wrapped; - //node = wrapped = mkDiskNode(); - //node = wrapped = mkTendermintNode(); - node = mkRemoteNode(wrapped = mkDiskNode()); - //node = mkRemoteNode(wrapped = mkTendermintNode()); - //node = wrapped = mkRemoteNode("ec2-54-194-239-91.eu-west-1.compute.amazonaws.com:8080"); - //node = wrapped = mkRemoteNode("localhost:8080"); - initializeNodeIfNeeded(wrapped); - - manifest = node.getManifest(); - takamakaCode = node.getTakamakaCode(); - - var gamete = node.runInstanceMethodCallTransaction(TransactionRequests.instanceViewMethodCall - (manifest, _100_000, takamakaCode, MethodSignatures.GET_GAMETE, manifest)) - .orElseThrow(() -> new NodeException(MethodSignatures.GET_GAMETE + " should not return void")) - .asReturnedReference(MethodSignatures.GET_GAMETE, NodeException::new); - - chainId = node.runInstanceMethodCallTransaction(TransactionRequests.instanceViewMethodCall - (manifest, _100_000, takamakaCode, MethodSignatures.GET_CHAIN_ID, manifest)) - .orElseThrow(() -> new NodeException(MethodSignatures.GET_CHAIN_ID + " should not return void")) - .asReturnedString(MethodSignatures.GET_CHAIN_ID, NodeException::new); - - BigInteger nonce = node.runInstanceMethodCallTransaction(TransactionRequests.instanceViewMethodCall - (gamete, _100_000, takamakaCode, MethodSignatures.NONCE, gamete)) - .orElseThrow(() -> new NodeException(MethodSignatures.NONCE + " should not return void")) - .asReturnedBigInteger(MethodSignatures.NONCE, NodeException::new); - - BigInteger aLot = Coin.level6(1000000000); - - // we set the thresholds for the faucets of the gamete - Signer> signerOfGamete = signature.getSigner(privateKeyOfGamete, SignedTransactionRequest::toByteArrayWithoutSignature); - node.addInstanceMethodCallTransaction(TransactionRequests.instanceMethodCall - (signerOfGamete, gamete, nonce, chainId, _100_000, BigInteger.ONE, takamakaCode, - MethodSignatures.ofVoid(StorageTypes.GAMETE, "setMaxFaucet", StorageTypes.BIG_INTEGER, StorageTypes.BIG_INTEGER), gamete, - StorageValues.bigIntegerOf(aLot), StorageValues.bigIntegerOf(aLot))); - - var local = AccountsNodes.ofGreenRed(node, gamete, privateKeyOfGamete, aLot, aLot); - localGamete = local.account(0); - privateKeyOfLocalGamete = local.privateKey(0); - } - catch (Exception e) { - e.printStackTrace(); - System.exit(0); - throw new ExceptionInInitializerError(e); - } - } - private static void initializeNodeIfNeeded(Node node) throws TransactionRejectedException, TransactionException, CodeExecutionException, IOException, NodeException, TimeoutException, InterruptedException { @@ -363,6 +378,10 @@ protected final static TransactionReference jar() { return jar; } + protected final static String chainId() { + return chainId; + } + protected final StorageReference account(int i) throws NoSuchElementException, NodeException, TimeoutException, InterruptedException { return nodeWithAccountsView.account(i); } diff --git a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/NodeFromNetwork.java b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/NodeFromNetwork.java index 43e82d10d..4053dd444 100644 --- a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/NodeFromNetwork.java +++ b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/NodeFromNetwork.java @@ -226,7 +226,7 @@ void testRemoteAddJarStoreTransaction() throws Exception { try (var service = NodeServices.of(node, PORT); var remote = RemoteNodes.of(URI, 10_000)) { assertNotNull(remote.addJarStoreTransaction(TransactionRequests.jarStore (signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), - ZERO, chainId, _500_000, ONE, takamakaCode(), bytesOf("lambdas.jar"), takamakaCode()))); + ZERO, chainId(), _500_000, ONE, takamakaCode(), bytesOf("lambdas.jar"), takamakaCode()))); } } @@ -240,7 +240,7 @@ void testRemoteAddJarStoreTransactionRejected() throws Exception { TransactionRejectedException e = assertThrows(TransactionRejectedException.class, () -> remote.addJarStoreTransaction(TransactionRequests.jarStore (signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), - ZERO, chainId, _500_000, ONE, takamakaCode(), bytesOf("lambdas.jar") + ZERO, chainId(), _500_000, ONE, takamakaCode(), bytesOf("lambdas.jar") // , takamakaCode() // <-- forgot that ))); assertTrue(e.getMessage().contains(ClassNotFoundException.class.getName())); @@ -254,7 +254,7 @@ void testRemoteAddJarStoreTransactionFailed() throws Exception { TransactionException e = assertThrows(TransactionException.class, () -> remote.addJarStoreTransaction(TransactionRequests.jarStore (signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), - ZERO, chainId, _100_000, ONE, takamakaCode(), bytesOf("callernotonthis.jar"), takamakaCode()))); + ZERO, chainId(), _100_000, ONE, takamakaCode(), bytesOf("callernotonthis.jar"), takamakaCode()))); assertTrue(e.getMessage().contains(VerificationException.class.getName())); assertTrue(e.getMessage().contains("caller() can only be called on \"this\"")); @@ -267,7 +267,7 @@ void testRemotePostJarStoreTransaction() throws Exception { try (var service = NodeServices.of(node, PORT); var remote = RemoteNodes.of(URI, 10_000)) { JarFuture future = remote.postJarStoreTransaction(TransactionRequests.jarStore (signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), - ZERO, chainId, _500_000, ONE, takamakaCode(), bytesOf("lambdas.jar"), takamakaCode())); + ZERO, chainId(), _500_000, ONE, takamakaCode(), bytesOf("lambdas.jar"), takamakaCode())); // we wait until the request has been processed assertNotNull(future.get()); @@ -283,7 +283,7 @@ void testRemotePostJarStoreTransactionRejected() throws Exception { // the execution does not stop, nor throws anything JarFuture future = remote.postJarStoreTransaction(TransactionRequests.jarStore (signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), - ZERO, chainId, _500_000, ONE, takamakaCode(), bytesOf("lambdas.jar") + ZERO, chainId(), _500_000, ONE, takamakaCode(), bytesOf("lambdas.jar") // , takamakaCode() // <-- forgot that )); @@ -303,7 +303,7 @@ void testRemotePostJarStoreTransactionFailed() throws Exception { // the execution does not stop, nor throws anything JarFuture future = remote.postJarStoreTransaction(TransactionRequests.jarStore (signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), - ZERO, chainId, _500_000, ONE, takamakaCode(), bytesOf("callernotonthis.jar"), takamakaCode())); + ZERO, chainId(), _500_000, ONE, takamakaCode(), bytesOf("callernotonthis.jar"), takamakaCode())); // we wait until the request has been processed; this will throw a TransactionException at the end, // since the request was accepted but its execution failed diff --git a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/Signatures.java b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/Signatures.java index ece97093e..f51283c3b 100644 --- a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/Signatures.java +++ b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/Signatures.java @@ -86,21 +86,21 @@ void createAccountsWithDistinctSigningAlgorithmsAndUseThem() throws TransactionE KeyPair sha256dsaKeyPair = sha256dsa.getKeyPair(); var sha256dsaPublicKey = StorageValues.stringOf(Base64.toBase64String(sha256dsa.encodingOf(sha256dsaKeyPair.getPublic()))); StorageReference sha256dsaAccount = addConstructorCallTransaction(privateKey(0), account(0), _500_000, ONE, takamakaCode(), ConstructorSignatures.of("io.takamaka.code.lang.ExternallyOwnedAccountSHA256DSA", StorageTypes.INT, StorageTypes.STRING), amount, sha256dsaPublicKey); - var sha256dsaResult = (BigIntegerValue) node.addStaticMethodCallTransaction(TransactionRequests.staticMethodCall(sha256dsa.getSigner(sha256dsaKeyPair.getPrivate(), SignedTransactionRequest::toByteArrayWithoutSignature), sha256dsaAccount, ZERO, chainId, _100_000, ONE, takamakaCode(), callee, StorageValues.longOf(1973))).get(); + var sha256dsaResult = (BigIntegerValue) node.addStaticMethodCallTransaction(TransactionRequests.staticMethodCall(sha256dsa.getSigner(sha256dsaKeyPair.getPrivate(), SignedTransactionRequest::toByteArrayWithoutSignature), sha256dsaAccount, ZERO, chainId(), _100_000, ONE, takamakaCode(), callee, StorageValues.longOf(1973))).get(); assertEquals(BigInteger.valueOf(1973), sha256dsaResult.getValue()); var qtesla1 = SignatureAlgorithms.qtesla1(); KeyPair qteslaKeyPair = qtesla1.getKeyPair(); var qteslaPublicKey = StorageValues.stringOf(Base64.toBase64String(qtesla1.encodingOf(qteslaKeyPair.getPublic()))); StorageReference qteslaAccount = addConstructorCallTransaction(privateKey(0), account(0), _10_000_000, ONE, takamakaCode(), ConstructorSignatures.of("io.takamaka.code.lang.ExternallyOwnedAccountQTESLA1", StorageTypes.INT, StorageTypes.STRING), amount, qteslaPublicKey); - var qteslaResult = (BigIntegerValue) node.addStaticMethodCallTransaction(TransactionRequests.staticMethodCall(qtesla1.getSigner(qteslaKeyPair.getPrivate(), SignedTransactionRequest::toByteArrayWithoutSignature), qteslaAccount, ZERO, chainId, _500_000, ONE, takamakaCode(), callee, StorageValues.longOf(1973))).get(); + var qteslaResult = (BigIntegerValue) node.addStaticMethodCallTransaction(TransactionRequests.staticMethodCall(qtesla1.getSigner(qteslaKeyPair.getPrivate(), SignedTransactionRequest::toByteArrayWithoutSignature), qteslaAccount, ZERO, chainId(), _500_000, ONE, takamakaCode(), callee, StorageValues.longOf(1973))).get(); assertEquals(BigInteger.valueOf(1973), qteslaResult.getValue()); var ed25519 = SignatureAlgorithms.ed25519(); KeyPair ed25519KeyPair = ed25519.getKeyPair(); var ed25519PublicKey = StorageValues.stringOf(Base64.toBase64String(ed25519.encodingOf(ed25519KeyPair.getPublic()))); StorageReference ed25519Account = addConstructorCallTransaction(privateKey(0), account(0), _500_000, ONE, takamakaCode(), ConstructorSignatures.of("io.takamaka.code.lang.ExternallyOwnedAccountED25519", StorageTypes.INT, StorageTypes.STRING), amount, ed25519PublicKey); - var ed25519Result = (BigIntegerValue) node.addStaticMethodCallTransaction(TransactionRequests.staticMethodCall(ed25519.getSigner(ed25519KeyPair.getPrivate(), SignedTransactionRequest::toByteArrayWithoutSignature), ed25519Account, ZERO, chainId, _500_000, ONE, takamakaCode(), callee, StorageValues.longOf(1973))).get(); + var ed25519Result = (BigIntegerValue) node.addStaticMethodCallTransaction(TransactionRequests.staticMethodCall(ed25519.getSigner(ed25519KeyPair.getPrivate(), SignedTransactionRequest::toByteArrayWithoutSignature), ed25519Account, ZERO, chainId(), _500_000, ONE, takamakaCode(), callee, StorageValues.longOf(1973))).get(); assertEquals(BigInteger.valueOf(1973), ed25519Result.getValue()); } } \ No newline at end of file diff --git a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/WrongChainId.java b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/WrongChainId.java index 52444047a..903ad5efe 100644 --- a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/WrongChainId.java +++ b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/WrongChainId.java @@ -50,7 +50,7 @@ void createAbstractFailImpl() throws NoSuchElementException, NodeException, Time StorageReference caller = account(0); throwsTransactionRejectedWithCause("Incorrect chain id", () -> - node.addConstructorCallTransaction(TransactionRequests.constructorCall(signature().getSigner(key, SignedTransactionRequest::toByteArrayWithoutSignature), caller, BigInteger.ZERO, chainId + "noise", + node.addConstructorCallTransaction(TransactionRequests.constructorCall(signature().getSigner(key, SignedTransactionRequest::toByteArrayWithoutSignature), caller, BigInteger.ZERO, chainId() + "noise", _100_000, panarea(1), takamakaCode(), ConstructorSignatures.EOA_CONSTRUCTOR, StorageValues.bigIntegerOf(_50_000), StorageValues.stringOf("ciao"))) ); } diff --git a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/WrongKey.java b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/WrongKey.java index b2bd56432..14d17b654 100644 --- a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/WrongKey.java +++ b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/WrongKey.java @@ -58,7 +58,7 @@ void createAbstractFailImpl() throws NoSuchElementException, NodeException, Time StorageReference caller = account(0); TransactionRejectedException e = assertThrows(TransactionRejectedException.class, () -> - node.addConstructorCallTransaction(TransactionRequests.constructorCall(signature().getSigner(key, SignedTransactionRequest::toByteArrayWithoutSignature), caller, BigInteger.ZERO, chainId, + node.addConstructorCallTransaction(TransactionRequests.constructorCall(signature().getSigner(key, SignedTransactionRequest::toByteArrayWithoutSignature), caller, BigInteger.ZERO, chainId(), _100_000, panarea(1), takamakaCode(), ConstructorSignatures.EOA_CONSTRUCTOR, StorageValues.bigIntegerOf(_50_000), StorageValues.stringOf("ciao")))); assertTrue(e.getMessage().contains("Invalid request signature")); } diff --git a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/errors/Repeated.java b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/errors/Repeated.java index 72360ff27..36acb747d 100644 --- a/io-hotmoka-tests/src/test/java/io/hotmoka/tests/errors/Repeated.java +++ b/io-hotmoka-tests/src/test/java/io/hotmoka/tests/errors/Repeated.java @@ -58,21 +58,21 @@ void beforeEach() throws Exception { @Test @DisplayName("install jar") void installJar() throws InvalidKeyException, SignatureException, TransactionException, TransactionRejectedException, IOException, NoSuchElementException, NodeException, TimeoutException, InterruptedException, UnknownReferenceException { - var request = TransactionRequests.jarStore(signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), getNonceOf(account(0)), chainId, _500_000, ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); + var request = TransactionRequests.jarStore(signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), getNonceOf(account(0)), chainId(), _500_000, ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); TransactionReference reference = node.addJarStoreTransaction(request); assertTrue(node.getResponse(reference) instanceof JarStoreTransactionSuccessfulResponse); } @Test @DisplayName("install jar twice") void installJarTwice() throws InvalidKeyException, SignatureException, TransactionException, TransactionRejectedException, IOException, NoSuchElementException, NodeException, TimeoutException, InterruptedException { - var request = TransactionRequests.jarStore(signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), getNonceOf(account(0)), chainId, _500_000, ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); + var request = TransactionRequests.jarStore(signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), getNonceOf(account(0)), chainId(), _500_000, ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); node.addJarStoreTransaction(request); assertThrows(TransactionRejectedException.class, () -> node.addJarStoreTransaction(request)); } @Test @DisplayName("install jar twice concurrently") void installJarTwiceConcurrently() throws InvalidKeyException, SignatureException, TransactionRejectedException, IOException, NoSuchElementException, NodeException, TimeoutException, InterruptedException { - var request = TransactionRequests.jarStore(signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), getNonceOf(account(0)), chainId, _500_000, ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); + var request = TransactionRequests.jarStore(signature().getSigner(privateKey(0), SignedTransactionRequest::toByteArrayWithoutSignature), account(0), getNonceOf(account(0)), chainId(), _500_000, ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); node.postJarStoreTransaction(request); assertThrows(TransactionRejectedException.class, () -> node.postJarStoreTransaction(request)); } @@ -84,18 +84,18 @@ void installJarFirstTimeFailsSecondTimeSucceeds() throws InvalidKeyException, Si // the following request uses the wrong nonce, hence it will be rejected now // it will charge 20,000 units of coin to account(0), for penalty - var request = TransactionRequests.jarStore(signer, account(0), nonce.add(ONE), chainId, _500_000, ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); + var request = TransactionRequests.jarStore(signer, account(0), nonce.add(ONE), chainId(), _500_000, ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); assertThrows(TransactionRejectedException.class, () -> node.addJarStoreTransaction(request)); // we run a transaction now, with the correct nonce, that increases the nonce of account(0) - BigInteger balance = ((BigIntegerValue) node.addInstanceMethodCallTransaction(TransactionRequests.instanceMethodCall(signer, account(0), nonce, chainId, _100_000, ONE, takamakaCode(), MethodSignatures.BALANCE, account(0))) + BigInteger balance = ((BigIntegerValue) node.addInstanceMethodCallTransaction(TransactionRequests.instanceMethodCall(signer, account(0), nonce, chainId(), _100_000, ONE, takamakaCode(), MethodSignatures.BALANCE, account(0))) .orElseThrow(() -> new NodeException(MethodSignatures.BALANCE + " should not return void"))).getValue(); assertEquals(BigInteger.valueOf(999900000), balance); // we perform a similar request now, that will pass since the nonce is correct this time: we need to change for instance the gas limit // otherwise this second request might be rejected (for instance by Tendermint), being considered as a repeated transaction - var request2 = TransactionRequests.jarStore(signer, account(0), nonce.add(ONE), chainId, _500_000.add(ONE), ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); + var request2 = TransactionRequests.jarStore(signer, account(0), nonce.add(ONE), chainId(), _500_000.add(ONE), ONE, takamakaCode(), bytesOf("calleronthis.jar"), takamakaCode()); TransactionReference reference = node.addJarStoreTransaction(request2); // getResponse() agrees diff --git a/pom.xml b/pom.xml index c336de6e2..757495244 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,7 @@ Note: submodules whose artifact must be deployed on Maven Central must activate 1.4.1 1.4.4 1.4.1 + 0.0.1 io.hotmoka @@ -116,6 +117,8 @@ Note: submodules whose artifact must be deployed on Maven Central must activate io-hotmoka-node-tendermint io-hotmoka-node-messages-api io-hotmoka-node-messages + io-hotmoka-node-mokamint-api + io-hotmoka-node-mokamint