-
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
Withdrawals in multisig #3925
Withdrawals in multisig #3925
Conversation
d7d4636
to
d21e220
Compare
>>= flip verify | ||
[ expectField | ||
(#balance . #reward) | ||
(`shouldBe` (Quantity 0)) |
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 probably add a check that we have some rewards before withdrawing 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.
This is checked before withdrawal and after withdrawal (should be zero as you underlined above):
1986 eventually "party1: Wallet gets rewards from pool1" $ do
1987 r <- request @ApiWallet ctx (Link.getWallet @'Shared party1) Default Empty
1988 verify r
1989 [ expectField
1990 (#balance . #reward)
1991 (.> (Quantity 0))
1992 ]
1993 eventually "party2: Wallet gets rewards from pool1" $ do
1994 r <- request @ApiWallet ctx (Link.getWallet @'Shared party2) Default Empty
1995 verify r
1996 [ expectField
1997 (#balance . #reward)
1998 (.> (Quantity 0))
1999 ]
[ "I couldn't read a reward account which is required for " | ||
, "withdrawals. Either there is db malfunction or withdrawals " | ||
, "was used for shared wallets missing delegation template." |
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 couldn't read a reward account which is required for " | |
, "withdrawals. Either there is db malfunction or withdrawals " | |
, "was used for shared wallets missing delegation template." | |
[ "Unable to read the reward account required for withdrawals. " | |
, "It appears that the withdrawals feature was utilized for a shared wallet " | |
, "without the corresponding delegation template." |
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
[ "It is regrettable but you've just attempted an operation " | ||
, "that is invalid for this type of wallet. Only new 'Shelley' and " | ||
, "'Shared' wallets can do something with rewards and this one isn't." | ||
] |
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 is regrettable but you've just attempted an operation " | |
, "that is invalid for this type of wallet. Only new 'Shelley' and " | |
, "'Shared' wallets can do something with rewards and this one isn't." | |
] | |
[ "It is regrettable but you've just attempted an operation " | |
, "that is invalid for this type of wallet. Only new 'Shelley' and " | |
, "'Shared' wallets have the capability to perform actions with rewards, " | |
, "which is not applicable to the current wallet." | |
] |
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
bors try |
tryBuild failed: |
0784414
to
c55c61c
Compare
bors try |
tryBuild succeeded: |
lib/wallet/src/Cardano/Wallet.hs
Outdated
when (isNothing rewardAccountM) $ | ||
throwIO $ ExceptionReadRewardAccount ErrReadRewardAccountMissing |
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 if we can unify the shared vs non-shared branches via:
readRewardAccount
:: forall s. Including '[ShelleyKey, SharedKey] (KeyOf s)
=> DBLayer IO s
-> IO (RewardAccount, XPub, NonEmpty DerivationIndex)
readRewardAccount = do
...
case keyFlavor @(KeyOf s) of
ShelleyKeyS -> ...
SharedKeyS -> ... case ... of
Just _ -> ...
Nothing -> throwIO $ ExceptionReadRewardAccount ErrReadRewardAccountMissing
It does at least look like all callers of readSharedRewardAccount
are throwing in the Nothing
case anyway... Though hiding the Nothing
more would be deceptive.
I suppose it would alternatively be possible to factor out the reading of the reward account somehow.
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 sugestion. done
|
||
sharedOnlyReadRewardAccount | ||
:: forall s | ||
. WalletFlavor s |
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.
Why not enforce that this is a shared wallet with WalletFlavor s ~ SharedWallet
or something similar?
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 followed the shelleyOnlyReadRewardAccount
pattern here. So want unsafe version that emits error if used not with non-shared wallet.
ErrReadRewardAccountMissing -> | ||
apiError err501 MissingRewardAccount $ mconcat |
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.
👌 ErrConstructTxDelegationInvalid
is what users would see
lib/wallet/src/Cardano/Wallet.hs
Outdated
let (rewardAccount, derivationPath) = fromJust rewardAccountM | ||
balance <- getCachedRewardAccountBalance netLayer rewardAccount | ||
pp <- currentProtocolParameters netLayer | ||
return $ case checkRewardIsWorthTxCost txWitnessTag pp era balance of |
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 seems checkRewardIsWorthTxCost
will underestimate the cost of making a withdrawal as it doesn't take the size of the delegation script into account.
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 suppose you could
A
Pass in the delegationTemplate
checkRewardIsWorthTxCost
. We'd then also need to update the logic here https://github.com/input-output-hk/cardano-wallet/blob/ca7eba61eb11b576d6e20a2237955c064ecd2b7a/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs#L1774 which would be antithetical to having estimateTxSize
know the bare minimum to support coin-selection.
B
Define
-- | Upper estimation of the number of bytes needed for a withdrawal.
txRewardWithdrawalSize
:: WalletState s
-> TxSize
which would be more in line with https://input-output.atlassian.net/browse/ADP-3016
C
Do nothing, or raise hard-code limit of 2 * costOfWithdrawal
.
This would likely work fine for most users. Users with large delegation templates could lose money from withdrawals which are too small to be worth it. Although I believe it would be on the order of 0.01 ada, and at most once per epoch... So probably completely 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.
opted for A
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.
Unless you also update the defaultTransactionCtx
in checkRewardIsWorthTxCost
, your changes have no effect
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
lib/wallet/src/Cardano/Wallet.hs
Outdated
rewardAccountM <- readSharedRewardAccount db | ||
when (isNothing rewardAccountM) $ | ||
throwIO $ ExceptionReadRewardAccount ErrReadRewardAccountMissing | ||
let (rewardAccount, derivationPath) = fromJust rewardAccountM |
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.
Again no need for fromJust
, they are a bad sign, and here it's completely avoidable.
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 to unifying readRewardAccount
not valid anymore
if ourRewardAcctM == Just rewardAcct then | ||
constructUnsignedTx networkId (md, []) ttl wdrl | ||
selection delta assetsToBeMinted assetsToBeBurned inpsScripts | ||
stakingScriptM | ||
(Write.shelleyBasedEraFromRecentEra Write.recentEra) | ||
else | ||
constructUnsignedTx networkId (md, []) ttl wdrl | ||
selection delta assetsToBeMinted assetsToBeBurned inpsScripts | ||
Nothing | ||
(Write.shelleyBasedEraFromRecentEra Write.recentEra) |
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 suspect these branches (including _ ->
) and the case
in mkUnsignedTx
could be unified through some one
mkWithdrawal :: wallet flavor or delegationTemplate etc -> Withdrawal -> Cardano.TxWithdrawals build era
rather than having logic spread out.
Could you think about it / have look on how to reduce the complexity 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.
(There seem to be so many "layers" in this module (mkUnsignedTx, mkUnsignedTransaction, constructUnsignedTransaction etc), we should move towards flattening 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.
I tried to use pattern matching but in the end it turn out not to be much easier .... I agree we need to unify and cut those artificial layers - but I would write down separate ticket for that - I am happy to take it.
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, please do if you see a plan of attack
ca7eba6
to
f0561b9
Compare
bors try |
tryBuild failed: |
bors try |
tryBuild failed: |
9f4cfc7
to
2f5106f
Compare
rm debugs
419638e
to
16f0cb4
Compare
bors r+ |
Build succeeded: |
…a=paweljakubas <!-- Detail in a few bullet points the work accomplished in this PR. Before you submit, don't forget to: CODE-OF-CONDUCT.md CODEOWNERS LICENSE README.md bors.toml cabal.project default.nix docker-compose.yml docs flake.lock flake.nix floskell.json hie-direnv.yaml lib nix prototypes reports scripts shell.nix 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 CODEOWNERS LICENSE README.md bors.toml cabal.project default.nix docker-compose.yml docs flake.lock flake.nix floskell.json hie-direnv.yaml lib nix prototypes reports scripts shell.nix 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 CODEOWNERS LICENSE README.md bors.toml cabal.project default.nix docker-compose.yml docs flake.lock flake.nix floskell.json hie-direnv.yaml lib nix prototypes reports scripts shell.nix 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] Added withdrawal support for multisig - [x] Added withdrawal integration test - [x] Added quit integration test - [x] Make sure getTransaction exposes certificates - shown in integration testing ### Comments <!-- Additional comments, links, or screenshots to attach, if any. --> ### Issue Number adp-2604 <!-- 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. --> 3970: Derive arithmetic operations for `{Coin,TokenQuantity}`. r=jonathanknowles a=jonathanknowles ## Summary This PR uses classes defined by the [`monoid-subclasses`](https://hackage.haskell.org/package/monoid-subclasses-1.2.3#readme) library to derive the definitions of all arithmetic operations for the `Coin` and `TokenQuantity` types. This takes advantage of the fact that both `Coin` and `TokenQuantity` have `Semigroup` and `Monoid` instances that are identical to those for `Sum Natural`. Co-authored-by: Pawel Jakubas <[email protected]> Co-authored-by: Piotr Stachyra <[email protected]> Co-authored-by: Jonathan Knowles <[email protected]> Source commit: 8622cfd
Comments
Issue Number
adp-2604