diff --git a/exonum-java-binding/CHANGELOG.md b/exonum-java-binding/CHANGELOG.md
index 19810d3d29..a8059b3d70 100644
--- a/exonum-java-binding/CHANGELOG.md
+++ b/exonum-java-binding/CHANGELOG.md
@@ -15,6 +15,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
+### Removed
+- Replaced Blockchain#getActualConfiguration with Blockchain#getConsensusConfiguration,
+ returning only the consensus configuration (now also containing the validator public keys)
+ as a protobuf message.
+
## [0.8.0] - 2019-09-09
### Overview
diff --git a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/ConsensusConfiguration.java b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/ConsensusConfiguration.java
deleted file mode 100644
index b8b1905ef8..0000000000
--- a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/ConsensusConfiguration.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2018 The Exonum Team
- *
- * 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 com.exonum.binding.common.configuration;
-
-import com.google.auto.value.AutoValue;
-import com.google.gson.Gson;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.SerializedName;
-
-/**
- * Blockchain Consensus algorithm parameters.
- *
- *
See Exonum configuration for
- * Consensus configuration details.
- */
-@AutoValue
-public abstract class ConsensusConfiguration {
-
- /**
- * Interval between first two rounds. This interval defines the time that passes
- * between the moment a new block is committed to the blockchain and the
- * time when second round starts, regardless of whether a new block has
- * been committed during this period or not.
- *
- *
Note that rounds in Exonum do not have a defined end time. Nodes in a new round can
- * continue to vote for proposals and process messages related to previous rounds.
- */
- @SerializedName("first_round_timeout")
- public abstract long firstRoundTimeout();
-
- /**
- * This parameter defines the frequency with which a node broadcasts its status message to the
- * network.
- */
- @SerializedName("status_timeout")
- public abstract long statusTimeout();
-
- /**
- * This parameter defines the frequency with which a node requests collected Connect messages
- * from a random peer node in the network.
- */
- @SerializedName("peers_timeout")
- public abstract long peersTimeout();
-
- /**
- * Maximum number of transactions per block.
- */
- @SerializedName("txs_block_limit")
- public abstract int txsBlockLimit();
-
- /**
- * This parameter determines the maximum size of both consensus messages and transactions.
- */
- @SerializedName("max_message_len")
- public abstract int maxMessageLen();
-
- /**
- * Minimal propose timeout.
- */
- @SerializedName("min_propose_timeout")
- public abstract long minProposeTimeout();
-
- /**
- * Maximal propose timeout.
- */
- @SerializedName("max_propose_timeout")
- public abstract long maxProposeTimeout();
-
- /**
- * Amount of transactions in pool to start use min_propose_timeout.
- */
- @SerializedName("propose_timeout_threshold")
- public abstract int proposeTimeoutThreshold();
-
- /**
- * Provides a Gson type adapter for this class.
- *
- * @see com.exonum.binding.common.serialization.json.CommonTypeAdapterFactory
- */
- public static TypeAdapter typeAdapter(Gson gson) {
- return new AutoValue_ConsensusConfiguration.GsonTypeAdapter(gson);
- }
-
- public static ConsensusConfiguration.Builder builder() {
- return new AutoValue_ConsensusConfiguration.Builder();
- }
-
- @AutoValue.Builder
- public abstract static class Builder {
- public abstract Builder firstRoundTimeout(long firstRoundTimeout);
-
- public abstract Builder statusTimeout(long statusTimeout);
-
- public abstract Builder peersTimeout(long peersTimeout);
-
- public abstract Builder txsBlockLimit(int txsBlockLimit);
-
- public abstract Builder maxMessageLen(int maxMessageLen);
-
- public abstract Builder minProposeTimeout(long minProposeTimeout);
-
- public abstract Builder maxProposeTimeout(long maxProposeTimeout);
-
- public abstract Builder proposeTimeoutThreshold(int proposeTimeoutThreshold);
-
- public abstract ConsensusConfiguration build();
- }
-}
diff --git a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/StoredConfiguration.java b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/StoredConfiguration.java
deleted file mode 100644
index 51030467c0..0000000000
--- a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/StoredConfiguration.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2018 The Exonum Team
- *
- * 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 com.exonum.binding.common.configuration;
-
-import com.exonum.binding.common.hash.HashCode;
-import com.google.auto.value.AutoValue;
-import com.google.gson.Gson;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.SerializedName;
-import java.util.List;
-
-/**
- * Represents a blockchain configuration which is a set of values that determine
- * the network access parameters of a node and behavior of the node while operating in the network.
- *
- * See Exonum configuration for
- * configuration details.
- *
- *
Services configuration parameters would be available after
- * (https://jira.bf.local/browse/ECR-2683) would be implemented.
- */
-@AutoValue
-public abstract class StoredConfiguration {
-
- /**
- * Hash of the previous configuration, which can be used to find that configuration.
- */
- @SerializedName("previous_cfg_hash")
- public abstract HashCode previousCfgHash();
-
- /**
- * The height, starting from which this configuration becomes actual.
- */
- @SerializedName("actual_from")
- public abstract long actualFrom();
-
- /**
- * List of validators consensus and service public keys.
- *
- * @see Validator keys configuration section
- */
- @SerializedName("validator_keys")
- public abstract List validatorKeys();
-
- /**
- * Consensus algorithm parameters.
- */
- @SerializedName("consensus")
- public abstract ConsensusConfiguration consensusConfiguration();
-
- //TODO add majorityCount, services fields (https://jira.bf.local/browse/ECR-2683)
-
- /**
- * Provides a Gson type adapter for this class.
- *
- * @see com.exonum.binding.common.serialization.json.CommonTypeAdapterFactory
- */
- public static TypeAdapter typeAdapter(Gson gson) {
- return new AutoValue_StoredConfiguration.GsonTypeAdapter(gson);
- }
-
- public static Builder builder() {
- return new AutoValue_StoredConfiguration.Builder();
- }
-
- @AutoValue.Builder
- public abstract static class Builder {
- public abstract Builder previousCfgHash(HashCode previousCfgHash);
-
- public abstract Builder actualFrom(long actualFrom);
-
- public abstract Builder validatorKeys(List validatorKeys);
-
- public abstract Builder consensusConfiguration(ConsensusConfiguration consensusConfiguration);
-
- public abstract StoredConfiguration build();
- }
-}
diff --git a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/ValidatorKey.java b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/ValidatorKey.java
deleted file mode 100644
index 1d5e3ff39b..0000000000
--- a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/configuration/ValidatorKey.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2018 The Exonum Team
- *
- * 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 com.exonum.binding.common.configuration;
-
-import com.exonum.binding.common.crypto.PublicKey;
-import com.google.auto.value.AutoValue;
-import com.google.gson.Gson;
-import com.google.gson.TypeAdapter;
-import com.google.gson.annotations.SerializedName;
-
-/**
- * Public keys of validator nodes.
- */
-@AutoValue
-public abstract class ValidatorKey {
- /**
- * Consensus key is used for messages related to the consensus algorithm.
- */
- @SerializedName("consensus_key")
- public abstract PublicKey consensusKey();
-
- /**
- * Service key is used for services, for example, the configuration updater service.
- */
- @SerializedName("service_key")
- public abstract PublicKey serviceKey();
-
- /**
- * Provides a Gson type adapter for this class.
- *
- * @see com.exonum.binding.common.serialization.json.CommonTypeAdapterFactory
- */
- public static TypeAdapter typeAdapter(Gson gson) {
- return new AutoValue_ValidatorKey.GsonTypeAdapter(gson);
- }
-
- public static ValidatorKey.Builder builder() {
- return new AutoValue_ValidatorKey.Builder();
- }
-
- @AutoValue.Builder
- public abstract static class Builder {
- public abstract Builder consensusKey(PublicKey consensusKey);
-
- public abstract Builder serviceKey(PublicKey serviceKey);
-
- public abstract ValidatorKey build();
- }
-}
diff --git a/exonum-java-binding/common/src/test/java/com/exonum/binding/common/serialization/json/StoredConfigurationGsonSerializerTest.java b/exonum-java-binding/common/src/test/java/com/exonum/binding/common/serialization/json/StoredConfigurationGsonSerializerTest.java
deleted file mode 100644
index 2cc8378d27..0000000000
--- a/exonum-java-binding/common/src/test/java/com/exonum/binding/common/serialization/json/StoredConfigurationGsonSerializerTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2018 The Exonum Team
- *
- * 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 com.exonum.binding.common.serialization.json;
-
-import static com.exonum.binding.common.serialization.json.JsonSerializer.json;
-import static java.util.Collections.singletonList;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import com.exonum.binding.common.configuration.ConsensusConfiguration;
-import com.exonum.binding.common.configuration.StoredConfiguration;
-import com.exonum.binding.common.configuration.ValidatorKey;
-import com.exonum.binding.common.crypto.PublicKey;
-import com.exonum.binding.common.hash.HashCode;
-import java.util.List;
-import org.junit.jupiter.api.Test;
-
-class StoredConfigurationGsonSerializerTest {
-
- private static final String CONFIG_EXAMPLE = "{\n"
- + "\"previous_cfg_hash\": \"000000000000000000000000000000000000000000000000000000000000000"
- + "0\",\n"
- + "\"actual_from\": 0,\n"
- + "\"validator_keys\": [\n"
- + " {\n"
- + " \"consensus_key\": \"43eb3be553c55b02b65e08c18bb060404b27e362ccf108cbad94ea097de"
- + "cbc0a\",\n"
- + " \"service_key\": \"79c1fcefcbfaeae43575ab0ef793c24aae7b39186244e6552c18b8f7d0b0d"
- + "e12\"\n"
- + " }\n"
- + "],\n"
- + "\"consensus\": {\n"
- + " \"first_round_timeout\": 3000,\n"
- + " \"status_timeout\": 5000,\n"
- + " \"peers_timeout\": 10000,\n"
- + " \"txs_block_limit\": 1000,\n"
- + " \"max_message_len\": 1048576,\n"
- + " \"min_propose_timeout\": 10,\n"
- + " \"max_propose_timeout\": 200,\n"
- + " \"propose_timeout_threshold\": 500\n"
- + "},\n"
- + "\"majority_count\": null,\n"
- + "\"services\": {\n"
- + " \"configuration\": null,\n"
- + " \"cryptocurrency-demo\": null\n"
- + "}\n"
- + "}";
-
- @Test
- void roundTripTest() {
- StoredConfiguration configuration = createConfiguration();
- StoredConfiguration restoredConfiguration = json().fromJson(
- json().toJson(configuration), StoredConfiguration.class);
-
- assertThat(restoredConfiguration, equalTo(configuration));
- }
-
- @Test
- void readConfiguration() {
- StoredConfiguration configuration = json()
- .fromJson(CONFIG_EXAMPLE, StoredConfiguration.class);
-
- assertThat(configuration, notNullValue());
- assertThat(configuration.previousCfgHash(),
- is(HashCode
- .fromString("0000000000000000000000000000000000000000000000000000000000000000"))
- );
- assertThat(configuration.actualFrom(), is(0L));
-
- ConsensusConfiguration consensusConfiguration = configuration.consensusConfiguration();
- assertThat(consensusConfiguration, notNullValue());
- assertThat(consensusConfiguration.maxMessageLen(), is(1048576));
- assertThat(consensusConfiguration.maxProposeTimeout(), is(200L));
- assertThat(consensusConfiguration.minProposeTimeout(), is(10L));
- assertThat(consensusConfiguration.peersTimeout(), is(10000L));
- assertThat(consensusConfiguration.proposeTimeoutThreshold(), is(500));
- assertThat(consensusConfiguration.firstRoundTimeout(), is(3000L));
- assertThat(consensusConfiguration.statusTimeout(), is(5000L));
- assertThat(consensusConfiguration.txsBlockLimit(), is(1000));
-
- List expectedValidatorKeys = singletonList(ValidatorKey.builder()
- .consensusKey(PublicKey.fromHexString(
- "43eb3be553c55b02b65e08c18bb060404b27e362ccf108cbad94ea097decbc0a"))
- .serviceKey(PublicKey.fromHexString(
- "79c1fcefcbfaeae43575ab0ef793c24aae7b39186244e6552c18b8f7d0b0de12"))
- .build());
- assertThat(configuration.validatorKeys(), is(expectedValidatorKeys));
- }
-
- private StoredConfiguration createConfiguration() {
- return StoredConfiguration.builder()
- .previousCfgHash(HashCode.fromString("11"))
- .actualFrom(1)
- .validatorKeys(
- singletonList(
- ValidatorKey.builder()
- .consensusKey(PublicKey.fromHexString("22"))
- .serviceKey(PublicKey.fromHexString("33"))
- .build()
- )
- )
- .consensusConfiguration(
- ConsensusConfiguration.builder()
- .firstRoundTimeout(1)
- .statusTimeout(2)
- .peersTimeout(3)
- .txsBlockLimit(4)
- .maxMessageLen(5)
- .minProposeTimeout(6)
- .maxProposeTimeout(7)
- .proposeTimeoutThreshold(8)
- .build()
- )
- .build();
- }
-}
diff --git a/exonum-java-binding/core/src/main/java/com/exonum/binding/core/blockchain/Blockchain.java b/exonum-java-binding/core/src/main/java/com/exonum/binding/core/blockchain/Blockchain.java
index 0f04b98971..454b5a0fd6 100644
--- a/exonum-java-binding/core/src/main/java/com/exonum/binding/core/blockchain/Blockchain.java
+++ b/exonum-java-binding/core/src/main/java/com/exonum/binding/core/blockchain/Blockchain.java
@@ -20,7 +20,6 @@
import com.exonum.binding.common.blockchain.TransactionLocation;
import com.exonum.binding.common.blockchain.TransactionResult;
-import com.exonum.binding.common.configuration.StoredConfiguration;
import com.exonum.binding.common.hash.HashCode;
import com.exonum.binding.common.message.TransactionMessage;
import com.exonum.binding.core.storage.database.View;
@@ -29,6 +28,7 @@
import com.exonum.binding.core.storage.indices.MapIndex;
import com.exonum.binding.core.storage.indices.ProofListIndexProxy;
import com.exonum.binding.core.storage.indices.ProofMapIndexProxy;
+import com.exonum.binding.messages.Blockchain.Config;
import com.google.common.annotations.VisibleForTesting;
import java.util.Optional;
@@ -231,13 +231,14 @@ public Block getLastBlock() {
}
/**
- * Returns the configuration for the latest height of the blockchain, including services and their
- * parameters.
+ * Returns the current consensus configuration of the network.
*
- * @throws RuntimeException if the "genesis block" was not created
+ * @throws IllegalStateException if the "genesis block" was not created
+ * @see Exonum configuration for
+ * consensus configuration information.
*/
- public StoredConfiguration getActualConfiguration() {
- return schema.getActualConfiguration();
+ public Config getConsensusConfiguration() {
+ return schema.getConsensusConfiguration();
}
/**
diff --git a/exonum-java-binding/core/src/main/java/com/exonum/binding/core/blockchain/CoreSchemaProxy.java b/exonum-java-binding/core/src/main/java/com/exonum/binding/core/blockchain/CoreSchemaProxy.java
index 22364b5833..00c97e17f3 100644
--- a/exonum-java-binding/core/src/main/java/com/exonum/binding/core/blockchain/CoreSchemaProxy.java
+++ b/exonum-java-binding/core/src/main/java/com/exonum/binding/core/blockchain/CoreSchemaProxy.java
@@ -16,12 +16,11 @@
package com.exonum.binding.core.blockchain;
-import static com.exonum.binding.common.serialization.json.JsonSerializer.json;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
import com.exonum.binding.common.blockchain.TransactionLocation;
import com.exonum.binding.common.blockchain.TransactionResult;
-import com.exonum.binding.common.configuration.StoredConfiguration;
import com.exonum.binding.common.hash.HashCode;
import com.exonum.binding.common.message.TransactionMessage;
import com.exonum.binding.common.serialization.Serializer;
@@ -33,6 +32,7 @@
import com.exonum.binding.core.proxy.NativeHandle;
import com.exonum.binding.core.proxy.ProxyDestructor;
import com.exonum.binding.core.storage.database.View;
+import com.exonum.binding.core.storage.indices.EntryIndexProxy;
import com.exonum.binding.core.storage.indices.KeySetIndexProxy;
import com.exonum.binding.core.storage.indices.ListIndex;
import com.exonum.binding.core.storage.indices.ListIndexProxy;
@@ -41,6 +41,7 @@
import com.exonum.binding.core.storage.indices.ProofListIndexProxy;
import com.exonum.binding.core.storage.indices.ProofMapIndexProxy;
import com.exonum.binding.core.util.LibraryLoader;
+import com.exonum.binding.messages.Blockchain.Config;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -64,6 +65,8 @@ final class CoreSchemaProxy {
TransactionResultSerializer.INSTANCE;
private static final Serializer TRANSACTION_MESSAGE_SERIALIZER =
StandardSerializers.transactionMessage();
+ private static final Serializer CONSENSUS_CONFIG_SERIALIZER =
+ StandardSerializers.protobuf(Config.class);
private CoreSchemaProxy(NativeHandle nativeHandle, View dbView) {
this.nativeHandle = nativeHandle;
@@ -175,14 +178,16 @@ KeySetIndexProxy getTransactionPool() {
}
/**
- * Returns the configuration for the latest height of the blockchain.
+ * Returns the current consensus configuration of the network.
*
- * @throws RuntimeException if the "genesis block" was not created
+ * @throws IllegalStateException if the "genesis block" was not created
*/
- StoredConfiguration getActualConfiguration() {
- String rawConfiguration = nativeGetActualConfiguration(nativeHandle.get());
-
- return json().fromJson(rawConfiguration, StoredConfiguration.class);
+ Config getConsensusConfiguration() {
+ EntryIndexProxy configEntry = EntryIndexProxy.newInstance(CoreIndex.CONSENSUS_CONFIG,
+ dbView, CONSENSUS_CONFIG_SERIALIZER);
+ checkState(configEntry.isPresent(), "No consensus configuration: requesting the configuration "
+ + "before the genesis block was created");
+ return configEntry.get();
}
private static native long nativeCreate(long viewNativeHandle);
@@ -191,8 +196,6 @@ StoredConfiguration getActualConfiguration() {
private static native long nativeGetHeight(long nativeHandle);
- private static native String nativeGetActualConfiguration(long nativeHandle);
-
/**
* Returns the latest committed block.
*
@@ -211,6 +214,7 @@ private byte[] toCoreStorageKey(long value) {
* Mapping for Exonum core indexes by name.
*/
private static final class CoreIndex {
+
private static final String PREFIX = "core.";
private static final String BLOCK_TRANSACTIONS = PREFIX + "block_transactions";
private static final String ALL_BLOCK_HASHES = PREFIX + "block_hashes_by_height";
@@ -219,6 +223,7 @@ private static final class CoreIndex {
private static final String TRANSACTIONS_RESULTS = PREFIX + "transaction_results";
private static final String TRANSACTIONS_LOCATIONS = PREFIX + "transactions_locations";
private static final String TRANSACTIONS_POOL = PREFIX + "transactions_pool";
+ private static final String CONSENSUS_CONFIG = "consensus.config";
}
}
diff --git a/exonum-java-binding/core/src/test/java/com/exonum/binding/core/blockchain/CoreSchemaProxyIntegrationTest.java b/exonum-java-binding/core/src/test/java/com/exonum/binding/core/blockchain/CoreSchemaProxyIntegrationTest.java
index 7bc6ad2561..e3e2ba5c45 100644
--- a/exonum-java-binding/core/src/test/java/com/exonum/binding/core/blockchain/CoreSchemaProxyIntegrationTest.java
+++ b/exonum-java-binding/core/src/test/java/com/exonum/binding/core/blockchain/CoreSchemaProxyIntegrationTest.java
@@ -30,7 +30,6 @@
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import java.util.function.Consumer;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@RequiresNativeLibrary
@@ -58,9 +57,9 @@ void getBlockTransactionsTest() {
}
@Test
- @Disabled("ECR-3612")
- void getActiveConfigurationBeforeGenesisBlock() {
- assertSchema((schema) -> assertThrows(RuntimeException.class, schema::getActualConfiguration));
+ void getConsensusConfigurationBeforeGenesisBlock() {
+ assertSchema((schema) ->
+ assertThrows(IllegalStateException.class, schema::getConsensusConfiguration));
}
@Test
diff --git a/exonum-java-binding/integration-tests/src/test/java/com/exonum/binding/test/BlockchainIntegrationTest.java b/exonum-java-binding/integration-tests/src/test/java/com/exonum/binding/test/BlockchainIntegrationTest.java
index 1a35fbf898..205fe74e26 100644
--- a/exonum-java-binding/integration-tests/src/test/java/com/exonum/binding/test/BlockchainIntegrationTest.java
+++ b/exonum-java-binding/integration-tests/src/test/java/com/exonum/binding/test/BlockchainIntegrationTest.java
@@ -25,8 +25,6 @@
import com.exonum.binding.common.blockchain.TransactionLocation;
import com.exonum.binding.common.blockchain.TransactionResult;
-import com.exonum.binding.common.configuration.StoredConfiguration;
-import com.exonum.binding.common.configuration.ValidatorKey;
import com.exonum.binding.common.crypto.CryptoFunction;
import com.exonum.binding.common.crypto.CryptoFunctions;
import com.exonum.binding.common.crypto.KeyPair;
@@ -42,6 +40,8 @@
import com.exonum.binding.core.storage.indices.MapIndex;
import com.exonum.binding.core.storage.indices.ProofMapIndexProxy;
import com.exonum.binding.core.transaction.RawTransaction;
+import com.exonum.binding.messages.Blockchain.Config;
+import com.exonum.binding.messages.Blockchain.ValidatorKeys;
import com.exonum.binding.testkit.EmulatedNode;
import com.exonum.binding.testkit.TestKit;
import com.google.common.collect.ImmutableList;
@@ -387,24 +387,24 @@ void getLastBlock() {
}
@Test
- void getActualConfiguration() {
+ void getConsensusConfiguration() {
testKitTest((blockchain) -> {
- StoredConfiguration configuration = blockchain.getActualConfiguration();
- List validatorKeys = configuration.validatorKeys();
+ Config configuration = blockchain.getConsensusConfiguration();
+ int numKeysInConfig = configuration.getValidatorKeysCount();
// Check the number of validator keys
- assertThat(validatorKeys).hasSize(VALIDATOR_COUNT);
-
- // Check the public key of the emulated node is included
- List serviceKeys = validatorKeys.stream()
- .map(ValidatorKey::serviceKey)
+ assertThat(numKeysInConfig).isEqualTo(VALIDATOR_COUNT);
+
+ // Check the public service key of the emulated node is included
+ List serviceKeys = configuration.getValidatorKeysList().stream()
+ .map(ValidatorKeys::getServiceKey)
+ // fixme: [ECR-3734] highly error-prone and verbose key#getData.toByteArray susceptible
+ // to incorrect key#toByteArray.
+ .map(key -> PublicKey.fromBytes(key.getData().toByteArray()))
.collect(toList());
EmulatedNode emulatedNode = testKit.getEmulatedNode();
PublicKey emulatedNodeServiceKey = emulatedNode.getServiceKeyPair().getPublicKey();
List expectedKeys = ImmutableList.of(emulatedNodeServiceKey);
assertThat(serviceKeys).isEqualTo(expectedKeys);
-
- // Check the previous config is empty
- assertThat(configuration.previousCfgHash()).isEqualTo(ZERO_HASH_CODE);
});
}
diff --git a/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/ApiController.java b/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/ApiController.java
index ec1aa32161..cbf36ea7c0 100644
--- a/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/ApiController.java
+++ b/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/ApiController.java
@@ -18,7 +18,7 @@
import static com.exonum.binding.common.serialization.json.JsonSerializer.json;
import static com.exonum.binding.qaservice.ApiController.QaPaths.COUNTER_ID_PARAM;
-import static com.exonum.binding.qaservice.ApiController.QaPaths.GET_ACTUAL_CONFIGURATION_PATH;
+import static com.exonum.binding.qaservice.ApiController.QaPaths.GET_CONSENSUS_CONFIGURATION_PATH;
import static com.exonum.binding.qaservice.ApiController.QaPaths.GET_COUNTER_PATH;
import static com.exonum.binding.qaservice.ApiController.QaPaths.SUBMIT_CREATE_COUNTER_TX_PATH;
import static com.exonum.binding.qaservice.ApiController.QaPaths.SUBMIT_INCREMENT_COUNTER_TX_PATH;
@@ -30,19 +30,21 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static com.google.common.net.HttpHeaders.LOCATION;
+import static com.google.common.net.MediaType.OCTET_STREAM;
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
import static java.net.HttpURLConnection.HTTP_CREATED;
import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
-import com.exonum.binding.common.configuration.StoredConfiguration;
import com.exonum.binding.common.crypto.PublicKey;
import com.exonum.binding.common.hash.HashCode;
+import com.exonum.binding.messages.Blockchain.Config;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
+import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Router;
@@ -80,7 +82,7 @@ void mountApi(Router router) {
.put(SUBMIT_VALID_ERROR_TX_PATH, this::submitValidErrorTx)
.put(SUBMIT_UNKNOWN_TX_PATH, this::submitUnknownTx)
.put(GET_COUNTER_PATH, this::getCounter)
- .put(GET_ACTUAL_CONFIGURATION_PATH, this::getActualConfiguration)
+ .put(GET_CONSENSUS_CONFIGURATION_PATH, this::getConsensusConfiguration)
.put(TIME_PATH, this::getTime)
.put(VALIDATORS_TIMES_PATH, this::getValidatorsTimes)
.build();
@@ -138,9 +140,12 @@ private void getCounter(RoutingContext rc) {
respondWithJson(rc, counter);
}
- private void getActualConfiguration(RoutingContext rc) {
- StoredConfiguration configuration = service.getActualConfiguration();
- respondWithJson(rc, configuration);
+ private void getConsensusConfiguration(RoutingContext rc) {
+ Config configuration = service.getConsensusConfiguration();
+
+ rc.response()
+ .putHeader(CONTENT_TYPE, OCTET_STREAM.toString())
+ .write(Buffer.buffer(configuration.toByteArray()));
}
private void getTime(RoutingContext rc) {
@@ -256,7 +261,7 @@ static class QaPaths {
static final String COUNTER_ID_PARAM = "counterId";
static final String GET_COUNTER_PATH = "/counter/:" + COUNTER_ID_PARAM;
@VisibleForTesting
- static final String GET_ACTUAL_CONFIGURATION_PATH = "/actualConfiguration";
+ static final String GET_CONSENSUS_CONFIGURATION_PATH = "/consensusConfiguration";
@VisibleForTesting
static final String TIME_PATH = "/time";
@VisibleForTesting
diff --git a/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaService.java b/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaService.java
index 712d0f91d8..e3d45697b2 100644
--- a/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaService.java
+++ b/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaService.java
@@ -16,10 +16,10 @@
package com.exonum.binding.qaservice;
-import com.exonum.binding.common.configuration.StoredConfiguration;
import com.exonum.binding.common.crypto.PublicKey;
import com.exonum.binding.common.hash.HashCode;
import com.exonum.binding.core.service.Service;
+import com.exonum.binding.messages.Blockchain.Config;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.Optional;
@@ -45,7 +45,7 @@ public interface QaService extends Service {
Optional getValue(HashCode counterId);
- StoredConfiguration getActualConfiguration();
+ Config getConsensusConfiguration();
Optional getTime();
diff --git a/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaServiceImpl.java b/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaServiceImpl.java
index 059faf1080..5678c9e01b 100644
--- a/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaServiceImpl.java
+++ b/exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaServiceImpl.java
@@ -20,7 +20,6 @@
import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;
-import com.exonum.binding.common.configuration.StoredConfiguration;
import com.exonum.binding.common.crypto.PublicKey;
import com.exonum.binding.common.hash.HashCode;
import com.exonum.binding.common.hash.Hashing;
@@ -36,6 +35,7 @@
import com.exonum.binding.core.storage.indices.EntryIndexProxy;
import com.exonum.binding.core.storage.indices.MapIndex;
import com.exonum.binding.core.transaction.RawTransaction;
+import com.exonum.binding.messages.Blockchain.Config;
import com.exonum.binding.qaservice.transactions.CreateCounterTx;
import com.exonum.binding.qaservice.transactions.ErrorTx;
import com.exonum.binding.qaservice.transactions.IncrementCounterTx;
@@ -190,13 +190,13 @@ public Optional getValue(HashCode counterId) {
}
@Override
- public StoredConfiguration getActualConfiguration() {
+ public Config getConsensusConfiguration() {
checkBlockchainInitialized();
return node.withSnapshot((view) -> {
Blockchain blockchain = Blockchain.newInstance(view);
- return blockchain.getActualConfiguration();
+ return blockchain.getConsensusConfiguration();
});
}
diff --git a/exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/ApiControllerIntegrationTest.java b/exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/ApiControllerIntegrationTest.java
index c80b689a53..2e4c9474ac 100644
--- a/exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/ApiControllerIntegrationTest.java
+++ b/exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/ApiControllerIntegrationTest.java
@@ -17,7 +17,7 @@
package com.exonum.binding.qaservice;
import static com.exonum.binding.common.hash.Hashing.sha256;
-import static com.exonum.binding.qaservice.ApiController.QaPaths.GET_ACTUAL_CONFIGURATION_PATH;
+import static com.exonum.binding.qaservice.ApiController.QaPaths.GET_CONSENSUS_CONFIGURATION_PATH;
import static com.exonum.binding.qaservice.ApiController.QaPaths.SUBMIT_CREATE_COUNTER_TX_PATH;
import static com.exonum.binding.qaservice.ApiController.QaPaths.SUBMIT_INCREMENT_COUNTER_TX_PATH;
import static com.exonum.binding.qaservice.ApiController.QaPaths.SUBMIT_UNKNOWN_TX_PATH;
@@ -32,7 +32,6 @@
import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import static java.net.HttpURLConnection.HTTP_OK;
-import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.mockito.ArgumentMatchers.eq;
@@ -40,13 +39,11 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import com.exonum.binding.common.configuration.ConsensusConfiguration;
-import com.exonum.binding.common.configuration.StoredConfiguration;
-import com.exonum.binding.common.configuration.ValidatorKey;
import com.exonum.binding.common.crypto.PublicKey;
import com.exonum.binding.common.hash.HashCode;
import com.exonum.binding.common.serialization.json.JsonSerializer;
import com.exonum.binding.core.blockchain.serialization.CoreTypeAdapterFactory;
+import com.exonum.binding.messages.Blockchain.Config;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@@ -325,20 +322,19 @@ void multiMapTest() {
}
@Test
- void getActualConfiguration(VertxTestContext context) {
- StoredConfiguration configuration = createConfiguration();
- when(qaService.getActualConfiguration()).thenReturn(configuration);
+ void getConsensusConfiguration(VertxTestContext context) {
+ Config configuration = createConfiguration();
+ when(qaService.getConsensusConfiguration()).thenReturn(configuration);
- get(GET_ACTUAL_CONFIGURATION_PATH)
+ get(GET_CONSENSUS_CONFIGURATION_PATH)
.send(context.succeeding(response -> context.verify(() -> {
assertAll(
() -> assertThat(response.statusCode()).isEqualTo(HTTP_OK),
() -> {
- String body = response.bodyAsString();
- StoredConfiguration storedConfiguration = JSON_SERIALIZER
- .fromJson(body, StoredConfiguration.class);
+ Buffer body = response.bodyAsBuffer();
+ Config consensusConfig = Config.parseFrom(body.getBytes());
- assertThat(storedConfiguration).isEqualTo(configuration);
+ assertThat(consensusConfig).isEqualTo(configuration);
});
context.completeNow();
})));
@@ -431,30 +427,16 @@ private Handler>> checkCreatedTransaction(
}));
}
- private StoredConfiguration createConfiguration() {
- return StoredConfiguration.builder()
- .previousCfgHash(HashCode.fromString("11"))
- .actualFrom(1)
- .validatorKeys(
- singletonList(
- ValidatorKey.builder()
- .consensusKey(PublicKey.fromHexString("22"))
- .serviceKey(PublicKey.fromHexString("33"))
- .build()
- )
- )
- .consensusConfiguration(
- ConsensusConfiguration.builder()
- .firstRoundTimeout(1)
- .statusTimeout(2)
- .peersTimeout(3)
- .txsBlockLimit(4)
- .maxMessageLen(5)
- .minProposeTimeout(6)
- .maxProposeTimeout(7)
- .proposeTimeoutThreshold(8)
- .build()
- )
+ private static Config createConfiguration() {
+ return Config.newBuilder()
+ .setFirstRoundTimeout(1)
+ .setStatusTimeout(2)
+ .setPeersTimeout(3)
+ .setTxsBlockLimit(4)
+ .setMaxMessageLen(5)
+ .setMinProposeTimeout(6)
+ .setMaxProposeTimeout(7)
+ .setProposeTimeoutThreshold(8)
.build();
}
}
diff --git a/exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/QaServiceImplIntegrationTest.java b/exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/QaServiceImplIntegrationTest.java
index 6d424f59ab..70b54156a5 100644
--- a/exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/QaServiceImplIntegrationTest.java
+++ b/exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/QaServiceImplIntegrationTest.java
@@ -16,7 +16,6 @@
package com.exonum.binding.qaservice;
-import static com.exonum.binding.common.hash.Hashing.DEFAULT_HASH_SIZE_BYTES;
import static com.exonum.binding.common.hash.Hashing.sha256;
import static com.exonum.binding.qaservice.QaServiceImpl.AFTER_COMMIT_COUNTER_NAME;
import static com.exonum.binding.qaservice.QaServiceImpl.DEFAULT_COUNTER_NAME;
@@ -28,14 +27,14 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import com.exonum.binding.common.configuration.StoredConfiguration;
-import com.exonum.binding.common.configuration.ValidatorKey;
import com.exonum.binding.common.crypto.PublicKey;
import com.exonum.binding.common.hash.HashCode;
import com.exonum.binding.common.message.TransactionMessage;
import com.exonum.binding.core.service.Schema;
import com.exonum.binding.core.storage.database.Snapshot;
import com.exonum.binding.core.storage.indices.MapIndex;
+import com.exonum.binding.messages.Blockchain.Config;
+import com.exonum.binding.messages.Blockchain.ValidatorKeys;
import com.exonum.binding.qaservice.transactions.UnknownTx;
import com.exonum.binding.test.RequiresNativeLibrary;
import com.exonum.binding.testkit.EmulatedNode;
@@ -180,21 +179,19 @@ void afterCommit(TestKit testKit) {
}
@Test
- void getActualConfiguration(@ValidatorCount(NEW_VALIDATOR_COUNT) TestKit testKit) {
+ void getConsensusConfiguration(@ValidatorCount(NEW_VALIDATOR_COUNT) TestKit testKit) {
QaServiceImpl service = testKit.getService(QaService.ID, QaServiceImpl.class);
- StoredConfiguration configuration = service.getActualConfiguration();
+ Config configuration = service.getConsensusConfiguration();
- HashCode expectedPreviousCfgHash = HashCode.fromBytes(new byte[DEFAULT_HASH_SIZE_BYTES]);
- assertThat(configuration.previousCfgHash()).isEqualTo(expectedPreviousCfgHash);
+ assertThat(configuration.getValidatorKeysCount()).isEqualTo(NEW_VALIDATOR_COUNT);
EmulatedNode emulatedNode = testKit.getEmulatedNode();
- List validatorKeys = configuration.validatorKeys();
-
- assertThat(validatorKeys).hasSize(NEW_VALIDATOR_COUNT);
-
PublicKey emulatedNodeServiceKey = emulatedNode.getServiceKeyPair().getPublicKey();
- List serviceKeys = configuration.validatorKeys().stream()
- .map(ValidatorKey::serviceKey)
+ List serviceKeys = configuration.getValidatorKeysList().stream()
+ .map(ValidatorKeys::getServiceKey)
+ // fixme: [ECR-3734] highly error-prone and verbose key#getData.toByteArray susceptible
+ // to incorrect key#toByteArray.
+ .map(key -> PublicKey.fromBytes(key.getData().toByteArray()))
.collect(toList());
assertThat(serviceKeys).hasSize(NEW_VALIDATOR_COUNT);
diff --git a/exonum-java-binding/testkit/src/test/java/com/exonum/binding/testkit/TestKitParameterizationTest.java b/exonum-java-binding/testkit/src/test/java/com/exonum/binding/testkit/TestKitParameterizationTest.java
index 52559418a1..5b2fdd61ea 100644
--- a/exonum-java-binding/testkit/src/test/java/com/exonum/binding/testkit/TestKitParameterizationTest.java
+++ b/exonum-java-binding/testkit/src/test/java/com/exonum/binding/testkit/TestKitParameterizationTest.java
@@ -21,7 +21,6 @@
import com.exonum.binding.core.blockchain.Blockchain;
import com.exonum.binding.core.storage.database.Snapshot;
import java.util.function.Consumer;
-
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -59,7 +58,7 @@ void testTestKitValidatorCount(@ValidatorCount(NEW_VALIDATOR_COUNT) TestKit test
private static Consumer verifyNumValidators(int expected) {
return (view) -> {
Blockchain blockchain = Blockchain.newInstance(view);
- assertThat(blockchain.getActualConfiguration().validatorKeys().size())
+ assertThat(blockchain.getConsensusConfiguration().getValidatorKeysCount())
.isEqualTo(expected);
};
}
diff --git a/exonum-java-binding/testkit/src/test/java/com/exonum/binding/testkit/TestKitTest.java b/exonum-java-binding/testkit/src/test/java/com/exonum/binding/testkit/TestKitTest.java
index b9c824a066..d58f9f139d 100644
--- a/exonum-java-binding/testkit/src/test/java/com/exonum/binding/testkit/TestKitTest.java
+++ b/exonum-java-binding/testkit/src/test/java/com/exonum/binding/testkit/TestKitTest.java
@@ -186,7 +186,7 @@ void createTestKitWithSeveralValidators() {
.build()) {
Snapshot view = testKit.getSnapshot();
Blockchain blockchain = Blockchain.newInstance(view);
- assertThat(blockchain.getActualConfiguration().validatorKeys().size())
+ assertThat(blockchain.getConsensusConfiguration().getValidatorKeysCount())
.isEqualTo(validatorCount);
}
}
@@ -201,7 +201,7 @@ void createTestKitWithAuditorAndAdditionalValidators() {
.build()) {
Snapshot view = testKit.getSnapshot();
Blockchain blockchain = Blockchain.newInstance(view);
- assertThat(blockchain.getActualConfiguration().validatorKeys().size())
+ assertThat(blockchain.getConsensusConfiguration().getValidatorKeysCount())
.isEqualTo(validatorCount);
}
}