mirror of
https://github.com/digital-asset/daml.git
synced 2024-11-10 00:35:25 +03:00
sandbox: Fail to start if a time mode is not explicitly specified. (#5033)
* sandbox: Fail to start if a time mode is not explicitly specified. CHANGELOG_BEGIN - [Sandbox] Sandbox is switching from Static Time mode to Wall Clock Time mode as the default. To ensure that our users know about this, for one version, there will be no default time mode. Instead, users will have to explicitly select their preferred time mode by means of the `--static-time` or `--wall-clock-time` switches. In the next release, Wall Clock Time will become the default, and users who are happy with the defaults will no longer need to specify the time mode. CHANGELOG_END * daml-script|triggers: Specify time mode when testing against Sandbox. * daml-assistant: Default the Sandbox to wall clock time. CHANGELOG_BEGIN - [DAML Assistant] Initializing a new DAML project adds a switch to ``daml.yaml`` to ensure Sandbox can continue to start with ``daml start``:: sandbox-options: - --wall-clock-time CHANGELOG_END * docs: Update the DAML Script and Triggers docs to use Wall Clock time. It's now what Sandbox will use by default when using `daml init`. * docs: Change the Quickstart to run Sandbox in wall clock time. This explains why the contract IDs may vary. It also updates the manual release testing script to match.
This commit is contained in:
parent
cf032a02cf
commit
cbeeb5aafc
@ -484,6 +484,7 @@ runInit targetFolderM = do
|
||||
, ("version", Y.String "1.0.0")
|
||||
, ("exposed-modules", Y.array [Y.String "Main"])
|
||||
, ("dependencies", Y.array [Y.String "daml-prim", Y.String "daml-stdlib"])
|
||||
, ("sandbox-options", Y.array [Y.String "--wall-clock-time"])
|
||||
]
|
||||
|
||||
putStrLn ("Done! Please verify " <> projectConfigRel)
|
||||
|
@ -202,6 +202,8 @@ packagingTests = testGroup "packaging"
|
||||
, "parties:"
|
||||
, "- Alice"
|
||||
, "init-script: Main:init"
|
||||
, "sandbox-options:"
|
||||
, " - --wall-clock-time"
|
||||
]
|
||||
writeFileUTF8 (projDir </> "daml/Main.daml") $ unlines
|
||||
[ "daml 1.2"
|
||||
@ -329,7 +331,7 @@ quickstartTests quickstartDir mvnDir = testGroup "quickstart"
|
||||
withCurrentDirectory quickstartDir $
|
||||
withDevNull $ \devNull -> do
|
||||
p :: Int <- fromIntegral <$> getFreePort
|
||||
let sandboxProc = (shell $ unwords ["daml", "sandbox", "--port", show p, ".daml/dist/quickstart-0.0.1.dar"]) { std_out = UseHandle devNull, std_in = CreatePipe }
|
||||
let sandboxProc = (shell $ unwords ["daml", "sandbox", "--wall-clock-time", "--port", show p, ".daml/dist/quickstart-0.0.1.dar"]) { std_out = UseHandle devNull, std_in = CreatePipe }
|
||||
withCreateProcess sandboxProc $
|
||||
\_ _ _ ph -> race_ (waitForProcess' sandboxProc ph) $ do
|
||||
waitForConnectionOnPort (threadDelay 100000) p
|
||||
@ -351,7 +353,7 @@ quickstartTests quickstartDir mvnDir = testGroup "quickstart"
|
||||
withDevNull $ \devNull1 -> do
|
||||
withDevNull $ \devNull2 -> do
|
||||
sandboxPort :: Int <- fromIntegral <$> getFreePort
|
||||
let sandboxProc = (shell $ unwords ["daml", "sandbox", "--port", show sandboxPort, ".daml/dist/quickstart-0.0.1.dar"]) { std_out = UseHandle devNull1, std_in = CreatePipe }
|
||||
let sandboxProc = (shell $ unwords ["daml", "sandbox", "--wall-clock-time", "--port", show sandboxPort, ".daml/dist/quickstart-0.0.1.dar"]) { std_out = UseHandle devNull1, std_in = CreatePipe }
|
||||
withCreateProcess sandboxProc $ \_ _ _ sandboxPh -> race_ (waitForProcess' sandboxProc sandboxPh) $ do
|
||||
waitForConnectionOnPort (threadDelay 100000) sandboxPort
|
||||
navigatorPort :: Int <- fromIntegral <$> getFreePort
|
||||
@ -367,7 +369,7 @@ quickstartTests quickstartDir mvnDir = testGroup "quickstart"
|
||||
withDevNull $ \devNull1 -> do
|
||||
withDevNull $ \devNull2 -> do
|
||||
sandboxPort :: Int <- fromIntegral <$> getFreePort
|
||||
let sandboxProc = (shell $ unwords ["daml", "sandbox", "--port", show sandboxPort, ".daml/dist/quickstart-0.0.1.dar"]) { std_out = UseHandle devNull1, std_in = CreatePipe }
|
||||
let sandboxProc = (shell $ unwords ["daml", "sandbox", "--wall-clock-time", "--port", show sandboxPort, ".daml/dist/quickstart-0.0.1.dar"]) { std_out = UseHandle devNull1, std_in = CreatePipe }
|
||||
withCreateProcess sandboxProc $ \_ _ _ sandboxPh -> race_ (waitForProcess' sandboxProc sandboxPh) $ do
|
||||
waitForConnectionOnPort (threadDelay 100000) sandboxPort
|
||||
jsonApiPort :: Int <- fromIntegral <$> getFreePort
|
||||
@ -398,7 +400,7 @@ quickstartTests quickstartDir mvnDir = testGroup "quickstart"
|
||||
withDevNull $ \devNull1 ->
|
||||
withDevNull $ \devNull2 -> do
|
||||
sandboxPort :: Int <- fromIntegral <$> getFreePort
|
||||
let sandboxProc = (shell $ unwords ["daml", "sandbox", "--", "--port", show sandboxPort, "--", "--scenario", "Main:setup", ".daml/dist/quickstart-0.0.1.dar"]) { std_out = UseHandle devNull1, std_in = CreatePipe }
|
||||
let sandboxProc = (shell $ unwords ["daml", "sandbox", "--", "--port", show sandboxPort, "--", "--static-time", "--scenario", "Main:setup", ".daml/dist/quickstart-0.0.1.dar"]) { std_out = UseHandle devNull1, std_in = CreatePipe }
|
||||
withCreateProcess sandboxProc $
|
||||
\_ _ _ ph -> race_ (waitForProcess' sandboxProc ph) $ do
|
||||
waitForConnectionOnPort (threadDelay 500000) sandboxPort
|
||||
@ -492,7 +494,9 @@ deployTest deployDir = testCase "daml deploy" $ do
|
||||
let sharedSecret = "TheSharedSecret"
|
||||
let sandboxProc =
|
||||
(shell $ unwords
|
||||
["daml sandbox"
|
||||
["daml"
|
||||
, "sandbox"
|
||||
, "--wall-clock-time"
|
||||
, "--auth-jwt-hs256-unsafe=" <> sharedSecret
|
||||
, "--port", show port
|
||||
, ".daml/dist/proj1-0.0.1.dar"
|
||||
|
@ -89,7 +89,10 @@ client_server_test(
|
||||
client_files = ["$(rootpath :script-test.dar)"],
|
||||
data = [":script-test.dar"],
|
||||
server = "//ledger/sandbox:sandbox-binary",
|
||||
server_args = ["--port=0"],
|
||||
server_args = [
|
||||
"--static-time",
|
||||
"--port=0",
|
||||
],
|
||||
server_files = ["$(rootpath :script-test.dar)"],
|
||||
)
|
||||
|
||||
@ -101,7 +104,7 @@ client_server_test(
|
||||
data = [":script-test.dar"],
|
||||
server = "//ledger/sandbox:sandbox-binary",
|
||||
server_args = [
|
||||
"-w",
|
||||
"--wall-clock-time",
|
||||
"--port=0",
|
||||
],
|
||||
server_files = ["$(rootpath :script-test.dar)"],
|
||||
@ -140,7 +143,7 @@ client_server_test(
|
||||
],
|
||||
server = "//ledger/sandbox:sandbox-binary",
|
||||
server_args = [
|
||||
"-w",
|
||||
"--wall-clock-time",
|
||||
"--port=0",
|
||||
"--auth-jwt-hs256-unsafe={}".format(AUTH_TOKEN),
|
||||
],
|
||||
@ -165,7 +168,7 @@ client_server_test(
|
||||
],
|
||||
server = "//ledger/sandbox:sandbox-binary",
|
||||
server_args = [
|
||||
"-w",
|
||||
"--wall-clock-time",
|
||||
"--port=0",
|
||||
"--crt $(rlocation $TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:server.crt))",
|
||||
"--pem $(rlocation $TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:server.pem))",
|
||||
|
@ -176,7 +176,7 @@ To run our script, we first build it with ``daml build`` and then run
|
||||
it by pointing to the DAR, the name of our script, the host and
|
||||
port our ledger is running on and the time mode of the ledger.
|
||||
|
||||
``daml script --dar .daml/dist/script-example-0.0.1.dar --script-name ScriptExample:test --ledger-host localhost --ledger-port 6865 --static-time``
|
||||
``daml script --dar .daml/dist/script-example-0.0.1.dar --script-name ScriptExample:test --ledger-host localhost --ledger-port 6865 --wall-clock-time``
|
||||
|
||||
Up to now, we have worked with parties that we have allocated in the
|
||||
test. We can also pass in the path to a file containing
|
||||
@ -187,7 +187,7 @@ the input in the :doc:`/json-api/lf-value-specification`.
|
||||
|
||||
We can then initialize our ledger passing in the json file via ``--input-file``.
|
||||
|
||||
``daml script --dar .daml/dist/script-example-0.0.1.dar --script-name ScriptExample:initialize --ledger-host localhost --ledger-port 6865 --input-file ledger-parties.json --static-time``
|
||||
``daml script --dar .daml/dist/script-example-0.0.1.dar --script-name ScriptExample:initialize --ledger-host localhost --ledger-port 6865 --input-file ledger-parties.json --wall-clock-time``
|
||||
|
||||
If you open Navigator, you can now see the contracts that have been created.
|
||||
|
||||
|
@ -12,3 +12,5 @@ dependencies:
|
||||
- daml-stdlib
|
||||
- daml-script
|
||||
# script-dependencies-end
|
||||
sandbox-options:
|
||||
- --wall-clock-time
|
||||
|
@ -5,3 +5,5 @@ version: 1.0.0
|
||||
dependencies:
|
||||
- daml-prim
|
||||
- daml-stdlib
|
||||
sandbox-options:
|
||||
- --wall-clock-time
|
||||
|
@ -125,7 +125,7 @@ In this section, you will run the quickstart application and get introduced to t
|
||||
|
||||
.. _quickstart-sandbox:
|
||||
|
||||
#. To run the :doc:`sandbox </tools/sandbox>` (a lightweight local version of the ledger), run ``daml sandbox .daml/dist/quickstart-0.0.1.dar``
|
||||
#. To run the :doc:`sandbox </tools/sandbox>` (a lightweight local version of the ledger), run ``daml sandbox --wall-clock-time .daml/dist/quickstart-0.0.1.dar``
|
||||
|
||||
The output should look like this:
|
||||
|
||||
@ -173,6 +173,8 @@ Now everything is running, you can try out the quickstart application:
|
||||
|
||||
This is showing you what contracts are currently active on the sandbox ledger and visible to *Alice*. You can see that there is a single such contract, with Id ``#9:1``, created from a *template* called ``Iou:Iou@ffb...``.
|
||||
|
||||
Your contract ID may vary. There's a lot going on in a DAML ledger, so things could have happened in a different order, or other internal ledger events might have occurred. The actual value doesn't matter. We'll refer to this contract as ``#9:1`` in the rest of this document, and you'll need to substitute your own value mentally.
|
||||
|
||||
#. On the left-hand side, you can see what the pages the Navigator contains:
|
||||
|
||||
- Contracts
|
||||
@ -210,7 +212,7 @@ Now everything is running, you can try out the quickstart application:
|
||||
|
||||
Go back to *Owned Ious*, open the Iou for €100 and click on the button *Iou_AddObserver*. Submit *Bob* as the *newObserver*.
|
||||
|
||||
Contracts in DAML are immutable, meaning they cannot be changed, only created and archived. If you head back to the **Owned Ious** screen, you can see that the Iou now has a new Contract ID `#13:1`.
|
||||
Contracts in DAML are immutable, meaning they cannot be changed, only created and archived. If you head back to the **Owned Ious** screen, you can see that the Iou now has a new Contract ID. In our case, it's `#13:1`.
|
||||
#. To propose the trade, go to the **Templates** screen. Click on the *IouTrade:IouTrade* template, fill in the form as shown below and submit the transaction.
|
||||
|
||||
.. figure:: quickstart/images/tradeProp.png
|
||||
@ -222,8 +224,8 @@ Now everything is running, you can try out the quickstart application:
|
||||
|
||||
It also shows an *Iou* for $110 issued by *USD_Bank*. This matches the trade proposal you made earlier as Alice.
|
||||
|
||||
Note its *Contract Id* ``#10:1``.
|
||||
#. Settle the trade. Go to the **Trades** page, and click on the row of the proposal. Accept the trade by clicking **IouTrade_Accept**. In the popup, enter ``#10:1`` as the *quoteIouCid*, then click **Submit**.
|
||||
Note its *Contract Id*.
|
||||
#. Settle the trade. Go to the **Trades** page, and click on the row of the proposal. Accept the trade by clicking **IouTrade_Accept**. In the popup, enter the Contract ID you just noted as the *quoteIouCid*, then click **Submit**.
|
||||
|
||||
The two legs of the transfer are now settled atomically in a single transaction. The trade either fails or succeeds as a whole.
|
||||
#. Privacy is an important feature of DAML. You can check that Alice and Bob's privacy relative to the Banks was preserved.
|
||||
|
@ -120,7 +120,7 @@ If you wanted to test out the tool, you can run it against :doc:`DAML Sandbox
|
||||
.. code-block:: console
|
||||
|
||||
$ java -jar ledger-api-test-tool.jar --extract
|
||||
$ daml sandbox -- *.dar
|
||||
$ daml sandbox --wall-clock-time *.dar
|
||||
$ java -jar ledger-api-test-tool.jar localhost:6865
|
||||
|
||||
This should always succeed, as the Sandbox is tested to correctly implement the
|
||||
|
@ -10,13 +10,15 @@ The DAML Sandbox, or Sandbox for short, is a simple ledger implementation that e
|
||||
|
||||
You can start Sandbox together with :doc:`Navigator </tools/navigator/index>` using the ``daml start`` command in a DAML SDK project. This command will compile the DAML file and its dependencies as specified in the ``daml.yaml``. It will then launch Sandbox passing the just obtained DAR packages. Sandbox will also be given the name of the startup scenario specified in the project's ``daml.yaml``. Finally, it launches the navigator connecting it to the running Sandbox.
|
||||
|
||||
It is possible to execute the Sandbox launching step in isolation by typing ``daml sandbox``.
|
||||
It is possible to execute the Sandbox launching step in isolation by typing ``daml sandbox --wall-clock-time``.
|
||||
|
||||
Note: Sandbox is currently in the process of moving from Static Time mode to Wall Clock Time mode as the default. For this version only, you need to specify the time mode explicitly when launching Sandbox outside ``daml start``. (When you use ``daml start``, it provides this flag and any other flags in the ``sandbox-options:`` section of ``daml.yaml``.) From the next release, you can omit this flag.
|
||||
|
||||
Sandbox can also be run manually as in this example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ daml sandbox Main.dar --scenario Main:example
|
||||
$ daml sandbox Main.dar --static-time --scenario Main:example
|
||||
|
||||
____ ____
|
||||
/ __/__ ____ ___/ / / ___ __ __
|
||||
@ -27,7 +29,7 @@ Sandbox can also be run manually as in this example:
|
||||
Initialized Static time provider, starting from 1970-01-01T00:00:00Z
|
||||
listening on localhost:6865
|
||||
|
||||
Here, ``daml sandbox`` tells the SDK Assistant to run ``sandbox`` from the active SDK release and pass it any arguments that follow. The example passes the DAR file to load (``Main.dar``) and the optional ``--scenario`` flag tells Sandbox to run the ``Main:example`` scenario on startup. The scenario must be fully qualified; here ``Main`` is the module and ``example`` is the name of the scenario, separated by a ``:``.
|
||||
Here, ``daml sandbox`` tells the SDK Assistant to run ``sandbox`` from the active SDK release and pass it any arguments that follow. The example passes the DAR file to load (``Main.dar``) and the optional ``--scenario`` flag tells Sandbox to run the ``Main:example`` scenario on startup. The scenario must be fully qualified; here ``Main`` is the module and ``example`` is the name of the scenario, separated by a ``:``. We also specify that the Sandbox should run in Static Time mode so that the scenario can control the time.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -55,7 +57,7 @@ Due to possible conflicts between the ``&`` character and various terminal shell
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ daml sandbox Main.dar --sql-backend-jdbcurl "jdbc:postgresql://localhost/test?user=fred&password=secret"
|
||||
$ daml sandbox Main.dar --wall-clock-time --sql-backend-jdbcurl "jdbc:postgresql://localhost/test?user=fred&password=secret"
|
||||
|
||||
If you're not familiar with JDBC URLs, see the JDBC docs for more information: https://jdbc.postgresql.org/documentation/head/connect.html
|
||||
|
||||
|
@ -240,7 +240,7 @@ Now we are ready to run the trigger using ``daml trigger``:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
daml trigger --dar .daml/dist/copy-trigger-0.0.1.dar --trigger-name CopyTrigger:copyTrigger --ledger-host localhost --ledger-port 6865 --ledger-party Alice --static-time
|
||||
daml trigger --dar .daml/dist/copy-trigger-0.0.1.dar --trigger-name CopyTrigger:copyTrigger --ledger-host localhost --ledger-port 6865 --ledger-party Alice --wall-clock-time
|
||||
|
||||
The first argument specifies the ``.dar`` file that we have just
|
||||
built. The second argument specifies the identifier of the trigger
|
||||
|
@ -11,3 +11,5 @@ dependencies:
|
||||
- daml-stdlib
|
||||
- daml-trigger
|
||||
# trigger-dependencies-end
|
||||
sandbox-options:
|
||||
- --wall-clock-time
|
||||
|
@ -104,7 +104,7 @@ First we'll need a sandbox ledger to which we can deploy.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ daml sandbox --port 6865
|
||||
$ daml sandbox --port 6865 --wall-clock-time
|
||||
|
||||
Now we'll setup the project for the original version of our coin. The project contains the DAML for just the ``Coin`` template, along with a ``CoinProposal`` template which will allow us to issue some coins in the example below.
|
||||
|
||||
|
@ -49,7 +49,7 @@ codegen:
|
||||
## Start Sandbox
|
||||
This examples requires a running sandbox. To start it, run the following command:
|
||||
```
|
||||
$ daml sandbox ./.daml/dist/quickstart-0.0.1.dar
|
||||
$ daml sandbox --wall-clock-time ./.daml/dist/quickstart-0.0.1.dar
|
||||
```
|
||||
where `./.daml/dist/quickstart-0.0.1.dar` is the DAR file created in the previous step.
|
||||
|
||||
|
@ -24,3 +24,5 @@ codegen:
|
||||
output-directory: scala-codegen/src/main/scala
|
||||
verbosity: 2
|
||||
# </doc-ref:codegen-scala>
|
||||
sandbox-options:
|
||||
- --wall-clock-time
|
||||
|
@ -385,6 +385,9 @@ server_conformance_test(
|
||||
|
||||
server_conformance_test(
|
||||
name = "conformance-test-config-management",
|
||||
server_args = [
|
||||
"--static-time",
|
||||
],
|
||||
servers = SERVERS,
|
||||
test_tool_args = [
|
||||
"--verbose",
|
||||
@ -395,6 +398,9 @@ server_conformance_test(
|
||||
|
||||
server_conformance_test(
|
||||
name = "conformance-test-command-deduplication",
|
||||
server_args = [
|
||||
"--static-time",
|
||||
],
|
||||
servers = SERVERS,
|
||||
test_tool_args = [
|
||||
"--verbose",
|
||||
@ -406,6 +412,7 @@ server_conformance_test(
|
||||
server_conformance_test(
|
||||
name = "conformance-test-contract-id-seeding",
|
||||
server_args = [
|
||||
"--static-time",
|
||||
"--contract-id-seeding=weak",
|
||||
],
|
||||
servers = SERVERS,
|
||||
|
@ -23,8 +23,8 @@ import com.digitalasset.ledger.api.auth.interceptor.AuthorizationInterceptor
|
||||
import com.digitalasset.ledger.api.auth.{AuthService, AuthServiceWildcard, Authorizer}
|
||||
import com.digitalasset.ledger.api.domain.LedgerId
|
||||
import com.digitalasset.ledger.api.health.HealthChecks
|
||||
import com.digitalasset.logging.ContextualizedLogger
|
||||
import com.digitalasset.logging.LoggingContext.newLoggingContext
|
||||
import com.digitalasset.logging.{ContextualizedLogger, LoggingContext}
|
||||
import com.digitalasset.platform.apiserver.{
|
||||
ApiServer,
|
||||
ApiServices,
|
||||
@ -34,7 +34,7 @@ import com.digitalasset.platform.apiserver.{
|
||||
import com.digitalasset.platform.packages.InMemoryPackageStore
|
||||
import com.digitalasset.platform.sandbox.SandboxServer._
|
||||
import com.digitalasset.platform.sandbox.banner.Banner
|
||||
import com.digitalasset.platform.sandbox.config.SandboxConfig
|
||||
import com.digitalasset.platform.sandbox.config.{InvalidConfigException, SandboxConfig}
|
||||
import com.digitalasset.platform.sandbox.metrics.MetricsReporting
|
||||
import com.digitalasset.platform.sandbox.services.SandboxResetService
|
||||
import com.digitalasset.platform.sandbox.stores.ledger.ScenarioLoader.LedgerEntryOrBump
|
||||
@ -180,7 +180,10 @@ final class SandboxServer(
|
||||
def portF(implicit executionContext: ExecutionContext): Future[Port] =
|
||||
apiServer.map(_.port)
|
||||
|
||||
def resetAndRestartServer()(implicit executionContext: ExecutionContext): Future[Unit] = {
|
||||
def resetAndRestartServer()(
|
||||
implicit executionContext: ExecutionContext,
|
||||
logCtx: LoggingContext,
|
||||
): Future[Unit] = {
|
||||
val apiServicesClosed = apiServer.flatMap(_.servicesClosed())
|
||||
|
||||
// TODO: eliminate the state mutation somehow
|
||||
@ -206,7 +209,7 @@ final class SandboxServer(
|
||||
packageStore: InMemoryPackageStore,
|
||||
startMode: SqlStartMode,
|
||||
currentPort: Option[Port],
|
||||
): Resource[ApiServer] = {
|
||||
)(implicit logCtx: LoggingContext): Resource[ApiServer] = {
|
||||
implicit val _materializer: Materializer = materializer
|
||||
implicit val actorSystem: ActorSystem = materializer.system
|
||||
implicit val executionContext: ExecutionContext = materializer.executionContext
|
||||
@ -228,126 +231,134 @@ final class SandboxServer(
|
||||
(ts, Some(ts))
|
||||
}
|
||||
|
||||
newLoggingContext(logging.participantId(participantId)) { implicit logCtx =>
|
||||
val (ledgerType, indexAndWriteServiceResourceOwner) = config.jdbcUrl match {
|
||||
case Some(jdbcUrl) =>
|
||||
"postgres" -> SandboxIndexAndWriteService.postgres(
|
||||
config.ledgerIdMode,
|
||||
participantId,
|
||||
jdbcUrl,
|
||||
config.timeModel,
|
||||
timeProvider,
|
||||
acs,
|
||||
ledgerEntries,
|
||||
startMode,
|
||||
config.commandConfig.maxCommandsInFlight * 2, // we can get commands directly as well on the submission service
|
||||
packageStore,
|
||||
metrics,
|
||||
)
|
||||
|
||||
case None =>
|
||||
"in-memory" -> SandboxIndexAndWriteService.inMemory(
|
||||
config.ledgerIdMode,
|
||||
participantId,
|
||||
config.timeModel,
|
||||
timeProvider,
|
||||
acs,
|
||||
ledgerEntries,
|
||||
packageStore,
|
||||
metrics,
|
||||
)
|
||||
}
|
||||
|
||||
for {
|
||||
indexAndWriteService <- indexAndWriteServiceResourceOwner.acquire()
|
||||
ledgerId <- Resource.fromFuture(indexAndWriteService.indexService.getLedgerId())
|
||||
authorizer = new Authorizer(
|
||||
() => java.time.Clock.systemUTC.instant(),
|
||||
LedgerId.unwrap(ledgerId),
|
||||
participantId)
|
||||
healthChecks = new HealthChecks(
|
||||
"index" -> indexAndWriteService.indexService,
|
||||
"write" -> indexAndWriteService.writeService,
|
||||
val (ledgerType, indexAndWriteServiceResourceOwner) = config.jdbcUrl match {
|
||||
case Some(jdbcUrl) =>
|
||||
"postgres" -> SandboxIndexAndWriteService.postgres(
|
||||
config.ledgerIdMode,
|
||||
participantId,
|
||||
jdbcUrl,
|
||||
config.timeModel,
|
||||
timeProvider,
|
||||
acs,
|
||||
ledgerEntries,
|
||||
startMode,
|
||||
config.commandConfig.maxCommandsInFlight * 2, // we can get commands directly as well on the submission service
|
||||
packageStore,
|
||||
metrics,
|
||||
)
|
||||
observingTimeServiceBackend = timeServiceBackendO.map(TimeServiceBackend.observing)
|
||||
_ <- observingTimeServiceBackend
|
||||
.map(_.changes.flatMap(source =>
|
||||
|
||||
case None =>
|
||||
"in-memory" -> SandboxIndexAndWriteService.inMemory(
|
||||
config.ledgerIdMode,
|
||||
participantId,
|
||||
config.timeModel,
|
||||
timeProvider,
|
||||
acs,
|
||||
ledgerEntries,
|
||||
packageStore,
|
||||
metrics,
|
||||
)
|
||||
}
|
||||
|
||||
for {
|
||||
indexAndWriteService <- indexAndWriteServiceResourceOwner.acquire()
|
||||
ledgerId <- Resource.fromFuture(indexAndWriteService.indexService.getLedgerId())
|
||||
authorizer = new Authorizer(
|
||||
() => java.time.Clock.systemUTC.instant(),
|
||||
LedgerId.unwrap(ledgerId),
|
||||
participantId)
|
||||
healthChecks = new HealthChecks(
|
||||
"index" -> indexAndWriteService.indexService,
|
||||
"write" -> indexAndWriteService.writeService,
|
||||
)
|
||||
observingTimeServiceBackend = timeServiceBackendO.map(TimeServiceBackend.observing)
|
||||
_ <- observingTimeServiceBackend
|
||||
.map(
|
||||
_.changes.flatMap(source =>
|
||||
ResourceOwner.forTry(() =>
|
||||
Try(source.runWith(Sink.foreachAsync(1)(indexAndWriteService.publishHeartbeat)))
|
||||
.map(_ => ()))))
|
||||
.getOrElse(ResourceOwner.unit)
|
||||
.acquire()
|
||||
// the reset service is special, since it triggers a server shutdown
|
||||
resetService = new SandboxResetService(
|
||||
ledgerId,
|
||||
() => resetAndRestartServer(),
|
||||
authorizer,
|
||||
)
|
||||
apiServer <- new LedgerApiServer(
|
||||
(mat: Materializer, esf: ExecutionSequencerFactory) =>
|
||||
ApiServices
|
||||
.create(
|
||||
participantId = participantId,
|
||||
writeService = indexAndWriteService.writeService,
|
||||
indexService = indexAndWriteService.indexService,
|
||||
authorizer = authorizer,
|
||||
engine = SandboxServer.engine,
|
||||
timeProvider = timeProvider,
|
||||
defaultLedgerConfiguration = defaultConfiguration,
|
||||
commandConfig = config.commandConfig,
|
||||
partyConfig = config.partyConfig,
|
||||
submissionConfig = config.submissionConfig,
|
||||
optTimeServiceBackend = observingTimeServiceBackend,
|
||||
metrics = metrics,
|
||||
healthChecks = healthChecks,
|
||||
seedService = config.seeding.map(SeedService(_)),
|
||||
)(mat, esf, logCtx)
|
||||
.map(_.withServices(List(resetService))),
|
||||
// NOTE: Re-use the same port after reset.
|
||||
currentPort.getOrElse(config.port),
|
||||
config.maxInboundMessageSize,
|
||||
config.address,
|
||||
config.tlsConfig.flatMap(_.server),
|
||||
List(
|
||||
AuthorizationInterceptor(authService, executionContext),
|
||||
resetService,
|
||||
),
|
||||
metrics
|
||||
).acquire()
|
||||
_ <- Resource.fromFuture(writePortFile(apiServer.port))
|
||||
} yield {
|
||||
Banner.show(Console.out)
|
||||
logger.withoutContext.info(
|
||||
"Initialized sandbox version {} with ledger-id = {}, port = {}, dar file = {}, time mode = {}, ledger = {}, auth-service = {}, contract ids seeding = {}",
|
||||
BuildInfo.Version,
|
||||
ledgerId,
|
||||
apiServer.port.toString,
|
||||
config.damlPackages,
|
||||
timeProviderType.description,
|
||||
ledgerType,
|
||||
authService.getClass.getSimpleName,
|
||||
config.seeding.fold("no")(_.toString.toLowerCase),
|
||||
)
|
||||
if (config.scenario.nonEmpty) {
|
||||
logger.withoutContext.warn(
|
||||
"""Initializing a ledger with scenarios is deprecated and will be removed in the future. You are advised to use DAML Script instead. Using scenarios in DAML Studio will continue to work as expected.
|
||||
|A migration guide for converting your scenarios to DAML Script is available at https://docs.daml.com/daml-script/#using-daml-script-for-ledger-initialization""".stripMargin)
|
||||
}
|
||||
apiServer
|
||||
.getOrElse(ResourceOwner.unit)
|
||||
.acquire()
|
||||
// the reset service is special, since it triggers a server shutdown
|
||||
resetService = new SandboxResetService(
|
||||
ledgerId,
|
||||
() => resetAndRestartServer(),
|
||||
authorizer,
|
||||
)
|
||||
apiServer <- new LedgerApiServer(
|
||||
(mat: Materializer, esf: ExecutionSequencerFactory) =>
|
||||
ApiServices
|
||||
.create(
|
||||
participantId = participantId,
|
||||
writeService = indexAndWriteService.writeService,
|
||||
indexService = indexAndWriteService.indexService,
|
||||
authorizer = authorizer,
|
||||
engine = SandboxServer.engine,
|
||||
timeProvider = timeProvider,
|
||||
defaultLedgerConfiguration = defaultConfiguration,
|
||||
commandConfig = config.commandConfig,
|
||||
partyConfig = config.partyConfig,
|
||||
submissionConfig = config.submissionConfig,
|
||||
optTimeServiceBackend = observingTimeServiceBackend,
|
||||
metrics = metrics,
|
||||
healthChecks = healthChecks,
|
||||
seedService = config.seeding.map(SeedService(_)),
|
||||
)(mat, esf, logCtx)
|
||||
.map(_.withServices(List(resetService))),
|
||||
// NOTE: Re-use the same port after reset.
|
||||
currentPort.getOrElse(config.port),
|
||||
config.maxInboundMessageSize,
|
||||
config.address,
|
||||
config.tlsConfig.flatMap(_.server),
|
||||
List(
|
||||
AuthorizationInterceptor(authService, executionContext),
|
||||
resetService,
|
||||
),
|
||||
metrics
|
||||
).acquire()
|
||||
_ <- Resource.fromFuture(writePortFile(apiServer.port))
|
||||
} yield {
|
||||
Banner.show(Console.out)
|
||||
logger.withoutContext.info(
|
||||
"Initialized sandbox version {} with ledger-id = {}, port = {}, dar file = {}, time mode = {}, ledger = {}, auth-service = {}, contract ids seeding = {}",
|
||||
BuildInfo.Version,
|
||||
ledgerId,
|
||||
apiServer.port.toString,
|
||||
config.damlPackages,
|
||||
timeProviderType.description,
|
||||
ledgerType,
|
||||
authService.getClass.getSimpleName,
|
||||
config.seeding.fold("no")(_.toString.toLowerCase),
|
||||
)
|
||||
if (config.scenario.nonEmpty) {
|
||||
logger.withoutContext.warn(
|
||||
"""|Initializing a ledger with scenarios is deprecated and will be removed in the future. You are advised to use DAML Script instead. Using scenarios in DAML Studio will continue to work as expected.
|
||||
|A migration guide for converting your scenarios to DAML Script is available at https://docs.daml.com/daml-script/#using-daml-script-for-ledger-initialization""".stripMargin)
|
||||
}
|
||||
apiServer
|
||||
}
|
||||
}
|
||||
|
||||
private def start(): Future[SandboxState] = {
|
||||
val packageStore = loadDamlPackages()
|
||||
val apiServerResource = buildAndStartApiServer(
|
||||
materializer,
|
||||
metrics,
|
||||
packageStore,
|
||||
SqlStartMode.ContinueIfExists,
|
||||
currentPort = None,
|
||||
)
|
||||
Future.successful(new SandboxState(materializer, metrics, packageStore, apiServerResource))
|
||||
newLoggingContext(logging.participantId(participantId)) { implicit logCtx =>
|
||||
if (config.timeProviderType.isEmpty) {
|
||||
throw new InvalidConfigException(
|
||||
"Sandbox used to default to Static Time mode. In the next release, Wall Clock Time mode"
|
||||
+ " will become the default. In this version, you will need to explicitly specify the"
|
||||
+ " `--static-time` flag to maintain the previous behavior, or `--wall-clock-time` if"
|
||||
+ " you would like to use the new defaults.")
|
||||
}
|
||||
val packageStore = loadDamlPackages()
|
||||
val apiServerResource = buildAndStartApiServer(
|
||||
materializer,
|
||||
metrics,
|
||||
packageStore,
|
||||
SqlStartMode.ContinueIfExists,
|
||||
currentPort = None,
|
||||
)
|
||||
Future.successful(new SandboxState(materializer, metrics, packageStore, apiServerResource))
|
||||
}
|
||||
}
|
||||
|
||||
private def loadDamlPackages(): InMemoryPackageStore = {
|
||||
|
@ -88,7 +88,13 @@ class Runner(config: SandboxConfig) extends ResourceOwner[Port] {
|
||||
("in-memory", InMemoryLedgerJdbcUrl, InMemoryIndexJdbcUrl, StartupMode.ResetAndStart)
|
||||
}
|
||||
|
||||
private val timeProviderType = config.timeProviderType.getOrElse(TimeProviderType.Static)
|
||||
private val timeProviderType = config.timeProviderType.getOrElse {
|
||||
throw new InvalidConfigException(
|
||||
"Sandbox used to default to Static Time mode. In the next release, Wall Clock Time mode will"
|
||||
+ " become the default. In this version, you will need to explicitly specify the"
|
||||
+ " `--static-time` flag to maintain the previous behavior, or `--wall-clock-time` if you"
|
||||
+ " would like to use the new defaults.")
|
||||
}
|
||||
|
||||
private val seeding = config.seeding.getOrElse {
|
||||
throw new InvalidConfigException(
|
||||
|
@ -94,7 +94,7 @@ latest commit on master.
|
||||
1 contract and 3 templates. Close the tab and kill `daml start` using `Ctrl-C`.
|
||||
1. Run `daml build`.
|
||||
1. In 3 separate terminals (since each command except for `daml script` will block), run
|
||||
1. `daml sandbox --port 6865 .daml/dist/quickstart-0.0.1.dar`
|
||||
1. `daml sandbox --wall-clock-time --port 6865 .daml/dist/quickstart-0.0.1.dar`
|
||||
1. `daml script --dar .daml/dist/quickstart-0.0.1.dar --script-name Setup:initialize --ledger-host localhost --ledger-port 6865 --static-time`
|
||||
1. `daml navigator server localhost 6865 --port 7500`
|
||||
1. `mvn compile exec:java@run-quickstart`
|
||||
|
@ -14,3 +14,5 @@ dependencies:
|
||||
- daml-prim
|
||||
- daml-stdlib
|
||||
- daml-script
|
||||
sandbox-options:
|
||||
- --wall-clock-time
|
||||
|
@ -14,6 +14,8 @@ dependencies:
|
||||
- daml-prim
|
||||
- daml-stdlib
|
||||
- daml-script
|
||||
sandbox-options:
|
||||
- --wall-clock-time
|
||||
codegen:
|
||||
scala:
|
||||
package-prefix: com.digitalasset.quickstart.iou.model
|
||||
|
@ -10,3 +10,5 @@ dependencies:
|
||||
- daml-prim
|
||||
- daml-stdlib
|
||||
- daml-script
|
||||
sandbox-options:
|
||||
- --wall-clock-time
|
||||
|
@ -82,7 +82,10 @@ client_server_test(
|
||||
client_files = ["$(rootpath :acs.dar)"],
|
||||
data = [":acs.dar"],
|
||||
server = "//ledger/sandbox:sandbox-binary",
|
||||
server_args = ["--port=0"],
|
||||
server_args = [
|
||||
"--static-time",
|
||||
"--port=0",
|
||||
],
|
||||
server_files = ["$(rootpath :acs.dar)"],
|
||||
)
|
||||
|
||||
@ -95,7 +98,7 @@ client_server_test(
|
||||
data = [":acs.dar"],
|
||||
server = "//ledger/sandbox:sandbox-binary",
|
||||
server_args = [
|
||||
"-w",
|
||||
"--wall-clock-time",
|
||||
"--port=0",
|
||||
],
|
||||
server_files = ["$(rootpath :acs.dar)"],
|
||||
@ -120,7 +123,7 @@ client_server_test(
|
||||
],
|
||||
server = "//ledger/sandbox:sandbox-binary",
|
||||
server_args = [
|
||||
"-w",
|
||||
"--wall-clock-time",
|
||||
"--port=0",
|
||||
"--crt $(rlocation $TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:server.crt))",
|
||||
"--pem $(rlocation $TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:server.pem))",
|
||||
@ -160,6 +163,7 @@ client_server_test(
|
||||
],
|
||||
server = "//ledger/sandbox:sandbox-binary",
|
||||
server_args = [
|
||||
"--static-time",
|
||||
"--port=0",
|
||||
"--auth-jwt-hs256-unsafe={}".format(AUTH_TOKEN),
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user