mirror of
https://github.com/corda/corda.git
synced 2024-12-19 04:57:58 +00:00
Moves filterFun and indexOffsets into MerkleTransaction.
This commit is contained in:
parent
8d29c78073
commit
574c476709
@ -159,11 +159,74 @@ class FilteredTransaction private constructor(
|
||||
fun buildMerkleTransaction(wtx: WireTransaction,
|
||||
filtering: Predicate<Any>
|
||||
): FilteredTransaction {
|
||||
val filteredLeaves = wtx.filterWithFun(filtering)
|
||||
val filteredLeaves = filterWithFun(wtx, filtering)
|
||||
val merkleTree = wtx.merkleTree
|
||||
val pmt = PartialMerkleTree.build(merkleTree, filteredLeaves.availableComponentHashes)
|
||||
return FilteredTransaction(merkleTree.hash, filteredLeaves, pmt)
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction of partial transaction from WireTransaction based on filtering.
|
||||
* Note that list of nonces to be sent is updated on the fly, based on the index of the filtered tx component.
|
||||
* @param filtering filtering over the whole WireTransaction
|
||||
* @returns FilteredLeaves used in PartialMerkleTree calculation and verification.
|
||||
*/
|
||||
private fun filterWithFun(wtx: WireTransaction, filtering: Predicate<Any>): FilteredLeaves {
|
||||
val nonces: MutableList<SecureHash> = mutableListOf()
|
||||
val offsets = indexOffsets(wtx)
|
||||
fun notNullFalseAndNoncesUpdate(elem: Any?, index: Int): Any? {
|
||||
return if (elem == null || !filtering.test(elem)) {
|
||||
null
|
||||
} else {
|
||||
nonces.add(computeNonce(wtx.privacySalt, index))
|
||||
elem
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Any> filterAndNoncesUpdate(t: T, index: Int): Boolean {
|
||||
return if (filtering.test(t)) {
|
||||
nonces.add(computeNonce(wtx.privacySalt, index))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We should have a warning (require) if all leaves (excluding salt) are visible after filtering.
|
||||
// Consider the above after refactoring FilteredTransaction to implement TraversableTransaction,
|
||||
// so that a WireTransaction can be used when required to send a full tx (e.g. RatesFixFlow in Oracles).
|
||||
return FilteredLeaves(
|
||||
wtx.inputs.filterIndexed { index, it -> filterAndNoncesUpdate(it, index) },
|
||||
wtx.attachments.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[0]) },
|
||||
wtx.outputs.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[1]) },
|
||||
wtx.commands.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[2]) },
|
||||
notNullFalseAndNoncesUpdate(wtx.notary, offsets[3]) as Party?,
|
||||
notNullFalseAndNoncesUpdate(wtx.timeWindow, offsets[4]) as TimeWindow?,
|
||||
nonces
|
||||
)
|
||||
}
|
||||
|
||||
// We use index offsets, to get the actual leaf-index per transaction component required for nonce computation.
|
||||
private fun indexOffsets(wtx: WireTransaction): List<Int> {
|
||||
// There is no need to add an index offset for inputs, because they are the first components in the
|
||||
// transaction format and it is always zero. Thus, offsets[0] corresponds to attachments,
|
||||
// offsets[1] to outputs, offsets[2] to commands and so on.
|
||||
val offsets = mutableListOf(wtx.inputs.size, wtx.inputs.size + wtx.attachments.size)
|
||||
offsets.add(offsets.last() + wtx.outputs.size)
|
||||
offsets.add(offsets.last() + wtx.commands.size)
|
||||
if (wtx.notary != null) {
|
||||
offsets.add(offsets.last() + 1)
|
||||
} else {
|
||||
offsets.add(offsets.last())
|
||||
}
|
||||
if (wtx.timeWindow != null) {
|
||||
offsets.add(offsets.last() + 1)
|
||||
} else {
|
||||
offsets.add(offsets.last())
|
||||
}
|
||||
// No need to add offset for privacySalt as it doesn't require a nonce.
|
||||
return offsets
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,69 +106,6 @@ data class WireTransaction(
|
||||
*/
|
||||
val merkleTree: MerkleTree by lazy { MerkleTree.getMerkleTree(availableComponentHashes) }
|
||||
|
||||
/**
|
||||
* Construction of partial transaction from WireTransaction based on filtering.
|
||||
* Note that list of nonces to be sent is updated on the fly, based on the index of the filtered tx component.
|
||||
* @param filtering filtering over the whole WireTransaction
|
||||
* @returns FilteredLeaves used in PartialMerkleTree calculation and verification.
|
||||
*/
|
||||
fun filterWithFun(filtering: Predicate<Any>): FilteredLeaves {
|
||||
val nonces: MutableList<SecureHash> = mutableListOf()
|
||||
val offsets = indexOffsets()
|
||||
fun notNullFalseAndNoncesUpdate(elem: Any?, index: Int): Any? {
|
||||
return if (elem == null || !filtering.test(elem)) {
|
||||
null
|
||||
} else {
|
||||
nonces.add(computeNonce(privacySalt, index))
|
||||
elem
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Any> filterAndNoncesUpdate(t: T, index: Int): Boolean {
|
||||
return if (filtering.test(t)) {
|
||||
nonces.add(computeNonce(privacySalt, index))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We should have a warning (require) if all leaves (excluding salt) are visible after filtering.
|
||||
// Consider the above after refactoring FilteredTransaction to implement TraversableTransaction,
|
||||
// so that a WireTransaction can be used when required to send a full tx (e.g. RatesFixFlow in Oracles).
|
||||
return FilteredLeaves(
|
||||
inputs.filterIndexed { index, it -> filterAndNoncesUpdate(it, index) },
|
||||
attachments.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[0]) },
|
||||
outputs.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[1]) },
|
||||
commands.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[2]) },
|
||||
notNullFalseAndNoncesUpdate(notary, offsets[3]) as Party?,
|
||||
notNullFalseAndNoncesUpdate(timeWindow, offsets[4]) as TimeWindow?,
|
||||
nonces
|
||||
)
|
||||
}
|
||||
|
||||
// We use index offsets, to get the actual leaf-index per transaction component required for nonce computation.
|
||||
private fun indexOffsets(): List<Int> {
|
||||
// There is no need to add an index offset for inputs, because they are the first components in the
|
||||
// transaction format and it is always zero. Thus, offsets[0] corresponds to attachments,
|
||||
// offsets[1] to outputs, offsets[2] to commands and so on.
|
||||
val offsets = mutableListOf(inputs.size, inputs.size + attachments.size)
|
||||
offsets.add(offsets.last() + outputs.size)
|
||||
offsets.add(offsets.last() + commands.size)
|
||||
if (notary != null) {
|
||||
offsets.add(offsets.last() + 1)
|
||||
} else {
|
||||
offsets.add(offsets.last())
|
||||
}
|
||||
if (timeWindow != null) {
|
||||
offsets.add(offsets.last() + 1)
|
||||
} else {
|
||||
offsets.add(offsets.last())
|
||||
}
|
||||
// No need to add offset for privacySalt as it doesn't require a nonce.
|
||||
return offsets
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the given signature matches one of the commands and that it is a correct signature over the tx.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user