Skip to content

Commit

Permalink
Merge #3830
Browse files Browse the repository at this point in the history
3830: Shared wallets delegation r=paweljakubas a=paweljakubas

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* 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.

* 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.

* 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] sneak delegation action to ctxTx
- [x] refactor constraints in constructSharedTx
- [x] introduce ErrConstructTxStakingInvalid with integration test
- [x] create proper staking credential during tx construction
- [x] introduce script as credential in shelley module
- [x] introduce txStakingTemplate in TxSkeleton
- [x] fee adjustment
- [x] inject delegation script if it is valid
- [x] add emptySharedWalletDelegating and fixtureSharedWalletdelegating
- [x] constructTx with delegation integration test
- [x] account deposit/refunds
- [x] make sure decodeSharedTransaction account deposits/refunds and certificates properly
- [x] extending WitnessCtx in the context of decodeSharedTransaction
- [x] signing mechanism
- [x] show signing in integration testing
- [x] sneaking WitnessCtx in signTransaction
- [x] guarding submission and adding proper integration tests   

### Comments

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number
adp-2602
<!-- 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. -->


Co-authored-by: Pawel Jakubas <[email protected]>
Co-authored-by: Johannes Lund <[email protected]>
  • Loading branch information
3 people authored Apr 17, 2023
2 parents 5767d34 + 0be97dc commit afc576a
Show file tree
Hide file tree
Showing 19 changed files with 918 additions and 223 deletions.
2 changes: 1 addition & 1 deletion lib/wallet/api/http/Cardano/Wallet/Api/Http/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ server byron icarus shelley multisig spl ntp blockchainSource =
(knownPools spl) (getPoolLifeCycleStatus spl)
:<|> signTransaction @_ @_ @_ @'CredFromScriptK apilayer
:<|> decodeSharedTransaction apilayer
:<|> submitSharedTransaction @_ @_ @_ apilayer
:<|> submitSharedTransaction @_ apilayer
:<|>
(\wid txId simpleMetadataFlag ->
getTransaction apilayer wid txId
Expand Down
5 changes: 5 additions & 0 deletions lib/wallet/api/http/Cardano/Wallet/Api/Http/Server/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,11 @@ instance IsServerError ErrConstructTx where
, "'PATCH /shared-wallets/{walletId}/delegation-script-template'"
, "to make it suitable for constructing transactions."
]
ErrConstructTxDelegationInvalid ->
apiError err403 DelegationInvalid $ T.unwords
[ "I cannot construct a delegating transaction for a shared wallet "
, "that is lacking a delegation script template."
]

instance IsServerError ErrGetPolicyId where
toServerError = \case
Expand Down
278 changes: 183 additions & 95 deletions lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions lib/wallet/api/http/Cardano/Wallet/Api/Types/Certificate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ instance ToJSON ApiCertificate where
toJSON = genericToJSON apiCertificateOptions

mkApiAnyCertificate
:: forall n . W.RewardAccount
:: forall n . Maybe W.RewardAccount
-> NonEmpty DerivationIndex
-> W.Certificate
-> ApiAnyCertificate n
Expand Down Expand Up @@ -219,20 +219,20 @@ mkApiAnyCertificate acct' acctPath' = \case
(ApiT poolId')
(ApiT retirementEpoch')

toApiDelCert acct acctPath (W.CertDelegateNone rewardKey) =
if rewardKey == acct then
toApiDelCert acctM acctPath (W.CertDelegateNone rewardKey) =
if Just rewardKey == acctM then
WalletDelegationCertificate $ QuitPool $ NE.map ApiT acctPath
else
DelegationCertificate $ QuitPoolExternal (ApiT rewardKey, Proxy @n)
toApiDelCert acct acctPath (W.CertRegisterKey rewardKey) =
if rewardKey == acct then
toApiDelCert acctM acctPath (W.CertRegisterKey rewardKey) =
if Just rewardKey == acctM then
WalletDelegationCertificate $
RegisterRewardAccount $ NE.map ApiT acctPath
else
DelegationCertificate $
RegisterRewardAccountExternal (ApiT rewardKey, Proxy @n)
toApiDelCert acct acctPath (W.CertDelegateFull rewardKey poolId') =
if rewardKey == acct then
toApiDelCert acctM acctPath (W.CertDelegateFull rewardKey poolId') =
if Just rewardKey == acctM then
WalletDelegationCertificate $
JoinPool (NE.map ApiT acctPath) (ApiT poolId')
else
Expand Down
1 change: 1 addition & 0 deletions lib/wallet/api/http/Cardano/Wallet/Api/Types/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ data ApiErrorInfo
| CreatedMultiaccountTransaction
| CreatedMultidelegationTransaction
| CreatedWrongPolicyScriptTemplate
| DelegationInvalid
| ExistingKeyWitnesses
| ForeignTransaction
| HardenedDerivationRequired
Expand Down
2 changes: 1 addition & 1 deletion lib/wallet/integration/src/Test/Integration/Faucet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2302,7 +2302,7 @@ genRewardAccounts mw =
rootXPrv =
Shelley.generateKeyFromSeed (seed, Nothing) pwd
acctXPrv =
deriveRewardAccount pwd rootXPrv
deriveRewardAccount pwd rootXPrv minBound
in
[getRawKey $ publicKey acctXPrv]

Expand Down
107 changes: 107 additions & 0 deletions lib/wallet/integration/src/Test/Integration/Framework/DSL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ module Test.Integration.Framework.DSL
, emptyByronWalletFromXPrvWith
, rewardWallet
, emptySharedWallet
, emptySharedWalletDelegating
, fundSharedWallet
, fixtureSharedWallet
, fixtureSharedWalletDelegating
, postSharedWallet
, deleteSharedWallet
, getSharedWallet
Expand Down Expand Up @@ -1715,6 +1717,96 @@ emptySharedWallet ctx = do
]
pure $ getFromResponse Prelude.id rPost

emptySharedWalletDelegating
:: forall m. MonadUnliftIO m
=> Context
-> ResourceT m (ApiSharedWallet,ApiSharedWallet)
emptySharedWalletDelegating ctx = do
--cosigner#0
m15txtA <- liftIO $ genMnemonics M15
m12txtA <- liftIO $ genMnemonics M12
let (Right m15A) = mkSomeMnemonic @'[ 15 ] m15txtA
let (Right m12A) = mkSomeMnemonic @'[ 12 ] m12txtA
let passphrase = Passphrase $
BA.convert $ T.encodeUtf8 fixturePassphrase
let indexA = 30
let accXPubDerivedA =
sharedAccPubKeyFromMnemonics m15A (Just m12A) indexA passphrase
--cosigner#1
m15txtB <- liftIO $ genMnemonics M15
m12txtB <- liftIO $ genMnemonics M12
let (Right m15B) = mkSomeMnemonic @'[ 15 ] m15txtB
let (Right m12B) = mkSomeMnemonic @'[ 12 ] m12txtB
let indexB = 40
let accXPubDerivedB =
sharedAccPubKeyFromMnemonics m15B (Just m12B) indexB passphrase

let payloadA = Json [aesonQQ| {
"name": "Shared Wallet",
"mnemonic_sentence": #{m15txtA},
"mnemonic_second_factor": #{m12txtA},
"passphrase": #{fixturePassphrase},
"account_index": "30H",
"payment_script_template":
{ "cosigners":
{ "cosigner#0": #{accXPubDerivedA}
, "cosigner#1": #{accXPubDerivedB}},
"template":
{ "any":
[ "cosigner#0", "cosigner#1" ]
}
},
"delegation_script_template":
{ "cosigners":
{ "cosigner#0": #{accXPubDerivedA}
, "cosigner#1": #{accXPubDerivedB}},
"template":
{ "all":
[ "cosigner#0",
"cosigner#1"
]
}
}
} |]
rPostA <- postSharedWallet ctx Default payloadA
verify (fmap (swapEither . view #wallet) <$> rPostA)
[ expectResponseCode HTTP.status201
]

let payloadB = Json [aesonQQ| {
"name": "Shared Wallet",
"mnemonic_sentence": #{m15txtB},
"mnemonic_second_factor": #{m12txtB},
"passphrase": #{fixturePassphrase},
"account_index": "40H",
"payment_script_template":
{ "cosigners":
{ "cosigner#0": #{accXPubDerivedA}
, "cosigner#1": #{accXPubDerivedB}},
"template":
{ "any":
[ "cosigner#0", "cosigner#1" ]
}
},
"delegation_script_template":
{ "cosigners":
{ "cosigner#0": #{accXPubDerivedA}
, "cosigner#1": #{accXPubDerivedB}},
"template":
{ "all":
[ "cosigner#0",
"cosigner#1"
]
}
}
} |]
rPostB <- postSharedWallet ctx Default payloadB
verify (fmap (swapEither . view #wallet) <$> rPostB)
[ expectResponseCode HTTP.status201
]

pure (getFromResponse Prelude.id rPostA, getFromResponse Prelude.id rPostB)

fundSharedWallet
:: forall (n :: NetworkDiscriminant) m.
( MonadUnliftIO m
Expand Down Expand Up @@ -1781,6 +1873,21 @@ fixtureSharedWallet ctx = do
fundSharedWallet @n ctx faucetUtxoAmt (pure walShared)
return wal

fixtureSharedWalletDelegating
:: forall (n :: NetworkDiscriminant) m.
( MonadUnliftIO m
, MonadFail m
, DecodeStakeAddress n
, DecodeAddress n
, EncodeAddress n )
=> Context
-> ResourceT m (ApiActiveSharedWallet, ApiActiveSharedWallet)
fixtureSharedWalletDelegating ctx = do
(walSharedA@(ApiSharedWallet (Right walA)), ApiSharedWallet (Right walB)) <-
emptySharedWalletDelegating ctx
fundSharedWallet @n ctx faucetUtxoAmt (NE.fromList [walSharedA])
return (walA, walB)

postSharedWallet
:: MonadUnliftIO m
=> Context
Expand Down
Loading

0 comments on commit afc576a

Please sign in to comment.