-
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
Wallet Management Remaining Endpoints: update & update passphrase #249
Conversation
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.
Sweet - questions/comments below...
@@ -144,8 +148,8 @@ newtype WalletPutData = WalletPutData | |||
} deriving (Eq, Generic, Show) | |||
|
|||
data WalletPutPassphraseData = WalletPutPassphraseData | |||
{ oldPassphrase :: !(ApiT (Passphrase "encryption")) | |||
, newPassphrase :: !(ApiT (Passphrase "encryption")) | |||
{ oldPassphrase :: !(ApiT (Passphrase "encryption-old")) |
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.
Are these -old/-new types really needed?
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, this has purely a self-documenting purpose. Like most of our phantom types actually.
-> (Passphrase "encryption-old", Passphrase "encryption-new") | ||
-> Property | ||
walletUpdatePassphraseWrong wallet (xprv, pwd) (old, new) = | ||
pwd /= coerce old ==> monadicIO $ liftIO $ do |
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.
Could the precondition be changed to be an assertion instead? i.e.
attempt `shouldBe` if pwd == coerce old then Left err else Right ()
Same goes for the other properties with preconditions.
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.
Hmmm, could be. But I'd rather have two properties with two opposite pre-conditions than a single one with a variable evaluation. It makes things clearer when a test fail, what exactly is failing.
@@ -461,7 +461,6 @@ definitions: | |||
- balance | |||
- delegation | |||
- name | |||
- passphrase |
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.
Just a question. Does this mean the swagger spec says that's it ok to create a wallet without a passphrase?
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.
It's even stronger than that. It means that ultimately, it's okay to create a wallet without a root private key. We'll come to that soonish.
e666879
to
ae7f1e1
Compare
meta <- _readWalletMeta wid | ||
DB.putWalletMeta db (PrimaryKey wid) (modify meta) | ||
|
||
, updateWalletPassphrase = \wid (old, new) -> do |
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 wonder what happens if there are two requests at the same time in a rece condition event both calling updateWalletPassphrase
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.
There's a DB lock, so ultimately, they'll be sequentialized.
-> ExceptT ErrNoSuchWallet IO () | ||
_attachPrivateKey wid (xprv, pwd) = do | ||
hpwd <- liftIO $ encryptPassphrase pwd | ||
DB.putPrivateKey db (PrimaryKey wid) (xprv, hpwd) |
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.
could this fail due to the race condition?
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.
If there's no wallet? Yes, it would fail with ErrNoSuchWallet
. Could happen if the wallet is deleted before the key gets added. That's okay
and already handled.
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.
MVar
implementation shouldn't. I hope sql version won't as well
ae7f1e1
to
b6c72b4
Compare
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 have few remarks on race condition. Don't have much experience there but it might be worth a look
return () | ||
Just (ApiT wName) -> | ||
liftHandler $ W.updateWallet w wid (\meta -> meta { name = wName }) | ||
getWallet w (ApiT wid) |
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.
hm - could we have race condition between L178 and L179?
- on line L178 wallet gets updated
- another request is made which changes content of the same wid to <something_else>
- on line L179 we return <something_else> which is not expected
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 more details:
- thread A wants to update a wallet to "Foo" but is stoped just before L179
- thread B runs and updates a wallet. It changes
name
to "Bar" - thread A is resumed and it runs L179. As a result it returns "Bar" (but what A expects is tu return "Foo")
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.
ps - its no big deal for wallet name - and in fact request for updating a wallet is not something that will likely be at a race condition situation a lot (I don't see a reason why multiple users would need to change wallet name)
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.
hm - could we have race condition between L178 and L179?
Yes. Could be. Though it doesn't matter much. I mean, the response will be slightly off in the case of concurrent calls. I don't think it's really important for things like metadata as long as, the internal DB state is updated correctly (which is the case with the lock mechanism).
@@ -7,6 +7,7 @@ | |||
{-# LANGUAGE InstanceSigs #-} | |||
{-# LANGUAGE LambdaCase #-} | |||
{-# LANGUAGE MultiParamTypeClasses #-} | |||
{-# LANGUAGE RoleAnnotations #-} |
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.
hm - never used this before
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.
Maybe I'll bring the topic on next week but, we could make more use of coerce
and Coercible
from the base package. This allows for coercing between newtypes that have a same (or compatible) underlying representation. So instead of paying the cost of unwrapping and then re-wrapping a newtype, we can just call coerce
which has no runtime cost as everything is done at compile-time; it's like a special primitive from GHC / base.
In order to do that, GHC needs some extra role
annotation to know whether things can be coerced safely or not.
b6c72b4
to
9b635c5
Compare
Issue Number
#220
Overview
Comments