From e96ce5027fbe7b70bbe8c40e163804a8d89e58db Mon Sep 17 00:00:00 2001 From: Sofia Faro Date: Mon, 17 Jan 2022 14:30:21 +0000 Subject: [PATCH] Change default sandbox to canton. Some progress on #11831 * made `daml start` use canton sandbox by default * changed the non-ledger api ports to use free ports by default (still haven't tried using port 0 instead of `getFreePort`). * renamed `daml sandbox-canton` to `daml sandbox` * implement a `--static-time` option for `daml sandbox` that sets the canton clock type parameter to `sim-clock` * moved the quickstart-java integration test to use the new sandbox * the test uses `--static-time`, but doesn't really depend on it changelog_begin changelog_end --- .../daml-helper/src/DA/Daml/Helper/Main.hs | 12 ++-- .../daml-helper/src/DA/Daml/Helper/Start.hs | 19 +++--- .../daml-helper/src/DA/Daml/Helper/Util.hs | 20 ++++-- .../src/DA/Daml/Assistant/IntegrationTests.hs | 64 +++++++++++-------- .../quickstart/template-root/daml/Main.daml | 4 +- release/RELEASE.md | 4 +- release/sdk-config.yaml.tmpl | 6 +- .../index.test.ts | 1 - 8 files changed, 72 insertions(+), 58 deletions(-) diff --git a/daml-assistant/daml-helper/src/DA/Daml/Helper/Main.hs b/daml-assistant/daml-helper/src/DA/Daml/Helper/Main.hs index 5e9f1aba6ce1..e2979d20973d 100644 --- a/daml-assistant/daml-helper/src/DA/Daml/Helper/Main.hs +++ b/daml-assistant/daml-helper/src/DA/Daml/Helper/Main.hs @@ -93,7 +93,7 @@ commandParser = subparser $ fold , command "run-jar" (info runJarCmd forwardOptions) , command "codegen" (info (codegenCmd <**> helper) forwardOptions) , command "packages" (info (packagesCmd <**> helper) packagesCmdInfo) - , command "sandbox-canton" (info (cantonSandboxCmd <**> helper) cantonSandboxCmdInfo) + , command "sandbox" (info (cantonSandboxCmd <**> helper) cantonSandboxCmdInfo) ] where @@ -166,13 +166,13 @@ commandParser = subparser $ fold sandboxChoiceOpt = flag' SandboxKV (long "sandbox-kv" <> help "Deprecated. Run with Sandbox KV.") - <|> flag' SandboxCanton (long "sandbox-canton" <> help "Run with Canton Sandbox. The 2.0 default.") + <|> (flag' SandboxCanton (long "sandbox-canton" <> help "Run with Canton Sandbox. The 2.0 default.") <|> pure SandboxCanton) <*> sandboxCantonPortSpecOpt sandboxCantonPortSpecOpt = do - adminApiSpec <- sandboxPortOpt "canton-admin-api-port" "Port number for the canton admin API (--sandbox-canton only)" - domainPublicApiSpec <- sandboxPortOpt "canton-domain-public-port" "Port number for the canton domain public API (--sandbox-canton only)" - domainAdminApiSpec <- sandboxPortOpt "canton-domain-admin-port" "Port number for the canton domain admin API (--sandbox-canton only)" + adminApiSpec <- sandboxPortOpt "sandbox-admin-api-port" "Port number for the canton admin API (--sandbox-canton only)" + domainPublicApiSpec <- sandboxPortOpt "sandbox-domain-public-port" "Port number for the canton domain public API (--sandbox-canton only)" + domainAdminApiSpec <- sandboxPortOpt "sandbox-domain-admin-port" "Port number for the canton domain admin API (--sandbox-canton only)" pure SandboxCantonPortSpec {..} navigatorPortOption = NavigatorPort <$> option auto @@ -415,7 +415,7 @@ commandParser = subparser $ fold <*> option auto (long "domain-public-port" <> value 6867) <*> option auto (long "domain-admin-port" <> value 6868) <*> optional (option str (long "port-file" <> metavar "PATH")) - ) + <*> (StaticTime <$> switch (long "static-time")) <*> many (argument str (metavar "ARG")) cantonSandboxCmdInfo = diff --git a/daml-assistant/daml-helper/src/DA/Daml/Helper/Start.hs b/daml-assistant/daml-helper/src/DA/Daml/Helper/Start.hs index 0605af81849e..2b91170dece6 100644 --- a/daml-assistant/daml-helper/src/DA/Daml/Helper/Start.hs +++ b/daml-assistant/daml-helper/src/DA/Daml/Helper/Start.hs @@ -71,19 +71,20 @@ navigatorURL (NavigatorPort p) = "http://localhost:" <> show p -- | Use SandboxPortSpec to determine a sandbox port number. -- This is racy thanks to getFreePort, but there's no good alternative at the moment. -getPortForSandbox :: Int -> Maybe SandboxPortSpec -> IO Int -getPortForSandbox defaultPort = \case - Nothing -> pure defaultPort - Just (SpecifiedPort port) -> pure (unSandboxPort port) - Just FreePort -> fromIntegral <$> getFreePort +getPortForSandbox :: SandboxPortSpec -> Maybe SandboxPortSpec -> IO Int +getPortForSandbox defaultPortSpec portSpecM = + case fromMaybe defaultPortSpec portSpecM of + SpecifiedPort port -> pure (unSandboxPort port) + FreePort -> fromIntegral <$> getFreePort determineCantonOptions :: Maybe SandboxPortSpec -> SandboxCantonPortSpec -> FilePath -> IO CantonOptions determineCantonOptions ledgerApiSpec SandboxCantonPortSpec{..} portFile = do - ledgerApi <- getPortForSandbox 6865 ledgerApiSpec - adminApi <- getPortForSandbox 6866 adminApiSpec - domainPublicApi <- getPortForSandbox 6867 domainPublicApiSpec - domainAdminApi <- getPortForSandbox 6868 domainAdminApiSpec + ledgerApi <- getPortForSandbox (SpecifiedPort (SandboxPort 6865)) ledgerApiSpec + adminApi <- getPortForSandbox FreePort adminApiSpec + domainPublicApi <- getPortForSandbox FreePort domainPublicApiSpec + domainAdminApi <- getPortForSandbox FreePort domainAdminApiSpec let portFileM = Just portFile -- TODO allow canton port file to be passed in from command line? + let staticTime = StaticTime False pure CantonOptions {..} withSandbox :: StartOptions -> FilePath -> [String] -> [String] -> (Process () () () -> SandboxPort -> IO a) -> IO a diff --git a/daml-assistant/daml-helper/src/DA/Daml/Helper/Util.hs b/daml-assistant/daml-helper/src/DA/Daml/Helper/Util.hs index 1bc3b49839d2..6d477586e50d 100644 --- a/daml-assistant/daml-helper/src/DA/Daml/Helper/Util.hs +++ b/daml-assistant/daml-helper/src/DA/Daml/Helper/Util.hs @@ -24,6 +24,7 @@ module DA.Daml.Helper.Util , waitForConnectionOnPort , waitForHttpServer , tokenFor + , StaticTime(..) , CantonOptions(..) , decodeCantonSandboxPort ) where @@ -283,19 +284,28 @@ withCantonSandbox options remainingArgs k = do BSL.writeFile config (cantonConfig options) withJar cantonJar [] ("daemon" : "-c" : config : "--auto-connect-local" : remainingArgs) k +newtype StaticTime = StaticTime Bool + data CantonOptions = CantonOptions { ledgerApi :: Int , adminApi :: Int , domainPublicApi :: Int , domainAdminApi :: Int , portFileM :: Maybe FilePath + , staticTime :: StaticTime } cantonConfig :: CantonOptions -> BSL.ByteString cantonConfig CantonOptions{..} = Aeson.encode $ Aeson.object - [ "canton" Aeson..= Aeson.object ( - [ "participants" Aeson..= Aeson.object + [ "canton" Aeson..= Aeson.object + [ "parameters" Aeson..= Aeson.object ( concat + [ [ "ports-file" Aeson..= portFile | Just portFile <- [portFileM] ] + , [ "clock" Aeson..= Aeson.object + [ "type" Aeson..= ("sim-clock" :: T.Text) ] + | StaticTime True <- [] ] + ] ) + , "participants" Aeson..= Aeson.object [ "sandbox" Aeson..= Aeson.object [ storage , "admin-api" Aeson..= port adminApi @@ -309,11 +319,7 @@ cantonConfig CantonOptions{..} = , "admin-api" Aeson..= port domainAdminApi ] ] - ] ++ - [ "parameters" Aeson..= Aeson.object - [ "ports-file" Aeson..= portFile ] - | Just portFile <- [portFileM] - ] ) + ] ] where port p = Aeson.object [ "port" Aeson..= p ] diff --git a/daml-assistant/integration-tests/src/DA/Daml/Assistant/IntegrationTests.hs b/daml-assistant/integration-tests/src/DA/Daml/Assistant/IntegrationTests.hs index 991c0e28ef84..0fc90cced3e2 100644 --- a/daml-assistant/integration-tests/src/DA/Daml/Assistant/IntegrationTests.hs +++ b/daml-assistant/integration-tests/src/DA/Daml/Assistant/IntegrationTests.hs @@ -11,6 +11,7 @@ import Control.Monad.Loops (untilM_) import qualified Data.Aeson as Aeson import Data.Aeson.Lens import qualified Data.ByteString.Lazy as LBS +import qualified Data.ByteString.Lazy.Char8 as LBS8 import qualified Data.Conduit.Tar.Extra as Tar.Conduit.Extra import Data.List.Extra import Data.String (fromString) @@ -137,20 +138,12 @@ damlStart tmpDir withCantonSandbox = do jsonApiPort <- getFreePort env <- subprocessEnv [] let startProc = - (shell $ unwords $ concat - [ [ "daml start" ] - , if withCantonSandbox then - [ "--sandbox-canton" - , "--canton-admin-api-port=0" - , "--canton-domain-public-port=0" - , "--canton-domain-admin-port=0" - ] - else - [ "--sandbox-kv"] - , [ "--start-navigator=no" - , "--sandbox-port", show sandboxPort - , "--json-api-port", show jsonApiPort - ] + (shell $ unwords + [ "daml start" + , if withCantonSandbox then "--sandbox-canton" else "--sandbox-kv" + , "--start-navigator=no" + , "--sandbox-port", show sandboxPort + , "--json-api-port", show jsonApiPort ] ) {std_in = CreatePipe, std_out = CreatePipe, cwd = Just projDir, create_group = True, env = Just env} (Just startStdin, Just startStdout, _, startPh) <- createProcess startProc @@ -192,27 +185,38 @@ quickSandbox projDir = do callCommandSilent $ unwords ["daml", "new", projDir, "--template=quickstart-java"] callCommandSilentIn projDir "daml build" sandboxPort <- getFreePort + adminApiPort <- getFreePort + domainPublicApiPort <- getFreePort + domainAdminApiPort <- getFreePort + let portFile = "portfile.json" + let darFile = ".daml" "dist" "quickstart-0.0.1.dar" let sandboxProc = (shell $ unwords [ "daml" - , "sandbox-kv" - , "--" - , "--port" - , show sandboxPort - , "--" + , "sandbox" + , "--port" , show sandboxPort + , "--admin-api-port", show adminApiPort + , "--domain-public-port", show domainPublicApiPort + , "--domain-admin-port", show domainAdminApiPort + , "--port-file", portFile , "--static-time" - , ".daml/dist/quickstart-0.0.1.dar" ]) {std_out = UseHandle devNull, create_group = True, cwd = Just projDir} (_, _, _, sandboxPh) <- createProcess sandboxProc - waitForConnectionOnPort 240 sandboxPh (threadDelay 500000) $ fromIntegral sandboxPort + _ <- readPortFileWith decodeCantonSandboxPort sandboxPh maxRetries (projDir portFile) + callCommandSilentIn projDir $ unwords + [ "daml ledger upload-dar" + , "--host=localhost" + , "--port=" <> show sandboxPort + , darFile + ] pure $ QuickSandboxResource { quickProjDir = projDir , quickSandboxPort = sandboxPort , quickSandboxPh = sandboxPh - , quickDar = projDir ".daml" "dist" "quickstart-0.0.1.dar" + , quickDar = projDir darFile } tests :: FilePath -> TestTree @@ -534,9 +538,6 @@ damlStartNotSharedTest = testCase "daml start --sandbox-port=0" $ , "--sandbox-port=0" , "--json-api-port=0" , "--json-api-option=--port-file=jsonapi.port" - , "--canton-admin-api-port=0" - , "--canton-domain-public-port=0" - , "--canton-domain-admin-port=0" ] $ \ ph -> do jsonApiPort <- readPortFile ph maxRetries (tmpDir "jsonapi.port") initialRequest <- @@ -671,13 +672,17 @@ quickstartTests quickstartDir mvnDir getSandbox = , "--ledger-host localhost" , "--ledger-port" , show quickSandboxPort + , "--output-file", "output.json" ] + scriptOutput <- readFileUTF8 (quickProjDir "output.json") + [alice, eurBank] <- pure (read scriptOutput :: [String]) restPort :: Int <- fromIntegral <$> getFreePort let mavenProc = (shell $ unwords [ "mvn" , mvnRepoFlag , "-Dledgerport=" <> show quickSandboxPort , "-Drestport=" <> show restPort + , "-Dparty=" <> alice , "exec:java@run-quickstart" ]) { std_out = UseHandle devNull @@ -691,8 +696,11 @@ quickstartTests quickstartDir mvnDir getSandbox = req <- pure req {requestHeaders = [(hContentType, "application/json")]} resp <- httpLbs req manager + statusCode (responseStatus resp) @?= 200 responseBody resp @?= - "{\"0\":{\"issuer\":\"EUR_Bank\",\"owner\":\"Alice\",\"currency\":\"EUR\",\"amount\":100.0000000000,\"observers\":[]}}" + "{\"0\":{\"issuer\":" <> LBS8.pack (show eurBank) + <> ",\"owner\":"<> LBS8.pack (show alice) + <> ",\"currency\":\"EUR\",\"amount\":100.0000000000,\"observers\":[]}}" -- Note (MK) You might be tempted to suggest using -- create_group and interruptProcessGroupOf -- or alternatively use_process_jobs here. @@ -802,7 +810,7 @@ codegenTests codegenDir = testGroup "daml codegen" ( assertBool "bindings were written" (not $ null contents) cantonTests :: TestTree -cantonTests = testGroup "daml sandbox-canton" +cantonTests = testGroup "daml sandbox" [ testCaseSteps "Can start Canton sandbox and run script" $ \step -> withTempDir $ \dir -> do step "Creating project" callCommandSilentIn dir $ unwords ["daml new", "skeleton", "--template=skeleton"] @@ -815,7 +823,7 @@ cantonTests = testGroup "daml sandbox-canton" domainAdminApiPort <- getFreePort step "Staring Canton sandbox" let portFile = dir "canton-portfile.json" - withDamlServiceIn (dir "skeleton") "sandbox-canton" + withDamlServiceIn (dir "skeleton") "sandbox" [ "--port", show ledgerApiPort , "--admin-api-port", show adminApiPort , "--domain-public-port", show domainPublicApiPort diff --git a/docs/source/app-dev/bindings-java/quickstart/template-root/daml/Main.daml b/docs/source/app-dev/bindings-java/quickstart/template-root/daml/Main.daml index e89f2ee90957..3191963e0754 100644 --- a/docs/source/app-dev/bindings-java/quickstart/template-root/daml/Main.daml +++ b/docs/source/app-dev/bindings-java/quickstart/template-root/daml/Main.daml @@ -8,7 +8,7 @@ import Daml.Script import Iou import IouTrade() -initialize : Script () +initialize : Script [Party] initialize = do -- allocate parties alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice") @@ -43,4 +43,4 @@ initialize = do submit alice do exerciseCmd iouTransferAliceCid IouTransfer_Accept submit bob do exerciseCmd iouTransferBobCid IouTransfer_Accept - pure () + pure [alice, eurBank] diff --git a/release/RELEASE.md b/release/RELEASE.md index e84f6f907ac9..0dab7361fbf3 100644 --- a/release/RELEASE.md +++ b/release/RELEASE.md @@ -130,7 +130,7 @@ patches we backport to the 1.0 release branch). 1. `cd create-daml-app` - 1. `daml start --sandbox-kv` + 1. `daml start` 1. In a new terminal, from the `ui` folder: @@ -235,7 +235,7 @@ patches we backport to the 1.0 release branch). 1. Verify the new version is specified in `daml.yaml` as the `sdk-version`. - 1. Run `daml start --sandbox-kv`. Your browser should be opened automatically at + 1. Run `daml start`. Your browser should be opened automatically at `http://localhost:7500`. Login as `Alice` and verify that there is 1 contract and 3 templates. Close the tab and kill `daml start` using `Ctrl-C`. diff --git a/release/sdk-config.yaml.tmpl b/release/sdk-config.yaml.tmpl index 46542b0b7b9d..029ec9df99d1 100644 --- a/release/sdk-config.yaml.tmpl +++ b/release/sdk-config.yaml.tmpl @@ -44,10 +44,10 @@ commands: path: damlc/damlc desc: "Run the Daml compiler" completion: true -- name: sandbox-canton +- name: sandbox path: daml-helper/daml-helper - desc: "Launch Sandbox Canton." - args: ["sandbox-canton"] + desc: "Launch Canton Sandbox" + args: ["sandbox"] - name: sandbox-kv path: daml-helper/daml-helper desc: "Deprecated. Launch Sandbox KV (the default Sandbox implementation for SDK < 2.0.0)" diff --git a/templates/create-daml-app-test-resources/index.test.ts b/templates/create-daml-app-test-resources/index.test.ts index 09bf92e09240..e4f317b67440 100644 --- a/templates/create-daml-app-test-resources/index.test.ts +++ b/templates/create-daml-app-test-resources/index.test.ts @@ -95,7 +95,6 @@ beforeAll(async () => { // Getting Started Guide. const startArgs = [ 'start', - '--sandbox-kv', `--json-api-option=--port-file=${JSON_API_PORT_FILE_NAME}`, ];