-
Notifications
You must be signed in to change notification settings - Fork 220
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
Join drep endpoint #4693
Join drep endpoint #4693
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.
Thank you! 😊
The functionality seems to work, but I request a different separation of concerns for the modules Cardano.Wallet.Delegation
and Cardano.Wallet.IO.Delegation
.
handleVoteRequest | ||
:: WalletLayer IO s | ||
-> DRep | ||
-> IO Tx.VotingAction | ||
handleVoteRequest ctx drep = do | ||
(vAction, votingRequest) <- voteAction ctx drep | ||
(Write.PParamsInAnyRecentEra era _, _) | ||
<- W.readNodeTipStateForTxWrite netLayer | ||
|
||
either (throwIO . ExceptionVoting) pure | ||
(WD.guardOnlyVoting era $ toDrepEnriched votingRequest) | ||
pure vAction | ||
where | ||
toDrepEnriched NotVotedYet = Nothing | ||
toDrepEnriched VotedSameAsBefore = Just (True, drep) | ||
toDrepEnriched VotedDifferently = Just (False, drep) | ||
|
||
netLayer = ctx ^. networkLayer |
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.
This function is okay, but harder to understand than necessary — in particular, it's not clear what exactly toDrepEnrichted
is supposed to be doing. Could you remove this function (handleVoteRequest
) and structure the function joinDRep
similar to the function quitStakePool
instead?
In other words, I would like you to structure the code in the following way:
joinDRep — IO, collects relevant parameter values, calls
joinDRepVotingAction — IO, provides additional parameter values (if necessary), calls
WD.joinDRepVotingAction — *pure*, computes a result based on all parameter values.
The idea is that the functions joinDRep
and joinDRepVotingAction
are responsible for providing sufficient parameter values to compute the result, but the actual computation of the result (= the Either ErrCannotJoin Tx.VotingAction
is contained within the pure function. In other words, the concern of figuring out what the vote action should be — if any — should be entirely confined to the definition of the pure function WD.joinDRepVotingAction
.
In contrast, at the moment, this function uses toDRepEnriched
to package some intermediate computation and hands it off to the function WD.guardOnlyVoting
in a different module, but the meaning of the intermediate data format Maybe (Bool, DRep)
is not apparent from the type signatures and function names. The logic becomes much clear if:
- Use pure functions to compute the result.
- Keep the computation of the result to a single module
Could you change this?
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.
sounds reasonable! done
7883d9d
to
9aec031
Compare
9078527
to
ff52060
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.
Thank you! 😊
With the improved separation of concerns for joinDRep
, we can now perform a further simplification in Cardano.Wallet.Delegation
— good to merge after that.
(In principle, the same considerations apply to the Cardano.Wallet.IO.Delegation.joinStakePool
function, but let's leave this for a future pull request when we need to touch this area of the code again.)
guardOnlyVoting | ||
:: Write.IsRecentEra era | ||
=> Write.RecentEra era | ||
-> (Bool,DRep) | ||
-> Either ErrCannotVote () | ||
guardOnlyVoting era votingSameAgain = do | ||
when (fst votingSameAgain) $ | ||
Left $ ErrAlreadyVoted $ snd votingSameAgain | ||
|
||
case era of | ||
Write.RecentEraBabbage -> | ||
Left ErrWrongEra | ||
Write.RecentEraConway -> | ||
Right () | ||
|
||
joinDRepVotingAction | ||
:: Write.IsRecentEra era | ||
=> Write.RecentEra era | ||
-> DRep | ||
-> W.WalletDelegation | ||
-> Bool | ||
-> Either ErrCannotVote Tx.VotingAction | ||
joinDRepVotingAction era action dlg stakeKeyIsRegistered = | ||
second (const vAction) $ guardOnlyVoting era votingRequest | ||
where | ||
isDRepSame (W.Voting drep) = drep == action | ||
isDRepSame (W.DelegatingVoting _ drep) = drep == action | ||
isDRepSame _ = False | ||
|
||
isSameNext (W.WalletDelegationNext _ deleg) = isDRepSame deleg | ||
|
||
sameWalletDelegation (W.WalletDelegation current coming) = | ||
isDRepSame current || any isSameNext coming | ||
|
||
(vAction, votingRequest) = | ||
if stakeKeyIsRegistered | ||
then (Tx.Vote action, (sameWalletDelegation dlg, action)) | ||
else (Tx.VoteRegisteringKey action, (sameWalletDelegation dlg,action)) |
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.
guardOnlyVoting | |
:: Write.IsRecentEra era | |
=> Write.RecentEra era | |
-> (Bool,DRep) | |
-> Either ErrCannotVote () | |
guardOnlyVoting era votingSameAgain = do | |
when (fst votingSameAgain) $ | |
Left $ ErrAlreadyVoted $ snd votingSameAgain | |
case era of | |
Write.RecentEraBabbage -> | |
Left ErrWrongEra | |
Write.RecentEraConway -> | |
Right () | |
joinDRepVotingAction | |
:: Write.IsRecentEra era | |
=> Write.RecentEra era | |
-> DRep | |
-> W.WalletDelegation | |
-> Bool | |
-> Either ErrCannotVote Tx.VotingAction | |
joinDRepVotingAction era action dlg stakeKeyIsRegistered = | |
second (const vAction) $ guardOnlyVoting era votingRequest | |
where | |
isDRepSame (W.Voting drep) = drep == action | |
isDRepSame (W.DelegatingVoting _ drep) = drep == action | |
isDRepSame _ = False | |
isSameNext (W.WalletDelegationNext _ deleg) = isDRepSame deleg | |
sameWalletDelegation (W.WalletDelegation current coming) = | |
isDRepSame current || any isSameNext coming | |
(vAction, votingRequest) = | |
if stakeKeyIsRegistered | |
then (Tx.Vote action, (sameWalletDelegation dlg, action)) | |
else (Tx.VoteRegisteringKey action, (sameWalletDelegation dlg,action)) | |
joinDRepVotingAction | |
:: Write.IsRecentEra era | |
=> Write.RecentEra era | |
-> DRep | |
-> W.WalletDelegation | |
-> Bool | |
-> Either ErrCannotVote Tx.VotingAction | |
joinDRepVotingAction era targetDRep dlg stakeKeyIsRegistered = do | |
guardEraIsConway era | |
when (sameWalletDelegation dlg) $ | |
Left $ ErrAlreadyVoted $ targetDRep | |
pure votingAction | |
where | |
isDRepSame (W.Voting drep) = drep == targetDRep | |
isDRepSame (W.DelegatingVoting _ drep) = drep == targetDRep | |
isDRepSame _ = False | |
isSameNext (W.WalletDelegationNext _ deleg) = isDRepSame deleg | |
sameWalletDelegation (W.WalletDelegation current coming) = | |
isDRepSame current || any isSameNext coming | |
guardEraIsConway Write.RecentEraBabbage = Left WrongEra | |
guardEraIsConway Write.RecentEraConway = Right () | |
votingAction = | |
if stakeKeyIsRegistered | |
then Tx.Vote targetDRep | |
else Tx.VoteRegisteringKey targetDRep |
… and after separating the concerns into a single, we can now merge the definitions of the two functions and get rid of the (Bool,DRep)
intermediate type while also making the logic more clear. 🤓
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.
good hint. Done!
ff52060
to
f642da2
Compare
…he work accomplished in this PR. Before you submit, don't forget to: CODE-OF-CONDUCT.md CONTRIBUTING.md LICENSE MAINTAINERS.md README.md cabal.project configs docker-compose.yml docs flake.lock flake.nix floskell.json fourmolu.yaml hie-direnv.yaml justfile lib nix prototypes reports run scripts specifications test touch.me.CI weeder.dhall Make sure the GitHub PR fields are correct: ✓ Set a good Title for your PR. ✓ Assign yourself to the PR. ✓ Assign one or more reviewer(s). ✓ Link to a Jira issue, and/or other GitHub issues or PRs. ✓ In the PR description delete any empty sections and all text commented in <!--, so that this text does not appear in merge commit messages. CODE-OF-CONDUCT.md CONTRIBUTING.md LICENSE MAINTAINERS.md README.md cabal.project configs docker-compose.yml docs flake.lock flake.nix floskell.json fourmolu.yaml hie-direnv.yaml justfile lib nix prototypes reports run scripts specifications test touch.me.CI weeder.dhall Don't waste reviewers' time: ✓ If it's a draft, select the Create Draft PR option. ✓ Self-review your changes to make sure nothing unexpected slipped through. CODE-OF-CONDUCT.md CONTRIBUTING.md LICENSE MAINTAINERS.md README.md cabal.project configs docker-compose.yml docs flake.lock flake.nix floskell.json fourmolu.yaml hie-direnv.yaml justfile lib nix prototypes reports run scripts specifications test touch.me.CI weeder.dhall Try to make your intent clear: ✓ Write a good Description that explains what this PR is meant to do. ✓ Jira will detect and link to this PR once created, but you can also link this PR in the description of the corresponding Jira ticket. ✓ Highlight what Testing you have done. ✓ Acknowledge any changes required to the Documentation. --> - [x] Swagger updated - [x] Api scaffolding, Api types, Api errors - [x] Adding Http.Shelley.Server joinDRep - [x] Adding IO Deleg functions - [x] Adding Delegation's guard - [x] Checking that error is emitted when used in Babbage - [x] Checking we can vote, re-vote and emit error when voting the same in the absence of pool delegation in Conway - [x] Checking we can vote, re-vote and emit error when voting the same in the presence of pool delegation in Conway ### Comments <!-- Additional comments, links, or screenshots to attach, if any. --> ### Issue Number adp-3383 <!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles. Note: Jira issues of the form ADP- will be auto-linked. --> Source commit: 8fb09f4
Comments
Issue Number
adp-3383