From df0948ec27431beb7ef183e3034a2914dc5f8ef7 Mon Sep 17 00:00:00 2001 From: Johannes Lund Date: Wed, 8 May 2019 16:59:30 +0200 Subject: [PATCH] Add stub cardano-wallet-jormungandr --- .weeder.yaml | 10 ++ lib/jormungandr/LICENSE | 1 + lib/jormungandr/README.md | 1 + .../cardano-wallet-jormungandr.cabal | 81 +++++++++ lib/jormungandr/src/Cardano/Environment.hs | 166 ++++++++++++++++++ .../src/Cardano/Wallet/Binary/Jormungandr.hs | 12 ++ .../Wallet/Compatibility/Jormungandr.hs | 30 ++++ .../Cardano/Wallet/Transaction/Jormungandr.hs | 19 ++ .../Cardano/Wallet/Binary/JormungandrSpec.hs | 45 +++++ lib/jormungandr/test/unit/Main.hs | 16 ++ lib/jormungandr/test/unit/Spec.hs | 1 + stack.yaml | 1 + 12 files changed, 383 insertions(+) create mode 120000 lib/jormungandr/LICENSE create mode 100644 lib/jormungandr/README.md create mode 100644 lib/jormungandr/cardano-wallet-jormungandr.cabal create mode 100644 lib/jormungandr/src/Cardano/Environment.hs create mode 100644 lib/jormungandr/src/Cardano/Wallet/Binary/Jormungandr.hs create mode 100644 lib/jormungandr/src/Cardano/Wallet/Compatibility/Jormungandr.hs create mode 100644 lib/jormungandr/src/Cardano/Wallet/Transaction/Jormungandr.hs create mode 100644 lib/jormungandr/test/unit/Cardano/Wallet/Binary/JormungandrSpec.hs create mode 100644 lib/jormungandr/test/unit/Main.hs create mode 100644 lib/jormungandr/test/unit/Spec.hs diff --git a/.weeder.yaml b/.weeder.yaml index 4d2384a2efa..df9afcc93c4 100644 --- a/.weeder.yaml +++ b/.weeder.yaml @@ -34,3 +34,13 @@ - name: Module not compiled - module: Cardano.Launcher.Windows +- package: + - name: cardano-wallet-jormungandr + - section: + - name: test:unit + - message: + - name: Weeds exported + - module: + - name: Spec + - identifier: main + diff --git a/lib/jormungandr/LICENSE b/lib/jormungandr/LICENSE new file mode 120000 index 00000000000..30cff7403da --- /dev/null +++ b/lib/jormungandr/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/lib/jormungandr/README.md b/lib/jormungandr/README.md new file mode 100644 index 00000000000..9897c28be0d --- /dev/null +++ b/lib/jormungandr/README.md @@ -0,0 +1 @@ +# Jörmungandr diff --git a/lib/jormungandr/cardano-wallet-jormungandr.cabal b/lib/jormungandr/cardano-wallet-jormungandr.cabal new file mode 100644 index 00000000000..4d42b5d5e35 --- /dev/null +++ b/lib/jormungandr/cardano-wallet-jormungandr.cabal @@ -0,0 +1,81 @@ +name: cardano-wallet-jormungandr +version: 2019.5.8 +synopsis: Wallet backend protocol-specific bits implemented using Jörmungandr +description: Please see README.md +homepage: https://github.com/input-output-hk/cardano-wallet +author: IOHK Engineering Team +maintainer: operations@iohk.io +copyright: 2019 IOHK +license: MIT +license-file: LICENSE +category: Web +build-type: Simple +extra-source-files: README.md +cabal-version: >=1.10 + +flag development + description: Disable `-Werror` + default: False + manual: True + +library + default-language: + Haskell2010 + default-extensions: + NoImplicitPrelude + OverloadedStrings + ghc-options: + -Wall + -Wcompat + -fwarn-redundant-constraints + if (!flag(development)) + ghc-options: + -Werror + build-depends: + base + , cardano-wallet-core + , fmt +-- , binary +-- , bytestring +-- , cardano-crypto +-- , cryptonite +-- , digest + , text + , text-class + hs-source-dirs: + src + exposed-modules: + Cardano.Environment + Cardano.Wallet.Binary.Jormungandr + Cardano.Wallet.Compatibility.Jormungandr + Cardano.Wallet.Transaction.Jormungandr + +test-suite unit + default-language: + Haskell2010 + default-extensions: + NoImplicitPrelude + OverloadedStrings + ghc-options: + -threaded -rtsopts + -Wall + -O2 + if (!flag(development)) + ghc-options: + -Werror + build-depends: + base + , bytestring + , cardano-wallet-core + , cardano-wallet-jormungandr + , memory + , hspec + type: + exitcode-stdio-1.0 + hs-source-dirs: + test/unit + main-is: + Main.hs + other-modules: + Cardano.Wallet.Binary.JormungandrSpec + Spec diff --git a/lib/jormungandr/src/Cardano/Environment.hs b/lib/jormungandr/src/Cardano/Environment.hs new file mode 100644 index 00000000000..9dc4c4fcda0 --- /dev/null +++ b/lib/jormungandr/src/Cardano/Environment.hs @@ -0,0 +1,166 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE TypeApplications #-} + +-- | +-- Copyright: © 2018-2019 IOHK +-- License: MIT +-- +-- This module contains static configuration parameters. Rather than providing +-- and carrying around a configuration file through the application, we resolve +-- configuration data at runtime using the available environment. +-- +-- This gives us a flexible and portable approach to software configuration, and +-- remove some pain from the development perspective. Prior to starting, the +-- wallet is expected to have a few configuration parameter available. One may +-- rely on a `.env` file to bundle configuration settings together for a given +-- target environment. + +module Cardano.Environment + ( + -- * Networking + Network(..) + , network + , ProtocolMagic(..) + , protocolMagic + + -- * Internals + , ErrMissingOrInvalidEnvVar(..) + , unsafeLookupEnv + ) where + +import Prelude + +import Control.Exception + ( Exception (..), throwIO ) +import Data.Int + ( Int32 ) +import Data.Text + ( Text ) +import Data.Text.Class + ( FromText (..), TextDecodingError (..), ToText (..) ) +import Fmt + ( Buildable (..), nameF, padLeftF, pretty ) +import GHC.Generics + ( Generic ) +import System.Environment + ( getProgName, lookupEnv ) +import System.IO.Unsafe + ( unsafePerformIO ) + +import qualified Data.Text as T + + +-- | Fatal exception thrown when a required ENV var is missing upon start-up. +data ErrMissingOrInvalidEnvVar = ErrMissingOrInvalidEnvVar + { name :: String + , command :: String + , additionalContext :: Maybe (String, TextDecodingError) + } + +instance Show ErrMissingOrInvalidEnvVar where + show = displayException + +-- | Produces a nice terminal output so that the error is very readable. +-- +-- @ +-- $ NETWORK=patate cardano-wallet-launcher +-- Starting... +-- cardano-wallet-launcher: Missing or invalid ENV var: +-- +-- ENV[NETWORK] = patate +-- | +-- | +-- *--> patate is neither "mainnet", "testnet" nor "staging" +-- +-- @ +-- +-- @ +-- $ cardano-wallet-launcher +-- Starting... +-- cardano-wallet-launcher: Missing or invalid ENV var: +-- +-- ENV[NETWORK] = ? +-- +-- What about trying to provide a valid ENV var `NETWORK=value cardano-wallet-launcher` ? +-- @ +instance Exception ErrMissingOrInvalidEnvVar where + displayException (ErrMissingOrInvalidEnvVar n cmd ctx) = pretty $ mempty + <> nameF "Missing or invalid ENV var" + ( "\n ENV[" <> build n <> "] = " <> ctxF ) + where + ctxF = case ctx of + Nothing -> "?" + <> "\n\nWhat about trying to provide a valid ENV var " + <> "`" <> build n <> "=value " <> build cmd <> "` ?" + Just (v, err) -> + let + pad = length n + (length v `div` 2) + 11 + in + build v + <> "\n " <> padLeftF @Text pad ' ' "| " + <> "\n " <> padLeftF @Text pad ' ' "| " + <> "\n " <> padLeftF @Text pad ' ' "*--> " + <> build err + +-- | Lookup the environment for a given variable +unsafeLookupEnv + :: FromText a + => String + -> a +unsafeLookupEnv k = unsafePerformIO $ do + cmd <- getProgName + v <- lookupEnv k >>= \case + Just v -> return v + Nothing -> throwIO $ ErrMissingOrInvalidEnvVar + { name = k + , command = cmd + , additionalContext = Nothing + } + case fromText (T.pack v) of + Right a -> return a + Left err -> throwIO $ ErrMissingOrInvalidEnvVar + { name = k + , command = cmd + , additionalContext = Just (v, err) + } + +{------------------------------------------------------------------------------- + Environment +-------------------------------------------------------------------------------} + +-- | Available network options. +data Network = Mainnet | Testnet | Staging + deriving (Generic, Show, Eq, Enum) + +instance FromText Network where + fromText = \case + "mainnet" -> Right Mainnet + "testnet" -> Right Testnet + "staging" -> Right Staging + s -> Left $ TextDecodingError $ T.unpack s + <> " is neither \"mainnet\", \"testnet\" nor \"staging\"." + +instance ToText Network where + toText = \case + Mainnet -> "mainnet" + Testnet -> "testnet" + Staging -> "staging" + +-- | Get the current target 'Network' from the Environment. +-- +-- Throws a runtime exception is the ENV var isn't set or, is invalid. +network :: Network +network = + unsafeLookupEnv "NETWORK" +{-# NOINLINE network #-} + +newtype ProtocolMagic = ProtocolMagic Int32 + deriving (Generic, Show) + +-- | Get the 'ProtocolMagic' corresponding to a given 'Network'. +protocolMagic :: Network -> ProtocolMagic +protocolMagic = \case + Mainnet -> ProtocolMagic 764824073 + Staging -> ProtocolMagic 633343913 + Testnet -> ProtocolMagic 1097911063 diff --git a/lib/jormungandr/src/Cardano/Wallet/Binary/Jormungandr.hs b/lib/jormungandr/src/Cardano/Wallet/Binary/Jormungandr.hs new file mode 100644 index 00000000000..b41fec73eb7 --- /dev/null +++ b/lib/jormungandr/src/Cardano/Wallet/Binary/Jormungandr.hs @@ -0,0 +1,12 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE RankNTypes #-} + +-- | +-- Copyright: © 2018-2019 IOHK +-- License: MIT +-- +-- The format is for the Shelley era as implemented by the Jörmungandr node. + +module Cardano.Wallet.Binary.Jormungandr + ( + ) where diff --git a/lib/jormungandr/src/Cardano/Wallet/Compatibility/Jormungandr.hs b/lib/jormungandr/src/Cardano/Wallet/Compatibility/Jormungandr.hs new file mode 100644 index 00000000000..9bf0cbe55ae --- /dev/null +++ b/lib/jormungandr/src/Cardano/Wallet/Compatibility/Jormungandr.hs @@ -0,0 +1,30 @@ +-- | +-- Copyright: © 2018-2019 IOHK +-- License: MIT +-- +-- Contains various implementation decision that are specific to a particular +-- network / protocol. This allows us to easily select a particular backend +-- (Byron, Shelley-Rust, Shelley-Haskell) and isolate the bits that vary between +-- those backends. + +module Cardano.Wallet.Compatibility.Jormungandr + ( -- * Target + Jormungandr + ) where + +import Prelude + +import Cardano.Wallet.Primitive.AddressDerivation + ( KeyToAddress (..) ) +import Cardano.Wallet.Primitive.Types + ( TxId (..) ) + +-- | A type representing the Jormungandr as a network target. This has an +-- influence on binary serializer & network primitives. See also 'TxId' +data Jormungandr + +instance TxId Jormungandr where + txId = undefined + +instance KeyToAddress Jormungandr where + keyToAddress = undefined diff --git a/lib/jormungandr/src/Cardano/Wallet/Transaction/Jormungandr.hs b/lib/jormungandr/src/Cardano/Wallet/Transaction/Jormungandr.hs new file mode 100644 index 00000000000..33ab4003852 --- /dev/null +++ b/lib/jormungandr/src/Cardano/Wallet/Transaction/Jormungandr.hs @@ -0,0 +1,19 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE RankNTypes #-} + +module Cardano.Wallet.Transaction.Jormungandr + ( newTransactionLayer + ) where + +import Prelude + +import Cardano.Wallet.Transaction + ( TransactionLayer (..) ) + + +-- | Construct a 'TransactionLayer' compatible with Shelley and 'Jörmungandr' +newTransactionLayer :: TransactionLayer +newTransactionLayer = TransactionLayer + { mkStdTx = error "TODO: See http-bridge as starting point" + , estimateSize = error "TODO: See http-bridge as starting point" + } diff --git a/lib/jormungandr/test/unit/Cardano/Wallet/Binary/JormungandrSpec.hs b/lib/jormungandr/test/unit/Cardano/Wallet/Binary/JormungandrSpec.hs new file mode 100644 index 00000000000..2a5eb1fc889 --- /dev/null +++ b/lib/jormungandr/test/unit/Cardano/Wallet/Binary/JormungandrSpec.hs @@ -0,0 +1,45 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE TypeApplications #-} + +module Cardano.Wallet.Binary.JormungandrSpec + ( spec + ) where + +import Prelude + +import Cardano.Wallet.Binary.Jormungandr + () +import Data.ByteString + ( ByteString ) + +import Cardano.Wallet.Primitive.Types + ( BlockHeader (..), Hash (..), SlotId (..) ) + +import Data.ByteArray.Encoding + ( Base (Base16), convertFromBase ) +import Test.Hspec + ( Spec, describe, shouldBe, xit ) + +{-# ANN spec ("HLint: ignore Use head" :: String) #-} +spec :: Spec +spec = do + describe "Decoding blocks" $ do + xit "should decode a genesis block" $ do + unsafeDeserialiseFromBytes decodeGenesisBlock genesisBlock + `shouldBe` + BlockHeader (SlotId 0 0) (Hash "?") + where + unsafeDeserialiseFromBytes = undefined + decodeGenesisBlock = error "TODO: import from Binary.Jormungandr" + +genesisBlock :: ByteString +genesisBlock = either error id $ convertFromBase @ByteString Base16 + "005200000000009f000000000000000000000000ffadebfecd59d9eaa12e903a\ + \d58100f7c1e35899739c3d05d022835c069d2b4f000000000000000000000000\ + \00000000000000000000000000000000000000000047000048000000005cc1c2\ + \4900810200c200010108000000000000087001410f01840000000a01e030a694\ + \b80dbba2d1b8a4b55652b03d96315c8414b054fa737445ac2d2a865c76002604\ + \0001000000ff0005000006000000000000000000000000000000000000000000\ + \0000000000002c020001833324c37869c122689a35917df53a4f2294a3a52f68\ + \5e05f5f8e53b87e7ea452f000000000000000e" diff --git a/lib/jormungandr/test/unit/Main.hs b/lib/jormungandr/test/unit/Main.hs new file mode 100644 index 00000000000..0ea7abaca0d --- /dev/null +++ b/lib/jormungandr/test/unit/Main.hs @@ -0,0 +1,16 @@ +module Main where + +import Prelude + +import Cardano.Environment + ( network ) +import Test.Hspec.Runner + ( hspecWith ) + +import qualified Spec +import qualified Test.Hspec.Runner as Hspec + +main :: IO () +main = do + network `seq` (return ()) + hspecWith Hspec.defaultConfig Spec.spec diff --git a/lib/jormungandr/test/unit/Spec.hs b/lib/jormungandr/test/unit/Spec.hs new file mode 100644 index 00000000000..5416ef6a866 --- /dev/null +++ b/lib/jormungandr/test/unit/Spec.hs @@ -0,0 +1 @@ +{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=Spec #-} diff --git a/stack.yaml b/stack.yaml index 39625c8a43b..3f28097987f 100644 --- a/stack.yaml +++ b/stack.yaml @@ -6,6 +6,7 @@ packages: - lib/launcher - lib/text-class - lib/http-bridge +- lib/jormungandr extra-deps: - base58-bytestring-0.1.0