How to fetch DAR from Canton bootstrap script?

How can this Canton 2.9.4 console function be called: dars.download(string, string) ?

I am getting this error:

@ participant.dars.download(packageId, ".") 
ERROR i.g.i.SerializingExecutor - Exception while executing runnable io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed@631eb9e7
java.lang.IllegalArgumentException: Invalid hex string: DefaultDeserializationError(message = Invalid hash algorithm: Unknown hash algorithm for index: 101)
	at com.digitalasset.canton.crypto.Hash$.$anonfun$tryFromHexString$1(Hash.scala:197)

Same package id can be used on ledger api:

$ daml ledger fetch-dar --main-package-id $packageId --host localhost --port 6865  -o x.dar
...
DAR fetch succeeded; contains 23 packages.

This package id is valid for the builtin PingPong DAR in Canton 2.9.4.

Steps to reproduce: canton -c canton-sandbox.conf --bootstrap fetch_dar.canton with:

canton-sandbox.conf

canton {
  participants {
    participant {
      admin-api.port = 6866
      ledger-api.port = 6865
    }
  }
  domains {
    mydomain {
      public-api.port = 5018
      admin-api.port = 5019
      init.domain-parameters.protocol-version = 5
    }
  }
  features.enable-testing-commands = yes
}

fetch_dar.canton

val packageId = "65921e553a353588e950cbc87e98a127730e63295f7ad8d3adae952ef0133b3e"
nodes.local.start()
participant.domains.connect_local(mydomain)
participant.dars.download(packageId, ".")
1 Like

The dars.download method has input parameters:

  • darHash: String
  • directory: String

The first parameter is darHash (which is not the same as the packageId). The following, for example,…

val dar = participant.dars.list().filter(_.name == "AdminWorkflowsWithVacuuming").head
participant.dars.download(dar.hash, ".")

…will save the AdminWorkflowsWithVacuuming.dar file. You can append the extension .zip to the file name to extract the files to view the contents. You will notice that one DAR file has lots of packages.

Managing DARs and Packages

2 Likes

In my example above, participant.dars.list() doesn’t list the mentioned package, unfortunately. I can fetch it with daml ledger fetch-dar, but not with canton script:

@ participant.dars.list() 
res0: Seq[com.digitalasset.canton.participant.admin.v0.DarDescription] = Vector(
  DarDescription(
    hash = "1220eac57ff8b70d67cb4c22751a8ad8d5af76c79df1356ff9e9e719d3a8b665db39",
    name = "AdminWorkflowsWithVacuuming"
  )
)

@  

But I need the other DAR. Note that this is the builtin PingPong package.

Interesting! Thanks, Richard, for bringing this up.

In my example above, participant.dars.list() doesn’t list the mentioned package, unfortunately.

You are right. It does not “list the mentioned package.” That call returns a list of DAR files, not packages. The package you are interested in, with package id 65921..., is in fact within the DAR file AdminWorkflowsWithVacuuming.dar.

What I learned today is that the example you gave in your original post…

$ daml ledger fetch-dar --main-package-id $packageId --host localhost --port 6865  -o x.dar
...
DAR fetch succeeded; contains 23 packages.

… creates a new DAR file named x.dar. It will contain the 65921... package and its 22 dependencies. That’s in contrast to the AdminWorkflowsWithVacuuming.dar, which is what is included by default in a 2.9.4 Canton node. The AdminWorkflowsWithVacuuming.dar contains 30+ packages, including the 23 that were exported into your new x.dar.

It feels like daml ledger fetch-dar is more like an “export a package and its dependencies” function, than it is a “download dar” function.

Am I missing anything?

1 Like

This seems to accomplish the original ask…

val src = participant.packages.find("PingPong").head

val dar = participant.dars.list().find(_.name == src.sourceDescription).head

participant.dars.download(dar.hash, ".")

…albeit, without handling the unhappy paths.

2 Likes