Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit ba4fb01

Browse files
authored
[GH-208] Add node-ipc for wallet. (#209)
* [GH-208] Add node-ipc for wallet. * [GH-208] Fix Nix deps. * DaedalusIPC clean ups (#213) * DaedalusIPC: Clean it up a bit * Add a test program for DaedalusIPC * Add DaedalusIPC nodejs test (#221) * tests: Add DaedalusIPC spec This uses nodejs to run daedalusIPC. * nix: Update and regenerate
1 parent 33e4d04 commit ba4fb01

File tree

10 files changed

+412
-8
lines changed

10 files changed

+412
-8
lines changed

app/daedalus-ipc.hs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
3+
module Main where
4+
5+
import Cardano.Prelude
6+
7+
import Cardano.BM.Configuration.Static (defaultConfigStdout)
8+
import Cardano.BM.Setup (setupTrace_)
9+
import Cardano.Shell.DaedalusIPC
10+
11+
main :: IO ()
12+
main = fmap readEither <$> getArgs >>= \case
13+
[Right port] -> do
14+
c <- defaultConfigStdout
15+
(tr, _sb) <- setupTrace_ c "daedalus-ipc"
16+
daedalusIPC tr port
17+
_ -> do
18+
putStrLn ("Usage: daedalus-ipc PORT" :: Text)
19+
exitFailure

cardano-shell.cabal

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
cabal-version: 2.2
12
name: cardano-shell
23
version: 0.1.0.0
34
description: Please see the README on GitHub at <https://github.com/githubuser/cardano-shell#readme>
@@ -10,10 +11,10 @@ copyright: 2018 IOHK
1011
license: Apache-2.0
1112
license-files: LICENSE, NOTICE
1213
build-type: Simple
13-
cabal-version: >= 1.10
1414
extra-source-files:
1515
ChangeLog.md
1616
README.md
17+
test/js/mock-daedalus.js
1718

1819
source-repository head
1920
type: git
@@ -28,6 +29,8 @@ library
2829
, Cardano.Shell.Configuration.Lib
2930
-- NodeIPC
3031
, Cardano.Shell.NodeIPC
32+
, Cardano.Shell.NodeIPC.General
33+
, Cardano.Shell.DaedalusIPC
3134
-- Update system
3235
, CardanoShellSpec
3336
, Cardano.Shell.Update.Types
@@ -66,6 +69,7 @@ library
6669
, QuickCheck
6770
, safe-exceptions
6871
, stm
72+
, async
6973
, text
7074
, transformers
7175
, generic-monoid
@@ -139,6 +143,28 @@ executable node-ipc
139143
-Wredundant-constraints
140144
-Wpartial-fields
141145

146+
executable daedalus-ipc
147+
main-is: app/daedalus-ipc.hs
148+
ghc-options: -threaded -rtsopts -with-rtsopts=-N
149+
build-depends:
150+
base >=4.7 && <5
151+
, cardano-shell
152+
, cardano-prelude
153+
, optparse-applicative
154+
, safe-exceptions
155+
, iohk-monitoring
156+
default-language: Haskell2010
157+
default-extensions: NoImplicitPrelude
158+
OverloadedStrings
159+
160+
ghc-options: -Wall
161+
-Werror
162+
-Wcompat
163+
-Wincomplete-record-updates
164+
-Wincomplete-uni-patterns
165+
-Wredundant-constraints
166+
-Wpartial-fields
167+
142168
executable cardano-launcher
143169
main-is: Main.hs
144170
other-modules:
@@ -183,6 +209,7 @@ test-suite cardano-shell-test
183209
other-modules:
184210
Paths_cardano_shell
185211
DhallConfigSpec
212+
DaedalusIPCSpec
186213
UpdaterSpec
187214
if !os(windows)
188215
other-modules:
@@ -199,6 +226,7 @@ test-suite cardano-shell-test
199226
, cardano-prelude
200227
, dhall
201228
, safe-exceptions
229+
, process
202230
-- quickcheck
203231
, QuickCheck
204232
-- SM
@@ -212,6 +240,8 @@ test-suite cardano-shell-test
212240
, concurrency
213241
, dejafu
214242
, hunit-dejafu
243+
build-tool-depends:
244+
cardano-shell:daedalus-ipc
215245
default-language: Haskell2010
216246
default-extensions: NoImplicitPrelude
217247
OverloadedStrings

nix/.stack.nix/cardano-shell.nix

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nix/iohk-nix-src.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"url": "https://github.com/input-output-hk/iohk-nix",
3-
"rev": "eec83e9bba05093c94004a001caebae252c0c83b",
4-
"date": "2019-06-26T17:23:10+00:00",
5-
"sha256": "00b11qmgr57pm6gg7a8m6fzjj6m5wmh8hnwg16jnqsmf52882y2j",
3+
"rev": "3cee475f26458ef113a494b216b1504513fa4d03",
4+
"date": "2019-07-05T14:51:43+00:00",
5+
"sha256": "04dqb2ii03y1lvyqn3v3xwardym2h6g5zbgvjljam758w768vmii",
66
"fetchSubmodules": false
77
}

nix/pkgs.nix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ let
3838
# turtle seems to have the same issue.
3939
packages.turtle.doExactConfig = true;
4040
}
41+
42+
{
43+
packages.cardano-shell.src = haskell.cleanSourceHaskell ../.;
44+
packages.cardano-shell.components.tests.cardano-shell-test.build-tools = [ pkgs.nodejs ];
45+
}
4146
];
4247
};
4348

src/Cardano/Shell/DaedalusIPC.hs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE RankNTypes #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
5+
6+
-- |
7+
-- Copyright: © 2018-2019 IOHK
8+
--
9+
-- Daedalus <-> Wallet child process port discovery protocol.
10+
-- Provides a mechanism for Daedalus to discover what port the cardano-wallet
11+
-- server is listening on.
12+
--
13+
-- See <https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options>
14+
-- for more information about the message protocol.
15+
16+
module Cardano.Shell.DaedalusIPC
17+
( daedalusIPC
18+
) where
19+
20+
import Cardano.Prelude
21+
22+
import Cardano.BM.Trace (Trace, logError, logInfo, logNotice)
23+
import Cardano.Shell.NodeIPC.General (NodeChannelError (..),
24+
NodeChannelFinished (..),
25+
runNodeChannel,
26+
setupNodeChannel)
27+
import Control.Concurrent (threadDelay)
28+
import Control.Monad (forever)
29+
import Data.Aeson (FromJSON (..), ToJSON (..), Value (..), object,
30+
withObject, (.:), (.=))
31+
import Data.Text (Text)
32+
33+
-- | Messages sent from Daedalus -> cardano-wallet
34+
data MsgIn = QueryPort
35+
deriving (Show, Eq)
36+
37+
-- | Messages sent from cardano-wallet -> Daedalus
38+
data MsgOut = Started | ReplyPort Int | ParseError Text
39+
deriving (Show, Eq)
40+
41+
instance FromJSON MsgIn where
42+
parseJSON = withObject "MsgIn" $ \v -> do
43+
(_ :: [()]) <- v .: "QueryPort"
44+
pure QueryPort
45+
46+
instance ToJSON MsgOut where
47+
toJSON Started = object [ "Started" .= Array mempty ]
48+
toJSON (ReplyPort p) = object [ "ReplyPort" .= p ]
49+
toJSON (ParseError e) = object [ "ParseError" .= e ]
50+
51+
-- | Start up the Daedalus IPC process. It's called 'daedalusIPC', but this
52+
-- could be any nodejs program that needs to start cardano-wallet. All it does
53+
-- is reply with a port number when asked, using a very nodejs-specific IPC
54+
-- method.
55+
--
56+
-- If the IPC channel was successfully set up, this function won't return until
57+
-- the parent process exits. Otherwise, it will return immediately. Before
58+
-- returning, it will log an message about why it has exited.
59+
daedalusIPC
60+
:: Trace IO Text
61+
-- ^ Logging object
62+
-> Int
63+
-- ^ Port number to send to Daedalus
64+
-> IO ()
65+
daedalusIPC tr port = setupNodeChannel >>= \case
66+
Right chan -> do
67+
logInfo tr "Daedalus IPC server starting"
68+
runNodeChannel (pure . msg) action chan >>= \case
69+
Left (NodeChannelFinished err) ->
70+
logNotice tr $ "Daedalus IPC finished for this reason: " <> show err
71+
Right () -> logError tr "Unreachable code"
72+
Left NodeChannelDisabled -> do
73+
logInfo tr "Daedalus IPC is not enabled."
74+
sleep
75+
Left (NodeChannelBadFD err) ->
76+
logError tr $ "Problem starting Daedalus IPC: " <> show err
77+
where
78+
-- How to respond to an incoming message, or when there is an incoming
79+
-- message that couldn't be parsed.
80+
msg (Right QueryPort) = Just (ReplyPort port)
81+
msg (Left e) = Just (ParseError e)
82+
83+
-- What to do in context of runNodeChannel
84+
action :: (MsgOut -> IO ()) -> IO ()
85+
action send = send Started >> sleep
86+
87+
sleep = forever $ threadDelay maxBound

0 commit comments

Comments
 (0)