From ff086b959b492eadefeed7224ba0d3229e1d245e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Wed, 20 Aug 2025 12:19:32 +0000 Subject: [PATCH 01/19] get a failing test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../store/MultiDomainAcsStoreTest.scala | 93 ++++++++++++++++--- 1 file changed, 82 insertions(+), 11 deletions(-) diff --git a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStoreTest.scala b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStoreTest.scala index 106d40564a..e950142c55 100644 --- a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStoreTest.scala +++ b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStoreTest.scala @@ -1601,23 +1601,94 @@ abstract class MultiDomainAcsStoreTest[ _ <- assertList() _ <- d1.create( goodContract, - implementedInterfaces = Map( - holdingv1.Holding.INTERFACE_ID_WITH_PACKAGE_ID -> goodView.toValue - ), + implementedInterfaces = goodImplementedInterfaces, ) _ <- d1.create( badContract, - implementedInterfaces = Map( - new Identifier( - maliciousPackageId, - holdingv1.Holding.INTERFACE_ID.getModuleName, - holdingv1.Holding.INTERFACE_ID.getEntityName, - ) -> badView.toValue + implementedInterfaces = badImplementedInterfaces, + ) + resultHolding <- store.listInterfaceViews(holdingv1.Holding.INTERFACE) + resultAmulet <- store.listContracts(Amulet.COMPANION) + } yield { + resultHolding.map(_.contractId.contractId) should contain theSameElementsAs Seq( + goodContract.contractId.contractId + ) + resultAmulet.map(_.contractId.contractId) should contain theSameElementsAs Seq( + goodContract.contractId.contractId + ) + } + } + + "prevent against ingestion of same (moduleName, entityName) with different package name - via interface fallback" in { + val filter = + MultiDomainAcsStore.SimpleContractFilter[GenericAcsRowData, GenericInterfaceRowData]( + dsoParty, + templateFilters = Map.empty, + interfaceFilters = Map( + mkFilterInterface(holdingv1.Holding.INTERFACE)(_ => true) { contract => + GenericInterfaceRowData(contract.identifier, contract.payload) + } ), ) - result <- store.listInterfaceViews(holdingv1.Holding.INTERFACE) + implicit val store = mkStore( + filter = filter + ) + val owner = providerParty(1) + val goodContract = amulet(owner, BigDecimal(10), 1L, BigDecimal(0.00001), dso = dsoParty) + val goodView = holdingView(owner, BigDecimal(10), dsoParty, "AMT") + val goodImplementedInterfaces = Map( + holdingv1.Holding.INTERFACE_ID_WITH_PACKAGE_ID -> goodView.toValue + ) + // like Splice's Amulet, but with different packageid + // that still implements the Holding interface + val fakeAmuletContract = + amulet(owner, BigDecimal(20), 2L, BigDecimal(0.00002), dso = dsoParty).copy(identifier = + new Identifier( + maliciousPackageId, + goodContract.identifier.getModuleName, + goodContract.identifier.getEntityName, + ) + ) + val fakeAmuletView = holdingView(owner, BigDecimal(20), dsoParty, "AMT") + val fakeAmuletImplementedInterfaces = Map( + holdingv1.Holding.INTERFACE_ID_WITH_PACKAGE_ID -> fakeAmuletView.toValue + ) + + filter.contains( + toCreatedEvent( + goodContract, + implementedInterfaces = goodImplementedInterfaces, + ) + ) should be(true) + + filter.contains( + toCreatedEvent( + fakeAmuletContract, + implementedInterfaces = fakeAmuletImplementedInterfaces, + ) + ) should be(true) // as a Holding, it is included. But it should not be included as an Amulet. + + for { + _ <- initWithAcs() + _ <- assertList() + _ <- d1.create( + goodContract, + implementedInterfaces = goodImplementedInterfaces, + ) + _ <- d1.create( + fakeAmuletContract, + implementedInterfaces = fakeAmuletImplementedInterfaces, + ) + resultHolding <- store.listInterfaceViews(holdingv1.Holding.INTERFACE) + resultAmulet <- store.listContracts(Amulet.COMPANION) } yield { - result.map(_.contractId.contractId) should contain theSameElementsAs Seq( + // fakeAmuletContract is a Holding + resultHolding.map(_.contractId.contractId) should contain theSameElementsAs Seq( + goodContract.contractId.contractId, + fakeAmuletContract.contractId.contractId, + ) + // but it is not an Amulet + resultAmulet.map(_.contractId.contractId) should contain theSameElementsAs Seq( goodContract.contractId.contractId ) } From ea2f40aeda9c3447167f759fb988205b66e8f67f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Wed, 20 Aug 2025 13:18:37 +0000 Subject: [PATCH 02/19] Break when the results would be bad [ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../stable/V043__package_name_acs_stores.sql | 8 +++++++ .../splice/store/MultiDomainAcsStore.scala | 4 ++++ .../splice/store/db/AcsJdbcTypes.scala | 12 ++++++++++- .../splice/store/db/AcsQueries.scala | 21 ++++++++++++++----- .../store/db/DbMultiDomainAcsStore.scala | 12 ++++++----- 5 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql diff --git a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql new file mode 100644 index 0000000000..50f6b86cb9 --- /dev/null +++ b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql @@ -0,0 +1,8 @@ +alter table acs_store_template add column package_name text; +alter table user_wallet_acs_store add column package_name text; +alter table external_party_wallet_acs_store add column package_name text; +alter table validator_acs_store add column package_name text; +alter table sv_acs_store add column package_name text; +alter table dso_acs_store add column package_name text; +alter table scan_acs_store add column package_name text; +alter table splitwell_acs_store add column package_name text; diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala index f418855fb2..d26788361b 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala @@ -600,6 +600,10 @@ object MultiDomainAcsStore { def typeId(companion: C): Identifier + // This is safe because if we have a companion, the package exists in resources + def packageQualifiedName(companion: C) = + PackageQualifiedName.getFromResources(typeId(companion)) + def toContractId(companion: C, contractId: String): TCid protected def fromJson( diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsJdbcTypes.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsJdbcTypes.scala index 5d93e7b155..a360a6f7f7 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsJdbcTypes.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsJdbcTypes.scala @@ -19,7 +19,12 @@ import io.circe.parser.parse as circeParse import org.lfdecentralizedtrust.splice.store.db.AcsQueries.AcsStoreId import org.lfdecentralizedtrust.splice.store.db.TxLogQueries.TxLogStoreId import org.lfdecentralizedtrust.splice.util.Contract.Companion -import org.lfdecentralizedtrust.splice.util.{Contract, LegacyOffset, QualifiedName} +import org.lfdecentralizedtrust.splice.util.{ + Contract, + LegacyOffset, + PackageQualifiedName, + QualifiedName, +} import slick.ast.FieldSymbol import slick.jdbc.{GetResult, JdbcType, PositionedParameters, PositionedResult, SetParameter} import com.digitalasset.canton.LfValue @@ -191,6 +196,11 @@ trait AcsJdbcTypes { protected implicit val qualifiedNameGetResult: GetResult[QualifiedName] = GetResult.GetString.andThen { s => QualifiedName.assertFromString(s) } + protected implicit val packageQualifiedNameGetResult: GetResult[PackageQualifiedName] = + implicitly[GetResult[(QualifiedName, String)]].andThen { case (qualifiedName, packageName) => + PackageQualifiedName(packageName, qualifiedName) + } + protected implicit lazy val qualifiedNameJdbcType: JdbcType[QualifiedName] = MappedColumnType.base[QualifiedName, String]( { _.toString }, { diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala index 882081f07a..d3537ecb8e 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala @@ -18,7 +18,7 @@ import org.lfdecentralizedtrust.splice.util.{ Contract, ContractWithState, LegacyOffset, - QualifiedName, + PackageQualifiedName, TemplateJsonDecoder, } import slick.jdbc.{GetResult, PositionedResult, SetParameter} @@ -60,7 +60,7 @@ trait AcsQueries extends AcsJdbcTypes { <<[Long], <<[ContractId[Any]], <<[String], - <<[QualifiedName], + <<[PackageQualifiedName], <<[Json], <<[Array[Byte]], <<[Timestamp], @@ -316,7 +316,7 @@ object AcsQueries { eventNumber: Long, contractId: ContractId[Any], templateIdPackageId: String, - templateIdQualifiedName: QualifiedName, + packageQualifiedName: PackageQualifiedName, createArguments: Json, createdEventBlob: Array[Byte], createdAt: Timestamp, @@ -326,12 +326,22 @@ object AcsQueries { companionClass: ContractCompanion[C, TCId, T], decoder: TemplateJsonDecoder, ): Contract[TCId, T] = { + // safety check: if the templates don't match, + // it means that we would be returning a contract of a different template + // note that the packageId not matching is expected due to upgrades, but the name will be stable + val expectedPackageQualifiedName = companionClass.packageQualifiedName(companion) + if (expectedPackageQualifiedName != packageQualifiedName) { + throw new IllegalStateException( + s"Contract $contractId has a different package qualified name than expected. Expected: $expectedPackageQualifiedName - Got: $packageQualifiedName" + ) + } + companionClass .fromJson(companion)( new Identifier( templateIdPackageId, - templateIdQualifiedName.moduleName, - templateIdQualifiedName.entityName, + packageQualifiedName.qualifiedName.moduleName, + packageQualifiedName.qualifiedName.entityName, ), contractId.contractId, createArguments, @@ -353,6 +363,7 @@ object AcsQueries { ${qualifier}contract_id, ${qualifier}template_id_package_id, ${qualifier}template_id_qualified_name, + ${qualifier}package_name, ${qualifier}create_arguments, ${qualifier}created_event_blob, ${qualifier}created_at, diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala index 0678838311..0c128517b4 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala @@ -29,6 +29,7 @@ import org.lfdecentralizedtrust.splice.util.{ Contract, ContractWithState, LegacyOffset, + PackageQualifiedName, QualifiedName, TemplateJsonDecoder, Trees, @@ -362,9 +363,9 @@ final class DbMultiDomainAcsStore[TXE]( limit: notOnDomainsTotalLimit.type, )(implicit tc: TraceContext): Future[Seq[AssignedContract[?, ?]]] = waitUntilAcsIngested { val templateIdMap = companions - .map(c => QualifiedName(c.getTemplateIdWithPackageId) -> c) + .map(c => PackageQualifiedName.getFromResources(c.getTemplateIdWithPackageId) -> c) .toMap - val templateIds = inClause(templateIdMap.keys) + val templateIds = inClause(templateIdMap.keys.map(_.qualifiedName)) // TODO: fix this for { result <- storage.query( selectFromAcsTableWithState( @@ -385,7 +386,7 @@ final class DbMultiDomainAcsStore[TXE]( ) } yield result.map { row => assignedContractFromRow( - templateIdMap(row.acsRow.templateIdQualifiedName) + templateIdMap(row.acsRow.packageQualifiedName) )(row) } } @@ -1631,6 +1632,7 @@ final class DbMultiDomainAcsStore[TXE]( val templateId = rowData.identifier val templateIdQualifiedName = QualifiedName(templateId) val templateIdPackageId = lengthLimited(rowData.identifier.getPackageId) + val packageName = createdEvent.getPackageName val createArguments = rowData.payload val createdAt = Timestamp.assertFromInstant(rowData.createdAt) val contractExpiresAt = rowData.contractExpiresAt @@ -1649,12 +1651,12 @@ final class DbMultiDomainAcsStore[TXE]( import storage.DbStorageConverters.setParameterByteArray (sql""" - insert into #$acsTableName(store_id, migration_id, contract_id, template_id_package_id, template_id_qualified_name, + insert into #$acsTableName(store_id, migration_id, contract_id, template_id_package_id, template_id_qualified_name, package_name, create_arguments, created_event_blob, created_at, contract_expires_at, assigned_domain, reassignment_counter, reassignment_target_domain, reassignment_source_domain, reassignment_submitter, reassignment_unassign_id #$indexColumnNames) - values ($acsStoreId, $domainMigrationId, $contractId, $templateIdPackageId, $templateIdQualifiedName, + values ($acsStoreId, $domainMigrationId, $contractId, $templateIdPackageId, $templateIdQualifiedName, $packageName, $createArguments, $createdEventBlob, $createdAt, $contractExpiresAt, $assignedDomain, $reassignmentCounter, $reassignmentTargetDomain, $reassignmentSourceDomain, $reassignmentSubmitter, $reassignmentUnassignId From ee72588734ba1696108160e42df8392175aebafe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Wed, 20 Aug 2025 13:51:57 +0000 Subject: [PATCH 03/19] [ci] fix things MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala index d3537ecb8e..d22c3eff2d 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala @@ -125,6 +125,7 @@ trait AcsQueries extends AcsJdbcTypes { contract_id, template_id_package_id, template_id_qualified_name, + package_name, create_arguments, created_event_blob, created_at, @@ -182,6 +183,7 @@ trait AcsQueries extends AcsJdbcTypes { acs.contract_id, acs.template_id_package_id, acs.template_id_qualified_name, + acs.package_name, acs.create_arguments, acs.created_event_blob, acs.created_at, From cae3fadd95e49336bc68ea0d275c289d49f7a55e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Wed, 20 Aug 2025 14:17:13 +0000 Subject: [PATCH 04/19] [ci] more fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala index 29ec5bacdf..221afba894 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala @@ -143,6 +143,7 @@ class DbSvDsoStore( idle.contract_id, idle.template_id_package_id, idle.template_id_qualified_name, + idle.package_name, idle.create_arguments, idle.created_event_blob, idle.created_at, @@ -153,6 +154,7 @@ class DbSvDsoStore( ctx.contract_id, ctx.template_id_package_id, ctx.template_id_qualified_name, + ctx.package_name, ctx.create_arguments, ctx.created_event_blob, ctx.created_at, From 41990504f3f9d24c026b535cdcef5ed6b75fb763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Wed, 20 Aug 2025 15:33:18 +0000 Subject: [PATCH 05/19] [ci] was that a gha/k8s failure or did i cause that? let's find out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz From 0c0112205bcca2a3be45534e43d00a6f3bb0f1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Thu, 21 Aug 2025 13:15:16 +0000 Subject: [PATCH 06/19] [ci] refactor so many queries something is bound to break MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../splice/console/LedgerApiExtensions.scala | 2 +- .../store/DbVotesStoreQueryBuilder.scala | 13 +- .../splice/store/MultiDomainAcsStore.scala | 16 -- .../splice/store/db/AcsQueries.scala | 52 +++- .../store/db/DbMultiDomainAcsStore.scala | 123 ++++----- .../splice/util/QualifiedName.scala | 10 + .../store/MultiDomainAcsStoreTest.scala | 45 ---- .../splice/scan/store/db/DbScanStore.scala | 78 ++---- .../splitwell/store/db/DbSplitwellStore.scala | 12 +- .../splice/sv/store/db/DbSvDsoStore.scala | 247 +++++++----------- .../splice/sv/store/db/DbSvSvStore.scala | 18 +- .../validator/store/db/DbValidatorStore.scala | 86 ++---- .../wallet/store/db/DbUserWalletStore.scala | 37 ++- 13 files changed, 270 insertions(+), 469 deletions(-) diff --git a/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/console/LedgerApiExtensions.scala b/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/console/LedgerApiExtensions.scala index ea7fd02166..569eab5453 100644 --- a/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/console/LedgerApiExtensions.scala +++ b/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/console/LedgerApiExtensions.scala @@ -391,7 +391,7 @@ trait LedgerApiExtensions extends AppendedClues with Matchers { predicate: TC => Boolean = (_: TC) => true, ): Seq[TC] = { val filterIdentifier = - PackageQualifiedName.getFromResources(templateCompanion.getTemplateIdWithPackageId) + PackageQualifiedName.fromJavaCodegenCompanion(templateCompanion) val templateId = TemplateId( s"#${filterIdentifier.packageName}", filterIdentifier.qualifiedName.moduleName, diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/DbVotesStoreQueryBuilder.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/DbVotesStoreQueryBuilder.scala index 0adcb616a6..d088861420 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/DbVotesStoreQueryBuilder.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/DbVotesStoreQueryBuilder.scala @@ -11,7 +11,6 @@ import org.lfdecentralizedtrust.splice.codegen.java.splice.dsorules.VoteRequest import org.lfdecentralizedtrust.splice.store.db.AcsQueries.AcsStoreId import org.lfdecentralizedtrust.splice.store.db.TxLogQueries.TxLogStoreId import org.lfdecentralizedtrust.splice.store.db.{AcsQueries, TxLogQueries} -import org.lfdecentralizedtrust.splice.util.QualifiedName import slick.dbio.{Effect, NoStream} import slick.jdbc.canton.ActionBasedSQLInterpolation.Implicits.actionBasedSQLInterpolationCanton import slick.sql.SqlStreamingAction @@ -110,10 +109,8 @@ trait DbVotesAcsStoreQueryBuilder extends AcsQueries with LimitHelpers with Name acsTableName, acsStoreId, domainMigrationId, - where = (sql""" template_id_qualified_name = ${QualifiedName( - VoteRequest.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and #$trackingCidColumnName in """ ++ voteRequestTrackingCidsSql).toActionBuilder, + VoteRequest.COMPANION, + where = (sql""" #$trackingCidColumnName in """ ++ voteRequestTrackingCidsSql).toActionBuilder, orderLimit = sql"""limit ${sqlLimit(limit)}""", ) } @@ -133,10 +130,8 @@ trait DbVotesAcsStoreQueryBuilder extends AcsQueries with LimitHelpers with Name acsTableName, acsStoreId, domainMigrationId, - where = (sql""" template_id_qualified_name = ${QualifiedName( - VoteRequest.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and #$trackingCidColumnName = $voteRequestCid """).toActionBuilder, + VoteRequest.COMPANION, + where = (sql""" #$trackingCidColumnName = $voteRequestCid """).toActionBuilder, ).headOption } diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala index d26788361b..985a842dd4 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala @@ -175,22 +175,6 @@ trait MultiDomainAcsStore extends HasIngestionSink with AutoCloseable with Named traceContext: TraceContext, ): Future[Seq[Contract[TCid, T]]] - /** At most 1000 (`notOnDomainsTotalLimit`) contracts sorted by a hash of - * contract ID and participant ID. - * - * The idea is that different apps making the same migration on different - * participants will split the work better, while preserving determinism of a - * specific running app for fault-tolerance. For the former to happen, the - * position of a contract on one list must have no correlation with that on - * another list; that is why the contract ID by itself cannot be used by - * itself as the source of the sort key. - */ - def listAssignedContractsNotOnDomainN( - excludedDomain: SynchronizerId, - companions: Seq[ConstrainedTemplate], - limit: notOnDomainsTotalLimit.type = notOnDomainsTotalLimit, - )(implicit tc: TraceContext): Future[Seq[AssignedContract[?, ?]]] - private[splice] def listExpiredFromPayloadExpiry[C, TCid <: ContractId[T], T <: Template]( companion: C )(implicit diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala index d22c3eff2d..88d029d8df 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala @@ -31,24 +31,33 @@ import io.grpc.Status import slick.jdbc.canton.SQLActionBuilder import com.google.protobuf.ByteString import scalaz.{@@, Tag} +import slick.dbio.Effect +import slick.sql.SqlStreamingAction trait AcsQueries extends AcsJdbcTypes { /** @param tableName Must be SQL-safe, as it needs to be interpolated unsafely. * This is fine, as all calls to this method should use static string constants. */ - protected def selectFromAcsTable( + protected def selectFromAcsTable[C, TCid <: ContractId[_], T]( tableName: String, storeId: AcsStoreId, migrationId: Long, - where: SQLActionBuilder, + companion: C, + where: SQLActionBuilder = sql"true", orderLimit: SQLActionBuilder = sql"", - ) = + )(implicit companionClass: ContractCompanion[C, TCid, T]) = { + val packageQualifiedName = companionClass.packageQualifiedName(companion) (sql""" select #${SelectFromAcsTableResult.sqlColumnsCommaSeparated()} from #$tableName acs - where acs.store_id = $storeId and acs.migration_id = $migrationId and """ ++ where ++ sql""" + where acs.store_id = $storeId + and acs.migration_id = $migrationId + and acs.package_name = ${packageQualifiedName.packageName} + and acs.template_id_qualified_name = ${packageQualifiedName.qualifiedName} + and """ ++ where ++ sql""" """ ++ orderLimit).toActionBuilder.as[AcsQueries.SelectFromAcsTableResult] + } implicit val GetResultSelectFromAcsTable: GetResult[AcsQueries.SelectFromAcsTableResult] = GetResult { prs => @@ -70,18 +79,27 @@ trait AcsQueries extends AcsJdbcTypes { } /** Similar to [[selectFromAcsTable]], but also returns the contract state (i.e., the domain to which a contract is currently assigned) */ - protected def selectFromAcsTableWithState( + protected def selectFromAcsTableWithState[C, TCid <: ContractId[_], T]( tableName: String, storeId: AcsStoreId, migrationId: Long, - where: SQLActionBuilder, + companion: C, + additionalWhere: SQLActionBuilder = sql"", orderLimit: SQLActionBuilder = sql"", - ) = + )(implicit companionClass: ContractCompanion[C, TCid, T]): SqlStreamingAction[Vector[ + SelectFromAcsTableWithStateResult + ], SelectFromAcsTableWithStateResult, Effect.Read] = { + val packageQualifiedName = companionClass.packageQualifiedName(companion) (sql""" select #${SelectFromAcsTableWithStateResult.sqlColumnsCommaSeparated()} from #$tableName acs - where acs.store_id = $storeId and acs.migration_id = $migrationId and """ ++ where ++ sql""" + where acs.store_id = $storeId + and acs.migration_id = $migrationId + and acs.package_name = ${packageQualifiedName.packageName} + and acs.template_id_qualified_name = ${packageQualifiedName.qualifiedName} + """ ++ additionalWhere ++ sql""" """ ++ orderLimit).toActionBuilder.as[AcsQueries.SelectFromAcsTableWithStateResult] + } implicit val GetResultSelectFromContractStateResult : GetResult[AcsQueries.SelectFromContractStateResult] = @@ -109,13 +127,15 @@ trait AcsQueries extends AcsJdbcTypes { * This guarantees that the fetched contracts exist in the given offset, * whereas two separate queries (one to fetch the contract and one to fetch the offset) don't guarantee that. */ - protected def selectFromAcsTableWithOffset( + protected def selectFromAcsTableWithOffset[C, TCid <: ContractId[_], T]( tableName: String, storeId: AcsStoreId, migrationId: Long, + companion: C, where: SQLActionBuilder, orderLimit: SQLActionBuilder = sql"", - ) = + )(implicit companionClass: ContractCompanion[C, TCid, T]) = { + val packageQualifiedName = companionClass.packageQualifiedName(companion) (sql""" select acs.store_id, @@ -136,10 +156,13 @@ trait AcsQueries extends AcsJdbcTypes { left join #$tableName acs on o.store_id = acs.store_id and o.migration_id = acs.migration_id + and acs.package_name = ${packageQualifiedName.packageName} + and acs.template_id_qualified_name = ${packageQualifiedName.qualifiedName} and """ ++ where ++ sql""" where sd.id = $storeId and o.migration_id = $migrationId """ ++ orderLimit).toActionBuilder .as[AcsQueries.SelectFromAcsTableResultWithOffset] + } implicit val GetResultSelectFromAcsTableResultWithOffset : GetResult[AcsQueries.SelectFromAcsTableResultWithOffset] = { (pp: PositionedResult) => @@ -167,13 +190,15 @@ trait AcsQueries extends AcsJdbcTypes { /** Same as [[selectFromAcsTableWithOffset]], but also includes the contract state. */ - protected def selectFromAcsTableWithStateAndOffset( + protected def selectFromAcsTableWithStateAndOffset[C, TCid <: ContractId[_], T]( tableName: String, storeId: AcsStoreId, migrationId: Long, + companion: C, where: SQLActionBuilder = sql"true", orderLimit: SQLActionBuilder = sql"", - ) = + )(implicit companionClass: ContractCompanion[C, TCid, T]) = { + val packageQualifiedName = companionClass.packageQualifiedName(companion) (sql""" select acs.store_id, @@ -201,10 +226,13 @@ trait AcsQueries extends AcsJdbcTypes { left join #$tableName acs on o.store_id = acs.store_id and o.migration_id = acs.migration_id + and acs.package_name = ${packageQualifiedName.packageName} + and acs.template_id_qualified_name = ${packageQualifiedName.qualifiedName} and """ ++ where ++ sql""" where sd.id = $storeId and o.migration_id = $migrationId """ ++ orderLimit).toActionBuilder .as[AcsQueries.SelectFromAcsTableResultWithStateAndOffset] + } implicit val GetResultSelectFromAcsTableResultWithStateOffset : GetResult[AcsQueries.SelectFromAcsTableResultWithStateAndOffset] = { diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala index 0c128517b4..3a4f5b279b 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala @@ -29,7 +29,6 @@ import org.lfdecentralizedtrust.splice.util.{ Contract, ContractWithState, LegacyOffset, - PackageQualifiedName, QualifiedName, TemplateJsonDecoder, Trees, @@ -74,6 +73,8 @@ import scala.collection.mutable import scala.reflect.ClassTag import org.lfdecentralizedtrust.splice.util.FutureUnlessShutdownUtil.futureUnlessShutdownToFuture +import scala.annotation.unused + final class DbMultiDomainAcsStore[TXE]( storage: DbStorage, acsTableName: String, @@ -88,7 +89,7 @@ final class DbMultiDomainAcsStore[TXE]( ], txLogConfig: TxLogStore.Config[TXE], domainMigrationInfo: DomainMigrationInfo, - participantId: ParticipantId, + @unused participantId: ParticipantId, // TODO: figure out what's up with this retryProvider: RetryProvider, /** Allows processing the summary in a store-specific manner, e.g., to produce metrics * on ingestion of certain contracts. @@ -175,7 +176,8 @@ final class DbMultiDomainAcsStore[TXE]( acsTableName, acsStoreId, domainMigrationId, - where = sql"""acs.contract_id = ${lengthLimited(id.contractId)}""", + companion, + additionalWhere = sql"""and acs.contract_id = ${lengthLimited(id.contractId)}""", ).headOption, "lookupContractById", ) @@ -189,7 +191,6 @@ final class DbMultiDomainAcsStore[TXE]( companionClass: ContractCompanion[C, TCid, T], traceContext: TraceContext, ): Future[QueryResult[Option[ContractWithState[TCid, T]]]] = waitUntilAcsIngested { - val templateId = companionClass.typeId(companion) for { resultWithOffset <- storage .querySingle( @@ -197,7 +198,7 @@ final class DbMultiDomainAcsStore[TXE]( acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName(templateId)}""", + companion, orderLimit = sql"limit 1", ).headOption, "findAnyContractWithOffset", @@ -217,12 +218,14 @@ final class DbMultiDomainAcsStore[TXE]( ): Future[Option[ContractState]] = waitUntilAcsIngested { storage .querySingle( // index: acs_store_template_sid_mid_cid - selectFromAcsTableWithState( - acsTableName, - acsStoreId, - domainMigrationId, - where = sql"""acs.contract_id = ${lengthLimited(id.contractId)}""", - ).headOption, + (sql""" + select #${SelectFromAcsTableWithStateResult.sqlColumnsCommaSeparated()} + from #$acsTableName acs + where acs.store_id = $acsStoreId + and acs.migration_id = $domainMigrationId + and acs.contract_id = ${lengthLimited(id.contractId)}""").toActionBuilder + .as[AcsQueries.SelectFromAcsTableWithStateResult] + .headOption, "lookupContractStateById", ) .map(result => contractStateFromRow(result.stateRow)) @@ -258,15 +261,15 @@ final class DbMultiDomainAcsStore[TXE]( val opName = s"listContracts:${templateId.getEntityName}" val afterCondition = after.fold(sql"")(a => (sql" and " ++ sortOrder.whereEventNumber(a)).toActionBuilder) + for { result <- storage.query( // index: acs_store_template_sid_mid_tid_en selectFromAcsTableWithState( acsTableName, acsStoreId, domainMigrationId, - where = (sql"""template_id_qualified_name = ${QualifiedName( - templateId - )} """ ++ afterCondition).toActionBuilder, + companion, + additionalWhere = afterCondition, orderLimit = (sortOrder.orderByAcsEventNumber ++ sql""" limit ${sqlLimit(limit)}""").toActionBuilder, ), @@ -292,12 +295,11 @@ final class DbMultiDomainAcsStore[TXE]( acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - templateId - )} and assigned_domain is not null""", + companion, + additionalWhere = sql"""and assigned_domain is not null""", orderLimit = sql"""order by event_number limit ${sqlLimit(limit)}""", ), - "listAssignedContracts", + s"listAssignedContracts:$templateId", ) limited = applyLimit("listAssignedContracts", limit, result) assigned = limited.map(assignedContractFromRow(companion)(_)) @@ -309,7 +311,6 @@ final class DbMultiDomainAcsStore[TXE]( ], T <: Template](companion: C)(implicit companionClass: ContractCompanion[C, TCid, T] ): ListExpiredContracts[TCid, T] = { (now, limit) => implicit traceContext => - val templateId = companionClass.typeId(companion) for { _ <- waitUntilAcsIngested() result <- storage @@ -318,9 +319,8 @@ final class DbMultiDomainAcsStore[TXE]( acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - templateId - )} and acs.contract_expires_at < $now""", + companion, + additionalWhere = sql"""and acs.contract_expires_at < $now""", orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listExpiredFromPayloadExpiry", @@ -338,16 +338,14 @@ final class DbMultiDomainAcsStore[TXE]( companionClass: ContractCompanion[C, TCid, T], traceContext: TraceContext, ): Future[Seq[Contract[TCid, T]]] = waitUntilAcsIngested { - val templateId = companionClass.typeId(companion) for { result <- storage.query( selectFromAcsTableWithState( acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - templateId - )} and assigned_domain = $domain""", + companion, + additionalWhere = sql"""and assigned_domain = $domain""", orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listContractsOnDomain", @@ -357,50 +355,16 @@ final class DbMultiDomainAcsStore[TXE]( } yield contracts } - override def listAssignedContractsNotOnDomainN( - excludedDomain: SynchronizerId, - companions: Seq[ConstrainedTemplate], - limit: notOnDomainsTotalLimit.type, - )(implicit tc: TraceContext): Future[Seq[AssignedContract[?, ?]]] = waitUntilAcsIngested { - val templateIdMap = companions - .map(c => PackageQualifiedName.getFromResources(c.getTemplateIdWithPackageId) -> c) - .toMap - val templateIds = inClause(templateIdMap.keys.map(_.qualifiedName)) // TODO: fix this - for { - result <- storage.query( - selectFromAcsTableWithState( - acsTableName, - acsStoreId, - domainMigrationId, - where = - (sql"""template_id_qualified_name IN """ ++ templateIds ++ sql""" and assigned_domain is not null and assigned_domain != $excludedDomain""").toActionBuilder, - // bytea comparison in PG is left-to-right unsigned ascending, shorter - // array is lesser if bytes are otherwise equal; there's an equivalent - // soft implementation in - // InMemoryMultiDomainAcsStore.reassignmentContractOrder - orderLimit = - sql"""order by extensions.digest((contract_id || $participantId)::bytea, 'md5'::text) - limit ${(limit: PageLimit).limit}""", - ), - "listAssignedContractsNotOnDomainN", - ) - } yield result.map { row => - assignedContractFromRow( - templateIdMap(row.acsRow.packageQualifiedName) - )(row) - } - } - override def streamAssignedContracts[C, TCid <: ContractId[_], T](companion: C)(implicit companionClass: ContractCompanion[C, TCid, T], traceContext: TraceContext, ): Source[AssignedContract[TCid, T], NotUsed] = { - val templateId = companionClass.typeId(companion) + val packageQualifiedName = companionClass.packageQualifiedName(companion) streamContractsWithState( pageSize = defaultPageSizeForContractStream, - where = sql"""assigned_domain is not null and template_id_qualified_name = ${QualifiedName( - templateId - )}""", + where = sql"""assigned_domain is not null + and package_name = ${packageQualifiedName.packageName} + and template_id_qualified_name = ${packageQualifiedName.qualifiedName}""", ) .map(assignedContractFromRow(companion)(_)) } @@ -675,14 +639,15 @@ final class DbMultiDomainAcsStore[TXE]( val offsetPromise = state.get().offsetChanged storage .query( - selectFromAcsTableWithState( - acsTableName, - acsStoreId, - domainMigrationId, - where = (where ++ sql" and state_number >= $fromNumber").toActionBuilder, - orderLimit = - (sql"order by state_number limit ${sqlLimit(pageSize)}").toActionBuilder, - ), + (sql""" + select #${SelectFromAcsTableWithStateResult.sqlColumnsCommaSeparated()} + from #$acsTableName acs + where acs.store_id = $acsStoreId + and acs.migration_id = $domainMigrationId + and state_number >= $fromNumber + and """ ++ where ++ sql""" + order by state_number limit ${sqlLimit(pageSize)}""").toActionBuilder + .as[AcsQueries.SelectFromAcsTableWithStateResult], "streamContractsWithState", ) .flatMap { rows => @@ -721,12 +686,14 @@ final class DbMultiDomainAcsStore[TXE]( waitUntilAcsIngested { storage .querySingle( - selectFromAcsTableWithState( - acsTableName, - acsStoreId, - domainMigrationId, - where = sql"""acs.contract_id = ${contractId}""", - ).headOption, + (sql""" + select #${SelectFromAcsTableWithStateResult.sqlColumnsCommaSeparated()} + from #$acsTableName acs + where acs.store_id = $acsStoreId + and acs.migration_id = $domainMigrationId + and acs.contract_id = $contractId""").toActionBuilder + .as[AcsQueries.SelectFromAcsTableWithStateResult] + .headOption, "isReadyForAssign", ) .value diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/util/QualifiedName.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/util/QualifiedName.scala index 72847a4fb5..173853b5af 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/util/QualifiedName.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/util/QualifiedName.scala @@ -26,6 +26,7 @@ object PackageQualifiedName { } } + // TODO: replace more usages of this with java codegen one def getFromResources(identifier: Identifier): PackageQualifiedName = { lookupFromResources(identifier) .getOrElse(throw new IllegalArgumentException(s"No package found for template $identifier")) @@ -37,6 +38,15 @@ object PackageQualifiedName { QualifiedName(event.getTemplateId.getModuleName, event.getTemplateId.getEntityName), ) } + + def fromJavaCodegenCompanion( + companion: com.daml.ledger.javaapi.data.codegen.ContractCompanion[?, ?, ?] + ): PackageQualifiedName = { + PackageQualifiedName( + companion.PACKAGE_NAME, + QualifiedName(companion.TEMPLATE_ID.getModuleName, companion.TEMPLATE_ID.getEntityName), + ) + } } object QualifiedName { diff --git a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStoreTest.scala b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStoreTest.scala index e950142c55..79fbee220a 100644 --- a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStoreTest.scala +++ b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStoreTest.scala @@ -837,51 +837,6 @@ abstract class MultiDomainAcsStoreTest[ MultiDomainAcsStoreTest.generatedCoids.value.size should (be >= 900 and be <= 1000) } - "read assignment-mismatched contracts in a stable order" in { - import com.digitalasset.daml.lf.value.Value - import org.lfdecentralizedtrust.splice.codegen.java.splice.amulet.{ - FeaturedAppRight, - AppRewardCoupon, - } - import MultiDomainAcsStore.ConstrainedTemplate - - // the specific templates don't matter, we just need 2 of them - val sampleParticipantId = ParticipantId("foo") - val evenCompanion = FeaturedAppRight.COMPANION - val oddCompanion = AppRewardCoupon.COMPANION - def smallestContract(coid: Value.ContractId, ix: Int) = - if (ix % 2 == 0) featuredAppRight(dsoParty, coid.coid) - else appRewardCoupon(1, dsoParty, contractId = coid.coid) - val coids = MultiDomainAcsStoreTest.generatedCoids.value - val expectedOrder = reassignmentContractOrder( - coids, - sampleParticipantId, - )(_.coid) - - val contractFilter = { - import MultiDomainAcsStore.mkFilter - - MultiDomainAcsStore.SimpleContractFilter[GenericAcsRowData, GenericInterfaceRowData]( - dsoParty, - templateFilters = Map( - mkFilter(evenCompanion)(_ => true)(GenericAcsRowData(_)), - mkFilter(oddCompanion)(_ => true)(GenericAcsRowData(_)), - ), - interfaceFilters = Map.empty, - ) - } - implicit val store: Store = mkStore(0, Some(0), 0L, sampleParticipantId, contractFilter) - for { - _ <- initWithAcs(coids.zipWithIndex.map { case (coid, ix) => - StoreTest.AcsImportEntry(smallestContract(coid, ix), dummyDomain, 0L) - }) - contracts <- store.listAssignedContractsNotOnDomainN( - dummy2Domain, - Seq[ConstrainedTemplate](evenCompanion, oddCompanion), - ) - } yield contracts.map(_.contractId.contractId) shouldBe expectedOrder.map(_.coid) - } - "ingest and return interface views for 1 interface 2 implementors" in { implicit val store = mkStore() val aDifferentIssuer = providerParty(42) diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanStore.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanStore.scala index fa2ace33e6..c2a4ba8e77 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanStore.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanStore.scala @@ -234,9 +234,7 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - AmuletRules.TEMPLATE_ID_WITH_PACKAGE_ID - )}""", + AmuletRules.COMPANION, orderLimit = sql"""order by event_number desc limit 1""", ).headOption, "lookupAmuletRules", @@ -259,9 +257,7 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - ExternalPartyAmuletRules.TEMPLATE_ID - )}""", + ExternalPartyAmuletRules.COMPANION, orderLimit = sql"""order by event_number desc limit 1""", ).headOption, "lookupExternalPartyAmuletRules", @@ -288,9 +284,7 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - AnsRules.TEMPLATE_ID_WITH_PACKAGE_ID - )}""", + AnsRules.COMPANION, orderLimit = sql"""order by event_number desc limit 1""", ).headOption, "lookupAnsRules", @@ -319,10 +313,9 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - AnsEntry.TEMPLATE_ID_WITH_PACKAGE_ID - )} and ans_entry_name ^@ $limitedPrefix + AnsEntry.COMPANION, + additionalWhere = sql""" + and ans_entry_name ^@ $limitedPrefix and acs.contract_expires_at >= $now """, orderLimit = sql""" @@ -350,10 +343,8 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - AnsEntry.TEMPLATE_ID_WITH_PACKAGE_ID - )} + AnsEntry.COMPANION, + additionalWhere = sql""" and ans_entry_owner = $partyId and ans_entry_name >= '' and acs.contract_expires_at >= $now @@ -380,10 +371,8 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - AnsEntry.TEMPLATE_ID_WITH_PACKAGE_ID - )} + AnsEntry.COMPANION, + additionalWhere = sql""" and ans_entry_name = ${lengthLimited(name)} and acs.contract_expires_at >= $now """, @@ -406,10 +395,8 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - TransferPreapproval.COMPANION.TEMPLATE_ID - )} + TransferPreapproval.COMPANION, + additionalWhere = sql""" and transfer_preapproval_receiver = $partyId """, orderLimit = sql""" @@ -433,10 +420,8 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - TransferCommandCounter.COMPANION.TEMPLATE_ID - )} + TransferCommandCounter.COMPANION, + additionalWhere = sql""" and wallet_party = $partyId """, orderLimit = sql"limit 1", @@ -513,10 +498,8 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - FeaturedAppRight.TEMPLATE_ID_WITH_PACKAGE_ID - )} + FeaturedAppRight.COMPANION, + additionalWhere = sql""" and featured_app_right_provider = $providerPartyId """, orderLimit = sql"limit 1", @@ -802,9 +785,7 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - ValidatorLicense.TEMPLATE_ID_WITH_PACKAGE_ID - )}""", + ValidatorLicense.COMPANION, orderLimit = sql"""order by validator_license_rounds_collected desc limit ${sqlLimit(limit)}""", ), @@ -828,9 +809,8 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = (sql"""template_id_qualified_name = ${QualifiedName( - ValidatorLicense.TEMPLATE_ID - )} and validator in """ ++ validatorPartyIds).toActionBuilder, + ValidatorLicense.COMPANION, + where = (sql"""validator in """ ++ validatorPartyIds).toActionBuilder, ), "getValidatorLicenseByValidator", ) @@ -853,6 +833,7 @@ class DbScanStore( from #${ScanTables.acsTableName} where store_id = $acsStoreId and migration_id = $domainMigrationId + and package_name = ${MemberTraffic.PACKAGE_NAME} and template_id_qualified_name = ${QualifiedName( MemberTraffic.TEMPLATE_ID_WITH_PACKAGE_ID )} @@ -955,9 +936,8 @@ class DbScanStore( ScanTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName(templateId)} - and sv_party = $svPartyId""", + companion, + additionalWhere = sql"""and sv_party = $svPartyId""", orderLimit = sql"""limit 1""", ).headOption, s"lookupContractBySvParty[$templateId]", @@ -1080,23 +1060,21 @@ class DbScanStore( companionClass: ContractCompanion[C, TCId, T], tc: TraceContext, ): Future[Option[Contract[TCId, T]]] = { - val templateId = companionClass.typeId(companion) - val packageName = PackageQualifiedName.getFromResources(templateId).packageName + val pqn @ PackageQualifiedName(packageName, QualifiedName(moduleName, entityName)) = + companionClass.packageQualifiedName(companion) for { row <- storage .querySingle( selectFromUpdateCreatesTableResult( updateHistory.historyId, - where = sql"""template_id_module_name = ${lengthLimited( - templateId.getModuleName - )} and template_id_entity_name = ${lengthLimited( - templateId.getEntityName - )} and package_name = ${lengthLimited(packageName)} + where = sql"""template_id_module_name = ${lengthLimited(moduleName)} + and template_id_entity_name = ${lengthLimited(entityName)} + and package_name = ${lengthLimited(packageName)} and record_time > $recordTime""", // TODO(#934): Order by row_id is suspicious orderLimit = sql"""order by row_id asc limit 1""", ).headOption, - s"lookup[$templateId]", + s"lookup[$pqn]", ) .value } yield { diff --git a/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala b/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala index d5c3b800bb..a496d56e8a 100644 --- a/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala +++ b/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala @@ -164,7 +164,7 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" + additionalWhere = sql""" template_id_qualified_name = ${QualifiedName( splitwellCodegen.Group.TEMPLATE_ID_WITH_PACKAGE_ID )} @@ -192,7 +192,7 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" + additionalWhere = sql""" template_id_qualified_name = ${QualifiedName( splitwellCodegen.GroupInvite.TEMPLATE_ID_WITH_PACKAGE_ID )} and group_owner = ${owner} @@ -221,7 +221,7 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" + additionalWhere = sql""" template_id_qualified_name = ${QualifiedName( splitwellCodegen.AcceptedGroupInvite.TEMPLATE_ID_WITH_PACKAGE_ID )} and group_owner = ${owner} @@ -250,7 +250,7 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" + additionalWhere = sql""" template_id_qualified_name = ${QualifiedName( splitwellCodegen.BalanceUpdate.TEMPLATE_ID_WITH_PACKAGE_ID )} and group_id = ${lengthLimited(key.id.unpack)} @@ -322,7 +322,7 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" + additionalWhere = sql""" template_id_qualified_name = ${QualifiedName( splitwellCodegen.SplitwellInstall.TEMPLATE_ID_WITH_PACKAGE_ID )} and install_user = ${user} @@ -352,7 +352,7 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" + additionalWhere = sql""" template_id_qualified_name = ${QualifiedName( splitwellCodegen.SplitwellRules.TEMPLATE_ID_WITH_PACKAGE_ID )} and assigned_domain is not null diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala index 221afba894..8e08fd06fe 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala @@ -6,7 +6,6 @@ package org.lfdecentralizedtrust.splice.sv.store.db import cats.data.OptionT import cats.implicits.* import com.daml.ledger.javaapi.data as javab -import com.daml.ledger.javaapi.data.Identifier import com.daml.ledger.javaapi.data.codegen.ContractId import org.lfdecentralizedtrust.splice.automation.MultiDomainExpiredContractTrigger.ListExpiredContracts import org.lfdecentralizedtrust.splice.codegen.java.splice @@ -197,9 +196,7 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - SvOnboardingConfirmed.TEMPLATE_ID_WITH_PACKAGE_ID - )}""", + SvOnboardingConfirmed.COMPANION, orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listSvOnboardingConfirmed", @@ -219,9 +216,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - SvOnboardingConfirmed.TEMPLATE_ID_WITH_PACKAGE_ID - )} and sv_candidate_party = $svParty""", + SvOnboardingConfirmed.COMPANION, + where = sql"""sv_candidate_party = $svParty""", orderLimit = sql"limit 1", ).headOption, "lookupSvOnboardingConfirmedByParty", @@ -240,10 +236,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - Confirmation.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and action_requiring_confirmation = ${payloadJsonFromDefinedDataType( + Confirmation.COMPANION, + where = sql"""action_requiring_confirmation = ${payloadJsonFromDefinedDataType( action )}""", orderLimit = sql"""limit ${sqlLimit(limit)}""", @@ -268,10 +262,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - Confirmation.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and confirmer = $confirmer + Confirmation.COMPANION, + where = sql""" + confirmer = $confirmer and action_requiring_confirmation = ${payloadJsonFromDefinedDataType(action)}""", orderLimit = sql"""limit ${sqlLimit(limit)}""", ), @@ -297,7 +290,7 @@ class DbSvDsoStore( sql"""select sum(case app_reward_is_featured when true then reward_amount else 0 end), sum(case app_reward_is_featured when true then 0 else reward_amount end)""", - AppRewardCoupon.TEMPLATE_ID_WITH_PACKAGE_ID, + PackageQualifiedName.fromJavaCodegenCompanion(AppRewardCoupon.COMPANION), round, synchronizerId, ) @@ -321,7 +314,7 @@ class DbSvDsoStore( ): Future[BigDecimal] = selectFromRewardCouponsOnDomain[Option[BigDecimal]]( sql"select sum(reward_amount)", - ValidatorRewardCoupon.TEMPLATE_ID_WITH_PACKAGE_ID, + PackageQualifiedName.fromJavaCodegenCompanion(ValidatorRewardCoupon.COMPANION), round, synchronizerId, ).map(_.headOption.flatten.getOrElse(BigDecimal(0))) @@ -364,7 +357,7 @@ class DbSvDsoStore( implicit tc: TraceContext ): Future[Long] = selectFromRewardCouponsOnDomain[Option[Long]]( sql"select count(*)", - ValidatorFaucetCoupon.TEMPLATE_ID_WITH_PACKAGE_ID, + PackageQualifiedName.fromJavaCodegenCompanion(ValidatorFaucetCoupon.COMPANION), round, synchronizerId, ).map(_.headOption.flatten.getOrElse(0L)) @@ -376,7 +369,7 @@ class DbSvDsoStore( tc: TraceContext ): Future[Long] = selectFromRewardCouponsOnDomain[Option[Long]]( sql"select count(*)", - ValidatorLivenessActivityRecord.COMPANION.TEMPLATE_ID, + PackageQualifiedName.fromJavaCodegenCompanion(ValidatorLivenessActivityRecord.COMPANION), round, synchronizerId, ).map(_.headOption.flatten.getOrElse(0L)) @@ -385,7 +378,7 @@ class DbSvDsoStore( implicit tc: TraceContext ): Future[Long] = selectFromRewardCouponsOnDomain[Option[Long]]( sql"select sum(reward_weight)", - SvRewardCoupon.TEMPLATE_ID_WITH_PACKAGE_ID, + PackageQualifiedName.fromJavaCodegenCompanion(SvRewardCoupon.COMPANION), round, synchronizerId, ).map(_.headOption.flatten.getOrElse(0L)) @@ -399,10 +392,9 @@ class DbSvDsoStore( companionClass: ContractCompanion[C, TCId, T], tc: TraceContext, ): Future[Seq[Contract[TCId, T]]] = { - val templateId = companionClass.typeId(companion) selectFromRewardCouponsOnDomain[SelectFromAcsTableResult]( sql"select #${SelectFromAcsTableResult.sqlColumnsCommaSeparated()}", - templateId, + companionClass.packageQualifiedName(companion), round, synchronizerId, limit = limit, @@ -411,14 +403,14 @@ class DbSvDsoStore( private def selectFromRewardCouponsOnDomain[R: GetResult]( selectClause: SQLActionBuilder, - templateId: Identifier, + packageQualifiedName: PackageQualifiedName, round: Long, synchronizerId: SynchronizerId, limit: Limit = Limit.DefaultLimit, )(implicit tc: TraceContext ): Future[Seq[R]] = { - val opName = s"selectFrom${templateId.getEntityName}OnDomain" + val opName = s"selectFrom${packageQualifiedName.qualifiedName.entityName}OnDomain" waitUntilAcsIngested { for { result <- storage @@ -428,7 +420,8 @@ class DbSvDsoStore( from #${DsoTables.acsTableName} where store_id = $acsStoreId and migration_id = $domainMigrationId - and template_id_qualified_name = ${QualifiedName(templateId)} + and package_name = ${packageQualifiedName.packageName} + and template_id_qualified_name = ${packageQualifiedName.qualifiedName} and assigned_domain = $synchronizerId and reward_round = $round and reward_party is not null -- otherwise index is not used @@ -507,6 +500,7 @@ class DbSvDsoStore( companionClass: ContractCompanion[C, TCId, T], tc: TraceContext, ): Future[Seq[SvDsoStore.RoundBatch[TCId]]] = { + val packageQualifiedName = companionClass.packageQualifiedName(companion) val templateId = companionClass.typeId(companion) val opName = s"list${templateId.getEntityName}GroupedByRound" waitUntilAcsIngested { @@ -518,7 +512,8 @@ class DbSvDsoStore( from dso_acs_store where store_id = $acsStoreId and migration_id = $domainMigrationId - and template_id_qualified_name = ${QualifiedName(templateId)} + and package_name = ${packageQualifiedName.packageName} + and template_id_qualified_name = ${packageQualifiedName.qualifiedName} and assigned_domain = $domain and reward_party is not null -- otherwise index is not used and reward_round is not null -- otherwise index is not used @@ -551,11 +546,10 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - ClosedMiningRound.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and assigned_domain = ${dsoRules.domain} - and mining_round is not null""", + ClosedMiningRound.COMPANION, + additionalWhere = sql""" + and assigned_domain = ${dsoRules.domain} + and mining_round is not null""", orderLimit = sql"""order by mining_round limit 1""", ).headOption, "lookupOldestClosedMiningRound", @@ -576,9 +570,7 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - SummarizingMiningRound.TEMPLATE_ID_WITH_PACKAGE_ID - )}""", + SummarizingMiningRound.COMPANION, orderLimit = sql"""order by mining_round limit ${sqlLimit(limit)}""", ), "listOldestSummarizingMiningRounds", @@ -599,11 +591,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, + Confirmation.COMPANION, where = sql""" - template_id_qualified_name = ${QualifiedName( - Confirmation.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and confirmer = $confirmer + confirmer = $confirmer and action_requiring_confirmation = ${payloadJsonFromDefinedDataType(action)} """, orderLimit = sql" limit 1", @@ -633,11 +623,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, + Confirmation.COMPANION, where = sql""" - template_id_qualified_name = ${QualifiedName( - Confirmation.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and confirmer = $confirmer + confirmer = $confirmer and action_ans_entry_context_payment_id = $paymentId and action_ans_entry_context_arc_type = ${lengthLimited( DsoTables.AnsActionTypeCollectInitialEntryPayment @@ -670,11 +658,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, + Confirmation.COMPANION, where = sql""" - template_id_qualified_name = ${QualifiedName( - Confirmation.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and confirmer = $confirmer + confirmer = $confirmer and action_ans_entry_context_payment_id = $paymentId and action_ans_entry_context_arc_type = ${lengthLimited( DsoTables.AnsActionTypeRejectEntryInitialPayment @@ -707,11 +693,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, + Confirmation.COMPANION, where = sql""" - template_id_qualified_name = ${QualifiedName( - Confirmation.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and confirmer = $confirmer + confirmer = $confirmer and action_ans_entry_context_payment_id = $paymentId """, orderLimit = sql"limit 1", @@ -737,10 +721,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - Confirmation.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and confirmer = $confirmer + Confirmation.COMPANION, + where = sql""" + confirmer = $confirmer and action_ans_entry_context_cid IN ( select contract_id from #${DsoTables.acsTableName} @@ -770,12 +753,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - SvOnboardingRequest.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and sv_onboarding_token = ${lengthLimited(token)} - """, + SvOnboardingRequest.COMPANION, + where = sql"""sv_onboarding_token = ${lengthLimited(token)}""", orderLimit = sql"limit 1", ).headOption, "lookupSvOnboardingRequestByTokenWithOffset", @@ -811,9 +790,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = (sql"""template_id_qualified_name = ${QualifiedName( - SvOnboardingRequest.TEMPLATE_ID_WITH_PACKAGE_ID - )} and (sv_candidate_party, sv_candidate_name) in (""" ++ svCandidates ++ sql")").toActionBuilder, + SvOnboardingRequest.COMPANION, + where = + (sql"""(sv_candidate_party, sv_candidate_name) in (""" ++ svCandidates ++ sql")").toActionBuilder, orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listSvOnboardingRequestsBySvs", @@ -834,14 +813,15 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName(companion.getTemplateIdWithPackageId)} + companion, + additionalWhere = sql""" and assigned_domain = $synchronizerId and acs.amulet_round_of_expiry <= ( select mining_round - 2 from dso_acs_store where store_id = $acsStoreId and migration_id = $domainMigrationId + and package_name = ${splice.round.OpenMiningRound.PACKAGE_NAME} and template_id_qualified_name = ${QualifiedName( splice.round.OpenMiningRound.TEMPLATE_ID_WITH_PACKAGE_ID )} @@ -869,11 +849,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - MemberTraffic.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and member_traffic_member = $memberId - and member_traffic_domain = $synchronizerId""", + MemberTraffic.COMPANION, + where = sql"""member_traffic_member = $memberId + and member_traffic_domain = $synchronizerId""", orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listMemberTrafficContracts", @@ -901,10 +879,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = (sql"""template_id_qualified_name = ${QualifiedName( - AmuletPriceVote.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and voter in """ ++ voterParties).toActionBuilder, + AmuletPriceVote.COMPANION, + where = (sql"""voter in """ ++ voterParties).toActionBuilder, orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listSvAmuletPriceVotes", @@ -925,12 +901,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - SvOnboardingRequest.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and sv_candidate_party = $candidateParty - """, + SvOnboardingRequest.COMPANION, + where = sql"""sv_candidate_party = $candidateParty""", orderLimit = sql"limit 1", ).headOption, "lookupSvOnboardingRequestByCandidatePartyWithOffset", @@ -953,12 +925,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - ValidatorLicense.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and validator = $validator - """, + ValidatorLicense.COMPANION, + where = sql"""validator = $validator""", orderLimit = sql"limit 1", ).headOption, "lookupValidatorLicenseWithOffset", @@ -979,11 +947,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - ValidatorLicense.TEMPLATE_ID_WITH_PACKAGE_ID - )} - AND validator = ${lengthLimited(validator)} - """, + ValidatorLicense.COMPANION, + where = sql"""validator = ${lengthLimited(validator)}""", orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listValidatorLicensePerValidator", @@ -1001,6 +966,7 @@ class DbSvDsoStore( from #${DsoTables.acsTableName} where store_id = $acsStoreId and migration_id = $domainMigrationId + and package_name = ${MemberTraffic.PACKAGE_NAME} and template_id_qualified_name = ${QualifiedName( MemberTraffic.TEMPLATE_ID_WITH_PACKAGE_ID )} @@ -1069,12 +1035,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - VoteRequest.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and vote_request_tracking_cid = $voteRequestCid - """, + VoteRequest.COMPANION, + where = sql"""vote_request_tracking_cid = $voteRequestCid""", orderLimit = sql"limit 1", ).headOption, "lookupVoteByThisSvAndVoteRequestWithOffset", @@ -1099,11 +1061,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - VoteRequest.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and action_requiring_confirmation = ${payloadJsonFromDefinedDataType(action)} + VoteRequest.COMPANION, + where = sql"""action_requiring_confirmation = ${payloadJsonFromDefinedDataType(action)} and requester_name = ${key.svParty} """, orderLimit = sql"limit 1", @@ -1126,10 +1085,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - AmuletPriceVote.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and voter = ${key.svParty}""", + AmuletPriceVote.COMPANION, + where = sql"""voter = ${key.svParty}""", orderLimit = sql"""limit 1""", ).headOption, "lookupAmuletPriceVoteByThisSv", @@ -1150,12 +1107,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - SvOnboardingRequest.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and sv_candidate_name = ${lengthLimited(candidateName)} - """, + SvOnboardingRequest.COMPANION, + where = sql"""sv_candidate_name = ${lengthLimited(candidateName)}""", orderLimit = sql"limit 1", ).headOption, "lookupSvOnboardingRequestByCandidateNameWithOffset", @@ -1178,12 +1131,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - SvOnboardingConfirmed.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and sv_candidate_name = ${lengthLimited(svName)} - """, + SvOnboardingConfirmed.COMPANION, + where = sql"""sv_candidate_name = ${lengthLimited(svName)}""", orderLimit = sql"limit 1", ).headOption, "lookupSvOnboardingConfirmedByNameWithOffset", @@ -1207,12 +1156,10 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - AnsEntry.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and ans_entry_name = ${lengthLimited(name)} - and assigned_domain is not null - and acs.contract_expires_at >= $now""", + AnsEntry.COMPANION, + where = sql"""ans_entry_name = ${lengthLimited(name)} + and assigned_domain is not null + and acs.contract_expires_at >= $now""", orderLimit = sql"limit 1", ).headOption, "lookupAnsEntryByNameWithOffset", @@ -1239,11 +1186,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - SubscriptionInitialPayment.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and contract_id = $paymentCid - and assigned_domain is not null""", + SubscriptionInitialPayment.COMPANION, + where = sql"""contract_id = $paymentCid + and assigned_domain is not null""", orderLimit = sql"limit 1", ).headOption, "lookupSubscriptionInitialPaymentWithOffset", @@ -1270,10 +1215,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - FeaturedAppRight.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and featured_app_right_provider = $providerPartyId + FeaturedAppRight.COMPANION, + where = sql"""featured_app_right_provider = $providerPartyId and assigned_domain is not null""", orderLimit = sql"limit 1", ).headOption, @@ -1300,11 +1243,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - AnsEntryContext.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and subscription_reference_contract_id = $reference""", + AnsEntryContext.COMPANION, + additionalWhere = sql"""and subscription_reference_contract_id = $reference""", orderLimit = sql"""limit 1""", ).headOption, "lookupAnsEntryContext", @@ -1332,9 +1272,9 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = (sql"""template_id_qualified_name = ${QualifiedName( - ClosedMiningRound.TEMPLATE_ID_WITH_PACKAGE_ID - )} AND assigned_domain = $synchronizerId AND mining_round IN """ ++ roundNumbersClause).toActionBuilder, + ClosedMiningRound.COMPANION, + where = + (sql"""assigned_domain = $synchronizerId AND mining_round IN """ ++ roundNumbersClause).toActionBuilder, orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listClosedRounds", @@ -1379,11 +1319,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - SvRewardState.TEMPLATE_ID_WITH_PACKAGE_ID - )} - AND sv_name = ${lengthLimited(svName)} - """, + SvRewardState.COMPANION, + where = sql"""sv_name = ${lengthLimited(svName)}""", orderLimit = sql"""limit ${sqlLimit(limit)}""", ), "listSvRewardStates", @@ -1406,9 +1343,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName(templateId)} - and sv_party = $svPartyId""", + companion, + additionalWhere = sql"""and sv_party = $svPartyId""", orderLimit = sql"""limit 1""", ).headOption, s"lookupContractBySvParty[$templateId]", @@ -1434,9 +1370,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName(templateId)} - and sv_name = ${lengthLimited(svName)}""", + companion, + additionalWhere = sql"""and sv_name = ${lengthLimited(svName)}""", orderLimit = sql"""limit 1""", ).headOption, s"lookupContractBySvName[$templateId]", @@ -1460,12 +1395,8 @@ class DbSvDsoStore( DsoTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - splice.externalpartyamuletrules.TransferCommandCounter.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and wallet_party = $partyId - """, + splice.externalpartyamuletrules.TransferCommandCounter.COMPANION, + where = sql"""wallet_party = $partyId""", orderLimit = sql" limit 1", ).headOption, "lookupTransferCommandCounterBySender", diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvSvStore.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvSvStore.scala index 95e9ae8616..e8bfb02527 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvSvStore.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvSvStore.scala @@ -14,7 +14,7 @@ import org.lfdecentralizedtrust.splice.store.db.DbMultiDomainAcsStore.StoreDescr import org.lfdecentralizedtrust.splice.store.db.{AcsQueries, AcsTables, DbAppStore} import org.lfdecentralizedtrust.splice.store.{MultiDomainAcsStore, StoreErrors} import org.lfdecentralizedtrust.splice.sv.store.{SvStore, SvSvStore} -import org.lfdecentralizedtrust.splice.util.{Contract, QualifiedName, TemplateJsonDecoder} +import org.lfdecentralizedtrust.splice.util.{Contract, TemplateJsonDecoder} import com.digitalasset.canton.lifecycle.CloseContext import com.digitalasset.canton.logging.{NamedLoggerFactory, NamedLogging} import com.digitalasset.canton.resource.DbStorage @@ -82,12 +82,8 @@ class DbSvSvStore( DbSvSvStore.tableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - ValidatorOnboarding.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and onboarding_secret = ${lengthLimited(secret)} - """, + ValidatorOnboarding.COMPANION, + where = sql"""onboarding_secret = ${lengthLimited(secret)}""", ).headOption, "lookupValidatorOnboardingBySecretWithOffset", ) @@ -108,12 +104,8 @@ class DbSvSvStore( DbSvSvStore.tableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - UsedSecret.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and onboarding_secret = ${lengthLimited(secret)} - """, + UsedSecret.COMPANION, + where = sql"""onboarding_secret = ${lengthLimited(secret)}""", ).headOption, "lookupUsedSecretWithOffset", ) diff --git a/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorStore.scala b/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorStore.scala index e2c061f894..e4c4c57aea 100644 --- a/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorStore.scala +++ b/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorStore.scala @@ -27,12 +27,7 @@ import org.lfdecentralizedtrust.splice.store.db.{ DbAppStore, } import org.lfdecentralizedtrust.splice.store.{LimitHelpers, PageLimit} -import org.lfdecentralizedtrust.splice.util.{ - Contract, - ContractWithState, - QualifiedName, - TemplateJsonDecoder, -} +import org.lfdecentralizedtrust.splice.util.{Contract, ContractWithState, TemplateJsonDecoder} import org.lfdecentralizedtrust.splice.validator.store.ValidatorStore import org.lfdecentralizedtrust.splice.wallet.store.WalletStore import com.digitalasset.canton.data.CantonTimestamp @@ -114,9 +109,8 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - walletCodegen.WalletAppInstall.TEMPLATE_ID_WITH_PACKAGE_ID - )} and user_party = $endUserParty""", + walletCodegen.WalletAppInstall.COMPANION, + where = sql"""user_party = $endUserParty""", orderLimit = sql"limit 1", ).headOption, "lookupInstallByParty", @@ -135,9 +129,8 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - walletCodegen.WalletAppInstall.TEMPLATE_ID_WITH_PACKAGE_ID - )} and user_name = ${lengthLimited(endUserName)}""", + walletCodegen.WalletAppInstall.COMPANION, + where = sql"""user_name = ${lengthLimited(endUserName)}""", orderLimit = sql"limit 1", ).headOption, "lookupInstallByName", @@ -156,9 +149,8 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - amuletCodegen.FeaturedAppRight.TEMPLATE_ID_WITH_PACKAGE_ID - )} and provider_party = ${walletKey.validatorParty}""", + amuletCodegen.FeaturedAppRight.COMPANION, + where = sql"""provider_party = ${walletKey.validatorParty}""", orderLimit = sql"limit 1", ).headOption, "lookupValidatorFeaturedAppRight", @@ -180,11 +172,8 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - walletCodegen.WalletAppInstall.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and user_name = ${lengthLimited(endUserName)} + walletCodegen.WalletAppInstall.COMPANION, + sql"""user_name = ${lengthLimited(endUserName)} """, sql"limit 1", ).headOption, @@ -211,10 +200,9 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - TransferPreapproval.TEMPLATE_ID_WITH_PACKAGE_ID - )} and contract_expires_at < ${now.plus(renewalDuration.asJava)} + TransferPreapproval.COMPANION, + additionalWhere = + sql"""and contract_expires_at < ${now.plus(renewalDuration.asJava)} """, ), "listExpiringTransferPreapprovals", @@ -238,12 +226,8 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - ExternalPartySetupProposal.COMPANION.TEMPLATE_ID - )} - and user_party = $partyId - """, + ExternalPartySetupProposal.COMPANION, + where = sql"""user_party = $partyId""", orderLimit = sql""" limit 1 """, @@ -272,15 +256,9 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - where = sql""" - template_id_qualified_name = ${QualifiedName( - TransferPreapproval.COMPANION.TEMPLATE_ID - )} - and user_party = $partyId - """, - orderLimit = sql""" - limit 1 - """, + TransferPreapproval.COMPANION, + where = sql"""user_party = $partyId""", + orderLimit = sql"""limit 1""", ).headOption, "lookupTransferPreapprovalReceiver", ) @@ -307,13 +285,9 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - validatorLicenseCodegen.ValidatorLicense.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and validator_party = ${key.validatorParty} - """, - sql"limit 1", + validatorLicenseCodegen.ValidatorLicense.COMPANION, + where = sql"""validator_party = ${key.validatorParty}""", + orderLimit = sql"limit 1", ).headOption, "lookupValidatorLicenseWithOffset", ) @@ -342,13 +316,9 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - amuletCodegen.ValidatorRight.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and user_party = $party - """, - sql"limit 1", + amuletCodegen.ValidatorRight.COMPANION, + where = sql"""user_party = $party""", + orderLimit = sql"limit 1", ).headOption, "lookupValidatorRightByPartyWithOffset", ) @@ -374,13 +344,9 @@ class DbValidatorStore( ValidatorTables.acsTableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - topupCodegen.ValidatorTopUpState.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and traffic_domain_id = $synchronizerId - """, - sql"limit 1", + topupCodegen.ValidatorTopUpState.COMPANION, + where = sql"""traffic_domain_id = $synchronizerId""", + orderLimit = sql"limit 1", ).headOption, "lookupValidatorTopUpStateWithOffset", ) diff --git a/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala b/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala index 1b7e086d04..412c66a79b 100644 --- a/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala +++ b/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala @@ -202,7 +202,7 @@ class DbUserWalletStore( companionClass: ContractCompanion[C, TCid, T], traceContext: TraceContext, ): Future[Seq[(Contract[TCid, T], BigDecimal)]] = { - val templateId = companionClass.typeId(companion) + val packageQualifiedName = companionClass.packageQualifiedName(companion) issuingRoundsMap .flatMap { case (round, contract) => roundToIssuance(contract).map(round.number.longValue() -> _) @@ -224,13 +224,14 @@ class DbUserWalletStore( from #${WalletTables.acsTableName} acs join round_to_issuance rti on acs.reward_coupon_round = rti.round where acs.store_id = $acsStoreId and migration_id = $domainMigrationId - and acs.template_id_qualified_name = ${QualifiedName(templateId)} + and acs.package_name = ${packageQualifiedName.packageName} + and acs.template_id_qualified_name = ${packageQualifiedName.qualifiedName} order by (acs.reward_coupon_round, -""" ++ ccValue ++ sql""") limit ${sqlLimit(limit)}""").toActionBuilder .as[(SelectFromAcsTableResult, BigDecimal)], - s"listSorted${templateId.getEntityName}", + s"listSorted:$packageQualifiedName", ) - } yield applyLimit(s"listSorted${templateId.getEntityName}", limit, result).map { + } yield applyLimit(s"listSorted:$packageQualifiedName", limit, result).map { case (row, issuance) => val contract = contractFromRow(companion)(row) contract -> issuance @@ -295,8 +296,10 @@ class DbUserWalletStore( where """ ++ filterAcsStoreMigrationIds("ansEntry.", "ansEntryContext.", "sub.", "st.") ++ sql" and " ++ subscriptionFilter(now) ++ sql""" + and ansEntry.package_name = ${ansCodegen.AnsEntry.PACKAGE_NAME} and ansEntry.template_id_qualified_name = ${QualifiedName(ansCodegen.AnsEntry.TEMPLATE_ID_WITH_PACKAGE_ID)} + and ansEntryContext.package_name = ${ansCodegen.AnsEntryContext.PACKAGE_NAME} and ansEntryContext.template_id_qualified_name = ${QualifiedName(ansCodegen.AnsEntryContext.TEMPLATE_ID_WITH_PACKAGE_ID)} and ansEntry.create_arguments ->> 'name' = ansEntryContext.create_arguments ->> 'name' @@ -388,8 +391,8 @@ class DbUserWalletStore( // provide a grace period for subscription payments. (sql"""select #${SelectFromAcsTableResult.sqlColumnsCommaSeparated("st.")}, #${SelectFromAcsTableResult.sqlColumnsCommaSeparated("sub.")}, - (case when st.template_id_qualified_name = - ${QualifiedName( + (case when st.package_name = ${subsCodegen.SubscriptionIdleState.PACKAGE_NAME} + and st.template_id_qualified_name = ${QualifiedName( subsCodegen.SubscriptionIdleState.TEMPLATE_ID_WITH_PACKAGE_ID )} then $idleStateFlag @@ -420,12 +423,12 @@ class DbUserWalletStore( } private[this] def subscriptionFilter(now: CantonTimestamp) = - sql"""((st.template_id_qualified_name = + sql"""((st.package_name = ${subsCodegen.SubscriptionIdleState.PACKAGE_NAME} and st.template_id_qualified_name = ${QualifiedName(subsCodegen.SubscriptionIdleState.TEMPLATE_ID_WITH_PACKAGE_ID)} and st.contract_expires_at >= $now) - or st.template_id_qualified_name = + or st.package_name = ${subsCodegen.SubscriptionPayment.PACKAGE_NAME} and st.template_id_qualified_name = ${QualifiedName(subsCodegen.SubscriptionPayment.TEMPLATE_ID_WITH_PACKAGE_ID)}) - and sub.template_id_qualified_name = + and sub.package_name = ${subsCodegen.Subscription.PACKAGE_NAME} and sub.template_id_qualified_name = ${QualifiedName(subsCodegen.Subscription.TEMPLATE_ID_WITH_PACKAGE_ID)} and (st.create_arguments ->> 'subscription') = sub.contract_id""" @@ -446,12 +449,8 @@ class DbUserWalletStore( WalletTables.acsTableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - TransferPreapproval.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and transfer_preapproval_receiver = ${receiver} - """, + TransferPreapproval.COMPANION, + sql""" transfer_preapproval_receiver = $receiver """, sql"limit 1", ).headOption, "lookupTransferPreapproval", @@ -478,12 +477,8 @@ class DbUserWalletStore( WalletTables.acsTableName, acsStoreId, domainMigrationId, - sql""" - template_id_qualified_name = ${QualifiedName( - TransferPreapprovalProposal.TEMPLATE_ID_WITH_PACKAGE_ID - )} - and transfer_preapproval_receiver = ${receiver} - """, + TransferPreapprovalProposal.COMPANION, + sql"""transfer_preapproval_receiver = $receiver""", sql"limit 1", ).headOption, "lookupTransferPreapprovalProposal", From 096ea5700692aaf6e940378557bc598e8bbf3cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Thu, 21 Aug 2025 13:20:36 +0000 Subject: [PATCH 07/19] [ci] remove many instances of getFromResources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../splice/console/LedgerApiExtensions.scala | 3 +-- ...SynchronizerMigrationIntegrationTest.scala | 8 +++--- .../tests/ScanTimeBasedIntegrationTest.scala | 4 +-- .../splice/store/MultiDomainAcsStore.scala | 26 +++++++++++++++---- .../splice/util/QualifiedName.scala | 1 - .../splice/scan/store/AcsSnapshotStore.scala | 14 +++++----- 6 files changed, 34 insertions(+), 22 deletions(-) diff --git a/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/console/LedgerApiExtensions.scala b/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/console/LedgerApiExtensions.scala index 569eab5453..91a9b570f8 100644 --- a/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/console/LedgerApiExtensions.scala +++ b/apps/app/src/main/scala/org/lfdecentralizedtrust/splice/console/LedgerApiExtensions.scala @@ -430,8 +430,7 @@ trait LedgerApiExtensions extends AppendedClues with Matchers { ](templateCompanion: javaapi.data.codegen.ContractCompanion[TC, TCid, T])( partyId: PartyId ): Seq[CreatedEvent] = { - val filterIdentifier = - PackageQualifiedName.getFromResources(templateCompanion.getTemplateIdWithPackageId) + val filterIdentifier = PackageQualifiedName.fromJavaCodegenCompanion(templateCompanion) val templateId = TemplateId( s"#${filterIdentifier.packageName}", filterIdentifier.qualifiedName.moduleName, diff --git a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DecentralizedSynchronizerMigrationIntegrationTest.scala b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DecentralizedSynchronizerMigrationIntegrationTest.scala index ebde78e5e7..234e7cdae5 100644 --- a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DecentralizedSynchronizerMigrationIntegrationTest.scala +++ b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/DecentralizedSynchronizerMigrationIntegrationTest.scala @@ -1120,11 +1120,11 @@ class DecentralizedSynchronizerMigrationIntegrationTest pageSize = 1000, templates = Some( Vector( - DsoRules.TEMPLATE_ID_WITH_PACKAGE_ID, - AmuletRules.TEMPLATE_ID_WITH_PACKAGE_ID, - AnsRules.TEMPLATE_ID_WITH_PACKAGE_ID, + DsoRules.COMPANION, + AmuletRules.COMPANION, + AnsRules.COMPANION, ).map( - PackageQualifiedName.getFromResources(_) + PackageQualifiedName.fromJavaCodegenCompanion ) ), ) diff --git a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/ScanTimeBasedIntegrationTest.scala b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/ScanTimeBasedIntegrationTest.scala index 120d04d063..15e3210d23 100644 --- a/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/ScanTimeBasedIntegrationTest.scala +++ b/apps/app/src/test/scala/org/lfdecentralizedtrust/splice/integration/tests/ScanTimeBasedIntegrationTest.scala @@ -510,8 +510,8 @@ class ScanTimeBasedIntegrationTest migrationId, templates = Some( Vector( - PackageQualifiedName.getFromResources(Amulet.TEMPLATE_ID_WITH_PACKAGE_ID), - PackageQualifiedName.getFromResources(AnsEntry.TEMPLATE_ID_WITH_PACKAGE_ID), + PackageQualifiedName.fromJavaCodegenCompanion(Amulet.COMPANION), + PackageQualifiedName.fromJavaCodegenCompanion(AnsEntry.COMPANION), ) ), partyIds = Some(Vector(aliceUserParty)), diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala index 985a842dd4..2e465c4f6e 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/MultiDomainAcsStore.scala @@ -9,7 +9,10 @@ import com.daml.ledger.api.v2.transaction_filter.{ CumulativeFilter, TransactionFilter as LapiTransactionFilter, } -import org.lfdecentralizedtrust.splice.util.Contract.Companion.Template as TemplateCompanion +import org.lfdecentralizedtrust.splice.util.Contract.Companion.{ + Interface, + Template as TemplateCompanion, +} import com.daml.ledger.javaapi.data.{CreatedEvent, ExercisedEvent, Identifier, Template} import com.daml.ledger.javaapi.data.codegen.{ContractId, DamlRecord} import com.daml.metrics.api.MetricsContext @@ -29,6 +32,7 @@ import org.lfdecentralizedtrust.splice.util.{ Contract, ContractWithState, PackageQualifiedName, + QualifiedName, TemplateJsonDecoder, } import org.lfdecentralizedtrust.splice.util.PrettyInstances.* @@ -457,7 +461,7 @@ object MultiDomainAcsStore { TemplateFilter[TCid, T, R], ) = ( - PackageQualifiedName.getFromResources(templateCompanion.getTemplateIdWithPackageId), + PackageQualifiedName.fromJavaCodegenCompanion(templateCompanion), TemplateFilter( ev => { val c = Contract.fromCreatedEvent(templateCompanion)(ev) @@ -584,9 +588,7 @@ object MultiDomainAcsStore { def typeId(companion: C): Identifier - // This is safe because if we have a companion, the package exists in resources - def packageQualifiedName(companion: C) = - PackageQualifiedName.getFromResources(typeId(companion)) + def packageQualifiedName(companion: C): PackageQualifiedName def toContractId(companion: C, contractId: String): TCid @@ -610,6 +612,13 @@ object MultiDomainAcsStore { override def typeId(companion: Contract.Companion.Template[TCid, T]): Identifier = companion.getTemplateIdWithPackageId + override def packageQualifiedName( + companion: TemplateCompanion[TCid, T] + ): PackageQualifiedName = PackageQualifiedName( + companion.PACKAGE_NAME, + QualifiedName(companion.getTemplateIdWithPackageId), + ) + override def toContractId(companion: Companion.Template[TCid, T], contractId: String): TCid = companion.toContractId(new ContractId[T](contractId)) @@ -643,6 +652,13 @@ object MultiDomainAcsStore { override def typeId(companion: Contract.Companion.Interface[ICid, Marker, View]): Identifier = companion.getTemplateIdWithPackageId + override def packageQualifiedName( + companion: Interface[ICid, Marker, View] + ): PackageQualifiedName = PackageQualifiedName( + companion.PACKAGE_NAME, + QualifiedName(companion.getTemplateIdWithPackageId), + ) + override def toContractId( companion: Companion.Interface[ICid, Marker, View], contractId: String, diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/util/QualifiedName.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/util/QualifiedName.scala index 173853b5af..156d4463f8 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/util/QualifiedName.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/util/QualifiedName.scala @@ -26,7 +26,6 @@ object PackageQualifiedName { } } - // TODO: replace more usages of this with java codegen one def getFromResources(identifier: Identifier): PackageQualifiedName = { lookupFromResources(identifier) .getOrElse(throw new IllegalArgumentException(s"No package found for template $identifier")) diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/AcsSnapshotStore.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/AcsSnapshotStore.scala index b69bb8ba03..ebf19c304b 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/AcsSnapshotStore.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/AcsSnapshotStore.scala @@ -381,8 +381,8 @@ object AcsSnapshotStore { ) private val holdingsTemplates = - Vector(Amulet.TEMPLATE_ID_WITH_PACKAGE_ID, LockedAmulet.TEMPLATE_ID_WITH_PACKAGE_ID).map( - PackageQualifiedName.getFromResources + Vector(Amulet.COMPANION, LockedAmulet.COMPANION).map( + PackageQualifiedName.fromJavaCodegenCompanion ) private def decodeHoldingContract(createdEvent: CreatedEvent): Either[ @@ -393,16 +393,14 @@ object AcsSnapshotStore { .withDescription(s"Failed to decode $createdEvent") .asRuntimeException() if ( - PackageQualifiedName.fromEvent(createdEvent) == PackageQualifiedName.getFromResources( - Amulet.TEMPLATE_ID_WITH_PACKAGE_ID - ) + PackageQualifiedName + .fromEvent(createdEvent) == PackageQualifiedName.fromJavaCodegenCompanion(Amulet.COMPANION) ) { Right(Contract.fromCreatedEvent(Amulet.COMPANION)(createdEvent).getOrElse(failedToDecode)) } else { if ( - PackageQualifiedName.fromEvent(createdEvent) != PackageQualifiedName.getFromResources( - LockedAmulet.TEMPLATE_ID_WITH_PACKAGE_ID - ) + PackageQualifiedName.fromEvent(createdEvent) != PackageQualifiedName + .fromJavaCodegenCompanion(LockedAmulet.COMPANION) ) { throw io.grpc.Status.INTERNAL .withDescription( From 24b712a5213f68a0ec9a9ef2c5bc8c2bb0b052bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Thu, 21 Aug 2025 13:36:52 +0000 Subject: [PATCH 08/19] [ci] fix splitwell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../splitwell/store/db/DbSplitwellStore.scala | 56 +++++++------------ 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala b/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala index a496d56e8a..2eef97532a 100644 --- a/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala +++ b/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala @@ -23,7 +23,6 @@ import org.lfdecentralizedtrust.splice.util.{ AssignedContract, Contract, ContractWithState, - QualifiedName, TemplateJsonDecoder, } import com.digitalasset.canton.lifecycle.CloseContext @@ -101,10 +100,8 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - splitwellCodegen.SplitwellInstall.TEMPLATE_ID_WITH_PACKAGE_ID - )} and assigned_domain = $synchronizerId - and install_user = ${user}""", + splitwellCodegen.SplitwellInstall.COMPANION, + where = sql"""assigned_domain = $synchronizerId and install_user = $user""", orderLimit = sql"limit 1", ).headOption, "lookupInstallWithOffset", @@ -134,9 +131,8 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - where = sql"""template_id_qualified_name = ${QualifiedName( - splitwellCodegen.Group.TEMPLATE_ID_WITH_PACKAGE_ID - )} and group_owner = ${owner} and group_id = ${lengthLimited(id.unpack)}""", + splitwellCodegen.Group.COMPANION, + where = sql"""group_owner = $owner and group_id = ${lengthLimited(id.unpack)}""", orderLimit = sql"limit 1", ).headOption, "lookupInstallWithOffset", @@ -164,11 +160,7 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - additionalWhere = sql""" - template_id_qualified_name = ${QualifiedName( - splitwellCodegen.Group.TEMPLATE_ID_WITH_PACKAGE_ID - )} - """, + splitwellCodegen.Group.COMPANION, ), "listGroups", ) @@ -192,11 +184,8 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - additionalWhere = sql""" - template_id_qualified_name = ${QualifiedName( - splitwellCodegen.GroupInvite.TEMPLATE_ID_WITH_PACKAGE_ID - )} and group_owner = ${owner} - """, + splitwellCodegen.GroupInvite.COMPANION, + additionalWhere = sql"""and group_owner = $owner""", ), "listGroupInvites", ) @@ -221,10 +210,9 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, + splitwellCodegen.AcceptedGroupInvite.COMPANION, additionalWhere = sql""" - template_id_qualified_name = ${QualifiedName( - splitwellCodegen.AcceptedGroupInvite.TEMPLATE_ID_WITH_PACKAGE_ID - )} and group_owner = ${owner} + and group_owner = ${owner} and group_id = ${lengthLimited(groupKey(owner, groupId).id.unpack)} """, ), @@ -250,10 +238,8 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, - additionalWhere = sql""" - template_id_qualified_name = ${QualifiedName( - splitwellCodegen.BalanceUpdate.TEMPLATE_ID_WITH_PACKAGE_ID - )} and group_id = ${lengthLimited(key.id.unpack)} + splitwellCodegen.BalanceUpdate.COMPANION, + additionalWhere = sql""" and group_id = ${lengthLimited(key.id.unpack)} """, orderLimit = sql"""order by event_number desc""", ), @@ -322,10 +308,9 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, + splitwellCodegen.SplitwellInstall.COMPANION, additionalWhere = sql""" - template_id_qualified_name = ${QualifiedName( - splitwellCodegen.SplitwellInstall.TEMPLATE_ID_WITH_PACKAGE_ID - )} and install_user = ${user} + and install_user = $user and assigned_domain is not null """, ), @@ -352,10 +337,9 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, + splitwellCodegen.SplitwellRules.COMPANION, additionalWhere = sql""" - template_id_qualified_name = ${QualifiedName( - splitwellCodegen.SplitwellRules.TEMPLATE_ID_WITH_PACKAGE_ID - )} and assigned_domain is not null + and assigned_domain is not null """, ), "listSplitwellRules", @@ -383,10 +367,9 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, + splitwellCodegen.SplitwellRules.COMPANION, where = sql""" - template_id_qualified_name = ${QualifiedName( - splitwellCodegen.SplitwellRules.TEMPLATE_ID_WITH_PACKAGE_ID - )} and assigned_domain = $synchronizerId + and assigned_domain = $synchronizerId """, ).headOption, "lookupSplitwellRules", @@ -490,10 +473,9 @@ class DbSplitwellStore( SplitwellTables.acsTableName, acsStoreId, domainMigrationId, + splitwellCodegen.TransferInProgress.COMPANION, where = sql""" - template_id_qualified_name = ${QualifiedName( - splitwellCodegen.TransferInProgress.TEMPLATE_ID_WITH_PACKAGE_ID - )} and payment_request_contract_id = ${paymentRequest} + payment_request_contract_id = $paymentRequest and assigned_domain is not null """, ).headOption, From 3b845ce5b206cfe9ff5ed5af7ef95ee9acbc514e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Thu, 21 Aug 2025 14:09:21 +0000 Subject: [PATCH 09/19] [ci] fix bad query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../splice/splitwell/store/db/DbSplitwellStore.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala b/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala index 2eef97532a..a342acd343 100644 --- a/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala +++ b/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala @@ -368,9 +368,7 @@ class DbSplitwellStore( acsStoreId, domainMigrationId, splitwellCodegen.SplitwellRules.COMPANION, - where = sql""" - and assigned_domain = $synchronizerId - """, + where = sql"""assigned_domain = $synchronizerId""", ).headOption, "lookupSplitwellRules", ) From 50077da38bfa80436ede2eeefefa526456f0c20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Thu, 21 Aug 2025 15:40:32 +0000 Subject: [PATCH 10/19] unused variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../splice/store/db/DbMultiDomainAcsStore.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala index 3a4f5b279b..72e47e48a8 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala @@ -89,7 +89,6 @@ final class DbMultiDomainAcsStore[TXE]( ], txLogConfig: TxLogStore.Config[TXE], domainMigrationInfo: DomainMigrationInfo, - @unused participantId: ParticipantId, // TODO: figure out what's up with this retryProvider: RetryProvider, /** Allows processing the summary in a store-specific manner, e.g., to produce metrics * on ingestion of certain contracts. From 15d666ab109e3e70199bb78105e186a87bf6979c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Thu, 21 Aug 2025 15:50:01 +0000 Subject: [PATCH 11/19] [ci] bump descriptors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../stable/V043__package_name_acs_stores.sql | 30 ++++++++++++++----- .../splice/scan/store/db/DbScanStore.scala | 2 +- .../splitwell/store/db/DbSplitwellStore.scala | 2 +- .../splice/sv/store/db/DbSvDsoStore.scala | 2 +- .../splice/sv/store/db/DbSvSvStore.scala | 2 +- .../validator/store/db/DbValidatorStore.scala | 2 +- .../store/db/DbExternalPartyWalletStore.scala | 2 +- .../wallet/store/db/DbUserWalletStore.scala | 8 ++--- 8 files changed, 30 insertions(+), 20 deletions(-) diff --git a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql index 50f6b86cb9..2821e05942 100644 --- a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql +++ b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql @@ -1,8 +1,22 @@ -alter table acs_store_template add column package_name text; -alter table user_wallet_acs_store add column package_name text; -alter table external_party_wallet_acs_store add column package_name text; -alter table validator_acs_store add column package_name text; -alter table sv_acs_store add column package_name text; -alter table dso_acs_store add column package_name text; -alter table scan_acs_store add column package_name text; -alter table splitwell_acs_store add column package_name text; +truncate table acs_store_template; +truncate table user_wallet_acs_store; +truncate table external_party_wallet_acs_store; +truncate table validator_acs_store; +truncate table sv_acs_store; +truncate table dso_acs_store; +truncate table scan_acs_store; +truncate table splitwell_acs_store; + +-- we just truncated the tables and there's no concurrent access while migrations are running, +-- so we can make the column not null. +-- All ACS store descriptors should be bumped in all stores to trigger reingestion. +alter table acs_store_template add column package_name text not null; +alter table user_wallet_acs_store add column package_name text not null; +alter table external_party_wallet_acs_store add column package_name text not null; +alter table validator_acs_store add column package_name text not null; +alter table sv_acs_store add column package_name text not null; +alter table dso_acs_store add column package_name text not null; +alter table scan_acs_store add column package_name text not null; +alter table splitwell_acs_store add column package_name text not null; + +-- TODO: add indexes including the package_name column, and drop all those that don't have it diff --git a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanStore.scala b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanStore.scala index c2a4ba8e77..71455d6bf0 100644 --- a/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanStore.scala +++ b/apps/scan/src/main/scala/org/lfdecentralizedtrust/splice/scan/store/db/DbScanStore.scala @@ -111,7 +111,7 @@ class DbScanStore( // Any change in the store descriptor will lead to previously deployed applications // forgetting all persisted data once they upgrade to the new version. acsStoreDescriptor = StoreDescriptor( - version = 2, // TODO (DACH-NY/canton-network-node#13454): bump when it will backfill. + version = 3, name = "DbScanStore", party = key.dsoParty, participant = participantId, diff --git a/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala b/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala index a342acd343..dd246bd255 100644 --- a/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala +++ b/apps/splitwell/src/main/scala/org/lfdecentralizedtrust/splice/splitwell/store/db/DbSplitwellStore.scala @@ -55,7 +55,7 @@ class DbSplitwellStore( // Any change in the store descriptor will lead to previously deployed applications // forgetting all persisted data once they upgrade to the new version. acsStoreDescriptor = StoreDescriptor( - version = 1, + version = 2, name = "DbSplitwellStore", party = key.providerParty, participant = participantId, diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala index 8e08fd06fe..ce3a20e641 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvDsoStore.scala @@ -86,7 +86,7 @@ class DbSvDsoStore( // Any change in the store descriptor will lead to previously deployed applications // forgetting all persisted data once they upgrade to the new version. acsStoreDescriptor = StoreDescriptor( - version = 1, + version = 2, name = "DbSvDsoStore", party = key.dsoParty, participant = participantId, diff --git a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvSvStore.scala b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvSvStore.scala index e8bfb02527..c392c95d99 100644 --- a/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvSvStore.scala +++ b/apps/sv/src/main/scala/org/lfdecentralizedtrust/splice/sv/store/db/DbSvSvStore.scala @@ -44,7 +44,7 @@ class DbSvSvStore( // Any change in the store descriptor will lead to previously deployed applications // forgetting all persisted data once they upgrade to the new version. acsStoreDescriptor = StoreDescriptor( - version = 1, + version = 2, name = "DbSvSvStore", party = key.svParty, participant = participantId, diff --git a/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorStore.scala b/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorStore.scala index e4c4c57aea..94c2e35cdc 100644 --- a/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorStore.scala +++ b/apps/validator/src/main/scala/org/lfdecentralizedtrust/splice/validator/store/db/DbValidatorStore.scala @@ -61,7 +61,7 @@ class DbValidatorStore( // Any change in the store descriptor will lead to previously deployed applications // forgetting all persisted data once they upgrade to the new version. acsStoreDescriptor = StoreDescriptor( - version = 1, + version = 2, name = "DbValidatorStore", party = key.validatorParty, participant = participantId, diff --git a/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbExternalPartyWalletStore.scala b/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbExternalPartyWalletStore.scala index acbc993afd..80a07f07a3 100644 --- a/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbExternalPartyWalletStore.scala +++ b/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbExternalPartyWalletStore.scala @@ -40,7 +40,7 @@ class DbExternalPartyWalletStore( acsTableName = WalletTables.externalPartyAcsTableName, interfaceViewsTableNameOpt = None, acsStoreDescriptor = StoreDescriptor( - version = 1, + version = 2, name = "DbExternalPartyWalletStore", party = key.externalParty, participant = participantId, diff --git a/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala b/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala index 412c66a79b..e669b876e4 100644 --- a/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala +++ b/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala @@ -70,9 +70,7 @@ class DbUserWalletStore( // Any change in the store descriptor will lead to previously deployed applications // forgetting all persisted data once they upgrade to the new version. acsStoreDescriptor = StoreDescriptor( - // Note that the V005__no_end_user_name_in_user_wallet_store.sql DB migration converts from version 1 descriptors - // to version 2 descriptors. - version = 2, + version = 3, name = "DbUserWalletStore", party = key.endUserParty, participant = participantId, @@ -83,9 +81,7 @@ class DbUserWalletStore( ), ), txLogStoreDescriptor = StoreDescriptor( - // Note that the V005__no_end_user_name_in_user_wallet_store.sql DB migration converts from version 1 descriptors - // to version 2 descriptors. - version = 2, + version = 3, name = "DbUserWalletStore", party = key.endUserParty, participant = participantId, From 59c58902382a26699408eb5de0e1ad4541646241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Mon, 25 Aug 2025 13:27:30 +0000 Subject: [PATCH 12/19] fix many compile errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../org/lfdecentralizedtrust/splice/store/db/DbAppStore.scala | 2 -- .../splice/store/db/DbMultiDomainAcsStore.scala | 2 -- .../splice/store/TxLogBackfillingStoreTest.scala | 1 - .../splice/store/db/DbMultiDomainAcsStoreTest.scala | 1 - 4 files changed, 6 deletions(-) diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbAppStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbAppStore.scala index 3a6de14bac..126c1a147f 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbAppStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbAppStore.scala @@ -58,7 +58,6 @@ abstract class DbTxLogAppStore[TXE]( acsContractFilter, txLogConfig, domainMigrationInfo, - participantId, retryProvider, handleIngestionSummary, ) @@ -98,7 +97,6 @@ abstract class DbAppStore( acsContractFilter, TxLogStore.Config.empty, domainMigrationInfo, - participantId, retryProvider, handleIngestionSummary, ) diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala index 72e47e48a8..e2cf1ce2a3 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStore.scala @@ -73,8 +73,6 @@ import scala.collection.mutable import scala.reflect.ClassTag import org.lfdecentralizedtrust.splice.util.FutureUnlessShutdownUtil.futureUnlessShutdownToFuture -import scala.annotation.unused - final class DbMultiDomainAcsStore[TXE]( storage: DbStorage, acsTableName: String, diff --git a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/TxLogBackfillingStoreTest.scala b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/TxLogBackfillingStoreTest.scala index 532d8b06d4..01ec2c698c 100644 --- a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/TxLogBackfillingStoreTest.scala +++ b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/TxLogBackfillingStoreTest.scala @@ -590,7 +590,6 @@ class TxLogBackfillingStoreTest migrationId, None, ), - participantId, RetryProvider(loggerFactory, timeouts, FutureSupervisor.Noop, NoOpMetricsFactory), ) } diff --git a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStoreTest.scala b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStoreTest.scala index 8aa8c60ded..42cee881c8 100644 --- a/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStoreTest.scala +++ b/apps/common/src/test/scala/org/lfdecentralizedtrust/splice/store/db/DbMultiDomainAcsStoreTest.scala @@ -629,7 +629,6 @@ class DbMultiDomainAcsStoreTest migrationId, None, ), - participantId, RetryProvider(loggerFactory, timeouts, FutureSupervisor.Noop, NoOpMetricsFactory), ) } From 3184d5ae325a664dccafaa2e6b1ca639c4f5cbed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Mon, 25 Aug 2025 14:52:10 +0000 Subject: [PATCH 13/19] add indexes with todo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../stable/V043__package_name_acs_stores.sql | 143 ++++++++++++++++-- 1 file changed, 134 insertions(+), 9 deletions(-) diff --git a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql index 2821e05942..8c94822411 100644 --- a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql +++ b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql @@ -1,11 +1,12 @@ -truncate table acs_store_template; -truncate table user_wallet_acs_store; -truncate table external_party_wallet_acs_store; -truncate table validator_acs_store; -truncate table sv_acs_store; -truncate table dso_acs_store; -truncate table scan_acs_store; -truncate table splitwell_acs_store; +-- strictly not necessary, but lets us define the constraint as mandatory afterwards +truncate table acs_store_template cascade; +truncate table user_wallet_acs_store cascade; +truncate table external_party_wallet_acs_store cascade; +truncate table validator_acs_store cascade; +truncate table sv_acs_store cascade; +truncate table dso_acs_store cascade; +truncate table scan_acs_store cascade; +truncate table splitwell_acs_store cascade; -- we just truncated the tables and there's no concurrent access while migrations are running, -- so we can make the column not null. @@ -19,4 +20,128 @@ alter table dso_acs_store add column package_name text not null; alter table scan_acs_store add column package_name text not null; alter table splitwell_acs_store add column package_name text not null; --- TODO: add indexes including the package_name column, and drop all those that don't have it +-- obtained with (unfortunately not all indexes are named consistently): +-- select +-- 'DROP INDEX ' || (regexp_matches(indexdef, 'CREATE INDEX (.*) ON'))[1] || ';' || E'\n' +-- 'CREATE INDEX replace_this ON ' || replace(replace(replace((regexp_matches(indexdef, 'CREATE INDEX (.*) ON (.*)'))[2], 'template_id_qualified_name', 'package_name, template_id_qualified_name'), 'public.', ''), 'USING btree', '') || ';' +-- from pg_indexes +-- where tablename like '%acs_store%' +-- and indexdef like '%template_id_qualified_name%'; +DROP INDEX acs_store_template_sid_mid_tid_ce; +CREATE INDEX fixme ON acs_store_template (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +DROP INDEX acs_store_template_sid_mid_tid_sn; +CREATE INDEX fixme ON acs_store_template (store_id, migration_id, package_name, template_id_qualified_name, state_number); +DROP INDEX user_wallet_acs_store_store_id_migration_id_template_id_qu_idx2; +CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +DROP INDEX user_wallet_acs_store_sid_mid_tid_rcr; +CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, reward_coupon_round) WHERE (reward_coupon_round IS NOT NULL); +DROP INDEX validator_acs_store_store_id_migration_id_template_id_qual_idx1; +CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +DROP INDEX validator_acs_store_store_id_migration_id_template_id_qual_idx2; +CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +DROP INDEX validator_acs_store_sid_mid_tid_up; +CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, user_party) WHERE (user_party IS NOT NULL); +DROP INDEX validator_acs_store_sid_mid_tid_un; +CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, user_name) WHERE (user_name IS NOT NULL); +DROP INDEX validator_acs_store_sid_mid_tid_pp; +CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, provider_party) WHERE (provider_party IS NOT NULL); +DROP INDEX validator_acs_store_sid_mid_tid_vp; +CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator_party) WHERE (validator_party IS NOT NULL); +DROP INDEX validator_acs_store_sid_mid_tid_tdi; +CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, traffic_domain_id) WHERE (traffic_domain_id IS NOT NULL); +DROP INDEX sv_acs_store_sid_mid_tid_vocs; +CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, onboarding_secret) WHERE (onboarding_secret IS NOT NULL); +DROP INDEX sv_acs_store_sid_mid_tid_asicn; +CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, sv_candidate_name) WHERE (sv_candidate_name IS NOT NULL); +DROP INDEX acs_store_template_sid_mid_tid_en; +CREATE INDEX fixme ON acs_store_template (store_id, migration_id, package_name, template_id_qualified_name, event_number); +DROP INDEX validator_acs_store_store_id_migration_id_template_id_quali_idx; +CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +DROP INDEX user_wallet_acs_store_store_id_migration_id_template_id_qua_idx; +CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +DROP INDEX user_wallet_acs_store_store_id_migration_id_template_id_qu_idx1; +CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +DROP INDEX dso_acs_store_store_id_migration_id_template_id_qualified_n_idx; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +DROP INDEX dso_acs_store_store_id_migration_id_template_id_qualified__idx1; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +DROP INDEX sv_acs_store_store_id_migration_id_template_id_qualified_na_idx; +CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +DROP INDEX sv_acs_store_store_id_migration_id_template_id_qualified_n_idx1; +CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +DROP INDEX sv_acs_store_store_id_migration_id_template_id_qualified_n_idx2; +CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +DROP INDEX dso_acs_store_store_id_migration_id_template_id_qualified__idx2; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +DROP INDEX dso_acs_store_sid_tid_mr; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, mining_round) WHERE (mining_round IS NOT NULL); +DROP INDEX dso_acs_store_sid_tid_tcid; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, vote_request_tracking_cid) WHERE (vote_request_tracking_cid IS NOT NULL); +DROP INDEX dso_acs_store_sid_tid_croe; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, amulet_round_of_expiry) WHERE (amulet_round_of_expiry IS NOT NULL); +DROP INDEX dso_acs_store_sid_tid_ah_c; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, action_requiring_confirmation, confirmer) WHERE (action_requiring_confirmation IS NOT NULL); +DROP INDEX dso_acs_store_coupons; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, reward_round, reward_party, app_reward_is_featured) WHERE ((reward_round IS NOT NULL) AND (reward_party IS NOT NULL)); +DROP INDEX dso_acs_store_sid_tid_sot; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, sv_onboarding_token) WHERE (sv_onboarding_token IS NOT NULL); +DROP INDEX dso_acs_store_sid_mid_tid_scp_scn; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, sv_candidate_party, sv_candidate_name) WHERE (sv_candidate_party IS NOT NULL); +DROP INDEX dso_acs_store_sid_mid_tid_scn; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, sv_candidate_name) WHERE (sv_candidate_name IS NOT NULL); +DROP INDEX dso_acs_store_sid_mid_tid_v_tp; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator, total_traffic_purchased) WHERE (validator IS NOT NULL); +DROP INDEX dso_acs_store_sid_mid_tid_ah_r; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, action_requiring_confirmation, requester) WHERE (action_requiring_confirmation IS NOT NULL); +DROP INDEX dso_acs_store_sid_mid_tid_ere_r; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, election_request_epoch, requester) WHERE ((election_request_epoch IS NOT NULL) AND (requester IS NOT NULL)); +DROP INDEX dso_acs_store_sid_mid_tid_acecc; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, action_ans_entry_context_cid) WHERE (action_ans_entry_context_cid IS NOT NULL); +DROP INDEX dso_acs_store_sid_mid_tid_sccid; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, subscription_reference_contract_id) WHERE (subscription_reference_contract_id IS NOT NULL); +DROP INDEX dso_acs_store_sid_mid_tid_snpd; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, subscription_next_payment_due_at) WHERE (subscription_next_payment_due_at IS NOT NULL); +DROP INDEX scan_acs_store_store_id_migration_id_template_id_qualified__idx; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +DROP INDEX scan_acs_store_store_id_migration_id_template_id_qualified_idx1; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +DROP INDEX scan_acs_store_store_id_migration_id_template_id_qualified_idx2; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +DROP INDEX scan_acs_store_sid_mid_tid_val; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator, event_number) WHERE (validator IS NOT NULL); +DROP INDEX scan_acs_store_sid_mid_tid_farp; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, featured_app_right_provider) WHERE (featured_app_right_provider IS NOT NULL); +DROP INDEX scan_acs_store_sid_mid_tid_vlrc; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator_license_rounds_collected) WHERE (validator_license_rounds_collected IS NOT NULL); +DROP INDEX scan_acs_store_sid_mid_tid_mtm_mtd; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, member_traffic_member, member_traffic_domain) WHERE (member_traffic_member IS NOT NULL); +DROP INDEX scan_acs_store_wallet_party_idx; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, wallet_party) WHERE (wallet_party IS NOT NULL); +DROP INDEX splitwell_acs_store_store_id_migration_id_template_id_quali_idx; +CREATE INDEX fixme ON splitwell_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +DROP INDEX splitwell_acs_store_store_id_migration_id_template_id_qual_idx1; +CREATE INDEX fixme ON splitwell_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +DROP INDEX splitwell_acs_store_store_id_migration_id_template_id_qual_idx2; +CREATE INDEX fixme ON splitwell_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +DROP INDEX dso_acs_store_sid_mid_tid_cen_exp; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, ans_entry_name, contract_expires_at) WHERE ((ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); +DROP INDEX scan_acs_store_sid_mid_den_tpo_exp; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, ans_entry_name text_pattern_ops, contract_expires_at) WHERE ((ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); +DROP INDEX scan_acs_store_sid_mid_deo_den_exp; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, ans_entry_owner, ans_entry_name, contract_expires_at) WHERE ((ans_entry_owner IS NOT NULL) AND (ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); +DROP INDEX scan_acs_store_sid_mid_tidqn_v; +CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator) WHERE (validator IS NOT NULL); +DROP INDEX user_wallet_acs_store_sid_mid_tid_rcv; +CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, transfer_preapproval_receiver) WHERE (transfer_preapproval_receiver IS NOT NULL); +DROP INDEX external_party_wallet_acs_sto_store_id_migration_id_templat_idx; +CREATE INDEX fixme ON external_party_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +DROP INDEX external_party_wallet_acs_sto_store_id_migration_id_templa_idx1; +CREATE INDEX fixme ON external_party_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +DROP INDEX external_party_wallet_acs_sto_store_id_migration_id_templa_idx2; +CREATE INDEX fixme ON external_party_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +DROP INDEX external_party_wallet_acs_store_sid_mid_tid_rcr; +CREATE INDEX fixme ON external_party_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, reward_coupon_round) WHERE (reward_coupon_round IS NOT NULL); +DROP INDEX dso_acs_store_wallet_party_idx; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, wallet_party) WHERE (wallet_party IS NOT NULL); +DROP INDEX dso_acs_store_sid_mid_tid_mtm_mtd; +CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, member_traffic_member, member_traffic_domain) WHERE (member_traffic_member IS NOT NULL); From 5910a9ffc422454501aafe5da8d3857b21f814f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Mon, 25 Aug 2025 15:05:28 +0000 Subject: [PATCH 14/19] [ci] change definition of all indexes involving tid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../stable/V043__package_name_acs_stores.sql | 340 ++++++++++++++---- 1 file changed, 277 insertions(+), 63 deletions(-) diff --git a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql index 8c94822411..2a3aecf1af 100644 --- a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql +++ b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql @@ -1,4 +1,5 @@ --- strictly not necessary, but lets us define the constraint as mandatory afterwards +-- strictly not necessary, but lets us define the constraint as mandatory afterwards, +-- and also makes index creation faster since there's no data to index truncate table acs_store_template cascade; truncate table user_wallet_acs_store cascade; truncate table external_party_wallet_acs_store cascade; @@ -20,128 +21,341 @@ alter table dso_acs_store add column package_name text not null; alter table scan_acs_store add column package_name text not null; alter table splitwell_acs_store add column package_name text not null; --- obtained with (unfortunately not all indexes are named consistently): +-- obtained with (unfortunately not all indexes are named consistently, so some require manual intervention) and IJ formatting: -- select -- 'DROP INDEX ' || (regexp_matches(indexdef, 'CREATE INDEX (.*) ON'))[1] || ';' || E'\n' --- 'CREATE INDEX replace_this ON ' || replace(replace(replace((regexp_matches(indexdef, 'CREATE INDEX (.*) ON (.*)'))[2], 'template_id_qualified_name', 'package_name, template_id_qualified_name'), 'public.', ''), 'USING btree', '') || ';' +-- 'CREATE INDEX ' || replace((regexp_matches(indexdef, 'CREATE INDEX (.*) ON'))[1], 'tid', 'pn_tid') || ' ON ' || replace(replace(replace((regexp_matches(indexdef, 'CREATE INDEX (.*) ON (.*)'))[2], 'template_id_qualified_name', 'package_name, template_id_qualified_name'), 'public.', ''), 'USING btree', '') || ';' || E'\n' -- from pg_indexes -- where tablename like '%acs_store%' --- and indexdef like '%template_id_qualified_name%'; +-- and indexdef like '%template_id_qualified_name%'; DROP INDEX acs_store_template_sid_mid_tid_ce; -CREATE INDEX fixme ON acs_store_template (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +CREATE INDEX acs_store_template_sid_mid_pn_tid_ce ON acs_store_template (store_id, migration_id, package_name, + template_id_qualified_name, + contract_expires_at) WHERE (contract_expires_at IS NOT NULL); + DROP INDEX acs_store_template_sid_mid_tid_sn; -CREATE INDEX fixme ON acs_store_template (store_id, migration_id, package_name, template_id_qualified_name, state_number); +CREATE INDEX acs_store_template_sid_mid_pn_tid_sn ON acs_store_template (store_id, migration_id, package_name, + template_id_qualified_name, state_number); + DROP INDEX user_wallet_acs_store_store_id_migration_id_template_id_qu_idx2; -CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +CREATE INDEX user_wallet_acs_store_sid_mid_pn_tid_sn ON user_wallet_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + state_number); + DROP INDEX user_wallet_acs_store_sid_mid_tid_rcr; -CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, reward_coupon_round) WHERE (reward_coupon_round IS NOT NULL); +CREATE INDEX user_wallet_acs_store_sid_mid_pn_tid_rcr ON user_wallet_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + reward_coupon_round) WHERE (reward_coupon_round IS NOT NULL); + DROP INDEX validator_acs_store_store_id_migration_id_template_id_qual_idx1; -CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +CREATE INDEX validator_acs_store_sid_mid_pn_tid_exp ON validator_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + contract_expires_at) WHERE (contract_expires_at IS NOT NULL); + DROP INDEX validator_acs_store_store_id_migration_id_template_id_qual_idx2; -CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +CREATE INDEX validator_acs_store_sid_mid_pn_tid_sn ON validator_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + state_number); + DROP INDEX validator_acs_store_sid_mid_tid_up; -CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, user_party) WHERE (user_party IS NOT NULL); +CREATE INDEX validator_acs_store_sid_mid_pn_tid_up ON validator_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + user_party) WHERE (user_party IS NOT NULL); + DROP INDEX validator_acs_store_sid_mid_tid_un; -CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, user_name) WHERE (user_name IS NOT NULL); +CREATE INDEX validator_acs_store_sid_mid_pn_tid_un ON validator_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + user_name) WHERE (user_name IS NOT NULL); + DROP INDEX validator_acs_store_sid_mid_tid_pp; -CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, provider_party) WHERE (provider_party IS NOT NULL); +CREATE INDEX validator_acs_store_sid_mid_pn_tid_pp ON validator_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + provider_party) WHERE (provider_party IS NOT NULL); + DROP INDEX validator_acs_store_sid_mid_tid_vp; -CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator_party) WHERE (validator_party IS NOT NULL); +CREATE INDEX validator_acs_store_sid_mid_pn_tid_vp ON validator_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + validator_party) WHERE (validator_party IS NOT NULL); + DROP INDEX validator_acs_store_sid_mid_tid_tdi; -CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, traffic_domain_id) WHERE (traffic_domain_id IS NOT NULL); +CREATE INDEX validator_acs_store_sid_mid_pn_tid_tdi ON validator_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + traffic_domain_id) WHERE (traffic_domain_id IS NOT NULL); + DROP INDEX sv_acs_store_sid_mid_tid_vocs; -CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, onboarding_secret) WHERE (onboarding_secret IS NOT NULL); +CREATE INDEX sv_acs_store_sid_mid_pn_tid_vocs ON sv_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + onboarding_secret) WHERE (onboarding_secret IS NOT NULL); + DROP INDEX sv_acs_store_sid_mid_tid_asicn; -CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, sv_candidate_name) WHERE (sv_candidate_name IS NOT NULL); +CREATE INDEX sv_acs_store_sid_mid_pn_tid_asicn ON sv_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + sv_candidate_name) WHERE (sv_candidate_name IS NOT NULL); + DROP INDEX acs_store_template_sid_mid_tid_en; -CREATE INDEX fixme ON acs_store_template (store_id, migration_id, package_name, template_id_qualified_name, event_number); +CREATE INDEX acs_store_template_sid_mid_pn_tid_en ON acs_store_template (store_id, migration_id, package_name, + template_id_qualified_name, event_number); + DROP INDEX validator_acs_store_store_id_migration_id_template_id_quali_idx; -CREATE INDEX fixme ON validator_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +CREATE INDEX validator_acs_store_sid_mid_pn_tid_en ON validator_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + event_number); + DROP INDEX user_wallet_acs_store_store_id_migration_id_template_id_qua_idx; -CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +CREATE INDEX user_wallet_acs_store_sid_mid_pn_tid_en ON user_wallet_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + event_number); + DROP INDEX user_wallet_acs_store_store_id_migration_id_template_id_qu_idx1; -CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +CREATE INDEX user_wallet_acs_store_sid_mid_pn_tid_exp ON user_wallet_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + contract_expires_at) WHERE (contract_expires_at IS NOT NULL); + DROP INDEX dso_acs_store_store_id_migration_id_template_id_qualified_n_idx; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_en ON dso_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + event_number); + DROP INDEX dso_acs_store_store_id_migration_id_template_id_qualified__idx1; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_exp ON dso_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + contract_expires_at) WHERE (contract_expires_at IS NOT NULL); + DROP INDEX sv_acs_store_store_id_migration_id_template_id_qualified_na_idx; -CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +CREATE INDEX sv_acs_store_sid_mid_pn_tid_en ON sv_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + event_number); + DROP INDEX sv_acs_store_store_id_migration_id_template_id_qualified_n_idx1; -CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +CREATE INDEX sv_acs_store_sid_mid_pn_tid_exp ON sv_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + contract_expires_at) WHERE (contract_expires_at IS NOT NULL); + DROP INDEX sv_acs_store_store_id_migration_id_template_id_qualified_n_idx2; -CREATE INDEX fixme ON sv_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +CREATE INDEX sv_acs_store_sid_mid_pn_tid_sn ON sv_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + state_number); + DROP INDEX dso_acs_store_store_id_migration_id_template_id_qualified__idx2; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_sn ON dso_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + state_number); + DROP INDEX dso_acs_store_sid_tid_mr; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, mining_round) WHERE (mining_round IS NOT NULL); +CREATE INDEX dso_acs_store_sid_pn_tid_mr ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + mining_round) WHERE (mining_round IS NOT NULL); + DROP INDEX dso_acs_store_sid_tid_tcid; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, vote_request_tracking_cid) WHERE (vote_request_tracking_cid IS NOT NULL); +CREATE INDEX dso_acs_store_sid_pn_tid_tcid ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + vote_request_tracking_cid) WHERE (vote_request_tracking_cid IS NOT NULL); + DROP INDEX dso_acs_store_sid_tid_croe; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, amulet_round_of_expiry) WHERE (amulet_round_of_expiry IS NOT NULL); +CREATE INDEX dso_acs_store_sid_pn_tid_croe ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + amulet_round_of_expiry) WHERE (amulet_round_of_expiry IS NOT NULL); + DROP INDEX dso_acs_store_sid_tid_ah_c; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, action_requiring_confirmation, confirmer) WHERE (action_requiring_confirmation IS NOT NULL); +CREATE INDEX dso_acs_store_sid_pn_tid_ah_c ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, action_requiring_confirmation, + confirmer) WHERE (action_requiring_confirmation IS NOT NULL); + DROP INDEX dso_acs_store_coupons; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, reward_round, reward_party, app_reward_is_featured) WHERE ((reward_round IS NOT NULL) AND (reward_party IS NOT NULL)); +CREATE INDEX dso_acs_store_coupons ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, + reward_round, reward_party, + app_reward_is_featured) WHERE ((reward_round IS NOT NULL) AND (reward_party IS NOT NULL)); + DROP INDEX dso_acs_store_sid_tid_sot; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, sv_onboarding_token) WHERE (sv_onboarding_token IS NOT NULL); +CREATE INDEX dso_acs_store_sid_pn_tid_sot ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + sv_onboarding_token) WHERE (sv_onboarding_token IS NOT NULL); + DROP INDEX dso_acs_store_sid_mid_tid_scp_scn; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, sv_candidate_party, sv_candidate_name) WHERE (sv_candidate_party IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_scp_scn ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, sv_candidate_party, + sv_candidate_name) WHERE (sv_candidate_party IS NOT NULL); + DROP INDEX dso_acs_store_sid_mid_tid_scn; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, sv_candidate_name) WHERE (sv_candidate_name IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_scn ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + sv_candidate_name) WHERE (sv_candidate_name IS NOT NULL); + DROP INDEX dso_acs_store_sid_mid_tid_v_tp; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator, total_traffic_purchased) WHERE (validator IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_v_tp ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, validator, + total_traffic_purchased) WHERE (validator IS NOT NULL); + DROP INDEX dso_acs_store_sid_mid_tid_ah_r; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, action_requiring_confirmation, requester) WHERE (action_requiring_confirmation IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_ah_r ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + action_requiring_confirmation, + requester) WHERE (action_requiring_confirmation IS NOT NULL); + DROP INDEX dso_acs_store_sid_mid_tid_ere_r; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, election_request_epoch, requester) WHERE ((election_request_epoch IS NOT NULL) AND (requester IS NOT NULL)); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_ere_r ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, election_request_epoch, + requester) WHERE ((election_request_epoch IS NOT NULL) AND (requester IS NOT NULL)); + DROP INDEX dso_acs_store_sid_mid_tid_acecc; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, action_ans_entry_context_cid) WHERE (action_ans_entry_context_cid IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_acecc ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + action_ans_entry_context_cid) WHERE (action_ans_entry_context_cid IS NOT NULL); + DROP INDEX dso_acs_store_sid_mid_tid_sccid; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, subscription_reference_contract_id) WHERE (subscription_reference_contract_id IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_sccid ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + subscription_reference_contract_id) WHERE (subscription_reference_contract_id IS NOT NULL); + DROP INDEX dso_acs_store_sid_mid_tid_snpd; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, subscription_next_payment_due_at) WHERE (subscription_next_payment_due_at IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_snpd ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + subscription_next_payment_due_at) WHERE (subscription_next_payment_due_at IS NOT NULL); + DROP INDEX scan_acs_store_store_id_migration_id_template_id_qualified__idx; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_en ON scan_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + event_number); + DROP INDEX scan_acs_store_store_id_migration_id_template_id_qualified_idx1; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_exp ON scan_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + contract_expires_at) WHERE (contract_expires_at IS NOT NULL); + DROP INDEX scan_acs_store_store_id_migration_id_template_id_qualified_idx2; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_sn ON scan_acs_store (store_id, migration_id, + package_name, + template_id_qualified_name, + state_number); + DROP INDEX scan_acs_store_sid_mid_tid_val; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator, event_number) WHERE (validator IS NOT NULL); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_val ON scan_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, validator, + event_number) WHERE (validator IS NOT NULL); + DROP INDEX scan_acs_store_sid_mid_tid_farp; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, featured_app_right_provider) WHERE (featured_app_right_provider IS NOT NULL); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_farp ON scan_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + featured_app_right_provider) WHERE (featured_app_right_provider IS NOT NULL); + DROP INDEX scan_acs_store_sid_mid_tid_vlrc; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator_license_rounds_collected) WHERE (validator_license_rounds_collected IS NOT NULL); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_vlrc ON scan_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + validator_license_rounds_collected) WHERE (validator_license_rounds_collected IS NOT NULL); + DROP INDEX scan_acs_store_sid_mid_tid_mtm_mtd; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, member_traffic_member, member_traffic_domain) WHERE (member_traffic_member IS NOT NULL); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_mtm_mtd ON scan_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, member_traffic_member, + member_traffic_domain) WHERE (member_traffic_member IS NOT NULL); + DROP INDEX scan_acs_store_wallet_party_idx; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, wallet_party) WHERE (wallet_party IS NOT NULL); +CREATE INDEX scan_acs_store_wallet_party_idx ON scan_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + wallet_party) WHERE (wallet_party IS NOT NULL); + DROP INDEX splitwell_acs_store_store_id_migration_id_template_id_quali_idx; -CREATE INDEX fixme ON splitwell_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +CREATE INDEX splitwell_acs_store_sid_mid_pn_tid_en ON splitwell_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + event_number); + DROP INDEX splitwell_acs_store_store_id_migration_id_template_id_qual_idx1; -CREATE INDEX fixme ON splitwell_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +CREATE INDEX splitwell_acs_store_sid_mid_pn_tid_exp ON splitwell_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + contract_expires_at) WHERE (contract_expires_at IS NOT NULL); + DROP INDEX splitwell_acs_store_store_id_migration_id_template_id_qual_idx2; -CREATE INDEX fixme ON splitwell_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +CREATE INDEX splitwell_acs_store_sid_mid_pn_tid_sn ON splitwell_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + state_number); + DROP INDEX dso_acs_store_sid_mid_tid_cen_exp; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, ans_entry_name, contract_expires_at) WHERE ((ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_cen_exp ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, ans_entry_name, + contract_expires_at) WHERE ((ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); + DROP INDEX scan_acs_store_sid_mid_den_tpo_exp; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, ans_entry_name text_pattern_ops, contract_expires_at) WHERE ((ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_aen_tpo_exp ON scan_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, ans_entry_name + text_pattern_ops, + contract_expires_at) WHERE ((ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); + DROP INDEX scan_acs_store_sid_mid_deo_den_exp; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, ans_entry_owner, ans_entry_name, contract_expires_at) WHERE ((ans_entry_owner IS NOT NULL) AND (ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); +CREATE INDEX scan_acs_store_sid_mid_deo_den_exp ON scan_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, ans_entry_owner, + ans_entry_name, contract_expires_at) WHERE ( + (ans_entry_owner IS NOT NULL) AND (ans_entry_name IS NOT NULL) AND (contract_expires_at IS NOT NULL)); + DROP INDEX scan_acs_store_sid_mid_tidqn_v; -CREATE INDEX fixme ON scan_acs_store (store_id, migration_id, package_name, template_id_qualified_name, validator) WHERE (validator IS NOT NULL); +CREATE INDEX scan_acs_store_sid_mid_pn_tid_v ON scan_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + validator) WHERE (validator IS NOT NULL); + DROP INDEX user_wallet_acs_store_sid_mid_tid_rcv; -CREATE INDEX fixme ON user_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, transfer_preapproval_receiver) WHERE (transfer_preapproval_receiver IS NOT NULL); +CREATE INDEX user_wallet_acs_store_sid_mid_pn_tid_rcv ON user_wallet_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + transfer_preapproval_receiver) WHERE (transfer_preapproval_receiver IS NOT NULL); + DROP INDEX external_party_wallet_acs_sto_store_id_migration_id_templat_idx; -CREATE INDEX fixme ON external_party_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, event_number); +CREATE INDEX external_party_wallet_acs_store_sid_mid_pn_tid_en ON external_party_wallet_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + event_number); + DROP INDEX external_party_wallet_acs_sto_store_id_migration_id_templa_idx1; -CREATE INDEX fixme ON external_party_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, contract_expires_at) WHERE (contract_expires_at IS NOT NULL); +CREATE INDEX external_party_wallet_acs_sid_mid_pn_tid_exp ON external_party_wallet_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + contract_expires_at) WHERE (contract_expires_at IS NOT NULL); + DROP INDEX external_party_wallet_acs_sto_store_id_migration_id_templa_idx2; -CREATE INDEX fixme ON external_party_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, state_number); +CREATE INDEX external_party_wallet_store_sid_mid_pn_tid_sn ON external_party_wallet_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + state_number); + DROP INDEX external_party_wallet_acs_store_sid_mid_tid_rcr; -CREATE INDEX fixme ON external_party_wallet_acs_store (store_id, migration_id, package_name, template_id_qualified_name, reward_coupon_round) WHERE (reward_coupon_round IS NOT NULL); +CREATE INDEX external_party_wallet_acs_store_sid_mid_pn_tid_rcr ON external_party_wallet_acs_store (store_id, + migration_id, + package_name, + template_id_qualified_name, + reward_coupon_round) WHERE (reward_coupon_round IS NOT NULL); + DROP INDEX dso_acs_store_wallet_party_idx; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, wallet_party) WHERE (wallet_party IS NOT NULL); +CREATE INDEX dso_acs_store_wallet_party_idx ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, + wallet_party) WHERE (wallet_party IS NOT NULL); + DROP INDEX dso_acs_store_sid_mid_tid_mtm_mtd; -CREATE INDEX fixme ON dso_acs_store (store_id, migration_id, package_name, template_id_qualified_name, member_traffic_member, member_traffic_domain) WHERE (member_traffic_member IS NOT NULL); +CREATE INDEX dso_acs_store_sid_mid_pn_tid_mtm_mtd ON dso_acs_store (store_id, migration_id, package_name, + template_id_qualified_name, member_traffic_member, + member_traffic_domain) WHERE (member_traffic_member IS NOT NULL); + From 1680a64b4cb0ace131dd19435f78cb0d69064cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Mon, 25 Aug 2025 15:31:11 +0000 Subject: [PATCH 15/19] [ci] also truncate store_last_ingested_offsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../postgres/stable/V043__package_name_acs_stores.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql index 2a3aecf1af..75a3d5e095 100644 --- a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql +++ b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql @@ -1,5 +1,6 @@ -- strictly not necessary, but lets us define the constraint as mandatory afterwards, -- and also makes index creation faster since there's no data to index +truncate table store_last_ingested_offsets cascade; truncate table acs_store_template cascade; truncate table user_wallet_acs_store cascade; truncate table external_party_wallet_acs_store cascade; From 5bfdbca61d43c7820a1cf63687a8237d33ad41d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Tue, 26 Aug 2025 15:01:57 +0000 Subject: [PATCH 16/19] [ci] revert bump of txlog descriptor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../splice/wallet/store/db/DbUserWalletStore.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala b/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala index e669b876e4..e739c5ba6e 100644 --- a/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala +++ b/apps/wallet/src/main/scala/org/lfdecentralizedtrust/splice/wallet/store/db/DbUserWalletStore.scala @@ -81,7 +81,9 @@ class DbUserWalletStore( ), ), txLogStoreDescriptor = StoreDescriptor( - version = 3, + // Note that the V005__no_end_user_name_in_user_wallet_store.sql DB migration converts from version 1 descriptors + // to version 2 descriptors. + version = 2, name = "DbUserWalletStore", party = key.endUserParty, participant = participantId, From cb9983fcbc10e73ea9beccc0f213cab25025020f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Tue, 26 Aug 2025 15:59:09 +0000 Subject: [PATCH 17/19] wip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../stable/V043__package_name_acs_stores.sql | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql index 75a3d5e095..58f46fdf0a 100644 --- a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql +++ b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql @@ -1,6 +1,15 @@ --- strictly not necessary, but lets us define the constraint as mandatory afterwards, +-- truncates are not strictly necessary, but lets us define the constraint as mandatory afterwards, -- and also makes index creation faster since there's no data to index -truncate table store_last_ingested_offsets cascade; +delete +from store_last_ingested_offsets +where store_id in (select id + from store_descriptors + where descriptor ->> 'name' IN + -- these are ACS only, so we can delete everything + ('DbSplitwellStore', 'DbSvSvStore', 'DbValidatorStore', 'DbExternalPartyWalletStore') + -- these have txlog, preserve it. Version matches that of the txlog descriptor + OR (descriptor ->> 'name' = 'DbUserWalletStore' AND descriptor ->> 'version' != 2) + OR (descriptor ->> 'name' = 'DbScanStore' AND descriptor ->> 'version' != 1)); truncate table acs_store_template cascade; truncate table user_wallet_acs_store cascade; truncate table external_party_wallet_acs_store cascade; From 16df3a3dcc7e4d1d8df0a75e611495c53903e668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Fri, 5 Sep 2025 11:34:07 +0000 Subject: [PATCH 18/19] fix comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala index 88d029d8df..e902e76728 100644 --- a/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala +++ b/apps/common/src/main/scala/org/lfdecentralizedtrust/splice/store/db/AcsQueries.scala @@ -356,7 +356,7 @@ object AcsQueries { companionClass: ContractCompanion[C, TCId, T], decoder: TemplateJsonDecoder, ): Contract[TCId, T] = { - // safety check: if the templates don't match, + // safety check: if the PackageQualifiedNames don't match, // it means that we would be returning a contract of a different template // note that the packageId not matching is expected due to upgrades, but the name will be stable val expectedPackageQualifiedName = companionClass.packageQualifiedName(companion) From 553b6c919f019acdabe7fd2373e3cccf8ff5a4c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Mu=C3=B1oz?= Date: Fri, 5 Sep 2025 11:40:53 +0000 Subject: [PATCH 19/19] [ci] update migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Oriol Muñoz --- .../stable/V043__package_name_acs_stores.sql | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql index 58f46fdf0a..9451d9b246 100644 --- a/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql +++ b/apps/common/src/main/resources/db/migration/canton-network/postgres/stable/V043__package_name_acs_stores.sql @@ -1,15 +1,5 @@ -- truncates are not strictly necessary, but lets us define the constraint as mandatory afterwards, -- and also makes index creation faster since there's no data to index -delete -from store_last_ingested_offsets -where store_id in (select id - from store_descriptors - where descriptor ->> 'name' IN - -- these are ACS only, so we can delete everything - ('DbSplitwellStore', 'DbSvSvStore', 'DbValidatorStore', 'DbExternalPartyWalletStore') - -- these have txlog, preserve it. Version matches that of the txlog descriptor - OR (descriptor ->> 'name' = 'DbUserWalletStore' AND descriptor ->> 'version' != 2) - OR (descriptor ->> 'name' = 'DbScanStore' AND descriptor ->> 'version' != 1)); truncate table acs_store_template cascade; truncate table user_wallet_acs_store cascade; truncate table external_party_wallet_acs_store cascade; @@ -31,6 +21,8 @@ alter table dso_acs_store add column package_name text not null; alter table scan_acs_store add column package_name text not null; alter table splitwell_acs_store add column package_name text not null; +-- index creation should be fast since all ACS stores have been truncated + -- obtained with (unfortunately not all indexes are named consistently, so some require manual intervention) and IJ formatting: -- select -- 'DROP INDEX ' || (regexp_matches(indexdef, 'CREATE INDEX (.*) ON'))[1] || ';' || E'\n'