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

Fix user facing encoding of stake pool ids (from base16 to bech32). #2055

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
16 changes: 12 additions & 4 deletions lib/core/src/Cardano/Wallet/Api/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ import Cardano.Wallet.Primitive.Types
, WalletBalance (..)
, WalletId (..)
, WalletName (..)
, decodePoolIdBech32
, encodePoolIdBech32
, isValidCoin
, unsafeEpochNo
)
Expand Down Expand Up @@ -1096,9 +1098,11 @@ instance ToJSON ApiByronWalletBalance where
toJSON = genericToJSON defaultRecordTypeOptions

instance FromJSON (ApiT PoolId) where
parseJSON = parseJSON >=> eitherToParser . bimap ShowFmt ApiT . fromText
parseJSON = parseJSON >=> eitherToParser
. bimap ShowFmt ApiT
. decodePoolIdBech32
Comment on lines +1102 to +1103
Copy link
Member

Choose a reason for hiding this comment

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

Request: use 4-space indents.

See #2055 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please provide a formatter or an editor config that works. Otherwise these issues will pop up over and over again. I'm not counting spaces while I code.

Copy link
Member

Choose a reason for hiding this comment

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

@hasufell wrote:

Please provide a formatter or an editor config that works. Otherwise these issues will pop up over and over again.

Regarding automated formatting: Unfortunately our team doesn't use an automated formatter besides stylish-haskell (for imports), but if you feel strongly that we should do, then you could start a discussion in our team channel, and try to convince the team of the benefits. 👍

Regarding an editor config: We do provide one here.

@hasufell wrote:

I'm not counting spaces while I code.

Our team coding standard is actually rather simple in this respect: we just indent each level by 4 spaces. (We make an exception for where clauses, which are indented by 2 spaces.)

Are you facing an issue that makes it hard to indent in this way? If so, we can discuss ways to fix the issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Regarding automated formatting: Unfortunately our team doesn't use an automated formatter besides stylish-haskell (for imports), but if you feel strongly that we should do, then you could start a discussion in our team channel, and try to convince the team of the benefits. +1

I don't have a strong opinion, except that I avoid formatting discussions as much as possible. I'm just saying these things will pop up again if the tooling (formatter or config) doesn't work consistently. I don't think about indentation while coding and I am not counting spaces while doing so.

I also believe developers time is too valuable to count spaces in pull requests (your time and my time). I'll do whatever formatting you want, as long as I'm provided with the tools to do so.

Regarding an editor config: We do provide one here.

I'm using that one and it seems it doesn't work consistently. Help appreciated. Here is my editor config https://gogs.hasufell.de/hasufell/vim-config/src/branch/workman

Are you facing an issue that makes it hard to indent in this way? If so, we can discuss ways to fix the issue.

See above.

Copy link
Member

@jonathanknowles jonathanknowles Aug 25, 2020

Choose a reason for hiding this comment

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

@hasufell wrote:

I'll do whatever formatting you want, as long as I'm provided with the tools to do so.

I'm sorry, I don't have an automated tool to provide you with, otherwise I would. As I mentioned before, if there is a tool that you think we could use, then feel free to discuss it in the team channel. I would happy to help with the discussion!

I don't think about indentation while coding and I am not counting spaces while doing so.
I also believe developers time is too valuable to count spaces in pull requests (your time and my time).

The reason for having a team standard is so that we don't have to waste time during PR reviews debating code style. If we have to discuss this in every PR, it would certainly waste time.

As far as I know, most people in our team just configure their tab key to emit 4 spaces. Then no counting is required. Would that work for you?

Copy link
Member

Choose a reason for hiding this comment

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

@hasufell Just in case there's any doubt, we generally indent code with:

  • 4 spaces per level of nesting.
  • 2 spaces for a where clause.

Example:

launchMissiles trace a b c = do
    missiles <- prepareMissiles
    forM_ missiles $ \missile -> do
        log trace Warning $ MsgMissileLaunch missile        
        launchMissile missile
    pure missiles    
  where
    launchMissile m =
        inializeLauncherModule m
        lightFuse m
    prepareMissiles = do
        missiles <- enumerateMissiles
        verifyMissilesIntact missiles
        pure missiles

Copy link
Contributor Author

@hasufell hasufell Aug 26, 2020

Choose a reason for hiding this comment

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

Which constructs?

As was in my link to the haskell-vim readme.

So my configuration for haskell-vim now is

let g:haskell_indent_if = 0
let g:haskell_indent_case = 4
let g:haskell_indent_let = 4
let g:haskell_indent_where = 6
let g:haskell_indent_before_where = 2
let g:haskell_indent_after_bare_where = 2
let g:haskell_indent_do = 4
let g:haskell_indent_in = 0
let g:haskell_indent_guard = 2

This doesn't play nicely with do I believe. See below.


  • do
foo :: IO Int
foo = do
    x <- pure 1
    do
        pure (2 + x)
  • if
foo :: IO Int
foo =
    if True
    then pure 3
    else pure 2
  • case
foo :: IO Int
foo =
    case True of
        True -> 3
        False -> 2
  • let
foo :: IO Int
foo =
    let x = 3 in
        x + 1

foo :: IO Int
foo =
    let x = 1
    in x + 1
  • guard
foo :: IO Int
foo
  | otherwise = 2
  • where
foo :: IO Int
foo = x + 1
  where
    x = 3

So please either confirm this configuration or suggest an alternative.

Copy link
Member

Choose a reason for hiding this comment

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

I don't see any problem with do above ? Also, guards should be 4-space indented like the rest

let g:haskell_indent_guard = 4

Copy link
Contributor Author

@hasufell hasufell Aug 26, 2020

Choose a reason for hiding this comment

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

The problem with do is if you write something on the same line as do:

foo :: IO Int
foo = do
    x <- pure 1
    do y <- pure 2
        pure (x + y)

This will cause a compile error.

Copy link
Member

@KtorZ KtorZ Aug 26, 2020

Choose a reason for hiding this comment

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

That is arguably a horrible choice of formatting and It's perhaps much better that the compiler fails to parse this :)

hasufell marked this conversation as resolved.
Show resolved Hide resolved
instance ToJSON (ApiT PoolId) where
toJSON = toJSON . toText . getApiT
toJSON = toJSON . encodePoolIdBech32 . getApiT

instance FromJSON ApiWalletDelegationStatus where
parseJSON = genericParseJSON defaultSumTypeOptions
Expand Down Expand Up @@ -1453,12 +1457,16 @@ instance FromHttpApiData ApiPoolId where
| t == "*" =
Right ApiPoolIdPlaceholder
| otherwise =
bimap pretty ApiPoolId (fromText t)
ApiPoolId <$> case fromText t of
Left _ ->
left (T.pack . show . ShowFmt) $ decodePoolIdBech32 t
Right r ->
Right r

instance ToHttpApiData ApiPoolId where
toUrlPiece = \case
ApiPoolIdPlaceholder -> "*"
ApiPoolId pid -> toText pid
ApiPoolId pid -> encodePoolIdBech32 pid
hasufell marked this conversation as resolved.
Show resolved Hide resolved

{-------------------------------------------------------------------------------
Aeson Options
Expand Down
24 changes: 24 additions & 0 deletions lib/core/src/Cardano/Wallet/Primitive/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ module Cardano.Wallet.Primitive.Types
, PoolOwner(..)
, StakeDistribution (..)
, poolIdBytesLength
, decodePoolIdBech32
, encodePoolIdBech32
, StakePoolMetadata (..)
, StakePoolMetadataHash (..)
, StakePoolMetadataUrl (..)
Expand Down Expand Up @@ -694,6 +696,28 @@ instance FromText PoolId where
, "bytes in length."
]

-- | Encode 'PoolId' as Bech32 with "pool" hrp.
encodePoolIdBech32 :: PoolId -> T.Text
hasufell marked this conversation as resolved.
Show resolved Hide resolved
encodePoolIdBech32 =
Bech32.encodeLenient hrp
. Bech32.dataPartFromBytes
. getPoolId
hasufell marked this conversation as resolved.
Show resolved Hide resolved
where
hrp = [Bech32.humanReadablePart|pool|]

-- | Decode a Bech32 encoded 'PoolId'.
decodePoolIdBech32 :: T.Text -> Either TextDecodingError PoolId
decodePoolIdBech32 t =
case fmap Bech32.dataPartToBytes <$> Bech32.decodeLenient t of
Left _ -> Left textDecodingError
Right (_, Just bytes) ->
Right $ PoolId bytes
Right _ -> Left textDecodingError
where
textDecodingError = TextDecodingError $ unwords
[ "Invalid stake pool id: expecting a Bech32 encoded value with human readable part of 'pool'."
hasufell marked this conversation as resolved.
Show resolved Hide resolved
]
jonathanknowles marked this conversation as resolved.
Show resolved Hide resolved

-- | A stake pool owner, which is a public key encoded in bech32 with prefix
-- ed25519_pk.
newtype PoolOwner = PoolOwner { getPoolOwner :: ByteString }
Expand Down
Loading