mirror of
https://github.com/corda/corda.git
synced 2025-01-18 10:46:38 +00:00
Style changes.
This commit is contained in:
parent
a5dfaa255d
commit
023ba380a0
@ -11,7 +11,7 @@ class MerkleTreeException(val reason: String): Exception() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Building and verification of Partial Merkle Tree.
|
* Building and verification of Partial Merkle Tree.
|
||||||
* Partial Merkle Tree is a minimal tree needed to check that given set of leaves belongs to a full Merkle Tree.
|
* Partial Merkle Tree is a minimal tree needed to check that a given set of leaves belongs to a full Merkle Tree.
|
||||||
*
|
*
|
||||||
* Example of Merkle tree with 5 leaves.
|
* Example of Merkle tree with 5 leaves.
|
||||||
*
|
*
|
||||||
@ -24,8 +24,8 @@ class MerkleTreeException(val reason: String): Exception() {
|
|||||||
* l1 l2 l3 l4 l5->d(l5)
|
* l1 l2 l3 l4 l5->d(l5)
|
||||||
*
|
*
|
||||||
* l* denote hashes of leaves, h* - hashes of nodes below.
|
* l* denote hashes of leaves, h* - hashes of nodes below.
|
||||||
* h5->d(h5) denotes duplication of left hand side node. These nodes are kept in a full tree as DuplicatedLeaf.
|
* h5->d(h5) denotes duplication of the left hand side node. These nodes are kept in a full tree as DuplicatedLeaf.
|
||||||
* When filtering the tree for l5, we don't want to keep both l5 and it's duplicate (it can also be solved using null
|
* When filtering the tree for l5, we don't want to keep both l5 and its duplicate (it can also be solved using null
|
||||||
* values in a tree, but this solution is clearer).
|
* values in a tree, but this solution is clearer).
|
||||||
*
|
*
|
||||||
* Example of Partial tree based on the tree above.
|
* Example of Partial tree based on the tree above.
|
||||||
@ -87,28 +87,26 @@ class PartialMerkleTree(val root: PartialTree) {
|
|||||||
includeHashes: List<SecureHash>,
|
includeHashes: List<SecureHash>,
|
||||||
usedHashes: MutableList<SecureHash>
|
usedHashes: MutableList<SecureHash>
|
||||||
): Pair<Boolean, PartialTree> {
|
): Pair<Boolean, PartialTree> {
|
||||||
if (root is MerkleTree.Leaf) {
|
return when (root) {
|
||||||
if (root.value in includeHashes) {
|
is MerkleTree.Leaf ->
|
||||||
usedHashes.add(root.value)
|
if (root.value in includeHashes) {
|
||||||
return Pair(true, PartialTree.IncludedLeaf(root.value))
|
usedHashes.add(root.value)
|
||||||
} else return Pair(false, PartialTree.Leaf(root.value))
|
Pair(true, PartialTree.IncludedLeaf(root.value))
|
||||||
} else if (root is MerkleTree.DuplicatedLeaf) {
|
} else Pair(false, PartialTree.Leaf(root.value))
|
||||||
//Duplicate leaves should be stored as normal leaves not included ones.
|
is MerkleTree.DuplicatedLeaf -> Pair(false, PartialTree.Leaf(root.value))
|
||||||
return Pair(false, PartialTree.Leaf(root.value))
|
is MerkleTree.Node -> {
|
||||||
} else if (root is MerkleTree.Node) {
|
val leftNode = buildPartialTree(root.left, includeHashes, usedHashes)
|
||||||
val leftNode = buildPartialTree(root.left, includeHashes, usedHashes)
|
val rightNode = buildPartialTree(root.right, includeHashes, usedHashes)
|
||||||
val rightNode = buildPartialTree(root.right, includeHashes, usedHashes)
|
if (leftNode.first or rightNode.first) {
|
||||||
if (leftNode.first or rightNode.first) {
|
//This node is on a path to some included leaves. Don't store hash.
|
||||||
//This node is on a path to some included leaves. Don't store hash.
|
val newTree = PartialTree.Node(leftNode.second, rightNode.second)
|
||||||
val newTree = PartialTree.Node(leftNode.second, rightNode.second)
|
return Pair(true, newTree)
|
||||||
return Pair(true, newTree)
|
} else {
|
||||||
} else {
|
//This node has no included leaves below. Cut the tree here and store a hash as a Leaf.
|
||||||
//This node has no included leaves below. Cut the tree here and store a hash as a Leaf.
|
val newTree = PartialTree.Leaf(root.value)
|
||||||
val newTree = PartialTree.Leaf(root.value)
|
return Pair(false, newTree)
|
||||||
return Pair(false, newTree)
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw MerkleTreeException("Invalid MerkleTree.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,7 +119,7 @@ class PartialMerkleTree(val root: PartialTree) {
|
|||||||
val usedHashes = ArrayList<SecureHash>()
|
val usedHashes = ArrayList<SecureHash>()
|
||||||
val verifyRoot = verify(root, usedHashes)
|
val verifyRoot = verify(root, usedHashes)
|
||||||
//It means that we obtained more/less hashes than needed or different sets of hashes.
|
//It means that we obtained more/less hashes than needed or different sets of hashes.
|
||||||
if(hashesToCheck.size != usedHashes.size || hashesToCheck.minus(usedHashes).isNotEmpty())
|
if (hashesToCheck.groupBy { it } != usedHashes.groupBy { it })
|
||||||
return false
|
return false
|
||||||
return (verifyRoot == merkleRootHash)
|
return (verifyRoot == merkleRootHash)
|
||||||
}
|
}
|
||||||
@ -130,18 +128,18 @@ class PartialMerkleTree(val root: PartialTree) {
|
|||||||
* Recursive calculation of root of this partial tree.
|
* Recursive calculation of root of this partial tree.
|
||||||
* Modifies usedHashes to later check for inclusion with hashes provided.
|
* Modifies usedHashes to later check for inclusion with hashes provided.
|
||||||
*/
|
*/
|
||||||
private fun verify(node: PartialTree, usedHashes: MutableList<SecureHash>): SecureHash{
|
private fun verify(node: PartialTree, usedHashes: MutableList<SecureHash>): SecureHash {
|
||||||
if (node is PartialTree.IncludedLeaf) {
|
return when (node) {
|
||||||
usedHashes.add(node.hash)
|
is PartialTree.IncludedLeaf -> {
|
||||||
return node.hash
|
usedHashes.add(node.hash)
|
||||||
} else if (node is PartialTree.Leaf ) {
|
node.hash
|
||||||
return node.hash
|
}
|
||||||
} else if (node is PartialTree.Node) {
|
is PartialTree.Leaf -> node.hash
|
||||||
val leftHash = verify(node.left, usedHashes)
|
is PartialTree.Node -> {
|
||||||
val rightHash = verify(node.right, usedHashes)
|
val leftHash = verify(node.left, usedHashes)
|
||||||
return leftHash.hashConcat(rightHash)
|
val rightHash = verify(node.right, usedHashes)
|
||||||
} else {
|
return leftHash.hashConcat(rightHash)
|
||||||
throw MerkleTreeException("Invalid node type.")
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ sealed class MerkleTree(val hash: SecureHash) {
|
|||||||
val right = when {
|
val right = when {
|
||||||
//If there is an odd number of elements at this level,
|
//If there is an odd number of elements at this level,
|
||||||
//the last element is hashed with itself and stored as a Leaf.
|
//the last element is hashed with itself and stored as a Leaf.
|
||||||
i+1 > n-1 -> MerkleTree.DuplicatedLeaf(lastNodesList[n-1].hash)
|
i + 1 > n - 1 -> MerkleTree.DuplicatedLeaf(lastNodesList[n-1].hash)
|
||||||
else -> lastNodesList[i+1]
|
else -> lastNodesList[i+1]
|
||||||
}
|
}
|
||||||
val combined = left.hashNodes(right)
|
val combined = left.hashNodes(right)
|
||||||
@ -112,10 +112,12 @@ class FilteredLeaves(
|
|||||||
* Holds filter functions on transactions fields.
|
* Holds filter functions on transactions fields.
|
||||||
* Functions are used to build a partial tree only out of some subset of original transaction fields.
|
* Functions are used to build a partial tree only out of some subset of original transaction fields.
|
||||||
*/
|
*/
|
||||||
class FilterFuns(val filterInputs: (StateRef) -> Boolean = { false },
|
class FilterFuns(
|
||||||
val filterOutputs: (TransactionState<ContractState>) -> Boolean = { false },
|
val filterInputs: (StateRef) -> Boolean = { false },
|
||||||
val filterAttachments: (SecureHash) -> Boolean = { false },
|
val filterOutputs: (TransactionState<ContractState>) -> Boolean = { false },
|
||||||
val filterCommands: (Command) -> Boolean = { false }) {
|
val filterAttachments: (SecureHash) -> Boolean = { false },
|
||||||
|
val filterCommands: (Command) -> Boolean = { false }
|
||||||
|
) {
|
||||||
fun <T: Any> genericFilter(elem: T): Boolean {
|
fun <T: Any> genericFilter(elem: T): Boolean {
|
||||||
return when (elem) {
|
return when (elem) {
|
||||||
is StateRef -> filterInputs(elem)
|
is StateRef -> filterInputs(elem)
|
||||||
|
@ -104,6 +104,14 @@ class PartialMerkleTreeTest {
|
|||||||
assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(merkleTree, inclHashes) }
|
assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(merkleTree, inclHashes) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `build Partial Merkle Tree - only duplicate leaves, less included failure`() {
|
||||||
|
val leaves = "aaa"
|
||||||
|
val hashes = leaves.map { it.serialize().hash }
|
||||||
|
val mt = MerkleTree.getMerkleTree(hashes)
|
||||||
|
assertFailsWith<MerkleTreeException> { PartialMerkleTree.build(mt, hashes.subList(0,1)) }
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `verify Partial Merkle Tree - too many leaves failure`() {
|
fun `verify Partial Merkle Tree - too many leaves failure`() {
|
||||||
val inclHashes = arrayListOf(hashed[3], hashed[5])
|
val inclHashes = arrayListOf(hashed[3], hashed[5])
|
||||||
|
Loading…
Reference in New Issue
Block a user