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

Add a Canton sandbox to the SDK #11881

Merged
merged 1 commit into from
Nov 26, 2021
Merged
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
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,35 @@ 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") "canton-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
]
]
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