Merge pull request #7430 from corda/adel/ENT-10122

ENT-10122: Add consuming transaction id to vault states table.
This commit is contained in:
Adel El-Beik
2023-08-07 13:35:04 +01:00
committed by GitHub
7 changed files with 101 additions and 11 deletions

View File

@ -37,6 +37,7 @@ import net.corda.core.node.services.vault.PageSpecification
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.node.services.vault.Sort
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.DeprecatedConstructorForDeserialization
import net.corda.core.toFuture
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.utilities.NonEmptySet
@ -68,7 +69,7 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
* other transactions observed, then the changes are observed "net" of those.
*/
@CordaSerializable
data class Update<U : ContractState> @JvmOverloads constructor(
data class Update<U : ContractState> constructor(
val consumed: Set<StateAndRef<U>>,
val produced: Set<StateAndRef<U>>,
val flowId: UUID? = null,
@ -78,8 +79,21 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
* differently.
*/
val type: UpdateType = UpdateType.GENERAL,
val references: Set<StateAndRef<U>> = emptySet()
val references: Set<StateAndRef<U>> = emptySet(),
val consumingTxIds: Map<StateRef, SecureHash> = emptyMap()
) {
@DeprecatedConstructorForDeserialization(1)
@JvmOverloads constructor( consumed: Set<StateAndRef<U>>,
produced: Set<StateAndRef<U>>,
flowId: UUID? = null,
/**
* Specifies the type of update, currently supported types are general and, contract upgrade and notary change.
* Notary change transactions only modify the notary field on states, and potentially need to be handled
* differently.
*/
type: UpdateType = UpdateType.GENERAL,
references: Set<StateAndRef<U>> = emptySet()) : this(consumed, produced, flowId, type, references, consumingTxIds = emptyMap())
/** Checks whether the update contains a state of the specified type. */
inline fun <reified T : ContractState> containsType() = consumed.any { it.state.data is T } || produced.any { it.state.data is T } || references.any { it.state.data is T }
@ -105,9 +119,9 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
val combinedConsumed = consumed + (rhs.consumed - produced)
// The ordering below matters to preserve ordering of consumed/produced Sets when they are insertion order dependent implementations.
val combinedProduced = produced.filter { it !in rhs.consumed }.toSet() + rhs.produced
return copy(consumed = combinedConsumed, produced = combinedProduced, references = references + rhs.references)
return copy(consumed = combinedConsumed, produced = combinedProduced, references = references + rhs.references, consumingTxIds = consumingTxIds + rhs.consumingTxIds)
}
override fun toString(): String {
val sb = StringBuilder()
sb.appendln("${consumed.size} consumed, ${produced.size} produced")
@ -125,6 +139,10 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
references.forEach {
sb.appendln("${it.ref}: ${it.state}")
}
sb.appendln("Consuming TxIds:")
consumingTxIds.forEach {
sb.appendln("${it.key}: ${it.value}")
}
return sb.toString()
}
@ -135,9 +153,19 @@ class Vault<out T : ContractState>(val states: Iterable<StateAndRef<T>>) {
flowId: UUID? = null,
type: UpdateType = UpdateType.GENERAL
): Update<U> {
return Update(consumed, produced, flowId, type, references)
return Update(consumed, produced, flowId, type, references, consumingTxIds)
}
/** Additional copy method to maintain backwards compatibility. */
fun copy(
consumed: Set<StateAndRef<U>>,
produced: Set<StateAndRef<U>>,
flowId: UUID? = null,
type: UpdateType = UpdateType.GENERAL,
references: Set<StateAndRef<U>> = emptySet()
): Update<U> {
return Update(consumed, produced, flowId, type, references, consumingTxIds)
}
}
@CordaSerializable