Error when running PingPong Example in daml-net

Hi, I’m attempting to run the PingPong example included in daml-net but getting the following error. Any suggestions appreciated:

$ dotnet run grpc localhost 6865
Alice starts reading transactions.
Bob starts reading transactions.
Alice is exercising RespondPong on 003e9f89fd2ab5b2158c6f304611839f5772546d6ce2781d008eb5cb48317d3c8d in workflow Ping-Bob-3 at count 0
Alice encountered an RpcException while processing transactions! Status(StatusCode=“InvalidArgument”, Detail=“Command interpretation error in LF-DAMLe: dependency error: couldn’t find contract ContractId(003e9f89fd2ab5b2158c6f304611839f5772546d6ce2781d008eb5cb48317d3c8d). Details: N/A.”, DebugException=“Grpc.Core.Internal.CoreErrorDetailException: {“created”:”@1629972219.556583935",“description”:“Error received from peer ipv4:127.0.0.1:6865”,“file”:"/var/local/git/grpc/src/core/lib/surface/call.cc",“file_line”:1068,“grpc_message”:“Command interpretation error in LF-DAMLe: dependency error: couldn’t find contract ContractId(003e9f89fd2ab5b2158c6f304611839f5772546d6ce2781d008eb5cb48317d3c8d). Details: N/A.”,“grpc_status”:3}")

Thanks!

Just noticed that it seems to run first time after a “daml start” then fails on subsequent runs.

Can you share with us your dotnet project configuration?

Sure:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <Configuration>Release</Configuration>
    <LangVersion>9.0</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'ReleaseNuget' ">
    <DebugType></DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\ReleaseNuget</OutputPath>
    <DefineConstants></DefineConstants>
    <WarningLevel>4</WarningLevel>
    <IntermediateOutputPath>obj\ReleaseNuget</IntermediateOutputPath>
    <NoWarn></NoWarn>
    <NoStdLib>false</NoStdLib>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Grpc.Core" Version="2.35.0" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include=".daml\dist\" />
    <Folder Include=".daml\interfaces\daml\" />
    <Folder Include="Properties\" />
  </ItemGroup>
  <Choose>
    <When Condition="'$(Configuration)' == 'ReleaseNuget'">
      <ItemGroup>
        <PackageReference Include="Daml.Ledger.Client" Version="$(Version)" />
        <PackageReference Include="Daml.Ledger.Fragment" Version="$(Version)" />
        <ProjectReference Include="..\Daml.Ledger.Client\Daml.Ledger.Client.csproj" ReferenceOutputAssembly="false" SkipGetTargetFrameworkProperties="true" />
        <ProjectReference Include="..\Daml.Ledger.Fragment\Daml.Ledger.Fragment.csproj" ReferenceOutputAssembly="false" SkipGetTargetFrameworkProperties="true" />
      </ItemGroup>
    </When>
    <Otherwise>
      <ItemGroup>
        <ProjectReference Include="..\Daml.Ledger.Client\Daml.Ledger.Client.csproj" />
        <ProjectReference Include="..\Daml.Ledger.Fragment\Daml.Ledger.Fragment.csproj" />
      </ItemGroup>
    </Otherwise>
  </Choose>
</Project>

I’ve been looking into it in a bit more detail and it seems that on subsequent runs it is trying to look up the contractID of a contract that was created and archived in the first run. But there is something else going on as well (or possibly a related issue) as even first runs don’t complete successfully:

$ dotnet run grpc localhost 6865 1
Alice starts reading transactions.
Bob starts reading transactions.
Bob is exercising RespondPong on 003c156c634ac3d2c274a6fe569f5828ec157a83be74ef8c574e50cef0dfc20264 in workflow Ping-Alice-0 at count 0
Alice is exercising RespondPong on 00f9d9ffecc81528828554babb1b4f91671601f28bfddcff130f5d03806ef77fa5 in workflow Ping-Bob-0 at count 0
Alice is exercising RespondPing on 004833bb3297fa7ae753ec0bd4d42e72b25d23bb73e8674b02adb2fe0a100dfc3b in workflow Ping-Alice-0 at count 1
Bob is exercising RespondPing on 00d79c7012fa3d30226439f78d18d703b48840081b511061d3bcfaad01a2749527 in workflow Ping-Bob-0 at count 1
Bob is exercising RespondPong on 0064e9adf90759b892e9d10d65673716ff1c6211af2b1a3ce22c1982ee11c03326 in workflow Ping-Alice-0 at count 2
Alice is exercising RespondPong on 0019d7940c13208a8a2e984f5ae05c338f8291590fcc3683a0aaa5dc26b3cafe3d in workflow Ping-Bob-0 at count 2
Alice is exercising RespondPing on 00270b30b07d1680c5d9bf40d18be03ac9622abed3f9292fb7e3805f9860860344 in workflow Ping-Alice-0 at count 3
Bob is exercising RespondPing on 0092fa918c08b5607c080371303e5fa729b4902ac2bf086240e9fd3bf1b046eef1 in workflow Ping-Bob-0 at count 3
Bob is exercising RespondPong on 00d8b0567c205eda8025bc61611f04a7844873d7e6d3200f486930597aff5e07f2 in workflow Ping-Alice-0 at count 4
Alice is exercising RespondPong on 007a14f64936efa5dfebcf9e281630389b5f499fb00e4835ce8393548b0c036ec0 in workflow Ping-Bob-0 at count 4
Alice is exercising RespondPing on 0048c3bc59709db034dc2b7ad1ac60c31546f5f16cd53f9228c45d00a95ca6752f in workflow Ping-Alice-0 at count 5
Bob is exercising RespondPing on 00f0f6cbd0c16ac8ed7782088c20f08ad20d41b533acdf0ccf5a535a3ce7984fdd in workflow Ping-Bob-0 at count 5
Bob is exercising RespondPong on 002178e463178974c9569428ebd8c341a03513fc5e2d3933073c530fe048bd1466 in workflow Ping-Alice-0 at count 6
Bob encountered an error while processing transactions! Shutdown has already been called

Thanks!

Same problem in the Java version, works on first run and then fails as cannot find the (archived) contract. Is the right approach to filter out archived transactions on GetTransactionsRequest? If so how should I do this?

The example is not intended to handle subsequent runs, it’s simply a demonstration on how to setup on-the-fly processing of the transaction stream.

So for your first error what happens is that you get back the full transaction list from the beginning of the ledger and the existing filtering for creation events in ProcessTransaction takes the first (created) event and tries to exercise a respond choice on it, in both processes. Since those were exercised in the first run they are already archived and the choices cannot be exercised on them anymore. A fix is to query the transactions from the offset that the ledger is at when the request is built. To achieve this easily change LedgerBegin to LedgerEnd in PingPongProcessor.cs (around line 42):

GetTransactionsRequest transactionsRequest = new GetTransactionsRequest { LedgerId = _ledgerId,
                                                                          Begin = new LedgerOffset { Boundary = LedgerOffset.Types.LedgerBoundary.LedgerEnd },
                                                                          Filter = filter,
                                                                          Verbose = true };

As for an error occurring on first runs, I just could not reproduce the issue. It would be nice to see the logs sandbox provides when that happens.

Thank you, that makes sense.

I think the second issue may just be due to the sandbox on my VM getting overloaded. I’ll scale back number and speed of contract creations and see if that fixes it.

What kind of VM are you using? Are you running the sandbox in the VM and the example client on the host?

I’ve a VirtualBox VM running Ubuntu on a Win10 host. Everything is running on the VM. I’ve just tried reducing the max count in the DAML to 3, the number of initial contracts to 4 and adding a Thread.Sleep(1000) to the end of CreateInitialContracts in PingPongGrpcMain (about line 127). Everything now works fine. Thanks!

2 Likes