diff --git a/lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs b/lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs index 9b57676a889..4b6243f2075 100644 --- a/lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs +++ b/lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs @@ -191,6 +191,7 @@ import Cardano.Wallet , readPrivateKey , readWalletMeta , transactionLayer + , txWitnessTagForKey , utxoAssumptionsForWallet ) import Cardano.Wallet.Address.Book @@ -538,7 +539,7 @@ import Cardano.Wallet.Registry import Cardano.Wallet.Shelley.Compatibility.Ledger ( toLedger ) import Cardano.Wallet.Shelley.Transaction - ( TxWitnessTag, TxWitnessTagFor (..) ) + ( TxWitnessTag ) import Cardano.Wallet.TokenMetadata ( TokenMetadataClient, fillMetadata ) import Cardano.Wallet.Transaction @@ -1768,7 +1769,6 @@ selectCoins , s ~ SeqState n k , AddressBookIso s , GenChange s - , TxWitnessTagFor k ) => ApiLayer s -> ArgGenChange s @@ -1785,8 +1785,10 @@ selectCoins ctx@ApiLayer {..} argGenChange (ApiT walletId) body = do withdrawal <- body ^. #withdrawal & maybe (pure NoWithdrawal) - (shelleyOnlyMkWithdrawal @s - netLayer (txWitnessTagFor @k) db) + (shelleyOnlyMkWithdrawal + netLayer + (txWitnessTagForKey $ keyOfWallet $ walletFlavor @s) + db) let genChange = W.defaultChangeAddressGen argGenChange let paymentOuts = NE.toList $ addressAmountToTxOut <$> body ^. #payments let txCtx = defaultTransactionCtx @@ -1892,7 +1894,6 @@ selectCoinsForQuit , AddressBookIso s , Seq.SupportsDiscovery n k , DelegationAddress k 'CredFromKeyK - , TxWitnessTagFor k ) => ApiLayer (SeqState n k) -> ApiT WalletId @@ -1902,8 +1903,10 @@ selectCoinsForQuit ctx@ApiLayer{..} (ApiT walletId) = do <- liftIO $ W.readNodeTipStateForTxWrite netLayer withWorkerCtx ctx walletId liftE liftE $ \workerCtx -> liftIO $ do let db = workerCtx ^. typed @(DBLayer IO s) - withdrawal <- W.shelleyOnlyMkSelfWithdrawal @s - netLayer (txWitnessTagFor @k) db + withdrawal <- W.shelleyOnlyMkSelfWithdrawal + netLayer + (txWitnessTagForKey $ keyOfWallet $ walletFlavor @s) + db currentEpochSlotting <- liftIO $ getCurrentEpochSlotting netLayer action <- WD.quitStakePoolDelegationAction db currentEpochSlotting withdrawal @@ -2154,7 +2157,6 @@ postTransactionOld , HardDerivation k , HasNetworkLayer IO ctx , Bounded (Index (AddressIndexDerivationType k) (AddressCredential k)) - , TxWitnessTagFor k , AddressBookIso s , HasDelegation s , IsOurs s Address @@ -2181,8 +2183,11 @@ postTransactionOld ctx@ApiLayer{..} argGenChange (ApiT wid) body = do wdrl <- case body ^. #withdrawal of Nothing -> pure NoWithdrawal Just apiWdrl -> - shelleyOnlyMkWithdrawal @s - netLayer (txWitnessTagFor @k) db apiWdrl + shelleyOnlyMkWithdrawal + netLayer + (txWitnessTagForKey $ keyOfWallet $ walletFlavor @s) + db + apiWdrl let txCtx = defaultTransactionCtx { txWithdrawal = wdrl , txMetadata = md @@ -2340,7 +2345,6 @@ postTransactionFeeOld . ( WalletFlavor s , Excluding '[SharedKey] k , AddressBookIso s - , TxWitnessTagFor k , k ~ KeyOf s , CredFromOf s ~ 'CredFromKeyK ) @@ -2363,8 +2367,11 @@ postTransactionFeeOld ctx@ApiLayer{..} (ApiT walletId) body = do wdrl <- case body ^. #withdrawal of Nothing -> pure NoWithdrawal Just apiWdrl -> - shelleyOnlyMkWithdrawal @s - netLayer (txWitnessTagFor @k) db apiWdrl + shelleyOnlyMkWithdrawal + netLayer + (txWitnessTagForKey $ keyOfWallet $ walletFlavor @s) + db + apiWdrl let outputs = F.toList $ addressAmountToTxOut <$> body ^. #payments minCoins = W.calcMinimumCoinValues walletPP txLayer <$> outputs @@ -2415,8 +2422,8 @@ postTransactionFeeOld ctx@ApiLayer{..} (ApiT walletId) body = do padding = Quantity 20 constructTransaction - :: forall s k n - . (HasSNetworkId n, s ~ SeqState n ShelleyKey, k ~ KeyOf s) + :: forall s n + . (HasSNetworkId n, s ~ SeqState n ShelleyKey) => ApiLayer s -> ArgGenChange s -> IO (Set PoolId) @@ -2462,7 +2469,9 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d withdrawal <- case body ^. #withdrawal of Just SelfWithdraw -> liftIO $ W.shelleyOnlyMkSelfWithdrawal - netLayer (txWitnessTagFor @k) db + netLayer + (txWitnessTagForKey $ keyOfWallet $ walletFlavor @s) + db _ -> pure NoWithdrawal let transactionCtx0 = defaultTransactionCtx @@ -2885,7 +2894,10 @@ constructSharedTransaction withdrawal <- case body ^. #withdrawal of Just SelfWithdraw -> liftIO $ W.mkSelfWithdrawalShared @n - netLayer (txWitnessTagFor @SharedKey) delegationTemplateM db + netLayer + (txWitnessTagForKey SharedKeyS) + delegationTemplateM + db _ -> pure NoWithdrawal when (isNothing delegationTemplateM && isJust delegationRequest) $ @@ -3735,7 +3747,6 @@ listStakeKeys lookupStakeRef ctx@ApiLayer{..} (ApiT wid) = createMigrationPlan :: forall s n k . ( WalletFlavor s - , TxWitnessTagFor k , k ~ KeyOf s , CredFromOf s ~ 'CredFromKeyK , IsOurs s Address @@ -3753,8 +3764,12 @@ createMigrationPlan ctx@ApiLayer{..} withdrawalType (ApiT wid) postData = let db = wrk ^. dbLayer rewardWithdrawal <- case withdrawalType of Nothing -> pure NoWithdrawal - Just pd -> shelleyOnlyMkWithdrawal @s - netLayer (txWitnessTagFor @k) db pd + Just pd -> + shelleyOnlyMkWithdrawal + netLayer + (txWitnessTagForKey $ keyOfWallet $ walletFlavor @s) + db + pd (wallet, _, _) <- handler $ W.readWallet wrk plan <- handler $ W.createMigrationPlan @_ wrk rewardWithdrawal liftHandler @@ -3829,7 +3844,6 @@ migrateWallet :: forall s p k n. ( Bounded (Index (AddressIndexDerivationType k) (AddressCredential k)) , HardDerivation k - , TxWitnessTagFor k , WalletFlavor s , HasDelegation s , k ~ KeyOf s @@ -3856,8 +3870,12 @@ migrateWallet ctx@ApiLayer{..} withdrawalType (ApiT wid) postData = do era <- liftIO $ NW.currentNodeEra netLayer rewardWithdrawal <- case withdrawalType of Nothing -> pure NoWithdrawal - Just pd -> shelleyOnlyMkWithdrawal @s - netLayer (txWitnessTagFor @k) db pd + Just pd -> + shelleyOnlyMkWithdrawal + netLayer + (txWitnessTagForKey $ keyOfWallet $ walletFlavor @s) + db + pd plan <- handler $ W.createMigrationPlan @_ wrk rewardWithdrawal ttl <- liftIO $ W.transactionExpirySlot ti Nothing pp <- liftIO $ NW.currentProtocolParameters netLayer diff --git a/lib/wallet/bench/api-bench.hs b/lib/wallet/bench/api-bench.hs index e004c0fe549..21319df1f57 100644 --- a/lib/wallet/bench/api-bench.hs +++ b/lib/wallet/bench/api-bench.hs @@ -95,7 +95,7 @@ import Cardano.Wallet.Read.NetworkId , withSNetworkId ) import Cardano.Wallet.Shelley.Transaction - ( TxWitnessTagFor (..), newTransactionLayer ) + ( newTransactionLayer ) import Cardano.Wallet.Unsafe ( unsafeRunExceptT ) import Control.Monad @@ -437,7 +437,6 @@ data BenchmarkConfig (n :: NetworkDiscriminant) s = benchmarkWallets :: forall n s results . ( PersistAddressBook s - , TxWitnessTagFor (KeyOf s) , KeyFlavor (KeyOf s) , Buildable results , ToJSON results @@ -489,7 +488,6 @@ withWalletsFromDirectory . ( PersistAddressBook s , WalletFlavor s , k ~ KeyOf s - , TxWitnessTagFor k , KeyFlavor k ) => FilePath diff --git a/lib/wallet/bench/restore-bench.hs b/lib/wallet/bench/restore-bench.hs index c6199eba441..89c20564cd0 100644 --- a/lib/wallet/bench/restore-bench.hs +++ b/lib/wallet/bench/restore-bench.hs @@ -159,7 +159,7 @@ import Cardano.Wallet.Shelley.Compatibility import Cardano.Wallet.Shelley.Network.Node ( withNetworkLayer ) import Cardano.Wallet.Shelley.Transaction - ( TxWitnessTagFor (..), newTransactionLayer ) + ( newTransactionLayer ) import Cardano.Wallet.Transaction ( PreSelection (..), defaultTransactionCtx ) import Cardano.Wallet.Unsafe @@ -184,8 +184,6 @@ import Data.Aeson ( ToJSON (..), genericToJSON, (.=) ) import Data.Functor.Contravariant ( contramap ) -import Data.Kind - ( Type ) import Data.List ( foldl' ) import Data.Proxy @@ -683,14 +681,12 @@ bench_baseline_restoration {- HLINT ignore bench_restoration "Use camelCase" -} bench_restoration - :: forall n (k :: Depth -> Type -> Type) s results. + :: forall n s results. ( IsOurs s RewardAccount , MaybeLight s , PersistAddressBook s , WalletFlavor s - , KeyOf s ~ k , HasSNetworkId n - , TxWitnessTagFor k , Buildable results , ToJSON results , IsOurs s Address diff --git a/lib/wallet/src/Cardano/Wallet.hs b/lib/wallet/src/Cardano/Wallet.hs index b950e947116..b58f43ccfe0 100644 --- a/lib/wallet/src/Cardano/Wallet.hs +++ b/lib/wallet/src/Cardano/Wallet.hs @@ -220,6 +220,7 @@ module Cardano.Wallet , throttle , guardHardIndex , utxoAssumptionsForWallet + , txWitnessTagForKey -- * Logging , WalletWorkerLog (..) @@ -497,6 +498,8 @@ import Cardano.Wallet.Shelley.Compatibility ) import Cardano.Wallet.Shelley.Compatibility.Ledger ( toWallet ) +import Cardano.Wallet.Shelley.Transaction + ( txWitnessTagForKey ) import Cardano.Wallet.Transaction ( DelegationAction (..) , ErrCannotJoin (..) @@ -515,7 +518,7 @@ import Cardano.Wallet.Transaction import Cardano.Wallet.Transaction.Built ( BuiltTx (..) ) import Cardano.Wallet.TxWitnessTag - ( TxWitnessTag ) + ( TxWitnessTag (..) ) import Cardano.Wallet.Write.Tx ( recentEra ) import Cardano.Wallet.Write.Tx.Balance diff --git a/lib/wallet/src/Cardano/Wallet/Address/Derivation/Byron.hs b/lib/wallet/src/Cardano/Wallet/Address/Derivation/Byron.hs index f2ef128faf8..1f5a5657c6e 100644 --- a/lib/wallet/src/Cardano/Wallet/Address/Derivation/Byron.hs +++ b/lib/wallet/src/Cardano/Wallet/Address/Derivation/Byron.hs @@ -74,8 +74,6 @@ import Cardano.Wallet.Primitive.Types.ProtocolMagic ( magicSNetworkId ) import Cardano.Wallet.Read.NetworkId ( SNetworkId (..) ) -import Cardano.Wallet.TxWitnessTag - ( TxWitnessTag (..), TxWitnessTagFor (..) ) import Control.DeepSeq ( NFData ) import Control.Lens @@ -123,10 +121,6 @@ byronKey = lens getKey (\x k -> x { getKey = k }) instance (NFData key, NFData (DerivationPathFrom depth)) => NFData (ByronKey depth key) deriving instance (Show key, Show (DerivationPathFrom depth)) => Show (ByronKey depth key) deriving instance (Eq key, Eq (DerivationPathFrom depth)) => Eq (ByronKey depth key) - -instance TxWitnessTagFor ByronKey where - txWitnessTagFor = TxWitnessByronUTxO - -- | The hierarchical derivation indices for a given level/depth. type family DerivationPathFrom (depth :: Depth) :: Type where -- The root key is generated from the seed. diff --git a/lib/wallet/src/Cardano/Wallet/Address/Derivation/Icarus.hs b/lib/wallet/src/Cardano/Wallet/Address/Derivation/Icarus.hs index 3bc2864b3cb..35199e839d7 100644 --- a/lib/wallet/src/Cardano/Wallet/Address/Derivation/Icarus.hs +++ b/lib/wallet/src/Cardano/Wallet/Address/Derivation/Icarus.hs @@ -77,8 +77,6 @@ import Cardano.Wallet.Read.NetworkId , NetworkDiscriminantCheck (..) , SNetworkId (..) ) -import Cardano.Wallet.TxWitnessTag - ( TxWitnessTag (..), TxWitnessTagFor (..) ) import Control.Arrow ( first, left ) import Control.DeepSeq @@ -137,9 +135,6 @@ icarusKey = iso getKey IcarusKey instance NFData key => NFData (IcarusKey depth key) -instance TxWitnessTagFor IcarusKey where - txWitnessTagFor = TxWitnessByronUTxO - -- | The minimum seed length for 'generateKeyFromSeed' and 'unsafeGenerateKeyFromSeed'. minSeedLengthBytes :: Int minSeedLengthBytes = 16 diff --git a/lib/wallet/src/Cardano/Wallet/Address/Derivation/SharedKey.hs b/lib/wallet/src/Cardano/Wallet/Address/Derivation/SharedKey.hs index c1e92802ce6..9db10494794 100644 --- a/lib/wallet/src/Cardano/Wallet/Address/Derivation/SharedKey.hs +++ b/lib/wallet/src/Cardano/Wallet/Address/Derivation/SharedKey.hs @@ -43,8 +43,6 @@ import Cardano.Wallet.Primitive.Types.Address ( Address (..) ) import Cardano.Wallet.Read.NetworkId ( HasSNetworkId (sNetworkId), SNetworkId (..) ) -import Cardano.Wallet.TxWitnessTag - ( TxWitnessTag (..), TxWitnessTagFor (..) ) import Control.DeepSeq ( NFData (..) ) import Control.Lens @@ -90,9 +88,6 @@ sharedKey = iso getKey SharedKey instance NFData key => NFData (SharedKey depth key) -instance TxWitnessTagFor SharedKey where - txWitnessTagFor = TxWitnessShelleyUTxO - constructAddressFromIx :: forall n . HasSNetworkId n diff --git a/lib/wallet/src/Cardano/Wallet/Address/Derivation/Shelley.hs b/lib/wallet/src/Cardano/Wallet/Address/Derivation/Shelley.hs index 7a507bf4891..b498df4172a 100644 --- a/lib/wallet/src/Cardano/Wallet/Address/Derivation/Shelley.hs +++ b/lib/wallet/src/Cardano/Wallet/Address/Derivation/Shelley.hs @@ -99,8 +99,6 @@ import Cardano.Wallet.Read.NetworkId , SNetworkId (..) , networkDiscriminantBits ) -import Cardano.Wallet.TxWitnessTag - ( TxWitnessTag (..), TxWitnessTagFor (..) ) import Control.DeepSeq ( NFData (..) ) import Control.Lens @@ -150,9 +148,6 @@ shelleyKey = iso getKey ShelleyKey instance NFData key => NFData (ShelleyKey depth key) -instance TxWitnessTagFor ShelleyKey where - txWitnessTagFor = TxWitnessShelleyUTxO - -- | The minimum seed length for 'generateKeyFromSeed' and -- 'unsafeGenerateKeyFromSeed'. minSeedLengthBytes :: Int diff --git a/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs b/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs index f8231343f8e..a54a88a532a 100644 --- a/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs +++ b/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs @@ -37,7 +37,6 @@ module Cardano.Wallet.Shelley.Transaction -- * Internals , TxPayload (..) , TxWitnessTag (..) - , TxWitnessTagFor (..) , EraConstraints , _decodeSealedTx , mkDelegationCertificates @@ -45,6 +44,7 @@ module Cardano.Wallet.Shelley.Transaction , mkShelleyWitness , mkTx , mkUnsignedTx + , txWitnessTagForKey ) where import Prelude @@ -91,7 +91,7 @@ import Cardano.Wallet.Address.Derivation.Shelley import Cardano.Wallet.Address.Keys.WalletKey ( getRawKey ) import Cardano.Wallet.Flavor - ( KeyFlavorS ) + ( KeyFlavorS (..) ) import Cardano.Wallet.Primitive.Passphrase ( Passphrase (..) ) import Cardano.Wallet.Primitive.Types @@ -153,7 +153,7 @@ import Cardano.Wallet.Transaction , WitnessCountCtx (..) ) import Cardano.Wallet.TxWitnessTag - ( TxWitnessTag (..), TxWitnessTagFor (..) ) + ( TxWitnessTag (..) ) import Cardano.Wallet.Util ( HasCallStack, internalError ) import Control.Arrow @@ -267,7 +267,7 @@ constructUnsignedTx mkTx :: forall k era - . (TxWitnessTagFor k, EraConstraints era) + . EraConstraints era => KeyFlavorS k -> Cardano.NetworkId -> TxPayload era @@ -324,7 +324,7 @@ mkTx keyF networkId payload ttl (rewardAcnt, pwdAcnt) addrResolver wdrl cs fees -- If a key for a given input isn't found, the input is skipped. signTransaction :: forall k ktype era - . (EraConstraints era, TxWitnessTagFor k) + . EraConstraints era => KeyFlavorS k -> Cardano.NetworkId -- ^ Network identifier (e.g. mainnet, testnet) @@ -435,7 +435,7 @@ signTransaction addr <- resolveInput i (k, pwd) <- resolveAddress addr let pk = (getRawKey keyF k, pwd) - pure $ case txWitnessTagFor @k of + pure $ case txWitnessTagForKey keyF of TxWitnessShelleyUTxO -> mkShelleyWitness body pk TxWitnessByronUTxO -> mkByronWitness body networkId addr pk @@ -466,9 +466,7 @@ signTransaction pure $ mkShelleyWitness body (getRawKey keyF k, pwd) newTransactionLayer - :: forall k ktype - . TxWitnessTagFor k - => KeyFlavorS k + :: KeyFlavorS k -> NetworkId -> TransactionLayer k ktype SealedTx newTransactionLayer keyF networkId = TransactionLayer @@ -594,7 +592,7 @@ newTransactionLayer keyF networkId = TransactionLayer , decodeTx = _decodeSealedTx - , transactionWitnessTag = txWitnessTagFor @k + , transactionWitnessTag = txWitnessTagForKey keyF } _decodeSealedTx @@ -653,7 +651,7 @@ withShelleyBasedEra era fn = case era of -- -- Which suggests that we may get away with Shelley-only transactions for now? mkUnsignedTx - :: forall era. Cardano.IsCardanoEra era + :: forall era. Cardano.IsCardanoEra era => ShelleyBasedEra era -> (Maybe SlotNo, SlotNo) -> Either PreSelection (SelectionOf TxOut) @@ -988,7 +986,7 @@ mkShelleyWitness body key = $ Crypto.HD.xPrvChangePass pwd BS.empty xprv mkByronWitness - :: forall era. (EraConstraints era) + :: forall era. EraConstraints era => Cardano.TxBody era -> Cardano.NetworkId -> Address @@ -1025,3 +1023,18 @@ explicitFees era = case era of Cardano.TxFeeExplicit Cardano.TxFeesExplicitInBabbageEra ShelleyBasedEraConway -> Cardano.TxFeeExplicit Cardano.TxFeesExplicitInConwayEra + +-- NOTE: Should probably not exist. We could consider replacing it with +-- `UTxOAssumptions`, which has the benefit of containing the script template we +-- often need in the case of shared wallets. `UTxOAssumptions` is difficult to +-- construct, but we need to do so anyway as part of constructing txs. We could +-- ensure 'checkRewardIsWorthTxCost' can reuse that `UTxOAssumptions`. A hickup +-- regarding the name however would be that 'checkRewardIsWorthTxCost' cares +-- about assumptions about the reward account credentials, not about the utxo +-- (credentials). +txWitnessTagForKey :: KeyFlavorS a -> TxWitnessTag +txWitnessTagForKey = \case + ByronKeyS -> TxWitnessByronUTxO + IcarusKeyS -> TxWitnessByronUTxO + ShelleyKeyS -> TxWitnessShelleyUTxO + SharedKeyS -> TxWitnessShelleyUTxO diff --git a/lib/wallet/src/Cardano/Wallet/TxWitnessTag.hs b/lib/wallet/src/Cardano/Wallet/TxWitnessTag.hs index c30ebd09189..c36c4c1f58c 100644 --- a/lib/wallet/src/Cardano/Wallet/TxWitnessTag.hs +++ b/lib/wallet/src/Cardano/Wallet/TxWitnessTag.hs @@ -1,23 +1,8 @@ -{-# LANGUAGE AllowAmbiguousTypes #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE KindSignatures #-} - module Cardano.Wallet.TxWitnessTag where import Prelude -import Cardano.Wallet.Address.Derivation - ( Depth ) -import Data.Kind - ( Type ) - data TxWitnessTag = TxWitnessByronUTxO | TxWitnessShelleyUTxO deriving (Show, Eq) - --- | Provide a transaction witness for a given private key. The type of witness --- is different between types of keys and, with backward-compatible support, we --- need to support many types for one backend target. -class TxWitnessTagFor (k :: Depth -> Type -> Type) where - txWitnessTagFor :: TxWitnessTag