diff --git a/exonum-java-binding/benchmarks/pom.xml b/exonum-java-binding/benchmarks/pom.xml
index f20adbebb5..031339ce0a 100644
--- a/exonum-java-binding/benchmarks/pom.xml
+++ b/exonum-java-binding/benchmarks/pom.xml
@@ -66,6 +66,17 @@ THE POSSIBILITY OF SUCH DAMAGE.
${jmh.version}
provided
+
+
+ com.google.guava
+ guava
+
+
+
+ com.exonum.binding
+ exonum-java-binding-common
+ ${project.version}
+
@@ -91,6 +102,7 @@ THE POSSIBILITY OF SUCH DAMAGE.
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
org.openjdk.jmh.Main
+
diff --git a/exonum-java-binding/benchmarks/src/main/java/com/exonum/binding/bench/FlatListProofBenchmark.java b/exonum-java-binding/benchmarks/src/main/java/com/exonum/binding/bench/FlatListProofBenchmark.java
new file mode 100644
index 0000000000..ea8f08ac4b
--- /dev/null
+++ b/exonum-java-binding/benchmarks/src/main/java/com/exonum/binding/bench/FlatListProofBenchmark.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2019 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.bench;
+
+import static com.exonum.binding.common.hash.Hashing.sha256;
+import static com.exonum.binding.common.proofs.list.ListProofEntry.checkHeight;
+import static java.util.Collections.singletonList;
+
+import com.exonum.binding.common.hash.HashCode;
+import com.exonum.binding.common.proofs.list.CheckedListProof;
+import com.exonum.binding.common.proofs.list.FlatListProof;
+import com.exonum.binding.common.proofs.list.ListProofElementEntry;
+import com.exonum.binding.common.proofs.list.ListProofHashedEntry;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+public class FlatListProofBenchmark {
+
+ @Param({"10"})
+ private int height;
+
+ private FlatListProof proof;
+
+ /**
+ * Creates a proof for a single element from a tree of the given height.
+ */
+ @Setup(Level.Trial)
+ public void createProof() {
+ /*
+ o
+ / \
+ h
+ /
+ o
+ / \
+ o h
+ / \
+ e h
+ */
+ checkHeight(height);
+ long size = 1L << height;
+ // Create the element(s)
+ // The value size can also be made configurable, though it is not expected to have
+ // a large effect on anything but the first hashing step.
+ byte[] value = {1};
+ List elements = singletonList(
+ ListProofElementEntry.newInstance(0L, value));
+ // Create the hash nodes
+ List hashed = new ArrayList<>(height);
+ for (int h = 0; h < height; h++) {
+ HashCode hash = sha256().hashInt(h);
+ hashed.add(ListProofHashedEntry.newInstance(1L, h, hash));
+ }
+ proof = new FlatListProof(elements, hashed, size);
+ }
+
+ @Benchmark
+ public CheckedListProof> verify() {
+ return proof.verify();
+ }
+}
diff --git a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/FlatListProof.java b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/FlatListProof.java
index 19b22e7762..4115031028 100644
--- a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/FlatListProof.java
+++ b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/FlatListProof.java
@@ -45,7 +45,7 @@
* A flat list proof. It proves that certain elements are present in a proof list
* of a certain size.
*/
-class FlatListProof {
+public class FlatListProof {
/*
Proof lists are represented as BSTs, where all leaf elements are at the same height.
Here is a tree for a three-element proof list:
@@ -95,14 +95,14 @@ class FlatListProof {
private final List proof;
private final long size;
- FlatListProof(List elements,
+ public FlatListProof(List elements,
List proof, long size) {
this.elements = checkNotNull(elements);
this.proof = checkNotNull(proof);
this.size = size;
}
- CheckedListProof verify() {
+ public CheckedListProof verify() {
// Check the size
if (size < 0 || MAX_SIZE < size) {
throw new InvalidProofException(String.format("Invalid size (%s), must be in range [0; 2^56]",
diff --git a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofElementEntry.java b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofElementEntry.java
index f62a952e81..be46a98011 100644
--- a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofElementEntry.java
+++ b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofElementEntry.java
@@ -22,14 +22,14 @@
* A value stored in the Merkle tree at its bottom level (at height 0).
*/
@AutoValue
-abstract class ListProofElementEntry implements ListProofEntry {
+public abstract class ListProofElementEntry implements ListProofEntry {
/**
* Returns a value of the element stored at this index in the list.
*/
abstract byte[] getElement();
- static ListProofElementEntry newInstance(long index, byte[] element) {
+ public static ListProofElementEntry newInstance(long index, byte[] element) {
ListProofEntry.checkIndex(index);
return new AutoValue_ListProofElementEntry(index, element);
}
diff --git a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofEntry.java b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofEntry.java
index 8c462d4780..06770ad095 100644
--- a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofEntry.java
+++ b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofEntry.java
@@ -18,7 +18,7 @@
import static com.google.common.base.Preconditions.checkArgument;
-interface ListProofEntry {
+public interface ListProofEntry {
/**
* The maximum height of a list proof tree.
diff --git a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofHashedEntry.java b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofHashedEntry.java
index 2e72bda0a3..a23a62f42e 100644
--- a/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofHashedEntry.java
+++ b/exonum-java-binding/common/src/main/java/com/exonum/binding/common/proofs/list/ListProofHashedEntry.java
@@ -23,7 +23,7 @@
* A hash of a sub-tree in a Merkle proof tree.
*/
@AutoValue
-abstract class ListProofHashedEntry implements ListProofEntry {
+public abstract class ListProofHashedEntry implements ListProofEntry {
/**
* Returns the height of the proof tree node corresponding to this entry.
@@ -37,7 +37,7 @@ abstract class ListProofHashedEntry implements ListProofEntry {
*/
abstract HashCode getHash();
- static ListProofHashedEntry newInstance(long index, int height, HashCode nodeHash) {
+ public static ListProofHashedEntry newInstance(long index, int height, HashCode nodeHash) {
ListProofEntry.checkIndex(index);
ListProofEntry.checkHeight(height);
return new AutoValue_ListProofHashedEntry(index, height, nodeHash);