From 01d5a28ad0d9774740e6b94078b6dc2535b4ed67 Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Tue, 26 Sep 2023 15:31:02 +0100 Subject: [PATCH 01/12] CORE-16183 Initial Ledger schema changes --- .../impl/VaultNamedQueryExecutorImpl.kt | 2 +- .../ledger/persistence/utxo/UtxoRepository.kt | 21 +++----- .../utxo/impl/AbstractUtxoQueryProvider.kt | 26 +++++---- .../utxo/impl/PostgresUtxoQueryProvider.kt | 40 +++----------- .../utxo/impl/UtxoPersistenceServiceImpl.kt | 36 ++----------- .../utxo/impl/UtxoQueryProvider.kt | 13 ++--- .../utxo/impl/UtxoRepositoryImpl.kt | 37 +++++-------- .../impl/UtxoPersistenceServiceImplTest.kt | 9 ++-- .../utxo/UtxoTransactionComponentEntity.kt | 8 +-- .../datamodel/utxo/UtxoTransactionEntity.kt | 9 ++-- .../utxo/UtxoTransactionStatusEntity.kt | 37 ------------- ... => UtxoVisibleTransactionOutputEntity.kt} | 20 ++++--- .../utxo/UtxoVisibleTransactionStateEntity.kt | 53 ------------------- .../queries/impl/SqlQueryProviderTokens.kt | 24 +++------ .../ledger/tests/HsqldbVaultNamedQueryTest.kt | 51 ++++++++---------- .../ledger/utxo/HsqldbUtxoQueryProvider.kt | 49 +++++------------ 16 files changed, 119 insertions(+), 316 deletions(-) delete mode 100644 components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionStatusEntity.kt rename components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/{UtxoTransactionOutputEntity.kt => UtxoVisibleTransactionOutputEntity.kt} (76%) delete mode 100644 components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoVisibleTransactionStateEntity.kt diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/query/execution/impl/VaultNamedQueryExecutorImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/query/execution/impl/VaultNamedQueryExecutorImpl.kt index 581cefb9812..f5f9d87461c 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/query/execution/impl/VaultNamedQueryExecutorImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/query/execution/impl/VaultNamedQueryExecutorImpl.kt @@ -27,7 +27,7 @@ class VaultNamedQueryExecutorImpl( ) : VaultNamedQueryExecutor { private companion object { - const val UTXO_VISIBLE_TX_TABLE = "utxo_visible_transaction_state" + const val UTXO_VISIBLE_TX_TABLE = "utxo_visible_transaction_output" const val UTXO_TX_COMPONENT_TABLE = "utxo_transaction_component" const val TIMESTAMP_LIMIT_PARAM_NAME = "Corda_TimestampLimit" diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt index 083dbdd86cb..30b21d90abb 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt @@ -61,7 +61,8 @@ interface UtxoRepository { id: String, privacySalt: ByteArray, account: String, - timestamp: Instant + timestamp: Instant, + status: TransactionStatus ) /** Persists transaction component leaf [data] (operation is idempotent) */ @@ -98,19 +99,9 @@ interface UtxoRepository { tokenTag: String? = null, tokenOwnerHash: String? = null, tokenAmount: BigDecimal? = null, - timestamp: Instant - ) - - /** Persists visible transaction states (operation is idempotent) */ - @Suppress("LongParameterList") - fun persistTransactionVisibleStates( - entityManager: EntityManager, - transactionId: String, - groupIndex: Int, - leafIndex: Int, + timestamp: Instant, consumed: Boolean, - customRepresentation: CustomRepresentation, - timestamp: Instant + customRepresentation: CustomRepresentation ) /** Persists transaction [signature] (operation is idempotent) */ @@ -136,13 +127,13 @@ interface UtxoRepository { ) /** - * Persists or updates transaction [transactionStatus]. There is only one status per transaction. In case that status already + * Updates transaction [transactionStatus]. There is only one status per transaction. In case that status already * exists, it will be updated only if old and new statuses are one of the following combinations (and ignored otherwise): * - UNVERIFIED -> * * - VERIFIED -> VERIFIED * - INVALID -> INVALID */ - fun persistTransactionStatus( + fun updateTransactionStatus( entityManager: EntityManager, transactionId: String, transactionStatus: TransactionStatus, diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt index 1f8e03dfe6b..05dabc882ac 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt @@ -30,7 +30,7 @@ abstract class AbstractUtxoQueryProvider : UtxoQueryProvider { tc_output.leaf_idx, tc_output_info.data as output_info_data, tc_output.data AS output_data - FROM {h-schema}utxo_visible_transaction_state AS rts + FROM {h-schema}utxo_visible_transaction_output AS rts JOIN {h-schema}utxo_transaction_component AS tc_output_info ON tc_output_info.transaction_id = rts.transaction_id AND tc_output_info.leaf_idx = rts.leaf_idx @@ -39,11 +39,11 @@ abstract class AbstractUtxoQueryProvider : UtxoQueryProvider { ON tc_output.transaction_id = tc_output_info.transaction_id AND tc_output.leaf_idx = tc_output_info.leaf_idx AND tc_output.group_idx = ${UtxoComponentGroup.OUTPUTS.ordinal} - JOIN {h-schema}utxo_transaction_status AS ts - ON ts.transaction_id = tc_output.transaction_id + JOIN {h-schema}utxo_transaction AS ts + ON ts.id = tc_output.transaction_id AND rts.consumed IS NULL AND ts.status = :verified - ORDER BY tc_output.created, tc_output.transaction_id, tc_output.leaf_idx""" + ORDER BY ts.updated, tc_output.transaction_id, tc_output.leaf_idx""" .trimIndent() override val findTransactionSignatures: String @@ -57,13 +57,13 @@ abstract class AbstractUtxoQueryProvider : UtxoQueryProvider { override val findTransactionStatus: String get() = """ SELECT status - FROM {h-schema}utxo_transaction_status - WHERE transaction_id = :transactionId""" + FROM {h-schema}utxo_transaction + WHERE id = :transactionId""" .trimIndent() override val markTransactionVisibleStatesConsumed: String get() = """ - UPDATE {h-schema}utxo_visible_transaction_state + UPDATE {h-schema}utxo_visible_transaction_output SET consumed = :consumed WHERE transaction_id in (:transactionIds) AND (transaction_id || ':' || leaf_idx) IN (:stateRefs)""" @@ -91,12 +91,18 @@ abstract class AbstractUtxoQueryProvider : UtxoQueryProvider { ON tc_output.transaction_id = tc_output_info.transaction_id AND tc_output.leaf_idx = tc_output_info.leaf_idx AND tc_output.group_idx = ${UtxoComponentGroup.OUTPUTS.ordinal} - JOIN {h-schema}utxo_transaction_status AS ts - ON ts.transaction_id = tc_output.transaction_id + JOIN {h-schema}utxo_transaction AS ts + ON ts.id = tc_output.transaction_id AND tc_output.transaction_id in (:transactionIds) AND (tc_output.transaction_id||':'|| tc_output.leaf_idx) in (:stateRefs) AND ts.status = :verified AND tc_output_info.group_idx = ${UtxoComponentGroup.OUTPUTS_INFO.ordinal} - ORDER BY tc_output.created, tc_output.transaction_id, tc_output.leaf_idx""" + ORDER BY ts.updated, tc_output.transaction_id, tc_output.leaf_idx""" + .trimIndent() + + override val updateTransactionStatus: String + get() = """ + UPDATE {h-schema}utxo_transaction ut SET ut.status = :status, updated = :updatedAt + WHERE ut.id = :transactionId AND ut.status = :status OR ut.status = '$UNVERIFIED'""" .trimIndent() } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt index 6e6594f3fdf..3335c1e6ed7 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt @@ -19,15 +19,15 @@ class PostgresUtxoQueryProvider @Activate constructor( override val persistTransaction: String get() = """ - INSERT INTO {h-schema}utxo_transaction(id, privacy_salt, account_id, created) - VALUES (:id, :privacySalt, :accountId, :createdAt) + INSERT INTO {h-schema}utxo_transaction(id, privacy_salt, account_id, created, status, updated) + VALUES (:id, :privacySalt, :accountId, :createdAt, :status, :updatedAt) ON CONFLICT DO NOTHING""" .trimIndent() override val persistTransactionComponentLeaf: String get() = """ - INSERT INTO {h-schema}utxo_transaction_component(transaction_id, group_idx, leaf_idx, data, hash, created) - VALUES(:transactionId, :groupIndex, :leafIndex, :data, :hash, :createdAt) + INSERT INTO {h-schema}utxo_transaction_component(transaction_id, group_idx, leaf_idx, data, hash) + VALUES(:transactionId, :groupIndex, :leafIndex, :data, :hash) ON CONFLICT DO NOTHING""" .trimIndent() @@ -40,30 +40,15 @@ class PostgresUtxoQueryProvider @Activate constructor( ON CONFLICT DO NOTHING""" .trimIndent() - override val persistTransactionOutput: String - get() = """ - INSERT INTO {h-schema}utxo_transaction_output( + override fun persistTransactionOutput(consumed: Boolean): String { + return """INSERT INTO {h-schema}utxo_visible_transaction_output( transaction_id, group_idx, leaf_idx, type, token_type, token_issuer_hash, token_notary_x500_name, - token_symbol, token_tag, token_owner_hash, token_amount, created) + token_symbol, token_tag, token_owner_hash, token_amount, created, consumed, custom_representation) VALUES( :transactionId, :groupIndex, :leafIndex, :type, :tokenType, :tokenIssuerHash, :tokenNotaryX500Name, - :tokenSymbol, :tokenTag, :tokenOwnerHash, :tokenAmount, :createdAt) + :tokenSymbol, :tokenTag, :tokenOwnerHash, :tokenAmount, :createdAt, :consumedAt, :customRepresentation) ON CONFLICT DO NOTHING""" .trimIndent() - - override fun persistTransactionVisibleStates(consumed: Boolean): String { - return """ - INSERT INTO {h-schema}utxo_visible_transaction_state( - transaction_id, group_idx, leaf_idx, custom_representation, created, consumed - ) VALUES( - :transactionId, - :groupIndex, - :leafIndex, - CAST(:custom_representation as JSONB), - :createdAt, - ${if (consumed) ":consumedAt" else "null"} - ) ON CONFLICT DO NOTHING""" - .trimIndent() } override val persistTransactionSignature: String @@ -84,15 +69,6 @@ class PostgresUtxoQueryProvider @Activate constructor( ON CONFLICT DO NOTHING""" .trimIndent() - override val persistTransactionStatus: String - get() = """ - INSERT INTO {h-schema}utxo_transaction_status(transaction_id, status, updated) - VALUES (:transactionId, :status, :updatedAt) - ON CONFLICT(transaction_id) DO - UPDATE SET status = EXCLUDED.status, updated = EXCLUDED.updated - WHERE utxo_transaction_status.status = EXCLUDED.status OR utxo_transaction_status.status = '$UNVERIFIED'""" - .trimIndent() - override val persistSignedGroupParameters: String get() = """ INSERT INTO {h-schema}utxo_group_parameters( diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt index 0153b869458..bdf1ca253bb 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt @@ -134,7 +134,8 @@ class UtxoPersistenceServiceImpl( transactionIdString, transaction.privacySalt.bytes, transaction.account, - nowUtc + nowUtc, + transaction.status ) // Insert the Transactions components @@ -183,28 +184,9 @@ class UtxoPersistenceServiceImpl( utxoToken?.filterFields?.tag, utxoToken?.filterFields?.ownerHash?.toString(), utxoToken?.amount, - nowUtc - ) - } - - // Insert relevancy information for outputs - transaction.visibleStatesIndexes.forEach { visibleStateIndex -> - - val jsonString = transaction.getVisibleStates()[visibleStateIndex]?.let { - extractJsonDataFromState(it) - } ?: run { - log.warn("Could not find visible state with index $visibleStateIndex, defaulting to empty JSON string.") - "{}" - } - - repository.persistTransactionVisibleStates( - em, - transactionIdString, - UtxoComponentGroup.OUTPUTS.ordinal, - visibleStateIndex, + nowUtc, consumed = false, - CustomRepresentation(jsonString), - nowUtc + CustomRepresentation(extractJsonDataFromState(stateAndRef)) ) } @@ -231,14 +213,6 @@ class UtxoPersistenceServiceImpl( ) } - // Insert the transactions current status - repository.persistTransactionStatus( - em, - transactionIdString, - transaction.status, - nowUtc - ) - // Insert the CPK details liked to this transaction // TODOs: The CPK file meta does not exist yet, this will be implemented by // https://r3-cev.atlassian.net/browse/CORE-7626 @@ -263,7 +237,7 @@ class UtxoPersistenceServiceImpl( override fun updateStatus(id: String, transactionStatus: TransactionStatus) { entityManagerFactory.transaction { em -> - repository.persistTransactionStatus(em, id, transactionStatus, utcClock.instant()) + repository.updateTransactionStatus(em, id, transactionStatus, utcClock.instant()) } } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt index 84e0d11bc78..ad5ff3e2787 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt @@ -66,16 +66,11 @@ interface UtxoQueryProvider { */ val persistTransactionCpk: String - /** - * @property persistTransactionOutput SQL text for [UtxoRepositoryImpl.persistTransactionOutput]. - */ - val persistTransactionOutput: String - /** * @param consumed Whether the persisted states have been consumed. - * @return SQL text for [UtxoRepositoryImpl.persistTransactionVisibleStates]. + * @property persistTransactionOutput SQL text for [UtxoRepositoryImpl.persistTransactionOutput]. */ - fun persistTransactionVisibleStates(consumed: Boolean): String + fun persistTransactionOutput(consumed: Boolean): String /** * @property persistTransactionSignature SQL text for [UtxoRepositoryImpl.persistTransactionSignature]. @@ -88,9 +83,9 @@ interface UtxoQueryProvider { val persistTransactionSource: String /** - * @property persistTransactionStatus SQL text for [UtxoRepositoryImpl.persistTransactionStatus]. + * @property updateTransactionStatus SQL text for [UtxoRepositoryImpl.updateTransactionStatus]. */ - val persistTransactionStatus: String + val updateTransactionStatus: String /** * @property persistSignedGroupParameters SQL text for [UtxoRepositoryImpl.persistSignedGroupParameters]. diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt index c4b8fe76ff8..c1f9dba6583 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt @@ -160,13 +160,16 @@ class UtxoRepositoryImpl @Activate constructor( id: String, privacySalt: ByteArray, account: String, - timestamp: Instant + timestamp: Instant, + status: TransactionStatus ) { entityManager.createNativeQuery(queryProvider.persistTransaction) .setParameter("id", id) .setParameter("privacySalt", privacySalt) .setParameter("accountId", account) .setParameter("createdAt", timestamp) + .setParameter("status", status) + .setParameter("updatedAt", timestamp) .executeUpdate() .logResult("transaction [$id]") } @@ -216,9 +219,11 @@ class UtxoRepositoryImpl @Activate constructor( tokenTag: String?, tokenOwnerHash: String?, tokenAmount: BigDecimal?, - timestamp: Instant + timestamp: Instant, + consumed: Boolean, + customRepresentation: CustomRepresentation ) { - entityManager.createNativeQuery(queryProvider.persistTransactionOutput) + entityManager.createNativeQuery(queryProvider.persistTransactionOutput(consumed)) .setParameter("transactionId", transactionId) .setParameter("groupIndex", groupIndex) .setParameter("leafIndex", leafIndex) @@ -234,28 +239,10 @@ class UtxoRepositoryImpl @Activate constructor( .setParameter("tokenAmount", BigDecimal.ZERO) .setParameter("tokenAmount", tokenAmount) .setParameter("createdAt", timestamp) - .executeUpdate() - .logResult("transaction output [$transactionId, $groupIndex, $leafIndex]") - } - - override fun persistTransactionVisibleStates( - entityManager: EntityManager, - transactionId: String, - groupIndex: Int, - leafIndex: Int, - consumed: Boolean, - customRepresentation: CustomRepresentation, - timestamp: Instant, - ) { - entityManager.createNativeQuery(queryProvider.persistTransactionVisibleStates(consumed)) - .setParameter("transactionId", transactionId) - .setParameter("groupIndex", groupIndex) - .setParameter("leafIndex", leafIndex) - .setParameter("custom_representation", customRepresentation.json) - .setParameter("createdAt", timestamp) + .setParameter("customRepresentation", customRepresentation.json) .run { if (consumed) setParameter("consumedAt", timestamp) else this } .executeUpdate() - .logResult("transaction relevancy [$transactionId, $groupIndex, $leafIndex]") + .logResult("transaction output [$transactionId, $leafIndex]") } override fun persistTransactionSignature( @@ -297,14 +284,14 @@ class UtxoRepositoryImpl @Activate constructor( .logResult("transaction source [$transactionId, $groupIndex, $leafIndex]") } - override fun persistTransactionStatus( + override fun updateTransactionStatus( entityManager: EntityManager, transactionId: String, transactionStatus: TransactionStatus, timestamp: Instant ) { // Insert/update status. Update ignored unless: UNVERIFIED -> * | VERIFIED -> VERIFIED | INVALID -> INVALID - val rowsUpdated = entityManager.createNativeQuery(queryProvider.persistTransactionStatus) + val rowsUpdated = entityManager.createNativeQuery(queryProvider.updateTransactionStatus) .setParameter("transactionId", transactionId) .setParameter("status", transactionStatus.value) .setParameter("updatedAt", timestamp) diff --git a/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt b/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt index e89a17da567..186fd638e21 100644 --- a/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt +++ b/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt @@ -43,16 +43,15 @@ class UtxoPersistenceServiceImplTest { private val persistedJsonStrings = mutableMapOf() private val mockRepository = mock { - on { persistTransactionVisibleStates(any(), any(), any(), any(), any(), any(), any()) } doAnswer { + on { persistTransactionOutput(any(), any(), any(), any(), any(), any(), any(), + any(), any(), any(), any(), any(), any(), any(), any()) } doAnswer { val txId = it.getArgument(1) - val customRepresentation = it.getArgument(5) + val customRepresentation = it.arguments.last() as CustomRepresentation persistedJsonStrings[txId] = customRepresentation } - on { persistTransaction(any(), any(), any(), any(), any()) } doAnswer {} + on { persistTransaction(any(), any(), any(), any(), any(), any()) } doAnswer {} on { persistTransactionComponentLeaf(any(), any(), any(), any(), any(), any(), any()) } doAnswer {} - on { persistTransactionOutput(any(), any(), any(), any(), any(), any(), any(), any(), any(), - any(), any(), any(), any()) } doAnswer {} } private val mockPrivacySalt = mock { diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt index f99abfe68a8..9526b0ca710 100644 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt @@ -1,7 +1,6 @@ package com.example.ledger.testing.datamodel.utxo import java.io.Serializable -import java.time.Instant import javax.persistence.Column import javax.persistence.Embeddable import javax.persistence.Entity @@ -35,10 +34,7 @@ data class UtxoTransactionComponentEntity( var data: ByteArray, @get:Column(name = "hash", nullable = false) - var hash: String, - - @get:Column(name = "created", nullable = false) - var created: Instant + var hash: String ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -51,7 +47,6 @@ data class UtxoTransactionComponentEntity( if (leafIndex != other.leafIndex) return false if (!data.contentEquals(other.data)) return false if (hash != other.hash) return false - if (created != other.created) return false return true } @@ -62,7 +57,6 @@ data class UtxoTransactionComponentEntity( result = 31 * result + leafIndex result = 31 * result + data.contentHashCode() result = 31 * result + hash.hashCode() - result = 31 * result + created.hashCode() return result } } diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt index 55035297d7e..a05002f509d 100644 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt @@ -28,13 +28,16 @@ data class UtxoTransactionEntity( @get:Column(name = "created", nullable = false) var created: Instant, + + @get:Column(name = "status", nullable = false) + var status: String, + + @get:Column(name = "updated", nullable = false) + var updated: Instant ) { @get:OneToMany(mappedBy = "transaction", cascade = [CascadeType.ALL], orphanRemoval = true) var components: MutableList = mutableListOf() - @get:OneToMany(mappedBy = "transaction", cascade = [CascadeType.ALL], orphanRemoval = true) - var statuses: MutableList = mutableListOf() - @get:OneToMany(mappedBy = "transaction", cascade = [CascadeType.ALL], orphanRemoval = true) var signatures: MutableList = mutableListOf() diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionStatusEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionStatusEntity.kt deleted file mode 100644 index 7b6c4d5e5ab..00000000000 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionStatusEntity.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.example.ledger.testing.datamodel.utxo - -import java.io.Serializable -import java.time.Instant -import javax.persistence.Column -import javax.persistence.Embeddable -import javax.persistence.Entity -import javax.persistence.Id -import javax.persistence.IdClass -import javax.persistence.JoinColumn -import javax.persistence.ManyToOne -import javax.persistence.Table -import net.corda.v5.base.annotations.CordaSerializable - -@CordaSerializable -@Entity -@Table(name = "utxo_transaction_status") -@IdClass(UtxoTransactionStatusEntityId::class) -data class UtxoTransactionStatusEntity( - @get:Id - @get:ManyToOne - @get:JoinColumn(name = "transaction_id", nullable = false, updatable = false) - var transaction: UtxoTransactionEntity, - - @get:Id - @get:Column(name = "status", nullable = false) - var status: String, - - @get:Column(name = "updated", nullable = false) - var updated: Instant -) - -@Embeddable -data class UtxoTransactionStatusEntityId( - var transaction: UtxoTransactionEntity, - var status: String -) : Serializable diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionOutputEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoVisibleTransactionOutputEntity.kt similarity index 76% rename from components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionOutputEntity.kt rename to components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoVisibleTransactionOutputEntity.kt index ea5d6a57cd5..1aa699e3f57 100644 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionOutputEntity.kt +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoVisibleTransactionOutputEntity.kt @@ -16,13 +16,13 @@ import javax.persistence.Table @CordaSerializable @NamedQuery( - name = "UtxoTransactionOutputEntity.findByTransactionId", - query = "from UtxoTransactionOutputEntity where transaction.id = :transactionId" + name = "UtxoVisibleTransactionOutputEntity.findByTransactionId", + query = "from UtxoVisibleTransactionOutputEntity where transaction.id = :transactionId" ) @Entity -@Table(name = "utxo_transaction_output") +@Table(name = "utxo_visible_transaction_output") @IdClass(UtxoTransactionOutputEntityId::class) -data class UtxoTransactionOutputEntity( +data class UtxoVisibleTransactionOutputEntity( @get:Id @get:ManyToOne @get:JoinColumn(name = "transaction_id", nullable = false, updatable = false) @@ -36,8 +36,8 @@ data class UtxoTransactionOutputEntity( @get:Column(name = "leaf_idx", nullable = false) var leafIndex: Int, - @get:Column(name = "type", nullable = true) - var type: String?, + @get:Column(name = "type", nullable = false) + var type: String, @get:Column(name = "token_type", nullable = true) var tokenType: String?, @@ -61,7 +61,13 @@ data class UtxoTransactionOutputEntity( var tokenAmount: BigDecimal?, @get:Column(name = "created", nullable = false) - var created: Instant + var created: Instant, + + @get:Column(name = "consumed", nullable = true) + var consumed: Instant?, + + @get:Column(name = "custom_representation", nullable = false) + var customRepresentation: String ) @Embeddable diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoVisibleTransactionStateEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoVisibleTransactionStateEntity.kt deleted file mode 100644 index db871f720cb..00000000000 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoVisibleTransactionStateEntity.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.example.ledger.testing.datamodel.utxo - -import net.corda.v5.base.annotations.CordaSerializable -import java.io.Serializable -import java.time.Instant -import javax.persistence.Column -import javax.persistence.Embeddable -import javax.persistence.Entity -import javax.persistence.Id -import javax.persistence.IdClass -import javax.persistence.JoinColumn -import javax.persistence.ManyToOne -import javax.persistence.NamedQuery -import javax.persistence.Table - -@CordaSerializable -@NamedQuery( - name = "UtxoVisibleTransactionStateEntity.findByTransactionId", - query = "from UtxoVisibleTransactionStateEntity where transaction.id = :transactionId" -) -@Entity -@Table(name = "utxo_visible_transaction_state") -@IdClass(UtxoVisibleTransactionStateEntityId::class) -data class UtxoVisibleTransactionStateEntity( - @get:Id - @get:ManyToOne - @get:JoinColumn(name = "transaction_id", nullable = false, updatable = false) - var transaction: UtxoTransactionEntity, - - @get:Id - @get:Column(name = "group_idx", nullable = false) - var groupIndex: Int, - - @get:Id - @get:Column(name = "leaf_idx", nullable = false) - var leafIndex: Int, - - @get:Column(name = "custom_representation", nullable = false, columnDefinition = "jsonb") - var customRepresentation: String, - - @get:Column(name = "created", nullable = false) - var created: Instant, - - @get:Column(name = "consumed", nullable = true) - var consumed: Instant? -) - -@Embeddable -data class UtxoVisibleTransactionStateEntityId( - var transaction: UtxoTransactionEntity, - var groupIndex: Int, - var leafIndex: Int -) : Serializable diff --git a/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/queries/impl/SqlQueryProviderTokens.kt b/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/queries/impl/SqlQueryProviderTokens.kt index 824e5d1edc8..986d9cd5df9 100644 --- a/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/queries/impl/SqlQueryProviderTokens.kt +++ b/components/ledger/ledger-utxo-token-cache/src/main/kotlin/net/corda/ledger/utxo/token/cache/queries/impl/SqlQueryProviderTokens.kt @@ -30,16 +30,12 @@ class SqlQueryProviderTokens : SqlQueryProvider { return """ SELECT COALESCE(SUM(token_amount), 0) - FROM {h-schema}utxo_transaction_output as t_output - INNER JOIN {h-schema}utxo_visible_transaction_state as t_state - ON t_output.transaction_id = t_state.transaction_id - AND t_output.group_idx = t_state.group_idx - AND t_output.leaf_idx = t_state.leaf_idx - WHERE t_state.consumed is null - AND token_type = :$SQL_PARAMETER_TOKEN_TYPE - AND token_issuer_hash = :$SQL_PARAMETER_ISSUER_HASH - AND token_symbol = :$SQL_PARAMETER_SYMBOL - AND token_notary_x500_name = :$SQL_PARAMETER_TOKEN_NOTARY_X500_NAME + FROM {h-schema}utxo_visible_transaction_output as t_output + WHERE t_output.consumed is null + AND t_output.token_type = :$SQL_PARAMETER_TOKEN_TYPE + AND t_output.token_issuer_hash = :$SQL_PARAMETER_ISSUER_HASH + AND t_output.token_symbol = :$SQL_PARAMETER_SYMBOL + AND t_output.token_notary_x500_name = :$SQL_PARAMETER_TOKEN_NOTARY_X500_NAME $tagFilter $ownerFilter """.trimIndent() @@ -65,12 +61,8 @@ class SqlQueryProviderTokens : SqlQueryProvider { t_output.token_tag, t_output.token_owner_hash, t_output.token_amount - FROM {h-schema}utxo_transaction_output as t_output - INNER JOIN {h-schema}utxo_visible_transaction_state as t_state - ON t_output.transaction_id = t_state.transaction_id - AND t_output.group_idx = t_state.group_idx - AND t_output.leaf_idx = t_state.leaf_idx - WHERE t_state.consumed is null + FROM {h-schema}utxo_visible_transaction_output as t_output + WHERE t_output.consumed is null AND t_output.token_type = :$SQL_PARAMETER_TOKEN_TYPE AND t_output.token_issuer_hash = :$SQL_PARAMETER_ISSUER_HASH AND t_output.token_symbol = :$SQL_PARAMETER_SYMBOL diff --git a/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt b/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt index 8923d7e1b04..bd4b7078611 100644 --- a/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt +++ b/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt @@ -3,16 +3,12 @@ package net.corda.testing.ledger.tests import com.example.ledger.testing.datamodel.utxo.UtxoTransactionComponentEntity import com.example.ledger.testing.datamodel.utxo.UtxoTransactionComponentEntityId import com.example.ledger.testing.datamodel.utxo.UtxoTransactionEntity -import com.example.ledger.testing.datamodel.utxo.UtxoTransactionOutputEntity +import com.example.ledger.testing.datamodel.utxo.UtxoVisibleTransactionOutputEntity import com.example.ledger.testing.datamodel.utxo.UtxoTransactionOutputEntityId import com.example.ledger.testing.datamodel.utxo.UtxoTransactionSignatureEntity import com.example.ledger.testing.datamodel.utxo.UtxoTransactionSignatureEntityId import com.example.ledger.testing.datamodel.utxo.UtxoTransactionSourceEntity import com.example.ledger.testing.datamodel.utxo.UtxoTransactionSourceEntityId -import com.example.ledger.testing.datamodel.utxo.UtxoTransactionStatusEntity -import com.example.ledger.testing.datamodel.utxo.UtxoTransactionStatusEntityId -import com.example.ledger.testing.datamodel.utxo.UtxoVisibleTransactionStateEntity -import com.example.ledger.testing.datamodel.utxo.UtxoVisibleTransactionStateEntityId import java.time.Instant import java.util.UUID import javax.persistence.EntityManagerFactory @@ -41,7 +37,7 @@ import org.osgi.test.junit5.service.ServiceExtension @ExtendWith(ServiceExtension::class) class HsqldbVaultNamedQueryTest { private companion object { - private const val UTXO_VISIBLE_TX_STATE = "utxo_visible_transaction_state" + private const val UTXO_VISIBLE_TX_STATE = "utxo_visible_transaction_output" private const val BASE_QUERY = "SELECT * FROM $UTXO_VISIBLE_TX_STATE AS visible_state WHERE " private const val TIMEOUT_MILLIS = 10000L @@ -85,16 +81,12 @@ class HsqldbVaultNamedQueryTest { UtxoTransactionEntity::class.java, UtxoTransactionComponentEntity::class.java, UtxoTransactionComponentEntityId::class.java, - UtxoTransactionStatusEntity::class.java, - UtxoTransactionStatusEntityId::class.java, - UtxoTransactionOutputEntity::class.java, + UtxoVisibleTransactionOutputEntity::class.java, UtxoTransactionOutputEntityId::class.java, UtxoTransactionSignatureEntity::class.java, UtxoTransactionSignatureEntityId::class.java, UtxoTransactionSourceEntity::class.java, - UtxoTransactionSourceEntityId::class.java, - UtxoVisibleTransactionStateEntity::class.java, - UtxoVisibleTransactionStateEntityId::class.java + UtxoTransactionSourceEntityId::class.java )) entityManagerFactory = dbConnectionManager.createEntityManagerFactory(dbConnectionId, entities) } @@ -107,25 +99,34 @@ class HsqldbVaultNamedQueryTest { id = txId.toString(), privacySalt = byteArrayOf(), accountId = ACCOUNT_ID.toString(), - created = timestamp + created = timestamp, + status = "V", + updated = timestamp ) - val visibleStates = mutableListOf() + val visibleStates = mutableListOf() for (state in states) { tx.components += UtxoTransactionComponentEntity( transaction = tx, groupIndex = state.groupIndex, leafIndex = state.leafIndex, data = byteArrayOf(0x01, 0x02, 0x03, 0x04), - hash = "", - timestamp + hash = "" ) - visibleStates += UtxoVisibleTransactionStateEntity( + visibleStates += UtxoVisibleTransactionOutputEntity( transaction = tx, groupIndex = state.groupIndex, leafIndex = state.leafIndex, - state.customRepresentation, + type = "com.r3.Dummy", + tokenType = null, + tokenIssuerHash = null, + tokenNotaryX500Name = null, + tokenSymbol = null, + tokenTag = null, + tokenOwnerHash = null, + tokenAmount = null, + customRepresentation = state.customRepresentation, created = timestamp, consumed = null ) @@ -136,14 +137,14 @@ class HsqldbVaultNamedQueryTest { } } - private fun executeQuery(sqlText: String, txId: UUID, parameters: (Query) -> Unit): List { + private fun executeQuery(sqlText: String, txId: UUID, parameters: (Query) -> Unit): List { @Suppress("unchecked_cast") return entityManagerFactory.transaction { em -> - em.createNativeQuery("$BASE_QUERY $sqlText AND transaction_id = :txId", UtxoVisibleTransactionStateEntity::class.java) + em.createNativeQuery("$BASE_QUERY $sqlText AND transaction_id = :txId", UtxoVisibleTransactionOutputEntity::class.java) .setParameter("txId", txId.toString()) .also(parameters) .resultList - } as List + } as List } @Test @@ -164,7 +165,6 @@ class HsqldbVaultNamedQueryTest { }.single() assertAll( { assertEquals(txId.toString(), numberResult.transaction.id) }, - { assertEquals(30, numberResult.groupIndex) }, { assertEquals(50, numberResult.leafIndex) } ) @@ -173,7 +173,6 @@ class HsqldbVaultNamedQueryTest { }.single() assertAll( { assertEquals(txId.toString(), stringResult.transaction.id) }, - { assertEquals(10, stringResult.groupIndex) }, { assertEquals(20, stringResult.leafIndex) } ) } @@ -197,7 +196,6 @@ class HsqldbVaultNamedQueryTest { }.single() assertAll( { assertEquals(txId.toString(), numberResult.transaction.id) }, - { assertEquals(15, numberResult.groupIndex) }, { assertEquals(25, numberResult.leafIndex) } ) @@ -207,7 +205,6 @@ class HsqldbVaultNamedQueryTest { }.single() assertAll( { assertEquals(txId.toString(), stringResult.transaction.id) }, - { assertEquals(0, stringResult.groupIndex) }, { assertEquals(1, stringResult.leafIndex) } ) } @@ -231,7 +228,6 @@ class HsqldbVaultNamedQueryTest { }.single() assertAll( { assertEquals(txId.toString(), numberResult.transaction.id) }, - { assertEquals(25, numberResult.groupIndex) }, { assertEquals(35, numberResult.leafIndex) } ) @@ -241,7 +237,6 @@ class HsqldbVaultNamedQueryTest { }.single() assertAll( { assertEquals(txId.toString(), stringResult.transaction.id) }, - { assertEquals(10, stringResult.groupIndex) }, { assertEquals(11, stringResult.leafIndex) } ) } @@ -262,7 +257,6 @@ class HsqldbVaultNamedQueryTest { val visibleState = executeQuery(sqlText, txId) {}.single() assertAll( { assertEquals(txId.toString(), visibleState.transaction.id) }, - { assertEquals(30, visibleState.groupIndex) }, { assertEquals(50, visibleState.leafIndex) } ) } @@ -286,7 +280,6 @@ class HsqldbVaultNamedQueryTest { assertAll( { assertEquals(txId.toString(), visibleState.transaction.id) }, - { assertEquals(10, visibleState.groupIndex) }, { assertEquals(20, visibleState.leafIndex) } ) } diff --git a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt index 8e171e66d6a..93be282dc2e 100644 --- a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt +++ b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt @@ -22,23 +22,23 @@ class HsqldbUtxoQueryProvider @Activate constructor( override val persistTransaction: String get() = """ MERGE INTO {h-schema}utxo_transaction AS ut - USING (VALUES :id, CAST(:privacySalt AS VARBINARY(64)), :accountId, CAST(:createdAt AS TIMESTAMP)) - AS x(id, privacy_salt, account_id, created) + USING (VALUES :id, CAST(:privacySalt AS VARBINARY(64)), :accountId, CAST(:createdAt AS TIMESTAMP), :status, CAST(:updatedAt AS TIMESTAMP)) + AS x(id, privacy_salt, account_id, created, status, updated) ON x.id = ut.id WHEN NOT MATCHED THEN - INSERT (id, privacy_salt, account_id, created) - VALUES (x.id, x.privacy_salt, x.account_id, x.created)""" + INSERT (id, privacy_salt, account_id, created, status, updated) + VALUES (x.id, x.privacy_salt, x.account_id, x.created, x.status, x.updated)""" .trimIndent() override val persistTransactionComponentLeaf: String get() = """ MERGE INTO {h-schema}utxo_transaction_component AS utc - USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), CAST(:data AS VARBINARY(1048576)), :hash, CAST(:createdAt AS TIMESTAMP)) - AS x(transaction_id, group_idx, leaf_idx, data, hash, created) + USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), CAST(:data AS VARBINARY(1048576)), :hash) + AS x(transaction_id, group_idx, leaf_idx, data, hash) ON x.transaction_id = utc.transaction_id AND x.group_idx = utc.group_idx AND x.leaf_idx = utc.leaf_idx WHEN NOT MATCHED THEN - INSERT (transaction_id, group_idx, leaf_idx, data, hash, created) - VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.data, x.hash, x.created)""" + INSERT (transaction_id, group_idx, leaf_idx, data, hash) + VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.data, x.hash)""" .trimIndent() override val persistTransactionCpk: String @@ -53,11 +53,12 @@ class HsqldbUtxoQueryProvider @Activate constructor( VALUES (x.transaction_id, x.file_checksum)""" .trimIndent() - override val persistTransactionOutput: String - get() = """ - MERGE INTO {h-schema}utxo_transaction_output AS uto + override fun persistTransactionOutput(consumed: Boolean): String { + return """ + MERGE INTO {h-schema}utxo_visible_transaction_output AS uto USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), :type, :tokenType, :tokenIssuerHash, - :tokenNotaryX500Name, :tokenSymbol, :tokenTag, :tokenOwnerHash, :tokenAmount, CAST(:createdAt AS TIMESTAMP)) + :tokenNotaryX500Name, :tokenSymbol, :tokenTag, :tokenOwnerHash, :tokenAmount, CAST(:createdAt AS TIMESTAMP), + ${if (consumed) "CAST(:consumedAt AS TIMESTAMP)" else "null"}, :customRepresentation) AS x(transaction_id, group_idx, leaf_idx, type, token_type, token_issuer_hash, token_notary_x500_name, token_symbol, token_tag, token_owner_hash, token_amount, created) ON uto.transaction_id = x.transaction_id AND uto.group_idx = x.group_idx AND uto.leaf_idx = x.leaf_idx @@ -67,18 +68,6 @@ class HsqldbUtxoQueryProvider @Activate constructor( VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.type, x.token_type, x.token_issuer_hash, x.token_notary_x500_name, x.token_symbol, x.token_tag, x.token_owner_hash, x.token_amount, x.created)""" .trimIndent() - - override fun persistTransactionVisibleStates(consumed: Boolean): String { - return """ - MERGE INTO {h-schema}utxo_visible_transaction_state AS uvts - USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), :custom_representation, - CAST(:createdAt AS TIMESTAMP), ${if (consumed) "CAST(:consumedAt AS TIMESTAMP)" else "null"}) - AS x(transaction_id, group_idx, leaf_idx, custom_representation, created, consumed) - ON uvts.transaction_id = x.transaction_id AND uvts.group_idx = x.group_idx AND uvts.leaf_idx = x.leaf_idx - WHEN NOT MATCHED THEN - INSERT (transaction_id, group_idx, leaf_idx, custom_representation, created, consumed) - VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.custom_representation, x.created, x.consumed)""" - .trimIndent() } override val persistTransactionSignature: String @@ -105,18 +94,6 @@ class HsqldbUtxoQueryProvider @Activate constructor( VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.ref_transaction_id, x.ref_leaf_idx, x.is_ref_input, x.created)""" .trimIndent() - override val persistTransactionStatus: String - get() = """ - MERGE INTO {h-schema}utxo_transaction_status AS uts - USING (VALUES :transactionId, :status, CAST(:updatedAt AS TIMESTAMP)) AS x(transaction_id, status, updated) - ON uts.transaction_id = x.transaction_id - WHEN NOT MATCHED THEN - INSERT (transaction_id, status, updated) - VALUES (x.transaction_id, x.status, x.updated) - WHEN MATCHED AND (uts.status = x.status OR uts.status = '$UNVERIFIED') THEN - UPDATE SET status = x.status, updated = x.updated""" - .trimIndent() - override val persistSignedGroupParameters: String get() = """ MERGE INTO {h-schema}utxo_group_parameters AS ugp From 6627481ec6517da3083304d6c17fc9085ead4b03 Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Tue, 10 Oct 2023 15:46:07 +0100 Subject: [PATCH 02/12] CORE-17430 Add transactionId and index for input/ref states --- .../tests/UtxoPersistenceServiceImplTest.kt | 4 +++- .../utxo/tests/datamodel/UtxoEntityFactory.kt | 8 +++++--- .../ledger/persistence/utxo/UtxoRepository.kt | 4 +++- .../utxo/impl/AbstractUtxoQueryProvider.kt | 7 +++++++ .../utxo/impl/PostgresUtxoQueryProvider.kt | 5 +++-- .../utxo/impl/UtxoPersistenceServiceImpl.kt | 18 +++++++++++++++++- .../persistence/utxo/impl/UtxoQueryProvider.kt | 5 +++++ .../utxo/impl/UtxoRepositoryImpl.kt | 14 ++++++-------- .../impl/UtxoPersistenceServiceImplTest.kt | 2 +- .../utxo/UtxoTransactionComponentEntity.kt | 12 +++++++++++- .../datamodel/utxo/UtxoTransactionEntity.kt | 4 ++++ .../ledger/tests/HsqldbVaultNamedQueryTest.kt | 4 +++- .../ledger/utxo/HsqldbUtxoQueryProvider.kt | 13 ++++++++----- 13 files changed, 76 insertions(+), 24 deletions(-) diff --git a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt index f6f8cf4b871..64b242a194f 100644 --- a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt +++ b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt @@ -572,7 +572,9 @@ class UtxoPersistenceServiceImplTest { groupIndex, leafIndex, component, - digest("SHA-256", component).toString() + digest("SHA-256", component).toString(), + null, + null ) } } diff --git a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/datamodel/UtxoEntityFactory.kt b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/datamodel/UtxoEntityFactory.kt index 3bbea0fdaa1..c3e6ee520a2 100644 --- a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/datamodel/UtxoEntityFactory.kt +++ b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/datamodel/UtxoEntityFactory.kt @@ -29,10 +29,12 @@ class UtxoEntityFactory(entityManagerFactory: EntityManagerFactory) { groupIdx: Int, leafIdx: Int, component: ByteArray, - hash: String + hash: String, + referencedTransactionId: String?, + referencedTransactionIndex: Int? ): Any { - return utxoTransactionComponent.constructors.single { it.parameterCount == 5 }.newInstance( - utxoTransaction, groupIdx, leafIdx, component, hash + return utxoTransactionComponent.constructors.single { it.parameterCount == 7 }.newInstance( + utxoTransaction, groupIdx, leafIdx, component, hash, referencedTransactionId, referencedTransactionIndex ) } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt index b566f85aad0..63699b69e5c 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt @@ -87,7 +87,9 @@ interface UtxoRepository { groupIndex: Int, leafIndex: Int, data: ByteArray, - hash: String + hash: String, + referencedStateTransactionId: String?, + referencedStateIndex: Int? ) /** Persists transaction output (operation is idempotent) */ diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt index 4a47246e39b..b7ceec46c6f 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt @@ -9,6 +9,13 @@ abstract class AbstractUtxoQueryProvider : UtxoQueryProvider { val UNVERIFIED = TransactionStatus.UNVERIFIED.value } + override val findTransactionIdsAndStatuses: String + get() = """ + SELECT id, status + FROM {h-schema}utxo_transaction + WHERE id IN (:transactionIds)""" + .trimIndent() + override val findTransactionPrivacySalt: String get() = """ SELECT privacy_salt diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt index 101bc0f1527..2b290ea5da3 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt @@ -28,8 +28,9 @@ class PostgresUtxoQueryProvider @Activate constructor( override val persistTransactionComponentLeaf: String get() = """ - INSERT INTO {h-schema}utxo_transaction_component(transaction_id, group_idx, leaf_idx, data, hash) - VALUES(:transactionId, :groupIndex, :leafIndex, :data, :hash) + INSERT INTO {h-schema}utxo_transaction_component(transaction_id, group_idx, leaf_idx, data, hash, + referenced_state_transaction_id, referenced_state_index) + VALUES(:transactionId, :groupIndex, :leafIndex, :data, :hash, :referencedStateTransactionId, :referencedStateIndex) ON CONFLICT DO NOTHING""" .trimIndent() diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt index 0ddde389b71..b7762cb42e4 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt @@ -158,13 +158,29 @@ class UtxoPersistenceServiceImpl( // Insert the Transactions components transaction.rawGroupLists.mapIndexed { groupIndex, leaves -> leaves.mapIndexed { leafIndex, data -> + val (referencedTransactionId, referencedStateIndex) = when (groupIndex) { + UtxoComponentGroup.INPUTS.ordinal, UtxoComponentGroup.REFERENCES.ordinal -> { + try { + val deserializedStateRef = serializationService.deserialize(data) + Pair(deserializedStateRef.transactionId.toString(), deserializedStateRef.index) + } catch (e: Exception) { + log.warn("Error deserializing input or reference state ref for transaction: $transactionIdString, " + + "group index: $groupIndex, leaf index: $leafIndex") + Pair(null, null) + } + } + else -> Pair(null, null) + } + repository.persistTransactionComponentLeaf( em, transactionIdString, groupIndex, leafIndex, data, - sandboxDigestService.hash(data, DigestAlgorithmName.SHA2_256).toString() + sandboxDigestService.hash(data, DigestAlgorithmName.SHA2_256).toString(), + referencedTransactionId, + referencedStateIndex ) } } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt index 572f9b50ab1..dfd63d5ff42 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt @@ -86,4 +86,9 @@ interface UtxoQueryProvider { * @property persistSignedGroupParameters SQL text for [UtxoRepositoryImpl.persistSignedGroupParameters]. */ val persistSignedGroupParameters: String + + /** + * @property findTransactionIdsAndStatuses SQL text for [UtxoRepositoryImpl.findTransactionIdsAndStatuses]. + */ + val findTransactionIdsAndStatuses: String } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt index 6ceed46eae3..60cd71cc312 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt @@ -75,13 +75,7 @@ class UtxoRepositoryImpl @Activate constructor( entityManager: EntityManager, transactionIds: List ): Map { - return entityManager.createNativeQuery( - """ - SELECT id, status - FROM {h-schema}utxo_transaction - WHERE id IN (:transactionIds)""", - Tuple::class.java - ) + return entityManager.createNativeQuery(queryProvider.findTransactionIdsAndStatuses, Tuple::class.java) .setParameter("transactionIds", transactionIds) .resultListAsTuples() .associate { r -> parseSecureHash(r.get(0) as String) to r.get(1) as String } @@ -202,7 +196,9 @@ class UtxoRepositoryImpl @Activate constructor( groupIndex: Int, leafIndex: Int, data: ByteArray, - hash: String + hash: String, + referencedStateTransactionId: String?, + referencedStateIndex: Int? ) { entityManager.createNativeQuery(queryProvider.persistTransactionComponentLeaf) .setParameter("transactionId", transactionId) @@ -210,6 +206,8 @@ class UtxoRepositoryImpl @Activate constructor( .setParameter("leafIndex", leafIndex) .setParameter("data", data) .setParameter("hash", hash) + .setParameter("referencedStateTransactionId", referencedStateTransactionId) + .setParameter("referencedStateIndex", referencedStateIndex) .executeUpdate() .logResult("transaction component [$transactionId, $groupIndex, $leafIndex]") } diff --git a/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt b/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt index c4b5ad22538..7fd33e8be4b 100644 --- a/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt +++ b/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt @@ -56,7 +56,7 @@ class UtxoPersistenceServiceImplTest { } on { persistTransaction(any(), any(), any(), any(), any(), any()) } doAnswer {} - on { persistTransactionComponentLeaf(any(), any(), any(), any(), any(), any()) } doAnswer {} + on { persistTransactionComponentLeaf(any(), any(), any(), any(), any(), any(), anyOrNull(), anyOrNull()) } doAnswer {} } private val mockPrivacySalt = mock { diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt index 9526b0ca710..e09adee451c 100644 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt @@ -34,7 +34,13 @@ data class UtxoTransactionComponentEntity( var data: ByteArray, @get:Column(name = "hash", nullable = false) - var hash: String + var hash: String, + + @get:Column(name = "referenced_state_transaction_id", nullable = true) + var referencedStateTransactionId: String?, + + @get:Column(name = "referenced_state_index", nullable = true) + var referencedStateIndex: Int? ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -47,6 +53,8 @@ data class UtxoTransactionComponentEntity( if (leafIndex != other.leafIndex) return false if (!data.contentEquals(other.data)) return false if (hash != other.hash) return false + if (referencedStateTransactionId != other.referencedStateTransactionId) return false + if (referencedStateIndex != other.referencedStateIndex) return false return true } @@ -57,6 +65,8 @@ data class UtxoTransactionComponentEntity( result = 31 * result + leafIndex result = 31 * result + data.contentHashCode() result = 31 * result + hash.hashCode() + result = 31 * result + referencedStateTransactionId.hashCode() + result = 31 * result + referencedStateIndex.hashCode() return result } } diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt index 83d102365fd..aa235f78716 100644 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt @@ -48,6 +48,8 @@ data class UtxoTransactionEntity( if (!privacySalt.contentEquals(other.privacySalt)) return false if (accountId != other.accountId) return false if (created != other.created) return false + if (status != other.status) return false + if (updated != other.updated) return false return true } @@ -57,6 +59,8 @@ data class UtxoTransactionEntity( result = 31 * result + privacySalt.contentHashCode() result = 31 * result + accountId.hashCode() result = 31 * result + created.hashCode() + result = 31 * result + status.hashCode() + result = 31 * result + updated.hashCode() return result } } diff --git a/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt b/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt index 350ac5fb32a..7774c1e6b3d 100644 --- a/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt +++ b/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt @@ -108,7 +108,9 @@ class HsqldbVaultNamedQueryTest { groupIndex = state.groupIndex, leafIndex = state.leafIndex, data = byteArrayOf(0x01, 0x02, 0x03, 0x04), - hash = "" + hash = "", + null, + null ) visibleStates += UtxoVisibleTransactionOutputEntity( diff --git a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt index 0eca180e0c8..0cbe7cab7d8 100644 --- a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt +++ b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt @@ -33,12 +33,15 @@ class HsqldbUtxoQueryProvider @Activate constructor( override val persistTransactionComponentLeaf: String get() = """ MERGE INTO {h-schema}utxo_transaction_component AS utc - USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), CAST(:data AS VARBINARY(1048576)), :hash) - AS x(transaction_id, group_idx, leaf_idx, data, hash) - ON x.transaction_id = utc.transaction_id AND x.group_idx = utc.group_idx AND x.leaf_idx = utc.leaf_idx + USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), CAST(:data AS VARBINARY(1048576)), :hash, + :referencedStateTransactionId, :referencedStateIndex) + AS x(transaction_id, group_idx, leaf_idx, data, hash, referenced_state_transaction_id, referenced_state_index) + ON x.transaction_id = utc.transaction_id AND x.group_idx = utc.group_idx AND x.leaf_idx = utc.leaf_idx + AND x.referenced_state_transaction_id = utc.referenced_state_transaction_id + AND x.referenced_state_index = utc.referenced_state_index WHEN NOT MATCHED THEN - INSERT (transaction_id, group_idx, leaf_idx, data, hash) - VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.data, x.hash)""" + INSERT (transaction_id, group_idx, leaf_idx, data, hash, referenced_state_transaction_id, referenced_state_index) + VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.data, x.hash, x.referenced_state_transaction_id, x.referenced_state_index)""" .trimIndent() override fun persistVisibleTransactionOutput(consumed: Boolean): String { From 8a6e3055bfb5bb609b9b405af521a3c5cb8afcbc Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Tue, 10 Oct 2023 15:46:07 +0100 Subject: [PATCH 03/12] vbump --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f900f54f449..9c8b6572f09 100644 --- a/gradle.properties +++ b/gradle.properties @@ -46,7 +46,7 @@ commonsTextVersion = 1.10.0 bouncycastleVersion=1.76 # Corda API libs revision (change in 4th digit indicates a breaking change) # Change to 5.1.0.xx-SNAPSHOT to pick up maven local published copy -cordaApiVersion=5.1.0.31-beta+ +cordaApiVersion=5.1.0.32-alpha-1696949940130 disruptorVersion=3.4.4 felixConfigAdminVersion=1.9.26 From 5f0b894b27bd68ce7847ec008aaf8f5e0c65d2d9 Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Wed, 11 Oct 2023 13:16:30 +0100 Subject: [PATCH 04/12] fix postgres bug --- .../corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt index 60cd71cc312..c1ec776b016 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt @@ -207,6 +207,9 @@ class UtxoRepositoryImpl @Activate constructor( .setParameter("data", data) .setParameter("hash", hash) .setParameter("referencedStateTransactionId", referencedStateTransactionId) + // This is a workaround for avoiding error when tokenAmount is null, see: + // https://stackoverflow.com/questions/53648865/postgresql-spring-data-jpa-integer-null-interpreted-as-bytea + .setParameter("referencedStateIndex", 0) .setParameter("referencedStateIndex", referencedStateIndex) .executeUpdate() .logResult("transaction component [$transactionId, $groupIndex, $leafIndex]") From e815529eb2b4cfc081d93678700e44efd218d243 Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Thu, 12 Oct 2023 13:00:27 +0100 Subject: [PATCH 05/12] CORE-17430 Re-add source persisting --- .../tests/UtxoLedgerMessageProcessorTests.kt | 2 +- .../tests/UtxoPersistenceServiceImplTest.kt | 26 ++++++++-- .../utxo/tests/datamodel/UtxoEntityFactory.kt | 9 ++-- .../ledger/persistence/utxo/UtxoRepository.kt | 15 ++++-- .../persistence/utxo/UtxoTransactionReader.kt | 2 + .../utxo/impl/PostgresUtxoQueryProvider.kt | 14 ++++-- .../utxo/impl/UtxoPersistenceServiceImpl.kt | 42 +++++++++------- .../utxo/impl/UtxoQueryProvider.kt | 5 ++ .../utxo/impl/UtxoRepositoryImpl.kt | 27 +++++++--- .../utxo/impl/UtxoTransactionReaderImpl.kt | 2 + .../impl/UtxoPersistenceServiceImplTest.kt | 2 +- .../utxo/UtxoTransactionComponentEntity.kt | 12 +---- .../utxo/UtxoTransactionSourceEntity.kt | 49 +++++++++++++++++++ gradle.properties | 2 +- .../ledger/tests/HsqldbVaultNamedQueryTest.kt | 10 ++-- .../ledger/utxo/HsqldbUtxoQueryProvider.kt | 23 ++++++--- 16 files changed, 178 insertions(+), 64 deletions(-) create mode 100644 components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionSourceEntity.kt diff --git a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoLedgerMessageProcessorTests.kt b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoLedgerMessageProcessorTests.kt index 82c7e544f96..c0aa0885359 100644 --- a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoLedgerMessageProcessorTests.kt +++ b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoLedgerMessageProcessorTests.kt @@ -207,7 +207,7 @@ class UtxoLedgerMessageProcessorTests { listOf("4".toByteArray()), listOf("5".toByteArray()), emptyList(), - listOf("7".toByteArray()), + emptyList(), listOf(outputState), listOf("9".toByteArray()) ), diff --git a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt index 64b242a194f..170e293e54d 100644 --- a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt +++ b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt @@ -437,6 +437,24 @@ class UtxoPersistenceServiceImplTest { } } + val dbTransactionSources = em.createNamedQuery( + "UtxoTransactionSourceEntity.findByTransactionId", + entityFactory.utxoTransactionSource + ) + .setParameter("transactionId", signedTransaction.id.toString()) + .resultList + assertThat(dbTransactionSources).isNotNull + .hasSameSizeAs(defaultInputStateRefs) + dbTransactionSources + .sortedWith(compareBy { it.field("groupIndex") }.thenBy { it.field("leafIndex") }) + .zip(defaultInputStateRefs) + .forEachIndexed { leafIndex, (dbInput, transactionInput) -> + assertThat(dbInput.field("groupIndex")).isEqualTo(UtxoComponentGroup.INPUTS.ordinal) + assertThat(dbInput.field("leafIndex")).isEqualTo(leafIndex) + assertThat(dbInput.field("refTransactionId")).isEqualTo(transactionInput.transactionId.toString()) + assertThat(dbInput.field("refLeafIndex")).isEqualTo(transactionInput.index) + } + val dbTransactionOutputs = em.createNamedQuery( "UtxoVisibleTransactionOutputEntity.findByTransactionId", entityFactory.utxoVisibleTransactionOutput @@ -572,9 +590,7 @@ class UtxoPersistenceServiceImplTest { groupIndex, leafIndex, component, - digest("SHA-256", component).toString(), - null, - null + digest("SHA-256", component).toString() ) } } @@ -678,6 +694,10 @@ class UtxoPersistenceServiceImplTest { TODO("Not yet implemented") } + override fun getReferenceStateRefs(): List { + return emptyList() + } + override fun getConsumedStateRefs(): List { return listOf(StateRef(SecureHashImpl("SHA-256", ByteArray(12)), 1)) } diff --git a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/datamodel/UtxoEntityFactory.kt b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/datamodel/UtxoEntityFactory.kt index c3e6ee520a2..2c861508590 100644 --- a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/datamodel/UtxoEntityFactory.kt +++ b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/datamodel/UtxoEntityFactory.kt @@ -10,6 +10,7 @@ class UtxoEntityFactory(entityManagerFactory: EntityManagerFactory) { val utxoTransactionComponent: Class<*> get() = classFor("UtxoTransactionComponentEntity") val utxoVisibleTransactionOutput: Class<*> get() = classFor("UtxoVisibleTransactionOutputEntity") val utxoTransactionSignature: Class<*> get() = classFor("UtxoTransactionSignatureEntity") + val utxoTransactionSource: Class<*> get() = classFor("UtxoTransactionSourceEntity") fun createUtxoTransactionEntity( transactionId: String, @@ -29,12 +30,10 @@ class UtxoEntityFactory(entityManagerFactory: EntityManagerFactory) { groupIdx: Int, leafIdx: Int, component: ByteArray, - hash: String, - referencedTransactionId: String?, - referencedTransactionIndex: Int? + hash: String ): Any { - return utxoTransactionComponent.constructors.single { it.parameterCount == 7 }.newInstance( - utxoTransaction, groupIdx, leafIdx, component, hash, referencedTransactionId, referencedTransactionIndex + return utxoTransactionComponent.constructors.single { it.parameterCount == 5 }.newInstance( + utxoTransaction, groupIdx, leafIdx, component, hash ) } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt index 63699b69e5c..8ee3eb50464 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt @@ -79,6 +79,17 @@ interface UtxoRepository { status: TransactionStatus ) + /** Persists transaction source (operation is idempotent) */ + @Suppress("LongParameterList") + fun persistTransactionSource( + entityManager: EntityManager, + transactionId: String, + groupIndex: Int, + leafIndex: Int, + referencedStateTransactionId: String, + referencedStateIndex: Int + ) + /** Persists transaction component leaf [data] (operation is idempotent) */ @Suppress("LongParameterList") fun persistTransactionComponentLeaf( @@ -87,9 +98,7 @@ interface UtxoRepository { groupIndex: Int, leafIndex: Int, data: ByteArray, - hash: String, - referencedStateTransactionId: String?, - referencedStateIndex: Int? + hash: String ) /** Persists transaction output (operation is idempotent) */ diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoTransactionReader.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoTransactionReader.kt index 4da18b7fd18..b6075023ff2 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoTransactionReader.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoTransactionReader.kt @@ -32,4 +32,6 @@ interface UtxoTransactionReader { fun getConsumedStates(persistenceService: UtxoPersistenceService): List> fun getConsumedStateRefs(): List + + fun getReferenceStateRefs(): List } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt index 2b290ea5da3..0e39cd858d9 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt @@ -26,11 +26,19 @@ class PostgresUtxoQueryProvider @Activate constructor( WHERE utxo_transaction.status = EXCLUDED.status OR utxo_transaction.status = '$UNVERIFIED'""" .trimIndent() + override val persistTransactionSource: String + get() = """ + INSERT INTO {h-schema}utxo_transaction_sources( + transaction_id, group_idx, leaf_idx, referenced_state_transaction_id, referenced_state_index) + VALUES( + :transactionId, :groupIndex, :leafIndex, :referencedStateTransactionId, :referencedStateIndex) + ON CONFLICT DO NOTHING""" + .trimIndent() + override val persistTransactionComponentLeaf: String get() = """ - INSERT INTO {h-schema}utxo_transaction_component(transaction_id, group_idx, leaf_idx, data, hash, - referenced_state_transaction_id, referenced_state_index) - VALUES(:transactionId, :groupIndex, :leafIndex, :data, :hash, :referencedStateTransactionId, :referencedStateIndex) + INSERT INTO {h-schema}utxo_transaction_component(transaction_id, group_idx, leaf_idx, data, hash) + VALUES(:transactionId, :groupIndex, :leafIndex, :data, :hash) ON CONFLICT DO NOTHING""" .trimIndent() diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt index b7762cb42e4..30b1f73db41 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt @@ -158,33 +158,41 @@ class UtxoPersistenceServiceImpl( // Insert the Transactions components transaction.rawGroupLists.mapIndexed { groupIndex, leaves -> leaves.mapIndexed { leafIndex, data -> - val (referencedTransactionId, referencedStateIndex) = when (groupIndex) { - UtxoComponentGroup.INPUTS.ordinal, UtxoComponentGroup.REFERENCES.ordinal -> { - try { - val deserializedStateRef = serializationService.deserialize(data) - Pair(deserializedStateRef.transactionId.toString(), deserializedStateRef.index) - } catch (e: Exception) { - log.warn("Error deserializing input or reference state ref for transaction: $transactionIdString, " + - "group index: $groupIndex, leaf index: $leafIndex") - Pair(null, null) - } - } - else -> Pair(null, null) - } - repository.persistTransactionComponentLeaf( em, transactionIdString, groupIndex, leafIndex, data, - sandboxDigestService.hash(data, DigestAlgorithmName.SHA2_256).toString(), - referencedTransactionId, - referencedStateIndex + sandboxDigestService.hash(data, DigestAlgorithmName.SHA2_256).toString() ) } } + // Insert inputs data + transaction.getConsumedStateRefs().forEachIndexed { index, input -> + repository.persistTransactionSource( + em, + transactionIdString, + UtxoComponentGroup.INPUTS.ordinal, + index, + input.transactionId.toString(), + input.index + ) + } + + // Insert reference data + transaction.getReferenceStateRefs().forEachIndexed { index, reference -> + repository.persistTransactionSource( + em, + transactionIdString, + UtxoComponentGroup.INPUTS.ordinal, + index, + reference.transactionId.toString(), + reference.index + ) + } + // Insert outputs data transaction.getVisibleStates().entries.forEach { (stateIndex, stateAndRef) -> val utxoToken = utxoTokenMap[stateAndRef.ref] diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt index dfd63d5ff42..7b1bf85a120 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt @@ -61,6 +61,11 @@ interface UtxoQueryProvider { */ val persistTransaction: String + /** + * @property persistTransactionSource SQL text for [UtxoRepositoryImpl.persistTransactionSource]. + */ + val persistTransactionSource: String + /** * @property persistTransactionComponentLeaf SQL text for [UtxoRepositoryImpl.persistTransactionComponentLeaf]. */ diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt index c1ec776b016..04e647df4d9 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt @@ -190,15 +190,31 @@ class UtxoRepositoryImpl @Activate constructor( .logResult("transaction [$id]") } + override fun persistTransactionSource( + entityManager: EntityManager, + transactionId: String, + groupIndex: Int, + leafIndex: Int, + referencedStateTransactionId: String, + referencedStateIndex: Int + ) { + entityManager.createNativeQuery(queryProvider.persistTransactionSource) + .setParameter("transactionId", transactionId) + .setParameter("groupIndex", groupIndex) + .setParameter("leafIndex", leafIndex) + .setParameter("referencedStateTransactionId", referencedStateTransactionId) + .setParameter("referencedStateIndex", referencedStateIndex) + .executeUpdate() + .logResult("transaction source [$transactionId, $groupIndex, $leafIndex]") + } + override fun persistTransactionComponentLeaf( entityManager: EntityManager, transactionId: String, groupIndex: Int, leafIndex: Int, data: ByteArray, - hash: String, - referencedStateTransactionId: String?, - referencedStateIndex: Int? + hash: String ) { entityManager.createNativeQuery(queryProvider.persistTransactionComponentLeaf) .setParameter("transactionId", transactionId) @@ -206,11 +222,6 @@ class UtxoRepositoryImpl @Activate constructor( .setParameter("leafIndex", leafIndex) .setParameter("data", data) .setParameter("hash", hash) - .setParameter("referencedStateTransactionId", referencedStateTransactionId) - // This is a workaround for avoiding error when tokenAmount is null, see: - // https://stackoverflow.com/questions/53648865/postgresql-spring-data-jpa-integer-null-interpreted-as-bytea - .setParameter("referencedStateIndex", 0) - .setParameter("referencedStateIndex", referencedStateIndex) .executeUpdate() .logResult("transaction component [$transactionId, $groupIndex, $leafIndex]") } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoTransactionReaderImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoTransactionReaderImpl.kt index 372ded0da64..46906cb6825 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoTransactionReaderImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoTransactionReaderImpl.kt @@ -118,4 +118,6 @@ class UtxoTransactionReaderImpl( } override fun getConsumedStateRefs(): List = wrappedWireTransaction.inputStateRefs + + override fun getReferenceStateRefs(): List = wrappedWireTransaction.referenceStateRefs } diff --git a/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt b/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt index 7fd33e8be4b..c4b5ad22538 100644 --- a/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt +++ b/components/ledger/ledger-persistence/src/test/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImplTest.kt @@ -56,7 +56,7 @@ class UtxoPersistenceServiceImplTest { } on { persistTransaction(any(), any(), any(), any(), any(), any()) } doAnswer {} - on { persistTransactionComponentLeaf(any(), any(), any(), any(), any(), any(), anyOrNull(), anyOrNull()) } doAnswer {} + on { persistTransactionComponentLeaf(any(), any(), any(), any(), any(), any()) } doAnswer {} } private val mockPrivacySalt = mock { diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt index e09adee451c..9526b0ca710 100644 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionComponentEntity.kt @@ -34,13 +34,7 @@ data class UtxoTransactionComponentEntity( var data: ByteArray, @get:Column(name = "hash", nullable = false) - var hash: String, - - @get:Column(name = "referenced_state_transaction_id", nullable = true) - var referencedStateTransactionId: String?, - - @get:Column(name = "referenced_state_index", nullable = true) - var referencedStateIndex: Int? + var hash: String ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -53,8 +47,6 @@ data class UtxoTransactionComponentEntity( if (leafIndex != other.leafIndex) return false if (!data.contentEquals(other.data)) return false if (hash != other.hash) return false - if (referencedStateTransactionId != other.referencedStateTransactionId) return false - if (referencedStateIndex != other.referencedStateIndex) return false return true } @@ -65,8 +57,6 @@ data class UtxoTransactionComponentEntity( result = 31 * result + leafIndex result = 31 * result + data.contentHashCode() result = 31 * result + hash.hashCode() - result = 31 * result + referencedStateTransactionId.hashCode() - result = 31 * result + referencedStateIndex.hashCode() return result } } diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionSourceEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionSourceEntity.kt new file mode 100644 index 00000000000..09f669a6e36 --- /dev/null +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionSourceEntity.kt @@ -0,0 +1,49 @@ +package com.example.ledger.testing.datamodel.utxo + +import net.corda.v5.base.annotations.CordaSerializable +import java.io.Serializable +import javax.persistence.Column +import javax.persistence.Embeddable +import javax.persistence.Entity +import javax.persistence.Id +import javax.persistence.IdClass +import javax.persistence.JoinColumn +import javax.persistence.ManyToOne +import javax.persistence.NamedQuery +import javax.persistence.Table + +@CordaSerializable +@NamedQuery( + name = "UtxoTransactionSourceEntity.findByTransactionId", + query = "from UtxoTransactionSourceEntity where transaction.id = :transactionId" +) +@Entity +@Table(name = "utxo_transaction_sources") +@IdClass(UtxoTransactionSourceEntityId::class) +data class UtxoTransactionSourceEntity( + @get:Id + @get:ManyToOne + @get:JoinColumn(name = "transaction_id", nullable = false, updatable = false) + var transaction: UtxoTransactionEntity, + + @get:Id + @get:Column(name = "group_idx", nullable = false) + var groupIndex: Int, + + @get:Id + @get:Column(name = "leaf_idx", nullable = false) + var leafIndex: Int, + + @get:Column(name = "referenced_state_transaction_id", nullable = false) + var refTransactionId: String, + + @get:Column(name = "referenced_state_index", nullable = false) + var refLeafIndex: Int +) + +@Embeddable +data class UtxoTransactionSourceEntityId( + var transaction: UtxoTransactionEntity, + var groupIndex: Int, + var leafIndex: Int +) : Serializable diff --git a/gradle.properties b/gradle.properties index 3e85537e5f8..1904144ba7e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -46,7 +46,7 @@ commonsTextVersion = 1.10.0 bouncycastleVersion=1.76 # Corda API libs revision (change in 4th digit indicates a breaking change) # Change to 5.1.0.xx-SNAPSHOT to pick up maven local published copy -cordaApiVersion=5.1.0.32-alpha-1696949940130 +cordaApiVersion=5.1.0.33-alpha-1697111536293 disruptorVersion=3.4.4 felixConfigAdminVersion=1.9.26 diff --git a/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt b/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt index 7774c1e6b3d..2c53415b32d 100644 --- a/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt +++ b/testing/ledger/ledger-hsqldb/src/integrationTest/kotlin/net/corda/testing/ledger/tests/HsqldbVaultNamedQueryTest.kt @@ -7,6 +7,8 @@ import com.example.ledger.testing.datamodel.utxo.UtxoVisibleTransactionOutputEnt import com.example.ledger.testing.datamodel.utxo.UtxoVisibleTransactionOutputEntityId import com.example.ledger.testing.datamodel.utxo.UtxoTransactionSignatureEntity import com.example.ledger.testing.datamodel.utxo.UtxoTransactionSignatureEntityId +import com.example.ledger.testing.datamodel.utxo.UtxoTransactionSourceEntity +import com.example.ledger.testing.datamodel.utxo.UtxoTransactionSourceEntityId import java.time.Instant import java.util.UUID import javax.persistence.EntityManagerFactory @@ -83,7 +85,9 @@ class HsqldbVaultNamedQueryTest { UtxoVisibleTransactionOutputEntity::class.java, UtxoVisibleTransactionOutputEntityId::class.java, UtxoTransactionSignatureEntity::class.java, - UtxoTransactionSignatureEntityId::class.java + UtxoTransactionSignatureEntityId::class.java, + UtxoTransactionSourceEntity::class.java, + UtxoTransactionSourceEntityId::class.java )) entityManagerFactory = dbConnectionManager.createEntityManagerFactory(dbConnectionId, entities) } @@ -108,9 +112,7 @@ class HsqldbVaultNamedQueryTest { groupIndex = state.groupIndex, leafIndex = state.leafIndex, data = byteArrayOf(0x01, 0x02, 0x03, 0x04), - hash = "", - null, - null + hash = "" ) visibleStates += UtxoVisibleTransactionOutputEntity( diff --git a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt index 0cbe7cab7d8..1d428c2988a 100644 --- a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt +++ b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt @@ -30,18 +30,27 @@ class HsqldbUtxoQueryProvider @Activate constructor( VALUES (x.id, x.privacy_salt, x.account_id, x.created, x.status, x.updated)""" .trimIndent() + override val persistTransactionSource: String + get() = """ + MERGE INTO {h-schema}utxo_transaction_sources AS uts + USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), + :referencedStateTransactionId, CAST(:referencedStateIndex AS INT)) + AS x(transaction_id, group_idx, leaf_idx, referenced_state_transaction_id, referenced_state_index) + ON uts.transaction_id = x.transaction_id AND uts.group_idx = x.group_idx AND uts.leaf_idx = x.leaf_idx + WHEN NOT MATCHED THEN + INSERT (transaction_id, group_idx, leaf_idx, referenced_state_transaction_id, referenced_state_index) + VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.referenced_state_transaction_id, x.referenced_state_index)""" + .trimIndent() + override val persistTransactionComponentLeaf: String get() = """ MERGE INTO {h-schema}utxo_transaction_component AS utc - USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), CAST(:data AS VARBINARY(1048576)), :hash, - :referencedStateTransactionId, :referencedStateIndex) - AS x(transaction_id, group_idx, leaf_idx, data, hash, referenced_state_transaction_id, referenced_state_index) + USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), CAST(:data AS VARBINARY(1048576)), :hash) + AS x(transaction_id, group_idx, leaf_idx, data, hash) ON x.transaction_id = utc.transaction_id AND x.group_idx = utc.group_idx AND x.leaf_idx = utc.leaf_idx - AND x.referenced_state_transaction_id = utc.referenced_state_transaction_id - AND x.referenced_state_index = utc.referenced_state_index WHEN NOT MATCHED THEN - INSERT (transaction_id, group_idx, leaf_idx, data, hash, referenced_state_transaction_id, referenced_state_index) - VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.data, x.hash, x.referenced_state_transaction_id, x.referenced_state_index)""" + INSERT (transaction_id, group_idx, leaf_idx, data, hash) + VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.data, x.hash)""" .trimIndent() override fun persistVisibleTransactionOutput(consumed: Boolean): String { From 11c218aa2ef47c964576d2bc0960fc3a9b1fba89 Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Thu, 12 Oct 2023 13:10:39 +0100 Subject: [PATCH 06/12] fix group idx --- .../ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt index 30b1f73db41..53cfa2e65f0 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoPersistenceServiceImpl.kt @@ -186,7 +186,7 @@ class UtxoPersistenceServiceImpl( repository.persistTransactionSource( em, transactionIdString, - UtxoComponentGroup.INPUTS.ordinal, + UtxoComponentGroup.REFERENCES.ordinal, index, reference.transactionId.toString(), reference.index From c19d4a6a20c8d6280108c202ab18ab0c98fc3cfe Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Thu, 12 Oct 2023 13:30:09 +0100 Subject: [PATCH 07/12] extend test to include ref states --- .../tests/UtxoPersistenceServiceImplTest.kt | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt index 170e293e54d..d8ad2c6daca 100644 --- a/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt +++ b/components/ledger/ledger-persistence/src/integrationTest/kotlin/net/corda/ledger/persistence/utxo/tests/UtxoPersistenceServiceImplTest.kt @@ -443,13 +443,35 @@ class UtxoPersistenceServiceImplTest { ) .setParameter("transactionId", signedTransaction.id.toString()) .resultList - assertThat(dbTransactionSources).isNotNull + + assertThat(dbTransactionSources).allMatch { + it.field("groupIndex") == UtxoComponentGroup.INPUTS.ordinal + || it.field("groupIndex") == UtxoComponentGroup.REFERENCES.ordinal + } + + val (dbTransactionInputs, dbTransactionReferences) = dbTransactionSources.partition { + it.field("groupIndex") == UtxoComponentGroup.INPUTS.ordinal + } + + assertThat(dbTransactionInputs).isNotNull .hasSameSizeAs(defaultInputStateRefs) - dbTransactionSources + + assertThat(dbTransactionReferences).isNotNull + .hasSameSizeAs(defaultReferenceStateRefs) + + dbTransactionInputs .sortedWith(compareBy { it.field("groupIndex") }.thenBy { it.field("leafIndex") }) .zip(defaultInputStateRefs) .forEachIndexed { leafIndex, (dbInput, transactionInput) -> - assertThat(dbInput.field("groupIndex")).isEqualTo(UtxoComponentGroup.INPUTS.ordinal) + assertThat(dbInput.field("leafIndex")).isEqualTo(leafIndex) + assertThat(dbInput.field("refTransactionId")).isEqualTo(transactionInput.transactionId.toString()) + assertThat(dbInput.field("refLeafIndex")).isEqualTo(transactionInput.index) + } + + dbTransactionReferences + .sortedWith(compareBy { it.field("groupIndex") }.thenBy { it.field("leafIndex") }) + .zip(defaultReferenceStateRefs) + .forEachIndexed { leafIndex, (dbInput, transactionInput) -> assertThat(dbInput.field("leafIndex")).isEqualTo(leafIndex) assertThat(dbInput.field("refTransactionId")).isEqualTo(transactionInput.transactionId.toString()) assertThat(dbInput.field("refLeafIndex")).isEqualTo(transactionInput.index) @@ -695,7 +717,7 @@ class UtxoPersistenceServiceImplTest { } override fun getReferenceStateRefs(): List { - return emptyList() + return listOf(StateRef(SecureHashImpl("SHA-256", ByteArray(34)), 2)) } override fun getConsumedStateRefs(): List { From 00688c8b89356f7302e6ddfd71fc4731cf4be82a Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Thu, 12 Oct 2023 15:18:15 +0100 Subject: [PATCH 08/12] remove whitespace --- .../net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt index 1d428c2988a..b9c422477c3 100644 --- a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt +++ b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt @@ -47,7 +47,7 @@ class HsqldbUtxoQueryProvider @Activate constructor( MERGE INTO {h-schema}utxo_transaction_component AS utc USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), CAST(:data AS VARBINARY(1048576)), :hash) AS x(transaction_id, group_idx, leaf_idx, data, hash) - ON x.transaction_id = utc.transaction_id AND x.group_idx = utc.group_idx AND x.leaf_idx = utc.leaf_idx + ON x.transaction_id = utc.transaction_id AND x.group_idx = utc.group_idx AND x.leaf_idx = utc.leaf_idx WHEN NOT MATCHED THEN INSERT (transaction_id, group_idx, leaf_idx, data, hash) VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.data, x.hash)""" From 39ec1e7f2f65669f5f518d72ad7feb02c87dfc1f Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Fri, 13 Oct 2023 09:16:23 +0100 Subject: [PATCH 09/12] revert unrelated change --- .../persistence/utxo/impl/AbstractUtxoQueryProvider.kt | 7 ------- .../ledger/persistence/utxo/impl/UtxoQueryProvider.kt | 5 ----- .../ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt | 8 +++++++- .../testing/datamodel/utxo/UtxoTransactionEntity.kt | 4 ---- 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt index b7ceec46c6f..4a47246e39b 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/AbstractUtxoQueryProvider.kt @@ -9,13 +9,6 @@ abstract class AbstractUtxoQueryProvider : UtxoQueryProvider { val UNVERIFIED = TransactionStatus.UNVERIFIED.value } - override val findTransactionIdsAndStatuses: String - get() = """ - SELECT id, status - FROM {h-schema}utxo_transaction - WHERE id IN (:transactionIds)""" - .trimIndent() - override val findTransactionPrivacySalt: String get() = """ SELECT privacy_salt diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt index 7b1bf85a120..8f107523483 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoQueryProvider.kt @@ -91,9 +91,4 @@ interface UtxoQueryProvider { * @property persistSignedGroupParameters SQL text for [UtxoRepositoryImpl.persistSignedGroupParameters]. */ val persistSignedGroupParameters: String - - /** - * @property findTransactionIdsAndStatuses SQL text for [UtxoRepositoryImpl.findTransactionIdsAndStatuses]. - */ - val findTransactionIdsAndStatuses: String } diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt index 04e647df4d9..09505a635da 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt @@ -75,7 +75,13 @@ class UtxoRepositoryImpl @Activate constructor( entityManager: EntityManager, transactionIds: List ): Map { - return entityManager.createNativeQuery(queryProvider.findTransactionIdsAndStatuses, Tuple::class.java) + return entityManager.createNativeQuery( + """ + SELECT id, status + FROM {h-schema}utxo_transaction + WHERE id IN (:transactionIds)""", + Tuple::class.java + ) .setParameter("transactionIds", transactionIds) .resultListAsTuples() .associate { r -> parseSecureHash(r.get(0) as String) to r.get(1) as String } diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt index aa235f78716..83d102365fd 100644 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionEntity.kt @@ -48,8 +48,6 @@ data class UtxoTransactionEntity( if (!privacySalt.contentEquals(other.privacySalt)) return false if (accountId != other.accountId) return false if (created != other.created) return false - if (status != other.status) return false - if (updated != other.updated) return false return true } @@ -59,8 +57,6 @@ data class UtxoTransactionEntity( result = 31 * result + privacySalt.contentHashCode() result = 31 * result + accountId.hashCode() result = 31 * result + created.hashCode() - result = 31 * result + status.hashCode() - result = 31 * result + updated.hashCode() return result } } From 839d771246d906b295e85f6a2d71ca5e21c0ee20 Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Fri, 13 Oct 2023 09:41:20 +0100 Subject: [PATCH 10/12] column naming, vbump --- .../net/corda/ledger/persistence/utxo/UtxoRepository.kt | 4 ++-- .../persistence/utxo/impl/PostgresUtxoQueryProvider.kt | 4 ++-- .../ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt | 8 ++++---- .../testing/datamodel/utxo/UtxoTransactionSourceEntity.kt | 4 ++-- gradle.properties | 2 +- .../corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt index 8ee3eb50464..ec5c3c27f3a 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/UtxoRepository.kt @@ -86,8 +86,8 @@ interface UtxoRepository { transactionId: String, groupIndex: Int, leafIndex: Int, - referencedStateTransactionId: String, - referencedStateIndex: Int + sourceStateTransactionId: String, + sourceStateIndex: Int ) /** Persists transaction component leaf [data] (operation is idempotent) */ diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt index 0e39cd858d9..d61ffcc6471 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/PostgresUtxoQueryProvider.kt @@ -29,9 +29,9 @@ class PostgresUtxoQueryProvider @Activate constructor( override val persistTransactionSource: String get() = """ INSERT INTO {h-schema}utxo_transaction_sources( - transaction_id, group_idx, leaf_idx, referenced_state_transaction_id, referenced_state_index) + transaction_id, group_idx, leaf_idx, source_state_transaction_id, source_state_idx) VALUES( - :transactionId, :groupIndex, :leafIndex, :referencedStateTransactionId, :referencedStateIndex) + :transactionId, :groupIndex, :leafIndex, :sourceStateTransactionId, :sourceStateIndex) ON CONFLICT DO NOTHING""" .trimIndent() diff --git a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt index 09505a635da..0a19ad9832c 100644 --- a/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt +++ b/components/ledger/ledger-persistence/src/main/kotlin/net/corda/ledger/persistence/utxo/impl/UtxoRepositoryImpl.kt @@ -201,15 +201,15 @@ class UtxoRepositoryImpl @Activate constructor( transactionId: String, groupIndex: Int, leafIndex: Int, - referencedStateTransactionId: String, - referencedStateIndex: Int + sourceStateTransactionId: String, + sourceStateIndex: Int ) { entityManager.createNativeQuery(queryProvider.persistTransactionSource) .setParameter("transactionId", transactionId) .setParameter("groupIndex", groupIndex) .setParameter("leafIndex", leafIndex) - .setParameter("referencedStateTransactionId", referencedStateTransactionId) - .setParameter("referencedStateIndex", referencedStateIndex) + .setParameter("sourceStateTransactionId", sourceStateTransactionId) + .setParameter("sourceStateIndex", sourceStateIndex) .executeUpdate() .logResult("transaction source [$transactionId, $groupIndex, $leafIndex]") } diff --git a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionSourceEntity.kt b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionSourceEntity.kt index 09f669a6e36..5eaa0810324 100644 --- a/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionSourceEntity.kt +++ b/components/ledger/ledger-persistence/testing-datamodel/src/main/kotlin/com/example/ledger/testing/datamodel/utxo/UtxoTransactionSourceEntity.kt @@ -34,10 +34,10 @@ data class UtxoTransactionSourceEntity( @get:Column(name = "leaf_idx", nullable = false) var leafIndex: Int, - @get:Column(name = "referenced_state_transaction_id", nullable = false) + @get:Column(name = "source_state_transaction_id", nullable = false) var refTransactionId: String, - @get:Column(name = "referenced_state_index", nullable = false) + @get:Column(name = "source_state_idx", nullable = false) var refLeafIndex: Int ) diff --git a/gradle.properties b/gradle.properties index 1904144ba7e..85415fd7839 100644 --- a/gradle.properties +++ b/gradle.properties @@ -46,7 +46,7 @@ commonsTextVersion = 1.10.0 bouncycastleVersion=1.76 # Corda API libs revision (change in 4th digit indicates a breaking change) # Change to 5.1.0.xx-SNAPSHOT to pick up maven local published copy -cordaApiVersion=5.1.0.33-alpha-1697111536293 +cordaApiVersion=5.1.0.34-alpha-1697185435117 disruptorVersion=3.4.4 felixConfigAdminVersion=1.9.26 diff --git a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt index b9c422477c3..bbb8d6f0523 100644 --- a/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt +++ b/testing/ledger/ledger-hsqldb/src/main/kotlin/net/corda/testing/ledger/utxo/HsqldbUtxoQueryProvider.kt @@ -34,12 +34,12 @@ class HsqldbUtxoQueryProvider @Activate constructor( get() = """ MERGE INTO {h-schema}utxo_transaction_sources AS uts USING (VALUES :transactionId, CAST(:groupIndex AS INT), CAST(:leafIndex AS INT), - :referencedStateTransactionId, CAST(:referencedStateIndex AS INT)) - AS x(transaction_id, group_idx, leaf_idx, referenced_state_transaction_id, referenced_state_index) + :sourceStateTransactionId, CAST(:sourceStateIndex AS INT)) + AS x(transaction_id, group_idx, leaf_idx, source_state_transaction_id, source_state_idx) ON uts.transaction_id = x.transaction_id AND uts.group_idx = x.group_idx AND uts.leaf_idx = x.leaf_idx WHEN NOT MATCHED THEN - INSERT (transaction_id, group_idx, leaf_idx, referenced_state_transaction_id, referenced_state_index) - VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.referenced_state_transaction_id, x.referenced_state_index)""" + INSERT (transaction_id, group_idx, leaf_idx, source_state_transaction_id, source_state_idx) + VALUES (x.transaction_id, x.group_idx, x.leaf_idx, x.source_state_transaction_id, x.source_state_idx)""" .trimIndent() override val persistTransactionComponentLeaf: String From aa1e6da06286a952812ef9b0ef7767e38fcbade8 Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Fri, 13 Oct 2023 10:42:20 +0100 Subject: [PATCH 11/12] vbump --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7a66c075b71..85415fd7839 100644 --- a/gradle.properties +++ b/gradle.properties @@ -46,7 +46,7 @@ commonsTextVersion = 1.10.0 bouncycastleVersion=1.76 # Corda API libs revision (change in 4th digit indicates a breaking change) # Change to 5.1.0.xx-SNAPSHOT to pick up maven local published copy -cordaApiVersion=5.1.0.33-beta+ +cordaApiVersion=5.1.0.34-alpha-1697185435117 disruptorVersion=3.4.4 felixConfigAdminVersion=1.9.26 From 4eb438ad1904fbceb5a63360b06a6d60892b4a95 Mon Sep 17 00:00:00 2001 From: nkovacsx Date: Fri, 13 Oct 2023 12:15:24 +0100 Subject: [PATCH 12/12] vbump --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 85415fd7839..0bd8bfe6dbc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -46,7 +46,7 @@ commonsTextVersion = 1.10.0 bouncycastleVersion=1.76 # Corda API libs revision (change in 4th digit indicates a breaking change) # Change to 5.1.0.xx-SNAPSHOT to pick up maven local published copy -cordaApiVersion=5.1.0.34-alpha-1697185435117 +cordaApiVersion=5.1.0.34-beta+ disruptorVersion=3.4.4 felixConfigAdminVersion=1.9.26