Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce memory usage of create staked command #4021

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ source-repository-package
tag: ee59880f47ab835dbd73bea0847dab7869fc20d8
--sha256: 1lrzknw765pz2j97nvv9ip3l1mcpf2zr4n56hwlz0rk7wq7ls4cm

source-repository-package
Copy link
Contributor

@Jimbo4350 Jimbo4350 Jul 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think we should duplicate the functions used from hw-lazy. The node has enough dependencies and we need to be stricter about introducing new ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put the functions into Cardano.CLI.IO.Lazy for the moment.

type: git
location: https://github.com/input-output-hk/aeson
tag: be4774468e651d1d512edad278cca7276e978034
--sha256: 12fr5xnr3ax0r5gzwbf4v49yirppgprmvzlfj1ldx4zhcrdf5j7j

constraints:
hedgehog >= 1.0
, bimap >= 0.4.0
Expand Down
3 changes: 2 additions & 1 deletion cardano-api/cardano-api.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ library
, cardano-protocol-tpraos
, cardano-slotting
, cborg
, vector-map
, contra-tracer
, containers
, cryptonite
Expand All @@ -141,6 +140,7 @@ library
, plutus-ledger-api
, prettyprinter
, prettyprinter-configurable
, random
, scientific
, serialise
, small-steps
Expand All @@ -155,6 +155,7 @@ library
, typed-protocols
, unordered-containers >= 0.2.11
, vector
, vector-map
, yaml

library gen
Expand Down
1 change: 1 addition & 0 deletions cardano-api/src/Cardano/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ module Cardano.Api (
castVerificationKey,
castSigningKey,
generateSigningKey,
generateInsecureSigningKey,

-- ** Hashes
-- | In Cardano most keys are identified by their hash, and hashes are
Expand Down
12 changes: 12 additions & 0 deletions cardano-api/src/Cardano/Api/Address.hs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ import Cardano.Api.Script
import Cardano.Api.SerialiseBech32
import Cardano.Api.SerialiseRaw
import Cardano.Api.Utils
import Control.DeepSeq (NFData(..), deepseq)



Expand Down Expand Up @@ -192,6 +193,10 @@ deriving instance Eq (Address addrtype)
deriving instance Ord (Address addrtype)
deriving instance Show (Address addrtype)

instance NFData (Address addrtype) where
rnf = \case
ByronAddress address -> deepseq address ()
ShelleyAddress n pc sr -> deepseq (deepseq (deepseq n pc) sr) ()

instance HasTypeProxy addrtype => HasTypeProxy (Address addrtype) where
data AsType (Address addrtype) = AsAddress (AsType addrtype)
Expand Down Expand Up @@ -337,6 +342,9 @@ data AddressInEra era where
-> Address addrtype
-> AddressInEra era

instance NFData (AddressInEra era) where
rnf (AddressInEra t a) = deepseq (deepseq t a) ()

instance IsCardanoEra era => ToJSON (AddressInEra era) where
toJSON = Aeson.String . serialiseAddress

Expand Down Expand Up @@ -387,6 +395,10 @@ data AddressTypeInEra addrtype era where

deriving instance Show (AddressTypeInEra addrtype era)

instance NFData (AddressTypeInEra addrtype era) where
rnf = \case
ByronAddressInAnyEra -> ()
ShelleyAddressInEra sbe -> deepseq sbe ()

instance HasTypeProxy era => HasTypeProxy (AddressInEra era) where
data AsType (AddressInEra era) = AsAddressInEra (AsType era)
Expand Down
9 changes: 9 additions & 0 deletions cardano-api/src/Cardano/Api/Eras.hs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import Ouroboros.Consensus.Shelley.Eras as Consensus (StandardAllegra,
StandardBabbage, StandardMary, StandardShelley)

import Cardano.Api.HasTypeProxy
import Control.DeepSeq (NFData(..))


-- | A type used as a tag to distinguish the Byron era.
Expand Down Expand Up @@ -306,6 +307,14 @@ data ShelleyBasedEra era where
ShelleyBasedEraAlonzo :: ShelleyBasedEra AlonzoEra
ShelleyBasedEraBabbage :: ShelleyBasedEra BabbageEra

instance NFData (ShelleyBasedEra era) where
rnf = \case
ShelleyBasedEraShelley -> ()
ShelleyBasedEraAllegra -> ()
ShelleyBasedEraMary -> ()
ShelleyBasedEraAlonzo -> ()
ShelleyBasedEraBabbage -> ()

deriving instance Eq (ShelleyBasedEra era)
deriving instance Ord (ShelleyBasedEra era)
deriving instance Show (ShelleyBasedEra era)
Expand Down
14 changes: 14 additions & 0 deletions cardano-api/src/Cardano/Api/Key.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
module Cardano.Api.Key
( Key(..)
, generateSigningKey
, generateInsecureSigningKey
, CastVerificationKeyRole(..)
, CastSigningKeyRole(..)
, AsType(AsVerificationKey, AsSigningKey)
Expand All @@ -21,7 +22,9 @@ import Cardano.Api.Hash
import Cardano.Api.HasTypeProxy
import Cardano.Api.SerialiseRaw
import Cardano.Api.SerialiseTextEnvelope
import System.Random (StdGen)

import qualified System.Random as Random

-- | An interface for cryptographic keys used for signatures with a 'SigningKey'
-- and a 'VerificationKey' key.
Expand Down Expand Up @@ -67,6 +70,17 @@ generateSigningKey keytype = do
seedSize = deterministicSigningKeySeedSize keytype


generateInsecureSigningKey
:: (Key keyrole, SerialiseAsRawBytes (SigningKey keyrole))
=> StdGen
-> AsType keyrole
-> IO (SigningKey keyrole, StdGen)
generateInsecureSigningKey g keytype = do
let (bs, g') = Random.genByteString (fromIntegral $ deterministicSigningKeySeedSize keytype) g
case deserialiseFromRawBytes (AsSigningKey keytype) bs of
Just key -> return (key, g')
Nothing -> error "generateInsecureSigningKey: Unable to generate insecure key"

instance HasTypeProxy a => HasTypeProxy (VerificationKey a) where
data AsType (VerificationKey a) = AsVerificationKey (AsType a)
proxyToAsType _ = AsVerificationKey (proxyToAsType (Proxy :: Proxy a))
Expand Down
5 changes: 3 additions & 2 deletions cardano-api/src/Cardano/Api/KeysShelley.hs
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,9 @@ instance HasTypeProxy StakeKey where

instance Key StakeKey where

newtype VerificationKey StakeKey =
StakeVerificationKey (Shelley.VKey Shelley.Staking StandardCrypto)
newtype VerificationKey StakeKey = StakeVerificationKey
{ unStakeVerificationKey :: Shelley.VKey Shelley.Staking StandardCrypto
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I am always in favour of added an accessor to a newtype. If its there and no one uses it, its not a big deal (especially with a totally un-ambiguous name like this), but when its needed having it already there is a huge win IMO.

}
deriving stock (Eq)
deriving newtype (ToCBOR, FromCBOR)
deriving anyclass SerialiseAsCBOR
Expand Down
4 changes: 2 additions & 2 deletions cardano-api/src/Cardano/Api/TxBody.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2680,8 +2680,8 @@ getByronTxBodyContent (Annotated Byron.UnsafeTx{txInputs, txOutputs} _) =
txScriptValidity = TxScriptValidityNone
}

makeShelleyTransactionBody :: ()
=> ShelleyBasedEra era
makeShelleyTransactionBody
:: ShelleyBasedEra era
-> TxBodyContent BuildTx era
-> Either TxBodyError (TxBody era)
makeShelleyTransactionBody era@ShelleyBasedEraShelley
Expand Down
4 changes: 4 additions & 0 deletions cardano-cli/cardano-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ library
Cardano.CLI.Byron.UpdateProposal
Cardano.CLI.Byron.Vote

Cardano.CLI.IO.Lazy

Cardano.CLI.Shelley.Commands
Cardano.CLI.Shelley.Key
Cardano.CLI.Shelley.Orphans
Expand Down Expand Up @@ -135,6 +137,7 @@ library
, ouroboros-network
, parsec
, prettyprinter
, random
, cardano-ledger-shelley
, set-algebra
, split
Expand All @@ -143,6 +146,7 @@ library
, time
, transformers
, transformers-except
, unliftio-core
, utf8-string
, vector
, yaml
Expand Down
70 changes: 70 additions & 0 deletions cardano-cli/src/Cardano/CLI/IO/Lazy.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Cardano.CLI.IO.Lazy
( replicateM
, sequenceM
, traverseM
, traverseStateM
, forM
, forStateM
) where

import Control.Applicative (Applicative((<*>), pure), (<$>))
import Control.Monad (Monad(..))
import Control.Monad.IO.Unlift (MonadIO(liftIO), MonadUnliftIO, askUnliftIO, UnliftIO(unliftIO))
import Data.Function (($), (.), flip)
import Data.Int (Int)
import System.IO (IO)

import qualified Data.List as L
import qualified System.IO.Unsafe as IO

replicateM :: MonadUnliftIO m => Int -> m a -> m [a]
replicateM n f = sequenceM (L.replicate n f)

sequenceM :: MonadUnliftIO m => [m a] -> m [a]
sequenceM as = do
f <- askUnliftIO
liftIO $ sequenceIO (L.map (unliftIO f) as)

-- | Traverses the function over the list and produces a lazy list in a
-- monadic context.
--
-- It is intended to be like the "standard" 'traverse' except
-- that the list is generated lazily.
traverseM :: MonadUnliftIO m => (a -> m b) -> [a] -> m [b]
traverseM f as = do
u <- askUnliftIO
liftIO $ IO.unsafeInterleaveIO (go u as)
where
go _ [] = pure []
go !u (v:vs) = do
!res <- unliftIO u (f v)
rest <- IO.unsafeInterleaveIO (go u vs)
pure (res:rest)

traverseStateM :: forall m s a b. MonadUnliftIO m => s -> (s -> a -> m (s, b)) -> [a] -> m [b]
traverseStateM s f as = do
u <- askUnliftIO
liftIO $ IO.unsafeInterleaveIO (go s u as)
where
go :: s -> UnliftIO m -> [a] -> IO [b]
go _ _ [] = pure []
go t !u (v:vs) = do
(t', !res) <- unliftIO u (f t v)
rest <- IO.unsafeInterleaveIO (go t' u vs)
pure (res:rest)

forM :: MonadUnliftIO m => [a] -> (a -> m b) -> m [b]
forM = flip traverseM

forStateM :: MonadUnliftIO m => s -> [a] -> (s -> a -> m (s, b)) -> m [b]
forStateM s as f = traverseStateM s f as

-- Internal
sequenceIO :: [IO a] -> IO [a]
sequenceIO = IO.unsafeInterleaveIO . go
where go :: [IO a] -> IO [a]
go [] = return []
go (fa:fas) = (:) <$> fa <*> IO.unsafeInterleaveIO (go fas)
7 changes: 7 additions & 0 deletions cardano-cli/src/Cardano/CLI/Shelley/Key.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ module Cardano.CLI.Shelley.Key

, PaymentVerifier(..)
, StakeVerifier(..)

, generateKeyPair
) where

import Cardano.Prelude
Expand Down Expand Up @@ -481,3 +483,8 @@ readVerificationKeyOrHashOrTextEnvFile asType verKeyOrHashOrFile =
eitherVk <- readVerificationKeyOrTextEnvFile asType vkOrFile
pure (verificationKeyHash <$> eitherVk)
VerificationKeyHash vkHash -> pure (Right vkHash)

generateKeyPair :: Key keyrole => AsType keyrole -> IO (VerificationKey keyrole, SigningKey keyrole)
generateKeyPair asType = do
skey <- generateSigningKey asType
return (getVerificationKey skey, skey)
Loading