Skip to content

Commit

Permalink
Merge e096edc into 3516bbf
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-timofeev committed Aug 20, 2019
2 parents 3516bbf + e096edc commit 333d046
Show file tree
Hide file tree
Showing 113 changed files with 2,214 additions and 1,136 deletions.
9 changes: 6 additions & 3 deletions .travis.yml
Expand Up @@ -21,7 +21,6 @@ addons:
- build-essential
- libsodium-dev
- librocksdb5.17
- libsnappy-dev
- libssl-dev
- pkg-config
- protobuf-compiler
Expand All @@ -32,7 +31,6 @@ env:
- RUST_COMPILER_VERSION=1.36.0
- OSX_PACKAGES="libsodium rocksdb pkg-config protobuf"
- ROCKSDB_LIB_DIR=/usr/lib
- SNAPPY_LIB_DIR=/usr/lib/x86_64-linux-gnu
# REPO_TOKEN used for integration with coveralls is encoded here
- secure: Fp22iaJpttsIArAyWmdCGNtljIALTYRVKO7O+H2hgBkwHHqrU7+15sbaq3xzhz4YNWNfuFMIkFUBgd/KYHgAuNDDrtm2agib13C0lQT1NFQO9ccmNCJNsXQrYrXGwpnNqPKp0YmfBfgNwzEpBerlbtvzV/T/RZukT/403XxwxU9y5tHfQokwVLibqP2jJsxdihTfCKIOs+o6hBfArmsn+e+panEv17ZrCjOmBIM/W70Rf2rEM26wFnYsfnAUTCkpl4Ong0SYNpZZxNMtw61W8ApDY8bpz7cKUxCv7SmD3kO7Y+TTHWfWYx6FNXtUpE1vCi6I7fZAY16rViTWOX55NCeFQz56XER7ArJQZtC/nC1lZ9tGKtcofu2Rq7WUoRuTwvLTaf6VzAP/CUj0DUxkV+8WUggl3s/Im7Y9rn8Aqvh8LReZmqzTY+dJ0hFG4DLoLtl71eTEnNoumi5UleBhJPaei3wPNPHg1WlOmhFyhRCsbIIGiyFtSj/faLmdc7tN/sBFANb0g4Exl0mRNvB0IfS1gM6XouEGUTlVree68p11PnsGJGs/QaUB9F9AAGVKTZ2kz7sqkCDdGmLxzbdidYDHZtYWfOIYSJCQsA09n2Txi0fwNByKfl/spdyMmtI1uGeT803rhN9vu0NGrQFG3mU7mqO33fUDEStIQ6/xn0A=

Expand All @@ -51,7 +49,12 @@ matrix:
# Specify the image containing JDK 8
# See: https://docs.travis-ci.com/user/reference/osx#os-x-version
osx_image: xcode9.3
env: CHECK_RUST=false
env:
- CHECK_RUST=false
- ROCKSDB_LIB_DIR=/usr/local/lib
- ROCKSDB_STATIC=1
- SNAPPY_LIB_DIR=/usr/local/lib
- SNAPPY_STATIC=1
- name: "Linux JDK 12 CHECK_RUST=false"
os: linux
jdk: openjdk12
Expand Down
Expand Up @@ -19,7 +19,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;

import com.exonum.binding.core.runtime.ServiceRuntime;
import com.exonum.binding.core.storage.database.MemoryDb;
import com.exonum.binding.core.storage.database.TemporaryDb;
import com.exonum.binding.test.RequiresNativeLibrary;
import org.junit.jupiter.api.Test;

Expand All @@ -37,7 +37,7 @@ void createServiceRuntime() {

// Check that once createServiceRuntime returns, the native library is loaded. If it’s not,
// we’ll get an UnsatisfiedLinkError, failing the test.
try (MemoryDb database = MemoryDb.newInstance()) {
try (TemporaryDb database = TemporaryDb.newInstance()) {
assertNotNull(database);
}
}
Expand Down
Expand Up @@ -23,12 +23,12 @@
* A proof that some elements exist in a proof list.
* Example usage:
* <pre>{@code
* HashCode expectedRootHash = // get a known root hash from block proof //
* HashCode expectedIndexHash = // get a known index hash from block proof //
* UncheckedListProof proof = new UncheckedListProofAdapter(rootProofNode, serializer);
* // Check the proof
* CheckedListProof checkedProof = proof.check();
* // Check the root hash
* if (checkedProof.isValid() && checkedProof.getRootHash().equals(expectedRootHash)) {
* // Check the index hash
* if (checkedProof.isValid() && checkedProof.getIndexHash().equals(expectedIndexHash)) {
* // Get and use elements
* NavigableMap value = checkedProof.getElements();
* }
Expand Down
Expand Up @@ -27,7 +27,7 @@
*
* <p>If it is {@linkplain #isValid() correct} you may access:
* <ul>
* <li>a calculated Merkle root hash
* <li>a calculated index hash of corresponding collection
* <li>proof elements
* </ul>
* If the proof is not valid, you may get the verification status using
Expand All @@ -36,21 +36,21 @@
*/
public class CheckedListProofImpl<E> implements CheckedListProof {

private final HashCode calculatedRootHash;
private final HashCode calculatedIndexHash;

private final NavigableMap<Long, E> elements;

private final ListProofStatus proofStatus;

/**
* Creates checked list proof.
* @param calculatedRootHash calculated root hash of the proof
* @param calculatedIndexHash calculated index hash of the proof
* @param elements proof elements collection
* @param proofStatus a status of proof verification
*/
public CheckedListProofImpl(HashCode calculatedRootHash,
public CheckedListProofImpl(HashCode calculatedIndexHash,
NavigableMap<Long, E> elements, ListProofStatus proofStatus) {
this.calculatedRootHash = checkNotNull(calculatedRootHash);
this.calculatedIndexHash = checkNotNull(calculatedIndexHash);
this.elements = checkNotNull(elements);
this.proofStatus = checkNotNull(proofStatus);
}
Expand All @@ -64,7 +64,7 @@ public NavigableMap<Long, E> getElements() {
@Override
public HashCode getRootHash() {
checkValid();
return calculatedRootHash;
return calculatedIndexHash;
}

@Override
Expand Down
@@ -0,0 +1,49 @@
/*
* 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.common.proofs.list;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* Represents a proof that some elements exist in a ProofList at certain positions and the length
* of corresponding index.
*/
public final class ListProof {

private final ListProofNode rootNode;

private final long length;

public ListProof(ListProofNode rootNode, long length) {
this.rootNode = checkNotNull(rootNode);
this.length = length;
}

/**
* Returns the root node of the proof tree.
*/
public ListProofNode getRootNode() {
return rootNode;
}

/**
* Returns the length of the corresponding index.
*/
public long getLength() {
return length;
}
}
Expand Up @@ -25,16 +25,25 @@
import com.exonum.binding.common.hash.PrimitiveSink;
import com.exonum.binding.common.serialization.CheckingSerializerDecorator;
import com.exonum.binding.common.serialization.Serializer;
import com.google.common.annotations.VisibleForTesting;

import java.util.NavigableMap;
import java.util.Optional;
import java.util.TreeMap;

/**
* List proof root hash calculator.
* List proof hash calculator.
*
* @param <E> the type of elements in the corresponding list
*/
final class ListProofRootHashCalculator<E> implements ListProofVisitor {
final class ListProofHashCalculator<E> implements ListProofVisitor {

@VisibleForTesting
static final byte BLOB_PREFIX = 0x00;
@VisibleForTesting
static final byte LIST_BRANCH_PREFIX = 0x01;
@VisibleForTesting
static final byte LIST_ROOT_PREFIX = 0x02;

private final CheckingSerializerDecorator<E> serializer;

Expand All @@ -44,26 +53,33 @@ final class ListProofRootHashCalculator<E> implements ListProofVisitor {

private long index;

private HashCode calculatedRootHash;
private HashCode hash;

/**
* Creates a new ListProofRootHashCalculator.
* Creates a new ListProofHashCalculator.
*
* @param serializer a serializer of list elements
*/
ListProofRootHashCalculator(ListProofNode listProof, Serializer<E> serializer) {
ListProofHashCalculator(ListProof listProof, Serializer<E> serializer) {
this(listProof, serializer, Hashing.defaultHashFunction());
}

private ListProofRootHashCalculator(ListProofNode listProof, Serializer<E> serializer,
HashFunction hashFunction) {
private ListProofHashCalculator(ListProof listProof, Serializer<E> serializer,
HashFunction hashFunction) {
this.serializer = CheckingSerializerDecorator.from(serializer);
this.hashFunction = checkNotNull(hashFunction);
elements = new TreeMap<>();
index = 0;
calculatedRootHash = null;
hash = null;

ListProofNode rootNode = listProof.getRootNode();
rootNode.accept(this);

listProof.accept(this);
hash = hashFunction.newHasher()
.putByte(LIST_ROOT_PREFIX)
.putLong(listProof.getLength())
.putObject(hash, hashCodeFunnel())
.hash();
}

@Override
Expand All @@ -72,7 +88,8 @@ public void visit(ListProofBranch branch) {
HashCode leftHash = visitLeft(branch, branchIndex);
Optional<HashCode> rightHash = visitRight(branch, branchIndex);

calculatedRootHash = hashFunction.newHasher()
hash = hashFunction.newHasher()
.putByte(LIST_BRANCH_PREFIX)
.putObject(leftHash, hashCodeFunnel())
.putObject(rightHash, (Optional<HashCode> from, PrimitiveSink into) ->
from.ifPresent((hash) -> hashCodeFunnel().funnel(hash, into)))
Expand All @@ -81,7 +98,7 @@ public void visit(ListProofBranch branch) {

@Override
public void visit(ListProofHashNode listProofHashNode) {
this.calculatedRootHash = listProofHashNode.getHash();
this.hash = listProofHashNode.getHash();
}

@Override
Expand All @@ -92,20 +109,23 @@ public void visit(ListProofElement value) {

E element = serializer.fromBytes(value.getElement().toByteArray());
elements.put(index, element);
calculatedRootHash = hashFunction.hashObject(value, ListProofElement.funnel());
hash = hashFunction.newHasher()
.putByte(BLOB_PREFIX)
.putObject(value, ListProofElement.funnel())
.hash();
}

private HashCode visitLeft(ListProofBranch branch, long parentIndex) {
index = 2 * parentIndex;
branch.getLeft().accept(this);
return calculatedRootHash;
return hash;
}

private Optional<HashCode> visitRight(ListProofBranch branch, long parentIndex) {
index = 2 * parentIndex + 1;
calculatedRootHash = null;
hash = null;
branch.getRight().ifPresent((right) -> right.accept(this));
return Optional.ofNullable(calculatedRootHash);
return Optional.ofNullable(hash);
}

/**
Expand All @@ -116,18 +136,16 @@ NavigableMap<Long, E> getElements() {
}

/**
* Returns calculated root hash of a list proof tree.
*
* @return hash code
* Returns calculated hash of the list proof.
*/
HashCode getCalculatedRootHash() {
return calculatedRootHash;
HashCode getHash() {
return hash;
}

@Override
public String toString() {
return "ListProofStructureValidator{"
+ "calculatedRootHash=" + calculatedRootHash
return "ListProofHashCalculator{"
+ "hash=" + hash
+ ", elements=" + elements
+ ", index=" + index
+ '}';
Expand Down
Expand Up @@ -18,7 +18,7 @@

/**
* A proof that some elements exist in a proof list. You must
* {@link #check} its structure and root hash before accessing the elements.
* {@link #check} its structure and index hash before accessing the elements.
*/
public interface UncheckedListProof {

Expand All @@ -30,5 +30,5 @@ public interface UncheckedListProof {
/**
* Returns raw source proof of this UncheckedListProof.
*/
ListProofNode getRootProofNode();
ListProof getListProof();
}
Expand Up @@ -25,41 +25,41 @@
*/
public class UncheckedListProofAdapter<E> implements UncheckedListProof {

private final ListProofNode rootProofNode;
private final ListProof listProof;

private final ListProofStructureValidator listProofStructureValidator;

private final ListProofRootHashCalculator<E> listProofRootHashCalculator;
private final ListProofHashCalculator<E> listProofHashCalculator;

/**
* Creates UncheckedListProofAdapter for convenient usage of ListProof interfaces.
*
* <p>UncheckedListProofAdapter {@link #check()} method will return CheckedListProof containing
* results of list proof verification.
*
* @param rootProofNode source list proof
* @param listProof source list proof with index length
* @param serializer proof elements serializer
*/
public UncheckedListProofAdapter(ListProofNode rootProofNode, Serializer<E> serializer) {
Preconditions.checkNotNull(rootProofNode, "ListProof node must be not null");
public UncheckedListProofAdapter(ListProof listProof, Serializer<E> serializer) {
Preconditions.checkNotNull(listProof, "ListProof node must be not null");
Preconditions.checkNotNull(serializer, "Serializer must be not null");

this.rootProofNode = rootProofNode;
this.listProofStructureValidator = new ListProofStructureValidator(rootProofNode);
this.listProofRootHashCalculator = new ListProofRootHashCalculator<>(rootProofNode, serializer);
this.listProof = listProof;
this.listProofStructureValidator = new ListProofStructureValidator(listProof.getRootNode());
this.listProofHashCalculator = new ListProofHashCalculator<>(listProof, serializer);
}

@Override
public CheckedListProof check() {
ListProofStatus structureCheckStatus = listProofStructureValidator.getProofStatus();
HashCode calculatedRootHash = listProofRootHashCalculator.getCalculatedRootHash();
HashCode calculatedIndexHash = listProofHashCalculator.getHash();

return new CheckedListProofImpl<>(
calculatedRootHash, listProofRootHashCalculator.getElements(), structureCheckStatus);
calculatedIndexHash, listProofHashCalculator.getElements(), structureCheckStatus);
}

@Override
public ListProofNode getRootProofNode() {
return rootProofNode;
public ListProof getListProof() {
return listProof;
}
}

0 comments on commit 333d046

Please sign in to comment.