Skip to content

Commit

Permalink
Add a Canton sandbox to the SDK
Browse files Browse the repository at this point in the history
This is only the first step so we have something to use in tests,
eventually `daml sandbox` should map to this Sandbox.

part of #11831

changelog_begin
changelog_end
  • Loading branch information
cocreature committed Nov 25, 2021
1 parent 6356f13 commit a4a639d
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
18 changes: 18 additions & 0 deletions daml-assistant/daml-helper/src/DA/Daml/Helper/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ data Command
| LedgerNavigator { flags :: LedgerFlags, remainingArguments :: [String] }
| Codegen { lang :: Lang, remainingArguments :: [String] }
| PackagesList {flags :: LedgerFlags}
| CantonSandbox
{ ports :: CantonPorts
, remainingArguments :: [String]
}

data AppTemplate
= AppTemplateDefault
Expand All @@ -106,6 +110,7 @@ commandParser = subparser $ fold
, command "run-platform-jar" (info runPlatformJarCmd forwardOptions)
, command "codegen" (info (codegenCmd <**> helper) forwardOptions)
, command "packages" (info (packagesCmd <**> helper) packagesCmdInfo)
, command "canton-sandbox" (info (cantonSandboxCmd <**> helper) cantonSandboxCmdInfo)
]
where

Expand Down Expand Up @@ -428,6 +433,18 @@ commandParser = subparser $ fold
, help "Timeout of gRPC operations in seconds. Defaults to 60s. Must be > 0."
]

cantonSandboxCmd = CantonSandbox
<$> (CantonPorts
<$> option auto (long "port" <> value 6865)
<*> option auto (long "admin-api-port" <> value 6866)
<*> option auto (long "domain-public-port" <> value 6867)
<*> option auto (long "domain-admin-port" <> value 6868)
)
<*> many (argument str (metavar "ARG"))

cantonSandboxCmdInfo =
forwardOptions

runCommand :: Command -> IO ()
runCommand = \case
DamlStudio {..} -> runDamlStudio replaceExtension remainingArguments
Expand Down Expand Up @@ -481,3 +498,4 @@ runCommand = \case
LedgerExport {..} -> runLedgerExport flags remainingArguments
LedgerNavigator {..} -> runLedgerNavigator flags remainingArguments
Codegen {..} -> runCodegen lang remainingArguments
CantonSandbox {..} -> runCantonSandbox ports remainingArguments
50 changes: 50 additions & 0 deletions daml-assistant/daml-helper/src/DA/Daml/Helper/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,30 @@ module DA.Daml.Helper.Util
, damlSdkJarFolder
, withJar
, runJar
, runCantonSandbox
, getLogbackArg
, waitForConnectionOnPort
, waitForHttpServer
, tokenFor
, CantonPorts(..)
) where

import Control.Exception.Safe
import Control.Monad.Extra
import Control.Monad.Loops (untilJust)
import qualified Data.Aeson as Aeson
import qualified Data.ByteString.Lazy as BSL
import Data.Foldable
import Data.Maybe
import qualified Data.Text as T
import qualified Data.Text.Extended as T
import qualified Network.HTTP.Simple as HTTP
import qualified Network.HTTP.Types as HTTP
import Network.Socket
import System.Directory
import System.FilePath
import System.IO
import System.IO.Extra (withTempFile)
import System.Info.Extra
import System.Process (showCommandForUser, terminateProcess)
import System.Process.Typed
Expand Down Expand Up @@ -238,3 +244,47 @@ tokenFor parties ledgerId applicationId =
])
]
}

runCantonSandbox :: CantonPorts -> [String] -> IO ()
runCantonSandbox ports remainingArgs = do
sdkPath <- getSdkPath
let cantonJar = sdkPath </> "canton" </> "canton.jar"
withTempFile $ \config ->
withTempFile $ \bootstrap -> do
BSL.writeFile config (cantonConfig ports)
T.writeFileUtf8 bootstrap $ T.unlines
[ "sandbox.domains.connect_local(local)"
, "println(\"Canton sandbox started\")"
]
runJar cantonJar Nothing ("daemon" : "-c" : config : "--bootstrap" : bootstrap : remainingArgs)

data CantonPorts = CantonPorts
{ ledgerApi :: Int
, adminApi :: Int
, domainPublicApi :: Int
, domainAdminApi :: Int
}

cantonConfig :: CantonPorts -> BSL.ByteString
cantonConfig CantonPorts{..} =
Aeson.encode $ Aeson.object
[ "canton" Aeson..= Aeson.object
[ "participants" Aeson..= Aeson.object
[ "sandbox" Aeson..= Aeson.object
[ storage
, "admin-api" Aeson..= port adminApi
, "ledger-api" Aeson..= port ledgerApi
]
]
, "domains" Aeson..= Aeson.object
[ "local" Aeson..= Aeson.object
[ storage
, "public-api" Aeson..= port domainPublicApi
, "admin-api" Aeson..= port domainAdminApi
]
]
]
]
where
port p = Aeson.object [ "port" Aeson..= p ]
storage = "storage" Aeson..= Aeson.object [ "type" Aeson..= ("memory" :: T.Text) ]
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ tests tmpDir =
, cleanTests cleanDir
, templateTests
, codegenTests codegenDir
, cantonTests
]
where
quickstartDir = tmpDir </> "q-u-i-c-k-s-t-a-r-t"
Expand Down Expand Up @@ -810,3 +811,36 @@ codegenTests codegenDir = testGroup "daml codegen" (
, "-o", outDir]
contents <- listDirectory (projectDir </> outDir)
assertBool "bindings were written" (not $ null contents)

cantonTests :: TestTree
cantonTests = testGroup "daml canton-sandbox"
[ testCaseSteps "Can start Canton sandbox and run script" $ \step -> withTempDir $ \dir -> do
step "Creating project"
callCommandSilentIn dir $ unwords ["daml new", "skeleton", "--template=skeleton"]
step "Building project"
callCommandSilentIn (dir </> "skeleton") "daml build"
step "Finding free ports"
ledgerApiPort <- getFreePort
adminApiPort <- getFreePort
domainPublicApiPort <- getFreePort
domainAdminApiPort <- getFreePort
step "Staring Canton sandbox"
withDamlServiceIn (dir </> "skeleton") "sandbox"
[ "--port", show ledgerApiPort
, "--admin-api-port", show adminApiPort
, "--domain-public-port", show domainPublicApiPort
, "--domain-admin-port", show domainAdminApiPort
] $ do
waitForConnectionOnPort (threadDelay 500000) (fromIntegral ledgerApiPort)
step "Uploading DAR"
callCommandSilentIn (dir </> "skeleton") $ unwords
["daml ledger upload-dar --host=localhost --port=" <> show ledgerApiPort, ".daml/dist/skeleton-0.0.1.dar"]
step "Running script"
callCommandSilentIn (dir </> "skeleton") $ unwords
[ "daml script"
, "--dar", ".daml/dist/skeleton-0.0.1.dar"
, "--script-name Main:setup"
, "--ledger-host=localhost", "--ledger-port=" <> show ledgerApiPort
]
pure ()
]
3 changes: 3 additions & 0 deletions release/sdk-config.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,6 @@ commands:
path: damlc/damlc
args: ["repl"]
desc: "Launch the Daml REPL"
- name: canton-sandbox
path: daml-helper/daml-helper
args: ["canton-sandbox"]
4 changes: 4 additions & 0 deletions release/util.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ inputs = {
"templates": "//templates:templates-tarball.tar.gz",
"trigger_dars": "//triggers/daml:daml-trigger-dars",
"script_dars": "//daml-script/daml:daml-script-dars",
"canton": "@canton//:lib",
"sdk_deploy_jar": {
"ce": "//daml-assistant/daml-sdk:sdk_deploy.jar",
"ee": "//daml-assistant/daml-sdk:sdk_ee_deploy.jar",
Expand Down Expand Up @@ -82,6 +83,9 @@ def sdk_tarball(name, version, config):
mkdir -p $$OUT/studio
cp $(location {daml_extension}) $$OUT/studio/daml-bundled.vsix
mkdir -p $$OUT/canton
cp $(location {canton}) $$OUT/canton/canton.jar
mkdir -p $$OUT/templates
tar xf $(location {templates}) --strip-components=1 -C $$OUT/templates
Expand Down

0 comments on commit a4a639d

Please sign in to comment.