Skip to content

Commit

Permalink
launch: merge necessary jormungandr config options with user's config
Browse files Browse the repository at this point in the history
  • Loading branch information
rvl committed Oct 17, 2019
1 parent d525e85 commit 0d0f0bb
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 79 deletions.
2 changes: 2 additions & 0 deletions lib/jormungandr/cardano-wallet-jormungandr.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ library
, extra
, filepath
, fmt
, generic-lens
, http-client
, http-types
, iohk-monitoring
Expand All @@ -66,6 +67,7 @@ library
, text-class
, time
, transformers
, unordered-containers
, yaml
, warp
hs-source-dirs:
Expand Down
55 changes: 38 additions & 17 deletions lib/jormungandr/exe/cardano-wallet-jormungandr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ import Cardano.Wallet.Version
( showVersion, version )
import Control.Applicative
( optional, (<|>) )
import Data.List
( isPrefixOf )
import Data.Maybe
( fromMaybe )
import Data.Text
Expand All @@ -90,11 +92,14 @@ import Options.Applicative
, helper
, info
, long
, many
, metavar
, option
, progDesc
, some
, str
)
import Options.Applicative.Types
( readerAsk, readerError )
import System.Exit
( exitWith )
import System.FilePath
Expand Down Expand Up @@ -158,8 +163,9 @@ data LaunchArgs = LaunchArgs
}

data JormungandrArgs = JormungandrArgs
{ genesisBlock :: Either (Hash "Genesis") FilePath
, extraJormungandrArgs :: [Text]
{ _genesisBlock :: Either (Hash "Genesis") FilePath
, _configFile :: Maybe FilePath
, _extraJormungandrArgs :: [String]
}

cmdLaunch
Expand All @@ -178,24 +184,26 @@ cmdLaunch dataDir = command "launch" $ info (helper <*> cmd) $ mempty
<*> verbosityOption
<*> (JormungandrArgs
<$> genesisBlockOption
<*> configFileOption
<*> extraArguments)
exec (LaunchArgs listen nodePort mStateDir verbosity jArgs) = do
let minSeverity = verbosityToMinSeverity verbosity
(cfg, sb, tr) <- initTracer minSeverity "launch"
case genesisBlock jArgs of
let minSeverity_ = verbosityToMinSeverity verbosity
(cfg, sb, tr) <- initTracer minSeverity_ "launch"
case _genesisBlock jArgs of
Right block0File -> requireFilePath block0File
Left _ -> pure ()
let stateDir = fromMaybe (dataDir </> "testnet") mStateDir
let databaseDir = stateDir </> "wallets"
let stateDir_ = fromMaybe (dataDir </> "testnet") mStateDir
let databaseDir = stateDir_ </> "wallets"
let cp = JormungandrConfig
{ _stateDir = stateDir
, _genesisBlock = genesisBlock jArgs
, _restApiPort = fromIntegral . getPort <$> nodePort
, _minSeverity = minSeverity
, _outputStream = Inherit
, _extraArgs = extraJormungandrArgs jArgs
{ stateDir = stateDir_
, genesisBlock = _genesisBlock jArgs
, restApiPort = fromIntegral . getPort <$> nodePort
, minSeverity = minSeverity_
, outputStream = Inherit
, configFile = _configFile jArgs
, extraArgs = _extraJormungandrArgs jArgs
}
setupDirectory (logInfo tr) stateDir
setupDirectory (logInfo tr) stateDir_
setupDirectory (logInfo tr) databaseDir
logInfo tr $ "Running as v" <> T.pack (showVersion version)
exitWith =<< serveWallet
Expand Down Expand Up @@ -272,8 +280,21 @@ genesisHashOption = optionT $ mempty
<> metavar "STRING"
<> help "Blake2b_256 hash of the genesis block, in base 16."

-- | [--config=FILE.YAML]
configFileOption :: Parser (Maybe FilePath)
configFileOption = optional $ option str $ mempty
<> long "config"
<> metavar "FILE.YAML"
<> help "Config file for jormungandr (note that this will be copied to a temporary location)"

-- | -- [ARGUMENTS...]
extraArguments :: Parser [Text]
extraArguments = some $ argument str $ mempty
extraArguments :: Parser [String]
extraArguments = many $ argument jmArg $ mempty
<> metavar "[-- ARGUMENTS...]"
<> help "Extra arguments to be passed to jormungandr."
where
jmArg = do
arg <- readerAsk
if "--config" `isPrefixOf` arg
then readerError "The --config option must be placed before the --"
else pure arg
6 changes: 4 additions & 2 deletions lib/jormungandr/src/Cardano/Wallet/Jormungandr.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
Expand Down Expand Up @@ -54,7 +55,6 @@ import Cardano.Wallet.Jormungandr.Network
, ErrGetBlockchainParams (..)
, ErrStartup (..)
, JormungandrBackend (..)
, JormungandrConnParams (..)
, withNetworkLayer
)
import Cardano.Wallet.Jormungandr.Primitive.Types
Expand Down Expand Up @@ -85,6 +85,8 @@ import Control.DeepSeq
( NFData )
import Data.Function
( (&) )
import Data.Generics.Internal.VL.Lens
( (^.) )
import Data.Text
( Text )
import Data.Text.Class
Expand Down Expand Up @@ -126,7 +128,7 @@ serveWallet (cfg, sb, tr) databaseDir listen lj beforeMainLoop = do
logInfo tr $ "Node is Jörmungandr on " <> toText (networkVal @n)
withNetworkLayer tr lj $ \case
Right (cp, nl) -> do
let nPort = Port $ baseUrlPort $ _restApi cp
let nPort = Port $ baseUrlPort $ cp ^. #restApi
waitForService "Jörmungandr" (sb, tr) nPort $
waitForNetwork nl defaultRetryPolicy
let (_, bp) = staticBlockchainParameters nl
Expand Down
73 changes: 59 additions & 14 deletions lib/jormungandr/src/Cardano/Wallet/Jormungandr/Compatibility.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module Cardano.Wallet.Jormungandr.Compatibility
, BaseUrl (..)
, Scheme (..)
, genConfigFile
, genConfigFileYaml
, localhostBaseUrl
, baseUrlToText
) where
Expand Down Expand Up @@ -66,6 +67,10 @@ import Data.ByteString
( ByteString )
import Data.ByteString.Base58
( bitcoinAlphabet, decodeBase58, encodeBase58 )
import Data.Function
( (&) )
import Data.List
( foldl' )
import Data.Maybe
( fromJust, isJust )
import Data.Proxy
Expand All @@ -85,11 +90,13 @@ import qualified Cardano.Byron.Codec.Cbor as CBOR
import qualified Cardano.Wallet.Primitive.Types as W
import qualified Codec.Binary.Bech32 as Bech32
import qualified Codec.CBOR.Write as CBOR
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Types as Aeson
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as B8
import qualified Data.HashMap.Strict as HM
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.Yaml as Yaml

-- | A type representing the Jormungandr as a network target. This has an
-- influence on binary serializer & network primitives. See also 'TxId'
Expand Down Expand Up @@ -223,29 +230,67 @@ instance KnownNetwork n => DecodeAddress (Jormungandr n) where
<> B8.unpack (BS.pack [discriminant])
<> "."

-- | Generate a configuration file for Jörmungandr@0.3.999
-- | Generate a configuration file for Jörmungandr@0.6
-- Will throw "YamlException" or "IOException" when files cannot be
-- read/written.
genConfigFileYaml
:: FilePath
-- ^ State directory
-> PortNumber
-- ^ P2P port
-> BaseUrl
-- ^ Rest API base URL
-> Maybe FilePath
-- ^ User's config file
-> IO FilePath
genConfigFileYaml stateDir addressPort restApiUrl baseConfig = do
let nodeConfigFile = stateDir </> "jormungandr-config.yaml"
base <- maybe (pure Aeson.Null) Yaml.decodeFileThrow baseConfig
genConfigFile stateDir addressPort restApiUrl base
& Yaml.encodeFile nodeConfigFile
pure nodeConfigFile

-- | Create a Jormungandr config by first making some defaults, then adding the
-- user's config file (if provided), then setting the API port to the value that
-- we have chosen.
genConfigFile
:: FilePath
-> PortNumber
-> BaseUrl
-> Aeson.Value
genConfigFile stateDir addressPort (BaseUrl _ host port _) = object
[ "storage" .= (stateDir </> "chain")
, "rest" .= object
[ "listen" .= String listen ]
, "p2p" .= object
[ "trusted_peers" .= ([] :: [()])
, "topics_of_interest" .= object
[ "messages" .= String "low"
, "blocks" .= String "normal"
-> Aeson.Value
genConfigFile stateDir addressPort (BaseUrl _ host port _) user =
mergeObjects [defaults, user, override]
where
defaults = object
[ "storage" .= (stateDir </> "chain")
, "p2p" .= object
[ "trusted_peers" .= ([] :: [()])
, "topics_of_interest" .= object
[ "messages" .= String "low"
, "blocks" .= String "normal"
]
, "public_address" .= String publicAddress
]
, "public_address" .= String publicAddress
]
]
where
override = object
[ "rest" .= object
[ "listen" .= String listen ]
]
listen = T.pack $ mconcat [host, ":", show port]
publicAddress = T.pack $ mconcat ["/ip4/127.0.0.1/tcp/", show addressPort]

-- | Recursively merge JSON objects, with the rightmost values taking
-- precedence.
mergeObjects :: [Aeson.Value] -> Aeson.Value
mergeObjects = foldl' merge Aeson.Null
where
merge :: Aeson.Value -> Aeson.Value -> Aeson.Value
merge (Aeson.Object a) (Aeson.Object b) = Aeson.Object $
HM.unionWith merge a b
merge a Aeson.Null = a
merge _ b = b

{-------------------------------------------------------------------------------
Base URL
-------------------------------------------------------------------------------}
Expand Down
Loading

0 comments on commit 0d0f0bb

Please sign in to comment.