-
Notifications
You must be signed in to change notification settings - Fork 217
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
Port mnemonic module #47
Conversation
be8da3e
to
4661019
Compare
4661019
to
2ec79d3
Compare
deriving (Show) | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of extra blank lines here! Perhaps just have one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/Cardano/Wallet/Mnemonic.hs
Outdated
:: Basement.String | ||
-> Text | ||
fromUtf8String = | ||
pack . Basement.toList |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Writing functions this way is going to use a lot of vertical space. While it's definitely good to wrap once the 80 character limit is exceeded, I think it's not required here.
Perhaps write the above pair of functions like this:
toUtf8String :: Text -> Basement.String
toUtf8String = Basement.fromString . unpack
fromUtf8String :: Basement.String -> Text
fromUtf8String = pack . Basement.toList
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I sticked to the types convention , but readjusted definition as requested
src/Cardano/Wallet/Mnemonic.hs
Outdated
Basement.toBytes Basement.UTF8 . mnemonicSentenceToString Dictionary.english | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to leave so much vertical space between functions. One blank line is really enough! :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/Cardano/Wallet/Mnemonic.hs
Outdated
|
||
module Cardano.Wallet.Mnemonic | ||
( | ||
-- * Types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should avoid variable length indentation here, and use a fixed-width indentation here (4 characters).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, let's indent module exports by 4 chars only 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
src/Cardano/Wallet/Mnemonic.hs
Outdated
|
||
import Prelude | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No blank line required here. From the coding guidelines.
in order to maximise readability, imports should be grouped into two groups, separated by a blank newline.
- Explicit imports
- Qualified imports
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the point. import Prelude is the only implicit import why it is standing separate. Then, explicit and quantified related groups go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see in every src file this convention
src/Cardano/Wallet/Mnemonic.hs
Outdated
|
||
-- | The initial seed has to be vector or length multiple of 4 bytes and shorter | ||
-- than 64 bytes. Not that this is good for testing or examples, but probably | ||
-- not for generating truly random Mnemonic words. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small typo? Perhaps this should be:
"Note that this is good for testing or examples, but probably not for generating truly random Mnemonic words."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
corrected
|
||
|
||
newtype MnemonicException csz = | ||
UnexpectedEntropyError (EntropyError csz) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does it mean to have an UnexpectedEntropyError
? Perhaps add a comment here with an explanation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added the explanation
src/Cardano/Wallet/Mnemonic.hs
Outdated
= ErrMnemonicWords MnemonicWordsError | ||
| ErrEntropy (EntropyError csz) | ||
| ErrDictionary DictionaryError | ||
| ErrForbidden |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do these errors mean? I recommend adding some comments here! :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added the explanation
cardano-wallet.cabal
Outdated
, cborg | ||
, containers | ||
, cryptonite | ||
, data-default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not, we don't need this. A plain defaultWhatever
function is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed data-default
cardano-wallet.cabal
Outdated
@@ -47,6 +53,7 @@ library | |||
, text | |||
, time-units | |||
, transformers | |||
, QuickCheck |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No QuickCheck / Arbitrary instances in the source please 🙏
Those only makes sense during testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
corrected
cardano-wallet.cabal
Outdated
, cardano-wallet | ||
, aeson | ||
hs-source-dirs: | ||
src/Cardano/Wallet/Mnemonic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All executables should be located in app/<executable-sub-folder>
. Let's try to stick with that 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added the executable to app/mnemonic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for porting this 👍
A few minor adjustments to make sure it fits with our current style and that we don't introduce some dependencies.
src/Cardano/Wallet/Mnemonic.hs
Outdated
|
||
module Cardano.Wallet.Mnemonic | ||
( | ||
-- * Types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, let's indent module exports by 4 chars only 👍
src/Cardano/Wallet/Mnemonic.hs
Outdated
[ mnemonicToSentence (def @(Mnemonic 12)) | ||
] | ||
in | ||
any (constEq bytes) forbiddenMnemonics |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also get rid of this one and make sure (as it's now in the spec) that the mnemonics from the documentation represent invalid mnemonics (so that we don't have to have an extra hard-coded mnemonic here..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the api spec we have (Mnemonic 15) - you mean - put the exact example from the spec and correct the affected tests, right? I assume so (please correct me if I am wrong)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, not check for forbidden mnemonics. They won't be needed if the mnemonic we put in the documentation is invalid (so by essence, it can't be used) such that we can remove all this logic from our way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, added respective test to make sure mnemonic example from API is invalid:
114 it "Mnemonic from Api is invalid" $ do
115 let mnemonicFromApi =
116 "[squirrel,material,silly,twice,direct,slush,pistol,razor,become,junk,kingdom,flee,squirrel,silly,twice]"
117 (mkMnemonic @15 . extractWords) mnemonicFromApi `shouldSatisfy` isLeft
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In detail it gives:
Left (ErrEntropy (ErrInvalidEntropyChecksum (Checksum 25) (Checksum 26)))
src/Cardano/Wallet/Mnemonic.hs
Outdated
import Data.Proxy | ||
( Proxy (..) ) | ||
import Data.Text | ||
( Text, pack, unpack ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pack
and unpack
are ambiguous (same name in all ByteString
packages), so let's use qualified imports for them 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
( when, (>=>) ) | ||
import Control.Monad.Catch | ||
( throwM ) | ||
import Crypto.Encoding.BIP39 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use explicit imports here 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added explicit imports
main = do | ||
backupPhrase <- generateBackupPhrase | ||
let backupPhraseString = backupPhraseToString backupPhrase | ||
putStrLn backupPhraseString |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor note: would be better to actually output a Text
or a ByteString
here. In practice, we probably never wants to output strings. They are inefficient (list of chars) and don't play well in multi-thread contexts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
used Text
src/Cardano/Wallet/Mnemonic.hs
Outdated
. map (fromUtf8String . dictionaryIndexToWord Dictionary.english) | ||
. unListN | ||
. mnemonicSentenceToListN | ||
. mnemonicToSentence |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest not to bring any JSON dependencies at this stage and provide instead, serialization combinators that may be use to define JSON instances where it's relevant.
mnemonicToText :: Mnemonic mw -> [Text]
mnemonicToText = ...
-- or
unMnemonic :: Mnemonic mw -> [Text]
unMnemonic = ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added mnemonicToText
because used in executable. But left aeson as they are used in the tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, the Aeson tests should also be removed 👍
They will probably be part of the API tests, but that's the responsibility of the API layer, not this module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aeson tests and ToJSON, FromJSON instances removed
( length ) | ||
|
||
|
||
import Cardano.Wallet.Mnemonic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explicit imports here 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
|
||
import Prelude hiding | ||
( length ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not hide length, but rather use a qualified import on Data.ByteString
for that 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
putStrLn backupPhraseString | ||
|
||
backupPhraseToString :: Mnemonic 12 -> String | ||
backupPhraseToString backupPhrase = show $ encode backupPhrase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The show
, instead of unpack, is a change in behaviour.
stack exec cardano-generate-mnemonic
"[\"gaze\",\"envelope\",\"submit\",\"umbrella\",\"diesel\",\"spirit\",\"twelve\",\"tonight\",\"arena\",\"salute\",\"gallery\",\"seminar\"]"
vs
cardano-generate-mnemonic
["moral","glass","grain","sure","weather","awful","scorpion","electric","vanish","injury","few","shell"]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now it is ok:
[pawel@arch cardano-wallet]$ stack exec cardano-generate-mnemonic
["grant","fan","matter","receive","shy","flash","buyer","worth","crater","interest","noble","pink","nurse","budget","pave"]
2ec79d3
to
0f88116
Compare
Complied with all remarks (hope so), rebased and squashed |
0f88116
to
dee07aa
Compare
[16] mnemonic module and unit tests working properly [16] add mnemonic executable [16] weeder and hlint fixes [16] one more hlint suggestion [16] move exec to app directory [16] Review changes [16] Removing aeson and resigning from forbiddenMnemonics
Removed Aeson instances and forbidenMnemonics from Code rebased and squashed. |
Issue Number
#16
Overview
mnemonicToSeed
,mnemonicToAesKey
,blake2b
from main module and adapted tests accordinglyCardano/Wallet/Mnemonic
Mnemonic 15
rather thanMnemonic 12
as default in executable and specMnemonic used in forbiddenNow it works like that:
Comments
cardano-crypto
eitherToParse
looks like below (relying onShow
rather thanBuildable
):