Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forbid daml-script at startup and upload time #20713

Draft
wants to merge 1 commit into
base: release/3.2.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ trait CantonConfig {
// TODO(i21341) Remove the flag before going to production
experimentalEnableTopologyEvents = participantParameters.experimentalEnableTopologyEvents,
enableExternalAuthorization = participantParameters.enableExternalAuthorization,
allowDamlScriptUpload = participantParameters.allowDamlScriptUpload,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,5 +330,37 @@ object PackageServiceErrors extends PackageServiceErrorGroup {
),
)
}

@Explanation(
"""Upload of Daml-Script is heavily deprecated in Daml 3.2, and will be forbidden in Daml 3.3"""
)
@Resolution(
"""Remove Daml-Script from the dependencies of the uploaded package.
|For Daml 3.2 only, `parameters.allow-daml-script-upload = true` can be added to your participant config
|""".stripMargin
)
object IllegalDamlScriptUpload
extends ErrorCode(
id = "ILLEGAL_DAML_SCRIPT_UPLOAD",
ErrorCategory.InvalidIndependentOfSystemState,
) {
final case class Error(
packages: List[(Ref.PackageId, Ref.PackageName, Ref.PackageVersion)]
)(implicit
val loggingContext: ContextualizedErrorLogger
) extends DamlError(
cause = {
val packagesStr = packages.map{case (pkgId, pkgName, pkgVersion) => s" - $pkgId ($pkgName-$pkgVersion)\n"}
s"Illegal upload of daml-script package(s)\n$packagesStr" +
"Uploading of daml-script to canton is deprecated in Daml 3.2, and will be disallowed in 3.3\n" +
"Please remove daml-script from the dependencies of the uploaded dar\n" +
"To temporarily avoid this error, add `parameters.allow-daml-script-upload = true` to your participant config, but be aware that this parameter will not exist in Daml 3.3"
},
extraContext = Map(
"packageIds" -> packages.map(_._1),

),
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -534,10 +534,12 @@ class ParticipantNodeBootstrap(
packageMetadataViewConfig = config.parameters.packageMetadataView,
packageOps = createPackageOps(syncDomainPersistentStateManager),
timeouts = parameterConfig.processingTimeouts,
allowDamlScriptUpload = parameterConfig.allowDamlScriptUpload,
),
loggerFactory = loggerFactory,
)
_ <- EitherT.right(packageServiceContainer.initializeNext())
_ <- packageServiceContainer.asEval.value.checkForDamlScript()

sequencerInfoLoader = new SequencerInfoLoader(
parameterConfig.processingTimeouts,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ final case class ParticipantNodeParameters(
unsafeEnableOnlinePartyReplication: Boolean,
experimentalEnableTopologyEvents: Boolean,
enableExternalAuthorization: Boolean,
allowDamlScriptUpload: Boolean,
) extends CantonNodeParameters
with HasGeneralCantonNodeParameters {
override def dontWarnOnDeprecatedPV: Boolean = protocolConfig.dontWarnOnDeprecatedPV
Expand Down Expand Up @@ -81,5 +82,6 @@ object ParticipantNodeParameters {
unsafeEnableOnlinePartyReplication = false,
experimentalEnableTopologyEvents = true,
enableExternalAuthorization = false,
allowDamlScriptUpload = false,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import cats.implicits.toBifunctorOps
import cats.syntax.functor.*
import cats.syntax.functorFilter.*
import cats.syntax.parallel.*
import cats.syntax.traverse.*
import com.daml.error.{ContextualizedErrorLogger, DamlError}
import com.digitalasset.canton.LedgerSubmissionId
import com.digitalasset.canton.concurrent.FutureSupervisor
Expand Down Expand Up @@ -81,6 +82,7 @@ class PackageService(
packageOps: PackageOps,
packageUploader: PackageUploader,
protected val timeouts: ProcessingTimeout,
val allowDamlScriptUpload: Boolean,
)(implicit ec: ExecutionContext)
extends DarService
with PackageInfoService
Expand Down Expand Up @@ -366,7 +368,31 @@ class PackageService(

override def onClosed(): Unit = Lifecycle.close(packageUploader, packageMetadataView)(logger)

}
def checkForDamlScript()(implicit traceContext: TraceContext): EitherT[FutureUnlessShutdown, String, Unit] =
if (!allowDamlScriptUpload) {
val snapshot = packageMetadataView.getSnapshot
val illegalPackages = snapshot.packageNameMap.toList.flatMap{
case (name @ ("daml-script" | "daml3-script" | "daml-script-lts" | "daml-script-lts-stable"), res) =>
res.allPackageIdsForName.toList.map(pkgId => (pkgId, name))
case _ => List.empty
}

if (!illegalPackages.isEmpty) {
illegalPackages.traverse{
case (pkgId, pkgName) => EitherT.liftF(getDescription(pkgId).map(desc => (pkgId, pkgName, desc.map(_.sourceDescription.str)))).mapK(FutureUnlessShutdown.outcomeK)
}.flatMap{pkgs =>
val pkgsStr = pkgs.map{case (pkgId, pkgName, pkgSource) => s" - $pkgId ($pkgName)" + pkgSource.fold("\n")(src => s" (from dar: $src)\n")}.mkString
val err =
"\nFound illegal daml-script package(s) in package store:\n" +
pkgsStr +
"Uploading of daml-script to canton is deprecated in Daml 3.2, and will be disallowed in 3.3\n" +
"Please remove daml-script from dependencies of all uploaded packages\n" +
"To temporarily avoid this error, add `parameters.allow-daml-script-upload = true` to your participant config, but be aware that this parameter will not exist in Daml 3.3"
EitherT.leftT[FutureUnlessShutdown, Unit](err)
}
} else EitherT.rightT[FutureUnlessShutdown, String](())
} else EitherT.rightT[FutureUnlessShutdown, String](())
}

object PackageService {
def createAndInitialize(
Expand All @@ -382,6 +408,7 @@ object PackageService {
packageMetadataViewConfig: PackageMetadataViewConfig,
packageOps: PackageOps,
timeouts: ProcessingTimeout,
allowDamlScriptUpload: Boolean,
)(implicit
ec: ExecutionContext,
actorSystem: ActorSystem,
Expand All @@ -404,6 +431,7 @@ object PackageService {
packageDependencyResolver,
mutablePackageMetadataView,
exitOnFatalFailures = exitOnFatalFailures,
allowDamlScriptUpload,
timeouts,
loggerFactory,
)
Expand All @@ -416,6 +444,7 @@ object PackageService {
packageOps,
packageUploader,
timeouts,
allowDamlScriptUpload,
)

// Initialize the packageMetadataView and return only the PackageService. It also takes care of teardown of the packageMetadataView and packageUploader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class PackageUploader(
packageDependencyResolver: PackageDependencyResolver,
packageMetadataView: MutablePackageMetadataView,
exitOnFatalFailures: Boolean,
allowDamlScriptUpload: Boolean,
protected val timeouts: ProcessingTimeout,
protected val loggerFactory: NamedLoggerFactory,
)(implicit executionContext: ExecutionContext)
Expand Down Expand Up @@ -219,6 +220,18 @@ class PackageUploader(
PackageServiceErrors.Validation.handleLfEnginePackageError(_): DamlError
)
)
_ <-
EitherT.fromEither[FutureUnlessShutdown]{
if (!allowDamlScriptUpload) {
val illegalPackages = packages.collect{
case (pkgId, pkg) if List("daml-script", "daml3-script", "daml-script-lts", "daml-script-lts-stable").contains(pkg.metadata.name) =>
(pkgId, pkg.metadata.name, pkg.metadata.version)
}
if (!illegalPackages.isEmpty) Left(PackageServiceErrors.Validation.IllegalDamlScriptUpload.Error(illegalPackages))
else Right(())
} else Right(())
}

_ <-
if (enableUpgradeValidation) {
packageUpgradeValidator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ object TestingTimeServiceConfig {
* @param packageMetadataView Initialization parameters for the package metadata in-memory store.
* @param experimentalEnableTopologyEvents If true, topology events are propagated to the Ledger API clients
* @param enableExternalAuthorization If true, external authentication is supported
* @param allowDamlScriptUpload Deprecated: Allow daml-script to be uploaded to the ledger. This will be removed in Daml 3.3.
*/
final case class ParticipantNodeParameterConfig(
adminWorkflow: AdminWorkflowConfig = AdminWorkflowConfig(),
Expand Down Expand Up @@ -307,6 +308,7 @@ final case class ParticipantNodeParameterConfig(
unsafeEnableOnlinePartyReplication: Boolean = false,
experimentalEnableTopologyEvents: Boolean = false,
enableExternalAuthorization: Boolean = false,
allowDamlScriptUpload: Boolean = false,
) extends LocalNodeParametersConfig

/** Parameters for the participant node's stores
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ object DAMLeTestInstance {
enableUpgradeValidation = false,
futureSupervisor = FutureSupervisor.Noop,
exitOnFatalFailures = true,
allowDamlScriptUpload = false,
timeouts = timeouts,
loggerFactory = loggerFactory,
packageMetadataView = NoopPackageMetadataView,
Expand Down
Loading